csdsolutions-csdjs
Version:
Libreria per i progetti di CSD Solutions
62 lines (51 loc) • 387 kB
JavaScript
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("$CSD", [], factory);
else if(typeof exports === 'object')
exports["$CSD"] = factory();
else
root["$CSD"] = factory();
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./component/csd-accordion.js":
/*!************************************!*\
!*** ./component/csd-accordion.js ***!
\************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ initializeAccordion: () => (/* binding */ initializeAccordion),\n/* harmony export */ showAccordion: () => (/* binding */ showAccordion)\n/* harmony export */ });\n/**\n * Triggers a custom accordion event with detailed state information\n * @param $item - The accordion item that triggered the event\n * @param {string} action - The action that was performed (show, hide, show-all, hide-all)\n * @param {boolean} fromFunction - Whether the event was triggered from showAccordion function\n * @private\n */\nfunction _triggerAccordionEvent($item, action) {\n var fromFunction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n var $accordion = $item.closest(\".csd-accordion\");\n var $allItems = $accordion.find(\".csd-accordion-item\");\n var $openItems = $allItems.filter(\".open\");\n\n // Create event object with all details\n var eventData = {\n type: \"csd_accordion_change\",\n // - type: \"csd_accordion_change\"\n action: action,\n // - action: \"show\", \"hide\", \"show-all\", o \"hide-all\"\n fromFunction: fromFunction,\n // - fromFunction: true if the event was triggered from showAccordion function\n targetValue: $item.attr(\"value\"),\n // - targetValue: value of the target element\n isMultiple: $accordion.hasClass(\"multiple\"),\n // - isMultiple: if the accordion is multiple\n totalItems: $allItems.length,\n // - totalItems: total number of items\n openItems: $openItems.length,\n // - openItems: number of open items\n allOpen: $allItems.length === $openItems.length,\n // - allOpen: true if all items are open\n allClosed: $openItems.length === 0,\n // - allClosed: true if all items are closed\n openValues: function () {\n // - openValues: array of open item values\n var array = [];\n $openItems.each(function () {\n array.push($CSD(this).attr(\"value\"));\n });\n return array;\n }()\n };\n\n // Trigger the event using CSD library on the accordion element\n $accordion.trigger(eventData);\n}\n\n/**\n * Destroys an accordion instance, removing all event handlers and data attributes\n * @param {HTMLElement} element - The root DOM element of the accordion\n */\nfunction destroyAccordion(element) {\n if (!element) return;\n var $element = $CSD(element);\n\n // Check if the element is already initialized\n if (!$element.attr('data-csd-accordion-initialized')) {\n return; // Not initialized, nothing to destroy\n }\n\n // Carefully remove only our event listeners\n var $headers = $element.find(\".csd-accordion-header\");\n $headers.each(function () {\n var $header = $CSD(this);\n // Clona il contenuto dell'header senza eventi ma mantenendo i figli\n var $newHeader = $header.clone(false, true);\n // Rimuovi solo l'icona accordion che abbiamo aggiunto\n $newHeader.find(\".csd-accordion-icon\").remove();\n // Sostituisci il vecchio header con quello nuovo (senza eventi)\n $header.replaceWith($newHeader);\n });\n\n // Remove the initialized flag\n $element.removeAttr('data-csd-accordion-initialized');\n}\n\n/**\n * Accordion Component\n * Initializes the accordion behavior on a DOM element\n * @param {HTMLElement} element - The root DOM element of the accordion\n */\nfunction initializeAccordion(element) {\n // Check if element exists, otherwise terminate\n if (!element) return;\n var $element = $CSD(element);\n\n // Check if the element is already initialized\n if ($element.attr('data-csd-accordion-initialized')) {\n // If already initialized, destroy it first\n destroyAccordion(element);\n }\n var $accordionItems = $element.find(\".csd-accordion-item\");\n // Check if the accordion allows multiple items to be open\n var isMultiple = $element.hasClass(\"multiple\");\n\n // Iterate over each accordion item\n $accordionItems.each(function (item) {\n var $item = $CSD(item);\n // Find the header of the current item\n var $header = $item.find(\".csd-accordion-header\");\n // Create chevron icon using ion-icons\n var $icon = $CSD('<ion-icon name=\"chevron-down-outline\" class=\"csd-accordion-icon\"></ion-icon>');\n\n // If header exists and is not disabled\n if ($header.length && !$header.prop(\"disabled\")) {\n // Add the icon to the header\n $header.append($icon);\n // Add click event handler\n $header.on(\"click\", function () {\n // Find the closest accordion-item to the clicked header\n var $currentItem = $CSD(this).closest(\".csd-accordion-item\");\n\n // If multiple open items are not allowed, close all other items\n if (!isMultiple) {\n $accordionItems.not($currentItem).removeClass(\"open\");\n }\n\n // Toggle the 'open' class on the current item\n $currentItem.toggleClass(\"open\");\n\n // Trigger event with the new state\n _triggerAccordionEvent($currentItem, $currentItem.hasClass(\"open\") ? \"show\" : \"hide\");\n });\n }\n });\n\n // Mark the element as initialized\n $element.attr('data-csd-accordion-initialized', 'true');\n}\n\n/**\n * Function to handle accordion actions\n * @param {string} param - Action parameter:\n * - 'show-all': Opens all items in multiple accordion\n * - 'hide-all': Closes all items in multiple accordion\n * - any other value: Toggles item with matching value attribute\n * @throws {TypeError} When parameter is missing or of wrong type\n * @throws {ReferenceError} When required elements are not found\n * @throws {SyntaxError} When action is not allowed for accordion type\n */\nfunction showAccordion(param) {\n try {\n // Validate input parameter type\n if (!param || typeof param !== \"string\" && typeof param !== \"number\") {\n throw new TypeError(\"Missing or invalid parameter type for showAccordion function\");\n }\n\n // Get all accordion items with value attribute\n var $items = $CSD(\".csd-accordion-item[value]\");\n if ($items.length === 0) {\n throw new ReferenceError(\"No accordion items found with value attribute\");\n }\n\n // Normalize param by removing quotes if present\n var normalizedParam = param.replace(/^['\"](.+)['\"]$/, \"$1\");\n\n // Handle show-all action\n if (normalizedParam === \"show-all\") {\n var $multipleItems = $items.filter(function () {\n return $CSD(this).closest(\".csd-accordion\").hasClass(\"multiple\");\n });\n if ($multipleItems.length === 0) {\n throw new ReferenceError(\"show-all is not allowed for single-accordion\");\n }\n $multipleItems.addClass(\"open\");\n // Trigger event for show-all\n _triggerAccordionEvent($multipleItems.first(), \"show-all\", true);\n return;\n }\n\n // Handle hide-all action\n if (normalizedParam === \"hide-all\") {\n var _$multipleItems = $items.filter(function () {\n return $CSD(this).closest(\".csd-accordion\").hasClass(\"multiple\");\n });\n if (_$multipleItems.length === 0) {\n throw new ReferenceError(\"hide-all is not allowed for single-accordion\");\n }\n _$multipleItems.removeClass(\"open\");\n // Trigger event for hide-all\n _triggerAccordionEvent(_$multipleItems.first(), \"hide-all\", true);\n return;\n }\n\n // Handle individual item toggle\n var $item = $CSD(\".csd-accordion-item\").filter(\"[value=\\\"\".concat(normalizedParam, \"\\\"]\"));\n if ($item.length === 0) {\n throw new ReferenceError(\"No accordion item found with value \\\"\".concat(normalizedParam, \"\\\"\"));\n }\n\n // Get accordion type and handle toggle\n var isMultiple = $item.closest(\".csd-accordion\").hasClass(\"multiple\");\n if (!isMultiple) {\n $items.not($item).removeClass(\"open\");\n }\n\n // Toggle the item and trigger event\n var wasOpen = $item.hasClass(\"open\");\n $item.toggleClass(\"open\");\n _triggerAccordionEvent($item, wasOpen ? \"hide\" : \"show\", true);\n } catch (error) {\n if (error instanceof TypeError || error instanceof ReferenceError || error instanceof SyntaxError) {\n throw error;\n }\n throw new Error(\"Accordion error: \".concat(error.message));\n }\n}\n\n\n//# sourceURL=webpack://$CSD/./component/csd-accordion.js?");
/***/ }),
/***/ "./component/csd-button.js":
/*!*********************************!*\
!*** ./component/csd-button.js ***!
\*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ destroyBtn: () => (/* binding */ destroyBtn),\n/* harmony export */ initializeBtn: () => (/* binding */ initializeBtn)\n/* harmony export */ });\n/* harmony import */ var _csd_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../csd-lib */ \"./csd-lib.js\");\n/* harmony import */ var _csd_lib__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_csd_lib__WEBPACK_IMPORTED_MODULE_0__);\n\n\n/**\n * Destroys a button instance, removing all event handlers and restoring original state\n * @param {HTMLElement} buttonElement - The button element to destroy\n */\nfunction destroyBtn(buttonElement) {\n if (!buttonElement) return null;\n var $btn = (0,_csd_lib__WEBPACK_IMPORTED_MODULE_0__.$CSD)(buttonElement);\n\n // Check if the element is already initialized\n if (!$btn.attr('data-csd-btn-initialized')) {\n return buttonElement; // Not initialized, return original element\n }\n\n // Ripristina il testo originale se salvato\n var originalText = $btn.attr('data-original-text');\n if (originalText) {\n $btn.text(originalText);\n }\n\n // Remove event listeners by cloning the element\n var $newBtn = $btn.clone(false, true);\n $btn.replaceWith($newBtn);\n\n // Disconnetti l'osservatore se presente\n if (buttonElement._csdBtnObserver) {\n buttonElement._csdBtnObserver.disconnect();\n delete buttonElement._csdBtnObserver;\n }\n\n // Remove the initialized flag and other data attributes\n $newBtn.removeAttr('data-csd-btn-initialized');\n $newBtn.removeAttr('data-original-text');\n $newBtn.removeAttr('data-current-icon');\n $newBtn.removeAttr('data-current-badge');\n $newBtn.removeAttr('data-current-place-icon');\n\n // Return the new element\n return $newBtn.elements[0];\n}\n\n/**\n * Triggers a custom button event with detailed state information\n * @param $btn - The button item that triggered the event\n * @private\n */\nfunction _triggerButtonEvent($btn) {\n // Create event object with all details\n var eventData = {\n type: \"csd_click\",\n // - type: \"csd_btn_click\"\n action: \"click\",\n // - action: \"click\", \"hide\", \"show-all\", o \"hide-all\"\n item: $btn // - item triggered\n };\n\n // Trigger the event using CSD library on the button element\n $btn.trigger(eventData);\n}\nfunction initializeBtn(btnElement) {\n // Check if element exists, otherwise terminate\n if (!btnElement) return;\n var $btn = (0,_csd_lib__WEBPACK_IMPORTED_MODULE_0__.$CSD)(btnElement);\n\n // Check if the element is already initialized\n if ($btn.attr('data-csd-btn-initialized')) {\n // If already initialized, destroy it first and get the new element\n var newElement = destroyBtn(btnElement);\n if (!newElement) return; // Destroy failed\n btnElement = newElement;\n $btn = (0,_csd_lib__WEBPACK_IMPORTED_MODULE_0__.$CSD)(btnElement);\n }\n var originalText = $btn.text();\n\n // Salva il testo originale per il destroy\n if (!$btn.attr('data-original-text')) {\n $btn.attr('data-original-text', originalText);\n }\n if ($btn.attr('icon')) {\n var attrIcon = $btn.attr('icon');\n var type = attrIcon.split('-', 1)[0];\n var newContentBTN;\n switch (type) {\n case 'ion':\n var ionIconData = attrIcon.split('-');\n var ionIcon = attrIcon.slice(type.length + 1);\n newContentBTN = \"<ion-icon name=\\\"\".concat(ionIcon, \"\\\"></ion-icon>\");\n if ($btn.attr('place-icon') == \"left\") {\n $btn.html(newContentBTN).append(originalText);\n } else {\n $btn.append(newContentBTN);\n }\n break;\n case 'fa':\n var faIconData = attrIcon.split('-');\n var faIcon = attrIcon.slice(type.length + 1 + faIconData[1].length + 1);\n newContentBTN = \"<i class=\\\"fa-\".concat(faIconData[1], \" fa-\").concat(faIcon, \"\\\"></i>\");\n if ($btn.attr('place-icon') == \"left\") {\n $btn.html(newContentBTN).append(originalText);\n } else {\n $btn.append(newContentBTN);\n }\n break;\n }\n }\n if ($btn.attr('badge')) {\n var badgeValue = $btn.attr('badge');\n var badgeItem = \"<span class=\\\"csd-badge\\\">\".concat(badgeValue, \"</span>\");\n $btn.append(badgeItem);\n }\n $btn.on('click', function () {\n _triggerButtonEvent($btn);\n });\n\n // Salva i valori correnti degli attributi per il confronto\n var currentIcon = $btn.attr('icon') || '';\n var currentBadge = $btn.attr('badge') || '';\n var currentPlaceIcon = $btn.attr('place-icon') || '';\n $btn.attr('data-current-icon', currentIcon);\n $btn.attr('data-current-badge', currentBadge);\n $btn.attr('data-current-place-icon', currentPlaceIcon);\n\n // Configura l'osservatore di attributi per reinizializzazione automatica\n if (typeof MutationObserver !== 'undefined') {\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n if (mutation.type === 'attributes') {\n var attrName = mutation.attributeName;\n\n // Controlla se sono cambiati gli attributi che ci interessano\n if (['icon', 'badge', 'place-icon'].includes(attrName)) {\n var currentValue = $btn.attr(attrName) || '';\n var savedValue = $btn.attr(\"data-current-\".concat(attrName)) || '';\n\n // Se il valore è cambiato, reinizializza\n if (currentValue !== savedValue) {\n // Usa setTimeout per evitare loop infiniti durante l'aggiornamento\n setTimeout(function () {\n initializeBtn(btnElement);\n }, 0);\n }\n }\n }\n });\n });\n\n // Osserva i cambiamenti agli attributi\n observer.observe(btnElement, {\n attributes: true,\n attributeFilter: ['icon', 'badge', 'place-icon']\n });\n\n // Salva l'observer per poterlo disconnettere durante il destroy\n btnElement._csdBtnObserver = observer;\n }\n\n // Mark the element as initialized\n $btn.attr('data-csd-btn-initialized', 'true');\n}\n\n\n//# sourceURL=webpack://$CSD/./component/csd-button.js?");
/***/ }),
/***/ "./component/csd-checkbox.js":
/*!***********************************!*\
!*** ./component/csd-checkbox.js ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getCheckboxValues: () => (/* binding */ getCheckboxValues),\n/* harmony export */ initializeCheckbox: () => (/* binding */ initializeCheckbox)\n/* harmony export */ });\n/**\n * Triggers a custom checkbox event with detailed state information\n * @param $checkbox - The checkbox item that triggered the event\n * @private\n */\nfunction _triggerCheckboxEvent($checkbox) {\n // Create event object with all details\n var $wrapper = $checkbox.closest(\".csd-field\");\n var $allItems = $wrapper.find(\".csd-checkbox-input\");\n var $checkedItems = $allItems.find(\".csd-checkbox-input:checked\");\n var eventData = {\n type: \"csd_change\",\n // - type: \"change\"\n action: \"change\",\n // - action: \"change\"\n item: $checkbox,\n // - item triggered\n targetValue: $checkbox.attr(\"value\"),\n // - targetValue: value of the target element\n totalItems: $allItems.length,\n // - totalItems: total number of items\n checkedItems: $checkedItems.length,\n // - checkedItems: number of checked items\n allChecked: $allItems.length === $checkedItems.length,\n // - allChecked: true if all items are checked\n allUnchecked: $checkedItems.length === 0,\n // - allUnchecked: true if all items are unchecked\n checkedValues: function () {\n // - checkedValues: array of checked item values\n var array = [];\n $checkedItems.each(function () {\n array.push($CSD(this).attr(\"value\"));\n });\n return array;\n }()\n };\n\n // Trigger the event using CSD library on the button element\n $checkbox.trigger(eventData);\n}\nfunction initializeCheckbox(checkboxElement) {\n var $originalCheckbox = $CSD(checkboxElement);\n var label = $originalCheckbox.attr(\"label\") || \"\";\n var id = $originalCheckbox.attr(\"id\") || \"checkbox-\" + Math.random().toString(36).substr(2, 9);\n var $wrapper = $CSD('<div class=\"csd-checkbox-wrapper\"></div>');\n var $checkbox = $CSD('<div class=\"csd-checkbox\"></div>');\n var $input = $CSD('<input type=\"checkbox\" class=\"csd-checkbox-input\">').attr(\"id\", id);\n var $box = $CSD('<div class=\"csd-checkbox-box\"><ion-icon name=\"checkmark-sharp\"></ion-icon></div>');\n\n // Copia le proprietà dall'originale\n if ($originalCheckbox.elements[0].checked) $input.elements[0].checked = true;\n if ($originalCheckbox.elements[0].disabled) $input.elements[0].disabled = true;\n if ($originalCheckbox.attr(\"name\")) $input.attr(\"name\", $originalCheckbox.attr(\"name\"));\n if ($originalCheckbox.attr(\"value\")) $input.attr(\"value\", $originalCheckbox.attr(\"value\"));\n\n // Copia le classi, escludendo csd-checkbox\n var originalClass = $originalCheckbox.attr(\"class\");\n if (originalClass) {\n var newClass = originalClass.split(\" \").filter(function (cls) {\n return cls !== \"csd-checkbox\";\n }).join(\" \");\n if (newClass) $input.addClass(newClass);\n }\n\n // Copia altri attributi\n var originalElement = $originalCheckbox.elements[0];\n for (var i = 0; i < originalElement.attributes.length; i++) {\n var attr = originalElement.attributes[i];\n if (![\"type\", \"class\", \"id\"].includes(attr.name)) {\n $input.attr(attr.name, attr.value);\n }\n }\n $checkbox.append($input);\n $checkbox.append($box);\n $wrapper.append($checkbox);\n if (label) {\n var $label = $CSD('<label class=\"csd-checkbox-label\"></label>').text(label).attr(\"for\", id);\n $wrapper.append($label);\n }\n $originalCheckbox.replaceWith($wrapper);\n $wrapper.find('.csd-checkbox-label').on(\"click\", function (e) {\n e.preventDefault();\n e.stopPropagation();\n if (!$wrapper.find('.csd-checkbox-input').prop(\"disabled\")) {\n var checked = $wrapper.find('.csd-checkbox-input').prop(\"checked\");\n $wrapper.find('.csd-checkbox-input').prop(\"checked\", !checked);\n _triggerCheckboxEvent($wrapper.find('.csd-checkbox-input'));\n }\n });\n $wrapper.find('.csd-checkbox-box').on(\"click\", function (e) {\n e.preventDefault();\n if (!$wrapper.find('.csd-checkbox-input').prop(\"disabled\")) {\n var checked = $wrapper.find('.csd-checkbox-input').prop(\"checked\");\n $wrapper.find('.csd-checkbox-input').prop(\"checked\", !checked);\n _triggerCheckboxEvent($wrapper.find('.csd-checkbox-input'));\n }\n });\n}\n\n// Funzione per ottenere i valori dei checkbox\nfunction getCheckboxValues(name) {\n var values = [];\n var $checkboxes = $CSD(\".csd-checkbox-wrapper input[name=\\\"\".concat(name, \"\\\"]\"));\n $checkboxes.each(function () {\n var $input = $CSD(this);\n values.push({\n value: $input.val() || \"on\",\n checked: $input.elements[0].checked,\n disabled: $input.elements[0].disabled,\n label: $input.closest(\".csd-checkbox-wrapper\").find(\".csd-checkbox-label\").text()\n });\n });\n return values;\n}\n;\n\n// Esponi globalmente solo se window è disponibile\nif (typeof window !== 'undefined') {\n window.getCheckboxValues = getCheckboxValues;\n}\n\n\n//# sourceURL=webpack://$CSD/./component/csd-checkbox.js?");
/***/ }),
/***/ "./component/csd-datepicker.js":
/*!*************************************!*\
!*** ./component/csd-datepicker.js ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ initializeDatepickers: () => (/* binding */ initializeDatepickers)\n/* harmony export */ });\n/* harmony import */ var _csd_mask_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./csd-mask.js */ \"./component/csd-mask.js\");\nfunction _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(r, a) { if (r) { if (\"string\" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return \"Object\" === t && r.constructor && (t = r.constructor.name), \"Map\" === t || \"Set\" === t ? Array.from(r) : \"Arguments\" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }\nfunction _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(r) { if (Array.isArray(r)) return r; }\n\n\n// Funzione per formattare la data per i preset\nfunction formatPresetDate(date) {\n return date.toLocaleDateString('it-IT', {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric'\n }).split('/').join('/');\n}\n\n// Funzione per posizionare il calendario\nfunction positionCalendar($input, $dropdown) {\n var inputRect = $input[0].getBoundingClientRect();\n var windowHeight = typeof window !== 'undefined' ? window.innerHeight : 800; // Default fallback\n var spaceBelow = windowHeight - inputRect.bottom;\n var calendarHeight = $dropdown[0].offsetHeight;\n\n // Check if there's enough space below for the calendar plus margin\n if (spaceBelow >= calendarHeight + 4) {\n // 4px for margin\n $dropdown.removeClass(\"position-above\").addClass(\"position-below\");\n } else {\n $dropdown.removeClass(\"position-below\").addClass(\"position-above\");\n }\n}\nfunction initializeDatepickers() {\n console.log(\"Initializing datepickers...\");\n\n // Inizializza il date range preset\n $CSD(\".csd-datepicker-range-preset\").each(function () {\n var $input = $CSD(this);\n\n // Crea il wrapper per il dropdown\n var $wrapper = $CSD('<div class=\"csd-select-container position-relative\"></div>');\n $input.wrap($wrapper);\n $input.prop(\"readonly\", true);\n\n // Crea il dropdown\n var $dropdown = $CSD('<div class=\"csd-select-options\"></div>');\n var options = [{\n label: \"Ultima settimana\",\n value: \"week\"\n }, {\n label: \"Ultimo mese\",\n value: \"month\"\n }, {\n label: \"Ultimi 3 mesi\",\n value: \"threeMonths\"\n }, {\n label: \"Ultimo anno\",\n value: \"year\"\n }, {\n label: \"Da inizio anno\",\n value: \"ytd\"\n }, {\n label: \"Personalizzato\",\n value: \"custom\"\n }];\n options.forEach(function (option) {\n var $option = $CSD(\"<div class=\\\"csd-select-option\\\" data-value=\\\"\".concat(option.value, \"\\\">\").concat(option.label, \"</div>\"));\n $dropdown.append($option);\n });\n $input.after($dropdown);\n\n // Gestisci il click sull'input\n $input.on(\"click\", function (e) {\n e.stopPropagation();\n $CSD(\".csd-select-options\").not($dropdown).hide();\n if (!$dropdown.hasClass(\"visible\")) {\n $dropdown.addClass(\"visible\");\n positionCalendar($input, $dropdown);\n }\n });\n\n // Gestisci la selezione delle opzioni\n $dropdown.on(\"click\", \".csd-select-option\", function (e) {\n e.stopPropagation();\n var value = $CSD(this).data(\"value\");\n $CSD(this).addClass(\"selected\");\n var today = new Date();\n var startDate, endDate;\n switch (value) {\n case \"week\":\n endDate = new Date(today);\n startDate = new Date(today);\n startDate.setDate(startDate.getDate() - 7);\n break;\n case \"month\":\n endDate = new Date(today);\n startDate = new Date(today);\n startDate.setMonth(startDate.getMonth() - 1);\n break;\n case \"threeMonths\":\n endDate = new Date(today);\n startDate = new Date(today);\n startDate.setMonth(startDate.getMonth() - 3);\n break;\n case \"year\":\n endDate = new Date(today);\n startDate = new Date(today);\n startDate.setFullYear(startDate.getFullYear() - 1);\n break;\n case \"ytd\":\n endDate = new Date(today);\n startDate = new Date(today.getFullYear(), 0, 1);\n break;\n case \"custom\":\n // Per l'opzione custom, aggiungiamo le classi necessarie\n $input.removeClass(\"csd-datepicker-range-preset\").addClass(\"csd-datepicker\").addClass(\"multi-months\").attr(\"data-range\", \"true\").attr(\"data-from-preset\", \"true\");\n\n // Rimuovi l'evento click esistente per evitare loop\n $input.off(\"click\");\n\n // Reinizializza i datepicker per applicare le nuove classi\n initializeDatepickers();\n\n // Nascondi il dropdown e triggera il click per aprire il calendario\n $dropdown.hide();\n $input.trigger(\"click\");\n return;\n }\n if (startDate && endDate) {\n var formattedStart = formatPresetDate(startDate);\n var formattedEnd = formatPresetDate(endDate);\n $input.val(\"\".concat(formattedStart, \" - \").concat(formattedEnd));\n }\n $dropdown.removeClass(\"visible\");\n });\n\n // Chiudi il dropdown quando si clicca fuori\n $CSD(document).on(\"click\", function (e) {\n if (!$CSD(e.target).closest(\".csd-select-container\").length) {\n $dropdown.removeClass(\"visible\");\n }\n });\n });\n\n // Inizializza i datepicker standard\n var $datepickers = $CSD(\".csd-datepicker:not(.csd-datepicker-range-preset), .csd-datetimepicker\");\n $datepickers.each(function () {\n var $input = $CSD(this);\n var isRange = $input.attr(\"data-range\") === \"true\";\n var isDateTimePicker = $input.hasClass(\"csd-datetimepicker\");\n var format = $input.attr(\"data-format\") || (isDateTimePicker ? \"DD/MM/YYYY HH:mm\" : \"DD/MM/YYYY\");\n var isManualInput = $input.attr(\"data-manual-input\") === \"true\";\n var multiple = $input.attr(\"data-multiple\") === \"true\";\n var showClearBtn = $input.attr(\"btn-clear\");\n var showTodayBtn = $input.attr(\"btn-today\");\n var minDate = $input.attr(\"min-date\") ? new Date($input.attr(\"min-date\")) : null;\n var maxDate = $input.attr(\"max-date\") ? new Date($input.attr(\"max-date\")) : null;\n var isPresetRange = $input.hasClass(\"csd-datepicker-range-preset\");\n var isFromPreset = $input.attr(\"data-from-preset\") === \"true\";\n\n // Rendi l'input readonly solo se non è manuale\n $input.prop(\"readonly\", !isManualInput);\n\n // Array per date multiple\n var selectedDates = [];\n\n // Funzione per aggiornare il valore dell'input con date multiple\n function updateMultipleInput() {\n if (multiple) {\n var formattedDates = selectedDates.sort(function (a, b) {\n return a - b;\n }).map(function (date) {\n return formatDate(date, format);\n });\n $input.val(formattedDates.join(\", \"));\n $input.trigger(\"change\");\n }\n }\n\n // Se è abilitato l'input manuale, aggiungi la validazione della maschera\n if (isManualInput) {\n var singleDateMask = format.replace(/YYYY/g, \"9999\").replace(/MM/g, \"19\").replace(/DD/g, \"39\").replace(/HH/g, \"29\").replace(/mm/g, \"59\");\n var dateMask = isRange ? \"\".concat(singleDateMask, \" - \").concat(singleDateMask) : singleDateMask;\n $input.attr(\"data-mask\", dateMask);\n (0,_csd_mask_js__WEBPACK_IMPORTED_MODULE_0__.initializeMask)($input.elements[0]);\n\n // Gestione dell'input manuale\n $input.on(\"change\", function () {\n var value = $input.val();\n if (isRange) {\n var _value$split$map = value.split(\"-\").map(function (s) {\n return s.trim();\n }),\n _value$split$map2 = _slicedToArray(_value$split$map, 2),\n startStr = _value$split$map2[0],\n endStr = _value$split$map2[1];\n var startDate = parseDate(startStr, format);\n var endDate = parseDate(endStr, format);\n if (startDate && endDate) {\n selectedDate = startDate;\n selectedEndDate = endDate;\n currentDate = new Date(startDate);\n renderCalendar();\n }\n } else if (multiple) {\n var dateStrings = value.split(\",\").map(function (s) {\n return s.trim();\n });\n selectedDates = dateStrings.map(function (dateStr) {\n return parseDate(dateStr, format);\n }).filter(function (date) {\n return date !== null;\n });\n if (selectedDates.length > 0) {\n currentDate = new Date(selectedDates[0]);\n }\n renderCalendar();\n } else {\n var date = parseDate(value, format);\n if (date) {\n selectedDate = date;\n currentDate = new Date(date);\n if (isDateTimePicker) {\n selectedHours = date.getHours();\n selectedMinutes = date.getMinutes();\n }\n renderCalendar();\n }\n }\n });\n }\n\n // Funzione helper per il parsing delle date\n function parseDate(dateStr, format) {\n if (!dateStr) return null;\n var formatParts = format.match(/[A-Za-z]+/g);\n var valueParts = dateStr.match(/\\d+/g);\n if (!valueParts || valueParts.length !== formatParts.length) return null;\n var year,\n month,\n day,\n hours = 0,\n minutes = 0;\n formatParts.forEach(function (part, index) {\n var value = parseInt(valueParts[index]);\n switch (part) {\n case \"YYYY\":\n year = value;\n break;\n case \"MM\":\n month = value - 1;\n break;\n case \"DD\":\n day = value;\n break;\n case \"HH\":\n hours = value;\n break;\n case \"mm\":\n minutes = value;\n break;\n }\n });\n var date = new Date(year, month, day, hours, minutes);\n return isNaN(date.getTime()) ? null : date;\n }\n\n // Crea il wrapper del calendario\n var $wrapper = multiple ? $CSD('<div class=\"csd-datepicker-wrapper csd-datepicker-wrapper-multiple\" style=\"display: none;\"></div>') : $CSD('<div class=\"csd-datepicker-wrapper\" style=\"display: none;\"></div>');\n $input.after($wrapper);\n\n // Stato del calendario\n var currentDate = new Date();\n var selectedDate = null;\n var selectedEndDate = null;\n var selecting = false;\n var showMonthSelect = false;\n var showYearSelect = false;\n var selectedHours = currentDate.getHours();\n var selectedMinutes = currentDate.getMinutes();\n\n // Se c'è un valore iniziale, usalo\n if ($input.val()) {\n var initialDate = new Date($input.val());\n if (!isNaN(initialDate.getTime())) {\n selectedDate = initialDate;\n selectedHours = initialDate.getHours();\n selectedMinutes = initialDate.getMinutes();\n }\n }\n\n // Array per i mesi e giorni abbreviati in inglese\n var months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n var weekdays = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\n // Funzione per formattare la data\n function formatDate(date) {\n var customFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : format;\n if (!date) return \"\";\n var year = date.getFullYear();\n var month = String(date.getMonth() + 1).padStart(2, \"0\");\n var day = String(date.getDate()).padStart(2, \"0\");\n var hours = String(selectedHours).padStart(2, \"0\");\n var minutes = String(selectedMinutes).padStart(2, \"0\");\n return customFormat.replace(\"YYYY\", year).replace(\"MM\", month).replace(\"DD\", day).replace(\"HH\", hours).replace(\"mm\", minutes);\n }\n\n // Funzione per aggiornare l'input\n function updateInput() {\n if (isRange && selectedDate && selectedEndDate) {\n $input.val(\"\".concat(formatDate(selectedDate), \" - \").concat(formatDate(selectedEndDate)));\n currentDate = new Date(selectedDate);\n } else if (selectedDate) {\n $input.val(formatDate(selectedDate));\n currentDate = new Date(selectedDate);\n } else {\n $input.val(\"\");\n }\n }\n\n // Funzione per verificare se una data è selezionabile\n function isDateSelectable(date) {\n if (minDate && date < minDate) return false;\n if (maxDate && date > maxDate) return false;\n return true;\n }\n\n // Funzione per verificare se una data è nel range\n function isInRange(date) {\n if (!isRange || !selectedDate || !selectedEndDate) return false;\n return date > selectedDate && date < selectedEndDate;\n }\n\n // Funzione per ottenere il primo giorno del mese\n function getFirstDayOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n }\n\n // Funzione per ottenere l'ultimo giorno del mese\n function getLastDayOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0);\n }\n\n // Funzione per ottenere i giorni del mese precedente\n function getPrevMonthDays(firstDay) {\n var prevMonth = new Date(firstDay);\n prevMonth.setMonth(prevMonth.getMonth() - 1);\n var lastDayPrevMonth = getLastDayOfMonth(prevMonth);\n var startingDay = firstDay.getDay() || 7; // Converte 0 (domenica) in 7\n var days = [];\n for (var i = startingDay - 1; i > 0; i--) {\n var day = new Date(lastDayPrevMonth);\n day.setDate(lastDayPrevMonth.getDate() - i + 1);\n days.push(day);\n }\n return days;\n }\n\n // Funzione per ottenere i giorni del mese successivo\n function getNextMonthDays(lastDay, totalCells) {\n var nextMonth = new Date(lastDay);\n nextMonth.setMonth(nextMonth.getMonth() + 1);\n var days = [];\n var dayCount = 1;\n while (days.length + totalCells < 42) {\n var day = new Date(nextMonth);\n day.setDate(dayCount);\n days.push(day);\n dayCount++;\n }\n return days;\n }\n\n // Funzione per confrontare le date (solo giorno/mese/anno)\n function isSameDay(date1, date2) {\n return date1 && date2 && date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();\n }\n\n // Funzione per renderizzare il selettore dei mesi\n function renderMonthSelect() {\n var html = '<div class=\"month-select\">';\n months.forEach(function (month, index) {\n var isSelected = index === currentDate.getMonth() ? \"\" : \"\";\n html += \"<button type=\\\"button\\\" class=\\\"month-option \".concat(isSelected, \"\\\" data-month=\\\"\").concat(index, \"\\\">\").concat(month, \"</button>\");\n });\n html += \"</div>\";\n return html;\n }\n\n // Funzione per renderizzare il selettore degli anni\n function renderYearSelect() {\n var currentYear = currentDate.getFullYear();\n var startYear = currentYear - 10;\n var endYear = currentYear + 10;\n var html = '<div class=\"year-select\">';\n for (var year = startYear; year <= endYear; year++) {\n var isSelected = year === currentYear ? \"\" : \"\";\n html += \"<button type=\\\"button\\\" class=\\\"year-option \".concat(isSelected, \"\\\" data-year=\\\"\").concat(year, \"\\\">\").concat(year, \"</button>\");\n }\n html += \"</div>\";\n return html;\n }\n\n // Funzione per renderizzare il selettore dell'ora\n function renderTimeSelect() {\n if (!isDateTimePicker) return \"\";\n return \"\\n <div class=\\\"time-select\\\">\\n <div class=\\\"time-field\\\">\\n <div class=\\\"time-spinner\\\">\\n <button type=\\\"button\\\" class=\\\"time-btn hour-up\\\">∧</button>\\n <input type=\\\"text\\\" class=\\\"time-input hour-input\\\" value=\\\"\".concat(String(selectedHours).padStart(2, \"0\"), \"\\\" readonly>\\n <button type=\\\"button\\\" class=\\\"time-btn hour-down\\\">∨</button>\\n </div>\\n </div>\\n <div class=\\\"time-separator\\\">:</div>\\n <div class=\\\"time-field\\\">\\n <div class=\\\"time-spinner\\\">\\n <button type=\\\"button\\\" class=\\\"time-btn minute-up\\\">∧</button>\\n <input type=\\\"text\\\" class=\\\"time-input minute-input\\\" value=\\\"\").concat(String(selectedMinutes).padStart(2, \"0\"), \"\\\" readonly>\\n <button type=\\\"button\\\" class=\\\"time-btn minute-down\\\">∨</button>\\n </div>\\n </div>\\n </div>\\n \");\n }\n\n // Funzione per renderizzare il calendario\n function renderCalendar() {\n var firstDay = getFirstDayOfMonth(currentDate);\n var lastDay = getLastDayOfMonth(currentDate);\n var daysInMonth = lastDay.getDate();\n var isMultiMonths = $input.hasClass(\"multi-months\");\n var html = \"\";\n\n // Se è multi-months, renderizza due calendari\n if (isMultiMonths) {\n html += '<div class=\"datepicker-multi-months\">';\n\n // Primo calendario (mese corrente)\n html += '<div class=\"datepicker-month\">';\n html += renderSingleMonth(currentDate, true, false);\n html += \"</div>\";\n\n // Secondo calendario (mese successivo)\n var nextMonth = new Date(currentDate);\n nextMonth.setMonth(nextMonth.getMonth() + 1);\n html += '<div class=\"datepicker-month\">';\n html += renderSingleMonth(nextMonth, false, true);\n html += \"</div>\";\n html += \"</div>\";\n } else {\n html += renderSingleMonth(currentDate, true, true);\n }\n\n // Aggiungi il selettore dell'ora se è un datetime picker\n html += renderTimeSelect();\n if (showClearBtn || showTodayBtn) {\n // Aggiungi i pulsanti Today e Clear\n html += \"\\n <div class=\\\"datepicker-footer\\\">\\n \".concat(showClearBtn && showClearBtn != \"false\" ? '<button type=\"button\" class=\"action-btn clear-btn\">' + (showClearBtn && showClearBtn != \"true\" ? showClearBtn : \"Clear\") + \"</button>\" : \"\", \"\\n \").concat(showTodayBtn && showTodayBtn != \"false\" ? '<button type=\"button\" class=\"action-btn today-btn\">' + (showTodayBtn && showTodayBtn != \"true\" ? showTodayBtn : \"Today\") + \"</button>\" : \"\", \"\\n </div>\\n \");\n }\n\n // Aggiungi il pulsante \"Indietro\" se il calendario viene da un preset\n if (isFromPreset) {\n html += \"\\n <div class=\\\"datepicker-footer\\\">\\n <button type=\\\"button\\\" class=\\\"action-btn back-btn\\\">Indietro</button>\\n </div>\\n \";\n }\n $wrapper.html(html);\n }\n\n // Funzione per renderizzare un singolo mese\n function renderSingleMonth(date) {\n var showPrevButton = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var showNextButton = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n var firstDay = getFirstDayOfMonth(date);\n var lastDay = getLastDayOfMonth(date);\n var daysInMonth = lastDay.getDate();\n var html = \"\\n <div class=\\\"datepicker-header\\\">\\n \".concat(showPrevButton ? '<button type=\"button\" class=\"nav-btn prev-month\"><</button>' : \"\", \"\\n <div class=\\\"month-year-select\\\">\\n <button type=\\\"button\\\" class=\\\"month-btn\\\">\").concat(months[date.getMonth()], \"</button>\\n <button type=\\\"button\\\" class=\\\"year-btn\\\">\").concat(date.getFullYear(), \"</button>\\n </div>\\n \").concat(showNextButton ? '<button type=\"button\" class=\"nav-btn next-month\">></button>' : \"\", \"\\n </div>\");\n\n // Aggiungi i selettori se sono visibili\n if (showMonthSelect) {\n html += renderMonthSelect();\n return html;\n }\n if (showYearSelect) {\n html += renderYearSelect();\n return html;\n }\n html += '<div class=\"datepicker-grid\">';\n\n // Giorni della settimana\n weekdays.forEach(function (day) {\n html += \"<div class=\\\"weekday\\\">\".concat(day, \"</div>\");\n });\n\n // Giorni del mese precedente\n var prevMonthDays = getPrevMonthDays(firstDay);\n prevMonthDays.forEach(function (date) {\n html += \"<div class=\\\"day other-month\\\" data-date=\\\"\".concat(formatDate(date, \"YYYY-MM-DD\"), \"\\\">\").concat(date.getDate(), \"</div>\");\n });\n\n // Giorni del mese corrente\n var _loop = function _loop() {\n var currentDate = new Date(date.getFullYear(), date.getMonth(), day);\n var isToday = isSameDay(currentDate, new Date());\n var isSelected = isSameDay(currentDate, selectedDate);\n var isEndDate = isSameDay(currentDate, selectedEndDate);\n var inRange = isInRange(currentDate);\n var selectable = isDateSelectable(currentDate);\n var isMultipleSelected = multiple && selectedDates.some(function (d) {\n return isSameDay(d, currentDate);\n });\n var classes = [\"day\", isToday ? \"today\" : \"\", isSelected ? isRange ? \"selected start\" : \"selected\" : \"\", isEndDate ? \"selected end\" : \"\", inRange ? \"in-range\" : \"\", isMultipleSelected ? \"selected\" : \"\", !selectable ? \"disabled\" : \"\"].filter(Boolean).join(\" \");\n html += \"<div class=\\\"\".concat(classes, \"\\\" data-date=\\\"\").concat(formatDate(currentDate, \"YYYY-MM-DD\"), \"\\\">\").concat(day, \"</div>\");\n };\n for (var day = 1; day <= daysInMonth; day++) {\n _loop();\n }\n\n // Giorni del mese successivo\n var totalCells = prevMonthDays.length + daysInMonth;\n var nextMonthDays = getNextMonthDays(lastDay, totalCells);\n nextMonthDays.forEach(function (date) {\n html += \"<div class=\\\"day other-month\\\" data-date=\\\"\".concat(formatDate(date, \"YYYY-MM-DD\"), \"\\\">\").concat(date.getDate(), \"</div>\");\n });\n html += \"</div>\";\n return html;\n }\n if (isManualInput) {\n // Togliere l'attributo readonly\n $input.prop(\"readonly\", false);\n $input.on(\"input\", function () {\n var inputValue = this.value.trim();\n var isValidFormat = inputValue.length === format.length && inputValue.split(\"\").every(function (_char, index) {\n if (format[index] === \"D\" || format[index] === \"M\" || format[index] === \"Y\") {\n return /\\d/.test(_char);\n }\n return _char === format[index];\n });\n if (isValidFormat) {\n var _inputValue$split$map = inputValue.split(\"/\").map(Number),\n _inputValue$split$map2 = _slicedToArray(_inputValue$split$map, 3),\n day = _inputValue$split$map2[0],\n month = _inputValue$split$map2[1],\n year = _inputValue$split$map2[2];\n var inputDate = new Date(year, month - 1, day);\n if (inputDate.getDate() === day && inputDate.getMonth() === month - 1 && inputDate.getFullYear() === year && isDateSelectable(inputDate)) {\n currentDate = inputDate;\n selectedDate = inputDate;\n updateInput();\n renderCalendar();\n } else {\n $input.addClass(\"error\");\n }\n } else {\n $input.addClass(\"error\");\n }\n });\n }\n\n // Event handlers\n $input.on(\"click\", function (e) {\n e.stopPropagation();\n $CSD(\".csd-datepicker-wrapper\").not($wrapper).hide();\n $wrapper.toggle();\n if ($wrapper.is(\":visible\")) {\n showMonthSelect = false;\n showYearSelect = false;\n renderCalendar();\n positionCalendar($input, $wrapper);\n } else {}\n });\n\n // Aggiorna la posizione quando la finestra viene ridimensionata\n $CSD(window).on(\"resize\", function () {\n if ($wrapper.is(\":visible\")) {\n positionCalendar($input, $wrapper);\n }\n });\n\n // Aggiorna la posizione quando si fa scroll\n $CSD(window).on(\"scroll\", function () {\n if ($wrapper.is(\":visible\")) {\n positionCalendar($input, $wrapper);\n }\n });\n $wrapper.on(\"click\", \".prev-month\", function (e) {\n e.stopPropagation();\n currentDate.setMonth(currentDate.getMonth() - 1);\n renderCalendar();\n });\n $wrapper.on(\"click\", \".next-month\", function (e) {\n e.stopPropagation();\n currentDate.setMonth(currentDate.getMonth() + 1);\n renderCalendar();\n });\n $wrapper.on(\"click\", \".month-btn\", function (e) {\n e.stopPropagation();\n showMonthSelect = !showMonthSelect;\n showYearSelect = false;\n renderCalendar();\n });\n $wrapper.on(\"click\", \".year-btn\", function (e) {\n e.stopPropagation();\n showYearSelect = !showYearSelect;\n showMonthSelect = false;\n renderCalendar();\n });\n $wrapper.on(\"click\", \".month-option\", function (e) {\n e.stopPropagation();\n var month = parseInt($CSD(this).data(\"month\"));\n currentDate.setMonth(month);\n showMonthSelect = false;\n renderCalendar();\n });\n $wrapper.on(\"click\", \".year-option\", function (e) {\n e.stopPropagation();\n var year = parseInt($CSD(this).data(\"year\"));\n currentDate.setFullYear(year);\n showYearSelect = false;\n renderCalendar();\n });\n $wrapper.on(\"click\", \".day:not(.disabled)\", function (e) {\n e.stopPropagation();\n var dateStr = $CSD(this).data(\"date\");\n var _dateStr$split$map = dateStr.split(\"-\").map(Number),\n _dateStr$split$map2 = _slicedToArray(_dateStr$split$map, 3),\n year = _dateStr$split$map2[0],\n month = _dateStr$split$map2[1],\n day = _dateStr$split$map2[2];\n var date = new Date(year, month - 1, day);\n if (multiple) {\n var existingIndex = selectedDates.findIndex(function (d) {\n return d.getFullYear() === date.getFullYear() && d.getMonth() === date.getMonth() && d.getDate() === date.getDate();\n });\n if (exis