1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('bootstrap')) : 3 typeof define === 'function' && define.amd ? define(['bootstrap'], factory) : 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.phoenix = factory(global.bootstrap)); 5})(this, (function (bootstrap) { 'use strict'; 6 7 /* -------------------------------------------------------------------------- */ 8 /* Utils */ 9 /* -------------------------------------------------------------------------- */ 10 const docReady = fn => { 11 // see if DOM is already available 12 if (document.readyState === 'loading') { 13 document.addEventListener('DOMContentLoaded', fn); 14 } else { 15 setTimeout(fn, 1); 16 } 17 }; 18 19 const toggleColor = (lightColor, darkColor) => { 20 const currentMode = getItemFromStore('phoenixTheme'); 21 const mode = currentMode === 'auto' ? getSystemTheme() : currentMode; 22 return mode === 'light' ? lightColor : darkColor; 23 }; 24 25 const resize = fn => window.addEventListener('resize', fn); 26 27 const isIterableArray = array => Array.isArray(array) && !!array.length; 28 29 const camelize = str => { 30 const text = str.replace(/[-_\s.]+(.)?/g, (_, c) => 31 c ? c.toUpperCase() : '' 32 ); 33 return `${text.substr(0, 1).toLowerCase()}${text.substr(1)}`; 34 }; 35 36 const getData = (el, data) => { 37 try { 38 return JSON.parse(el.dataset[camelize(data)]); 39 } catch (e) { 40 return el.dataset[camelize(data)]; 41 } 42 }; 43 44 /* ----------------------------- Colors function ---------------------------- */ 45 46 const hexToRgb = hexValue => { 47 let hex; 48 hexValue.indexOf('#') === 0 49 ? (hex = hexValue.substring(1)) 50 : (hex = hexValue); 51 // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") 52 const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 53 const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( 54 hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b) 55 ); 56 return result 57 ? [ 58 parseInt(result[1], 16), 59 parseInt(result[2], 16), 60 parseInt(result[3], 16) 61 ] 62 : null; 63 }; 64 65 const rgbaColor = (color = '#fff', alpha = 0.5) => 66 `rgba(${hexToRgb(color)}, ${alpha})`; 67 68 /* --------------------------------- Colors --------------------------------- */ 69 70 const getColor = (name, dom = document.documentElement) => { 71 return getComputedStyle(dom).getPropertyValue(`--phoenix-${name}`).trim(); 72 }; 73 74 const hasClass = (el, className) => { 75 return el.classList.value.includes(className); 76 }; 77 78 const addClass = (el, className) => { 79 el.classList.add(className); 80 }; 81 82 const getOffset = el => { 83 const rect = el.getBoundingClientRect(); 84 const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; 85 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 86 return { top: rect.top + scrollTop, left: rect.left + scrollLeft }; 87 }; 88 89 const isScrolledIntoView = el => { 90 let top = el.offsetTop; 91 let left = el.offsetLeft; 92 const width = el.offsetWidth; 93 const height = el.offsetHeight; 94 95 while (el.offsetParent) { 96 // eslint-disable-next-line no-param-reassign 97 el = el.offsetParent; 98 top += el.offsetTop; 99 left += el.offsetLeft; 100 } 101 102 return { 103 all: 104 top >= window.pageYOffset && 105 left >= window.pageXOffset && 106 top + height <= window.pageYOffset + window.innerHeight && 107 left + width <= window.pageXOffset + window.innerWidth, 108 partial: 109 top < window.pageYOffset + window.innerHeight && 110 left < window.pageXOffset + window.innerWidth && 111 top + height > window.pageYOffset && 112 left + width > window.pageXOffset 113 }; 114 }; 115 116 const breakpoints = { 117 xs: 0, 118 sm: 576, 119 md: 768, 120 lg: 992, 121 xl: 1200, 122 xxl: 1540 123 }; 124
125 const getBreakpoint = el => { 126 const classes = el && el.classList.value; 127 let breakpoint; 128 if (classes) { 129 breakpoint = 130 breakpoints[ 131 classes 132 .split(' ') 133 .filter(cls => cls.includes('navbar-expand-')) 134 .pop() 135 .split('-') 136 .pop() 137 ]; 138 } 139 return breakpoint; 140 }; 141 142 /* --------------------------------- Cookie --------------------------------- */ 143 144 const setCookie = (name, value, seconds) => { 145 const expires = window.dayjs().add(seconds, 'second').toDate(); 146 document.cookie = `${name}=${value};expires=${expires}`; 147 }; 148 149 const getCookie = name => { 150 const keyValue = document.cookie.match(`(^|;) ?${name}=([^;]*)(;|$)`); 151 return keyValue ? keyValue[2] : keyValue; 152 }; 153 154 const settings = { 155 tinymce: { 156 theme: 'oxide' 157 }, 158 chart: { 159 borderColor: 'rgba(255, 255, 255, 0.8)' 160 } 161 }; 162 163 /* -------------------------- Chart Initialization -------------------------- */ 164 165 const newChart = (chart, config) => { 166 const ctx = chart.getContext('2d'); 167 return new window.Chart(ctx, config); 168 }; 169 170 /* ---------------------------------- Store --------------------------------- */ 171 172 const getItemFromStore = (key, defaultValue, store = localStorage) => { 173 try { 174 return JSON.parse(store.getItem(key)) || defaultValue; 175 } catch { 176 return store.getItem(key) || defaultValue; 177 } 178 }; 179 180 const setItemToStore = (key, payload, store = localStorage) => 181 store.setItem(key, payload); 182 const getStoreSpace = (store = localStorage) => 183 parseFloat( 184 ( 185 escape(encodeURIComponent(JSON.stringify(store))).length / 186 (1024 * 1024) 187 ).toFixed(2) 188 ); 189 190 /* get Dates between */ 191 192 const getDates = ( 193 startDate, 194 endDate, 195 interval = 1000 * 60 * 60 * 24 196 ) => { 197 const duration = endDate - startDate; 198 const steps = duration / interval; 199 return Array.from( 200 { length: steps + 1 }, 201 (v, i) => new Date(startDate.valueOf() + interval * i) 202 ); 203 }; 204 205 const getPastDates = duration => { 206 let days; 207 208 switch (duration) { 209 case 'week': 210 days = 7; 211 break; 212 case 'month': 213 days = 30; 214 break; 215 case 'year': 216 days = 365; 217 break; 218 219 default: 220 days = duration; 221 } 222 223 const date = new Date(); 224 const endDate = date; 225 const startDate = new Date(new Date().setDate(date.getDate() - (days - 1))); 226 return getDates(startDate, endDate); 227 }; 228 229 /* Get Random Number */ 230 const getRandomNumber = (min, max) => { 231 return Math.floor(Math.random() * (max - min) + min); 232 }; 233 234 const getSystemTheme = () => 235 window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; 236 237 // export const handleThemeDropdownIcon = value => { 238 // document.querySelectorAll('[data-theme-dropdown-toggle-icon]').forEach(el => { 239 // const theme = getData(el, 'theme-dropdown-toggle-icon'); 240 241 // if (value === theme) { 242 // el.classList.remove('d-none'); 243 // } else { 244 // el.classList.add('d-none'); 245 // } 246 // }); 247 // }; 248 // handleThemeDropdownIcon(getItemFromStore('phoenixTheme')); 249 250 var utils = { 251 docReady, 252 toggleColor, 253 resize, 254 isIterableArray, 255 camelize, 256 getData, 257 hasClass, 258 addClass, 259 hexToRgb, 260 rgbaColor, 261 getColor, 262 breakpoints, 263 // getGrays, 264 getOffset, 265 isScrolledIntoView, 266 getBreakpoint, 267 setCookie, 268 getCookie, 269 newChart, 270 settings, 271 getItemFromStore, 272 setItemToStore, 273 getStoreSpace, 274 getDates, 275 getPastDates, 276 getRandomNumber, 277 getSystemTheme 278 // handleThemeDropdownIcon 279 }; 280 281 const docComponentInit = () => { 282 const componentCards = document.querySelectorAll('[data-component-card]'); 283 const iconCopiedToast = document.getElementById('icon-copied-toast'); 284 const iconCopiedToastInstance = new bootstrap.Toast(iconCopiedToast); 285 286 componentCards.forEach(card => { 287 const copyCodeBtn = card.querySelector('.copy-code-btn'); 288 const copyCodeEl = card.querySelector('.code-to-copy'); 289 const previewBtn = card.querySelector('.preview-btn'); 290 const collapseElement = card.querySelector('.code-collapse'); 291 const collapseInstance = bootstrap.Collapse.getOrCreateInstance(collapseElement, { 292 toggle: false 293 }); 294 295 previewBtn?.addEventListener('click', () => {
296 collapseInstance.toggle(); 297 }); 298 299 copyCodeBtn?.addEventListener('click', () => { 300 const el = document.createElement('textarea'); 301 el.value = copyCodeEl.innerHTML; 302 document.body.appendChild(el); 303 304 el.select(); 305 document.execCommand('copy'); 306 document.body.removeChild(el); 307 308 iconCopiedToast.querySelector( 309 '.toast-body' 310 ).innerHTML = `<code class='text-body-quaternary'>Code has been copied to clipboard.</code>`; 311 iconCopiedToastInstance.show(); 312 }); 313 }); 314 }; 315 316 /* eslint-disable */ 317 const orders = [ 318 { 319 id: 1, 320 dropdownId: 'order-dropdown-1', 321 orderId: '#2181', 322 mailLink: 'mailto:[email protected]', 323 customer: 'Carry Anna', 324 date: '10/03/2023', 325 address: 'Carry Anna, 2392 Main Avenue, Penasauka, New Jersey 02149', 326 deliveryType: 'Cash on Delivery', 327 status: 'Completed', 328 badge: { type: 'success', icon: 'fas fa-check' }, 329 amount: '$99' 330 }, 331 { 332 id: 2, 333 dropdownId: 'order-dropdown-2', 334 orderId: '#2182', 335 mailLink: 'mailto:[email protected]', 336 customer: 'Milind Mikuja', 337 date: '10/03/2023', 338 address: 'Milind Mikuja, 1 Hollywood Blvd,Beverly Hills, California 90210', 339 deliveryType: 'Cash on Delivery', 340 status: 'Processing', 341 badge: { type: 'primary', icon: 'fas fa-redo' }, 342 amount: '$120' 343 }, 344 { 345 id: 3, 346 dropdownId: 'order-dropdown-3', 347 orderId: '#2183', 348 mailLink: 'mailto:[email protected]', 349 customer: 'Stanly Drinkwater', 350 date: '30/04/2023', 351 address: 'Stanly Drinkwater, 1 Infinite Loop, Cupertino, California 90210', 352 deliveryType: 'Local Delivery', 353 status: 'On Hold', 354 badge: { type: 'secondary', icon: 'fas fa-ban' }, 355 amount: '$70' 356 }, 357 { 358 id: 4, 359 dropdownId: 'order-dropdown-4', 360 orderId: '#2184', 361 mailLink: 'mailto:[email protected]', 362 customer: 'Bucky Robert', 363 date: '30/04/2023', 364 address: 'Bucky Robert, 1 Infinite Loop, Cupertino, California 90210', 365 deliveryType: 'Free Shipping', 366 status: 'Pending', 367 badge: { type: 'warning', icon: 'fas fa-stream' }, 368 amount: '$92' 369 }, 370 { 371 id: 5, 372 dropdownId: 'order-dropdown-5', 373 orderId: '#2185', 374 mailLink: 'mailto:[email protected]', 375 customer: 'Josef Stravinsky', 376 date: '30/04/2023', 377 address: 'Josef Stravinsky, 1 Infinite Loop, Cupertino, California 90210', 378 deliveryType: 'Via Free Road', 379 status: 'On Hold', 380 badge: { type: 'secondary', icon: 'fas fa-ban' }, 381 amount: '$120' 382 }, 383 { 384 id: 6, 385 dropdownId: 'order-dropdown-6', 386 orderId: '#2186', 387 mailLink: 'mailto:[email protected]', 388 customer: 'Igor Borvibson', 389 date: '30/04/2023', 390 address: 'Igor Borvibson, 1 Infinite Loop, Cupertino, California 90210', 391 deliveryType: 'Free Shipping', 392 status: 'Processing', 393 badge: { type: 'primary', icon: 'fas fa-redo' }, 394 amount: '$145' 395 }, 396 { 397 id: 7, 398 dropdownId: 'order-dropdown-7', 399 orderId: '#2187', 400 mailLink: 'mailto:[email protected]', 401 customer: 'Katerina Karenin', 402 date: '30/04/2023', 403 address: 'Katerina Karenin, 1 Infinite Loop, Cupertino, California 90210', 404 deliveryType: 'Flat Rate', 405 status: 'Completed', 406 badge: { type: 'success', icon: 'fas fa-check' }, 407 amount: '$55' 408 }, 409 { 410 id: 8, 411 dropdownId: 'order-dropdown-8', 412 orderId: '#2188', 413 mailLink: 'mailto:[email protected]', 414 customer: 'Roy Anderson', 415 date: '29/04/2023', 416 address: 'Roy Anderson, 1 Infinite Loop, Cupertino, California 90210', 417 deliveryType: 'Local Delivery', 418 status: 'On Hold', 419 badge: { type: 'secondary', icon: 'fas fa-ban' }, 420 amount: '$90' 421 }, 422 { 423 id: 9, 424 dropdownId: 'order-dropdown-9', 425 orderId: '#2189',
426 mailLink: 'mailto:[email protected]', 427 customer: 'Thomas Stephenson', 428 date: '29/04/2023', 429 address: 'Thomas Stephenson, 116 Ballifeary Road, Bamff', 430 deliveryType: 'Flat Rate', 431 status: 'Processing', 432 badge: { type: 'primary', icon: 'fas fa-redo' }, 433 amount: '$52' 434 }, 435 { 436 id: 10, 437 dropdownId: 'order-dropdown-10', 438 orderId: '#2190', 439 mailLink: 'mailto:[email protected]', 440 customer: 'Evie Singh', 441 date: '29/04/2023', 442 address: 'Evie Singh, 54 Castledore Road, Tunstead', 443 deliveryType: 'Flat Rate', 444 status: 'Completed', 445 badge: { type: 'success', icon: 'fas fa-check' }, 446 amount: '$90' 447 }, 448 { 449 id: 11, 450 dropdownId: 'order-dropdown-11', 451 orderId: '#2191', 452 mailLink: 'mailto:[email protected]', 453 customer: 'David Peters', 454 date: '29/04/2023', 455 address: 'David Peters, Rhyd Y Groes, Rhosgoch, LL66 0AT', 456 deliveryType: 'Local Delivery', 457 status: 'Completed', 458 badge: { type: 'success', icon: 'fas fa-check' }, 459 amount: '$69' 460 }, 461 { 462 id: 12, 463 dropdownId: 'order-dropdown-12', 464 orderId: '#2192', 465 mailLink: 'mailto:[email protected]', 466 customer: 'Jennifer Johnson', 467 date: '28/04/2023', 468 address: 'Jennifer Johnson, Rhyd Y Groes, Rhosgoch, LL66 0AT', 469 deliveryType: 'Flat Rate', 470 status: 'Processing', 471 badge: { type: 'primary', icon: 'fas fa-redo' }, 472 amount: '$112' 473 }, 474 { 475 id: 13, 476 dropdownId: 'order-dropdown-13', 477 orderId: '#2193', 478 mailLink: 'mailto:[email protected]', 479 customer: 'Demarcus Okuneva', 480 date: '28/04/2023', 481 address: 'Demarcus Okuneva, 90555 Upton Drive Jeffreyview, UT 08771', 482 deliveryType: 'Flat Rate', 483 status: 'Completed', 484 badge: { type: 'success', icon: 'fas fa-check' }, 485 amount: '$99' 486 }, 487 { 488 id: 14, 489 dropdownId: 'order-dropdown-14', 490 orderId: '#2194', 491 mailLink: 'mailto:[email protected]', 492 customer: 'Simeon Harber', 493 date: '27/04/2023', 494 address: 495 'Simeon Harber, 702 Kunde Plain Apt. 634 East Bridgetview, HI 13134-1862', 496 deliveryType: 'Free Shipping', 497 status: 'On Hold', 498 badge: { type: 'secondary', icon: 'fas fa-ban' }, 499 amount: '$129' 500 }, 501 { 502 id: 15, 503 dropdownId: 'order-dropdown-15', 504 orderId: '#2195', 505 mailLink: 'mailto:[email protected]', 506 customer: 'Lavon Haley', 507 date: '27/04/2023', 508 address: 'Lavon Haley, 30998 Adonis Locks McGlynnside, ID 27241', 509 deliveryType: 'Free Shipping', 510 status: 'Pending', 511 badge: { type: 'warning', icon: 'fas fa-stream' }, 512 amount: '$70' 513 }, 514 { 515 id: 16, 516 dropdownId: 'order-dropdown-16', 517 orderId: '#2196', 518 mailLink: 'mailto:[email protected]', 519 customer: 'Ashley Kirlin', 520 date: '26/04/2023', 521 address: 522 'Ashley Kirlin, 43304 Prosacco Shore South Dejuanfurt, MO 18623-0505', 523 deliveryType: 'Local Delivery', 524 status: 'Processing', 525 badge: { type: 'primary', icon: 'fas fa-redo' }, 526 amount: '$39' 527 }, 528 { 529 id: 17, 530 dropdownId: 'order-dropdown-17', 531 orderId: '#2197', 532 mailLink: 'mailto:[email protected]', 533 customer: 'Johnnie Considine', 534 date: '26/04/2023', 535 address: 536 'Johnnie Considine, 6008 Hermann Points Suite 294 Hansenville, TN 14210', 537 deliveryType: 'Flat Rate', 538 status: 'Pending', 539 badge: { type: 'warning', icon: 'fas fa-stream' }, 540 amount: '$70' 541 }, 542 { 543 id: 18, 544 dropdownId: 'order-dropdown-18', 545 orderId: '#2198', 546 mailLink: 'mailto:[email protected]', 547 customer: 'Trace Farrell', 548 date: '26/04/2023', 549 address: 'Trace Farrell, 431 Steuber Mews Apt. 252 Germanland, AK 25882', 550 deliveryType: 'Free Shipping', 551 status: 'Completed', 552 badge: { type: 'success', icon: 'fas fa-check' }, 553 amount: '$70' 554 }, 555 { 556 id: 19, 557 dropdownId: 'order-dropdown-19', 558 orderId: '#2199', 559 mailLink: 'mailto:[email protected]', 560 customer: 'Estell Nienow', 561 date: '26/04/2023', 562 address: 'Estell Nienow, 4167 Laverna Manor Marysemouth, NV 74590', 563 deliveryType: 'Free Shipping',
564 status: 'Completed', 565 badge: { type: 'success', icon: 'fas fa-check' }, 566 amount: '$59' 567 }, 568 { 569 id: 20, 570 dropdownId: 'order-dropdown-20', 571 orderId: '#2200', 572 mailLink: 'mailto:[email protected]', 573 customer: 'Daisha Howe', 574 date: '25/04/2023', 575 address: 576 'Daisha Howe, 829 Lavonne Valley Apt. 074 Stehrfort, RI 77914-0379', 577 deliveryType: 'Free Shipping', 578 status: 'Completed', 579 badge: { type: 'success', icon: 'fas fa-check' }, 580 amount: '$39' 581 }, 582 { 583 id: 21, 584 dropdownId: 'order-dropdown-21', 585 orderId: '#2201', 586 mailLink: 'mailto:[email protected]', 587 customer: 'Miles Haley', 588 date: '24/04/2023', 589 address: 'Miles Haley, 53150 Thad Squares Apt. 263 Archibaldfort, MO 00837', 590 deliveryType: 'Flat Rate', 591 status: 'Completed', 592 badge: { type: 'success', icon: 'fas fa-check' }, 593 amount: '$55' 594 }, 595 { 596 id: 22, 597 dropdownId: 'order-dropdown-22', 598 orderId: '#2202', 599 mailLink: 'mailto:[email protected]', 600 customer: 'Brenda Watsica', 601 date: '24/04/2023', 602 address: "Brenda Watsica, 9198 O'Kon Harbors Morarborough, IA 75409-7383", 603 deliveryType: 'Free Shipping', 604 status: 'Completed', 605 badge: { type: 'success', icon: 'fas fa-check' }, 606 amount: '$89' 607 }, 608 { 609 id: 23, 610 dropdownId: 'order-dropdown-23', 611 orderId: '#2203', 612 mailLink: 'mailto:[email protected]', 613 customer: "Ellie O'Reilly", 614 date: '24/04/2023', 615 address: 616 "Ellie O'Reilly, 1478 Kaitlin Haven Apt. 061 Lake Muhammadmouth, SC 35848", 617 deliveryType: 'Free Shipping', 618 status: 'Completed', 619 badge: { type: 'success', icon: 'fas fa-check' }, 620 amount: '$47' 621 }, 622 { 623 id: 24, 624 dropdownId: 'order-dropdown-24', 625 orderId: '#2204', 626 mailLink: 'mailto:[email protected]', 627 customer: 'Garry Brainstrow', 628 date: '23/04/2023', 629 address: 'Garry Brainstrow, 13572 Kurt Mews South Merritt, IA 52491', 630 deliveryType: 'Free Shipping', 631 status: 'Completed', 632 badge: { type: 'success', icon: 'fas fa-check' }, 633 amount: '$139' 634 }, 635 { 636 id: 25, 637 dropdownId: 'order-dropdown-25', 638 orderId: '#2205', 639 mailLink: 'mailto:[email protected]', 640 customer: 'Estell Pollich', 641 date: '23/04/2023', 642 address: 'Estell Pollich, 13572 Kurt Mews South Merritt, IA 52491', 643 deliveryType: 'Free Shipping', 644 status: 'On Hold', 645 badge: { type: 'secondary', icon: 'fas fa-ban' }, 646 amount: '$49' 647 }, 648 { 649 id: 26, 650 dropdownId: 'order-dropdown-26', 651 orderId: '#2206', 652 mailLink: 'mailto:[email protected]', 653 customer: 'Ara Mueller', 654 date: '23/04/2023', 655 address: 'Ara Mueller, 91979 Kohler Place Waelchiborough, CT 41291', 656 deliveryType: 'Flat Rate', 657 status: 'On Hold', 658 badge: { type: 'secondary', icon: 'fas fa-ban' }, 659 amount: '$19' 660 }, 661 { 662 id: 27, 663 dropdownId: 'order-dropdown-27', 664 orderId: '#2207', 665 mailLink: 'mailto:[email protected]', 666 customer: 'Lucienne Blick', 667 date: '23/04/2023', 668 address: 669 'Lucienne Blick, 6757 Giuseppe Meadows Geraldinemouth, MO 48819-4970', 670 deliveryType: 'Flat Rate', 671 status: 'On Hold', 672 badge: { type: 'secondary', icon: 'fas fa-ban' }, 673 amount: '$59' 674 }, 675 { 676 id: 28, 677 dropdownId: 'order-dropdown-28', 678 orderId: '#2208', 679 mailLink: 'mailto:[email protected]', 680 customer: 'Laverne Haag', 681 date: '22/04/2023', 682 address: 'Laverne Haag, 2327 Kaylee Mill East Citlalli, AZ 89582-3143', 683 deliveryType: 'Flat Rate', 684 status: 'On Hold', 685 badge: { type: 'secondary', icon: 'fas fa-ban' }, 686 amount: '$49' 687 }, 688 { 689 id: 29, 690 dropdownId: 'order-dropdown-29', 691 orderId: '#2209', 692 mailLink: 'mailto:[email protected]', 693 customer: 'Brandon Bednar', 694 date: '22/04/2023', 695 address: 696 'Brandon Bednar, 25156 Isaac Crossing Apt. 810 Lonborough,
696CO 83774-5999', 697 deliveryType: 'Flat Rate', 698 status: 'On Hold', 699 badge: { type: 'secondary', icon: 'fas fa-ban' }, 700 amount: '$39' 701 }, 702 { 703 id: 30, 704 dropdownId: 'order-dropdown-30', 705 orderId: '#2210', 706 mailLink: 'mailto:[email protected]', 707 customer: 'Dimitri Boehm', 708 date: '23/04/2023', 709 address: 'Dimitri Boehm, 71603 Wolff Plains Apt. 885 Johnstonton, MI 01581', 710 deliveryType: 'Flat Rate', 711 status: 'On Hold', 712 badge: { type: 'secondary', icon: 'fas fa-ban' }, 713 amount: '$111' 714 } 715 ]; 716 717 const advanceAjaxTableInit = () => { 718 const togglePaginationButtonDisable = (button, disabled) => { 719 button.disabled = disabled; 720 button.classList[disabled ? 'add' : 'remove']('disabled'); 721 }; 722 // Selectors 723 const table = document.getElementById('advanceAjaxTable'); 724 725 if (table) { 726 const options = { 727 page: 10, 728 pagination: { 729 item: "<li><button class='page' type='button'></button></li>" 730 }, 731 item: values => { 732 const { 733 orderId, 734 id, 735 customer, 736 date, 737 address, 738 deliveryType, 739 status, 740 badge, 741 amount 742 } = values; 743 return ` 744 <tr class="btn-reveal-trigger"> 745 <td class="order py-2 ps-3 align-middle white-space-nowrap"> 746 <a class="fw-semibold" href="https://prium.github.io/phoenix/v1.12.0/apps/e-commerce/admin/order-details.html"> 747 ${orderId} 748 </a> 749 </td> 750 <td class="py-2 align-middle fw-bold"> 751 <a class="fw-semibold text-body" href="#!"> 752 ${customer} 753 </a> 754 </td> 755 <td class="py-2 align-middle"> 756 ${date} 757 </td> 758 <td class="py-2 align-middle white-space-nowrap"> 759 ${address} 760 </td> 761 <td class="py-2 align-middle white-space-nowrap"> 762 <p class="mb-0">${deliveryType}</p> 763 </td> 764 <td class="py-2 align-middle text-center fs-8 white-space-nowrap"> 765 <span class="badge fs-10 badge-phoenix badge-phoenix-${badge.type}"> 766 ${status} 767 <span class="ms-1 ${badge.icon}" data-fa-transform="shrink-2"></span> 768 </span> 769 </td> 770 <td class="py-2 align-middle text-end fs-8 fw-medium"> 771 ${amount} 772 </td> 773 <td class="py-2 align-middle white-space-nowrap text-end"> 774 <div class="dropstart position-static d-inline-block"> 775 <button class="btn btn-link text-body btn-sm dropdown-toggle btn-reveal" type='button' id="order-dropdown-${id}" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"> 776 <span class="fas fa-ellipsis-h fs-9"></span> 777 </button> 778 <div class="dropdown-menu dropdown-menu-end border py-2" aria-labelledby="order-dropdown-${id}"> 779 <a href="#!" class="dropdown-item">View</a> 780 <a href="#!" class="dropdown-item">Edit</a> 781 <div class"dropdown-divider"></div> 782 <a href="#!" class="dropdown-item text-warning">Archive</a> 783 </div> 784 </div> 785 </td> 786 </tr> 787 `; 788 } 789 }; 790 const paginationButtonNext = table.querySelector( 791 '[data-list-pagination="next"]' 792 ); 793 const paginationButtonPrev = table.querySelector( 794 '[data-list-pagination="prev"]' 795 ); 796 const viewAll = table.querySelector('[data-list-view="*"]'); 797 const viewLess = table.querySelector('[data-list-view="less"]'); 798 const listInfo = table.querySelector('[data-list-info]'); 799 const listFilter = document.querySelector('[data-list-filter]'); 800 801 const orderList = new window.List(table, options, orders); 802 803 // Fallback 804 orderList.on('updated', item => { 805 const fallback = 806 table.querySelector('.fallback') || 807 document.getElementById(options.fallback); 808 809 if (fallback) { 810 if (item.matchingItems.length === 0) { 811 fallback.classList.remove('d-none'); 812 } else { 813 fallback.classList.add('d-none'); 814 } 815 } 816 }); 817 818 const totalItem = orderList.items.length; 819 const itemsPerPage = orderList.page; 820 const btnDropdownClose = 821 orderList.listContainer.querySelector('.btn-close'); 822 let pageQuantity = Math.ceil(totalItem / itemsPerPage); 823 let numberOfcurrentItems = orderList.visibleItems.length; 824 let pageCount = 1; 825 826 btnDropdownClose && 827 btnDropdownClose.addEventListener('search.close', () => 828 orderList.fuzzySearch('') 829 ); 830 831 const updateListControls = () => { 832 listInfo && 833 (listInfo.innerHTML = `${orderList.i} to ${numberOfcurrentItems} of ${totalItem}`); 834 paginationButtonPrev && 835 togglePaginationButtonDisable(paginationButtonPrev, pageCount === 1); 836 paginationButtonNext && 837 togglePaginationButtonDisable( 838 paginationButtonNext, 839 pageCount === pageQuantity 840 ); 841 842 if (pageCount > 1 && pageCount < pageQuantity) { 843 togglePaginationButtonDisable(paginationButtonNext, false); 844 togglePaginationButtonDisable(paginationButtonPrev, false); 845 } 846 }; 847 updateListControls(); 848 849 if (paginationButtonNext) { 850 paginationButtonNext.addEventListener('click', e => { 851 e.preventDefault(); 852 pageCount += 1; 853 854 const nextInitialIndex = orderList.i + itemsPerPage; 855 nextInitialIndex <= orderList.size() && 856 orderList.show(nextInitialIndex, itemsPerPage); 857 numberOfcurrentItems += orderList.visibleItems.length; 858 updateListControls(); 859 }); 860 } 861 862 if (paginationButtonPrev) { 863 paginationButtonPrev.addEventListener('click', e => { 864 e.preventDefault(); 865 pageCount -= 1;
866 867 numberOfcurrentItems -= orderList.visibleItems.length; 868 const prevItem = orderList.i - itemsPerPage; 869 prevItem > 0 && orderList.show(prevItem, itemsPerPage); 870 updateListControls(); 871 }); 872 } 873 874 const toggleViewBtn = () => { 875 viewLess.classList.toggle('d-none'); 876 viewAll.classList.toggle('d-none'); 877 }; 878 879 if (viewAll) { 880 viewAll.addEventListener('click', () => { 881 orderList.show(1, totalItem); 882 pageQuantity = 1; 883 pageCount = 1; 884 numberOfcurrentItems = totalItem; 885 updateListControls(); 886 toggleViewBtn(); 887 }); 888 } 889 if (viewLess) { 890 viewLess.addEventListener('click', () => { 891 orderList.show(1, itemsPerPage); 892 pageQuantity = Math.ceil(totalItem / itemsPerPage); 893 pageCount = 1; 894 numberOfcurrentItems = orderList.visibleItems.length; 895 updateListControls(); 896 toggleViewBtn(); 897 }); 898 } 899 if (options.pagination) { 900 table.querySelector('.pagination').addEventListener('click', e => { 901 if (e.target.classList[0] === 'page') { 902 pageCount = Number(e.target.innerText); 903 updateListControls(); 904 } 905 }); 906 } 907 if (options.filter) { 908 const { key } = options.filter; 909 listFilter.addEventListener('change', e => { 910 orderList.filter(item => { 911 if (e.target.value === '') { 912 return true; 913 } 914 return item 915 .values() 916 [key].toLowerCase() 917 .includes(e.target.value.toLowerCase()); 918 }); 919 }); 920 } 921 } 922 }; 923 924 // import AnchorJS from 'anchor-js'; 925 926 const anchorJSInit = () => { 927 const anchors = new window.AnchorJS({ 928 icon: '#' 929 }); 930 anchors.add('[data-anchor]'); 931 }; 932 933 /* -------------------------------------------------------------------------- */ 934 /* bigPicture */ 935 /* -------------------------------------------------------------------------- */ 936 const bigPictureInit = () => { 937 const { getData } = window.phoenix.utils; 938 if (window.BigPicture) { 939 const bpItems = document.querySelectorAll('[data-bigpicture]'); 940 bpItems.forEach(bpItem => { 941 const userOptions = getData(bpItem, 'bigpicture'); 942 const defaultOptions = { 943 el: bpItem, 944 noLoader: true, 945 allowfullscreen: true 946 }; 947 const options = window._.merge(defaultOptions, userOptions); 948 949 bpItem.addEventListener('click', () => { 950 window.BigPicture(options); 951 }); 952 }); 953 } 954 }; 955 956 /* eslint-disable no-unused-expressions */ 957 /*----------------------------------------------- 958 | DomNode 959 -----------------------------------------------*/ 960 class DomNode { 961 constructor(node) { 962 this.node = node; 963 } 964 965 addClass(className) { 966 this.isValidNode() && this.node.classList.add(className); 967 } 968 969 removeClass(className) { 970 this.isValidNode() && this.node.classList.remove(className); 971 } 972 973 toggleClass(className) { 974 this.isValidNode() && this.node.classList.toggle(className); 975 } 976 977 hasClass(className) { 978 this.isValidNode() && this.node.classList.contains(className); 979 } 980 981 data(key) { 982 if (this.isValidNode()) { 983 try { 984 return JSON.parse(this.node.dataset[this.camelize(key)]); 985 } catch (e) { 986 return this.node.dataset[this.camelize(key)]; 987 } 988 } 989 return null; 990 } 991 992 attr(name) { 993 return this.isValidNode() && this.node[name]; 994 } 995 996 setAttribute(name, value) { 997 this.isValidNode() && this.node.setAttribute(name, value); 998 } 999 1000 removeAttribute(name) { 1001 this.isValidNode() && this.node.removeAttribute(name); 1002 } 1003 1004 setProp(name, value) { 1005 this.isValidNode() && (this.node[name] = value); 1006 } 1007 1008 on(event, cb) { 1009 this.isValidNode() && this.node.addEventListener(event, cb); 1010 } 1011 1012 isValidNode() { 1013 return !!this.node; 1014 } 1015 1016 // eslint-disable-next-line class-methods-use-this 1017 camelize(str) { 1018 const text = str.replace(/[-_\s.]+(.)?/g, (_, c) => 1019 c ? c.toUpperCase() : '' 1020 ); 1021 return `${text.substr(0, 1).toLowerCase()}${text.substr(1)}`; 1022 } 1023 } 1024 1025 /*----------------------------------------------- 1026 | Bulk Select 1027 -----------------------------------------------*/ 1028 1029 const elementMap = new Map(); 1030 1031 class BulkSelect { 1032 constructor(element, option) { 1033 this.element = element; 1034 this.option = { 1035 displayNoneClassName: 'd-none', 1036 ...option 1037 }; 1038 elementMap.set(this.element, this); 1039 } 1040 1041 // Static 1042 static getInstance(element) { 1043 if (elementMap.has(element)) { 1044 return elementMap.get(element); 1045 } 1046 return null; 1047 } 1048 1049 init() { 1050 this.attachNodes(); 1051 this.clickBulkCheckbox(); 1052 this.clickRowCheckbox(); 1053 } 1054 1055 getSelectedRows() { 1056 return Array.from(this.bulkSelectRows) 1057 .filter(row => row.checked) 1058 .map(row => getData(row, 'bulk-select-row')); 1059 } 1060 1061 attachNodes() { 1062 const { body, actions, replacedElement } = getData( 1063 this.element, 1064 'bulk-select' 1065 ); 1066 1067 this.actions = new DomNode(document.getElementById(actions)); 1068 this.replacedElement = new DomNode( 1069 document.getElementById(replacedElement) 1070 ); 1071 this.bulkSelectRows = document 1072 .getElementById(body) 1073 .querySelectorAll('[data-bulk-select-row]'); 1074 } 1075 1076 attachRowNodes(elms) { 1077 this.bulkSelectRows = elms; 1078 } 1079 1080 clickBulkCheckbox() { 1081 // Handle click event in bulk checkbox 1082 this.element.addEventListener('click', () => { 1083 if (this.element.indeterminate === 'indeterminate') { 1084 this.actions.addClass(this.option.displayNoneClassName); 1085 this.replacedElement.removeClass(this.option.displayNoneClassName); 1086 1087 this.removeBulkCheck(); 1088 1089 this.bulkSelectRows.forEach(el => { 1090 const rowCheck = new DomNode(el); 1091 rowCheck.checked = false; 1092 rowCheck.setAttribute('checked', false); 1093 }); 1094 return; 1095 } 1096 1097 this.toggleDisplay(); 1098 this.bulkSelectRows.forEach(el => { 1099 el.checked = this.element.checked; 1100 }); 1101 }); 1102 } 1103 1104 clickRowCheckbox() { 1105 // Handle click event in checkbox of each row 1106 this.bulkSelectRows.forEach(el => { 1107 const rowCheck = new DomNode(el); 1108 rowCheck.on('click', () => { 1109 if (this.element.indeterminate !== 'indeterminate') { 1110 this.element.indeterminate = true; 1111 this.element.setAttribute('indeterminate', 'indeterminate'); 1112 this.element.checked = true; 1113 this.element.setAttribute('checked', true); 1114 1115 this.actions.removeClass(this.option.displayNoneClassName); 1116 this.replacedElement.addClass(this.option.displayNoneClassName); 1117 } 1118 1119 if ([...this.bulkSelectRows].every(element => element.checked)) { 1120 this.element.indeterminate = false; 1121 this.element.setAttribute('indeterminate', false); 1122 } 1123 1124 if ([...this.bulkSelectRows].every(element => !element.checked)) { 1125 this.removeBulkCheck(); 1126 this.toggleDisplay(); 1127 } 1128 }); 1129 }); 1130 } 1131 1132 removeBulkCheck() { 1133 this.element.indeterminate = false; 1134 this.element.removeAttribute('indeterminate'); 1135 this.element.checked = false; 1136 this.element.setAttribute('checked', false); 1137 } 1138 1139 toggleDisplay(replacedElement, actions) { 1140 if (replacedElement || actions) { 1141 replacedElement.classList.toggle(this.option.displayNoneClassName); 1142 actions.classList.toggle(this.option.displayNoneClassName); 1143 } 1144 this.actions.toggleClass(this.option.displayNoneClassName); 1145 this.replacedElement.toggleClass(this.option.displayNoneClassName); 1146 } 1147 1148 deselectAll(replacedElement, actions) { 1149 this.removeBulkCheck(); 1150 this.toggleDisplay(replacedElement, actions); 1151 this.bulkSelectRows.forEach(el => { 1152 el.checked = false; 1153 el.removeAttribute('checked'); 1154 }); 1155 } 1156 } 1157 1158 const bulkSelectInit = () => { 1159 const bulkSelects = document.querySelectorAll('[data-bulk-select]'); 1160 1161 if (bulkSelects.length) {
1162 bulkSelects.forEach(el => { 1163 const bulkSelect = new BulkSelect(el); 1164 bulkSelect.init(); 1165 }); 1166 } 1167 }; 1168 1169 // import * as echarts from 'echarts'; 1170 const { merge: merge$2 } = window._; 1171 1172 // form config.js 1173 const echartSetOption = ( 1174 chart, 1175 userOptions, 1176 getDefaultOptions, 1177 responsiveOptions 1178 ) => { 1179 const { breakpoints, resize } = window.phoenix.utils; 1180 const handleResize = options => { 1181 Object.keys(options).forEach(item => { 1182 if (window.innerWidth > breakpoints[item]) { 1183 chart.setOption(options[item]); 1184 } 1185 }); 1186 }; 1187 1188 const themeController = document.body; 1189 // Merge user options with lodash 1190 chart.setOption(merge$2(getDefaultOptions(), userOptions)); 1191 1192 const navbarVerticalToggle = document.querySelector( 1193 '.navbar-vertical-toggle' 1194 ); 1195 if (navbarVerticalToggle) { 1196 navbarVerticalToggle.addEventListener('navbar.vertical.toggle', () => { 1197 chart.resize(); 1198 if (responsiveOptions) { 1199 handleResize(responsiveOptions); 1200 } 1201 }); 1202 } 1203 1204 resize(() => { 1205 chart.resize(); 1206 if (responsiveOptions) { 1207 handleResize(responsiveOptions); 1208 } 1209 }); 1210 if (responsiveOptions) { 1211 handleResize(responsiveOptions); 1212 } 1213 1214 themeController.addEventListener( 1215 'clickControl', 1216 ({ detail: { control } }) => { 1217 if (control === 'phoenixTheme') { 1218 chart.setOption(window._.merge(getDefaultOptions(), userOptions)); 1219 } 1220 if (responsiveOptions) { 1221 handleResize(responsiveOptions); 1222 } 1223 } 1224 ); 1225 }; 1226 // -------------------end config.js-------------------- 1227 1228 const echartTabs = document.querySelectorAll('[data-tab-has-echarts]'); 1229 if (echartTabs) { 1230 echartTabs.forEach(tab => { 1231 tab.addEventListener('shown.bs.tab', e => { 1232 const el = e.target; 1233 const { hash } = el; 1234 const id = hash || el.dataset.bsTarget; 1235 const content = document.getElementById(id.substring(1)); 1236 const chart = content?.querySelector('[data-echart-tab]'); 1237 if (chart) { 1238 window.echarts.init(chart).resize(); 1239 } 1240 }); 1241 }); 1242 } 1243 1244 const handleTooltipPosition = ([pos, , dom, , size]) => { 1245 // only for mobile device 1246 if (window.innerWidth <= 540) { 1247 const tooltipHeight = dom.offsetHeight; 1248 const obj = { top: pos[1] - tooltipHeight - 20 }; 1249 obj[pos[0] < size.viewSize[0] / 2 ? 'left' : 'right'] = 5; 1250 return obj; 1251 } 1252 return null; // else default behaviour 1253 }; 1254 1255 // import dayjs from 'dayjs'; 1256 /* -------------------------------------------------------------------------- */ 1257 /* Echart Bar Member info */ 1258 /* -------------------------------------------------------------------------- */ 1259 1260 const basicEchartsInit = () => { 1261 const { getColor, getData, getDates } = window.phoenix.utils; 1262 1263 const $echartBasicCharts = document.querySelectorAll('[data-echarts]'); 1264 $echartBasicCharts.forEach($echartBasicChart => { 1265 const userOptions = getData($echartBasicChart, 'echarts'); 1266 const chart = window.echarts.init($echartBasicChart); 1267 const getDefaultOptions = () => ({ 1268 color: getColor('primary'), 1269 tooltip: { 1270 trigger: 'item', 1271 padding: [7, 10], 1272 backgroundColor: getColor('body-highlight-bg'), 1273 borderColor: getColor('border-color'), 1274 textStyle: { color: getColor('light-text-emphasis') }, 1275 borderWidth: 1, 1276 transitionDuration: 0, 1277 extraCssText: 'z-index: 1000' 1278 }, 1279 xAxis: { 1280 type: 'category', 1281 data: getDates( 1282 new Date('5/1/2022'), 1283 new Date('5/7/2022'), 1284 1000 * 60 * 60 * 24 1285 ), 1286 show: true, 1287 boundaryGap: false, 1288 axisLine: { 1289 show: true, 1290 lineStyle: { color: getColor('secondary-bg') } 1291 }, 1292 axisTick: { 1293 show: false 1294 }, 1295 axisLabel: { 1296 formatter: value => window.dayjs(value).format('DD MMM'), 1297 interval: 6, 1298 showMinLabel: true, 1299 showMaxLabel: true, 1300 color: getColor('secondary-color') 1301 } 1302 }, 1303 yAxis: { 1304 show: false, 1305 type: 'value', 1306 boundaryGap: false 1307 }, 1308 series: [ 1309 { 1310 type: 'bar', 1311 symbol: 'none' 1312 } 1313 ], 1314 grid: { left: 22, right: 22, top: 0, bottom: 20 } 1315 });
1316 echartSetOption(chart, userOptions, getDefaultOptions); 1317 }); 1318 }; 1319 1320 /* -------------------------------------------------------------------------- */ 1321 /* Echarts Total Sales */ 1322 /* -------------------------------------------------------------------------- */ 1323 1324 const reportsDetailsChartInit = () => { 1325 const { getColor, getData, toggleColor } = window.phoenix.utils; 1326 // const phoenixTheme = window.config.config; 1327 const $chartEl = document.querySelector('.echart-reports-details'); 1328 1329 const tooltipFormatter = (params, dateFormatter = 'MMM DD') => { 1330 let tooltipItem = ``; 1331 params.forEach(el => { 1332 tooltipItem += `<div class='ms-1'> 1333 <h6 class="text-body-tertiary"><span class="fas fa-circle me-1 fs-10" style="color:${ 1334 el.color 1335 }"></span> 1336 ${el.seriesName} : ${ 1337 typeof el.value === 'object' ? el.value[1] : el.value 1338 } 1339 </h6> 1340 </div>`; 1341 }); 1342 return `<div> 1343 <p class='mb-2 text-body-tertiary'> 1344 ${ 1345 window.dayjs(params[0].axisValue).isValid() 1346 ? window.dayjs(params[0].axisValue).format('DD MMM, YYYY') 1347 : params[0].axisValue 1348 } 1349 </p> 1350 ${tooltipItem} 1351 </div>`; 1352 }; 1353 1354 // const dates = getPastDates(7); 1355 const data = [64, 40, 45, 62, 82]; 1356 1357 if ($chartEl) { 1358 const userOptions = getData($chartEl, 'echarts'); 1359 const chart = window.echarts.init($chartEl); 1360 1361 const getDefaultOptions = () => ({ 1362 color: [getColor('primary-lighter'), getColor('info-light')], 1363 tooltip: { 1364 trigger: 'axis', 1365 padding: [7, 10], 1366 backgroundColor: getColor('body-highlight-bg'), 1367 borderColor: getColor('border-color'), 1368 textStyle: { color: getColor('light-text-emphasis') }, 1369 borderWidth: 1, 1370 transitionDuration: 0, 1371 axisPointer: { 1372 type: 'none' 1373 }, 1374 formatter: tooltipFormatter, 1375 extraCssText: 'z-index: 1000' 1376 }, 1377 // legend: { 1378 // left: '76%', 1379 // top: 'auto', 1380 // icon: 'circle', 1381 // }, 1382 xAxis: { 1383 type: 'category', 1384 data: ['Analysis', 'Statement', 'Action', 'Offering', 'Interlocution'], 1385 axisLabel: { 1386 color: getColor('body-color'), 1387 fontFamily: 'Nunito Sans', 1388 fontWeight: 600, 1389 fontSize: 12.8, 1390 rotate: 30, 1391 formatter: value => `${value.slice(0, 5)}...` 1392 }, 1393 axisLine: { 1394 lineStyle: { 1395 color: getColor('secondary-bg') 1396 } 1397 }, 1398 axisTick: false 1399 }, 1400 yAxis: { 1401 type: 'value', 1402 splitLine: { 1403 lineStyle: { 1404 color: getColor('secondary-bg') 1405 } 1406 }, 1407 // splitLine: { 1408 // show: true, 1409 // lineStyle: { 1410 // color: "rgba(217, 21, 21, 1)" 1411 // } 1412 // }, 1413 axisLabel: { 1414 color: getColor('body-color'), 1415 fontFamily: 'Nunito Sans', 1416 fontWeight: 700, 1417 fontSize: 12.8, 1418 margin: 24, 1419 formatter: value => `${value}%` 1420 } 1421 }, 1422 series: [ 1423 { 1424 name: 'Revenue', 1425 type: 'bar', 1426 barWidth: '32px', 1427 barGap: '48%', 1428 showBackground: true, 1429 backgroundStyle: { 1430 color: toggleColor( 1431 getColor('primary-bg-subtle'), 1432 getColor('body-highlight-bg') 1433 ) 1434 }, 1435 label: { 1436 show: false 1437 }, 1438 itemStyle: { 1439 color: toggleColor(getColor('primary-light'), getColor('primary')) 1440 }, 1441 data 1442 } 1443 ], 1444 grid: { 1445 right: '0', 1446 left: '0', 1447 bottom: 0, 1448 top: 10, 1449 containLabel: true 1450 }, 1451 animation: false 1452 }); 1453
1454 echartSetOption(chart, userOptions, getDefaultOptions); 1455 } 1456 }; 1457 1458 /*----------------------------------------------- 1459 | Chat 1460 -----------------------------------------------*/ 1461 const chatInit = () => { 1462 const { getData } = window.phoenix.utils; 1463 1464 const Selector = { 1465 CHAT_SIDEBAR: '.chat-sidebar', 1466 CHAT_TEXT_AREA: '.chat-textarea', 1467 CHAT_THREADS: '[data-chat-thread]', 1468 CHAT_THREAD_TAB: '[data-chat-thread-tab]', 1469 CHAT_THREAD_TAB_CONTENT: '[data-chat-thread-tab-content]' 1470 }; 1471 1472 const $chatSidebar = document.querySelector(Selector.CHAT_SIDEBAR); 1473 const $chatTextArea = document.querySelector(Selector.CHAT_TEXT_AREA); 1474 const $chatThreads = document.querySelectorAll(Selector.CHAT_THREADS); 1475 const threadTab = document.querySelector(Selector.CHAT_THREAD_TAB); 1476 const threadTabContent = document.querySelector( 1477 Selector.CHAT_THREAD_TAB_CONTENT 1478 ); 1479 1480 if (threadTab) { 1481 const threadTabItems = threadTab.querySelectorAll("[data-bs-toggle='tab']"); 1482 1483 const list = new window.List(threadTabContent, { 1484 valueNames: ['read', 'unreadItem'] 1485 }); 1486 1487 const chatBox = document.querySelector('.chat .card-body'); 1488 chatBox.scrollTop = chatBox.scrollHeight; 1489 1490 threadTabItems.forEach(tabEl => 1491 tabEl.addEventListener('shown.bs.tab', () => { 1492 const value = getData(tabEl, 'chat-thread-list'); 1493 list.filter(item => { 1494 if (value === 'all') { 1495 return true; 1496 } 1497 return item.elm.classList.contains(value); 1498 }); 1499 }) 1500 ); 1501 } 1502 1503 $chatThreads.forEach((thread, index) => { 1504 thread.addEventListener('click', () => { 1505 const chatContentArea = document.querySelector( 1506 `.chat-content-body-${index}` 1507 ); 1508 chatContentArea.scrollTop = chatContentArea.scrollHeight; 1509 $chatSidebar.classList.remove('show'); 1510 if (thread.classList.contains('unread')) { 1511 thread.classList.remove('unread'); 1512 const unreadBadge = thread.querySelector('.unread-badge'); 1513 if (unreadBadge) { 1514 unreadBadge.remove(); 1515 } 1516 } 1517 }); 1518 }); 1519 1520 if ($chatTextArea) { 1521 $chatTextArea.setAttribute('placeholder', 'Type your message...'); 1522 } 1523 }; 1524 1525 /* -------------------------------------------------------------------------- */ 1526 /* choices */ 1527 /* -------------------------------------------------------------------------- */ 1528 const choicesInit = () => { 1529 const { getData } = window.phoenix.utils; 1530 1531 if (window.Choices) { 1532 const elements = document.querySelectorAll('[data-choices]'); 1533 elements.forEach(item => { 1534 const userOptions = getData(item, 'options'); 1535 const choices = new window.Choices(item, { 1536 itemSelectText: '', 1537 addItems: true, 1538 allowHTML: true, 1539 ...userOptions 1540 }); 1541 1542 const needsValidation = document.querySelectorAll('.needs-validation'); 1543 1544 needsValidation.forEach(validationItem => { 1545 const selectFormValidation = () => { 1546 validationItem.querySelectorAll('.choices').forEach(choicesItem => { 1547 const singleSelect = choicesItem.querySelector( 1548 '.choices__list--single' 1549 ); 1550 const multipleSelect = choicesItem.querySelector( 1551 '.choices__list--multiple' 1552 ); 1553 1554 if (choicesItem.querySelector('[required]')) { 1555 if (singleSelect) { 1556 if ( 1557 singleSelect 1558 .querySelector('.choices__item--selectable') 1559 ?.getAttribute('data-value') !== '' 1560 ) { 1561 choicesItem.classList.remove('invalid'); 1562 choicesItem.classList.add('valid'); 1563 } else { 1564 choicesItem.classList.remove('valid'); 1565 choicesItem.classList.add('invalid'); 1566 } 1567 } 1568 // ----- for multiple select only ---------- 1569 if (multipleSelect) { 1570 if (choicesItem.getElementsByTagName('option').length) { 1571 choicesItem.classList.remove('invalid');
1572 choicesItem.classList.add('valid'); 1573 } else { 1574 choicesItem.classList.remove('valid'); 1575 choicesItem.classList.add('invalid'); 1576 } 1577 } 1578 1579 // ------ select end --------------- 1580 } 1581 }); 1582 }; 1583 1584 validationItem.addEventListener('submit', () => { 1585 selectFormValidation(); 1586 }); 1587 1588 item.addEventListener('change', () => { 1589 selectFormValidation(); 1590 }); 1591 }); 1592 1593 return choices; 1594 }); 1595 } 1596 }; 1597 1598 /* -------------------------------------------------------------------------- */ 1599 /* Copy LinK */ 1600 /* -------------------------------------------------------------------------- */ 1601 1602 const copyLink = () => { 1603 const { getData } = window.phoenix.utils; 1604 1605 const copyButtons = document.querySelectorAll('[data-copy]'); 1606 1607 copyButtons.forEach(button => { 1608 const tooltip = new window.bootstrap.Tooltip(button); 1609 1610 button.addEventListener('mouseover', () => tooltip.show()); 1611 button.addEventListener('mouseleave', () => tooltip.hide()); 1612 1613 button.addEventListener('click', () => { 1614 button.setAttribute('data-bs-original-title', 'Copied'); 1615 tooltip.show(); 1616 const inputID = getData(button, 'copy'); 1617 const input = document.querySelector(inputID); 1618 input.select(); 1619 navigator.clipboard.writeText(input.value); 1620 button.setAttribute('data-bs-original-title', 'click to copy'); 1621 }); 1622 }); 1623 }; 1624 1625 /* -------------------------------------------------------------------------- */ 1626 /* Count Up */ 1627 /* -------------------------------------------------------------------------- */ 1628 1629 const countupInit = () => { 1630 const { getData } = window.phoenix.utils; 1631 if (window.countUp) { 1632 const countups = document.querySelectorAll('[data-countup]'); 1633 countups.forEach(node => { 1634 const { endValue, ...options } = getData(node, 'countup'); 1635 const countUp = new window.countUp.CountUp(node, endValue, { 1636 duration: 4, 1637 // suffix: '+', 1638 1639 ...options 1640 }); 1641 if (!countUp.error) { 1642 countUp.start(); 1643 } else { 1644 console.error(countUp.error); 1645 } 1646 }); 1647 } 1648 }; 1649 1650 /* -------------------------------------------------------------------------- */ 1651 /* step wizard */ 1652 /* -------------------------------------------------------------------------- */ 1653 const createBoardInit = () => { 1654 const { getData } = window.phoenix.utils; 1655 const selectors = { 1656 CREATE_BOARD: '[data-create-board]', 1657 TOGGLE_BUTTON_EL: '[data-wizard-step]', 1658 FORMS: '[data-wizard-form]', 1659 PASSWORD_INPUT: '[data-wizard-password]', 1660 CONFIRM_PASSWORD_INPUT: '[data-wizard-confirm-password]', 1661 NEXT_BTN: '[data-wizard-next-btn]', 1662 PREV_BTN: '[data-wizard-prev-btn]', 1663 FOOTER: '[data-wizard-footer]', 1664 KANBAN_STEP: '[data-kanban-step]', 1665 BOARD_PREV_BTN: '[data-board-prev-btn]', 1666 CUSTOM_COLOR: '[data-custom-color-radio]' 1667 }; 1668 1669 const events = { 1670 SUBMIT: 'submit', 1671 SHOW: 'show.bs.tab', 1672 SHOWN: 'shown.bs.tab', 1673 CLICK: 'click', 1674 CHANGE: 'change' 1675 }; 1676 1677 const createBoard = document.querySelector(selectors.CREATE_BOARD); 1678 if (createBoard) { 1679 const tabToggleButtonEl = createBoard.querySelectorAll( 1680 selectors.TOGGLE_BUTTON_EL 1681 ); 1682 const tabs = Array.from(tabToggleButtonEl).map(item => { 1683 return window.bootstrap.Tab.getOrCreateInstance(item); 1684 }); 1685 1686 // previous button only for create board last step 1687 const boardPrevButton = document.querySelector(selectors.BOARD_PREV_BTN); 1688 boardPrevButton?.addEventListener(events.CLICK, () => { 1689 tabs[tabs.length - 2].show(); 1690 }); 1691 1692 // update kanban step 1693 if (tabToggleButtonEl.length) { 1694 tabToggleButtonEl.forEach(item => { 1695 item.addEventListener(events.SHOW, () => { 1696 const step = getData(item, 'wizard-step');
1697 const kanbanStep = document.querySelector(selectors.KANBAN_STEP); 1698 if (kanbanStep) { 1699 kanbanStep.textContent = step; 1700 } 1701 }); 1702 }); 1703 } 1704 1705 const forms = createBoard.querySelectorAll(selectors.FORMS); 1706 forms.forEach((form, index) => { 1707 form.addEventListener(events.SUBMIT, e => { 1708 e.preventDefault(); 1709 const formData = new FormData(e.target); 1710 Object.fromEntries(formData.entries()); 1711 if (index + 1 === forms.length) { 1712 window.location.reload(); 1713 } 1714 return null; 1715 }); 1716 }); 1717 // custom color 1718 const colorPicker = document.querySelector('#customColorInput'); 1719 colorPicker?.addEventListener(events.CHANGE, event => { 1720 const selectedColor = event.target.value; 1721 const customColorRadioBtn = document.querySelector( 1722 selectors.CUSTOM_COLOR 1723 ); 1724 customColorRadioBtn.setAttribute('checked', 'checked'); 1725 customColorRadioBtn.value = selectedColor; 1726 }); 1727 } 1728 }; 1729 1730 /* -------------------------------------------------------------------------- */ 1731 /* Detector */ 1732 /* -------------------------------------------------------------------------- */ 1733 1734 const detectorInit = () => { 1735 const { addClass } = window.phoenix.utils; 1736 const { is } = window; 1737 const html = document.querySelector('html'); 1738 1739 is.opera() && addClass(html, 'opera'); 1740 is.mobile() && addClass(html, 'mobile'); 1741 is.firefox() && addClass(html, 'firefox'); 1742 is.safari() && addClass(html, 'safari'); 1743 is.ios() && addClass(html, 'ios'); 1744 is.iphone() && addClass(html, 'iphone'); 1745 is.ipad() && addClass(html, 'ipad'); 1746 is.ie() && addClass(html, 'ie'); 1747 is.edge() && addClass(html, 'edge'); 1748 is.chrome() && addClass(html, 'chrome'); 1749 is.mac() && addClass(html, 'osx'); 1750 is.windows() && addClass(html, 'windows'); 1751 navigator.userAgent.match('CriOS') && addClass(html, 'chrome'); 1752 }; 1753 1754 /* -------------------------------------------------------------------------- */ 1755 /* Open dropdown on hover */ 1756 /* -------------------------------------------------------------------------- */ 1757 1758 const dropdownOnHover = () => { 1759 const navbarArea = document.querySelector('[data-dropdown-on-hover]'); 1760 1761 if (navbarArea) { 1762 navbarArea.addEventListener('mouseover', e => { 1763 if ( 1764 e.target?.classList.contains('dropdown-toggle') && 1765 !e.target.parentNode.className.includes('dropdown-inside') && 1766 window.innerWidth > 992 1767 ) { 1768 const dropdownInstance = new window.bootstrap.Dropdown(e.target); 1769 1770 /* eslint-disable no-underscore-dangle */ 1771 dropdownInstance._element.classList.add('show'); 1772 dropdownInstance._menu.classList.add('show'); 1773 dropdownInstance._menu.setAttribute('data-bs-popper', 'none'); 1774 1775 e.target.parentNode.addEventListener('mouseleave', () => { 1776 if (window.innerWidth > 992) { 1777 dropdownInstance.hide(); 1778 } 1779 }); 1780 } 1781 }); 1782 } 1783 }; 1784 1785 /* eslint-disable */ 1786 const { merge: merge$1 } = window._; 1787 1788 /*----------------------------------------------- 1789 | Dropzone 1790 -----------------------------------------------*/ 1791 1792 window.Dropzone ? (window.Dropzone.autoDiscover = false) : ''; 1793 1794 const dropzoneInit = () => { 1795 const { getData } = window.phoenix.utils; 1796 const Selector = { 1797 DROPZONE: '[data-dropzone]', 1798 DZ_ERROR_MESSAGE: '.dz-error-message', 1799 DZ_PREVIEW: '.dz-preview', 1800 DZ_PROGRESS: '.dz-preview .dz-preview-cover .dz-progress', 1801 DZ_PREVIEW_COVER: '.dz-preview .dz-preview-cover' 1802 }; 1803 1804 const ClassName = { 1805 DZ_FILE_PROCESSING: 'dz-file-processing', 1806 DZ_FILE_COMPLETE: 'dz-file-complete', 1807 DZ_COMPLETE: 'dz-complete', 1808 DZ_PROCESSING: 'dz-processing' 1809 }; 1810 1811 const DATA_KEY = { 1812 OPTIONS: 'options' 1813 }; 1814 1815 const Events = { 1816 ADDED_FILE: 'addedfile', 1817 REMOVED_FILE: 'removedfile', 1818 COMPLETE: 'complete' 1819 }; 1820 1821 const dropzones = document.querySelectorAll(Selector.DROPZONE); 1822 1823 !!dropzones.length &&
1824 dropzones.forEach(item => { 1825 let userOptions = getData(item, DATA_KEY.OPTIONS); 1826 userOptions = userOptions ? userOptions : {}; 1827 const data = userOptions.data ? userOptions.data : {}; 1828 const options = merge$1( 1829 { 1830 url: '/assets/php/', 1831 addRemoveLinks: false, 1832 previewsContainer: item.querySelector(Selector.DZ_PREVIEW), 1833 previewTemplate: item.querySelector(Selector.DZ_PREVIEW).innerHTML, 1834 thumbnailWidth: null, 1835 thumbnailHeight: null, 1836 maxFilesize: 2, 1837 autoProcessQueue: false, 1838 filesizeBase: 1000, 1839 init: function init() { 1840 const thisDropzone = this; 1841 1842 if (data.length) { 1843 data.forEach(v => { 1844 const mockFile = { name: v.name, size: v.size }; 1845 thisDropzone.options.addedfile.call(thisDropzone, mockFile); 1846 thisDropzone.options.thumbnail.call( 1847 thisDropzone, 1848 mockFile, 1849 `${v.url}/${v.name}` 1850 ); 1851 }); 1852 } 1853 1854 thisDropzone.on(Events.ADDED_FILE, function addedfile() { 1855 if ('maxFiles' in userOptions) { 1856 if ( 1857 userOptions.maxFiles === 1 && 1858 item.querySelectorAll(Selector.DZ_PREVIEW_COVER).length > 1 1859 ) { 1860 item.querySelector(Selector.DZ_PREVIEW_COVER).remove(); 1861 } 1862 if (userOptions.maxFiles === 1 && this.files.length > 1) { 1863 this.removeFile(this.files[0]); 1864 } 1865 } 1866 }); 1867 }, 1868 error(file, message) { 1869 if (file.previewElement) { 1870 file.previewElement.classList.add('dz-error'); 1871 if (typeof message !== 'string' && message.error) { 1872 message = message.error; 1873 } 1874 for (let node of file.previewElement.querySelectorAll( 1875 '[data-dz-errormessage]' 1876 )) { 1877 node.textContent = message; 1878 } 1879 } 1880 } 1881 }, 1882 userOptions 1883 ); 1884 // eslint-disable-next-line 1885 item.querySelector(Selector.DZ_PREVIEW).innerHTML = ''; 1886 1887 const dropzone = new window.Dropzone(item, options); 1888 1889 dropzone.on(Events.ADDED_FILE, () => { 1890 if (item.querySelector(Selector.DZ_PREVIEW_COVER)) { 1891 item 1892 .querySelector(Selector.DZ_PREVIEW_COVER) 1893 .classList.remove(ClassName.DZ_FILE_COMPLETE); 1894 } 1895 item.classList.add(ClassName.DZ_FILE_PROCESSING); 1896 // Kanban custom bg radio select 1897 document 1898 .querySelector('.kanban-custom-bg-radio') 1899 ?.setAttribute('checked', true); 1900 }); 1901 dropzone.on(Events.REMOVED_FILE, () => { 1902 if (item.querySelector(Selector.DZ_PREVIEW_COVER)) { 1903 item 1904 .querySelector(Selector.DZ_PREVIEW_COVER) 1905 .classList.remove(ClassName.DZ_PROCESSING); 1906 } 1907 item.classList.add(ClassName.DZ_FILE_COMPLETE); 1908 }); 1909 dropzone.on(Events.COMPLETE, () => { 1910 if (item.querySelector(Selector.DZ_PREVIEW_COVER)) { 1911 item 1912 .querySelector(Selector.DZ_PREVIEW_COVER) 1913 .classList.remove(ClassName.DZ_PROCESSING); 1914 } 1915 1916 item.classList.add(ClassName.DZ_FILE_COMPLETE); 1917 }); 1918 }); 1919 }; 1920 1921 // import feather from 'feather-icons'; 1922 /* -------------------------------------------------------------------------- */ 1923 /* Feather Icons */ 1924 /* -------------------------------------------------------------------------- */ 1925 1926 const featherIconsInit = () => { 1927 if (window.feather) { 1928 window.feather.replace({ 1929 width: '16px', 1930 height: '16px' 1931 }); 1932 } 1933 }; 1934 1935 /* -------------------------------------------------------------------------- */ 1936 /* Flatpickr */ 1937 /* -------------------------------------------------------------------------- */ 1938 1939 const flatpickrInit = () => { 1940 const { getData } = window.phoenix.utils; 1941 document.querySelectorAll('.datetimepicker').forEach(item => { 1942 const userOptions = getData(item, 'options'); 1943 window.flatpickr(item, { 1944 nextArrow: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.1.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z"/></svg>`, 1945 prevArrow: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.1.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
1945<path d="M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z"/></svg>`, 1946 locale: { 1947 firstDayOfWeek: 1, 1948 1949 shorthand: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] 1950 }, 1951 monthSelectorType: 'static', 1952 onDayCreate: (dObj, dStr, fp, dayElem) => { 1953 if (dayElem.dateObj.getDay() === 6 || dayElem.dateObj.getDay() === 0) { 1954 dayElem.className += ' weekend-days'; 1955 } 1956 }, 1957 ...userOptions 1958 }); 1959 1960 // datepicker.l10n.weekdays.shorthand = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; 1961 }); 1962 }; 1963 1964 /* -------------------------------------------------------------------------- */ 1965 /* Form Validation */ 1966 /* -------------------------------------------------------------------------- */ 1967 1968 const formValidationInit = () => { 1969 const forms = document.querySelectorAll('.needs-validation'); 1970 1971 forms.forEach(form => { 1972 form.addEventListener( 1973 'submit', 1974 event => { 1975 if (!form.checkValidity()) { 1976 event.preventDefault(); 1977 event.stopPropagation(); 1978 } 1979 form.classList.add('was-validated'); 1980 }, 1981 false 1982 ); 1983 }); 1984 }; 1985 1986 /* -------------------------------------------------------------------------- */ 1987 /* Calendar */ 1988 1989 /* -------------------------------------------------------------------------- */ 1990 const renderCalendar = (el, option) => { 1991 const { merge } = window._; 1992 1993 const options = merge( 1994 { 1995 initialView: 'dayGridMonth', 1996 weekNumberCalculation: 'ISO', 1997 editable: true, 1998 direction: document.querySelector('html').getAttribute('dir'), 1999 headerToolbar: { 2000 left: 'prev,next today', 2001 center: 'title', 2002 right: 'dayGridMonth,timeGridWeek,timeGridDay' 2003 }, 2004 buttonText: { 2005 month: 'Month', 2006 week: 'Week', 2007 day: 'Day' 2008 } 2009 }, 2010 option 2011 ); 2012 const calendar = new window.FullCalendar.Calendar(el, options); 2013 calendar.render(); 2014 document 2015 .querySelector('.navbar-vertical-toggle') 2016 ?.addEventListener('navbar.vertical.toggle', () => calendar.updateSize()); 2017 return calendar; 2018 }; 2019 2020 const fullCalendarInit = () => { 2021 const { getData } = window.phoenix.utils; 2022 2023 const calendars = document.querySelectorAll('[data-calendar]'); 2024 calendars.forEach(item => { 2025 const options = getData(item, 'calendar'); 2026 renderCalendar(item, options); 2027 }); 2028 }; 2029 2030 /* -------------------------------------------------------------------------- */ 2031 /* Glightbox */ 2032 /* -------------------------------------------------------------------------- */ 2033 2034 const glightboxInit = () => { 2035 if (window.GLightbox) { 2036 window.GLightbox({ 2037 selector: '[data-gallery]' 2038 }); 2039 } 2040 }; 2041 2042 /*----------------------------------------------- 2043 | Gooogle Map 2044 -----------------------------------------------*/ 2045 2046 function initMap() { 2047 const { getData } = window.phoenix.utils; 2048 const themeController = document.body; 2049 const $googlemaps = document.querySelectorAll('[data-googlemap]'); 2050 if ($googlemaps.length && window.google) { 2051 const createControlBtn = (map, type) => { 2052 const controlButton = document.createElement('button'); 2053 controlButton.classList.add(type); 2054 controlButton.innerHTML = 2055 type === 'zoomIn' 2056 ? '<span class="fas fa-plus text-body-emphasis"></span>' 2057 : '<span class="fas fa-minus text-body-emphasis"></span>'; 2058 2059 controlButton.addEventListener('click', () => { 2060 const zoom = map.getZoom(); 2061 if (type === 'zoomIn') { 2062 map.setZoom(zoom + 1); 2063 } 2064 if (type === 'zoomOut') { 2065 map.setZoom(zoom - 1); 2066 } 2067 }); 2068 2069 return controlButton; 2070 }; 2071 const mapStyles = { 2072 SnazzyCustomLight: [ 2073 { 2074 featureType: 'administrative', 2075 elementType: 'all', 2076 stylers: [ 2077 { 2078 visibility: 'off' 2079 } 2080 ] 2081 }, 2082 { 2083 featureType: 'administrative', 2084 elementType: 'labels', 2085 stylers: [ 2086 { 2087 visibility: 'on' 2088 } 2089 ] 2090 }, 2091 { 2092 featureType: 'administrative', 2093 elementType: 'labels.text.fill', 2094 stylers: [ 2095 { 2096 color: '#525b75' 2097 } 2098 ] 2099 }, 2100 { 2101 featureType: 'administrative', 2102 elementType: 'labels.text.stroke', 2103 stylers: [ 2104 { 2105 visibility: 'off' 2106 } 2107 ] 2108 }, 2109 { 2110 featureType: 'administrative', 2111 elementType: 'labels.icon', 2112 stylers: [ 2113 { 2114 visibility: 'off' 2115 } 2116 ] 2117 }, 2118 { 2119 featureType: 'administrative.country', 2120 elementType: 'geometry.stroke', 2121 stylers: [ 2122 { 2123 visibility: 'on' 2124 }, 2125 { 2126 color: '#ffffff' 2127 } 2128 ] 2129 }, 2130 { 2131 featureType: 'administrative.province', 2132 elementType: 'geometry.stroke', 2133 stylers: [ 2134 { 2135 visibility: 'off' 2136 } 2137 ] 2138 }, 2139 { 2140 featureType: 'landscape', 2141 elementType: 'geometry', 2142 stylers: [ 2143 { 2144 visibility: 'on' 2145 }, 2146 { 2147 color: '#E3E6ED' 2148 } 2149 ] 2150 }, 2151 { 2152 featureType: 'landscape.natural', 2153 elementType: 'labels', 2154 stylers: [ 2155 { 2156 visibility: 'off' 2157 } 2158 ] 2159 }, 2160 { 2161 featureType: 'poi', 2162 elementType: 'all', 2163 stylers: [ 2164 { 2165 visibility: 'off' 2166 } 2167 ] 2168 }, 2169 { 2170 featureType: 'road', 2171 elementType: 'all', 2172 stylers: [ 2173 { 2174 color: '#eff2f6' 2175 } 2176 ] 2177 }, 2178 { 2179 featureType: 'road', 2180 elementType: 'labels', 2181 stylers: [ 2182 { 2183 visibility: 'off' 2184 } 2185 ] 2186 }, 2187 { 2188 featureType: 'road.arterial', 2189 elementType: 'all', 2190 stylers: [ 2191 { 2192 visibility: 'on' 2193 } 2194 ] 2195 }, 2196 { 2197 featureType: 'road.arterial', 2198 elementType: 'geometry', 2199 stylers: [ 2200 { 2201 visibility: 'on' 2202 }, 2203 { 2204 color: '#eff2f6' 2205 } 2206 ] 2207 }, 2208 { 2209 featureType: 'road.arterial', 2210 elementType: 'labels.text.fill', 2211 stylers: [ 2212 { 2213 visibility: 'on' 2214 }, 2215 { 2216 color: '#9fa6bc' 2217 } 2218 ] 2219 }, 2220 { 2221 featureType: 'road.arterial', 2222 elementType: 'labels.text.stroke', 2223 stylers: [ 2224 { 2225 visibility: 'off' 2226 } 2227 ] 2228 }, 2229 { 2230 featureType: 'road.local', 2231 elementType: 'geometry.fill', 2232 stylers: [ 2233 { 2234 visibility: 'on' 2235 }, 2236 { 2237 color: '#eff2f6' 2238 } 2239 ] 2240 }, 2241 { 2242 featureType: 'road.local', 2243 elementType: 'labels.text.fill', 2244 stylers: [ 2245 { 2246 visibility: 'on' 2247 }, 2248 { 2249 color: '#9fa6bc' 2250 } 2251 ] 2252 }, 2253 { 2254 featureType: 'road.local', 2255 elementType: 'labels.text.stroke', 2256 stylers: [ 2257 { 2258 visibility: 'off' 2259 } 2260 ] 2261 }, 2262 { 2263 featureType: 'transit', 2264 elementType: 'labels.icon', 2265 stylers: [ 2266 { 2267 visibility: 'off' 2268 } 2269 ] 2270 }, 2271 { 2272 featureType: 'transit.line', 2273 elementType: 'geometry', 2274 stylers: [ 2275 { 2276 visibility: 'off' 2277 } 2278 ] 2279 }, 2280 { 2281 featureType: 'transit.line', 2282 elementType: 'labels.text', 2283 stylers: [ 2284 { 2285 visibility: 'off' 2286 } 2287 ] 2288 }, 2289 { 2290 featureType: 'transit.station.airport', 2291 elementType: 'geometry', 2292 stylers: [ 2293 { 2294 visibility: 'off' 2295 } 2296 ] 2297 }, 2298 { 2299 featureType: 'transit.station.airport', 2300 elementType: 'labels', 2301 stylers: [ 2302 { 2303 visibility: 'off' 2304 } 2305 ] 2306 }, 2307 { 2308 featureType: 'water', 2309 elementType: 'geometry', 2310 stylers: [ 2311 { 2312 color: '#F5F7FA' 2313 } 2314 ] 2315 }, 2316 { 2317 featureType: 'water', 2318 elementType: 'labels', 2319 stylers: [ 2320 { 2321 visibility: 'off' 2322 } 2323 ] 2324 } 2325 ], 2326 SnazzyCustomDark: [ 2327 { 2328 featureType: 'administrative', 2329 elementType: 'all', 2330 stylers: [ 2331 { 2332 visibility: 'off' 2333 } 2334 ] 2335 }, 2336 { 2337 featureType: 'administrative', 2338 elementType: 'labels', 2339 stylers: [{ visibility: 'on' }] 2340 }, 2341 { 2342 featureType: 'administrative', 2343 elementType: 'labels.text.fill', 2344 stylers: [ 2345 { 2346 color: '#8a94ad' 2347 } 2348 ] 2349 }, 2350 { 2351 featureType: 'administrative', 2352 elementType: 'labels.text.stroke', 2353 stylers: [ 2354 { 2355 visibility: 'off' 2356 } 2357 ] 2358 }, 2359 { 2360 featureType: 'administrative', 2361 elementType: 'labels.icon', 2362 stylers: [ 2363 { 2364 visibility: 'off' 2365 } 2366 ] 2367 }, 2368 { 2369 featureType: 'administrative.country', 2370 elementType: 'geometry.stroke', 2371 stylers: [ 2372 { visibility: 'on' }, 2373 { 2374 color: '#000000' 2375 } 2376 ] 2377 }, 2378 { 2379 featureType: 'administrative.province', 2380 elementType: 'geometry.stroke', 2381 stylers: [{ visibility: 'off' }] 2382 }, 2383 { 2384 featureType: 'landscape', 2385 elementType: 'geometry', 2386 stylers: [{ visibility: 'on' }, { color: '#222834' }] 2387 }, 2388 { 2389 featureType: 'landscape.natural', 2390 elementType: 'labels', 2391 stylers: [{ visibility: 'off' }] 2392 }, 2393 { 2394 featureType: 'poi', 2395 elementType: 'all', 2396 stylers: [{ visibility: 'off' }] 2397 }, 2398 { 2399 featureType: 'road', 2400 elementType: 'all', 2401 stylers: [{ color: '#141824' }] 2402 }, 2403 { 2404 featureType: 'road', 2405 elementType: 'labels', 2406 stylers: [{ visibility: 'off' }] 2407 }, 2408 { 2409 featureType: 'road.arterial', 2410 elementType: 'all', 2411 stylers: [ 2412 { 2413 visibility: 'on' 2414 } 2415 ] 2416 }, 2417 { 2418 featureType: 'road.arterial', 2419 elementType: 'geometry', 2420 stylers: [ 2421 { 2422 visibility: 'on' 2423 }, 2424 { 2425 color: '#141824' 2426 } 2427 ] 2428 }, 2429 { 2430 featureType: 'road.arterial', 2431 elementType: 'labels.text.fill', 2432 stylers: [ 2433 { 2434 visibility: 'on' 2435 }, 2436 { 2437 color: '#525b75' 2438 } 2439 ] 2440 }, 2441 { 2442 featureType: 'road.arterial', 2443 elementType: 'labels.text.stroke', 2444 stylers: [ 2445 { 2446 visibility: 'off' 2447 } 2448 ] 2449 }, 2450 { 2451 featureType: 'road.local', 2452 elementType: 'geometry.fill', 2453 stylers: [ 2454 { 2455 visibility: 'on' 2456 }, 2457 { 2458 color: '#141824' 2459 } 2460 ] 2461 }, 2462 { 2463 featureType: 'road.local', 2464 elementType: 'labels.text.fill', 2465 stylers: [ 2466 { 2467 visibility: 'on' 2468 }, 2469 { 2470 color: '#67718A' 2471 } 2472 ] 2473 }, 2474 { 2475 featureType: 'road.local', 2476 elementType: 'labels.text.stroke', 2477 stylers: [ 2478 { 2479 visibility: 'off' 2480 } 2481 ] 2482 }, 2483 { 2484 featureType: 'transit', 2485 elementType: 'labels.icon', 2486 stylers: [{ visibility: 'off' }] 2487 }, 2488 { 2489 featureType: 'transit.line', 2490 elementType: 'geometry', 2491 stylers: [{ visibility: 'off' }] 2492 }, 2493 { 2494 featureType: 'transit.line', 2495 elementType: 'labels.text', 2496 stylers: [{ visibility: 'off' }] 2497 }, 2498 { 2499 featureType: 'transit.station.airport', 2500 elementType: 'geometry', 2501 stylers: [{ visibility: 'off' }] 2502 }, 2503 { 2504 featureType: 'transit.station.airport', 2505 elementType: 'labels', 2506 stylers: [{ visibility: 'off' }] 2507 }, 2508 { 2509 featureType: 'water', 2510 elementType: 'geometry', 2511 stylers: [{ color: '#0f111a' }] 2512 }, 2513 { 2514 featureType: 'water', 2515 elementType: 'labels', 2516 stylers: [{ visibility: 'off' }] 2517 } 2518 ] 2519 }; 2520 2521 $googlemaps.forEach(itm => { 2522 const latLng = getData(itm, 'latlng').split(','); 2523 const markerPopup = itm.innerHTML; 2524 const zoom = getData(itm, 'zoom'); 2525 const mapElement = itm; 2526 const mapStyle = getData(itm, 'phoenixTheme'); 2527 2528 if (getData(itm, 'phoenixTheme') === 'streetview') { 2529 const pov = getData(itm, 'pov'); 2530 const mapOptions = { 2531 position: { lat: Number(latLng[0]), lng: Number(latLng[1]) }, 2532 pov, 2533 zoom, 2534 gestureHandling: 'none', 2535 scrollwheel: false 2536 }; 2537 2538 return new window.google.maps.StreetViewPanorama( 2539 mapElement, 2540 mapOptions 2541 ); 2542 } 2543 2544 const mapOptions = { 2545 zoom, 2546 minZo
2546om: 1.2, 2547 clickableIcons: false, 2548 zoomControl: false, 2549 zoomControlOptions: { 2550 position: window.google.maps.ControlPosition.LEFT 2551 }, 2552 scrollwheel: getData(itm, 'scrollwheel'), 2553 disableDefaultUI: true, 2554 center: new window.google.maps.LatLng(latLng[0], latLng[1]), 2555 styles: 2556 window.config.config.phoenixTheme === 'dark' 2557 ? mapStyles.SnazzyCustomDark 2558 : mapStyles[mapStyle || 'SnazzyCustomLight'] 2559 }; 2560 2561 const map = new window.google.maps.Map(mapElement, mapOptions); 2562 const infoWindow = new window.google.maps.InfoWindow({ 2563 content: markerPopup 2564 }); 2565 2566 // Create the DIV to hold the control. 2567 const controlDiv = document.createElement('div'); 2568 controlDiv.classList.add('google-map-control-btn'); 2569 // Create the control. 2570 const zoomInBtn = createControlBtn(map, 'zoomIn'); 2571 const zoomOutBtn = createControlBtn(map, 'zoomOut'); 2572 // Append the control to the DIV. 2573 controlDiv.appendChild(zoomInBtn); 2574 controlDiv.appendChild(zoomOutBtn); 2575 2576 map.controls[window.google.maps.ControlPosition.LEFT].push(controlDiv); 2577 2578 const marker = new window.google.maps.Marker({ 2579 position: new window.google.maps.LatLng(latLng[0], latLng[1]), 2580 // icon, 2581 map 2582 }); 2583 2584 marker.addListener('click', () => { 2585 infoWindow.open(map, marker); 2586 }); 2587 2588 themeController && 2589 themeController.addEventListener( 2590 'clickControl', 2591 ({ detail: { control, value } }) => { 2592 if (control === 'phoenixTheme') { 2593 map.set( 2594 'styles', 2595 value === 'dark' 2596 ? mapStyles.SnazzyCustomDark 2597 : mapStyles.SnazzyCustomLight 2598 ); 2599 } 2600 } 2601 ); 2602 2603 // return null; 2604 }); 2605 } 2606 } 2607 2608 /* -------------------------------------------------------------------------- */ 2609 /* Icon copy to clipboard */ 2610 /* -------------------------------------------------------------------------- */ 2611 2612 const iconCopiedInit = () => { 2613 const iconList = document.getElementById('icon-list'); 2614 const iconCopiedToast = document.getElementById('icon-copied-toast'); 2615 const iconCopiedToastInstance = new window.bootstrap.Toast(iconCopiedToast); 2616 2617 if (iconList) { 2618 iconList.addEventListener('click', e => { 2619 const el = e.target; 2620 if (el.tagName === 'INPUT') { 2621 el.select(); 2622 el.setSelectionRange(0, 99999); 2623 document.execCommand('copy'); 2624 iconCopiedToast.querySelector( 2625 '.toast-body' 2626 ).innerHTML = `<span class="fw-black">Copied:</span> <code>${el.value}</code>`; 2627 iconCopiedToastInstance.show(); 2628 } 2629 }); 2630 } 2631 }; 2632 2633 /*----------------------------------------------- 2634 | Isotope 2635 -----------------------------------------------*/ 2636 2637 const isotopeInit = () => { 2638 const { getData } = window.phoenix.utils; 2639 const Selector = { 2640 ISOTOPE_ITEM: '.isotope-item', 2641 DATA_ISOTOPE: '[data-sl-isotope]', 2642 DATA_FILTER: '[data-filter]', 2643 DATA_FILER_NAV: '[data-filter-nav]', 2644 DATA_GALLERY_COLUMN: '[data-gallery-column]' 2645 }; 2646 2647 const DATA_KEY = { 2648 ISOTOPE: 'sl-isotope' 2649 }; 2650 const ClassName = { 2651 ACTIVE: 'active' 2652 }; 2653 2654 if (window.Isotope) { 2655 const masonryItems = document.querySelectorAll(Selector.DATA_ISOTOPE); 2656 const columnGallery = document.querySelector(Selector.DATA_GALLERY_COLUMN); 2657 if (masonryItems.length) { 2658 masonryItems.forEach(masonryItem => { 2659 window.imagesLoaded(masonryItem, () => { 2660 document.querySelectorAll(Selector.ISOTOPE_ITEM).forEach(item => { 2661 // eslint-disable-next-line no-param-reassign 2662 item.style.visibility = 'visible'; 2663 }); 2664 2665 const userOptions = getData(masonryItem, DATA_KEY.ISOTOPE); 2666 const defaultOptions = {
2667 itemSelector: Selector.ISOTOPE_ITEM, 2668 layoutMode: 'packery' 2669 }; 2670 2671 const options = window._.merge(defaultOptions, userOptions); 2672 const isotope = new window.Isotope(masonryItem, options); 2673 const addSeparator = (count = 4) => { 2674 for (let i = 1; i < count; i += 1) { 2675 const separator = document.createElement('span'); 2676 separator.classList.add( 2677 `gallery-column-separator`, 2678 `gallery-column-separator-${i}` 2679 ); 2680 masonryItem.appendChild(separator); 2681 } 2682 }; 2683 const removeSeparator = () => { 2684 document 2685 .querySelectorAll('span[class*="gallery-column-separator-"]') 2686 .forEach(separatorEle => separatorEle.remove()); 2687 }; 2688 if (columnGallery) addSeparator(); 2689 // --------- filter ----------------- 2690 const filterElement = document.querySelector(Selector.DATA_FILER_NAV); 2691 filterElement?.addEventListener('click', e => { 2692 const item = e.target.dataset.filter; 2693 isotope.arrange({ filter: item }); 2694 document.querySelectorAll(Selector.DATA_FILTER).forEach(el => { 2695 el.classList.remove(ClassName.ACTIVE); 2696 }); 2697 e.target.classList.add(ClassName.ACTIVE); 2698 const filteredItems = isotope.getFilteredItemElements(); 2699 if (columnGallery) { 2700 removeSeparator(); 2701 } 2702 setTimeout(() => { 2703 if (columnGallery) { 2704 addSeparator( 2705 filteredItems.length > 4 ? 4 : filteredItems.length 2706 ); 2707 } 2708 isotope.layout(); 2709 }, 400); 2710 }); 2711 // ---------- filter end ------------ 2712 isotope.layout(); 2713 return isotope; 2714 }); 2715 }); 2716 } 2717 } 2718 }; 2719 2720 /* eslint-disable no-unused-expressions */ 2721 /* -------------------------------------------------------------------------- */ 2722 /* Data Table */ 2723 /* -------------------------------------------------------------------------- */ 2724 /* eslint-disable no-param-reassign */ 2725 const togglePaginationButtonDisable = (button, disabled) => { 2726 button.disabled = disabled; 2727 button.classList[disabled ? 'add' : 'remove']('disabled'); 2728 }; 2729 2730 const listInit = () => { 2731 const { getData } = window.phoenix.utils; 2732 if (window.List) { 2733 const lists = document.querySelectorAll('[data-list]'); 2734 2735 if (lists.length) { 2736 lists.forEach(el => { 2737 const bulkSelect = el.querySelector('[data-bulk-select]'); 2738 2739 let options = getData(el, 'list'); 2740 2741 if (options.pagination) { 2742 options = { 2743 ...options, 2744 pagination: { 2745 item: `<li><button class='page' type='button'></button></li>`, 2746 ...options.pagination 2747 } 2748 }; 2749 } 2750 2751 const paginationButtonNext = el.querySelector( 2752 '[data-list-pagination="next"]' 2753 ); 2754 const paginationButtonPrev = el.querySelector( 2755 '[data-list-pagination="prev"]' 2756 ); 2757 const viewAll = el.querySelector('[data-list-view="*"]'); 2758 const viewLess = el.querySelector('[data-list-view="less"]'); 2759 const listInfo = el.querySelector('[data-list-info]'); 2760 const listFilter = el.querySelector('[data-list-filter]'); 2761 const list = new List(el, options); 2762 2763 // --------------------------------------- 2764 2765 let totalItem = list.items.length; 2766 const itemsPerPage = list.page; 2767 const btnDropdownClose = list.listContainer.querySelector('.btn-close'); 2768 let pageQuantity = Math.ceil(list.size() / list.page); 2769 let pageCount = 1; 2770 let numberOfcurrentItems = 2771 (pageCount - 1) * Number(list.page) + list.visibleItems.length; 2772 let isSearching = false; 2773 2774 btnDropdownClose && 2775 btnDropdownClose.addEventListener('search.close', () => { 2776 list.fuzzySearch(''); 2777 }); 2778 2779 const updateListControls = () => { 2780 listInfo && 2781 (listInfo.innerHTML = `${list.i} to ${numberOfcurrentItems} <span class='text-body-tertiary'> Items of </span>${totalItem}`); 2782 2783 paginationButtonPrev && 2784 togglePaginationButtonDisable( 2785 paginationButtonPrev, 2786 pageCount === 1 || pageCount === 0 2787 ); 2788 paginationButtonNext && 2789 togglePaginationButtonDisable( 2790 paginationButtonNext, 2791 pageCount === pageQuantity || pageCount === 0 2792 ); 2793 2794 if (pageCount > 1 && pageCount < pageQuantity) { 2795 togglePaginationButtonDisable(paginationButtonNext, false); 2796 togglePaginationButtonDisable(paginationButtonPrev, false); 2797 } 2798 }; 2799 2800 // List info 2801 updateListControls(); 2802 2803 if (paginationButtonNext) { 2804 paginationButtonNext.addEventListener('click', e => { 2805 e.preventDefault(); 2806 pageCount += 1; 2807 const nextInitialIndex = list.i + itemsPerPage; 2808 nextInitialIndex <= list.size() && 2809 list.show(nextInitialIndex, itemsPerPage); 2810 }); 2811 } 2812 2813 if (paginationButtonPrev) { 2814 paginationButtonPrev.addEventListener('click', e => { 2815 e.preventDefault(); 2816 pageCount -= 1;
2817 const prevItem = list.i - itemsPerPage; 2818 prevItem > 0 && list.show(prevItem, itemsPerPage); 2819 }); 2820 } 2821 2822 const toggleViewBtn = () => { 2823 viewLess.classList.toggle('d-none'); 2824 viewAll.classList.toggle('d-none'); 2825 }; 2826 2827 if (viewAll) { 2828 viewAll.addEventListener('click', () => { 2829 list.show(1, totalItem); 2830 pageCount = 1; 2831 toggleViewBtn(); 2832 }); 2833 } 2834 if (viewLess) { 2835 viewLess.addEventListener('click', () => { 2836 list.show(1, itemsPerPage); 2837 pageCount = 1; 2838 toggleViewBtn(); 2839 }); 2840 } 2841 // numbering pagination 2842 if (options.pagination) { 2843 el.querySelector('.pagination').addEventListener('click', e => { 2844 if (e.target.classList[0] === 'page') { 2845 const pageNum = Number(e.target.getAttribute('data-i')); 2846 if (pageNum) { 2847 list.show(itemsPerPage * (pageNum - 1) + 1, list.page); 2848 pageCount = pageNum; 2849 } 2850 } 2851 }); 2852 } 2853 // filter 2854 if (options.filter) { 2855 const { key } = options.filter; 2856 listFilter.addEventListener('change', e => { 2857 list.filter(item => { 2858 if (e.target.value === '') { 2859 return true; 2860 } 2861 pageQuantity = Math.ceil(list.matchingItems.length / list.page); 2862 pageCount = 1; 2863 updateListControls(); 2864 return item 2865 .values() 2866 [key].toLowerCase() 2867 .includes(e.target.value.toLowerCase()); 2868 }); 2869 }); 2870 } 2871 2872 // bulk-select 2873 if (bulkSelect) { 2874 const bulkSelectInstance = 2875 window.phoenix.BulkSelect.getInstance(bulkSelect); 2876 bulkSelectInstance.attachRowNodes( 2877 list.items.map(item => 2878 item.elm.querySelector('[data-bulk-select-row]') 2879 ) 2880 ); 2881 2882 bulkSelect.addEventListener('change', () => { 2883 if (list) { 2884 if (bulkSelect.checked) { 2885 list.items.forEach(item => { 2886 item.elm.querySelector( 2887 '[data-bulk-select-row]' 2888 ).checked = true; 2889 }); 2890 } else { 2891 list.items.forEach(item => { 2892 item.elm.querySelector( 2893 '[data-bulk-select-row]' 2894 ).checked = false; 2895 }); 2896 } 2897 } 2898 }); 2899 } 2900 2901 list.on('searchStart', () => { 2902 isSearching = true; 2903 }); 2904 list.on('searchComplete', () => { 2905 isSearching = false; 2906 }); 2907 2908 list.on('updated', item => { 2909 if (!list.matchingItems.length) { 2910 pageQuantity = Math.ceil(list.size() / list.page); 2911 } else { 2912 pageQuantity = Math.ceil(list.matchingItems.length / list.page); 2913 } 2914 numberOfcurrentItems = 2915 (pageCount - 1) * Number(list.page) + list.visibleItems.length; 2916 updateListControls(); 2917 2918 // -------search----------- 2919 if (isSearching) { 2920 if (list.matchingItems.length === 0) { 2921 pageCount = 0; 2922 } else { 2923 pageCount = 1; 2924 } 2925 totalItem = list.matchingItems.length; 2926 numberOfcurrentItems = 2927 (pageCount === 0 ? 1 : pageCount - 1) * Number(list.page) + 2928 list.visibleItems.length; 2929 2930 updateListControls(); 2931 listInfo && 2932 (listInfo.innerHTML = `${ 2933 list.matchingItems.length === 0 ? 0 : list.i 2934 } to ${ 2935 list.matchingItems.length === 0 ? 0 : numberOfcurrentItems 2936 } <span class='text-body-tertiary'> Items of </span>${ 2937 list.matchingItems.length 2938 }`); 2939 } 2940 2941 // -------fallback----------- 2942 const fallback = 2943 el.querySelector('.fallback') || 2944 document.getElementById(options.fallback); 2945 2946 if (fallback) { 2947 if (item.matchingItems.length === 0) { 2948 fallback.classList.remove('d-none'); 2949 } else { 2950 fallback.classList.add('d-none'); 2951 } 2952 } 2953 }); 2954 }); 2955 } 2956 } 2957 }; 2958 2959 const lottieInit = () => { 2960 const { getData } = window.phoenix.utils; 2961 const lotties = document.querySelectorAll('.lottie'); 2962 if (lotties.length) {
2963 lotties.forEach(item => { 2964 const options = getData(item, 'options'); 2965 window.bodymovin.loadAnimation({ 2966 container: item, 2967 path: '../img/animated-icons/warning-light.json', 2968 renderer: 'svg', 2969 loop: true, 2970 autoplay: true, 2971 name: 'Hello World', 2972 ...options 2973 }); 2974 }); 2975 } 2976 }; 2977 2978 /* ----------------------------------------------------------------- */ 2979 /* Modal */ 2980 /* ----------------------------------------------------------------- */ 2981 2982 const modalInit = () => { 2983 const $modals = document.querySelectorAll('[data-phoenix-modal]'); 2984 2985 if ($modals) { 2986 const { getData, getCookie, setCookie } = window.phoenix.utils; 2987 $modals.forEach(modal => { 2988 const userOptions = getData(modal, 'phoenix-modal'); 2989 const defaultOptions = { 2990 autoShow: false 2991 }; 2992 const options = window._.merge(defaultOptions, userOptions); 2993 if (options.autoShow) { 2994 const autoShowModal = new window.bootstrap.Modal(modal); 2995 const disableModalBtn = modal.querySelector( 2996 '[data-disable-modal-auto-show]' 2997 ); 2998 2999 disableModalBtn.addEventListener('click', () => { 3000 const seconds = 24 * 60 * 60; 3001 setCookie('disableAutoShowModal', 'true', seconds); 3002 }); 3003 3004 const disableAutoShowModalCookie = getCookie('disableAutoShowModal'); 3005 if (!disableAutoShowModalCookie) { 3006 autoShowModal.show(); 3007 } 3008 } else { 3009 modal.addEventListener('shown.bs.modal', () => { 3010 const $autofocusEls = modal.querySelectorAll('[autofocus=autofocus]'); 3011 $autofocusEls.forEach(el => { 3012 el.focus(); 3013 }); 3014 }); 3015 } 3016 }); 3017 } 3018 }; 3019 3020 /* -------------------------------------------------------------------------- */ 3021 /* Navbar Combo Layout */ 3022 /* -------------------------------------------------------------------------- */ 3023
3024 const navbarComboInit = () => { 3025 const { getBreakpoint, getData, addClass, hasClass, resize } = 3026 window.phoenix.utils; 3027 3028 const Selector = { 3029 NAVBAR_VERTICAL: '.navbar-vertical', 3030 NAVBAR_TOP_COMBO: '[data-navbar-top="combo"]', 3031 COLLAPSE: '.collapse', 3032 DATA_MOVE_CONTAINER: '[data-move-container]', 3033 NAVBAR_NAV: '.navbar-nav', 3034 NAVBAR_VERTICAL_DIVIDER: '.navbar-vertical-divider' 3035 }; 3036 3037 const ClassName = { 3038 FLEX_COLUMN: 'flex-column' 3039 }; 3040 3041 const navbarVertical = document.querySelector(Selector.NAVBAR_VERTICAL); 3042 const navbarTopCombo = document.querySelector(Selector.NAVBAR_TOP_COMBO); 3043 3044 const moveNavContent = windowWidth => { 3045 const navbarVerticalBreakpoint = getBreakpoint(navbarVertical); 3046 const navbarTopBreakpoint = getBreakpoint(navbarTopCombo); 3047 3048 if (windowWidth < navbarTopBreakpoint) { 3049 const navbarCollapse = navbarTopCombo.querySelector(Selector.COLLAPSE); 3050 const navbarTopContent = navbarCollapse.innerHTML; 3051 3052 if (navbarTopContent) { 3053 const targetID = getData(navbarTopCombo, 'move-target'); 3054 const targetElement = document.querySelector(targetID); 3055 3056 navbarCollapse.innerHTML = ''; 3057 targetElement.insertAdjacentHTML( 3058 'afterend', 3059 ` 3060 <div data-move-container class='move-container'> 3061 <div class='navbar-vertical-divider'> 3062 <hr class='navbar-vertical-hr' /> 3063 </div> 3064 ${navbarTopContent} 3065 </div> 3066 ` 3067 ); 3068 3069 if (navbarVerticalBreakpoint < navbarTopBreakpoint) { 3070 const navbarNav = document 3071 .querySelector(Selector.DATA_MOVE_CONTAINER) 3072 .querySelector(Selector.NAVBAR_NAV); 3073 addClass(navbarNav, ClassName.FLEX_COLUMN); 3074 } 3075 } 3076 } else { 3077 const moveableContainer = document.querySelector( 3078 Selector.DATA_MOVE_CONTAINER 3079 ); 3080 if (moveableContainer) { 3081 const navbarNav = moveableContainer.querySelector(Selector.NAVBAR_NAV); 3082 hasClass(navbarNav, ClassName.FLEX_COLUMN) && 3083 navbarNav.classList.remove(ClassName.FLEX_COLUMN); 3084 moveableContainer 3085 .querySelector(Selector.NAVBAR_VERTICAL_DIVIDER) 3086 .remove(); 3087 navbarTopCombo.querySelector(Selector.COLLAPSE).innerHTML = 3088 moveableContainer.innerHTML; 3089 moveableContainer.remove(); 3090 } 3091 } 3092 }; 3093 3094 moveNavContent(window.innerWidth); 3095 3096 resize(() => moveNavContent(window.innerWidth)); 3097 }; 3098 3099 const navbarShadowOnScrollInit = () => { 3100 const navbar = document.querySelector('[data-navbar-shadow-on-scroll]'); 3101 if (navbar) { 3102 window.onscroll = () => { 3103 if (window.scrollY > 300) { 3104 navbar.classList.add('navbar-shadow'); 3105 } else { 3106 navbar.classList.remove('navbar-shadow'); 3107 } 3108 }; 3109 } 3110 }; 3111 3112 const navbarInit = () => { 3113 const navbar = document.querySelector('[data-navbar-soft-on-scroll]'); 3114 if (navbar) { 3115 const windowHeight = window.innerHeight; 3116 const handleAlpha = () => { 3117 const scrollTop = window.pageYOffset; 3118 let alpha = (scrollTop / windowHeight) * 2; 3119 alpha >= 1 && (alpha = 1); 3120 navbar.style.backgroundColor = `rgba(255, 255, 255, ${alpha})`; 3121 }; 3122 handleAlpha(); 3123 document.addEventListener('scroll', () => handleAlpha()); 3124 } 3125 }; 3126 3127 /* -------------------------------------------------------------------------- */ 3128 /* Navbar Vertical */ 3129 /* -------------------------------------------------------------------------- */ 3130 3131 const handleNavbarVerticalCollapsed = () => { 3132 const { getItemFromStore, setItemToStore, resize } = window.phoenix.utils; 3133 const Selector = { 3134 HTML: 'html', 3135 BODY: 'body', 3136 NAVBAR_VERTICAL: '.navbar-vertical', 3137 NAVBAR_VERTICAL_TOGGLE: '.navbar-vertical-toggle', 3138 NAVBAR_VERTICAL_COLLAPSE: '.navbar-vertical .navbar-collapse', 3139 ACTIVE_NAV_LINK: '.navbar-vertical .nav-link.active' 3140 }; 3141 3142 const Events = { 3143 CLICK: 'click', 3144 MOUSE_OVER: 'mouseover', 3145 MOUSE_LEAVE: 'mouseleave', 3146 NAVBAR_VERTICAL_TOGGLE: 'navbar.vertical.toggle' 3147 }; 3148 const ClassNames = { 3149 NAVBAR_VERTICAL_COLLAPSED: 'navbar-vertical-collapsed' 3150 }; 3151 const navbarVerticalToggle = document.querySelector( 3152 Selector.NAVBAR_VERTICAL_TOGGLE 3153 ); 3154 // const html = document.querySelector(Selector.HTML); 3155 const navbarVerticalCollapse = document.querySelector( 3156 Selector.NAVBAR_VERTICAL_COLLAPSE 3157 ); 3158 const activeNavLinkItem = document.querySelector(Selector.ACTIVE_NAV_LINK); 3159 if (navbarVerticalToggle) { 3160 navbarVerticalToggle.addEventListener(Events.CLICK, e => { 3161 const isNavbarVerticalCollapsed = getItemFromStore( 3162 'phoenixIsNavbarVerticalCollapsed', 3163 false 3164 ); 3165 navbarVerticalToggle.blur(); 3166 document.documentElement.classList.toggle( 3167 ClassNames.NAVBAR_VERTICAL_COLLAPSED 3168 ); 3169 3170 // Set collapse state on localStorage 3171 setItemToStore( 3172 'phoenixIsNavbarVerticalCollapsed', 3173 !isNavbarVerticalCollapsed 3174 ); 3175 3176 const event = new CustomEvent(Events.NAVBAR_VERTICAL_TOGGLE); 3177 e.currentTarget?.dispatchEvent(event); 3178 }); 3179 } 3180 if (navbarVerticalCollapse) { 3181 const isNavbarVerticalCollapsed = getItemFromStore( 3182 'phoenixIsNavbarVerticalCollapsed', 3183 false 3184 ); 3185 if (activeNavLinkItem && !isNavbarVerticalCollapsed) { 3186 activeNavLinkItem.scrollIntoView({ behavior: 'smooth' });
3187 } 3188 } 3189 const setDocumentMinHeight = () => { 3190 const bodyHeight = document.querySelector(Selector.BODY).offsetHeight; 3191 const navbarVerticalHeight = document.querySelector( 3192 Selector.NAVBAR_VERTICAL 3193 )?.offsetHeight; 3194 3195 if ( 3196 document.documentElement.classList.contains( 3197 ClassNames.NAVBAR_VERTICAL_COLLAPSED 3198 ) && 3199 bodyHeight < navbarVerticalHeight 3200 ) { 3201 document.documentElement.style.minHeight = `${navbarVerticalHeight}px`; 3202 } else { 3203 document.documentElement.removeAttribute('style'); 3204 } 3205 }; 3206 3207 // set document min height for collapse vertical nav 3208 setDocumentMinHeight(); 3209 resize(() => { 3210 setDocumentMinHeight(); 3211 }); 3212 if (navbarVerticalToggle) { 3213 navbarVerticalToggle.addEventListener('navbar.vertical.toggle', () => { 3214 setDocumentMinHeight(); 3215 }); 3216 } 3217 }; 3218 3219 /* eslint-disable no-new */ 3220 /*----------------------------------------------- 3221 | Phoenix Offcanvas 3222 -----------------------------------------------*/ 3223 3224 const phoenixOffcanvasInit = () => { 3225 const { getData } = window.phoenix.utils; 3226 const toggleEls = document.querySelectorAll( 3227 "[data-phoenix-toggle='offcanvas']" 3228 ); 3229 const offcanvasBackdrops = document.querySelectorAll( 3230 '[data-phoenix-backdrop]' 3231 ); 3232 const offcanvasBodyScroll = document.querySelector('[data-phoenix-scroll]'); 3233 const offcanvases = document.querySelectorAll('.phoenix-offcanvas'); 3234 const offcanvasFaq = document.querySelector('.faq'); 3235 const offcanvasFaqShow = document.querySelector('.faq-sidebar'); 3236 3237 if (offcanvases) { 3238 const breakpoints = { 3239 sm: 576, 3240 md: 768, 3241 lg: 992, 3242 xl: 1200, 3243 xxl: 1540 3244 }; 3245 3246 window.addEventListener('resize', () => { 3247 offcanvases.forEach(offcanvas => { 3248 const offcanvasInstance = new window.bootstrap.Offcanvas(offcanvas); 3249 const breakpoint = offcanvas.getAttribute('data-breakpoint'); 3250 const breakpointValue = breakpoints[breakpoint]; 3251 if (window.innerWidth >= breakpointValue) { 3252 document.body.style.overflow = ''; 3253 offcanvasInstance.hide(); 3254 } 3255 }); 3256 }); 3257 } 3258 3259 const showFilterCol = offcanvasEl => { 3260 offcanvasEl.classList.add('show'); 3261 if (!offcanvasBodyScroll) { 3262 document.body.style.overflow = 'hidden'; 3263 } 3264 }; 3265 const hideFilterCol = offcanvasEl => { 3266 offcanvasEl.classList.remove('show'); 3267 document.body.style.removeProperty('overflow'); 3268 }; 3269 3270 if (toggleEls) { 3271 toggleEls.forEach(toggleEl => { 3272 const offcanvasTarget = getData(toggleEl, 'phoenix-target'); 3273 const offcanvasTargetEl = document.querySelector(offcanvasTarget); 3274 const closeBtn = offcanvasTargetEl.querySelectorAll( 3275 "[data-phoenix-dismiss='offcanvas']" 3276 ); 3277 toggleEl.addEventListener('click', () => { 3278 showFilterCol(offcanvasTargetEl); 3279 }); 3280 if (closeBtn) { 3281 closeBtn.forEach(el => { 3282 el.addEventListener('click', () => { 3283 hideFilterCol(offcanvasTargetEl); 3284 }); 3285 }); 3286 } 3287 if (offcanvasBackdrops) { 3288 offcanvasBackdrops.forEach(offcanvasBackdrop => { 3289 offcanvasBackdrop.addEventListener('click', () => { 3290 hideFilterCol(offcanvasTargetEl); 3291 }); 3292 }); 3293 } 3294 }); 3295 } 3296 3297 if (offcanvasFaq) { 3298 if (offcanvasFaqShow.classList.contains('show')) { 3299 offcanvasFaq.classList.add = 'newFaq'; 3300 } 3301 } 3302 }; 3303 3304 /* -------------------------------------------------------------------------- */ 3305 /* Popover */ 3306 /* -------------------------------------------------------------------------- */ 3307 3308 const picmoInit = () => { 3309 const { getData } = window.phoenix.utils; 3310 3311 const picmoBtns = document.querySelectorAll('[data-picmo]'); 3312 3313 if (picmoBtns) {
3314 Array.from(picmoBtns).forEach(btn => { 3315 const options = getData(btn, 'picmo'); 3316 3317 const picker = window.picmoPopup.createPopup( 3318 {}, 3319 { 3320 referenceElement: btn, 3321 triggerElement: btn, 3322 position: 'bottom-start', 3323 showCloseButton: false 3324 } 3325 ); 3326 btn.addEventListener('click', () => { 3327 picker.toggle(); 3328 }); 3329 3330 const input = document.querySelector(options.inputTarget); 3331 3332 picker.addEventListener('emoji:select', selection => { 3333 if (input) { 3334 input.innerHTML += selection.emoji; 3335 } 3336 }); 3337 }); 3338 } 3339 }; 3340 3341 /* -------------------------------------------------------------------------- */ 3342 /* Popover */ 3343 /* -------------------------------------------------------------------------- */ 3344 3345 const popoverInit = () => { 3346 const popoverTriggerList = Array.from( 3347 document.querySelectorAll('[data-bs-toggle="popover"]') 3348 ); 3349 3350 popoverTriggerList.map(popoverTriggerEl => { 3351 return new bootstrap.Popover(popoverTriggerEl); 3352 }); 3353 }; 3354 3355 /* eslint-disable no-new */ 3356 /*----------------------------------------------- 3357 | Swiper 3358 -----------------------------------------------*/ 3359 3360 const getThubmnailDirection = () => { 3361 if ( 3362 window.innerWidth < 768 || 3363 (window.innerWidth >= 992 && window.innerWidth < 1200) 3364 ) { 3365 return 'horizontal'; 3366 } 3367 return 'vertical'; 3368 }; 3369 3370 const productDetailsInit = () => { 3371 const { getData, resize } = window.phoenix.utils; 3372 const productDetailsEl = document.querySelector('[data-product-details]'); 3373 if (productDetailsEl) { 3374 const colorVariantEl = productDetailsEl.querySelector( 3375 '[data-product-color]' 3376 ); 3377 productDetailsEl.querySelector( 3378 '[data-product-quantity]' 3379 ); 3380 const productQuantityInputEl = productDetailsEl.querySelector( 3381 '[data-quantity] input[type="number"]' 3382 ); 3383 const productColorVariantConatiner = productDetailsEl.querySelector( 3384 '[data-product-color-variants]' 3385 ); 3386 3387 const swiperInit = productImages => { 3388 const productSwiper = productDetailsEl.querySelector( 3389 '[data-products-swiper]' 3390 ); 3391 3392 const options = getData(productSwiper, 'swiper'); 3393 3394 const thumbTarget = getData(productSwiper, 'thumb-target'); 3395 3396 const thumbEl = document.getElementById(thumbTarget); 3397 3398 let slides = ''; 3399 productImages.forEach(img => { 3400 slides += ` 3401 <div class='swiper-slide '> 3402 <img class='w-100' src=${img} alt=""> 3403 </div> 3404 `; 3405 }); 3406 productSwiper.innerHTML = `<div class='swiper-wrapper'>${slides}</div>`; 3407 3408 let thumbSlides = ''; 3409 productImages.forEach(img => { 3410 thumbSlides += ` 3411 <div class='swiper-slide '> 3412 <div class="product-thumb-container p-2 p-sm-3 p-xl-2"> 3413 <img src=${img} alt=""> 3414 </div> 3415 </div> 3416 `; 3417 }); 3418 thumbEl.innerHTML = `<div class='swiper-wrapper'>${thumbSlides}</div>`; 3419 3420 const thumbSwiper = new window.Swiper(thumbEl, { 3421 slidesPerView: 5, 3422 spaceBetween: 16, 3423 direction: getThubmnailDirection(), 3424 breakpoints: { 3425 768: { 3426 spaceBetween: 100 3427 }, 3428 992: { 3429 spaceBetween: 16 3430 } 3431 } 3432 }); 3433 3434 const swiperNav = productSwiper.querySelector('.swiper-nav'); 3435 3436 resize(() => { 3437 thumbSwiper.changeDirection(getThubmnailDirection()); 3438 }); 3439 3440 new Swiper(productSwiper, { 3441 ...options, 3442 navigation: { 3443 nextEl: swiperNav?.querySelector('.swiper-button-next'), 3444 prevEl: swiperNav?.querySelector('.swiper-button-prev') 3445 }, 3446 thumbs: { 3447 swiper: thumbSwiper 3448 } 3449 }); 3450 }; 3451 3452 const colorVariants =
3453 productColorVariantConatiner.querySelectorAll('[data-variant]'); 3454 3455 colorVariants.forEach(variant => { 3456 if (variant.classList.contains('active')) { 3457 swiperInit(getData(variant, 'products-images')); 3458 colorVariantEl.innerHTML = getData(variant, 'variant'); 3459 } 3460 const productImages = getData(variant, 'products-images'); 3461 3462 variant.addEventListener('click', () => { 3463 swiperInit(productImages); 3464 colorVariants.forEach(colorVariant => { 3465 colorVariant.classList.remove('active'); 3466 }); 3467 variant.classList.add('active'); 3468 colorVariantEl.innerHTML = getData(variant, 'variant'); 3469 }); 3470 }); 3471 productQuantityInputEl.addEventListener('change', e => { 3472 if (e.target.value == '') { 3473 e.target.value = 0; 3474 } 3475 }); 3476 } 3477 }; 3478 3479 /*----------------------------------------------- 3480 | Quantity 3481 -----------------------------------------------*/ 3482 const quantityInit = () => { 3483 const { getData } = window.phoenix.utils; 3484 const Selector = { 3485 DATA_QUANTITY_BTN: '[data-quantity] [data-type]', 3486 DATA_QUANTITY: '[data-quantity]', 3487 DATA_QUANTITY_INPUT: '[data-quantity] input[type="number"]' 3488 }; 3489 3490 const Events = { 3491 CLICK: 'click' 3492 }; 3493 3494 const Attributes = { 3495 MIN: 'min' 3496 }; 3497 3498 const DataKey = { 3499 TYPE: 'type' 3500 }; 3501 3502 const quantities = document.querySelectorAll(Selector.DATA_QUANTITY_BTN); 3503 3504 quantities.forEach(quantity => { 3505 quantity.addEventListener(Events.CLICK, e => { 3506 const el = e.currentTarget; 3507 const type = getData(el, DataKey.TYPE); 3508 const numberInput = el 3509 .closest(Selector.DATA_QUANTITY) 3510 .querySelector(Selector.DATA_QUANTITY_INPUT); 3511 3512 const min = numberInput.getAttribute(Attributes.MIN); 3513 let value = parseInt(numberInput.value, 10); 3514 3515 if (type === 'plus') { 3516 value += 1; 3517 } else { 3518 value = value > min ? (value -= 1) : value; 3519 } 3520 numberInput.value = value; 3521 }); 3522 }); 3523 }; 3524 3525 /* -------------------------------------------------------------------------- */ 3526 /* Ratings */ 3527 /* -------------------------------------------------------------------------- */ 3528 3529 const randomColorInit = () => { 3530 const { getData } = window.phoenix.utils; 3531 3532 const randomColorElements = document.querySelectorAll('[data-random-color]'); 3533 const defaultColors = [ 3534 '#85A9FF', 3535 '#60C6FF', 3536 '#90D67F', 3537 '#F48270', 3538 '#3874FF', 3539 '#0097EB', 3540 '#25B003', 3541 '#EC1F00', 3542 '#E5780B', 3543 '#004DFF', 3544 '#0080C7', 3545 '#23890B', 3546 '#CC1B00', 3547 '#D6700A', 3548 '#222834', 3549 '#3E465B', 3550 '#6E7891', 3551 '#9FA6BC' 3552 ]; 3553 3554 randomColorElements.forEach(el => { 3555 const userColors = getData(el, 'random-color'); 3556 let colors; 3557 if (Array.isArray(userColors)) { 3558 colors = [...defaultColors, ...userColors]; 3559 } else { 3560 colors = [...defaultColors]; 3561 } 3562 3563 el.addEventListener('click', e => { 3564 const randomColor = 3565 colors[Math.floor(Math.random() * (colors.length - 1))]; 3566 e.target.value = randomColor; 3567 const inputLabel = e.target.nextElementSibling; 3568 // e.target.nextElementSibling.style.boxShadow = `0 0 0 0.2rem ${randomColor}`; 3569 inputLabel.style.background = `${randomColor}`; 3570 inputLabel.style.borderColor = `${randomColor}`; 3571 inputLabel.style.color = `white`; 3572 }); 3573 }); 3574 }; 3575 3576 /* -------------------------------------------------------------------------- */ 3577 /* Ratings */ 3578 /* -------------------------------------------------------------------------- */ 3579 3580 const ratingInit = () => { 3581 const { getData, getItemFromStore } = window.phoenix.utils; 3582 const raters = document.querySelectorAll('[data-rater]'); 3583
3584 raters.forEach(rater => { 3585 const options = { 3586 reverse: getItemFromStore('phoenixIsRTL'), 3587 starSize: 32, 3588 step: 0.5, 3589 element: rater, 3590 rateCallback(rating, done) { 3591 this.setRating(rating); 3592 done(); 3593 }, 3594 ...getData(rater, 'rater') 3595 }; 3596 3597 return window.raterJs(options); 3598 }); 3599 }; 3600 3601 /*eslint-disable*/ 3602 /*----------------------------------------------- 3603 | Top navigation opacity on scroll 3604 -----------------------------------------------*/ 3605 3606 const responsiveNavItemsInit = () => { 3607 const { resize } = window.phoenix.utils; 3608 const Selector = { 3609 NAV_ITEM: '[data-nav-item]', 3610 NAVBAR: '[data-navbar]', 3611 DROPDOWN: '[data-more-item]', 3612 CATEGORY_LIST: '[data-category-list]', 3613 CATEGORY_BUTTON: '[data-category-btn]' 3614 }; 3615 3616 const navbarEl = document.querySelector(Selector.NAVBAR); 3617 3618 const navbar = () => { 3619 const navbarWidth = navbarEl.clientWidth; 3620 const dropdown = navbarEl.querySelector(Selector.DROPDOWN); 3621 const dropdownWidth = dropdown.clientWidth;
3622 const navbarContainerWidth = navbarWidth - dropdownWidth; 3623 const elements = navbarEl.querySelectorAll(Selector.NAV_ITEM); 3624 const categoryBtn = navbarEl.querySelector(Selector.CATEGORY_BUTTON); 3625 const categoryBtnWidth = categoryBtn?.clientWidth; 3626 3627 let totalItemsWidth = 0; 3628 dropdown.style.display = 'none'; 3629 3630 elements.forEach(item => { 3631 const itemWidth = item.clientWidth; 3632 3633 totalItemsWidth = totalItemsWidth + itemWidth; 3634 3635 if ( 3636 totalItemsWidth + (categoryBtnWidth || 0) + dropdownWidth > 3637 navbarContainerWidth && 3638 !item.classList.contains('dropdown') 3639 ) { 3640 dropdown.style.display = 'block'; 3641 item.style.display = 'none'; 3642 const link = item.firstChild; 3643 const linkItem = link.cloneNode(true); 3644 3645 navbarEl.querySelector('.category-list').appendChild(linkItem); 3646 } 3647 }); 3648 const dropdownMenu = navbarEl.querySelectorAll('.dropdown-menu .nav-link'); 3649 3650 dropdownMenu.forEach(item => { 3651 item.classList.remove('nav-link'); 3652 item.classList.add('dropdown-item'); 3653 }); 3654 }; 3655 3656 if (navbarEl) { 3657 window.addEventListener('load', () => { 3658 navbar(); 3659 // hideDropdown(); 3660 }); 3661 3662 resize(() => { 3663 const navElements = navbarEl.querySelectorAll(Selector.NAV_ITEM); 3664 const dropElements = navbarEl.querySelectorAll(Selector.CATEGORY_LIST); 3665 3666 navElements.forEach(item => item.removeAttribute('style')); 3667 dropElements.forEach(item => (item.innerHTML = '')); 3668 navbar(); 3669 // hideDropdown(); 3670 }); 3671 3672 const navbarLinks = navbarEl.querySelectorAll('.nav-link'); 3673 3674 navbarEl.addEventListener('click', function (e) { 3675 for (let x = 0; x < navbarLinks.length; x++) { 3676 navbarLinks[x].classList.remove('active'); 3677 } 3678 if (e.target.closest('li')) { 3679 e.target.closest('li').classList.add('active'); 3680 } 3681 }); 3682 } 3683 }; 3684 3685 const searchInit = () => { 3686 const Selectors = { 3687 SEARCH_DISMISS: '[data-bs-dismiss="search"]', 3688 DROPDOWN_TOGGLE: '[data-bs-toggle="dropdown"]', 3689 DROPDOWN_MENU: '.dropdown-menu', 3690 SEARCH_BOX: '.search-box', 3691 SEARCH_INPUT: '.search-input', 3692 SEARCH_TOGGLE: '[data-bs-toggle="search"]' 3693 }; 3694 3695 const ClassName = { 3696 SHOW: 'show' 3697 }; 3698 3699 const Attribute = { 3700 ARIA_EXPANDED: 'aria-expanded' 3701 }; 3702 3703 const Events = { 3704 CLICK: 'click', 3705 FOCUS: 'focus', 3706 SHOW_BS_DROPDOWN: 'show.bs.dropdown', 3707 SEARCH_CLOSE: 'search.close' 3708 }; 3709 3710 const hideSearchSuggestion = searchArea => { 3711 const el = searchArea.querySelector(Selectors.SEARCH_TOGGLE); 3712 const dropdownMenu = searchArea.querySelector(Selectors.DROPDOWN_MENU); 3713 if (!el || !dropdownMenu) return; 3714 3715 el.setAttribute(Attribute.ARIA_EXPANDED, 'false'); 3716 el.classList.remove(ClassName.SHOW); 3717 dropdownMenu.classList.remove(ClassName.SHOW); 3718 }; 3719 3720 const searchAreas = document.querySelectorAll(Selectors.SEARCH_BOX); 3721 3722 const hideAllSearchAreas = () => { 3723 searchAreas.forEach(hideSearchSuggestion); 3724 }; 3725 3726 searchAreas.forEach(searchArea => { 3727 const input = searchArea.querySelector(Selectors.SEARCH_INPUT); 3728 const btnDropdownClose = searchArea.querySelector(Selectors.SEARCH_DISMISS); 3729 const dropdownMenu = searchArea.querySelector(Selectors.DROPDOWN_MENU); 3730 3731 if (input) { 3732 input.addEventListener(Events.FOCUS, () => { 3733 hideAllSearchAreas(); 3734 const el = searchArea.querySelector(Selectors.SEARCH_TOGGLE); 3735 if (!el || !dropdownMenu) return; 3736 el.setAttribute(Attribute.ARIA_EXPANDED, 'true'); 3737 el.classList.add(ClassName.SHOW); 3738 dropdownMenu.classList.add(ClassName.SHOW); 3739 }); 3740 } 3741 3742 document.addEventListener(Events.CLICK, ({ target }) => { 3743 !searchArea.contains(target) && hideSearchSuggestion(searchArea); 3744 }); 3745 3746 btnDropdownClose && 3747 btnDropdownClose.addEventListener(Events.CLICK, e => { 3748 hideSearchSuggestion(searchArea); 3749 input.value = ''; 3750 const event = new CustomEvent(Events.SEARCH_CLOSE); 3751 e.currentTarget.dispatchEvent(event); 3752 }); 3753 });
3754 3755 document.querySelectorAll(Selectors.DROPDOWN_TOGGLE).forEach(dropdown => { 3756 dropdown.addEventListener(Events.SHOW_BS_DROPDOWN, () => { 3757 hideAllSearchAreas(); 3758 }); 3759 }); 3760 }; 3761 3762 /* -------------------------------------------------------------------------- */ 3763 /* Toast */ 3764 /* -------------------------------------------------------------------------- */ 3765 3766 const simplebarInit = () => { 3767 const scrollEl = Array.from(document.querySelectorAll('.scrollbar-overlay')); 3768 3769 scrollEl.forEach(el => { 3770 return new window.SimpleBar(el); 3771 }); 3772 }; 3773 3774 /* -------------------------------------------------------------------------- */ 3775 /* SortableJS */ 3776 /* -------------------------------------------------------------------------- */ 3777 3778 const sortableInit = () => { 3779 const { getData } = window.phoenix.utils; 3780 3781 const sortableEl = document.querySelectorAll('[data-sortable]'); 3782 3783 const defaultOptions = { 3784 animation: 150, 3785 group: { 3786 name: 'shared' 3787 }, 3788 delay: 100, 3789 delayOnTouchOnly: true, // useful for mobile touch 3790 forceFallback: true, // * ignore the HTML5 DnD behaviour 3791 onStart() { 3792 document.body.classList.add('sortable-dragging'); // to add cursor grabbing 3793 }, 3794 onEnd() { 3795 document.body.classList.remove('sortable-dragging'); 3796 } 3797 }; 3798 3799 sortableEl.forEach(el => { 3800 const userOptions = getData(el, 'sortable'); 3801 const options = window._.merge(defaultOptions, userOptions); 3802 3803 return window.Sortable.create(el, options); 3804 }); 3805 }; 3806 3807 const supportChatInit = () => { 3808 const supportChat = document.querySelector('.support-chat'); 3809 const supportChatBtn = document.querySelectorAll('.btn-support-chat'); 3810 const supportChatcontainer = document.querySelector( 3811 '.support-chat-container' 3812 ); 3813 const { phoenixSupportChat } = window.config.config; 3814 3815 if (phoenixSupportChat) { 3816 supportChatcontainer?.classList.add('show'); 3817 } 3818 if (supportChatBtn) { 3819 supportChatBtn.forEach(item => { 3820 item.addEventListener('click', () => { 3821 supportChat.classList.toggle('show-chat'); 3822 3823 supportChatBtn[supportChatBtn.length - 1].classList.toggle( 3824 'btn-chat-close' 3825 ); 3826 3827 supportChatcontainer.classList.add('show'); 3828 }); 3829 }); 3830 } 3831 }; 3832 3833 /* eslint-disable no-new */ 3834 /*----------------------------------------------- 3835 | Swiper 3836 -----------------------------------------------*/ 3837 3838 const swiperInit = () => { 3839 const { getData } = window.phoenix.utils; 3840 const swiperContainers = document.querySelectorAll('.swiper-theme-container'); 3841 if (swiperContainers) { 3842 swiperContainers.forEach(swiperContainer => { 3843 const swiper = swiperContainer.querySelector('[data-swiper]'); 3844 const options = getData(swiper, 'swiper'); 3845 const thumbsOptions = options.thumb; 3846 let thumbsInit; 3847 if (thumbsOptions) { 3848 const thumbImages = swiper.querySelectorAll('img'); 3849 let slides = ''; 3850 thumbImages.forEach(img => { 3851 slides += ` 3852 <div class='swiper-slide'> 3853 <img class='img-fluid rounded mt-2' src=${img.src} alt=''/> 3854 </div> 3855 `; 3856 }); 3857 3858 const thumbs = document.createElement('div'); 3859 thumbs.setAttribute('class', 'swiper thumb'); 3860 thumbs.innerHTML = `<div class='swiper-wrapper'>${slides}</div>`; 3861 3862 if (thumbsOptions.parent) { 3863 const parent = document.querySelector(thumbsOptions.parent); 3864 parent.parentNode.appendChild(thumbs); 3865 } else { 3866 swiper.parentNode.appendChild(thumbs); 3867 } 3868 3869 thumbsInit = new window.Swiper(thumbs, thumbsOptions); 3870 } 3871 const swiperNav = swiperContainer.querySelector('.swiper-nav'); 3872 new window.Swiper(swiper, { 3873 ...options, 3874 navigation: { 3875 nextEl: swiperNav?.querySelector('.swiper-button-next'), 3876 prevEl: swiperNav?.querySelector('.swiper-button-prev') 3877 }, 3878 thumbs: { 3879 swiper: thumbsInit 3880 } 3881 }); 3882 const gallerySlider = document.querySelector('.swiper-slider-gallery'); 3883 if (gallerySlider) { 3884 window.addEventListener('resize', () => {
3885 thumbsInit.update(); 3886 }); 3887 } 3888 }); 3889 } 3890 }; 3891 3892 /* -------------------------------------------------------------------------- */ 3893 /* Theme Control */ 3894 /* -------------------------------------------------------------------------- */ 3895 /* eslint-disable no-param-reassign */ 3896 /* eslint-disable */ 3897 const { config } = window.config; 3898 3899 const initialDomSetup = element => { 3900 const { getData, getItemFromStore, getSystemTheme } = window.phoenix.utils; 3901 if (!element) return; 3902 3903 element.querySelectorAll('[data-theme-control]').forEach(el => { 3904 const inputDataAttributeValue = getData(el, 'theme-control'); 3905 const localStorageValue = getItemFromStore(inputDataAttributeValue); 3906 3907 // diable horizontal navbar shape for dual nav 3908 if ( 3909 inputDataAttributeValue === 'phoenixNavbarTopShape' && 3910 getItemFromStore('phoenixNavbarPosition') === 'dual-nav' 3911 ) { 3912 el.setAttribute('disabled', true); 3913 } 3914 3915 // diable navbar vertical style for horizontal & dual navbar 3916 const currentNavbarPosition = getItemFromStore('phoenixNavbarPosition'); 3917 const isHorizontalOrDualNav = 3918 currentNavbarPosition === 'horizontal' || 3919 currentNavbarPosition === 'dual-nav'; 3920 if ( 3921 inputDataAttributeValue === 'phoenixNavbarVerticalStyle' && 3922 isHorizontalOrDualNav 3923 ) { 3924 el.setAttribute('disabled', true); 3925 } 3926 3927 if (el.type === 'checkbox') { 3928 if (inputDataAttributeValue === 'phoenixTheme') { 3929 if ( 3930 localStorageValue === 'auto' 3931 ? getSystemTheme() === 'dark' 3932 : localStorageValue === 'dark' 3933 ) { 3934 el.setAttribute('checked', true); 3935 } 3936 } else { 3937 localStorageValue && el.setAttribute('checked', true); 3938 } 3939 } else if ( 3940 el.type === 'radio' && 3941 inputDataAttributeValue === 'phoenixNavbarVerticalStyle' 3942 ) { 3943 localStorageValue === 'darker' && 3944 el.value === 'darker' && 3945 el.setAttribute('checked', true); 3946 localStorageValue === 'default' && 3947 el.value === 'default' && 3948 el.setAttribute('checked', true); 3949 } else if ( 3950 el.type === 'radio' && 3951 inputDataAttributeValue === 'phoenixNavbarTopShape' 3952 ) { 3953 localStorageValue === 'slim' && 3954 el.value === 'slim' && 3955 el.setAttribute('checked', true); 3956 localStorageValue === 'default' && 3957 el.value === 'default' && 3958 el.setAttribute('checked', true); 3959 } else if ( 3960 el.type === 'radio' && 3961 inputDataAttributeValue === 'phoenixNavbarTopStyle' 3962 ) { 3963 localStorageValue === 'darker' && 3964 el.value === 'darker' && 3965 el.setAttribute('checked', true); 3966 localStorageValue === 'default' && 3967 el.value === 'default' && 3968 el.setAttribute('checked', true); 3969 } else if ( 3970 el.type === 'radio' && 3971 inputDataAttributeValue === 'phoenixTheme' 3972 ) { 3973 const isChecked = localStorageValue === el.value; 3974 isChecked && el.setAttribute('checked', true); 3975 } else if ( 3976 el.type === 'radio' && 3977 inputDataAttributeValue === 'phoenixNavbarPosition' 3978 ) { 3979 const isChecked = localStorageValue === el.value; 3980 isChecked && el.setAttribute('checked', true); 3981 } else { 3982 const isActive = localStorageValue === el.value; 3983 isActive && el.classList.add('active'); 3984 } 3985 }); 3986 }; 3987 3988 const changeTheme = element => { 3989 const { getData, getItemFromStore, getSystemTheme } = window.phoenix.utils; 3990 3991 element 3992 .querySelectorAll('[data-theme-control = "phoenixTheme"]') 3993 .forEach(el => { 3994 const inputDataAttributeValue = getData(el, 'theme-control'); 3995 const localStorageValue = getItemFromStore(inputDataAttributeValue); 3996 3997 if (el.type === 'checkbox') { 3998 if (localStorageValue === 'auto') { 3999 getSystemTheme() === 'dark' 4000 ? (el.checked = true) 4001 : (el.checked = false); 4002 } else { 4003 localStorageValue === 'dark' 4004 ? (el.checked = true) 4005 : (el.checked = false); 4006 } 4007 } else if (el.type === 'radio') { 4008 localStorageValue === el.value 4009 ? (el.checked = true) 4010 : (el.checked = false); 4011 } else { 4012 localStorageValue === el.value 4013 ? el.classList.add('active') 4014 : el.classList.remove('active'); 4015 } 4016 }); 4017 }; 4018 4019 const handleThemeDropdownIcon = value => { 4020 document.querySelectorAll('[data-theme-dropdown-toggle-icon]').forEach(el => { 4021 el.classList.toggle( 4022 'd-none', 4023 value !== el.getAttribute('data-theme-dropdown-toggle-icon') 4024 // value !== getData(el, 'theme-dropdown-toggle-icon') 4025 ); 4026 });
4027 }; 4028 4029 handleThemeDropdownIcon(localStorage.getItem('phoenixTheme')); 4030 4031 const themeControl = () => { 4032 const { getData, getItemFromStore, getSystemTheme } = window.phoenix.utils; 4033 // handleThemeDropdownIcon( 4034 // window.phoenix.utils.getItemFromStore('phoenixTheme'), 4035 // getData 4036 // ); 4037 4038 const handlePageUrl = el => { 4039 const pageUrl = getData(el, 'page-url'); 4040 if (pageUrl) { 4041 window.location.replace(pageUrl); 4042 } else { 4043 window.location.reload(); 4044 } 4045 }; 4046 4047 const themeController = new DomNode(document.body); 4048 4049 const navbarVertical = document.querySelector('.navbar-vertical'); 4050 const navbarTop = document.querySelector('.navbar-top'); 4051 const supportChat = document.querySelector('.support-chat-container'); 4052 initialDomSetup(themeController.node); 4053 4054 themeController.on('click', e => { 4055 const target = new DomNode(e.target); 4056 4057 if (target.data('theme-control')) { 4058 const control = target.data('theme-control'); 4059 4060 let value = e.target[e.target.type === 'checkbox' ? 'checked' : 'value']; 4061 4062 if (control === 'phoenixTheme') { 4063 typeof value === 'boolean' && (value = value ? 'dark' : 'light'); 4064 } 4065 4066 // config.hasOwnProperty(control) && setItemToStore(control, value); 4067 config.hasOwnProperty(control) && 4068 window.config.set({ 4069 [control]: value 4070 }); 4071 4072 const params = new URLSearchParams(window.location.search); 4073 const isThemeControlTrue = params.get('theme-control') === 'true'; 4074 if (isThemeControlTrue) { 4075 window.history.replaceState(null, null, window.location.pathname); 4076 } 4077 4078 switch (control) { 4079 case 'phoenixTheme': { 4080 document.documentElement.setAttribute( 4081 'data-bs-theme', 4082 value === 'auto' ? getSystemTheme() : value 4083 ); 4084 // document.documentElement.classList[ 4085 // value === 'dark' ? 'add' : 'remove' 4086 // ]('dark'); 4087 const clickControl = new CustomEvent('clickControl', { 4088 detail: { control, value } 4089 }); 4090 e.currentTarget.dispatchEvent(clickControl); 4091 changeTheme(themeController.node); 4092 break; 4093 } 4094 case 'phoenixNavbarVerticalStyle': { 4095 navbarVertical.setAttribute('data-navbar-appearance', 'default'); 4096 if (value !== 'default') { 4097 navbarVertical.setAttribute('data-navbar-appearance', 'darker'); 4098 } 4099 break; 4100 } 4101 case 'phoenixNavbarTopStyle': { 4102 navbarTop.setAttribute('data-navbar-appearance', 'default'); 4103 if (value !== 'default') { 4104 navbarTop.setAttribute('data-navbar-appearance', 'darker'); 4105 } 4106 break; 4107 } 4108 case 'phoenixNavbarTopShape': 4109 { 4110 if (getItemFromStore('phoenixNavbarPosition') === 'dual-nav') { 4111 el.setAttribute('disabled', true); 4112 // document.documentElement.setAttribute("data-bs-theme", value); 4113 } else handlePageUrl(target.node); 4114 } 4115 break; 4116 case 'phoenixNavbarPosition': 4117 { 4118 handlePageUrl(target.node); 4119 } 4120 4121 break; 4122 case 'phoenixIsRTL': 4123 { 4124 // localStorage.setItem('phoenixIsRTL', target.node.checked); 4125 window.config.set({ 4126 phoenixIsRTL: target.node.checked 4127 }); 4128 window.location.reload(); 4129 } 4130 break; 4131 4132 case 'phoenixSupportChat': { 4133 supportChat?.classList.remove('show'); 4134 if (value) { 4135 supportChat?.classList.add('show'); 4136 } 4137 break; 4138 } 4139 4140 case 'reset': { 4141 window.config.reset(); 4142 window.location.reload(); 4143 break; 4144 } 4145 4146 default: { 4147 window.location.reload(); 4148 } 4149 } 4150 } 4151 });
4152 4153 themeController.on('clickControl', ({ detail: { control, value } }) => { 4154 if (control === 'phoenixTheme') { 4155 handleThemeDropdownIcon(value); 4156 } 4157 }); 4158 }; 4159 4160 const { merge } = window._; 4161 4162 /* -------------------------------------------------------------------------- */ 4163 /* Tinymce */ 4164 /* -------------------------------------------------------------------------- */ 4165 4166 const tinymceInit = () => { 4167 const { getColor, getData, getItemFromStore } = window.phoenix.utils; 4168 4169 const tinymces = document.querySelectorAll('[data-tinymce]'); 4170 4171 if (window.tinymce) { 4172 // const wrapper = document.querySelector('.tox-sidebar-wrap'); 4173 tinymces.forEach(tinymceEl => { 4174 const userOptions = getData(tinymceEl, 'tinymce'); 4175 const options = merge( 4176 { 4177 selector: '.tinymce', 4178 height: '50vh', 4179 skin: 'oxide', 4180 menubar: false, 4181 content_style: ` 4182 .mce-content-body { 4183 color: ${getColor('emphasis-color')}; 4184 background-color: ${getColor('tinymce-bg')}; 4185 } 4186 .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before { 4187 color: ${getColor('quaternary-color')}; 4188 font-weight: 400; 4189 font-size: 12.8px; 4190 } 4191 `, 4192 // mobile: { 4193 // theme: 'mobile', 4194 // toolbar: ['undo', 'bold'] 4195 // }, 4196 statusbar: false, 4197 plugins: 'link,image,lists,table,media', 4198 theme_advanced_toolbar_align: 'center', 4199 directionality: getItemFromStore('phoenixIsRTL') ? 'rtl' : 'ltr', 4200 toolbar: [ 4201 { name: 'history', items: ['undo', 'redo'] }, 4202 { 4203 name: 'formatting', 4204 items: ['bold', 'italic', 'underline', 'strikethrough'] 4205 }, 4206 { 4207 name: 'alignment', 4208 items: ['alignleft', 'aligncenter', 'alignright', 'alignjustify'] 4209 }, 4210 { name: 'list', items: ['numlist', 'bullist'] }, 4211 { name: 'link', items: ['link'] } 4212 ], 4213 setup: editor => { 4214 editor.on('focus', () => { 4215 const wraper = document.querySelector('.tox-sidebar-wrap'); 4216 wraper.classList.add('editor-focused'); 4217 }); 4218 editor.on('blur', () => { 4219 const wraper = document.querySelector('.tox-sidebar-wrap'); 4220 wraper.classList.remove('editor-focused'); 4221 }); 4222 } 4223 }, 4224 userOptions 4225 ); 4226 window.tinymce.init(options); 4227 }); 4228 4229 const themeController = document.body; 4230 if (themeController) { 4231 themeController.addEventListener( 4232 'clickControl', 4233 ({ detail: { control } }) => { 4234 if (control === 'phoenixTheme') { 4235 tinymces.forEach(tinymceEl => { 4236 const instance = window.tinymce.get(tinymceEl.id); 4237 instance.dom.addStyle( 4238 `.mce-content-body{ 4239 color: ${getColor('emphasis-color')} !important; 4240 background-color: ${getColor('tinymce-bg')} !important; 4241 }` 4242 ); 4243 }); 4244 } 4245 } 4246 ); 4247 } 4248 } 4249 }; 4250 4251 /* -------------------------------------------------------------------------- */ 4252 /* Toast */ 4253 /* -------------------------------------------------------------------------- */ 4254 4255 const toastInit = () => { 4256 const toastElList = [].slice.call(document.querySelectorAll('.toast')); 4257 toastElList.map(toastEl => new bootstrap.Toast(toastEl)); 4258 4259 const liveToastBtn = document.getElementById('liveToastBtn'); 4260 4261 if (liveToastBtn) { 4262 const liveToast = new bootstrap.Toast(document.getElementById('liveToast'));
4263 4264 liveToastBtn.addEventListener('click', () => { 4265 liveToast && liveToast.show(); 4266 }); 4267 } 4268 }; 4269 4270 /* -------------------------------------------------------------------------- */ 4271 /* TODO Offacanvas */ 4272 /* -------------------------------------------------------------------------- */ 4273 4274 const todoOffcanvasInit = () => { 4275 const { getData } = window.phoenix.utils; 4276 4277 const stopPropagationElements = document.querySelectorAll( 4278 '[data-event-propagation-prevent]' 4279 ); 4280 4281 if (stopPropagationElements) { 4282 stopPropagationElements.forEach(el => { 4283 el.addEventListener('click', e => { 4284 e.stopPropagation(); 4285 }); 4286 }); 4287 } 4288 4289 const todoList = document.querySelector('.todo-list'); 4290 4291 if (todoList) { 4292 const offcanvasToggles = todoList.querySelectorAll( 4293 '[data-todo-offcanvas-toogle]' 4294 ); 4295 4296 offcanvasToggles.forEach(toggle => { 4297 const target = getData(toggle, 'todo-offcanvas-target'); 4298 const offcanvasEl = todoList.querySelector(`#${target}`); 4299 const todoOffcanvas = new window.bootstrap.Offcanvas(offcanvasEl, { 4300 backdrop: true 4301 }); 4302 toggle.addEventListener('click', () => { 4303 todoOffcanvas.show(); 4304 }); 4305 }); 4306 } 4307 }; 4308 4309 /* -------------------------------------------------------------------------- */ 4310 /* Tooltip */ 4311 /* -------------------------------------------------------------------------- */ 4312 const tooltipInit = () => { 4313 const tooltipTriggerList = [].slice.call( 4314 document.querySelectorAll('[data-bs-toggle="tooltip"]') 4315 ); 4316 4317 tooltipTriggerList.map( 4318 tooltipTriggerEl => 4319 new bootstrap.Tooltip(tooltipTriggerEl, { 4320 trigger: 'hover' 4321 }) 4322 ); 4323 }; 4324 4325 /* eslint-disable no-restricted-syntax */ 4326 /* -------------------------------------------------------------------------- */ 4327 /* step wizard */ 4328 /* -------------------------------------------------------------------------- */ 4329 const wizardInit = () => { 4330 const { getData } = window.phoenix.utils; 4331 4332 const selectors = { 4333 WIZARDS: '[data-theme-wizard]', 4334 TOGGLE_BUTTON_EL: '[data-wizard-step]', 4335 FORMS: '[data-wizard-form]', 4336 PASSWORD_INPUT: '[data-wizard-password]', 4337 CONFIRM_PASSWORD_INPUT: '[data-wizard-confirm-password]', 4338 NEXT_BTN: '[data-wizard-next-btn]', 4339 PREV_BTN: '[data-wizard-prev-btn]', 4340 FOOTER: '[data-wizard-footer]' 4341 }; 4342 4343 const events = { 4344 SUBMIT: 'submit', 4345 SHOW: 'show.bs.tab', 4346 SHOWN: 'shown.bs.tab', 4347 CLICK: 'click' 4348 }; 4349 4350 const wizards = document.querySelectorAll(selectors.WIZARDS); 4351 4352 wizards.forEach(wizard => { 4353 const tabToggleButtonEl = wizard.querySelectorAll( 4354 selectors.TOGGLE_BUTTON_EL 4355 ); 4356 const forms = wizard.querySelectorAll(selectors.FORMS); 4357 const passwordInput = wizard.querySelector(selectors.PASSWORD_INPUT); 4358 const confirmPasswordInput = wizard.querySelector( 4359 selectors.CONFIRM_PASSWORD_INPUT 4360 ); 4361 const nextButton = wizard.querySelector(selectors.NEXT_BTN); 4362 const prevButton = wizard.querySelector(selectors.PREV_BTN); 4363 const wizardFooter = wizard.querySelector(selectors.FOOTER); 4364 const submitEvent = new Event(events.SUBMIT, { 4365 bubbles: true, 4366 cancelable: true 4367 }); 4368 const hasWizardModal = wizard.hasAttribute('data-wizard-modal-disabled'); 4369 4370 const tabs = Array.from(tabToggleButtonEl).map(item => { 4371 return window.bootstrap.Tab.getOrCreateInstance(item); 4372 }); 4373 // console.log({ tabs }); 4374 4375 let count = 0; 4376 let showEvent = null; 4377 4378 forms.forEach(form => { 4379 form.addEventListener(events.SUBMIT, e => { 4380 e.preventDefault(); 4381 if (form.classList.contains('needs-validation')) { 4382 if (passwordInput && confirmPasswordInput) { 4383 if (passwordInput.value !== confirmPasswordInput.value) { 4384 confirmPasswordInput.setCustomValidity('Invalid field.'); 4385 } else { 4386 confirmPasswordInput.setCustomValidity(''); 4387 } 4388 } 4389 if (!form.checkValidity()) { 4390 showEvent.preventDefault(); 4391 return false; 4392 } 4393 } 4394 count += 1; 4395 return null; 4396 }); 4397 }); 4398 4399 nextButton.addEventListener(events.CLICK, () => { 4400 if (count + 1 < tabs.length) { 4401 tabs[count + 1].show(); 4402 } 4403 }); 4404 4405 if (prevButton) { 4406 prevButton.addEventListener(events.CLICK, () => { 4407 count -= 1;
4408 tabs[count].show(); 4409 }); 4410 } 4411 4412 if (tabToggleButtonEl.length) { 4413 tabToggleButtonEl.forEach((item, index) => { 4414 item.addEventListener(events.SHOW, e => { 4415 const step = getData(item, 'wizard-step'); 4416 showEvent = e; 4417 if (step > count) { 4418 forms[count].dispatchEvent(submitEvent); 4419 } 4420 }); 4421 item.addEventListener(events.SHOWN, () => { 4422 count = index; 4423 // can't go back tab 4424 if (count === tabToggleButtonEl.length - 1 && !hasWizardModal) { 4425 tabToggleButtonEl.forEach(tab => { 4426 tab.setAttribute('data-bs-toggle', 'modal'); 4427 tab.setAttribute('data-bs-target', '#error-modal'); 4428 }); 4429 } 4430 // add done class 4431 for (let i = 0; i < count; i += 1) { 4432 tabToggleButtonEl[i].classList.add('done'); 4433 if (i > 0) { 4434 tabToggleButtonEl[i - 1].classList.add('complete'); 4435 } 4436 } 4437 // remove done class 4438 for (let j = count; j < tabToggleButtonEl.length; j += 1) { 4439 tabToggleButtonEl[j].classList.remove('done'); 4440 if (j > 0) { 4441 tabToggleButtonEl[j - 1].classList.remove('complete'); 4442 } 4443 } 4444 4445 // card footer remove at last step 4446 if (count > tabToggleButtonEl.length - 2) { 4447 wizardFooter.classList.add('d-none'); 4448 } else { 4449 wizardFooter.classList.remove('d-none'); 4450 } 4451 // prev-button removing 4452 if (prevButton) { 4453 if (count > 0 && count !== tabToggleButtonEl.length - 1) { 4454 prevButton.classList.remove('d-none'); 4455 } else { 4456 prevButton.classList.add('d-none'); 4457 } 4458 } 4459 }); 4460 }); 4461 } 4462 }); 4463 }; 4464 4465 const faqTabInit = () => { 4466 const triggerEls = document.querySelectorAll('[data-vertical-category-tab]'); 4467 const offcanvasEle = document.querySelector( 4468 '[data-vertical-category-offcanvas]' 4469 ); 4470 const filterEles = document.querySelectorAll('[data-category-filter]'); 4471 const faqSubcategoryTabs = document.querySelectorAll( 4472 '.faq-subcategory-tab .nav-item' 4473 ); 4474 4475 if (offcanvasEle) { 4476 const offcanvas = 4477 window.bootstrap.Offcanvas?.getOrCreateInstance(offcanvasEle); 4478 4479 triggerEls.forEach(el => { 4480 el.addEventListener('click', () => { 4481 offcanvas.hide(); 4482 }); 4483 }); 4484 } 4485 4486 if (filterEles) { 4487 filterEles.forEach(el => { 4488 if (el.classList.contains('active')) {
4489 faqSubcategoryTabs.forEach(item => { 4490 if ( 4491 !item.classList.contains(el.getAttribute('data-category-filter')) && 4492 el.getAttribute('data-category-filter') !== 'all' 4493 ) { 4494 item.classList.add('d-none'); 4495 } 4496 }); 4497 } 4498 el.addEventListener('click', () => { 4499 faqSubcategoryTabs.forEach(item => { 4500 if (el.getAttribute('data-category-filter') === 'all') { 4501 item.classList.remove('d-none'); 4502 } else if ( 4503 !item.classList.contains(el.getAttribute('data-category-filter')) 4504 ) { 4505 item.classList.add('d-none'); 4506 } 4507 }); 4508 }); 4509 }); 4510 } 4511 }; 4512 4513 /* -------------------------------------------------------------------------- */ 4514 /* Kanban */ 4515 /* -------------------------------------------------------------------------- */ 4516 4517 const kanbanInit = () => { 4518 // kanbanContainer to controll collapse behavior in kanban board 4519 const kanbanContainer = document.querySelector('[data-kanban-container]'); 4520 if (kanbanContainer) { 4521 kanbanContainer.addEventListener('click', e => { 4522 if (e.target.hasAttribute('data-kanban-collapse')) { 4523 e.target.closest('.kanban-column').classList.toggle('collapsed'); 4524 } 4525 }); 4526 4527 const kanbanGroups = kanbanContainer.querySelectorAll('[data-sortable]'); 4528 kanbanGroups.forEach(item => { 4529 const itemInstance = window.Sortable.get(item); 4530 itemInstance.option('onStart', e => { 4531 document.body.classList.add('sortable-dragging'); 4532 window.Sortable.ghost 4533 .querySelector('.dropdown-menu') 4534 ?.classList.remove('show'); 4535 const dropdownElement = e.item.querySelector( 4536 `[data-bs-toggle='dropdown']` 4537 ); 4538 window.bootstrap.Dropdown.getInstance(dropdownElement)?.hide(); 4539 }); 4540 4541 // return itemInstance; 4542 }); 4543 } 4544 }; 4545 4546 const towFAVerificarionInit = () => { 4547 const verificationForm = document.querySelector('[data-2fa-form]'); 4548 const inputFields = verificationForm?.querySelectorAll('input[type=number]'); 4549 const varificationBtn = verificationForm?.querySelector( 4550 'button[type=submit]' 4551 ); 4552 4553 if (verificationForm) { 4554 window.addEventListener('load', () => inputFields[0].focus()); 4555 const totalInputLength = 6; 4556 inputFields.forEach((input, index) => { 4557 input.addEventListener('keyup', e => { 4558 const { value } = e.target; 4559 if (value) { 4560 [...value].slice(0, totalInputLength).forEach((char, charIndex) => { 4561 if (inputFields && inputFields[index + charIndex]) { 4562 inputFields[index + charIndex].value = char; 4563 inputFields[index + charIndex + 1]?.focus(); 4564 } 4565 }); 4566 } else { 4567 inputFields[index].value = ''; 4568 inputFields[index - 1]?.focus(); 4569 } 4570 const inputs = [...inputFields]; 4571 const updatedOtp = inputs.reduce( 4572 (acc, inputData) => acc + (inputData?.value || ''), 4573 '' 4574 ); 4575 if (totalInputLength === updatedOtp.length) { 4576 varificationBtn.removeAttribute('disabled'); 4577 } else { 4578 varificationBtn.setAttribute('disabled', true); 4579 } 4580 }); 4581 }); 4582 } 4583 }; 4584 4585 /* -------------------------------------------------------------------------- */ 4586 /* mapbox */ 4587 /* -------------------------------------------------------------------------- */ 4588 4589 const mapboxInit = () => { 4590 const { getData } = window.phoenix.utils; 4591 const mapboxContainers = document.querySelectorAll('.mapbox-container'); 4592 const mapContainerTab = document.querySelectorAll('[data-tab-map-container]');
4593 if (mapboxContainers) { 4594 mapboxContainers.forEach(mapboxContainer => { 4595 window.mapboxgl.accessToken = 4596 'pk.eyJ1IjoidGhlbWV3YWdvbiIsImEiOiJjbGhmNW5ybzkxcmoxM2RvN2RmbW1nZW90In0.hGIvQ890TYkZ948MVrsMIQ'; 4597 4598 const mapbox = mapboxContainer.querySelector('[data-mapbox]'); 4599 if (mapbox) { 4600 const options = getData(mapbox, 'mapbox'); 4601 4602 const zoomIn = document.querySelector('.zoomIn'); 4603 const zoomOut = document.querySelector('.zoomOut'); 4604 const fullScreen = document.querySelector('.fullScreen'); 4605 4606 const styles = { 4607 default: 'mapbox://styles/mapbox/light-v11', 4608 light: 'mapbox://styles/themewagon/clj57pads001701qo25756jtw', 4609 dark: 'mapbox://styles/themewagon/cljzg9juf007x01pk1bepfgew' 4610 }; 4611 4612 const map = new window.mapboxgl.Map({ 4613 ...options, 4614 container: 'mapbox', 4615 style: styles[window.config.config.phoenixTheme] 4616 }); 4617 4618 if (options.center) { 4619 new window.mapboxgl.Marker({ 4620 color: getColor('danger') 4621 }) 4622 .setLngLat(options.center) 4623 .addTo(map); 4624 } 4625 4626 if (zoomIn && zoomOut) { 4627 zoomIn.addEventListener('click', () => map.zoomIn()); 4628 zoomOut.addEventListener('click', () => map.zoomOut()); 4629 } 4630 if (fullScreen) { 4631 fullScreen.addEventListener('click', () => 4632 map.getContainer().requestFullscreen() 4633 ); 4634 } 4635 4636 mapContainerTab.forEach(ele => { 4637 ele.addEventListener('shown.bs.tab', () => { 4638 map.resize(); 4639 }); 4640 }); 4641 } 4642 }); 4643 } 4644 }; 4645 4646 const themeController$2 = document.body; 4647 if (themeController$2) { 4648 themeController$2.addEventListener('clickControl', () => { 4649 mapboxInit(); 4650 }); 4651 } 4652 4653 const flightMapInit = () => { 4654 const flightMap = document.querySelector('#flightMap'); 4655 if (flightMap) { 4656 window.mapboxgl.accessToken = 4657 'pk.eyJ1IjoidGhlbWV3YWdvbiIsImEiOiJjbGhmNW5ybzkxcmoxM2RvN2RmbW1nZW90In0.hGIvQ890TYkZ948MVrsMIQ'; 4658 4659 const zoomIn = document.querySelector('.zoomIn'); 4660 const zoomOut = document.querySelector('.zoomOut'); 4661 const fullScreen = document.querySelector('.fullScreen'); 4662 4663 const styles = { 4664 default: 'mapbox://styles/mapbox/light-v11', 4665 light: 'mapbox://styles/themewagon/clj57pads001701qo25756jtw', 4666 dark: 'mapbox://styles/themewagon/cljzg9juf007x01pk1bepfgew' 4667 }; 4668 4669 const map = new window.mapboxgl.Map({ 4670 container: 'flightMap', 4671 style: styles[window.config.config.phoenixTheme], 4672 center: [-73.102712, 7.102257], 4673 zoom: 5, 4674 pitch: 40, 4675 attributionControl: false 4676 }); 4677 4678 zoomIn.addEventListener('click', () => map.zoomIn()); 4679 zoomOut.addEventListener('click', () => map.zoomOut()); 4680 fullScreen.addEventListener('click', () => 4681 map.getContainer().requestFullscreen() 4682 ); 4683 4684 const origin = [-61.100583, 5.044713]; 4685 const currentPosition = [-74.2139449434892, 8.136553550752552]; 4686 const destination = [-84.913785, 10.325774]; 4687 4688 const originToCurrentRoute = { 4689 type: 'FeatureCollection', 4690 features: [ 4691 { 4692 type: 'Feature', 4693 geometry: { 4694 type: 'LineString', 4695 coordinates: [origin, currentPosition] 4696 } 4697 } 4698 ] 4699 }; 4700 const currentToDestinationRoute = { 4701 type: 'FeatureCollection', 4702 features: [ 4703 { 4704 type: 'Feature', 4705 geometry: { 4706 type: 'LineString', 4707 coordinates: [currentPosition, destination] 4708 } 4709 } 4710 ] 4711 }; 4712 4713 const points = { 4714 type: 'FeatureCollection', 4715 features: [ 4716 { 4717 type: 'Feature', 4718 properties: {}, 4719 geometry: { 4720 type: 'Point', 4721 coordinates: origin 4722 } 4723 }, 4724 { 4725 type: 'Feature', 4726 properties: {}, 4727 geometry: { 4728 type: 'Point', 4729 coordinates: currentPosition 4730 } 4731 }, 4732 { 4733 type: 'Feature', 4734 properties: {}, 4735 geometry: { 4736 type: 'Point', 4737 coordinates: destination 4738 } 4739 } 4740 ] 4741 }; 4742 4743 let count = 1;
4744 points.features.forEach(feature => { 4745 const el = document.createElement('div'); 4746 el.className = `marker-${count}`; 4747 new window.mapboxgl.Marker(el) 4748 .setLngLat(feature.geometry.coordinates) 4749 .addTo(map); 4750 count += 1; 4751 }); 4752 4753 const lineDistance = window.turf.length(originToCurrentRoute.features[0]); 4754 const lineDistance2 = window.turf.length(originToCurrentRoute.features[0]); 4755 4756 const arc = []; 4757 const arc2 = []; 4758 4759 const steps = 500; 4760 4761 for (let i = 0; i < lineDistance; i += lineDistance / steps) { 4762 const segment = window.turf.along(originToCurrentRoute.features[0], i); 4763 arc.push(segment.geometry.coordinates); 4764 } 4765 for (let i = 0; i < lineDistance2; i += lineDistance2 / steps) { 4766 const segment = window.turf.along( 4767 currentToDestinationRoute.features[0], 4768 i 4769 ); 4770 arc2.push(segment.geometry.coordinates); 4771 } 4772 4773 originToCurrentRoute.features[0].geometry.coordinates = arc; 4774 currentToDestinationRoute.features[0].geometry.coordinates = arc2; 4775 4776 map.on('load', () => { 4777 map.addSource('route', { 4778 type: 'geojson', 4779 data: originToCurrentRoute.features[0] 4780 }); 4781 map.addSource('route2', { 4782 type: 'geojson', 4783 data: currentToDestinationRoute.features[0] 4784 }); 4785 4786 map.addLayer({ 4787 id: 'route', 4788 source: 'route', 4789 type: 'line', 4790 paint: { 4791 'line-width': 2, 4792 'line-color': 4793 getItemFromStore('phoenixTheme') === 'dark' 4794 ? getColor('primary') 4795 : getColor('primary-light') 4796 } 4797 }); 4798 map.addLayer({ 4799 id: 'route2', 4800 source: 'route2', 4801 type: 'line', 4802 paint: { 4803 'line-width': 1, 4804 'line-color': getColor('warning') 4805 } 4806 }); 4807 }); 4808 } 4809 }; 4810 4811 const themeController$1 = document.body; 4812 if (themeController$1) { 4813 themeController$1.addEventListener('clickControl', () => { 4814 flightMapInit(); 4815 }); 4816 } 4817 4818 /* -------------------------------------------------------------------------- */ 4819 /* Typed Text */ 4820 /* -------------------------------------------------------------------------- */ 4821 4822 const typedTextInit = () => { 4823 const typedTexts = document.querySelectorAll('.typed-text'); 4824 if (typedTexts.length && window.Typed) { 4825 typedTexts.forEach(typedText => { 4826 return new window.Typed(typedText, { 4827 strings: getData(typedText, 'typedText'), 4828 typeSpeed: 70, 4829 backSpeed: 70, 4830 loop: true, 4831 backDelay: 1000 4832 }); 4833 }); 4834 } 4835 }; 4836 4837 /* -------------------------------------------------------------------------- */ 4838 /* price tier form */ 4839 /* -------------------------------------------------------------------------- */ 4840 4841 const priceTierFormInit = () => { 4842 const priceTierForms = document.querySelectorAll('[data-form-price-tier]'); 4843 if (priceTierForms) { 4844 priceTierForms.forEach(priceTierForm => { 4845 const priceToggler = priceTierForm.querySelector('[data-price-toggle]'); 4846 const pricings = priceTierForm.querySelectorAll('[data-pricing]'); 4847 const bottomOption = priceTierForm.querySelector( 4848 '[data-pricing-collapse]' 4849 ); 4850 4851 const pricingCollapse = new window.bootstrap.Collapse(bottomOption, { 4852 toggle: false 4853 }); 4854 4855 priceToggler.addEventListener('change', e => { 4856 pricings[0].checked = true; 4857 if (e.target.checked) { 4858 priceTierForm.classList.add('active'); 4859 } else { 4860 priceTierForm.classList.remove('active'); 4861 pricingCollapse.hide(); 4862 } 4863 }); 4864 pricings.forEach(pricing => { 4865 pricing.addEventListener('change', e => { 4866 if (e.target.value === 'paid') { 4867 pricingCollapse.show(); 4868 } else { 4869 pricingCollapse.hide(); 4870 } 4871 }); 4872 }); 4873 }); 4874 } 4875 }; 4876 4877 /* -------------------------------------------------------------------------- */ 4878 /* noUiSlider */ 4879 /* -------------------------------------------------------------------------- */ 4880 const nouisliderInit = () => { 4881 const { getData } = window.phoenix.utils; 4882 if (window.noUiSlider) { 4883 const elements = document.querySelectorAll('[data-nouislider]');
4884 elements.forEach(item => { 4885 const userOptions = getData(item, 'nouislider'); 4886 const sliderValues = getData(item, 'nouislider-values'); 4887 let defaultOptions; 4888 if (sliderValues && sliderValues.length) { 4889 defaultOptions = { 4890 connect: true, 4891 step: 1, 4892 range: { min: 0, max: sliderValues.length - 1 }, 4893 tooltips: true, 4894 format: { 4895 to(value) { 4896 return sliderValues[Math.round(value)]; 4897 }, 4898 from(value) { 4899 return sliderValues.indexOf(value); 4900 } 4901 } 4902 }; 4903 } else { 4904 defaultOptions = { 4905 start: [10], 4906 connect: [true, false], 4907 step: 1, 4908 range: { min: [0], max: [100] }, 4909 tooltips: true 4910 }; 4911 } 4912 const options = window._.merge(defaultOptions, userOptions); 4913 window.noUiSlider.create(item, { ...options }); 4914 }); 4915 } 4916 }; 4917 4918 const collapseAllInit = () => { 4919 const collapseParent = document.querySelector('[data-collapse-all]'); 4920 const collapseBtn = document.querySelector('[data-btn-collapse-all]'); 4921 if (collapseParent) { 4922 const collapseElements = collapseParent.querySelectorAll('.collapse'); 4923 collapseElements.forEach(ele => { 4924 const collapse = window.bootstrap.Collapse.getOrCreateInstance(ele, { 4925 toggle: false 4926 }); 4927 collapseBtn.addEventListener('click', () => { 4928 collapse.hide(); 4929 }); 4930 }); 4931 } 4932 }; 4933 4934 const leaftletPoints = [ 4935 { 4936 lat: 53.958332, 4937 long: -1.080278, 4938 name: 'Diana Meyer', 4939 street: 'Slude Strand 27', 4940 location: '1130 Kobenhavn' 4941 }, 4942 { 4943 lat: 52.958332, 4944 long: -1.080278, 4945 name: 'Diana Meyer', 4946 street: 'Slude Strand 27', 4947 location: '1130 Kobenhavn' 4948 }, 4949 { 4950 lat: 51.958332, 4951 long: -1.080278, 4952 name: 'Diana Meyer', 4953 street: 'Slude Strand 27', 4954 location: '1130 Kobenhavn' 4955 }, 4956 { 4957 lat: 53.958332, 4958 long: -1.080278, 4959 name: 'Diana Meyer', 4960 street: 'Slude Strand 27', 4961 location: '1130 Kobenhavn' 4962 }, 4963 { 4964 lat: 54.958332, 4965 long: -1.080278, 4966 name: 'Diana Meyer', 4967 street: 'Slude Strand 27', 4968 location: '1130 Kobenhavn' 4969 }, 4970 { 4971 lat: 55.958332, 4972 long: -1.080278, 4973 name: 'Diana Meyer', 4974 street: 'Slude Strand 27', 4975 location: '1130 Kobenhavn' 4976 }, 4977 { 4978 lat: 53.908332, 4979 long: -1.080278, 4980 name: 'Diana Meyer', 4981 street: 'Slude Strand 27', 4982 location: '1130 Kobenhavn' 4983 }, 4984 { 4985 lat: 53.008332, 4986 long: -1.080278, 4987 name: 'Diana Meyer', 4988 street: 'Slude Strand 27', 4989 location: '1130 Kobenhavn' 4990 }, 4991 { 4992 lat: 53.158332, 4993 long: -1.080278, 4994 name: 'Diana Meyer', 4995 street: 'Slude Strand 27', 4996 location: '1130 Kobenhavn' 4997 }, 4998 { 4999 lat: 53.000032, 5000 long: -1.080278, 5001 name: 'Diana Meyer', 5002 street: 'Slude Strand 27', 5003 location: '1130 Kobenhavn' 5004 }, 5005 { 5006 lat: 52.292001, 5007 long: -2.22, 5008 name: 'Anke Schroder', 5009 street: 'Industrivej 54', 5010 location: '4140 Borup' 5011 }, 5012 { 5013 lat: 52.392001, 5014 long: -2.22, 5015 name: 'Anke Schroder', 5016 street: 'Industrivej 54', 5017 location: '4140 Borup' 5018 }, 5019 { 5020 lat: 51.492001, 5021 long: -2.22, 5022 name: 'Anke Schroder', 5023 street: 'Industrivej 54', 5024 location: '4140 Borup' 5025 }, 5026 { 5027 lat: 51.192001, 5028 long: -2.22, 5029 name: 'Anke Schroder', 5030 street: 'Industrivej 54', 5031 location: '4140 Borup' 5032 }, 5033 { 5034 lat: 52.292001, 5035 long: -2.22, 5036 name: 'Anke Schroder', 5037 street: 'Industrivej 54', 5038 location: '4140 Borup' 5039 }, 5040 { 5041 lat: 54.392001, 5042 long: -2.22, 5043 name: 'Anke Schroder', 5044 street: 'Industrivej 54', 5045 location: '4140 Borup' 5046 }, 5047 { 5048 lat: 51.292001, 5049 long: -2.22, 5050 name: 'Anke Schroder', 5051 street: 'Industrivej 54', 5052 location: '4140 Borup' 5053 }, 5054 { 5055 lat: 52.102001, 5056 long: -2.22, 5057 name: 'Anke Schroder', 5058 street: 'Industrivej 54', 5059 location: '4140 Borup' 5060 }, 5061 { 5062 lat: 52.202001, 5063 long: -2.22, 5064 name: 'Anke Schroder', 5065 street: 'Industrivej 54', 5066 location: '4140 Borup' 5067 }, 5068 { 5069 lat: 51.063202, 5070 long: -1.308, 5071 name: 'Tobias Vogel',
5072 street: 'Mollebakken 33', 5073 location: '3650 Olstykke' 5074 }, 5075 { 5076 lat: 51.363202, 5077 long: -1.308, 5078 name: 'Tobias Vogel', 5079 street: 'Mollebakken 33', 5080 location: '3650 Olstykke' 5081 }, 5082 { 5083 lat: 51.463202, 5084 long: -1.308, 5085 name: 'Tobias Vogel', 5086 street: 'Mollebakken 33', 5087 location: '3650 Olstykke' 5088 }, 5089 { 5090 lat: 51.563202, 5091 long: -1.308, 5092 name: 'Tobias Vogel', 5093 street: 'Mollebakken 33', 5094 location: '3650 Olstykke' 5095 }, 5096 { 5097 lat: 51.763202, 5098 long: -1.308, 5099 name: 'Tobias Vogel', 5100 street: 'Mollebakken 33', 5101 location: '3650 Olstykke' 5102 }, 5103 { 5104 lat: 51.863202, 5105 long: -1.308, 5106 name: 'Tobias Vogel', 5107 street: 'Mollebakken 33', 5108 location: '3650 Olstykke' 5109 }, 5110 { 5111 lat: 51.963202, 5112 long: -1.308, 5113 name: 'Tobias Vogel', 5114 street: 'Mollebakken 33', 5115 location: '3650 Olstykke' 5116 }, 5117 { 5118 lat: 51.000202, 5119 long: -1.308, 5120 name: 'Tobias Vogel', 5121 street: 'Mollebakken 33', 5122 location: '3650 Olstykke' 5123 }, 5124 { 5125 lat: 51.000202, 5126 long: -1.308, 5127 name: 'Tobias Vogel', 5128 street: 'Mollebakken 33', 5129 location: '3650 Olstykke' 5130 }, 5131 { 5132 lat: 51.163202, 5133 long: -1.308, 5134 name: 'Tobias Vogel', 5135 street: 'Mollebakken 33', 5136 location: '3650 Olstykke' 5137 }, 5138 { 5139 lat: 52.263202, 5140 long: -1.308, 5141 name: 'Tobias Vogel', 5142 street: 'Mollebakken 33', 5143 location: '3650 Olstykke' 5144 }, 5145 { 5146 lat: 53.463202, 5147 long: -1.308, 5148 name: 'Tobias Vogel', 5149 street: 'Mollebakken 33', 5150 location: '3650 Olstykke' 5151 }, 5152 { 5153 lat: 55.163202, 5154 long: -1.308, 5155 name: 'Tobias Vogel', 5156 street: 'Mollebakken 33', 5157 location: '3650 Olstykke' 5158 }, 5159 { 5160 lat: 56.263202, 5161 long: -1.308, 5162 name: 'Tobias Vogel', 5163 street: 'Mollebakken 33', 5164 location: '3650 Olstykke' 5165 }, 5166 { 5167 lat: 56.463202, 5168 long: -1.308, 5169 name: 'Tobias Vogel', 5170 street: 'Mollebakken 33', 5171 location: '3650 Olstykke' 5172 }, 5173 { 5174 lat: 56.563202, 5175 long: -1.308, 5176 name: 'Tobias Vogel', 5177 street: 'Mollebakken 33', 5178 location: '3650 Olstykke' 5179 }, 5180 { 5181 lat: 56.663202, 5182 long: -1.308, 5183 name: 'Tobias Vogel', 5184 street: 'Mollebakken 33', 5185 location: '3650 Olstykke' 5186 }, 5187 { 5188 lat: 56.763202, 5189 long: -1.308, 5190 name: 'Tobias Vogel', 5191 street: 'Mollebakken 33', 5192 location: '3650 Olstykke' 5193 }, 5194 { 5195 lat: 56.863202, 5196 long: -1.308, 5197 name: 'Tobias Vogel', 5198 street: 'Mollebakken 33', 5199 location: '3650 Olstykke' 5200 }, 5201 { 5202 lat: 56.963202, 5203 long: -1.308, 5204 name: 'Tobias Vogel', 5205 street: 'Mollebakken 33', 5206 location: '3650 Olstykke' 5207 }, 5208 { 5209 lat: 57.973202, 5210 long: -1.308, 5211 name: 'Tobias Vogel', 5212 street: 'Mollebakken 33', 5213 location: '3650 Olstykke' 5214 }, 5215 { 5216 lat: 57.163202, 5217 long: -1.308, 5218 name: 'Tobias Vogel', 5219 street: 'Mollebakken 33', 5220 location: '3650 Olstykke' 5221 }, 5222 { 5223 lat: 51.163202, 5224 long: -1.308, 5225 name: 'Tobias Vogel', 5226 street: 'Mollebakken 33', 5227 location: '3650 Olstykke' 5228 }, 5229 { 5230 lat: 51.263202, 5231 long: -1.308, 5232 name: 'Tobias Vogel', 5233 street: 'Mollebakken 33', 5234 location: '3650 Olstykke' 5235 }, 5236 { 5237 lat: 51.363202, 5238 long: -1.308, 5239 name: 'Tobias Vogel', 5240 street: 'Mollebakken 33', 5241 location: '3650 Olstykke' 5242 }, 5243 { 5244 lat: 51.409, 5245 long: -2.647, 5246 name: 'Richard Hendricks', 5247 street: '37 Seafield Place', 5248 location: 'London' 5249 }, 5250 { 5251 lat: 53.68, 5252 long: -1.49, 5253 name: 'Richard Hendricks', 5254 street: '37 Seafield Place', 5255 location: 'London' 5256 }, 5257 { 5258 lat: 50.259998, 5259 long: -5.051,
5260 name: 'Richard Hendricks', 5261 street: '37 Seafield Place', 5262 location: 'London' 5263 }, 5264 { 5265 lat: 54.906101, 5266 long: -1.38113, 5267 name: 'Richard Hendricks', 5268 street: '37 Seafield Place', 5269 location: 'London' 5270 }, 5271 { 5272 lat: 53.383331, 5273 long: -1.466667, 5274 name: 'Richard Hendricks', 5275 street: '37 Seafield Place', 5276 location: 'London' 5277 }, 5278 { 5279 lat: 53.483002, 5280 long: -2.2931, 5281 name: 'Richard Hendricks', 5282 street: '37 Seafield Place', 5283 location: 'London' 5284 }, 5285 { 5286 lat: 51.509865, 5287 long: -0.118092, 5288 name: 'Richard Hendricks', 5289 street: '37 Seafield Place', 5290 location: 'London' 5291 }, 5292 { 5293 lat: 51.109865, 5294 long: -0.118092, 5295 name: 'Richard Hendricks', 5296 street: '37 Seafield Place', 5297 location: 'London' 5298 }, 5299 { 5300 lat: 51.209865, 5301 long: -0.118092, 5302 name: 'Richard Hendricks', 5303 street: '37 Seafield Place', 5304 location: 'London' 5305 }, 5306 { 5307 lat: 51.309865, 5308 long: -0.118092, 5309 name: 'Richard Hendricks', 5310 street: '37 Seafield Place', 5311 location: 'London' 5312 }, 5313 { 5314 lat: 51.409865, 5315 long: -0.118092, 5316 name: 'Richard Hendricks', 5317 street: '37 Seafield Place', 5318 location: 'London' 5319 }, 5320 { 5321 lat: 51.609865, 5322 long: -0.118092, 5323 name: 'Richard Hendricks', 5324 street: '37 Seafield Place', 5325 location: 'London' 5326 }, 5327 { 5328 lat: 51.709865, 5329 long: -0.118092, 5330 name: 'Richard Hendricks', 5331 street: '37 Seafield Place', 5332 location: 'London' 5333 }, 5334 { 5335 lat: 51.809865, 5336 long: -0.118092, 5337 name: 'Richard Hendricks', 5338 street: '37 Seafield Place', 5339 location: 'London' 5340 }, 5341 { 5342 lat: 51.909865, 5343 long: -0.118092, 5344 name: 'Richard Hendricks', 5345 street: '37 Seafield Place', 5346 location: 'London' 5347 }, 5348 { 5349 lat: 52.109865, 5350 long: -0.118092, 5351 name: 'Richard Hendricks', 5352 street: '37 Seafield Place', 5353 location: 'London' 5354 }, 5355 { 5356 lat: 52.209865, 5357 long: -0.118092, 5358 name: 'Richard Hendricks', 5359 street: '37 Seafield Place', 5360 location: 'London' 5361 }, 5362 { 5363 lat: 52.309865, 5364 long: -0.118092, 5365 name: 'Richard Hendricks', 5366 street: '37 Seafield Place', 5367 location: 'London' 5368 }, 5369 { 5370 lat: 52.409865, 5371 long: -0.118092, 5372 name: 'Richard Hendricks', 5373 street: '37 Seafield Place', 5374 location: 'London' 5375 }, 5376 { 5377 lat: 52.509865, 5378 long: -0.118092, 5379 name: 'Richard Hendricks', 5380 street: '37 Seafield Place', 5381 location: 'London' 5382 }, 5383 { 5384 lat: 52.609865, 5385 long: -0.118092, 5386 name: 'Richard Hendricks', 5387 street: '37 Seafield Place', 5388 location: 'London' 5389 }, 5390 { 5391 lat: 52.709865, 5392 long: -0.118092, 5393 name: 'Richard Hendricks', 5394 street: '37 Seafield Place', 5395 location: 'London' 5396 }, 5397 { 5398 lat: 52.809865, 5399 long: -0.118092, 5400 name: 'Richard Hendricks', 5401 street: '37 Seafield Place', 5402 location: 'London' 5403 }, 5404 { 5405 lat: 52.909865, 5406 long: -0.118092, 5407 name: 'Richard Hendricks', 5408 street: '37 Seafield Place', 5409 location: 'London' 5410 }, 5411 { 5412 lat: 52.519865, 5413 long: -0.118092, 5414 name: 'Richard Hendricks', 5415 street: '37 Seafield Place', 5416 location: 'London' 5417 }, 5418 { 5419 lat: 52.529865, 5420 long: -0.118092, 5421 name: 'Richard Hendricks', 5422 street: '37 Seafield Place', 5423 location: 'London' 5424 }, 5425 { 5426 lat: 52.539865, 5427 long: -0.118092, 5428 name: 'Richard Hendricks', 5429 street: '37 Seafield Place', 5430 location: 'London' 5431 }, 5432 { 5433 lat: 53.549865, 5434 long: -0.118092, 5435 name: 'Richard Hendricks', 5436 street: '37 Seafield Place', 5437 location: 'London' 5438 }, 5439 { 5440 lat: 52.549865, 5441 long: -0.118092,
5442 name: 'Richard Hendricks', 5443 street: '37 Seafield Place', 5444 location: 'London' 5445 }, 5446 { 5447 lat: 53.109865, 5448 long: -0.118092, 5449 name: 'Richard Hendricks', 5450 street: '37 Seafield Place', 5451 location: 'London' 5452 }, 5453 { 5454 lat: 53.209865, 5455 long: -0.118092, 5456 name: 'Richard Hendricks', 5457 street: '37 Seafield Place', 5458 location: 'London' 5459 }, 5460 { 5461 lat: 53.319865, 5462 long: -0.118092, 5463 name: 'Richard Hendricks', 5464 street: '37 Seafield Place', 5465 location: 'London' 5466 }, 5467 { 5468 lat: 53.329865, 5469 long: -0.118092, 5470 name: 'Richard Hendricks', 5471 street: '37 Seafield Place', 5472 location: 'London' 5473 }, 5474 { 5475 lat: 53.409865, 5476 long: -0.118092, 5477 name: 'Richard Hendricks', 5478 street: '37 Seafield Place', 5479 location: 'London' 5480 }, 5481 { 5482 lat: 53.559865, 5483 long: -0.118092, 5484 name: 'Richard Hendricks', 5485 street: '37 Seafield Place', 5486 location: 'London' 5487 }, 5488 { 5489 lat: 53.619865, 5490 long: -0.118092, 5491 name: 'Richard Hendricks', 5492 street: '37 Seafield Place', 5493 location: 'London' 5494 }, 5495 { 5496 lat: 53.629865, 5497 long: -0.118092, 5498 name: 'Richard Hendricks', 5499 street: '37 Seafield Place', 5500 location: 'London' 5501 }, 5502 { 5503 lat: 53.639865, 5504 long: -0.118092, 5505 name: 'Richard Hendricks', 5506 street: '37 Seafield Place', 5507 location: 'London' 5508 }, 5509 { 5510 lat: 53.649865, 5511 long: -0.118092, 5512 name: 'Richard Hendricks', 5513 street: '37 Seafield Place', 5514 location: 'London' 5515 }, 5516 { 5517 lat: 53.669865, 5518 long: -0.118092, 5519 name: 'Richard Hendricks', 5520 street: '37 Seafield Place', 5521 location: 'London' 5522 }, 5523 { 5524 lat: 53.669865, 5525 long: -0.118092, 5526 name: 'Richard Hendricks', 5527 street: '37 Seafield Place', 5528 location: 'London' 5529 }, 5530 { 5531 lat: 53.719865, 5532 long: -0.118092, 5533 name: 'Richard Hendricks', 5534 street: '37 Seafield Place', 5535 location: 'London' 5536 }, 5537 { 5538 lat: 53.739865, 5539 long: -0.118092, 5540 name: 'Richard Hendricks', 5541 street: '37 Seafield Place', 5542 location: 'London' 5543 }, 5544 { 5545 lat: 53.749865, 5546 long: -0.118092, 5547 name: 'Richard Hendricks', 5548 street: '37 Seafield Place', 5549 location: 'London' 5550 }, 5551 { 5552 lat: 53.759865, 5553 long: -0.118092, 5554 name: 'Richard Hendricks', 5555 street: '37 Seafield Place', 5556 location: 'London' 5557 }, 5558 { 5559 lat: 53.769865, 5560 long: -0.118092, 5561 name: 'Richard Hendricks', 5562 street: '37 Seafield Place', 5563 location: 'London' 5564 }, 5565 { 5566 lat: 53.769865, 5567 long: -0.118092, 5568 name: 'Richard Hendricks', 5569 street: '37 Seafield Place', 5570 location: 'London' 5571 }, 5572 { 5573 lat: 53.819865, 5574 long: -0.118092, 5575 name: 'Richard Hendricks', 5576 street: '37 Seafield Place', 5577 location: 'London' 5578 }, 5579 { 5580 lat: 53.829865, 5581 long: -0.118092, 5582 name: 'Richard Hendricks', 5583 street: '37 Seafield Place', 5584 location: 'London' 5585 }, 5586 { 5587 lat: 53.483959, 5588 long: -2.244644, 5589 name: 'Ethel B. Brooks', 5590 street: '2576 Sun Valley Road' 5591 }, 5592 { 5593 lat: 40.737, 5594 long: -73.923, 5595 name: 'Marshall D. Lewis', 5596 street: '1489 Michigan Avenue', 5597 location: 'Michigan' 5598 }, 5599 { 5600 lat: 39.737, 5601 long: -73.923, 5602 name: 'Marshall D. Lewis', 5603 street: '1489 Michigan Avenue', 5604 location: 'Michigan' 5605 }, 5606 { 5607 lat: 38.737, 5608 long: -73.923, 5609 name: 'Marshall D. Lewis', 5610 street: '1489 Michigan Avenue', 5611 location: 'Michigan' 5612 }, 5613 { 5614 lat: 37.737, 5615 long: -73.923, 5616 name: 'Marshall D. Lewis', 5617 street: '1489 Michigan Avenue', 5618 location: 'Michigan' 5619 }, 5620 { 5621 lat: 40.737, 5622 long: -73.923, 5623 name: 'Marshall D. Lewis', 5624 street: '1489 Michigan Avenue', 5625 location: 'Michigan' 5626 }, 5627 { 5628 lat: 41.737, 5629 long: -73.923, 5630 name: 'Marshall D. Lewis', 5631 street: '1489 Michigan Avenue', 5632 location: 'Michigan' 5633 }, 5634 { 5635 lat: 42.737, 5636 long: -73.923, 5637 name: 'Marshall D. Lewis', 5638 street: '1489 Michigan Avenue', 5639 location: 'Michigan' 5640 }, 5641 { 5642 lat: 43.737, 5643 long: -73.923, 5644 name: 'Marshall D. Lewis', 5645 street: '1489 Michigan Avenue', 5646 location: 'Michigan' 5647 }, 5648 { 5649 lat: 44.737, 5650 long: -73.923, 5651 name: 'Marshall D. Lewis', 5652 street: '1489 Michigan Avenue', 5653 location: 'Michigan' 5654 }, 5655 { 5656 lat: 45.737, 5657 long: -73.923, 5658 name: 'Marshall D. Lewis', 5659 street: '1489 Michigan Avenue', 5660 location: 'Michigan' 5661 }, 5662 { 5663 lat: 46.7128, 5664 long: 74.006, 5665 name: 'Elizabeth C. Lyons', 5666 street: '4553 Kenwood Place', 5667 location: 'Fort Lauderdale' 5668 }, 5669 { 5670 lat: 40.7128, 5671 long: 74.1181, 5672 name: 'Elizabeth C. Lyons', 5673 street: '4553 Kenwood Place', 5674 location: 'Fort Lauderdale' 5675 }, 5676 { 5677 lat: 14.235, 5678 long: 51.9253, 5679 name: 'Ralph D. Wylie', 5680 street: '3186 Levy Court', 5681 location: 'North Reading' 5682 }, 5683 { 5684 lat: 15.235, 5685 long: 51.9253, 5686 name: 'Ralph D. Wylie', 5687 street: '3186 Levy Court', 5688 location: 'North Reading' 5689 }, 5690 { 5691 lat: 16.235, 5692 long: 51.9253, 5693 name: 'Ralph D. Wylie', 5694 street: '3186 Levy Court', 5695 location: 'North Reading' 5696 }, 5697 { 5698 lat: 14.235, 5699 long: 51.9253, 5700 name: 'Ralph D. Wylie', 5701 street: '3186 Levy Court', 5702 location: 'North Reading' 5703 }, 5704 { 5705 lat: 15.8267, 5706 long: 47.9218, 5707 name: 'Hope A. Atkins',
5708 street: '3715 Hillcrest Drive', 5709 location: 'Seattle' 5710 }, 5711 { 5712 lat: 15.9267, 5713 long: 47.9218, 5714 name: 'Hope A. Atkins', 5715 street: '3715 Hillcrest Drive', 5716 location: 'Seattle' 5717 }, 5718 { 5719 lat: 23.4425, 5720 long: 58.4438, 5721 name: 'Samuel R. Bailey', 5722 street: '2883 Raoul Wallenberg Place', 5723 location: 'Cheshire' 5724 }, 5725 { 5726 lat: 23.5425, 5727 long: 58.3438, 5728 name: 'Samuel R. Bailey', 5729 street: '2883 Raoul Wallenberg Place', 5730 location: 'Cheshire' 5731 }, 5732 { 5733 lat: -37.8927369333, 5734 long: 175.4087452333, 5735 name: 'Samuel R. Bailey', 5736 street: '3228 Glory Road', 5737 location: 'Nashville' 5738 }, 5739 { 5740 lat: -38.9064188833, 5741 long: 175.4441556833, 5742 name: 'Samuel R. Bailey', 5743 street: '3228 Glory Road', 5744 location: 'Nashville' 5745 }, 5746 { 5747 lat: -12.409874, 5748 long: -65.596832, 5749 name: 'Ann J. Perdue', 5750 street: '921 Ella Street', 5751 location: 'Dublin' 5752 }, 5753 { 5754 lat: -22.090887, 5755 long: -57.411827, 5756 name: 'Jorge C. Woods', 5757 street: '4800 North Bend River Road', 5758 location: 'Allen' 5759 }, 5760 { 5761 lat: -19.019585, 5762 long: -65.261963, 5763 name: 'Russ E. Panek', 5764 street: '4068 Hartland Avenue', 5765 location: 'Appleton' 5766 }, 5767 { 5768 lat: -16.500093, 5769 long: -68.214684, 5770 name: 'Russ E. Panek', 5771 street: '4068 Hartland Avenue', 5772 location: 'Appleton' 5773 }, 5774 { 5775 lat: -17.413977, 5776 long: -66.165321, 5777 name: 'Russ E. Panek', 5778 street: '4068 Hartland Avenue', 5779 location: 'Appleton' 5780 }, 5781 { 5782 lat: -16.489689, 5783 long: -68.119293, 5784 name: 'Russ E. Panek', 5785 street: '4068 Hartland Avenue', 5786 location: 'Appleton' 5787 }, 5788 { 5789 lat: 54.766323, 5790 long: 3.08603729, 5791 name: 'Russ E. Panek', 5792 street: '4068 Hartland Avenue', 5793 location: 'Appleton' 5794 }, 5795 { 5796 lat: 54.866323, 5797 long: 3.08603729, 5798 name: 'Russ E. Panek', 5799 street: '4068 Hartland Avenue', 5800 location: 'Appleton' 5801 }, 5802 { 5803 lat: 49.537685, 5804 long: 3.08603729, 5805 name: 'Russ E. Panek', 5806 street: '4068 Hartland Avenue', 5807 location: 'Appleton' 5808 }, 5809 { 5810 lat: 54.715424, 5811 long: 0.509207, 5812 name: 'Russ E. Panek', 5813 street: '4068 Hartland Avenue', 5814 location: 'Appleton' 5815 }, 5816 { 5817 lat: 44.891666, 5818 long: 10.136665, 5819 name: 'Russ E. Panek', 5820 street: '4068 Hartland Avenue', 5821 location: 'Appleton' 5822 }, 5823 { 5824 lat: 48.078335, 5825 long: 14.535004, 5826 name: 'Russ E. Panek', 5827 street: '4068 Hartland Avenue', 5828 location: 'Appleton' 5829 }, 5830 { 5831 lat: -26.358055, 5832 long: 27.398056, 5833 name: 'Russ E. Panek', 5834 street: '4068 Hartland Avenue', 5835 location: 'Appleton' 5836 }, 5837 { 5838 lat: -29.1, 5839 long: 26.2167, 5840 name: 'Wilbur J. Dry', 5841 street: '2043 Jadewood Drive', 5842 location: 'Northbrook' 5843 }, 5844 { 5845 lat: -29.883333, 5846 long: 31.049999, 5847 name: 'Wilbur J. Dry', 5848 street: '2043 Jadewood Drive', 5849 location: 'Northbrook' 5850 }, 5851 { 5852 lat: -26.266111, 5853 long: 27.865833, 5854 name: 'Wilbur J. Dry', 5855 street: '2043 Jadewood Drive', 5856 location: 'Northbrook' 5857 }, 5858 { 5859 lat: -29.087217, 5860 long: 26.154898, 5861 name: 'Wilbur J. Dry', 5862 street: '2043 Jadewood Drive', 5863 location: 'Northbrook' 5864 }, 5865 { 5866 lat: -33.958252, 5867 long: 25.619022, 5868 name: 'Wilbur J. Dry', 5869 street: '2043 Jadewood Drive', 5870 location: 'Northbrook' 5871 }, 5872 { 5873 lat: -33.977074, 5874 long: 22.457581, 5875 name: 'Wilbur J. Dry', 5876 street: '2043 Jadewood Drive', 5877 location: 'Northbrook' 5878 }, 5879 { 5880 lat: -26.563404, 5881 long: 27.844164, 5882 name: 'Wilbur J. Dry', 5883 street: '2043 Jadewood Drive', 5884 location: 'Northbrook' 5885 }, 5886 { 5887 lat: 51.21389, 5888 long: -102.462776, 5889 name: 'Joseph B. Poole', 5890 street: '3364 Lunetta Street', 5891 location: 'Wichita Falls' 5892 }, 5893 { 5894 lat: 52.321945, 5895 long: -106.584167, 5896 name: 'Joseph B. Poole', 5897 street: '3364 Lunetta Street', 5898 location: 'Wichita Falls' 5899 }, 5900 { 5901 lat: 50.288055, 5902 long: -107.793892, 5903 name: 'Joseph B. Poole', 5904 street: '3364 Lunetta Street', 5905 location: 'Wichita Falls' 5906 }, 5907 { 5908 lat: 52.7575, 5909 long: -108.28611, 5910 name: 'Joseph B. Poole', 5911 street: '3364 Lunetta Street', 5912 location: 'Wichita Falls' 5913 }, 5914 { 5915 lat: 50.393333, 5916 long: -105.551941, 5917 name: 'Joseph B. Poole', 5918 street: '3364 Lunetta Street', 5919 location: 'Wichita Falls' 5920 }, 5921 { 5922 lat: 50.930557, 5923 long: -102.807777, 5924 name: 'Joseph B. Poole', 5925 street: '3364 Lunetta Street', 5926 location: 'Wichita Falls' 5927 }, 5928 { 5929 lat: 52.856388, 5930 long: -104.610001, 5931 name: 'Joseph B. Poole', 5932 street: '3364 Lunetta Street', 5933 location: 'Wichita Falls' 5934 }, 5935 { 5936 lat: 52.289722, 5937 long: -106.666664, 5938 name: 'Joseph B. Poole', 5939 street: '3364 Lunetta Street', 5940 location: 'Wichita Falls' 5941 }, 5942 { 5943 lat: 52.201942, 5944 long: -105.123055, 5945 name: 'Joseph B. Poole', 5946 street: '3364 Lunetta Street', 5947 location: 'Wichita Falls' 5948 }, 5949 { 5950 lat: 53.278046, 5951 long: -110.00547, 5952 name: 'Joseph B. Poole', 5953 street: '3364 Lunetta Street', 5954 location: 'Wichita Falls' 5955 }, 5956 { 5957 lat: 49.13673, 5958 long: -102.990959, 5959 name: 'Joseph B. Poole', 5960 street: '3364 Lunetta Street', 5961 location: 'Wichita Falls' 5962 }, 5963 { 5964 lat: 45.484531, 5965 long: -73.597023, 5966 name: 'Claudette D. Nowakowski', 5967 street: '3742 Farland Avenue', 5968 location: 'San Antonio' 5969 }, 5970 { 5971 lat: 45.266666, 5972 long: -71.900002, 5973 name: 'Claudette D. Nowakowski', 5974 street: '3742 Farland Avenue', 5975 location: 'San Antonio' 5976 }, 5977 { 5978 lat: 45.349998, 5979 long: -72.51667, 5980 name: 'Claudette D. Nowakowski', 5981 street: '3742 Farland Avenue', 5982 location: 'San Antonio' 5983 }, 5984 { 5985 lat: 47.333332, 5986 long: -79.433334, 5987 name: 'Claudette D. Nowakowski', 5988 street: '3742 Farland Avenue', 5989 location: 'San Antonio' 5990 }, 5991 { 5992 lat: 45.400002, 5993 long: -74.033333, 5994 name: 'Claudette D. Nowakowski', 5995 street: '3742 Farland Avenue', 5996 location: 'San Antonio' 5997 }, 5998 { 5999 lat: 45.683334, 6000 long: -73.433334, 6001 name: 'Claudette D. Nowakowski', 6002 street: '3742 Farland Avenue', 6003 location: 'San Antonio' 6004 }, 6005 { 6006 lat: 48.099998, 6007 long: -77.783333, 6008 name: 'Claudette D. Nowakowski', 6009 street: '3742 Farland Avenue', 6010 location: 'San Antonio' 6011 }, 6012 { 6013 lat: 45.5, 6014 long: -72.316666, 6015 name: 'Claudette D. Nowakowski', 6016 street: '3742 Farland Avenue', 6017 location: 'San Antonio' 6018 }, 6019 { 6020 lat: 46.349998, 6021 long: -72.550003, 6022 name: 'Claudette D. Nowakowski', 6023 street: '3742 Farland Avenue', 6024 location: 'San Antonio' 6025 }, 6026 { 6027 lat: 48.119999, 6028 long: -69.18, 6029 name: 'Claudette D. Nowakowski', 6030 street: '3742 Farland Avenue', 6031 location: 'San Antonio' 6032 }, 6033 { 6034 lat: 45.599998, 6035 long: -75.25, 6036 name: 'Claudette D. Nowakowski', 6037 street: '3742 Farland Avenue', 6038 location: 'San Antonio' 6039 }, 6040 { 6041 lat: 46.099998, 6042 long: -71.300003, 6043 name: 'Claudette D. Nowakowski', 6044 street: '3742 Farland Avenue', 6045 location: 'San Antonio' 6046 }, 6047 { 6048 lat: 45.700001, 6049 long: -73.633331, 6050 name: 'Claudette D. Nowakowski', 6051 street: '3742 Farland Avenue', 6052 location: 'San Antonio' 6053 }, 6054 { 6055 lat: 47.68, 6056 long: -68.879997, 6057 name: 'Claudette D. Nowakowski', 6058 street: '3742 Farland Avenue', 6059 location: 'San Antonio' 6060 }, 6061 { 6062 lat: 46.716667, 6063 long: -79.099998, 6064 name: '299' 6065 }, 6066 { 6067 lat: 45.016666, 6068 long: -72.099998, 6069 name: '299' 6070 } 6071 ]; 6072 6073 const { L } = window; 6074 6075 /* -------------------------------------------------------------------------- */ 6076 /* leaflet */ 6077 /* -------------------------------------------------------------------------- */ 6078 6079 const leafletInit = () => { 6080 const mapContainer = document.getElementById('map'); 6081 if (L && mapContainer) { 6082 const getFilterColor = () => { 6083 return window.config.config.phoenixTheme === 'dark' 6084 ? [ 6085 'invert:98%', 6086 'grayscale:69%', 6087 'bright:89%', 6088 'contrast:111%', 6089 'hue:205deg',
6090 'saturate:1000%' 6091 ] 6092 : ['bright:101%', 'contrast:101%', 'hue:23deg', 'saturate:225%']; 6093 }; 6094 const tileLayerTheme = 6095 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png'; 6096 6097 const tiles = L.tileLayer.colorFilter(tileLayerTheme, { 6098 attribution: null, 6099 transparent: true, 6100 filter: getFilterColor() 6101 }); 6102 6103 const map = L.map('map', { 6104 center: L.latLng(25.659195, 30.182691), 6105 zoom: 0.6, 6106 layers: [tiles], 6107 minZoom: 1.4 6108 }); 6109 6110 const mcg = L.markerClusterGroup({ 6111 chunkedLoading: false, 6112 spiderfyOnMaxZoom: false 6113 }); 6114 6115 leaftletPoints.map(point => { 6116 const { name, location, street } = point; 6117 const icon = L.icon({ 6118 iconUrl: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAACXBIWXMAAAFgAAABYAEg2RPaAAADpElEQVRYCZ1XS1LbQBBtybIdiMEJKSpUqihgEW/xDdARyAnirOIl3MBH8NK7mBvkBpFv4Gy9IRSpFIQiRPyNfqkeZkY9HwmFt7Lm06+7p/vN2MmyDIrQ6QebALAHAD4AbFuWfQeAAACGs5H/w5jlsJJw4wMA+GhMFuMA99jIDJJOP+ihZwDQFmNuowWO1wS3viDXpdEdZPEc0odruj0EgN5s5H8tJOEEX8R3rbkMtcU34NTqhe5nSQTJ7Tkk80s6/Gk28scGiULguFBffgdufdEwWoQ0uoXo8hdAlooVH0REjISfwZSlyHGh0V5n6aHAtKTxXI5g6nQnMH0P4bEgwtR18Yw8Pj8QZ4ARUAI0Hl+fQZZGisGEBVwHr7XKzox57DXZ/ij8Cdwe2u057z9/wygOxRl4S2vSUHx1oucaMQGAHTrgtdag9mK5aN+Wx/uAAQ9Zenp/SRce4TpaNbQK4+sTcGqeTB/aIXv3XN5oj2VKqii++U0JunpZ8urxee4hvjqVc2hHpBDXuKKT9XMgVYJ1/1fPGSeaikzgmWWkMIi9bVf8UhotXxzORn5gWFchI8QyttlzjS0qpsaIGY2MMsujV/AUSdcY0dDpB6/EiOPYzclR1CI5mOez3ekHvrFLxa7cR5pTscfrXjk0Vhm5V2PqLUWnH3R5GbPGpMVD7E1ckXesKBQ7AS/vmQ1c0+kHuxpBj98lTCm8pbc5QRJRdZ6qHb/wGryXq3Lxszv+5gySuwvxueXySwYvHEjuQ9ofTGKYlrmK1EsCHMd5SoD7mZ1HHFCBHLNbMEshvrugqWLn01hpVVJhFgVGkDvK7hR6n2B+d9C7xsqWsbkqHv4cCsWezEb+o2SR+SFweUBxfA5wH7kShjKt2vWL57Px3GhIFEezkb8pxvUWHYhotAfCk2AtkEcxoOttrxUWDR5svb1emSQKj0WXK1HYIgFREbiBqmoZcB2RkbE+byMZiosorVgAZF1ID7yQhEs38wa7nUqNDezdlavC2HbBGSQkGgZ8uJVBmzeiKCRRpEa9ilWghORVeGB7BxeSKF5xqbFBkxBrFKUk/JHA7ppENQaCnCjthK+3opCEYyANztXmZN858cDYWSUSHk3A311GAZDvo6deNKUk1EsqnJoQlkYBNlmxQZeaMgmxoUokICoHDce351RCCiuKoirJWEgNOYvQplM2VCLhUqF7jf94rW9kHVUjQeheV4riv0i4ZOzzz/2y/+0KAOAfr4EE4HpCFhwAAAAASUVORK5CYII=` 6119 }); 6120 const marker = L.marker([point.lat, point.long], { 6121 icon 6122 }); 6123 const popupContent = ` 6124 <h6 class="mb-1">${name}</h6> 6125 <p class="m-0 text-body-quaternary">${street}, ${location}</p> 6126 `; 6127 const popup = L.popup({ minWidth: 180 }).setContent(popupContent); 6128 marker.bindPopup(popup); 6129 mcg.addLayer(marker); 6130 return true; 6131 }); 6132 map.addLayer(mcg); 6133 6134 const themeController = document.body; 6135 themeController.addEventListener( 6136 'clickControl', 6137 ({ detail: { control, value } }) => { 6138 if (control === 'phoenixTheme') { 6139 tiles.updateFilter( 6140 value === 'dark' 6141 ? [ 6142 'invert:98%', 6143 'grayscale:69%', 6144 'bright:89%', 6145 'contrast:111%', 6146 'hue:205deg', 6147 'saturate:1000%' 6148 ] 6149 : ['bright:101%', 'contrast:101%', 'hue:23deg', 'saturate:225%'] 6150 ); 6151 } 6152 } 6153 ); 6154 } 6155 }; 6156 6157 /* -------------------------------------------------------------------------- */ 6158 /* mapbox cluster */ 6159 /* -------------------------------------------------------------------------- */ 6160 6161 const mapboxClusterInit = () => { 6162 const mapboxCluster = document.querySelectorAll('#mapbox-cluster'); 6163 if (mapboxCluster) { 6164 mapboxCluster.forEach(() => { 6165 window.mapboxgl.accessToken = 6166 'pk.eyJ1IjoidGhlbWV3YWdvbiIsImEiOiJjbGhmNW5ybzkxcmoxM2RvN2RmbW1nZW90In0.hGIvQ890TYkZ948MVrsMIQ'; 6167 6168 const styles = { 6169 default: 'mapbox://styles/mapbox/light-v11', 6170 light: 'mapbox://styles/themewagon/clj57pads001701qo25756jtw', 6171 dark: 'mapbox://styles/themewagon/cljzg9juf007x01pk1bepfgew' 6172 }; 6173 6174 const map = new window.mapboxgl.Map({ 6175 container: 'mapbox-cluster', 6176 style: styles[window.config.config.phoenixTheme], 6177 center: [-73.102712, 7.102257], 6178 zoom: 3.5, 6179 pitch: 40, 6180 attributionControl: false 6181 }); 6182 6183 map.on('load', () => { 6184 map.addSource('earthquakes', { 6185 type: 'geojson', 6186 data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson', 6187 cluster: true,
6188 clusterMaxZoom: 14, 6189 clusterRadius: 50 6190 }); 6191 6192 map.addLayer({ 6193 id: 'clusters', 6194 type: 'circle', 6195 source: 'earthquakes', 6196 filter: ['has', 'point_count'], 6197 paint: { 6198 'circle-color': [ 6199 'step', 6200 ['get', 'point_count'], 6201 getColor('secondary'), 6202 100, 6203 getColor('info'), 6204 750, 6205 getColor('warning') 6206 ], 6207 'circle-radius': [ 6208 'step', 6209 ['get', 'point_count'], 6210 20, 6211 100, 6212 30, 6213 750, 6214 40 6215 ] 6216 } 6217 }); 6218 6219 map.addLayer({ 6220 id: 'cluster-count', 6221 type: 'symbol', 6222 source: 'earthquakes', 6223 filter: ['has', 'point_count'], 6224 layout: { 6225 'text-field': ['get', 'point_count_abbreviated'], 6226 'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'], 6227 'text-size': 12 6228 }, 6229 paint: { 6230 'text-color': getColor('white') 6231 } 6232 }); 6233 6234 map.addLayer({ 6235 id: 'unclustered-point', 6236 type: 'circle', 6237 source: 'earthquakes', 6238 filter: ['!', ['has', 'point_count']], 6239 paint: { 6240 'circle-color': getColor('primary-light'), 6241 'circle-radius': 4, 6242 'circle-stroke-width': 1, 6243 'circle-stroke-color': getColor('emphasis-bg') 6244 } 6245 }); 6246 6247 map.on('click', 'clusters', e => { 6248 const features = map.queryRenderedFeatures(e.point, { 6249 layers: ['clusters'] 6250 }); 6251 const clusterId = features[0].properties.cluster_id; 6252 map 6253 .getSource('earthquakes') 6254 .getClusterExpansionZoom(clusterId, (err, zoom) => { 6255 if (err) return; 6256 6257 map.easeTo({ 6258 center: features[0].geometry.coordinates, 6259 zoom 6260 }); 6261 }); 6262 }); 6263 6264 map.on('click', 'unclustered-point', e => { 6265 const coordinates = e.features[0].geometry.coordinates.slice(); 6266 const { mag } = e.features[0].properties; 6267 const tsunami = e.features[0].properties.tsunami === 1 ? 'yes' : 'no'; 6268 6269 while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) { 6270 coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360; 6271 } 6272 6273 new window.mapboxgl.Popup() 6274 .setLngLat(coordinates) 6275 .setHTML(`magnitude: ${mag}<br>Was there a tsunami?: ${tsunami}`) 6276 .addTo(map); 6277 }); 6278 6279 map.on('mouseenter', 'clusters', () => { 6280 map.getCanvas().style.cursor = 'pointer'; 6281 }); 6282 map.on('mouseleave', 'clusters', () => { 6283 map.getCanvas().style.cursor = ''; 6284 }); 6285 }); 6286 }); 6287 } 6288 }; 6289 6290 const themeController = document.body; 6291 if (themeController) { 6292 themeController.addEventListener('clickControl', () => { 6293 mapboxClusterInit(); 6294 }); 6295 } 6296 6297 /* -------------------------------------------------------------------------- */ 6298 /* Echarts trip review */ 6299 /* -------------------------------------------------------------------------- */ 6300 6301 const { echarts } = window; 6302 6303 const tripReviewChartInit = () => { 6304 const { getData, getColor } = window.phoenix.utils; 6305 const $echartTripReviews = document.querySelectorAll('.echart-trip-review'); 6306 6307 if ($echartTripReviews) { 6308 $echartTripReviews.forEach($echartTripReview => { 6309 const userOptions = getData($echartTripReview, 'options'); 6310 const chart = echarts.init($echartTripReview); 6311 6312 const getDefaultOptions = () => ({ 6313 tooltip: { 6314 trigger: 'item', 6315 padding: [7, 10], 6316 backgroundColor: getColor('body-highlight-bg'), 6317 borderColor: getColor('border-color'), 6318 textStyle: { color: getColor('light-text-emphasis') }, 6319 borderWidth: 1, 6320 position: (...params) => handleTooltipPosition(params), 6321 transitionDuration: 0, 6322 formatter: params => { 6323 return `<strong>${params.seriesName}:</strong> ${params.value}%`; 6324 }, 6325 extraCssText: 'z-index: 1000' 6326 }, 6327 series: [ 6328 { 6329 type: 'gauge', 6330 name: 'Commission', 6331 startAngle: 90, 6332 endAngle: -270, 6333 radius: '90%', 6334 pointer: { 6335 show: false 6336 }, 6337 progress: { 6338 show: true, 6339 overlap: false, 6340 // roundCap: true, 6341 clip: false, 6342 itemStyle: { 6343 color: getColor('primary') 6344 } 6345 },
6346 axisLine: { 6347 lineStyle: { 6348 width: 4, 6349 color: [[1, getColor('secondary-bg')]] 6350 } 6351 }, 6352 splitLine: { 6353 show: false 6354 }, 6355 axisTick: { 6356 show: false 6357 }, 6358 axisLabel: { 6359 show: false 6360 }, 6361 detail: { 6362 fontSize: '20px', 6363 color: getColor('body-color'), 6364 offsetCenter: [0, '10%'] 6365 } 6366 } 6367 ] 6368 }); 6369 6370 echartSetOption(chart, userOptions, getDefaultOptions); 6371 }); 6372 } 6373 }; 6374 6375 const playOnHoverInit = () => { 6376 const isPause = (playIcon, pauseIcon) => { 6377 playIcon.classList.add('d-block'); 6378 pauseIcon.classList.add('d-none'); 6379 playIcon.classList.remove('d-none'); 6380 pauseIcon.classList.remove('d-block'); 6381 }; 6382 6383 const isPlay = (playIcon, pauseIcon) => { 6384 playIcon.classList.add('d-none'); 6385 pauseIcon.classList.add('d-block'); 6386 playIcon.classList.remove('d-block'); 6387 pauseIcon.classList.remove('d-none'); 6388 }; 6389 6390 const playVideo = (video, playIcon, pauseIcon) => { 6391 video.play(); 6392 isPlay(playIcon, pauseIcon); 6393 }; 6394 6395 const pauseVideo = (video, playIcon, pauseIcon) => { 6396 video.pause(); 6397 isPause(playIcon, pauseIcon); 6398 }; 6399 6400 const controlIsContainer = (container, state) => { 6401 const video = container.querySelector('[data-play-on-hover]'); 6402 const controller = container.querySelector('[data-video-controller]'); 6403 if (controller) { 6404 const playIcon = controller.querySelector('.play-icon'); 6405 const pauseIcon = controller.querySelector('.pause-icon'); 6406 if (state === 'play') { 6407 playVideo(video, playIcon, pauseIcon); 6408 } else { 6409 pauseVideo(video, playIcon, pauseIcon); 6410 } 6411 } 6412 }; 6413 6414 document.addEventListener('mouseover', e => { 6415 if (e.target.closest('[data-play-on-hover]')) { 6416 const video = e.target.closest('[data-play-on-hover]'); 6417 playVideo(video, null, null); 6418 } else if (e.target.closest('[data-play-on-container-hover]')) { 6419 const container = e.target.closest('[data-play-on-container-hover]'); 6420 controlIsContainer(container, 'play'); 6421 } 6422 }); 6423 6424 document.addEventListener('mouseout', e => { 6425 if (e.target.closest('[data-play-on-hover]')) { 6426 const video = e.target.closest('[data-play-on-hover]'); 6427 pauseVideo(video, null, null); 6428 } else if (e.target.closest('[data-play-on-container-hover]')) { 6429 const container = e.target.closest('[data-play-on-container-hover]'); 6430 controlIsContainer(container, 'pause'); 6431 } 6432 }); 6433 6434 document.addEventListener('touchstart', e => { 6435 if (e.target.closest('[data-play-on-hover]')) { 6436 const video = e.target.closest('[data-play-on-hover]'); 6437 playVideo(video, null, null); 6438 } else if (e.target.closest('[data-play-on-container-hover]')) { 6439 const container = e.target.closest('[data-play-on-container-hover]'); 6440 controlIsContainer(container, 'play'); 6441 } 6442 }); 6443 6444 document.addEventListener('touchend', e => { 6445 if (e.target.closest('[data-play-on-hover]')) { 6446 const video = e.target.closest('[data-play-on-hover]'); 6447 pauseVideo(video, null, null); 6448 } else if (e.target.closest('[data-play-on-container-hover]')) { 6449 const container = e.target.closest('[data-play-on-container-hover]'); 6450 controlIsContainer(container, 'pause'); 6451 } 6452 }); 6453 6454 document.addEventListener('click', e => { 6455 if (e.target.closest('[data-video-controller]')) { 6456 const controller = e.target.closest('[data-video-controller]'); 6457 const container = controller.closest('[data-play-on-container-hover]'); 6458 const video = container.querySelector('[data-play-on-hover]'); 6459 const playIcon = controller.querySelector('.play-icon'); 6460 const pauseIcon = controller.querySelector('.pause-icon'); 6461 6462 if (video.paused) { 6463 playVideo(video, playIcon, pauseIcon); 6464 } else { 6465 pauseVideo(video, playIcon, pauseIcon); 6466 } 6467 } 6468 });
6469 6470 const videoContainers = document.querySelectorAll( 6471 '[data-play-on-container-hover]' 6472 ); 6473 videoContainers.forEach(container => { 6474 const video = container.querySelector('[data-play-on-hover]'); 6475 const controller = container.querySelector('[data-video-controller]'); 6476 if (controller) { 6477 const playIcon = controller.querySelector('.play-icon'); 6478 const pauseIcon = controller.querySelector('.pause-icon'); 6479 6480 if (video.paused) { 6481 isPause(playIcon, pauseIcon); 6482 } 6483 } 6484 }); 6485 }; 6486 6487 const passwordToggleInit = () => { 6488 const passwords = document.querySelectorAll('[data-password]'); 6489 if (passwords) { 6490 passwords.forEach(password => { 6491 const passwordInput = password.querySelector('[data-password-input]'); 6492 const passwordToggler = password.querySelector('[data-password-toggle]'); 6493 passwordToggler.addEventListener('click', () => { 6494 if (passwordInput.type === 'password') { 6495 passwordInput.setAttribute('type', 'text'); 6496 passwordToggler.classList.add('show-password'); 6497 } else { 6498 passwordInput.setAttribute('type', 'password'); 6499 passwordToggler.classList.remove('show-password'); 6500 } 6501 }); 6502 }); 6503 } 6504 }; 6505 6506 /* -------------------------------------------------------------------------- */ 6507 /* Treeview */ 6508 /* -------------------------------------------------------------------------- */ 6509 const treeviewInit = () => { 6510 const Events = { 6511 CHANGE: 'change', 6512 SHOW_BS_COLLAPSE: 'show.bs.collapse', 6513 HIDE_BS_COLLAPSE: 'hide.bs.collapse' 6514 }; 6515 6516 const Selector = { 6517 TREEVIEW_ROW: 6518 '.treeview > li > .treeview-row,.treeview-list.collapse-show > li > .treeview-row', 6519 TREEVIEW: '.treeview', 6520 TREEVIEW_LIST: '.treeview-list', 6521 TOGGLE_ELEMENT: "[data-bs-toggle='collapse']", 6522 INPUT: 'input', 6523 TREEVIEW_LIST_ITEM: '.treeview-list-item', 6524 CHILD_SELECTOR: ':scope > li > .collapse.collapse-show' 6525 }; 6526 6527 const ClassName = { 6528 TREEVIEW: 'treeview', 6529 TREEVIEW_LIST: 'treeview-list', 6530 TREEVIEW_BORDER: 'treeview-border', 6531 TREEVIEW_BORDER_TRANSPARENT: 'treeview-border-transparent', 6532 COLLAPSE_SHOW: 'collapse-show', 6533 COLLAPSE_HIDDEN: 'collapse-hidden', 6534 TREEVIEW_ROW: 'treeview-row', 6535 TREEVIEW_ROW_ODD: 'treeview-row-odd', 6536 TREEVIEW_ROW_EVEN: 'treeview-row-even' 6537 }; 6538 6539 const treeviews = document.querySelectorAll(Selector.TREEVIEW); 6540 6541 const makeStriped = treeview => { 6542 const tags = Array.from(treeview.querySelectorAll(Selector.TREEVIEW_ROW)); 6543 6544 const uTags = tags.filter(tag => { 6545 let result = true; 6546 while (tag.parentElement) { 6547 if (tag.parentElement.classList.contains(ClassName.COLLAPSE_HIDDEN)) { 6548 result = false; 6549 break; 6550 } 6551 tag = tag.parentElement; 6552 } 6553 return result; 6554 }); 6555 uTags.forEach((tag, index) => { 6556 if (index % 2 === 0) { 6557 tag.classList.add(ClassName.TREEVIEW_ROW_EVEN); 6558 tag.classList.remove(ClassName.TREEVIEW_ROW_ODD); 6559 } else { 6560 tag.classList.add(ClassName.TREEVIEW_ROW_ODD); 6561 tag.classList.remove(ClassName.TREEVIEW_ROW_EVEN); 6562 } 6563 }); 6564 }; 6565 6566 if (treeviews.length) { 6567 treeviews.forEach(treeview => { 6568 const options = getData(treeview, 'options'); 6569 const striped = options?.striped; 6570 const select = options?.select; 6571 6572 if (striped) { 6573 makeStriped(treeview); 6574 } 6575 6576 const collapseElementList = Array.from( 6577 treeview.querySelectorAll(Selector.TREEVIEW_LIST) 6578 ); 6579 const collapseListItem = Array.from( 6580 treeview.querySelectorAll(Selector.TREEVIEW_LIST_ITEM) 6581 ); 6582 6583 collapseListItem.forEach(item => { 6584 const wholeRow = document.createElement('div'); 6585 wholeRow.setAttribute('class', ClassName.TREEVIEW_ROW); 6586 item.prepend(wholeRow); 6587 }); 6588 collapseElementList.forEach(collapse => { 6589 const collapseId = collapse.id; 6590 if (!striped) { 6591 collapse.classList.add(ClassName.TREEVIEW_BORDER); 6592 } 6593 collapse.addEventListener(Events.SHOW_BS_COLLAPSE, e => { 6594 e.target.classList.remove(ClassName.COLLAPSE_HIDDEN); 6595 e.target.classList.add(ClassName.COLLAPSE_SHOW); 6596 if (striped) { 6597 makeStriped(treeview); 6598 } 6599 }); 6600 6601 collapse.addEventListener(Events.HIDE_BS_COLLAPSE, e => { 6602 e.target.classList.add(ClassName.COLLAPSE_HIDDEN); 6603 e.target.classList.remove(ClassName.COLLAPSE_SHOW); 6604 6605 if (striped) { 6606 makeStriped(treeview); 6607 } else { 6608 const childs = e 6609 .composedPath()[2] 6610 .querySelectorAll(Selector.CHILD_SELECTOR); 6611 if ( 6612 !e.composedPath()[2].classList.contains(ClassName.TREEVIEW) && 6613 childs.length === 0 6614 ) { 6615 e.composedPath()[2].classList.remove( 6616 ClassName.TREEVIEW_BORDER_TRANSPARENT 6617 ); 6618 } 6619 } 6620 }); 6621 6622 if (collapse.dataset.show === 'true') { 6623 const parents = [collapse]; 6624 while (collapse.parentElement) { 6625 if ( 6626 collapse.parentElement.classList.contains(ClassName.TREEVIEW_LIST) 6627 ) { 6628 parents.unshift(collapse.parentElement); 6629 } 6630 collapse = collapse.parentElement; 6631 }
6632 parents.forEach(collapseEl => { 6633 // eslint-disable-next-line no-new 6634 new window.bootstrap.Collapse(collapseEl, { 6635 show: true 6636 }); 6637 }); 6638 } 6639 6640 if (select) { 6641 const inputElement = treeview.querySelector( 6642 `input[data-target='#${collapseId}']` 6643 ); 6644 inputElement.addEventListener(Events.CHANGE, e => { 6645 const childInputElements = Array.from( 6646 treeview 6647 .querySelector(`#${collapseId}`) 6648 .querySelectorAll(Selector.INPUT) 6649 ); 6650 childInputElements.forEach(input => { 6651 input.checked = e.target.checked; 6652 }); 6653 }); 6654 } 6655 }); 6656 }); 6657 } 6658 }; 6659 6660 /* eslint-disable no-new */ 6661 6662 window.initMap = initMap; 6663 docReady(detectorInit); 6664 docReady(simplebarInit); 6665 docReady(toastInit); 6666 docReady(tooltipInit); 6667 docReady(featherIconsInit); 6668 docReady(basicEchartsInit); 6669 docReady(bulkSelectInit); 6670 docReady(listInit); 6671 docReady(anchorJSInit); 6672 docReady(popoverInit); 6673 docReady(formValidationInit); 6674 docReady(docComponentInit); 6675 docReady(swiperInit); 6676 docReady(productDetailsInit); 6677 docReady(ratingInit); 6678 docReady(quantityInit); 6679 docReady(dropzoneInit); 6680 docReady(choicesInit); 6681 docReady(tinymceInit); 6682 docReady(responsiveNavItemsInit); 6683 docReady(flatpickrInit); 6684 docReady(iconCopiedInit); 6685 docReady(isotopeInit); 6686 docReady(bigPictureInit); 6687 docReady(countupInit); 6688 docReady(phoenixOffcanvasInit); 6689 docReady(todoOffcanvasInit); 6690 docReady(wizardInit); 6691 docReady(reportsDetailsChartInit); 6692 docReady(glightboxInit); 6693 docReady(themeControl); 6694 docReady(searchInit); 6695 docReady(handleNavbarVerticalCollapsed); 6696 docReady(navbarInit); 6697 docReady(navbarComboInit); 6698 docReady(fullCalendarInit); 6699 docReady(picmoInit); 6700 6701 docReady(chatInit); 6702 docReady(modalInit); 6703 docReady(lottieInit); 6704 docReady(navbarShadowOnScrollInit); 6705 docReady(dropdownOnHover); 6706 docReady(supportChatInit); 6707 docReady(sortableInit); 6708 6709 docReady(copyLink); 6710 docReady(randomColorInit); 6711 docReady(faqTabInit); 6712 docReady(createBoardInit); 6713 docReady(advanceAjaxTableInit); 6714 docReady(kanbanInit); 6715 docReady(towFAVerificarionInit); 6716 docReady(mapboxInit); 6717 docReady(flightMapInit); 6718 docReady(typedTextInit); 6719 docReady(priceTierFormInit); 6720 docReady(nouisliderInit); 6721 docReady(collapseAllInit); 6722 docReady(leafletInit); 6723 docReady(mapboxClusterInit); 6724 docReady(tripReviewChartInit); 6725 docReady(playOnHoverInit); 6726 docReady(passwordToggleInit); 6727 docReady(treeviewInit); 6728 6729 docReady(() => { 6730 const selectedRowsBtn = document.querySelector('[data-selected-rows]'); 6731 const selectedRows = document.getElementById('selectedRows'); 6732 if (selectedRowsBtn) { 6733 const bulkSelectEl = document.getElementById('bulk-select-example'); 6734 const bulkSelectInstance = 6735 window.phoenix.BulkSelect.getInstance(bulkSelectEl); 6736 selectedRowsBtn.addEventListener('click', () => { 6737 selectedRows.innerHTML = JSON.stringify( 6738 bulkSelectInstance.getSelectedRows(), 6739 undefined, 6740 2 6741 ); 6742 }); 6743 } 6744 }); 6745 6746 var phoenix = { 6747 utils, 6748 BulkSelect 6749 }; 6750 6751 return phoenix; 6752 6753})); 6754//# sourceMappingURL=phoenix.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.