@formio/js 5.1.0-dev.6030.abc8cfc → 5.1.0-dev.6036.0df1d6a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/formio.builder.css +15 -17
- package/dist/formio.builder.min.css +1 -1
- package/dist/formio.form.css +15 -17
- package/dist/formio.form.js +20 -20
- package/dist/formio.form.min.css +1 -1
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +2 -2
- package/dist/formio.full.css +15 -17
- package/dist/formio.full.js +21 -21
- package/dist/formio.full.min.css +1 -1
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +2 -2
- package/dist/formio.js +1 -1
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +1 -1
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/Form.d.ts +2 -4
- package/lib/cjs/WizardBuilder.js +14 -1
- package/lib/cjs/components/_classes/component/Component.d.ts +2 -7
- package/lib/cjs/components/_classes/component/Component.js +23 -17
- package/lib/cjs/components/_classes/nested/NestedComponent.js +2 -5
- package/lib/cjs/components/editgrid/EditGrid.js +0 -4
- package/lib/cjs/components/form/Form.d.ts +1 -1
- package/lib/cjs/components/form/Form.js +5 -1
- package/lib/cjs/components/html/HTML.js +1 -2
- package/lib/cjs/components/select/Select.d.ts +0 -1
- package/lib/cjs/components/select/Select.js +3 -23
- package/lib/cjs/components/tabs/Tabs.js +1 -0
- package/lib/cjs/components/tags/Tags.d.ts +1 -1
- package/lib/cjs/components/tags/Tags.js +2 -2
- package/lib/cjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/cjs/utils/ChoicesWrapper.js +47 -124
- package/lib/mjs/Form.d.ts +2 -4
- package/lib/mjs/Form.js +1 -1
- package/lib/mjs/WizardBuilder.js +14 -1
- package/lib/mjs/components/_classes/component/Component.d.ts +2 -7
- package/lib/mjs/components/_classes/component/Component.js +23 -17
- package/lib/mjs/components/_classes/nested/NestedComponent.js +2 -5
- package/lib/mjs/components/editgrid/EditGrid.js +0 -4
- package/lib/mjs/components/form/Form.d.ts +1 -1
- package/lib/mjs/components/form/Form.js +4 -1
- package/lib/mjs/components/html/HTML.js +1 -2
- package/lib/mjs/components/select/Select.d.ts +0 -1
- package/lib/mjs/components/select/Select.js +3 -22
- package/lib/mjs/components/tabs/Tabs.js +1 -0
- package/lib/mjs/components/tags/Tags.d.ts +1 -1
- package/lib/mjs/components/tags/Tags.js +2 -2
- package/lib/mjs/utils/ChoicesWrapper.d.ts +4 -25
- package/lib/mjs/utils/ChoicesWrapper.js +26 -119
- package/package.json +2 -2
package/dist/formio.form.js
CHANGED
@@ -19,16 +19,6 @@
|
|
19
19
|
return /******/ (function() { // webpackBootstrap
|
20
20
|
/******/ var __webpack_modules__ = ({
|
21
21
|
|
22
|
-
/***/ "./node_modules/@formio/choices.js/public/assets/scripts/choices.js":
|
23
|
-
/*!**************************************************************************!*\
|
24
|
-
!*** ./node_modules/@formio/choices.js/public/assets/scripts/choices.js ***!
|
25
|
-
\**************************************************************************/
|
26
|
-
/***/ (function(module) {
|
27
|
-
|
28
|
-
eval("/*! @formio/choices.js v10.2.1 | © 2024 Josh Johnson | https://github.com/jshjohnson/Choices#readme */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse {}\n})(window, () => {\nreturn /******/ (() => { // webpackBootstrap\n/******/ \t\"use strict\";\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 282:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_622__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.clearChoices = exports.activateChoices = exports.filterChoices = exports.addChoice = void 0;\nvar constants_1 = __nested_webpack_require_622__(883);\nvar addChoice = function (_a) {\n var value = _a.value,\n label = _a.label,\n id = _a.id,\n groupId = _a.groupId,\n disabled = _a.disabled,\n elementId = _a.elementId,\n customProperties = _a.customProperties,\n placeholder = _a.placeholder,\n keyCode = _a.keyCode;\n return {\n type: constants_1.ACTION_TYPES.ADD_CHOICE,\n value: value,\n label: label,\n id: id,\n groupId: groupId,\n disabled: disabled,\n elementId: elementId,\n customProperties: customProperties,\n placeholder: placeholder,\n keyCode: keyCode\n };\n};\nexports.addChoice = addChoice;\nvar filterChoices = function (results) {\n return {\n type: constants_1.ACTION_TYPES.FILTER_CHOICES,\n results: results\n };\n};\nexports.filterChoices = filterChoices;\nvar activateChoices = function (active) {\n if (active === void 0) {\n active = true;\n }\n return {\n type: constants_1.ACTION_TYPES.ACTIVATE_CHOICES,\n active: active\n };\n};\nexports.activateChoices = activateChoices;\nvar clearChoices = function () {\n return {\n type: constants_1.ACTION_TYPES.CLEAR_CHOICES\n };\n};\nexports.clearChoices = clearChoices;\n\n/***/ }),\n\n/***/ 783:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_2053__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.addGroup = void 0;\nvar constants_1 = __nested_webpack_require_2053__(883);\nvar addGroup = function (_a) {\n var value = _a.value,\n id = _a.id,\n active = _a.active,\n disabled = _a.disabled;\n return {\n type: constants_1.ACTION_TYPES.ADD_GROUP,\n value: value,\n id: id,\n active: active,\n disabled: disabled\n };\n};\nexports.addGroup = addGroup;\n\n/***/ }),\n\n/***/ 464:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_2575__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.highlightItem = exports.removeItem = exports.addItem = void 0;\nvar constants_1 = __nested_webpack_require_2575__(883);\nvar addItem = function (_a) {\n var value = _a.value,\n label = _a.label,\n id = _a.id,\n choiceId = _a.choiceId,\n groupId = _a.groupId,\n customProperties = _a.customProperties,\n placeholder = _a.placeholder,\n keyCode = _a.keyCode;\n return {\n type: constants_1.ACTION_TYPES.ADD_ITEM,\n value: value,\n label: label,\n id: id,\n choiceId: choiceId,\n groupId: groupId,\n customProperties: customProperties,\n placeholder: placeholder,\n keyCode: keyCode\n };\n};\nexports.addItem = addItem;\nvar removeItem = function (id, choiceId) {\n return {\n type: constants_1.ACTION_TYPES.REMOVE_ITEM,\n id: id,\n choiceId: choiceId\n };\n};\nexports.removeItem = removeItem;\nvar highlightItem = function (id, highlighted) {\n return {\n type: constants_1.ACTION_TYPES.HIGHLIGHT_ITEM,\n id: id,\n highlighted: highlighted\n };\n};\nexports.highlightItem = highlightItem;\n\n/***/ }),\n\n/***/ 137:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_3754__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.setIsLoading = exports.resetTo = exports.clearAll = void 0;\nvar constants_1 = __nested_webpack_require_3754__(883);\nvar clearAll = function () {\n return {\n type: constants_1.ACTION_TYPES.CLEAR_ALL\n };\n};\nexports.clearAll = clearAll;\nvar resetTo = function (state) {\n return {\n type: constants_1.ACTION_TYPES.RESET_TO,\n state: state\n };\n};\nexports.resetTo = resetTo;\nvar setIsLoading = function (isLoading) {\n return {\n type: constants_1.ACTION_TYPES.SET_IS_LOADING,\n isLoading: isLoading\n };\n};\nexports.setIsLoading = setIsLoading;\n\n/***/ }),\n\n/***/ 373:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_4472__) {\n\n\n\nvar __spreadArray = this && this.__spreadArray || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar deepmerge_1 = __importDefault(__nested_webpack_require_4472__(996));\n/* eslint-disable @typescript-eslint/no-explicit-any */\nvar fuse_js_1 = __importDefault(__nested_webpack_require_4472__(221));\nvar choices_1 = __nested_webpack_require_4472__(282);\nvar groups_1 = __nested_webpack_require_4472__(783);\nvar items_1 = __nested_webpack_require_4472__(464);\nvar misc_1 = __nested_webpack_require_4472__(137);\nvar components_1 = __nested_webpack_require_4472__(520);\nvar constants_1 = __nested_webpack_require_4472__(883);\nvar defaults_1 = __nested_webpack_require_4472__(789);\nvar utils_1 = __nested_webpack_require_4472__(799);\nvar reducers_1 = __nested_webpack_require_4472__(655);\nvar store_1 = __importDefault(__nested_webpack_require_4472__(744));\nvar templates_1 = __importDefault(__nested_webpack_require_4472__(686));\n/** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */\nvar IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style;\nvar USER_DEFAULTS = {};\n/**\n * Choices\n * @author Josh Johnson<josh@joshuajohnson.co.uk>\n */\nvar Choices = /** @class */function () {\n function Choices(element, userConfig) {\n if (element === void 0) {\n element = '[data-choice]';\n }\n if (userConfig === void 0) {\n userConfig = {};\n }\n var _this = this;\n if (userConfig.allowHTML === undefined) {\n console.warn('Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.');\n }\n this.config = deepmerge_1.default.all([defaults_1.DEFAULT_CONFIG, Choices.defaults.options, userConfig],\n // When merging array configs, replace with a copy of the userConfig array,\n // instead of concatenating with the default array\n {\n arrayMerge: function (_, sourceArray) {\n return __spreadArray([], sourceArray, true);\n }\n });\n // Restore the shadowRoot if provided. deeperge converts it into an empty object.\n if (userConfig.shadowRoot) {\n this.config.shadowRoot = userConfig.shadowRoot;\n }\n var invalidConfigOptions = (0, utils_1.diff)(this.config, defaults_1.DEFAULT_CONFIG);\n if (invalidConfigOptions.length) {\n console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', '));\n }\n var passedElement = typeof element === 'string' ? document.querySelector(element) : element;\n if (!(passedElement instanceof HTMLInputElement || passedElement instanceof HTMLSelectElement)) {\n throw TypeError('Expected one of the following types text|select-one|select-multiple');\n }\n this._isTextElement = passedElement.type === constants_1.TEXT_TYPE;\n this._isSelectOneElement = passedElement.type === constants_1.SELECT_ONE_TYPE;\n this._isSelectMultipleElement = passedElement.type === constants_1.SELECT_MULTIPLE_TYPE;\n this._isSelectElement = this._isSelectOneElement || this._isSelectMultipleElement;\n this.config.searchEnabled = this._isSelectMultipleElement || this.config.searchEnabled;\n if (!['auto', 'always'].includes(\"\".concat(this.config.renderSelectedChoices))) {\n this.config.renderSelectedChoices = 'auto';\n }\n if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') {\n var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter);\n this.config.addItemFilter = re.test.bind(re);\n }\n if (this._isTextElement) {\n this.passedElement = new components_1.WrappedInput({\n element: passedElement,\n classNames: this.config.classNames,\n delimiter: this.config.delimiter\n });\n } else {\n this.passedElement = new components_1.WrappedSelect({\n element: passedElement,\n classNames: this.config.classNames,\n template: function (data) {\n return _this._templates.option(data);\n }\n });\n }\n this.initialised = false;\n this._store = new store_1.default();\n this._initialState = reducers_1.defaultState;\n this._currentState = reducers_1.defaultState;\n this._prevState = reducers_1.defaultState;\n this._currentValue = '';\n this._canSearch = !!this.config.searchEnabled;\n this._isScrollingOnIe = false;\n this._highlightPosition = 0;\n this._wasTap = true;\n this._placeholderValue = this._generatePlaceholderValue();\n this._baseId = (0, utils_1.generateId)(this.passedElement.element, 'choices-');\n /**\n * setting direction in cases where it's explicitly set on passedElement\n * or when calculated direction is different from the document\n */\n this._direction = this.passedElement.dir;\n if (!this._direction) {\n var elementDirection = window.getComputedStyle(this.passedElement.element).direction;\n var documentDirection = window.getComputedStyle(document.documentElement).direction;\n if (elementDirection !== documentDirection) {\n this._direction = elementDirection;\n }\n }\n this._idNames = {\n itemChoice: 'item-choice'\n };\n if (this._isSelectElement) {\n // Assign preset groups from passed element\n this._presetGroups = this.passedElement.optionGroups;\n // Assign preset options from passed element\n this._presetOptions = this.passedElement.options;\n }\n // Assign preset choices from passed object\n this._presetChoices = this.config.choices;\n // Assign preset items from passed object first\n this._presetItems = this.config.items;\n // Add any values passed from attribute\n if (this.passedElement.value && this._isTextElement) {\n var splitValues = this.passedElement.value.split(this.config.delimiter);\n this._presetItems = this._presetItems.concat(splitValues);\n }\n // Create array of choices from option elements\n if (this.passedElement.options) {\n this.passedElement.options.forEach(function (option) {\n _this._presetChoices.push({\n value: option.value,\n label: option.innerHTML,\n selected: !!option.selected,\n disabled: option.disabled || option.parentNode.disabled,\n placeholder: option.value === '' || option.hasAttribute('placeholder'),\n customProperties: (0, utils_1.parseCustomProperties)(option.dataset.customProperties)\n });\n });\n }\n this._render = this._render.bind(this);\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n this._onKeyUp = this._onKeyUp.bind(this);\n this._onKeyDown = this._onKeyDown.bind(this);\n this._onClick = this._onClick.bind(this);\n this._onTouchMove = this._onTouchMove.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseOver = this._onMouseOver.bind(this);\n this._onFormReset = this._onFormReset.bind(this);\n this._onSelectKey = this._onSelectKey.bind(this);\n this._onEnterKey = this._onEnterKey.bind(this);\n this._onEscapeKey = this._onEscapeKey.bind(this);\n this._onDirectionKey = this._onDirectionKey.bind(this);\n this._onDeleteKey = this._onDeleteKey.bind(this);\n // If element has already been initialised with Choices, fail silently\n if (this.passedElement.isActive) {\n if (!this.config.silent) {\n console.warn('Trying to initialise Choices on element already initialised', {\n element: element\n });\n }\n this.initialised = true;\n return;\n }\n // Let's go\n this.init();\n }\n Object.defineProperty(Choices, \"defaults\", {\n get: function () {\n return Object.preventExtensions({\n get options() {\n return USER_DEFAULTS;\n },\n get templates() {\n return templates_1.default;\n }\n });\n },\n enumerable: false,\n configurable: true\n });\n Choices.prototype.init = function () {\n if (this.initialised) {\n return;\n }\n this._createTemplates();\n this._createElements();\n this._createStructure();\n this._store.subscribe(this._render);\n this._render();\n this._addEventListeners();\n var shouldDisable = !this.config.addItems || this.passedElement.element.hasAttribute('disabled');\n if (shouldDisable) {\n this.disable();\n }\n this.initialised = true;\n var callbackOnInit = this.config.callbackOnInit;\n // Run callback if it is a function\n if (callbackOnInit && typeof callbackOnInit === 'function') {\n callbackOnInit.call(this);\n }\n };\n Choices.prototype.destroy = function () {\n if (!this.initialised) {\n return;\n }\n this._removeEventListeners();\n this.passedElement.reveal();\n this.containerOuter.unwrap(this.passedElement.element);\n this.clearStore();\n if (this._isSelectElement) {\n this.passedElement.options = this._presetOptions;\n }\n this._templates = templates_1.default;\n this.initialised = false;\n };\n Choices.prototype.enable = function () {\n if (this.passedElement.isDisabled) {\n this.passedElement.enable();\n }\n if (this.containerOuter.isDisabled) {\n this._addEventListeners();\n this.input.enable();\n this.containerOuter.enable();\n }\n return this;\n };\n Choices.prototype.disable = function () {\n if (!this.passedElement.isDisabled) {\n this.passedElement.disable();\n }\n if (!this.containerOuter.isDisabled) {\n this._removeEventListeners();\n this.input.disable();\n this.containerOuter.disable();\n }\n return this;\n };\n Choices.prototype.highlightItem = function (item, runEvent) {\n if (runEvent === void 0) {\n runEvent = true;\n }\n if (!item || !item.id) {\n return this;\n }\n var id = item.id,\n _a = item.groupId,\n groupId = _a === void 0 ? -1 : _a,\n _b = item.value,\n value = _b === void 0 ? '' : _b,\n _c = item.label,\n label = _c === void 0 ? '' : _c;\n var group = groupId >= 0 ? this._store.getGroupById(groupId) : null;\n this._store.dispatch((0, items_1.highlightItem)(id, true));\n if (runEvent) {\n this.passedElement.triggerEvent(constants_1.EVENTS.highlightItem, {\n id: id,\n value: value,\n label: label,\n groupValue: group && group.value ? group.value : null\n });\n }\n return this;\n };\n Choices.prototype.unhighlightItem = function (item) {\n if (!item || !item.id) {\n return this;\n }\n var id = item.id,\n _a = item.groupId,\n groupId = _a === void 0 ? -1 : _a,\n _b = item.value,\n value = _b === void 0 ? '' : _b,\n _c = item.label,\n label = _c === void 0 ? '' : _c;\n var group = groupId >= 0 ? this._store.getGroupById(groupId) : null;\n this._store.dispatch((0, items_1.highlightItem)(id, false));\n this.passedElement.triggerEvent(constants_1.EVENTS.highlightItem, {\n id: id,\n value: value,\n label: label,\n groupValue: group && group.value ? group.value : null\n });\n return this;\n };\n Choices.prototype.highlightAll = function () {\n var _this = this;\n this._store.items.forEach(function (item) {\n return _this.highlightItem(item);\n });\n return this;\n };\n Choices.prototype.unhighlightAll = function () {\n var _this = this;\n this._store.items.forEach(function (item) {\n return _this.unhighlightItem(item);\n });\n return this;\n };\n Choices.prototype.removeActiveItemsByValue = function (value) {\n var _this = this;\n this._store.activeItems.filter(function (item) {\n return item.value === value;\n }).forEach(function (item) {\n return _this._removeItem(item);\n });\n return this;\n };\n Choices.prototype.removeActiveItems = function (excludedId) {\n var _this = this;\n this._store.activeItems.filter(function (_a) {\n var id = _a.id;\n return id !== excludedId;\n }).forEach(function (item) {\n return _this._removeItem(item);\n });\n return this;\n };\n Choices.prototype.removeHighlightedItems = function (runEvent) {\n var _this = this;\n if (runEvent === void 0) {\n runEvent = false;\n }\n this._store.highlightedActiveItems.forEach(function (item) {\n _this._removeItem(item);\n // If this action was performed by the user\n // trigger the event\n if (runEvent) {\n _this._triggerChange(item.value);\n }\n });\n return this;\n };\n Choices.prototype.showDropdown = function (preventInputFocus) {\n var _this = this;\n if (this.dropdown.isActive) {\n return this;\n }\n requestAnimationFrame(function () {\n _this.dropdown.show();\n _this.containerOuter.open(_this.dropdown.distanceFromTopWindow, _this.dropdown.height);\n if (!preventInputFocus && _this._canSearch) {\n _this.input.focus();\n }\n _this.passedElement.triggerEvent(constants_1.EVENTS.showDropdown, {});\n });\n return this;\n };\n Choices.prototype.hideDropdown = function (preventInputBlur) {\n var _this = this;\n if (!this.dropdown.isActive) {\n return this;\n }\n requestAnimationFrame(function () {\n _this.dropdown.hide();\n _this.containerOuter.close();\n if (!preventInputBlur && _this._canSearch) {\n _this.input.removeActiveDescendant();\n _this.input.blur();\n }\n _this.passedElement.triggerEvent(constants_1.EVENTS.hideDropdown, {});\n });\n return this;\n };\n Choices.prototype.getValue = function (valueOnly) {\n if (valueOnly === void 0) {\n valueOnly = false;\n }\n var values = this._store.activeItems.reduce(function (selectedItems, item) {\n var itemValue = valueOnly ? item.value : item;\n selectedItems.push(itemValue);\n return selectedItems;\n }, []);\n return this._isSelectOneElement ? values[0] : values;\n };\n Choices.prototype.setValue = function (items) {\n var _this = this;\n if (!this.initialised) {\n return this;\n }\n items.forEach(function (value) {\n return _this._setChoiceOrItem(value);\n });\n return this;\n };\n Choices.prototype.setChoiceByValue = function (value) {\n var _this = this;\n if (!this.initialised || this._isTextElement) {\n return this;\n }\n // If only one value has been passed, convert to array\n var choiceValue = Array.isArray(value) ? value : [value];\n // Loop through each value and\n choiceValue.forEach(function (val) {\n return _this._findAndSelectChoiceByValue(val);\n });\n return this;\n };\n /**\n * Set choices of select input via an array of objects (or function that returns array of object or promise of it),\n * a value field name and a label field name.\n * This behaves the same as passing items via the choices option but can be called after initialising Choices.\n * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.\n * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).\n *\n * **Input types affected:** select-one, select-multiple\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices([\n * {value: 'One', label: 'Label One', disabled: true},\n * {value: 'Two', label: 'Label Two', selected: true},\n * {value: 'Three', label: 'Label Three'},\n * ], 'value', 'label', false);\n * ```\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices(async () => {\n * try {\n * const items = await fetch('/items');\n * return items.json()\n * } catch(err) {\n * console.error(err)\n * }\n * });\n * ```\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices([{\n * label: 'Group one',\n * id: 1,\n * disabled: false,\n * choices: [\n * {value: 'Child One', label: 'Child One', selected: true},\n * {value: 'Child Two', label: 'Child Two', disabled: true},\n * {value: 'Child Three', label: 'Child Three'},\n * ]\n * },\n * {\n * label: 'Group two',\n * id: 2,\n * disabled: false,\n * choices: [\n * {value: 'Child Four', label: 'Child Four', disabled: true},\n * {value: 'Child Five', label: 'Child Five'},\n * {value: 'Child Six', label: 'Child Six', customProperties: {\n * description: 'Custom description about child six',\n * random: 'Another random custom property'\n * }},\n * ]\n * }], 'value', 'label', false);\n * ```\n */\n Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices) {\n var _this = this;\n if (choicesArrayOrFetcher === void 0) {\n choicesArrayOrFetcher = [];\n }\n if (value === void 0) {\n value = 'value';\n }\n if (label === void 0) {\n label = 'label';\n }\n if (replaceChoices === void 0) {\n replaceChoices = false;\n }\n if (!this.initialised) {\n throw new ReferenceError(\"setChoices was called on a non-initialized instance of Choices\");\n }\n if (!this._isSelectElement) {\n throw new TypeError(\"setChoices can't be used with INPUT based Choices\");\n }\n if (typeof value !== 'string' || !value) {\n throw new TypeError(\"value parameter must be a name of 'value' field in passed objects\");\n }\n // Clear choices if needed\n if (replaceChoices) {\n this.clearChoices();\n }\n if (typeof choicesArrayOrFetcher === 'function') {\n // it's a choices fetcher function\n var fetcher_1 = choicesArrayOrFetcher(this);\n if (typeof Promise === 'function' && fetcher_1 instanceof Promise) {\n // that's a promise\n // eslint-disable-next-line no-promise-executor-return\n return new Promise(function (resolve) {\n return requestAnimationFrame(resolve);\n }).then(function () {\n return _this._handleLoadingState(true);\n }).then(function () {\n return fetcher_1;\n }).then(function (data) {\n return _this.setChoices(data, value, label, replaceChoices);\n }).catch(function (err) {\n if (!_this.config.silent) {\n console.error(err);\n }\n }).then(function () {\n return _this._handleLoadingState(false);\n }).then(function () {\n return _this;\n });\n }\n // function returned something else than promise, let's check if it's an array of choices\n if (!Array.isArray(fetcher_1)) {\n throw new TypeError(\".setChoices first argument function must return either array of choices or Promise, got: \".concat(typeof fetcher_1));\n }\n // recursion with results, it's sync and choices were cleared already\n return this.setChoices(fetcher_1, value, label, false);\n }\n if (!Array.isArray(choicesArrayOrFetcher)) {\n throw new TypeError(\".setChoices must be called either with array of choices with a function resulting into Promise of array of choices\");\n }\n this.containerOuter.removeLoadingState();\n this._startLoading();\n choicesArrayOrFetcher.forEach(function (groupOrChoice) {\n if (groupOrChoice.choices) {\n _this._addGroup({\n id: groupOrChoice.id ? parseInt(\"\".concat(groupOrChoice.id), 10) : null,\n group: groupOrChoice,\n valueKey: value,\n labelKey: label\n });\n } else {\n var choice = groupOrChoice;\n _this._addChoice({\n value: choice[value],\n label: choice[label],\n isSelected: !!choice.selected,\n isDisabled: !!choice.disabled,\n placeholder: !!choice.placeholder,\n customProperties: choice.customProperties\n });\n }\n });\n this._stopLoading();\n return this;\n };\n Choices.prototype.clearChoices = function () {\n this._store.dispatch((0, choices_1.clearChoices)());\n return this;\n };\n Choices.prototype.clearStore = function () {\n this._store.dispatch((0, misc_1.clearAll)());\n return this;\n };\n Choices.prototype.clearInput = function () {\n var shouldSetInputWidth = !this._isSelectOneElement;\n this.input.clear(shouldSetInputWidth);\n if (!this._isTextElement && this._canSearch) {\n this._isSearching = false;\n this._store.dispatch((0, choices_1.activateChoices)(true));\n }\n return this;\n };\n Choices.prototype._render = function () {\n if (this._store.isLoading()) {\n return;\n }\n this._currentState = this._store.state;\n var stateChanged = this._currentState.choices !== this._prevState.choices || this._currentState.groups !== this._prevState.groups || this._currentState.items !== this._prevState.items;\n var shouldRenderChoices = this._isSelectElement;\n var shouldRenderItems = this._currentState.items !== this._prevState.items;\n if (!stateChanged) {\n return;\n }\n if (shouldRenderChoices) {\n this._renderChoices();\n }\n if (shouldRenderItems) {\n this._renderItems();\n }\n this._prevState = this._currentState;\n };\n Choices.prototype._renderChoices = function () {\n var _this = this;\n var _a = this._store,\n activeGroups = _a.activeGroups,\n activeChoices = _a.activeChoices;\n var choiceListFragment = document.createDocumentFragment();\n this.choiceList.clear();\n if (this.config.resetScrollPosition) {\n requestAnimationFrame(function () {\n return _this.choiceList.scrollToTop();\n });\n }\n // If we have grouped options\n if (activeGroups.length >= 1 && !this._isSearching) {\n // If we have a placeholder choice along with groups\n var activePlaceholders = activeChoices.filter(function (activeChoice) {\n return activeChoice.placeholder === true && activeChoice.groupId === -1;\n });\n if (activePlaceholders.length >= 1) {\n choiceListFragment = this._createChoicesFragment(activePlaceholders, choiceListFragment);\n }\n choiceListFragment = this._createGroupsFragment(activeGroups, activeChoices, choiceListFragment);\n } else if (activeChoices.length >= 1) {\n choiceListFragment = this._createChoicesFragment(activeChoices, choiceListFragment);\n }\n // If we have choices to show\n if (choiceListFragment.childNodes && choiceListFragment.childNodes.length > 0) {\n var activeItems = this._store.activeItems;\n var canAddItem = this._canAddItem(activeItems, this.input.value);\n // ...and we can select them\n if (canAddItem.response) {\n // ...append them and highlight the first choice\n this.choiceList.append(choiceListFragment);\n this._highlightChoice();\n } else {\n var notice = this._getTemplate('notice', canAddItem.notice);\n this.choiceList.append(notice);\n }\n } else {\n // Otherwise show a notice\n var dropdownItem = void 0;\n var notice = void 0;\n if (this._isSearching) {\n notice = typeof this.config.noResultsText === 'function' ? this.config.noResultsText() : this.config.noResultsText;\n dropdownItem = this._getTemplate('notice', notice, 'no-results');\n } else {\n notice = typeof this.config.noChoicesText === 'function' ? this.config.noChoicesText() : this.config.noChoicesText;\n dropdownItem = this._getTemplate('notice', notice, 'no-choices');\n }\n this.choiceList.append(dropdownItem);\n }\n };\n Choices.prototype._renderItems = function () {\n var activeItems = this._store.activeItems || [];\n this.itemList.clear();\n // Create a fragment to store our list items\n // (so we don't have to update the DOM for each item)\n var itemListFragment = this._createItemsFragment(activeItems);\n // If we have items to add, append them\n if (itemListFragment.childNodes) {\n this.itemList.append(itemListFragment);\n }\n };\n Choices.prototype._createGroupsFragment = function (groups, choices, fragment) {\n var _this = this;\n if (fragment === void 0) {\n fragment = document.createDocumentFragment();\n }\n var getGroupChoices = function (group) {\n return choices.filter(function (choice) {\n if (_this._isSelectOneElement) {\n return choice.groupId === group.id;\n }\n return choice.groupId === group.id && (_this.config.renderSelectedChoices === 'always' || !choice.selected);\n });\n };\n // If sorting is enabled, filter groups\n if (this.config.shouldSort) {\n groups.sort(this.config.sorter);\n }\n groups.forEach(function (group) {\n var groupChoices = getGroupChoices(group);\n if (groupChoices.length >= 1) {\n var dropdownGroup = _this._getTemplate('choiceGroup', group);\n fragment.appendChild(dropdownGroup);\n _this._createChoicesFragment(groupChoices, fragment, true);\n }\n });\n return fragment;\n };\n Choices.prototype._createChoicesFragment = function (choices, fragment, withinGroup) {\n var _this = this;\n if (fragment === void 0) {\n fragment = document.createDocumentFragment();\n }\n if (withinGroup === void 0) {\n withinGroup = false;\n }\n // Create a fragment to store our list items (so we don't have to update the DOM for each item)\n var _a = this.config,\n renderSelectedChoices = _a.renderSelectedChoices,\n searchResultLimit = _a.searchResultLimit,\n renderChoiceLimit = _a.renderChoiceLimit;\n var filter = this._isSearching ? utils_1.sortByScore : this.config.sorter;\n var appendChoice = function (choice) {\n var shouldRender = renderSelectedChoices === 'auto' ? _this._isSelectOneElement || !choice.selected : true;\n if (shouldRender) {\n var dropdownItem = _this._getTemplate('choice', choice, _this.config.itemSelectText);\n fragment.appendChild(dropdownItem);\n }\n };\n var rendererableChoices = choices;\n if (renderSelectedChoices === 'auto' && !this._isSelectOneElement) {\n rendererableChoices = choices.filter(function (choice) {\n return !choice.selected;\n });\n }\n // Split array into placeholders and \"normal\" choices\n var _b = rendererableChoices.reduce(function (acc, choice) {\n if (choice.placeholder) {\n acc.placeholderChoices.push(choice);\n } else {\n acc.normalChoices.push(choice);\n }\n return acc;\n }, {\n placeholderChoices: [],\n normalChoices: []\n }),\n placeholderChoices = _b.placeholderChoices,\n normalChoices = _b.normalChoices;\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort || this._isSearching) {\n normalChoices.sort(filter);\n }\n var choiceLimit = rendererableChoices.length;\n // Prepend placeholeder\n var sortedChoices = this._isSelectOneElement ? __spreadArray(__spreadArray([], placeholderChoices, true), normalChoices, true) : normalChoices;\n if (this._isSearching) {\n choiceLimit = searchResultLimit;\n } else if (renderChoiceLimit && renderChoiceLimit > 0 && !withinGroup) {\n choiceLimit = renderChoiceLimit;\n }\n // Add each choice to dropdown within range\n for (var i = 0; i < choiceLimit; i += 1) {\n if (sortedChoices[i]) {\n appendChoice(sortedChoices[i]);\n }\n }\n return fragment;\n };\n Choices.prototype._createItemsFragment = function (items, fragment) {\n var _this = this;\n if (fragment === void 0) {\n fragment = document.createDocumentFragment();\n }\n // Create fragment to add elements to\n var _a = this.config,\n shouldSortItems = _a.shouldSortItems,\n sorter = _a.sorter,\n removeItemButton = _a.removeItemButton;\n // If sorting is enabled, filter items\n if (shouldSortItems && !this._isSelectOneElement) {\n items.sort(sorter);\n }\n if (this._isTextElement) {\n // Update the value of the hidden input\n this.passedElement.value = items.map(function (_a) {\n var value = _a.value;\n return value;\n }).join(this.config.delimiter);\n } else {\n // Update the options of the hidden input\n this.passedElement.options = items;\n }\n var addItemToFragment = function (item) {\n // Create new list element\n var listItem = _this._getTemplate('item', item, removeItemButton);\n // Append it to list\n fragment.appendChild(listItem);\n };\n // Add each list item to list\n items.forEach(addItemToFragment);\n return fragment;\n };\n Choices.prototype._triggerChange = function (value) {\n if (value === undefined || value === null) {\n return;\n }\n this.passedElement.triggerEvent(constants_1.EVENTS.change, {\n value: value\n });\n };\n Choices.prototype._selectPlaceholderChoice = function (placeholderChoice) {\n this._addItem({\n value: placeholderChoice.value,\n label: placeholderChoice.label,\n choiceId: placeholderChoice.id,\n groupId: placeholderChoice.groupId,\n placeholder: placeholderChoice.placeholder\n });\n this._triggerChange(placeholderChoice.value);\n };\n Choices.prototype._handleButtonAction = function (activeItems, element) {\n if (!activeItems || !element || !this.config.removeItems || !this.config.removeItemButton) {\n return;\n }\n var itemId = element.parentNode && element.parentNode.dataset.id;\n var itemToRemove = itemId && activeItems.find(function (item) {\n return item.id === parseInt(itemId, 10);\n });\n if (!itemToRemove) {\n return;\n }\n // Remove item associated with button\n this._removeItem(itemToRemove);\n this._triggerChange(itemToRemove.value);\n if (this._isSelectOneElement && this._store.placeholderChoice) {\n this._selectPlaceholderChoice(this._store.placeholderChoice);\n }\n };\n Choices.prototype._handleItemAction = function (activeItems, element, hasShiftKey) {\n var _this = this;\n if (hasShiftKey === void 0) {\n hasShiftKey = false;\n }\n if (!activeItems || !element || !this.config.removeItems || this._isSelectOneElement) {\n return;\n }\n var passedId = element.dataset.id;\n // We only want to select one item with a click\n // so we deselect any items that aren't the target\n // unless shift is being pressed\n activeItems.forEach(function (item) {\n if (item.id === parseInt(\"\".concat(passedId), 10) && !item.highlighted) {\n _this.highlightItem(item);\n } else if (!hasShiftKey && item.highlighted) {\n _this.unhighlightItem(item);\n }\n });\n // Focus input as without focus, a user cannot do anything with a\n // highlighted item\n this.input.focus();\n };\n Choices.prototype._handleChoiceAction = function (activeItems, element) {\n if (!activeItems || !element) {\n return;\n }\n // If we are clicking on an option\n var id = element.dataset.id;\n var choice = id && this._store.getChoiceById(id);\n if (!choice) {\n return;\n }\n var passedKeyCode = activeItems[0] && activeItems[0].keyCode ? activeItems[0].keyCode : undefined;\n var hasActiveDropdown = this.dropdown.isActive;\n // Update choice keyCode\n choice.keyCode = passedKeyCode;\n this.passedElement.triggerEvent(constants_1.EVENTS.choice, {\n choice: choice\n });\n if (!choice.selected && !choice.disabled) {\n var canAddItem = this._canAddItem(activeItems, choice.value);\n if (canAddItem.response) {\n this._addItem({\n value: choice.value,\n label: choice.label,\n choiceId: choice.id,\n groupId: choice.groupId,\n customProperties: choice.customProperties,\n placeholder: choice.placeholder,\n keyCode: choice.keyCode\n });\n this._triggerChange(choice.value);\n }\n }\n this.clearInput();\n // We want to close the dropdown if we are dealing with a single select box\n if (hasActiveDropdown && this._isSelectOneElement) {\n this.hideDropdown(true);\n this.containerOuter.focus();\n }\n };\n Choices.prototype._handleBackspace = function (activeItems) {\n if (!this.config.removeItems || !activeItems) {\n return;\n }\n var lastItem = activeItems[activeItems.length - 1];\n var hasHighlightedItems = activeItems.some(function (item) {\n return item.highlighted;\n });\n // If editing the last item is allowed and there are not other selected items,\n // we can edit the item value. Otherwise if we can remove items, remove all selected items\n if (this.config.editItems && !hasHighlightedItems && lastItem) {\n this.input.value = lastItem.value;\n this.input.setWidth();\n this._removeItem(lastItem);\n this._triggerChange(lastItem.value);\n } else {\n if (!hasHighlightedItems) {\n // Highlight last item if none already highlighted\n this.highlightItem(lastItem, false);\n }\n this.removeHighlightedItems(true);\n }\n };\n Choices.prototype._startLoading = function () {\n this._store.dispatch((0, misc_1.setIsLoading)(true));\n };\n Choices.prototype._stopLoading = function () {\n this._store.dispatch((0, misc_1.setIsLoading)(false));\n };\n Choices.prototype._handleLoadingState = function (setLoading) {\n if (setLoading === void 0) {\n setLoading = true;\n }\n var placeholderItem = this.itemList.getChild(\".\".concat(this.config.classNames.placeholder));\n if (setLoading) {\n this.disable();\n this.containerOuter.addLoadingState();\n if (this._isSelectOneElement) {\n if (!placeholderItem) {\n placeholderItem = this._getTemplate('placeholder', this.config.loadingText);\n if (placeholderItem) {\n this.itemList.append(placeholderItem);\n }\n } else {\n placeholderItem.innerHTML = this.config.loadingText;\n }\n } else {\n this.input.placeholder = this.config.loadingText;\n }\n } else {\n this.enable();\n this.containerOuter.removeLoadingState();\n if (this._isSelectOneElement) {\n if (placeholderItem) {\n placeholderItem.innerHTML = this._placeholderValue || '';\n }\n } else {\n this.input.placeholder = this._placeholderValue || '';\n }\n }\n };\n Choices.prototype._handleSearch = function (value) {\n if (!this.input.isFocussed) {\n return;\n }\n var choices = this._store.choices;\n var _a = this.config,\n searchFloor = _a.searchFloor,\n searchChoices = _a.searchChoices;\n var hasUnactiveChoices = choices.some(function (option) {\n return !option.active;\n });\n // Check that we have a value to search and the input was an alphanumeric character\n if (value !== null && typeof value !== 'undefined' && value.length >= searchFloor) {\n var resultCount = searchChoices ? this._searchChoices(value) : 0;\n // Trigger search event\n this.passedElement.triggerEvent(constants_1.EVENTS.search, {\n value: value,\n resultCount: resultCount\n });\n } else if (hasUnactiveChoices) {\n // Otherwise reset choices to active\n this._isSearching = false;\n this._store.dispatch((0, choices_1.activateChoices)(true));\n }\n };\n Choices.prototype._canAddItem = function (activeItems, value) {\n var canAddItem = true;\n var notice = typeof this.config.addItemText === 'function' ? this.config.addItemText(value) : this.config.addItemText;\n if (!this._isSelectOneElement) {\n var isDuplicateValue = (0, utils_1.existsInArray)(activeItems, value);\n if (this.config.maxItemCount > 0 && this.config.maxItemCount <= activeItems.length) {\n // If there is a max entry limit and we have reached that limit\n // don't update\n canAddItem = false;\n notice = typeof this.config.maxItemText === 'function' ? this.config.maxItemText(this.config.maxItemCount) : this.config.maxItemText;\n }\n if (!this.config.duplicateItemsAllowed && isDuplicateValue && canAddItem) {\n canAddItem = false;\n notice = typeof this.config.uniqueItemText === 'function' ? this.config.uniqueItemText(value) : this.config.uniqueItemText;\n }\n if (this._isTextElement && this.config.addItems && canAddItem && typeof this.config.addItemFilter === 'function' && !this.config.addItemFilter(value)) {\n canAddItem = false;\n notice = typeof this.config.customAddItemText === 'function' ? this.config.customAddItemText(value) : this.config.customAddItemText;\n }\n }\n return {\n response: canAddItem,\n notice: notice\n };\n };\n Choices.prototype._searchChoices = function (value) {\n var newValue = typeof value === 'string' ? value.trim() : value;\n var currentValue = typeof this._currentValue === 'string' ? this._currentValue.trim() : this._currentValue;\n if (newValue.length < 1 && newValue === \"\".concat(currentValue, \" \")) {\n return 0;\n }\n // If new value matches the desired length and is not the same as the current value with a space\n var haystack = this._store.searchableChoices;\n var needle = newValue;\n var options = Object.assign(this.config.fuseOptions, {\n keys: __spreadArray([], this.config.searchFields, true),\n includeMatches: true\n });\n var fuse = new fuse_js_1.default(haystack, options);\n var results = fuse.search(needle); // see https://github.com/krisk/Fuse/issues/303\n this._currentValue = newValue;\n this._highlightPosition = 0;\n this._isSearching = true;\n this._store.dispatch((0, choices_1.filterChoices)(results));\n return results.length;\n };\n Choices.prototype._addEventListeners = function () {\n var documentElement = this.config.shadowRoot || document.documentElement;\n // capture events - can cancel event processing or propagation\n documentElement.addEventListener('touchend', this._onTouchEnd, true);\n this.containerOuter.element.addEventListener('keydown', this._onKeyDown, true);\n this.containerOuter.element.addEventListener('mousedown', this._onMouseDown, true);\n // passive events - doesn't call `preventDefault` or `stopPropagation`\n documentElement.addEventListener('click', this._onClick, {\n passive: true\n });\n documentElement.addEventListener('touchmove', this._onTouchMove, {\n passive: true\n });\n this.dropdown.element.addEventListener('mouseover', this._onMouseOver, {\n passive: true\n });\n if (this._isSelectOneElement) {\n this.containerOuter.element.addEventListener('focus', this._onFocus, {\n passive: true\n });\n this.containerOuter.element.addEventListener('blur', this._onBlur, {\n passive: true\n });\n }\n this.input.element.addEventListener('keyup', this._onKeyUp, {\n passive: true\n });\n this.input.element.addEventListener('focus', this._onFocus, {\n passive: true\n });\n this.input.element.addEventListener('blur', this._onBlur, {\n passive: true\n });\n if (this.input.element.form) {\n this.input.element.form.addEventListener('reset', this._onFormReset, {\n passive: true\n });\n }\n this.input.addEventListeners();\n };\n Choices.prototype._removeEventListeners = function () {\n var documentElement = this.config.shadowRoot || document.documentElement;\n documentElement.removeEventListener('touchend', this._onTouchEnd, true);\n this.containerOuter.element.removeEventListener('keydown', this._onKeyDown, true);\n this.containerOuter.element.removeEventListener('mousedown', this._onMouseDown, true);\n documentElement.removeEventListener('click', this._onClick);\n documentElement.removeEventListener('touchmove', this._onTouchMove);\n this.dropdown.element.removeEventListener('mouseover', this._onMouseOver);\n if (this._isSelectOneElement) {\n this.containerOuter.element.removeEventListener('focus', this._onFocus);\n this.containerOuter.element.removeEventListener('blur', this._onBlur);\n }\n this.input.element.removeEventListener('keyup', this._onKeyUp);\n this.input.element.removeEventListener('focus', this._onFocus);\n this.input.element.removeEventListener('blur', this._onBlur);\n if (this.input.element.form) {\n this.input.element.form.removeEventListener('reset', this._onFormReset);\n }\n this.input.removeEventListeners();\n };\n Choices.prototype._onKeyDown = function (event) {\n var keyCode = event.keyCode;\n var activeItems = this._store.activeItems;\n var hasFocusedInput = this.input.isFocussed;\n var hasActiveDropdown = this.dropdown.isActive;\n var hasItems = this.itemList.hasChildren();\n var keyString = String.fromCharCode(keyCode);\n // eslint-disable-next-line no-control-regex\n var wasPrintableChar = /[^\\x00-\\x1F]/.test(keyString);\n var BACK_KEY = constants_1.KEY_CODES.BACK_KEY,\n DELETE_KEY = constants_1.KEY_CODES.DELETE_KEY,\n ENTER_KEY = constants_1.KEY_CODES.ENTER_KEY,\n A_KEY = constants_1.KEY_CODES.A_KEY,\n ESC_KEY = constants_1.KEY_CODES.ESC_KEY,\n UP_KEY = constants_1.KEY_CODES.UP_KEY,\n DOWN_KEY = constants_1.KEY_CODES.DOWN_KEY,\n PAGE_UP_KEY = constants_1.KEY_CODES.PAGE_UP_KEY,\n PAGE_DOWN_KEY = constants_1.KEY_CODES.PAGE_DOWN_KEY;\n if (!this._isTextElement && !hasActiveDropdown && wasPrintableChar) {\n this.showDropdown();\n if (!this.input.isFocussed) {\n /*\n We update the input value with the pressed key as\n the input was not focussed at the time of key press\n therefore does not have the value of the key.\n */\n this.input.value += event.key.toLowerCase();\n }\n }\n switch (keyCode) {\n case A_KEY:\n return this._onSelectKey(event, hasItems);\n case ENTER_KEY:\n return this._onEnterKey({\n event: event,\n activeItems: activeItems,\n hasActiveDropdown: hasActiveDropdown\n });\n case ESC_KEY:\n return this._onEscapeKey(hasActiveDropdown);\n case UP_KEY:\n case PAGE_UP_KEY:\n case DOWN_KEY:\n case PAGE_DOWN_KEY:\n return this._onDirectionKey({\n event: event,\n hasActiveDropdown: hasActiveDropdown\n });\n case DELETE_KEY:\n case BACK_KEY:\n return this._onDeleteKey(event, activeItems, hasFocusedInput);\n default:\n }\n };\n Choices.prototype._onKeyUp = function (_a) {\n var target = _a.target,\n keyCode = _a.keyCode;\n var value = this.input.value;\n var activeItems = this._store.activeItems;\n var canAddItem = this._canAddItem(activeItems, value);\n var backKey = constants_1.KEY_CODES.BACK_KEY,\n deleteKey = constants_1.KEY_CODES.DELETE_KEY;\n // We are typing into a text input and have a value, we want to show a dropdown\n // notice. Otherwise hide the dropdown\n if (this._isTextElement) {\n var canShowDropdownNotice = canAddItem.notice && value;\n if (canShowDropdownNotice) {\n var dropdownItem = this._getTemplate('notice', canAddItem.notice);\n this.dropdown.element.innerHTML = dropdownItem.outerHTML;\n this.showDropdown(true);\n } else {\n this.hideDropdown(true);\n }\n } else {\n var wasRemovalKeyCode = keyCode === backKey || keyCode === deleteKey;\n var userHasRemovedValue = wasRemovalKeyCode && target && !target.value;\n var canReactivateChoices = !this._isTextElement && this._isSearching;\n var canSearch = this._canSearch && canAddItem.response;\n if (userHasRemovedValue && canReactivateChoices) {\n this._isSearching = false;\n this._store.dispatch((0, choices_1.activateChoices)(true));\n } else if (canSearch) {\n this._handleSearch(this.input.rawValue);\n }\n }\n this._canSearch = this.config.searchEnabled;\n };\n Choices.prototype._onSelectKey = function (event, hasItems) {\n var ctrlKey = event.ctrlKey,\n metaKey = event.metaKey;\n var hasCtrlDownKeyPressed = ctrlKey || metaKey;\n // If CTRL + A or CMD + A have been pressed and there are items to select\n if (hasCtrlDownKeyPressed && hasItems) {\n this._canSearch = false;\n var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement;\n if (shouldHightlightAll) {\n this.highlightAll();\n }\n }\n };\n Choices.prototype._onEnterKey = function (eventArgs) {\n var event = eventArgs.event,\n activeItems = eventArgs.activeItems,\n hasActiveDropdown = eventArgs.hasActiveDropdown;\n var target = event.target;\n var enterKey = constants_1.KEY_CODES.ENTER_KEY;\n var targetWasButton = target && target.hasAttribute('data-button');\n if (this._isTextElement && target && target.value) {\n var value = this.input.value;\n var canAddItem = this._canAddItem(activeItems, value);\n if (canAddItem.response) {\n this.hideDropdown(true);\n this._addItem({\n value: value\n });\n this._triggerChange(value);\n this.clearInput();\n }\n }\n if (targetWasButton) {\n this._handleButtonAction(activeItems, target);\n event.preventDefault();\n }\n if (hasActiveDropdown) {\n var highlightedChoice = this.dropdown.getChild(\".\".concat(this.config.classNames.highlightedState));\n if (highlightedChoice) {\n // add enter keyCode value\n if (activeItems[0]) {\n activeItems[0].keyCode = enterKey; // eslint-disable-line no-param-reassign\n }\n\n this._handleChoiceAction(activeItems, highlightedChoice);\n }\n event.preventDefault();\n } else if (this._isSelectOneElement) {\n this.showDropdown();\n event.preventDefault();\n }\n };\n Choices.prototype._onEscapeKey = function (hasActiveDropdown) {\n if (hasActiveDropdown) {\n this.hideDropdown(true);\n this.containerOuter.focus();\n }\n };\n Choices.prototype._onDirectionKey = function (eventArgs) {\n var event = eventArgs.event,\n hasActiveDropdown = eventArgs.hasActiveDropdown;\n var keyCode = event.keyCode,\n metaKey = event.metaKey;\n var downKey = constants_1.KEY_CODES.DOWN_KEY,\n pageUpKey = constants_1.KEY_CODES.PAGE_UP_KEY,\n pageDownKey = constants_1.KEY_CODES.PAGE_DOWN_KEY;\n // If up or down key is pressed, traverse through options\n if (hasActiveDropdown || this._isSelectOneElement) {\n this.showDropdown();\n this._canSearch = false;\n var directionInt = keyCode === downKey || keyCode === pageDownKey ? 1 : -1;\n var skipKey = metaKey || keyCode === pageDownKey || keyCode === pageUpKey;\n var selectableChoiceIdentifier = '[data-choice-selectable]';\n var nextEl = void 0;\n if (skipKey) {\n if (directionInt > 0) {\n nextEl = this.dropdown.element.querySelector(\"\".concat(selectableChoiceIdentifier, \":last-of-type\"));\n } else {\n nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);\n }\n } else {\n var currentEl = this.dropdown.element.querySelector(\".\".concat(this.config.classNames.highlightedState));\n if (currentEl) {\n nextEl = (0, utils_1.getAdjacentEl)(currentEl, selectableChoiceIdentifier, directionInt);\n } else {\n nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);\n }\n }\n if (nextEl) {\n // We prevent default to stop the cursor moving\n // when pressing the arrow\n if (!(0, utils_1.isScrolledIntoView)(nextEl, this.choiceList.element, directionInt)) {\n this.choiceList.scrollToChildElement(nextEl, directionInt);\n }\n this._highlightChoice(nextEl);\n }\n // Prevent default to maintain cursor position whilst\n // traversing dropdown options\n event.preventDefault();\n }\n };\n Choices.prototype._onDeleteKey = function (event, activeItems, hasFocusedInput) {\n var target = event.target;\n // If backspace or delete key is pressed and the input has no value\n if (!this._isSelectOneElement && !target.value && hasFocusedInput) {\n this._handleBackspace(activeItems);\n event.preventDefault();\n }\n };\n Choices.prototype._onTouchMove = function () {\n if (this._wasTap) {\n this._wasTap = false;\n }\n };\n Choices.prototype._onTouchEnd = function (event) {\n var target = (event || event.touches[0]).target;\n var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target);\n if (touchWasWithinContainer) {\n var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element;\n if (containerWasExactTarget) {\n if (this._isTextElement) {\n this.input.focus();\n } else if (this._isSelectMultipleElement) {\n this.showDropdown();\n }\n }\n // Prevents focus event firing\n event.stopPropagation();\n }\n this._wasTap = true;\n };\n /**\n * Handles mousedown event in capture mode for containetOuter.element\n */\n Choices.prototype._onMouseDown = function (event) {\n var target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n // If we have our mouse down on the scrollbar and are on IE11...\n if (IS_IE11 && this.choiceList.element.contains(target)) {\n // check if click was on a scrollbar area\n var firstChoice = this.choiceList.element.firstElementChild;\n var isOnScrollbar = this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft;\n this._isScrollingOnIe = isOnScrollbar;\n }\n if (target === this.input.element) {\n return;\n }\n var item = target.closest('[data-button],[data-item],[data-choice]');\n if (item instanceof HTMLElement) {\n var hasShiftKey = event.shiftKey;\n var activeItems = this._store.activeItems;\n var dataset = item.dataset;\n if ('button' in dataset) {\n this._handleButtonAction(activeItems, item);\n } else if ('item' in dataset) {\n this._handleItemAction(activeItems, item, hasShiftKey);\n } else if ('choice' in dataset) {\n this._handleChoiceAction(activeItems, item);\n }\n }\n event.preventDefault();\n };\n /**\n * Handles mouseover event over this.dropdown\n * @param {MouseEvent} event\n */\n Choices.prototype._onMouseOver = function (_a) {\n var target = _a.target;\n if (target instanceof HTMLElement && 'choice' in target.dataset) {\n this._highlightChoice(target);\n }\n };\n Choices.prototype._onClick = function (_a) {\n var target = _a.target;\n var clickWasWithinContainer = this.containerOuter.element.contains(target);\n if (clickWasWithinContainer) {\n if (!this.dropdown.isActive && !this.containerOuter.isDisabled) {\n if (this._isTextElement) {\n if (document.activeElement !== this.input.element) {\n this.input.focus();\n }\n } else {\n this.showDropdown();\n this.containerOuter.focus();\n }\n } else if (this._isSelectOneElement && target !== this.input.element && !this.dropdown.element.contains(target)) {\n this.hideDropdown();\n }\n } else {\n var hasHighlightedItems = this._store.highlightedActiveItems.length > 0;\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n this.containerOuter.removeFocusState();\n this.hideDropdown(true);\n }\n };\n Choices.prototype._onFocus = function (_a) {\n var _b;\n var _this = this;\n var target = _a.target;\n var focusWasWithinContainer = target && this.containerOuter.element.contains(target);\n if (!focusWasWithinContainer) {\n return;\n }\n var focusActions = (_b = {}, _b[constants_1.TEXT_TYPE] = function () {\n if (target === _this.input.element) {\n _this.containerOuter.addFocusState();\n }\n }, _b[constants_1.SELECT_ONE_TYPE] = function () {\n _this.containerOuter.addFocusState();\n if (target === _this.input.element) {\n _this.showDropdown(true);\n }\n }, _b[constants_1.SELECT_MULTIPLE_TYPE] = function () {\n if (target === _this.input.element) {\n _this.showDropdown(true);\n // If element is a select box, the focused element is the container and the dropdown\n // isn't already open, focus and show dropdown\n _this.containerOuter.addFocusState();\n }\n }, _b);\n focusActions[this.passedElement.element.type]();\n };\n Choices.prototype._onBlur = function (_a) {\n var _b;\n var _this = this;\n var target = _a.target;\n var blurWasWithinContainer = target && this.containerOuter.element.contains(target);\n if (blurWasWithinContainer && !this._isScrollingOnIe) {\n var activeItems = this._store.activeItems;\n var hasHighlightedItems_1 = activeItems.some(function (item) {\n return item.highlighted;\n });\n var blurActions = (_b = {}, _b[constants_1.TEXT_TYPE] = function () {\n if (target === _this.input.element) {\n _this.containerOuter.removeFocusState();\n if (hasHighlightedItems_1) {\n _this.unhighlightAll();\n }\n _this.hideDropdown(true);\n }\n }, _b[constants_1.SELECT_ONE_TYPE] = function () {\n _this.containerOuter.removeFocusState();\n if (target === _this.input.element || target === _this.containerOuter.element && !_this._canSearch) {\n _this.hideDropdown(true);\n }\n }, _b[constants_1.SELECT_MULTIPLE_TYPE] = function () {\n if (target === _this.input.element) {\n _this.containerOuter.removeFocusState();\n _this.hideDropdown(true);\n if (hasHighlightedItems_1) {\n _this.unhighlightAll();\n }\n }\n }, _b);\n blurActions[this.passedElement.element.type]();\n } else {\n // On IE11, clicking the scollbar blurs our input and thus\n // closes the dropdown. To stop this, we refocus our input\n // if we know we are on IE *and* are scrolling.\n this._isScrollingOnIe = false;\n this.input.element.focus();\n }\n };\n Choices.prototype._onFormReset = function () {\n this._store.dispatch((0, misc_1.resetTo)(this._initialState));\n };\n Choices.prototype._highlightChoice = function (el) {\n var _this = this;\n if (el === void 0) {\n el = null;\n }\n var choices = Array.from(this.dropdown.element.querySelectorAll('[data-choice-selectable]'));\n if (!choices.length) {\n return;\n }\n var passedEl = el;\n var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(\".\".concat(this.config.classNames.highlightedState)));\n // Remove any highlighted choices\n highlightedChoices.forEach(function (choice) {\n choice.classList.remove(_this.config.classNames.highlightedState);\n choice.setAttribute('aria-selected', 'false');\n });\n if (passedEl) {\n this._highlightPosition = choices.indexOf(passedEl);\n } else {\n // Highlight choice based on last known highlight location\n if (choices.length > this._highlightPosition) {\n // If we have an option to highlight\n passedEl = choices[this._highlightPosition];\n } else {\n // Otherwise highlight the option before\n passedEl = choices[choices.length - 1];\n }\n if (!passedEl) {\n passedEl = choices[0];\n }\n }\n passedEl.classList.add(this.config.classNames.highlightedState);\n passedEl.setAttribute('aria-selected', 'true');\n this.passedElement.triggerEvent(constants_1.EVENTS.highlightChoice, {\n el: passedEl\n });\n if (this.dropdown.isActive) {\n // IE11 ignores aria-label and blocks virtual keyboard\n // if aria-activedescendant is set without a dropdown\n this.input.setActiveDescendant(passedEl.id);\n this.containerOuter.setActiveDescendant(passedEl.id);\n }\n };\n Choices.prototype._addItem = function (_a) {\n var value = _a.value,\n _b = _a.label,\n label = _b === void 0 ? null : _b,\n _c = _a.choiceId,\n choiceId = _c === void 0 ? -1 : _c,\n _d = _a.groupId,\n groupId = _d === void 0 ? -1 : _d,\n _e = _a.customProperties,\n customProperties = _e === void 0 ? {} : _e,\n _f = _a.placeholder,\n placeholder = _f === void 0 ? false : _f,\n _g = _a.keyCode,\n keyCode = _g === void 0 ? -1 : _g;\n var passedValue = typeof value === 'string' ? value.trim() : value;\n var items = this._store.items;\n var passedLabel = label || passedValue;\n var passedOptionId = choiceId || -1;\n var group = groupId >= 0 ? this._store.getGroupById(groupId) : null;\n var id = items ? items.length + 1 : 1;\n // If a prepended value has been passed, prepend it\n if (this.config.prependValue) {\n passedValue = this.config.prependValue + passedValue.toString();\n }\n // If an appended value has been passed, append it\n if (this.config.appendValue) {\n passedValue += this.config.appendValue.toString();\n }\n this._store.dispatch((0, items_1.addItem)({\n value: passedValue,\n label: passedLabel,\n id: id,\n choiceId: passedOptionId,\n groupId: groupId,\n customProperties: customProperties,\n placeholder: placeholder,\n keyCode: keyCode\n }));\n if (this._isSelectOneElement) {\n this.removeActiveItems(id);\n }\n // Trigger change event\n this.passedElement.triggerEvent(constants_1.EVENTS.addItem, {\n id: id,\n value: passedValue,\n label: passedLabel,\n customProperties: customProperties,\n groupValue: group && group.value ? group.value : null,\n keyCode: keyCode\n });\n };\n Choices.prototype._removeItem = function (item) {\n var id = item.id,\n value = item.value,\n label = item.label,\n customProperties = item.customProperties,\n choiceId = item.choiceId,\n groupId = item.groupId;\n var group = groupId && groupId >= 0 ? this._store.getGroupById(groupId) : null;\n if (!id || !choiceId) {\n return;\n }\n this._store.dispatch((0, items_1.removeItem)(id, choiceId));\n this.passedElement.triggerEvent(constants_1.EVENTS.removeItem, {\n id: id,\n value: value,\n label: label,\n customProperties: customProperties,\n groupValue: group && group.value ? group.value : null\n });\n };\n Choices.prototype._addChoice = function (_a) {\n var value = _a.value,\n _b = _a.label,\n label = _b === void 0 ? null : _b,\n _c = _a.isSelected,\n isSelected = _c === void 0 ? false : _c,\n _d = _a.isDisabled,\n isDisabled = _d === void 0 ? false : _d,\n _e = _a.groupId,\n groupId = _e === void 0 ? -1 : _e,\n _f = _a.customProperties,\n customProperties = _f === void 0 ? {} : _f,\n _g = _a.placeholder,\n placeholder = _g === void 0 ? false : _g,\n _h = _a.keyCode,\n keyCode = _h === void 0 ? -1 : _h;\n if (typeof value === 'undefined' || value === null) {\n return;\n }\n // Generate unique id\n var choices = this._store.choices;\n var choiceLabel = label || value;\n var choiceId = choices ? choices.length + 1 : 1;\n var choiceElementId = \"\".concat(this._baseId, \"-\").concat(this._idNames.itemChoice, \"-\").concat(choiceId);\n this._store.dispatch((0, choices_1.addChoice)({\n id: choiceId,\n groupId: groupId,\n elementId: choiceElementId,\n value: value,\n label: choiceLabel,\n disabled: isDisabled,\n customProperties: customProperties,\n placeholder: placeholder,\n keyCode: keyCode\n }));\n if (isSelected) {\n this._addItem({\n value: value,\n label: choiceLabel,\n choiceId: choiceId,\n customProperties: customProperties,\n placeholder: placeholder,\n keyCode: keyCode\n });\n }\n };\n Choices.prototype._addGroup = function (_a) {\n var _this = this;\n var group = _a.group,\n id = _a.id,\n _b = _a.valueKey,\n valueKey = _b === void 0 ? 'value' : _b,\n _c = _a.labelKey,\n labelKey = _c === void 0 ? 'label' : _c;\n var groupChoices = (0, utils_1.isType)('Object', group) ? group.choices : Array.from(group.getElementsByTagName('OPTION'));\n var groupId = id || Math.floor(new Date().valueOf() * Math.random());\n var isDisabled = group.disabled ? group.disabled : false;\n if (groupChoices) {\n this._store.dispatch((0, groups_1.addGroup)({\n value: group.label,\n id: groupId,\n active: true,\n disabled: isDisabled\n }));\n var addGroupChoices = function (choice) {\n var isOptDisabled = choice.disabled || choice.parentNode && choice.parentNode.disabled;\n _this._addChoice({\n value: choice[valueKey],\n label: (0, utils_1.isType)('Object', choice) ? choice[labelKey] : choice.innerHTML,\n isSelected: choice.selected,\n isDisabled: isOptDisabled,\n groupId: groupId,\n customProperties: choice.customProperties,\n placeholder: choice.placeholder\n });\n };\n groupChoices.forEach(addGroupChoices);\n } else {\n this._store.dispatch((0, groups_1.addGroup)({\n value: group.label,\n id: group.id,\n active: false,\n disabled: group.disabled\n }));\n }\n };\n Choices.prototype._getTemplate = function (template) {\n var _a;\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n return (_a = this._templates[template]).call.apply(_a, __spreadArray([this, this.config], args, false));\n };\n Choices.prototype._createTemplates = function () {\n var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates;\n var userTemplates = {};\n if (callbackOnCreateTemplates && typeof callbackOnCreateTemplates === 'function') {\n userTemplates = callbackOnCreateTemplates.call(this, utils_1.strToEl);\n }\n this._templates = (0, deepmerge_1.default)(templates_1.default, userTemplates);\n };\n Choices.prototype._createElements = function () {\n this.containerOuter = new components_1.Container({\n element: this._getTemplate('containerOuter', this._direction, this._isSelectElement, this._isSelectOneElement, this.config.searchEnabled, this.passedElement.element.type, this.config.labelId),\n classNames: this.config.classNames,\n type: this.passedElement.element.type,\n position: this.config.position\n });\n this.containerInner = new components_1.Container({\n element: this._getTemplate('containerInner'),\n classNames: this.config.classNames,\n type: this.passedElement.element.type,\n position: this.config.position\n });\n this.input = new components_1.Input({\n element: this._getTemplate('input', this._placeholderValue),\n classNames: this.config.classNames,\n type: this.passedElement.element.type,\n preventPaste: !this.config.paste\n });\n this.choiceList = new components_1.List({\n element: this._getTemplate('choiceList', this._isSelectOneElement)\n });\n this.itemList = new components_1.List({\n element: this._getTemplate('itemList', this._isSelectOneElement)\n });\n this.dropdown = new components_1.Dropdown({\n element: this._getTemplate('dropdown'),\n classNames: this.config.classNames,\n type: this.passedElement.element.type\n });\n };\n Choices.prototype._createStructure = function () {\n // Hide original element\n this.passedElement.conceal();\n // Wrap input in container preserving DOM ordering\n this.containerInner.wrap(this.passedElement.element);\n // Wrapper inner container with outer container\n this.containerOuter.wrap(this.containerInner.element);\n if (this._isSelectOneElement) {\n this.input.placeholder = this.config.searchPlaceholderValue || '';\n } else if (this._placeholderValue) {\n this.input.placeholder = this._placeholderValue;\n this.input.setWidth();\n }\n this.containerOuter.element.appendChild(this.containerInner.element);\n this.containerOuter.element.appendChild(this.dropdown.element);\n this.containerInner.element.appendChild(this.itemList.element);\n if (!this._isTextElement) {\n this.dropdown.element.appendChild(this.choiceList.element);\n }\n if (!this._isSelectOneElement) {\n this.containerInner.element.appendChild(this.input.element);\n } else if (this.config.searchEnabled) {\n this.dropdown.element.insertBefore(this.input.element, this.dropdown.element.firstChild);\n }\n if (this._isSelectElement) {\n this._highlightPosition = 0;\n this._isSearching = false;\n this._startLoading();\n if (this._presetGroups.length) {\n this._addPredefinedGroups(this._presetGroups);\n } else {\n this._addPredefinedChoices(this._presetChoices);\n }\n this._stopLoading();\n }\n if (this._isTextElement) {\n this._addPredefinedItems(this._presetItems);\n }\n };\n Choices.prototype._addPredefinedGroups = function (groups) {\n var _this = this;\n // If we have a placeholder option\n var placeholderChoice = this.passedElement.placeholderOption;\n if (placeholderChoice && placeholderChoice.parentNode && placeholderChoice.parentNode.tagName === 'SELECT') {\n this._addChoice({\n value: placeholderChoice.value,\n label: placeholderChoice.innerHTML,\n isSelected: placeholderChoice.selected,\n isDisabled: placeholderChoice.disabled,\n placeholder: true\n });\n }\n groups.forEach(function (group) {\n return _this._addGroup({\n group: group,\n id: group.id || null\n });\n });\n };\n Choices.prototype._addPredefinedChoices = function (choices) {\n var _this = this;\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort) {\n choices.sort(this.config.sorter);\n }\n var hasSelectedChoice = choices.some(function (choice) {\n return choice.selected;\n });\n var firstEnabledChoiceIndex = choices.findIndex(function (choice) {\n return choice.disabled === undefined || !choice.disabled;\n });\n choices.forEach(function (choice, index) {\n var _a = choice.value,\n value = _a === void 0 ? '' : _a,\n label = choice.label,\n customProperties = choice.customProperties,\n placeholder = choice.placeholder;\n if (_this._isSelectElement) {\n // If the choice is actually a group\n if (choice.choices) {\n _this._addGroup({\n group: choice,\n id: choice.id || null\n });\n } else {\n /**\n * If there is a selected choice already or the choice is not the first in\n * the array, add each choice normally.\n *\n * Otherwise we pre-select the first enabled choice in the array (\"select-one\" only)\n */\n var shouldPreselect = _this._isSelectOneElement && !hasSelectedChoice && index === firstEnabledChoiceIndex;\n var isSelected = shouldPreselect ? true : choice.selected;\n var isDisabled = choice.disabled;\n _this._addChoice({\n value: value,\n label: label,\n isSelected: !!isSelected,\n isDisabled: !!isDisabled,\n placeholder: !!placeholder,\n customProperties: customProperties\n });\n }\n } else {\n _this._addChoice({\n value: value,\n label: label,\n isSelected: !!choice.selected,\n isDisabled: !!choice.disabled,\n placeholder: !!choice.placeholder,\n customProperties: customProperties\n });\n }\n });\n };\n Choices.prototype._addPredefinedItems = function (items) {\n var _this = this;\n items.forEach(function (item) {\n if (typeof item === 'object' && item.value) {\n _this._addItem({\n value: item.value,\n label: item.label,\n choiceId: item.id,\n customProperties: item.customProperties,\n placeholder: item.placeholder\n });\n }\n if (typeof item === 'string') {\n _this._addItem({\n value: item\n });\n }\n });\n };\n Choices.prototype._setChoiceOrItem = function (item) {\n var _this = this;\n var itemType = (0, utils_1.getType)(item).toLowerCase();\n var handleType = {\n object: function () {\n if (!item.value) {\n return;\n }\n // If we are dealing with a select input, we need to create an option first\n // that is then selected. For text inputs we can just add items normally.\n if (!_this._isTextElement) {\n _this._addChoice({\n value: item.value,\n label: item.label,\n isSelected: true,\n isDisabled: false,\n customProperties: item.customProperties,\n placeholder: item.placeholder\n });\n } else {\n _this._addItem({\n value: item.value,\n label: item.label,\n choiceId: item.id,\n customProperties: item.customProperties,\n placeholder: item.placeholder\n });\n }\n },\n string: function () {\n if (!_this._isTextElement) {\n _this._addChoice({\n value: item,\n label: item,\n isSelected: true,\n isDisabled: false\n });\n } else {\n _this._addItem({\n value: item\n });\n }\n }\n };\n handleType[itemType]();\n };\n Choices.prototype._findAndSelectChoiceByValue = function (value) {\n var _this = this;\n var choices = this._store.choices;\n // Check 'value' property exists and the choice isn't already selected\n var foundChoice = choices.find(function (choice) {\n return _this.config.valueComparer(choice.value, value);\n });\n if (foundChoice && !foundChoice.selected) {\n this._addItem({\n value: foundChoice.value,\n label: foundChoice.label,\n choiceId: foundChoice.id,\n groupId: foundChoice.groupId,\n customProperties: foundChoice.customProperties,\n placeholder: foundChoice.placeholder,\n keyCode: foundChoice.keyCode\n });\n }\n };\n Choices.prototype._generatePlaceholderValue = function () {\n if (this._isSelectElement && this.passedElement.placeholderOption) {\n var placeholderOption = this.passedElement.placeholderOption;\n return placeholderOption ? placeholderOption.text : null;\n }\n var _a = this.config,\n placeholder = _a.placeholder,\n placeholderValue = _a.placeholderValue;\n var dataset = this.passedElement.element.dataset;\n if (placeholder) {\n if (placeholderValue) {\n return placeholderValue;\n }\n if (dataset.placeholder) {\n return dataset.placeholder;\n }\n }\n return null;\n };\n return Choices;\n}();\nexports[\"default\"] = Choices;\n\n/***/ }),\n\n/***/ 613:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_75455__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar utils_1 = __nested_webpack_require_75455__(799);\nvar constants_1 = __nested_webpack_require_75455__(883);\nvar Container = /** @class */function () {\n function Container(_a) {\n var element = _a.element,\n type = _a.type,\n classNames = _a.classNames,\n position = _a.position;\n this.element = element;\n this.classNames = classNames;\n this.type = type;\n this.position = position;\n this.isOpen = false;\n this.isFlipped = false;\n this.isFocussed = false;\n this.isDisabled = false;\n this.isLoading = false;\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n }\n Container.prototype.addEventListeners = function () {\n this.element.addEventListener('focus', this._onFocus);\n this.element.addEventListener('blur', this._onBlur);\n };\n Container.prototype.removeEventListeners = function () {\n this.element.removeEventListener('focus', this._onFocus);\n this.element.removeEventListener('blur', this._onBlur);\n };\n /**\n * Determine whether container should be flipped based on passed\n * dropdown position\n */\n Container.prototype.shouldFlip = function (dropdownPos, dropdownHeight, containerElem) {\n if (typeof dropdownPos !== 'number') {\n return false;\n }\n // If flip is enabled and the dropdown bottom position is\n // greater than the window height flip the dropdown.\n var shouldFlip = false;\n if (this.position === 'auto') {\n shouldFlip = !window.matchMedia(\"(min-height: \".concat(dropdownPos + 1, \"px)\")).matches;\n if (shouldFlip) {\n if (containerElem.getBoundingClientRect().top - dropdownHeight < 0) {\n shouldFlip = false;\n }\n }\n } else if (this.position === 'top') {\n shouldFlip = true;\n }\n return shouldFlip;\n };\n Container.prototype.setActiveDescendant = function (activeDescendantID) {\n this.element.setAttribute('aria-activedescendant', activeDescendantID);\n };\n Container.prototype.removeActiveDescendant = function () {\n this.element.removeAttribute('aria-activedescendant');\n };\n Container.prototype.open = function (dropdownPos, dropdownHeight) {\n this.element.classList.add(this.classNames.openState);\n this.element.setAttribute('aria-expanded', 'true');\n this.isOpen = true;\n if (this.shouldFlip(dropdownPos, dropdownHeight, this.element)) {\n this.element.classList.add(this.classNames.flippedState);\n this.isFlipped = true;\n }\n };\n Container.prototype.close = function () {\n this.element.classList.remove(this.classNames.openState);\n this.element.setAttribute('aria-expanded', 'false');\n this.removeActiveDescendant();\n this.isOpen = false;\n // A dropdown flips if it does not have space within the page\n if (this.isFlipped) {\n this.element.classList.remove(this.classNames.flippedState);\n this.isFlipped = false;\n }\n };\n Container.prototype.focus = function () {\n if (!this.isFocussed) {\n this.element.focus();\n }\n };\n Container.prototype.addFocusState = function () {\n this.element.classList.add(this.classNames.focusState);\n };\n Container.prototype.removeFocusState = function () {\n this.element.classList.remove(this.classNames.focusState);\n };\n Container.prototype.enable = function () {\n this.element.classList.remove(this.classNames.disabledState);\n this.element.removeAttribute('aria-disabled');\n if (this.type === constants_1.SELECT_ONE_TYPE) {\n this.element.setAttribute('tabindex', '0');\n }\n this.isDisabled = false;\n };\n Container.prototype.disable = function () {\n this.element.classList.add(this.classNames.disabledState);\n this.element.setAttribute('aria-disabled', 'true');\n if (this.type === constants_1.SELECT_ONE_TYPE) {\n this.element.setAttribute('tabindex', '-1');\n }\n this.isDisabled = true;\n };\n Container.prototype.wrap = function (element) {\n (0, utils_1.wrap)(element, this.element);\n };\n Container.prototype.unwrap = function (element) {\n if (this.element.parentNode) {\n // Move passed element outside this element\n this.element.parentNode.insertBefore(element, this.element);\n // Remove this element\n this.element.parentNode.removeChild(this.element);\n }\n };\n Container.prototype.addLoadingState = function () {\n this.element.classList.add(this.classNames.loadingState);\n this.element.setAttribute('aria-busy', 'true');\n this.isLoading = true;\n };\n Container.prototype.removeLoadingState = function () {\n this.element.classList.remove(this.classNames.loadingState);\n this.element.removeAttribute('aria-busy');\n this.isLoading = false;\n };\n Container.prototype._onFocus = function () {\n this.isFocussed = true;\n };\n Container.prototype._onBlur = function () {\n this.isFocussed = false;\n };\n return Container;\n}();\nexports[\"default\"] = Container;\n\n/***/ }),\n\n/***/ 217:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar Dropdown = /** @class */function () {\n function Dropdown(_a) {\n var element = _a.element,\n type = _a.type,\n classNames = _a.classNames;\n this.element = element;\n this.classNames = classNames;\n this.type = type;\n this.isActive = false;\n }\n Object.defineProperty(Dropdown.prototype, \"distanceFromTopWindow\", {\n /**\n * Bottom position of dropdown in viewport coordinates\n */\n get: function () {\n return this.element.getBoundingClientRect().bottom;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Dropdown.prototype, \"height\", {\n get: function () {\n return this.element.getBoundingClientRect().height;\n },\n enumerable: false,\n configurable: true\n });\n Dropdown.prototype.getChild = function (selector) {\n return this.element.querySelector(selector);\n };\n /**\n * Show dropdown to user by adding active state class\n */\n Dropdown.prototype.show = function () {\n this.element.classList.add(this.classNames.activeState);\n this.element.setAttribute('aria-expanded', 'true');\n this.isActive = true;\n return this;\n };\n /**\n * Hide dropdown from user\n */\n Dropdown.prototype.hide = function () {\n this.element.classList.remove(this.classNames.activeState);\n this.element.setAttribute('aria-expanded', 'false');\n this.isActive = false;\n return this;\n };\n return Dropdown;\n}();\nexports[\"default\"] = Dropdown;\n\n/***/ }),\n\n/***/ 520:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_82050__) {\n\n\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.WrappedSelect = exports.WrappedInput = exports.List = exports.Input = exports.Container = exports.Dropdown = void 0;\nvar dropdown_1 = __importDefault(__nested_webpack_require_82050__(217));\nexports.Dropdown = dropdown_1.default;\nvar container_1 = __importDefault(__nested_webpack_require_82050__(613));\nexports.Container = container_1.default;\nvar input_1 = __importDefault(__nested_webpack_require_82050__(11));\nexports.Input = input_1.default;\nvar list_1 = __importDefault(__nested_webpack_require_82050__(624));\nexports.List = list_1.default;\nvar wrapped_input_1 = __importDefault(__nested_webpack_require_82050__(541));\nexports.WrappedInput = wrapped_input_1.default;\nvar wrapped_select_1 = __importDefault(__nested_webpack_require_82050__(982));\nexports.WrappedSelect = wrapped_select_1.default;\n\n/***/ }),\n\n/***/ 11:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_83077__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar utils_1 = __nested_webpack_require_83077__(799);\nvar constants_1 = __nested_webpack_require_83077__(883);\nvar Input = /** @class */function () {\n function Input(_a) {\n var element = _a.element,\n type = _a.type,\n classNames = _a.classNames,\n preventPaste = _a.preventPaste;\n this.element = element;\n this.type = type;\n this.classNames = classNames;\n this.preventPaste = preventPaste;\n this.isFocussed = this.element.isEqualNode(document.activeElement);\n this.isDisabled = element.disabled;\n this._onPaste = this._onPaste.bind(this);\n this._onInput = this._onInput.bind(this);\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n }\n Object.defineProperty(Input.prototype, \"placeholder\", {\n set: function (placeholder) {\n this.element.placeholder = placeholder;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Input.prototype, \"value\", {\n get: function () {\n return (0, utils_1.sanitise)(this.element.value);\n },\n set: function (value) {\n this.element.value = value;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Input.prototype, \"rawValue\", {\n get: function () {\n return this.element.value;\n },\n enumerable: false,\n configurable: true\n });\n Input.prototype.addEventListeners = function () {\n this.element.addEventListener('paste', this._onPaste);\n this.element.addEventListener('input', this._onInput, {\n passive: true\n });\n this.element.addEventListener('focus', this._onFocus, {\n passive: true\n });\n this.element.addEventListener('blur', this._onBlur, {\n passive: true\n });\n };\n Input.prototype.removeEventListeners = function () {\n this.element.removeEventListener('input', this._onInput);\n this.element.removeEventListener('paste', this._onPaste);\n this.element.removeEventListener('focus', this._onFocus);\n this.element.removeEventListener('blur', this._onBlur);\n };\n Input.prototype.enable = function () {\n this.element.removeAttribute('disabled');\n this.isDisabled = false;\n };\n Input.prototype.disable = function () {\n this.element.setAttribute('disabled', '');\n this.isDisabled = true;\n };\n Input.prototype.focus = function () {\n if (!this.isFocussed) {\n this.element.focus();\n }\n };\n Input.prototype.blur = function () {\n if (this.isFocussed) {\n this.element.blur();\n }\n };\n Input.prototype.clear = function (setWidth) {\n if (setWidth === void 0) {\n setWidth = true;\n }\n if (this.element.value) {\n this.element.value = '';\n }\n if (setWidth) {\n this.setWidth();\n }\n return this;\n };\n /**\n * Set the correct input width based on placeholder\n * value or input value\n */\n Input.prototype.setWidth = function () {\n // Resize input to contents or placeholder\n var _a = this.element,\n style = _a.style,\n value = _a.value,\n placeholder = _a.placeholder;\n style.minWidth = \"\".concat(placeholder.length + 1, \"ch\");\n style.width = \"\".concat(value.length + 1, \"ch\");\n };\n Input.prototype.setActiveDescendant = function (activeDescendantID) {\n this.element.setAttribute('aria-activedescendant', activeDescendantID);\n };\n Input.prototype.removeActiveDescendant = function () {\n this.element.removeAttribute('aria-activedescendant');\n };\n Input.prototype._onInput = function () {\n if (this.type !== constants_1.SELECT_ONE_TYPE) {\n this.setWidth();\n }\n };\n Input.prototype._onPaste = function (event) {\n if (this.preventPaste) {\n event.preventDefault();\n }\n };\n Input.prototype._onFocus = function () {\n this.isFocussed = true;\n };\n Input.prototype._onBlur = function () {\n this.isFocussed = false;\n };\n return Input;\n}();\nexports[\"default\"] = Input;\n\n/***/ }),\n\n/***/ 624:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_87074__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar constants_1 = __nested_webpack_require_87074__(883);\nvar List = /** @class */function () {\n function List(_a) {\n var element = _a.element;\n this.element = element;\n this.scrollPos = this.element.scrollTop;\n this.height = this.element.offsetHeight;\n }\n List.prototype.clear = function () {\n this.element.innerHTML = '';\n };\n List.prototype.append = function (node) {\n this.element.appendChild(node);\n };\n List.prototype.getChild = function (selector) {\n return this.element.querySelector(selector);\n };\n List.prototype.hasChildren = function () {\n return this.element.hasChildNodes();\n };\n List.prototype.scrollToTop = function () {\n this.element.scrollTop = 0;\n };\n List.prototype.scrollToChildElement = function (element, direction) {\n var _this = this;\n if (!element) {\n return;\n }\n var listHeight = this.element.offsetHeight;\n // Scroll position of dropdown\n var listScrollPosition = this.element.scrollTop + listHeight;\n var elementHeight = element.offsetHeight;\n // Distance from bottom of element to top of parent\n var elementPos = element.offsetTop + elementHeight;\n // Difference between the element and scroll position\n var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop;\n requestAnimationFrame(function () {\n _this._animateScroll(destination, direction);\n });\n };\n List.prototype._scrollDown = function (scrollPos, strength, destination) {\n var easing = (destination - scrollPos) / strength;\n var distance = easing > 1 ? easing : 1;\n this.element.scrollTop = scrollPos + distance;\n };\n List.prototype._scrollUp = function (scrollPos, strength, destination) {\n var easing = (scrollPos - destination) / strength;\n var distance = easing > 1 ? easing : 1;\n this.element.scrollTop = scrollPos - distance;\n };\n List.prototype._animateScroll = function (destination, direction) {\n var _this = this;\n var strength = constants_1.SCROLLING_SPEED;\n var choiceListScrollTop = this.element.scrollTop;\n var continueAnimation = false;\n if (direction > 0) {\n this._scrollDown(choiceListScrollTop, strength, destination);\n if (choiceListScrollTop < destination) {\n continueAnimation = true;\n }\n } else {\n this._scrollUp(choiceListScrollTop, strength, destination);\n if (choiceListScrollTop > destination) {\n continueAnimation = true;\n }\n }\n if (continueAnimation) {\n requestAnimationFrame(function () {\n _this._animateScroll(destination, direction);\n });\n }\n };\n return List;\n}();\nexports[\"default\"] = List;\n\n/***/ }),\n\n/***/ 730:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_89890__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar utils_1 = __nested_webpack_require_89890__(799);\nvar WrappedElement = /** @class */function () {\n function WrappedElement(_a) {\n var element = _a.element,\n classNames = _a.classNames;\n this.element = element;\n this.classNames = classNames;\n if (!(element instanceof HTMLInputElement) && !(element instanceof HTMLSelectElement)) {\n throw new TypeError('Invalid element passed');\n }\n this.isDisabled = false;\n }\n Object.defineProperty(WrappedElement.prototype, \"isActive\", {\n get: function () {\n return this.element.dataset.choice === 'active';\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedElement.prototype, \"dir\", {\n get: function () {\n return this.element.dir;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedElement.prototype, \"value\", {\n get: function () {\n return this.element.value;\n },\n set: function (value) {\n // you must define setter here otherwise it will be readonly property\n this.element.value = value;\n },\n enumerable: false,\n configurable: true\n });\n WrappedElement.prototype.conceal = function () {\n // Hide passed input\n this.element.classList.add(this.classNames.input);\n this.element.hidden = true;\n // Remove element from tab index\n this.element.tabIndex = -1;\n // Backup original styles if any\n var origStyle = this.element.getAttribute('style');\n if (origStyle) {\n this.element.setAttribute('data-choice-orig-style', origStyle);\n }\n this.element.setAttribute('data-choice', 'active');\n };\n WrappedElement.prototype.reveal = function () {\n // Reinstate passed element\n this.element.classList.remove(this.classNames.input);\n this.element.hidden = false;\n this.element.removeAttribute('tabindex');\n // Recover original styles if any\n var origStyle = this.element.getAttribute('data-choice-orig-style');\n if (origStyle) {\n this.element.removeAttribute('data-choice-orig-style');\n this.element.setAttribute('style', origStyle);\n } else {\n this.element.removeAttribute('style');\n }\n this.element.removeAttribute('data-choice');\n // Re-assign values - this is weird, I know\n // @todo Figure out why we need to do this\n this.element.value = this.element.value; // eslint-disable-line no-self-assign\n };\n\n WrappedElement.prototype.enable = function () {\n this.element.removeAttribute('disabled');\n this.element.disabled = false;\n this.isDisabled = false;\n };\n WrappedElement.prototype.disable = function () {\n this.element.setAttribute('disabled', '');\n this.element.disabled = true;\n this.isDisabled = true;\n };\n WrappedElement.prototype.triggerEvent = function (eventType, data) {\n (0, utils_1.dispatchEvent)(this.element, eventType, data);\n };\n return WrappedElement;\n}();\nexports[\"default\"] = WrappedElement;\n\n/***/ }),\n\n/***/ 541:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_92966__) {\n\n\n\nvar __extends = this && this.__extends || function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar wrapped_element_1 = __importDefault(__nested_webpack_require_92966__(730));\nvar WrappedInput = /** @class */function (_super) {\n __extends(WrappedInput, _super);\n function WrappedInput(_a) {\n var element = _a.element,\n classNames = _a.classNames,\n delimiter = _a.delimiter;\n var _this = _super.call(this, {\n element: element,\n classNames: classNames\n }) || this;\n _this.delimiter = delimiter;\n return _this;\n }\n Object.defineProperty(WrappedInput.prototype, \"value\", {\n get: function () {\n return this.element.value;\n },\n set: function (value) {\n this.element.setAttribute('value', value);\n this.element.value = value;\n },\n enumerable: false,\n configurable: true\n });\n return WrappedInput;\n}(wrapped_element_1.default);\nexports[\"default\"] = WrappedInput;\n\n/***/ }),\n\n/***/ 982:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_94820__) {\n\n\n\nvar __extends = this && this.__extends || function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar wrapped_element_1 = __importDefault(__nested_webpack_require_94820__(730));\nvar WrappedSelect = /** @class */function (_super) {\n __extends(WrappedSelect, _super);\n function WrappedSelect(_a) {\n var element = _a.element,\n classNames = _a.classNames,\n template = _a.template;\n var _this = _super.call(this, {\n element: element,\n classNames: classNames\n }) || this;\n _this.template = template;\n return _this;\n }\n Object.defineProperty(WrappedSelect.prototype, \"placeholderOption\", {\n get: function () {\n return this.element.querySelector('option[value=\"\"]') ||\n // Backward compatibility layer for the non-standard placeholder attribute supported in older versions.\n this.element.querySelector('option[placeholder]');\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedSelect.prototype, \"optionGroups\", {\n get: function () {\n return Array.from(this.element.getElementsByTagName('OPTGROUP'));\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedSelect.prototype, \"options\", {\n get: function () {\n return Array.from(this.element.options);\n },\n set: function (options) {\n var _this = this;\n var fragment = document.createDocumentFragment();\n var addOptionToFragment = function (data) {\n // Create a standard select option\n var option = _this.template(data);\n // Append it to fragment\n fragment.appendChild(option);\n };\n // Add each list item to list\n options.forEach(function (optionData) {\n return addOptionToFragment(optionData);\n });\n this.appendDocFragment(fragment);\n },\n enumerable: false,\n configurable: true\n });\n WrappedSelect.prototype.appendDocFragment = function (fragment) {\n this.element.innerHTML = '';\n this.element.appendChild(fragment);\n };\n return WrappedSelect;\n}(wrapped_element_1.default);\nexports[\"default\"] = WrappedSelect;\n\n/***/ }),\n\n/***/ 883:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.SCROLLING_SPEED = exports.SELECT_MULTIPLE_TYPE = exports.SELECT_ONE_TYPE = exports.TEXT_TYPE = exports.KEY_CODES = exports.ACTION_TYPES = exports.EVENTS = void 0;\nexports.EVENTS = {\n showDropdown: 'showDropdown',\n hideDropdown: 'hideDropdown',\n change: 'change',\n choice: 'choice',\n search: 'search',\n addItem: 'addItem',\n removeItem: 'removeItem',\n highlightItem: 'highlightItem',\n highlightChoice: 'highlightChoice',\n unhighlightItem: 'unhighlightItem'\n};\nexports.ACTION_TYPES = {\n ADD_CHOICE: 'ADD_CHOICE',\n FILTER_CHOICES: 'FILTER_CHOICES',\n ACTIVATE_CHOICES: 'ACTIVATE_CHOICES',\n CLEAR_CHOICES: 'CLEAR_CHOICES',\n ADD_GROUP: 'ADD_GROUP',\n ADD_ITEM: 'ADD_ITEM',\n REMOVE_ITEM: 'REMOVE_ITEM',\n HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM',\n CLEAR_ALL: 'CLEAR_ALL',\n RESET_TO: 'RESET_TO',\n SET_IS_LOADING: 'SET_IS_LOADING'\n};\nexports.KEY_CODES = {\n BACK_KEY: 46,\n DELETE_KEY: 8,\n ENTER_KEY: 13,\n A_KEY: 65,\n ESC_KEY: 27,\n UP_KEY: 38,\n DOWN_KEY: 40,\n PAGE_UP_KEY: 33,\n PAGE_DOWN_KEY: 34\n};\nexports.TEXT_TYPE = 'text';\nexports.SELECT_ONE_TYPE = 'select-one';\nexports.SELECT_MULTIPLE_TYPE = 'select-multiple';\nexports.SCROLLING_SPEED = 4;\n\n/***/ }),\n\n/***/ 789:\n/***/ ((__unused_webpack_module, exports, __nested_webpack_require_99132__) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.DEFAULT_CONFIG = exports.DEFAULT_CLASSNAMES = void 0;\nvar utils_1 = __nested_webpack_require_99132__(799);\nexports.DEFAULT_CLASSNAMES = {\n containerOuter: 'choices',\n containerInner: 'choices__inner',\n input: 'choices__input',\n inputCloned: 'choices__input--cloned',\n list: 'choices__list',\n listItems: 'choices__list--multiple',\n listSingle: 'choices__list--single',\n listDropdown: 'choices__list--dropdown',\n item: 'choices__item',\n itemSelectable: 'choices__item--selectable',\n itemDisabled: 'choices__item--disabled',\n itemChoice: 'choices__item--choice',\n placeholder: 'choices__placeholder',\n group: 'choices__group',\n groupHeading: 'choices__heading',\n button: 'choices__button',\n activeState: 'is-active',\n focusState: 'is-focused',\n openState: 'is-open',\n disabledState: 'is-disabled',\n highlightedState: 'is-highlighted',\n selectedState: 'is-selected',\n flippedState: 'is-flipped',\n loadingState: 'is-loading',\n noResults: 'has-no-results',\n noChoices: 'has-no-choices'\n};\nexports.DEFAULT_CONFIG = {\n items: [],\n choices: [],\n silent: false,\n renderChoiceLimit: -1,\n maxItemCount: -1,\n addItems: true,\n addItemFilter: null,\n removeItems: true,\n removeItemButton: false,\n editItems: false,\n allowHTML: true,\n duplicateItemsAllowed: true,\n delimiter: ',',\n paste: true,\n searchEnabled: true,\n searchChoices: true,\n searchFloor: 1,\n searchResultLimit: 4,\n searchFields: ['label', 'value'],\n position: 'auto',\n resetScrollPosition: true,\n shouldSort: true,\n shouldSortItems: false,\n sorter: utils_1.sortByAlpha,\n shadowRoot: null,\n placeholder: true,\n placeholderValue: null,\n searchPlaceholderValue: null,\n prependValue: null,\n appendValue: null,\n renderSelectedChoices: 'auto',\n loadingText: 'Loading...',\n noResultsText: 'No results found',\n noChoicesText: 'No choices to choose from',\n itemSelectText: 'Press to select',\n uniqueItemText: 'Only unique values can be added',\n customAddItemText: 'Only values matching specific conditions can be added',\n addItemText: function (value) {\n return \"Press Enter to add <b>\\\"\".concat((0, utils_1.sanitise)(value), \"\\\"</b>\");\n },\n maxItemText: function (maxItemCount) {\n return \"Only \".concat(maxItemCount, \" values can be added\");\n },\n valueComparer: function (value1, value2) {\n return value1 === value2;\n },\n fuseOptions: {\n includeScore: true\n },\n labelId: '',\n callbackOnInit: null,\n callbackOnCreateTemplates: null,\n classNames: exports.DEFAULT_CLASSNAMES\n};\n\n/***/ }),\n\n/***/ 18:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 978:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 948:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 359:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 285:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 533:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 187:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_102749__) {\n\n\n\nvar __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = {\n enumerable: true,\n get: function () {\n return m[k];\n }\n };\n }\n Object.defineProperty(o, k2, desc);\n} : function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\nvar __exportStar = this && this.__exportStar || function (m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n__exportStar(__nested_webpack_require_102749__(18), exports);\n__exportStar(__nested_webpack_require_102749__(978), exports);\n__exportStar(__nested_webpack_require_102749__(948), exports);\n__exportStar(__nested_webpack_require_102749__(359), exports);\n__exportStar(__nested_webpack_require_102749__(285), exports);\n__exportStar(__nested_webpack_require_102749__(533), exports);\n__exportStar(__nested_webpack_require_102749__(287), exports);\n__exportStar(__nested_webpack_require_102749__(132), exports);\n__exportStar(__nested_webpack_require_102749__(837), exports);\n__exportStar(__nested_webpack_require_102749__(598), exports);\n__exportStar(__nested_webpack_require_102749__(369), exports);\n__exportStar(__nested_webpack_require_102749__(37), exports);\n__exportStar(__nested_webpack_require_102749__(47), exports);\n__exportStar(__nested_webpack_require_102749__(923), exports);\n__exportStar(__nested_webpack_require_102749__(876), exports);\n\n/***/ }),\n\n/***/ 287:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 132:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 837:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 598:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 37:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 369:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 47:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 923:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 876:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n\n/***/ }),\n\n/***/ 799:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.parseCustomProperties = exports.diff = exports.cloneObject = exports.existsInArray = exports.dispatchEvent = exports.sortByScore = exports.sortByAlpha = exports.strToEl = exports.sanitise = exports.isScrolledIntoView = exports.getAdjacentEl = exports.wrap = exports.isType = exports.getType = exports.generateId = exports.generateChars = exports.getRandomNumber = void 0;\nvar getRandomNumber = function (min, max) {\n return Math.floor(Math.random() * (max - min) + min);\n};\nexports.getRandomNumber = getRandomNumber;\nvar generateChars = function (length) {\n return Array.from({\n length: length\n }, function () {\n return (0, exports.getRandomNumber)(0, 36).toString(36);\n }).join('');\n};\nexports.generateChars = generateChars;\nvar generateId = function (element, prefix) {\n var id = element.id || element.name && \"\".concat(element.name, \"-\").concat((0, exports.generateChars)(2)) || (0, exports.generateChars)(4);\n id = id.replace(/(:|\\.|\\[|\\]|,)/g, '');\n id = \"\".concat(prefix, \"-\").concat(id);\n return id;\n};\nexports.generateId = generateId;\nvar getType = function (obj) {\n return Object.prototype.toString.call(obj).slice(8, -1);\n};\nexports.getType = getType;\nvar isType = function (type, obj) {\n return obj !== undefined && obj !== null && (0, exports.getType)(obj) === type;\n};\nexports.isType = isType;\nvar wrap = function (element, wrapper) {\n if (wrapper === void 0) {\n wrapper = document.createElement('div');\n }\n if (element.parentNode) {\n if (element.nextSibling) {\n element.parentNode.insertBefore(wrapper, element.nextSibling);\n } else {\n element.parentNode.appendChild(wrapper);\n }\n }\n return wrapper.appendChild(element);\n};\nexports.wrap = wrap;\nvar getAdjacentEl = function (startEl, selector, direction) {\n if (direction === void 0) {\n direction = 1;\n }\n var prop = \"\".concat(direction > 0 ? 'next' : 'previous', \"ElementSibling\");\n var sibling = startEl[prop];\n while (sibling) {\n if (sibling.matches(selector)) {\n return sibling;\n }\n sibling = sibling[prop];\n }\n return sibling;\n};\nexports.getAdjacentEl = getAdjacentEl;\nvar isScrolledIntoView = function (element, parent, direction) {\n if (direction === void 0) {\n direction = 1;\n }\n if (!element) {\n return false;\n }\n var isVisible;\n if (direction > 0) {\n // In view from bottom\n isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight;\n } else {\n // In view from top\n isVisible = element.offsetTop >= parent.scrollTop;\n }\n return isVisible;\n};\nexports.isScrolledIntoView = isScrolledIntoView;\nvar sanitise = function (value) {\n if (typeof value !== 'string') {\n return value;\n }\n return value.replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/\"/g, '"');\n};\nexports.sanitise = sanitise;\nexports.strToEl = function () {\n var tmpEl = document.createElement('div');\n return function (str) {\n var cleanedInput = str.trim();\n tmpEl.innerHTML = cleanedInput;\n var firldChild = tmpEl.children[0];\n while (tmpEl.firstChild) {\n tmpEl.removeChild(tmpEl.firstChild);\n }\n return firldChild;\n };\n}();\nvar sortByAlpha = function (_a, _b) {\n var value = _a.value,\n _c = _a.label,\n label = _c === void 0 ? value : _c;\n var value2 = _b.value,\n _d = _b.label,\n label2 = _d === void 0 ? value2 : _d;\n return label.localeCompare(label2, [], {\n sensitivity: 'base',\n ignorePunctuation: true,\n numeric: true\n });\n};\nexports.sortByAlpha = sortByAlpha;\nvar sortByScore = function (a, b) {\n var _a = a.score,\n scoreA = _a === void 0 ? 0 : _a;\n var _b = b.score,\n scoreB = _b === void 0 ? 0 : _b;\n return scoreA - scoreB;\n};\nexports.sortByScore = sortByScore;\nvar dispatchEvent = function (element, type, customArgs) {\n if (customArgs === void 0) {\n customArgs = null;\n }\n var event = new CustomEvent(type, {\n detail: customArgs,\n bubbles: true,\n cancelable: true\n });\n return element.dispatchEvent(event);\n};\nexports.dispatchEvent = dispatchEvent;\nvar existsInArray = function (array, value, key) {\n if (key === void 0) {\n key = 'value';\n }\n return array.some(function (item) {\n if (typeof value === 'string') {\n return item[key] === value.trim();\n }\n return item[key] === value;\n });\n};\nexports.existsInArray = existsInArray;\nvar cloneObject = function (obj) {\n return JSON.parse(JSON.stringify(obj));\n};\nexports.cloneObject = cloneObject;\n/**\n * Returns an array of keys present on the first but missing on the second object\n */\nvar diff = function (a, b) {\n var aKeys = Object.keys(a).sort();\n var bKeys = Object.keys(b).sort();\n return aKeys.filter(function (i) {\n return bKeys.indexOf(i) < 0;\n });\n};\nexports.diff = diff;\nvar parseCustomProperties = function (customProperties) {\n if (typeof customProperties !== 'undefined') {\n try {\n return JSON.parse(customProperties);\n } catch (e) {\n return customProperties;\n }\n }\n return {};\n};\nexports.parseCustomProperties = parseCustomProperties;\n\n/***/ }),\n\n/***/ 273:\n/***/ (function(__unused_webpack_module, exports) {\n\n\n\nvar __spreadArray = this && this.__spreadArray || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.defaultState = void 0;\nexports.defaultState = [];\nfunction choices(state, action) {\n if (state === void 0) {\n state = exports.defaultState;\n }\n if (action === void 0) {\n action = {};\n }\n switch (action.type) {\n case 'ADD_CHOICE':\n {\n var addChoiceAction = action;\n var choice = {\n id: addChoiceAction.id,\n elementId: addChoiceAction.elementId,\n groupId: addChoiceAction.groupId,\n value: addChoiceAction.value,\n label: addChoiceAction.label || addChoiceAction.value,\n disabled: addChoiceAction.disabled || false,\n selected: false,\n active: true,\n score: 9999,\n customProperties: addChoiceAction.customProperties,\n placeholder: addChoiceAction.placeholder || false\n };\n /*\n A disabled choice appears in the choice dropdown but cannot be selected\n A selected choice has been added to the passed input's value (added as an item)\n An active choice appears within the choice dropdown\n */\n return __spreadArray(__spreadArray([], state, true), [choice], false);\n }\n case 'ADD_ITEM':\n {\n var addItemAction_1 = action;\n // When an item is added and it has an associated choice,\n // we want to disable it so it can't be chosen again\n if (addItemAction_1.choiceId > -1) {\n return state.map(function (obj) {\n var choice = obj;\n if (choice.id === parseInt(\"\".concat(addItemAction_1.choiceId), 10)) {\n choice.selected = true;\n }\n return choice;\n });\n }\n return state;\n }\n case 'REMOVE_ITEM':\n {\n var removeItemAction_1 = action;\n // When an item is removed and it has an associated choice,\n // we want to re-enable it so it can be chosen again\n if (removeItemAction_1.choiceId && removeItemAction_1.choiceId > -1) {\n return state.map(function (obj) {\n var choice = obj;\n if (choice.id === parseInt(\"\".concat(removeItemAction_1.choiceId), 10)) {\n choice.selected = false;\n }\n return choice;\n });\n }\n return state;\n }\n case 'FILTER_CHOICES':\n {\n var filterChoicesAction_1 = action;\n return state.map(function (obj) {\n var choice = obj;\n // Set active state based on whether choice is\n // within filtered results\n choice.active = filterChoicesAction_1.results.some(function (_a) {\n var item = _a.item,\n score = _a.score;\n if (item.id === choice.id) {\n choice.score = score;\n return true;\n }\n return false;\n });\n return choice;\n });\n }\n case 'ACTIVATE_CHOICES':\n {\n var activateChoicesAction_1 = action;\n return state.map(function (obj) {\n var choice = obj;\n choice.active = activateChoicesAction_1.active;\n return choice;\n });\n }\n case 'CLEAR_CHOICES':\n {\n return exports.defaultState;\n }\n default:\n {\n return state;\n }\n }\n}\nexports[\"default\"] = choices;\n\n/***/ }),\n\n/***/ 871:\n/***/ (function(__unused_webpack_module, exports) {\n\n\n\nvar __spreadArray = this && this.__spreadArray || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.defaultState = void 0;\nexports.defaultState = [];\nfunction groups(state, action) {\n if (state === void 0) {\n state = exports.defaultState;\n }\n if (action === void 0) {\n action = {};\n }\n switch (action.type) {\n case 'ADD_GROUP':\n {\n var addGroupAction = action;\n return __spreadArray(__spreadArray([], state, true), [{\n id: addGroupAction.id,\n value: addGroupAction.value,\n active: addGroupAction.active,\n disabled: addGroupAction.disabled\n }], false);\n }\n case 'CLEAR_CHOICES':\n {\n return [];\n }\n default:\n {\n return state;\n }\n }\n}\nexports[\"default\"] = groups;\n\n/***/ }),\n\n/***/ 655:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_115791__) {\n\n\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.defaultState = void 0;\nvar redux_1 = __nested_webpack_require_115791__(791);\nvar items_1 = __importDefault(__nested_webpack_require_115791__(52));\nvar groups_1 = __importDefault(__nested_webpack_require_115791__(871));\nvar choices_1 = __importDefault(__nested_webpack_require_115791__(273));\nvar loading_1 = __importDefault(__nested_webpack_require_115791__(502));\nvar utils_1 = __nested_webpack_require_115791__(799);\nexports.defaultState = {\n groups: [],\n items: [],\n choices: [],\n loading: false\n};\nvar appReducer = (0, redux_1.combineReducers)({\n items: items_1.default,\n groups: groups_1.default,\n choices: choices_1.default,\n loading: loading_1.default\n});\nvar rootReducer = function (passedState, action) {\n var state = passedState;\n // If we are clearing all items, groups and options we reassign\n // state and then pass that state to our proper reducer. This isn't\n // mutating our actual state\n // See: http://stackoverflow.com/a/35641992\n if (action.type === 'CLEAR_ALL') {\n state = exports.defaultState;\n } else if (action.type === 'RESET_TO') {\n return (0, utils_1.cloneObject)(action.state);\n }\n return appReducer(state, action);\n};\nexports[\"default\"] = rootReducer;\n\n/***/ }),\n\n/***/ 52:\n/***/ (function(__unused_webpack_module, exports) {\n\n\n\nvar __spreadArray = this && this.__spreadArray || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.defaultState = void 0;\nexports.defaultState = [];\nfunction items(state, action) {\n if (state === void 0) {\n state = exports.defaultState;\n }\n if (action === void 0) {\n action = {};\n }\n switch (action.type) {\n case 'ADD_ITEM':\n {\n var addItemAction = action;\n // Add object to items array\n var newState = __spreadArray(__spreadArray([], state, true), [{\n id: addItemAction.id,\n choiceId: addItemAction.choiceId,\n groupId: addItemAction.groupId,\n value: addItemAction.value,\n label: addItemAction.label,\n active: true,\n highlighted: false,\n customProperties: addItemAction.customProperties,\n placeholder: addItemAction.placeholder || false,\n keyCode: null\n }], false);\n return newState.map(function (obj) {\n var item = obj;\n item.highlighted = false;\n return item;\n });\n }\n case 'REMOVE_ITEM':\n {\n // Set item to inactive\n return state.map(function (obj) {\n var item = obj;\n if (item.id === action.id) {\n item.active = false;\n }\n return item;\n });\n }\n case 'HIGHLIGHT_ITEM':\n {\n var highlightItemAction_1 = action;\n return state.map(function (obj) {\n var item = obj;\n if (item.id === highlightItemAction_1.id) {\n item.highlighted = highlightItemAction_1.highlighted;\n }\n return item;\n });\n }\n default:\n {\n return state;\n }\n }\n}\nexports[\"default\"] = items;\n\n/***/ }),\n\n/***/ 502:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.defaultState = void 0;\nexports.defaultState = false;\nvar general = function (state, action) {\n if (state === void 0) {\n state = exports.defaultState;\n }\n if (action === void 0) {\n action = {};\n }\n switch (action.type) {\n case 'SET_IS_LOADING':\n {\n return action.isLoading;\n }\n default:\n {\n return state;\n }\n }\n};\nexports[\"default\"] = general;\n\n/***/ }),\n\n/***/ 744:\n/***/ (function(__unused_webpack_module, exports, __nested_webpack_require_119892__) {\n\n\n\nvar __spreadArray = this && this.__spreadArray || function (to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\n/* eslint-disable @typescript-eslint/no-explicit-any */\nvar redux_1 = __nested_webpack_require_119892__(791);\nvar index_1 = __importDefault(__nested_webpack_require_119892__(655));\nvar Store = /** @class */function () {\n function Store() {\n this._store = (0, redux_1.createStore)(index_1.default, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());\n }\n /**\n * Subscribe store to function call (wrapped Redux method)\n */\n Store.prototype.subscribe = function (onChange) {\n this._store.subscribe(onChange);\n };\n /**\n * Dispatch event to store (wrapped Redux method)\n */\n Store.prototype.dispatch = function (action) {\n this._store.dispatch(action);\n };\n Object.defineProperty(Store.prototype, \"state\", {\n /**\n * Get store object (wrapping Redux method)\n */\n get: function () {\n return this._store.getState();\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"items\", {\n /**\n * Get items from store\n */\n get: function () {\n return this.state.items;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"activeItems\", {\n /**\n * Get active items from store\n */\n get: function () {\n return this.items.filter(function (item) {\n return item.active === true;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"highlightedActiveItems\", {\n /**\n * Get highlighted items from store\n */\n get: function () {\n return this.items.filter(function (item) {\n return item.active && item.highlighted;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"choices\", {\n /**\n * Get choices from store\n */\n get: function () {\n return this.state.choices;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"activeChoices\", {\n /**\n * Get active choices from store\n */\n get: function () {\n return this.choices.filter(function (choice) {\n return choice.active === true;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"selectableChoices\", {\n /**\n * Get selectable choices from store\n */\n get: function () {\n return this.choices.filter(function (choice) {\n return choice.disabled !== true;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"searchableChoices\", {\n /**\n * Get choices that can be searched (excluding placeholders)\n */\n get: function () {\n return this.selectableChoices.filter(function (choice) {\n return choice.placeholder !== true;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"placeholderChoice\", {\n /**\n * Get placeholder choice from store\n */\n get: function () {\n return __spreadArray([], this.choices, true).reverse().find(function (choice) {\n return choice.placeholder === true;\n });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"groups\", {\n /**\n * Get groups from store\n */\n get: function () {\n return this.state.groups;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"activeGroups\", {\n /**\n * Get active groups from store\n */\n get: function () {\n var _a = this,\n groups = _a.groups,\n choices = _a.choices;\n return groups.filter(function (group) {\n var isActive = group.active === true && group.disabled === false;\n var hasActiveOptions = choices.some(function (choice) {\n return choice.active === true && choice.disabled === false;\n });\n return isActive && hasActiveOptions;\n }, []);\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Get loading state from store\n */\n Store.prototype.isLoading = function () {\n return this.state.loading;\n };\n /**\n * Get single choice by it's ID\n */\n Store.prototype.getChoiceById = function (id) {\n return this.activeChoices.find(function (choice) {\n return choice.id === parseInt(id, 10);\n });\n };\n /**\n * Get group by group id\n */\n Store.prototype.getGroupById = function (id) {\n return this.groups.find(function (group) {\n return group.id === id;\n });\n };\n return Store;\n}();\nexports[\"default\"] = Store;\n\n/***/ }),\n\n/***/ 686:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n\n/**\n * Helpers to create HTML elements used by Choices\n * Can be overridden by providing `callbackOnCreateTemplates` option\n */\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nvar templates = {\n containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) {\n var containerOuter = _a.classNames.containerOuter;\n var div = Object.assign(document.createElement('div'), {\n className: containerOuter\n });\n div.dataset.type = passedElementType;\n if (dir) {\n div.dir = dir;\n }\n if (isSelectOneElement) {\n div.tabIndex = 0;\n }\n if (isSelectElement) {\n div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox');\n if (searchEnabled) {\n div.setAttribute('aria-autocomplete', 'list');\n }\n }\n div.setAttribute('aria-haspopup', 'true');\n div.setAttribute('aria-expanded', 'false');\n if (labelId) {\n div.setAttribute('aria-labelledby', labelId);\n }\n return div;\n },\n containerInner: function (_a) {\n var containerInner = _a.classNames.containerInner;\n return Object.assign(document.createElement('div'), {\n className: containerInner\n });\n },\n itemList: function (_a, isSelectOneElement) {\n var _b = _a.classNames,\n list = _b.list,\n listSingle = _b.listSingle,\n listItems = _b.listItems;\n return Object.assign(document.createElement('div'), {\n className: \"\".concat(list, \" \").concat(isSelectOneElement ? listSingle : listItems)\n });\n },\n placeholder: function (_a, value) {\n var _b;\n var allowHTML = _a.allowHTML,\n placeholder = _a.classNames.placeholder;\n return Object.assign(document.createElement('div'), (_b = {\n className: placeholder\n }, _b[allowHTML ? 'innerHTML' : 'innerText'] = value, _b));\n },\n item: function (_a, _b, removeItemButton) {\n var _c, _d;\n var allowHTML = _a.allowHTML,\n _e = _a.classNames,\n item = _e.item,\n button = _e.button,\n highlightedState = _e.highlightedState,\n itemSelectable = _e.itemSelectable,\n placeholder = _e.placeholder;\n var id = _b.id,\n value = _b.value,\n label = _b.label,\n customProperties = _b.customProperties,\n active = _b.active,\n disabled = _b.disabled,\n highlighted = _b.highlighted,\n isPlaceholder = _b.placeholder;\n var div = Object.assign(document.createElement('div'), (_c = {\n className: item\n }, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c));\n Object.assign(div.dataset, {\n item: '',\n id: id,\n value: value,\n customProperties: customProperties\n });\n if (active) {\n div.setAttribute('aria-selected', 'true');\n }\n if (disabled) {\n div.setAttribute('aria-disabled', 'true');\n }\n if (isPlaceholder) {\n div.classList.add(placeholder);\n }\n div.classList.add(highlighted ? highlightedState : itemSelectable);\n if (removeItemButton) {\n if (disabled) {\n div.classList.remove(itemSelectable);\n }\n div.dataset.deletable = '';\n /** @todo This MUST be localizable, not hardcoded! */\n var REMOVE_ITEM_TEXT = 'Remove item';\n var removeButton = Object.assign(document.createElement('button'), (_d = {\n type: 'button',\n className: button\n }, _d[allowHTML ? 'innerHTML' : 'innerText'] = REMOVE_ITEM_TEXT, _d));\n removeButton.setAttribute('aria-label', \"\".concat(REMOVE_ITEM_TEXT, \": '\").concat(value, \"'\"));\n removeButton.dataset.button = '';\n div.appendChild(removeButton);\n }\n return div;\n },\n choiceList: function (_a, isSelectOneElement) {\n var list = _a.classNames.list;\n var div = Object.assign(document.createElement('div'), {\n className: list\n });\n if (!isSelectOneElement) {\n div.setAttribute('aria-multiselectable', 'true');\n }\n div.setAttribute('role', 'listbox');\n return div;\n },\n choiceGroup: function (_a, _b) {\n var _c;\n var allowHTML = _a.allowHTML,\n _d = _a.classNames,\n group = _d.group,\n groupHeading = _d.groupHeading,\n itemDisabled = _d.itemDisabled;\n var id = _b.id,\n value = _b.value,\n disabled = _b.disabled;\n var div = Object.assign(document.createElement('div'), {\n className: \"\".concat(group, \" \").concat(disabled ? itemDisabled : '')\n });\n div.setAttribute('role', 'group');\n Object.assign(div.dataset, {\n group: '',\n id: id,\n value: value\n });\n if (disabled) {\n div.setAttribute('aria-disabled', 'true');\n }\n div.appendChild(Object.assign(document.createElement('div'), (_c = {\n className: groupHeading\n }, _c[allowHTML ? 'innerHTML' : 'innerText'] = value, _c)));\n return div;\n },\n choice: function (_a, _b, selectText) {\n var _c;\n var allowHTML = _a.allowHTML,\n _d = _a.classNames,\n item = _d.item,\n itemChoice = _d.itemChoice,\n itemSelectable = _d.itemSelectable,\n selectedState = _d.selectedState,\n itemDisabled = _d.itemDisabled,\n placeholder = _d.placeholder;\n var id = _b.id,\n value = _b.value,\n label = _b.label,\n groupId = _b.groupId,\n elementId = _b.elementId,\n isDisabled = _b.disabled,\n isSelected = _b.selected,\n isPlaceholder = _b.placeholder;\n var div = Object.assign(document.createElement('div'), (_c = {\n id: elementId\n }, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c.className = \"\".concat(item, \" \").concat(itemChoice), _c));\n if (isSelected) {\n div.classList.add(selectedState);\n }\n if (isPlaceholder) {\n div.classList.add(placeholder);\n }\n div.setAttribute('role', groupId && groupId > 0 ? 'treeitem' : 'option');\n Object.assign(div.dataset, {\n choice: '',\n id: id,\n value: value,\n selectText: selectText\n });\n if (isDisabled) {\n div.classList.add(itemDisabled);\n div.dataset.choiceDisabled = '';\n div.setAttribute('aria-disabled', 'true');\n } else {\n div.classList.add(itemSelectable);\n div.dataset.choiceSelectable = '';\n }\n return div;\n },\n input: function (_a, placeholderValue) {\n var _b = _a.classNames,\n input = _b.input,\n inputCloned = _b.inputCloned;\n var inp = Object.assign(document.createElement('input'), {\n type: 'text',\n name: 'search_terms',\n className: \"\".concat(input, \" \").concat(inputCloned),\n autocomplete: 'off',\n autocapitalize: 'off',\n spellcheck: false\n });\n inp.setAttribute('role', 'textbox');\n inp.setAttribute('aria-autocomplete', 'list');\n inp.setAttribute('aria-label', placeholderValue);\n return inp;\n },\n dropdown: function (_a) {\n var _b = _a.classNames,\n list = _b.list,\n listDropdown = _b.listDropdown;\n var div = document.createElement('div');\n div.classList.add(list, listDropdown);\n div.setAttribute('aria-expanded', 'false');\n return div;\n },\n notice: function (_a, innerText, type) {\n var _b;\n var allowHTML = _a.allowHTML,\n _c = _a.classNames,\n item = _c.item,\n itemChoice = _c.itemChoice,\n noResults = _c.noResults,\n noChoices = _c.noChoices;\n if (type === void 0) {\n type = '';\n }\n var classes = [item, itemChoice];\n if (type === 'no-choices') {\n classes.push(noChoices);\n } else if (type === 'no-results') {\n classes.push(noResults);\n }\n return Object.assign(document.createElement('div'), (_b = {}, _b[allowHTML ? 'innerHTML' : 'innerText'] = innerText, _b.className = classes.join(' '), _b));\n },\n option: function (_a) {\n var label = _a.label,\n value = _a.value,\n customProperties = _a.customProperties,\n active = _a.active,\n disabled = _a.disabled;\n var opt = new Option(label, value, false, active);\n if (customProperties) {\n opt.dataset.customProperties = \"\".concat(customProperties);\n }\n opt.disabled = !!disabled;\n return opt;\n }\n};\nexports[\"default\"] = templates;\n\n/***/ }),\n\n/***/ 996:\n/***/ ((module) => {\n\n\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn target.propertyIsEnumerable(symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n\n\n/***/ }),\n\n/***/ 221:\n/***/ ((__unused_webpack_module, __nested_webpack_exports__, __nested_webpack_require_137291__) => {\n\n__nested_webpack_require_137291__.r(__nested_webpack_exports__);\n/* harmony export */ __nested_webpack_require_137291__.d(__nested_webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Fuse)\n/* harmony export */ });\n/**\n * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2022 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\nfunction isArray(value) {\n return !Array.isArray\n ? getTag(value) === '[object Array]'\n : Array.isArray(value)\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js\nconst INFINITY = 1 / 0;\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value\n }\n let result = value + '';\n return result == '0' && 1 / value == -INFINITY ? '-0' : result\n}\n\nfunction toString(value) {\n return value == null ? '' : baseToString(value)\n}\n\nfunction isString(value) {\n return typeof value === 'string'\n}\n\nfunction isNumber(value) {\n return typeof value === 'number'\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js\nfunction isBoolean(value) {\n return (\n value === true ||\n value === false ||\n (isObjectLike(value) && getTag(value) == '[object Boolean]')\n )\n}\n\nfunction isObject(value) {\n return typeof value === 'object'\n}\n\n// Checks if `value` is object-like.\nfunction isObjectLike(value) {\n return isObject(value) && value !== null\n}\n\nfunction isDefined(value) {\n return value !== undefined && value !== null\n}\n\nfunction isBlank(value) {\n return !value.trim().length\n}\n\n// Gets the `toStringTag` of `value`.\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js\nfunction getTag(value) {\n return value == null\n ? value === undefined\n ? '[object Undefined]'\n : '[object Null]'\n : Object.prototype.toString.call(value)\n}\n\nconst EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';\n\nconst INCORRECT_INDEX_TYPE = \"Incorrect 'index' type\";\n\nconst LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) =>\n `Invalid value for key ${key}`;\n\nconst PATTERN_LENGTH_TOO_LARGE = (max) =>\n `Pattern length exceeds max of ${max}.`;\n\nconst MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;\n\nconst INVALID_KEY_WEIGHT_VALUE = (key) =>\n `Property 'weight' in key '${key}' must be a positive integer`;\n\nconst hasOwn = Object.prototype.hasOwnProperty;\n\nclass KeyStore {\n constructor(keys) {\n this._keys = [];\n this._keyMap = {};\n\n let totalWeight = 0;\n\n keys.forEach((key) => {\n let obj = createKey(key);\n\n totalWeight += obj.weight;\n\n this._keys.push(obj);\n this._keyMap[obj.id] = obj;\n\n totalWeight += obj.weight;\n });\n\n // Normalize weights so that their sum is equal to 1\n this._keys.forEach((key) => {\n key.weight /= totalWeight;\n });\n }\n get(keyId) {\n return this._keyMap[keyId]\n }\n keys() {\n return this._keys\n }\n toJSON() {\n return JSON.stringify(this._keys)\n }\n}\n\nfunction createKey(key) {\n let path = null;\n let id = null;\n let src = null;\n let weight = 1;\n let getFn = null;\n\n if (isString(key) || isArray(key)) {\n src = key;\n path = createKeyPath(key);\n id = createKeyId(key);\n } else {\n if (!hasOwn.call(key, 'name')) {\n throw new Error(MISSING_KEY_PROPERTY('name'))\n }\n\n const name = key.name;\n src = name;\n\n if (hasOwn.call(key, 'weight')) {\n weight = key.weight;\n\n if (weight <= 0) {\n throw new Error(INVALID_KEY_WEIGHT_VALUE(name))\n }\n }\n\n path = createKeyPath(name);\n id = createKeyId(name);\n getFn = key.getFn;\n }\n\n return { path, id, weight, src, getFn }\n}\n\nfunction createKeyPath(key) {\n return isArray(key) ? key : key.split('.')\n}\n\nfunction createKeyId(key) {\n return isArray(key) ? key.join('.') : key\n}\n\nfunction get(obj, path) {\n let list = [];\n let arr = false;\n\n const deepGet = (obj, path, index) => {\n if (!isDefined(obj)) {\n return\n }\n if (!path[index]) {\n // If there's no path left, we've arrived at the object we care about.\n list.push(obj);\n } else {\n let key = path[index];\n\n const value = obj[key];\n\n if (!isDefined(value)) {\n return\n }\n\n // If we're at the last value in the path, and if it's a string/number/bool,\n // add it to the list\n if (\n index === path.length - 1 &&\n (isString(value) || isNumber(value) || isBoolean(value))\n ) {\n list.push(toString(value));\n } else if (isArray(value)) {\n arr = true;\n // Search each item in the array.\n for (let i = 0, len = value.length; i < len; i += 1) {\n deepGet(value[i], path, index + 1);\n }\n } else if (path.length) {\n // An object. Recurse further.\n deepGet(value, path, index + 1);\n }\n }\n };\n\n // Backwards compatibility (since path used to be a string)\n deepGet(obj, isString(path) ? path.split('.') : path, 0);\n\n return arr ? list : list[0]\n}\n\nconst MatchOptions = {\n // Whether the matches should be included in the result set. When `true`, each record in the result\n // set will include the indices of the matched characters.\n // These can consequently be used for highlighting purposes.\n includeMatches: false,\n // When `true`, the matching function will continue to the end of a search pattern even if\n // a perfect match has already been located in the string.\n findAllMatches: false,\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1\n};\n\nconst BasicOptions = {\n // When `true`, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n isCaseSensitive: false,\n // When true, the matching function will continue to the end of a search pattern even if\n includeScore: false,\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n // Whether to sort the result list, by score\n shouldSort: true,\n // Default sort function: sort by ascending score, ascending index\n sortFn: (a, b) =>\n a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1\n};\n\nconst FuzzyOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100\n};\n\nconst AdvancedOptions = {\n // When `true`, it enables the use of unix-like search commands\n useExtendedSearch: false,\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: get,\n // When `true`, search will ignore `location` and `distance`, so it won't matter\n // where in the string the pattern appears.\n // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score\n ignoreLocation: false,\n // When `true`, the calculation for the relevance score (used for sorting) will\n // ignore the field-length norm.\n // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm\n ignoreFieldNorm: false,\n // The weight to determine how much field length norm effects scoring.\n fieldNormWeight: 1\n};\n\nvar Config = {\n ...BasicOptions,\n ...MatchOptions,\n ...FuzzyOptions,\n ...AdvancedOptions\n};\n\nconst SPACE = /[^ ]+/g;\n\n// Field-length norm: the shorter the field, the higher the weight.\n// Set to 3 decimals to reduce index size.\nfunction norm(weight = 1, mantissa = 3) {\n const cache = new Map();\n const m = Math.pow(10, mantissa);\n\n return {\n get(value) {\n const numTokens = value.match(SPACE).length;\n\n if (cache.has(numTokens)) {\n return cache.get(numTokens)\n }\n\n // Default function is 1/sqrt(x), weight makes that variable\n const norm = 1 / Math.pow(numTokens, 0.5 * weight);\n\n // In place of `toFixed(mantissa)`, for faster computation\n const n = parseFloat(Math.round(norm * m) / m);\n\n cache.set(numTokens, n);\n\n return n\n },\n clear() {\n cache.clear();\n }\n }\n}\n\nclass FuseIndex {\n constructor({\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n this.norm = norm(fieldNormWeight, 3);\n this.getFn = getFn;\n this.isCreated = false;\n\n this.setIndexRecords();\n }\n setSources(docs = []) {\n this.docs = docs;\n }\n setIndexRecords(records = []) {\n this.records = records;\n }\n setKeys(keys = []) {\n this.keys = keys;\n this._keysMap = {};\n keys.forEach((key, idx) => {\n this._keysMap[key.id] = idx;\n });\n }\n create() {\n if (this.isCreated || !this.docs.length) {\n return\n }\n\n this.isCreated = true;\n\n // List is Array<String>\n if (isString(this.docs[0])) {\n this.docs.forEach((doc, docIndex) => {\n this._addString(doc, docIndex);\n });\n } else {\n // List is Array<Object>\n this.docs.forEach((doc, docIndex) => {\n this._addObject(doc, docIndex);\n });\n }\n\n this.norm.clear();\n }\n // Adds a doc to the end of the index\n add(doc) {\n const idx = this.size();\n\n if (isString(doc)) {\n this._addString(doc, idx);\n } else {\n this._addObject(doc, idx);\n }\n }\n // Removes the doc at the specified index of the index\n removeAt(idx) {\n this.records.splice(idx, 1);\n\n // Change ref index of every subsquent doc\n for (let i = idx, len = this.size(); i < len; i += 1) {\n this.records[i].i -= 1;\n }\n }\n getValueForItemAtKeyId(item, keyId) {\n return item[this._keysMap[keyId]]\n }\n size() {\n return this.records.length\n }\n _addString(doc, docIndex) {\n if (!isDefined(doc) || isBlank(doc)) {\n return\n }\n\n let record = {\n v: doc,\n i: docIndex,\n n: this.norm.get(doc)\n };\n\n this.records.push(record);\n }\n _addObject(doc, docIndex) {\n let record = { i: docIndex, $: {} };\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n this.keys.forEach((key, keyIndex) => {\n let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);\n\n if (!isDefined(value)) {\n return\n }\n\n if (isArray(value)) {\n let subRecords = [];\n const stack = [{ nestedArrIndex: -1, value }];\n\n while (stack.length) {\n const { nestedArrIndex, value } = stack.pop();\n\n if (!isDefined(value)) {\n continue\n }\n\n if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n i: nestedArrIndex,\n n: this.norm.get(value)\n };\n\n subRecords.push(subRecord);\n } else if (isArray(value)) {\n value.forEach((item, k) => {\n stack.push({\n nestedArrIndex: k,\n value: item\n });\n });\n } else ;\n }\n record.$[keyIndex] = subRecords;\n } else if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n n: this.norm.get(value)\n };\n\n record.$[keyIndex] = subRecord;\n }\n });\n\n this.records.push(record);\n }\n toJSON() {\n return {\n keys: this.keys,\n records: this.records\n }\n }\n}\n\nfunction createIndex(\n keys,\n docs,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys.map(createKey));\n myIndex.setSources(docs);\n myIndex.create();\n return myIndex\n}\n\nfunction parseIndex(\n data,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const { keys, records } = data;\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys);\n myIndex.setIndexRecords(records);\n return myIndex\n}\n\nfunction computeScore$1(\n pattern,\n {\n errors = 0,\n currentLocation = 0,\n expectedLocation = 0,\n distance = Config.distance,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n const accuracy = errors / pattern.length;\n\n if (ignoreLocation) {\n return accuracy\n }\n\n const proximity = Math.abs(expectedLocation - currentLocation);\n\n if (!distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy\n }\n\n return accuracy + proximity / distance\n}\n\nfunction convertMaskToIndices(\n matchmask = [],\n minMatchCharLength = Config.minMatchCharLength\n) {\n let indices = [];\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (let len = matchmask.length; i < len; i += 1) {\n let match = matchmask[i];\n if (match && start === -1) {\n start = i;\n } else if (!match && start !== -1) {\n end = i - 1;\n if (end - start + 1 >= minMatchCharLength) {\n indices.push([start, end]);\n }\n start = -1;\n }\n }\n\n // (i-1 - start) + 1 => i - start\n if (matchmask[i - 1] && i - start >= minMatchCharLength) {\n indices.push([start, i - 1]);\n }\n\n return indices\n}\n\n// Machine word size\nconst MAX_BITS = 32;\n\nfunction search(\n text,\n pattern,\n patternAlphabet,\n {\n location = Config.location,\n distance = Config.distance,\n threshold = Config.threshold,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n includeMatches = Config.includeMatches,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n if (pattern.length > MAX_BITS) {\n throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS))\n }\n\n const patternLen = pattern.length;\n // Set starting location at beginning text and initialize the alphabet.\n const textLen = text.length;\n // Handle the case when location > text.length\n const expectedLocation = Math.max(0, Math.min(location, textLen));\n // Highest score beyond which we give up.\n let currentThreshold = threshold;\n // Is there a nearby exact match? (speedup)\n let bestLocation = expectedLocation;\n\n // Performance: only computer matches when the minMatchCharLength > 1\n // OR if `includeMatches` is true.\n const computeMatches = minMatchCharLength > 1 || includeMatches;\n // A mask of the matches, used for building the indices\n const matchMask = computeMatches ? Array(textLen) : [];\n\n let index;\n\n // Get all exact matches, here for speed up\n while ((index = text.indexOf(pattern, bestLocation)) > -1) {\n let score = computeScore$1(pattern, {\n currentLocation: index,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n currentThreshold = Math.min(score, currentThreshold);\n bestLocation = index + patternLen;\n\n if (computeMatches) {\n let i = 0;\n while (i < patternLen) {\n matchMask[index + i] = 1;\n i += 1;\n }\n }\n }\n\n // Reset the best location\n bestLocation = -1;\n\n let lastBitArr = [];\n let finalScore = 1;\n let binMax = patternLen + textLen;\n\n const mask = 1 << (patternLen - 1);\n\n for (let i = 0; i < patternLen; i += 1) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n let binMin = 0;\n let binMid = binMax;\n\n while (binMin < binMid) {\n const score = computeScore$1(pattern, {\n errors: i,\n currentLocation: expectedLocation + binMid,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score <= currentThreshold) {\n binMin = binMid;\n } else {\n binMax = binMid;\n }\n\n binMid = Math.floor((binMax - binMin) / 2 + binMin);\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid;\n\n let start = Math.max(1, expectedLocation - binMid + 1);\n let finish = findAllMatches\n ? textLen\n : Math.min(expectedLocation + binMid, textLen) + patternLen;\n\n // Initialize the bit array\n let bitArr = Array(finish + 2);\n\n bitArr[finish + 1] = (1 << i) - 1;\n\n for (let j = finish; j >= start; j -= 1) {\n let currentLocation = j - 1;\n let charMatch = patternAlphabet[text.charAt(currentLocation)];\n\n if (computeMatches) {\n // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)\n matchMask[currentLocation] = +!!charMatch;\n }\n\n // First pass: exact match\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch;\n\n // Subsequent passes: fuzzy match\n if (i) {\n bitArr[j] |=\n ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1];\n }\n\n if (bitArr[j] & mask) {\n finalScore = computeScore$1(pattern, {\n errors: i,\n currentLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (finalScore <= currentThreshold) {\n // Indeed it is\n currentThreshold = finalScore;\n bestLocation = currentLocation;\n\n // Already passed `loc`, downhill from here on in.\n if (bestLocation <= expectedLocation) {\n break\n }\n\n // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.\n start = Math.max(1, 2 * expectedLocation - bestLocation);\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n const score = computeScore$1(pattern, {\n errors: i + 1,\n currentLocation: expectedLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score > currentThreshold) {\n break\n }\n\n lastBitArr = bitArr;\n }\n\n const result = {\n isMatch: bestLocation >= 0,\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n score: Math.max(0.001, finalScore)\n };\n\n if (computeMatches) {\n const indices = convertMaskToIndices(matchMask, minMatchCharLength);\n if (!indices.length) {\n result.isMatch = false;\n } else if (includeMatches) {\n result.indices = indices;\n }\n }\n\n return result\n}\n\nfunction createPatternAlphabet(pattern) {\n let mask = {};\n\n for (let i = 0, len = pattern.length; i < len; i += 1) {\n const char = pattern.charAt(i);\n mask[char] = (mask[char] || 0) | (1 << (len - i - 1));\n }\n\n return mask\n}\n\nclass BitapSearch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n this.options = {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreLocation\n };\n\n this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n\n this.chunks = [];\n\n if (!this.pattern.length) {\n return\n }\n\n const addChunk = (pattern, startIndex) => {\n this.chunks.push({\n pattern,\n alphabet: createPatternAlphabet(pattern),\n startIndex\n });\n };\n\n const len = this.pattern.length;\n\n if (len > MAX_BITS) {\n let i = 0;\n const remainder = len % MAX_BITS;\n const end = len - remainder;\n\n while (i < end) {\n addChunk(this.pattern.substr(i, MAX_BITS), i);\n i += MAX_BITS;\n }\n\n if (remainder) {\n const startIndex = len - MAX_BITS;\n addChunk(this.pattern.substr(startIndex), startIndex);\n }\n } else {\n addChunk(this.pattern, 0);\n }\n }\n\n searchIn(text) {\n const { isCaseSensitive, includeMatches } = this.options;\n\n if (!isCaseSensitive) {\n text = text.toLowerCase();\n }\n\n // Exact match\n if (this.pattern === text) {\n let result = {\n isMatch: true,\n score: 0\n };\n\n if (includeMatches) {\n result.indices = [[0, text.length - 1]];\n }\n\n return result\n }\n\n // Otherwise, use Bitap algorithm\n const {\n location,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n ignoreLocation\n } = this.options;\n\n let allIndices = [];\n let totalScore = 0;\n let hasMatches = false;\n\n this.chunks.forEach(({ pattern, alphabet, startIndex }) => {\n const { isMatch, score, indices } = search(text, pattern, alphabet, {\n location: location + startIndex,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n includeMatches,\n ignoreLocation\n });\n\n if (isMatch) {\n hasMatches = true;\n }\n\n totalScore += score;\n\n if (isMatch && indices) {\n allIndices = [...allIndices, ...indices];\n }\n });\n\n let result = {\n isMatch: hasMatches,\n score: hasMatches ? totalScore / this.chunks.length : 1\n };\n\n if (hasMatches && includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n}\n\nclass BaseMatch {\n constructor(pattern) {\n this.pattern = pattern;\n }\n static isMultiMatch(pattern) {\n return getMatch(pattern, this.multiRegex)\n }\n static isSingleMatch(pattern) {\n return getMatch(pattern, this.singleRegex)\n }\n search(/*text*/) {}\n}\n\nfunction getMatch(pattern, exp) {\n const matches = pattern.match(exp);\n return matches ? matches[1] : null\n}\n\n// Token: 'file\n\nclass ExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'exact'\n }\n static get multiRegex() {\n return /^=\"(.*)\"$/\n }\n static get singleRegex() {\n return /^=(.*)$/\n }\n search(text) {\n const isMatch = text === this.pattern;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !fire\n\nclass InverseExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!(.*)$/\n }\n search(text) {\n const index = text.indexOf(this.pattern);\n const isMatch = index === -1;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: ^file\n\nclass PrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'prefix-exact'\n }\n static get multiRegex() {\n return /^\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^\\^(.*)$/\n }\n search(text) {\n const isMatch = text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !^fire\n\nclass InversePrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-prefix-exact'\n }\n static get multiRegex() {\n return /^!\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!\\^(.*)$/\n }\n search(text) {\n const isMatch = !text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: .file$\n\nclass SuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'suffix-exact'\n }\n static get multiRegex() {\n return /^\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^(.*)\\$$/\n }\n search(text) {\n const isMatch = text.endsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [text.length - this.pattern.length, text.length - 1]\n }\n }\n}\n\n// Token: !.file$\n\nclass InverseSuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-suffix-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^!(.*)\\$$/\n }\n search(text) {\n const isMatch = !text.endsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\nclass FuzzyMatch extends BaseMatch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n super(pattern);\n this._bitapSearch = new BitapSearch(pattern, {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreLocation\n });\n }\n static get type() {\n return 'fuzzy'\n }\n static get multiRegex() {\n return /^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^(.*)$/\n }\n search(text) {\n return this._bitapSearch.searchIn(text)\n }\n}\n\n// Token: 'file\n\nclass IncludeMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'include'\n }\n static get multiRegex() {\n return /^'\"(.*)\"$/\n }\n static get singleRegex() {\n return /^'(.*)$/\n }\n search(text) {\n let location = 0;\n let index;\n\n const indices = [];\n const patternLen = this.pattern.length;\n\n // Get all exact matches\n while ((index = text.indexOf(this.pattern, location)) > -1) {\n location = index + patternLen;\n indices.push([index, location - 1]);\n }\n\n const isMatch = !!indices.length;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices\n }\n }\n}\n\n// ❗Order is important. DO NOT CHANGE.\nconst searchers = [\n ExactMatch,\n IncludeMatch,\n PrefixExactMatch,\n InversePrefixExactMatch,\n InverseSuffixExactMatch,\n SuffixExactMatch,\n InverseExactMatch,\n FuzzyMatch\n];\n\nconst searchersLen = searchers.length;\n\n// Regex to split by spaces, but keep anything in quotes together\nconst SPACE_RE = / +(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/;\nconst OR_TOKEN = '|';\n\n// Return a 2D array representation of the query, for simpler parsing.\n// Example:\n// \"^core go$ | rb$ | py$ xy$\" => [[\"^core\", \"go$\"], [\"rb$\"], [\"py$\", \"xy$\"]]\nfunction parseQuery(pattern, options = {}) {\n return pattern.split(OR_TOKEN).map((item) => {\n let query = item\n .trim()\n .split(SPACE_RE)\n .filter((item) => item && !!item.trim());\n\n let results = [];\n for (let i = 0, len = query.length; i < len; i += 1) {\n const queryItem = query[i];\n\n // 1. Handle multiple query match (i.e, once that are quoted, like `\"hello world\"`)\n let found = false;\n let idx = -1;\n while (!found && ++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isMultiMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n found = true;\n }\n }\n\n if (found) {\n continue\n }\n\n // 2. Handle single query matches (i.e, once that are *not* quoted)\n idx = -1;\n while (++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isSingleMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n break\n }\n }\n }\n\n return results\n })\n}\n\n// These extended matchers can return an array of matches, as opposed\n// to a singl match\nconst MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);\n\n/**\n * Command-like searching\n * ======================\n *\n * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,\n * search in a given text.\n *\n * Search syntax:\n *\n * | Token | Match type | Description |\n * | ----------- | -------------------------- | -------------------------------------- |\n * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |\n * | `=scheme` | exact-match | Items that are `scheme` |\n * | `'python` | include-match | Items that include `python` |\n * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |\n * | `^java` | prefix-exact-match | Items that start with `java` |\n * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |\n * | `.js$` | suffix-exact-match | Items that end with `.js` |\n * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |\n *\n * A single pipe character acts as an OR operator. For example, the following\n * query matches entries that start with `core` and end with either`go`, `rb`,\n * or`py`.\n *\n * ```\n * ^core go$ | rb$ | py$\n * ```\n */\nclass ExtendedSearch {\n constructor(\n pattern,\n {\n isCaseSensitive = Config.isCaseSensitive,\n includeMatches = Config.includeMatches,\n minMatchCharLength = Config.minMatchCharLength,\n ignoreLocation = Config.ignoreLocation,\n findAllMatches = Config.findAllMatches,\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance\n } = {}\n ) {\n this.query = null;\n this.options = {\n isCaseSensitive,\n includeMatches,\n minMatchCharLength,\n findAllMatches,\n ignoreLocation,\n location,\n threshold,\n distance\n };\n\n this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n this.query = parseQuery(this.pattern, this.options);\n }\n\n static condition(_, options) {\n return options.useExtendedSearch\n }\n\n searchIn(text) {\n const query = this.query;\n\n if (!query) {\n return {\n isMatch: false,\n score: 1\n }\n }\n\n const { includeMatches, isCaseSensitive } = this.options;\n\n text = isCaseSensitive ? text : text.toLowerCase();\n\n let numMatches = 0;\n let allIndices = [];\n let totalScore = 0;\n\n // ORs\n for (let i = 0, qLen = query.length; i < qLen; i += 1) {\n const searchers = query[i];\n\n // Reset indices\n allIndices.length = 0;\n numMatches = 0;\n\n // ANDs\n for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {\n const searcher = searchers[j];\n const { isMatch, indices, score } = searcher.search(text);\n\n if (isMatch) {\n numMatches += 1;\n totalScore += score;\n if (includeMatches) {\n const type = searcher.constructor.type;\n if (MultiMatchSet.has(type)) {\n allIndices = [...allIndices, ...indices];\n } else {\n allIndices.push(indices);\n }\n }\n } else {\n totalScore = 0;\n numMatches = 0;\n allIndices.length = 0;\n break\n }\n }\n\n // OR condition, so if TRUE, return\n if (numMatches) {\n let result = {\n isMatch: true,\n score: totalScore / numMatches\n };\n\n if (includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n }\n\n // Nothing was matched\n return {\n isMatch: false,\n score: 1\n }\n }\n}\n\nconst registeredSearchers = [];\n\nfunction register(...args) {\n registeredSearchers.push(...args);\n}\n\nfunction createSearcher(pattern, options) {\n for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {\n let searcherClass = registeredSearchers[i];\n if (searcherClass.condition(pattern, options)) {\n return new searcherClass(pattern, options)\n }\n }\n\n return new BitapSearch(pattern, options)\n}\n\nconst LogicalOperator = {\n AND: '$and',\n OR: '$or'\n};\n\nconst KeyType = {\n PATH: '$path',\n PATTERN: '$val'\n};\n\nconst isExpression = (query) =>\n !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);\n\nconst isPath = (query) => !!query[KeyType.PATH];\n\nconst isLeaf = (query) =>\n !isArray(query) && isObject(query) && !isExpression(query);\n\nconst convertToExplicit = (query) => ({\n [LogicalOperator.AND]: Object.keys(query).map((key) => ({\n [key]: query[key]\n }))\n});\n\n// When `auto` is `true`, the parse function will infer and initialize and add\n// the appropriate `Searcher` instance\nfunction parse(query, options, { auto = true } = {}) {\n const next = (query) => {\n let keys = Object.keys(query);\n\n const isQueryPath = isPath(query);\n\n if (!isQueryPath && keys.length > 1 && !isExpression(query)) {\n return next(convertToExplicit(query))\n }\n\n if (isLeaf(query)) {\n const key = isQueryPath ? query[KeyType.PATH] : keys[0];\n\n const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key];\n\n if (!isString(pattern)) {\n throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key))\n }\n\n const obj = {\n keyId: createKeyId(key),\n pattern\n };\n\n if (auto) {\n obj.searcher = createSearcher(pattern, options);\n }\n\n return obj\n }\n\n let node = {\n children: [],\n operator: keys[0]\n };\n\n keys.forEach((key) => {\n const value = query[key];\n\n if (isArray(value)) {\n value.forEach((item) => {\n node.children.push(next(item));\n });\n }\n });\n\n return node\n };\n\n if (!isExpression(query)) {\n query = convertToExplicit(query);\n }\n\n return next(query)\n}\n\n// Practical scoring function\nfunction computeScore(\n results,\n { ignoreFieldNorm = Config.ignoreFieldNorm }\n) {\n results.forEach((result) => {\n let totalScore = 1;\n\n result.matches.forEach(({ key, norm, score }) => {\n const weight = key ? key.weight : null;\n\n totalScore *= Math.pow(\n score === 0 && weight ? Number.EPSILON : score,\n (weight || 1) * (ignoreFieldNorm ? 1 : norm)\n );\n });\n\n result.score = totalScore;\n });\n}\n\nfunction transformMatches(result, data) {\n const matches = result.matches;\n data.matches = [];\n\n if (!isDefined(matches)) {\n return\n }\n\n matches.forEach((match) => {\n if (!isDefined(match.indices) || !match.indices.length) {\n return\n }\n\n const { indices, value } = match;\n\n let obj = {\n indices,\n value\n };\n\n if (match.key) {\n obj.key = match.key.src;\n }\n\n if (match.idx > -1) {\n obj.refIndex = match.idx;\n }\n\n data.matches.push(obj);\n });\n}\n\nfunction transformScore(result, data) {\n data.score = result.score;\n}\n\nfunction format(\n results,\n docs,\n {\n includeMatches = Config.includeMatches,\n includeScore = Config.includeScore\n } = {}\n) {\n const transformers = [];\n\n if (includeMatches) transformers.push(transformMatches);\n if (includeScore) transformers.push(transformScore);\n\n return results.map((result) => {\n const { idx } = result;\n\n const data = {\n item: docs[idx],\n refIndex: idx\n };\n\n if (transformers.length) {\n transformers.forEach((transformer) => {\n transformer(result, data);\n });\n }\n\n return data\n })\n}\n\nclass Fuse {\n constructor(docs, options = {}, index) {\n this.options = { ...Config, ...options };\n\n if (\n this.options.useExtendedSearch &&\n !true\n ) {}\n\n this._keyStore = new KeyStore(this.options.keys);\n\n this.setCollection(docs, index);\n }\n\n setCollection(docs, index) {\n this._docs = docs;\n\n if (index && !(index instanceof FuseIndex)) {\n throw new Error(INCORRECT_INDEX_TYPE)\n }\n\n this._myIndex =\n index ||\n createIndex(this.options.keys, this._docs, {\n getFn: this.options.getFn,\n fieldNormWeight: this.options.fieldNormWeight\n });\n }\n\n add(doc) {\n if (!isDefined(doc)) {\n return\n }\n\n this._docs.push(doc);\n this._myIndex.add(doc);\n }\n\n remove(predicate = (/* doc, idx */) => false) {\n const results = [];\n\n for (let i = 0, len = this._docs.length; i < len; i += 1) {\n const doc = this._docs[i];\n if (predicate(doc, i)) {\n this.removeAt(i);\n i -= 1;\n len -= 1;\n\n results.push(doc);\n }\n }\n\n return results\n }\n\n removeAt(idx) {\n this._docs.splice(idx, 1);\n this._myIndex.removeAt(idx);\n }\n\n getIndex() {\n return this._myIndex\n }\n\n search(query, { limit = -1 } = {}) {\n const {\n includeMatches,\n includeScore,\n shouldSort,\n sortFn,\n ignoreFieldNorm\n } = this.options;\n\n let results = isString(query)\n ? isString(this._docs[0])\n ? this._searchStringList(query)\n : this._searchObjectList(query)\n : this._searchLogical(query);\n\n computeScore(results, { ignoreFieldNorm });\n\n if (shouldSort) {\n results.sort(sortFn);\n }\n\n if (isNumber(limit) && limit > -1) {\n results = results.slice(0, limit);\n }\n\n return format(results, this._docs, {\n includeMatches,\n includeScore\n })\n }\n\n _searchStringList(query) {\n const searcher = createSearcher(query, this.options);\n const { records } = this._myIndex;\n const results = [];\n\n // Iterate over every string in the index\n records.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n results.push({\n item: text,\n idx,\n matches: [{ score, value: text, norm, indices }]\n });\n }\n });\n\n return results\n }\n\n _searchLogical(query) {\n\n const expression = parse(query, this.options);\n\n const evaluate = (node, item, idx) => {\n if (!node.children) {\n const { keyId, searcher } = node;\n\n const matches = this._findMatches({\n key: this._keyStore.get(keyId),\n value: this._myIndex.getValueForItemAtKeyId(item, keyId),\n searcher\n });\n\n if (matches && matches.length) {\n return [\n {\n idx,\n item,\n matches\n }\n ]\n }\n\n return []\n }\n\n const res = [];\n for (let i = 0, len = node.children.length; i < len; i += 1) {\n const child = node.children[i];\n const result = evaluate(child, item, idx);\n if (result.length) {\n res.push(...result);\n } else if (node.operator === LogicalOperator.AND) {\n return []\n }\n }\n return res\n };\n\n const records = this._myIndex.records;\n const resultMap = {};\n const results = [];\n\n records.forEach(({ $: item, i: idx }) => {\n if (isDefined(item)) {\n let expResults = evaluate(expression, item, idx);\n\n if (expResults.length) {\n // Dedupe when adding\n if (!resultMap[idx]) {\n resultMap[idx] = { idx, item, matches: [] };\n results.push(resultMap[idx]);\n }\n expResults.forEach(({ matches }) => {\n resultMap[idx].matches.push(...matches);\n });\n }\n }\n });\n\n return results\n }\n\n _searchObjectList(query) {\n const searcher = createSearcher(query, this.options);\n const { keys, records } = this._myIndex;\n const results = [];\n\n // List is Array<Object>\n records.forEach(({ $: item, i: idx }) => {\n if (!isDefined(item)) {\n return\n }\n\n let matches = [];\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n keys.forEach((key, keyIndex) => {\n matches.push(\n ...this._findMatches({\n key,\n value: item[keyIndex],\n searcher\n })\n );\n });\n\n if (matches.length) {\n results.push({\n idx,\n item,\n matches\n });\n }\n });\n\n return results\n }\n _findMatches({ key, value, searcher }) {\n if (!isDefined(value)) {\n return []\n }\n\n let matches = [];\n\n if (isArray(value)) {\n value.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({\n score,\n key,\n value: text,\n idx,\n norm,\n indices\n });\n }\n });\n } else {\n const { v: text, n: norm } = value;\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({ score, key, value: text, norm, indices });\n }\n }\n\n return matches\n }\n}\n\nFuse.version = '6.6.2';\nFuse.createIndex = createIndex;\nFuse.parseIndex = parseIndex;\nFuse.config = Config;\n\n{\n Fuse.parseQuery = parse;\n}\n\n{\n register(ExtendedSearch);\n}\n\n\n\n\n/***/ }),\n\n/***/ 791:\n/***/ ((__unused_webpack_module, __nested_webpack_exports__, __nested_webpack_require_178829__) => {\n\n// ESM COMPAT FLAG\n__nested_webpack_require_178829__.r(__nested_webpack_exports__);\n\n// EXPORTS\n__nested_webpack_require_178829__.d(__nested_webpack_exports__, {\n \"__DO_NOT_USE__ActionTypes\": () => (/* binding */ ActionTypes),\n \"applyMiddleware\": () => (/* binding */ applyMiddleware),\n \"bindActionCreators\": () => (/* binding */ bindActionCreators),\n \"combineReducers\": () => (/* binding */ combineReducers),\n \"compose\": () => (/* binding */ compose),\n \"createStore\": () => (/* binding */ createStore),\n \"legacy_createStore\": () => (/* binding */ legacy_createStore)\n});\n\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js\nfunction _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPrimitive.js\n\nfunction _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPropertyKey.js\n\n\nfunction _toPropertyKey(arg) {\n var key = _toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\n\nfunction _defineProperty(obj, key, value) {\n key = _toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectSpread2.js\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n return keys;\n}\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/redux/es/redux.js\n\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\n// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\nfunction miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n}\n\nfunction ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n}\n\nfunction isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n}\n\nfunction isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (false) {}\n\n return typeOfVal;\n}\n\n/**\n * @deprecated\n *\n * **We recommend using the `configureStore` method\n * of the `@reduxjs/toolkit` package**, which replaces `createStore`.\n *\n * Redux Toolkit is our recommended approach for writing Redux logic today,\n * including store setup, reducers, data fetching, and more.\n *\n * **For more details, please read this Redux docs page:**\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * `configureStore` from Redux Toolkit is an improved version of `createStore` that\n * simplifies setup and helps avoid common bugs.\n *\n * You should not be using the `redux` core package by itself today, except for learning purposes.\n * The `createStore` method from the core `redux` package will not be removed, but we encourage\n * all users to migrate to using Redux Toolkit for all Redux code.\n *\n * If you want to use `createStore` without this visual deprecation warning, use\n * the `legacy_createStore` import instead:\n *\n * `import { legacy_createStore as createStore} from 'redux'`\n *\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error( true ? formatProdErrorMessage(0) : 0);\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error( true ? formatProdErrorMessage(1) : 0);\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error( true ? formatProdErrorMessage(2) : 0);\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error( true ? formatProdErrorMessage(3) : 0);\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error( true ? formatProdErrorMessage(4) : 0);\n }\n\n if (isDispatching) {\n throw new Error( true ? formatProdErrorMessage(5) : 0);\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error( true ? formatProdErrorMessage(6) : 0);\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error( true ? formatProdErrorMessage(7) : 0);\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error( true ? formatProdErrorMessage(8) : 0);\n }\n\n if (isDispatching) {\n throw new Error( true ? formatProdErrorMessage(9) : 0);\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error( true ? formatProdErrorMessage(10) : 0);\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error( true ? formatProdErrorMessage(11) : 0);\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n/**\n * Creates a Redux store that holds the state tree.\n *\n * **We recommend using `configureStore` from the\n * `@reduxjs/toolkit` package**, which replaces `createStore`:\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nvar legacy_createStore = createStore;\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error( true ? formatProdErrorMessage(12) : 0);\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error( true ? formatProdErrorMessage(13) : 0);\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (false) {}\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (false) {}\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (false) { var warningMessage; }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error( true ? formatProdErrorMessage(14) : 0);\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error( true ? formatProdErrorMessage(16) : 0);\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error( true ? formatProdErrorMessage(15) : 0);\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread2(_objectSpread2({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\n/*\n * This is a dummy function to check if the function name has been altered by minification.\n * If the function has been minified and NODE_ENV !== 'production', warn the user.\n */\n\nfunction isCrushed() {}\n\nif (false) {}\n\n\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __nested_webpack_require_205024__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_205024__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t(() => {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__nested_webpack_require_205024__.n = (module) => {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\t() => (module['default']) :\n/******/ \t\t\t\t() => (module);\n/******/ \t\t\t__nested_webpack_require_205024__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t})();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t(() => {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__nested_webpack_require_205024__.d = (exports, definition) => {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__nested_webpack_require_205024__.o(definition, key) && !__nested_webpack_require_205024__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t})();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t(() => {\n/******/ \t\t__nested_webpack_require_205024__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\n/******/ \t})();\n/******/ \t\n/******/ \t/* webpack/runtime/make namespace object */\n/******/ \t(() => {\n/******/ \t\t// define __esModule on exports\n/******/ \t\t__nested_webpack_require_205024__.r = (exports) => {\n/******/ \t\t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t\t}\n/******/ \t\t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t\t};\n/******/ \t})();\n/******/ \t\n/************************************************************************/\nvar __nested_webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\n/* harmony export */ __nested_webpack_require_205024__.d(__nested_webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _scripts_choices__WEBPACK_IMPORTED_MODULE_0__ = __nested_webpack_require_205024__(373);\n/* harmony import */ var _scripts_choices__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__nested_webpack_require_205024__.n(_scripts_choices__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _scripts_interfaces__WEBPACK_IMPORTED_MODULE_1__ = __nested_webpack_require_205024__(187);\n/* harmony import */ var _scripts_interfaces__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__nested_webpack_require_205024__.n(_scripts_interfaces__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _scripts_constants__WEBPACK_IMPORTED_MODULE_2__ = __nested_webpack_require_205024__(883);\n/* harmony import */ var _scripts_defaults__WEBPACK_IMPORTED_MODULE_3__ = __nested_webpack_require_205024__(789);\n/* harmony import */ var _scripts_templates__WEBPACK_IMPORTED_MODULE_4__ = __nested_webpack_require_205024__(686);\n\n\n\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((_scripts_choices__WEBPACK_IMPORTED_MODULE_0___default()));\n\n})();\n\n__nested_webpack_exports__ = __nested_webpack_exports__[\"default\"];\n/******/ \treturn __nested_webpack_exports__;\n/******/ })()\n;\n});\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/choices.js/public/assets/scripts/choices.js?");
|
29
|
-
|
30
|
-
/***/ }),
|
31
|
-
|
32
22
|
/***/ "./node_modules/@formio/core/lib/error/FieldError.js":
|
33
23
|
/*!***********************************************************!*\
|
34
24
|
!*** ./node_modules/@formio/core/lib/error/FieldError.js ***!
|
@@ -2673,6 +2663,16 @@ eval("(function (global, factory) {\n\t true ? module.exports = factory() :\n\t0
|
|
2673
2663
|
|
2674
2664
|
/***/ }),
|
2675
2665
|
|
2666
|
+
/***/ "./node_modules/choices.js/public/assets/scripts/choices.js":
|
2667
|
+
/*!******************************************************************!*\
|
2668
|
+
!*** ./node_modules/choices.js/public/assets/scripts/choices.js ***!
|
2669
|
+
\******************************************************************/
|
2670
|
+
/***/ (function(module) {
|
2671
|
+
|
2672
|
+
eval("/*! choices.js v11.0.6 | © 2025 Josh Johnson | https://github.com/jshjohnson/Choices#readme */\n\n(function (global, factory) {\n true ? module.exports = factory() :\n 0;\n})(this, (function () { 'use strict';\n\n /******************************************************************************\r\n Copyright (c) Microsoft Corporation.\r\n\r\n Permission to use, copy, modify, and/or distribute this software for any\r\n purpose with or without fee is hereby granted.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\n AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n PERFORMANCE OF THIS SOFTWARE.\r\n ***************************************************************************** */\n /* global Reflect, Promise, SuppressedError, Symbol */\n\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d, b);\n };\n function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n }\n var __assign = function () {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n };\n function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n }\n typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n };\n\n var ActionType = {\n ADD_CHOICE: 'ADD_CHOICE',\n REMOVE_CHOICE: 'REMOVE_CHOICE',\n FILTER_CHOICES: 'FILTER_CHOICES',\n ACTIVATE_CHOICES: 'ACTIVATE_CHOICES',\n CLEAR_CHOICES: 'CLEAR_CHOICES',\n ADD_GROUP: 'ADD_GROUP',\n ADD_ITEM: 'ADD_ITEM',\n REMOVE_ITEM: 'REMOVE_ITEM',\n HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM',\n };\n\n var EventType = {\n showDropdown: 'showDropdown',\n hideDropdown: 'hideDropdown',\n change: 'change',\n choice: 'choice',\n search: 'search',\n addItem: 'addItem',\n removeItem: 'removeItem',\n highlightItem: 'highlightItem',\n highlightChoice: 'highlightChoice',\n unhighlightItem: 'unhighlightItem',\n };\n\n var KeyCodeMap = {\n TAB_KEY: 9,\n SHIFT_KEY: 16,\n BACK_KEY: 46,\n DELETE_KEY: 8,\n ENTER_KEY: 13,\n A_KEY: 65,\n ESC_KEY: 27,\n UP_KEY: 38,\n DOWN_KEY: 40,\n PAGE_UP_KEY: 33,\n PAGE_DOWN_KEY: 34,\n };\n\n var ObjectsInConfig = ['fuseOptions', 'classNames'];\n\n var PassedElementTypes = {\n Text: 'text',\n SelectOne: 'select-one',\n SelectMultiple: 'select-multiple',\n };\n\n var addChoice = function (choice) { return ({\n type: ActionType.ADD_CHOICE,\n choice: choice,\n }); };\n var removeChoice = function (choice) { return ({\n type: ActionType.REMOVE_CHOICE,\n choice: choice,\n }); };\n var filterChoices = function (results) { return ({\n type: ActionType.FILTER_CHOICES,\n results: results,\n }); };\n var activateChoices = function (active) {\n return ({\n type: ActionType.ACTIVATE_CHOICES,\n active: active,\n });\n };\n\n var addGroup = function (group) { return ({\n type: ActionType.ADD_GROUP,\n group: group,\n }); };\n\n var addItem = function (item) { return ({\n type: ActionType.ADD_ITEM,\n item: item,\n }); };\n var removeItem$1 = function (item) { return ({\n type: ActionType.REMOVE_ITEM,\n item: item,\n }); };\n var highlightItem = function (item, highlighted) { return ({\n type: ActionType.HIGHLIGHT_ITEM,\n item: item,\n highlighted: highlighted,\n }); };\n\n var getRandomNumber = function (min, max) { return Math.floor(Math.random() * (max - min) + min); };\n var generateChars = function (length) {\n return Array.from({ length: length }, function () { return getRandomNumber(0, 36).toString(36); }).join('');\n };\n var generateId = function (element, prefix) {\n var id = element.id || (element.name && \"\".concat(element.name, \"-\").concat(generateChars(2))) || generateChars(4);\n id = id.replace(/(:|\\.|\\[|\\]|,)/g, '');\n id = \"\".concat(prefix, \"-\").concat(id);\n return id;\n };\n var getAdjacentEl = function (startEl, selector, direction) {\n if (direction === void 0) { direction = 1; }\n var prop = \"\".concat(direction > 0 ? 'next' : 'previous', \"ElementSibling\");\n var sibling = startEl[prop];\n while (sibling) {\n if (sibling.matches(selector)) {\n return sibling;\n }\n sibling = sibling[prop];\n }\n return null;\n };\n var isScrolledIntoView = function (element, parent, direction) {\n if (direction === void 0) { direction = 1; }\n var isVisible;\n if (direction > 0) {\n // In view from bottom\n isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight;\n }\n else {\n // In view from top\n isVisible = element.offsetTop >= parent.scrollTop;\n }\n return isVisible;\n };\n var sanitise = function (value) {\n if (typeof value !== 'string') {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'object') {\n if ('raw' in value) {\n return sanitise(value.raw);\n }\n if ('trusted' in value) {\n return value.trusted;\n }\n }\n return value;\n }\n return value\n .replace(/&/g, '&')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/'/g, ''')\n .replace(/\"/g, '"');\n };\n var strToEl = (function () {\n var tmpEl = document.createElement('div');\n return function (str) {\n tmpEl.innerHTML = str.trim();\n var firstChild = tmpEl.children[0];\n while (tmpEl.firstChild) {\n tmpEl.removeChild(tmpEl.firstChild);\n }\n return firstChild;\n };\n })();\n var resolveNoticeFunction = function (fn, value) {\n return typeof fn === 'function' ? fn(sanitise(value), value) : fn;\n };\n var resolveStringFunction = function (fn) {\n return typeof fn === 'function' ? fn() : fn;\n };\n var unwrapStringForRaw = function (s) {\n if (typeof s === 'string') {\n return s;\n }\n if (typeof s === 'object') {\n if ('trusted' in s) {\n return s.trusted;\n }\n if ('raw' in s) {\n return s.raw;\n }\n }\n return '';\n };\n var unwrapStringForEscaped = function (s) {\n if (typeof s === 'string') {\n return s;\n }\n if (typeof s === 'object') {\n if ('escaped' in s) {\n return s.escaped;\n }\n if ('trusted' in s) {\n return s.trusted;\n }\n }\n return '';\n };\n var escapeForTemplate = function (allowHTML, s) {\n return allowHTML ? unwrapStringForEscaped(s) : sanitise(s);\n };\n var setElementHtml = function (el, allowHtml, html) {\n el.innerHTML = escapeForTemplate(allowHtml, html);\n };\n var sortByAlpha = function (_a, _b) {\n var value = _a.value, _c = _a.label, label = _c === void 0 ? value : _c;\n var value2 = _b.value, _d = _b.label, label2 = _d === void 0 ? value2 : _d;\n return unwrapStringForRaw(label).localeCompare(unwrapStringForRaw(label2), [], {\n sensitivity: 'base',\n ignorePunctuation: true,\n numeric: true,\n });\n };\n var sortByRank = function (a, b) {\n return a.rank - b.rank;\n };\n var dispatchEvent = function (element, type, customArgs) {\n if (customArgs === void 0) { customArgs = null; }\n var event = new CustomEvent(type, {\n detail: customArgs,\n bubbles: true,\n cancelable: true,\n });\n return element.dispatchEvent(event);\n };\n /**\n * Returns an array of keys present on the first but missing on the second object\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n var diff = function (a, b) {\n var aKeys = Object.keys(a).sort();\n var bKeys = Object.keys(b).sort();\n return aKeys.filter(function (i) { return bKeys.indexOf(i) < 0; });\n };\n var getClassNames = function (ClassNames) {\n return Array.isArray(ClassNames) ? ClassNames : [ClassNames];\n };\n var getClassNamesSelector = function (option) {\n if (option && Array.isArray(option)) {\n return option\n .map(function (item) {\n return \".\".concat(item);\n })\n .join('');\n }\n return \".\".concat(option);\n };\n var addClassesToElement = function (element, className) {\n var _a;\n (_a = element.classList).add.apply(_a, getClassNames(className));\n };\n var removeClassesFromElement = function (element, className) {\n var _a;\n (_a = element.classList).remove.apply(_a, getClassNames(className));\n };\n var parseCustomProperties = function (customProperties) {\n if (typeof customProperties !== 'undefined') {\n try {\n return JSON.parse(customProperties);\n }\n catch (e) {\n return customProperties;\n }\n }\n return {};\n };\n var updateClassList = function (item, add, remove) {\n var itemEl = item.itemEl;\n if (itemEl) {\n removeClassesFromElement(itemEl, remove);\n addClassesToElement(itemEl, add);\n }\n };\n\n var Dropdown = /** @class */ (function () {\n function Dropdown(_a) {\n var element = _a.element, type = _a.type, classNames = _a.classNames;\n this.element = element;\n this.classNames = classNames;\n this.type = type;\n this.isActive = false;\n }\n /**\n * Show dropdown to user by adding active state class\n */\n Dropdown.prototype.show = function () {\n addClassesToElement(this.element, this.classNames.activeState);\n this.element.setAttribute('aria-expanded', 'true');\n this.isActive = true;\n return this;\n };\n /**\n * Hide dropdown from user\n */\n Dropdown.prototype.hide = function () {\n removeClassesFromElement(this.element, this.classNames.activeState);\n this.element.setAttribute('aria-expanded', 'false');\n this.isActive = false;\n return this;\n };\n return Dropdown;\n }());\n\n var Container = /** @class */ (function () {\n function Container(_a) {\n var element = _a.element, type = _a.type, classNames = _a.classNames, position = _a.position;\n this.element = element;\n this.classNames = classNames;\n this.type = type;\n this.position = position;\n this.isOpen = false;\n this.isFlipped = false;\n this.isDisabled = false;\n this.isLoading = false;\n }\n /**\n * Determine whether container should be flipped based on passed\n * dropdown position\n */\n Container.prototype.shouldFlip = function (dropdownPos, dropdownHeight) {\n // If flip is enabled and the dropdown bottom position is\n // greater than the window height flip the dropdown.\n var shouldFlip = false;\n if (this.position === 'auto') {\n shouldFlip =\n this.element.getBoundingClientRect().top - dropdownHeight >= 0 &&\n !window.matchMedia(\"(min-height: \".concat(dropdownPos + 1, \"px)\")).matches;\n }\n else if (this.position === 'top') {\n shouldFlip = true;\n }\n return shouldFlip;\n };\n Container.prototype.setActiveDescendant = function (activeDescendantID) {\n this.element.setAttribute('aria-activedescendant', activeDescendantID);\n };\n Container.prototype.removeActiveDescendant = function () {\n this.element.removeAttribute('aria-activedescendant');\n };\n Container.prototype.open = function (dropdownPos, dropdownHeight) {\n addClassesToElement(this.element, this.classNames.openState);\n this.element.setAttribute('aria-expanded', 'true');\n this.isOpen = true;\n if (this.shouldFlip(dropdownPos, dropdownHeight)) {\n addClassesToElement(this.element, this.classNames.flippedState);\n this.isFlipped = true;\n }\n };\n Container.prototype.close = function () {\n removeClassesFromElement(this.element, this.classNames.openState);\n this.element.setAttribute('aria-expanded', 'false');\n this.removeActiveDescendant();\n this.isOpen = false;\n // A dropdown flips if it does not have space within the page\n if (this.isFlipped) {\n removeClassesFromElement(this.element, this.classNames.flippedState);\n this.isFlipped = false;\n }\n };\n Container.prototype.addFocusState = function () {\n addClassesToElement(this.element, this.classNames.focusState);\n };\n Container.prototype.removeFocusState = function () {\n removeClassesFromElement(this.element, this.classNames.focusState);\n };\n Container.prototype.enable = function () {\n removeClassesFromElement(this.element, this.classNames.disabledState);\n this.element.removeAttribute('aria-disabled');\n if (this.type === PassedElementTypes.SelectOne) {\n this.element.setAttribute('tabindex', '0');\n }\n this.isDisabled = false;\n };\n Container.prototype.disable = function () {\n addClassesToElement(this.element, this.classNames.disabledState);\n this.element.setAttribute('aria-disabled', 'true');\n if (this.type === PassedElementTypes.SelectOne) {\n this.element.setAttribute('tabindex', '-1');\n }\n this.isDisabled = true;\n };\n Container.prototype.wrap = function (element) {\n var el = this.element;\n var parentNode = element.parentNode;\n if (parentNode) {\n if (element.nextSibling) {\n parentNode.insertBefore(el, element.nextSibling);\n }\n else {\n parentNode.appendChild(el);\n }\n }\n el.appendChild(element);\n };\n Container.prototype.unwrap = function (element) {\n var el = this.element;\n var parentNode = el.parentNode;\n if (parentNode) {\n // Move passed element outside this element\n parentNode.insertBefore(element, el);\n // Remove this element\n parentNode.removeChild(el);\n }\n };\n Container.prototype.addLoadingState = function () {\n addClassesToElement(this.element, this.classNames.loadingState);\n this.element.setAttribute('aria-busy', 'true');\n this.isLoading = true;\n };\n Container.prototype.removeLoadingState = function () {\n removeClassesFromElement(this.element, this.classNames.loadingState);\n this.element.removeAttribute('aria-busy');\n this.isLoading = false;\n };\n return Container;\n }());\n\n var Input = /** @class */ (function () {\n function Input(_a) {\n var element = _a.element, type = _a.type, classNames = _a.classNames, preventPaste = _a.preventPaste;\n this.element = element;\n this.type = type;\n this.classNames = classNames;\n this.preventPaste = preventPaste;\n this.isFocussed = this.element.isEqualNode(document.activeElement);\n this.isDisabled = element.disabled;\n this._onPaste = this._onPaste.bind(this);\n this._onInput = this._onInput.bind(this);\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n }\n Object.defineProperty(Input.prototype, \"placeholder\", {\n set: function (placeholder) {\n this.element.placeholder = placeholder;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Input.prototype, \"value\", {\n get: function () {\n return this.element.value;\n },\n set: function (value) {\n this.element.value = value;\n },\n enumerable: false,\n configurable: true\n });\n Input.prototype.addEventListeners = function () {\n var el = this.element;\n el.addEventListener('paste', this._onPaste);\n el.addEventListener('input', this._onInput, {\n passive: true,\n });\n el.addEventListener('focus', this._onFocus, {\n passive: true,\n });\n el.addEventListener('blur', this._onBlur, {\n passive: true,\n });\n };\n Input.prototype.removeEventListeners = function () {\n var el = this.element;\n el.removeEventListener('input', this._onInput);\n el.removeEventListener('paste', this._onPaste);\n el.removeEventListener('focus', this._onFocus);\n el.removeEventListener('blur', this._onBlur);\n };\n Input.prototype.enable = function () {\n var el = this.element;\n el.removeAttribute('disabled');\n this.isDisabled = false;\n };\n Input.prototype.disable = function () {\n var el = this.element;\n el.setAttribute('disabled', '');\n this.isDisabled = true;\n };\n Input.prototype.focus = function () {\n if (!this.isFocussed) {\n this.element.focus();\n }\n };\n Input.prototype.blur = function () {\n if (this.isFocussed) {\n this.element.blur();\n }\n };\n Input.prototype.clear = function (setWidth) {\n if (setWidth === void 0) { setWidth = true; }\n this.element.value = '';\n if (setWidth) {\n this.setWidth();\n }\n return this;\n };\n /**\n * Set the correct input width based on placeholder\n * value or input value\n */\n Input.prototype.setWidth = function () {\n // Resize input to contents or placeholder\n var element = this.element;\n element.style.minWidth = \"\".concat(element.placeholder.length + 1, \"ch\");\n element.style.width = \"\".concat(element.value.length + 1, \"ch\");\n };\n Input.prototype.setActiveDescendant = function (activeDescendantID) {\n this.element.setAttribute('aria-activedescendant', activeDescendantID);\n };\n Input.prototype.removeActiveDescendant = function () {\n this.element.removeAttribute('aria-activedescendant');\n };\n Input.prototype._onInput = function () {\n if (this.type !== PassedElementTypes.SelectOne) {\n this.setWidth();\n }\n };\n Input.prototype._onPaste = function (event) {\n if (this.preventPaste) {\n event.preventDefault();\n }\n };\n Input.prototype._onFocus = function () {\n this.isFocussed = true;\n };\n Input.prototype._onBlur = function () {\n this.isFocussed = false;\n };\n return Input;\n }());\n\n var SCROLLING_SPEED = 4;\n\n var List = /** @class */ (function () {\n function List(_a) {\n var element = _a.element;\n this.element = element;\n this.scrollPos = this.element.scrollTop;\n this.height = this.element.offsetHeight;\n }\n List.prototype.prepend = function (node) {\n var child = this.element.firstElementChild;\n if (child) {\n this.element.insertBefore(node, child);\n }\n else {\n this.element.append(node);\n }\n };\n List.prototype.scrollToTop = function () {\n this.element.scrollTop = 0;\n };\n List.prototype.scrollToChildElement = function (element, direction) {\n var _this = this;\n if (!element) {\n return;\n }\n var listHeight = this.element.offsetHeight;\n // Scroll position of dropdown\n var listScrollPosition = this.element.scrollTop + listHeight;\n var elementHeight = element.offsetHeight;\n // Distance from bottom of element to top of parent\n var elementPos = element.offsetTop + elementHeight;\n // Difference between the element and scroll position\n var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop;\n requestAnimationFrame(function () {\n _this._animateScroll(destination, direction);\n });\n };\n List.prototype._scrollDown = function (scrollPos, strength, destination) {\n var easing = (destination - scrollPos) / strength;\n var distance = easing > 1 ? easing : 1;\n this.element.scrollTop = scrollPos + distance;\n };\n List.prototype._scrollUp = function (scrollPos, strength, destination) {\n var easing = (scrollPos - destination) / strength;\n var distance = easing > 1 ? easing : 1;\n this.element.scrollTop = scrollPos - distance;\n };\n List.prototype._animateScroll = function (destination, direction) {\n var _this = this;\n var strength = SCROLLING_SPEED;\n var choiceListScrollTop = this.element.scrollTop;\n var continueAnimation = false;\n if (direction > 0) {\n this._scrollDown(choiceListScrollTop, strength, destination);\n if (choiceListScrollTop < destination) {\n continueAnimation = true;\n }\n }\n else {\n this._scrollUp(choiceListScrollTop, strength, destination);\n if (choiceListScrollTop > destination) {\n continueAnimation = true;\n }\n }\n if (continueAnimation) {\n requestAnimationFrame(function () {\n _this._animateScroll(destination, direction);\n });\n }\n };\n return List;\n }());\n\n var WrappedElement = /** @class */ (function () {\n function WrappedElement(_a) {\n var element = _a.element, classNames = _a.classNames;\n this.element = element;\n this.classNames = classNames;\n this.isDisabled = false;\n }\n Object.defineProperty(WrappedElement.prototype, \"isActive\", {\n get: function () {\n return this.element.dataset.choice === 'active';\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedElement.prototype, \"dir\", {\n get: function () {\n return this.element.dir;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(WrappedElement.prototype, \"value\", {\n get: function () {\n return this.element.value;\n },\n set: function (value) {\n this.element.setAttribute('value', value);\n this.element.value = value;\n },\n enumerable: false,\n configurable: true\n });\n WrappedElement.prototype.conceal = function () {\n var el = this.element;\n // Hide passed input\n addClassesToElement(el, this.classNames.input);\n el.hidden = true;\n // Remove element from tab index\n el.tabIndex = -1;\n // Backup original styles if any\n var origStyle = el.getAttribute('style');\n if (origStyle) {\n el.setAttribute('data-choice-orig-style', origStyle);\n }\n el.setAttribute('data-choice', 'active');\n };\n WrappedElement.prototype.reveal = function () {\n var el = this.element;\n // Reinstate passed element\n removeClassesFromElement(el, this.classNames.input);\n el.hidden = false;\n el.removeAttribute('tabindex');\n // Recover original styles if any\n var origStyle = el.getAttribute('data-choice-orig-style');\n if (origStyle) {\n el.removeAttribute('data-choice-orig-style');\n el.setAttribute('style', origStyle);\n }\n else {\n el.removeAttribute('style');\n }\n el.removeAttribute('data-choice');\n };\n WrappedElement.prototype.enable = function () {\n this.element.removeAttribute('disabled');\n this.element.disabled = false;\n this.isDisabled = false;\n };\n WrappedElement.prototype.disable = function () {\n this.element.setAttribute('disabled', '');\n this.element.disabled = true;\n this.isDisabled = true;\n };\n WrappedElement.prototype.triggerEvent = function (eventType, data) {\n dispatchEvent(this.element, eventType, data || {});\n };\n return WrappedElement;\n }());\n\n var WrappedInput = /** @class */ (function (_super) {\n __extends(WrappedInput, _super);\n function WrappedInput() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return WrappedInput;\n }(WrappedElement));\n\n var coerceBool = function (arg, defaultValue) {\n if (defaultValue === void 0) { defaultValue = true; }\n return typeof arg === 'undefined' ? defaultValue : !!arg;\n };\n var stringToHtmlClass = function (input) {\n if (typeof input === 'string') {\n // eslint-disable-next-line no-param-reassign\n input = input.split(' ').filter(function (s) { return s.length; });\n }\n if (Array.isArray(input) && input.length) {\n return input;\n }\n return undefined;\n };\n var mapInputToChoice = function (value, allowGroup, allowRawString) {\n if (allowRawString === void 0) { allowRawString = true; }\n if (typeof value === 'string') {\n var sanitisedValue = sanitise(value);\n var userValue = allowRawString || sanitisedValue === value ? value : { escaped: sanitisedValue, raw: value };\n var result_1 = mapInputToChoice({\n value: value,\n label: userValue,\n selected: true,\n }, false);\n return result_1;\n }\n var groupOrChoice = value;\n if ('choices' in groupOrChoice) {\n if (!allowGroup) {\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup\n throw new TypeError(\"optGroup is not allowed\");\n }\n var group = groupOrChoice;\n var choices = group.choices.map(function (e) { return mapInputToChoice(e, false); });\n var result_2 = {\n id: 0, // actual ID will be assigned during _addGroup\n label: unwrapStringForRaw(group.label) || group.value,\n active: !!choices.length,\n disabled: !!group.disabled,\n choices: choices,\n };\n return result_2;\n }\n var choice = groupOrChoice;\n var result = {\n id: 0, // actual ID will be assigned during _addChoice\n group: null, // actual group will be assigned during _addGroup but before _addChoice\n score: 0, // used in search\n rank: 0, // used in search, stable sort order\n value: choice.value,\n label: choice.label || choice.value,\n active: coerceBool(choice.active),\n selected: coerceBool(choice.selected, false),\n disabled: coerceBool(choice.disabled, false),\n placeholder: coerceBool(choice.placeholder, false),\n highlighted: false,\n labelClass: stringToHtmlClass(choice.labelClass),\n labelDescription: choice.labelDescription,\n customProperties: choice.customProperties,\n };\n return result;\n };\n\n var isHtmlInputElement = function (e) { return e.tagName === 'INPUT'; };\n var isHtmlSelectElement = function (e) { return e.tagName === 'SELECT'; };\n var isHtmlOption = function (e) { return e.tagName === 'OPTION'; };\n var isHtmlOptgroup = function (e) { return e.tagName === 'OPTGROUP'; };\n\n var WrappedSelect = /** @class */ (function (_super) {\n __extends(WrappedSelect, _super);\n function WrappedSelect(_a) {\n var element = _a.element, classNames = _a.classNames, template = _a.template, extractPlaceholder = _a.extractPlaceholder;\n var _this = _super.call(this, { element: element, classNames: classNames }) || this;\n _this.template = template;\n _this.extractPlaceholder = extractPlaceholder;\n return _this;\n }\n Object.defineProperty(WrappedSelect.prototype, \"placeholderOption\", {\n get: function () {\n return (this.element.querySelector('option[value=\"\"]') ||\n // Backward compatibility layer for the non-standard placeholder attribute supported in older versions.\n this.element.querySelector('option[placeholder]'));\n },\n enumerable: false,\n configurable: true\n });\n WrappedSelect.prototype.addOptions = function (choices) {\n var _this = this;\n var fragment = document.createDocumentFragment();\n choices.forEach(function (obj) {\n var choice = obj;\n if (choice.element) {\n return;\n }\n var option = _this.template(choice);\n fragment.appendChild(option);\n choice.element = option;\n });\n this.element.appendChild(fragment);\n };\n WrappedSelect.prototype.optionsAsChoices = function () {\n var _this = this;\n var choices = [];\n this.element.querySelectorAll(':scope > option, :scope > optgroup').forEach(function (e) {\n if (isHtmlOption(e)) {\n choices.push(_this._optionToChoice(e));\n }\n else if (isHtmlOptgroup(e)) {\n choices.push(_this._optgroupToChoice(e));\n }\n // todo: hr as empty optgroup, requires displaying empty opt-groups to be useful\n });\n return choices;\n };\n // eslint-disable-next-line class-methods-use-this\n WrappedSelect.prototype._optionToChoice = function (option) {\n // option.value returns the label if there is no value attribute, which can break legacy placeholder attribute support\n if (!option.hasAttribute('value') && option.hasAttribute('placeholder')) {\n option.setAttribute('value', '');\n option.value = '';\n }\n return {\n id: 0,\n group: null,\n score: 0,\n rank: 0,\n value: option.value,\n label: option.innerText, // HTML options do not support most html tags, but innerHtml will extract html comments...\n element: option,\n active: true,\n // this returns true if nothing is selected on initial load, which will break placeholder support\n selected: this.extractPlaceholder ? option.selected : option.hasAttribute('selected'),\n disabled: option.disabled,\n highlighted: false,\n placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')),\n labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined,\n labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined,\n customProperties: parseCustomProperties(option.dataset.customProperties),\n };\n };\n WrappedSelect.prototype._optgroupToChoice = function (optgroup) {\n var _this = this;\n var options = optgroup.querySelectorAll('option');\n var choices = Array.from(options).map(function (option) { return _this._optionToChoice(option); });\n return {\n id: 0,\n label: optgroup.label || '',\n element: optgroup,\n active: !!choices.length,\n disabled: optgroup.disabled,\n choices: choices,\n };\n };\n return WrappedSelect;\n }(WrappedElement));\n\n var DEFAULT_CLASSNAMES = {\n containerOuter: ['choices'],\n containerInner: ['choices__inner'],\n input: ['choices__input'],\n inputCloned: ['choices__input--cloned'],\n list: ['choices__list'],\n listItems: ['choices__list--multiple'],\n listSingle: ['choices__list--single'],\n listDropdown: ['choices__list--dropdown'],\n item: ['choices__item'],\n itemSelectable: ['choices__item--selectable'],\n itemDisabled: ['choices__item--disabled'],\n itemChoice: ['choices__item--choice'],\n description: ['choices__description'],\n placeholder: ['choices__placeholder'],\n group: ['choices__group'],\n groupHeading: ['choices__heading'],\n button: ['choices__button'],\n activeState: ['is-active'],\n focusState: ['is-focused'],\n openState: ['is-open'],\n disabledState: ['is-disabled'],\n highlightedState: ['is-highlighted'],\n selectedState: ['is-selected'],\n flippedState: ['is-flipped'],\n loadingState: ['is-loading'],\n notice: ['choices__notice'],\n addChoice: ['choices__item--selectable', 'add-choice'],\n noResults: ['has-no-results'],\n noChoices: ['has-no-choices'],\n };\n var DEFAULT_CONFIG = {\n items: [],\n choices: [],\n silent: false,\n renderChoiceLimit: -1,\n maxItemCount: -1,\n closeDropdownOnSelect: 'auto',\n singleModeForMultiSelect: false,\n addChoices: false,\n addItems: true,\n addItemFilter: function (value) { return !!value && value !== ''; },\n removeItems: true,\n removeItemButton: false,\n removeItemButtonAlignLeft: false,\n editItems: false,\n allowHTML: false,\n allowHtmlUserInput: false,\n duplicateItemsAllowed: true,\n delimiter: ',',\n paste: true,\n searchEnabled: true,\n searchChoices: true,\n searchFloor: 1,\n searchResultLimit: 4,\n searchFields: ['label', 'value'],\n position: 'auto',\n resetScrollPosition: true,\n shouldSort: true,\n shouldSortItems: false,\n sorter: sortByAlpha,\n shadowRoot: null,\n placeholder: true,\n placeholderValue: null,\n searchPlaceholderValue: null,\n prependValue: null,\n appendValue: null,\n renderSelectedChoices: 'auto',\n loadingText: 'Loading...',\n noResultsText: 'No results found',\n noChoicesText: 'No choices to choose from',\n itemSelectText: 'Press to select',\n uniqueItemText: 'Only unique values can be added',\n customAddItemText: 'Only values matching specific conditions can be added',\n addItemText: function (value) { return \"Press Enter to add <b>\\\"\".concat(value, \"\\\"</b>\"); },\n removeItemIconText: function () { return \"Remove item\"; },\n removeItemLabelText: function (value) { return \"Remove item: \".concat(value); },\n maxItemText: function (maxItemCount) { return \"Only \".concat(maxItemCount, \" values can be added\"); },\n valueComparer: function (value1, value2) { return value1 === value2; },\n fuseOptions: {\n includeScore: true,\n },\n labelId: '',\n callbackOnInit: null,\n callbackOnCreateTemplates: null,\n classNames: DEFAULT_CLASSNAMES,\n appendGroupInSearch: false,\n };\n\n var removeItem = function (item) {\n var itemEl = item.itemEl;\n if (itemEl) {\n itemEl.remove();\n item.itemEl = undefined;\n }\n };\n function items(s, action, context) {\n var state = s;\n var update = true;\n switch (action.type) {\n case ActionType.ADD_ITEM: {\n action.item.selected = true;\n var el = action.item.element;\n if (el) {\n el.selected = true;\n el.setAttribute('selected', '');\n }\n state.push(action.item);\n break;\n }\n case ActionType.REMOVE_ITEM: {\n action.item.selected = false;\n var el = action.item.element;\n if (el) {\n el.selected = false;\n el.removeAttribute('selected');\n // For a select-one, if all options are deselected, the first item is selected. To set a black value, select.value needs to be set\n var select = el.parentElement;\n if (select && isHtmlSelectElement(select) && select.type === PassedElementTypes.SelectOne) {\n select.value = '';\n }\n }\n // this is mixing concerns, but this is *so much faster*\n removeItem(action.item);\n state = state.filter(function (choice) { return choice.id !== action.item.id; });\n break;\n }\n case ActionType.REMOVE_CHOICE: {\n removeItem(action.choice);\n state = state.filter(function (item) { return item.id !== action.choice.id; });\n break;\n }\n case ActionType.HIGHLIGHT_ITEM: {\n var highlighted = action.highlighted;\n var item = state.find(function (obj) { return obj.id === action.item.id; });\n if (item && item.highlighted !== highlighted) {\n item.highlighted = highlighted;\n if (context) {\n updateClassList(item, highlighted ? context.classNames.highlightedState : context.classNames.selectedState, highlighted ? context.classNames.selectedState : context.classNames.highlightedState);\n }\n }\n break;\n }\n default: {\n update = false;\n break;\n }\n }\n return { state: state, update: update };\n }\n\n function groups(s, action) {\n var state = s;\n var update = true;\n switch (action.type) {\n case ActionType.ADD_GROUP: {\n state.push(action.group);\n break;\n }\n case ActionType.CLEAR_CHOICES: {\n state = [];\n break;\n }\n default: {\n update = false;\n break;\n }\n }\n return { state: state, update: update };\n }\n\n /* eslint-disable */\n function choices(s, action, context) {\n var state = s;\n var update = true;\n switch (action.type) {\n case ActionType.ADD_CHOICE: {\n state.push(action.choice);\n break;\n }\n case ActionType.REMOVE_CHOICE: {\n action.choice.choiceEl = undefined;\n if (action.choice.group) {\n action.choice.group.choices = action.choice.group.choices.filter(function (obj) { return obj.id !== action.choice.id; });\n }\n state = state.filter(function (obj) { return obj.id !== action.choice.id; });\n break;\n }\n case ActionType.ADD_ITEM:\n case ActionType.REMOVE_ITEM: {\n action.item.choiceEl = undefined;\n break;\n }\n case ActionType.FILTER_CHOICES: {\n // avoid O(n^2) algorithm complexity when searching/filtering choices\n var scoreLookup_1 = [];\n action.results.forEach(function (result) {\n scoreLookup_1[result.item.id] = result;\n });\n state.forEach(function (choice) {\n var result = scoreLookup_1[choice.id];\n if (result !== undefined) {\n choice.score = result.score;\n choice.rank = result.rank;\n choice.active = true;\n }\n else {\n choice.score = 0;\n choice.rank = 0;\n choice.active = false;\n }\n if (context && context.appendGroupInSearch) {\n choice.choiceEl = undefined;\n }\n });\n break;\n }\n case ActionType.ACTIVATE_CHOICES: {\n state.forEach(function (choice) {\n choice.active = action.active;\n if (context && context.appendGroupInSearch) {\n choice.choiceEl = undefined;\n }\n });\n break;\n }\n case ActionType.CLEAR_CHOICES: {\n state = [];\n break;\n }\n default: {\n update = false;\n break;\n }\n }\n return { state: state, update: update };\n }\n\n var reducers = {\n groups: groups,\n items: items,\n choices: choices,\n };\n var Store = /** @class */ (function () {\n function Store(context) {\n this._state = this.defaultState;\n this._listeners = [];\n this._txn = 0;\n this._context = context;\n }\n Object.defineProperty(Store.prototype, \"defaultState\", {\n // eslint-disable-next-line class-methods-use-this\n get: function () {\n return {\n groups: [],\n items: [],\n choices: [],\n };\n },\n enumerable: false,\n configurable: true\n });\n // eslint-disable-next-line class-methods-use-this\n Store.prototype.changeSet = function (init) {\n return {\n groups: init,\n items: init,\n choices: init,\n };\n };\n Store.prototype.reset = function () {\n this._state = this.defaultState;\n var changes = this.changeSet(true);\n if (this._txn) {\n this._changeSet = changes;\n }\n else {\n this._listeners.forEach(function (l) { return l(changes); });\n }\n };\n Store.prototype.subscribe = function (onChange) {\n this._listeners.push(onChange);\n return this;\n };\n Store.prototype.dispatch = function (action) {\n var _this = this;\n var state = this._state;\n var hasChanges = false;\n var changes = this._changeSet || this.changeSet(false);\n Object.keys(reducers).forEach(function (key) {\n var stateUpdate = reducers[key](state[key], action, _this._context);\n if (stateUpdate.update) {\n hasChanges = true;\n changes[key] = true;\n state[key] = stateUpdate.state;\n }\n });\n if (hasChanges) {\n if (this._txn) {\n this._changeSet = changes;\n }\n else {\n this._listeners.forEach(function (l) { return l(changes); });\n }\n }\n };\n Store.prototype.withTxn = function (func) {\n this._txn++;\n try {\n func();\n }\n finally {\n this._txn = Math.max(0, this._txn - 1);\n if (!this._txn) {\n var changeSet_1 = this._changeSet;\n if (changeSet_1) {\n this._changeSet = undefined;\n this._listeners.forEach(function (l) { return l(changeSet_1); });\n }\n }\n }\n };\n Object.defineProperty(Store.prototype, \"state\", {\n /**\n * Get store object\n */\n get: function () {\n return this._state;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"items\", {\n /**\n * Get items from store\n */\n get: function () {\n return this.state.items;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"highlightedActiveItems\", {\n /**\n * Get highlighted items from store\n */\n get: function () {\n return this.items.filter(function (item) { return item.active && item.highlighted; });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"choices\", {\n /**\n * Get choices from store\n */\n get: function () {\n return this.state.choices;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"activeChoices\", {\n /**\n * Get active choices from store\n */\n get: function () {\n return this.choices.filter(function (choice) { return choice.active; });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"searchableChoices\", {\n /**\n * Get choices that can be searched (excluding placeholders or disabled choices)\n */\n get: function () {\n return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; });\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"groups\", {\n /**\n * Get groups from store\n */\n get: function () {\n return this.state.groups;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Store.prototype, \"activeGroups\", {\n /**\n * Get active groups from store\n */\n get: function () {\n var _this = this;\n return this.state.groups.filter(function (group) {\n var isActive = group.active && !group.disabled;\n var hasActiveOptions = _this.state.choices.some(function (choice) { return choice.active && !choice.disabled; });\n return isActive && hasActiveOptions;\n }, []);\n },\n enumerable: false,\n configurable: true\n });\n Store.prototype.inTxn = function () {\n return this._txn > 0;\n };\n /**\n * Get single choice by it's ID\n */\n Store.prototype.getChoiceById = function (id) {\n return this.activeChoices.find(function (choice) { return choice.id === id; });\n };\n /**\n * Get group by group id\n */\n Store.prototype.getGroupById = function (id) {\n return this.groups.find(function (group) { return group.id === id; });\n };\n return Store;\n }());\n\n var NoticeTypes = {\n noChoices: 'no-choices',\n noResults: 'no-results',\n addChoice: 'add-choice',\n generic: '',\n };\n\n function _defineProperty(e, r, t) {\n return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {\n value: t,\n enumerable: !0,\n configurable: !0,\n writable: !0\n }) : e[r] = t, e;\n }\n function ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n }\n function _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n }\n function _toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n }\n function _toPropertyKey(t) {\n var i = _toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : i + \"\";\n }\n\n /**\n * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2023 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n function isArray(value) {\n return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value);\n }\n\n // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js\n const INFINITY = 1 / 0;\n function baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n let result = value + '';\n return result == '0' && 1 / value == -INFINITY ? '-0' : result;\n }\n function toString(value) {\n return value == null ? '' : baseToString(value);\n }\n function isString(value) {\n return typeof value === 'string';\n }\n function isNumber(value) {\n return typeof value === 'number';\n }\n\n // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js\n function isBoolean(value) {\n return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]';\n }\n function isObject(value) {\n return typeof value === 'object';\n }\n\n // Checks if `value` is object-like.\n function isObjectLike(value) {\n return isObject(value) && value !== null;\n }\n function isDefined(value) {\n return value !== undefined && value !== null;\n }\n function isBlank(value) {\n return !value.trim().length;\n }\n\n // Gets the `toStringTag` of `value`.\n // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js\n function getTag(value) {\n return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value);\n }\n const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';\n const INCORRECT_INDEX_TYPE = \"Incorrect 'index' type\";\n const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`;\n const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`;\n const MISSING_KEY_PROPERTY = name => `Missing ${name} property in key`;\n const INVALID_KEY_WEIGHT_VALUE = key => `Property 'weight' in key '${key}' must be a positive integer`;\n const hasOwn = Object.prototype.hasOwnProperty;\n class KeyStore {\n constructor(keys) {\n this._keys = [];\n this._keyMap = {};\n let totalWeight = 0;\n keys.forEach(key => {\n let obj = createKey(key);\n this._keys.push(obj);\n this._keyMap[obj.id] = obj;\n totalWeight += obj.weight;\n });\n\n // Normalize weights so that their sum is equal to 1\n this._keys.forEach(key => {\n key.weight /= totalWeight;\n });\n }\n get(keyId) {\n return this._keyMap[keyId];\n }\n keys() {\n return this._keys;\n }\n toJSON() {\n return JSON.stringify(this._keys);\n }\n }\n function createKey(key) {\n let path = null;\n let id = null;\n let src = null;\n let weight = 1;\n let getFn = null;\n if (isString(key) || isArray(key)) {\n src = key;\n path = createKeyPath(key);\n id = createKeyId(key);\n } else {\n if (!hasOwn.call(key, 'name')) {\n throw new Error(MISSING_KEY_PROPERTY('name'));\n }\n const name = key.name;\n src = name;\n if (hasOwn.call(key, 'weight')) {\n weight = key.weight;\n if (weight <= 0) {\n throw new Error(INVALID_KEY_WEIGHT_VALUE(name));\n }\n }\n path = createKeyPath(name);\n id = createKeyId(name);\n getFn = key.getFn;\n }\n return {\n path,\n id,\n weight,\n src,\n getFn\n };\n }\n function createKeyPath(key) {\n return isArray(key) ? key : key.split('.');\n }\n function createKeyId(key) {\n return isArray(key) ? key.join('.') : key;\n }\n function get(obj, path) {\n let list = [];\n let arr = false;\n const deepGet = (obj, path, index) => {\n if (!isDefined(obj)) {\n return;\n }\n if (!path[index]) {\n // If there's no path left, we've arrived at the object we care about.\n list.push(obj);\n } else {\n let key = path[index];\n const value = obj[key];\n if (!isDefined(value)) {\n return;\n }\n\n // If we're at the last value in the path, and if it's a string/number/bool,\n // add it to the list\n if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {\n list.push(toString(value));\n } else if (isArray(value)) {\n arr = true;\n // Search each item in the array.\n for (let i = 0, len = value.length; i < len; i += 1) {\n deepGet(value[i], path, index + 1);\n }\n } else if (path.length) {\n // An object. Recurse further.\n deepGet(value, path, index + 1);\n }\n }\n };\n\n // Backwards compatibility (since path used to be a string)\n deepGet(obj, isString(path) ? path.split('.') : path, 0);\n return arr ? list : list[0];\n }\n const MatchOptions = {\n // Whether the matches should be included in the result set. When `true`, each record in the result\n // set will include the indices of the matched characters.\n // These can consequently be used for highlighting purposes.\n includeMatches: false,\n // When `true`, the matching function will continue to the end of a search pattern even if\n // a perfect match has already been located in the string.\n findAllMatches: false,\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1\n };\n const BasicOptions = {\n // When `true`, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n isCaseSensitive: false,\n // When true, the matching function will continue to the end of a search pattern even if\n includeScore: false,\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n // Whether to sort the result list, by score\n shouldSort: true,\n // Default sort function: sort by ascending score, ascending index\n sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1\n };\n const FuzzyOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100\n };\n const AdvancedOptions = {\n // When `true`, it enables the use of unix-like search commands\n useExtendedSearch: false,\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: get,\n // When `true`, search will ignore `location` and `distance`, so it won't matter\n // where in the string the pattern appears.\n // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score\n ignoreLocation: false,\n // When `true`, the calculation for the relevance score (used for sorting) will\n // ignore the field-length norm.\n // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm\n ignoreFieldNorm: false,\n // The weight to determine how much field length norm effects scoring.\n fieldNormWeight: 1\n };\n var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions);\n const SPACE = /[^ ]+/g;\n\n // Field-length norm: the shorter the field, the higher the weight.\n // Set to 3 decimals to reduce index size.\n function norm(weight = 1, mantissa = 3) {\n const cache = new Map();\n const m = Math.pow(10, mantissa);\n return {\n get(value) {\n const numTokens = value.match(SPACE).length;\n if (cache.has(numTokens)) {\n return cache.get(numTokens);\n }\n\n // Default function is 1/sqrt(x), weight makes that variable\n const norm = 1 / Math.pow(numTokens, 0.5 * weight);\n\n // In place of `toFixed(mantissa)`, for faster computation\n const n = parseFloat(Math.round(norm * m) / m);\n cache.set(numTokens, n);\n return n;\n },\n clear() {\n cache.clear();\n }\n };\n }\n class FuseIndex {\n constructor({\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n this.norm = norm(fieldNormWeight, 3);\n this.getFn = getFn;\n this.isCreated = false;\n this.setIndexRecords();\n }\n setSources(docs = []) {\n this.docs = docs;\n }\n setIndexRecords(records = []) {\n this.records = records;\n }\n setKeys(keys = []) {\n this.keys = keys;\n this._keysMap = {};\n keys.forEach((key, idx) => {\n this._keysMap[key.id] = idx;\n });\n }\n create() {\n if (this.isCreated || !this.docs.length) {\n return;\n }\n this.isCreated = true;\n\n // List is Array<String>\n if (isString(this.docs[0])) {\n this.docs.forEach((doc, docIndex) => {\n this._addString(doc, docIndex);\n });\n } else {\n // List is Array<Object>\n this.docs.forEach((doc, docIndex) => {\n this._addObject(doc, docIndex);\n });\n }\n this.norm.clear();\n }\n // Adds a doc to the end of the index\n add(doc) {\n const idx = this.size();\n if (isString(doc)) {\n this._addString(doc, idx);\n } else {\n this._addObject(doc, idx);\n }\n }\n // Removes the doc at the specified index of the index\n removeAt(idx) {\n this.records.splice(idx, 1);\n\n // Change ref index of every subsquent doc\n for (let i = idx, len = this.size(); i < len; i += 1) {\n this.records[i].i -= 1;\n }\n }\n getValueForItemAtKeyId(item, keyId) {\n return item[this._keysMap[keyId]];\n }\n size() {\n return this.records.length;\n }\n _addString(doc, docIndex) {\n if (!isDefined(doc) || isBlank(doc)) {\n return;\n }\n let record = {\n v: doc,\n i: docIndex,\n n: this.norm.get(doc)\n };\n this.records.push(record);\n }\n _addObject(doc, docIndex) {\n let record = {\n i: docIndex,\n $: {}\n };\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n this.keys.forEach((key, keyIndex) => {\n let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);\n if (!isDefined(value)) {\n return;\n }\n if (isArray(value)) {\n let subRecords = [];\n const stack = [{\n nestedArrIndex: -1,\n value\n }];\n while (stack.length) {\n const {\n nestedArrIndex,\n value\n } = stack.pop();\n if (!isDefined(value)) {\n continue;\n }\n if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n i: nestedArrIndex,\n n: this.norm.get(value)\n };\n subRecords.push(subRecord);\n } else if (isArray(value)) {\n value.forEach((item, k) => {\n stack.push({\n nestedArrIndex: k,\n value: item\n });\n });\n } else ;\n }\n record.$[keyIndex] = subRecords;\n } else if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n n: this.norm.get(value)\n };\n record.$[keyIndex] = subRecord;\n }\n });\n this.records.push(record);\n }\n toJSON() {\n return {\n keys: this.keys,\n records: this.records\n };\n }\n }\n function createIndex(keys, docs, {\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n const myIndex = new FuseIndex({\n getFn,\n fieldNormWeight\n });\n myIndex.setKeys(keys.map(createKey));\n myIndex.setSources(docs);\n myIndex.create();\n return myIndex;\n }\n function parseIndex(data, {\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n const {\n keys,\n records\n } = data;\n const myIndex = new FuseIndex({\n getFn,\n fieldNormWeight\n });\n myIndex.setKeys(keys);\n myIndex.setIndexRecords(records);\n return myIndex;\n }\n function computeScore$1(pattern, {\n errors = 0,\n currentLocation = 0,\n expectedLocation = 0,\n distance = Config.distance,\n ignoreLocation = Config.ignoreLocation\n } = {}) {\n const accuracy = errors / pattern.length;\n if (ignoreLocation) {\n return accuracy;\n }\n const proximity = Math.abs(expectedLocation - currentLocation);\n if (!distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy;\n }\n return accuracy + proximity / distance;\n }\n function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {\n let indices = [];\n let start = -1;\n let end = -1;\n let i = 0;\n for (let len = matchmask.length; i < len; i += 1) {\n let match = matchmask[i];\n if (match && start === -1) {\n start = i;\n } else if (!match && start !== -1) {\n end = i - 1;\n if (end - start + 1 >= minMatchCharLength) {\n indices.push([start, end]);\n }\n start = -1;\n }\n }\n\n // (i-1 - start) + 1 => i - start\n if (matchmask[i - 1] && i - start >= minMatchCharLength) {\n indices.push([start, i - 1]);\n }\n return indices;\n }\n\n // Machine word size\n const MAX_BITS = 32;\n function search(text, pattern, patternAlphabet, {\n location = Config.location,\n distance = Config.distance,\n threshold = Config.threshold,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n includeMatches = Config.includeMatches,\n ignoreLocation = Config.ignoreLocation\n } = {}) {\n if (pattern.length > MAX_BITS) {\n throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));\n }\n const patternLen = pattern.length;\n // Set starting location at beginning text and initialize the alphabet.\n const textLen = text.length;\n // Handle the case when location > text.length\n const expectedLocation = Math.max(0, Math.min(location, textLen));\n // Highest score beyond which we give up.\n let currentThreshold = threshold;\n // Is there a nearby exact match? (speedup)\n let bestLocation = expectedLocation;\n\n // Performance: only computer matches when the minMatchCharLength > 1\n // OR if `includeMatches` is true.\n const computeMatches = minMatchCharLength > 1 || includeMatches;\n // A mask of the matches, used for building the indices\n const matchMask = computeMatches ? Array(textLen) : [];\n let index;\n\n // Get all exact matches, here for speed up\n while ((index = text.indexOf(pattern, bestLocation)) > -1) {\n let score = computeScore$1(pattern, {\n currentLocation: index,\n expectedLocation,\n distance,\n ignoreLocation\n });\n currentThreshold = Math.min(score, currentThreshold);\n bestLocation = index + patternLen;\n if (computeMatches) {\n let i = 0;\n while (i < patternLen) {\n matchMask[index + i] = 1;\n i += 1;\n }\n }\n }\n\n // Reset the best location\n bestLocation = -1;\n let lastBitArr = [];\n let finalScore = 1;\n let binMax = patternLen + textLen;\n const mask = 1 << patternLen - 1;\n for (let i = 0; i < patternLen; i += 1) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n let binMin = 0;\n let binMid = binMax;\n while (binMin < binMid) {\n const score = computeScore$1(pattern, {\n errors: i,\n currentLocation: expectedLocation + binMid,\n expectedLocation,\n distance,\n ignoreLocation\n });\n if (score <= currentThreshold) {\n binMin = binMid;\n } else {\n binMax = binMid;\n }\n binMid = Math.floor((binMax - binMin) / 2 + binMin);\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid;\n let start = Math.max(1, expectedLocation - binMid + 1);\n let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;\n\n // Initialize the bit array\n let bitArr = Array(finish + 2);\n bitArr[finish + 1] = (1 << i) - 1;\n for (let j = finish; j >= start; j -= 1) {\n let currentLocation = j - 1;\n let charMatch = patternAlphabet[text.charAt(currentLocation)];\n if (computeMatches) {\n // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)\n matchMask[currentLocation] = +!!charMatch;\n }\n\n // First pass: exact match\n bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;\n\n // Subsequent passes: fuzzy match\n if (i) {\n bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];\n }\n if (bitArr[j] & mask) {\n finalScore = computeScore$1(pattern, {\n errors: i,\n currentLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (finalScore <= currentThreshold) {\n // Indeed it is\n currentThreshold = finalScore;\n bestLocation = currentLocation;\n\n // Already passed `loc`, downhill from here on in.\n if (bestLocation <= expectedLocation) {\n break;\n }\n\n // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.\n start = Math.max(1, 2 * expectedLocation - bestLocation);\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n const score = computeScore$1(pattern, {\n errors: i + 1,\n currentLocation: expectedLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n if (score > currentThreshold) {\n break;\n }\n lastBitArr = bitArr;\n }\n const result = {\n isMatch: bestLocation >= 0,\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n score: Math.max(0.001, finalScore)\n };\n if (computeMatches) {\n const indices = convertMaskToIndices(matchMask, minMatchCharLength);\n if (!indices.length) {\n result.isMatch = false;\n } else if (includeMatches) {\n result.indices = indices;\n }\n }\n return result;\n }\n function createPatternAlphabet(pattern) {\n let mask = {};\n for (let i = 0, len = pattern.length; i < len; i += 1) {\n const char = pattern.charAt(i);\n mask[char] = (mask[char] || 0) | 1 << len - i - 1;\n }\n return mask;\n }\n class BitapSearch {\n constructor(pattern, {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreLocation = Config.ignoreLocation\n } = {}) {\n this.options = {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreLocation\n };\n this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n this.chunks = [];\n if (!this.pattern.length) {\n return;\n }\n const addChunk = (pattern, startIndex) => {\n this.chunks.push({\n pattern,\n alphabet: createPatternAlphabet(pattern),\n startIndex\n });\n };\n const len = this.pattern.length;\n if (len > MAX_BITS) {\n let i = 0;\n const remainder = len % MAX_BITS;\n const end = len - remainder;\n while (i < end) {\n addChunk(this.pattern.substr(i, MAX_BITS), i);\n i += MAX_BITS;\n }\n if (remainder) {\n const startIndex = len - MAX_BITS;\n addChunk(this.pattern.substr(startIndex), startIndex);\n }\n } else {\n addChunk(this.pattern, 0);\n }\n }\n searchIn(text) {\n const {\n isCaseSensitive,\n includeMatches\n } = this.options;\n if (!isCaseSensitive) {\n text = text.toLowerCase();\n }\n\n // Exact match\n if (this.pattern === text) {\n let result = {\n isMatch: true,\n score: 0\n };\n if (includeMatches) {\n result.indices = [[0, text.length - 1]];\n }\n return result;\n }\n\n // Otherwise, use Bitap algorithm\n const {\n location,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n ignoreLocation\n } = this.options;\n let allIndices = [];\n let totalScore = 0;\n let hasMatches = false;\n this.chunks.forEach(({\n pattern,\n alphabet,\n startIndex\n }) => {\n const {\n isMatch,\n score,\n indices\n } = search(text, pattern, alphabet, {\n location: location + startIndex,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n includeMatches,\n ignoreLocation\n });\n if (isMatch) {\n hasMatches = true;\n }\n totalScore += score;\n if (isMatch && indices) {\n allIndices = [...allIndices, ...indices];\n }\n });\n let result = {\n isMatch: hasMatches,\n score: hasMatches ? totalScore / this.chunks.length : 1\n };\n if (hasMatches && includeMatches) {\n result.indices = allIndices;\n }\n return result;\n }\n }\n class BaseMatch {\n constructor(pattern) {\n this.pattern = pattern;\n }\n static isMultiMatch(pattern) {\n return getMatch(pattern, this.multiRegex);\n }\n static isSingleMatch(pattern) {\n return getMatch(pattern, this.singleRegex);\n }\n search( /*text*/) {}\n }\n function getMatch(pattern, exp) {\n const matches = pattern.match(exp);\n return matches ? matches[1] : null;\n }\n\n // Token: 'file\n\n class ExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'exact';\n }\n static get multiRegex() {\n return /^=\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^=(.*)$/;\n }\n search(text) {\n const isMatch = text === this.pattern;\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n };\n }\n }\n\n // Token: !fire\n\n class InverseExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-exact';\n }\n static get multiRegex() {\n return /^!\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^!(.*)$/;\n }\n search(text) {\n const index = text.indexOf(this.pattern);\n const isMatch = index === -1;\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n };\n }\n }\n\n // Token: ^file\n\n class PrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'prefix-exact';\n }\n static get multiRegex() {\n return /^\\^\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^\\^(.*)$/;\n }\n search(text) {\n const isMatch = text.startsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n };\n }\n }\n\n // Token: !^fire\n\n class InversePrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-prefix-exact';\n }\n static get multiRegex() {\n return /^!\\^\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^!\\^(.*)$/;\n }\n search(text) {\n const isMatch = !text.startsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n };\n }\n }\n\n // Token: .file$\n\n class SuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'suffix-exact';\n }\n static get multiRegex() {\n return /^\"(.*)\"\\$$/;\n }\n static get singleRegex() {\n return /^(.*)\\$$/;\n }\n search(text) {\n const isMatch = text.endsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [text.length - this.pattern.length, text.length - 1]\n };\n }\n }\n\n // Token: !.file$\n\n class InverseSuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-suffix-exact';\n }\n static get multiRegex() {\n return /^!\"(.*)\"\\$$/;\n }\n static get singleRegex() {\n return /^!(.*)\\$$/;\n }\n search(text) {\n const isMatch = !text.endsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n };\n }\n }\n class FuzzyMatch extends BaseMatch {\n constructor(pattern, {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreLocation = Config.ignoreLocation\n } = {}) {\n super(pattern);\n this._bitapSearch = new BitapSearch(pattern, {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreLocation\n });\n }\n static get type() {\n return 'fuzzy';\n }\n static get multiRegex() {\n return /^\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^(.*)$/;\n }\n search(text) {\n return this._bitapSearch.searchIn(text);\n }\n }\n\n // Token: 'file\n\n class IncludeMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'include';\n }\n static get multiRegex() {\n return /^'\"(.*)\"$/;\n }\n static get singleRegex() {\n return /^'(.*)$/;\n }\n search(text) {\n let location = 0;\n let index;\n const indices = [];\n const patternLen = this.pattern.length;\n\n // Get all exact matches\n while ((index = text.indexOf(this.pattern, location)) > -1) {\n location = index + patternLen;\n indices.push([index, location - 1]);\n }\n const isMatch = !!indices.length;\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices\n };\n }\n }\n\n // ❗Order is important. DO NOT CHANGE.\n const searchers = [ExactMatch, IncludeMatch, PrefixExactMatch, InversePrefixExactMatch, InverseSuffixExactMatch, SuffixExactMatch, InverseExactMatch, FuzzyMatch];\n const searchersLen = searchers.length;\n\n // Regex to split by spaces, but keep anything in quotes together\n const SPACE_RE = / +(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/;\n const OR_TOKEN = '|';\n\n // Return a 2D array representation of the query, for simpler parsing.\n // Example:\n // \"^core go$ | rb$ | py$ xy$\" => [[\"^core\", \"go$\"], [\"rb$\"], [\"py$\", \"xy$\"]]\n function parseQuery(pattern, options = {}) {\n return pattern.split(OR_TOKEN).map(item => {\n let query = item.trim().split(SPACE_RE).filter(item => item && !!item.trim());\n let results = [];\n for (let i = 0, len = query.length; i < len; i += 1) {\n const queryItem = query[i];\n\n // 1. Handle multiple query match (i.e, once that are quoted, like `\"hello world\"`)\n let found = false;\n let idx = -1;\n while (!found && ++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isMultiMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n found = true;\n }\n }\n if (found) {\n continue;\n }\n\n // 2. Handle single query matches (i.e, once that are *not* quoted)\n idx = -1;\n while (++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isSingleMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n break;\n }\n }\n }\n return results;\n });\n }\n\n // These extended matchers can return an array of matches, as opposed\n // to a singl match\n const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);\n\n /**\n * Command-like searching\n * ======================\n *\n * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,\n * search in a given text.\n *\n * Search syntax:\n *\n * | Token | Match type | Description |\n * | ----------- | -------------------------- | -------------------------------------- |\n * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |\n * | `=scheme` | exact-match | Items that are `scheme` |\n * | `'python` | include-match | Items that include `python` |\n * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |\n * | `^java` | prefix-exact-match | Items that start with `java` |\n * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |\n * | `.js$` | suffix-exact-match | Items that end with `.js` |\n * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |\n *\n * A single pipe character acts as an OR operator. For example, the following\n * query matches entries that start with `core` and end with either`go`, `rb`,\n * or`py`.\n *\n * ```\n * ^core go$ | rb$ | py$\n * ```\n */\n class ExtendedSearch {\n constructor(pattern, {\n isCaseSensitive = Config.isCaseSensitive,\n includeMatches = Config.includeMatches,\n minMatchCharLength = Config.minMatchCharLength,\n ignoreLocation = Config.ignoreLocation,\n findAllMatches = Config.findAllMatches,\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance\n } = {}) {\n this.query = null;\n this.options = {\n isCaseSensitive,\n includeMatches,\n minMatchCharLength,\n findAllMatches,\n ignoreLocation,\n location,\n threshold,\n distance\n };\n this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n this.query = parseQuery(this.pattern, this.options);\n }\n static condition(_, options) {\n return options.useExtendedSearch;\n }\n searchIn(text) {\n const query = this.query;\n if (!query) {\n return {\n isMatch: false,\n score: 1\n };\n }\n const {\n includeMatches,\n isCaseSensitive\n } = this.options;\n text = isCaseSensitive ? text : text.toLowerCase();\n let numMatches = 0;\n let allIndices = [];\n let totalScore = 0;\n\n // ORs\n for (let i = 0, qLen = query.length; i < qLen; i += 1) {\n const searchers = query[i];\n\n // Reset indices\n allIndices.length = 0;\n numMatches = 0;\n\n // ANDs\n for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {\n const searcher = searchers[j];\n const {\n isMatch,\n indices,\n score\n } = searcher.search(text);\n if (isMatch) {\n numMatches += 1;\n totalScore += score;\n if (includeMatches) {\n const type = searcher.constructor.type;\n if (MultiMatchSet.has(type)) {\n allIndices = [...allIndices, ...indices];\n } else {\n allIndices.push(indices);\n }\n }\n } else {\n totalScore = 0;\n numMatches = 0;\n allIndices.length = 0;\n break;\n }\n }\n\n // OR condition, so if TRUE, return\n if (numMatches) {\n let result = {\n isMatch: true,\n score: totalScore / numMatches\n };\n if (includeMatches) {\n result.indices = allIndices;\n }\n return result;\n }\n }\n\n // Nothing was matched\n return {\n isMatch: false,\n score: 1\n };\n }\n }\n const registeredSearchers = [];\n function register(...args) {\n registeredSearchers.push(...args);\n }\n function createSearcher(pattern, options) {\n for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {\n let searcherClass = registeredSearchers[i];\n if (searcherClass.condition(pattern, options)) {\n return new searcherClass(pattern, options);\n }\n }\n return new BitapSearch(pattern, options);\n }\n const LogicalOperator = {\n AND: '$and',\n OR: '$or'\n };\n const KeyType = {\n PATH: '$path',\n PATTERN: '$val'\n };\n const isExpression = query => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);\n const isPath = query => !!query[KeyType.PATH];\n const isLeaf = query => !isArray(query) && isObject(query) && !isExpression(query);\n const convertToExplicit = query => ({\n [LogicalOperator.AND]: Object.keys(query).map(key => ({\n [key]: query[key]\n }))\n });\n\n // When `auto` is `true`, the parse function will infer and initialize and add\n // the appropriate `Searcher` instance\n function parse(query, options, {\n auto = true\n } = {}) {\n const next = query => {\n let keys = Object.keys(query);\n const isQueryPath = isPath(query);\n if (!isQueryPath && keys.length > 1 && !isExpression(query)) {\n return next(convertToExplicit(query));\n }\n if (isLeaf(query)) {\n const key = isQueryPath ? query[KeyType.PATH] : keys[0];\n const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key];\n if (!isString(pattern)) {\n throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));\n }\n const obj = {\n keyId: createKeyId(key),\n pattern\n };\n if (auto) {\n obj.searcher = createSearcher(pattern, options);\n }\n return obj;\n }\n let node = {\n children: [],\n operator: keys[0]\n };\n keys.forEach(key => {\n const value = query[key];\n if (isArray(value)) {\n value.forEach(item => {\n node.children.push(next(item));\n });\n }\n });\n return node;\n };\n if (!isExpression(query)) {\n query = convertToExplicit(query);\n }\n return next(query);\n }\n\n // Practical scoring function\n function computeScore(results, {\n ignoreFieldNorm = Config.ignoreFieldNorm\n }) {\n results.forEach(result => {\n let totalScore = 1;\n result.matches.forEach(({\n key,\n norm,\n score\n }) => {\n const weight = key ? key.weight : null;\n totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm));\n });\n result.score = totalScore;\n });\n }\n function transformMatches(result, data) {\n const matches = result.matches;\n data.matches = [];\n if (!isDefined(matches)) {\n return;\n }\n matches.forEach(match => {\n if (!isDefined(match.indices) || !match.indices.length) {\n return;\n }\n const {\n indices,\n value\n } = match;\n let obj = {\n indices,\n value\n };\n if (match.key) {\n obj.key = match.key.src;\n }\n if (match.idx > -1) {\n obj.refIndex = match.idx;\n }\n data.matches.push(obj);\n });\n }\n function transformScore(result, data) {\n data.score = result.score;\n }\n function format(results, docs, {\n includeMatches = Config.includeMatches,\n includeScore = Config.includeScore\n } = {}) {\n const transformers = [];\n if (includeMatches) transformers.push(transformMatches);\n if (includeScore) transformers.push(transformScore);\n return results.map(result => {\n const {\n idx\n } = result;\n const data = {\n item: docs[idx],\n refIndex: idx\n };\n if (transformers.length) {\n transformers.forEach(transformer => {\n transformer(result, data);\n });\n }\n return data;\n });\n }\n class Fuse {\n constructor(docs, options = {}, index) {\n this.options = _objectSpread2(_objectSpread2({}, Config), options);\n if (this.options.useExtendedSearch && !true) {}\n this._keyStore = new KeyStore(this.options.keys);\n this.setCollection(docs, index);\n }\n setCollection(docs, index) {\n this._docs = docs;\n if (index && !(index instanceof FuseIndex)) {\n throw new Error(INCORRECT_INDEX_TYPE);\n }\n this._myIndex = index || createIndex(this.options.keys, this._docs, {\n getFn: this.options.getFn,\n fieldNormWeight: this.options.fieldNormWeight\n });\n }\n add(doc) {\n if (!isDefined(doc)) {\n return;\n }\n this._docs.push(doc);\n this._myIndex.add(doc);\n }\n remove(predicate = ( /* doc, idx */) => false) {\n const results = [];\n for (let i = 0, len = this._docs.length; i < len; i += 1) {\n const doc = this._docs[i];\n if (predicate(doc, i)) {\n this.removeAt(i);\n i -= 1;\n len -= 1;\n results.push(doc);\n }\n }\n return results;\n }\n removeAt(idx) {\n this._docs.splice(idx, 1);\n this._myIndex.removeAt(idx);\n }\n getIndex() {\n return this._myIndex;\n }\n search(query, {\n limit = -1\n } = {}) {\n const {\n includeMatches,\n includeScore,\n shouldSort,\n sortFn,\n ignoreFieldNorm\n } = this.options;\n let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);\n computeScore(results, {\n ignoreFieldNorm\n });\n if (shouldSort) {\n results.sort(sortFn);\n }\n if (isNumber(limit) && limit > -1) {\n results = results.slice(0, limit);\n }\n return format(results, this._docs, {\n includeMatches,\n includeScore\n });\n }\n _searchStringList(query) {\n const searcher = createSearcher(query, this.options);\n const {\n records\n } = this._myIndex;\n const results = [];\n\n // Iterate over every string in the index\n records.forEach(({\n v: text,\n i: idx,\n n: norm\n }) => {\n if (!isDefined(text)) {\n return;\n }\n const {\n isMatch,\n score,\n indices\n } = searcher.searchIn(text);\n if (isMatch) {\n results.push({\n item: text,\n idx,\n matches: [{\n score,\n value: text,\n norm,\n indices\n }]\n });\n }\n });\n return results;\n }\n _searchLogical(query) {\n const expression = parse(query, this.options);\n const evaluate = (node, item, idx) => {\n if (!node.children) {\n const {\n keyId,\n searcher\n } = node;\n const matches = this._findMatches({\n key: this._keyStore.get(keyId),\n value: this._myIndex.getValueForItemAtKeyId(item, keyId),\n searcher\n });\n if (matches && matches.length) {\n return [{\n idx,\n item,\n matches\n }];\n }\n return [];\n }\n const res = [];\n for (let i = 0, len = node.children.length; i < len; i += 1) {\n const child = node.children[i];\n const result = evaluate(child, item, idx);\n if (result.length) {\n res.push(...result);\n } else if (node.operator === LogicalOperator.AND) {\n return [];\n }\n }\n return res;\n };\n const records = this._myIndex.records;\n const resultMap = {};\n const results = [];\n records.forEach(({\n $: item,\n i: idx\n }) => {\n if (isDefined(item)) {\n let expResults = evaluate(expression, item, idx);\n if (expResults.length) {\n // Dedupe when adding\n if (!resultMap[idx]) {\n resultMap[idx] = {\n idx,\n item,\n matches: []\n };\n results.push(resultMap[idx]);\n }\n expResults.forEach(({\n matches\n }) => {\n resultMap[idx].matches.push(...matches);\n });\n }\n }\n });\n return results;\n }\n _searchObjectList(query) {\n const searcher = createSearcher(query, this.options);\n const {\n keys,\n records\n } = this._myIndex;\n const results = [];\n\n // List is Array<Object>\n records.forEach(({\n $: item,\n i: idx\n }) => {\n if (!isDefined(item)) {\n return;\n }\n let matches = [];\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n keys.forEach((key, keyIndex) => {\n matches.push(...this._findMatches({\n key,\n value: item[keyIndex],\n searcher\n }));\n });\n if (matches.length) {\n results.push({\n idx,\n item,\n matches\n });\n }\n });\n return results;\n }\n _findMatches({\n key,\n value,\n searcher\n }) {\n if (!isDefined(value)) {\n return [];\n }\n let matches = [];\n if (isArray(value)) {\n value.forEach(({\n v: text,\n i: idx,\n n: norm\n }) => {\n if (!isDefined(text)) {\n return;\n }\n const {\n isMatch,\n score,\n indices\n } = searcher.searchIn(text);\n if (isMatch) {\n matches.push({\n score,\n key,\n value: text,\n idx,\n norm,\n indices\n });\n }\n });\n } else {\n const {\n v: text,\n n: norm\n } = value;\n const {\n isMatch,\n score,\n indices\n } = searcher.searchIn(text);\n if (isMatch) {\n matches.push({\n score,\n key,\n value: text,\n norm,\n indices\n });\n }\n }\n return matches;\n }\n }\n Fuse.version = '7.0.0';\n Fuse.createIndex = createIndex;\n Fuse.parseIndex = parseIndex;\n Fuse.config = Config;\n {\n Fuse.parseQuery = parse;\n }\n {\n register(ExtendedSearch);\n }\n\n var SearchByFuse = /** @class */ (function () {\n function SearchByFuse(config) {\n this._haystack = [];\n this._fuseOptions = __assign(__assign({}, config.fuseOptions), { keys: __spreadArray([], config.searchFields, true), includeMatches: true });\n }\n SearchByFuse.prototype.index = function (data) {\n this._haystack = data;\n if (this._fuse) {\n this._fuse.setCollection(data);\n }\n };\n SearchByFuse.prototype.reset = function () {\n this._haystack = [];\n this._fuse = undefined;\n };\n SearchByFuse.prototype.isEmptyIndex = function () {\n return !this._haystack.length;\n };\n SearchByFuse.prototype.search = function (needle) {\n if (!this._fuse) {\n {\n this._fuse = new Fuse(this._haystack, this._fuseOptions);\n }\n }\n var results = this._fuse.search(needle);\n return results.map(function (value, i) {\n return {\n item: value.item,\n score: value.score || 0,\n rank: i + 1, // If value.score is used for sorting, this can create non-stable sorts!\n };\n });\n };\n return SearchByFuse;\n }());\n\n function getSearcher(config) {\n {\n return new SearchByFuse(config);\n }\n }\n\n /**\n * Helpers to create HTML elements used by Choices\n * Can be overridden by providing `callbackOnCreateTemplates` option.\n * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates`\n */\n var isEmptyObject = function (obj) {\n // eslint-disable-next-line no-restricted-syntax\n for (var prop in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n return false;\n }\n }\n return true;\n };\n var assignCustomProperties = function (el, choice, withCustomProperties) {\n var dataset = el.dataset;\n var customProperties = choice.customProperties, labelClass = choice.labelClass, labelDescription = choice.labelDescription;\n if (labelClass) {\n dataset.labelClass = getClassNames(labelClass).join(' ');\n }\n if (labelDescription) {\n dataset.labelDescription = labelDescription;\n }\n if (withCustomProperties && customProperties) {\n if (typeof customProperties === 'string') {\n dataset.customProperties = customProperties;\n }\n else if (typeof customProperties === 'object' && !isEmptyObject(customProperties)) {\n dataset.customProperties = JSON.stringify(customProperties);\n }\n }\n };\n var addAriaLabel = function (docRoot, id, element) {\n var label = id && docRoot.querySelector(\"label[for='\".concat(id, \"']\"));\n var text = label && label.innerText;\n if (text) {\n element.setAttribute('aria-label', text);\n }\n };\n var templates = {\n containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) {\n var containerOuter = _a.classNames.containerOuter;\n var div = document.createElement('div');\n addClassesToElement(div, containerOuter);\n div.dataset.type = passedElementType;\n if (dir) {\n div.dir = dir;\n }\n if (isSelectOneElement) {\n div.tabIndex = 0;\n }\n if (isSelectElement) {\n div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox');\n if (searchEnabled) {\n div.setAttribute('aria-autocomplete', 'list');\n }\n else if (!labelId) {\n addAriaLabel(this._docRoot, this.passedElement.element.id, div);\n }\n div.setAttribute('aria-haspopup', 'true');\n div.setAttribute('aria-expanded', 'false');\n }\n if (labelId) {\n div.setAttribute('aria-labelledby', labelId);\n }\n return div;\n },\n containerInner: function (_a) {\n var containerInner = _a.classNames.containerInner;\n var div = document.createElement('div');\n addClassesToElement(div, containerInner);\n return div;\n },\n itemList: function (_a, isSelectOneElement) {\n var searchEnabled = _a.searchEnabled, _b = _a.classNames, list = _b.list, listSingle = _b.listSingle, listItems = _b.listItems;\n var div = document.createElement('div');\n addClassesToElement(div, list);\n addClassesToElement(div, isSelectOneElement ? listSingle : listItems);\n if (this._isSelectElement && searchEnabled) {\n div.setAttribute('role', 'listbox');\n }\n return div;\n },\n placeholder: function (_a, value) {\n var allowHTML = _a.allowHTML, placeholder = _a.classNames.placeholder;\n var div = document.createElement('div');\n addClassesToElement(div, placeholder);\n setElementHtml(div, allowHTML, value);\n return div;\n },\n item: function (_a, choice, removeItemButton) {\n var allowHTML = _a.allowHTML, removeItemButtonAlignLeft = _a.removeItemButtonAlignLeft, removeItemIconText = _a.removeItemIconText, removeItemLabelText = _a.removeItemLabelText, _b = _a.classNames, item = _b.item, button = _b.button, highlightedState = _b.highlightedState, itemSelectable = _b.itemSelectable, placeholder = _b.placeholder;\n var rawValue = unwrapStringForRaw(choice.value);\n var div = document.createElement('div');\n addClassesToElement(div, item);\n if (choice.labelClass) {\n var spanLabel = document.createElement('span');\n setElementHtml(spanLabel, allowHTML, choice.label);\n addClassesToElement(spanLabel, choice.labelClass);\n div.appendChild(spanLabel);\n }\n else {\n setElementHtml(div, allowHTML, choice.label);\n }\n div.dataset.item = '';\n div.dataset.id = choice.id;\n div.dataset.value = rawValue;\n assignCustomProperties(div, choice, true);\n if (choice.disabled || this.containerOuter.isDisabled) {\n div.setAttribute('aria-disabled', 'true');\n }\n if (this._isSelectElement) {\n div.setAttribute('aria-selected', 'true');\n div.setAttribute('role', 'option');\n }\n if (choice.placeholder) {\n addClassesToElement(div, placeholder);\n div.dataset.placeholder = '';\n }\n addClassesToElement(div, choice.highlighted ? highlightedState : itemSelectable);\n if (removeItemButton) {\n if (choice.disabled) {\n removeClassesFromElement(div, itemSelectable);\n }\n div.dataset.deletable = '';\n var removeButton = document.createElement('button');\n removeButton.type = 'button';\n addClassesToElement(removeButton, button);\n setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value));\n var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value);\n if (REMOVE_ITEM_LABEL) {\n removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL);\n }\n removeButton.dataset.button = '';\n if (removeItemButtonAlignLeft) {\n div.insertAdjacentElement('afterbegin', removeButton);\n }\n else {\n div.appendChild(removeButton);\n }\n }\n return div;\n },\n choiceList: function (_a, isSelectOneElement) {\n var list = _a.classNames.list;\n var div = document.createElement('div');\n addClassesToElement(div, list);\n if (!isSelectOneElement) {\n div.setAttribute('aria-multiselectable', 'true');\n }\n div.setAttribute('role', 'listbox');\n return div;\n },\n choiceGroup: function (_a, _b) {\n var allowHTML = _a.allowHTML, _c = _a.classNames, group = _c.group, groupHeading = _c.groupHeading, itemDisabled = _c.itemDisabled;\n var id = _b.id, label = _b.label, disabled = _b.disabled;\n var rawLabel = unwrapStringForRaw(label);\n var div = document.createElement('div');\n addClassesToElement(div, group);\n if (disabled) {\n addClassesToElement(div, itemDisabled);\n }\n div.setAttribute('role', 'group');\n div.dataset.group = '';\n div.dataset.id = id;\n div.dataset.value = rawLabel;\n if (disabled) {\n div.setAttribute('aria-disabled', 'true');\n }\n var heading = document.createElement('div');\n addClassesToElement(heading, groupHeading);\n setElementHtml(heading, allowHTML, label || '');\n div.appendChild(heading);\n return div;\n },\n choice: function (_a, choice, selectText, groupName) {\n var allowHTML = _a.allowHTML, _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, itemSelectable = _b.itemSelectable, selectedState = _b.selectedState, itemDisabled = _b.itemDisabled, description = _b.description, placeholder = _b.placeholder;\n // eslint-disable-next-line prefer-destructuring\n var label = choice.label;\n var rawValue = unwrapStringForRaw(choice.value);\n var div = document.createElement('div');\n div.id = choice.elementId;\n addClassesToElement(div, item);\n addClassesToElement(div, itemChoice);\n if (groupName && typeof label === 'string') {\n label = escapeForTemplate(allowHTML, label);\n label += \" (\".concat(groupName, \")\");\n label = { trusted: label };\n }\n var describedBy = div;\n if (choice.labelClass) {\n var spanLabel = document.createElement('span');\n setElementHtml(spanLabel, allowHTML, label);\n addClassesToElement(spanLabel, choice.labelClass);\n describedBy = spanLabel;\n div.appendChild(spanLabel);\n }\n else {\n setElementHtml(div, allowHTML, label);\n }\n if (choice.labelDescription) {\n var descId = \"\".concat(choice.elementId, \"-description\");\n describedBy.setAttribute('aria-describedby', descId);\n var spanDesc = document.createElement('span');\n setElementHtml(spanDesc, allowHTML, choice.labelDescription);\n spanDesc.id = descId;\n addClassesToElement(spanDesc, description);\n div.appendChild(spanDesc);\n }\n if (choice.selected) {\n addClassesToElement(div, selectedState);\n }\n if (choice.placeholder) {\n addClassesToElement(div, placeholder);\n }\n div.setAttribute('role', choice.group ? 'treeitem' : 'option');\n div.dataset.choice = '';\n div.dataset.id = choice.id;\n div.dataset.value = rawValue;\n if (selectText) {\n div.dataset.selectText = selectText;\n }\n if (choice.group) {\n div.dataset.groupId = \"\".concat(choice.group.id);\n }\n assignCustomProperties(div, choice, false);\n if (choice.disabled) {\n addClassesToElement(div, itemDisabled);\n div.dataset.choiceDisabled = '';\n div.setAttribute('aria-disabled', 'true');\n }\n else {\n addClassesToElement(div, itemSelectable);\n div.dataset.choiceSelectable = '';\n }\n return div;\n },\n input: function (_a, placeholderValue) {\n var _b = _a.classNames, input = _b.input, inputCloned = _b.inputCloned, labelId = _a.labelId;\n var inp = document.createElement('input');\n inp.type = 'search';\n addClassesToElement(inp, input);\n addClassesToElement(inp, inputCloned);\n inp.autocomplete = 'off';\n inp.autocapitalize = 'off';\n inp.spellcheck = false;\n inp.setAttribute('role', 'textbox');\n inp.setAttribute('aria-autocomplete', 'list');\n if (placeholderValue) {\n inp.setAttribute('aria-label', placeholderValue);\n }\n else if (!labelId) {\n addAriaLabel(this._docRoot, this.passedElement.element.id, inp);\n }\n return inp;\n },\n dropdown: function (_a) {\n var _b = _a.classNames, list = _b.list, listDropdown = _b.listDropdown;\n var div = document.createElement('div');\n addClassesToElement(div, list);\n addClassesToElement(div, listDropdown);\n div.setAttribute('aria-expanded', 'false');\n return div;\n },\n notice: function (_a, innerHTML, type) {\n var _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, addChoice = _b.addChoice, noResults = _b.noResults, noChoices = _b.noChoices, noticeItem = _b.notice;\n if (type === void 0) { type = NoticeTypes.generic; }\n var notice = document.createElement('div');\n setElementHtml(notice, true, innerHTML);\n addClassesToElement(notice, item);\n addClassesToElement(notice, itemChoice);\n addClassesToElement(notice, noticeItem);\n // eslint-disable-next-line default-case\n switch (type) {\n case NoticeTypes.addChoice:\n addClassesToElement(notice, addChoice);\n break;\n case NoticeTypes.noResults:\n addClassesToElement(notice, noResults);\n break;\n case NoticeTypes.noChoices:\n addClassesToElement(notice, noChoices);\n break;\n }\n if (type === NoticeTypes.addChoice) {\n notice.dataset.choiceSelectable = '';\n notice.dataset.choice = '';\n }\n return notice;\n },\n option: function (choice) {\n // HtmlOptionElement's label value does not support HTML, so the avoid double escaping unwrap the untrusted string.\n var labelValue = unwrapStringForRaw(choice.label);\n var opt = new Option(labelValue, choice.value, false, choice.selected);\n assignCustomProperties(opt, choice, true);\n opt.disabled = choice.disabled;\n if (choice.selected) {\n opt.setAttribute('selected', '');\n }\n return opt;\n },\n };\n\n /** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */\n var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style &&\n '-ms-ime-align' in document.documentElement.style;\n var USER_DEFAULTS = {};\n var parseDataSetId = function (element) {\n if (!element) {\n return undefined;\n }\n return element.dataset.id ? parseInt(element.dataset.id, 10) : undefined;\n };\n var selectableChoiceIdentifier = '[data-choice-selectable]';\n /**\n * Choices\n * @author Josh Johnson<josh@joshuajohnson.co.uk>\n */\n var Choices = /** @class */ (function () {\n function Choices(element, userConfig) {\n if (element === void 0) { element = '[data-choice]'; }\n if (userConfig === void 0) { userConfig = {}; }\n var _this = this;\n this.initialisedOK = undefined;\n this._hasNonChoicePlaceholder = false;\n this._lastAddedChoiceId = 0;\n this._lastAddedGroupId = 0;\n var defaults = Choices.defaults;\n this.config = __assign(__assign(__assign({}, defaults.allOptions), defaults.options), userConfig);\n ObjectsInConfig.forEach(function (key) {\n _this.config[key] = __assign(__assign(__assign({}, defaults.allOptions[key]), defaults.options[key]), userConfig[key]);\n });\n var config = this.config;\n if (!config.silent) {\n this._validateConfig();\n }\n var docRoot = config.shadowRoot || document.documentElement;\n this._docRoot = docRoot;\n var passedElement = typeof element === 'string' ? docRoot.querySelector(element) : element;\n if (!passedElement ||\n typeof passedElement !== 'object' ||\n !(isHtmlInputElement(passedElement) || isHtmlSelectElement(passedElement))) {\n if (!passedElement && typeof element === 'string') {\n throw TypeError(\"Selector \".concat(element, \" failed to find an element\"));\n }\n throw TypeError(\"Expected one of the following types text|select-one|select-multiple\");\n }\n var elementType = passedElement.type;\n var isText = elementType === PassedElementTypes.Text;\n if (isText || config.maxItemCount !== 1) {\n config.singleModeForMultiSelect = false;\n }\n if (config.singleModeForMultiSelect) {\n elementType = PassedElementTypes.SelectMultiple;\n }\n var isSelectOne = elementType === PassedElementTypes.SelectOne;\n var isSelectMultiple = elementType === PassedElementTypes.SelectMultiple;\n var isSelect = isSelectOne || isSelectMultiple;\n this._elementType = elementType;\n this._isTextElement = isText;\n this._isSelectOneElement = isSelectOne;\n this._isSelectMultipleElement = isSelectMultiple;\n this._isSelectElement = isSelectOne || isSelectMultiple;\n this._canAddUserChoices = (isText && config.addItems) || (isSelect && config.addChoices);\n if (typeof config.renderSelectedChoices !== 'boolean') {\n config.renderSelectedChoices = config.renderSelectedChoices === 'always' || isSelectOne;\n }\n if (config.closeDropdownOnSelect === 'auto') {\n config.closeDropdownOnSelect = isText || isSelectOne || config.singleModeForMultiSelect;\n }\n else {\n config.closeDropdownOnSelect = coerceBool(config.closeDropdownOnSelect);\n }\n if (config.placeholder) {\n if (config.placeholderValue) {\n this._hasNonChoicePlaceholder = true;\n }\n else if (passedElement.dataset.placeholder) {\n this._hasNonChoicePlaceholder = true;\n config.placeholderValue = passedElement.dataset.placeholder;\n }\n }\n if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') {\n var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter);\n config.addItemFilter = re.test.bind(re);\n }\n if (this._isTextElement) {\n this.passedElement = new WrappedInput({\n element: passedElement,\n classNames: config.classNames,\n });\n }\n else {\n var selectEl = passedElement;\n this.passedElement = new WrappedSelect({\n element: selectEl,\n classNames: config.classNames,\n template: function (data) { return _this._templates.option(data); },\n extractPlaceholder: config.placeholder && !this._hasNonChoicePlaceholder,\n });\n }\n this.initialised = false;\n this._store = new Store(config);\n this._currentValue = '';\n config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple;\n this._canSearch = config.searchEnabled;\n this._isScrollingOnIe = false;\n this._highlightPosition = 0;\n this._wasTap = true;\n this._placeholderValue = this._generatePlaceholderValue();\n this._baseId = generateId(passedElement, 'choices-');\n /**\n * setting direction in cases where it's explicitly set on passedElement\n * or when calculated direction is different from the document\n */\n this._direction = passedElement.dir;\n if (!this._direction) {\n var elementDirection = window.getComputedStyle(passedElement).direction;\n var documentDirection = window.getComputedStyle(document.documentElement).direction;\n if (elementDirection !== documentDirection) {\n this._direction = elementDirection;\n }\n }\n this._idNames = {\n itemChoice: 'item-choice',\n };\n this._templates = defaults.templates;\n this._render = this._render.bind(this);\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n this._onKeyUp = this._onKeyUp.bind(this);\n this._onKeyDown = this._onKeyDown.bind(this);\n this._onInput = this._onInput.bind(this);\n this._onClick = this._onClick.bind(this);\n this._onTouchMove = this._onTouchMove.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseOver = this._onMouseOver.bind(this);\n this._onFormReset = this._onFormReset.bind(this);\n this._onSelectKey = this._onSelectKey.bind(this);\n this._onEnterKey = this._onEnterKey.bind(this);\n this._onEscapeKey = this._onEscapeKey.bind(this);\n this._onDirectionKey = this._onDirectionKey.bind(this);\n this._onDeleteKey = this._onDeleteKey.bind(this);\n // If element has already been initialised with Choices, fail silently\n if (this.passedElement.isActive) {\n if (!config.silent) {\n console.warn('Trying to initialise Choices on element already initialised', { element: element });\n }\n this.initialised = true;\n this.initialisedOK = false;\n return;\n }\n // Let's go\n this.init();\n // preserve the selected item list after setup for form reset\n this._initialItems = this._store.items.map(function (choice) { return choice.value; });\n }\n Object.defineProperty(Choices, \"defaults\", {\n get: function () {\n return Object.preventExtensions({\n get options() {\n return USER_DEFAULTS;\n },\n get allOptions() {\n return DEFAULT_CONFIG;\n },\n get templates() {\n return templates;\n },\n });\n },\n enumerable: false,\n configurable: true\n });\n Choices.prototype.init = function () {\n if (this.initialised || this.initialisedOK !== undefined) {\n return;\n }\n this._searcher = getSearcher(this.config);\n this._loadChoices();\n this._createTemplates();\n this._createElements();\n this._createStructure();\n if ((this._isTextElement && !this.config.addItems) ||\n this.passedElement.element.hasAttribute('disabled') ||\n !!this.passedElement.element.closest('fieldset:disabled')) {\n this.disable();\n }\n else {\n this.enable();\n this._addEventListeners();\n }\n // should be triggered **after** disabled state to avoid additional re-draws\n this._initStore();\n this.initialised = true;\n this.initialisedOK = true;\n var callbackOnInit = this.config.callbackOnInit;\n // Run callback if it is a function\n if (typeof callbackOnInit === 'function') {\n callbackOnInit.call(this);\n }\n };\n Choices.prototype.destroy = function () {\n if (!this.initialised) {\n return;\n }\n this._removeEventListeners();\n this.passedElement.reveal();\n this.containerOuter.unwrap(this.passedElement.element);\n this._store._listeners = []; // prevents select/input value being wiped\n this.clearStore(false);\n this._stopSearch();\n this._templates = Choices.defaults.templates;\n this.initialised = false;\n this.initialisedOK = undefined;\n };\n Choices.prototype.enable = function () {\n if (this.passedElement.isDisabled) {\n this.passedElement.enable();\n }\n if (this.containerOuter.isDisabled) {\n this._addEventListeners();\n this.input.enable();\n this.containerOuter.enable();\n }\n return this;\n };\n Choices.prototype.disable = function () {\n if (!this.passedElement.isDisabled) {\n this.passedElement.disable();\n }\n if (!this.containerOuter.isDisabled) {\n this._removeEventListeners();\n this.input.disable();\n this.containerOuter.disable();\n }\n return this;\n };\n Choices.prototype.highlightItem = function (item, runEvent) {\n if (runEvent === void 0) { runEvent = true; }\n if (!item || !item.id) {\n return this;\n }\n var choice = this._store.items.find(function (c) { return c.id === item.id; });\n if (!choice || choice.highlighted) {\n return this;\n }\n this._store.dispatch(highlightItem(choice, true));\n if (runEvent) {\n this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice));\n }\n return this;\n };\n Choices.prototype.unhighlightItem = function (item, runEvent) {\n if (runEvent === void 0) { runEvent = true; }\n if (!item || !item.id) {\n return this;\n }\n var choice = this._store.items.find(function (c) { return c.id === item.id; });\n if (!choice || !choice.highlighted) {\n return this;\n }\n this._store.dispatch(highlightItem(choice, false));\n if (runEvent) {\n this.passedElement.triggerEvent(EventType.unhighlightItem, this._getChoiceForOutput(choice));\n }\n return this;\n };\n Choices.prototype.highlightAll = function () {\n var _this = this;\n this._store.withTxn(function () {\n _this._store.items.forEach(function (item) {\n if (!item.highlighted) {\n _this._store.dispatch(highlightItem(item, true));\n _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));\n }\n });\n });\n return this;\n };\n Choices.prototype.unhighlightAll = function () {\n var _this = this;\n this._store.withTxn(function () {\n _this._store.items.forEach(function (item) {\n if (item.highlighted) {\n _this._store.dispatch(highlightItem(item, false));\n _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item));\n }\n });\n });\n return this;\n };\n Choices.prototype.removeActiveItemsByValue = function (value) {\n var _this = this;\n this._store.withTxn(function () {\n _this._store.items.filter(function (item) { return item.value === value; }).forEach(function (item) { return _this._removeItem(item); });\n });\n return this;\n };\n Choices.prototype.removeActiveItems = function (excludedId) {\n var _this = this;\n this._store.withTxn(function () {\n _this._store.items.filter(function (_a) {\n var id = _a.id;\n return id !== excludedId;\n }).forEach(function (item) { return _this._removeItem(item); });\n });\n return this;\n };\n Choices.prototype.removeHighlightedItems = function (runEvent) {\n var _this = this;\n if (runEvent === void 0) { runEvent = false; }\n this._store.withTxn(function () {\n _this._store.highlightedActiveItems.forEach(function (item) {\n _this._removeItem(item);\n // If this action was performed by the user\n // trigger the event\n if (runEvent) {\n _this._triggerChange(item.value);\n }\n });\n });\n return this;\n };\n Choices.prototype.showDropdown = function (preventInputFocus) {\n var _this = this;\n if (this.dropdown.isActive) {\n return this;\n }\n if (preventInputFocus === undefined) {\n // eslint-disable-next-line no-param-reassign\n preventInputFocus = !this._canSearch;\n }\n requestAnimationFrame(function () {\n _this.dropdown.show();\n var rect = _this.dropdown.element.getBoundingClientRect();\n _this.containerOuter.open(rect.bottom, rect.height);\n if (!preventInputFocus) {\n _this.input.focus();\n }\n _this.passedElement.triggerEvent(EventType.showDropdown);\n });\n return this;\n };\n Choices.prototype.hideDropdown = function (preventInputBlur) {\n var _this = this;\n if (!this.dropdown.isActive) {\n return this;\n }\n requestAnimationFrame(function () {\n _this.dropdown.hide();\n _this.containerOuter.close();\n if (!preventInputBlur && _this._canSearch) {\n _this.input.removeActiveDescendant();\n _this.input.blur();\n }\n _this.passedElement.triggerEvent(EventType.hideDropdown);\n });\n return this;\n };\n Choices.prototype.getValue = function (valueOnly) {\n var _this = this;\n var values = this._store.items.map(function (item) {\n return (valueOnly ? item.value : _this._getChoiceForOutput(item));\n });\n return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values;\n };\n Choices.prototype.setValue = function (items) {\n var _this = this;\n if (!this.initialisedOK) {\n this._warnChoicesInitFailed('setValue');\n return this;\n }\n this._store.withTxn(function () {\n items.forEach(function (value) {\n if (value) {\n _this._addChoice(mapInputToChoice(value, false));\n }\n });\n });\n // @todo integrate with Store\n this._searcher.reset();\n return this;\n };\n Choices.prototype.setChoiceByValue = function (value) {\n var _this = this;\n if (!this.initialisedOK) {\n this._warnChoicesInitFailed('setChoiceByValue');\n return this;\n }\n if (this._isTextElement) {\n return this;\n }\n this._store.withTxn(function () {\n // If only one value has been passed, convert to array\n var choiceValue = Array.isArray(value) ? value : [value];\n // Loop through each value and\n choiceValue.forEach(function (val) { return _this._findAndSelectChoiceByValue(val); });\n _this.unhighlightAll();\n });\n // @todo integrate with Store\n this._searcher.reset();\n return this;\n };\n /**\n * Set choices of select input via an array of objects (or function that returns array of object or promise of it),\n * a value field name and a label field name.\n * This behaves the same as passing items via the choices option but can be called after initialising Choices.\n * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.\n * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).\n *\n * **Input types affected:** select-one, select-multiple\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices([\n * {value: 'One', label: 'Label One', disabled: true},\n * {value: 'Two', label: 'Label Two', selected: true},\n * {value: 'Three', label: 'Label Three'},\n * ], 'value', 'label', false);\n * ```\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices(async () => {\n * try {\n * const items = await fetch('/items');\n * return items.json()\n * } catch(err) {\n * console.error(err)\n * }\n * });\n * ```\n *\n * @example\n * ```js\n * const example = new Choices(element);\n *\n * example.setChoices([{\n * label: 'Group one',\n * id: 1,\n * disabled: false,\n * choices: [\n * {value: 'Child One', label: 'Child One', selected: true},\n * {value: 'Child Two', label: 'Child Two', disabled: true},\n * {value: 'Child Three', label: 'Child Three'},\n * ]\n * },\n * {\n * label: 'Group two',\n * id: 2,\n * disabled: false,\n * choices: [\n * {value: 'Child Four', label: 'Child Four', disabled: true},\n * {value: 'Child Five', label: 'Child Five'},\n * {value: 'Child Six', label: 'Child Six', customProperties: {\n * description: 'Custom description about child six',\n * random: 'Another random custom property'\n * }},\n * ]\n * }], 'value', 'label', false);\n * ```\n */\n Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices, clearSearchFlag, replaceItems) {\n var _this = this;\n if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; }\n if (value === void 0) { value = 'value'; }\n if (label === void 0) { label = 'label'; }\n if (replaceChoices === void 0) { replaceChoices = false; }\n if (clearSearchFlag === void 0) { clearSearchFlag = true; }\n if (replaceItems === void 0) { replaceItems = false; }\n if (!this.initialisedOK) {\n this._warnChoicesInitFailed('setChoices');\n return this;\n }\n if (!this._isSelectElement) {\n throw new TypeError(\"setChoices can't be used with INPUT based Choices\");\n }\n if (typeof value !== 'string' || !value) {\n throw new TypeError(\"value parameter must be a name of 'value' field in passed objects\");\n }\n if (typeof choicesArrayOrFetcher === 'function') {\n // it's a choices fetcher function\n var fetcher_1 = choicesArrayOrFetcher(this);\n if (typeof Promise === 'function' && fetcher_1 instanceof Promise) {\n // that's a promise\n // eslint-disable-next-line no-promise-executor-return\n return new Promise(function (resolve) { return requestAnimationFrame(resolve); })\n .then(function () { return _this._handleLoadingState(true); })\n .then(function () { return fetcher_1; })\n .then(function (data) {\n return _this.setChoices(data, value, label, replaceChoices, clearSearchFlag, replaceItems);\n })\n .catch(function (err) {\n if (!_this.config.silent) {\n console.error(err);\n }\n })\n .then(function () { return _this._handleLoadingState(false); })\n .then(function () { return _this; });\n }\n // function returned something else than promise, let's check if it's an array of choices\n if (!Array.isArray(fetcher_1)) {\n throw new TypeError(\".setChoices first argument function must return either array of choices or Promise, got: \".concat(typeof fetcher_1));\n }\n // recursion with results, it's sync and choices were cleared already\n return this.setChoices(fetcher_1, value, label, false);\n }\n if (!Array.isArray(choicesArrayOrFetcher)) {\n throw new TypeError(\".setChoices must be called either with array of choices with a function resulting into Promise of array of choices\");\n }\n this.containerOuter.removeLoadingState();\n this._store.withTxn(function () {\n if (clearSearchFlag) {\n _this._isSearching = false;\n }\n // Clear choices if needed\n if (replaceChoices) {\n _this.clearChoices(true, replaceItems);\n }\n var isDefaultValue = value === 'value';\n var isDefaultLabel = label === 'label';\n choicesArrayOrFetcher.forEach(function (groupOrChoice) {\n if ('choices' in groupOrChoice) {\n var group = groupOrChoice;\n if (!isDefaultLabel) {\n group = __assign(__assign({}, group), { label: group[label] });\n }\n _this._addGroup(mapInputToChoice(group, true));\n }\n else {\n var choice = groupOrChoice;\n if (!isDefaultLabel || !isDefaultValue) {\n choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] });\n }\n var choiceFull = mapInputToChoice(choice, false);\n _this._addChoice(choiceFull);\n if (choiceFull.placeholder && !_this._hasNonChoicePlaceholder) {\n _this._placeholderValue = unwrapStringForEscaped(choiceFull.label);\n }\n }\n });\n _this.unhighlightAll();\n });\n // @todo integrate with Store\n this._searcher.reset();\n return this;\n };\n Choices.prototype.refresh = function (withEvents, selectFirstOption, deselectAll) {\n var _this = this;\n if (withEvents === void 0) { withEvents = false; }\n if (selectFirstOption === void 0) { selectFirstOption = false; }\n if (deselectAll === void 0) { deselectAll = false; }\n if (!this._isSelectElement) {\n if (!this.config.silent) {\n console.warn('refresh method can only be used on choices backed by a <select> element');\n }\n return this;\n }\n this._store.withTxn(function () {\n var choicesFromOptions = _this.passedElement.optionsAsChoices();\n // Build the list of items which require preserving\n var existingItems = {};\n if (!deselectAll) {\n _this._store.items.forEach(function (choice) {\n if (choice.id && choice.active && choice.selected) {\n existingItems[choice.value] = true;\n }\n });\n }\n _this.clearStore(false);\n var updateChoice = function (choice) {\n if (deselectAll) {\n _this._store.dispatch(removeItem$1(choice));\n }\n else if (existingItems[choice.value]) {\n choice.selected = true;\n }\n };\n choicesFromOptions.forEach(function (groupOrChoice) {\n if ('choices' in groupOrChoice) {\n groupOrChoice.choices.forEach(updateChoice);\n return;\n }\n updateChoice(groupOrChoice);\n });\n /* @todo only generate add events for the added options instead of all\n if (withEvents) {\n items.forEach((choice) => {\n if (existingItems[choice.value]) {\n this.passedElement.triggerEvent(\n EventType.removeItem,\n this._getChoiceForEvent(choice),\n );\n }\n });\n }\n */\n // load new choices & items\n _this._addPredefinedChoices(choicesFromOptions, selectFirstOption, withEvents);\n // re-do search if required\n if (_this._isSearching) {\n _this._searchChoices(_this.input.value);\n }\n });\n return this;\n };\n Choices.prototype.removeChoice = function (value) {\n var choice = this._store.choices.find(function (c) { return c.value === value; });\n if (!choice) {\n return this;\n }\n this._clearNotice();\n this._store.dispatch(removeChoice(choice));\n // @todo integrate with Store\n this._searcher.reset();\n if (choice.selected) {\n this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice));\n }\n return this;\n };\n Choices.prototype.clearChoices = function (clearOptions, clearItems) {\n var _this = this;\n if (clearOptions === void 0) { clearOptions = true; }\n if (clearItems === void 0) { clearItems = false; }\n if (clearOptions) {\n if (clearItems) {\n this.passedElement.element.replaceChildren('');\n }\n else {\n this.passedElement.element.querySelectorAll(':not([selected])').forEach(function (el) {\n el.remove();\n });\n }\n }\n this.itemList.element.replaceChildren('');\n this.choiceList.element.replaceChildren('');\n this._clearNotice();\n this._store.withTxn(function () {\n var items = clearItems ? [] : _this._store.items;\n _this._store.reset();\n items.forEach(function (item) {\n _this._store.dispatch(addChoice(item));\n _this._store.dispatch(addItem(item));\n });\n });\n // @todo integrate with Store\n this._searcher.reset();\n return this;\n };\n Choices.prototype.clearStore = function (clearOptions) {\n if (clearOptions === void 0) { clearOptions = true; }\n this.clearChoices(clearOptions, true);\n this._stopSearch();\n this._lastAddedChoiceId = 0;\n this._lastAddedGroupId = 0;\n return this;\n };\n Choices.prototype.clearInput = function () {\n var shouldSetInputWidth = !this._isSelectOneElement;\n this.input.clear(shouldSetInputWidth);\n this._stopSearch();\n return this;\n };\n Choices.prototype._validateConfig = function () {\n var config = this.config;\n var invalidConfigOptions = diff(config, DEFAULT_CONFIG);\n if (invalidConfigOptions.length) {\n console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', '));\n }\n if (config.allowHTML && config.allowHtmlUserInput) {\n if (config.addItems) {\n console.warn('Warning: allowHTML/allowHtmlUserInput/addItems all being true is strongly not recommended and may lead to XSS attacks');\n }\n if (config.addChoices) {\n console.warn('Warning: allowHTML/allowHtmlUserInput/addChoices all being true is strongly not recommended and may lead to XSS attacks');\n }\n }\n };\n Choices.prototype._render = function (changes) {\n if (changes === void 0) { changes = { choices: true, groups: true, items: true }; }\n if (this._store.inTxn()) {\n return;\n }\n if (this._isSelectElement) {\n if (changes.choices || changes.groups) {\n this._renderChoices();\n }\n }\n if (changes.items) {\n this._renderItems();\n }\n };\n Choices.prototype._renderChoices = function () {\n var _this = this;\n if (!this._canAddItems()) {\n return; // block rendering choices if the input limit is reached.\n }\n var _a = this, config = _a.config, isSearching = _a._isSearching;\n var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices;\n var renderLimit = 0;\n if (isSearching && config.searchResultLimit > 0) {\n renderLimit = config.searchResultLimit;\n }\n else if (config.renderChoiceLimit > 0) {\n renderLimit = config.renderChoiceLimit;\n }\n if (this._isSelectElement) {\n var backingOptions = activeChoices.filter(function (choice) { return !choice.element; });\n if (backingOptions.length) {\n this.passedElement.addOptions(backingOptions);\n }\n }\n var fragment = document.createDocumentFragment();\n var renderableChoices = function (choices) {\n return choices.filter(function (choice) {\n return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected);\n });\n };\n var selectableChoices = false;\n var renderChoices = function (choices, withinGroup, groupLabel) {\n if (isSearching) {\n // sortByRank is used to ensure stable sorting, as scores are non-unique\n // this additionally ensures fuseOptions.sortFn is not ignored\n choices.sort(sortByRank);\n }\n else if (config.shouldSort) {\n choices.sort(config.sorter);\n }\n var choiceLimit = choices.length;\n choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit;\n choiceLimit--;\n choices.every(function (choice, index) {\n // choiceEl being empty signals the contents has probably significantly changed\n var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel);\n choice.choiceEl = dropdownItem;\n fragment.appendChild(dropdownItem);\n if (isSearching || !choice.selected) {\n selectableChoices = true;\n }\n return index < choiceLimit;\n });\n };\n if (activeChoices.length) {\n if (config.resetScrollPosition) {\n requestAnimationFrame(function () { return _this.choiceList.scrollToTop(); });\n }\n if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) {\n // If we have a placeholder choice along with groups\n renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.group; }), false, undefined);\n }\n // If we have grouped options\n if (activeGroups.length && !isSearching) {\n if (config.shouldSort) {\n activeGroups.sort(config.sorter);\n }\n // render Choices without group first, regardless of sort, otherwise they won't be distinguishable\n // from the last group\n renderChoices(activeChoices.filter(function (choice) { return !choice.placeholder && !choice.group; }), false, undefined);\n activeGroups.forEach(function (group) {\n var groupChoices = renderableChoices(group.choices);\n if (groupChoices.length) {\n if (group.label) {\n var dropdownGroup = group.groupEl || _this._templates.choiceGroup(_this.config, group);\n group.groupEl = dropdownGroup;\n dropdownGroup.remove();\n fragment.appendChild(dropdownGroup);\n }\n renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined);\n }\n });\n }\n else {\n renderChoices(renderableChoices(activeChoices), false, undefined);\n }\n }\n if (!selectableChoices && (isSearching || !fragment.children.length || !config.renderSelectedChoices)) {\n if (!this._notice) {\n this._notice = {\n text: resolveStringFunction(isSearching ? config.noResultsText : config.noChoicesText),\n type: isSearching ? NoticeTypes.noResults : NoticeTypes.noChoices,\n };\n }\n fragment.replaceChildren('');\n }\n this._renderNotice(fragment);\n this.choiceList.element.replaceChildren(fragment);\n if (selectableChoices) {\n this._highlightChoice();\n }\n };\n Choices.prototype._renderItems = function () {\n var _this = this;\n var items = this._store.items || [];\n var itemList = this.itemList.element;\n var config = this.config;\n var fragment = document.createDocumentFragment();\n var itemFromList = function (item) {\n return itemList.querySelector(\"[data-item][data-id=\\\"\".concat(item.id, \"\\\"]\"));\n };\n var addItemToFragment = function (item) {\n var el = item.itemEl;\n if (el && el.parentElement) {\n return;\n }\n el = itemFromList(item) || _this._templates.item(config, item, config.removeItemButton);\n item.itemEl = el;\n fragment.appendChild(el);\n };\n // new items\n items.forEach(addItemToFragment);\n var addedItems = !!fragment.childNodes.length;\n if (this._isSelectOneElement) {\n var existingItems = itemList.children.length;\n if (addedItems || existingItems > 1) {\n var placeholder = itemList.querySelector(getClassNamesSelector(config.classNames.placeholder));\n if (placeholder) {\n placeholder.remove();\n }\n }\n else if (!addedItems && !existingItems && this._placeholderValue) {\n addedItems = true;\n addItemToFragment(mapInputToChoice({\n selected: true,\n value: '',\n label: this._placeholderValue,\n placeholder: true,\n }, false));\n }\n }\n if (addedItems) {\n itemList.append(fragment);\n if (config.shouldSortItems && !this._isSelectOneElement) {\n items.sort(config.sorter);\n // push sorting into the DOM\n items.forEach(function (item) {\n var el = itemFromList(item);\n if (el) {\n el.remove();\n fragment.append(el);\n }\n });\n itemList.append(fragment);\n }\n }\n if (this._isTextElement) {\n // Update the value of the hidden input\n this.passedElement.value = items.map(function (_a) {\n var value = _a.value;\n return value;\n }).join(config.delimiter);\n }\n };\n Choices.prototype._displayNotice = function (text, type, openDropdown) {\n if (openDropdown === void 0) { openDropdown = true; }\n var oldNotice = this._notice;\n if (oldNotice &&\n ((oldNotice.type === type && oldNotice.text === text) ||\n (oldNotice.type === NoticeTypes.addChoice &&\n (type === NoticeTypes.noResults || type === NoticeTypes.noChoices)))) {\n if (openDropdown) {\n this.showDropdown(true);\n }\n return;\n }\n this._clearNotice();\n this._notice = text\n ? {\n text: text,\n type: type,\n }\n : undefined;\n this._renderNotice();\n if (openDropdown && text) {\n this.showDropdown(true);\n }\n };\n Choices.prototype._clearNotice = function () {\n if (!this._notice) {\n return;\n }\n var noticeElement = this.choiceList.element.querySelector(getClassNamesSelector(this.config.classNames.notice));\n if (noticeElement) {\n noticeElement.remove();\n }\n this._notice = undefined;\n };\n Choices.prototype._renderNotice = function (fragment) {\n var noticeConf = this._notice;\n if (noticeConf) {\n var notice = this._templates.notice(this.config, noticeConf.text, noticeConf.type);\n if (fragment) {\n fragment.append(notice);\n }\n else {\n this.choiceList.prepend(notice);\n }\n }\n };\n // eslint-disable-next-line class-methods-use-this\n Choices.prototype._getChoiceForOutput = function (choice, keyCode) {\n return {\n id: choice.id,\n highlighted: choice.highlighted,\n labelClass: choice.labelClass,\n labelDescription: choice.labelDescription,\n customProperties: choice.customProperties,\n disabled: choice.disabled,\n active: choice.active,\n label: choice.label,\n placeholder: choice.placeholder,\n value: choice.value,\n groupValue: choice.group ? choice.group.label : undefined,\n element: choice.element,\n keyCode: keyCode,\n };\n };\n Choices.prototype._triggerChange = function (value) {\n if (value === undefined || value === null) {\n return;\n }\n this.passedElement.triggerEvent(EventType.change, {\n value: value,\n });\n };\n Choices.prototype._handleButtonAction = function (element) {\n var _this = this;\n var items = this._store.items;\n if (!items.length || !this.config.removeItems || !this.config.removeItemButton) {\n return;\n }\n var id = element && parseDataSetId(element.parentElement);\n var itemToRemove = id && items.find(function (item) { return item.id === id; });\n if (!itemToRemove) {\n return;\n }\n this._store.withTxn(function () {\n // Remove item associated with button\n _this._removeItem(itemToRemove);\n _this._triggerChange(itemToRemove.value);\n if (_this._isSelectOneElement && !_this._hasNonChoicePlaceholder) {\n var placeholderChoice = (_this.config.shouldSort ? _this._store.choices.reverse() : _this._store.choices).find(function (choice) { return choice.placeholder; });\n if (placeholderChoice) {\n _this._addItem(placeholderChoice);\n _this.unhighlightAll();\n if (placeholderChoice.value) {\n _this._triggerChange(placeholderChoice.value);\n }\n }\n }\n });\n };\n Choices.prototype._handleItemAction = function (element, hasShiftKey) {\n var _this = this;\n if (hasShiftKey === void 0) { hasShiftKey = false; }\n var items = this._store.items;\n if (!items.length || !this.config.removeItems || this._isSelectOneElement) {\n return;\n }\n var id = parseDataSetId(element);\n if (!id) {\n return;\n }\n // We only want to select one item with a click\n // so we deselect any items that aren't the target\n // unless shift is being pressed\n items.forEach(function (item) {\n if (item.id === id && !item.highlighted) {\n _this.highlightItem(item);\n }\n else if (!hasShiftKey && item.highlighted) {\n _this.unhighlightItem(item);\n }\n });\n // Focus input as without focus, a user cannot do anything with a\n // highlighted item\n this.input.focus();\n };\n Choices.prototype._handleChoiceAction = function (element) {\n var _this = this;\n // If we are clicking on an option\n var id = parseDataSetId(element);\n var choice = id && this._store.getChoiceById(id);\n if (!choice || choice.disabled) {\n return false;\n }\n var hasActiveDropdown = this.dropdown.isActive;\n if (!choice.selected) {\n if (!this._canAddItems()) {\n return true; // causes _onEnterKey to early out\n }\n this._store.withTxn(function () {\n _this._addItem(choice, true, true);\n _this.clearInput();\n _this.unhighlightAll();\n });\n this._triggerChange(choice.value);\n }\n // We want to close the dropdown if we are dealing with a single select box\n if (hasActiveDropdown && this.config.closeDropdownOnSelect) {\n this.hideDropdown(true);\n this.containerOuter.element.focus();\n }\n return true;\n };\n Choices.prototype._handleBackspace = function (items) {\n var config = this.config;\n if (!config.removeItems || !items.length) {\n return;\n }\n var lastItem = items[items.length - 1];\n var hasHighlightedItems = items.some(function (item) { return item.highlighted; });\n // If editing the last item is allowed and there are not other selected items,\n // we can edit the item value. Otherwise if we can remove items, remove all selected items\n if (config.editItems && !hasHighlightedItems && lastItem) {\n this.input.value = lastItem.value;\n this.input.setWidth();\n this._removeItem(lastItem);\n this._triggerChange(lastItem.value);\n }\n else {\n if (!hasHighlightedItems) {\n // Highlight last item if none already highlighted\n this.highlightItem(lastItem, false);\n }\n this.removeHighlightedItems(true);\n }\n };\n Choices.prototype._loadChoices = function () {\n var _a;\n var _this = this;\n var config = this.config;\n if (this._isTextElement) {\n // Assign preset items from passed object first\n this._presetChoices = config.items.map(function (e) { return mapInputToChoice(e, false); });\n // Add any values passed from attribute\n if (this.passedElement.value) {\n var elementItems = this.passedElement.value\n .split(config.delimiter)\n .map(function (e) { return mapInputToChoice(e, false, _this.config.allowHtmlUserInput); });\n this._presetChoices = this._presetChoices.concat(elementItems);\n }\n this._presetChoices.forEach(function (choice) {\n choice.selected = true;\n });\n }\n else if (this._isSelectElement) {\n // Assign preset choices from passed object\n this._presetChoices = config.choices.map(function (e) { return mapInputToChoice(e, true); });\n // Create array of choices from option elements\n var choicesFromOptions = this.passedElement.optionsAsChoices();\n if (choicesFromOptions) {\n (_a = this._presetChoices).push.apply(_a, choicesFromOptions);\n }\n }\n };\n Choices.prototype._handleLoadingState = function (setLoading) {\n if (setLoading === void 0) { setLoading = true; }\n var el = this.itemList.element;\n if (setLoading) {\n this.disable();\n this.containerOuter.addLoadingState();\n if (this._isSelectOneElement) {\n el.replaceChildren(this._templates.placeholder(this.config, this.config.loadingText));\n }\n else {\n this.input.placeholder = this.config.loadingText;\n }\n }\n else {\n this.enable();\n this.containerOuter.removeLoadingState();\n if (this._isSelectOneElement) {\n el.replaceChildren('');\n this._render();\n }\n else {\n this.input.placeholder = this._placeholderValue || '';\n }\n }\n };\n Choices.prototype._handleSearch = function (value) {\n if (!this.input.isFocussed) {\n return;\n }\n // Check that we have a value to search and the input was an alphanumeric character\n if (value !== null && typeof value !== 'undefined' && value.length >= this.config.searchFloor) {\n var resultCount = this.config.searchChoices ? this._searchChoices(value) : 0;\n if (resultCount !== null) {\n // Trigger search event\n this.passedElement.triggerEvent(EventType.search, {\n value: value,\n resultCount: resultCount,\n });\n }\n }\n else if (this._store.choices.some(function (option) { return !option.active; })) {\n this._stopSearch();\n }\n };\n Choices.prototype._canAddItems = function () {\n var config = this.config;\n var maxItemCount = config.maxItemCount, maxItemText = config.maxItemText;\n if (!config.singleModeForMultiSelect && maxItemCount > 0 && maxItemCount <= this._store.items.length) {\n this.choiceList.element.replaceChildren('');\n this._notice = undefined;\n this._displayNotice(typeof maxItemText === 'function' ? maxItemText(maxItemCount) : maxItemText, NoticeTypes.addChoice);\n return false;\n }\n if (this._notice && this._notice.type === NoticeTypes.addChoice) {\n this._clearNotice();\n }\n return true;\n };\n Choices.prototype._canCreateItem = function (value) {\n var config = this.config;\n var canAddItem = true;\n var notice = '';\n if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) {\n canAddItem = false;\n notice = resolveNoticeFunction(config.customAddItemText, value);\n }\n if (canAddItem) {\n var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); });\n if (foundChoice) {\n if (this._isSelectElement) {\n // for exact matches, do not prompt to add it as a custom choice\n this._displayNotice('', NoticeTypes.addChoice);\n return false;\n }\n if (!config.duplicateItemsAllowed) {\n canAddItem = false;\n notice = resolveNoticeFunction(config.uniqueItemText, value);\n }\n }\n }\n if (canAddItem) {\n notice = resolveNoticeFunction(config.addItemText, value);\n }\n if (notice) {\n this._displayNotice(notice, NoticeTypes.addChoice);\n }\n return canAddItem;\n };\n Choices.prototype._searchChoices = function (value) {\n var newValue = value.trim().replace(/\\s{2,}/, ' ');\n // signal input didn't change search\n if (!newValue.length || newValue === this._currentValue) {\n return null;\n }\n var searcher = this._searcher;\n if (searcher.isEmptyIndex()) {\n searcher.index(this._store.searchableChoices);\n }\n // If new value matches the desired length and is not the same as the current value with a space\n var results = searcher.search(newValue);\n this._currentValue = newValue;\n this._highlightPosition = 0;\n this._isSearching = true;\n var notice = this._notice;\n var noticeType = notice && notice.type;\n if (noticeType !== NoticeTypes.addChoice) {\n if (!results.length) {\n this._displayNotice(resolveStringFunction(this.config.noResultsText), NoticeTypes.noResults);\n }\n else {\n this._clearNotice();\n }\n }\n this._store.dispatch(filterChoices(results));\n return results.length;\n };\n Choices.prototype._stopSearch = function () {\n if (this._isSearching) {\n this._currentValue = '';\n this._isSearching = false;\n this._clearNotice();\n this._store.dispatch(activateChoices(true));\n this.passedElement.triggerEvent(EventType.search, {\n value: '',\n resultCount: 0,\n });\n }\n };\n Choices.prototype._addEventListeners = function () {\n var documentElement = this._docRoot;\n var outerElement = this.containerOuter.element;\n var inputElement = this.input.element;\n // capture events - can cancel event processing or propagation\n documentElement.addEventListener('touchend', this._onTouchEnd, true);\n outerElement.addEventListener('keydown', this._onKeyDown, true);\n outerElement.addEventListener('mousedown', this._onMouseDown, true);\n // passive events - doesn't call `preventDefault` or `stopPropagation`\n documentElement.addEventListener('click', this._onClick, { passive: true });\n documentElement.addEventListener('touchmove', this._onTouchMove, {\n passive: true,\n });\n this.dropdown.element.addEventListener('mouseover', this._onMouseOver, {\n passive: true,\n });\n if (this._isSelectOneElement) {\n outerElement.addEventListener('focus', this._onFocus, {\n passive: true,\n });\n outerElement.addEventListener('blur', this._onBlur, {\n passive: true,\n });\n }\n inputElement.addEventListener('keyup', this._onKeyUp, {\n passive: true,\n });\n inputElement.addEventListener('input', this._onInput, {\n passive: true,\n });\n inputElement.addEventListener('focus', this._onFocus, {\n passive: true,\n });\n inputElement.addEventListener('blur', this._onBlur, {\n passive: true,\n });\n if (inputElement.form) {\n inputElement.form.addEventListener('reset', this._onFormReset, {\n passive: true,\n });\n }\n this.input.addEventListeners();\n };\n Choices.prototype._removeEventListeners = function () {\n var documentElement = this._docRoot;\n var outerElement = this.containerOuter.element;\n var inputElement = this.input.element;\n documentElement.removeEventListener('touchend', this._onTouchEnd, true);\n outerElement.removeEventListener('keydown', this._onKeyDown, true);\n outerElement.removeEventListener('mousedown', this._onMouseDown, true);\n documentElement.removeEventListener('click', this._onClick);\n documentElement.removeEventListener('touchmove', this._onTouchMove);\n this.dropdown.element.removeEventListener('mouseover', this._onMouseOver);\n if (this._isSelectOneElement) {\n outerElement.removeEventListener('focus', this._onFocus);\n outerElement.removeEventListener('blur', this._onBlur);\n }\n inputElement.removeEventListener('keyup', this._onKeyUp);\n inputElement.removeEventListener('input', this._onInput);\n inputElement.removeEventListener('focus', this._onFocus);\n inputElement.removeEventListener('blur', this._onBlur);\n if (inputElement.form) {\n inputElement.form.removeEventListener('reset', this._onFormReset);\n }\n this.input.removeEventListeners();\n };\n Choices.prototype._onKeyDown = function (event) {\n var keyCode = event.keyCode;\n var hasActiveDropdown = this.dropdown.isActive;\n /*\n See:\n https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key\n https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values\n https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF - UTF-16 surrogate pairs\n https://stackoverflow.com/a/70866532 - \"Unidentified\" for mobile\n http://www.unicode.org/versions/Unicode5.2.0/ch16.pdf#G19635 - U+FFFF is reserved (Section 16.7)\n \n Logic: when a key event is sent, `event.key` represents its printable value _or_ one\n of a large list of special values indicating meta keys/functionality. In addition,\n key events for compose functionality contain a value of `Dead` when mid-composition.\n \n I can't quite verify it, but non-English IMEs may also be able to generate key codes\n for code points in the surrogate-pair range, which could potentially be seen as having\n key.length > 1. Since `Fn` is one of the special keys, we can't distinguish by that\n alone.\n \n Here, key.length === 1 means we know for sure the input was printable and not a special\n `key` value. When the length is greater than 1, it could be either a printable surrogate\n pair or a special `key` value. We can tell the difference by checking if the _character\n code_ value (not code point!) is in the \"surrogate pair\" range or not.\n \n We don't use .codePointAt because an invalid code point would return 65535, which wouldn't\n pass the >= 0x10000 check we would otherwise use.\n \n > ...The Unicode Standard sets aside 66 noncharacter code points. The last two code points\n > of each plane are noncharacters: U+FFFE and U+FFFF on the BMP...\n */\n var wasPrintableChar = event.key.length === 1 ||\n (event.key.length === 2 && event.key.charCodeAt(0) >= 0xd800) ||\n event.key === 'Unidentified';\n /*\n We do not show the dropdown if focusing out with esc or navigating through input fields.\n An activated search can still be opened with any other key.\n */\n if (!this._isTextElement &&\n !hasActiveDropdown &&\n keyCode !== KeyCodeMap.ESC_KEY &&\n keyCode !== KeyCodeMap.TAB_KEY &&\n keyCode !== KeyCodeMap.SHIFT_KEY) {\n this.showDropdown();\n if (!this.input.isFocussed && wasPrintableChar) {\n /*\n We update the input value with the pressed key as\n the input was not focussed at the time of key press\n therefore does not have the value of the key.\n */\n this.input.value += event.key;\n // browsers interpret a space as pagedown\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n }\n switch (keyCode) {\n case KeyCodeMap.A_KEY:\n return this._onSelectKey(event, this.itemList.element.hasChildNodes());\n case KeyCodeMap.ENTER_KEY:\n return this._onEnterKey(event, hasActiveDropdown);\n case KeyCodeMap.ESC_KEY:\n return this._onEscapeKey(event, hasActiveDropdown);\n case KeyCodeMap.UP_KEY:\n case KeyCodeMap.PAGE_UP_KEY:\n case KeyCodeMap.DOWN_KEY:\n case KeyCodeMap.PAGE_DOWN_KEY:\n return this._onDirectionKey(event, hasActiveDropdown);\n case KeyCodeMap.DELETE_KEY:\n case KeyCodeMap.BACK_KEY:\n return this._onDeleteKey(event, this._store.items, this.input.isFocussed);\n }\n };\n Choices.prototype._onKeyUp = function ( /* event: KeyboardEvent */) {\n this._canSearch = this.config.searchEnabled;\n };\n Choices.prototype._onInput = function ( /* event: InputEvent */) {\n var value = this.input.value;\n if (!value) {\n if (this._isTextElement) {\n this.hideDropdown(true);\n }\n else {\n this._stopSearch();\n }\n return;\n }\n if (!this._canAddItems()) {\n return;\n }\n if (this._canSearch) {\n // do the search even if the entered text can not be added\n this._handleSearch(value);\n }\n if (!this._canAddUserChoices) {\n return;\n }\n // determine if a notice needs to be displayed for why a search result can't be added\n this._canCreateItem(value);\n if (this._isSelectElement) {\n this._highlightPosition = 0; // reset to select the notice and/or exact match\n this._highlightChoice();\n }\n };\n Choices.prototype._onSelectKey = function (event, hasItems) {\n // If CTRL + A or CMD + A have been pressed and there are items to select\n if ((event.ctrlKey || event.metaKey) && hasItems) {\n this._canSearch = false;\n var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement;\n if (shouldHightlightAll) {\n this.highlightAll();\n }\n }\n };\n Choices.prototype._onEnterKey = function (event, hasActiveDropdown) {\n var _this = this;\n var value = this.input.value;\n var target = event.target;\n event.preventDefault();\n if (target && target.hasAttribute('data-button')) {\n this._handleButtonAction(target);\n return;\n }\n if (!hasActiveDropdown) {\n if (this._isSelectElement || this._notice) {\n this.showDropdown();\n }\n return;\n }\n var highlightedChoice = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState));\n if (highlightedChoice && this._handleChoiceAction(highlightedChoice)) {\n return;\n }\n if (!target || !value) {\n this.hideDropdown(true);\n return;\n }\n if (!this._canAddItems()) {\n return;\n }\n var addedItem = false;\n this._store.withTxn(function () {\n addedItem = _this._findAndSelectChoiceByValue(value, true);\n if (!addedItem) {\n if (!_this._canAddUserChoices) {\n return;\n }\n if (!_this._canCreateItem(value)) {\n return;\n }\n _this._addChoice(mapInputToChoice(value, false, _this.config.allowHtmlUserInput), true, true);\n addedItem = true;\n }\n _this.clearInput();\n _this.unhighlightAll();\n });\n if (!addedItem) {\n return;\n }\n this._triggerChange(value);\n if (this.config.closeDropdownOnSelect) {\n this.hideDropdown(true);\n }\n };\n Choices.prototype._onEscapeKey = function (event, hasActiveDropdown) {\n if (hasActiveDropdown) {\n event.stopPropagation();\n this.hideDropdown(true);\n this._stopSearch();\n this.containerOuter.element.focus();\n }\n };\n Choices.prototype._onDirectionKey = function (event, hasActiveDropdown) {\n var keyCode = event.keyCode;\n // If up or down key is pressed, traverse through options\n if (hasActiveDropdown || this._isSelectOneElement) {\n this.showDropdown();\n this._canSearch = false;\n var directionInt = keyCode === KeyCodeMap.DOWN_KEY || keyCode === KeyCodeMap.PAGE_DOWN_KEY ? 1 : -1;\n var skipKey = event.metaKey || keyCode === KeyCodeMap.PAGE_DOWN_KEY || keyCode === KeyCodeMap.PAGE_UP_KEY;\n var nextEl = void 0;\n if (skipKey) {\n if (directionInt > 0) {\n nextEl = this.dropdown.element.querySelector(\"\".concat(selectableChoiceIdentifier, \":last-of-type\"));\n }\n else {\n nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);\n }\n }\n else {\n var currentEl = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState));\n if (currentEl) {\n nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt);\n }\n else {\n nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);\n }\n }\n if (nextEl) {\n // We prevent default to stop the cursor moving\n // when pressing the arrow\n if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) {\n this.choiceList.scrollToChildElement(nextEl, directionInt);\n }\n this._highlightChoice(nextEl);\n }\n // Prevent default to maintain cursor position whilst\n // traversing dropdown options\n event.preventDefault();\n }\n };\n Choices.prototype._onDeleteKey = function (event, items, hasFocusedInput) {\n // If backspace or delete key is pressed and the input has no value\n if (!this._isSelectOneElement && !event.target.value && hasFocusedInput) {\n this._handleBackspace(items);\n event.preventDefault();\n }\n };\n Choices.prototype._onTouchMove = function () {\n if (this._wasTap) {\n this._wasTap = false;\n }\n };\n Choices.prototype._onTouchEnd = function (event) {\n var target = (event || event.touches[0]).target;\n var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target);\n if (touchWasWithinContainer) {\n var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element;\n if (containerWasExactTarget) {\n if (this._isTextElement) {\n this.input.focus();\n }\n else if (this._isSelectMultipleElement) {\n this.showDropdown();\n }\n }\n // Prevents focus event firing\n event.stopPropagation();\n }\n this._wasTap = true;\n };\n /**\n * Handles mousedown event in capture mode for containetOuter.element\n */\n Choices.prototype._onMouseDown = function (event) {\n var target = event.target;\n if (!(target instanceof HTMLElement)) {\n return;\n }\n // If we have our mouse down on the scrollbar and are on IE11...\n if (IS_IE11 && this.choiceList.element.contains(target)) {\n // check if click was on a scrollbar area\n var firstChoice = this.choiceList.element.firstElementChild;\n this._isScrollingOnIe =\n this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft;\n }\n if (target === this.input.element) {\n return;\n }\n var item = target.closest('[data-button],[data-item],[data-choice]');\n if (item instanceof HTMLElement) {\n if ('button' in item.dataset) {\n this._handleButtonAction(item);\n }\n else if ('item' in item.dataset) {\n this._handleItemAction(item, event.shiftKey);\n }\n else if ('choice' in item.dataset) {\n this._handleChoiceAction(item);\n }\n }\n event.preventDefault();\n };\n /**\n * Handles mouseover event over this.dropdown\n * @param {MouseEvent} event\n */\n Choices.prototype._onMouseOver = function (_a) {\n var target = _a.target;\n if (target instanceof HTMLElement && 'choice' in target.dataset) {\n this._highlightChoice(target);\n }\n };\n Choices.prototype._onClick = function (_a) {\n var target = _a.target;\n var containerOuter = this.containerOuter;\n var clickWasWithinContainer = containerOuter.element.contains(target);\n if (clickWasWithinContainer) {\n if (!this.dropdown.isActive && !containerOuter.isDisabled) {\n if (this._isTextElement) {\n if (document.activeElement !== this.input.element) {\n this.input.focus();\n }\n }\n else {\n this.showDropdown();\n containerOuter.element.focus();\n }\n }\n else if (this._isSelectOneElement &&\n target !== this.input.element &&\n !this.dropdown.element.contains(target)) {\n this.hideDropdown();\n }\n }\n else {\n containerOuter.removeFocusState();\n this.hideDropdown(true);\n this.unhighlightAll();\n }\n };\n Choices.prototype._onFocus = function (_a) {\n var target = _a.target;\n var containerOuter = this.containerOuter;\n var focusWasWithinContainer = target && containerOuter.element.contains(target);\n if (!focusWasWithinContainer) {\n return;\n }\n var targetIsInput = target === this.input.element;\n if (this._isTextElement) {\n if (targetIsInput) {\n containerOuter.addFocusState();\n }\n }\n else if (this._isSelectMultipleElement) {\n if (targetIsInput) {\n this.showDropdown(true);\n // If element is a select box, the focused element is the container and the dropdown\n // isn't already open, focus and show dropdown\n containerOuter.addFocusState();\n }\n }\n else {\n containerOuter.addFocusState();\n if (targetIsInput) {\n this.showDropdown(true);\n }\n }\n };\n Choices.prototype._onBlur = function (_a) {\n var target = _a.target;\n var containerOuter = this.containerOuter;\n var blurWasWithinContainer = target && containerOuter.element.contains(target);\n if (blurWasWithinContainer && !this._isScrollingOnIe) {\n if (target === this.input.element) {\n containerOuter.removeFocusState();\n this.hideDropdown(true);\n if (this._isTextElement || this._isSelectMultipleElement) {\n this.unhighlightAll();\n }\n }\n else if (target === this.containerOuter.element) {\n // Remove the focus state when the past outerContainer was the target\n containerOuter.removeFocusState();\n // Also close the dropdown if search is disabled\n if (!this._canSearch) {\n this.hideDropdown(true);\n }\n }\n }\n else {\n // On IE11, clicking the scollbar blurs our input and thus\n // closes the dropdown. To stop this, we refocus our input\n // if we know we are on IE *and* are scrolling.\n this._isScrollingOnIe = false;\n this.input.element.focus();\n }\n };\n Choices.prototype._onFormReset = function () {\n var _this = this;\n this._store.withTxn(function () {\n _this.clearInput();\n _this.hideDropdown();\n _this.refresh(false, false, true);\n if (_this._initialItems.length) {\n _this.setChoiceByValue(_this._initialItems);\n }\n });\n };\n Choices.prototype._highlightChoice = function (el) {\n if (el === void 0) { el = null; }\n var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier));\n if (!choices.length) {\n return;\n }\n var passedEl = el;\n var highlightedState = this.config.classNames.highlightedState;\n var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState)));\n // Remove any highlighted choices\n highlightedChoices.forEach(function (choice) {\n removeClassesFromElement(choice, highlightedState);\n choice.setAttribute('aria-selected', 'false');\n });\n if (passedEl) {\n this._highlightPosition = choices.indexOf(passedEl);\n }\n else {\n // Highlight choice based on last known highlight location\n if (choices.length > this._highlightPosition) {\n // If we have an option to highlight\n passedEl = choices[this._highlightPosition];\n }\n else {\n // Otherwise highlight the option before\n passedEl = choices[choices.length - 1];\n }\n if (!passedEl) {\n passedEl = choices[0];\n }\n }\n addClassesToElement(passedEl, highlightedState);\n passedEl.setAttribute('aria-selected', 'true');\n this.passedElement.triggerEvent(EventType.highlightChoice, {\n el: passedEl,\n });\n if (this.dropdown.isActive) {\n // IE11 ignores aria-label and blocks virtual keyboard\n // if aria-activedescendant is set without a dropdown\n this.input.setActiveDescendant(passedEl.id);\n this.containerOuter.setActiveDescendant(passedEl.id);\n }\n };\n Choices.prototype._addItem = function (item, withEvents, userTriggered) {\n if (withEvents === void 0) { withEvents = true; }\n if (userTriggered === void 0) { userTriggered = false; }\n if (!item.id) {\n throw new TypeError('item.id must be set before _addItem is called for a choice/item');\n }\n if (this.config.singleModeForMultiSelect || this._isSelectOneElement) {\n this.removeActiveItems(item.id);\n }\n this._store.dispatch(addItem(item));\n if (withEvents) {\n this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item));\n if (userTriggered) {\n this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item));\n }\n }\n };\n Choices.prototype._removeItem = function (item) {\n if (!item.id) {\n return;\n }\n this._store.dispatch(removeItem$1(item));\n var notice = this._notice;\n if (notice && notice.type === NoticeTypes.noChoices) {\n this._clearNotice();\n }\n this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item));\n };\n Choices.prototype._addChoice = function (choice, withEvents, userTriggered) {\n if (withEvents === void 0) { withEvents = true; }\n if (userTriggered === void 0) { userTriggered = false; }\n if (choice.id) {\n throw new TypeError('Can not re-add a choice which has already been added');\n }\n var config = this.config;\n if (!config.duplicateItemsAllowed && this._store.choices.find(function (c) { return config.valueComparer(c.value, choice.value); })) {\n return;\n }\n // Generate unique id, in-place update is required so chaining _addItem works as expected\n this._lastAddedChoiceId++;\n choice.id = this._lastAddedChoiceId;\n choice.elementId = \"\".concat(this._baseId, \"-\").concat(this._idNames.itemChoice, \"-\").concat(choice.id);\n var prependValue = config.prependValue, appendValue = config.appendValue;\n if (prependValue) {\n choice.value = prependValue + choice.value;\n }\n if (appendValue) {\n choice.value += appendValue.toString();\n }\n if ((prependValue || appendValue) && choice.element) {\n choice.element.value = choice.value;\n }\n this._clearNotice();\n this._store.dispatch(addChoice(choice));\n if (choice.selected) {\n this._addItem(choice, withEvents, userTriggered);\n }\n };\n Choices.prototype._addGroup = function (group, withEvents) {\n var _this = this;\n if (withEvents === void 0) { withEvents = true; }\n if (group.id) {\n throw new TypeError('Can not re-add a group which has already been added');\n }\n this._store.dispatch(addGroup(group));\n if (!group.choices) {\n return;\n }\n // add unique id for the group(s), and do not store the full list of choices in this group\n this._lastAddedGroupId++;\n group.id = this._lastAddedGroupId;\n group.choices.forEach(function (item) {\n item.group = group;\n if (group.disabled) {\n item.disabled = true;\n }\n _this._addChoice(item, withEvents);\n });\n };\n Choices.prototype._createTemplates = function () {\n var _this = this;\n var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates;\n var userTemplates = {};\n if (typeof callbackOnCreateTemplates === 'function') {\n userTemplates = callbackOnCreateTemplates.call(this, strToEl, escapeForTemplate, getClassNames);\n }\n var templating = {};\n Object.keys(this._templates).forEach(function (name) {\n if (name in userTemplates) {\n templating[name] = userTemplates[name].bind(_this);\n }\n else {\n templating[name] = _this._templates[name].bind(_this);\n }\n });\n this._templates = templating;\n };\n Choices.prototype._createElements = function () {\n var templating = this._templates;\n var _a = this, config = _a.config, isSelectOneElement = _a._isSelectOneElement;\n var position = config.position, classNames = config.classNames;\n var elementType = this._elementType;\n this.containerOuter = new Container({\n element: templating.containerOuter(config, this._direction, this._isSelectElement, isSelectOneElement, config.searchEnabled, elementType, config.labelId),\n classNames: classNames,\n type: elementType,\n position: position,\n });\n this.containerInner = new Container({\n element: templating.containerInner(config),\n classNames: classNames,\n type: elementType,\n position: position,\n });\n this.input = new Input({\n element: templating.input(config, this._placeholderValue),\n classNames: classNames,\n type: elementType,\n preventPaste: !config.paste,\n });\n this.choiceList = new List({\n element: templating.choiceList(config, isSelectOneElement),\n });\n this.itemList = new List({\n element: templating.itemList(config, isSelectOneElement),\n });\n this.dropdown = new Dropdown({\n element: templating.dropdown(config),\n classNames: classNames,\n type: elementType,\n });\n };\n Choices.prototype._createStructure = function () {\n var _a = this, containerInner = _a.containerInner, containerOuter = _a.containerOuter, passedElement = _a.passedElement;\n var dropdownElement = this.dropdown.element;\n // Hide original element\n passedElement.conceal();\n // Wrap input in container preserving DOM ordering\n containerInner.wrap(passedElement.element);\n // Wrapper inner container with outer container\n containerOuter.wrap(containerInner.element);\n if (this._isSelectOneElement) {\n this.input.placeholder = this.config.searchPlaceholderValue || '';\n }\n else {\n if (this._placeholderValue) {\n this.input.placeholder = this._placeholderValue;\n }\n this.input.setWidth();\n }\n containerOuter.element.appendChild(containerInner.element);\n containerOuter.element.appendChild(dropdownElement);\n containerInner.element.appendChild(this.itemList.element);\n dropdownElement.appendChild(this.choiceList.element);\n if (!this._isSelectOneElement) {\n containerInner.element.appendChild(this.input.element);\n }\n else if (this.config.searchEnabled) {\n dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild);\n }\n this._highlightPosition = 0;\n this._isSearching = false;\n };\n Choices.prototype._initStore = function () {\n var _this = this;\n this._store.subscribe(this._render).withTxn(function () {\n _this._addPredefinedChoices(_this._presetChoices, _this._isSelectOneElement && !_this._hasNonChoicePlaceholder, false);\n });\n if (!this._store.choices.length || (this._isSelectOneElement && this._hasNonChoicePlaceholder)) {\n this._render();\n }\n };\n Choices.prototype._addPredefinedChoices = function (choices, selectFirstOption, withEvents) {\n var _this = this;\n if (selectFirstOption === void 0) { selectFirstOption = false; }\n if (withEvents === void 0) { withEvents = true; }\n if (selectFirstOption) {\n /**\n * If there is a selected choice already or the choice is not the first in\n * the array, add each choice normally.\n *\n * Otherwise we pre-select the first enabled choice in the array (\"select-one\" only)\n */\n var noSelectedChoices = choices.findIndex(function (choice) { return choice.selected; }) === -1;\n if (noSelectedChoices) {\n choices.some(function (choice) {\n if (choice.disabled || 'choices' in choice) {\n return false;\n }\n choice.selected = true;\n return true;\n });\n }\n }\n choices.forEach(function (item) {\n if ('choices' in item) {\n if (_this._isSelectElement) {\n _this._addGroup(item, withEvents);\n }\n }\n else {\n _this._addChoice(item, withEvents);\n }\n });\n };\n Choices.prototype._findAndSelectChoiceByValue = function (value, userTriggered) {\n var _this = this;\n if (userTriggered === void 0) { userTriggered = false; }\n // Check 'value' property exists and the choice isn't already selected\n var foundChoice = this._store.choices.find(function (choice) { return _this.config.valueComparer(choice.value, value); });\n if (foundChoice && !foundChoice.disabled && !foundChoice.selected) {\n this._addItem(foundChoice, true, userTriggered);\n return true;\n }\n return false;\n };\n Choices.prototype._generatePlaceholderValue = function () {\n var config = this.config;\n if (!config.placeholder) {\n return null;\n }\n if (this._hasNonChoicePlaceholder) {\n return config.placeholderValue;\n }\n if (this._isSelectElement) {\n var placeholderOption = this.passedElement.placeholderOption;\n return placeholderOption ? placeholderOption.text : null;\n }\n return null;\n };\n Choices.prototype._warnChoicesInitFailed = function (caller) {\n if (this.config.silent) {\n return;\n }\n if (!this.initialised) {\n throw new TypeError(\"\".concat(caller, \" called on a non-initialised instance of Choices\"));\n }\n else if (!this.initialisedOK) {\n throw new TypeError(\"\".concat(caller, \" called for an element which has multiple instances of Choices initialised on it\"));\n }\n };\n Choices.version = '11.0.6';\n return Choices;\n }());\n\n return Choices;\n\n}));\n\n\n//# sourceURL=webpack://Formio/./node_modules/choices.js/public/assets/scripts/choices.js?");
|
2673
|
+
|
2674
|
+
/***/ }),
|
2675
|
+
|
2676
2676
|
/***/ "./node_modules/compare-versions/lib/esm/compare.js":
|
2677
2677
|
/*!**********************************************************!*\
|
2678
2678
|
!*** ./node_modules/compare-versions/lib/esm/compare.js ***!
|
@@ -2796,7 +2796,7 @@ eval("!function(t,i){ true?module.exports=i():0}(this,(function(){\"use strict\"
|
|
2796
2796
|
/***/ (function(module) {
|
2797
2797
|
|
2798
2798
|
"use strict";
|
2799
|
-
eval("/*! @license DOMPurify 3.2.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.3/LICENSE */\n\n\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\nif (!apply) {\n apply = function apply(fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\nif (!construct) {\n construct = function construct(Func, args) {\n return new Func(...args);\n };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return function (thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n return apply(func, thisArg, args);\n };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(func) {\n return function () {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n return construct(func, args);\n };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n element = lcElement;\n }\n }\n set[element] = true;\n }\n return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (value && typeof value === 'object' && value.constructor === Object) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n object = getPrototypeOf(object);\n }\n function fallbackValue() {\n return null;\n }\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*}/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ARIA_ATTR: ARIA_ATTR,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n DATA_ATTR: DATA_ATTR,\n DOCTYPE_NAME: DOCTYPE_NAME,\n ERB_EXPR: ERB_EXPR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5,\n // Deprecated\n entityNode: 6,\n // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\nconst _createHooksMap = function _createHooksMap() {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: []\n };\n};\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n const DOMPurify = root => createDOMPurify(root);\n DOMPurify.version = '3.2.3';\n DOMPurify.removed = [];\n if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n let {\n document\n } = window;\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = _createHooksMap();\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n const formElement = document.createElement('form');\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function _parseConfig() {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n }\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n }\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n CONFIG = cfg;\n };\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element);\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n // For XHTML and XML documents that support custom namespaces\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n }\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function _removeAttribute(name, element) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element\n });\n }\n element.removeAttribute(name);\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' + dirty + '</body></html>';\n }\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n const body = doc.body || doc.documentElement;\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function _createNodeIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n };\n /**\n * _isClobbered\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function _isClobbered(element) {\n return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n };\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param value object to check whether it's a DOM node\n * @return true is object is a DOM node\n */\n const _isNode = function _isNode(value) {\n return typeof Node === 'function' && value instanceof Node;\n };\n function _executeHooks(hooks, currentNode, data) {\n arrayForEach(hooks, hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content = null;\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any kind of possibly harmful comments */\n if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n return false;\n }\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n return false;\n }\n }\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n _forceRemove(currentNode);\n return true;\n }\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n content = stringReplace(content, expr, ' ');\n });\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n return true;\n };\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined\n };\n let l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const {\n name,\n namespaceURI,\n value: attrValue\n } = attr;\n const lcName = transformCaseFunc(name);\n let value = name === 'value' ? attrValue : stringTrim(attrValue);\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n value = stringReplace(value, expr, ' ');\n });\n }\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n /* Handle attributes that require Trusted Types */\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {}\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode);\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode);\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n return returnNode;\n }\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n DOMPurify.setConfig = function () {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n arrayPush(hooks[entryPoint], hookFunction);\n };\n DOMPurify.removeHook = function (entryPoint) {\n return arrayPop(hooks[entryPoint]);\n };\n DOMPurify.removeHooks = function (entryPoint) {\n hooks[entryPoint] = [];\n };\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nmodule.exports = purify;\n//# sourceMappingURL=purify.cjs.js.map\n\n\n//# sourceURL=webpack://Formio/./node_modules/dompurify/dist/purify.cjs.js?");
|
2799
|
+
eval("/*! @license DOMPurify 3.2.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.4/LICENSE */\n\n\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\nif (!apply) {\n apply = function apply(fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\nif (!construct) {\n construct = function construct(Func, args) {\n return new Func(...args);\n };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySplice = unapply(Array.prototype.splice);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return function (thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n return apply(func, thisArg, args);\n };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(func) {\n return function () {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n return construct(func, args);\n };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n element = lcElement;\n }\n }\n set[element] = true;\n }\n return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (value && typeof value === 'object' && value.constructor === Object) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n object = getPrototypeOf(object);\n }\n function fallbackValue() {\n return null;\n }\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ARIA_ATTR: ARIA_ATTR,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n DATA_ATTR: DATA_ATTR,\n DOCTYPE_NAME: DOCTYPE_NAME,\n ERB_EXPR: ERB_EXPR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5,\n // Deprecated\n entityNode: 6,\n // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\nconst _createHooksMap = function _createHooksMap() {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: []\n };\n};\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n const DOMPurify = root => createDOMPurify(root);\n DOMPurify.version = '3.2.4';\n DOMPurify.removed = [];\n if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n let {\n document\n } = window;\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = _createHooksMap();\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n const formElement = document.createElement('form');\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function _parseConfig() {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n }\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n }\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n CONFIG = cfg;\n };\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element);\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n // For XHTML and XML documents that support custom namespaces\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n }\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function _removeAttribute(name, element) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element\n });\n }\n element.removeAttribute(name);\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' + dirty + '</body></html>';\n }\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n const body = doc.body || doc.documentElement;\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function _createNodeIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n };\n /**\n * _isClobbered\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function _isClobbered(element) {\n return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n };\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param value object to check whether it's a DOM node\n * @return true is object is a DOM node\n */\n const _isNode = function _isNode(value) {\n return typeof Node === 'function' && value instanceof Node;\n };\n function _executeHooks(hooks, currentNode, data) {\n arrayForEach(hooks, hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content = null;\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any kind of possibly harmful comments */\n if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n return false;\n }\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n return false;\n }\n }\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n _forceRemove(currentNode);\n return true;\n }\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n content = stringReplace(content, expr, ' ');\n });\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n return true;\n };\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined\n };\n let l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const {\n name,\n namespaceURI,\n value: attrValue\n } = attr;\n const lcName = transformCaseFunc(name);\n let value = name === 'value' ? attrValue : stringTrim(attrValue);\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n value = stringReplace(value, expr, ' ');\n });\n }\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n /* Handle attributes that require Trusted Types */\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {}\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode);\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode);\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n return returnNode;\n }\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n DOMPurify.setConfig = function () {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n arrayPush(hooks[entryPoint], hookFunction);\n };\n DOMPurify.removeHook = function (entryPoint, hookFunction) {\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n return arrayPop(hooks[entryPoint]);\n };\n DOMPurify.removeHooks = function (entryPoint) {\n hooks[entryPoint] = [];\n };\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nmodule.exports = purify;\n//# sourceMappingURL=purify.cjs.js.map\n\n\n//# sourceURL=webpack://Formio/./node_modules/dompurify/dist/purify.cjs.js?");
|
2800
2800
|
|
2801
2801
|
/***/ }),
|
2802
2802
|
|
@@ -4853,7 +4853,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4853
4853
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
4854
4854
|
|
4855
4855
|
"use strict";
|
4856
|
-
eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\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};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* globals Quill, ClassicEditor, CKEDITOR */\nconst vanilla_text_mask_1 = __webpack_require__(/*! @formio/vanilla-text-mask */ \"./node_modules/@formio/vanilla-text-mask/dist/vanillaTextMask.js\");\nconst tippy_js_1 = __importDefault(__webpack_require__(/*! tippy.js */ \"./node_modules/tippy.js/dist/tippy.esm.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ismobilejs_1 = __importDefault(__webpack_require__(/*! ismobilejs */ \"./node_modules/ismobilejs/esm/index.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst Formio_1 = __webpack_require__(/*! ../../../Formio */ \"./lib/cjs/Formio.js\");\nconst FormioUtils = __importStar(__webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Element_1 = __importDefault(__webpack_require__(/*! ../../../Element */ \"./lib/cjs/Element.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst widgets_1 = __importDefault(__webpack_require__(/*! ../../../widgets */ \"./lib/cjs/widgets/index.js\"));\nconst addons_1 = __importDefault(__webpack_require__(/*! ../../../addons */ \"./lib/cjs/addons/index.js\"));\nconst uploadAdapter_1 = __webpack_require__(/*! ../../../providers/storage/uploadAdapter */ \"./lib/cjs/providers/storage/uploadAdapter.js\");\nconst en_1 = __importDefault(__webpack_require__(/*! ../../../translations/en */ \"./lib/cjs/translations/en.js\"));\nconst Templates_1 = __importDefault(__webpack_require__(/*! ../../../templates/Templates */ \"./lib/cjs/templates/Templates.js\"));\nconst isIEBrowser = FormioUtils.getBrowserInfo().ie;\n/**\n * This is the Component class\n which all elements within the FormioForm derive from.\n */\nclass Component extends Element_1.default {\n static schema(...sources) {\n return lodash_1.default.merge({\n /**\n * Determines if this component provides an input.\n */\n input: true,\n /**\n * The data key for this component (how the data is stored in the database).\n */\n key: '',\n /**\n * The input placeholder for this component.\n */\n placeholder: '',\n /**\n * The input prefix\n */\n prefix: '',\n /**\n * The custom CSS class to provide to this component.\n */\n customClass: '',\n /**\n * The input suffix.\n */\n suffix: '',\n /**\n * If this component should allow an array of values to be captured.\n */\n multiple: false,\n /**\n * The default value of this component.\n */\n defaultValue: null,\n /**\n * If the data of this component should be protected (no GET api requests can see the data)\n */\n protected: false,\n /**\n * Validate if the value of this component should be unique within the form.\n */\n unique: false,\n /**\n * If the value of this component should be persisted within the backend api database.\n */\n persistent: true,\n /**\n * Determines if the component should be within the form, but not visible.\n */\n hidden: false,\n /**\n * If the component should be cleared when hidden.\n */\n clearOnHide: true,\n /**\n * This will refresh this component options when this field changes.\n */\n refreshOn: '',\n /**\n * This will redraw the component when this field changes.\n */\n redrawOn: '',\n /**\n * If this component should be included as a column within a submission table.\n */\n tableView: false,\n /**\n * If this component should be rendering in modal.\n */\n modalEdit: false,\n /**\n * The input label provided to this component.\n */\n label: '',\n dataGridLabel: false,\n labelPosition: 'top',\n description: '',\n errorLabel: '',\n tooltip: '',\n hideLabel: false,\n tabindex: '',\n disabled: false,\n autofocus: false,\n dbIndex: false,\n customDefaultValue: '',\n calculateValue: '',\n calculateServer: false,\n widget: null,\n /**\n * Attributes that will be assigned to the input elements of this component.\n */\n attributes: {},\n /**\n * This will perform the validation on either \"change\" or \"blur\" of the input element.\n */\n validateOn: 'change',\n /**\n * The validation criteria for this component.\n */\n validate: {\n /**\n * If this component is required.\n */\n required: false,\n /**\n * Custom JavaScript validation.\n */\n custom: '',\n /**\n * If the custom validation should remain private (only the backend will see it and execute it).\n */\n customPrivate: false,\n /**\n * If this component should implement a strict date validation if the Calendar widget is implemented.\n */\n strictDateValidation: false,\n multiple: false,\n unique: false\n },\n /**\n * The simple conditional settings for a component.\n */\n conditional: {\n show: null,\n when: null,\n eq: ''\n },\n overlay: {\n style: '',\n left: '',\n top: '',\n width: '',\n height: '',\n },\n allowCalculateOverride: false,\n encrypted: false,\n showCharCount: false,\n showWordCount: false,\n properties: {},\n allowMultipleMasks: false,\n addons: [],\n serverOverride: {},\n }, ...sources);\n }\n /**\n * Return the simple condition settings as part of the component.\n * @returns {object} - The simple conditional settings.\n */\n static get conditionOperatorsSettings() {\n return {\n operators: ['isEqual', 'isNotEqual', 'isEmpty', 'isNotEmpty'],\n valueComponent() {\n return {\n type: 'textfield',\n widget: {\n type: 'input'\n }\n };\n }\n };\n }\n /**\n * Return the array of possible types of component value absed on its schema.\n * @param schema\n * @returns {Array}\n */\n static savedValueTypes(schema) {\n schema = schema || {};\n return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.any];\n }\n /**\n * Provides a table view for this component. Override if you wish to do something different than using getView\n * method of your instance.\n * @param value\n * @param options\n */\n /* eslint-disable no-unused-vars */\n static tableView(value, options) { }\n /* eslint-enable no-unused-vars */\n /**\n * Initialize a new Component.\n * @param {object} component - The component JSON you wish to initialize.\n * @param {object} options - The options for this component.\n * @param {object} data - The global data submission object this component will belong.\n */\n /* eslint-disable max-statements */\n constructor(component, options, data) {\n var _a, _b, _c, _d;\n super(Object.assign({\n renderMode: 'form',\n attachMode: 'full',\n noDefaults: false\n }, options || {}));\n // Restore the component id.\n if (component && component.id) {\n this.id = component.id;\n }\n /**\n * Determines if this component has a condition assigned to it.\n * @type {null}\n * @private\n */\n this._hasCondition = null;\n /**\n * The row index for this component.\n */\n this._rowIndex = undefined;\n /**\n * References to dom elements\n */\n this.refs = {};\n // Allow global override for any component JSON.\n if (component &&\n this.options.components &&\n this.options.components[component.type]) {\n lodash_1.default.merge(component, this.options.components[component.type]);\n }\n /**\n * An array of all the children components errors.\n */\n this.childErrors = [];\n /**\n * Last validation errors that have occured.\n */\n this._errors = [];\n this._visibleErrors = [];\n /**\n * The Form.io component JSON schema.\n * @type {*}\n */\n this.component = this.mergeSchema(component || {});\n // Add the id to the component.\n this.component.id = this.id;\n this.afterComponentAssign();\n // Save off the original component to be used in logic.\n this.originalComponent = (0, utils_1.fastCloneDeep)(this.component);\n /**\n * If the component has been attached\n */\n this.attached = false;\n /**\n * If the component has been rendered\n */\n this.rendered = false;\n /**\n * The data object in which this component resides.\n * @type {*}\n */\n this._data = data || {};\n /**\n * Tool tip text after processing\n * @type {string}\n */\n this.tooltip = '';\n /**\n * The row path of this component.\n * @type {number}\n */\n this.row = this.options.row;\n /**\n * Points to a flat map of child components (if applicable).\n * @type {object}\n */\n this.childComponentsMap = {};\n /**\n * Determines if this component is disabled, or not.\n * @type {boolean}\n */\n this._disabled = (0, utils_1.boolValue)(this.component.disabled) ? this.component.disabled : false;\n /**\n * Points to the root component, usually the FormComponent.\n * @type {Component}\n */\n this.root = this.options.root || this;\n this.localRoot = this.options.localRoot || this;\n /**\n * If this input has been input and provided value.\n * @type {boolean}\n */\n this.pristine = true;\n /**\n * Points to the parent component.\n * @type {Component}\n */\n this.parent = this.options.parent;\n /**\n * The component paths for this component.\n * @type {import('@formio/core').ComponentPaths} - The component paths.\n */\n this.paths = FormioUtils.getComponentPaths(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths), { dataIndex: this.options.rowIndex === undefined ? (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.paths) === null || _d === void 0 ? void 0 : _d.dataIndex : this.options.rowIndex }));\n this.options.name = this.options.name || 'data';\n this._path = '';\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n /**\n * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.\n * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track\n * conditionallyHidden separately from \"regular\" visibility.\n */\n this._parentConditionallyHidden = this.options.hasOwnProperty('parentConditionallyHidden') ? this.options.parentConditionallyHidden : false;\n this._conditionallyHidden = this.checkConditionallyHidden(null, data) || this._parentConditionallyHidden;\n /**\n * Determines if this component is visible, or not.\n */\n this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;\n this._visible = this._parentVisible && (this.hasCondition() ? !this._conditionallyHidden : !this.component.hidden);\n this._parentDisabled = false;\n /**\n * The reference attribute name for this component\n */\n this._referenceAttributeName = 'ref';\n /**\n * Used to trigger a new change in this component.\n * @type {Function} - Call to trigger a change in this component.\n */\n let changes = [];\n let lastChanged = null;\n let triggerArgs = [];\n const _triggerChange = lodash_1.default.debounce((...args) => {\n if (this.root) {\n this.root.changing = false;\n }\n triggerArgs = [];\n if (!args[1] && lastChanged) {\n // Set the changed component if one isn't provided.\n args[1] = lastChanged;\n }\n if (lodash_1.default.isEmpty(args[0]) && lastChanged) {\n // Set the flags if it is empty and lastChanged exists.\n args[0] = lastChanged.flags;\n }\n lastChanged = null;\n args[3] = changes;\n const retVal = this.onChange(...args);\n changes = [];\n return retVal;\n }, 100);\n this.triggerChange = (...args) => {\n if (args[1]) {\n // Make sure that during the debounce that we always track lastChanged component, even if they\n // don't provide one later.\n lastChanged = args[1];\n changes.push(lastChanged);\n }\n if (this.root) {\n this.root.changing = true;\n }\n if (args.length) {\n triggerArgs = args;\n }\n return _triggerChange(...triggerArgs);\n };\n /**\n * Used to trigger a redraw event within this component.\n * @type {Function}\n */\n this.triggerRedraw = lodash_1.default.debounce(this.redraw.bind(this), 100);\n /**\n * list of attached tooltips\n * @type {Array}\n */\n this.tooltips = [];\n /**\n * List of attached addons\n * @type {Array}\n */\n this.addons = [];\n // To force this component to be invalid.\n this.invalid = false;\n if (this.component) {\n this.type = this.component.type;\n if (this.allowData && this.key) {\n this.options.name += `[${this.key}]`;\n // If component is visible or not set to clear on hide, set the default value.\n if (!(this.conditionallyHidden && this.component.clearOnHide)) {\n if (!this.hasValue()) {\n if (this.shouldAddDefaultValue) {\n this.dataValue = this.defaultValue;\n }\n }\n else {\n // Ensure the dataValue is set.\n /* eslint-disable no-self-assign */\n this.dataValue = this.dataValue;\n /* eslint-enable no-self-assign */\n }\n }\n }\n /**\n * The element information for creating the input element.\n * @type {*}\n */\n this.info = this.elementInfo();\n }\n // Allow anyone to hook into the component creation.\n this.hook('component');\n if (!this.options.skipInit) {\n if (typeof this.beforeInit === 'function') {\n this.beforeInit();\n }\n this.init();\n }\n }\n /* eslint-enable max-statements */\n get componentsMap() {\n var _a;\n return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.childComponentsMap) || {};\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n }\n mergeSchema(component = {}) {\n return lodash_1.default.defaultsDeep(component, this.defaultSchema);\n }\n // Allow componets to notify when ready.\n get ready() {\n return Promise.resolve(this);\n }\n get isPDFReadOnlyMode() {\n return this.parent &&\n this.parent.form &&\n (this.parent.form.display === 'pdf') &&\n this.options.readOnly;\n }\n get labelInfo() {\n const label = {};\n label.hidden = this.labelIsHidden();\n label.className = '';\n label.labelPosition = this.component.labelPosition;\n label.tooltipClass = `${this.iconClass('question-sign')} text-muted`;\n const isPDFReadOnlyMode = this.isPDFReadOnlyMode;\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required) && !isPDFReadOnlyMode) {\n label.className += ' field-required';\n }\n if (label.hidden) {\n label.className += ' control-label--hidden';\n }\n if (this.info.attr.id) {\n label.for = this.info.attr.id;\n }\n return label;\n }\n init() {\n var _a;\n this.disabled = this.shouldDisabled;\n this._conditionallyHidden = this.checkConditionallyHidden();\n this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);\n if ((_a = this.component.addons) === null || _a === void 0 ? void 0 : _a.length) {\n this.component.addons.forEach((addon) => this.createAddon(addon));\n }\n }\n /**\n * Get Row Index.\n * @returns {number} - The row index.\n */\n get rowIndex() {\n return this._rowIndex;\n }\n /**\n * Set Row Index to row and update each component.\n * @param {number} value - The row index.\n * @returns {void}\n */\n set rowIndex(value) {\n var _a, _b;\n this.paths = FormioUtils.getComponentPaths(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (((_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths) || {})), { dataIndex: value }));\n this._rowIndex = value;\n }\n afterComponentAssign() {\n //implement in extended classes\n }\n createAddon(addonConfiguration) {\n var _a;\n const name = addonConfiguration.name;\n if (!name) {\n return;\n }\n const settings = ((_a = addonConfiguration.settings) === null || _a === void 0 ? void 0 : _a.data) || {};\n const Addon = addons_1.default[name.value];\n let addon = null;\n if (Addon) {\n const supportedComponents = Addon.info.supportedComponents;\n const supportsThisComponentType = !(supportedComponents === null || supportedComponents === void 0 ? void 0 : supportedComponents.length) ||\n supportedComponents.indexOf(this.component.type) !== -1;\n if (supportsThisComponentType) {\n addon = new Addon(settings, this);\n this.addons.push(addon);\n }\n else {\n console.warn(this.t('addonSupportTypeError', {\n type: this.component.type,\n label: name.label\n }));\n }\n }\n return addon;\n }\n teardown() {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n delete this._currentForm;\n delete this.parent;\n delete this.root;\n delete this.triggerChange;\n delete this.triggerRedraw;\n if (this.options) {\n delete this.options.root;\n delete this.options.parent;\n delete this.options.i18next;\n }\n super.teardown();\n }\n destroy(all = false) {\n super.destroy(all);\n this.detach();\n this.addons.forEach((addon) => addon.destroy());\n if (all) {\n this.teardown();\n }\n }\n get shouldDisabled() {\n return this.options.readOnly || this.component.disabled || (this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]);\n }\n get isInputComponent() {\n return !this.component.hasOwnProperty('input') || this.component.input;\n }\n get allowData() {\n return this.hasInput;\n }\n get hasInput() {\n return this.isInputComponent || (this.refs.input && this.refs.input.length);\n }\n get defaultSchema() {\n return Component.schema();\n }\n get key() {\n return lodash_1.default.get(this.component, 'key', '');\n }\n get path() {\n return this.paths.dataPath;\n }\n set path(path) {\n throw new Error(this.t('setPathError'));\n }\n set parentVisible(value) {\n this._parentVisible = value;\n }\n get parentVisible() {\n return this._parentVisible;\n }\n set parentDisabled(value) {\n this._parentDisabled = value;\n }\n get parentDisabled() {\n return this._parentDisabled;\n }\n shouldForceVisibility(component, visibility) {\n if (!this.options[visibility]) {\n return false;\n }\n if (!component) {\n component = this.component;\n }\n if (lodash_1.default.isArray(this.options[visibility])) {\n return this.options[visibility].includes(component.key);\n }\n return this.options[visibility][component.key];\n }\n shouldForceHide(component) {\n return this.shouldForceVisibility(component, 'hide');\n }\n shouldForceShow(component) {\n return this.shouldForceVisibility(component, 'show');\n }\n /**\n * Sets the component visibility.\n * @param {boolean} value - Whether the component should be visible or not.\n */\n set visible(value) {\n if (this._visible !== value) {\n // Skip if this component is set to visible and is supposed to be hidden.\n if (value && this.shouldForceHide()) {\n return;\n }\n // Skip if this component is set to hidden and is supposed to be shown.\n if (!value && this.shouldForceShow()) {\n return;\n }\n this._visible = value;\n this.redraw();\n }\n }\n /**\n * Returns the component visibility\n * @returns {boolean} - Whether the component is visible or not.\n */\n get visible() {\n // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown.\n if (this.builderMode || this.previewMode || this.options.showHiddenFields) {\n return true;\n }\n if (this.shouldForceHide()) {\n return false;\n }\n if (this.shouldForceShow()) {\n return true;\n }\n return this._visible && this._parentVisible;\n }\n get conditionallyHidden() {\n return this._conditionallyHidden || this._parentConditionallyHidden;\n }\n /**\n * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).\n * @param {object} data - The data object to evaluate the condition against.\n * @param {object} row - The row object to evaluate the condition against.\n * @returns {boolean} - Whether the component is conditionally hidden.\n */\n checkConditionallyHidden(data = null, row = null) {\n if (!this.hasCondition()) {\n return false;\n }\n return !this.conditionallyVisible(data, row);\n }\n get currentForm() {\n return this._currentForm;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n }\n get fullMode() {\n return this.options.attachMode === 'full';\n }\n get builderMode() {\n return this.options.attachMode === 'builder';\n }\n get calculatedPath() {\n console.error(this.t('calculatedPathDeprecation'));\n return this.path;\n }\n get labelPosition() {\n return this.component.labelPosition;\n }\n get labelWidth() {\n const width = this.component.labelWidth;\n return width >= 0 ? width : 30;\n }\n get labelMargin() {\n const margin = this.component.labelMargin;\n return margin >= 0 ? margin : 3;\n }\n get isAdvancedLabel() {\n return [\n 'left-left',\n 'left-right',\n 'right-left',\n 'right-right'\n ].includes(this.labelPosition);\n }\n get labelPositions() {\n return this.labelPosition.split('-');\n }\n get skipInEmail() {\n return false;\n }\n rightDirection(direction) {\n if (this.options.condensedMode) {\n return false;\n }\n return direction === 'right';\n }\n getLabelInfo(isCondensed = false) {\n const isRightPosition = this.rightDirection(this.labelPositions[0]);\n const isLeftPosition = this.labelPositions[0] === 'left' || isCondensed;\n const isRightAlign = this.rightDirection(this.labelPositions[1]);\n let contentMargin = '';\n if (this.component.hideLabel) {\n const margin = isCondensed ? 0 : this.labelWidth + this.labelMargin;\n contentMargin = isRightPosition ? `margin-right: ${margin}%` : '';\n contentMargin = isLeftPosition ? `margin-left: ${margin}%` : '';\n }\n const labelStyles = `\n flex: ${this.labelWidth};\n ${isRightPosition ? 'margin-left' : 'margin-right'}: ${this.labelMargin}%;\n `;\n const contentStyles = `\n flex: ${100 - this.labelWidth - this.labelMargin};\n ${contentMargin};\n ${this.component.hideLabel ? `max-width: ${100 - this.labelWidth - this.labelMargin}` : ''};\n `;\n return {\n isRightPosition,\n isRightAlign,\n labelStyles,\n contentStyles\n };\n }\n /**\n * Returns only the schema that is different from the default.\n * @param {object} schema - The \"full\" json schema for the component.\n * @param {object} defaultSchema - The \"default\" json schema for the component.\n * @param {boolean} recursion - If we are currently in a recursive loop.\n * @returns {object} - The minified json schema for this component.\n */\n getModifiedSchema(schema, defaultSchema, recursion) {\n const modified = {};\n if (!defaultSchema) {\n return schema;\n }\n lodash_1.default.each(schema, (val, key) => {\n if (!lodash_1.default.isArray(val) && lodash_1.default.isObject(val) && defaultSchema.hasOwnProperty(key)) {\n const subModified = this.getModifiedSchema(val, defaultSchema[key], true);\n if (!lodash_1.default.isEmpty(subModified)) {\n modified[key] = subModified;\n }\n }\n else if (lodash_1.default.isArray(val)) {\n if (val.length !== 0 && !lodash_1.default.isEqual(val, defaultSchema[key])) {\n modified[key] = val;\n }\n }\n else if ((!recursion && (key === 'type')) ||\n (!recursion && (key === 'key')) ||\n (!recursion && (key === 'label')) ||\n (!recursion && (key === 'input')) ||\n (!recursion && (key === 'tableView')) ||\n (val !== '' && !defaultSchema.hasOwnProperty(key)) ||\n (val !== '' && val !== defaultSchema[key]) ||\n (defaultSchema[key] && val !== defaultSchema[key])) {\n modified[key] = val;\n }\n });\n return modified;\n }\n /**\n * Returns the JSON schema for this component.\n * @returns {object} - The JSON schema for this component.\n */\n get schema() {\n return (0, utils_1.fastCloneDeep)(this.getModifiedSchema(lodash_1.default.omit(this.component, 'id'), this.defaultSchema));\n }\n /**\n * Returns true if component is inside DataGrid\n * @returns {boolean} - True if component is inside DataGrid\n */\n get isInDataGrid() {\n return this.inDataGrid;\n }\n /**\n * Translate a text using the i18n system.\n * @param {string} text - The i18n identifier.\n * @param {object} params - The i18n parameters to use for translation.\n * @param {...any} args - Additional arguments to pass to the translation library.\n * @returns {string} - The translated text.\n */\n t(text, params = {}, ...args) {\n if (!text) {\n return '';\n }\n // Use _userInput: true to ignore translations from defaults\n if (text in en_1.default && params._userInput) {\n return text;\n }\n params.data = params.data || this.rootValue;\n params.row = params.row || this.data;\n params.component = params.component || this.component;\n return super.t(text, params, ...args);\n }\n labelIsHidden() {\n return !this.component.label ||\n ((!this.isInDataGrid && this.component.hideLabel) ||\n (this.isInDataGrid && !this.component.dataGridLabel) ||\n this.options.floatingLabels ||\n this.options.inputsOnly) && !this.builderMode;\n }\n transform(type, value) {\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n return frameworkTemplates.hasOwnProperty('transform')\n ? frameworkTemplates.transform(type, value, this)\n : (type, value) => value;\n }\n getTemplate(names, modes) {\n modes = Array.isArray(modes) ? modes : [modes];\n names = Array.isArray(names) ? names : [names];\n if (!modes.includes('form')) {\n modes.push('form');\n }\n let result = null;\n if (this.options.templates) {\n result = this.checkTemplate(this.options.templates, names, modes);\n if (result) {\n return result;\n }\n }\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n result = this.checkTemplate(frameworkTemplates, names, modes);\n if (result) {\n return result;\n }\n // Default back to bootstrap if not defined.\n const name = names[names.length - 1];\n const templatesByName = Templates_1.default.defaultTemplates[name];\n if (!templatesByName) {\n return { template: this.t('unknownTemplate', { name }) };\n }\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode };\n }\n return { template: templatesByName.form };\n }\n checkTemplate(templates, names, modes) {\n for (const name of names) {\n const templatesByName = templates[name];\n if (templatesByName) {\n const { referenceAttributeName } = templatesByName;\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode, referenceAttributeName };\n }\n }\n }\n return null;\n }\n checkTemplateMode(templatesByName, modes) {\n for (const mode of modes) {\n const templateByMode = templatesByName[mode];\n if (templateByMode) {\n return templateByMode;\n }\n }\n return null;\n }\n getFormattedAttribute(attr) {\n return attr ? this.t(attr, { _userInput: true }).replace(/\"/g, '"') : '';\n }\n getFormattedTooltip(tooltipValue) {\n const tooltip = this.interpolate(tooltipValue || '').replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return this.getFormattedAttribute(tooltip);\n }\n isHtmlRenderMode() {\n return this.options.renderMode === 'html';\n }\n renderTemplate(name, data = {}, modeOption = '') {\n // Need to make this fall back to form if renderMode is not found similar to how we search templates.\n const mode = modeOption || this.options.renderMode || 'form';\n data.component = this.component;\n data.self = this;\n data.options = this.options;\n data.readOnly = this.options.readOnly;\n data.iconClass = this.iconClass.bind(this);\n data.size = this.size.bind(this);\n data.t = this.t.bind(this);\n data.transform = this.transform.bind(this);\n data.id = data.id || this.id;\n data.key = data.key || this.key;\n data.value = data.value || this.dataValue;\n data.disabled = this.disabled;\n data.builder = this.builderMode;\n data.render = (...args) => {\n console.warn(this.t('renderTemplateFunctionDeprecation'));\n return this.renderTemplate(...args);\n };\n data.label = data.labelInfo || this.labelInfo;\n data.tooltip = this.getFormattedTooltip(this.component.tooltip);\n // Allow more specific template names\n const names = [\n `${name}-${this.component.type}-${this.key}`,\n `${name}-${this.component.type}`,\n `${name}-${this.key}`,\n `${name}`,\n ];\n // Allow template alters.\n const { referenceAttributeName, template } = this.getTemplate(names, mode);\n if (referenceAttributeName) {\n this._referenceAttributeName = referenceAttributeName;\n }\n return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);\n }\n /**\n * Sanitize an html string.\n * @param {string} dirty - The dirty html string to sanitize.\n * @param {boolean} forceSanitize - If we should force the sanitize to occur.\n * @param {object} options - The options for the sanitize.\n * @returns {*} - The sanitized html string.\n */\n sanitize(dirty, forceSanitize = false, options = {}) {\n var _a;\n if (!this.shouldSanitizeValue && !forceSanitize) {\n return dirty;\n }\n return FormioUtils.sanitize(dirty, {\n sanitizeConfig: lodash_1.default.merge(((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitizeConfig) || {}, options || {}),\n });\n }\n /**\n * Render a template string into html.\n * @param {string} template - The template to render.\n * @param {object} data - The data to provide to the template.\n * @returns {HTMLElement | string} - The created element or an empty string if template is not specified.\n */\n renderString(template, data) {\n if (!template) {\n return '';\n }\n // Interpolate the template and populate\n return this.interpolate(template, data);\n }\n /**\n * Allows for modification of the component value prior to submission.\n * @param {*} input - The input to be modified.\n * @returns {*} - The modified input mapping for the extended component.\n */\n performInputMapping(input) {\n return input;\n }\n /**\n * Returns the component \"widget\" if one is available.\n * @returns {Widget|null} - The widget instance. null if not available.\n */\n get widget() {\n var _a;\n const settings = this.component.widget;\n if (settings && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.shadowRoot)) {\n settings.shadowRoot = this.root.shadowRoot;\n }\n const widget = settings && widgets_1.default[settings.type] ? new widgets_1.default[settings.type](settings, this.component, this) : null;\n return widget;\n }\n /**\n * Returns the native supported browser language.\n * @returns {string|null} - The native browser language that is supported.\n */\n getBrowserLanguage() {\n const nav = window.navigator;\n const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];\n let language;\n // support for HTML 5.1 \"navigator.languages\"\n if (Array.isArray(nav.languages)) {\n for (let i = 0; i < nav.languages.length; i++) {\n language = nav.languages[i];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n }\n // support for other well known properties in browsers\n for (let i = 0; i < browserLanguagePropertyKeys.length; i++) {\n language = nav[browserLanguagePropertyKeys[i]];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n return null;\n }\n /**\n * Called before a next and previous page is triggered allowing the components to perform special functions.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the next/previous page navigation.\n */\n beforePage() {\n return Promise.resolve(true);\n }\n /**\n * Called before the next page is triggered allowing the components to hook into the page navigation and perform tasks.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the next page navigation.\n */\n beforeNext() {\n return this.beforePage(true);\n }\n /**\n * Called before a submission is triggered allowing the components to perform special async functions.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the submission.\n */\n beforeSubmit() {\n return Promise.resolve(true);\n }\n /**\n * Return the submission timezone.\n * @returns {string} - The submission timezone.\n */\n get submissionTimezone() {\n this.options.submissionTimezone = this.options.submissionTimezone || lodash_1.default.get(this.root, 'options.submissionTimezone');\n return this.options.submissionTimezone;\n }\n /**\n * Return the current timezone.\n * @returns {string} - The current timezone.\n */\n get timezone() {\n return this.getTimezone(this.component);\n }\n /**\n * Return the current timezone.\n * @param {object} settings - Settings to control how the timezone should be returned.\n * @returns {string} - The current timezone.\n */\n getTimezone(settings) {\n if (settings.timezone) {\n return settings.timezone;\n }\n if (settings.displayInTimezone === 'utc') {\n return 'UTC';\n }\n const submissionTimezone = this.submissionTimezone;\n if (submissionTimezone &&\n ((settings.displayInTimezone === 'submission') ||\n ((this.options.pdf || this.options.server) && (settings.displayInTimezone === 'viewer')))) {\n return submissionTimezone;\n }\n // Return current timezone if none are provided.\n return (0, utils_1.currentTimezone)();\n }\n /**\n *\n * @param {HTMLElement} element - The containing DOM element to query for the ref value.\n * @param {object} refs - The references to load.\n * @param {string} [referenceAttributeName] - The attribute name to use for the reference.\n */\n loadRefs(element, refs, referenceAttributeName) {\n if (!element) {\n return;\n }\n for (const ref in refs) {\n const refType = refs[ref];\n const isString = typeof refType === 'string';\n const selector = isString && refType.includes('scope')\n ? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`\n : `[${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`;\n if (isString && refType.startsWith('single')) {\n this.refs[ref] = element.querySelector(selector);\n }\n else {\n this.refs[ref] = element.querySelectorAll(selector);\n }\n }\n }\n /**\n * Opens the modal element.\n * @param {string} template - The template to use for the modal dialog.\n */\n setOpenModalElement(template = null) {\n this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());\n }\n /**\n * Renders a modal preview template and returns the markup as a string\n * @param {object|null|undefined} ctx - The rendering context\n * @returns {string} - The modal preview markup\n */\n renderModalPreview(ctx) {\n return this.renderTemplate('modalPreview', ctx || {});\n }\n /**\n * Returns the modal preview template.\n * @returns {string} - The modal preview template.\n */\n getModalPreviewTemplate() {\n var _a;\n const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;\n let modalLabel;\n if (this.hasInput && ((_a = this.component.validate) === null || _a === void 0 ? void 0 : _a.required) && !this.isPDFReadOnlyMode) {\n modalLabel = { className: 'field-required' };\n }\n return this.renderModalPreview({\n previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('clickToSetValue'),\n messages: '',\n labelInfo: modalLabel,\n });\n }\n /**\n * Performs a complete build of a component, which empties, renders, sets the content in the DOM, and then finally attaches events.\n * @param {HTMLElement} element - The element to attach this component to.\n * @returns {Promise<void>} - A promise that resolves when the component has been built.\n */\n build(element) {\n element = element || this.element;\n this.empty(element);\n this.setContent(element, this.render());\n return this.attach(element);\n }\n get hasModalSaveButton() {\n return true;\n }\n /**\n * Renders a component as an HTML string.\n * @param {string} children - The contents of all the children HTML as a string.\n * @param {boolean} topLevel - If this is the topmost component that is being rendered.\n * @returns {string} - The rendered HTML string of a component.\n */\n render(children = this.t('unknownComponent', { type: this.component.type }), topLevel = false) {\n const isVisible = this.visible;\n this.rendered = true;\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n return ComponentModal_1.default.render(this, {\n visible: isVisible,\n showSaveButton: this.hasModalSaveButton,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n else {\n return this.renderTemplate('component', {\n visible: isVisible,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n }\n /**\n * Creates the tooltip instance using tippy.js and returns it\n * @param {HTMLElement} tooltipEl - HTML element to attach the tooltip\n * @param {object|null|undefined} settings - tippy.js options\n * @returns {import('tippy.js').Tippy} - tippy.js instance\n */\n createTooltip(tooltipEl, settings = {}) {\n const tooltipAttribute = tooltipEl.getAttribute('data-tooltip');\n const tooltipDataTitle = tooltipEl.getAttribute('data-title');\n const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)\n .replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return (0, tippy_js_1.default)(tooltipEl, Object.assign(Object.assign({ allowHTML: true, trigger: 'mouseenter click focus', placement: 'right', zIndex: 10000, interactive: true }, settings), { content: this.t(this.sanitize(tooltipText), { _userInput: true }) }));\n }\n /**\n * Attaches all the tooltips provided the refs object.\n * @param {object} toolTipsRefs - The refs for the tooltips within your template.\n * @returns {void}\n */\n attachTooltips(toolTipsRefs) {\n toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach((tooltip, index) => {\n if (tooltip) {\n this.tooltips[index] = this.createTooltip(tooltip);\n }\n });\n }\n /**\n * Create a new component modal for this component.\n * @param {HTMLElement} element - The element to attach the modal to.\n * @param {boolean} modalShouldBeOpened - TRUE if the modal should open immediately.\n * @param {any} currentValue - The current value of the component.\n * @returns {ComponentModal} - The created component modal.\n */\n createComponentModal(element, modalShouldBeOpened, currentValue) {\n return new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n }\n /**\n * Attaches all event listensers for this component to the DOM elements that were rendered.\n * @param {HTMLElement} element - The element to attach the listeners to.\n * @returns {Promise<void>} - Resolves when the component is done attaching to the DOM.\n */\n attach(element) {\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n const openModalTemplate = this.componentModal && modalShouldBeOpened\n ? this.componentModal.openModalTemplate\n : null;\n this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue);\n this.setOpenModalElement(openModalTemplate);\n }\n this.attached = true;\n this.setElement(element);\n element.component = this;\n // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id.\n if (this.element.id) {\n this.id = this.element.id;\n this.component.id = this.id;\n }\n this.loadRefs(element, {\n messageContainer: 'single',\n tooltip: 'multiple'\n });\n this.attachTooltips(this.refs.tooltip);\n // Attach logic.\n this.attachLogic();\n this.autofocus();\n // Allow global attach.\n this.hook('attachComponent', element, this);\n // Allow attach per component type.\n const type = this.component.type;\n if (type) {\n this.hook(`attach${type.charAt(0).toUpperCase() + type.substring(1, type.length)}`, element, this);\n }\n this.restoreFocus();\n this.addons.forEach((addon) => addon.attach(element));\n return Promise.resolve();\n }\n /**\n * Restors the \"focus\" on a component after a redraw event has occured.\n */\n restoreFocus() {\n var _a, _b, _c;\n const isFocused = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.path) === this.path;\n if (isFocused) {\n this.loadRefs(this.element, { input: 'multiple' });\n this.focus((_c = this.root.currentSelection) === null || _c === void 0 ? void 0 : _c.index);\n this.restoreCaretPosition();\n }\n }\n /**\n * Adds a keyboard shortcut to this component.\n * @param {HTMLElement} element - The element to attach the keyboard shortcut to.\n * @param {string} shortcut - The keyboard shortcut to add.\n * @returns {void}\n */\n addShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || !this.root || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.addShortcut(element, shortcut);\n }\n /**\n * Removes a keyboard shortcut from this component.\n * @param {HTMLElement} element - The element to remove the keyboard shortcut from.\n * @param {string} shortcut - The keyboard shortcut to remove.\n * @returns {void}\n */\n removeShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.removeShortcut(element, shortcut);\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n // First iterate through each ref and delete the component so there are no dangling component references.\n lodash_1.default.each(this.refs, (ref) => {\n if (ref instanceof NodeList) {\n ref.forEach((elem) => {\n delete elem.component;\n });\n }\n else if (ref) {\n delete ref.component;\n }\n });\n this.refs = {};\n this.removeEventListeners();\n this.detachLogic();\n if (this.tooltip) {\n this.tooltip.destroy();\n }\n }\n /**\n * Determines if the component should be refreshed based on the path of another component that changed.\n * @param {string} refreshData - The path of the data that needs to trigger a refresh.\n * @param {boolean} changed - Flag that is true if the data has been changed.\n * @param {any} flags - The flags for the checkData procedure.\n * @returns {void}\n */\n checkRefresh(refreshData, changed, flags) {\n var _a, _b;\n const changePath = lodash_1.default.get(changed, 'instance.path', false);\n // Don't let components change themselves.\n if (changePath && this.path === changePath) {\n return;\n }\n if (refreshData === 'data') {\n this.refresh(this.data, changed, flags);\n }\n else if ((changePath && (((_b = (_a = changed.instance) === null || _a === void 0 ? void 0 : _a.paths) === null || _b === void 0 ? void 0 : _b.localPath) === refreshData)) && changed && changed.instance &&\n // Make sure the changed component is not in a different \"context\". Solves issues where refreshOn being set\n // in fields inside EditGrids could alter their state from other rows (which is bad).\n this.inContext(changed.instance)) {\n this.refresh(changed.value, changed, flags);\n }\n }\n /**\n * Iterates over a list of changes, and determines if the component should be refreshed if it is configured to refresh on any of those components.\n * @param {Array<any>} changes - The list of components that have changed.\n * @param {any} flags - The checkData flags.\n * @returns {void}\n */\n checkRefreshOn(changes, flags = {}) {\n changes = changes || [];\n if (flags.noRefresh) {\n return;\n }\n if (!changes.length && flags.changed) {\n changes = [flags.changed];\n }\n const refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn;\n // If they wish to refresh on a value, then add that here.\n if (refreshOn) {\n if (Array.isArray(refreshOn)) {\n refreshOn.forEach(refreshData => changes.forEach(changed => this.checkRefresh(refreshData, changed, flags)));\n }\n else {\n changes.forEach(changed => this.checkRefresh(refreshOn, changed, flags));\n }\n }\n }\n /**\n * Refreshes the component with a new value.\n * @param {any} value - The latest value of the component to check if it needs to be refreshed.\n * @returns {void}\n */\n refresh(value) {\n if (this.hasOwnProperty('refreshOnValue')) {\n this.refreshOnChanged = !lodash_1.default.isEqual(value, this.refreshOnValue);\n }\n else {\n this.refreshOnChanged = true;\n }\n this.refreshOnValue = (0, utils_1.fastCloneDeep)(value);\n if (this.refreshOnChanged) {\n if (this.component.clearOnRefresh) {\n this.setValue(null);\n }\n this.triggerRedraw();\n }\n }\n /**\n * Checks to see if a separate component is in the \"context\" of this component. This is determined by first checking\n * if they share the same \"data\" object. It will then walk up the parent tree and compare its parents data objects\n * with the components data and returns true if they are in the same context.\n *\n * Different rows of the same EditGrid, for example, are in different contexts.\n * @param {any} component - The component to check if it is in the same context as this component.\n * @returns {boolean} - TRUE if the component is in the same context as this component.\n */\n inContext(component) {\n if (component.data === this.data) {\n return true;\n }\n let parent = this.parent;\n while (parent) {\n if (parent.data === component.data) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n /**\n * Determines if we are in \"view\" only mode.\n * @returns {boolean} - TRUE if we are in \"view\" only mode.\n */\n get viewOnly() {\n return this.options.readOnly && this.options.viewAsHtml;\n }\n /**\n * Sets the HTMLElement for this component.\n * @param {HTMLElement} element - The element that is attached to this component.\n * @returns {void}\n */\n setElement(element) {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n this.element = element;\n }\n /**\n * Creates an element to hold the \"view only\" version of this component.\n * @returns {HTMLElement} - The element for this component.\n */\n createViewOnlyElement() {\n this.setElement(this.ce('dl', {\n id: this.id\n }));\n if (this.element) {\n // Ensure you can get the component info from the element.\n this.element.component = this;\n }\n return this.element;\n }\n /**\n * The default value for the \"view only\" mode of a component if the value is not provided.\n * @returns {string} - The default value for this component.\n */\n get defaultViewOnlyValue() {\n return '-';\n }\n /**\n * Uses the widget to determine the output string.\n * @param {any} value - The current value of the component.\n * @param {any} options - The options for getValueAsString.\n * @returns {any|Array<any>} - The value as a string.\n */\n getWidgetValueAsString(value, options) {\n const noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget;\n if (!value || noInputWidget) {\n if (!this.widget || !value) {\n return value;\n }\n else {\n return this.widget.getValueAsString(value);\n }\n }\n if (Array.isArray(value)) {\n const values = [];\n value.forEach((val, index) => {\n const widget = this.refs.input[index] && this.refs.input[index].widget;\n if (widget) {\n values.push(widget.getValueAsString(val, options));\n }\n });\n return values;\n }\n const widget = this.refs.input[0].widget;\n return widget.getValueAsString(value, options);\n }\n /**\n * Returns the value of the component as a string.\n * @param {any} value - The value for this component.\n * @param {any} options - The options for this component.\n * @returns {string} - The string representation of the value of this component.\n */\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n value = this.getWidgetValueAsString(value, options);\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n if (lodash_1.default.isPlainObject(value)) {\n return JSON.stringify(value);\n }\n if (value === null || value === undefined) {\n return '';\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue);\n }\n /**\n * Returns the string representation \"view\" of the component value.\n * @param {any} value - The value of the component.\n * @param {any} options - The options for this component.\n * @returns {string} - The string representation of the value of this component.\n */\n getView(value, options) {\n if (this.component.protected) {\n return '--- PROTECTED ---';\n }\n return this.getValueAsString(value, options);\n }\n /**\n * Updates the items list for this component. Useful for Select and other List component types.\n * @param {...any} args - The arguments to pass to the onChange event.\n * @returns {void}\n */\n updateItems(...args) {\n this.restoreValue();\n this.onChange(...args);\n }\n /**\n * Returns the value for a specific item in a List type component.\n * @param {any} data - The data for this component.\n * @param {boolean} [forceUseValue] - if true, return 'value' property of the data\n * @returns {any} - The value of the item.\n */\n itemValue(data, forceUseValue = false) {\n if (lodash_1.default.isObject(data) && !lodash_1.default.isArray(data)) {\n if (this.valueProperty) {\n return lodash_1.default.get(data, this.valueProperty);\n }\n if (forceUseValue) {\n return data.value;\n }\n }\n return data;\n }\n /**\n * Returns the item value for html mode.\n * @param {any} value - The value for this component.\n * @returns {any} - The value of the item for html mode.\n */\n itemValueForHTMLMode(value) {\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item) ? this.itemValueForHTMLMode(item) : this.itemValue(item));\n return values.join(', ');\n }\n return this.itemValue(value);\n }\n /**\n * Creates a modal to input the value of this component.\n * @param {HTMLElement} element - The element to attach the modal to.\n * @param {any} attr - A list of attributes to add to the modal.\n * @param {boolean} confirm - If we should add a confirmation to the modal that keeps it from closing unless confirmed.\n * @returns {HTMLElement} - The created modal element.\n */\n createModal(element, attr, confirm) {\n const dialog = this.ce('div', attr || {});\n this.setContent(dialog, this.renderTemplate('dialog'));\n // Add refs to dialog, not \"this\".\n dialog.refs = {};\n this.loadRefs.call(dialog, dialog, {\n dialogOverlay: 'single',\n dialogContents: 'single',\n dialogClose: 'single',\n });\n dialog.refs.dialogContents.appendChild(element);\n document.body.appendChild(dialog);\n document.body.classList.add('modal-open');\n dialog.close = () => {\n document.body.classList.remove('modal-open');\n dialog.dispatchEvent(new CustomEvent('close'));\n };\n this.addEventListener(dialog, 'close', () => this.removeChildFrom(dialog, document.body));\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n const handleCloseClick = (e) => {\n if (confirm) {\n confirm().then(() => close(e))\n .catch(() => { });\n }\n else {\n close(e);\n }\n };\n this.addEventListener(dialog.refs.dialogOverlay, 'click', handleCloseClick);\n this.addEventListener(dialog.refs.dialogClose, 'click', handleCloseClick);\n return dialog;\n }\n /**\n * Uses CSS classes to show or hide an element.\n * @returns {boolean} - TRUE if the element has been css removed.\n */\n get optimizeRedraw() {\n if (this.options.optimizeRedraw && this.element && !this.visible) {\n this.addClass(this.element, 'formio-removed');\n return true;\n }\n return false;\n }\n /**\n * Retrieves the CSS class name of this component.\n * @returns {string} - The class name of this component.\n */\n get className() {\n let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback ` : '';\n className += `formio-component formio-component-${this.component.type} `;\n // TODO: find proper way to avoid overriding of default type-based component styles\n if (this.key && this.key !== 'form') {\n className += `formio-component-${this.key} `;\n }\n if (this.component.multiple) {\n className += 'formio-component-multiple ';\n }\n if (this.component.customClass) {\n className += this.component.customClass;\n }\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required)) {\n className += ' required';\n }\n if (this.labelIsHidden()) {\n className += ' formio-component-label-hidden';\n }\n if (!this.visible) {\n className += ' formio-hidden';\n }\n return className;\n }\n /**\n * Build the custom style from the layout values\n * @returns {string} - The custom style\n */\n get customStyle() {\n let customCSS = '';\n lodash_1.default.each(this.component.style, (value, key) => {\n if (value !== '') {\n customCSS += `${key}:${value};`;\n }\n });\n return customCSS;\n }\n /**\n * Returns the component condition operator settings if available.\n * @returns {object} - The component condition operator settings.\n */\n static get serverConditionSettings() {\n return Component.conditionOperatorsSettings;\n }\n /**\n * Returns if the application is on a mobile device.\n * @returns {boolean} - TRUE if the application is on a mobile device.\n */\n get isMobile() {\n return (0, ismobilejs_1.default)();\n }\n /**\n * Returns the outside wrapping element of this component.\n * @returns {HTMLElement} - The wrapping element of this component.\n */\n getElement() {\n return this.element;\n }\n /**\n * Create an evaluation context for all script executions and interpolations.\n * @param {any} additional - Additional context to provide.\n * @returns {any} - The evaluation context.\n */\n evalContext(additional) {\n return super.evalContext(Object.assign({\n component: this.component,\n row: this.data,\n rowIndex: this.rowIndex,\n data: this.rootValue,\n iconClass: this.iconClass.bind(this),\n // Bind the translate function to the data context of any interpolated string.\n // It is useful to translate strings in different scenarions (eg: custom edit grid templates, custom error messages etc.)\n // and desirable to be publicly available rather than calling the internal {instance.t} function in the template string.\n t: this.t.bind(this),\n submission: (this.root ? this.root._submission : {\n data: this.rootValue\n }),\n form: this.root ? this.root._form : {},\n options: this.options,\n }, additional));\n }\n /**\n * Sets the pristine flag for this component.\n * @param {boolean} pristine - TRUE to make pristine, FALSE not pristine.\n */\n setPristine(pristine) {\n this.pristine = pristine;\n }\n /**\n * Returns if the component is pristine.\n * @returns {boolean} - TRUE if the component is pristine.\n */\n get isPristine() {\n return this.pristine;\n }\n /**\n * Sets the dirty flag for this component.\n * @param {boolean} dirty - TRUE to make dirty, FALSE not dirty.\n */\n setDirty(dirty) {\n this.dirty = dirty;\n }\n /**\n * Returns if the component is dirty.\n * @returns {boolean} - TRUE if the component is dirty.\n */\n get isDirty() {\n return this.dirty;\n }\n /**\n * Removes a value out of the data array and rebuild the rows.\n * @param {number} index - The index of the data element to remove.\n */\n removeValue(index) {\n this.splice(index);\n this.redraw();\n this.restoreValue();\n this.triggerRootChange();\n }\n /**\n * Returns the icon class for a given icon name.\n * @param {string} name - The name of the icon you wish to fetch provided the icon class. This is the \"font awesome\" version of the name of the icon.\n * @param {boolean} spinning - If the component should be spinning.\n * @returns {string} - The icon class for the equivalent icon in the iconset we are using.\n */\n iconClass(name, spinning) {\n const iconset = this.options.iconset || Templates_1.default.current.defaultIconset || 'fa';\n return Templates_1.default.current.hasOwnProperty('iconClass')\n ? Templates_1.default.current.iconClass(iconset, name, spinning)\n : this.options.iconset === 'fa' ? Templates_1.default.defaultTemplates.iconClass(iconset, name, spinning) : name;\n }\n /**\n * Returns the size css class names for our current template.\n * @param {string} size - The size class name for the default iconset.\n * @returns {string} - The size class for our component.\n */\n size(size) {\n return Templates_1.default.current.hasOwnProperty('size')\n ? Templates_1.default.current.size(size)\n : size;\n }\n /**\n * The readible name for this component.\n * @returns {string} - The name of the component.\n */\n get name() {\n return this.t(this.component.label || this.component.placeholder || this.key, { _userInput: true });\n }\n /**\n * Returns the visible errors for this component.\n * @returns {Array<object>} - The visible errors for this component.\n */\n get visibleErrors() {\n return this._visibleErrors;\n }\n /**\n * Returns all the errors for this component, visible or not.\n * @returns {Array<object>} - All the errors for this component.\n */\n get errors() {\n return this._errors;\n }\n /**\n * Returns the error label for this component.\n * @returns {string} - The error label for this component.\n */\n get errorLabel() {\n return this.t(this.component.errorLabel\n || this.component.label\n || this.component.placeholder\n || this.key);\n }\n /**\n * Get the error message provided a certain type of error.\n * @param {string} type - The type of error to fetch the message for.\n * @returns {string} - The error message configured for this component.\n */\n errorMessage(type) {\n return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type;\n }\n /**\n * Sets the content, innerHTML, of an element to the sanitized content.\n * @param {HTMLElement} element - The element to set the innerHTML to.\n * @param {string} content - The HTML string content that we wish to set.\n * @param {boolean} forceSanitize - If we should force the content to be sanitized.\n * @param {any} sanitizeOptions - The options for the sanitize function.\n * @returns {boolean} - TRUE if the content was sanitized and set.\n */\n setContent(element, content, forceSanitize, sanitizeOptions) {\n if (element instanceof HTMLElement) {\n element.innerHTML = this.sanitize(content, forceSanitize, sanitizeOptions);\n return true;\n }\n return false;\n }\n /**\n * Restores the caret position in the input element after a refresh occurs.\n */\n restoreCaretPosition() {\n var _a, _b, _c;\n if ((_a = this.root) === null || _a === void 0 ? void 0 : _a.currentSelection) {\n if ((_b = this.refs.input) === null || _b === void 0 ? void 0 : _b.length) {\n const { index } = this.root.currentSelection;\n let input = this.refs.input[index];\n const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test((i === null || i === void 0 ? void 0 : i.type) || '');\n if (input) {\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(input.value.length, input.value.length);\n }\n }\n else {\n input = this.refs.input[this.refs.input.length];\n const lastCharacter = ((_c = input.value) === null || _c === void 0 ? void 0 : _c.length) || 0;\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(lastCharacter, lastCharacter);\n }\n }\n }\n }\n }\n /**\n * Redraw the component.\n * @returns {Promise<void>} - A promise that resolves when the component is done redrawing.\n */\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element || !this.element.parentNode || this.optimizeRedraw) {\n // Return a non-resolving promise.\n return Promise.resolve();\n }\n this.detach();\n this.emit('redraw');\n // Since we are going to replace the element, we need to know it's position so we can find it in the parent's children.\n const parent = this.element.parentNode;\n const index = Array.prototype.indexOf.call(parent.children, this.element);\n this.element.outerHTML = this.sanitize(this.render());\n this.setElement(parent.children[index]);\n return this.attach(this.element);\n }\n /**\n * Rebuild and redraw a component.\n * @returns {Promise<void>} - A promise that resolves when the component is done rebuilding and redrawing.\n */\n rebuild() {\n this.destroy();\n this.init();\n this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;\n return this.redraw();\n }\n /**\n * Removes all event listeners attached to this component.\n */\n removeEventListeners() {\n super.removeEventListeners();\n this.tooltips.forEach(tooltip => tooltip.destroy());\n this.tooltips = [];\n }\n /**\n * Returns if the dom node has the classes provided.\n * @param {HTMLElement} element - The element to check for the class.\n * @param {string} className - The name of the class to check.\n * @returns {boolean|void} - TRUE if the element has the class.\n */\n hasClass(element, className) {\n if (!element) {\n return;\n }\n return super.hasClass(element, this.transform('class', className));\n }\n /**\n * Adds a class to an HTML element.\n * @param {HTMLElement} element - The dom element to add the class to.\n * @param {string} className - The class name you wish to add.\n * @returns {this|void} - The component instance.\n */\n addClass(element, className) {\n if (!element) {\n return;\n }\n return super.addClass(element, this.transform('class', className));\n }\n /**\n * Removes a class from an element.\n * @param {HTMLElement} element - The element to remove the class from.\n * @param {string} className - The class name to remove.\n * @returns {this|void} - The component instance.\n */\n removeClass(element, className) {\n if (!element) {\n return;\n }\n return super.removeClass(element, this.transform('class', className));\n }\n /**\n * Determines if this component has a condition defined.\n * @returns {boolean} - TRUE if the component has a condition defined.\n */\n hasCondition() {\n if (this._hasCondition !== null) {\n return this._hasCondition;\n }\n this._hasCondition = FormioUtils.hasCondition(this.component);\n return this._hasCondition;\n }\n /**\n * Check if this component is conditionally visible.\n * @param {any} data - The data to check against.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is conditionally visible.\n */\n conditionallyVisible(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n if (this.builderMode || this.previewMode) {\n return true;\n }\n data = data || (this.root ? this.root.data : {});\n return this.checkCondition(row, data);\n }\n /**\n * Checks the condition of this component.\n *\n * TODO: Switch row and data parameters to be consistent with other methods.\n * @param {any} row - The row contextual data.\n * @param {any} data - The global data object.\n * @returns {boolean} - True if the condition applies to this component.\n */\n checkCondition(row, data) {\n return FormioUtils.checkCondition(this.component, row || this.data, data || this.rootValue, this.root ? this.root._form : {}, this);\n }\n /**\n * Check for conditionals and hide/show the element based on those conditions.\n * @param {any} data - The data to check against.\n * @param {any} flags - The flags passed to checkData function.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is visible.\n */\n checkComponentConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {\n this.redraw();\n }\n // Check advanced conditions (and cache the result)\n const isConditionallyHidden = this.checkConditionallyHidden(data, row) || this._parentConditionallyHidden;\n let shouldClear = false;\n if (isConditionallyHidden !== this._conditionallyHidden) {\n this._conditionallyHidden = isConditionallyHidden;\n shouldClear = true;\n }\n // Check visibility\n const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);\n if (this.visible !== visible) {\n this.visible = visible;\n }\n // Wait for visibility to update for nested components, so the component state is up-to-date when\n // calling clearOnHide\n if (shouldClear) {\n this.clearOnHide();\n }\n return visible;\n }\n /**\n * Checks conditions for this component and any sub components.\n * @param {any} data - The data to check against.\n * @param {any} flags - The flags passed to checkData function.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is visible.\n */\n checkConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.checkComponentConditions(data, flags, row);\n }\n /**\n * Returns the component logic if applicable.\n * @returns {Array<object>} - The component logic.\n */\n get logic() {\n return this.component.logic || [];\n }\n /**\n * Check all triggers and apply necessary actions.\n * @param {any} data - The data to check against.\n * @param {any} row - The row data to check against.\n * @returns {boolean|void} - TRUE if the component was altered.\n */\n fieldLogic(data = this.rootValue, row = this.data) {\n const logics = this.logic;\n // If there aren't logic, don't go further.\n if (logics.length === 0) {\n return;\n }\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n let changed = logics.reduce((changed, logic) => {\n const result = FormioUtils.checkTrigger(newComponent, logic.trigger, row, data, this.root ? this.root._form : {}, this);\n return (result ? this.applyActions(newComponent, logic.actions, result, row, data) : false) || changed;\n }, false);\n // If component definition changed, replace and mark as changed.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n changed = true;\n const disabled = this.shouldDisabled;\n // Change disabled state if it has changed\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n }\n return changed;\n }\n /**\n * Retuns if the browser is Internet Explorer.\n * @returns {boolean} - TRUE if the browser is IE.\n */\n isIE() {\n if (typeof window === 'undefined') {\n return false;\n }\n const userAgent = window.navigator.userAgent;\n const msie = userAgent.indexOf('MSIE ');\n if (msie > 0) {\n // IE 10 or older => return version number\n return parseInt(userAgent.substring(msie + 5, userAgent.indexOf('.', msie)), 10);\n }\n const trident = userAgent.indexOf('Trident/');\n if (trident > 0) {\n // IE 11 => return version number\n const rv = userAgent.indexOf('rv:');\n return parseInt(userAgent.substring(rv + 3, userAgent.indexOf('.', rv)), 10);\n }\n const edge = userAgent.indexOf('Edge/');\n if (edge > 0) {\n // IE 12 (aka Edge) => return version number\n return parseInt(userAgent.substring(edge + 5, userAgent.indexOf('.', edge)), 10);\n }\n // other browser\n return false;\n }\n /**\n * Defines the logic action value through evaluation.\n * @param {object} action - The action within the Logic system to perform.\n * @param {object} argsObject - The arguments to pass to the evaluation.\n * @returns {any} - The result of the evaluation.\n */\n defineActionValue(action, argsObject) {\n return this.evaluate(action.value, argsObject, 'value');\n }\n /**\n * Apply the actions of Logic for a component once the conditions have been met.\n * @param {object} newComponent - The new component to apply the actions to.\n * @param {Array<object>} actions - An array of actions\n * @param {any} result - The result of the conditional check in order to evaluate the actions.\n * @param {any} row - The contextual row data for this component.\n * @param {any} data - The global data object for the submission.\n * @returns {boolean} - TRUE if the component was altered.\n */\n applyActions(newComponent, actions, result, row, data) {\n data = data || this.rootValue;\n row = row || this.data;\n return actions.reduce((changed, action) => {\n switch (action.type) {\n case 'property': {\n FormioUtils.setActionProperty(newComponent, action, result, row, data, this);\n const property = action.property.value;\n if (!lodash_1.default.isEqual(lodash_1.default.get(this.component, property), lodash_1.default.get(newComponent, property))) {\n // Advanced Logic can modify the component's hidden property; because we track conditionally hidden state\n // separately from the component's hidden property, and technically this Advanced Logic conditionally hides\n // a component, we need to set _conditionallyHidden to the new value\n if (property === 'hidden') {\n this._conditionallyHidden = newComponent.hidden;\n }\n changed = true;\n }\n break;\n }\n case 'value': {\n const oldValue = this.getValue();\n const newValue = this.defineActionValue(action, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n component: newComponent,\n result,\n });\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n case 'mergeComponentSchema': {\n const schema = this.evaluate(action.schemaDefinition, {\n value: lodash_1.default.clone(this.getValue()),\n data,\n row,\n component: newComponent,\n result,\n }, 'schema');\n lodash_1.default.assign(newComponent, schema);\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n changed = true;\n }\n break;\n }\n case 'customAction': {\n const oldValue = this.getValue();\n const newValue = this.evaluate(action.customAction, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n input: oldValue,\n component: newComponent,\n result,\n }, 'value');\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n }\n return changed;\n }, false);\n }\n // Deprecated\n addInputError(message, dirty, elements) {\n this.addMessages(message);\n this.setErrorClasses(elements, dirty, !!message);\n }\n // Deprecated\n removeInputError(elements) {\n this.setErrorClasses(elements, true, false);\n }\n /**\n * Add a new input error to this element.\n * @param {Array<object>|string} messages - An array of messages to add to the element.\n * @returns {void}\n */\n addMessages(messages) {\n if (!messages) {\n return;\n }\n // Standardize on array of objects for message.\n if (typeof messages === 'string') {\n messages = {\n messages,\n level: 'error',\n };\n }\n if (!Array.isArray(messages)) {\n messages = [messages];\n }\n messages = lodash_1.default.uniqBy(messages, message => message.message);\n if (this.refs.messageContainer) {\n this.setContent(this.refs.messageContainer, messages.map((message) => {\n return this.renderTemplate('message', Object.assign({}, message));\n }).join(''));\n }\n }\n /**\n * Sets the form input widget error classes.\n * @param {Array<HTMLElement>} elements - An array of DOM elements to set the error classes on.\n * @param {boolean} dirty - If the input is dirty.\n * @param {boolean} hasErrors - If the input has errors.\n * @param {boolean} hasMessages - If the input has messages.\n * @param {HTMLElement} element - The wrapper element for all the other elements passed in first argument.\n * @returns {void}\n */\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n this.clearErrorClasses();\n elements.forEach((element) => {\n this.setElementInvalid(this.performInputMapping(element), false);\n });\n this.setInputWidgetErrorClasses(elements, hasErrors);\n // do not set error classes for hidden components\n if (!this.visible) {\n return;\n }\n if (hasErrors) {\n // Add error classes\n elements.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), true);\n });\n if (dirty && this.options.highlightErrors) {\n this.addClass(element, this.options.componentErrorClass);\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n if (hasMessages) {\n this.addClass(element, 'has-message');\n }\n }\n /**\n * Adds the classes necessary to mark an element as invalid.\n * @param {HTMLElement} element - The element you wish to add the invalid classes to.\n * @param {boolean} invalid - TRUE if the component is invalid, FALSE otherwise.\n * @returns {void}\n */\n setElementInvalid(element, invalid) {\n if (!element)\n return;\n if (invalid) {\n this.addClass(element, 'is-invalid');\n }\n else {\n this.removeClass(element, 'is-invalid');\n }\n element.setAttribute('aria-invalid', invalid ? 'true' : 'false');\n }\n /**\n * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.\n */\n clearOnHide() {\n // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.\n if (\n // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true\n (!this.rootPristine || this.options.server || (0, utils_1.isInsideScopingComponent)(this)) &&\n this.component.clearOnHide !== false &&\n !this.options.readOnly &&\n !this.options.showHiddenFields) {\n if (this.conditionallyHidden) {\n this.deleteValue();\n }\n else if (!this.hasValue() && this.shouldAddDefaultValue) {\n // If shown, ensure the default is set.\n this.setValue(this.defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n }\n /**\n * Triggers a debounced onChange event for the root component (usually Webform).\n * @param {...any} args - The arguments to pass to the onChange event.\n */\n triggerRootChange(...args) {\n if (this.options.onChange) {\n this.options.onChange(...args);\n }\n else if (this.root && this.root.triggerChange) {\n this.root.triggerChange(...args);\n }\n }\n /**\n * Called when the component value has been changed. This will then trigger the root level onChange handler which\n * propagates the checkData methods for the full component tree.\n * @param {any} flags - The flags for the change event propagation.\n * @param {boolean} fromRoot - If the change event is from the root component.\n * @returns {boolean} - TRUE if the component has changed.\n */\n onChange(flags, fromRoot) {\n flags = flags || {};\n if (flags.modified) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n this.addClass(this.getElement(), 'formio-modified');\n }\n // If we are supposed to validate on blur, then don't trigger validation yet.\n if (this.component.validateOn === 'blur' || this.component.validateOn === 'submit') {\n flags.noValidate = true;\n }\n if (this.component.onChange) {\n this.evaluate(this.component.onChange, {\n flags\n });\n }\n // Set the changed variable.\n const changed = {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: flags\n };\n // Emit the change.\n this.emit('componentChange', changed);\n // Do not propogate the modified flag.\n let modified = false;\n if (flags.modified) {\n modified = true;\n delete flags.modified;\n }\n // Bubble this change up to the top.\n if (!fromRoot) {\n this.triggerRootChange(flags, changed, modified);\n }\n return changed;\n }\n get wysiwygDefault() {\n return {\n quill: {\n theme: 'snow',\n placeholder: this.t(this.component.placeholder, { _userInput: true }),\n modules: {\n toolbar: [\n [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown\n [{ 'header': [1, 2, 3, 4, 5, 6, false] }],\n [{ 'font': [] }],\n ['bold', 'italic', 'underline', 'strike', { 'script': 'sub' }, { 'script': 'super' }, 'clean'],\n [{ 'color': [] }, { 'background': [] }],\n [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }, { 'align': [] }],\n ['blockquote', 'code-block'],\n ['link', 'image', 'video', 'formula', 'source']\n ]\n }\n },\n ace: {\n theme: 'ace/theme/xcode',\n maxLines: 12,\n minLines: 12,\n tabSize: 2,\n mode: 'ace/mode/javascript',\n placeholder: this.t(this.component.placeholder, { _userInput: true })\n },\n ckeditor: {\n image: {\n toolbar: [\n 'imageTextAlternative',\n '|',\n 'imageStyle:full',\n 'imageStyle:alignLeft',\n 'imageStyle:alignCenter',\n 'imageStyle:alignRight'\n ],\n styles: [\n 'full',\n 'alignLeft',\n 'alignCenter',\n 'alignRight'\n ]\n },\n extraPlugins: []\n },\n default: {}\n };\n }\n addCKE(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? {} : settings;\n settings.base64Upload = this.component.isUploadEnabled ? false : true;\n settings.mediaEmbed = { previewsInData: true };\n settings = lodash_1.default.merge(this.wysiwygDefault.ckeditor, lodash_1.default.get(this.options, 'editors.ckeditor.settings', {}), settings);\n if (this.component.isUploadEnabled) {\n settings.extraPlugins.push((0, uploadAdapter_1.getFormioUploadAdapterPlugin)(this.fileService, this));\n }\n return Formio_1.Formio.requireLibrary('ckeditor', isIEBrowser ? 'CKEDITOR' : 'ClassicEditor', lodash_1.default.get(this.options, 'editors.ckeditor.src', `${Formio_1.Formio.cdn.ckeditor}/ckeditor.js`), true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n if (isIEBrowser) {\n const editor = CKEDITOR.replace(element);\n editor.on('change', () => onChange(editor.getData()));\n return Promise.resolve(editor);\n }\n else {\n return ClassicEditor.create(element, settings).then(editor => {\n editor.model.document.on('change', () => onChange(editor.data.get()));\n return editor;\n });\n }\n });\n }\n addQuill(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? this.wysiwygDefault.quill : settings;\n settings = lodash_1.default.merge(this.wysiwygDefault.quill, lodash_1.default.get(this.options, 'editors.quill.settings', {}), settings);\n settings = Object.assign(Object.assign({}, settings), { modules: Object.assign({ table: true }, settings.modules) });\n // Lazy load the quill css.\n Formio_1.Formio.requireLibrary(`quill-css-${settings.theme}`, 'Quill', [\n { type: 'styles', src: `${Formio_1.Formio.cdn.quill}/quill.${settings.theme}.css` }\n ], true);\n // Lazy load the quill library.\n return Formio_1.Formio.requireLibrary('quill', 'Quill', lodash_1.default.get(this.options, 'editors.quill.src', `${Formio_1.Formio.cdn.quill}/quill.min.js`), true)\n .then(() => {\n return Formio_1.Formio.requireLibrary('quill-table', 'Quill', `${Formio_1.Formio.cdn.baseUrl}/quill/quill-table.js`, true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n this.quill = new Quill(element, isIEBrowser ? Object.assign(Object.assign({}, settings), { modules: {} }) : settings);\n /** This block of code adds the [source] capabilities. See https://codepen.io/anon/pen/ZyEjrQ */\n const txtArea = document.createElement('textarea');\n txtArea.setAttribute('class', 'quill-source-code');\n this.quill.addContainer('ql-custom').appendChild(txtArea);\n const qlSource = element.parentNode.querySelector('.ql-source');\n if (qlSource) {\n this.addEventListener(qlSource, 'click', (event) => {\n event.preventDefault();\n if (txtArea.style.display === 'inherit') {\n this.quill.setContents(this.quill.clipboard.convert({ html: txtArea.value }));\n }\n txtArea.style.display = (txtArea.style.display === 'none') ? 'inherit' : 'none';\n });\n }\n /** END CODEBLOCK */\n // Make sure to select cursor when they click on the element.\n this.addEventListener(element, 'click', () => this.quill.focus());\n // Allows users to skip toolbar items when tabbing though form\n const elm = document.querySelectorAll('.ql-formats > button');\n for (let i = 0; i < elm.length; i++) {\n elm[i].setAttribute('tabindex', '-1');\n }\n this.quill.on('text-change', () => {\n txtArea.value = this.quill.root.innerHTML;\n onChange(txtArea);\n });\n return this.quill;\n });\n });\n }\n get shouldSanitizeValue() {\n var _a;\n // Sanitize value if sanitizing for thw whole content is turned off\n return (((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitize) !== false);\n }\n addAce(element, settings, onChange) {\n if (!settings || (settings.theme === 'snow')) {\n const mode = settings ? settings.mode : '';\n settings = {};\n if (mode) {\n settings.mode = mode;\n }\n }\n settings = lodash_1.default.merge(this.wysiwygDefault.ace, lodash_1.default.get(this.options, 'editors.ace.settings', {}), settings || {});\n return Formio_1.Formio.requireLibrary('ace', 'ace', lodash_1.default.get(this.options, 'editors.ace.src', `${Formio_1.Formio.cdn.ace}/ace.js`), true)\n .then((editor) => {\n editor = editor.edit(element);\n editor.removeAllListeners('change');\n editor.setOptions(settings);\n editor.getSession().setMode(settings.mode);\n editor.on('change', () => onChange(editor.getValue()));\n if (settings.isUseWorkerDisabled) {\n editor.session.setUseWorker(false);\n }\n return editor;\n });\n }\n getDragula() {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve) => {\n return Formio_1.Formio.requireLibrary('dragula', 'dragula', `${Formio_1.Formio.cdn.dragula}/dragula.js`, true, (ready) => {\n return ready.then(resolve);\n });\n });\n });\n }\n get tree() {\n return this.component.tree || false;\n }\n /**\n * The empty value for this component.\n * @returns {null} - The empty value for this component.\n */\n get emptyValue() {\n return null;\n }\n /**\n * Returns if this component has a value set.\n * @param {any} data - The global data object.\n * @returns {boolean} - TRUE if a value is set.\n */\n hasValue(data) {\n return !lodash_1.default.isUndefined(lodash_1.default.get(data || this.data, this.key));\n }\n /**\n * Get the data value at the root level.\n * @returns {*} - The root value for the component, typically the Webform data object.\n */\n get rootValue() {\n return this.root ? this.root.data : this.data;\n }\n get rootPristine() {\n return lodash_1.default.get(this, 'root.pristine', false);\n }\n /**\n * Get the static value of this component.\n * @returns {*} - The value for this component.\n */\n get dataValue() {\n if (!this.key ||\n (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {\n return this.emptyValue;\n }\n if (!this.hasValue() && this.shouldAddDefaultValue) {\n const empty = this.component.multiple ? [] : this.emptyValue;\n if (!this.rootPristine) {\n this.dataValue = empty;\n }\n return empty;\n }\n return lodash_1.default.get(this._data, this.key);\n }\n /**\n * Sets the static value of this component.\n * @param {*} value - The value to set for this component.\n */\n set dataValue(value) {\n if (!this.allowData ||\n !this.key ||\n (this.conditionallyHidden && this.component.clearOnHide && !this.rootPristine)) {\n return;\n }\n if ((value !== null) && (value !== undefined)) {\n value = this.hook('setDataValue', value, this.key, this._data);\n }\n if ((value === null) || (value === undefined)) {\n this.unset();\n return;\n }\n lodash_1.default.set(this._data, this.key, value);\n return;\n }\n /**\n * Splice a value from the dataValue.\n * @param {number} index - The index to splice for an array component values.\n * @param {*} flags - The flags to use when splicing the value.\n */\n splice(index, flags = {}) {\n if (this.hasValue()) {\n const dataValue = this.dataValue || [];\n if (lodash_1.default.isArray(dataValue) && dataValue.hasOwnProperty(index)) {\n dataValue.splice(index, 1);\n this.dataValue = dataValue;\n this.triggerChange(flags);\n }\n }\n }\n unset() {\n lodash_1.default.unset(this._data, this.key);\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n getCustomDefaultValue(defaultValue) {\n if (this.component.customDefaultValue && !this.options.preview) {\n defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');\n }\n return defaultValue;\n }\n get shouldAddDefaultValue() {\n return !this.options.noDefaults || (this.component.defaultValue && !this.isEmpty(this.component.defaultValue)) || this.component.customDefaultValue;\n }\n get defaultValue() {\n let defaultValue = this.emptyValue;\n if (this.component.defaultValue) {\n defaultValue = this.component.defaultValue;\n }\n defaultValue = this.getCustomDefaultValue(defaultValue);\n const checkMask = (value) => {\n if (typeof value === 'string') {\n if (this.component.type !== 'textfield') {\n const placeholderChar = this.placeholderChar;\n value = (0, vanilla_text_mask_1.conformToMask)(value, this.defaultMask, { placeholderChar }).conformedValue;\n if (!FormioUtils.matchInputMask(value, this.defaultMask)) {\n value = '';\n }\n }\n }\n else {\n value = '';\n }\n return value;\n };\n if (Array.isArray(this.defaultMask) ? this.defaultMask.length > 0 : this.defaultMask) {\n if (Array.isArray(defaultValue)) {\n defaultValue = defaultValue.map(checkMask);\n }\n else {\n defaultValue = checkMask(defaultValue);\n }\n }\n // Clone so that it creates a new instance.\n return lodash_1.default.cloneDeep(defaultValue);\n }\n /**\n * Get the input value of this component.\n * @returns {*} - The value for the component.\n */\n getValue() {\n if (!this.hasInput || this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n const values = [];\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n if (!this.component.multiple) {\n return this.getValueAt(i);\n }\n values.push(this.getValueAt(i));\n }\n }\n if (values.length === 0 && !this.component.multiple) {\n return '';\n }\n return values;\n }\n /**\n * Get the value at a specific index.\n * @param {number} index - For an array component or multiple values, this returns the value at a specific index.\n * @returns {*} - The value at the specified index.\n */\n getValueAt(index) {\n const input = this.performInputMapping(this.refs.input[index]);\n return input ? input.value : undefined;\n }\n /**\n * Set the value of this component.\n * @param {*} value - The value to set for this component.\n * @param {*} flags - The flags to use when setting the value.\n * @returns {boolean} - If the value changed.\n */\n setValue(value, flags = {}) {\n const changed = this.updateValue(value, flags);\n value = this.dataValue;\n if (!this.hasInput) {\n return changed;\n }\n const isArray = Array.isArray(value);\n const valueInput = this.refs.fileLink || this.refs.input;\n if (isArray &&\n Array.isArray(this.defaultValue) &&\n this.refs.hasOwnProperty('input') &&\n valueInput &&\n (valueInput.length !== value.length) &&\n this.visible) {\n this.redraw();\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.redraw();\n return changed;\n }\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n this.setValueAt(i, isArray && !this.isSingleInputValue() ? value[i] : value, flags);\n }\n }\n return changed;\n }\n /**\n * Returns if the value (e.g. array) should be divided between several inputs\n * @returns {boolean}\n */\n isSingleInputValue() {\n return false;\n }\n /**\n * Set the value at a specific index.\n * @param {number} index - The index to set the value at.\n * @param {*} value - The value to set at the specified index.\n * @param {*} flags - The flags to use when setting the value.\n */\n setValueAt(index, value, flags = {}) {\n if (!flags.noDefault && (value === null || value === undefined) && !this.component.multiple) {\n value = this.defaultValue;\n }\n const input = this.performInputMapping(this.refs.input[index]);\n const valueMaskInput = this.refs.valueMaskInput;\n if ((valueMaskInput === null || valueMaskInput === void 0 ? void 0 : valueMaskInput.mask) && valueMaskInput.mask.textMaskInputElement) {\n valueMaskInput.mask.textMaskInputElement.update(value);\n }\n if (input.mask && input.mask.textMaskInputElement) {\n input.mask.textMaskInputElement.update(value);\n }\n else if (input.widget && input.widget.setValue) {\n input.widget.setValue(value);\n }\n else {\n input.value = value;\n }\n }\n get hasSetValue() {\n return this.hasValue() && !this.isEmpty(this.dataValue);\n }\n setDefaultValue() {\n if (this.defaultValue && this.shouldAddDefaultValue) {\n const defaultValue = (this.component.multiple && !this.dataValue.length) ? [] : this.defaultValue;\n this.setValue(defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n /**\n * Restore the value of a control.\n */\n restoreValue() {\n if (this.hasSetValue) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else {\n this.setDefaultValue();\n }\n }\n /**\n * Normalize values coming into updateValue.\n * @param {*} value - The value to normalize before setting.\n * @returns {*} - The normalized value.\n */\n normalizeValue(value) {\n return value;\n }\n /**\n * Update a value of this component.\n * @param {*} value - The value to update.\n * @param {*} flags - The flags to use when updating the value.\n * @returns {boolean} - If the value changed.\n */\n updateComponentValue(value, flags = {}) {\n let newValue = (!flags.resetValue && (value === undefined || value === null)) ? this.getValue() : value;\n newValue = this.normalizeValue(newValue, flags);\n const oldValue = this.dataValue;\n let changed = ((newValue !== undefined) ? this.hasChanged(newValue, oldValue) : false);\n if (changed) {\n this.dataValue = newValue;\n changed = this.dataValue !== oldValue;\n this.updateOnChange(flags, changed);\n }\n if (this.componentModal && flags && flags.fromSubmission) {\n this.componentModal.setValue(value);\n }\n return changed;\n }\n /**\n * Updates the value of this component plus all sub-components.\n * @param {...any} args - The arguments to pass to updateValue.\n * @returns {boolean} - If the value changed.\n */\n updateValue(...args) {\n return this.updateComponentValue(...args);\n }\n getIcon(name, content, styles, ref = 'icon') {\n return this.renderTemplate('icon', {\n className: this.iconClass(name),\n ref,\n styles,\n content\n });\n }\n /**\n * Resets the value of this component.\n */\n resetValue() {\n this.unset();\n this.setValue(this.defaultValue || this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n /**\n * Determine if the value of this component has changed.\n * @param {*} newValue - The new value to check.\n * @param {*} oldValue - The existing value of the component.\n * @returns {boolean} - TRUE if the value has changed.\n */\n hasChanged(newValue, oldValue) {\n if (((newValue === undefined) || (newValue === null)) &&\n ((oldValue === undefined) || (oldValue === null) || this.isEmpty(oldValue))) {\n return false;\n }\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n this.allowData &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n /**\n * Update the value on change.\n * @param {*} flags - The flags to use when triggering the on change event.\n * @param {boolean} changed - If the value has changed.\n * @returns {boolean} - If the value changed.\n */\n updateOnChange(flags = {}, changed = false) {\n if (!flags.noUpdateEvent && changed) {\n if (flags.fromSubmission) {\n // Reset the errors when a submission has been made and allow it to revalidate.\n this._errors = [];\n }\n this.triggerChange(flags);\n return true;\n }\n return false;\n }\n convertNumberOrBoolToString(value) {\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n return value;\n }\n doValueCalculation(dataValue, data, row) {\n var _a;\n return this.evaluate(this.component.calculateValue, {\n value: dataValue,\n data,\n row: row || this.data,\n submission: ((_a = this.root) === null || _a === void 0 ? void 0 : _a._submission) || {\n data: this.rootValue\n }\n }, 'value');\n }\n /* eslint-disable max-statements */\n calculateComponentValue(data, flags, row) {\n // Skip value calculation for the component if we don't have entire form data set or in builder mode\n if (this.builderMode || lodash_1.default.isUndefined(lodash_1.default.get(this, 'root.data'))) {\n return false;\n }\n // If no calculated value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n const { clearOnHide } = this.component;\n const shouldBeCleared = this.conditionallyHidden && clearOnHide;\n const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);\n if (shouldBeCleared) {\n // remove calculated value so that the value is recalculated once component becomes visible\n if (this.hasOwnProperty('calculatedValue') && allowOverride) {\n lodash_1.default.unset(this, 'calculatedValue');\n }\n return false;\n }\n // Handle all cases when calculated values should not fire.\n if ((this.options.readOnly && !this.options.pdf && !this.component.calculateValue) ||\n !(this.component.calculateValue || this.component.calculateValueVariable) ||\n (this.options.server && !this.component.calculateServer) ||\n (flags.dataSourceInitialLoading && allowOverride)) {\n return false;\n }\n const dataValue = this.dataValue;\n // Calculate the new value.\n let calculatedValue = this.doValueCalculation(dataValue, data, row, flags);\n if (this.options.readOnly && dataValue && !calculatedValue) {\n return false;\n }\n if (lodash_1.default.isNil(calculatedValue)) {\n calculatedValue = this.emptyValue;\n }\n const changed = !lodash_1.default.isEqual(dataValue, calculatedValue);\n // Do not override calculations on server if they have calculateServer set.\n if (allowOverride) {\n // The value is considered locked if it is not empty and comes from a submission value.\n const fromSubmission = (flags.fromSubmission && this.component.persistent === true);\n if (this.isEmpty(dataValue)) {\n // Reset the calculation lock if ever the data is cleared.\n this.calculationLocked = false;\n }\n else if (this.calculationLocked || fromSubmission) {\n this.calculationLocked = true;\n return false;\n }\n const firstPass = (this.calculatedValue === undefined) || flags.resetValue;\n if (firstPass) {\n this.calculatedValue = null;\n }\n const newCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(calculatedValue));\n const previousCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(this.calculatedValue));\n const normalizedDataValue = this.normalizeValue(this.convertNumberOrBoolToString(dataValue));\n const calculationChanged = !lodash_1.default.isEqual(previousCalculatedValue, newCalculatedValue);\n const previousChanged = !lodash_1.default.isEqual(normalizedDataValue, previousCalculatedValue);\n if (calculationChanged && previousChanged && !firstPass) {\n return false;\n }\n // Check to ensure that the calculated value is different than the previously calculated value.\n if (previousCalculatedValue && previousChanged && !calculationChanged) {\n this.calculatedValue = null;\n return false;\n }\n if (flags.isReordered || !calculationChanged) {\n return false;\n }\n if (fromSubmission) {\n // If we set value from submission and it differs from calculated one, set the calculated value to prevent overriding dataValue in the next pass\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n return false;\n }\n // If this is the firstPass, and the dataValue is different than to the calculatedValue.\n if (firstPass && !this.isEmpty(dataValue) && changed && calculationChanged) {\n // Return that we have a change so it will perform another pass.\n return true;\n }\n }\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n if (changed) {\n if (!flags.noPristineChangeOnModified && this.root.initialized) {\n this.pristine = false;\n }\n flags.triggeredComponentId = this.id;\n return this.setValue(calculatedValue, flags);\n }\n return false;\n }\n /* eslint-enable max-statements */\n /**\n * Performs calculations in this component plus any child components.\n * @param {*} data - The data to perform the calculation with.\n * @param {*} flags - The flags to use when calculating the value.\n * @param {*} row - The contextual row data to use when performing the calculation.\n * @returns {boolean} - TRUE if the value changed.\n */\n calculateValue(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.calculateComponentValue(data, flags, row);\n }\n /**\n * Get this component's label text.\n * @returns {string} - The label text for this component.\n */\n get label() {\n return this.component.label;\n }\n /**\n * Set this component's label text and render it.\n * @param {string} value - The new label text.\n */\n set label(value) {\n this.component.label = value;\n if (this.labelElement) {\n this.labelElement.innerText = value;\n }\n }\n /**\n * Get FormioForm element at the root of this component tree.\n * @returns {*} root - The root component to search from.\n */\n getRoot() {\n return this.root;\n }\n /**\n * Returns the invalid message, or empty string if the component is valid.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.\n * @param {*} row - Contextual row data for this component.\n * @returns {string} - The message to show when the component is invalid.\n */\n invalidMessage(data, dirty, ignoreCondition, row) {\n var _a;\n if (!row) {\n row = (0, utils_1.getContextualRowData)(this.component, data, this.paths);\n }\n if (!ignoreCondition && !this.checkCondition(row, data)) {\n return '';\n }\n // See if this is forced invalid.\n if (this.invalid) {\n return this.invalid;\n }\n // No need to check for errors if there is no input or if it is pristine.\n if (!this.hasInput || (!dirty && this.pristine)) {\n return '';\n }\n const validationScope = { errors: [] };\n (0, process_1.processOneSync)({\n component: this.component,\n data,\n row,\n path: this.path || this.component.key,\n parent: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component,\n paths: this.paths,\n scope: validationScope,\n instance: this,\n processors: [\n process_1.validateProcessInfo\n ]\n });\n const errors = validationScope.errors;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return lodash_1.default.map(interpolatedErrors, 'message').join('\\n\\n');\n }\n /**\n * Returns if the component is valid or not.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @returns {boolean} - TRUE if the component is valid.\n */\n isValid(data, dirty) {\n return !this.invalidMessage(data, dirty);\n }\n setComponentValidity(errors, dirty, silentCheck) {\n if (silentCheck) {\n return [];\n }\n const messages = errors.filter(message => !message.fromServer);\n if (errors.length && !!messages.length && (!this.isEmpty(this.defaultValue) || dirty || !this.pristine)) {\n return this.setCustomValidity(messages, dirty);\n }\n else {\n return this.setCustomValidity('');\n }\n }\n /**\n * Interpolate errors from the validation methods.\n * @param {Array<any>} errors - An array of errors to interpolate.\n * @returns {Array<any>} - The interpolated errors.\n */\n interpolateErrors(errors) {\n var _a;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return ((_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.length) ? [...interpolatedErrors, ...this.serverErrors] : interpolatedErrors;\n }\n /**\n * Show component validation errors.\n * @param {*} errors - An array of errors that have occured.\n * @param {*} data - The root submission data.\n * @param {*} row - The contextual row data.\n * @param {*} flags - The flags to perform validation.\n * @returns {boolean} - TRUE if the component is valid.\n */\n showValidationErrors(errors, data, row, flags) {\n if (flags.silentCheck) {\n return [];\n }\n let isDirty = (flags.dirty === false) ? false : (this.dirty || flags.dirty);\n if (this.options.alwaysDirty) {\n isDirty = true;\n }\n this.setDirty(isDirty);\n return this.setComponentValidity(errors, isDirty, flags.silentCheck, flags.fromSubmission);\n }\n /**\n * Perform a component validation.\n * @param {*} data - The root data you wish to use for this component.\n * @param {*} row - The contextual row data you wish to use for this component.\n * @param {*} flags - The flags to control the behavior of the validation.\n * @returns {Array<any>} - An array of errors if the component is invalid.\n */\n validateComponent(data = null, row = null, flags = {}) {\n var _a;\n data = data || this.rootValue;\n row = row || this.data;\n const { async = false } = flags;\n if (this.shouldSkipValidation(data, row, flags)) {\n return async ? Promise.resolve([]) : [];\n }\n const processContext = {\n component: this.component,\n data,\n row,\n local: !!flags.local,\n value: this.validationValue,\n parent: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component,\n paths: this.paths,\n path: this.path || this.component.key,\n instance: this,\n form: this.root ? this.root._form : {},\n scope: { errors: [] },\n processors: [\n process_1.validateProcessInfo\n ]\n };\n if (async) {\n return (0, process_1.processOne)(processContext).then(() => {\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n });\n }\n (0, process_1.processOneSync)(processContext);\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n }\n /**\n * Checks the validity of this component and sets the error message if it is invalid.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {*} flags - The flags to use when checking the validity.\n * @param {Array<any>} allErrors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkComponentValidity(data = null, dirty = false, row = null, flags = {}, allErrors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n flags.dirty = dirty || false;\n if (flags.async) {\n return this.validateComponent(data, row, flags).then((errors) => {\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => { var _a, _b; return (((_a = err === null || err === void 0 ? void 0 : err.component) === null || _a === void 0 ? void 0 : _a.key) || ((_b = err === null || err === void 0 ? void 0 : err.context) === null || _b === void 0 ? void 0 : _b.key)) === this.component.key; });\n }\n }\n this.showValidationErrors(errors, data, row, flags);\n return errors.length === 0;\n });\n }\n else {\n const errors = this.validateComponent(data, row, flags);\n this.showValidationErrors(errors, data, row, flags);\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => { var _a, _b; return (((_a = err === null || err === void 0 ? void 0 : err.component) === null || _a === void 0 ? void 0 : _a.key) || ((_b = err === null || err === void 0 ? void 0 : err.context) === null || _b === void 0 ? void 0 : _b.key)) === this.component.key; });\n }\n }\n return errors.length === 0;\n }\n }\n /**\n * Checks the validity of the component.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {boolean} silentCheck - If the check should be silent and not set the error messages.\n * @param {Array<any>} errors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkValidity(data = null, dirty = false, row = null, silentCheck = false, errors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n return this.checkComponentValidity(data, dirty, row, { silentCheck }, errors);\n }\n checkAsyncValidity(data = null, dirty = false, row = null, silentCheck = false, errors = []) {\n return this.checkComponentValidity(data, dirty, row, { async: true, silentCheck }, errors);\n }\n /**\n * Check the conditions, calculations, and validity of a single component and triggers an update if\n * something changed.\n * @param {*} data - The root data of the change event.\n * @param {*} flags - The flags from this change event.\n * @param {*} row - The contextual row data for this component.\n * @returns {void|boolean} - TRUE if no check should be performed on the component.\n */\n checkData(data = null, flags = null, row = null) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n // Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners\n if (!flags.fromBlur) {\n this.checkRefreshOn(flags.changes, flags);\n }\n if (flags.noCheck) {\n return true;\n }\n this.checkComponentConditions(data, flags, row);\n if (this.id !== flags.triggeredComponentId) {\n this.calculateComponentValue(data, flags, row);\n }\n }\n checkModal(errors = [], dirty = false) {\n const messages = errors.filter(error => !error.fromServer);\n const isValid = errors.length === 0;\n if (!this.component.modalEdit || !this.componentModal) {\n return;\n }\n if (dirty && !isValid) {\n this.setErrorClasses([this.refs.openModal], dirty, !isValid, !!messages.length, this.refs.openModalWrapper);\n }\n else {\n this.clearErrorClasses(this.refs.openModalWrapper);\n }\n }\n get validationValue() {\n return this.dataValue;\n }\n isEmpty(value = this.dataValue) {\n const isEmptyArray = (lodash_1.default.isArray(value) && value.length === 1) ? lodash_1.default.isEqual(value[0], this.emptyValue) : false;\n return value == null || value.length === 0 || lodash_1.default.isEqual(value, this.emptyValue) || isEmptyArray;\n }\n isEqual(valueA, valueB = this.dataValue) {\n return (this.isEmpty(valueA) && this.isEmpty(valueB)) || lodash_1.default.isEqual(valueA, valueB);\n }\n /**\n * Check if a component is eligible for multiple validation\n * @returns {boolean} - TRUE if the component is eligible for multiple validation.\n */\n validateMultiple() {\n return true;\n }\n clearErrorClasses(element = this.element) {\n this.removeClass(element, this.options.componentErrorClass);\n this.removeClass(element, 'alert alert-danger');\n this.removeClass(element, 'has-error');\n this.removeClass(element, 'has-message');\n }\n setInputWidgetErrorClasses(inputRefs, hasErrors) {\n if (!this.isInputComponent || !this.component.widget || !(inputRefs === null || inputRefs === void 0 ? void 0 : inputRefs.length)) {\n return;\n }\n inputRefs.forEach((input) => {\n if ((input === null || input === void 0 ? void 0 : input.widget) && input.widget.setErrorClasses) {\n input.widget.setErrorClasses(hasErrors);\n }\n });\n }\n addFocusBlurEvents(element) {\n this.addEventListener(element, 'focus', () => {\n if (this.root.focusedComponent !== this) {\n if (this.root.pendingBlur) {\n this.root.pendingBlur();\n }\n this.root.focusedComponent = this;\n this.emit('focus', this);\n }\n else if (this.root.focusedComponent === this && this.root.pendingBlur) {\n this.root.pendingBlur.cancel();\n this.root.pendingBlur = null;\n }\n });\n this.addEventListener(element, 'blur', () => {\n this.root.pendingBlur = FormioUtils.delay(() => {\n this.emit('blur', this);\n if (this.component.validateOn === 'blur') {\n this.root.triggerChange({ fromBlur: true }, {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: { fromBlur: true }\n });\n }\n this.root.focusedComponent = null;\n this.root.pendingBlur = null;\n });\n });\n }\n // eslint-disable-next-line max-statements\n setCustomValidity(messages, dirty, external) {\n const inputRefs = this.isInputComponent ? this.refs.input || [] : null;\n if (typeof messages === 'string' && messages) {\n messages = {\n level: 'error',\n message: messages,\n component: this.component,\n };\n }\n if (!Array.isArray(messages)) {\n if (messages) {\n messages = [messages];\n }\n else {\n messages = [];\n }\n }\n const errors = messages.filter(message => message.level === 'error');\n let invalidInputRefs = inputRefs;\n // Filter the invalid input refs in multiple components\n if (this.component.multiple) {\n const refsArray = Array.from(inputRefs);\n refsArray.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), false);\n });\n this.setInputWidgetErrorClasses(refsArray, false);\n invalidInputRefs = refsArray.filter((ref, index) => {\n var _a;\n return (_a = messages.some) === null || _a === void 0 ? void 0 : _a.call(messages, (msg) => {\n var _a;\n return ((_a = msg === null || msg === void 0 ? void 0 : msg.context) === null || _a === void 0 ? void 0 : _a.index) === index;\n });\n });\n }\n if (messages.length) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n this.emit('componentError', {\n instance: this,\n component: this.component,\n message: messages[0].message,\n messages,\n external: !!external,\n });\n this.addMessages(messages, dirty, invalidInputRefs);\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n }\n else if (!errors.length || (errors[0].external === !!external)) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n if (this.refs.modalMessageContainer) {\n this.empty(this.refs.modalMessageContainer);\n }\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n this.clearErrorClasses();\n }\n this._visibleErrors = messages;\n return messages;\n }\n /**\n * Determines if the value of this component is hidden from the user as if it is coming from the server, but is\n * protected.\n * @returns {boolean|*} - TRUE if the value is hidden.\n */\n isValueHidden() {\n if (this.component.protected && this.root.editing) {\n return false;\n }\n if (!this.root || !this.root.hasOwnProperty('editing')) {\n return false;\n }\n if (!this.root || !this.root.editing) {\n return false;\n }\n return (this.component.protected || !this.component.persistent || (this.component.persistent === 'client-only'));\n }\n shouldSkipValidation(data, row, flags = {}) {\n const rules = [\n // Do not validate if the flags say not too.\n () => flags.noValidate,\n // Force valid if component is read-only\n () => this.options.readOnly,\n // Do not check validations if component is not an input component.\n () => !this.hasInput,\n // Check to see if we are editing and if so, check component persistence.\n () => this.isValueHidden(),\n // Force valid if component is hidden.\n () => {\n if (!this.component.validateWhenHidden && (!this.visible || !this.checkCondition(row, data))) {\n // If this component is forced valid when it is hidden, then we also need to reset the errors for this component.\n this._errors = [];\n return true;\n }\n return false;\n }\n ];\n return rules.some(pred => pred());\n }\n // Maintain reverse compatibility.\n whenReady() {\n console.warn(this.t('whenReadyDeprecation'));\n return this.dataReady;\n }\n get dataReady() {\n return Promise.resolve();\n }\n /**\n * Prints out the value of this component as a string value.\n * @param {*} value - The value to print out.\n * @returns {string} - The string representation of the value.\n */\n asString(value) {\n value = value || this.getValue();\n return (Array.isArray(value) ? value : [value]).map(lodash_1.default.toString).join(', ');\n }\n /**\n * Return if the component is disabled.\n * @returns {boolean} - TRUE if the component is disabled.\n */\n get disabled() {\n return this._disabled || this.parentDisabled;\n }\n /**\n * Disable this component.\n * @param {boolean} disabled - TRUE to disable the component.\n */\n set disabled(disabled) {\n this._disabled = disabled;\n }\n setDisabled(element, disabled) {\n if (!element) {\n return;\n }\n element.disabled = disabled;\n if (disabled) {\n element.setAttribute('disabled', 'disabled');\n }\n else {\n element.removeAttribute('disabled');\n }\n }\n setLoading(element, loading) {\n if (!element || (element.loading === loading)) {\n return;\n }\n element.loading = loading;\n if (!element.loader && loading) {\n element.loader = this.ce('i', {\n class: `${this.iconClass('refresh', true)} button-icon-right`\n });\n }\n if (element.loader) {\n if (loading) {\n this.appendTo(element.loader, element);\n }\n else {\n this.removeChildFrom(element.loader, element);\n }\n }\n }\n selectOptions(select, tag, options, defaultValue) {\n lodash_1.default.each(options, (option) => {\n const attrs = {\n value: option.value\n };\n if (defaultValue !== undefined && (option.value === defaultValue)) {\n attrs.selected = 'selected';\n }\n const optionElement = this.ce('option', attrs);\n optionElement.appendChild(this.text(option.label));\n select.appendChild(optionElement);\n });\n }\n setSelectValue(select, value) {\n const options = select.querySelectorAll('option');\n lodash_1.default.each(options, (option) => {\n if (option.value === value) {\n option.setAttribute('selected', 'selected');\n }\n else {\n option.removeAttribute('selected');\n }\n });\n if (select.onchange) {\n select.onchange();\n }\n if (select.onselect) {\n select.onselect();\n }\n }\n getRelativePath(path) {\n const keyPart = `.${this.key}`;\n const thisPath = this.isInputComponent ? this.path\n : this.path.slice(0).replace(keyPart, '');\n return path.replace(thisPath, '');\n }\n clear() {\n this.detach();\n this.empty(this.getElement());\n }\n append(element) {\n this.appendTo(element, this.element);\n }\n prepend(element) {\n this.prependTo(element, this.element);\n }\n removeChild(element) {\n this.removeChildFrom(element, this.element);\n }\n detachLogic() {\n this.logic.forEach(logic => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.off(event); // only applies to callbacks on this component\n }\n });\n }\n attachLogic() {\n // Do not attach logic during builder mode.\n if (this.builderMode) {\n return;\n }\n this.logic.forEach((logic) => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.on(event, (...args) => {\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n if (this.applyActions(newComponent, logic.actions, args)) {\n // If component definition changed, replace it.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;\n const disabled = this.shouldDisabled;\n // Change states which won't be recalculated during redrawing\n if (this.visible !== visible) {\n // If the logic is triggered by an event and the action sets the hidden state then the original\n // component definition must be changed so that the components hidden state does not get flipped back by\n // the fieldLogic function\n this.originalComponent.hidden = !visible;\n this.visible = visible;\n }\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n this.redraw();\n }\n }\n }, true);\n }\n });\n }\n /**\n * Get the element information.\n * @returns {*} - The components \"input\" DOM element information.\n */\n elementInfo() {\n const attributes = {\n name: this.options.name,\n type: this.component.inputType || 'text',\n class: 'form-control',\n lang: this.options.language\n };\n if (this.component.placeholder) {\n attributes.placeholder = this.t(this.component.placeholder, { _userInput: true });\n }\n if (this.component.tabindex) {\n attributes.tabindex = this.component.tabindex;\n }\n if (this.disabled) {\n attributes.disabled = 'disabled';\n }\n lodash_1.default.defaults(attributes, this.component.attributes);\n return {\n type: 'input',\n component: this.component,\n changeEvent: 'change',\n attr: attributes\n };\n }\n autofocus() {\n const hasAutofocus = this.component.autofocus && !this.builderMode && !this.options.preview;\n if (hasAutofocus) {\n this.on('render', () => this.focus(), true);\n }\n }\n scrollIntoView(element = this.element, verticalOnly) {\n if (!element) {\n return;\n }\n const { left, top } = element.getBoundingClientRect();\n window.scrollTo(verticalOnly ? window.scrollX : left + window.scrollX, top + window.scrollY);\n }\n focus(index) {\n var _a, _b, _c, _d;\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n if (!index && !lodash_1.default.isNumber(index) && ((_b = (_a = this.refs) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.length)) {\n index = this.refs.input.length - 1;\n }\n if ((_c = this.refs.input) === null || _c === void 0 ? void 0 : _c.length) {\n const focusingInput = this.refs.input[index];\n if (((_d = this.component.widget) === null || _d === void 0 ? void 0 : _d.type) === 'calendar') {\n const sibling = focusingInput.nextSibling;\n if (sibling) {\n sibling.focus();\n }\n }\n else {\n focusingInput.focus();\n }\n }\n if (this.refs.openModal) {\n this.refs.openModal.focus();\n }\n if (this.parent.refs.openModal) {\n this.parent.refs.openModal.focus();\n }\n }\n /**\n * Get `Formio` instance for working with files\n * @returns {import('@formio/core').Formio} - The Formio instance file service.\n */\n get fileService() {\n if (this.options.fileService) {\n return this.options.fileService;\n }\n if (this.options.formio) {\n return this.options.formio;\n }\n if (this.root && this.root.formio) {\n return this.root.formio;\n }\n const formio = new Formio_1.Formio();\n // If a form is loaded, then make sure to set the correct formUrl.\n if (this.root && this.root._form && this.root._form._id) {\n formio.formUrl = `${formio.projectUrl}/form/${this.root._form._id}`;\n }\n return formio;\n }\n resetCaches() { }\n get previewMode() {\n return false;\n }\n}\nexports[\"default\"] = Component;\nComponent.externalLibraries = {};\nComponent.requireLibrary = function (name, property, src, polling) {\n if (!Component.externalLibraries.hasOwnProperty(name)) {\n Component.externalLibraries[name] = {};\n Component.externalLibraries[name].ready = new Promise((resolve, reject) => {\n Component.externalLibraries[name].resolve = resolve;\n Component.externalLibraries[name].reject = reject;\n });\n const callbackName = `${name}Callback`;\n if (!polling && !window[callbackName]) {\n window[callbackName] = function () {\n this.resolve();\n }.bind(Component.externalLibraries[name]);\n }\n // See if the plugin already exists.\n const plugin = (0, utils_1.getScriptPlugin)(property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n src = Array.isArray(src) ? src : [src];\n src.forEach((lib) => {\n let attrs = {};\n let elementType = '';\n if (typeof lib === 'string') {\n lib = {\n type: 'script',\n src: lib\n };\n }\n switch (lib.type) {\n case 'script':\n elementType = 'script';\n attrs = {\n src: lib.src,\n type: 'text/javascript',\n defer: true,\n async: true\n };\n break;\n case 'styles':\n elementType = 'link';\n attrs = {\n href: lib.src,\n rel: 'stylesheet'\n };\n break;\n }\n // Add the script to the top page.\n const script = document.createElement(elementType);\n for (const attr in attrs) {\n script.setAttribute(attr, attrs[attr]);\n }\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n // if no callback is provided, then check periodically for the script.\n if (polling) {\n setTimeout(function checkLibrary() {\n const plugin = (0, utils_1.getScriptPlugin)(property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n // check again after 200 ms.\n setTimeout(checkLibrary, 200);\n }\n }, 200);\n }\n }\n }\n return Component.externalLibraries[name].ready;\n};\nComponent.libraryReady = function (name) {\n if (Component.externalLibraries.hasOwnProperty(name) &&\n Component.externalLibraries[name].ready) {\n return Component.externalLibraries[name].ready;\n }\n return Promise.reject(`${name} library was not required.`);\n};\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/component/Component.js?");
|
4856
|
+
eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\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};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* globals Quill, ClassicEditor, CKEDITOR */\nconst vanilla_text_mask_1 = __webpack_require__(/*! @formio/vanilla-text-mask */ \"./node_modules/@formio/vanilla-text-mask/dist/vanillaTextMask.js\");\nconst tippy_js_1 = __importDefault(__webpack_require__(/*! tippy.js */ \"./node_modules/tippy.js/dist/tippy.esm.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ismobilejs_1 = __importDefault(__webpack_require__(/*! ismobilejs */ \"./node_modules/ismobilejs/esm/index.js\"));\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst Formio_1 = __webpack_require__(/*! ../../../Formio */ \"./lib/cjs/Formio.js\");\nconst FormioUtils = __importStar(__webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\"));\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Element_1 = __importDefault(__webpack_require__(/*! ../../../Element */ \"./lib/cjs/Element.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst widgets_1 = __importDefault(__webpack_require__(/*! ../../../widgets */ \"./lib/cjs/widgets/index.js\"));\nconst addons_1 = __importDefault(__webpack_require__(/*! ../../../addons */ \"./lib/cjs/addons/index.js\"));\nconst uploadAdapter_1 = __webpack_require__(/*! ../../../providers/storage/uploadAdapter */ \"./lib/cjs/providers/storage/uploadAdapter.js\");\nconst en_1 = __importDefault(__webpack_require__(/*! ../../../translations/en */ \"./lib/cjs/translations/en.js\"));\nconst Templates_1 = __importDefault(__webpack_require__(/*! ../../../templates/Templates */ \"./lib/cjs/templates/Templates.js\"));\nconst isIEBrowser = FormioUtils.getBrowserInfo().ie;\n/**\n * This is the Component class\n which all elements within the FormioForm derive from.\n */\nclass Component extends Element_1.default {\n static schema(...sources) {\n return lodash_1.default.merge({\n /**\n * Determines if this component provides an input.\n */\n input: true,\n /**\n * The data key for this component (how the data is stored in the database).\n */\n key: '',\n /**\n * The input placeholder for this component.\n */\n placeholder: '',\n /**\n * The input prefix\n */\n prefix: '',\n /**\n * The custom CSS class to provide to this component.\n */\n customClass: '',\n /**\n * The input suffix.\n */\n suffix: '',\n /**\n * If this component should allow an array of values to be captured.\n */\n multiple: false,\n /**\n * The default value of this component.\n */\n defaultValue: null,\n /**\n * If the data of this component should be protected (no GET api requests can see the data)\n */\n protected: false,\n /**\n * Validate if the value of this component should be unique within the form.\n */\n unique: false,\n /**\n * If the value of this component should be persisted within the backend api database.\n */\n persistent: true,\n /**\n * Determines if the component should be within the form, but not visible.\n */\n hidden: false,\n /**\n * If the component should be cleared when hidden.\n */\n clearOnHide: true,\n /**\n * This will refresh this component options when this field changes.\n */\n refreshOn: '',\n /**\n * This will redraw the component when this field changes.\n */\n redrawOn: '',\n /**\n * If this component should be included as a column within a submission table.\n */\n tableView: false,\n /**\n * If this component should be rendering in modal.\n */\n modalEdit: false,\n /**\n * The input label provided to this component.\n */\n label: '',\n dataGridLabel: false,\n labelPosition: 'top',\n description: '',\n errorLabel: '',\n tooltip: '',\n hideLabel: false,\n tabindex: '',\n disabled: false,\n autofocus: false,\n dbIndex: false,\n customDefaultValue: '',\n calculateValue: '',\n calculateServer: false,\n widget: null,\n /**\n * Attributes that will be assigned to the input elements of this component.\n */\n attributes: {},\n /**\n * This will perform the validation on either \"change\" or \"blur\" of the input element.\n */\n validateOn: 'change',\n /**\n * The validation criteria for this component.\n */\n validate: {\n /**\n * If this component is required.\n */\n required: false,\n /**\n * Custom JavaScript validation.\n */\n custom: '',\n /**\n * If the custom validation should remain private (only the backend will see it and execute it).\n */\n customPrivate: false,\n /**\n * If this component should implement a strict date validation if the Calendar widget is implemented.\n */\n strictDateValidation: false,\n multiple: false,\n unique: false\n },\n /**\n * The simple conditional settings for a component.\n */\n conditional: {\n show: null,\n when: null,\n eq: ''\n },\n overlay: {\n style: '',\n left: '',\n top: '',\n width: '',\n height: '',\n },\n allowCalculateOverride: false,\n encrypted: false,\n showCharCount: false,\n showWordCount: false,\n properties: {},\n allowMultipleMasks: false,\n addons: [],\n serverOverride: {},\n }, ...sources);\n }\n /**\n * Return the simple condition settings as part of the component.\n * @returns {object} - The simple conditional settings.\n */\n static get conditionOperatorsSettings() {\n return {\n operators: ['isEqual', 'isNotEqual', 'isEmpty', 'isNotEmpty'],\n valueComponent() {\n return {\n type: 'textfield',\n widget: {\n type: 'input'\n }\n };\n }\n };\n }\n /**\n * Return the array of possible types of component value absed on its schema.\n * @param schema\n * @returns {Array}\n */\n static savedValueTypes(schema) {\n schema = schema || {};\n return FormioUtils.getComponentSavedTypes(schema) || [FormioUtils.componentValueTypes.any];\n }\n /**\n * Provides a table view for this component. Override if you wish to do something different than using getView\n * method of your instance.\n * @param value\n * @param options\n */\n /* eslint-disable no-unused-vars */\n static tableView(value, options) { }\n /* eslint-enable no-unused-vars */\n /**\n * Initialize a new Component.\n * @param {object} component - The component JSON you wish to initialize.\n * @param {object} options - The options for this component.\n * @param {object} data - The global data submission object this component will belong.\n */\n /* eslint-disable max-statements */\n constructor(component, options, data) {\n var _a, _b, _c, _d;\n super(Object.assign({\n renderMode: 'form',\n attachMode: 'full',\n noDefaults: false\n }, options || {}));\n // Restore the component id.\n if (component && component.id) {\n this.id = component.id;\n }\n /**\n * Determines if this component has a condition assigned to it.\n * @type {null}\n * @private\n */\n this._hasCondition = null;\n /**\n * The row index for this component.\n */\n this._rowIndex = undefined;\n /**\n * References to dom elements\n */\n this.refs = {};\n // Allow global override for any component JSON.\n if (component &&\n this.options.components &&\n this.options.components[component.type]) {\n lodash_1.default.merge(component, this.options.components[component.type]);\n }\n /**\n * An array of all the children components errors.\n */\n this.childErrors = [];\n /**\n * Last validation errors that have occured.\n */\n this._errors = [];\n this._visibleErrors = [];\n /**\n * The Form.io component JSON schema.\n * @type {*}\n */\n this.component = this.mergeSchema(component || {});\n // Add the id to the component.\n this.component.id = this.id;\n this.afterComponentAssign();\n // Save off the original component to be used in logic.\n this.originalComponent = (0, utils_1.fastCloneDeep)(this.component);\n /**\n * If the component has been attached\n */\n this.attached = false;\n /**\n * If the component has been rendered\n */\n this.rendered = false;\n /**\n * The data object in which this component resides.\n * @type {*}\n */\n this._data = data || {};\n /**\n * Tool tip text after processing\n * @type {string}\n */\n this.tooltip = '';\n /**\n * The row path of this component.\n * @type {number}\n */\n this.row = this.options.row;\n /**\n * Points to a flat map of child components (if applicable).\n * @type {object}\n */\n this.childComponentsMap = {};\n /**\n * Determines if this component is disabled, or not.\n * @type {boolean}\n */\n this._disabled = (0, utils_1.boolValue)(this.component.disabled) ? this.component.disabled : false;\n /**\n * Points to the root component, usually the FormComponent.\n * @type {Component}\n */\n this.root = this.options.root || this;\n this.localRoot = this.options.localRoot || this;\n /**\n * If this input has been input and provided value.\n * @type {boolean}\n */\n this.pristine = true;\n /**\n * Points to the parent component.\n * @type {Component}\n */\n this.parent = this.options.parent;\n /**\n * The component paths for this component.\n * @type {import('@formio/core').ComponentPaths} - The component paths.\n */\n this.paths = FormioUtils.getComponentPaths(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths), { dataIndex: this.options.rowIndex === undefined ? (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.paths) === null || _d === void 0 ? void 0 : _d.dataIndex : this.options.rowIndex }));\n this.options.name = this.options.name || 'data';\n this._path = '';\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n /**\n * Determines if this component is conditionally hidden. Should generally not be set outside of conditional logic pipeline.\n * This is necessary because of clearOnHide behavior that only clears when conditionally hidden - we need to track\n * conditionallyHidden separately from \"regular\" visibility.\n */\n this.checkConditionallyHidden(null, data);\n /**\n * Determines if this component is visible, or not.\n */\n this._parentVisible = this.options.hasOwnProperty('parentVisible') ? this.options.parentVisible : true;\n this._visible = this._parentVisible && (this.hasCondition() ? !this._conditionallyHidden : !this.component.hidden);\n this._parentDisabled = false;\n /**\n * The reference attribute name for this component\n */\n this._referenceAttributeName = 'ref';\n /**\n * Used to trigger a new change in this component.\n * @type {Function} - Call to trigger a change in this component.\n */\n let changes = [];\n let lastChanged = null;\n let triggerArgs = [];\n const _triggerChange = lodash_1.default.debounce((...args) => {\n if (this.root) {\n this.root.changing = false;\n }\n triggerArgs = [];\n if (!args[1] && lastChanged) {\n // Set the changed component if one isn't provided.\n args[1] = lastChanged;\n }\n if (lodash_1.default.isEmpty(args[0]) && lastChanged) {\n // Set the flags if it is empty and lastChanged exists.\n args[0] = lastChanged.flags;\n }\n lastChanged = null;\n args[3] = changes;\n const retVal = this.onChange(...args);\n changes = [];\n return retVal;\n }, 100);\n this.triggerChange = (...args) => {\n if (args[1]) {\n // Make sure that during the debounce that we always track lastChanged component, even if they\n // don't provide one later.\n lastChanged = args[1];\n changes.push(lastChanged);\n }\n if (this.root) {\n this.root.changing = true;\n }\n if (args.length) {\n triggerArgs = args;\n }\n return _triggerChange(...triggerArgs);\n };\n /**\n * Used to trigger a redraw event within this component.\n * @type {Function}\n */\n this.triggerRedraw = lodash_1.default.debounce(this.redraw.bind(this), 100);\n /**\n * list of attached tooltips\n * @type {Array}\n */\n this.tooltips = [];\n /**\n * List of attached addons\n * @type {Array}\n */\n this.addons = [];\n // To force this component to be invalid.\n this.invalid = false;\n if (this.component) {\n this.type = this.component.type;\n if (this.allowData && this.key) {\n this.options.name += `[${this.key}]`;\n // If component is visible or not set to clear on hide, set the default value.\n if (!(this.conditionallyHidden && this.component.clearOnHide)) {\n if (!this.hasValue()) {\n if (this.shouldAddDefaultValue) {\n this.dataValue = this.defaultValue;\n }\n }\n else {\n // Ensure the dataValue is set.\n /* eslint-disable no-self-assign */\n this.dataValue = this.dataValue;\n /* eslint-enable no-self-assign */\n }\n }\n }\n /**\n * The element information for creating the input element.\n * @type {*}\n */\n this.info = this.elementInfo();\n }\n // Allow anyone to hook into the component creation.\n this.hook('component');\n if (!this.options.skipInit) {\n if (typeof this.beforeInit === 'function') {\n this.beforeInit();\n }\n this.init();\n }\n }\n /* eslint-enable max-statements */\n get componentsMap() {\n var _a;\n return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.childComponentsMap) || {};\n }\n get parentConditionallyHidden() {\n let parentHidden = false;\n let currentParent = this.parent;\n while (currentParent) {\n parentHidden = parentHidden || currentParent._conditionallyHidden;\n if (parentHidden) {\n break;\n }\n currentParent = currentParent.parent;\n }\n return parentHidden;\n }\n get data() {\n return this._data;\n }\n set data(value) {\n this._data = value;\n }\n mergeSchema(component = {}) {\n return lodash_1.default.defaultsDeep(component, this.defaultSchema);\n }\n // Allow componets to notify when ready.\n get ready() {\n return Promise.resolve(this);\n }\n get isPDFReadOnlyMode() {\n return this.parent &&\n this.parent.form &&\n (this.parent.form.display === 'pdf') &&\n this.options.readOnly;\n }\n get labelInfo() {\n const label = {};\n label.hidden = this.labelIsHidden();\n label.className = '';\n label.labelPosition = this.component.labelPosition;\n label.tooltipClass = `${this.iconClass('question-sign')} text-muted`;\n const isPDFReadOnlyMode = this.isPDFReadOnlyMode;\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required) && !isPDFReadOnlyMode) {\n label.className += ' field-required';\n }\n if (label.hidden) {\n label.className += ' control-label--hidden';\n }\n if (this.info.attr.id) {\n label.for = this.info.attr.id;\n }\n return label;\n }\n init() {\n var _a;\n this.disabled = this.shouldDisabled;\n this.checkConditionallyHidden();\n this._visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);\n if ((_a = this.component.addons) === null || _a === void 0 ? void 0 : _a.length) {\n this.component.addons.forEach((addon) => this.createAddon(addon));\n }\n }\n /**\n * Get Row Index.\n * @returns {number} - The row index.\n */\n get rowIndex() {\n return this._rowIndex;\n }\n /**\n * Set Row Index to row and update each component.\n * @param {number} value - The row index.\n * @returns {void}\n */\n set rowIndex(value) {\n var _a, _b;\n this.paths = FormioUtils.getComponentPaths(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (((_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths) || {})), { dataIndex: value }));\n this._rowIndex = value;\n }\n afterComponentAssign() {\n //implement in extended classes\n }\n createAddon(addonConfiguration) {\n var _a;\n const name = addonConfiguration.name;\n if (!name) {\n return;\n }\n const settings = ((_a = addonConfiguration.settings) === null || _a === void 0 ? void 0 : _a.data) || {};\n const Addon = addons_1.default[name.value];\n let addon = null;\n if (Addon) {\n const supportedComponents = Addon.info.supportedComponents;\n const supportsThisComponentType = !(supportedComponents === null || supportedComponents === void 0 ? void 0 : supportedComponents.length) ||\n supportedComponents.indexOf(this.component.type) !== -1;\n if (supportsThisComponentType) {\n addon = new Addon(settings, this);\n this.addons.push(addon);\n }\n else {\n console.warn(this.t('addonSupportTypeError', {\n type: this.component.type,\n label: name.label\n }));\n }\n }\n return addon;\n }\n teardown() {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n delete this._currentForm;\n delete this.parent;\n delete this.root;\n delete this.triggerChange;\n delete this.triggerRedraw;\n if (this.options) {\n delete this.options.root;\n delete this.options.parent;\n delete this.options.i18next;\n }\n super.teardown();\n }\n destroy(all = false) {\n super.destroy(all);\n this.detach();\n this.addons.forEach((addon) => addon.destroy());\n if (all) {\n this.teardown();\n }\n }\n get shouldDisabled() {\n return this.options.readOnly || this.component.disabled || (this.options.hasOwnProperty('disabled') && this.options.disabled[this.key]);\n }\n get isInputComponent() {\n return !this.component.hasOwnProperty('input') || this.component.input;\n }\n get allowData() {\n return this.hasInput;\n }\n get hasInput() {\n return this.isInputComponent || (this.refs.input && this.refs.input.length);\n }\n get defaultSchema() {\n return Component.schema();\n }\n get key() {\n return lodash_1.default.get(this.component, 'key', '');\n }\n get path() {\n return this.paths.dataPath;\n }\n set path(path) {\n throw new Error(this.t('setPathError'));\n }\n set parentVisible(value) {\n this._parentVisible = value;\n }\n get parentVisible() {\n return this._parentVisible;\n }\n set parentDisabled(value) {\n this._parentDisabled = value;\n }\n get parentDisabled() {\n return this._parentDisabled;\n }\n shouldForceVisibility(component, visibility) {\n if (!this.options[visibility]) {\n return false;\n }\n if (!component) {\n component = this.component;\n }\n if (lodash_1.default.isArray(this.options[visibility])) {\n return this.options[visibility].includes(component.key);\n }\n return this.options[visibility][component.key];\n }\n shouldForceHide(component) {\n return this.shouldForceVisibility(component, 'hide');\n }\n shouldForceShow(component) {\n return this.shouldForceVisibility(component, 'show');\n }\n /**\n * Sets the component visibility.\n * @param {boolean} value - Whether the component should be visible or not.\n */\n set visible(value) {\n if (this._visible !== value) {\n // Skip if this component is set to visible and is supposed to be hidden.\n if (value && this.shouldForceHide()) {\n return;\n }\n // Skip if this component is set to hidden and is supposed to be shown.\n if (!value && this.shouldForceShow()) {\n return;\n }\n this._visible = value;\n this.redraw();\n }\n }\n /**\n * Returns the component visibility\n * @returns {boolean} - Whether the component is visible or not.\n */\n get visible() {\n // Show only if visibility changes or if we are in builder mode or if hidden fields should be shown.\n if (this.builderMode || this.previewMode || this.options.showHiddenFields) {\n return true;\n }\n if (this.shouldForceHide()) {\n return false;\n }\n if (this.shouldForceShow()) {\n return true;\n }\n return this._visible && this._parentVisible;\n }\n get conditionallyHidden() {\n return this._conditionallyHidden || this.parentConditionallyHidden;\n }\n /**\n * Evaluates whether the component is conditionally hidden (as opposed to intentionally hidden, e.g. via the `hidden` component schema property).\n * @param {object} data - The data object to evaluate the condition against.\n * @param {object} row - The row object to evaluate the condition against.\n * @returns {boolean} - Whether the component is conditionally hidden.\n */\n checkConditionallyHidden(data = null, row = null) {\n this._conditionallyHidden = false;\n if (!this.hasCondition()) {\n this._conditionallyHidden = this.parentConditionallyHidden;\n return this._conditionallyHidden;\n }\n this._conditionallyHidden = !this.conditionallyVisible(data, row) || this.parentConditionallyHidden;\n return this._conditionallyHidden;\n }\n get currentForm() {\n return this._currentForm;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n }\n get fullMode() {\n return this.options.attachMode === 'full';\n }\n get builderMode() {\n return this.options.attachMode === 'builder';\n }\n get calculatedPath() {\n console.error(this.t('calculatedPathDeprecation'));\n return this.path;\n }\n get labelPosition() {\n return this.component.labelPosition;\n }\n get labelWidth() {\n const width = this.component.labelWidth;\n return width >= 0 ? width : 30;\n }\n get labelMargin() {\n const margin = this.component.labelMargin;\n return margin >= 0 ? margin : 3;\n }\n get isAdvancedLabel() {\n return [\n 'left-left',\n 'left-right',\n 'right-left',\n 'right-right'\n ].includes(this.labelPosition);\n }\n get labelPositions() {\n return this.labelPosition.split('-');\n }\n get skipInEmail() {\n return false;\n }\n rightDirection(direction) {\n if (this.options.condensedMode) {\n return false;\n }\n return direction === 'right';\n }\n getLabelInfo(isCondensed = false) {\n const isRightPosition = this.rightDirection(this.labelPositions[0]);\n const isLeftPosition = this.labelPositions[0] === 'left' || isCondensed;\n const isRightAlign = this.rightDirection(this.labelPositions[1]);\n let contentMargin = '';\n if (this.component.hideLabel) {\n const margin = isCondensed ? 0 : this.labelWidth + this.labelMargin;\n contentMargin = isRightPosition ? `margin-right: ${margin}%` : '';\n contentMargin = isLeftPosition ? `margin-left: ${margin}%` : '';\n }\n const labelStyles = `\n flex: ${this.labelWidth};\n ${isRightPosition ? 'margin-left' : 'margin-right'}: ${this.labelMargin}%;\n `;\n const contentStyles = `\n flex: ${100 - this.labelWidth - this.labelMargin};\n ${contentMargin};\n ${this.component.hideLabel ? `max-width: ${100 - this.labelWidth - this.labelMargin}` : ''};\n `;\n return {\n isRightPosition,\n isRightAlign,\n labelStyles,\n contentStyles\n };\n }\n /**\n * Returns only the schema that is different from the default.\n * @param {object} schema - The \"full\" json schema for the component.\n * @param {object} defaultSchema - The \"default\" json schema for the component.\n * @param {boolean} recursion - If we are currently in a recursive loop.\n * @returns {object} - The minified json schema for this component.\n */\n getModifiedSchema(schema, defaultSchema, recursion) {\n const modified = {};\n if (!defaultSchema) {\n return schema;\n }\n lodash_1.default.each(schema, (val, key) => {\n if (!lodash_1.default.isArray(val) && lodash_1.default.isObject(val) && defaultSchema.hasOwnProperty(key)) {\n const subModified = this.getModifiedSchema(val, defaultSchema[key], true);\n if (!lodash_1.default.isEmpty(subModified)) {\n modified[key] = subModified;\n }\n }\n else if (lodash_1.default.isArray(val)) {\n if (val.length !== 0 && !lodash_1.default.isEqual(val, defaultSchema[key])) {\n modified[key] = val;\n }\n }\n else if ((!recursion && (key === 'type')) ||\n (!recursion && (key === 'key')) ||\n (!recursion && (key === 'label')) ||\n (!recursion && (key === 'input')) ||\n (!recursion && (key === 'tableView')) ||\n (val !== '' && !defaultSchema.hasOwnProperty(key)) ||\n (val !== '' && val !== defaultSchema[key]) ||\n (defaultSchema[key] && val !== defaultSchema[key])) {\n modified[key] = val;\n }\n });\n return modified;\n }\n /**\n * Returns the JSON schema for this component.\n * @returns {object} - The JSON schema for this component.\n */\n get schema() {\n return (0, utils_1.fastCloneDeep)(this.getModifiedSchema(lodash_1.default.omit(this.component, 'id'), this.defaultSchema));\n }\n /**\n * Returns true if component is inside DataGrid\n * @returns {boolean} - True if component is inside DataGrid\n */\n get isInDataGrid() {\n return this.inDataGrid;\n }\n /**\n * Translate a text using the i18n system.\n * @param {string} text - The i18n identifier.\n * @param {object} params - The i18n parameters to use for translation.\n * @param {...any} args - Additional arguments to pass to the translation library.\n * @returns {string} - The translated text.\n */\n t(text, params = {}, ...args) {\n if (!text) {\n return '';\n }\n // Use _userInput: true to ignore translations from defaults\n if (text in en_1.default && params._userInput) {\n return text;\n }\n params.data = params.data || this.rootValue;\n params.row = params.row || this.data;\n params.component = params.component || this.component;\n return super.t(text, params, ...args);\n }\n labelIsHidden() {\n return !this.component.label ||\n ((!this.isInDataGrid && this.component.hideLabel) ||\n (this.isInDataGrid && !this.component.dataGridLabel) ||\n this.options.floatingLabels ||\n this.options.inputsOnly) && !this.builderMode;\n }\n transform(type, value) {\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n return frameworkTemplates.hasOwnProperty('transform')\n ? frameworkTemplates.transform(type, value, this)\n : (type, value) => value;\n }\n getTemplate(names, modes) {\n modes = Array.isArray(modes) ? modes : [modes];\n names = Array.isArray(names) ? names : [names];\n if (!modes.includes('form')) {\n modes.push('form');\n }\n let result = null;\n if (this.options.templates) {\n result = this.checkTemplate(this.options.templates, names, modes);\n if (result) {\n return result;\n }\n }\n const frameworkTemplates = this.options.template ? Templates_1.default.templates[this.options.template] : Templates_1.default.current;\n result = this.checkTemplate(frameworkTemplates, names, modes);\n if (result) {\n return result;\n }\n // Default back to bootstrap if not defined.\n const name = names[names.length - 1];\n const templatesByName = Templates_1.default.defaultTemplates[name];\n if (!templatesByName) {\n return { template: this.t('unknownTemplate', { name }) };\n }\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode };\n }\n return { template: templatesByName.form };\n }\n checkTemplate(templates, names, modes) {\n for (const name of names) {\n const templatesByName = templates[name];\n if (templatesByName) {\n const { referenceAttributeName } = templatesByName;\n const templateByMode = this.checkTemplateMode(templatesByName, modes);\n if (templateByMode) {\n return { template: templateByMode, referenceAttributeName };\n }\n }\n }\n return null;\n }\n checkTemplateMode(templatesByName, modes) {\n for (const mode of modes) {\n const templateByMode = templatesByName[mode];\n if (templateByMode) {\n return templateByMode;\n }\n }\n return null;\n }\n getFormattedAttribute(attr) {\n return attr ? this.t(attr, { _userInput: true }).replace(/\"/g, '"') : '';\n }\n getFormattedTooltip(tooltipValue) {\n const tooltip = this.interpolate(tooltipValue || '').replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return this.getFormattedAttribute(tooltip);\n }\n isHtmlRenderMode() {\n return this.options.renderMode === 'html';\n }\n renderTemplate(name, data = {}, modeOption = '') {\n // Need to make this fall back to form if renderMode is not found similar to how we search templates.\n const mode = modeOption || this.options.renderMode || 'form';\n data.component = this.component;\n data.self = this;\n data.options = this.options;\n data.readOnly = this.options.readOnly;\n data.iconClass = this.iconClass.bind(this);\n data.size = this.size.bind(this);\n data.t = this.t.bind(this);\n data.transform = this.transform.bind(this);\n data.id = data.id || this.id;\n data.key = data.key || this.key;\n data.value = data.value || this.dataValue;\n data.disabled = this.disabled;\n data.builder = this.builderMode;\n data.render = (...args) => {\n console.warn(this.t('renderTemplateFunctionDeprecation'));\n return this.renderTemplate(...args);\n };\n data.label = data.labelInfo || this.labelInfo;\n data.tooltip = this.getFormattedTooltip(this.component.tooltip);\n // Allow more specific template names\n const names = [\n `${name}-${this.component.type}-${this.key}`,\n `${name}-${this.component.type}`,\n `${name}-${this.key}`,\n `${name}`,\n ];\n // Allow template alters.\n const { referenceAttributeName, template } = this.getTemplate(names, mode);\n if (referenceAttributeName) {\n this._referenceAttributeName = referenceAttributeName;\n }\n return this.hook(`render${name.charAt(0).toUpperCase() + name.substring(1, name.length)}`, this.interpolate(template, data), data, mode);\n }\n /**\n * Sanitize an html string.\n * @param {string} dirty - The dirty html string to sanitize.\n * @param {boolean} forceSanitize - If we should force the sanitize to occur.\n * @param {object} options - The options for the sanitize.\n * @returns {*} - The sanitized html string.\n */\n sanitize(dirty, forceSanitize = false, options = {}) {\n var _a;\n if (!this.shouldSanitizeValue && !forceSanitize) {\n return dirty;\n }\n return FormioUtils.sanitize(dirty, {\n sanitizeConfig: lodash_1.default.merge(((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitizeConfig) || {}, options || {}),\n });\n }\n /**\n * Render a template string into html.\n * @param {string} template - The template to render.\n * @param {object} data - The data to provide to the template.\n * @returns {HTMLElement | string} - The created element or an empty string if template is not specified.\n */\n renderString(template, data) {\n if (!template) {\n return '';\n }\n // Interpolate the template and populate\n return this.interpolate(template, data);\n }\n /**\n * Allows for modification of the component value prior to submission.\n * @param {*} input - The input to be modified.\n * @returns {*} - The modified input mapping for the extended component.\n */\n performInputMapping(input) {\n return input;\n }\n /**\n * Returns the component \"widget\" if one is available.\n * @returns {Widget|null} - The widget instance. null if not available.\n */\n get widget() {\n var _a;\n const settings = this.component.widget;\n if (settings && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.shadowRoot)) {\n settings.shadowRoot = this.root.shadowRoot;\n }\n const widget = settings && widgets_1.default[settings.type] ? new widgets_1.default[settings.type](settings, this.component, this) : null;\n return widget;\n }\n /**\n * Returns the native supported browser language.\n * @returns {string|null} - The native browser language that is supported.\n */\n getBrowserLanguage() {\n const nav = window.navigator;\n const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];\n let language;\n // support for HTML 5.1 \"navigator.languages\"\n if (Array.isArray(nav.languages)) {\n for (let i = 0; i < nav.languages.length; i++) {\n language = nav.languages[i];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n }\n // support for other well known properties in browsers\n for (let i = 0; i < browserLanguagePropertyKeys.length; i++) {\n language = nav[browserLanguagePropertyKeys[i]];\n if (language && language.length) {\n return language.split(';')[0];\n }\n }\n return null;\n }\n /**\n * Called before a next and previous page is triggered allowing the components to perform special functions.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the next/previous page navigation.\n */\n beforePage() {\n return Promise.resolve(true);\n }\n /**\n * Called before the next page is triggered allowing the components to hook into the page navigation and perform tasks.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the next page navigation.\n */\n beforeNext() {\n return this.beforePage(true);\n }\n /**\n * Called before a submission is triggered allowing the components to perform special async functions.\n * @returns {Promise<boolean>} - A promise to resolve when the component is no longer blocking the submission.\n */\n beforeSubmit() {\n return Promise.resolve(true);\n }\n /**\n * Return the submission timezone.\n * @returns {string} - The submission timezone.\n */\n get submissionTimezone() {\n this.options.submissionTimezone = this.options.submissionTimezone || lodash_1.default.get(this.root, 'options.submissionTimezone');\n return this.options.submissionTimezone;\n }\n /**\n * Return the current timezone.\n * @returns {string} - The current timezone.\n */\n get timezone() {\n return this.getTimezone(this.component);\n }\n /**\n * Return the current timezone.\n * @param {object} settings - Settings to control how the timezone should be returned.\n * @returns {string} - The current timezone.\n */\n getTimezone(settings) {\n if (settings.timezone) {\n return settings.timezone;\n }\n if (settings.displayInTimezone === 'utc') {\n return 'UTC';\n }\n const submissionTimezone = this.submissionTimezone;\n if (submissionTimezone &&\n ((settings.displayInTimezone === 'submission') ||\n ((this.options.pdf || this.options.server) && (settings.displayInTimezone === 'viewer')))) {\n return submissionTimezone;\n }\n // Return current timezone if none are provided.\n return (0, utils_1.currentTimezone)();\n }\n /**\n *\n * @param {HTMLElement} element - The containing DOM element to query for the ref value.\n * @param {object} refs - The references to load.\n * @param {string} [referenceAttributeName] - The attribute name to use for the reference.\n */\n loadRefs(element, refs, referenceAttributeName) {\n if (!element) {\n return;\n }\n for (const ref in refs) {\n const refType = refs[ref];\n const isString = typeof refType === 'string';\n const selector = isString && refType.includes('scope')\n ? `:scope > [${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`\n : `[${referenceAttributeName || this._referenceAttributeName || 'ref'}=\"${ref}\"]`;\n if (isString && refType.startsWith('single')) {\n this.refs[ref] = element.querySelector(selector);\n }\n else {\n this.refs[ref] = element.querySelectorAll(selector);\n }\n }\n }\n /**\n * Opens the modal element.\n * @param {string} template - The template to use for the modal dialog.\n */\n setOpenModalElement(template = null) {\n this.componentModal.setOpenModalElement(template || this.getModalPreviewTemplate());\n }\n /**\n * Renders a modal preview template and returns the markup as a string\n * @param {object|null|undefined} ctx - The rendering context\n * @returns {string} - The modal preview markup\n */\n renderModalPreview(ctx) {\n return this.renderTemplate('modalPreview', ctx || {});\n }\n /**\n * Returns the modal preview template.\n * @returns {string} - The modal preview template.\n */\n getModalPreviewTemplate() {\n var _a;\n const dataValue = this.component.type === 'password' ? this.dataValue.replace(/./g, '•') : this.dataValue;\n let modalLabel;\n if (this.hasInput && ((_a = this.component.validate) === null || _a === void 0 ? void 0 : _a.required) && !this.isPDFReadOnlyMode) {\n modalLabel = { className: 'field-required' };\n }\n return this.renderModalPreview({\n previewText: this.getValueAsString(dataValue, { modalPreview: true }) || this.t('clickToSetValue'),\n messages: '',\n labelInfo: modalLabel,\n });\n }\n /**\n * Performs a complete build of a component, which empties, renders, sets the content in the DOM, and then finally attaches events.\n * @param {HTMLElement} element - The element to attach this component to.\n * @returns {Promise<void>} - A promise that resolves when the component has been built.\n */\n build(element) {\n element = element || this.element;\n this.empty(element);\n this.setContent(element, this.render());\n return this.attach(element);\n }\n get hasModalSaveButton() {\n return true;\n }\n /**\n * Renders a component as an HTML string.\n * @param {string} children - The contents of all the children HTML as a string.\n * @param {boolean} topLevel - If this is the topmost component that is being rendered.\n * @returns {string} - The rendered HTML string of a component.\n */\n render(children = this.t('unknownComponent', { type: this.component.type }), topLevel = false) {\n const isVisible = this.visible;\n this.rendered = true;\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n return ComponentModal_1.default.render(this, {\n visible: isVisible,\n showSaveButton: this.hasModalSaveButton,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n else {\n return this.renderTemplate('component', {\n visible: isVisible,\n id: this.id,\n classes: this.className,\n styles: this.customStyle,\n children\n }, topLevel);\n }\n }\n /**\n * Creates the tooltip instance using tippy.js and returns it\n * @param {HTMLElement} tooltipEl - HTML element to attach the tooltip\n * @param {object|null|undefined} settings - tippy.js options\n * @returns {import('tippy.js').Tippy} - tippy.js instance\n */\n createTooltip(tooltipEl, settings = {}) {\n const tooltipAttribute = tooltipEl.getAttribute('data-tooltip');\n const tooltipDataTitle = tooltipEl.getAttribute('data-title');\n const tooltipText = this.interpolate(tooltipDataTitle || tooltipAttribute)\n .replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n return (0, tippy_js_1.default)(tooltipEl, Object.assign(Object.assign({ allowHTML: true, trigger: 'mouseenter click focus', placement: 'right', zIndex: 10000, interactive: true }, settings), { content: this.t(this.sanitize(tooltipText), { _userInput: true }) }));\n }\n /**\n * Attaches all the tooltips provided the refs object.\n * @param {object} toolTipsRefs - The refs for the tooltips within your template.\n * @returns {void}\n */\n attachTooltips(toolTipsRefs) {\n toolTipsRefs === null || toolTipsRefs === void 0 ? void 0 : toolTipsRefs.forEach((tooltip, index) => {\n if (tooltip) {\n this.tooltips[index] = this.createTooltip(tooltip);\n }\n });\n }\n /**\n * Create a new component modal for this component.\n * @param {HTMLElement} element - The element to attach the modal to.\n * @param {boolean} modalShouldBeOpened - TRUE if the modal should open immediately.\n * @param {any} currentValue - The current value of the component.\n * @returns {ComponentModal} - The created component modal.\n */\n createComponentModal(element, modalShouldBeOpened, currentValue) {\n return new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n }\n /**\n * Attaches all event listensers for this component to the DOM elements that were rendered.\n * @param {HTMLElement} element - The element to attach the listeners to.\n * @returns {Promise<void>} - Resolves when the component is done attaching to the DOM.\n */\n attach(element) {\n if (!this.builderMode && !this.previewMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n const openModalTemplate = this.componentModal && modalShouldBeOpened\n ? this.componentModal.openModalTemplate\n : null;\n this.componentModal = this.createComponentModal(element, modalShouldBeOpened, currentValue);\n this.setOpenModalElement(openModalTemplate);\n }\n this.attached = true;\n this.setElement(element);\n element.component = this;\n // If this already has an id, get it from the dom. If SSR, it could be different from the initiated id.\n if (this.element.id) {\n this.id = this.element.id;\n this.component.id = this.id;\n }\n this.loadRefs(element, {\n messageContainer: 'single',\n tooltip: 'multiple'\n });\n this.attachTooltips(this.refs.tooltip);\n // Attach logic.\n this.attachLogic();\n this.autofocus();\n // Allow global attach.\n this.hook('attachComponent', element, this);\n // Allow attach per component type.\n const type = this.component.type;\n if (type) {\n this.hook(`attach${type.charAt(0).toUpperCase() + type.substring(1, type.length)}`, element, this);\n }\n this.restoreFocus();\n this.addons.forEach((addon) => addon.attach(element));\n return Promise.resolve();\n }\n /**\n * Restors the \"focus\" on a component after a redraw event has occured.\n */\n restoreFocus() {\n var _a, _b, _c;\n const isFocused = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.path) === this.path;\n if (isFocused) {\n this.loadRefs(this.element, { input: 'multiple' });\n this.focus((_c = this.root.currentSelection) === null || _c === void 0 ? void 0 : _c.index);\n this.restoreCaretPosition();\n }\n }\n /**\n * Adds a keyboard shortcut to this component.\n * @param {HTMLElement} element - The element to attach the keyboard shortcut to.\n * @param {string} shortcut - The keyboard shortcut to add.\n * @returns {void}\n */\n addShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || !this.root || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.addShortcut(element, shortcut);\n }\n /**\n * Removes a keyboard shortcut from this component.\n * @param {HTMLElement} element - The element to remove the keyboard shortcut from.\n * @param {string} shortcut - The keyboard shortcut to remove.\n * @returns {void}\n */\n removeShortcut(element, shortcut) {\n // Avoid infinite recursion.\n if (!element || (this.root === this)) {\n return;\n }\n if (!shortcut) {\n shortcut = this.component.shortcut;\n }\n this.root.removeShortcut(element, shortcut);\n }\n /**\n * Remove all event handlers.\n */\n detach() {\n // First iterate through each ref and delete the component so there are no dangling component references.\n lodash_1.default.each(this.refs, (ref) => {\n if (ref instanceof NodeList) {\n ref.forEach((elem) => {\n delete elem.component;\n });\n }\n else if (ref) {\n delete ref.component;\n }\n });\n this.refs = {};\n this.removeEventListeners();\n this.detachLogic();\n if (this.tooltip) {\n this.tooltip.destroy();\n }\n }\n /**\n * Determines if the component should be refreshed based on the path of another component that changed.\n * @param {string} refreshData - The path of the data that needs to trigger a refresh.\n * @param {boolean} changed - Flag that is true if the data has been changed.\n * @param {any} flags - The flags for the checkData procedure.\n * @returns {void}\n */\n checkRefresh(refreshData, changed, flags) {\n var _a, _b;\n const changePath = lodash_1.default.get(changed, 'instance.path', false);\n // Don't let components change themselves.\n if (changePath && this.path === changePath) {\n return;\n }\n if (refreshData === 'data') {\n this.refresh(this.data, changed, flags);\n }\n else if ((changePath && (((_b = (_a = changed.instance) === null || _a === void 0 ? void 0 : _a.paths) === null || _b === void 0 ? void 0 : _b.localPath) === refreshData)) && changed && changed.instance &&\n // Make sure the changed component is not in a different \"context\". Solves issues where refreshOn being set\n // in fields inside EditGrids could alter their state from other rows (which is bad).\n this.inContext(changed.instance)) {\n this.refresh(changed.value, changed, flags);\n }\n }\n /**\n * Iterates over a list of changes, and determines if the component should be refreshed if it is configured to refresh on any of those components.\n * @param {Array<any>} changes - The list of components that have changed.\n * @param {any} flags - The checkData flags.\n * @returns {void}\n */\n checkRefreshOn(changes, flags = {}) {\n changes = changes || [];\n if (flags.noRefresh) {\n return;\n }\n if (!changes.length && flags.changed) {\n changes = [flags.changed];\n }\n const refreshOn = flags.fromBlur ? this.component.refreshOnBlur : this.component.refreshOn || this.component.redrawOn;\n // If they wish to refresh on a value, then add that here.\n if (refreshOn) {\n if (Array.isArray(refreshOn)) {\n refreshOn.forEach(refreshData => changes.forEach(changed => this.checkRefresh(refreshData, changed, flags)));\n }\n else {\n changes.forEach(changed => this.checkRefresh(refreshOn, changed, flags));\n }\n }\n }\n /**\n * Refreshes the component with a new value.\n * @param {any} value - The latest value of the component to check if it needs to be refreshed.\n * @returns {void}\n */\n refresh(value) {\n if (this.hasOwnProperty('refreshOnValue')) {\n this.refreshOnChanged = !lodash_1.default.isEqual(value, this.refreshOnValue);\n }\n else {\n this.refreshOnChanged = true;\n }\n this.refreshOnValue = (0, utils_1.fastCloneDeep)(value);\n if (this.refreshOnChanged) {\n if (this.component.clearOnRefresh) {\n this.setValue(null);\n }\n this.triggerRedraw();\n }\n }\n /**\n * Checks to see if a separate component is in the \"context\" of this component. This is determined by first checking\n * if they share the same \"data\" object. It will then walk up the parent tree and compare its parents data objects\n * with the components data and returns true if they are in the same context.\n *\n * Different rows of the same EditGrid, for example, are in different contexts.\n * @param {any} component - The component to check if it is in the same context as this component.\n * @returns {boolean} - TRUE if the component is in the same context as this component.\n */\n inContext(component) {\n if (component.data === this.data) {\n return true;\n }\n let parent = this.parent;\n while (parent) {\n if (parent.data === component.data) {\n return true;\n }\n parent = parent.parent;\n }\n return false;\n }\n /**\n * Determines if we are in \"view\" only mode.\n * @returns {boolean} - TRUE if we are in \"view\" only mode.\n */\n get viewOnly() {\n return this.options.readOnly && this.options.viewAsHtml;\n }\n /**\n * Sets the HTMLElement for this component.\n * @param {HTMLElement} element - The element that is attached to this component.\n * @returns {void}\n */\n setElement(element) {\n if (this.element) {\n delete this.element.component;\n delete this.element;\n }\n this.element = element;\n }\n /**\n * Creates an element to hold the \"view only\" version of this component.\n * @returns {HTMLElement} - The element for this component.\n */\n createViewOnlyElement() {\n this.setElement(this.ce('dl', {\n id: this.id\n }));\n if (this.element) {\n // Ensure you can get the component info from the element.\n this.element.component = this;\n }\n return this.element;\n }\n /**\n * The default value for the \"view only\" mode of a component if the value is not provided.\n * @returns {string} - The default value for this component.\n */\n get defaultViewOnlyValue() {\n return '-';\n }\n /**\n * Uses the widget to determine the output string.\n * @param {any} value - The current value of the component.\n * @param {any} options - The options for getValueAsString.\n * @returns {any|Array<any>} - The value as a string.\n */\n getWidgetValueAsString(value, options) {\n const noInputWidget = !this.refs.input || !this.refs.input[0] || !this.refs.input[0].widget;\n if (!value || noInputWidget) {\n if (!this.widget || !value) {\n return value;\n }\n else {\n return this.widget.getValueAsString(value);\n }\n }\n if (Array.isArray(value)) {\n const values = [];\n value.forEach((val, index) => {\n const widget = this.refs.input[index] && this.refs.input[index].widget;\n if (widget) {\n values.push(widget.getValueAsString(val, options));\n }\n });\n return values;\n }\n const widget = this.refs.input[0].widget;\n return widget.getValueAsString(value, options);\n }\n /**\n * Returns the value of the component as a string.\n * @param {any} value - The value for this component.\n * @param {any} options - The options for this component.\n * @returns {string} - The string representation of the value of this component.\n */\n getValueAsString(value, options) {\n if (!value) {\n return '';\n }\n value = this.getWidgetValueAsString(value, options);\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n if (lodash_1.default.isPlainObject(value)) {\n return JSON.stringify(value);\n }\n if (value === null || value === undefined) {\n return '';\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue);\n }\n /**\n * Returns the string representation \"view\" of the component value.\n * @param {any} value - The value of the component.\n * @param {any} options - The options for this component.\n * @returns {string} - The string representation of the value of this component.\n */\n getView(value, options) {\n if (this.component.protected) {\n return '--- PROTECTED ---';\n }\n return this.getValueAsString(value, options);\n }\n /**\n * Updates the items list for this component. Useful for Select and other List component types.\n * @param {...any} args - The arguments to pass to the onChange event.\n * @returns {void}\n */\n updateItems(...args) {\n this.restoreValue();\n this.onChange(...args);\n }\n /**\n * Returns the value for a specific item in a List type component.\n * @param {any} data - The data for this component.\n * @param {boolean} [forceUseValue] - if true, return 'value' property of the data\n * @returns {any} - The value of the item.\n */\n itemValue(data, forceUseValue = false) {\n if (lodash_1.default.isObject(data) && !lodash_1.default.isArray(data)) {\n if (this.valueProperty) {\n return lodash_1.default.get(data, this.valueProperty);\n }\n if (forceUseValue) {\n return data.value;\n }\n }\n return data;\n }\n /**\n * Returns the item value for html mode.\n * @param {any} value - The value for this component.\n * @returns {any} - The value of the item for html mode.\n */\n itemValueForHTMLMode(value) {\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item) ? this.itemValueForHTMLMode(item) : this.itemValue(item));\n return values.join(', ');\n }\n return this.itemValue(value);\n }\n /**\n * Creates a modal to input the value of this component.\n * @param {HTMLElement} element - The element to attach the modal to.\n * @param {any} attr - A list of attributes to add to the modal.\n * @param {boolean} confirm - If we should add a confirmation to the modal that keeps it from closing unless confirmed.\n * @returns {HTMLElement} - The created modal element.\n */\n createModal(element, attr, confirm) {\n const dialog = this.ce('div', attr || {});\n this.setContent(dialog, this.renderTemplate('dialog'));\n // Add refs to dialog, not \"this\".\n dialog.refs = {};\n this.loadRefs.call(dialog, dialog, {\n dialogOverlay: 'single',\n dialogContents: 'single',\n dialogClose: 'single',\n });\n dialog.refs.dialogContents.appendChild(element);\n document.body.appendChild(dialog);\n document.body.classList.add('modal-open');\n dialog.close = () => {\n document.body.classList.remove('modal-open');\n dialog.dispatchEvent(new CustomEvent('close'));\n };\n this.addEventListener(dialog, 'close', () => this.removeChildFrom(dialog, document.body));\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n const handleCloseClick = (e) => {\n if (confirm) {\n confirm().then(() => close(e))\n .catch(() => { });\n }\n else {\n close(e);\n }\n };\n this.addEventListener(dialog.refs.dialogOverlay, 'click', handleCloseClick);\n this.addEventListener(dialog.refs.dialogClose, 'click', handleCloseClick);\n return dialog;\n }\n /**\n * Uses CSS classes to show or hide an element.\n * @returns {boolean} - TRUE if the element has been css removed.\n */\n get optimizeRedraw() {\n if (this.options.optimizeRedraw && this.element && !this.visible) {\n this.addClass(this.element, 'formio-removed');\n return true;\n }\n return false;\n }\n /**\n * Retrieves the CSS class name of this component.\n * @returns {string} - The class name of this component.\n */\n get className() {\n let className = this.hasInput ? `${this.transform('class', 'form-group')} has-feedback ` : '';\n className += `formio-component formio-component-${this.component.type} `;\n // TODO: find proper way to avoid overriding of default type-based component styles\n if (this.key && this.key !== 'form') {\n className += `formio-component-${this.key} `;\n }\n if (this.component.multiple) {\n className += 'formio-component-multiple ';\n }\n if (this.component.customClass) {\n className += this.component.customClass;\n }\n if (this.hasInput && this.component.validate && (0, utils_1.boolValue)(this.component.validate.required)) {\n className += ' required';\n }\n if (this.labelIsHidden()) {\n className += ' formio-component-label-hidden';\n }\n if (!this.visible) {\n className += ' formio-hidden';\n }\n return className;\n }\n /**\n * Build the custom style from the layout values\n * @returns {string} - The custom style\n */\n get customStyle() {\n let customCSS = '';\n lodash_1.default.each(this.component.style, (value, key) => {\n if (value !== '') {\n customCSS += `${key}:${value};`;\n }\n });\n return customCSS;\n }\n /**\n * Returns the component condition operator settings if available.\n * @returns {object} - The component condition operator settings.\n */\n static get serverConditionSettings() {\n return Component.conditionOperatorsSettings;\n }\n /**\n * Returns if the application is on a mobile device.\n * @returns {boolean} - TRUE if the application is on a mobile device.\n */\n get isMobile() {\n return (0, ismobilejs_1.default)();\n }\n /**\n * Returns the outside wrapping element of this component.\n * @returns {HTMLElement} - The wrapping element of this component.\n */\n getElement() {\n return this.element;\n }\n /**\n * Create an evaluation context for all script executions and interpolations.\n * @param {any} additional - Additional context to provide.\n * @returns {any} - The evaluation context.\n */\n evalContext(additional) {\n return super.evalContext(Object.assign({\n component: this.component,\n row: this.data,\n rowIndex: this.rowIndex,\n data: this.rootValue,\n iconClass: this.iconClass.bind(this),\n // Bind the translate function to the data context of any interpolated string.\n // It is useful to translate strings in different scenarions (eg: custom edit grid templates, custom error messages etc.)\n // and desirable to be publicly available rather than calling the internal {instance.t} function in the template string.\n t: this.t.bind(this),\n submission: (this.root ? this.root._submission : {\n data: this.rootValue\n }),\n form: this.root ? this.root._form : {},\n options: this.options,\n }, additional));\n }\n /**\n * Sets the pristine flag for this component.\n * @param {boolean} pristine - TRUE to make pristine, FALSE not pristine.\n */\n setPristine(pristine) {\n this.pristine = pristine;\n }\n /**\n * Returns if the component is pristine.\n * @returns {boolean} - TRUE if the component is pristine.\n */\n get isPristine() {\n return this.pristine;\n }\n /**\n * Sets the dirty flag for this component.\n * @param {boolean} dirty - TRUE to make dirty, FALSE not dirty.\n */\n setDirty(dirty) {\n this.dirty = dirty;\n }\n /**\n * Returns if the component is dirty.\n * @returns {boolean} - TRUE if the component is dirty.\n */\n get isDirty() {\n return this.dirty;\n }\n /**\n * Removes a value out of the data array and rebuild the rows.\n * @param {number} index - The index of the data element to remove.\n */\n removeValue(index) {\n this.splice(index);\n this.redraw();\n this.restoreValue();\n this.triggerRootChange();\n }\n /**\n * Returns the icon class for a given icon name.\n * @param {string} name - The name of the icon you wish to fetch provided the icon class. This is the \"font awesome\" version of the name of the icon.\n * @param {boolean} spinning - If the component should be spinning.\n * @returns {string} - The icon class for the equivalent icon in the iconset we are using.\n */\n iconClass(name, spinning) {\n const iconset = this.options.iconset || Templates_1.default.current.defaultIconset || 'fa';\n return Templates_1.default.current.hasOwnProperty('iconClass')\n ? Templates_1.default.current.iconClass(iconset, name, spinning)\n : this.options.iconset === 'fa' ? Templates_1.default.defaultTemplates.iconClass(iconset, name, spinning) : name;\n }\n /**\n * Returns the size css class names for our current template.\n * @param {string} size - The size class name for the default iconset.\n * @returns {string} - The size class for our component.\n */\n size(size) {\n return Templates_1.default.current.hasOwnProperty('size')\n ? Templates_1.default.current.size(size)\n : size;\n }\n /**\n * The readible name for this component.\n * @returns {string} - The name of the component.\n */\n get name() {\n return this.t(this.component.label || this.component.placeholder || this.key, { _userInput: true });\n }\n /**\n * Returns the visible errors for this component.\n * @returns {Array<object>} - The visible errors for this component.\n */\n get visibleErrors() {\n return this._visibleErrors;\n }\n /**\n * Returns all the errors for this component, visible or not.\n * @returns {Array<object>} - All the errors for this component.\n */\n get errors() {\n return this._errors;\n }\n /**\n * Returns the error label for this component.\n * @returns {string} - The error label for this component.\n */\n get errorLabel() {\n return this.t(this.component.errorLabel\n || this.component.label\n || this.component.placeholder\n || this.key);\n }\n /**\n * Get the error message provided a certain type of error.\n * @param {string} type - The type of error to fetch the message for.\n * @returns {string} - The error message configured for this component.\n */\n errorMessage(type) {\n return (this.component.errors && this.component.errors[type]) ? this.component.errors[type] : type;\n }\n /**\n * Sets the content, innerHTML, of an element to the sanitized content.\n * @param {HTMLElement} element - The element to set the innerHTML to.\n * @param {string} content - The HTML string content that we wish to set.\n * @param {boolean} forceSanitize - If we should force the content to be sanitized.\n * @param {any} sanitizeOptions - The options for the sanitize function.\n * @returns {boolean} - TRUE if the content was sanitized and set.\n */\n setContent(element, content, forceSanitize, sanitizeOptions) {\n if (element instanceof HTMLElement) {\n element.innerHTML = this.sanitize(content, forceSanitize, sanitizeOptions);\n return true;\n }\n return false;\n }\n /**\n * Restores the caret position in the input element after a refresh occurs.\n */\n restoreCaretPosition() {\n var _a, _b, _c;\n if ((_a = this.root) === null || _a === void 0 ? void 0 : _a.currentSelection) {\n if ((_b = this.refs.input) === null || _b === void 0 ? void 0 : _b.length) {\n const { index } = this.root.currentSelection;\n let input = this.refs.input[index];\n const isInputRangeSelectable = (i) => /text|search|password|tel|url/i.test((i === null || i === void 0 ? void 0 : i.type) || '');\n if (input) {\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(input.value.length, input.value.length);\n }\n }\n else {\n input = this.refs.input[this.refs.input.length];\n const lastCharacter = ((_c = input.value) === null || _c === void 0 ? void 0 : _c.length) || 0;\n if (isInputRangeSelectable(input)) {\n input.setSelectionRange(lastCharacter, lastCharacter);\n }\n }\n }\n }\n }\n /**\n * Redraw the component.\n * @returns {Promise<void>} - A promise that resolves when the component is done redrawing.\n */\n redraw() {\n // Don't bother if we have not built yet.\n if (!this.element || !this.element.parentNode || this.optimizeRedraw) {\n // Return a non-resolving promise.\n return Promise.resolve();\n }\n this.detach();\n this.emit('redraw');\n // Since we are going to replace the element, we need to know it's position so we can find it in the parent's children.\n const parent = this.element.parentNode;\n const index = Array.prototype.indexOf.call(parent.children, this.element);\n this.element.outerHTML = this.sanitize(this.render());\n this.setElement(parent.children[index]);\n return this.attach(this.element);\n }\n /**\n * Rebuild and redraw a component.\n * @returns {Promise<void>} - A promise that resolves when the component is done rebuilding and redrawing.\n */\n rebuild() {\n this.destroy();\n this.init();\n this.visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;\n return this.redraw();\n }\n /**\n * Removes all event listeners attached to this component.\n */\n removeEventListeners() {\n super.removeEventListeners();\n this.tooltips.forEach(tooltip => tooltip.destroy());\n this.tooltips = [];\n }\n /**\n * Returns if the dom node has the classes provided.\n * @param {HTMLElement} element - The element to check for the class.\n * @param {string} className - The name of the class to check.\n * @returns {boolean|void} - TRUE if the element has the class.\n */\n hasClass(element, className) {\n if (!element) {\n return;\n }\n return super.hasClass(element, this.transform('class', className));\n }\n /**\n * Adds a class to an HTML element.\n * @param {HTMLElement} element - The dom element to add the class to.\n * @param {string} className - The class name you wish to add.\n * @returns {this|void} - The component instance.\n */\n addClass(element, className) {\n if (!element) {\n return;\n }\n return super.addClass(element, this.transform('class', className));\n }\n /**\n * Removes a class from an element.\n * @param {HTMLElement} element - The element to remove the class from.\n * @param {string} className - The class name to remove.\n * @returns {this|void} - The component instance.\n */\n removeClass(element, className) {\n if (!element) {\n return;\n }\n return super.removeClass(element, this.transform('class', className));\n }\n /**\n * Determines if this component has a condition defined.\n * @returns {boolean} - TRUE if the component has a condition defined.\n */\n hasCondition() {\n if (this._hasCondition !== null) {\n return this._hasCondition;\n }\n this._hasCondition = FormioUtils.hasCondition(this.component);\n return this._hasCondition;\n }\n /**\n * Check if this component is conditionally visible.\n * @param {any} data - The data to check against.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is conditionally visible.\n */\n conditionallyVisible(data, row) {\n data = data || this.rootValue;\n row = row || this.data;\n if (this.builderMode || this.previewMode) {\n return true;\n }\n data = data || (this.root ? this.root.data : {});\n return this.checkCondition(row, data);\n }\n /**\n * Checks the condition of this component.\n *\n * TODO: Switch row and data parameters to be consistent with other methods.\n * @param {any} row - The row contextual data.\n * @param {any} data - The global data object.\n * @returns {boolean} - True if the condition applies to this component.\n */\n checkCondition(row, data) {\n return FormioUtils.checkCondition(this.component, row || this.data, data || this.rootValue, this.root ? this.root._form : {}, this);\n }\n /**\n * Check for conditionals and hide/show the element based on those conditions.\n * @param {any} data - The data to check against.\n * @param {any} flags - The flags passed to checkData function.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is visible.\n */\n checkComponentConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n if (!this.builderMode & !this.previewMode && this.fieldLogic(data, row)) {\n this.redraw();\n }\n // Check advanced conditions (and cache the result)\n const shouldClear = this.checkConditionallyHidden(data, row);\n // Check visibility\n const visible = (this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden);\n if (this.visible !== visible) {\n this.visible = visible;\n }\n // Wait for visibility to update for nested components, so the component state is up-to-date when\n // calling clearOnHide\n if (shouldClear) {\n this.clearOnHide();\n }\n return visible;\n }\n /**\n * Checks conditions for this component and any sub components.\n * @param {any} data - The data to check against.\n * @param {any} flags - The flags passed to checkData function.\n * @param {any} row - The row data to check against.\n * @returns {boolean} - TRUE if the component is visible.\n */\n checkConditions(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.checkComponentConditions(data, flags, row);\n }\n /**\n * Returns the component logic if applicable.\n * @returns {Array<object>} - The component logic.\n */\n get logic() {\n return this.component.logic || [];\n }\n /**\n * Check all triggers and apply necessary actions.\n * @param {any} data - The data to check against.\n * @param {any} row - The row data to check against.\n * @returns {boolean|void} - TRUE if the component was altered.\n */\n fieldLogic(data = this.rootValue, row = this.data) {\n const logics = this.logic;\n // If there aren't logic, don't go further.\n if (logics.length === 0) {\n return;\n }\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n let changed = logics.reduce((changed, logic) => {\n const result = FormioUtils.checkTrigger(newComponent, logic.trigger, row, data, this.root ? this.root._form : {}, this);\n return (result ? this.applyActions(newComponent, logic.actions, result, row, data) : false) || changed;\n }, false);\n // If component definition changed, replace and mark as changed.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n changed = true;\n const disabled = this.shouldDisabled;\n // Change disabled state if it has changed\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n }\n return changed;\n }\n /**\n * Retuns if the browser is Internet Explorer.\n * @returns {boolean} - TRUE if the browser is IE.\n */\n isIE() {\n if (typeof window === 'undefined') {\n return false;\n }\n const userAgent = window.navigator.userAgent;\n const msie = userAgent.indexOf('MSIE ');\n if (msie > 0) {\n // IE 10 or older => return version number\n return parseInt(userAgent.substring(msie + 5, userAgent.indexOf('.', msie)), 10);\n }\n const trident = userAgent.indexOf('Trident/');\n if (trident > 0) {\n // IE 11 => return version number\n const rv = userAgent.indexOf('rv:');\n return parseInt(userAgent.substring(rv + 3, userAgent.indexOf('.', rv)), 10);\n }\n const edge = userAgent.indexOf('Edge/');\n if (edge > 0) {\n // IE 12 (aka Edge) => return version number\n return parseInt(userAgent.substring(edge + 5, userAgent.indexOf('.', edge)), 10);\n }\n // other browser\n return false;\n }\n /**\n * Defines the logic action value through evaluation.\n * @param {object} action - The action within the Logic system to perform.\n * @param {object} argsObject - The arguments to pass to the evaluation.\n * @returns {any} - The result of the evaluation.\n */\n defineActionValue(action, argsObject) {\n return this.evaluate(action.value, argsObject, 'value');\n }\n /**\n * Apply the actions of Logic for a component once the conditions have been met.\n * @param {object} newComponent - The new component to apply the actions to.\n * @param {Array<object>} actions - An array of actions\n * @param {any} result - The result of the conditional check in order to evaluate the actions.\n * @param {any} row - The contextual row data for this component.\n * @param {any} data - The global data object for the submission.\n * @returns {boolean} - TRUE if the component was altered.\n */\n applyActions(newComponent, actions, result, row, data) {\n data = data || this.rootValue;\n row = row || this.data;\n return actions.reduce((changed, action) => {\n switch (action.type) {\n case 'property': {\n FormioUtils.setActionProperty(newComponent, action, result, row, data, this);\n const property = action.property.value;\n if (!lodash_1.default.isEqual(lodash_1.default.get(this.component, property), lodash_1.default.get(newComponent, property))) {\n // Advanced Logic can modify the component's hidden property; because we track conditionally hidden state\n // separately from the component's hidden property, and technically this Advanced Logic conditionally hides\n // a component, we need to set _conditionallyHidden to the new value\n if (property === 'hidden') {\n this._conditionallyHidden = newComponent.hidden;\n }\n changed = true;\n }\n break;\n }\n case 'value': {\n const oldValue = this.getValue();\n const newValue = this.defineActionValue(action, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n component: newComponent,\n result,\n });\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n case 'mergeComponentSchema': {\n const schema = this.evaluate(action.schemaDefinition, {\n value: lodash_1.default.clone(this.getValue()),\n data,\n row,\n component: newComponent,\n result,\n }, 'schema');\n lodash_1.default.assign(newComponent, schema);\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n changed = true;\n }\n break;\n }\n case 'customAction': {\n const oldValue = this.getValue();\n const newValue = this.evaluate(action.customAction, {\n value: lodash_1.default.clone(oldValue),\n data,\n row,\n input: oldValue,\n component: newComponent,\n result,\n }, 'value');\n if (!lodash_1.default.isEqual(oldValue, newValue) && !(this.component.clearOnHide && this.conditionallyHidden)) {\n this.setValue(newValue);\n if (this.viewOnly) {\n this.dataValue = newValue;\n }\n changed = true;\n }\n break;\n }\n }\n return changed;\n }, false);\n }\n // Deprecated\n addInputError(message, dirty, elements) {\n this.addMessages(message);\n this.setErrorClasses(elements, dirty, !!message);\n }\n // Deprecated\n removeInputError(elements) {\n this.setErrorClasses(elements, true, false);\n }\n /**\n * Add a new input error to this element.\n * @param {Array<object>|string} messages - An array of messages to add to the element.\n * @returns {void}\n */\n addMessages(messages) {\n if (!messages) {\n return;\n }\n // Standardize on array of objects for message.\n if (typeof messages === 'string') {\n messages = {\n messages,\n level: 'error',\n };\n }\n if (!Array.isArray(messages)) {\n messages = [messages];\n }\n messages = lodash_1.default.uniqBy(messages, message => message.message);\n if (this.refs.messageContainer) {\n this.setContent(this.refs.messageContainer, messages.map((message) => {\n return this.renderTemplate('message', Object.assign({}, message));\n }).join(''));\n }\n }\n /**\n * Sets the form input widget error classes.\n * @param {Array<HTMLElement>} elements - An array of DOM elements to set the error classes on.\n * @param {boolean} dirty - If the input is dirty.\n * @param {boolean} hasErrors - If the input has errors.\n * @param {boolean} hasMessages - If the input has messages.\n * @param {HTMLElement} element - The wrapper element for all the other elements passed in first argument.\n * @returns {void}\n */\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n this.clearErrorClasses();\n elements.forEach((element) => {\n this.setElementInvalid(this.performInputMapping(element), false);\n });\n this.setInputWidgetErrorClasses(elements, hasErrors);\n // do not set error classes for hidden components\n if (!this.visible) {\n return;\n }\n if (hasErrors) {\n // Add error classes\n elements.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), true);\n });\n if (dirty && this.options.highlightErrors) {\n this.addClass(element, this.options.componentErrorClass);\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n if (hasMessages) {\n this.addClass(element, 'has-message');\n }\n }\n /**\n * Adds the classes necessary to mark an element as invalid.\n * @param {HTMLElement} element - The element you wish to add the invalid classes to.\n * @param {boolean} invalid - TRUE if the component is invalid, FALSE otherwise.\n * @returns {void}\n */\n setElementInvalid(element, invalid) {\n if (!element)\n return;\n if (invalid) {\n this.addClass(element, 'is-invalid');\n }\n else {\n this.removeClass(element, 'is-invalid');\n }\n element.setAttribute('aria-invalid', invalid ? 'true' : 'false');\n }\n /**\n * Clears the components data if it is conditionally hidden AND clearOnHide is set to true for this component.\n */\n clearOnHide() {\n // clearOnHide defaults to true for old forms (without the value set) so only trigger if the value is false.\n if (\n // if change happens inside EditGrid's row, it doesn't trigger change on the root level, so rootPristine will be true\n (!this.rootPristine || this.options.server || (0, utils_1.isInsideScopingComponent)(this)) &&\n this.component.clearOnHide !== false &&\n !this.options.readOnly &&\n !this.options.showHiddenFields) {\n if (this.conditionallyHidden) {\n this.deleteValue();\n }\n else if (!this.hasValue() && this.shouldAddDefaultValue) {\n // If shown, ensure the default is set.\n this.setValue(this.defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n }\n /**\n * Triggers a debounced onChange event for the root component (usually Webform).\n * @param {...any} args - The arguments to pass to the onChange event.\n */\n triggerRootChange(...args) {\n if (this.options.onChange) {\n this.options.onChange(...args);\n }\n else if (this.root && this.root.triggerChange) {\n this.root.triggerChange(...args);\n }\n }\n /**\n * Called when the component value has been changed. This will then trigger the root level onChange handler which\n * propagates the checkData methods for the full component tree.\n * @param {any} flags - The flags for the change event propagation.\n * @param {boolean} fromRoot - If the change event is from the root component.\n * @returns {boolean} - TRUE if the component has changed.\n */\n onChange(flags, fromRoot) {\n flags = flags || {};\n if (flags.modified) {\n if (!flags.noPristineChangeOnModified) {\n this.pristine = false;\n }\n this.addClass(this.getElement(), 'formio-modified');\n }\n // If we are supposed to validate on blur, then don't trigger validation yet.\n if (this.component.validateOn === 'blur' || this.component.validateOn === 'submit') {\n flags.noValidate = true;\n }\n if (this.component.onChange) {\n this.evaluate(this.component.onChange, {\n flags\n });\n }\n // Set the changed variable.\n const changed = {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: flags\n };\n // Emit the change.\n this.emit('componentChange', changed);\n // Do not propogate the modified flag.\n let modified = false;\n if (flags.modified) {\n modified = true;\n delete flags.modified;\n }\n // Bubble this change up to the top.\n if (!fromRoot) {\n this.triggerRootChange(flags, changed, modified);\n }\n return changed;\n }\n get wysiwygDefault() {\n return {\n quill: {\n theme: 'snow',\n placeholder: this.t(this.component.placeholder, { _userInput: true }),\n modules: {\n toolbar: [\n [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown\n [{ 'header': [1, 2, 3, 4, 5, 6, false] }],\n [{ 'font': [] }],\n ['bold', 'italic', 'underline', 'strike', { 'script': 'sub' }, { 'script': 'super' }, 'clean'],\n [{ 'color': [] }, { 'background': [] }],\n [{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }, { 'align': [] }],\n ['blockquote', 'code-block'],\n ['link', 'image', 'video', 'formula', 'source']\n ]\n }\n },\n ace: {\n theme: 'ace/theme/xcode',\n maxLines: 12,\n minLines: 12,\n tabSize: 2,\n mode: 'ace/mode/javascript',\n placeholder: this.t(this.component.placeholder, { _userInput: true })\n },\n ckeditor: {\n image: {\n toolbar: [\n 'imageTextAlternative',\n '|',\n 'imageStyle:full',\n 'imageStyle:alignLeft',\n 'imageStyle:alignCenter',\n 'imageStyle:alignRight'\n ],\n styles: [\n 'full',\n 'alignLeft',\n 'alignCenter',\n 'alignRight'\n ]\n },\n extraPlugins: []\n },\n default: {}\n };\n }\n addCKE(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? {} : settings;\n settings.base64Upload = this.component.isUploadEnabled ? false : true;\n settings.mediaEmbed = { previewsInData: true };\n settings = lodash_1.default.merge(this.wysiwygDefault.ckeditor, lodash_1.default.get(this.options, 'editors.ckeditor.settings', {}), settings);\n if (this.component.isUploadEnabled) {\n settings.extraPlugins.push((0, uploadAdapter_1.getFormioUploadAdapterPlugin)(this.fileService, this));\n }\n return Formio_1.Formio.requireLibrary('ckeditor', isIEBrowser ? 'CKEDITOR' : 'ClassicEditor', lodash_1.default.get(this.options, 'editors.ckeditor.src', `${Formio_1.Formio.cdn.ckeditor}/ckeditor.js`), true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n if (isIEBrowser) {\n const editor = CKEDITOR.replace(element);\n editor.on('change', () => onChange(editor.getData()));\n return Promise.resolve(editor);\n }\n else {\n return ClassicEditor.create(element, settings).then(editor => {\n editor.model.document.on('change', () => onChange(editor.data.get()));\n return editor;\n });\n }\n });\n }\n addQuill(element, settings, onChange) {\n settings = lodash_1.default.isEmpty(settings) ? this.wysiwygDefault.quill : settings;\n settings = lodash_1.default.merge(this.wysiwygDefault.quill, lodash_1.default.get(this.options, 'editors.quill.settings', {}), settings);\n settings = Object.assign(Object.assign({}, settings), { modules: Object.assign({ table: true }, settings.modules) });\n // Lazy load the quill css.\n Formio_1.Formio.requireLibrary(`quill-css-${settings.theme}`, 'Quill', [\n { type: 'styles', src: `${Formio_1.Formio.cdn.quill}/quill.${settings.theme}.css` }\n ], true);\n // Lazy load the quill library.\n return Formio_1.Formio.requireLibrary('quill', 'Quill', lodash_1.default.get(this.options, 'editors.quill.src', `${Formio_1.Formio.cdn.quill}/quill.min.js`), true)\n .then(() => {\n return Formio_1.Formio.requireLibrary('quill-table', 'Quill', `${Formio_1.Formio.cdn.baseUrl}/quill/quill-table.js`, true)\n .then(() => {\n if (!element.parentNode) {\n return Promise.reject();\n }\n this.quill = new Quill(element, isIEBrowser ? Object.assign(Object.assign({}, settings), { modules: {} }) : settings);\n /** This block of code adds the [source] capabilities. See https://codepen.io/anon/pen/ZyEjrQ */\n const txtArea = document.createElement('textarea');\n txtArea.setAttribute('class', 'quill-source-code');\n this.quill.addContainer('ql-custom').appendChild(txtArea);\n const qlSource = element.parentNode.querySelector('.ql-source');\n if (qlSource) {\n this.addEventListener(qlSource, 'click', (event) => {\n event.preventDefault();\n if (txtArea.style.display === 'inherit') {\n this.quill.setContents(this.quill.clipboard.convert({ html: txtArea.value }));\n }\n txtArea.style.display = (txtArea.style.display === 'none') ? 'inherit' : 'none';\n });\n }\n /** END CODEBLOCK */\n // Make sure to select cursor when they click on the element.\n this.addEventListener(element, 'click', () => this.quill.focus());\n // Allows users to skip toolbar items when tabbing though form\n const elm = document.querySelectorAll('.ql-formats > button');\n for (let i = 0; i < elm.length; i++) {\n elm[i].setAttribute('tabindex', '-1');\n }\n this.quill.on('text-change', () => {\n txtArea.value = this.quill.root.innerHTML;\n onChange(txtArea);\n });\n return this.quill;\n });\n });\n }\n get shouldSanitizeValue() {\n var _a;\n // Sanitize value if sanitizing for thw whole content is turned off\n return (((_a = this.options) === null || _a === void 0 ? void 0 : _a.sanitize) !== false);\n }\n addAce(element, settings, onChange) {\n if (!settings || (settings.theme === 'snow')) {\n const mode = settings ? settings.mode : '';\n settings = {};\n if (mode) {\n settings.mode = mode;\n }\n }\n settings = lodash_1.default.merge(this.wysiwygDefault.ace, lodash_1.default.get(this.options, 'editors.ace.settings', {}), settings || {});\n return Formio_1.Formio.requireLibrary('ace', 'ace', lodash_1.default.get(this.options, 'editors.ace.src', `${Formio_1.Formio.cdn.ace}/ace.js`), true)\n .then((editor) => {\n editor = editor.edit(element);\n editor.removeAllListeners('change');\n editor.setOptions(settings);\n editor.getSession().setMode(settings.mode);\n editor.on('change', () => onChange(editor.getValue()));\n if (settings.isUseWorkerDisabled) {\n editor.session.setUseWorker(false);\n }\n return editor;\n });\n }\n getDragula() {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve) => {\n return Formio_1.Formio.requireLibrary('dragula', 'dragula', `${Formio_1.Formio.cdn.dragula}/dragula.js`, true, (ready) => {\n return ready.then(resolve);\n });\n });\n });\n }\n get tree() {\n return this.component.tree || false;\n }\n /**\n * The empty value for this component.\n * @returns {null} - The empty value for this component.\n */\n get emptyValue() {\n return null;\n }\n /**\n * Returns if this component has a value set.\n * @param {any} data - The global data object.\n * @returns {boolean} - TRUE if a value is set.\n */\n hasValue(data) {\n return !lodash_1.default.isUndefined(lodash_1.default.get(data || this.data, this.key));\n }\n /**\n * Get the data value at the root level.\n * @returns {*} - The root value for the component, typically the Webform data object.\n */\n get rootValue() {\n return this.root ? this.root.data : this.data;\n }\n get rootPristine() {\n return lodash_1.default.get(this, 'root.pristine', false);\n }\n /**\n * Get the static value of this component.\n * @returns {*} - The value for this component.\n */\n get dataValue() {\n if (!this.key) {\n return this.emptyValue;\n }\n if (!this.hasValue() && this.shouldAddDefaultValue) {\n const empty = this.component.multiple ? [] : this.emptyValue;\n if (!this.rootPristine) {\n this.dataValue = empty;\n }\n return empty;\n }\n return lodash_1.default.get(this._data, this.key);\n }\n /**\n * Sets the static value of this component.\n * @param {*} value - The value to set for this component.\n */\n set dataValue(value) {\n if (!this.allowData || !this.key) {\n return;\n }\n if ((value !== null) && (value !== undefined)) {\n value = this.hook('setDataValue', value, this.key, this._data);\n }\n if ((value === null) || (value === undefined)) {\n this.unset();\n return;\n }\n lodash_1.default.set(this._data, this.key, value);\n return;\n }\n /**\n * Splice a value from the dataValue.\n * @param {number} index - The index to splice for an array component values.\n * @param {*} flags - The flags to use when splicing the value.\n */\n splice(index, flags = {}) {\n if (this.hasValue()) {\n const dataValue = this.dataValue || [];\n if (lodash_1.default.isArray(dataValue) && dataValue.hasOwnProperty(index)) {\n dataValue.splice(index, 1);\n this.dataValue = dataValue;\n this.triggerChange(flags);\n }\n }\n }\n unset() {\n lodash_1.default.unset(this._data, this.key);\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n getCustomDefaultValue(defaultValue) {\n if (this.component.customDefaultValue && !this.options.preview) {\n defaultValue = this.evaluate(this.component.customDefaultValue, { value: '' }, 'value');\n }\n return defaultValue;\n }\n get shouldAddDefaultValue() {\n return !this.options.noDefaults || (this.component.defaultValue && !this.isEmpty(this.component.defaultValue)) || this.component.customDefaultValue;\n }\n get defaultValue() {\n let defaultValue = this.emptyValue;\n if (this.component.defaultValue) {\n defaultValue = this.component.defaultValue;\n }\n defaultValue = this.getCustomDefaultValue(defaultValue);\n const checkMask = (value) => {\n if (typeof value === 'string') {\n if (this.component.type !== 'textfield') {\n const placeholderChar = this.placeholderChar;\n value = (0, vanilla_text_mask_1.conformToMask)(value, this.defaultMask, { placeholderChar }).conformedValue;\n if (!FormioUtils.matchInputMask(value, this.defaultMask)) {\n value = '';\n }\n }\n }\n else {\n value = '';\n }\n return value;\n };\n if (Array.isArray(this.defaultMask) ? this.defaultMask.length > 0 : this.defaultMask) {\n if (Array.isArray(defaultValue)) {\n defaultValue = defaultValue.map(checkMask);\n }\n else {\n defaultValue = checkMask(defaultValue);\n }\n }\n // Clone so that it creates a new instance.\n return lodash_1.default.cloneDeep(defaultValue);\n }\n /**\n * Get the input value of this component.\n * @returns {*} - The value for the component.\n */\n getValue() {\n if (!this.hasInput || this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n const values = [];\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n if (!this.component.multiple) {\n return this.getValueAt(i);\n }\n values.push(this.getValueAt(i));\n }\n }\n if (values.length === 0 && !this.component.multiple) {\n return '';\n }\n return values;\n }\n /**\n * Get the value at a specific index.\n * @param {number} index - For an array component or multiple values, this returns the value at a specific index.\n * @returns {*} - The value at the specified index.\n */\n getValueAt(index) {\n const input = this.performInputMapping(this.refs.input[index]);\n return input ? input.value : undefined;\n }\n /**\n * Set the value of this component.\n * @param {*} value - The value to set for this component.\n * @param {*} flags - The flags to use when setting the value.\n * @returns {boolean} - If the value changed.\n */\n setValue(value, flags = {}) {\n const changed = this.updateValue(value, flags);\n value = this.dataValue;\n if (!this.hasInput) {\n return changed;\n }\n const isArray = Array.isArray(value);\n const valueInput = this.refs.fileLink || this.refs.input;\n if (isArray &&\n Array.isArray(this.defaultValue) &&\n this.refs.hasOwnProperty('input') &&\n valueInput &&\n (valueInput.length !== value.length) &&\n this.visible) {\n this.redraw();\n }\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.redraw();\n return changed;\n }\n for (const i in this.refs.input) {\n if (this.refs.input.hasOwnProperty(i)) {\n this.setValueAt(i, isArray && !this.isSingleInputValue() ? value[i] : value, flags);\n }\n }\n return changed;\n }\n /**\n * Returns if the value (e.g. array) should be divided between several inputs\n * @returns {boolean}\n */\n isSingleInputValue() {\n return false;\n }\n /**\n * Set the value at a specific index.\n * @param {number} index - The index to set the value at.\n * @param {*} value - The value to set at the specified index.\n * @param {*} flags - The flags to use when setting the value.\n */\n setValueAt(index, value, flags = {}) {\n if (!flags.noDefault && (value === null || value === undefined) && !this.component.multiple) {\n value = this.defaultValue;\n }\n const input = this.performInputMapping(this.refs.input[index]);\n const valueMaskInput = this.refs.valueMaskInput;\n if ((valueMaskInput === null || valueMaskInput === void 0 ? void 0 : valueMaskInput.mask) && valueMaskInput.mask.textMaskInputElement) {\n valueMaskInput.mask.textMaskInputElement.update(value);\n }\n if (input.mask && input.mask.textMaskInputElement) {\n input.mask.textMaskInputElement.update(value);\n }\n else if (input.widget && input.widget.setValue) {\n input.widget.setValue(value);\n }\n else {\n input.value = value;\n }\n }\n get hasSetValue() {\n return this.hasValue() && !this.isEmpty(this.dataValue);\n }\n setDefaultValue() {\n if (this.defaultValue && this.shouldAddDefaultValue) {\n const defaultValue = (this.component.multiple && !this.dataValue.length) ? [] : this.defaultValue;\n this.setValue(defaultValue, {\n noUpdateEvent: true\n });\n }\n }\n /**\n * Restore the value of a control.\n */\n restoreValue() {\n if (this.hasSetValue) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else {\n this.setDefaultValue();\n }\n }\n /**\n * Normalize values coming into updateValue.\n * @param {*} value - The value to normalize before setting.\n * @returns {*} - The normalized value.\n */\n normalizeValue(value) {\n return value;\n }\n /**\n * Update a value of this component.\n * @param {*} value - The value to update.\n * @param {*} flags - The flags to use when updating the value.\n * @returns {boolean} - If the value changed.\n */\n updateComponentValue(value, flags = {}) {\n let newValue = (!flags.resetValue && (value === undefined || value === null)) ? this.getValue() : value;\n newValue = this.normalizeValue(newValue, flags);\n const oldValue = this.dataValue;\n let changed = ((newValue !== undefined) ? this.hasChanged(newValue, oldValue) : false);\n if (changed) {\n this.dataValue = newValue;\n changed = this.dataValue !== oldValue;\n this.updateOnChange(flags, changed);\n }\n if (this.componentModal && flags && flags.fromSubmission) {\n this.componentModal.setValue(value);\n }\n return changed;\n }\n /**\n * Updates the value of this component plus all sub-components.\n * @param {...any} args - The arguments to pass to updateValue.\n * @returns {boolean} - If the value changed.\n */\n updateValue(...args) {\n return this.updateComponentValue(...args);\n }\n getIcon(name, content, styles, ref = 'icon') {\n return this.renderTemplate('icon', {\n className: this.iconClass(name),\n ref,\n styles,\n content\n });\n }\n /**\n * Resets the value of this component.\n */\n resetValue() {\n this.unset();\n this.setValue(this.defaultValue || this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n /**\n * Determine if the value of this component has changed.\n * @param {*} newValue - The new value to check.\n * @param {*} oldValue - The existing value of the component.\n * @returns {boolean} - TRUE if the value has changed.\n */\n hasChanged(newValue, oldValue) {\n if (((newValue === undefined) || (newValue === null)) &&\n ((oldValue === undefined) || (oldValue === null) || this.isEmpty(oldValue))) {\n return false;\n }\n // If we do not have a value and are getting set to anything other than undefined or null, then we changed.\n if (newValue !== undefined &&\n newValue !== null &&\n this.allowData &&\n !this.hasValue()) {\n return true;\n }\n return !lodash_1.default.isEqual(newValue, oldValue);\n }\n /**\n * Update the value on change.\n * @param {*} flags - The flags to use when triggering the on change event.\n * @param {boolean} changed - If the value has changed.\n * @returns {boolean} - If the value changed.\n */\n updateOnChange(flags = {}, changed = false) {\n if (!flags.noUpdateEvent && changed) {\n if (flags.fromSubmission) {\n // Reset the errors when a submission has been made and allow it to revalidate.\n this._errors = [];\n }\n this.triggerChange(flags);\n return true;\n }\n return false;\n }\n convertNumberOrBoolToString(value) {\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value.toString();\n }\n return value;\n }\n doValueCalculation(dataValue, data, row) {\n var _a;\n return this.evaluate(this.component.calculateValue, {\n value: dataValue,\n data,\n row: row || this.data,\n submission: ((_a = this.root) === null || _a === void 0 ? void 0 : _a._submission) || {\n data: this.rootValue\n }\n }, 'value');\n }\n /* eslint-disable max-statements */\n calculateComponentValue(data, flags, row) {\n // Skip value calculation for the component if we don't have entire form data set or in builder mode\n if (this.builderMode || lodash_1.default.isUndefined(lodash_1.default.get(this, 'root.data'))) {\n return false;\n }\n // If no calculated value or\n // hidden and set to clearOnHide (Don't calculate a value for a hidden field set to clear when hidden)\n const { clearOnHide } = this.component;\n const shouldBeCleared = this.conditionallyHidden && clearOnHide;\n const allowOverride = lodash_1.default.get(this.component, 'allowCalculateOverride', false);\n if (shouldBeCleared) {\n // remove calculated value so that the value is recalculated once component becomes visible\n if (this.hasOwnProperty('calculatedValue') && allowOverride) {\n lodash_1.default.unset(this, 'calculatedValue');\n }\n return false;\n }\n // Handle all cases when calculated values should not fire.\n if ((this.options.readOnly && !this.options.pdf && !this.component.calculateValue) ||\n !(this.component.calculateValue || this.component.calculateValueVariable) ||\n (this.options.server && !this.component.calculateServer) ||\n (flags.dataSourceInitialLoading && allowOverride)) {\n return false;\n }\n const dataValue = this.dataValue;\n // Calculate the new value.\n let calculatedValue = this.doValueCalculation(dataValue, data, row, flags);\n if (this.options.readOnly && dataValue && !calculatedValue) {\n return false;\n }\n if (lodash_1.default.isNil(calculatedValue)) {\n calculatedValue = this.emptyValue;\n }\n const changed = !lodash_1.default.isEqual(dataValue, calculatedValue);\n // Do not override calculations on server if they have calculateServer set.\n if (allowOverride) {\n // The value is considered locked if it is not empty and comes from a submission value.\n const fromSubmission = (flags.fromSubmission && this.component.persistent === true);\n if (this.isEmpty(dataValue)) {\n // Reset the calculation lock if ever the data is cleared.\n this.calculationLocked = false;\n }\n else if (this.calculationLocked || fromSubmission) {\n this.calculationLocked = true;\n return false;\n }\n const firstPass = (this.calculatedValue === undefined) || flags.resetValue;\n if (firstPass) {\n this.calculatedValue = null;\n }\n const newCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(calculatedValue));\n const previousCalculatedValue = this.normalizeValue(this.convertNumberOrBoolToString(this.calculatedValue));\n const normalizedDataValue = this.normalizeValue(this.convertNumberOrBoolToString(dataValue));\n const calculationChanged = !lodash_1.default.isEqual(previousCalculatedValue, newCalculatedValue);\n const previousChanged = !lodash_1.default.isEqual(normalizedDataValue, previousCalculatedValue);\n if (calculationChanged && previousChanged && !firstPass) {\n return false;\n }\n // Check to ensure that the calculated value is different than the previously calculated value.\n if (previousCalculatedValue && previousChanged && !calculationChanged) {\n this.calculatedValue = null;\n return false;\n }\n if (flags.isReordered || !calculationChanged) {\n return false;\n }\n if (fromSubmission) {\n // If we set value from submission and it differs from calculated one, set the calculated value to prevent overriding dataValue in the next pass\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n return false;\n }\n // If this is the firstPass, and the dataValue is different than to the calculatedValue.\n if (firstPass && !this.isEmpty(dataValue) && changed && calculationChanged) {\n // Return that we have a change so it will perform another pass.\n return true;\n }\n }\n this.calculatedValue = (0, utils_1.fastCloneDeep)(calculatedValue);\n if (changed) {\n if (!flags.noPristineChangeOnModified && this.root.initialized) {\n this.pristine = false;\n }\n flags.triggeredComponentId = this.id;\n return this.setValue(calculatedValue, flags);\n }\n return false;\n }\n /* eslint-enable max-statements */\n /**\n * Performs calculations in this component plus any child components.\n * @param {*} data - The data to perform the calculation with.\n * @param {*} flags - The flags to use when calculating the value.\n * @param {*} row - The contextual row data to use when performing the calculation.\n * @returns {boolean} - TRUE if the value changed.\n */\n calculateValue(data, flags, row) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n return this.calculateComponentValue(data, flags, row);\n }\n /**\n * Get this component's label text.\n * @returns {string} - The label text for this component.\n */\n get label() {\n return this.component.label;\n }\n /**\n * Set this component's label text and render it.\n * @param {string} value - The new label text.\n */\n set label(value) {\n this.component.label = value;\n if (this.labelElement) {\n this.labelElement.innerText = value;\n }\n }\n /**\n * Get FormioForm element at the root of this component tree.\n * @returns {*} root - The root component to search from.\n */\n getRoot() {\n return this.root;\n }\n /**\n * Returns the invalid message, or empty string if the component is valid.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {boolean} ignoreCondition - If conditions for the component should be ignored when checking validity.\n * @param {*} row - Contextual row data for this component.\n * @returns {string} - The message to show when the component is invalid.\n */\n invalidMessage(data, dirty, ignoreCondition, row) {\n var _a;\n if (!row) {\n row = (0, utils_1.getContextualRowData)(this.component, data, this.paths);\n }\n if (!ignoreCondition && !this.checkCondition(row, data)) {\n return '';\n }\n // See if this is forced invalid.\n if (this.invalid) {\n return this.invalid;\n }\n // No need to check for errors if there is no input or if it is pristine.\n if (!this.hasInput || (!dirty && this.pristine)) {\n return '';\n }\n const validationScope = { errors: [] };\n (0, process_1.processOneSync)({\n component: this.component,\n data,\n row,\n path: this.path || this.component.key,\n parent: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component,\n paths: this.paths,\n scope: validationScope,\n instance: this,\n processors: [\n process_1.validateProcessInfo\n ]\n });\n const errors = validationScope.errors;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return lodash_1.default.map(interpolatedErrors, 'message').join('\\n\\n');\n }\n /**\n * Returns if the component is valid or not.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @returns {boolean} - TRUE if the component is valid.\n */\n isValid(data, dirty) {\n return !this.invalidMessage(data, dirty);\n }\n setComponentValidity(errors, dirty, silentCheck) {\n if (silentCheck) {\n return [];\n }\n const messages = errors.filter(message => !message.fromServer);\n if (errors.length && !!messages.length && (!this.isEmpty(this.defaultValue) || dirty || !this.pristine)) {\n return this.setCustomValidity(messages, dirty);\n }\n else {\n return this.setCustomValidity('');\n }\n }\n /**\n * Interpolate errors from the validation methods.\n * @param {Array<any>} errors - An array of errors to interpolate.\n * @returns {Array<any>} - The interpolated errors.\n */\n interpolateErrors(errors) {\n var _a;\n const interpolatedErrors = FormioUtils.interpolateErrors(this.component, errors, this.t.bind(this));\n return ((_a = this.serverErrors) === null || _a === void 0 ? void 0 : _a.length) ? [...interpolatedErrors, ...this.serverErrors] : interpolatedErrors;\n }\n /**\n * Show component validation errors.\n * @param {*} errors - An array of errors that have occured.\n * @param {*} data - The root submission data.\n * @param {*} row - The contextual row data.\n * @param {*} flags - The flags to perform validation.\n * @returns {boolean} - TRUE if the component is valid.\n */\n showValidationErrors(errors, data, row, flags) {\n if (flags.silentCheck) {\n return [];\n }\n let isDirty = (flags.dirty === false) ? false : (this.dirty || flags.dirty);\n if (this.options.alwaysDirty) {\n isDirty = true;\n }\n this.setDirty(isDirty);\n return this.setComponentValidity(errors, isDirty, flags.silentCheck, flags.fromSubmission);\n }\n /**\n * Perform a component validation.\n * @param {*} data - The root data you wish to use for this component.\n * @param {*} row - The contextual row data you wish to use for this component.\n * @param {*} flags - The flags to control the behavior of the validation.\n * @returns {Array<any>} - An array of errors if the component is invalid.\n */\n validateComponent(data = null, row = null, flags = {}) {\n var _a;\n data = data || this.rootValue;\n row = row || this.data;\n const { async = false } = flags;\n if (this.shouldSkipValidation(data, row, flags)) {\n return async ? Promise.resolve([]) : [];\n }\n const processContext = {\n component: this.component,\n data,\n row,\n local: !!flags.local,\n value: this.validationValue,\n parent: (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component,\n paths: this.paths,\n path: this.path || this.component.key,\n instance: this,\n form: this.root ? this.root._form : {},\n scope: { errors: [] },\n processors: [\n process_1.validateProcessInfo\n ]\n };\n if (async) {\n return (0, process_1.processOne)(processContext).then(() => {\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n });\n }\n (0, process_1.processOneSync)(processContext);\n this._errors = this.interpolateErrors(processContext.scope.errors);\n return this._errors;\n }\n /**\n * Checks the validity of this component and sets the error message if it is invalid.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {*} flags - The flags to use when checking the validity.\n * @param {Array<any>} allErrors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkComponentValidity(data = null, dirty = false, row = null, flags = {}, allErrors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n flags.dirty = dirty || false;\n if (flags.async) {\n return this.validateComponent(data, row, flags).then((errors) => {\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => { var _a, _b; return (((_a = err === null || err === void 0 ? void 0 : err.component) === null || _a === void 0 ? void 0 : _a.key) || ((_b = err === null || err === void 0 ? void 0 : err.context) === null || _b === void 0 ? void 0 : _b.key)) === this.component.key; });\n }\n }\n this.showValidationErrors(errors, data, row, flags);\n return errors.length === 0;\n });\n }\n else {\n const errors = this.validateComponent(data, row, flags);\n this.showValidationErrors(errors, data, row, flags);\n allErrors.push(...errors);\n if (this.parent && this.parent.childErrors) {\n if (errors.length) {\n this.parent.childErrors.push(...errors);\n }\n else {\n lodash_1.default.remove(this.parent.childErrors, (err) => { var _a, _b; return (((_a = err === null || err === void 0 ? void 0 : err.component) === null || _a === void 0 ? void 0 : _a.key) || ((_b = err === null || err === void 0 ? void 0 : err.context) === null || _b === void 0 ? void 0 : _b.key)) === this.component.key; });\n }\n }\n return errors.length === 0;\n }\n }\n /**\n * Checks the validity of the component.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {boolean} silentCheck - If the check should be silent and not set the error messages.\n * @param {Array<any>} errors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkValidity(data = null, dirty = false, row = null, silentCheck = false, errors = []) {\n data = data || this.rootValue;\n row = row || this.data;\n return this.checkComponentValidity(data, dirty, row, { silentCheck }, errors);\n }\n checkAsyncValidity(data = null, dirty = false, row = null, silentCheck = false, errors = []) {\n return this.checkComponentValidity(data, dirty, row, { async: true, silentCheck }, errors);\n }\n /**\n * Check the conditions, calculations, and validity of a single component and triggers an update if\n * something changed.\n * @param {*} data - The root data of the change event.\n * @param {*} flags - The flags from this change event.\n * @param {*} row - The contextual row data for this component.\n * @returns {void|boolean} - TRUE if no check should be performed on the component.\n */\n checkData(data = null, flags = null, row = null) {\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n // Needs for Nextgen Rules Engine\n this.resetCaches();\n // Do not trigger refresh if change was triggered on blur event since components with Refresh on Blur have their own listeners\n if (!flags.fromBlur) {\n this.checkRefreshOn(flags.changes, flags);\n }\n if (flags.noCheck) {\n return true;\n }\n this.checkComponentConditions(data, flags, row);\n if (this.id !== flags.triggeredComponentId) {\n this.calculateComponentValue(data, flags, row);\n }\n }\n checkModal(errors = [], dirty = false) {\n const messages = errors.filter(error => !error.fromServer);\n const isValid = errors.length === 0;\n if (!this.component.modalEdit || !this.componentModal) {\n return;\n }\n if (dirty && !isValid) {\n this.setErrorClasses([this.refs.openModal], dirty, !isValid, !!messages.length, this.refs.openModalWrapper);\n }\n else {\n this.clearErrorClasses(this.refs.openModalWrapper);\n }\n }\n get validationValue() {\n return this.dataValue;\n }\n isEmpty(value = this.dataValue) {\n const isEmptyArray = (lodash_1.default.isArray(value) && value.length === 1) ? lodash_1.default.isEqual(value[0], this.emptyValue) : false;\n return value == null || value.length === 0 || lodash_1.default.isEqual(value, this.emptyValue) || isEmptyArray;\n }\n isEqual(valueA, valueB = this.dataValue) {\n return (this.isEmpty(valueA) && this.isEmpty(valueB)) || lodash_1.default.isEqual(valueA, valueB);\n }\n /**\n * Check if a component is eligible for multiple validation\n * @returns {boolean} - TRUE if the component is eligible for multiple validation.\n */\n validateMultiple() {\n return true;\n }\n clearErrorClasses(element = this.element) {\n this.removeClass(element, this.options.componentErrorClass);\n this.removeClass(element, 'alert alert-danger');\n this.removeClass(element, 'has-error');\n this.removeClass(element, 'has-message');\n }\n setInputWidgetErrorClasses(inputRefs, hasErrors) {\n if (!this.isInputComponent || !this.component.widget || !(inputRefs === null || inputRefs === void 0 ? void 0 : inputRefs.length)) {\n return;\n }\n inputRefs.forEach((input) => {\n if ((input === null || input === void 0 ? void 0 : input.widget) && input.widget.setErrorClasses) {\n input.widget.setErrorClasses(hasErrors);\n }\n });\n }\n addFocusBlurEvents(element) {\n this.addEventListener(element, 'focus', () => {\n if (this.root.focusedComponent !== this) {\n if (this.root.pendingBlur) {\n this.root.pendingBlur();\n }\n this.root.focusedComponent = this;\n this.emit('focus', this);\n }\n else if (this.root.focusedComponent === this && this.root.pendingBlur) {\n this.root.pendingBlur.cancel();\n this.root.pendingBlur = null;\n }\n });\n this.addEventListener(element, 'blur', () => {\n this.root.pendingBlur = FormioUtils.delay(() => {\n this.emit('blur', this);\n if (this.component.validateOn === 'blur') {\n this.root.triggerChange({ fromBlur: true }, {\n instance: this,\n component: this.component,\n value: this.dataValue,\n flags: { fromBlur: true }\n });\n }\n this.root.focusedComponent = null;\n this.root.pendingBlur = null;\n });\n });\n }\n // eslint-disable-next-line max-statements\n setCustomValidity(messages, dirty, external) {\n const inputRefs = this.isInputComponent ? this.refs.input || [] : null;\n if (typeof messages === 'string' && messages) {\n messages = {\n level: 'error',\n message: messages,\n component: this.component,\n };\n }\n if (!Array.isArray(messages)) {\n if (messages) {\n messages = [messages];\n }\n else {\n messages = [];\n }\n }\n const errors = messages.filter(message => message.level === 'error');\n let invalidInputRefs = inputRefs;\n // Filter the invalid input refs in multiple components\n if (this.component.multiple) {\n const refsArray = Array.from(inputRefs);\n refsArray.forEach((input) => {\n this.setElementInvalid(this.performInputMapping(input), false);\n });\n this.setInputWidgetErrorClasses(refsArray, false);\n invalidInputRefs = refsArray.filter((ref, index) => {\n var _a;\n return (_a = messages.some) === null || _a === void 0 ? void 0 : _a.call(messages, (msg) => {\n var _a;\n return ((_a = msg === null || msg === void 0 ? void 0 : msg.context) === null || _a === void 0 ? void 0 : _a.index) === index;\n });\n });\n }\n if (messages.length) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n this.emit('componentError', {\n instance: this,\n component: this.component,\n message: messages[0].message,\n messages,\n external: !!external,\n });\n this.addMessages(messages, dirty, invalidInputRefs);\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n }\n else if (!errors.length || (errors[0].external === !!external)) {\n if (this.refs.messageContainer) {\n this.empty(this.refs.messageContainer);\n }\n if (this.refs.modalMessageContainer) {\n this.empty(this.refs.modalMessageContainer);\n }\n if (invalidInputRefs) {\n this.setErrorClasses(invalidInputRefs, dirty, !!errors.length, !!messages.length);\n }\n this.clearErrorClasses();\n }\n this._visibleErrors = messages;\n return messages;\n }\n /**\n * Determines if the value of this component is hidden from the user as if it is coming from the server, but is\n * protected.\n * @returns {boolean|*} - TRUE if the value is hidden.\n */\n isValueHidden() {\n if (this.component.protected && this.root.editing) {\n return false;\n }\n if (!this.root || !this.root.hasOwnProperty('editing')) {\n return false;\n }\n if (!this.root || !this.root.editing) {\n return false;\n }\n return (this.component.protected || !this.component.persistent || (this.component.persistent === 'client-only'));\n }\n shouldSkipValidation(data, row, flags = {}) {\n const rules = [\n // Do not validate if the flags say not too.\n () => flags.noValidate,\n // Force valid if component is read-only\n () => this.options.readOnly,\n // Do not check validations if component is not an input component.\n () => !this.hasInput,\n // Check to see if we are editing and if so, check component persistence.\n () => this.isValueHidden(),\n // Force valid if component is hidden.\n () => {\n if (!this.component.validateWhenHidden && (!this.visible || !this.checkCondition(row, data))) {\n // If this component is forced valid when it is hidden, then we also need to reset the errors for this component.\n this._errors = [];\n return true;\n }\n return false;\n }\n ];\n return rules.some(pred => pred());\n }\n // Maintain reverse compatibility.\n whenReady() {\n console.warn(this.t('whenReadyDeprecation'));\n return this.dataReady;\n }\n get dataReady() {\n return Promise.resolve();\n }\n /**\n * Prints out the value of this component as a string value.\n * @param {*} value - The value to print out.\n * @returns {string} - The string representation of the value.\n */\n asString(value) {\n value = value || this.getValue();\n return (Array.isArray(value) ? value : [value]).map(lodash_1.default.toString).join(', ');\n }\n /**\n * Return if the component is disabled.\n * @returns {boolean} - TRUE if the component is disabled.\n */\n get disabled() {\n return this._disabled || this.parentDisabled;\n }\n /**\n * Disable this component.\n * @param {boolean} disabled - TRUE to disable the component.\n */\n set disabled(disabled) {\n this._disabled = disabled;\n }\n setDisabled(element, disabled) {\n if (!element) {\n return;\n }\n element.disabled = disabled;\n if (disabled) {\n element.setAttribute('disabled', 'disabled');\n }\n else {\n element.removeAttribute('disabled');\n }\n }\n setLoading(element, loading) {\n if (!element || (element.loading === loading)) {\n return;\n }\n element.loading = loading;\n if (!element.loader && loading) {\n element.loader = this.ce('i', {\n class: `${this.iconClass('refresh', true)} button-icon-right`\n });\n }\n if (element.loader) {\n if (loading) {\n this.appendTo(element.loader, element);\n }\n else {\n this.removeChildFrom(element.loader, element);\n }\n }\n }\n selectOptions(select, tag, options, defaultValue) {\n lodash_1.default.each(options, (option) => {\n const attrs = {\n value: option.value\n };\n if (defaultValue !== undefined && (option.value === defaultValue)) {\n attrs.selected = 'selected';\n }\n const optionElement = this.ce('option', attrs);\n optionElement.appendChild(this.text(option.label));\n select.appendChild(optionElement);\n });\n }\n setSelectValue(select, value) {\n const options = select.querySelectorAll('option');\n lodash_1.default.each(options, (option) => {\n if (option.value === value) {\n option.setAttribute('selected', 'selected');\n }\n else {\n option.removeAttribute('selected');\n }\n });\n if (select.onchange) {\n select.onchange();\n }\n if (select.onselect) {\n select.onselect();\n }\n }\n getRelativePath(path) {\n const keyPart = `.${this.key}`;\n const thisPath = this.isInputComponent ? this.path\n : this.path.slice(0).replace(keyPart, '');\n return path.replace(thisPath, '');\n }\n clear() {\n this.detach();\n this.empty(this.getElement());\n }\n append(element) {\n this.appendTo(element, this.element);\n }\n prepend(element) {\n this.prependTo(element, this.element);\n }\n removeChild(element) {\n this.removeChildFrom(element, this.element);\n }\n detachLogic() {\n this.logic.forEach(logic => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.off(event); // only applies to callbacks on this component\n }\n });\n }\n attachLogic() {\n // Do not attach logic during builder mode.\n if (this.builderMode) {\n return;\n }\n this.logic.forEach((logic) => {\n if (logic.trigger.type === 'event') {\n const event = this.interpolate(logic.trigger.event);\n this.on(event, (...args) => {\n const newComponent = (0, utils_1.fastCloneDeep)(this.originalComponent);\n if (this.applyActions(newComponent, logic.actions, args)) {\n // If component definition changed, replace it.\n if (!lodash_1.default.isEqual(this.component, newComponent)) {\n this.component = newComponent;\n const visible = this.hasCondition() ? !this.conditionallyHidden : !this.component.hidden;\n const disabled = this.shouldDisabled;\n // Change states which won't be recalculated during redrawing\n if (this.visible !== visible) {\n // If the logic is triggered by an event and the action sets the hidden state then the original\n // component definition must be changed so that the components hidden state does not get flipped back by\n // the fieldLogic function\n this.originalComponent.hidden = !visible;\n this.visible = visible;\n }\n if (this.disabled !== disabled) {\n this.disabled = disabled;\n }\n this.redraw();\n }\n }\n }, true);\n }\n });\n }\n /**\n * Get the element information.\n * @returns {*} - The components \"input\" DOM element information.\n */\n elementInfo() {\n const attributes = {\n name: this.options.name,\n type: this.component.inputType || 'text',\n class: 'form-control',\n lang: this.options.language\n };\n if (this.component.placeholder) {\n attributes.placeholder = this.t(this.component.placeholder, { _userInput: true });\n }\n if (this.component.tabindex) {\n attributes.tabindex = this.component.tabindex;\n }\n if (this.disabled) {\n attributes.disabled = 'disabled';\n }\n lodash_1.default.defaults(attributes, this.component.attributes);\n return {\n type: 'input',\n component: this.component,\n changeEvent: 'change',\n attr: attributes\n };\n }\n autofocus() {\n const hasAutofocus = this.component.autofocus && !this.builderMode && !this.options.preview;\n if (hasAutofocus) {\n this.on('render', () => this.focus(), true);\n }\n }\n scrollIntoView(element = this.element, verticalOnly) {\n if (!element) {\n return;\n }\n const { left, top } = element.getBoundingClientRect();\n window.scrollTo(verticalOnly ? window.scrollX : left + window.scrollX, top + window.scrollY);\n }\n focus(index) {\n var _a, _b, _c, _d;\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n if (!index && !lodash_1.default.isNumber(index) && ((_b = (_a = this.refs) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.length)) {\n index = this.refs.input.length - 1;\n }\n if ((_c = this.refs.input) === null || _c === void 0 ? void 0 : _c.length) {\n const focusingInput = this.refs.input[index];\n if (((_d = this.component.widget) === null || _d === void 0 ? void 0 : _d.type) === 'calendar') {\n const sibling = focusingInput.nextSibling;\n if (sibling) {\n sibling.focus();\n }\n }\n else {\n focusingInput.focus();\n }\n }\n if (this.refs.openModal) {\n this.refs.openModal.focus();\n }\n if (this.parent.refs.openModal) {\n this.parent.refs.openModal.focus();\n }\n }\n /**\n * Get `Formio` instance for working with files\n * @returns {import('@formio/core').Formio} - The Formio instance file service.\n */\n get fileService() {\n if (this.options.fileService) {\n return this.options.fileService;\n }\n if (this.options.formio) {\n return this.options.formio;\n }\n if (this.root && this.root.formio) {\n return this.root.formio;\n }\n const formio = new Formio_1.Formio();\n // If a form is loaded, then make sure to set the correct formUrl.\n if (this.root && this.root._form && this.root._form._id) {\n formio.formUrl = `${formio.projectUrl}/form/${this.root._form._id}`;\n }\n return formio;\n }\n resetCaches() { }\n get previewMode() {\n return false;\n }\n}\nexports[\"default\"] = Component;\nComponent.externalLibraries = {};\nComponent.requireLibrary = function (name, property, src, polling) {\n if (!Component.externalLibraries.hasOwnProperty(name)) {\n Component.externalLibraries[name] = {};\n Component.externalLibraries[name].ready = new Promise((resolve, reject) => {\n Component.externalLibraries[name].resolve = resolve;\n Component.externalLibraries[name].reject = reject;\n });\n const callbackName = `${name}Callback`;\n if (!polling && !window[callbackName]) {\n window[callbackName] = function () {\n this.resolve();\n }.bind(Component.externalLibraries[name]);\n }\n // See if the plugin already exists.\n const plugin = (0, utils_1.getScriptPlugin)(property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n src = Array.isArray(src) ? src : [src];\n src.forEach((lib) => {\n let attrs = {};\n let elementType = '';\n if (typeof lib === 'string') {\n lib = {\n type: 'script',\n src: lib\n };\n }\n switch (lib.type) {\n case 'script':\n elementType = 'script';\n attrs = {\n src: lib.src,\n type: 'text/javascript',\n defer: true,\n async: true\n };\n break;\n case 'styles':\n elementType = 'link';\n attrs = {\n href: lib.src,\n rel: 'stylesheet'\n };\n break;\n }\n // Add the script to the top page.\n const script = document.createElement(elementType);\n for (const attr in attrs) {\n script.setAttribute(attr, attrs[attr]);\n }\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n // if no callback is provided, then check periodically for the script.\n if (polling) {\n setTimeout(function checkLibrary() {\n const plugin = (0, utils_1.getScriptPlugin)(property);\n if (plugin) {\n Component.externalLibraries[name].resolve(plugin);\n }\n else {\n // check again after 200 ms.\n setTimeout(checkLibrary, 200);\n }\n }, 200);\n }\n }\n }\n return Component.externalLibraries[name].ready;\n};\nComponent.libraryReady = function (name) {\n if (Component.externalLibraries.hasOwnProperty(name) &&\n Component.externalLibraries[name].ready) {\n return Component.externalLibraries[name].ready;\n }\n return Promise.reject(`${name} library was not required.`);\n};\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/component/Component.js?");
|
4857
4857
|
|
4858
4858
|
/***/ }),
|
4859
4859
|
|
@@ -5007,7 +5007,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5007
5007
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5008
5008
|
|
5009
5009
|
"use strict";
|
5010
|
-
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__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Components_1 = __importDefault(__webpack_require__(/*! ../../Components */ \"./lib/cjs/components/Components.js\"));\n'';\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\n/**\n * NestedComponent class.\n * @augments Field\n */\nclass NestedComponent extends Field_1.default {\n static schema(...extend) {\n return Field_1.default.schema({\n tree: false,\n lazyLoad: false,\n }, ...extend);\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.type = 'components';\n /**\n * The collapsed state of this NestedComponent.\n * @type {boolean}\n * @default false\n * @private\n */\n this._collapsed = !!this.component.collapsed;\n }\n get defaultSchema() {\n return NestedComponent.schema();\n }\n /**\n * Get the schema for the NestedComponent.\n * @returns {object} The schema for the NestedComponent.\n * @override\n */\n get schema() {\n const schema = super.schema;\n const components = lodash_1.default.uniqBy(this.getComponents(), 'component.key');\n schema.components = lodash_1.default.map(components, 'schema');\n return schema;\n }\n /**\n * Get collapsed state.\n * @returns {boolean} The collapsed state.\n */\n get collapsed() {\n return this._collapsed;\n }\n /**\n * Set collapsed state.\n * @param {boolean} value - The collapsed state.\n * @returns {void}\n */\n collapse(value) {\n const promise = this.redraw();\n if (!value) {\n this.checkValidity(this.data, !this.pristine);\n }\n return promise;\n }\n /**\n * Set collapsed state.\n * @param {boolean} value - The collapsed state.\n * @returns {void}\n */\n set collapsed(value) {\n this._collapsed = value;\n this.collapse(value);\n }\n /**\n * Set visible state of parent and each child component.\n * @param {boolean} value - The visible state.\n * @returns {void}\n */\n set visible(value) {\n // DO NOT CALL super here. There is an issue where clearOnHide was getting triggered with\n // subcomponents because the \"parentVisible\" flag was set to false when it should really be\n // set to true.\n const visibilityChanged = this._visible !== value;\n this._visible = value;\n const isVisible = this.visible;\n const isConditionallyHidden = this.checkConditionallyHidden();\n const forceShow = this.shouldForceShow();\n const forceHide = this.shouldForceHide();\n this.components.forEach((component) => {\n // Set the parent visibility first since we may have nested components within nested components\n // and they need to be able to determine their visibility based on the parent visibility.\n component.parentVisible = isVisible;\n component._parentConditionallyHidden = isConditionallyHidden;\n let visible;\n if (component.hasCondition()) {\n component._conditionallyHidden = component.checkConditionallyHidden() || component._parentConditionallyHidden;\n visible = !component.conditionallyHidden;\n }\n else {\n visible = !component.component.hidden;\n }\n if (forceShow || visible) {\n component.visible = true;\n }\n else if (forceHide || !isVisible || !visible) {\n component.visible = false;\n }\n // If hiding a nested component, clear all errors below.\n if (!component.visible) {\n component.error = '';\n }\n });\n if (visibilityChanged) {\n this.redraw();\n }\n }\n /**\n * Get visible state.\n * @returns {boolean} The visible state.\n */\n get visible() {\n return super.visible;\n }\n /**\n * Set parent visibility.\n * @param {boolean} value - The parent visibility.\n * @returns {void}\n */\n set parentVisible(value) {\n super.parentVisible = value;\n this.components.forEach(component => component.parentVisible = this.visible);\n }\n /**\n * Get parent visibility.\n * @returns {boolean} The parent visibility.\n */\n get parentVisible() {\n return super.parentVisible;\n }\n /**\n * Get the disabled state.\n * @returns {boolean} - The disabled state.\n */\n get disabled() {\n return super.disabled;\n }\n /**\n * Set the disabled state.\n * @param {boolean} disabled - The disabled state.\n */\n set disabled(disabled) {\n super.disabled = disabled;\n this.components.forEach((component) => component.parentDisabled = disabled);\n }\n /**\n * Set parent disabled state.\n * @param {boolean} value - The parent disabled state.\n * @returns {void}\n */\n set parentDisabled(value) {\n super.parentDisabled = value;\n this.components.forEach(component => {\n component.parentDisabled = this.disabled;\n });\n }\n /**\n * Get parent disabled state.\n * @returns {boolean} The parent disabled state.\n */\n get parentDisabled() {\n return super.parentDisabled;\n }\n /**\n * Get ready state from all components.\n * @returns {Promise<Array>} - The promise that resolves when all components are ready.\n */\n get ready() {\n return Promise.all(this.getComponents().map(component => component.ready));\n }\n /**\n * Get currentForm object.\n * @returns {object} - The current form object.\n */\n get currentForm() {\n return super.currentForm;\n }\n /**\n * Set currentForm object.\n * @param {object} instance - The current form object.\n * @returns {void}\n */\n set currentForm(instance) {\n super.currentForm = instance;\n this.getComponents().forEach(component => {\n component.currentForm = instance;\n });\n }\n /**\n * Get Row Index.\n * @returns {number} - The row index.\n */\n get rowIndex() {\n return this._rowIndex;\n }\n /**\n * Set Row Index to row and update each component.\n * @param {number} value - The row index.\n * @returns {void}\n */\n set rowIndex(value) {\n var _a, _b;\n this._rowIndex = value;\n this.paths = (0, utils_1.getComponentPaths)(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (((_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths) || {})), { dataIndex: value }));\n this.eachComponent((component) => {\n component.rowIndex = value;\n });\n }\n /**\n * Get Contextual data of the component.\n * @returns {object} - The contextual data of the component.\n * @override\n */\n componentContext() {\n return this._data;\n }\n /**\n * Get the data of the component.\n * @returns {object} - The data of the component.\n * @override\n */\n get data() {\n return this._data;\n }\n /**\n * Set the data of the component.\n * @param {object} value - The data of the component.\n * @returns {void}\n */\n set data(value) {\n this._data = value;\n this.eachComponent((component) => {\n component.data = this.componentContext(component);\n });\n }\n /**\n * Get components array.\n * @returns {Array} - The components array.\n */\n getComponents() {\n return this.components || [];\n }\n /**\n * Perform a deep iteration over every component, including those\n * within other container based components.\n * @param {Function} fn - Called for every component.\n * @param {any} options - The options to include with this everyComponent call.\n */\n everyComponent(fn, options = {}) {\n const components = this.getComponents();\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n /**\n * Check if the component has a component.\n * @param {import('@formio/core').Component} component - The component to check.\n * @returns {boolean} - TRUE if the component has a component, FALSE otherwise.\n */\n hasComponent(component) {\n let result = false;\n this.everyComponent((comp) => {\n if (comp === component) {\n result = true;\n return false;\n }\n });\n return result;\n }\n /**\n * Get the flattened components of this NestedComponent.\n * @returns {object} - The flattened components of this NestedComponent.\n */\n flattenComponents() {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n });\n return result;\n }\n /**\n * Perform an iteration over each component within this container component.\n * @param {Function} fn - Called for each component\n */\n eachComponent(fn) {\n lodash_1.default.each(this.getComponents(), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n /**\n * Returns a component provided a key. This performs a deep search within the component tree.\n * @param {string} path - The path to the component.\n * @returns {any} - The component that is located.\n */\n getComponent(path) {\n var _a;\n path = (0, utils_1.getStringFromComponentPath)(path);\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 this.everyComponent((component) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;\n // All searches are relative to this component so replace this path from the child paths.\n (0, utils_1.componentMatches)(component.component, {\n path: (_b = (_a = component.paths) === null || _a === void 0 ? void 0 : _a.path) === null || _b === void 0 ? void 0 : _b.replace(new RegExp(`^${(_c = this.paths) === null || _c === void 0 ? void 0 : _c.path}\\\\.?`), ''),\n fullPath: (_e = (_d = component.paths) === null || _d === void 0 ? void 0 : _d.fullPath) === null || _e === void 0 ? void 0 : _e.replace(new RegExp(`^${(_f = this.paths) === null || _f === void 0 ? void 0 : _f.fullPath}\\\\.?`), ''),\n localPath: (_h = (_g = component.paths) === null || _g === void 0 ? void 0 : _g.localPath) === null || _h === void 0 ? void 0 : _h.replace(new RegExp(`^${(_j = this.paths) === null || _j === void 0 ? void 0 : _j.localPath}\\\\.?`), ''),\n fullLocalPath: (_l = (_k = component.paths) === null || _k === void 0 ? void 0 : _k.fullLocalPath) === null || _l === void 0 ? void 0 : _l.replace(new RegExp(`^${(_m = this.paths) === null || _m === void 0 ? void 0 : _m.fullLocalPath}\\\\.?`), ''),\n dataPath: (_p = (_o = component.paths) === null || _o === void 0 ? void 0 : _o.dataPath) === null || _p === void 0 ? void 0 : _p.replace(new RegExp(`^${(_q = this.paths) === null || _q === void 0 ? void 0 : _q.dataPath}\\\\.?`), ''),\n localDataPath: (_s = (_r = component.paths) === null || _r === void 0 ? void 0 : _r.localDataPath) === null || _s === void 0 ? void 0 : _s.replace(new RegExp(`^${(_t = this.paths) === null || _t === void 0 ? void 0 : _t.localDataPath}\\\\.?`), ''),\n }, path, this.rowIndex, matches, (type, match) => {\n match.instance = component;\n return match;\n });\n });\n return (_a = (0, utils_1.getBestMatch)(matches)) === null || _a === void 0 ? void 0 : _a.instance;\n }\n /**\n * Return a component provided the Id of the component.\n * @param {string} id - The Id of the component.\n * @param {Function} fn - Called with the component once it is retrieved.\n * @returns {object} - The component retrieved.\n */\n getComponentById(id, fn = null) {\n let comp = null;\n this.everyComponent((component, components) => {\n if (component.id === id) {\n comp = component;\n if (fn) {\n fn(component, components);\n }\n return false;\n }\n });\n return comp;\n }\n /**\n * Create a new component and add it to the components array.\n * @param {import('@formio/core').Component} component - The component JSON schema to create.\n * @param {object} options - The options to create the component with.\n * @param {import('@formio/core').DataObject} data - The submission data object to house the data for this component.\n * @param {import('@formio/core').Component} [before] - The component before which to add this component.\n * @param {import('@formio/core').Component} [replacedComp] - The component to replace with this component.\n * @returns {any} - The created component instance.\n */\n createComponent(component, options, data, before, replacedComp) {\n if (!component) {\n return;\n }\n options = options || this.options;\n data = data || this.data;\n options.parent = this;\n options.parentVisible = this.visible;\n options.parentConditionallyHidden = this.conditionallyHidden;\n options.root = (options === null || options === void 0 ? void 0 : options.root) || this.root || this;\n options.localRoot = this.localRoot;\n options.skipInit = true;\n if (!(options.display === 'pdf' && this.builderMode)) {\n component.id = (0, utils_1.getRandomComponentId)();\n }\n const comp = Components_1.default.create(component, options, data, true);\n comp.init();\n if (component.internal) {\n return comp;\n }\n if (before) {\n const index = lodash_1.default.findIndex(this.components, { id: before.id });\n if (index !== -1) {\n this.components.splice(index, 0, comp);\n }\n else {\n this.components.push(comp);\n }\n }\n else if (replacedComp) {\n const index = lodash_1.default.findIndex(this.components, { id: replacedComp.id });\n if (index !== -1) {\n this.components[index] = comp;\n }\n else {\n this.components.push(comp);\n }\n }\n else {\n this.components.push(comp);\n }\n return comp;\n }\n getContainer() {\n return this.element;\n }\n get componentComponents() {\n return this.component.components || [];\n }\n get nestedKey() {\n return `nested-${this.key}`;\n }\n get templateName() {\n return 'container';\n }\n init() {\n this.components = this.components || [];\n this.addComponents();\n return super.init();\n }\n /**\n * Add a new component instance to the components array.\n * @param {import('@formio/core').DataObject} [data] - The Submission data for this component.\n * @param {object} [options] - The options for this component.\n */\n addComponents(data, options) {\n data = data || this.data;\n this.components = this.components || [];\n options = options || this.options;\n if (options.components) {\n this.components = options.components;\n }\n else {\n const components = this.hook('addComponents', this.componentComponents, this) || [];\n components.forEach((component) => this.addComponent(component, data));\n }\n }\n /**\n * Add a new component to the components array.\n * @param {import('@formio/core').Component} component - The component JSON schema to add.\n * @param {object} data - The submission data object to house the data for this component.\n * @param {HTMLElement} before - A DOM element to insert this element before.\n * @param {boolean} [noAdd] - A possibly extraneous boolean flag.\n * @returns {any} - The created component instance.\n */\n addComponent(component, data = null, before = null, noAdd = false) {\n data = data || this.data;\n this.components = this.components || [];\n component = this.hook('addComponent', component, data, before, noAdd);\n const comp = this.createComponent(component, this.options, data, before ? before : null);\n if (noAdd) {\n return comp;\n }\n return comp;\n }\n beforeFocus() {\n if (this.parent && 'beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n }\n render(children) {\n // If already rendering, don't re-render.\n return super.render(children || this.renderTemplate(this.templateName, {\n children: !this.visible ? '' : this.renderComponents(),\n nestedKey: this.nestedKey,\n collapsed: this.options.pdf ? false : this.collapsed,\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n return this.renderTemplate('components', {\n children,\n components,\n });\n }\n attach(element) {\n const superPromise = super.attach(element);\n this.loadRefs(element, {\n header: 'single',\n collapsed: this.collapsed,\n [this.nestedKey]: 'single',\n messageContainer: 'single-scope',\n });\n let childPromise = Promise.resolve();\n if (this.refs[this.nestedKey]) {\n childPromise = this.attachComponents(this.refs[this.nestedKey]);\n }\n if (!this.visible) {\n this.attachComponentsLogic();\n }\n if (this.component.collapsible && this.refs.header) {\n this.addEventListener(this.refs.header, 'click', () => {\n this.collapsed = !this.collapsed;\n });\n this.addEventListener(this.refs.header, 'keydown', (e) => {\n if (e.keyCode === 13 || e.keyCode === 32) {\n e.preventDefault();\n this.collapsed = !this.collapsed;\n }\n });\n }\n return Promise.all([\n superPromise,\n childPromise,\n ]);\n }\n /**\n * Attach the logic to the components.\n * @param {import('@formio/core').Component[]} components - The components to attach logic to.\n */\n attachComponentsLogic(components) {\n components = components || this.components;\n lodash_1.default.each(components, (comp) => {\n comp.attachLogic();\n if (lodash_1.default.isFunction(comp.attachComponentsLogic)) {\n comp.attachComponentsLogic();\n }\n });\n }\n attachComponents(element, components, container) {\n components = components || this.components;\n container = container || this.component.components;\n element = this.hook('attachComponents', element, components, container, this);\n if (!element) {\n // Return a non-resolving promise.\n return (new Promise(() => { }));\n }\n let index = 0;\n const promises = [];\n Array.prototype.slice.call(element.children).forEach(child => {\n if (!child.getAttribute('data-noattach') && components[index]) {\n promises.push(components[index].attach(child));\n index++;\n }\n });\n return Promise.all(promises);\n }\n /**\n * Remove a component from the components array and from the children object\n * @param {import('@formio/core').Component} component - The component to remove from the components.\n * @param {import('@formio/core').Component[]} components - An array of components to remove this component from.\n * @param {boolean} [all] - If set to TRUE will cascade remove all components.\n */\n removeComponent(component, components, all = false) {\n components = components || this.components;\n component.destroy(all);\n lodash_1.default.remove(components, { id: component.id });\n if (this.componentsMap[component.path]) {\n delete this.componentsMap[component.path];\n }\n }\n /**\n * Removes a component provided the API key of that component.\n * @param {string} key - The API key of the component to remove.\n * @param {Function} fn - Called once the component is removed.\n * @returns {null|void} - Returns nothing if the component is not found.\n */\n removeComponentByKey(key, fn = null) {\n const comp = this.getComponent(key, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n /**\n * Removes a component provided the Id of the component.\n * @param {string} id - The Id of the component to remove.\n * @param {Function} fn - Called when the component is removed.\n * @returns {null|void} - Returns nothing if the component is not found.\n */\n removeComponentById(id, fn = null) {\n const comp = this.getComponentById(id, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n updateValue(value, flags = {}) {\n return this.components.reduce((changed, comp) => {\n return comp.updateValue(null, flags) || changed;\n }, super.updateValue(value, flags));\n }\n shouldSkipValidation(data, row, flags) {\n // Nested components with no input should not be validated.\n if (!this.component.input) {\n return true;\n }\n else {\n return super.shouldSkipValidation(data, row, flags);\n }\n }\n checkData(data, flags, row, components) {\n if (this.builderMode) {\n return true;\n }\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n components = components && lodash_1.default.isArray(components) ? components : this.getComponents();\n super.checkData(data, Object.assign({}, flags), row);\n components.forEach((comp) => comp.checkData(data, Object.assign({}, flags), row));\n }\n checkConditions(data, flags, row) {\n // check conditions of parent component first, because it may influence on visibility of it's children\n const check = super.checkConditions(data, flags, row);\n //row data of parent component not always corresponds to row of nested components, use comp.data as row data for children instead\n this.getComponents().forEach(comp => comp.checkConditions(data, flags, comp.data));\n return check;\n }\n clearOnHide(show) {\n super.clearOnHide(show);\n if (this.component.clearOnHide) {\n if (this.allowData && !this.hasValue() && !this.conditionallyHidden) {\n this.dataValue = this.defaultValue;\n }\n if (this.hasValue()) {\n this.restoreComponentsContext();\n }\n }\n this.getComponents().forEach(component => component.clearOnHide(show));\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => component.data = this.dataValue);\n }\n /**\n * Allow components to hook into the next page trigger to perform their own logic.\n * @param {Function} next - The callback to continue to the next page.\n * @returns {Promise} - A promise when the page has been processed.\n */\n beforePage(next) {\n return Promise.all(this.getComponents().map((comp) => comp.beforePage(next)));\n }\n /**\n * Allow components to hook into the submission to provide their own async data.\n * @returns {Promise} - Returns a promise when the constituent beforeSubmit functions are complete.\n */\n beforeSubmit() {\n return Promise.allSettled(this.getComponents().map((comp) => comp.beforeSubmit()));\n }\n calculateValue(data, flags, row) {\n // Do not iterate into children and calculateValues if this nested component is conditionally hidden.\n if (this.conditionallyHidden) {\n return false;\n }\n return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));\n }\n isLastPage() {\n return this.pages.length - 1 === this.page;\n }\n isValid(data, dirty) {\n return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));\n }\n validationProcessor({ scope, data, row, instance, paths }, flags) {\n var _a;\n const { dirty } = flags;\n if (this.root.hasExtraPages && this.page !== this.root.page) {\n instance = ((_a = this.componentsMap) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(paths.dataPath))\n ? this.componentsMap[paths.dataPath]\n : this.getComponent(paths.dataPath);\n }\n if (!instance) {\n return;\n }\n instance.checkComponentValidity(data, dirty, row, flags, scope.errors);\n if (instance.processOwnValidation) {\n scope.noRecurse = true;\n }\n }\n /**\n * Perform a validation on all child components of this nested component.\n * @param {import('@formio/core').Component[]} components - The components to validate.\n * @param {import('@formio/core').DataObject} data - The data to validate.\n * @param {object} flags - The flags to use when validating.\n * @returns {Promise<Array>|Array} - The errors if any exist.\n */\n validateComponents(components = null, data = null, flags = {}) {\n components = components || this.component.components;\n data = data || this.rootValue;\n const { async, dirty, process } = flags;\n const validationProcessorProcess = (context) => this.validationProcessor(context, flags);\n const checkModalProcessorProcess = ({ instance, component, components }) => {\n // If we just validated the last component, and there are errors from our parent, then we need to show a model of those errors.\n if (instance &&\n instance.parent &&\n (component === components[components.length - 1]) &&\n instance.parent.componentModal) {\n instance.parent.checkModal(instance.parent.childErrors, dirty);\n }\n };\n const processorContext = {\n process: process || 'unknown',\n components,\n instances: this.componentsMap,\n data: data,\n local: !!flags.local,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: this.paths,\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n },\n {\n process: checkModalProcessorProcess,\n processSync: checkModalProcessorProcess\n }\n ]\n };\n return async ? (0, process_1.process)(processorContext).then((scope) => scope.errors) : (0, process_1.processSync)(processorContext).errors;\n }\n /**\n * Validate a nested component with data, or its own internal data.\n * @param {import('@formio/core').DataObject} data - The data to validate.\n * @param {object} flags - The flags to use when validating.\n * @returns {Array} - The errors if any exist.\n */\n validate(data = null, flags = {}) {\n data = data || this.rootValue;\n return this.validateComponents(this.getComponents().map((component) => component.component), data, flags);\n }\n checkComponentValidity(data = null, dirty = false, row = null, flags = {}, allErrors = []) {\n this.childErrors = [];\n return super.checkComponentValidity(data, dirty, row, flags, allErrors);\n }\n /**\n * Checks the validity of the component.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {boolean} silentCheck - If the check should be silent and not set the error messages.\n * @param {Array<any>} childErrors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkValidity(data = null, dirty = false, row = null, silentCheck = false, childErrors = []) {\n childErrors.push(...this.validate(data, { dirty, silentCheck }));\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck }, childErrors) && childErrors.length === 0;\n }\n checkAsyncValidity(data = null, dirty = false, row = null, silentCheck = false) {\n return this.ready.then(() => {\n return this.validate(data, { dirty, silentCheck, async: true }).then((childErrors) => {\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck, async: true }, childErrors).then((valid) => {\n return valid && childErrors.length === 0;\n });\n });\n });\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n this.getComponents().forEach((comp) => comp.setPristine(pristine));\n }\n get isPristine() {\n return this.pristine && this.getComponents().every((c) => c.isPristine);\n }\n get isDirty() {\n return this.dirty && this.getComponents().every((c) => c.isDirty);\n }\n detach() {\n this.components.forEach(component => {\n component.detach();\n });\n super.detach();\n }\n clear() {\n this.components.forEach(component => {\n component.clear();\n });\n super.clear();\n }\n destroy(all = false) {\n this.destroyComponents(all);\n super.destroy(all);\n }\n destroyComponents(all = false) {\n const components = this.getComponents().slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n this.components = [];\n }\n get visibleErrors() {\n return this.getComponents().reduce((errors, comp) => errors.concat(comp.visibleErrors || []), super.visibleErrors);\n }\n get errors() {\n const thisErrors = super.errors;\n return this.getComponents()\n .reduce((errors, comp) => errors.concat(comp.errors || []), thisErrors)\n .filter(err => err.level !== 'hidden');\n }\n getValue() {\n return this.data;\n }\n resetValue() {\n super.resetValue();\n this.getComponents().forEach((comp) => comp.resetValue());\n this.setPristine(true);\n }\n get dataReady() {\n return Promise.all(this.getComponents().map((component) => component.dataReady));\n }\n setNestedValue(component, value, flags = {}) {\n component._data = this.componentContext(component);\n if (component.type === 'button') {\n return false;\n }\n if (component.type === 'components') {\n if (component.tree && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n return component.setValue(value, flags);\n }\n else if (value && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {\n flags.noValidate = !flags.dirty;\n flags.resetValue = true;\n return component.setValue(component.defaultValue, flags);\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n return false;\n }\n return this.getComponents().reduce((changed, component) => {\n return this.setNestedValue(component, value, flags, changed) || changed;\n }, false);\n }\n get lazyLoad() {\n var _a;\n return (_a = this.component.lazyLoad) !== null && _a !== void 0 ? _a : false;\n }\n}\nexports[\"default\"] = NestedComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nested/NestedComponent.js?");
|
5010
|
+
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__(/*! ../field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Components_1 = __importDefault(__webpack_require__(/*! ../../Components */ \"./lib/cjs/components/Components.js\"));\n'';\nconst utils_1 = __webpack_require__(/*! ../../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\n/**\n * NestedComponent class.\n * @augments Field\n */\nclass NestedComponent extends Field_1.default {\n static schema(...extend) {\n return Field_1.default.schema({\n tree: false,\n lazyLoad: false,\n }, ...extend);\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.type = 'components';\n /**\n * The collapsed state of this NestedComponent.\n * @type {boolean}\n * @default false\n * @private\n */\n this._collapsed = !!this.component.collapsed;\n }\n get defaultSchema() {\n return NestedComponent.schema();\n }\n /**\n * Get the schema for the NestedComponent.\n * @returns {object} The schema for the NestedComponent.\n * @override\n */\n get schema() {\n const schema = super.schema;\n const components = lodash_1.default.uniqBy(this.getComponents(), 'component.key');\n schema.components = lodash_1.default.map(components, 'schema');\n return schema;\n }\n /**\n * Get collapsed state.\n * @returns {boolean} The collapsed state.\n */\n get collapsed() {\n return this._collapsed;\n }\n /**\n * Set collapsed state.\n * @param {boolean} value - The collapsed state.\n * @returns {void}\n */\n collapse(value) {\n const promise = this.redraw();\n if (!value) {\n this.checkValidity(this.data, !this.pristine);\n }\n return promise;\n }\n /**\n * Set collapsed state.\n * @param {boolean} value - The collapsed state.\n * @returns {void}\n */\n set collapsed(value) {\n this._collapsed = value;\n this.collapse(value);\n }\n /**\n * Set visible state of parent and each child component.\n * @param {boolean} value - The visible state.\n * @returns {void}\n */\n set visible(value) {\n // DO NOT CALL super here. There is an issue where clearOnHide was getting triggered with\n // subcomponents because the \"parentVisible\" flag was set to false when it should really be\n // set to true.\n const visibilityChanged = this._visible !== value;\n this._visible = value;\n const isVisible = this.visible;\n this.checkConditionallyHidden();\n const forceShow = this.shouldForceShow();\n const forceHide = this.shouldForceHide();\n this.components.forEach((component) => {\n // Set the parent visibility first since we may have nested components within nested components\n // and they need to be able to determine their visibility based on the parent visibility.\n component.parentVisible = isVisible;\n let visible;\n if (component.hasCondition()) {\n visible = !component.checkConditionallyHidden();\n }\n else {\n visible = !component.component.hidden;\n }\n if (forceShow || visible) {\n component.visible = true;\n }\n else if (forceHide || !isVisible || !visible) {\n component.visible = false;\n }\n // If hiding a nested component, clear all errors below.\n if (!component.visible) {\n component.error = '';\n }\n });\n if (visibilityChanged) {\n this.redraw();\n }\n }\n /**\n * Get visible state.\n * @returns {boolean} The visible state.\n */\n get visible() {\n return super.visible;\n }\n /**\n * Set parent visibility.\n * @param {boolean} value - The parent visibility.\n * @returns {void}\n */\n set parentVisible(value) {\n super.parentVisible = value;\n this.components.forEach(component => component.parentVisible = this.visible);\n }\n /**\n * Get parent visibility.\n * @returns {boolean} The parent visibility.\n */\n get parentVisible() {\n return super.parentVisible;\n }\n /**\n * Get the disabled state.\n * @returns {boolean} - The disabled state.\n */\n get disabled() {\n return super.disabled;\n }\n /**\n * Set the disabled state.\n * @param {boolean} disabled - The disabled state.\n */\n set disabled(disabled) {\n super.disabled = disabled;\n this.components.forEach((component) => component.parentDisabled = disabled);\n }\n /**\n * Set parent disabled state.\n * @param {boolean} value - The parent disabled state.\n * @returns {void}\n */\n set parentDisabled(value) {\n super.parentDisabled = value;\n this.components.forEach(component => {\n component.parentDisabled = this.disabled;\n });\n }\n /**\n * Get parent disabled state.\n * @returns {boolean} The parent disabled state.\n */\n get parentDisabled() {\n return super.parentDisabled;\n }\n /**\n * Get ready state from all components.\n * @returns {Promise<Array>} - The promise that resolves when all components are ready.\n */\n get ready() {\n return Promise.all(this.getComponents().map(component => component.ready));\n }\n /**\n * Get currentForm object.\n * @returns {object} - The current form object.\n */\n get currentForm() {\n return super.currentForm;\n }\n /**\n * Set currentForm object.\n * @param {object} instance - The current form object.\n * @returns {void}\n */\n set currentForm(instance) {\n super.currentForm = instance;\n this.getComponents().forEach(component => {\n component.currentForm = instance;\n });\n }\n /**\n * Get Row Index.\n * @returns {number} - The row index.\n */\n get rowIndex() {\n return this._rowIndex;\n }\n /**\n * Set Row Index to row and update each component.\n * @param {number} value - The row index.\n * @returns {void}\n */\n set rowIndex(value) {\n var _a, _b;\n this._rowIndex = value;\n this.paths = (0, utils_1.getComponentPaths)(this.component, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.component, Object.assign(Object.assign({}, (((_b = this.parent) === null || _b === void 0 ? void 0 : _b.paths) || {})), { dataIndex: value }));\n this.eachComponent((component) => {\n component.rowIndex = value;\n });\n }\n /**\n * Get Contextual data of the component.\n * @returns {object} - The contextual data of the component.\n * @override\n */\n componentContext() {\n return this._data;\n }\n /**\n * Get the data of the component.\n * @returns {object} - The data of the component.\n * @override\n */\n get data() {\n return this._data;\n }\n /**\n * Set the data of the component.\n * @param {object} value - The data of the component.\n * @returns {void}\n */\n set data(value) {\n this._data = value;\n this.eachComponent((component) => {\n component.data = this.componentContext(component);\n });\n }\n /**\n * Get components array.\n * @returns {Array} - The components array.\n */\n getComponents() {\n return this.components || [];\n }\n /**\n * Perform a deep iteration over every component, including those\n * within other container based components.\n * @param {Function} fn - Called for every component.\n * @param {any} options - The options to include with this everyComponent call.\n */\n everyComponent(fn, options = {}) {\n const components = this.getComponents();\n lodash_1.default.each(components, (component, index) => {\n if (fn(component, components, index) === false) {\n return false;\n }\n if (typeof component.everyComponent === 'function') {\n if (component.everyComponent(fn, options) === false) {\n return false;\n }\n }\n });\n }\n /**\n * Check if the component has a component.\n * @param {import('@formio/core').Component} component - The component to check.\n * @returns {boolean} - TRUE if the component has a component, FALSE otherwise.\n */\n hasComponent(component) {\n let result = false;\n this.everyComponent((comp) => {\n if (comp === component) {\n result = true;\n return false;\n }\n });\n return result;\n }\n /**\n * Get the flattened components of this NestedComponent.\n * @returns {object} - The flattened components of this NestedComponent.\n */\n flattenComponents() {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n });\n return result;\n }\n /**\n * Perform an iteration over each component within this container component.\n * @param {Function} fn - Called for each component\n */\n eachComponent(fn) {\n lodash_1.default.each(this.getComponents(), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n /**\n * Returns a component provided a key. This performs a deep search within the component tree.\n * @param {string} path - The path to the component.\n * @returns {any} - The component that is located.\n */\n getComponent(path) {\n var _a;\n path = (0, utils_1.getStringFromComponentPath)(path);\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 this.everyComponent((component) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;\n // All searches are relative to this component so replace this path from the child paths.\n (0, utils_1.componentMatches)(component.component, {\n path: (_b = (_a = component.paths) === null || _a === void 0 ? void 0 : _a.path) === null || _b === void 0 ? void 0 : _b.replace(new RegExp(`^${(_c = this.paths) === null || _c === void 0 ? void 0 : _c.path}\\\\.?`), ''),\n fullPath: (_e = (_d = component.paths) === null || _d === void 0 ? void 0 : _d.fullPath) === null || _e === void 0 ? void 0 : _e.replace(new RegExp(`^${(_f = this.paths) === null || _f === void 0 ? void 0 : _f.fullPath}\\\\.?`), ''),\n localPath: (_h = (_g = component.paths) === null || _g === void 0 ? void 0 : _g.localPath) === null || _h === void 0 ? void 0 : _h.replace(new RegExp(`^${(_j = this.paths) === null || _j === void 0 ? void 0 : _j.localPath}\\\\.?`), ''),\n fullLocalPath: (_l = (_k = component.paths) === null || _k === void 0 ? void 0 : _k.fullLocalPath) === null || _l === void 0 ? void 0 : _l.replace(new RegExp(`^${(_m = this.paths) === null || _m === void 0 ? void 0 : _m.fullLocalPath}\\\\.?`), ''),\n dataPath: (_p = (_o = component.paths) === null || _o === void 0 ? void 0 : _o.dataPath) === null || _p === void 0 ? void 0 : _p.replace(new RegExp(`^${(_q = this.paths) === null || _q === void 0 ? void 0 : _q.dataPath}\\\\.?`), ''),\n localDataPath: (_s = (_r = component.paths) === null || _r === void 0 ? void 0 : _r.localDataPath) === null || _s === void 0 ? void 0 : _s.replace(new RegExp(`^${(_t = this.paths) === null || _t === void 0 ? void 0 : _t.localDataPath}\\\\.?`), ''),\n }, path, this.rowIndex, matches, (type, match) => {\n match.instance = component;\n return match;\n });\n });\n return (_a = (0, utils_1.getBestMatch)(matches)) === null || _a === void 0 ? void 0 : _a.instance;\n }\n /**\n * Return a component provided the Id of the component.\n * @param {string} id - The Id of the component.\n * @param {Function} fn - Called with the component once it is retrieved.\n * @returns {object} - The component retrieved.\n */\n getComponentById(id, fn = null) {\n let comp = null;\n this.everyComponent((component, components) => {\n if (component.id === id) {\n comp = component;\n if (fn) {\n fn(component, components);\n }\n return false;\n }\n });\n return comp;\n }\n /**\n * Create a new component and add it to the components array.\n * @param {import('@formio/core').Component} component - The component JSON schema to create.\n * @param {object} options - The options to create the component with.\n * @param {import('@formio/core').DataObject} data - The submission data object to house the data for this component.\n * @param {import('@formio/core').Component} [before] - The component before which to add this component.\n * @param {import('@formio/core').Component} [replacedComp] - The component to replace with this component.\n * @returns {any} - The created component instance.\n */\n createComponent(component, options, data, before, replacedComp) {\n if (!component) {\n return;\n }\n options = options || this.options;\n data = data || this.data;\n options.parent = this;\n options.parentVisible = this.visible;\n options.root = (options === null || options === void 0 ? void 0 : options.root) || this.root || this;\n options.localRoot = this.localRoot;\n options.skipInit = true;\n if (!(options.display === 'pdf' && this.builderMode)) {\n component.id = (0, utils_1.getRandomComponentId)();\n }\n const comp = Components_1.default.create(component, options, data, true);\n comp.init();\n if (component.internal) {\n return comp;\n }\n if (before) {\n const index = lodash_1.default.findIndex(this.components, { id: before.id });\n if (index !== -1) {\n this.components.splice(index, 0, comp);\n }\n else {\n this.components.push(comp);\n }\n }\n else if (replacedComp) {\n const index = lodash_1.default.findIndex(this.components, { id: replacedComp.id });\n if (index !== -1) {\n this.components[index] = comp;\n }\n else {\n this.components.push(comp);\n }\n }\n else {\n this.components.push(comp);\n }\n return comp;\n }\n getContainer() {\n return this.element;\n }\n get componentComponents() {\n return this.component.components || [];\n }\n get nestedKey() {\n return `nested-${this.key}`;\n }\n get templateName() {\n return 'container';\n }\n init() {\n this.components = this.components || [];\n this.addComponents();\n return super.init();\n }\n /**\n * Add a new component instance to the components array.\n * @param {import('@formio/core').DataObject} [data] - The Submission data for this component.\n * @param {object} [options] - The options for this component.\n */\n addComponents(data, options) {\n data = data || this.data;\n this.components = this.components || [];\n options = options || this.options;\n if (options.components) {\n this.components = options.components;\n }\n else {\n const components = this.hook('addComponents', this.componentComponents, this) || [];\n components.forEach((component) => this.addComponent(component, data));\n }\n }\n /**\n * Add a new component to the components array.\n * @param {import('@formio/core').Component} component - The component JSON schema to add.\n * @param {object} data - The submission data object to house the data for this component.\n * @param {HTMLElement} before - A DOM element to insert this element before.\n * @param {boolean} [noAdd] - A possibly extraneous boolean flag.\n * @returns {any} - The created component instance.\n */\n addComponent(component, data = null, before = null, noAdd = false) {\n data = data || this.data;\n this.components = this.components || [];\n component = this.hook('addComponent', component, data, before, noAdd);\n const comp = this.createComponent(component, this.options, data, before ? before : null);\n if (noAdd) {\n return comp;\n }\n return comp;\n }\n beforeFocus() {\n if (this.parent && 'beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n }\n render(children) {\n // If already rendering, don't re-render.\n return super.render(children || this.renderTemplate(this.templateName, {\n children: !this.visible ? '' : this.renderComponents(),\n nestedKey: this.nestedKey,\n collapsed: this.options.pdf ? false : this.collapsed,\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n return this.renderTemplate('components', {\n children,\n components,\n });\n }\n attach(element) {\n const superPromise = super.attach(element);\n this.loadRefs(element, {\n header: 'single',\n collapsed: this.collapsed,\n [this.nestedKey]: 'single',\n messageContainer: 'single-scope',\n });\n let childPromise = Promise.resolve();\n if (this.refs[this.nestedKey]) {\n childPromise = this.attachComponents(this.refs[this.nestedKey]);\n }\n if (!this.visible) {\n this.attachComponentsLogic();\n }\n if (this.component.collapsible && this.refs.header) {\n this.addEventListener(this.refs.header, 'click', () => {\n this.collapsed = !this.collapsed;\n });\n this.addEventListener(this.refs.header, 'keydown', (e) => {\n if (e.keyCode === 13 || e.keyCode === 32) {\n e.preventDefault();\n this.collapsed = !this.collapsed;\n }\n });\n }\n return Promise.all([\n superPromise,\n childPromise,\n ]);\n }\n /**\n * Attach the logic to the components.\n * @param {import('@formio/core').Component[]} components - The components to attach logic to.\n */\n attachComponentsLogic(components) {\n components = components || this.components;\n lodash_1.default.each(components, (comp) => {\n comp.attachLogic();\n if (lodash_1.default.isFunction(comp.attachComponentsLogic)) {\n comp.attachComponentsLogic();\n }\n });\n }\n attachComponents(element, components, container) {\n components = components || this.components;\n container = container || this.component.components;\n element = this.hook('attachComponents', element, components, container, this);\n if (!element) {\n // Return a non-resolving promise.\n return (new Promise(() => { }));\n }\n let index = 0;\n const promises = [];\n Array.prototype.slice.call(element.children).forEach(child => {\n if (!child.getAttribute('data-noattach') && components[index]) {\n promises.push(components[index].attach(child));\n index++;\n }\n });\n return Promise.all(promises);\n }\n /**\n * Remove a component from the components array and from the children object\n * @param {import('@formio/core').Component} component - The component to remove from the components.\n * @param {import('@formio/core').Component[]} components - An array of components to remove this component from.\n * @param {boolean} [all] - If set to TRUE will cascade remove all components.\n */\n removeComponent(component, components, all = false) {\n components = components || this.components;\n component.destroy(all);\n lodash_1.default.remove(components, { id: component.id });\n if (this.componentsMap[component.path]) {\n delete this.componentsMap[component.path];\n }\n }\n /**\n * Removes a component provided the API key of that component.\n * @param {string} key - The API key of the component to remove.\n * @param {Function} fn - Called once the component is removed.\n * @returns {null|void} - Returns nothing if the component is not found.\n */\n removeComponentByKey(key, fn = null) {\n const comp = this.getComponent(key, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n /**\n * Removes a component provided the Id of the component.\n * @param {string} id - The Id of the component to remove.\n * @param {Function} fn - Called when the component is removed.\n * @returns {null|void} - Returns nothing if the component is not found.\n */\n removeComponentById(id, fn = null) {\n const comp = this.getComponentById(id, (component, components) => {\n this.removeComponent(component, components);\n if (fn) {\n fn(component, components);\n }\n });\n if (!comp) {\n if (fn) {\n fn(null);\n }\n return null;\n }\n }\n updateValue(value, flags = {}) {\n return this.components.reduce((changed, comp) => {\n return comp.updateValue(null, flags) || changed;\n }, super.updateValue(value, flags));\n }\n shouldSkipValidation(data, row, flags) {\n // Nested components with no input should not be validated.\n if (!this.component.input) {\n return true;\n }\n else {\n return super.shouldSkipValidation(data, row, flags);\n }\n }\n checkData(data, flags, row, components) {\n if (this.builderMode) {\n return true;\n }\n data = data || this.rootValue;\n flags = flags || {};\n row = row || this.data;\n components = components && lodash_1.default.isArray(components) ? components : this.getComponents();\n super.checkData(data, Object.assign({}, flags), row);\n components.forEach((comp) => comp.checkData(data, Object.assign({}, flags), row));\n }\n checkConditions(data, flags, row) {\n // check conditions of parent component first, because it may influence on visibility of it's children\n const check = super.checkConditions(data, flags, row);\n //row data of parent component not always corresponds to row of nested components, use comp.data as row data for children instead\n this.getComponents().forEach(comp => comp.checkConditions(data, flags, comp.data));\n return check;\n }\n clearOnHide(show) {\n super.clearOnHide(show);\n if (this.component.clearOnHide) {\n if (this.allowData && !this.hasValue() && !this.conditionallyHidden) {\n this.dataValue = this.defaultValue;\n }\n if (this.hasValue()) {\n this.restoreComponentsContext();\n }\n }\n this.getComponents().forEach(component => component.clearOnHide(show));\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => component.data = this.dataValue);\n }\n /**\n * Allow components to hook into the next page trigger to perform their own logic.\n * @param {Function} next - The callback to continue to the next page.\n * @returns {Promise} - A promise when the page has been processed.\n */\n beforePage(next) {\n return Promise.all(this.getComponents().map((comp) => comp.beforePage(next)));\n }\n /**\n * Allow components to hook into the submission to provide their own async data.\n * @returns {Promise} - Returns a promise when the constituent beforeSubmit functions are complete.\n */\n beforeSubmit() {\n return Promise.allSettled(this.getComponents().map((comp) => comp.beforeSubmit()));\n }\n calculateValue(data, flags, row) {\n // Do not iterate into children and calculateValues if this nested component is conditionally hidden.\n if (this.conditionallyHidden) {\n return false;\n }\n return this.getComponents().reduce((changed, comp) => comp.calculateValue(data, flags, row) || changed, super.calculateValue(data, flags, row));\n }\n isLastPage() {\n return this.pages.length - 1 === this.page;\n }\n isValid(data, dirty) {\n return this.getComponents().reduce((valid, comp) => comp.isValid(data, dirty) && valid, super.isValid(data, dirty));\n }\n validationProcessor({ scope, data, row, instance, paths }, flags) {\n var _a;\n const { dirty } = flags;\n if (this.root.hasExtraPages && this.page !== this.root.page) {\n instance = ((_a = this.componentsMap) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(paths.dataPath))\n ? this.componentsMap[paths.dataPath]\n : this.getComponent(paths.dataPath);\n }\n if (!instance) {\n return;\n }\n instance.checkComponentValidity(data, dirty, row, flags, scope.errors);\n if (instance.processOwnValidation) {\n scope.noRecurse = true;\n }\n }\n /**\n * Perform a validation on all child components of this nested component.\n * @param {import('@formio/core').Component[]} components - The components to validate.\n * @param {import('@formio/core').DataObject} data - The data to validate.\n * @param {object} flags - The flags to use when validating.\n * @returns {Promise<Array>|Array} - The errors if any exist.\n */\n validateComponents(components = null, data = null, flags = {}) {\n components = components || this.component.components;\n data = data || this.rootValue;\n const { async, dirty, process } = flags;\n const validationProcessorProcess = (context) => this.validationProcessor(context, flags);\n const checkModalProcessorProcess = ({ instance, component, components }) => {\n // If we just validated the last component, and there are errors from our parent, then we need to show a model of those errors.\n if (instance &&\n instance.parent &&\n (component === components[components.length - 1]) &&\n instance.parent.componentModal) {\n instance.parent.checkModal(instance.parent.childErrors, dirty);\n }\n };\n const processorContext = {\n process: process || 'unknown',\n components,\n instances: this.componentsMap,\n data: data,\n local: !!flags.local,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: this.paths,\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n },\n {\n process: checkModalProcessorProcess,\n processSync: checkModalProcessorProcess\n }\n ]\n };\n return async ? (0, process_1.process)(processorContext).then((scope) => scope.errors) : (0, process_1.processSync)(processorContext).errors;\n }\n /**\n * Validate a nested component with data, or its own internal data.\n * @param {import('@formio/core').DataObject} data - The data to validate.\n * @param {object} flags - The flags to use when validating.\n * @returns {Array} - The errors if any exist.\n */\n validate(data = null, flags = {}) {\n data = data || this.rootValue;\n return this.validateComponents(this.getComponents().map((component) => component.component), data, flags);\n }\n checkComponentValidity(data = null, dirty = false, row = null, flags = {}, allErrors = []) {\n this.childErrors = [];\n return super.checkComponentValidity(data, dirty, row, flags, allErrors);\n }\n /**\n * Checks the validity of the component.\n * @param {*} data - The data to check if the component is valid.\n * @param {boolean} dirty - If the component is dirty.\n * @param {*} row - The contextual row data for this component.\n * @param {boolean} silentCheck - If the check should be silent and not set the error messages.\n * @param {Array<any>} childErrors - An array of all errors that have occured so that it can be appended when another one occurs here.\n * @returns {boolean} - TRUE if the component is valid.\n */\n checkValidity(data = null, dirty = false, row = null, silentCheck = false, childErrors = []) {\n childErrors.push(...this.validate(data, { dirty, silentCheck }));\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck }, childErrors) && childErrors.length === 0;\n }\n checkAsyncValidity(data = null, dirty = false, row = null, silentCheck = false) {\n return this.ready.then(() => {\n return this.validate(data, { dirty, silentCheck, async: true }).then((childErrors) => {\n return this.checkComponentValidity(data, dirty, row, { dirty, silentCheck, async: true }, childErrors).then((valid) => {\n return valid && childErrors.length === 0;\n });\n });\n });\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n this.getComponents().forEach((comp) => comp.setPristine(pristine));\n }\n get isPristine() {\n return this.pristine && this.getComponents().every((c) => c.isPristine);\n }\n get isDirty() {\n return this.dirty && this.getComponents().every((c) => c.isDirty);\n }\n detach() {\n this.components.forEach(component => {\n component.detach();\n });\n super.detach();\n }\n clear() {\n this.components.forEach(component => {\n component.clear();\n });\n super.clear();\n }\n destroy(all = false) {\n this.destroyComponents(all);\n super.destroy(all);\n }\n destroyComponents(all = false) {\n const components = this.getComponents().slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n this.components = [];\n }\n get visibleErrors() {\n return this.getComponents().reduce((errors, comp) => errors.concat(comp.visibleErrors || []), super.visibleErrors);\n }\n get errors() {\n const thisErrors = super.errors;\n return this.getComponents()\n .reduce((errors, comp) => errors.concat(comp.errors || []), thisErrors)\n .filter(err => err.level !== 'hidden');\n }\n getValue() {\n return this.data;\n }\n resetValue() {\n super.resetValue();\n this.getComponents().forEach((comp) => comp.resetValue());\n this.setPristine(true);\n }\n get dataReady() {\n return Promise.all(this.getComponents().map((component) => component.dataReady));\n }\n setNestedValue(component, value, flags = {}) {\n component._data = this.componentContext(component);\n if (component.type === 'button') {\n return false;\n }\n if (component.type === 'components') {\n if (component.tree && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n return component.setValue(value, flags);\n }\n else if (value && component.hasValue(value)) {\n return component.setValue(lodash_1.default.get(value, component.key), flags);\n }\n else if ((!this.rootPristine || component.visible) && component.shouldAddDefaultValue) {\n flags.noValidate = !flags.dirty;\n flags.resetValue = true;\n return component.setValue(component.defaultValue, flags);\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n return false;\n }\n return this.getComponents().reduce((changed, component) => {\n return this.setNestedValue(component, value, flags, changed) || changed;\n }, false);\n }\n get lazyLoad() {\n var _a;\n return (_a = this.component.lazyLoad) !== null && _a !== void 0 ? _a : false;\n }\n}\nexports[\"default\"] = NestedComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/_classes/nested/NestedComponent.js?");
|
5011
5011
|
|
5012
5012
|
/***/ }),
|
5013
5013
|
|
@@ -5172,7 +5172,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5172
5172
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5173
5173
|
|
5174
5174
|
"use strict";
|
5175
|
-
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 process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst components_1 = __webpack_require__(/*! @formio/bootstrap/components */ \"./node_modules/@formio/bootstrap/lib/cjs/templates/components/index.js\");\nconst NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst Alert_1 = __importDefault(__webpack_require__(/*! ../alert/Alert */ \"./lib/cjs/components/alert/Alert.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst EditRowState = {\n New: 'new',\n Editing: 'editing',\n Saved: 'saved',\n Viewing: 'viewing',\n Removed: 'removed',\n Draft: 'draft',\n};\nclass EditGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n type: 'editgrid',\n label: 'Edit Grid',\n key: 'editGrid',\n clearOnHide: true,\n input: true,\n tree: true,\n removeRow: 'Cancel',\n defaultOpen: false,\n openWhenEmpty: false,\n modal: false,\n components: [],\n inlineEdit: false,\n templates: {\n header: EditGridComponent.defaultHeaderTemplate,\n row: EditGridComponent.defaultRowTemplate,\n tableHeader: EditGridComponent.defaultTableHeaderTemplate,\n tableRow: EditGridComponent.defaultTableRowTemplate,\n footer: '',\n },\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Edit Grid',\n icon: 'tasks',\n group: 'data',\n documentation: '/userguide/form-building/data-components#edit-grid',\n showPreview: false,\n weight: 30,\n schema: EditGridComponent.schema(),\n };\n }\n static get defaultHeaderTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">{{ t(component.label) }}</div>\n {% } %}\n {% }) %}\n </div>`;\n }\n static get defaultTableHeaderTemplate() {\n return `\n <tr>\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">{{ component.label }}</td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">Actions</td>\n {% } %}\n </tr>\n `;\n }\n static get defaultRowTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">\n {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}\n </div>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <div class=\"col-sm-2\">\n <div class=\"btn-group pull-right\">\n <button class=\"btn btn-default btn-light btn-sm editRow\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </div>\n {% } %}\n </div>`;\n }\n static get defaultTableRowTemplate() {\n return `\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">\n {{ getView(component, row[component.key]) }}\n </td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">\n <div class=\"btn-group\">\n <button class=\"btn btn-default btn-light btn-sm editRow\" aria-label=\"{{ t('Edit row') }}\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\" aria-label=\"{{ t('Remove row') }}\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </td>\n {% } %}\n `;\n }\n get defaultDialogTemplate() {\n return `\n <h3 ${this._referenceAttributeName}=\"dialogHeader\">${this.t('wantToClearData')}</h3>\n <div style=\"display:flex; justify-content: flex-end;\">\n <button ${this._referenceAttributeName}=\"dialogCancelButton\" class=\"btn btn-secondary\" aria-label=\"${this.t('cancel')}\">${this.t('cancel')}</button>\n <button ${this._referenceAttributeName}=\"dialogYesButton\" class=\"btn btn-danger\" aria-label=\"${this.t('yesDelete')}\">${this.t('yesDelete')}</button>\n </div>\n `;\n }\n get defaultRowTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableRowTemplate\n : EditGridComponent.defaultRowTemplate;\n }\n get defaultHeaderTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableHeaderTemplate\n : EditGridComponent.defaultHeaderTemplate;\n }\n get rowTemplate() {\n let rowTemplate;\n if (utils_1.Evaluator.noeval) {\n rowTemplate = this.displayAsTable ?\n components_1.editgrid.tableRow\n : components_1.editgrid.row;\n }\n else {\n rowTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableRow', this.defaultRowTemplate)\n : lodash_1.default.get(this.component, 'templates.row', this.defaultRowTemplate);\n }\n return rowTemplate;\n }\n get headerTemplate() {\n let headerTemplate;\n if (utils_1.Evaluator.noeval) {\n headerTemplate = this.displayAsTable ?\n components_1.editgrid.tableHeader\n : components_1.editgrid.header;\n }\n else {\n headerTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableHeader', this.defaultHeaderTemplate)\n : lodash_1.default.get(this.component, 'templates.header', this.defaultHeaderTemplate);\n }\n return headerTemplate;\n }\n /**\n * @returns {boolean} - Returns true if the component has nested components which don't trigger changes on the root level\n */\n get hasScopedChildren() {\n return !this.inlineEditMode;\n }\n get defaultSchema() {\n return EditGridComponent.schema();\n }\n get emptyValue() {\n return [];\n }\n get editgridKey() {\n return `editgrid-${this.key}`;\n }\n get rowRef() {\n return `${this.editgridKey}-row`;\n }\n get rowElements() {\n return this.refs[this.rowRef];\n }\n get rowRefs() {\n return this.refs[`editgrid-${this.component.key}-row`];\n }\n get addRowRef() {\n return `${this.editgridKey}-addRow`;\n }\n get addRowElements() {\n return this.refs[this.addRowRef];\n }\n get saveRowRef() {\n return `${this.editgridKey}-saveRow`;\n }\n get saveRowElements() {\n return this.refs[this.saveRowRef];\n }\n get cancelRowRef() {\n return `${this.editgridKey}-cancelRow`;\n }\n get cancelRowElements() {\n return this.refs[this.cancelRowRef];\n }\n get inlineEditMode() {\n return this.component.inlineEdit;\n }\n get saveEditMode() {\n return !this.inlineEditMode;\n }\n get minLength() {\n return this.builderMode ? 0 : lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n get data() {\n return this._data;\n }\n get dataValue() {\n return super.dataValue || [];\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get displayAsTable() {\n return this.component.displayAsTable;\n }\n set data(value) {\n this._data = value;\n const data = this.dataValue;\n (this.editRows || []).forEach((row, index) => {\n if (!data[index] && row.state !== EditRowState.New) {\n data[index] = {};\n }\n const rowData = data[index] || {};\n row.data = rowData;\n row.components.forEach((component) => {\n component.data = rowData;\n });\n });\n }\n get iteratableRows() {\n return this.editRows;\n }\n get defaultValue() {\n const value = super.defaultValue;\n const defaultValue = Array.isArray(value) ? value : [];\n lodash_1.default.times(this.minLength - defaultValue.length, () => defaultValue.push({}));\n return defaultValue;\n }\n constructor(...args) {\n super(...args);\n this.type = 'editgrid';\n }\n hasRemoveButtons() {\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n init() {\n if (this.builderMode) {\n this.editRows = [];\n return super.init();\n }\n this.components = this.components || [];\n const dataValue = this.dataValue;\n const openWhenEmpty = !dataValue.length && this.component.openWhenEmpty;\n if (openWhenEmpty) {\n const dataObj = {};\n this.editRows = [];\n this.createRow(dataObj, 0);\n }\n else {\n this.editRows = dataValue.map((row, rowIndex) => ({\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n error: null,\n rowIndex,\n }));\n }\n this.prevHasAddButton = this.hasAddButton();\n this.checkData();\n this.setVariableTypeComponents();\n if (this.variableTypeComponentsIndexes.length) {\n lodash_1.default.each(this.editRows || [], (editRow, rowIndex) => this.checkRowVariableTypeComponents(editRow, rowIndex));\n }\n }\n checkRowVariableTypeComponents(editRow, rowIndex) {\n const rowComponents = editRow.components;\n let typeChanged = false;\n if (lodash_1.default.some(this.variableTypeComponentsIndexes, (compIndex) => {\n const variableTypeComp = rowComponents[compIndex];\n return variableTypeComp.type !== variableTypeComp.component.type;\n })) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex, true);\n typeChanged = true;\n }\n return typeChanged;\n }\n setVariableTypeComponents() {\n //set components which type is changing within a row (e.g.,by mergeComponentSchema action)\n this.variableTypeComponentsIndexes = [];\n lodash_1.default.each(this.component.components, (comp, index) => {\n if (comp.typeChangeEnabled) {\n this.variableTypeComponentsIndexes.push(index);\n }\n });\n }\n isOpen(editRow) {\n return [EditRowState.New, EditRowState.Editing, EditRowState.Viewing].includes(editRow.state);\n }\n isComponentVisibleInSomeRow(component) {\n const rows = this.editRows;\n const savedStates = [EditRowState.Saved, EditRowState.Editing, EditRowState.Draft];\n const savedRows = rows.filter(row => lodash_1.default.includes(savedStates, row.state));\n this.visibleInHeader = this.visibleInHeader || [];\n const changeVisibleInHeader = (component, isVisible) => {\n if (!isVisible) {\n lodash_1.default.remove(this.visibleInHeader, (key) => key === component.key);\n }\n if (isVisible && !lodash_1.default.includes(this.visibleInHeader, component.key)) {\n this.visibleInHeader.push(component.key);\n }\n };\n if (lodash_1.default.isEmpty(rows)) {\n const rowComponents = this.createRowComponents({}, 0);\n let checkComponent;\n (0, utils_1.eachComponent)(rowComponents, (comp) => {\n if (comp.component.key === component.key) {\n checkComponent = comp;\n }\n comp.checkConditions();\n });\n const isVisible = checkComponent ? checkComponent.visible : true;\n [...this.components].forEach((comp) => this.removeComponent(comp, this.components));\n changeVisibleInHeader(component, isVisible);\n return isVisible;\n }\n const isOpenRowWhenEmpty = lodash_1.default.get(this.component, 'openWhenEmpty') && rows.length === 1 && rows[0].state === EditRowState.New;\n if (!lodash_1.default.isEmpty(rows) && lodash_1.default.isEmpty(savedRows) && !isOpenRowWhenEmpty) {\n return lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return lodash_1.default.some(isOpenRowWhenEmpty ? rows : savedRows, (row, index) => {\n const editingRow = row.state === EditRowState.Editing;\n let isVisible;\n if (!editingRow) {\n const flattenedComponents = this.flattenComponents(index);\n const instance = flattenedComponents[component.key];\n isVisible = instance ? instance.visible : true;\n changeVisibleInHeader(component, isVisible);\n }\n else {\n isVisible = lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return isVisible;\n });\n }\n render(children) {\n if (this.builderMode) {\n return super.render();\n }\n const dataValue = this.dataValue;\n const headerTemplate = this.headerTemplate;\n const t = this.t.bind(this);\n const templateName = this.displayAsTable ? 'editgridTable' : 'editgrid';\n return super.render(children || this.renderTemplate(templateName, {\n ref: {\n row: this.rowRef,\n addRow: this.addRowRef,\n saveRow: this.saveRowRef,\n cancelRow: this.cancelRowRef,\n },\n header: this.renderString(headerTemplate, {\n displayValue: (component) => this.displayComponentValue(component, true),\n components: this.component.components,\n value: dataValue,\n t\n }),\n footer: this.renderString(lodash_1.default.get(this.component, 'templates.footer'), {\n components: this.component.components,\n value: dataValue,\n t\n }),\n rows: this.editRows.map(this.renderRow.bind(this)),\n openRows: this.editRows.map((row) => this.isOpen(row)),\n errors: this.editRows.map((row) => row.error),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons: this.hasRemoveButtons(),\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n const templateName = this.displayAsTable && this.prevHasAddButton ? 'tableComponents' : 'components';\n return this.renderTemplate(templateName, {\n children,\n components,\n });\n }\n attach(element) {\n if (this.builderMode) {\n return super.attach(element);\n }\n this.loadRefs(element, {\n [this.addRowRef]: 'multiple',\n [this.saveRowRef]: 'multiple',\n [this.cancelRowRef]: 'multiple',\n [this.rowRef]: 'multiple',\n });\n this.addRowElements.forEach((addButton) => {\n this.addEventListener(addButton, 'click', () => this.addRow());\n });\n let openRowCount = 0;\n this.rowElements.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow === null || editRow === void 0 ? void 0 : editRow.isRowSelected) {\n row.classList.add('selected');\n }\n if (this.isOpen(editRow)) {\n this.attachComponents(row, editRow.components);\n this.addEventListener(this.saveRowElements[openRowCount], 'click', () => this.saveRow(rowIndex, true));\n this.addEventListener(this.cancelRowElements[openRowCount], 'click', () => this.cancelRow(rowIndex));\n openRowCount++;\n }\n else {\n // Attach edit and remove button events.\n [\n {\n className: 'removeRow',\n event: 'click',\n action: () => this.removeRow(rowIndex, true),\n },\n {\n className: 'editRow',\n event: 'click',\n action: () => {\n this.editRow(rowIndex).then(() => {\n var _a;\n if (this.component.rowDrafts) {\n const errors = this.validateRow(editRow, false);\n const shouldShowRowErrorsAlert = this.component.modal && errors.length && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted);\n if (shouldShowRowErrorsAlert) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n }\n });\n },\n },\n {\n className: 'row',\n event: 'click',\n action: () => {\n row.classList.toggle('selected');\n let eventName = 'editGridSelectRow';\n if (Array.from(row.classList).includes('selected')) {\n editRow.isRowSelected = true;\n }\n else {\n delete editRow.isRowSelected;\n eventName = 'editGridUnSelectRow';\n }\n this.emit(eventName, {\n component: this.component,\n data: this.dataValue[rowIndex]\n });\n },\n }\n ].forEach(({ className, event, action, }) => {\n const elements = row.getElementsByClassName(className);\n Array.prototype.forEach.call(elements, (element) => {\n if (this.options.pdf && lodash_1.default.intersection(element.classList, ['editRow', 'removeRow']).length) {\n element.style.display = 'none';\n }\n else {\n this.addEventListener(element, event, action);\n }\n });\n });\n }\n });\n // Add open class to the element if any edit grid row is open\n if (openRowCount) {\n this.addClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n else {\n this.removeClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n return super.attach(element);\n }\n flattenRowDataValue(dataValue) {\n const flattened = {};\n Object.keys(dataValue).forEach((key) => {\n if (lodash_1.default.isObject(dataValue[key]) && !lodash_1.default.isNil(dataValue[key])) {\n Object.assign(flattened, this.flattenRowDataValue(dataValue[key]));\n }\n else {\n flattened[key] = dataValue[key];\n }\n });\n return flattened;\n }\n isComponentVisibleInRow(component, flattenedComponents) {\n const instance = flattenedComponents[component.key];\n return instance ? instance.visible : true;\n }\n displayComponentValue(component, header) {\n return !!((!component.hasOwnProperty('tableView') || component.tableView)\n && header ? this.isComponentVisibleInSomeRow(component) : lodash_1.default.includes(this.visibleInHeader, component.key));\n }\n renderRow(row, rowIndex) {\n const dataValue = this.dataValue;\n if (this.isOpen(row)) {\n return this.renderComponents(row.components);\n }\n else {\n const flattenedComponents = this.flattenComponents(rowIndex);\n const rowTemplate = this.rowTemplate;\n return this.renderString(rowTemplate, {\n row: dataValue[rowIndex] || {},\n data: this.data,\n rowIndex,\n components: this.component.components,\n flattenedComponents,\n displayValue: (component) => this.displayComponentValue(component),\n isVisibleInRow: (component) => this.isComponentVisibleInRow(component, flattenedComponents),\n getView: (component, data) => {\n var _a, _b;\n const instance = flattenedComponents[component.key];\n const view = instance ? instance.getView(data || instance.dataValue) : '';\n // If there is an html tag in view, don't allow it to be injected in template\n const htmlTagRegExp = new RegExp('<(.*?)>');\n return typeof view === 'string' && view.length && !((_a = instance.component) === null || _a === void 0 ? void 0 : _a.template) && htmlTagRegExp.test(view) && ((_b = instance.component) === null || _b === void 0 ? void 0 : _b.inputFormat) !== 'html'\n ? `<input type=\"text\" value=\"${view.replace(/\"/g, '"')}\" readonly/>`\n : view;\n },\n state: this.editRows[rowIndex].state,\n t: this.t.bind(this)\n });\n }\n }\n eachComponent(fn, rowIndex) {\n lodash_1.default.each(this.getComponents(rowIndex), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n var _a;\n const rowData = this.dataValue[component.rowIndex];\n const editRowData = (_a = this.editRows[component.rowIndex]) === null || _a === void 0 ? void 0 : _a.data;\n component.data = rowData || editRowData;\n });\n }\n flattenComponents(rowIndex) {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n }, rowIndex);\n return result;\n }\n getComponents(rowIndex) {\n var _a;\n // Ensure editrows is set.\n this.editRows = this.editRows || [];\n return this.builderMode\n ? super.getComponents()\n : lodash_1.default.isNumber(rowIndex)\n ? (((_a = this.editRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.components) || [])\n : this.editRows.reduce((result, row) => result.concat(row.components || []), []);\n }\n destroy(all = false) {\n this.calculatedValue = undefined;\n super.destroy(all);\n }\n destroyComponents(all = false, rowIndex = 0) {\n if (this.builderMode) {\n return super.destroyComponents(all);\n }\n const components = this.getComponents(rowIndex).slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n }\n createRow(dataObj, rowIndex) {\n const editRow = {\n components: this.createRowComponents(dataObj, rowIndex),\n data: dataObj,\n state: EditRowState.New,\n backup: null,\n error: null,\n rowIndex,\n };\n this.editRows.push(editRow);\n if (this.inlineEditMode) {\n this.dataValue.push(dataObj);\n }\n return editRow;\n }\n addRow() {\n if (this.options.readOnly) {\n return;\n }\n const dataObj = {};\n const rowIndex = this.editRows.length;\n const editRow = this.createRow(dataObj, rowIndex);\n if (editRow.state === EditRowState.New) {\n this.emptyRow = (0, utils_1.fastCloneDeep)(editRow.data);\n }\n if (this.inlineEditMode) {\n this.triggerChange();\n }\n this.emit('editGridAddRow', {\n component: this.component,\n row: editRow,\n });\n this.processRow('checkData', null, {}, editRow.data, editRow.components);\n if (this.component.modal) {\n this.addRowModal(rowIndex);\n }\n else {\n this.redraw();\n }\n return editRow;\n }\n addRowModal(rowIndex) {\n const modalContent = this.ce('div');\n const editRow = this.editRows[rowIndex];\n editRow.willBeSaved = false;\n const { components } = editRow;\n modalContent.innerHTML = this.renderComponents(components);\n const dialog = this.component.modal ? this.createModal(modalContent, {}, () => this.showDialog(rowIndex)) : undefined;\n dialog.classList.add(`editgrid-row-modal-${this.id}`);\n editRow.dialog = dialog;\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n this.alert = new Alert_1.default(dialog.refs.dialogContents, this);\n this.addEventListener(dialog, 'close', () => {\n if (!editRow.willBeSaved) {\n if (this.editRows[rowIndex] && this.editRows[rowIndex].state !== EditRowState.New) {\n this.editRows[rowIndex].components.forEach((comp) => {\n comp.setPristine(true);\n });\n }\n this.cancelRow(rowIndex);\n }\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n // Remove references to dialog elements to prevent possible in some cases memory leaks\n delete editRow.confirmationDialog;\n delete editRow.dialog;\n });\n dialog.refs.dialogContents.appendChild(this.ce('button', {\n class: 'btn btn-primary',\n onClick: () => {\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!errors.length || this.component.rowDrafts) {\n editRow.willBeSaved = true;\n dialog.close();\n this.saveRow(rowIndex, true);\n }\n else {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n },\n }, this.component.saveRow || 'Save'));\n this.emit('editGridOpenModal', {\n component: this.component,\n row: editRow,\n instance: this,\n });\n return this.attachComponents(modalContent, components);\n }\n showDialog(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow.state === EditRowState.New ? lodash_1.default.isEqual(this.emptyRow, editRow.data) : lodash_1.default.isEqual(editRow.backup, editRow.data)) {\n return Promise.resolve();\n }\n const wrapper = this.ce('div', { ref: 'confirmationDialog' });\n const dialogContent = this.component.dialogTemplate || this.defaultDialogTemplate;\n wrapper.innerHTML = dialogContent;\n wrapper.refs = {};\n this.loadRefs.call(wrapper, wrapper, {\n dialogHeader: 'single',\n dialogCancelButton: 'single',\n dialogYesButton: 'single',\n });\n const dialog = this.createModal(wrapper);\n dialog.classList.add(`editgrid-row-modal-confirmation-${this.id}`);\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n let dialogResult;\n const promise = new Promise((resolve, reject) => {\n dialogResult = { resolve, reject };\n });\n this.addEventListener(wrapper.refs.dialogYesButton, 'click', (event) => {\n close(event);\n dialogResult.resolve();\n });\n this.addEventListener(wrapper.refs.dialogCancelButton, 'click', (event) => {\n close(event);\n dialogResult.reject();\n });\n editRow.confirmationDialog = dialog;\n return promise;\n }\n editRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n const isAlreadyEditing = editRow.state === EditRowState.Editing || editRow.state === EditRowState.New;\n if (!editRow || isAlreadyEditing) {\n return Promise.resolve();\n }\n editRow.prevState = editRow.state;\n editRow.state = this.options.readOnly ? EditRowState.Viewing : EditRowState.Editing;\n if (this.lazyLoad && (editRow.components.length === 0)) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex);\n }\n const dataSnapshot = (0, utils_1.fastCloneDeep)(editRow.data);\n if (this.inlineEditMode) {\n editRow.backup = dataSnapshot;\n }\n else {\n editRow.backup = (0, utils_1.fastCloneDeep)(editRow.data);\n editRow.data = dataSnapshot;\n this.restoreRowContext(editRow);\n }\n this.emit('editGridEditRow', {\n component: this.component,\n row: editRow,\n instance: this,\n });\n if (this.component.modal) {\n return this.addRowModal(rowIndex);\n }\n return this.redraw();\n }\n clearErrors(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow && Array.isArray(editRow.components)) {\n editRow.components.forEach((comp) => {\n comp.setPristine(true);\n comp.setCustomValidity('');\n });\n }\n }\n cancelRow(rowIndex) {\n if (this.options.readOnly) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n switch (editRow.state) {\n case EditRowState.New: {\n editRow.state = EditRowState.Removed;\n this.clearErrors(rowIndex);\n this.destroyComponents(false, rowIndex);\n if (this.inlineEditMode) {\n this.splice(rowIndex);\n }\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n break;\n }\n case EditRowState.Editing: {\n editRow.state = editRow.prevState;\n if (this.inlineEditMode) {\n this.dataValue[rowIndex] = editRow.backup;\n }\n editRow.data = editRow.backup;\n editRow.backup = null;\n this.restoreRowContext(editRow);\n this.clearErrors(rowIndex);\n break;\n }\n }\n this.emit('editGridCancelRow', {\n instance: this,\n component: this.component,\n editRow,\n });\n this.checkValidity(null, true);\n this.redraw();\n if (this.component.rowDrafts) {\n this.checkValidity(this.data, false);\n }\n }\n saveRow(rowIndex, modified) {\n var _a, _b;\n const editRow = this.editRows[rowIndex];\n if (this.options.readOnly) {\n return;\n }\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!this.component.rowDrafts) {\n if (errors.length) {\n return false;\n }\n }\n if (this.saveEditMode) {\n const dataValue = this.dataValue;\n if ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.component.typeChangeEnabled) {\n this.root.focusedComponent = null;\n }\n switch (editRow.state) {\n case EditRowState.New: {\n const newIndex = dataValue.length;\n dataValue.push(editRow.data);\n editRow.components.forEach(component => component.rowIndex = newIndex);\n if (rowIndex !== newIndex) {\n this.editRows.splice(rowIndex, 1);\n this.editRows.splice(newIndex, 0, editRow);\n }\n break;\n }\n case EditRowState.Editing: {\n dataValue[rowIndex] = editRow.data;\n break;\n }\n }\n }\n editRow.state = this.component.rowDrafts && errors.length ? EditRowState.Draft : EditRowState.Saved;\n editRow.backup = null;\n this.updateValue();\n this.emit('editGridSaveRow', {\n component: this.component,\n row: editRow.data,\n instance: this\n });\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n if (this.component.rowDrafts) {\n editRow.components.forEach(comp => comp.setPristine(this.pristine));\n }\n this.checkValidity(null, true);\n this.redraw();\n if (editRow.alerts) {\n editRow.alerts = false;\n }\n return true;\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const relativePath = this.getRelativePath(component.path);\n const arrayPath = (0, utils_1.getArrayFromComponentPath)(relativePath);\n const rowIndex = arrayPath[0];\n let rowToEditIndex = arrayPath[0];\n this.editRows.forEach((row, indexInArray) => {\n if (row.rowIndex === rowIndex) {\n rowToEditIndex = indexInArray;\n }\n });\n if (lodash_1.default.isNumber(rowToEditIndex)) {\n this.editRow(rowToEditIndex);\n }\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n });\n }\n updateRowsComponents(rowIndex) {\n this.editRows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(row.components, rowIndex + index);\n });\n }\n baseRemoveRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n editRow.state = EditRowState.Removed;\n this.destroyComponents(false, rowIndex);\n return editRow;\n }\n removeRow(rowIndex, modified) {\n if (this.options.readOnly) {\n return;\n }\n this.clearErrors(rowIndex);\n this.baseRemoveRow(rowIndex);\n this.removeSubmissionMetadataRow(rowIndex);\n this.splice(rowIndex);\n this.emit('editGridDeleteRow', {\n index: rowIndex\n });\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n this.updateRowsComponents(rowIndex);\n this.updateValue();\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n this.checkValidity(null, true);\n this.checkData();\n this.redraw();\n }\n createRowComponents(row, rowIndex, recreatePartially) {\n // Iterate through existing components and destroy the ones with the same rowIndex.\n if (this.components) {\n for (let i = 0; i < this.components.length; i++) {\n if (this.components[i].rowIndex === rowIndex) {\n this.components[i].destroy();\n this.components.splice(i, 1);\n }\n }\n }\n const currentRowComponents = lodash_1.default.get(this.editRows, `[${rowIndex}].components`, null);\n return this.component.components.map((col, colIndex) => {\n var _a;\n if (recreatePartially && currentRowComponents && this.variableTypeComponentsIndexes.length) {\n const currentComp = currentRowComponents[colIndex];\n const shouldRecreate = lodash_1.default.includes(this.variableTypeComponentsIndexes, colIndex) && (currentComp === null || currentComp === void 0 ? void 0 : currentComp.type) !== ((_a = currentComp === null || currentComp === void 0 ? void 0 : currentComp.component) === null || _a === void 0 ? void 0 : _a.type);\n if (!shouldRecreate) {\n return currentComp;\n }\n col = currentComp.component;\n }\n const column = lodash_1.default.clone(col);\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n options.rowIndex = rowIndex;\n options.onChange = (flags = {}, changed, modified) => {\n var _a, _b;\n if (((_a = changed.instance.root) === null || _a === void 0 ? void 0 : _a.id) && (((_b = this.root) === null || _b === void 0 ? void 0 : _b.id) !== changed.instance.root.id)) {\n changed.instance.root.triggerChange(flags, changed, modified);\n }\n else if (!this.component.modal) {\n this.triggerRootChange(flags, changed, modified);\n }\n if (this.inlineEditMode) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), editRow.data, editRow.components);\n this.validateRow(editRow, false, false);\n }\n if (this.variableTypeComponentsIndexes.length) {\n const typeChanged = this.checkRowVariableTypeComponents(editRow, rowIndex);\n if (typeChanged) {\n this.redraw();\n }\n }\n };\n const comp = this.createComponent(lodash_1.default.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);\n comp.rowIndex = rowIndex;\n comp.inEditGrid = true;\n return comp;\n });\n }\n hasOpenRows() {\n return this.editRows.some(row => this.isOpen(row));\n }\n getAttachedData(data = null) {\n const ourData = (0, utils_1.fastCloneDeep)(data || this._data || this.rootValue);\n lodash_1.default.set(ourData, this.key, this.editRows.map((row) => row.data));\n return ourData;\n }\n shouldValidateDraft(editRow) {\n var _a, _b;\n // Draft rows should be validated only when there was an attempt to submit a form\n return (editRow.state === EditRowState.Draft &&\n !this.pristine &&\n !((_a = this.root) === null || _a === void 0 ? void 0 : _a.pristine) &&\n !this.hasOpenRows()) ||\n ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted);\n }\n shouldValidateRow(editRow, dirty, fromSubmission) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n fromSubmission ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {\n var _a, _b;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {\n const silentCheck = forceSilentCheck === false ? false : ((this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck);\n const rootValue = (0, utils_1.fastCloneDeep)(this.rootValue);\n const editGridValue = lodash_1.default.get(rootValue, this.path, []);\n editGridValue[editRow.rowIndex] = editRow.data;\n lodash_1.default.set(rootValue, this.path, editGridValue);\n const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });\n const errors = (0, process_1.processSync)({\n components: this.component.components,\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: Object.assign(Object.assign({}, this.paths), { dataIndex: editRow.rowIndex }),\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n editRow.errors = (this.component.modal || this.component.rowDrafts)\n ? errors\n : errors.filter((err) => lodash_1.default.find(this.visibleErrors, ['component.id', err.component.id]));\n }\n // TODO: this is essentially running its own custom validation and should be moved into a validation rule\n if (this.component.validate && this.component.validate.row) {\n const valid = this.evaluate(this.component.validate.row, {\n valid: (editRow.length === 0),\n row: editRow.data\n }, 'valid', true);\n if (valid.toString() !== 'true') {\n editRow.errors.push({\n type: 'error',\n rowError: true,\n message: valid.toString()\n });\n }\n if (valid === null) {\n editRow.errors.push({\n type: 'error',\n message: this.t('componentInvalidRowValidation', { componentKey: this.key })\n });\n }\n }\n if (editRow.alerts && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n else if ((_b = editRow.errors) === null || _b === void 0 ? void 0 : _b.length) {\n this.setCustomValidity(editRow.errors, dirty);\n }\n return editRow.errors;\n }\n showRowErrorAlerts(editRow, errors) {\n if (editRow.alerts) {\n if (this.alert) {\n if (errors.length) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n else {\n this.alert.clear();\n this.alert = null;\n }\n }\n }\n }\n /**\n * @returns {boolean} - Return that this component processes its own validation.\n */\n get processOwnValidation() {\n return true;\n }\n checkComponentValidity(data, dirty, row, options = {}, errors = []) {\n var _a, _b;\n const { silentCheck, fromSubmission } = options;\n const superValid = super.checkComponentValidity(data, dirty, row, options, errors);\n // If super tells us that component invalid and there is no need to update alerts, just return false\n if (!superValid && (!this.alert && !this.hasOpenRows())) {\n return false;\n }\n let rowsEditing = false;\n const allRowErrors = [];\n this.editRows.forEach((editRow, index) => {\n // Trigger all errors on the row.\n const rowErrors = this.validateRow(editRow, dirty, silentCheck, fromSubmission);\n errors.push(...rowErrors);\n allRowErrors.push(...rowErrors);\n if (this.rowRefs) {\n const rowContainer = this.rowRefs[index];\n if (rowContainer) {\n const errorContainer = rowContainer.querySelector('.editgrid-row-error');\n if (rowErrors.length && errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n const rowError = rowErrors.find(error => error.rowError);\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(rowError ? rowError.message : this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n this.removeClass(errorContainer, 'help-block');\n }\n }\n }\n // If this is a dirty check, and any rows are still editing, we need to throw validation error.\n rowsEditing |= (dirty && this.isOpen(editRow));\n });\n if (allRowErrors.length) {\n if (!silentCheck && (dirty || this.dirty) && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.setCustomValidity(this.t(this.errorMessage('invalidRowsError')), dirty);\n this.removeClass(this.element, 'has-error');\n }\n return false;\n }\n else if (rowsEditing && this.saveEditMode && !this.component.openWhenEmpty) {\n this._errors = this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);\n errors.push(...this._errors);\n return false;\n }\n const message = this.invalid || this.invalidMessage(data, dirty, false, row);\n if (allRowErrors.length && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted) && !message) {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n this.root.showErrors([message]);\n }\n else {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n }\n return superValid;\n }\n setRowInvalid(ref, index) {\n const editRow = this.editRows[index];\n const errorContainer = ref.querySelector('.editgrid-row-error');\n if (errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n changeState(changed, flags) {\n if (this.visible && (changed || (flags.resetValue && this.component.modalEdit))) {\n this.rebuild();\n }\n else {\n this.redraw();\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n value = this.defaultValue;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n return false;\n }\n }\n const changed = this.hasChanged(value, this.dataValue);\n if (this.parent) {\n this.parent.checkComponentConditions();\n }\n this.dataValue = value;\n // Refresh editRow data when data changes.\n this.dataValue.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n editRow.data = row;\n this.restoreRowContext(editRow, flags);\n editRow.state = EditRowState.Saved;\n editRow.backup = null;\n editRow.errors = [];\n }\n else {\n this.editRows[rowIndex] = {\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n errors: [],\n };\n }\n });\n let { length: dataLength } = this.dataValue;\n // If the last row is a new row, then do not remove it.\n if (this.editRows[dataLength] && (this.editRows[dataLength].state === EditRowState.New)) {\n dataLength = (dataLength + 1);\n }\n this.editRows.slice(dataLength).forEach((editRow, index) => this.baseRemoveRow(dataLength + index));\n this.editRows = this.editRows.slice(0, dataLength);\n this.openWhenEmpty();\n this.updateOnChange(flags, changed);\n this.checkData();\n this.changeState(changed, flags);\n return changed;\n }\n openWhenEmpty() {\n const shouldBeOpened = !this.dataValue.length && this.component.openWhenEmpty;\n const hasNoRows = !this.editRows.length;\n if (hasNoRows && shouldBeOpened && !this.builderMode) {\n const dataObj = {};\n this.createRow(dataObj, 0);\n }\n }\n restoreRowContext(editRow, flags = {}) {\n editRow.components.forEach((component) => {\n component.data = editRow.data;\n this.setNestedValue(component, editRow.data, flags);\n });\n }\n emptyRows() {\n this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));\n this.editRows = [];\n }\n resetValue() {\n super.resetValue();\n this.emptyRows();\n }\n}\nexports[\"default\"] = EditGridComponent;\nEditGridComponent.prototype.hasChanged = Component_1.default.prototype.hasChanged;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/editgrid/EditGrid.js?");
|
5175
|
+
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 process_1 = __webpack_require__(/*! @formio/core/process */ \"./node_modules/@formio/core/lib/process/index.js\");\nconst components_1 = __webpack_require__(/*! @formio/bootstrap/components */ \"./node_modules/@formio/bootstrap/lib/cjs/templates/components/index.js\");\nconst NestedArrayComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nestedarray/NestedArrayComponent */ \"./lib/cjs/components/_classes/nestedarray/NestedArrayComponent.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst Alert_1 = __importDefault(__webpack_require__(/*! ../alert/Alert */ \"./lib/cjs/components/alert/Alert.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst EditRowState = {\n New: 'new',\n Editing: 'editing',\n Saved: 'saved',\n Viewing: 'viewing',\n Removed: 'removed',\n Draft: 'draft',\n};\nclass EditGridComponent extends NestedArrayComponent_1.default {\n static schema(...extend) {\n return NestedArrayComponent_1.default.schema({\n type: 'editgrid',\n label: 'Edit Grid',\n key: 'editGrid',\n clearOnHide: true,\n input: true,\n tree: true,\n removeRow: 'Cancel',\n defaultOpen: false,\n openWhenEmpty: false,\n modal: false,\n components: [],\n inlineEdit: false,\n templates: {\n header: EditGridComponent.defaultHeaderTemplate,\n row: EditGridComponent.defaultRowTemplate,\n tableHeader: EditGridComponent.defaultTableHeaderTemplate,\n tableRow: EditGridComponent.defaultTableRowTemplate,\n footer: '',\n },\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Edit Grid',\n icon: 'tasks',\n group: 'data',\n documentation: '/userguide/form-building/data-components#edit-grid',\n showPreview: false,\n weight: 30,\n schema: EditGridComponent.schema(),\n };\n }\n static get defaultHeaderTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">{{ t(component.label) }}</div>\n {% } %}\n {% }) %}\n </div>`;\n }\n static get defaultTableHeaderTemplate() {\n return `\n <tr>\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">{{ component.label }}</td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">Actions</td>\n {% } %}\n </tr>\n `;\n }\n static get defaultRowTemplate() {\n return `<div class=\"row\">\n {% util.eachComponent(components, function(component) { %}\n {% if (displayValue(component)) { %}\n <div class=\"col-sm-2\">\n {{ isVisibleInRow(component) ? getView(component, row[component.key]) : ''}}\n </div>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <div class=\"col-sm-2\">\n <div class=\"btn-group pull-right\">\n <button class=\"btn btn-default btn-light btn-sm editRow\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </div>\n {% } %}\n </div>`;\n }\n static get defaultTableRowTemplate() {\n return `\n {% util.eachComponent(components, function(component) { %}\n {% if (!component.hasOwnProperty('tableView') || component.tableView) { %}\n <td class=\"editgrid-table-column\">\n {{ getView(component, row[component.key]) }}\n </td>\n {% } %}\n {% }) %}\n {% if (!instance.options.readOnly && !instance.disabled) { %}\n <td class=\"editgrid-table-column\">\n <div class=\"btn-group\">\n <button class=\"btn btn-default btn-light btn-sm editRow\" aria-label=\"{{ t('Edit row') }}\"><i class=\"{{ iconClass('edit') }}\"></i></button>\n {% if (!instance.hasRemoveButtons || instance.hasRemoveButtons()) { %}\n <button class=\"btn btn-danger btn-sm removeRow\" aria-label=\"{{ t('Remove row') }}\"><i class=\"{{ iconClass('trash') }}\"></i></button>\n {% } %}\n </div>\n </td>\n {% } %}\n `;\n }\n get defaultDialogTemplate() {\n return `\n <h3 ${this._referenceAttributeName}=\"dialogHeader\">${this.t('wantToClearData')}</h3>\n <div style=\"display:flex; justify-content: flex-end;\">\n <button ${this._referenceAttributeName}=\"dialogCancelButton\" class=\"btn btn-secondary\" aria-label=\"${this.t('cancel')}\">${this.t('cancel')}</button>\n <button ${this._referenceAttributeName}=\"dialogYesButton\" class=\"btn btn-danger\" aria-label=\"${this.t('yesDelete')}\">${this.t('yesDelete')}</button>\n </div>\n `;\n }\n get defaultRowTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableRowTemplate\n : EditGridComponent.defaultRowTemplate;\n }\n get defaultHeaderTemplate() {\n return this.displayAsTable\n ? EditGridComponent.defaultTableHeaderTemplate\n : EditGridComponent.defaultHeaderTemplate;\n }\n get rowTemplate() {\n let rowTemplate;\n if (utils_1.Evaluator.noeval) {\n rowTemplate = this.displayAsTable ?\n components_1.editgrid.tableRow\n : components_1.editgrid.row;\n }\n else {\n rowTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableRow', this.defaultRowTemplate)\n : lodash_1.default.get(this.component, 'templates.row', this.defaultRowTemplate);\n }\n return rowTemplate;\n }\n get headerTemplate() {\n let headerTemplate;\n if (utils_1.Evaluator.noeval) {\n headerTemplate = this.displayAsTable ?\n components_1.editgrid.tableHeader\n : components_1.editgrid.header;\n }\n else {\n headerTemplate = this.displayAsTable ?\n lodash_1.default.get(this.component, 'templates.tableHeader', this.defaultHeaderTemplate)\n : lodash_1.default.get(this.component, 'templates.header', this.defaultHeaderTemplate);\n }\n return headerTemplate;\n }\n /**\n * @returns {boolean} - Returns true if the component has nested components which don't trigger changes on the root level\n */\n get hasScopedChildren() {\n return !this.inlineEditMode;\n }\n get defaultSchema() {\n return EditGridComponent.schema();\n }\n get emptyValue() {\n return [];\n }\n get editgridKey() {\n return `editgrid-${this.key}`;\n }\n get rowRef() {\n return `${this.editgridKey}-row`;\n }\n get rowElements() {\n return this.refs[this.rowRef];\n }\n get rowRefs() {\n return this.refs[`editgrid-${this.component.key}-row`];\n }\n get addRowRef() {\n return `${this.editgridKey}-addRow`;\n }\n get addRowElements() {\n return this.refs[this.addRowRef];\n }\n get saveRowRef() {\n return `${this.editgridKey}-saveRow`;\n }\n get saveRowElements() {\n return this.refs[this.saveRowRef];\n }\n get cancelRowRef() {\n return `${this.editgridKey}-cancelRow`;\n }\n get cancelRowElements() {\n return this.refs[this.cancelRowRef];\n }\n get inlineEditMode() {\n return this.component.inlineEdit;\n }\n get saveEditMode() {\n return !this.inlineEditMode;\n }\n get minLength() {\n return this.builderMode ? 0 : lodash_1.default.get(this.component, 'validate.minLength', 0);\n }\n get data() {\n return this._data;\n }\n get dataValue() {\n return super.dataValue || [];\n }\n set dataValue(value) {\n super.dataValue = value;\n }\n get displayAsTable() {\n return this.component.displayAsTable;\n }\n set data(value) {\n this._data = value;\n const data = this.dataValue;\n (this.editRows || []).forEach((row, index) => {\n if (!data[index] && row.state !== EditRowState.New) {\n data[index] = {};\n }\n const rowData = data[index] || {};\n row.data = rowData;\n row.components.forEach((component) => {\n component.data = rowData;\n });\n });\n }\n get iteratableRows() {\n return this.editRows;\n }\n get defaultValue() {\n const value = super.defaultValue;\n const defaultValue = Array.isArray(value) ? value : [];\n lodash_1.default.times(this.minLength - defaultValue.length, () => defaultValue.push({}));\n return defaultValue;\n }\n constructor(...args) {\n super(...args);\n this.type = 'editgrid';\n }\n hasRemoveButtons() {\n return !this.component.disableAddingRemovingRows &&\n !this.options.readOnly &&\n !this.disabled &&\n this.fullMode &&\n (this.dataValue.length > lodash_1.default.get(this.component, 'validate.minLength', 0));\n }\n init() {\n if (this.builderMode) {\n this.editRows = [];\n return super.init();\n }\n this.components = this.components || [];\n const dataValue = this.dataValue;\n const openWhenEmpty = !dataValue.length && this.component.openWhenEmpty;\n if (openWhenEmpty) {\n const dataObj = {};\n this.editRows = [];\n this.createRow(dataObj, 0);\n }\n else {\n this.editRows = dataValue.map((row, rowIndex) => ({\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n error: null,\n rowIndex,\n }));\n }\n this.prevHasAddButton = this.hasAddButton();\n this.checkData();\n this.setVariableTypeComponents();\n if (this.variableTypeComponentsIndexes.length) {\n lodash_1.default.each(this.editRows || [], (editRow, rowIndex) => this.checkRowVariableTypeComponents(editRow, rowIndex));\n }\n }\n checkRowVariableTypeComponents(editRow, rowIndex) {\n const rowComponents = editRow.components;\n let typeChanged = false;\n if (lodash_1.default.some(this.variableTypeComponentsIndexes, (compIndex) => {\n const variableTypeComp = rowComponents[compIndex];\n return variableTypeComp.type !== variableTypeComp.component.type;\n })) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex, true);\n typeChanged = true;\n }\n return typeChanged;\n }\n setVariableTypeComponents() {\n //set components which type is changing within a row (e.g.,by mergeComponentSchema action)\n this.variableTypeComponentsIndexes = [];\n lodash_1.default.each(this.component.components, (comp, index) => {\n if (comp.typeChangeEnabled) {\n this.variableTypeComponentsIndexes.push(index);\n }\n });\n }\n isOpen(editRow) {\n return [EditRowState.New, EditRowState.Editing, EditRowState.Viewing].includes(editRow.state);\n }\n isComponentVisibleInSomeRow(component) {\n const rows = this.editRows;\n const savedStates = [EditRowState.Saved, EditRowState.Editing, EditRowState.Draft];\n const savedRows = rows.filter(row => lodash_1.default.includes(savedStates, row.state));\n this.visibleInHeader = this.visibleInHeader || [];\n const changeVisibleInHeader = (component, isVisible) => {\n if (!isVisible) {\n lodash_1.default.remove(this.visibleInHeader, (key) => key === component.key);\n }\n if (isVisible && !lodash_1.default.includes(this.visibleInHeader, component.key)) {\n this.visibleInHeader.push(component.key);\n }\n };\n if (lodash_1.default.isEmpty(rows)) {\n const rowComponents = this.createRowComponents({}, 0);\n let checkComponent;\n (0, utils_1.eachComponent)(rowComponents, (comp) => {\n if (comp.component.key === component.key) {\n checkComponent = comp;\n }\n comp.checkConditions();\n });\n const isVisible = checkComponent ? checkComponent.visible : true;\n [...this.components].forEach((comp) => this.removeComponent(comp, this.components));\n changeVisibleInHeader(component, isVisible);\n return isVisible;\n }\n const isOpenRowWhenEmpty = lodash_1.default.get(this.component, 'openWhenEmpty') && rows.length === 1 && rows[0].state === EditRowState.New;\n if (!lodash_1.default.isEmpty(rows) && lodash_1.default.isEmpty(savedRows) && !isOpenRowWhenEmpty) {\n return lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return lodash_1.default.some(isOpenRowWhenEmpty ? rows : savedRows, (row, index) => {\n const editingRow = row.state === EditRowState.Editing;\n let isVisible;\n if (!editingRow) {\n const flattenedComponents = this.flattenComponents(index);\n const instance = flattenedComponents[component.key];\n isVisible = instance ? instance.visible : true;\n changeVisibleInHeader(component, isVisible);\n }\n else {\n isVisible = lodash_1.default.includes(this.visibleInHeader, component.key);\n }\n return isVisible;\n });\n }\n render(children) {\n if (this.builderMode) {\n return super.render();\n }\n const dataValue = this.dataValue;\n const headerTemplate = this.headerTemplate;\n const t = this.t.bind(this);\n const templateName = this.displayAsTable ? 'editgridTable' : 'editgrid';\n return super.render(children || this.renderTemplate(templateName, {\n ref: {\n row: this.rowRef,\n addRow: this.addRowRef,\n saveRow: this.saveRowRef,\n cancelRow: this.cancelRowRef,\n },\n header: this.renderString(headerTemplate, {\n displayValue: (component) => this.displayComponentValue(component, true),\n components: this.component.components,\n value: dataValue,\n t\n }),\n footer: this.renderString(lodash_1.default.get(this.component, 'templates.footer'), {\n components: this.component.components,\n value: dataValue,\n t\n }),\n rows: this.editRows.map(this.renderRow.bind(this)),\n openRows: this.editRows.map((row) => this.isOpen(row)),\n errors: this.editRows.map((row) => row.error),\n hasAddButton: this.hasAddButton(),\n hasRemoveButtons: this.hasRemoveButtons(),\n }));\n }\n renderComponents(components) {\n components = components || this.getComponents();\n const children = components.map(component => component.render());\n const templateName = this.displayAsTable && this.prevHasAddButton ? 'tableComponents' : 'components';\n return this.renderTemplate(templateName, {\n children,\n components,\n });\n }\n attach(element) {\n if (this.builderMode) {\n return super.attach(element);\n }\n this.loadRefs(element, {\n [this.addRowRef]: 'multiple',\n [this.saveRowRef]: 'multiple',\n [this.cancelRowRef]: 'multiple',\n [this.rowRef]: 'multiple',\n });\n this.addRowElements.forEach((addButton) => {\n this.addEventListener(addButton, 'click', () => this.addRow());\n });\n let openRowCount = 0;\n this.rowElements.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow === null || editRow === void 0 ? void 0 : editRow.isRowSelected) {\n row.classList.add('selected');\n }\n if (this.isOpen(editRow)) {\n this.attachComponents(row, editRow.components);\n this.addEventListener(this.saveRowElements[openRowCount], 'click', () => this.saveRow(rowIndex, true));\n this.addEventListener(this.cancelRowElements[openRowCount], 'click', () => this.cancelRow(rowIndex));\n openRowCount++;\n }\n else {\n // Attach edit and remove button events.\n [\n {\n className: 'removeRow',\n event: 'click',\n action: () => this.removeRow(rowIndex, true),\n },\n {\n className: 'editRow',\n event: 'click',\n action: () => {\n this.editRow(rowIndex).then(() => {\n var _a;\n if (this.component.rowDrafts) {\n const errors = this.validateRow(editRow, false);\n const shouldShowRowErrorsAlert = this.component.modal && errors.length && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted);\n if (shouldShowRowErrorsAlert) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n }\n });\n },\n },\n {\n className: 'row',\n event: 'click',\n action: () => {\n row.classList.toggle('selected');\n let eventName = 'editGridSelectRow';\n if (Array.from(row.classList).includes('selected')) {\n editRow.isRowSelected = true;\n }\n else {\n delete editRow.isRowSelected;\n eventName = 'editGridUnSelectRow';\n }\n this.emit(eventName, {\n component: this.component,\n data: this.dataValue[rowIndex]\n });\n },\n }\n ].forEach(({ className, event, action, }) => {\n const elements = row.getElementsByClassName(className);\n Array.prototype.forEach.call(elements, (element) => {\n if (this.options.pdf && lodash_1.default.intersection(element.classList, ['editRow', 'removeRow']).length) {\n element.style.display = 'none';\n }\n else {\n this.addEventListener(element, event, action);\n }\n });\n });\n }\n });\n // Add open class to the element if any edit grid row is open\n if (openRowCount) {\n this.addClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n else {\n this.removeClass(this.refs.component, `formio-component-${this.component.type}-row-open`);\n }\n return super.attach(element);\n }\n flattenRowDataValue(dataValue) {\n const flattened = {};\n Object.keys(dataValue).forEach((key) => {\n if (lodash_1.default.isObject(dataValue[key]) && !lodash_1.default.isNil(dataValue[key])) {\n Object.assign(flattened, this.flattenRowDataValue(dataValue[key]));\n }\n else {\n flattened[key] = dataValue[key];\n }\n });\n return flattened;\n }\n isComponentVisibleInRow(component, flattenedComponents) {\n const instance = flattenedComponents[component.key];\n return instance ? instance.visible : true;\n }\n displayComponentValue(component, header) {\n return !!((!component.hasOwnProperty('tableView') || component.tableView)\n && header ? this.isComponentVisibleInSomeRow(component) : lodash_1.default.includes(this.visibleInHeader, component.key));\n }\n renderRow(row, rowIndex) {\n const dataValue = this.dataValue;\n if (this.isOpen(row)) {\n return this.renderComponents(row.components);\n }\n else {\n const flattenedComponents = this.flattenComponents(rowIndex);\n const rowTemplate = this.rowTemplate;\n return this.renderString(rowTemplate, {\n row: dataValue[rowIndex] || {},\n data: this.data,\n rowIndex,\n components: this.component.components,\n flattenedComponents,\n displayValue: (component) => this.displayComponentValue(component),\n isVisibleInRow: (component) => this.isComponentVisibleInRow(component, flattenedComponents),\n getView: (component, data) => {\n var _a, _b;\n const instance = flattenedComponents[component.key];\n const view = instance ? instance.getView(data || instance.dataValue) : '';\n // If there is an html tag in view, don't allow it to be injected in template\n const htmlTagRegExp = new RegExp('<(.*?)>');\n return typeof view === 'string' && view.length && !((_a = instance.component) === null || _a === void 0 ? void 0 : _a.template) && htmlTagRegExp.test(view) && ((_b = instance.component) === null || _b === void 0 ? void 0 : _b.inputFormat) !== 'html'\n ? `<input type=\"text\" value=\"${view.replace(/\"/g, '"')}\" readonly/>`\n : view;\n },\n state: this.editRows[rowIndex].state,\n t: this.t.bind(this)\n });\n }\n }\n eachComponent(fn, rowIndex) {\n lodash_1.default.each(this.getComponents(rowIndex), (component, index) => {\n if (fn(component, index) === false) {\n return false;\n }\n });\n }\n restoreComponentsContext() {\n this.getComponents().forEach((component) => {\n var _a;\n const rowData = this.dataValue[component.rowIndex];\n const editRowData = (_a = this.editRows[component.rowIndex]) === null || _a === void 0 ? void 0 : _a.data;\n component.data = rowData || editRowData;\n });\n }\n flattenComponents(rowIndex) {\n const result = {};\n this.everyComponent((component) => {\n result[component.component.flattenAs || component.key] = component;\n }, rowIndex);\n return result;\n }\n getComponents(rowIndex) {\n var _a;\n // Ensure editrows is set.\n this.editRows = this.editRows || [];\n return this.builderMode\n ? super.getComponents()\n : lodash_1.default.isNumber(rowIndex)\n ? (((_a = this.editRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.components) || [])\n : this.editRows.reduce((result, row) => result.concat(row.components || []), []);\n }\n destroy(all = false) {\n this.calculatedValue = undefined;\n super.destroy(all);\n }\n destroyComponents(all = false, rowIndex = 0) {\n if (this.builderMode) {\n return super.destroyComponents(all);\n }\n const components = this.getComponents(rowIndex).slice();\n components.forEach((comp) => this.removeComponent(comp, this.components, all));\n }\n createRow(dataObj, rowIndex) {\n const editRow = {\n components: this.createRowComponents(dataObj, rowIndex),\n data: dataObj,\n state: EditRowState.New,\n backup: null,\n error: null,\n rowIndex,\n };\n this.editRows.push(editRow);\n if (this.inlineEditMode) {\n this.dataValue.push(dataObj);\n }\n return editRow;\n }\n addRow() {\n if (this.options.readOnly) {\n return;\n }\n const dataObj = {};\n const rowIndex = this.editRows.length;\n const editRow = this.createRow(dataObj, rowIndex);\n if (editRow.state === EditRowState.New) {\n this.emptyRow = (0, utils_1.fastCloneDeep)(editRow.data);\n }\n if (this.inlineEditMode) {\n this.triggerChange();\n }\n this.emit('editGridAddRow', {\n component: this.component,\n row: editRow,\n });\n this.processRow('checkData', null, {}, editRow.data, editRow.components);\n if (this.component.modal) {\n this.addRowModal(rowIndex);\n }\n else {\n this.redraw();\n }\n return editRow;\n }\n addRowModal(rowIndex) {\n const modalContent = this.ce('div');\n const editRow = this.editRows[rowIndex];\n editRow.willBeSaved = false;\n const { components } = editRow;\n modalContent.innerHTML = this.renderComponents(components);\n const dialog = this.component.modal ? this.createModal(modalContent, {}, () => this.showDialog(rowIndex)) : undefined;\n dialog.classList.add(`editgrid-row-modal-${this.id}`);\n editRow.dialog = dialog;\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n this.alert = new Alert_1.default(dialog.refs.dialogContents, this);\n this.addEventListener(dialog, 'close', () => {\n if (!editRow.willBeSaved) {\n if (this.editRows[rowIndex] && this.editRows[rowIndex].state !== EditRowState.New) {\n this.editRows[rowIndex].components.forEach((comp) => {\n comp.setPristine(true);\n });\n }\n this.cancelRow(rowIndex);\n }\n if (this.alert) {\n this.alert.clear();\n this.alert = null;\n }\n // Remove references to dialog elements to prevent possible in some cases memory leaks\n delete editRow.confirmationDialog;\n delete editRow.dialog;\n });\n dialog.refs.dialogContents.appendChild(this.ce('button', {\n class: 'btn btn-primary',\n onClick: () => {\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!errors.length || this.component.rowDrafts) {\n editRow.willBeSaved = true;\n dialog.close();\n this.saveRow(rowIndex, true);\n }\n else {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n },\n }, this.component.saveRow || 'Save'));\n this.emit('editGridOpenModal', {\n component: this.component,\n row: editRow,\n instance: this,\n });\n return this.attachComponents(modalContent, components);\n }\n showDialog(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow.state === EditRowState.New ? lodash_1.default.isEqual(this.emptyRow, editRow.data) : lodash_1.default.isEqual(editRow.backup, editRow.data)) {\n return Promise.resolve();\n }\n const wrapper = this.ce('div', { ref: 'confirmationDialog' });\n const dialogContent = this.component.dialogTemplate || this.defaultDialogTemplate;\n wrapper.innerHTML = dialogContent;\n wrapper.refs = {};\n this.loadRefs.call(wrapper, wrapper, {\n dialogHeader: 'single',\n dialogCancelButton: 'single',\n dialogYesButton: 'single',\n });\n const dialog = this.createModal(wrapper);\n dialog.classList.add(`editgrid-row-modal-confirmation-${this.id}`);\n const close = (event) => {\n event.preventDefault();\n dialog.close();\n };\n let dialogResult;\n const promise = new Promise((resolve, reject) => {\n dialogResult = { resolve, reject };\n });\n this.addEventListener(wrapper.refs.dialogYesButton, 'click', (event) => {\n close(event);\n dialogResult.resolve();\n });\n this.addEventListener(wrapper.refs.dialogCancelButton, 'click', (event) => {\n close(event);\n dialogResult.reject();\n });\n editRow.confirmationDialog = dialog;\n return promise;\n }\n editRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n const isAlreadyEditing = editRow.state === EditRowState.Editing || editRow.state === EditRowState.New;\n if (!editRow || isAlreadyEditing) {\n return Promise.resolve();\n }\n editRow.prevState = editRow.state;\n editRow.state = this.options.readOnly ? EditRowState.Viewing : EditRowState.Editing;\n if (this.lazyLoad && (editRow.components.length === 0)) {\n editRow.components = this.createRowComponents(editRow.data, rowIndex);\n }\n const dataSnapshot = (0, utils_1.fastCloneDeep)(editRow.data);\n if (this.inlineEditMode) {\n editRow.backup = dataSnapshot;\n }\n else {\n editRow.backup = (0, utils_1.fastCloneDeep)(editRow.data);\n editRow.data = dataSnapshot;\n this.restoreRowContext(editRow);\n }\n this.emit('editGridEditRow', {\n component: this.component,\n row: editRow,\n instance: this,\n });\n if (this.component.modal) {\n return this.addRowModal(rowIndex);\n }\n return this.redraw();\n }\n clearErrors(rowIndex) {\n const editRow = this.editRows[rowIndex];\n if (editRow && Array.isArray(editRow.components)) {\n editRow.components.forEach((comp) => {\n comp.setPristine(true);\n comp.setCustomValidity('');\n });\n }\n }\n cancelRow(rowIndex) {\n if (this.options.readOnly) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n switch (editRow.state) {\n case EditRowState.New: {\n editRow.state = EditRowState.Removed;\n this.clearErrors(rowIndex);\n this.destroyComponents(false, rowIndex);\n if (this.inlineEditMode) {\n this.splice(rowIndex);\n }\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n break;\n }\n case EditRowState.Editing: {\n editRow.state = editRow.prevState;\n if (this.inlineEditMode) {\n this.dataValue[rowIndex] = editRow.backup;\n }\n editRow.data = editRow.backup;\n editRow.backup = null;\n this.restoreRowContext(editRow);\n this.clearErrors(rowIndex);\n break;\n }\n }\n this.emit('editGridCancelRow', {\n instance: this,\n component: this.component,\n editRow,\n });\n this.checkValidity(null, true);\n this.redraw();\n if (this.component.rowDrafts) {\n this.checkValidity(this.data, false);\n }\n }\n saveRow(rowIndex, modified) {\n var _a, _b;\n const editRow = this.editRows[rowIndex];\n if (this.options.readOnly) {\n return;\n }\n // After an attempt to save, all the components inside the row should become not pristine\n if (!this.component.rowDrafts) {\n editRow.components.forEach((comp) => comp.setPristine(false));\n }\n const errors = this.validateRow(editRow, true);\n if (!this.component.rowDrafts) {\n if (errors.length) {\n return false;\n }\n }\n if (this.saveEditMode) {\n const dataValue = this.dataValue;\n if ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.focusedComponent) === null || _b === void 0 ? void 0 : _b.component.typeChangeEnabled) {\n this.root.focusedComponent = null;\n }\n switch (editRow.state) {\n case EditRowState.New: {\n const newIndex = dataValue.length;\n dataValue.push(editRow.data);\n editRow.components.forEach(component => component.rowIndex = newIndex);\n if (rowIndex !== newIndex) {\n this.editRows.splice(rowIndex, 1);\n this.editRows.splice(newIndex, 0, editRow);\n }\n break;\n }\n case EditRowState.Editing: {\n dataValue[rowIndex] = editRow.data;\n break;\n }\n }\n }\n editRow.state = this.component.rowDrafts && errors.length ? EditRowState.Draft : EditRowState.Saved;\n editRow.backup = null;\n this.updateValue();\n this.emit('editGridSaveRow', {\n component: this.component,\n row: editRow.data,\n instance: this\n });\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n if (this.component.rowDrafts) {\n editRow.components.forEach(comp => comp.setPristine(this.pristine));\n }\n this.checkValidity(null, true);\n this.redraw();\n if (editRow.alerts) {\n editRow.alerts = false;\n }\n return true;\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const relativePath = this.getRelativePath(component.path);\n const arrayPath = (0, utils_1.getArrayFromComponentPath)(relativePath);\n const rowIndex = arrayPath[0];\n let rowToEditIndex = arrayPath[0];\n this.editRows.forEach((row, indexInArray) => {\n if (row.rowIndex === rowIndex) {\n rowToEditIndex = indexInArray;\n }\n });\n if (lodash_1.default.isNumber(rowToEditIndex)) {\n this.editRow(rowToEditIndex);\n }\n }\n updateComponentsRowIndex(components, rowIndex) {\n components.forEach((component, colIndex) => {\n component.rowIndex = rowIndex;\n component.row = `${rowIndex}-${colIndex}`;\n });\n }\n updateRowsComponents(rowIndex) {\n this.editRows.slice(rowIndex).forEach((row, index) => {\n this.updateComponentsRowIndex(row.components, rowIndex + index);\n });\n }\n baseRemoveRow(rowIndex) {\n const editRow = this.editRows[rowIndex];\n editRow.state = EditRowState.Removed;\n this.destroyComponents(false, rowIndex);\n return editRow;\n }\n removeRow(rowIndex, modified) {\n if (this.options.readOnly) {\n return;\n }\n this.clearErrors(rowIndex);\n this.baseRemoveRow(rowIndex);\n this.removeSubmissionMetadataRow(rowIndex);\n this.splice(rowIndex);\n this.emit('editGridDeleteRow', {\n index: rowIndex\n });\n this.editRows.splice(rowIndex, 1);\n this.openWhenEmpty();\n this.updateRowsComponents(rowIndex);\n this.updateValue();\n this.triggerChange({ modified, noPristineChangeOnModified: modified && this.component.rowDrafts, isolateRow: true });\n this.checkValidity(null, true);\n this.checkData();\n this.redraw();\n }\n createRowComponents(row, rowIndex, recreatePartially) {\n // Iterate through existing components and destroy the ones with the same rowIndex.\n if (this.components) {\n for (let i = 0; i < this.components.length; i++) {\n if (this.components[i].rowIndex === rowIndex) {\n this.components[i].destroy();\n this.components.splice(i, 1);\n }\n }\n }\n const currentRowComponents = lodash_1.default.get(this.editRows, `[${rowIndex}].components`, null);\n return this.component.components.map((col, colIndex) => {\n var _a;\n if (recreatePartially && currentRowComponents && this.variableTypeComponentsIndexes.length) {\n const currentComp = currentRowComponents[colIndex];\n const shouldRecreate = lodash_1.default.includes(this.variableTypeComponentsIndexes, colIndex) && (currentComp === null || currentComp === void 0 ? void 0 : currentComp.type) !== ((_a = currentComp === null || currentComp === void 0 ? void 0 : currentComp.component) === null || _a === void 0 ? void 0 : _a.type);\n if (!shouldRecreate) {\n return currentComp;\n }\n col = currentComp.component;\n }\n const column = lodash_1.default.clone(col);\n const options = lodash_1.default.clone(this.options);\n options.name += `[${rowIndex}]`;\n options.row = `${rowIndex}-${colIndex}`;\n options.rowIndex = rowIndex;\n options.onChange = (flags = {}, changed, modified) => {\n var _a, _b;\n if (((_a = changed.instance.root) === null || _a === void 0 ? void 0 : _a.id) && (((_b = this.root) === null || _b === void 0 ? void 0 : _b.id) !== changed.instance.root.id)) {\n changed.instance.root.triggerChange(flags, changed, modified);\n }\n else if (!this.component.modal) {\n this.triggerRootChange(flags, changed, modified);\n }\n if (this.inlineEditMode) {\n return;\n }\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n this.processRow('checkData', null, Object.assign(Object.assign({}, flags), { changed }), editRow.data, editRow.components);\n this.validateRow(editRow, false, false);\n }\n if (this.variableTypeComponentsIndexes.length) {\n const typeChanged = this.checkRowVariableTypeComponents(editRow, rowIndex);\n if (typeChanged) {\n this.redraw();\n }\n }\n };\n const comp = this.createComponent(lodash_1.default.assign({}, column, { row: options.row }), options, row, null, recreatePartially && currentRowComponents ? currentRowComponents[colIndex] : null);\n comp.rowIndex = rowIndex;\n comp.inEditGrid = true;\n return comp;\n });\n }\n hasOpenRows() {\n return this.editRows.some(row => this.isOpen(row));\n }\n getAttachedData(data = null) {\n const ourData = (0, utils_1.fastCloneDeep)(data || this._data || this.rootValue);\n lodash_1.default.set(ourData, this.key, this.editRows.map((row) => row.data));\n return ourData;\n }\n shouldValidateDraft(editRow) {\n var _a, _b;\n // Draft rows should be validated only when there was an attempt to submit a form\n return (editRow.state === EditRowState.Draft &&\n !this.pristine &&\n !((_a = this.root) === null || _a === void 0 ? void 0 : _a.pristine) &&\n !this.hasOpenRows()) ||\n ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted);\n }\n shouldValidateRow(editRow, dirty, fromSubmission) {\n return this.shouldValidateDraft(editRow) ||\n editRow.state === EditRowState.New ||\n editRow.state === EditRowState.Editing ||\n editRow.alerts ||\n fromSubmission ||\n dirty;\n }\n validateRow(editRow, dirty, forceSilentCheck, fromSubmission) {\n var _a, _b;\n editRow.errors = [];\n if (this.shouldValidateRow(editRow, dirty, fromSubmission)) {\n const silentCheck = forceSilentCheck === false ? false : ((this.component.rowDrafts && !this.shouldValidateDraft(editRow)) || forceSilentCheck);\n const rootValue = (0, utils_1.fastCloneDeep)(this.rootValue);\n const editGridValue = lodash_1.default.get(rootValue, this.path, []);\n editGridValue[editRow.rowIndex] = editRow.data;\n lodash_1.default.set(rootValue, this.path, editGridValue);\n const validationProcessorProcess = (context) => this.validationProcessor(context, { dirty, silentCheck });\n const errors = (0, process_1.processSync)({\n components: this.component.components,\n data: rootValue,\n row: editRow.data,\n process: 'validateRow',\n instances: this.componentsMap,\n scope: { errors: [] },\n parent: this.component,\n parentPaths: Object.assign(Object.assign({}, this.paths), { dataIndex: editRow.rowIndex }),\n processors: [\n {\n process: validationProcessorProcess,\n processSync: validationProcessorProcess\n }\n ]\n }).errors;\n editRow.errors = (this.component.modal || this.component.rowDrafts)\n ? errors\n : errors.filter((err) => lodash_1.default.find(this.visibleErrors, ['component.id', err.component.id]));\n }\n // TODO: this is essentially running its own custom validation and should be moved into a validation rule\n if (this.component.validate && this.component.validate.row) {\n const valid = this.evaluate(this.component.validate.row, {\n valid: (editRow.length === 0),\n row: editRow.data\n }, 'valid', true);\n if (valid.toString() !== 'true') {\n editRow.errors.push({\n type: 'error',\n rowError: true,\n message: valid.toString()\n });\n }\n if (valid === null) {\n editRow.errors.push({\n type: 'error',\n message: this.t('componentInvalidRowValidation', { componentKey: this.key })\n });\n }\n }\n if (editRow.alerts && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.showRowErrorAlerts(editRow, editRow.errors);\n }\n else if ((_b = editRow.errors) === null || _b === void 0 ? void 0 : _b.length) {\n this.setCustomValidity(editRow.errors, dirty);\n }\n return editRow.errors;\n }\n showRowErrorAlerts(editRow, errors) {\n if (editRow.alerts) {\n if (this.alert) {\n if (errors.length) {\n this.alert.showErrors(errors, false);\n editRow.alerts = true;\n }\n else {\n this.alert.clear();\n this.alert = null;\n }\n }\n }\n }\n /**\n * @returns {boolean} - Return that this component processes its own validation.\n */\n get processOwnValidation() {\n return true;\n }\n checkComponentValidity(data, dirty, row, options = {}, errors = []) {\n var _a, _b;\n const { silentCheck, fromSubmission } = options;\n const superValid = super.checkComponentValidity(data, dirty, row, options, errors);\n // If super tells us that component invalid and there is no need to update alerts, just return false\n if (!superValid && (!this.alert && !this.hasOpenRows())) {\n return false;\n }\n let rowsEditing = false;\n const allRowErrors = [];\n this.editRows.forEach((editRow, index) => {\n // Trigger all errors on the row.\n const rowErrors = this.validateRow(editRow, dirty, silentCheck, fromSubmission);\n errors.push(...rowErrors);\n allRowErrors.push(...rowErrors);\n if (this.rowRefs) {\n const rowContainer = this.rowRefs[index];\n if (rowContainer) {\n const errorContainer = rowContainer.querySelector('.editgrid-row-error');\n if (rowErrors.length && errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n const rowError = rowErrors.find(error => error.rowError);\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(rowError ? rowError.message : this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n this.removeClass(errorContainer, 'help-block');\n }\n }\n }\n // If this is a dirty check, and any rows are still editing, we need to throw validation error.\n rowsEditing |= (dirty && this.isOpen(editRow));\n });\n if (allRowErrors.length) {\n if (!silentCheck && (dirty || this.dirty) && (!this.component.rowDrafts || ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submitted))) {\n this.setCustomValidity(this.t(this.errorMessage('invalidRowsError')), dirty);\n this.removeClass(this.element, 'has-error');\n }\n return false;\n }\n else if (rowsEditing && this.saveEditMode && !this.component.openWhenEmpty) {\n this._errors = this.setCustomValidity(this.t(this.errorMessage('unsavedRowsError')), dirty);\n errors.push(...this._errors);\n return false;\n }\n const message = this.invalid || this.invalidMessage(data, dirty, false, row);\n if (allRowErrors.length && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submitted) && !message) {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n this.root.showErrors([message]);\n }\n else {\n this._errors = this.setCustomValidity(message, dirty);\n errors.push(...this._errors);\n }\n return superValid;\n }\n setRowInvalid(ref, index) {\n const editRow = this.editRows[index];\n const errorContainer = ref.querySelector('.editgrid-row-error');\n if (errorContainer && (!this.component.rowDrafts || this.shouldValidateDraft(editRow))) {\n this.addClass(errorContainer, 'help-block');\n errorContainer.textContent = this.t(this.errorMessage('invalidRowError'));\n }\n else if (errorContainer) {\n errorContainer.textContent = '';\n }\n }\n changeState(changed, flags) {\n if (this.visible && (changed || (flags.resetValue && this.component.modalEdit))) {\n this.rebuild();\n }\n else {\n this.redraw();\n }\n }\n setValue(value, flags = {}) {\n if (!value) {\n value = this.defaultValue;\n }\n if (!Array.isArray(value)) {\n if (typeof value === 'object') {\n value = [value];\n }\n else {\n return false;\n }\n }\n const changed = this.hasChanged(value, this.dataValue);\n this.dataValue = value;\n // Refresh editRow data when data changes.\n this.dataValue.forEach((row, rowIndex) => {\n const editRow = this.editRows[rowIndex];\n if (editRow) {\n editRow.data = row;\n this.restoreRowContext(editRow, flags);\n editRow.state = EditRowState.Saved;\n editRow.backup = null;\n editRow.errors = [];\n }\n else {\n this.editRows[rowIndex] = {\n components: this.lazyLoad ? [] : this.createRowComponents(row, rowIndex),\n data: row,\n state: EditRowState.Saved,\n backup: null,\n errors: [],\n };\n }\n });\n let { length: dataLength } = this.dataValue;\n // If the last row is a new row, then do not remove it.\n if (this.editRows[dataLength] && (this.editRows[dataLength].state === EditRowState.New)) {\n dataLength = (dataLength + 1);\n }\n this.editRows.slice(dataLength).forEach((editRow, index) => this.baseRemoveRow(dataLength + index));\n this.editRows = this.editRows.slice(0, dataLength);\n this.openWhenEmpty();\n this.updateOnChange(flags, changed);\n this.changeState(changed, flags);\n return changed;\n }\n openWhenEmpty() {\n const shouldBeOpened = !this.dataValue.length && this.component.openWhenEmpty;\n const hasNoRows = !this.editRows.length;\n if (hasNoRows && shouldBeOpened && !this.builderMode) {\n const dataObj = {};\n this.createRow(dataObj, 0);\n }\n }\n restoreRowContext(editRow, flags = {}) {\n editRow.components.forEach((component) => {\n component.data = editRow.data;\n this.setNestedValue(component, editRow.data, flags);\n });\n }\n emptyRows() {\n this.editRows.forEach((editRow, index) => this.destroyComponents(false, index));\n this.editRows = [];\n }\n resetValue() {\n super.resetValue();\n this.emptyRows();\n }\n}\nexports[\"default\"] = EditGridComponent;\nEditGridComponent.prototype.hasChanged = Component_1.default.prototype.hasChanged;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/editgrid/EditGrid.js?");
|
5176
5176
|
|
5177
5177
|
/***/ }),
|
5178
5178
|
|
@@ -5216,7 +5216,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
5216
5216
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5217
5217
|
|
5218
5218
|
"use strict";
|
5219
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* eslint-disable max-statements */\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../_classes/componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nclass FormComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'Form',\n type: 'form',\n key: 'form',\n src: '',\n reference: true,\n form: '',\n path: '',\n tableView: true,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Nested Form',\n icon: 'wpforms',\n group: 'premium',\n documentation: '/userguide/form-building/premium-components#nested-form',\n weight: 110,\n schema: FormComponent.schema()\n };\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.object];\n }\n init() {\n super.init();\n this.formObj = {\n display: this.component.display,\n settings: this.component.settings,\n components: this.component.components\n };\n this.valueChanged = false;\n this.subForm = null;\n this.formSrc = '';\n if (this.component.src) {\n this.formSrc = this.component.src;\n }\n if (!this.component.src &&\n !this.options.formio &&\n (this.component.form || this.component.path)) {\n if (this.component.project) {\n this.formSrc = Formio_1.Formio.getBaseUrl();\n // Check to see if it is a MongoID.\n if ((0, utils_1.isMongoId)(this.component.project)) {\n this.formSrc += '/project';\n }\n this.formSrc += `/${this.component.project}`;\n this.options.project = this.formSrc;\n }\n else {\n this.formSrc = Formio_1.Formio.getProjectUrl();\n this.options.project = this.formSrc;\n }\n if (this.component.form) {\n if ((0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc += `/form/${this.component.form}`;\n }\n else {\n this.formSrc += `/${this.component.form}`;\n }\n }\n else if (this.component.path) {\n this.formSrc += `/${this.component.path}`;\n }\n }\n // Build the source based on the root src path.\n if (!this.formSrc && this.options.formio) {\n const rootSrc = this.options.formio.formsUrl;\n if (this.component.form && (0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc = `${rootSrc}/${this.component.form}`;\n }\n else {\n const formPath = this.component.path || this.component.form;\n this.formSrc = `${rootSrc.replace(/\\/form$/, '')}/${formPath}`;\n }\n }\n if (this.builderMode && this.component.hasOwnProperty('formRevision')) {\n this.component.revision = this.component.formRevision;\n delete this.component.formRevision;\n }\n // Add revision version if set.\n if (this.component.revision || this.component.revision === 0 ||\n this.component.formRevision || this.component.formRevision === 0\n || this.component.revisionId) {\n this.setFormRevision(this.component.revisionId || this.component.revision || this.component.formRevision);\n }\n return this.createSubForm();\n }\n get dataReady() {\n return this.subFormReady || Promise.resolve();\n }\n get defaultValue() {\n // Not not provide a default value unless the subform is ready so that it will initialize correctly.\n return this.subForm ? super.defaultValue : null;\n }\n get defaultSchema() {\n return FormComponent.schema();\n }\n get emptyValue() {\n return { data: {} };\n }\n get ready() {\n return this.subFormReady || Promise.resolve();\n }\n get useOriginalRevision() {\n var _a, _b;\n return ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && !!((_b = this.formObj) === null || _b === void 0 ? void 0 : _b.revisions);\n }\n setFormRevision(rev) {\n // Remove current revisions from src if it is\n this.formSrc = this.formSrc.replace(/\\/v\\/[0-9a-z]+/, '');\n const revNumber = Number.parseInt(rev);\n if (!isNaN(revNumber)) {\n this.subFormRevision = rev;\n this.formSrc += `/v/${rev}`;\n }\n else {\n this.subFormRevision = undefined;\n }\n }\n getComponent(path) {\n if (!this.subForm) {\n return null;\n }\n return this.subForm.getComponent(path);\n }\n /* eslint-disable max-statements */\n getSubOptions(options = {}) {\n options.events = this.createEmitter();\n // Make sure to not show the submit button in wizards in the nested forms.\n lodash_1.default.set(options, 'buttonSettings.showSubmit', false);\n // Set the parent option to the subform so those references are stable when the subform is created\n options.parent = this;\n if (!this.options) {\n return options;\n }\n if (this.options.base) {\n options.base = this.options.base;\n }\n if (this.options.project) {\n options.project = this.options.project;\n }\n if (this.options.readOnly || this.component.disabled) {\n options.readOnly = this.options.readOnly || this.component.disabled;\n }\n if (this.options.breadcrumbSettings) {\n options.breadcrumbSettings = this.options.breadcrumbSettings;\n }\n if (this.options.buttonSettings) {\n options.buttonSettings = lodash_1.default.clone(this.options.buttonSettings);\n }\n if (this.options.viewAsHtml) {\n options.viewAsHtml = this.options.viewAsHtml;\n }\n if (this.options.language) {\n options.language = this.options.language;\n }\n if (this.options.template) {\n options.template = this.options.template;\n }\n if (this.options.templates) {\n options.templates = this.options.templates;\n }\n if (this.options.renderMode) {\n options.renderMode = this.options.renderMode;\n }\n if (this.options.attachMode) {\n options.attachMode = this.options.attachMode;\n }\n if (this.options.iconset) {\n options.iconset = this.options.iconset;\n }\n if (this.options.fileService) {\n options.fileService = this.options.fileService;\n }\n if (this.options.onChange) {\n options.onChange = this.options.onChange;\n }\n if (this.options.preview) {\n options.preview = this.options.preview;\n }\n if (this.options.inEditGrid) {\n options.inEditGrid = this.options.inEditGrid;\n }\n if (this.options.saveDraft) {\n options.saveDraft = this.options.saveDraft;\n options.formio = new Formio_1.Formio(this.formSrc);\n }\n if (this.options.saveDraftThrottle) {\n options.saveDraftThrottle = this.options.saveDraftThrottle;\n }\n if (this.options.skipDraftRestore) {\n options.skipDraftRestore = this.options.skipDraftRestore;\n }\n options.parent = this;\n return options;\n }\n /* eslint-enable max-statements */\n render() {\n if (this.builderMode) {\n return super.render(this.t(this.component.label || 'nestedForm'));\n }\n const subform = this.subForm ? this.subForm.render() : this.renderTemplate('loading');\n return super.render(subform);\n }\n asString(value) {\n return this.getValueAsString(value);\n }\n /**\n * Prints out the value of form components as a datagrid value.\n */\n getValueAsString(value, options) {\n if (!value) {\n return this.t('noDataProvided');\n }\n if (!value.data && value._id) {\n return value._id;\n }\n if (!value.data || !Object.keys(value.data).length) {\n return this.t('noDataProvided');\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n return '[Complex Data]';\n }\n attach(element) {\n // Don't attach in builder.\n if (this.builderMode) {\n return super.attach(element);\n }\n return super.attach(element)\n .then(() => {\n if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {\n this.createSubForm(true);\n }\n return this.subFormReady.then(() => {\n this.empty(element);\n if (this.options.builder) {\n this.setContent(element, this.ce('div', {\n class: 'text-muted text-center p-2'\n }, this.text(this.formObj.title)));\n return;\n }\n this.setContent(element, this.render());\n if (this.subForm) {\n if (this.isNestedWizard) {\n element = this.root.element;\n }\n this.subForm.attach(element);\n this.valueChanged = this.hasSetValue;\n if (!this.valueChanged && this.dataValue.state !== 'submitted') {\n this.setDefaultValue();\n }\n else {\n this.restoreValue();\n }\n }\n if (!this.builderMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n this.componentModal = new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;\n this.setOpenModalElement();\n }\n this.calculateValue();\n });\n });\n }\n detach() {\n if (this.subForm) {\n this.subForm.detach();\n }\n super.detach();\n }\n get currentForm() {\n return this._currentForm;\n }\n get hasLoadedForm() {\n return this.formObj\n && this.formObj.components\n && Array.isArray(this.formObj.components)\n && this.formObj.components.length;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n if (!this.subForm) {\n return;\n }\n this.subForm.getComponents().forEach(component => {\n component.currentForm = this;\n });\n }\n get isRevisionChanged() {\n return lodash_1.default.isNumber(this.subFormRevision)\n && lodash_1.default.isNumber(this.formObj._vid)\n && this.formObj._vid !== this.subFormRevision;\n }\n get subFormData() {\n var _a;\n return ((_a = this.dataValue) === null || _a === void 0 ? void 0 : _a.data) || {};\n }\n destroy(all = false) {\n if (this.subForm) {\n this.subForm.destroy(all);\n this.subForm = null;\n this.subFormReady = null;\n }\n super.destroy(all);\n }\n redraw() {\n if (this.subForm) {\n this.subForm.form = this.formObj;\n this.setSubFormDisabled(this.subForm);\n }\n return super.redraw();\n }\n /**\n * Pass everyComponent to subform.\n * @param {any[]} args - Arguments to pass through to the subform's everyComponent method.\n * @returns {*} - The result of the subform's everyComponent method.\n */\n everyComponent(...args) {\n if (this.subForm) {\n this.subForm.everyComponent(...args);\n }\n }\n setSubFormDisabled(subForm) {\n subForm.disabled = this.disabled; // When the Nested Form is disabled make the subForm disabled\n }\n updateSubWizards(subForm) {\n var _a, _b;\n if (this.isNestedWizard && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.subWizards) && ((_b = subForm === null || subForm === void 0 ? void 0 : subForm._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard') {\n const existedForm = this.root.subWizards.findIndex(form => form.component.form === this.component.form);\n if (existedForm !== -1) {\n this.root.subWizards[existedForm] = this;\n }\n else {\n this.root.subWizards.push(this);\n }\n this.emit('subWizardsUpdated', subForm);\n }\n }\n /**\n * Create a subform instance.\n * @param {boolean} [fromAttach] - This function is being called from an `attach` method.\n * @param {boolean} [beforeSubmit] - This function is being called from a `beforeSubmit` method.\n * @returns {*} - The subform instance.\n */\n createSubForm(fromAttach, beforeSubmit) {\n this.subFormReady = this.loadSubForm(fromAttach, beforeSubmit).then((form) => {\n if (!form) {\n return;\n }\n // Iterate through every component and hide the submit button.\n (0, utils_1.eachComponent)(form.components, (component) => {\n this.hideSubmitButton(component);\n });\n // If the subform is already created then destroy the old one.\n if (this.subForm) {\n this.subForm.destroy();\n }\n // Render the form.\n return (new Form_1.default(form, this.getSubOptions())).ready.then((instance) => {\n this.subForm = instance;\n this.subForm.currentForm = this;\n this.subForm.parentVisible = this.visible;\n const componentsMap = this.componentsMap;\n const formComponentsMap = this.subForm.componentsMap;\n lodash_1.default.assign(componentsMap, formComponentsMap);\n this.component.components = this.subForm.components.map((comp) => comp.component);\n this.subForm.on('change', () => {\n if (this.subForm) {\n this.dataValue = this.subForm.getValue();\n this.triggerChange({\n noEmit: true\n });\n }\n });\n this.subForm.url = this.formSrc;\n this.subForm.nosubmit = true;\n this.subForm.root = this.root;\n this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;\n this.restoreValue();\n this.valueChanged = this.hasSetValue;\n this.onChange();\n return this.subForm;\n }).catch((err) => {\n console.log(err);\n });\n }).then((subForm) => {\n this.updateSubWizards(subForm);\n return subForm;\n });\n return this.subFormReady;\n }\n hideSubmitButton(component) {\n const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);\n if (isSubmitButton) {\n component.hidden = true;\n // clearOnHide no longer clears from the JSON `hidden` flag, so we make the button conditionally hidden to clear its data\n component.customConditional = 'show = false';\n }\n }\n /**\n * Load the subform.\n * @param {boolean} fromAttach - This function is being called from an `attach` method.\n * @param {boolean} beforeSubmit - This function is being called from a `beforeSubmit` method.\n * @returns {Promise} - The promise that resolves when the subform is loaded.\n */\n loadSubForm(fromAttach, beforeSubmit) {\n var _a, _b, _c, _d, _e;\n const loadHiddenForm = beforeSubmit && !this.component.clearOnHide;\n if (this.builderMode || (this.conditionallyHidden && !loadHiddenForm) || (this.isSubFormLazyLoad() && !fromAttach)) {\n return Promise.resolve();\n }\n if (this.hasLoadedForm && !this.isRevisionChanged &&\n !(this.options.pdf && ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && lodash_1.default.isNull(this.subForm) && !this.subFormLoading)) {\n // Pass config down to sub forms.\n if (this.root && this.root.form && this.root.form.config && !this.formObj.config) {\n this.formObj.config = this.root.form.config;\n }\n return Promise.resolve(this.formObj);\n }\n else if (this.formSrc) {\n this.subFormLoading = true;\n const options = ((_c = (_b = this.root) === null || _b === void 0 ? void 0 : _b.formio) === null || _c === void 0 ? void 0 : _c.base) && ((_e = (_d = this.root) === null || _d === void 0 ? void 0 : _d.formio) === null || _e === void 0 ? void 0 : _e.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n return (new Formio_1.Formio(this.formSrc, options)).loadForm({ params: { live: 1 } })\n .then((formObj) => {\n this.formObj = formObj;\n if (this.options.pdf && this.component.useOriginalRevision) {\n this.formObj.display = 'form';\n }\n this.subFormLoading = false;\n return formObj;\n })\n .catch((err) => {\n console.log(err);\n return null;\n });\n }\n return Promise.resolve();\n }\n checkComponentConditions(data, flags, row) {\n const visible = super.checkComponentConditions(data, flags, row);\n // Return if already hidden\n if (!visible) {\n return visible;\n }\n if (this.subForm) {\n return this.subForm.checkConditions(this.subFormData, flags);\n }\n // There are few cases when subForm is not loaded when a change is triggered,\n // so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode\n else if (this.subFormReady) {\n this.subFormReady.then(() => {\n if (this.subForm) {\n return this.subForm.checkConditions(this.subFormData, flags);\n }\n });\n }\n return visible;\n }\n calculateValue(data, flags, row) {\n if (this.subForm) {\n return this.subForm.calculateValue(this.subFormData, flags);\n }\n return super.calculateValue(data, flags, row);\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n if (this.subForm) {\n this.subForm.setPristine(pristine);\n }\n }\n /**\n * Determine if the subform should be submitted.\n * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.\n */\n get shouldSubmit() {\n return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden || !this.component.clearOnHide);\n }\n /**\n * Returns the data for the subform.\n * @returns {*} - the data for the subform.\n */\n getSubFormData() {\n if (lodash_1.default.get(this.subForm, 'form.display') === 'pdf') {\n return this.subForm.getSubmission();\n }\n else {\n return Promise.resolve(this.dataValue);\n }\n }\n /**\n * Submit the subform if configured to do so.\n * @returns {Promise} - The promise that resolves when the subform is submitted.\n */\n submitSubForm() {\n // If we wish to submit the form on next page, then do that here.\n if (this.shouldSubmit) {\n return this.subFormReady.then(() => {\n if (!this.subForm) {\n return this.dataValue;\n }\n this.subForm.nosubmit = false;\n this.subForm.submitted = true;\n return this.subForm.submitForm({}, true).then(result => {\n this.subForm.loading = false;\n this.subForm.showAllErrors = false;\n this.dataValue = result.submission;\n return this.dataValue;\n }).catch(err => {\n this.subForm.showAllErrors = true;\n this.subForm.onSubmissionError(err);\n return Promise.reject(err);\n });\n });\n }\n return this.getSubFormData();\n }\n /**\n * Submit the form before the next page is triggered.\n * @param {Function} next - The function to trigger the next page.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the next page is triggered.\n */\n beforePage(next) {\n // Should not submit child forms if we are going to the previous page\n if (!next) {\n return super.beforePage(next);\n }\n return this.submitSubForm(true).then(() => super.beforePage(next));\n }\n /**\n * Submit the form before the whole form is triggered.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the form is submitted.\n */\n beforeSubmit() {\n var _a, _b, _c;\n const submission = this.dataValue;\n // Cancel triggered saveDraft\n if (((_a = this.subForm) === null || _a === void 0 ? void 0 : _a.draftEnabled) && ((_b = this.subForm.triggerSaveDraft) === null || _b === void 0 ? void 0 : _b.cancel)) {\n this.subForm.triggerSaveDraft.cancel();\n }\n const isAlreadySubmitted = submission && submission._id && submission.form;\n const isDraftSubmission = this.options.saveDraft && submission.state === 'draft';\n // This submission has already been submitted, so just return the reference data.\n if (isAlreadySubmitted && !((_c = this.subForm) === null || _c === void 0 ? void 0 : _c.wizard) && !isDraftSubmission) {\n this.dataValue = submission;\n return Promise.resolve(this.dataValue);\n }\n // we need to load a hidden form (when clearOnHide is disabled) in order to get and submit (if needed) its data\n const loadHiddenForm = !this.subForm && !this.component.clearOnHide;\n if ((this.isSubFormLazyLoad() || loadHiddenForm) && !this.subFormLoading) {\n return this.createSubForm(true, true)\n .then(this.submitSubForm(false))\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n else {\n return this.submitSubForm(false)\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n }\n isSubFormLazyLoad() {\n var _a, _b;\n return ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && this.component.lazyLoad;\n }\n isHidden() {\n if (!this.visible) {\n return true;\n }\n return !super.checkConditions(this.rootValue);\n }\n setValue(submission, flags = {}) {\n var _a;\n const changed = super.setValue(submission, flags);\n this.valueChanged = true;\n if (this.subForm) {\n const revisionPath = submission._frid ? '_frid' : '_vid';\n const shouldLoadOriginalRevision = this.useOriginalRevision\n && (lodash_1.default.isNumber(submission[revisionPath]) || lodash_1.default.isNumber(submission._fvid))\n && lodash_1.default.isNumber((_a = this.subForm.form) === null || _a === void 0 ? void 0 : _a[revisionPath])\n && submission._fvid !== this.subForm.form[revisionPath];\n if (shouldLoadOriginalRevision) {\n this.setFormRevision(submission._frid || submission._fvid);\n this.createSubForm().then(() => {\n this.attach(this.element);\n });\n }\n else {\n this.setSubFormValue(submission, flags);\n }\n }\n return changed;\n }\n setSubFormValue(submission, flags) {\n var _a, _b, _c, _d;\n const shouldLoadSubmissionById = submission\n && submission._id\n && this.subForm.formio\n && lodash_1.default.isEmpty(submission.data);\n const shouldLoadDraftById = this.options.saveDraft && lodash_1.default.isEmpty(submission.data) && lodash_1.default.get(this.subForm, 'submission._id');\n if (shouldLoadSubmissionById || shouldLoadDraftById) {\n const formId = submission.form || this.formObj.form || this.component.form;\n const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;\n const options = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.formio) === null || _b === void 0 ? void 0 : _b.base) && ((_d = (_c = this.root) === null || _c === void 0 ? void 0 : _c.formio) === null || _d === void 0 ? void 0 : _d.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n this.subForm.setUrl(submissionUrl, Object.assign(Object.assign({}, this.options), options));\n this.subForm.loadSubmission().catch((err) => {\n console.error(this.t('subformSubmissionLoadingError', { submissionId: submission._id }), err);\n });\n }\n else {\n this.onSetSubFormValue(submission, flags);\n }\n }\n /**\n * Sets the subform value\n * @param {object|null|undefined} submission - The submission to set.\n * @param {object|null|undefined} flags - Any flags to apply when setting the submission.\n * @returns {void}\n */\n onSetSubFormValue(submission, flags) {\n this.subForm.setValue(submission, flags);\n }\n isEmpty(value = this.dataValue) {\n return value === null || lodash_1.default.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value === null || value === void 0 ? void 0 : value.data) && !(value === null || value === void 0 ? void 0 : value._id));\n }\n areAllComponentsEmpty(data) {\n let res = true;\n if (this.subForm) {\n this.subForm.everyComponent((comp) => {\n const componentValue = lodash_1.default.get(data, comp.key);\n res &= comp.isEmpty(componentValue);\n });\n }\n else {\n res = false;\n }\n return res;\n }\n getValue() {\n if (this.subForm) {\n return this.subForm.getValue();\n }\n return this.dataValue;\n }\n get errors() {\n let errors = super.errors;\n if (this.subForm) {\n errors = errors.concat(this.subForm.errors);\n }\n return errors;\n }\n updateSubFormVisibility() {\n if (this.subForm) {\n this.subForm.parentVisible = this.visible;\n }\n }\n /**\n * Determines if this form is a Nested Wizard\n * which means it should be a Wizard itself and should be a direct child of a Wizard's page\n * @returns {boolean} - TRUE if this form is a Nested Wizard, FALSE otherwise\n */\n get isNestedWizard() {\n var _a, _b, _c, _d, _e;\n return ((_b = (_a = this.subForm) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && ((_e = (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d._form) === null || _e === void 0 ? void 0 : _e.display) === 'wizard';\n }\n get visible() {\n return super.visible;\n }\n set visible(value) {\n const isNestedWizard = this.isNestedWizard;\n if (this._visible !== value) {\n this._visible = value;\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n this.clearOnHide();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.clearOnHide();\n isNestedWizard ? this.rebuild() : this.redraw();\n }\n if (!value && isNestedWizard) {\n this.root.redraw();\n }\n }\n get parentVisible() {\n return super.parentVisible;\n }\n set parentVisible(value) {\n if (this._parentVisible !== value) {\n this._parentVisible = value;\n this.clearOnHide();\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.redraw();\n }\n }\n isInternalEvent(event) {\n switch (event) {\n case 'focus':\n case 'blur':\n case 'componentChange':\n case 'componentError':\n case 'error':\n case 'formLoad':\n case 'languageChanged':\n case 'render':\n case 'checkValidity':\n case 'initialized':\n case 'submit':\n case 'submitButton':\n case 'nosubmit':\n case 'updateComponent':\n case 'submitDone':\n case 'submissionDeleted':\n case 'requestDone':\n case 'nextPage':\n case 'prevPage':\n case 'wizardNavigationClicked':\n case 'updateWizardNav':\n case 'restoreDraft':\n case 'saveDraft':\n case 'saveComponent':\n case 'pdfUploaded':\n return true;\n default:\n return false;\n }\n }\n createEmitter() {\n const emitter = new eventemitter3_1.default();\n const nativeEmit = emitter.emit;\n const that = this;\n emitter.emit = function (event, ...args) {\n const eventType = event.replace(`${that.options.namespace}.`, '');\n nativeEmit.call(this, event, ...args);\n if (!that.isInternalEvent(eventType)) {\n that.emit(eventType, ...args);\n }\n };\n return emitter;\n }\n deleteValue() {\n super.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n}\nexports[\"default\"] = FormComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/form/Form.js?");
|
5219
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/* eslint-disable max-statements */\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst ComponentModal_1 = __importDefault(__webpack_require__(/*! ../_classes/componentModal/ComponentModal */ \"./lib/cjs/components/_classes/componentModal/ComponentModal.js\"));\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nclass FormComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'Form',\n type: 'form',\n key: 'form',\n src: '',\n reference: true,\n form: '',\n path: '',\n tableView: true,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Nested Form',\n icon: 'wpforms',\n group: 'premium',\n documentation: '/userguide/form-building/premium-components#nested-form',\n weight: 110,\n schema: FormComponent.schema()\n };\n }\n static savedValueTypes() {\n return [utils_1.componentValueTypes.object];\n }\n init() {\n super.init();\n this.formObj = {\n display: this.component.display,\n settings: this.component.settings,\n components: this.component.components\n };\n this.valueChanged = false;\n this.subForm = null;\n this.formSrc = '';\n if (this.component.src) {\n this.formSrc = this.component.src;\n }\n if (!this.component.src &&\n !this.options.formio &&\n (this.component.form || this.component.path)) {\n if (this.component.project) {\n this.formSrc = Formio_1.Formio.getBaseUrl();\n // Check to see if it is a MongoID.\n if ((0, utils_1.isMongoId)(this.component.project)) {\n this.formSrc += '/project';\n }\n this.formSrc += `/${this.component.project}`;\n this.options.project = this.formSrc;\n }\n else {\n this.formSrc = Formio_1.Formio.getProjectUrl();\n this.options.project = this.formSrc;\n }\n if (this.component.form) {\n if ((0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc += `/form/${this.component.form}`;\n }\n else {\n this.formSrc += `/${this.component.form}`;\n }\n }\n else if (this.component.path) {\n this.formSrc += `/${this.component.path}`;\n }\n }\n // Build the source based on the root src path.\n if (!this.formSrc && this.options.formio) {\n const rootSrc = this.options.formio.formsUrl;\n if (this.component.form && (0, utils_1.isMongoId)(this.component.form)) {\n this.formSrc = `${rootSrc}/${this.component.form}`;\n }\n else {\n const formPath = this.component.path || this.component.form;\n this.formSrc = `${rootSrc.replace(/\\/form$/, '')}/${formPath}`;\n }\n }\n if (this.builderMode && this.component.hasOwnProperty('formRevision')) {\n this.component.revision = this.component.formRevision;\n delete this.component.formRevision;\n }\n // Add revision version if set.\n if (this.component.revision || this.component.revision === 0 ||\n this.component.formRevision || this.component.formRevision === 0\n || this.component.revisionId) {\n this.setFormRevision(this.component.revisionId || this.component.revision || this.component.formRevision);\n }\n return this.createSubForm();\n }\n get dataReady() {\n var _a;\n return ((_a = this.subForm) === null || _a === void 0 ? void 0 : _a.dataReady) || this.subFormReady || Promise.resolve();\n }\n get defaultValue() {\n // Not not provide a default value unless the subform is ready so that it will initialize correctly.\n return this.subForm ? super.defaultValue : null;\n }\n get defaultSchema() {\n return FormComponent.schema();\n }\n get emptyValue() {\n return { data: {} };\n }\n get ready() {\n return this.subFormReady || Promise.resolve();\n }\n get useOriginalRevision() {\n var _a, _b;\n return ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && !!((_b = this.formObj) === null || _b === void 0 ? void 0 : _b.revisions);\n }\n setFormRevision(rev) {\n // Remove current revisions from src if it is\n this.formSrc = this.formSrc.replace(/\\/v\\/[0-9a-z]+/, '');\n const revNumber = Number.parseInt(rev);\n if (!isNaN(revNumber)) {\n this.subFormRevision = rev;\n this.formSrc += `/v/${rev}`;\n }\n else {\n this.subFormRevision = undefined;\n }\n }\n getComponent(path) {\n if (!this.subForm) {\n return null;\n }\n return this.subForm.getComponent(path);\n }\n /* eslint-disable max-statements */\n getSubOptions(options = {}) {\n options.events = this.createEmitter();\n // Make sure to not show the submit button in wizards in the nested forms.\n lodash_1.default.set(options, 'buttonSettings.showSubmit', false);\n // Set the parent option to the subform so those references are stable when the subform is created\n options.parent = this;\n if (!this.options) {\n return options;\n }\n if (this.options.base) {\n options.base = this.options.base;\n }\n if (this.options.project) {\n options.project = this.options.project;\n }\n if (this.options.readOnly || this.component.disabled) {\n options.readOnly = this.options.readOnly || this.component.disabled;\n }\n if (this.options.breadcrumbSettings) {\n options.breadcrumbSettings = this.options.breadcrumbSettings;\n }\n if (this.options.buttonSettings) {\n options.buttonSettings = lodash_1.default.clone(this.options.buttonSettings);\n }\n if (this.options.viewAsHtml) {\n options.viewAsHtml = this.options.viewAsHtml;\n }\n if (this.options.language) {\n options.language = this.options.language;\n }\n if (this.options.template) {\n options.template = this.options.template;\n }\n if (this.options.templates) {\n options.templates = this.options.templates;\n }\n if (this.options.renderMode) {\n options.renderMode = this.options.renderMode;\n }\n if (this.options.attachMode) {\n options.attachMode = this.options.attachMode;\n }\n if (this.options.iconset) {\n options.iconset = this.options.iconset;\n }\n if (this.options.fileService) {\n options.fileService = this.options.fileService;\n }\n if (this.options.onChange) {\n options.onChange = this.options.onChange;\n }\n if (this.options.preview) {\n options.preview = this.options.preview;\n }\n if (this.options.inEditGrid) {\n options.inEditGrid = this.options.inEditGrid;\n }\n if (this.options.saveDraft) {\n options.saveDraft = this.options.saveDraft;\n options.formio = new Formio_1.Formio(this.formSrc);\n }\n if (this.options.saveDraftThrottle) {\n options.saveDraftThrottle = this.options.saveDraftThrottle;\n }\n if (this.options.skipDraftRestore) {\n options.skipDraftRestore = this.options.skipDraftRestore;\n }\n options.parent = this;\n return options;\n }\n /* eslint-enable max-statements */\n render() {\n if (this.builderMode) {\n return super.render(this.t(this.component.label || 'nestedForm'));\n }\n const subform = this.subForm ? this.subForm.render() : this.renderTemplate('loading');\n return super.render(subform);\n }\n asString(value) {\n return this.getValueAsString(value);\n }\n /**\n * Prints out the value of form components as a datagrid value.\n */\n getValueAsString(value, options) {\n if (!value) {\n return this.t('noDataProvided');\n }\n if (!value.data && value._id) {\n return value._id;\n }\n if (!value.data || !Object.keys(value.data).length) {\n return this.t('noDataProvided');\n }\n if (options === null || options === void 0 ? void 0 : options.email) {\n let result = (`\n <table border=\"1\" style=\"width:100%\">\n <tbody>\n `);\n this.everyComponent((component) => {\n if (component.isInputComponent && component.visible && !component.skipInEmail) {\n result += (`\n <tr>\n <th style=\"padding: 5px 10px;\">${component.label}</th>\n <td style=\"width:100%;padding:5px 10px;\">${component.getView(component.dataValue, options)}</td>\n </tr>\n `);\n }\n }, Object.assign(Object.assign({}, options), { fromRoot: true }));\n result += (`\n </tbody>\n </table>\n `);\n return result;\n }\n if (lodash_1.default.isEmpty(value)) {\n return '';\n }\n return '[Complex Data]';\n }\n attach(element) {\n // Don't attach in builder.\n if (this.builderMode) {\n return super.attach(element);\n }\n return super.attach(element)\n .then(() => {\n if (this.isSubFormLazyLoad() && !this.hasLoadedForm && !this.subFormLoading) {\n this.createSubForm(true);\n }\n return this.subFormReady.then(() => {\n this.empty(element);\n if (this.options.builder) {\n this.setContent(element, this.ce('div', {\n class: 'text-muted text-center p-2'\n }, this.text(this.formObj.title)));\n return;\n }\n this.setContent(element, this.render());\n if (this.subForm) {\n if (this.isNestedWizard) {\n element = this.root.element;\n }\n this.subForm.attach(element);\n this.valueChanged = this.hasSetValue;\n if (!this.valueChanged && this.dataValue.state !== 'submitted') {\n this.setDefaultValue();\n }\n else {\n this.restoreValue();\n }\n }\n if (!this.builderMode && this.component.modalEdit) {\n const modalShouldBeOpened = this.componentModal ? this.componentModal.isOpened : false;\n const currentValue = modalShouldBeOpened ? this.componentModal.currentValue : this.dataValue;\n this.componentModal = new ComponentModal_1.default(this, element, modalShouldBeOpened, currentValue, this._referenceAttributeName);\n this.subForm.element = this.componentModal.refs.componentContent || this.subForm.element;\n this.setOpenModalElement();\n }\n this.calculateValue();\n });\n });\n }\n detach() {\n if (this.subForm) {\n this.subForm.detach();\n }\n super.detach();\n }\n get currentForm() {\n return this._currentForm;\n }\n get hasLoadedForm() {\n return this.formObj\n && this.formObj.components\n && Array.isArray(this.formObj.components)\n && this.formObj.components.length;\n }\n set currentForm(instance) {\n this._currentForm = instance;\n if (!this.subForm) {\n return;\n }\n this.subForm.getComponents().forEach(component => {\n component.currentForm = this;\n });\n }\n get isRevisionChanged() {\n return lodash_1.default.isNumber(this.subFormRevision)\n && lodash_1.default.isNumber(this.formObj._vid)\n && this.formObj._vid !== this.subFormRevision;\n }\n get subFormData() {\n var _a;\n return ((_a = this.dataValue) === null || _a === void 0 ? void 0 : _a.data) || {};\n }\n destroy(all = false) {\n if (this.subForm) {\n this.subForm.destroy(all);\n this.subForm = null;\n this.subFormReady = null;\n }\n super.destroy(all);\n }\n redraw() {\n if (this.subForm) {\n this.subForm.form = this.formObj;\n this.setSubFormDisabled(this.subForm);\n }\n return super.redraw();\n }\n /**\n * Pass everyComponent to subform.\n * @param {any[]} args - Arguments to pass through to the subform's everyComponent method.\n * @returns {*} - The result of the subform's everyComponent method.\n */\n everyComponent(...args) {\n if (this.subForm) {\n this.subForm.everyComponent(...args);\n }\n }\n setSubFormDisabled(subForm) {\n subForm.disabled = this.disabled; // When the Nested Form is disabled make the subForm disabled\n }\n updateSubWizards(subForm) {\n var _a, _b;\n if (this.isNestedWizard && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.subWizards) && ((_b = subForm === null || subForm === void 0 ? void 0 : subForm._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard') {\n const existedForm = this.root.subWizards.findIndex(form => form.component.form === this.component.form);\n if (existedForm !== -1) {\n this.root.subWizards[existedForm] = this;\n }\n else {\n this.root.subWizards.push(this);\n }\n this.emit('subWizardsUpdated', subForm);\n }\n }\n /**\n * Create a subform instance.\n * @param {boolean} [fromAttach] - This function is being called from an `attach` method.\n * @param {boolean} [beforeSubmit] - This function is being called from a `beforeSubmit` method.\n * @returns {*} - The subform instance.\n */\n createSubForm(fromAttach, beforeSubmit) {\n this.subFormReady = this.loadSubForm(fromAttach, beforeSubmit).then((form) => {\n if (!form) {\n return;\n }\n // Iterate through every component and hide the submit button.\n (0, utils_1.eachComponent)(form.components, (component) => {\n this.hideSubmitButton(component);\n });\n // If the subform is already created then destroy the old one.\n if (this.subForm) {\n this.subForm.destroy();\n }\n // Render the form.\n return (new Form_1.default(form, this.getSubOptions())).ready.then((instance) => {\n this.subForm = instance;\n this.subForm.currentForm = this;\n this.subForm.parentVisible = this.visible;\n const componentsMap = this.componentsMap;\n const formComponentsMap = this.subForm.componentsMap;\n lodash_1.default.assign(componentsMap, formComponentsMap);\n this.component.components = this.subForm.components.map((comp) => comp.component);\n this.subForm.on('change', () => {\n if (this.subForm) {\n this.dataValue = this.subForm.getValue();\n this.triggerChange({\n noEmit: true\n });\n }\n });\n this.subForm.url = this.formSrc;\n this.subForm.nosubmit = true;\n this.subForm.root = this.root;\n this.subForm.localRoot = this.isNestedWizard ? this.localRoot : this.subForm;\n this.restoreValue();\n this.valueChanged = this.hasSetValue;\n this.onChange();\n return this.subForm;\n }).catch((err) => {\n console.log(err);\n });\n }).then((subForm) => {\n this.updateSubWizards(subForm);\n return subForm;\n });\n return this.subFormReady;\n }\n hideSubmitButton(component) {\n const isSubmitButton = component.type === 'button' && (component.action === 'submit' || !component.action);\n if (isSubmitButton) {\n component.hidden = true;\n // clearOnHide no longer clears from the JSON `hidden` flag, so we make the button conditionally hidden to clear its data\n component.customConditional = 'show = false';\n }\n }\n /**\n * Load the subform.\n * @param {boolean} fromAttach - This function is being called from an `attach` method.\n * @param {boolean} beforeSubmit - This function is being called from a `beforeSubmit` method.\n * @returns {Promise} - The promise that resolves when the subform is loaded.\n */\n loadSubForm(fromAttach, beforeSubmit) {\n var _a, _b, _c, _d, _e;\n const loadHiddenForm = beforeSubmit && !this.component.clearOnHide;\n if (this.builderMode || (this.conditionallyHidden && !loadHiddenForm) || (this.isSubFormLazyLoad() && !fromAttach)) {\n return Promise.resolve();\n }\n if (this.hasLoadedForm && !this.isRevisionChanged &&\n !(this.options.pdf && ((_a = this.component) === null || _a === void 0 ? void 0 : _a.useOriginalRevision) && lodash_1.default.isNull(this.subForm) && !this.subFormLoading)) {\n // Pass config down to sub forms.\n if (this.root && this.root.form && this.root.form.config && !this.formObj.config) {\n this.formObj.config = this.root.form.config;\n }\n return Promise.resolve(this.formObj);\n }\n else if (this.formSrc) {\n this.subFormLoading = true;\n const options = ((_c = (_b = this.root) === null || _b === void 0 ? void 0 : _b.formio) === null || _c === void 0 ? void 0 : _c.base) && ((_e = (_d = this.root) === null || _d === void 0 ? void 0 : _d.formio) === null || _e === void 0 ? void 0 : _e.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n return (new Formio_1.Formio(this.formSrc, options)).loadForm({ params: { live: 1 } })\n .then((formObj) => {\n this.formObj = formObj;\n if (this.options.pdf && this.component.useOriginalRevision) {\n this.formObj.display = 'form';\n }\n this.subFormLoading = false;\n return formObj;\n })\n .catch((err) => {\n console.log(err);\n return null;\n });\n }\n return Promise.resolve();\n }\n checkComponentConditions(data, flags, row) {\n const visible = super.checkComponentConditions(data, flags, row);\n // Return if already hidden\n if (!visible) {\n return visible;\n }\n if (this.subForm) {\n return this.subForm.checkConditions(this.subFormData, flags);\n }\n // There are few cases when subForm is not loaded when a change is triggered,\n // so we need to perform checkConditions after it is ready, or some conditional fields might be hidden in View mode\n else if (this.subFormReady) {\n this.subFormReady.then(() => {\n if (this.subForm) {\n return this.subForm.checkConditions(this.subFormData, flags);\n }\n });\n }\n return visible;\n }\n calculateValue(data, flags, row) {\n if (this.subForm) {\n return this.subForm.calculateValue(this.subFormData, flags);\n }\n return super.calculateValue(data, flags, row);\n }\n setPristine(pristine) {\n super.setPristine(pristine);\n if (this.subForm) {\n this.subForm.setPristine(pristine);\n }\n }\n /**\n * Determine if the subform should be submitted.\n * @returns {*|boolean} - TRUE if the subform should be submitted, FALSE if it should not.\n */\n get shouldSubmit() {\n return this.subFormReady && (!this.component.hasOwnProperty('reference') || this.component.reference) && (!this.conditionallyHidden || !this.component.clearOnHide);\n }\n /**\n * Returns the data for the subform.\n * @returns {*} - the data for the subform.\n */\n getSubFormData() {\n if (lodash_1.default.get(this.subForm, 'form.display') === 'pdf') {\n return this.subForm.getSubmission();\n }\n else {\n return Promise.resolve(this.dataValue);\n }\n }\n /**\n * Submit the subform if configured to do so.\n * @returns {Promise} - The promise that resolves when the subform is submitted.\n */\n submitSubForm() {\n // If we wish to submit the form on next page, then do that here.\n if (this.shouldSubmit) {\n return this.subFormReady.then(() => {\n if (!this.subForm) {\n return this.dataValue;\n }\n this.subForm.nosubmit = false;\n this.subForm.submitted = true;\n return this.subForm.submitForm({}, true).then(result => {\n this.subForm.loading = false;\n this.subForm.showAllErrors = false;\n this.dataValue = result.submission;\n return this.dataValue;\n }).catch(err => {\n this.subForm.showAllErrors = true;\n this.subForm.onSubmissionError(err);\n return Promise.reject(err);\n });\n });\n }\n return this.getSubFormData();\n }\n /**\n * Submit the form before the next page is triggered.\n * @param {Function} next - The function to trigger the next page.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the next page is triggered.\n */\n beforePage(next) {\n // Should not submit child forms if we are going to the previous page\n if (!next) {\n return super.beforePage(next);\n }\n return this.submitSubForm(true).then(() => super.beforePage(next));\n }\n /**\n * Submit the form before the whole form is triggered.\n * @returns {Promise} - The promise that resolves when the subform submission is complete (if necessary) and the form is submitted.\n */\n beforeSubmit() {\n var _a, _b, _c;\n const submission = this.dataValue;\n // Cancel triggered saveDraft\n if (((_a = this.subForm) === null || _a === void 0 ? void 0 : _a.draftEnabled) && ((_b = this.subForm.triggerSaveDraft) === null || _b === void 0 ? void 0 : _b.cancel)) {\n this.subForm.triggerSaveDraft.cancel();\n }\n const isAlreadySubmitted = submission && submission._id && submission.form;\n const isDraftSubmission = this.options.saveDraft && submission.state === 'draft';\n // This submission has already been submitted, so just return the reference data.\n if (isAlreadySubmitted && !((_c = this.subForm) === null || _c === void 0 ? void 0 : _c.wizard) && !isDraftSubmission) {\n this.dataValue = submission;\n return Promise.resolve(this.dataValue);\n }\n // we need to load a hidden form (when clearOnHide is disabled) in order to get and submit (if needed) its data\n const loadHiddenForm = !this.subForm && !this.component.clearOnHide;\n if ((this.isSubFormLazyLoad() || loadHiddenForm) && !this.subFormLoading) {\n return this.createSubForm(true, true)\n .then(this.submitSubForm(false))\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n else {\n return this.submitSubForm(false)\n .then(() => {\n return this.dataValue;\n })\n .then(() => super.beforeSubmit());\n }\n }\n isSubFormLazyLoad() {\n var _a, _b;\n return ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && this.component.lazyLoad;\n }\n isHidden() {\n if (!this.visible) {\n return true;\n }\n return !super.checkConditions(this.rootValue);\n }\n setValue(submission, flags = {}) {\n var _a;\n const changed = super.setValue(submission, flags);\n this.valueChanged = true;\n if (this.subForm) {\n const revisionPath = submission._frid ? '_frid' : '_vid';\n const shouldLoadOriginalRevision = this.useOriginalRevision\n && (lodash_1.default.isNumber(submission[revisionPath]) || lodash_1.default.isNumber(submission._fvid))\n && lodash_1.default.isNumber((_a = this.subForm.form) === null || _a === void 0 ? void 0 : _a[revisionPath])\n && submission._fvid !== this.subForm.form[revisionPath];\n if (shouldLoadOriginalRevision) {\n this.setFormRevision(submission._frid || submission._fvid);\n this.createSubForm().then(() => {\n this.attach(this.element);\n });\n }\n else {\n this.setSubFormValue(submission, flags);\n }\n }\n return changed;\n }\n setSubFormValue(submission, flags) {\n var _a, _b, _c, _d;\n const shouldLoadSubmissionById = submission\n && submission._id\n && this.subForm.formio\n && lodash_1.default.isEmpty(submission.data);\n const shouldLoadDraftById = this.options.saveDraft && lodash_1.default.isEmpty(submission.data) && lodash_1.default.get(this.subForm, 'submission._id');\n if (shouldLoadSubmissionById || shouldLoadDraftById) {\n const formId = submission.form || this.formObj.form || this.component.form;\n const submissionUrl = `${this.subForm.formio.formsUrl}/${formId}/submission/${submission._id || this.subForm.submission._id}`;\n const options = ((_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.formio) === null || _b === void 0 ? void 0 : _b.base) && ((_d = (_c = this.root) === null || _c === void 0 ? void 0 : _c.formio) === null || _d === void 0 ? void 0 : _d.projectUrl)\n ? {\n base: this.root.formio.base,\n project: this.root.formio.projectUrl,\n }\n : {};\n this.subForm.setUrl(submissionUrl, Object.assign(Object.assign({}, this.options), options));\n this.subForm.loadSubmission().catch((err) => {\n console.error(this.t('subformSubmissionLoadingError', { submissionId: submission._id }), err);\n });\n }\n else {\n this.onSetSubFormValue(submission, flags);\n }\n }\n /**\n * Sets the subform value\n * @param {object|null|undefined} submission - The submission to set.\n * @param {object|null|undefined} flags - Any flags to apply when setting the submission.\n * @returns {void}\n */\n onSetSubFormValue(submission, flags) {\n this.subForm.setValue(submission, flags);\n if (flags === null || flags === void 0 ? void 0 : flags.fromSubmission) {\n this.subForm.submissionReadyResolve(submission);\n }\n }\n isEmpty(value = this.dataValue) {\n return value === null || lodash_1.default.isEqual(value, this.emptyValue) || (this.areAllComponentsEmpty(value === null || value === void 0 ? void 0 : value.data) && !(value === null || value === void 0 ? void 0 : value._id));\n }\n areAllComponentsEmpty(data) {\n let res = true;\n if (this.subForm) {\n this.subForm.everyComponent((comp) => {\n const componentValue = lodash_1.default.get(data, comp.key);\n res &= comp.isEmpty(componentValue);\n });\n }\n else {\n res = false;\n }\n return res;\n }\n getValue() {\n if (this.subForm) {\n return this.subForm.getValue();\n }\n return this.dataValue;\n }\n get errors() {\n let errors = super.errors;\n if (this.subForm) {\n errors = errors.concat(this.subForm.errors);\n }\n return errors;\n }\n updateSubFormVisibility() {\n if (this.subForm) {\n this.subForm.parentVisible = this.visible;\n }\n }\n /**\n * Determines if this form is a Nested Wizard\n * which means it should be a Wizard itself and should be a direct child of a Wizard's page\n * @returns {boolean} - TRUE if this form is a Nested Wizard, FALSE otherwise\n */\n get isNestedWizard() {\n var _a, _b, _c, _d, _e;\n return ((_b = (_a = this.subForm) === null || _a === void 0 ? void 0 : _a._form) === null || _b === void 0 ? void 0 : _b.display) === 'wizard' && ((_e = (_d = (_c = this.parent) === null || _c === void 0 ? void 0 : _c.parent) === null || _d === void 0 ? void 0 : _d._form) === null || _e === void 0 ? void 0 : _e.display) === 'wizard';\n }\n get visible() {\n return super.visible;\n }\n set visible(value) {\n const isNestedWizard = this.isNestedWizard;\n if (this._visible !== value) {\n this._visible = value;\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n this.clearOnHide();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.clearOnHide();\n isNestedWizard ? this.rebuild() : this.redraw();\n }\n if (!value && isNestedWizard) {\n this.root.redraw();\n }\n }\n get parentVisible() {\n return super.parentVisible;\n }\n set parentVisible(value) {\n if (this._parentVisible !== value) {\n this._parentVisible = value;\n this.clearOnHide();\n // Form doesn't load if hidden. If it becomes visible, create the form.\n if (!this.subForm && value) {\n this.createSubForm();\n this.subFormReady.then(() => {\n this.updateSubFormVisibility();\n });\n this.redraw();\n return;\n }\n this.updateSubFormVisibility();\n this.redraw();\n }\n }\n isInternalEvent(event) {\n switch (event) {\n case 'focus':\n case 'blur':\n case 'componentChange':\n case 'componentError':\n case 'error':\n case 'formLoad':\n case 'languageChanged':\n case 'render':\n case 'checkValidity':\n case 'initialized':\n case 'submit':\n case 'submitButton':\n case 'nosubmit':\n case 'updateComponent':\n case 'submitDone':\n case 'submissionDeleted':\n case 'requestDone':\n case 'nextPage':\n case 'prevPage':\n case 'wizardNavigationClicked':\n case 'updateWizardNav':\n case 'restoreDraft':\n case 'saveDraft':\n case 'saveComponent':\n case 'pdfUploaded':\n return true;\n default:\n return false;\n }\n }\n createEmitter() {\n const emitter = new eventemitter3_1.default();\n const nativeEmit = emitter.emit;\n const that = this;\n emitter.emit = function (event, ...args) {\n const eventType = event.replace(`${that.options.namespace}.`, '');\n nativeEmit.call(this, event, ...args);\n if (!that.isInternalEvent(eventType)) {\n that.emit(eventType, ...args);\n }\n };\n return emitter;\n }\n deleteValue() {\n super.setValue(null, {\n noUpdateEvent: true,\n noDefault: true\n });\n this.unset();\n }\n}\nexports[\"default\"] = FormComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/form/Form.js?");
|
5220
5220
|
|
5221
5221
|
/***/ }),
|
5222
5222
|
|
@@ -5238,7 +5238,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5238
5238
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5239
5239
|
|
5240
5240
|
"use strict";
|
5241
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass HTMLComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'HTML',\n type: 'htmlelement',\n tag: 'div',\n attrs: [],\n content: '',\n input: false,\n persistent: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'HTML Element',\n group: 'layout',\n icon: 'code',\n weight: 0,\n documentation: '/userguide/form-building/layout-components#html-element',\n showPreview: false,\n schema: HTMLComponent.schema()\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return HTMLComponent.schema();\n }\n get content() {\n if (this.builderMode) {\n return this.component.content;\n }\n // i18n returns error exactly with word 'select', spaces will be trimmed\n if (this.component.content.replace(/(<(\\/?[^>]+)>)/g, '').trim() === 'select') {\n return ` ${this.component.content} `;\n }\n const submission = lodash_1.default.get(this.root, 'submission', {});\n const content = this.component.content ? this.interpolate(this.sanitize(this.component.content, this.shouldSanitizeValue), {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n }) : '';\n return content;\n }\n get singleTags() {\n return ['br', 'img', 'hr'];\n }\n checkRefreshOn(changed) {\n super.checkRefreshOn(changed);\n let visible;\n if (this.hasCondition()) {\n
|
5241
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst Component_1 = __importDefault(__webpack_require__(/*! ../_classes/component/Component */ \"./lib/cjs/components/_classes/component/Component.js\"));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nclass HTMLComponent extends Component_1.default {\n static schema(...extend) {\n return Component_1.default.schema({\n label: 'HTML',\n type: 'htmlelement',\n tag: 'div',\n attrs: [],\n content: '',\n input: false,\n persistent: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'HTML Element',\n group: 'layout',\n icon: 'code',\n weight: 0,\n documentation: '/userguide/form-building/layout-components#html-element',\n showPreview: false,\n schema: HTMLComponent.schema()\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return HTMLComponent.schema();\n }\n get content() {\n if (this.builderMode) {\n return this.component.content;\n }\n // i18n returns error exactly with word 'select', spaces will be trimmed\n if (this.component.content.replace(/(<(\\/?[^>]+)>)/g, '').trim() === 'select') {\n return ` ${this.component.content} `;\n }\n const submission = lodash_1.default.get(this.root, 'submission', {});\n const content = this.component.content ? this.interpolate(this.sanitize(this.component.content, this.shouldSanitizeValue), {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n }) : '';\n return content;\n }\n get singleTags() {\n return ['br', 'img', 'hr'];\n }\n checkRefreshOn(changed) {\n super.checkRefreshOn(changed);\n let visible;\n if (this.hasCondition()) {\n visible = !this.checkConditionallyHidden();\n }\n else {\n visible = !this.component.hidden;\n }\n const shouldSetContent = !this.builderMode\n && this.component.refreshOnChange\n && this.element\n && !lodash_1.default.isUndefined(changed)\n && ((lodash_1.default.isBoolean(changed) && changed) || !lodash_1.default.isEmpty(changed))\n && visible;\n if (shouldSetContent) {\n this.setContent(this.element, this.renderContent());\n }\n }\n renderContent() {\n const submission = lodash_1.default.get(this.root, 'submission', {});\n return this.renderTemplate('html', {\n component: this.component,\n tag: this.component.tag,\n attrs: (this.component.attrs || []).map((attr) => {\n return {\n attr: attr.attr,\n value: this.interpolate(attr.value, {\n metadata: submission.metadata || {},\n submission: submission,\n data: this.rootValue,\n row: this.data\n })\n };\n }),\n content: this.content,\n singleTags: this.singleTags,\n });\n }\n render() {\n return super.render(this.renderContent());\n }\n get dataReady() {\n var _a;\n return ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submissionReady) || Promise.resolve();\n }\n attach(element) {\n this.loadRefs(element, { html: 'single' });\n this.dataReady.then(() => {\n if (this.refs.html) {\n this.setContent(this.refs.html, this.content);\n }\n });\n return super.attach(element);\n }\n}\nexports[\"default\"] = HTMLComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/html/HTML.js?");
|
5242
5242
|
|
5243
5243
|
/***/ }),
|
5244
5244
|
|
@@ -5326,7 +5326,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
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 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/utils */ \"./lib/cjs/utils/utils.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')\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 }, 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 if (this.choices && choicesOptions.placeholderValue && this.choices._isSelectOneElement) {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\n this.addEventListener(input, 'removeItem', () => {\n this.addPlaceholderItem(choicesOptions.placeholderValue);\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 addPlaceholderItem(placeholderValue) {\n const items = this.choices._store.activeItems;\n if (!items.length) {\n this.choices._addItem({\n value: '',\n label: placeholderValue,\n choiceId: 0,\n groupId: -1,\n customProperties: null,\n placeholder: true,\n keyCode: null\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) {\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?");
|
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 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/utils */ \"./lib/cjs/utils/utils.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) {\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?");
|
5330
5330
|
|
5331
5331
|
/***/ }),
|
5332
5332
|
|
@@ -5381,7 +5381,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5381
5381
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5382
5382
|
|
5383
5383
|
"use strict";
|
5384
|
-
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 NestedComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nclass TabsComponent extends NestedComponent_1.default {\n static schema(...extend) {\n return NestedComponent_1.default.schema({\n label: 'Tabs',\n type: 'tabs',\n input: false,\n key: 'tabs',\n persistent: false,\n tableView: false,\n components: [\n {\n label: 'Tab 1',\n key: 'tab1',\n components: [],\n },\n ],\n verticalLayout: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Tabs',\n group: 'layout',\n icon: 'folder-o',\n weight: 50,\n documentation: '/userguide/form-building/layout-components#tabs',\n showPreview: false,\n schema: TabsComponent.schema(),\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return TabsComponent.schema();\n }\n get schema() {\n const schema = super.schema;\n // We need to clone this because the builder uses the \"components\" reference and this would reset that reference.\n const components = lodash_1.default.cloneDeep(this.component.components);\n schema.components = components.map((tab, index) => {\n tab.components = this.tabs[index].map((component) => component.schema);\n return tab;\n });\n return schema;\n }\n get tabKey() {\n return `tab-${this.key}`;\n }\n get tabLikey() {\n return `tabLi-${this.key}`;\n }\n get tabLinkKey() {\n return `tabLink-${this.key}`;\n }\n constructor(...args) {\n super(...args);\n this.currentTab = 0;\n this.noField = true;\n }\n init() {\n this.components = [];\n this.tabs = [];\n lodash_1.default.each(this.component.components, (tab, index) => {\n this.tabs[index] = [];\n // Initialize empty tabs.\n tab.components = tab.components || [];\n lodash_1.default.each(tab.components, (comp) => {\n const component = this.createComponent(comp);\n component.tab = index;\n this.tabs[index].push(component);\n });\n });\n }\n render() {\n return super.render(this.renderTemplate('tab', {\n tabKey: this.tabKey,\n tabLikey: this.tabLikey,\n tabLinkKey: this.tabLinkKey,\n currentTab: this.currentTab,\n tabComponents: this.tabs.map(tab => this.renderComponents(tab)),\n }, (this.options.flatten || this.options.pdf ? 'flat' : null)));\n }\n attach(element) {\n this.loadRefs(element, {\n [this.tabLinkKey]: 'multiple',\n [this.tabKey]: 'multiple',\n [this.tabLikey]: 'multiple',\n });\n ['change', 'error'].forEach(event => this.on(event, this.handleTabsValidation.bind(this)));\n const superAttach = super.attach(element);\n this.refs[this.tabLinkKey].forEach((tabLink, index) => {\n this.addEventListener(tabLink, 'click', (event) => {\n event.preventDefault();\n this.setTab(index);\n });\n });\n this.refs[this.tabKey].forEach((tab, index) => {\n this.attachComponents(tab, this.tabs[index], this.component.components[index].components);\n });\n return superAttach;\n }\n detach(all) {\n super.detach(all);\n }\n /**\n * Set the current tab.\n * @param {number} index - The index of the tab to set.\n */\n setTab(index) {\n if (!this.tabs || !this.tabs[index] || !this.refs[this.tabKey] || !this.refs[this.tabKey][index]) {\n return;\n }\n this.currentTab = index;\n lodash_1.default.each(this.refs[this.tabKey], (tab) => {\n this.removeClass(tab, 'formio-tab-panel-active');\n tab.style.display = 'none';\n });\n this.addClass(this.refs[this.tabKey][index], 'formio-tab-panel-active');\n this.refs[this.tabKey][index].style.display = 'block';\n lodash_1.default.each(this.refs[this.tabLinkKey], (tabLink, tabIndex) => {\n if (this.refs[this.tabLinkKey][tabIndex]) {\n this.removeClass(tabLink, 'active');\n this.removeClass(tabLink, 'formio-tab-link-active');\n }\n if (this.refs[this.tabLikey][tabIndex]) {\n this.removeClass(this.refs[this.tabLikey][tabIndex], 'active');\n this.removeClass(this.refs[this.tabLikey][tabIndex], 'formio-tab-link-container-active');\n }\n });\n if (this.refs[this.tabLikey][index]) {\n this.addClass(this.refs[this.tabLikey][index], 'active');\n this.addClass(this.refs[this.tabLikey][index], 'formio-tab-link-container-active');\n }\n if (this.refs[this.tabLinkKey][index]) {\n this.addClass(this.refs[this.tabLinkKey][index], 'active');\n this.addClass(this.refs[this.tabLinkKey][index], 'formio-tab-link-active');\n }\n this.triggerChange();\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const tabIndex = this.tabs.findIndex((tab) => {\n return tab.some((comp) => comp === component);\n });\n if (tabIndex !== -1 && this.currentTab !== tabIndex) {\n this.setTab(tabIndex);\n }\n }\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n if (this.component.modalEdit) {\n super.setErrorClasses(elements, dirty, hasErrors, hasMessages, element);\n }\n elements.forEach((element) => {\n this.addClass(element, 'is-invalid');\n if (element.getAttribute('ref') !== 'openModal') {\n if (this.options.highlightErrors) {\n this.addClass(element, 'tab-error');\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n });\n }\n clearErrorClasses(elements) {\n if (this.options.server || !this.rendered) {\n return;\n }\n if (this.component.modalEdit) {\n const element = Array.isArray(elements) || elements instanceof NodeList ? this.element : elements;\n super.clearErrorClasses(element);\n }\n elements = Array.isArray(elements) || elements instanceof NodeList ? elements : [elements];\n elements.forEach((element) => {\n this.removeClass(element, 'is-invalid');\n this.removeClass(element, 'tab-error');\n this.removeClass(element, 'has-error');\n });\n }\n handleTabsValidation() {\n if (!this.refs[this.tabLinkKey] || !this.refs[this.tabLinkKey].length || !this.tabs.length) {\n return;\n }\n this.clearErrorClasses(this.refs[this.tabLinkKey]);\n const invalidTabsIndexes = this.tabs.reduce((invalidTabs, tab, tabIndex) => {\n const hasComponentWithError = tab.some(comp => !!comp.error);\n return hasComponentWithError ? [...invalidTabs, tabIndex] : invalidTabs;\n }, []);\n if (!invalidTabsIndexes.length) {\n return;\n }\n const invalidTabs = [...this.refs[this.tabLinkKey]].filter((_, tabIndex) => invalidTabsIndexes.includes(tabIndex));\n this.setErrorClasses(invalidTabs);\n }\n}\nexports[\"default\"] = TabsComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/tabs/Tabs.js?");
|
5384
|
+
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 NestedComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/nested/NestedComponent */ \"./lib/cjs/components/_classes/nested/NestedComponent.js\"));\nclass TabsComponent extends NestedComponent_1.default {\n static schema(...extend) {\n return NestedComponent_1.default.schema({\n label: 'Tabs',\n type: 'tabs',\n input: false,\n key: 'tabs',\n persistent: false,\n tableView: false,\n components: [\n {\n label: 'Tab 1',\n key: 'tab1',\n components: [],\n },\n ],\n verticalLayout: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Tabs',\n group: 'layout',\n icon: 'folder-o',\n weight: 50,\n documentation: '/userguide/form-building/layout-components#tabs',\n showPreview: false,\n schema: TabsComponent.schema(),\n };\n }\n static savedValueTypes() {\n return [];\n }\n get defaultSchema() {\n return TabsComponent.schema();\n }\n get schema() {\n const schema = super.schema;\n // We need to clone this because the builder uses the \"components\" reference and this would reset that reference.\n const components = lodash_1.default.cloneDeep(this.component.components);\n schema.components = components.map((tab, index) => {\n tab.components = this.tabs[index].map((component) => component.schema);\n return tab;\n });\n return schema;\n }\n get tabKey() {\n return `tab-${this.key}`;\n }\n get tabLikey() {\n return `tabLi-${this.key}`;\n }\n get tabLinkKey() {\n return `tabLink-${this.key}`;\n }\n constructor(...args) {\n super(...args);\n this.currentTab = 0;\n this.noField = true;\n }\n init() {\n this.components = [];\n this.tabs = [];\n lodash_1.default.each(this.component.components, (tab, index) => {\n this.tabs[index] = [];\n // Initialize empty tabs.\n tab.components = tab.components || [];\n lodash_1.default.each(tab.components, (comp) => {\n const component = this.createComponent(comp);\n component.tab = index;\n this.tabs[index].push(component);\n });\n });\n }\n render() {\n return super.render(this.renderTemplate('tab', {\n tabKey: this.tabKey,\n tabLikey: this.tabLikey,\n tabLinkKey: this.tabLinkKey,\n currentTab: this.currentTab,\n tabComponents: this.tabs.map(tab => this.renderComponents(tab)),\n }, (this.options.flatten || this.options.pdf ? 'flat' : null)));\n }\n attach(element) {\n this.loadRefs(element, {\n [this.tabLinkKey]: 'multiple',\n [this.tabKey]: 'multiple',\n [this.tabLikey]: 'multiple',\n });\n ['change', 'error'].forEach(event => this.on(event, this.handleTabsValidation.bind(this)));\n const superAttach = super.attach(element);\n this.refs[this.tabLinkKey].forEach((tabLink, index) => {\n this.addEventListener(tabLink, 'click', (event) => {\n event.preventDefault();\n this.setTab(index);\n });\n });\n this.refs[this.tabKey].forEach((tab, index) => {\n this.attachComponents(tab, this.tabs[index], this.component.components[index].components);\n });\n return superAttach;\n }\n detach(all) {\n super.detach(all);\n }\n /**\n * Set the current tab.\n * @param {number} index - The index of the tab to set.\n */\n setTab(index) {\n if (!this.tabs || !this.tabs[index] || !this.refs[this.tabKey] || !this.refs[this.tabKey][index]) {\n return;\n }\n this.currentTab = index;\n lodash_1.default.each(this.refs[this.tabKey], (tab) => {\n this.removeClass(tab, 'formio-tab-panel-active');\n tab.style.display = 'none';\n });\n this.addClass(this.refs[this.tabKey][index], 'formio-tab-panel-active');\n this.refs[this.tabKey][index].style.display = 'block';\n lodash_1.default.each(this.refs[this.tabLinkKey], (tabLink, tabIndex) => {\n if (this.refs[this.tabLinkKey][tabIndex]) {\n this.removeClass(tabLink, 'active');\n this.removeClass(tabLink, 'formio-tab-link-active');\n }\n if (this.refs[this.tabLikey][tabIndex]) {\n this.removeClass(this.refs[this.tabLikey][tabIndex], 'active');\n this.removeClass(this.refs[this.tabLikey][tabIndex], 'formio-tab-link-container-active');\n }\n });\n if (this.refs[this.tabLikey][index]) {\n this.addClass(this.refs[this.tabLikey][index], 'active');\n this.addClass(this.refs[this.tabLikey][index], 'formio-tab-link-container-active');\n }\n if (this.refs[this.tabLinkKey][index]) {\n this.addClass(this.refs[this.tabLinkKey][index], 'active');\n this.addClass(this.refs[this.tabLinkKey][index], 'formio-tab-link-active');\n }\n this.setValue(this.data);\n this.triggerChange();\n }\n beforeFocus(component) {\n if ('beforeFocus' in this.parent) {\n this.parent.beforeFocus(this);\n }\n const tabIndex = this.tabs.findIndex((tab) => {\n return tab.some((comp) => comp === component);\n });\n if (tabIndex !== -1 && this.currentTab !== tabIndex) {\n this.setTab(tabIndex);\n }\n }\n setErrorClasses(elements, dirty, hasErrors, hasMessages, element = this.element) {\n if (this.component.modalEdit) {\n super.setErrorClasses(elements, dirty, hasErrors, hasMessages, element);\n }\n elements.forEach((element) => {\n this.addClass(element, 'is-invalid');\n if (element.getAttribute('ref') !== 'openModal') {\n if (this.options.highlightErrors) {\n this.addClass(element, 'tab-error');\n }\n else {\n this.addClass(element, 'has-error');\n }\n }\n });\n }\n clearErrorClasses(elements) {\n if (this.options.server || !this.rendered) {\n return;\n }\n if (this.component.modalEdit) {\n const element = Array.isArray(elements) || elements instanceof NodeList ? this.element : elements;\n super.clearErrorClasses(element);\n }\n elements = Array.isArray(elements) || elements instanceof NodeList ? elements : [elements];\n elements.forEach((element) => {\n this.removeClass(element, 'is-invalid');\n this.removeClass(element, 'tab-error');\n this.removeClass(element, 'has-error');\n });\n }\n handleTabsValidation() {\n if (!this.refs[this.tabLinkKey] || !this.refs[this.tabLinkKey].length || !this.tabs.length) {\n return;\n }\n this.clearErrorClasses(this.refs[this.tabLinkKey]);\n const invalidTabsIndexes = this.tabs.reduce((invalidTabs, tab, tabIndex) => {\n const hasComponentWithError = tab.some(comp => !!comp.error);\n return hasComponentWithError ? [...invalidTabs, tabIndex] : invalidTabs;\n }, []);\n if (!invalidTabsIndexes.length) {\n return;\n }\n const invalidTabs = [...this.refs[this.tabLinkKey]].filter((_, tabIndex) => invalidTabsIndexes.includes(tabIndex));\n this.setErrorClasses(invalidTabs);\n }\n}\nexports[\"default\"] = TabsComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/tabs/Tabs.js?");
|
5385
5385
|
|
5386
5386
|
/***/ }),
|
5387
5387
|
|
@@ -5392,7 +5392,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5392
5392
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5393
5393
|
|
5394
5394
|
"use strict";
|
5395
|
-
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst choices_js_1 = __importDefault(__webpack_require__(/*!
|
5395
|
+
eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst utils_1 = __webpack_require__(/*! ../../utils/utils */ \"./lib/cjs/utils/utils.js\");\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst choices_js_1 = __importDefault(__webpack_require__(/*! choices.js */ \"./node_modules/choices.js/public/assets/scripts/choices.js\"));\nclass TagsComponent extends Input_1.default {\n static schema(...extend) {\n return Input_1.default.schema({\n type: 'tags',\n label: 'Tags',\n key: 'tags',\n delimeter: ',',\n storeas: 'string',\n maxTags: 0\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Tags',\n icon: 'tags',\n group: 'advanced',\n documentation: '/userguide/form-building/advanced-components#tags',\n weight: 30,\n schema: TagsComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return TagsComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { operators: [...super.conditionOperatorsSettings.operators, 'includes', 'notIncludes'] });\n }\n static savedValueTypes(schema) {\n schema = schema || {};\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes[schema.storeas] || utils_1.componentValueTypes.string];\n }\n init() {\n super.init();\n }\n get emptyValue() {\n return (this.component.storeas === 'string') ? '' : [];\n }\n get defaultSchema() {\n return TagsComponent.schema();\n }\n get inputInfo() {\n const info = super.inputInfo;\n info.type = 'input';\n info.attr.type = 'text';\n info.changeEvent = 'change';\n return info;\n }\n get delimiter() {\n return this.component.delimeter || ',';\n }\n attachElement(element, index) {\n super.attachElement(element, index);\n if (!element) {\n return;\n }\n if (this.i18next) {\n element.setAttribute('dir', this.i18next.dir());\n }\n if (this.choices) {\n this.choices.destroy();\n }\n if (!choices_js_1.default) {\n return;\n }\n const hasPlaceholder = !!this.component.placeholder;\n this.choices = new choices_js_1.default(element, {\n delimiter: this.delimiter,\n editItems: true,\n allowHTML: true,\n maxItemCount: this.component.maxTags,\n removeItemButton: true,\n duplicateItemsAllowed: false,\n shadowRoot: this.root ? this.root.shadowRoot : null,\n placeholder: hasPlaceholder,\n placeholderValue: hasPlaceholder ? this.t(this.component.placeholder, { _userInput: true }) : null,\n });\n this.choices.itemList.element.tabIndex = element.tabIndex;\n this.addEventListener(this.choices.input.element, 'blur', () => {\n // Emit event to the native Formio input, so the listener attached in the Input.js will be invoked\n element.dispatchEvent(new Event('blur'));\n const value = this.choices.input.value;\n const maxTagsNumber = this.component.maxTags;\n const valuesCount = this.choices.getValue(true).length;\n const isRepeatedValue = this.choices.getValue(true).some(existingValue => existingValue.trim() === value.trim());\n if (value) {\n if (maxTagsNumber && valuesCount === maxTagsNumber) {\n this.choices.addItems = false;\n this.choices.clearInput();\n }\n else if (isRepeatedValue) {\n this.choices.clearInput();\n }\n else {\n this.choices.setValue([value]);\n this.choices.clearInput();\n this.choices.hideDropdown(true);\n this.updateValue(null, {\n modified: true\n });\n }\n }\n });\n }\n detach() {\n if (this.choices) {\n this.choices.destroy();\n this.choices = null;\n }\n super.detach();\n }\n normalizeValue(value) {\n if (this.component.storeas === 'string' && Array.isArray(value)) {\n return super.normalizeValue(value.join(this.delimiter));\n }\n else if (this.component.storeas === 'array' && typeof value === 'string') {\n return super.normalizeValue(value.split(this.delimiter).filter(result => result));\n }\n return super.normalizeValue(value);\n }\n setValue(value, flags = {}) {\n const changed = super.setValue(value, flags);\n if (this.choices) {\n let dataValue = this.dataValue;\n this.choices.clearStore();\n if (dataValue) {\n if (typeof dataValue === 'string') {\n dataValue = dataValue.split(this.delimiter).filter(result => result);\n }\n const value = Array.isArray(dataValue) ? dataValue : [dataValue];\n this.choices.setValue(value.map((val) => this.sanitize(val, this.shouldSanitizeValue)));\n }\n }\n return changed;\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.choices.disable();\n }\n else {\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n focus() {\n if (this.refs.input && this.refs.input.length) {\n this.refs.input[0].parentNode.lastChild.focus();\n }\n }\n getValueAsString(value) {\n if (!value) {\n return '';\n }\n if (Array.isArray(value)) {\n return value.join(`${this.delimiter || ','} `);\n }\n const stringValue = value.toString();\n return this.sanitize(stringValue, this.shouldSanitizeValue);\n }\n}\nexports[\"default\"] = TagsComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/tags/Tags.js?");
|
5396
5396
|
|
5397
5397
|
/***/ }),
|
5398
5398
|
|
@@ -5788,7 +5788,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5788
5788
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
5789
5789
|
|
5790
5790
|
"use strict";
|
5791
|
-
eval("\nvar
|
5791
|
+
eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst choices_js_1 = __importStar(__webpack_require__(/*! choices.js */ \"./node_modules/choices.js/public/assets/scripts/choices.js\"));\nconst ExtendedKeyCodeMap = Object.assign(Object.assign({}, choices_js_1.KeyCodeMap), { TAB_KEY: 9 });\nclass ChoicesWrapper extends choices_js_1.default {\n constructor(...args) {\n super(...args);\n this._onTabKey = this._onTabKey.bind(this);\n this.isDirectionUsing = false;\n this.shouldOpenDropDown = true;\n }\n _onTouchEnd(event) {\n var target = (event || event.touches[0]).target;\n var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target);\n if (touchWasWithinContainer) {\n var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element;\n if (containerWasExactTarget) {\n if (this._isTextElement) {\n this.input.focus();\n }\n else if (this._isSelectMultipleElement) {\n this.input.focus();\n this.showDropdown();\n }\n }\n // Prevents focus event firing\n event.stopPropagation();\n }\n this._wasTap = true;\n }\n _onEnterKey(...args) {\n const [event] = args;\n // Prevent dropdown form opening when removeItemButton was pressed using 'Enter' on keyboard\n if (event.target.className === 'choices__button') {\n this.shouldOpenDropDown = false;\n }\n super._onEnterKey(...args);\n }\n _onDirectionKey(...args) {\n if (!this._isSelectOneElement) {\n return super._onDirectionKey(...args);\n }\n this.isDirectionUsing = true;\n super._onDirectionKey(...args);\n this.onSelectValue(...args);\n clearTimeout(this.timeout);\n this.timeout = setTimeout(() => {\n this.isDirectionUsing = false;\n }, 250);\n }\n _onTabKey() {\n if (this.dropdown.isActive) {\n this._selectHighlightedChoice();\n }\n }\n _selectHighlightedChoice() {\n const highlightedChoice = this.dropdown.element.querySelector(`.${this.config.classNames.highlightedState}`);\n if (highlightedChoice) {\n const id = highlightedChoice.dataset.id;\n const choice = id && this._store.getChoiceById(Number(id));\n this._addItem({\n id: choice.id,\n value: choice.value,\n label: choice.label,\n choiceId: choice.id,\n groupId: choice.groupId,\n customProperties: choice.customProperties,\n placeholder: choice.placeholder,\n keyCode: choice.keyCode\n });\n this._triggerChange(choice.value);\n }\n }\n _onKeyDown(event) {\n const keyCode = event.keyCode;\n return this._isSelectOneElement && keyCode === ExtendedKeyCodeMap.TAB_KEY\n ? this._onTabKey()\n : super._onKeyDown(event);\n }\n onSelectValue(event, hasActiveDropdown) {\n if (hasActiveDropdown) {\n this._selectHighlightedChoice();\n }\n else if (this._isSelectOneElement) {\n this.showDropdown();\n event.preventDefault();\n }\n }\n showDropdown(...args) {\n setTimeout(() => {\n if (!this.shouldOpenDropDown) {\n this.shouldOpenDropDown = true;\n return;\n }\n super.showDropdown(...args);\n }, 0);\n }\n hideDropdown(...args) {\n if (this.isDirectionUsing) {\n return;\n }\n super.hideDropdown(...args);\n }\n}\nexports[\"default\"] = ChoicesWrapper;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/utils/ChoicesWrapper.js?");
|
5792
5792
|
|
5793
5793
|
/***/ }),
|
5794
5794
|
|