{"version":3,"file":"phoenix.js","sources":["../../../src/js/utils.js","../../../src/js/docs.js","../../../src/js/theme/anchor.js","../../../src/js/theme/bigPicture.js","../../../src/js/theme/fullcalendar.js","../../../src/js/theme/calendar/events.js","../../../src/js/theme/calendar/template.js","../../../src/js/theme/calendar/app-calendar.js","../../../src/js/theme/charts/echarts/echarts-utils.js","../../../src/js/theme/charts/echarts/basic-echarts.js","../../../src/js/theme/charts/echarts/zero-rodamap-chart.js","../../../src/js/theme/chat.js","../../../src/js/theme/choices.js","../../../src/js/theme/countUp.js","../../../src/js/theme/detector.js","../../../src/js/theme/dropzone.js","../../../src/js/theme/featherIcons.js","../../../node_modules/flatpickr/dist/esm/types/options.js","../../../node_modules/flatpickr/dist/esm/l10n/default.js","../../../node_modules/flatpickr/dist/esm/utils/index.js","../../../node_modules/flatpickr/dist/esm/utils/dom.js","../../../node_modules/flatpickr/dist/esm/utils/formatting.js","../../../node_modules/flatpickr/dist/esm/utils/dates.js","../../../node_modules/flatpickr/dist/esm/utils/polyfills.js","../../../node_modules/flatpickr/dist/esm/index.js","../../../src/js/theme/flatpickr.js","../../../src/js/theme/form-validation.js","../../../src/js/theme/glightbox.js","../../../src/js/theme/googleMap.js","../../../src/js/theme/icons.js","../../../src/js/theme/isotope.js","../../../src/js/theme/list.js","../../../src/js/theme/lottie.js","../../../src/js/theme/modal.js","../../../src/js/theme/navbar-combo.js","../../../src/js/theme/navbar-soft-on-scroll.js","../../../src/js/theme/navbar-vertical.js","../../../src/js/theme/phoenix-offcanvas.js","../../../src/js/theme/popover.js","../../../src/js/theme/product-details.js","../../../src/js/theme/quantity.js","../../../src/js/theme/rater.js","../../../src/js/theme/responsiveNavItems.js","../../../src/js/theme/search.js","../../../src/js/theme/simplabar.js","../../../src/js/theme/stop-propagation.js","../../../src/js/theme/swiper.js","../../../src/js/theme/node.js","../../../src/js/theme/theme-control.js","../../../src/js/theme/tinymce.js","../../../src/js/theme/toast.js","../../../src/js/theme/todoOffCanvas.js","../../../src/js/theme/tooltip.js","../../../src/js/theme/wizard.js","../../../src/js/theme/bulk-select.js","../../../src/js/phoenix.js"],"sourcesContent":["/* -------------------------------------------------------------------------- */\n/* Utils */\n/* -------------------------------------------------------------------------- */\nexport const docReady = fn => {\n // see if DOM is already available\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', fn);\n } else {\n setTimeout(fn, 1);\n }\n};\n\nexport const resize = fn => window.addEventListener('resize', fn);\n\nexport const isIterableArray = array => Array.isArray(array) && !!array.length;\n\nexport const camelize = str => {\n const text = str.replace(/[-_\\s.]+(.)?/g, (_, c) =>\n c ? c.toUpperCase() : ''\n );\n return `${text.substr(0, 1).toLowerCase()}${text.substr(1)}`;\n};\n\nexport const getData = (el, data) => {\n try {\n return JSON.parse(el.dataset[camelize(data)]);\n } catch (e) {\n return el.dataset[camelize(data)];\n }\n};\n\n/* ----------------------------- Colors function ---------------------------- */\n\nexport const hexToRgb = hexValue => {\n let hex;\n hexValue.indexOf('#') === 0\n ? (hex = hexValue.substring(1))\n : (hex = hexValue);\n // Expand shorthand form (e.g. \"03F\") to full form (e.g. \"0033FF\")\n const shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(\n hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b)\n );\n return result\n ? [\n parseInt(result[1], 16),\n parseInt(result[2], 16),\n parseInt(result[3], 16)\n ]\n : null;\n};\n\nexport const rgbaColor = (color = '#fff', alpha = 0.5) =>\n `rgba(${hexToRgb(color)}, ${alpha})`;\n\n/* --------------------------------- Colors --------------------------------- */\n\nexport const getColor = (name, dom = document.documentElement) => {\n return getComputedStyle(dom).getPropertyValue(`--phoenix-${name}`).trim();\n};\n\nexport const hasClass = (el, className) => {\n !el && false;\n return el.classList.value.includes(className);\n};\n\nexport const addClass = (el, className) => {\n el.classList.add(className);\n};\n\nexport const getOffset = el => {\n const rect = el.getBoundingClientRect();\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n};\n\nexport const isScrolledIntoView = el => {\n let top = el.offsetTop;\n let left = el.offsetLeft;\n const width = el.offsetWidth;\n const height = el.offsetHeight;\n\n while (el.offsetParent) {\n // eslint-disable-next-line no-param-reassign\n el = el.offsetParent;\n top += el.offsetTop;\n left += el.offsetLeft;\n }\n\n return {\n all:\n top >= window.pageYOffset &&\n left >= window.pageXOffset &&\n top + height <= window.pageYOffset + window.innerHeight &&\n left + width <= window.pageXOffset + window.innerWidth,\n partial:\n top < window.pageYOffset + window.innerHeight &&\n left < window.pageXOffset + window.innerWidth &&\n top + height > window.pageYOffset &&\n left + width > window.pageXOffset\n };\n};\n\nexport const breakpoints = {\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n xxl: 1540\n};\n\nexport const getBreakpoint = el => {\n const classes = el && el.classList.value;\n let breakpoint;\n if (classes) {\n breakpoint =\n breakpoints[\n classes\n .split(' ')\n .filter(cls => cls.includes('navbar-expand-'))\n .pop()\n .split('-')\n .pop()\n ];\n }\n return breakpoint;\n};\n\n/* --------------------------------- Cookie --------------------------------- */\n\nexport const setCookie = (name, value, expire) => {\n const expires = new Date();\n expires.setTime(expires.getTime() + expire);\n document.cookie = name + '=' + value + ';expires=' + expires.toUTCString();\n};\n\nexport const getCookie = name => {\n var keyValue = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');\n return keyValue ? keyValue[2] : keyValue;\n};\n\nexport const settings = {\n tinymce: {\n theme: 'oxide'\n },\n chart: {\n borderColor: 'rgba(255, 255, 255, 0.8)'\n }\n};\n\n/* -------------------------- Chart Initialization -------------------------- */\n\nexport const newChart = (chart, config) => {\n const ctx = chart.getContext('2d');\n return new window.Chart(ctx, config);\n};\n\n/* ---------------------------------- Store --------------------------------- */\n\nexport const getItemFromStore = (key, defaultValue, store = localStorage) => {\n try {\n return JSON.parse(store.getItem(key)) || defaultValue;\n } catch {\n return store.getItem(key) || defaultValue;\n }\n};\n\nexport const setItemToStore = (key, payload, store = localStorage) =>\n store.setItem(key, payload);\nexport const getStoreSpace = (store = localStorage) =>\n parseFloat(\n (\n escape(encodeURIComponent(JSON.stringify(store))).length /\n (1024 * 1024)\n ).toFixed(2)\n );\n\n/* get Dates between */\n\nexport const getDates = (\n startDate,\n endDate,\n interval = 1000 * 60 * 60 * 24\n) => {\n const duration = endDate - startDate;\n const steps = duration / interval;\n return Array.from(\n { length: steps + 1 },\n (v, i) => new Date(startDate.valueOf() + interval * i)\n );\n};\n\nexport const getPastDates = duration => {\n let days;\n\n switch (duration) {\n case 'week':\n days = 7;\n break;\n case 'month':\n days = 30;\n break;\n case 'year':\n days = 365;\n break;\n\n default:\n days = duration;\n }\n\n const date = new Date();\n const endDate = date;\n const startDate = new Date(new Date().setDate(date.getDate() - (days - 1)));\n return getDates(startDate, endDate);\n};\n\n/* Get Random Number */\nexport const getRandomNumber = (min, max) => {\n return Math.floor(Math.random() * (max - min) + min);\n};\n\nexport default {\n docReady,\n resize,\n isIterableArray,\n camelize,\n getData,\n hasClass,\n addClass,\n hexToRgb,\n rgbaColor,\n getColor,\n // getGrays,\n getOffset,\n isScrolledIntoView,\n getBreakpoint,\n setCookie,\n getCookie,\n newChart,\n settings,\n getItemFromStore,\n setItemToStore,\n getStoreSpace,\n getDates,\n getPastDates,\n getRandomNumber\n};\n","import { Collapse, Toast } from 'bootstrap';\n\nconst docComponentInit = () => {\n const componentCards = document.querySelectorAll('[data-component-card]');\n const iconCopiedToast = document.getElementById('icon-copied-toast');\n const iconCopiedToastInstance = new Toast(iconCopiedToast);\n\n componentCards.forEach(card => {\n const copyCodeBtn = card.querySelector('.copy-code-btn');\n const copyCodeEl = card.querySelector('.code-to-copy');\n const previewBtn = card.querySelector('.preview-btn');\n const collapseElement = card.querySelector('.code-collapse');\n const collapseInstance = Collapse.getOrCreateInstance(collapseElement, {\n toggle: false\n });\n\n previewBtn?.addEventListener('click', () => {\n collapseInstance.toggle();\n });\n\n copyCodeBtn?.addEventListener('click', () => {\n const el = document.createElement('textarea');\n el.value = copyCodeEl.innerHTML;\n document.body.appendChild(el);\n\n el.select();\n document.execCommand('copy');\n document.body.removeChild(el);\n\n iconCopiedToast.querySelector(\n '.toast-body'\n ).innerHTML = `Code has been copied to clipboard.
`;\n iconCopiedToastInstance.show();\n });\n });\n};\n\nexport default docComponentInit;\n","// import AnchorJS from 'anchor-js';\n\nconst anchorJSInit = () => {\n const anchors = new window.AnchorJS({\n icon: '#'\n });\n anchors.add('[data-anchor]');\n};\n\nexport default anchorJSInit;\n","/* -------------------------------------------------------------------------- */\n/* bigPicture */\n/* -------------------------------------------------------------------------- */\nconst bigPictureInit = () => {\n const { getData } = window.phoenix.utils;\n if (window.BigPicture) {\n const bpItems = document.querySelectorAll('[data-bigpicture]');\n bpItems.forEach(bpItem => {\n const userOptions = getData(bpItem, 'bigpicture');\n const defaultOptions = {\n el: bpItem,\n noLoader: true,\n allowfullscreen: true\n };\n const options = window._.merge(defaultOptions, userOptions);\n\n bpItem.addEventListener('click', () => {\n window.BigPicture(options);\n });\n });\n }\n};\n\nexport default bigPictureInit;\n","/* -------------------------------------------------------------------------- */\n/* Calendar */\n\n/* -------------------------------------------------------------------------- */\nconst renderCalendar = (el, option) => {\n const { merge } = window._;\n\n const options = merge(\n {\n initialView: 'dayGridMonth',\n editable: true,\n direction: document.querySelector('html').getAttribute('dir'),\n headerToolbar: {\n left: 'prev,next today',\n center: 'title',\n right: 'dayGridMonth,timeGridWeek,timeGridDay'\n },\n buttonText: {\n month: 'Month',\n week: 'Week',\n day: 'Day'\n }\n },\n option\n );\n const calendar = new window.FullCalendar.Calendar(el, options);\n calendar.render();\n document\n .querySelector('.navbar-vertical-toggle')\n ?.addEventListener('navbar.vertical.toggle', () => calendar.updateSize());\n return calendar;\n};\n\nexport const fullCalendarInit = () => {\n const { getData } = window.phoenix.utils;\n\n const calendars = document.querySelectorAll('[data-calendar]');\n calendars.forEach(item => {\n console.log(item);\n const options = getData(item, 'calendar');\n renderCalendar(item, options);\n });\n};\n\nconst fullCalendar = {\n renderCalendar,\n fullCalendarInit\n};\nexport default fullCalendar;\n","const { dayjs } = window;\nconst currentDay = dayjs && dayjs().format('DD');\nconst currentMonth = dayjs && dayjs().format('MM');\nconst prevMonth = dayjs && dayjs().subtract(1, 'month').format('MM');\nconst nextMonth = dayjs && dayjs().add(1, 'month').format('MM');\nconst currentYear = dayjs && dayjs().format('YYYY');\nconst events = [\n {\n title: 'Boot Camp',\n start: `${currentYear}-${currentMonth}-01 10:00:00`,\n end: `${currentYear}-${currentMonth}-03 16:00:00`,\n description:\n \"Boston Harbor Now in partnership with the Friends of Christopher Columbus Park, the Wharf District Council and the City of Boston is proud to announce the New Year's Eve Midnight Harbor Fireworks! This beloved nearly 40-year old tradition is made possible by the generous support of local waterfront organizations and businesses and the support of the City of Boston and the Office of Mayor Marty Walsh.\",\n className: 'text-success',\n location:\n 'Boston Harborwalk, Christopher Columbus Park,
Boston, MA 02109, United States',\n organizer: 'Boston Harbor Now'\n },\n {\n title: `Crain's New York Business `,\n start: `${currentYear}-${currentMonth}-11`,\n description:\n \"Crain's 2020 Hall of Fame. Sponsored Content By Crain's Content Studio. Crain's Content Studio Presents: New Jersey: Perfect for Business. Crain's Business Forum: Letitia James, New York State Attorney General. Crain's NYC Summit: Examining racial disparities during the pandemic\",\n className: 'text-primary'\n },\n {\n title: 'Conference',\n start: `${currentYear}-${currentMonth}-${currentDay}`,\n description:\n 'The Milken Institute Global Conference gathered the best minds in the world to tackle some of its most stubborn challenges. It was a unique experience in which individuals with the power to enact change connected with experts who are reinventing health, technology, philanthropy, industry, and media.',\n className: 'text-success',\n // allDay: true,\n schedules: [\n {\n title: 'Reporting',\n start: `${currentYear}-${currentMonth}-${currentDay} 11:00:00`,\n description:\n 'Time to start the conference and will briefly describe all information about the event. ',\n className: 'text-success '\n },\n {\n title: 'Lunch',\n start: `${currentYear}-${currentMonth}-${currentDay} 14:00:00`,\n description: 'Lunch facility for all the attendance in the conference.',\n className: 'text-info'\n },\n {\n title: 'Contest',\n start: `${currentYear}-${currentMonth}-${currentDay} 16:00:00`,\n description: 'The starting of the programming contest',\n className: 'text-success'\n },\n {\n title: 'Dinner',\n start: `${currentYear}-${currentMonth}-${currentDay} 22:00:00`,\n description: 'Dinner facility for all the attendance in the conference',\n className: 'text-success'\n }\n ]\n },\n {\n title: `ICT Expo ${currentYear} - Product Release`,\n start: `${currentYear}-${currentMonth}-16 10:00:00`,\n description: `ICT Expo ${currentYear} is the largest private-sector exposition aimed at showcasing IT and ITES products and services in Switzerland.`,\n end: `${currentYear}-${currentMonth}-18 16:00:00`,\n className: 'text-warning',\n allDay: true\n },\n {\n title: 'Meeting',\n start: `${currentYear}-${currentMonth}-07 10:00:00`,\n description:\n 'Discuss about the upcoming projects in current year and assign all tasks to the individuals',\n className: 'text-info'\n },\n {\n title: 'Contest',\n start: `${currentYear}-${currentMonth}-14 10:00:00`,\n className: 'text-info',\n description:\n 'PeaceX is an international peace and amity organisation that aims at casting a pall at the striking issues surmounting the development of peoples and is committed to impacting the lives of young people all over the world.'\n },\n {\n title: 'Event With Url',\n start: `${currentYear}-${currentMonth}-23`,\n description:\n 'Sample example of a event with url. Click the event, will redirect to the given link.',\n className: 'text-success',\n url: 'http://google.com'\n },\n {\n title: 'Competition',\n start: `${currentYear}-${currentMonth}-26`,\n description:\n 'The Future of Zambia – Top 30 Under 30 is an annual award, ranking scheme, and recognition platform for young Zambian achievers under the age of 30, who are building brands, creating jobs, changing the game, and transforming the country.',\n className: 'text-danger'\n },\n {\n title: 'Birthday Party',\n start: `${currentYear}-${nextMonth}-05`,\n description: 'Will celebrate birthday party with my friends and family',\n className: 'text-primary'\n },\n {\n title: 'Click for Google',\n url: 'http://google.com/',\n start: `${currentYear}-${prevMonth}-10`,\n description:\n 'Applications are open for the New Media Writing Prize 2020. The New Media Writing Prize (NMWP) showcases exciting and inventive stories and poetry that integrate a variety of formats, platforms, and digital media.',\n className: 'text-primary'\n }\n];\n\nexport default events;\n","const getTemplate = event => `\n
\n by ${event.extendedProps.organizer}\n
`\n : ''\n }\n\n ${event.extendedProps.description.split(' ').slice(0, 30).join(' ')}\n
\n\n ${\n window.dayjs &&\n window.dayjs(event.start).format('dddd, MMMM D, YYYY, h:mm A')\n } \n ${\n event.end\n ? `– ${\n window.dayjs &&\n window\n .dayjs(event.end)\n .subtract(1, 'day')\n .format('dddd, MMMM D, YYYY, h:mm A')\n }`\n : ''\n }\n
\n\n${event.extendedProps.location}
\n\n ${\n window.dayjs(params[0].axisValue).isValid()\n ? window.dayjs(params[0].axisValue).format(dateFormatter)\n : params[0].axisValue\n }\n
\n ${tooltipItem}\n${el.value}
`;\n iconCopiedToastInstance.show();\n }\n });\n }\n};\n\nexport default iconCopiedInit;\n","/*-----------------------------------------------\n| Isotope\n-----------------------------------------------*/\n\nconst isotopeInit = () => {\n const { getData } = window.phoenix.utils;\n const Selector = {\n ISOTOPE_ITEM: '.isotope-item',\n DATA_ISOTOPE: '[data-sl-isotope]',\n DATA_FILTER: '[data-filter]',\n DATA_FILER_NAV: '[data-filter-nav]'\n };\n\n const DATA_KEY = {\n ISOTOPE: 'sl-isotope'\n };\n const ClassName = {\n ACTIVE: 'active'\n };\n\n if (window.Isotope) {\n const masonryItems = document.querySelectorAll(Selector.DATA_ISOTOPE);\n masonryItems.length &&\n masonryItems.forEach(masonryItem => {\n window.imagesLoaded(masonryItem, () => {\n masonryItem.querySelectorAll(Selector.ISOTOPE_ITEM).forEach(item => {\n // eslint-disable-next-line\n item.style.visibility = 'visible';\n });\n\n const userOptions = getData(masonryItem, DATA_KEY.ISOTOPE);\n const defaultOptions = {\n itemSelector: Selector.ISOTOPE_ITEM,\n layoutMode: 'packery'\n };\n\n const options = window._.merge(defaultOptions, userOptions);\n const isotope = new window.Isotope(masonryItem, options);\n\n // --------- filter -----------------\n const filterElement = document.querySelector(Selector.DATA_FILER_NAV);\n filterElement?.addEventListener('click', function (e) {\n const item = e.target.dataset.filter;\n isotope.arrange({ filter: item });\n document.querySelectorAll(Selector.DATA_FILTER).forEach(el => {\n el.classList.remove(ClassName.ACTIVE);\n });\n e.target.classList.add(ClassName.ACTIVE);\n });\n // ---------- filter end ------------\n\n return isotope;\n });\n });\n }\n};\n\nexport default isotopeInit;\n","/* -------------------------------------------------------------------------- */\n/* Data Table */\n/* -------------------------------------------------------------------------- */\n/* eslint-disable no-param-reassign */\nconst togglePaginationButtonDisable = (button, disabled) => {\n button.disabled = disabled;\n button.classList[disabled ? 'add' : 'remove']('disabled');\n};\n\nconst listInit = () => {\n const { getData } = window.phoenix.utils;\n if (window.List) {\n const lists = document.querySelectorAll('[data-list]');\n\n if (lists.length) {\n lists.forEach(el => {\n const bulkSelect = el.querySelector('[data-bulk-select]');\n\n let options = getData(el, 'list');\n\n if (options.pagination) {\n options = {\n ...options,\n pagination: {\n item: ``,\n ...options.pagination\n }\n };\n }\n\n const paginationButtonNext = el.querySelector(\n '[data-list-pagination=\"next\"]'\n );\n const paginationButtonPrev = el.querySelector(\n '[data-list-pagination=\"prev\"]'\n );\n const viewAll = el.querySelector('[data-list-view=\"*\"]');\n const viewLess = el.querySelector('[data-list-view=\"less\"]');\n const listInfo = el.querySelector('[data-list-info]');\n const listFilter = document.querySelector('[data-list-filter]');\n const list = new List(el, options);\n\n // -------fallback-----------\n\n list.on('updated', item => {\n const fallback =\n el.querySelector('.fallback') ||\n document.getElementById(options.fallback);\n\n if (fallback) {\n if (item.matchingItems.length === 0) {\n fallback.classList.remove('d-none');\n } else {\n fallback.classList.add('d-none');\n }\n }\n });\n\n // ---------------------------------------\n\n const totalItem = list.items.length;\n const itemsPerPage = list.page;\n const btnDropdownClose = list.listContainer.querySelector('.btn-close');\n let pageQuantity = Math.ceil(totalItem / itemsPerPage);\n let numberOfcurrentItems = list.visibleItems.length;\n let pageCount = 1;\n\n btnDropdownClose &&\n btnDropdownClose.addEventListener('search.close', () => {\n list.fuzzySearch('');\n });\n\n const updateListControls = () => {\n listInfo &&\n (listInfo.innerHTML = `${list.i} to ${numberOfcurrentItems} Items of ${totalItem}`);\n paginationButtonPrev &&\n togglePaginationButtonDisable(\n paginationButtonPrev,\n pageCount === 1\n );\n paginationButtonNext &&\n togglePaginationButtonDisable(\n paginationButtonNext,\n pageCount === pageQuantity\n );\n\n if (pageCount > 1 && pageCount < pageQuantity) {\n togglePaginationButtonDisable(paginationButtonNext, false);\n togglePaginationButtonDisable(paginationButtonPrev, false);\n }\n };\n\n // List info\n updateListControls();\n\n if (paginationButtonNext) {\n paginationButtonNext.addEventListener('click', e => {\n e.preventDefault();\n pageCount += 1;\n\n const nextInitialIndex = list.i + itemsPerPage;\n nextInitialIndex <= list.size() &&\n list.show(nextInitialIndex, itemsPerPage);\n numberOfcurrentItems += list.visibleItems.length;\n updateListControls();\n });\n }\n\n if (paginationButtonPrev) {\n paginationButtonPrev.addEventListener('click', e => {\n e.preventDefault();\n pageCount -= 1;\n\n numberOfcurrentItems -= list.visibleItems.length;\n const prevItem = list.i - itemsPerPage;\n prevItem > 0 && list.show(prevItem, itemsPerPage);\n updateListControls();\n });\n }\n\n const toggleViewBtn = () => {\n viewLess.classList.toggle('d-none');\n viewAll.classList.toggle('d-none');\n };\n\n if (viewAll) {\n viewAll.addEventListener('click', () => {\n console.log({ items: list.items });\n\n list.show(1, totalItem);\n pageQuantity = 1;\n pageCount = 1;\n numberOfcurrentItems = totalItem;\n updateListControls();\n toggleViewBtn();\n });\n }\n if (viewLess) {\n viewLess.addEventListener('click', () => {\n list.show(1, itemsPerPage);\n pageQuantity = Math.ceil(totalItem / itemsPerPage);\n pageCount = 1;\n numberOfcurrentItems = list.visibleItems.length;\n updateListControls();\n toggleViewBtn();\n });\n }\n // numbering pagination\n if (options.pagination) {\n el.querySelector('.pagination').addEventListener('click', e => {\n if (e.target.classList[0] === 'page') {\n pageCount = Number(e.target.innerText);\n updateListControls();\n }\n });\n }\n //filter\n if (options.filter) {\n const { key } = options.filter;\n listFilter.addEventListener('change', e => {\n list.filter(item => {\n if (e.target.value === '') {\n return true;\n }\n return item\n .values()\n [key].toLowerCase()\n .includes(e.target.value.toLowerCase());\n });\n });\n }\n\n //bulk-select\n\n if (bulkSelect) {\n bulkSelect.addEventListener('change', () => {\n console.log({ bulkSelect: bulkSelect.checked });\n if (list) {\n if (bulkSelect.checked) {\n list.items.forEach(item => {\n item.elm.querySelector(\n '[data-bulk-select-row]'\n ).checked = true;\n });\n } else {\n list.items.forEach(item => {\n item.elm.querySelector(\n '[data-bulk-select-row]'\n ).checked = false;\n });\n }\n }\n });\n }\n });\n }\n }\n};\n\nexport default listInit;\n","const lottieInit = () => {\n const { getData } = window.phoenix.utils;\n const lotties = document.querySelectorAll('.lottie');\n if (lotties.length) {\n lotties.forEach(item => {\n const options = getData(item, 'options');\n window.bodymovin.loadAnimation({\n container: item,\n path: '../img/animated-icons/warning-light.json',\n renderer: 'svg',\n loop: true,\n autoplay: true,\n name: 'Hello World',\n ...options\n });\n });\n }\n};\n\nexport default lottieInit;\n","/* -------------------------------------------------------------------------- */\n/* Modal */\n/* -------------------------------------------------------------------------- */\n\nconst modalInit = () => {\n const $modals = document.querySelectorAll('[data-phoenix-modal]');\n\n if ($modals) {\n $modals.forEach(modal => {\n modal.addEventListener('shown.bs.modal', () => {\n const $autofocusEls = modal.querySelectorAll('[autofocus=autofocus]');\n $autofocusEls.forEach(el => {\n el.focus();\n });\n });\n });\n }\n};\nexport default modalInit;\n","/* -------------------------------------------------------------------------- */\n/* Navbar Combo Layout */\n/* -------------------------------------------------------------------------- */\n\nconst navbarComboInit = () => {\n const { getBreakpoint, getData, addClass, hasClass, resize } =\n window.phoenix.utils;\n\n const Selector = {\n NAVBAR_VERTICAL: '.navbar-vertical',\n NAVBAR_TOP_COMBO: '[data-navbar-top=\"combo\"]',\n COLLAPSE: '.collapse',\n DATA_MOVE_CONTAINER: '[data-move-container]',\n NAVBAR_NAV: '.navbar-nav',\n NAVBAR_VERTICAL_DIVIDER: '.navbar-vertical-divider'\n };\n\n const ClassName = {\n FLEX_COLUMN: 'flex-column'\n };\n\n const navbarVertical = document.querySelector(Selector.NAVBAR_VERTICAL);\n const navbarTopCombo = document.querySelector(Selector.NAVBAR_TOP_COMBO);\n\n const moveNavContent = windowWidth => {\n const navbarVerticalBreakpoint = getBreakpoint(navbarVertical);\n const navbarTopBreakpoint = getBreakpoint(navbarTopCombo);\n\n if (windowWidth < navbarTopBreakpoint) {\n const navbarCollapse = navbarTopCombo.querySelector(Selector.COLLAPSE);\n const navbarTopContent = navbarCollapse.innerHTML;\n\n if (navbarTopContent) {\n const targetID = getData(navbarTopCombo, 'move-target');\n const targetElement = document.querySelector(targetID);\n console.log(targetElement);\n\n navbarCollapse.innerHTML = '';\n targetElement.insertAdjacentHTML(\n 'afterend',\n `\n