web-mojo 2.2.2 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.es.js +12 -12
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.es.js +4 -4
- package/dist/chunks/{ChatView-CWNoGk-B.js → ChatView-DZ7f2Rl5.js} +7 -7
- package/dist/chunks/{ChatView-CWNoGk-B.js.map → ChatView-DZ7f2Rl5.js.map} +1 -1
- package/dist/chunks/{ChatView-DSEEMnNt.js → ChatView-DoA8h81E.js} +2 -2
- package/dist/chunks/{ChatView-DSEEMnNt.js.map → ChatView-DoA8h81E.js.map} +1 -1
- package/dist/chunks/{Collection-CqLcHgQG.js → Collection-CREl6Fa9.js} +2 -2
- package/dist/chunks/{Collection-CqLcHgQG.js.map → Collection-CREl6Fa9.js.map} +1 -1
- package/dist/chunks/{Collection-C7rteLDn.js → Collection-DJaa8dhS.js} +2 -2
- package/dist/chunks/{Collection-C7rteLDn.js.map → Collection-DJaa8dhS.js.map} +1 -1
- package/dist/chunks/{ContextMenu-JJ51hS-a.js → ContextMenu-CvLNRuJb.js} +3 -3
- package/dist/chunks/{ContextMenu-JJ51hS-a.js.map → ContextMenu-CvLNRuJb.js.map} +1 -1
- package/dist/chunks/{ContextMenu-BY3BgxM5.js → ContextMenu-DvsDXgOe.js} +2 -2
- package/dist/chunks/{ContextMenu-BY3BgxM5.js.map → ContextMenu-DvsDXgOe.js.map} +1 -1
- package/dist/chunks/{DataView-CsYXM9vF.js → DataView-Bm8dffDn.js} +2 -2
- package/dist/chunks/{DataView-CsYXM9vF.js.map → DataView-Bm8dffDn.js.map} +1 -1
- package/dist/chunks/{DataView-CHvoEI4M.js → DataView-gc1VouWJ.js} +2 -2
- package/dist/chunks/{DataView-CHvoEI4M.js.map → DataView-gc1VouWJ.js.map} +1 -1
- package/dist/chunks/{Dialog-BKPwBCDC.js → Dialog-Cl_rBFSh.js} +2 -2
- package/dist/chunks/{Dialog-BKPwBCDC.js.map → Dialog-Cl_rBFSh.js.map} +1 -1
- package/dist/chunks/{Dialog-D4DsB-N1.js → Dialog-LPU__Q7Z.js} +5 -5
- package/dist/chunks/{Dialog-D4DsB-N1.js.map → Dialog-LPU__Q7Z.js.map} +1 -1
- package/dist/chunks/{FormView-DYX_yeho.js → FormView-Cc5iagqS.js} +2 -2
- package/dist/chunks/{FormView-DYX_yeho.js.map → FormView-Cc5iagqS.js.map} +1 -1
- package/dist/chunks/{FormView-B9nIO_AX.js → FormView-DMMUiciW.js} +2 -2
- package/dist/chunks/{FormView-B9nIO_AX.js.map → FormView-DMMUiciW.js.map} +1 -1
- package/dist/chunks/{ListView-DWaowghQ.js → ListView-8FqhYWRU.js} +3 -3
- package/dist/chunks/{ListView-DWaowghQ.js.map → ListView-8FqhYWRU.js.map} +1 -1
- package/dist/chunks/{ListView-D2vt0koT.js → ListView-Xcsfu4IL.js} +2 -2
- package/dist/chunks/{ListView-D2vt0koT.js.map → ListView-Xcsfu4IL.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-BfZ-dcbW.js → MetricsMiniChartWidget-BuvhT5NG.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-BfZ-dcbW.js.map → MetricsMiniChartWidget-BuvhT5NG.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-Cl-TA-Q9.js → MetricsMiniChartWidget-CsawNLeS.js} +4 -4
- package/dist/chunks/{MetricsMiniChartWidget-Cl-TA-Q9.js.map → MetricsMiniChartWidget-CsawNLeS.js.map} +1 -1
- package/dist/chunks/{PDFViewer-Cgr3T15i.js → PDFViewer-Bg06w3Cu.js} +2 -2
- package/dist/chunks/{PDFViewer-Cgr3T15i.js.map → PDFViewer-Bg06w3Cu.js.map} +1 -1
- package/dist/chunks/{PDFViewer-Bzifr-dn.js → PDFViewer-Dr72gJt1.js} +3 -3
- package/dist/chunks/{PDFViewer-Bzifr-dn.js.map → PDFViewer-Dr72gJt1.js.map} +1 -1
- package/dist/chunks/Rest-29RtA7pe.js +2 -0
- package/dist/chunks/Rest-29RtA7pe.js.map +1 -0
- package/dist/chunks/{Rest-C3fPzCIA.js → Rest-BoKp2Hj4.js} +34 -1
- package/dist/chunks/Rest-BoKp2Hj4.js.map +1 -0
- package/dist/chunks/TokenManager-Bh1WshcR.js +2 -0
- package/dist/chunks/TokenManager-Bh1WshcR.js.map +1 -0
- package/dist/chunks/{TokenManager-CoHKTGNX.js → TokenManager-BoolOcxQ.js} +26 -11
- package/dist/chunks/TokenManager-BoolOcxQ.js.map +1 -0
- package/dist/chunks/{WebSocketClient-Dzwprd15.js → WebSocketClient-DcJBT-iB.js} +2 -2
- package/dist/chunks/{WebSocketClient-Dzwprd15.js.map → WebSocketClient-DcJBT-iB.js.map} +1 -1
- package/dist/chunks/{WebSocketClient-CkAL55qy.js → WebSocketClient-Do0CazHx.js} +2 -2
- package/dist/chunks/{WebSocketClient-CkAL55qy.js.map → WebSocketClient-Do0CazHx.js.map} +1 -1
- package/dist/chunks/{version-CJnLNR-g.js → version-Bado0p82.js} +2 -2
- package/dist/chunks/{version-CJnLNR-g.js.map → version-Bado0p82.js.map} +1 -1
- package/dist/chunks/{version-Bl3PlRrV.js → version-_FYWwpG_.js} +4 -4
- package/dist/chunks/{version-Bl3PlRrV.js.map → version-_FYWwpG_.js.map} +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +6 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +15 -15
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +5 -5
- package/dist/map.cjs.js +1 -1
- package/dist/map.es.js +2 -2
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +4 -4
- package/package.json +1 -1
- package/dist/chunks/Rest-C3fPzCIA.js.map +0 -1
- package/dist/chunks/Rest-DYPLEzNy.js +0 -2
- package/dist/chunks/Rest-DYPLEzNy.js.map +0 -1
- package/dist/chunks/TokenManager-CoHKTGNX.js.map +0 -1
- package/dist/chunks/TokenManager-DSyRWlvc.js +0 -2
- package/dist/chunks/TokenManager-DSyRWlvc.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PDFViewer-Bzifr-dn.js","sources":["../../src/extensions/lightbox/LightboxGallery.js","../../src/extensions/lightbox/PDFViewer.js"],"sourcesContent":["/**\n * LightboxGallery - Simple fullscreen image gallery\n * Clean, minimal lightbox for viewing single images or galleries\n */\n\nimport View from '@core/View.js';\n\nexport default class LightboxGallery extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `lightbox-gallery ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Handle single image or array of images and normalize to objects\n const rawImages = Array.isArray(options.images) ? options.images : [options.images || options.src].filter(Boolean);\n this.images = rawImages.map(img => {\n if (typeof img === 'string') {\n return { src: img, alt: '' };\n }\n return { src: img.src, alt: img.alt || '' };\n });\n this.currentIndex = options.startIndex || 0;\n this.showNavigation = options.showNavigation !== false && this.images.length > 1;\n this.showCounter = options.showCounter !== false && this.images.length > 1;\n this.allowKeyboard = options.allowKeyboard !== false;\n this.closeOnBackdrop = options.closeOnBackdrop !== false;\n this.fitToScreen = options.fitToScreen !== false; // Start in fit-to-screen mode\n\n // Bind keyboard handler for cleanup\n this._keyboardHandler = this.handleKeyboard.bind(this);\n\n // Set template properties directly on view instance\n this.updateTemplateProperties();\n }\n\n updateTemplateProperties() {\n this.currentImage = this.images[this.currentIndex] || { src: '', alt: '' };\n this.currentNumber = this.currentIndex + 1;\n this.total = this.images.length;\n this.isFirst = this.currentIndex === 0;\n this.isLast = this.currentIndex === this.images.length - 1;\n this.imageStyle = this.fitToScreen\n ? 'width: 90vw; max-height: 100%; object-fit: contain; user-select: none; cursor: zoom-in;'\n : 'max-width: none; max-height: none; user-select: none; cursor: zoom-out;';\n this.containerStyle = this.fitToScreen\n ? ''\n : 'overflow: auto;';\n this.modeIndicator = this.fitToScreen ? 'Fit to Screen' : 'Original Size';\n }\n\n async getTemplate() {\n const currentImage = this.images[this.currentIndex];\n const hasMultiple = this.images.length > 1;\n\n return `\n <div class=\"lightbox-overlay position-fixed top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center\"\n style=\"background: rgba(0,0,0,0.9); z-index: 9999;\"\n data-action=\"backdrop-click\">\n\n <!-- Close button -->\n <button type=\"button\" class=\"btn-close btn-close-white position-absolute top-0 end-0 m-4\"\n data-action=\"close\"\n style=\"z-index: 10001;\"\n title=\"Close\"></button>\n\n <!-- Counter -->\n {{#showCounter}}\n <div class=\"lightbox-counter position-absolute top-0 start-50 translate-middle-x mt-4 text-white\"\n style=\"z-index: 10001; font-size: 1.1rem;\">\n {{currentNumber}} of {{total}}\n </div>\n {{/showCounter}}\n\n <!-- Mode Indicator -->\n <div class=\"lightbox-mode-indicator position-absolute bottom-0 start-50 translate-middle-x mb-4 text-white bg-dark bg-opacity-75 px-3 py-2 rounded\"\n style=\"z-index: 10001; font-size: 0.9rem;\">\n {{modeIndicator}} • Click image to toggle\n </div>\n\n <!-- Navigation -->\n {{#showNavigation}}\n <button type=\"button\" class=\"btn btn-light btn-lg position-absolute start-0 top-50 translate-middle-y ms-4\"\n data-action=\"prev\"\n style=\"z-index: 10001;\"\n title=\"Previous\"\n {{#isFirst}}disabled{{/isFirst}}>\n <i class=\"bi bi-chevron-left\"></i>\n </button>\n\n <button type=\"button\" class=\"btn btn-light btn-lg position-absolute end-0 top-50 translate-middle-y me-4\"\n data-action=\"next\"\n style=\"z-index: 10001;\"\n title=\"Next\"\n {{#isLast}}disabled{{/isLast}}>\n <i class=\"bi bi-chevron-right\"></i>\n </button>\n {{/showNavigation}}\n\n <!-- Image container -->\n <div class=\"lightbox-image-container w-100 h-100 d-flex align-items-center justify-content-center p-5\"\n style=\"{{containerStyle}}\">\n {{#currentImage}}\n <img src=\"{{src}}\"\n alt=\"{{alt}}\"\n class=\"lightbox-image img-fluid\"\n style=\"{{imageStyle}}\"\n data-action=\"image-click\">\n {{/currentImage}}\n </div>\n\n <!-- Loading spinner -->\n <div class=\"lightbox-loading position-absolute top-50 start-50 translate-middle text-white\"\n style=\"display: none;\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n </div>\n `;\n }\n\n\n\n async onAfterRender() {\n // Add to body for fullscreen\n document.body.appendChild(this.element);\n document.body.style.overflow = 'hidden';\n\n // Set up keyboard navigation\n if (this.allowKeyboard) {\n document.addEventListener('keydown', this._keyboardHandler);\n }\n\n // Preload next/previous images\n this.preloadAdjacentImages();\n }\n\n // Action handlers\n async handleActionClose() {\n this.close();\n }\n\n async handleActionBackdropClick(e) {\n // Only close if clicked on backdrop, not image\n if (this.closeOnBackdrop && e.target === e.currentTarget) {\n this.close();\n }\n }\n\n async handleActionPrev() {\n this.showPrevious();\n }\n\n async handleActionNext() {\n this.showNext();\n }\n\n async handleActionImageClick() {\n this.toggleImageMode();\n }\n\n // Navigation methods\n showPrevious() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n showNext() {\n if (this.currentIndex < this.images.length - 1) {\n this.currentIndex++;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n goToImage(index) {\n if (index >= 0 && index < this.images.length && index !== this.currentIndex) {\n this.currentIndex = index;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n // Update image without full re-render\n async updateImage() {\n const currentImage = this.images[this.currentIndex];\n const imgElement = this.element.querySelector('.lightbox-image');\n const counterElement = this.element.querySelector('.lightbox-counter');\n const prevBtn = this.element.querySelector('[data-action=\"prev\"]');\n const nextBtn = this.element.querySelector('[data-action=\"next\"]');\n\n if (imgElement) {\n // Show loading\n this.showLoading();\n\n // Update image\n imgElement.src = currentImage.src;\n imgElement.alt = currentImage.alt;\n\n // Wait for image to load\n await this.waitForImageLoad(imgElement);\n\n // Hide loading\n this.hideLoading();\n }\n\n // Update counter\n if (counterElement) {\n counterElement.textContent = `${this.currentIndex + 1} of ${this.images.length}`;\n }\n\n // Update navigation buttons\n if (prevBtn) {\n prevBtn.disabled = this.currentIndex === 0;\n }\n if (nextBtn) {\n nextBtn.disabled = this.currentIndex === this.images.length - 1;\n }\n\n // Update template properties\n this.updateTemplateProperties();\n\n // Update image display mode\n this.updateImageDisplay();\n\n // Emit event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:image-changed', {\n gallery: this,\n index: this.currentIndex,\n image: currentImage\n });\n }\n }\n\n showLoading() {\n const loading = this.element.querySelector('.lightbox-loading');\n if (loading) {\n loading.style.display = 'block';\n }\n }\n\n hideLoading() {\n const loading = this.element.querySelector('.lightbox-loading');\n if (loading) {\n loading.style.display = 'none';\n }\n }\n\n waitForImageLoad(imgElement) {\n return new Promise((resolve) => {\n if (imgElement.complete) {\n resolve();\n } else {\n imgElement.onload = resolve;\n imgElement.onerror = resolve; // Still resolve on error\n }\n });\n }\n\n // Preload adjacent images for smooth navigation\n preloadAdjacentImages() {\n const preloadIndexes = [];\n\n // Previous image\n if (this.currentIndex > 0) {\n preloadIndexes.push(this.currentIndex - 1);\n }\n\n // Next image\n if (this.currentIndex < this.images.length - 1) {\n preloadIndexes.push(this.currentIndex + 1);\n }\n\n preloadIndexes.forEach(index => {\n const image = this.images[index];\n\n // Create image element to trigger browser caching\n const preloadImg = new Image();\n preloadImg.src = image.src;\n });\n }\n\n // Keyboard navigation\n handleKeyboard(e) {\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n case 'ArrowLeft':\n e.preventDefault();\n this.showPrevious();\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.showNext();\n break;\n case 'Home':\n e.preventDefault();\n this.goToImage(0);\n break;\n case 'End':\n e.preventDefault();\n this.goToImage(this.images.length - 1);\n break;\n }\n }\n\n // Toggle between fit-to-screen and original size\n toggleImageMode() {\n this.fitToScreen = !this.fitToScreen;\n this.updateTemplateProperties();\n this.updateImageDisplay();\n\n // Emit mode change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:mode-changed', {\n gallery: this,\n fitToScreen: this.fitToScreen\n });\n }\n }\n\n // Update image display without full re-render\n updateImageDisplay() {\n const imgElement = this.element.querySelector('.lightbox-image');\n const containerElement = this.element.querySelector('.lightbox-image-container');\n const indicatorElement = this.element.querySelector('.lightbox-mode-indicator');\n\n if (imgElement) {\n if (this.fitToScreen) {\n imgElement.style.maxWidth = '100%';\n imgElement.style.maxHeight = '100%';\n imgElement.style.objectFit = 'contain';\n imgElement.style.cursor = 'zoom-in';\n } else {\n imgElement.style.maxWidth = 'none';\n imgElement.style.maxHeight = 'none';\n imgElement.style.objectFit = 'none';\n imgElement.style.cursor = 'zoom-out';\n }\n imgElement.style.userSelect = 'none';\n }\n\n if (containerElement) {\n containerElement.style.overflow = this.fitToScreen ? '' : 'auto';\n }\n\n if (indicatorElement) {\n indicatorElement.textContent = `${this.modeIndicator} • Click image to toggle`;\n }\n }\n\n // Close lightbox\n close() {\n // Emit close event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:closed', { gallery: this });\n }\n\n this.destroy();\n }\n\n async onBeforeDestroy() {\n // Restore body overflow\n document.body.style.overflow = '';\n\n // Remove keyboard listener\n if (this.allowKeyboard) {\n document.removeEventListener('keydown', this._keyboardHandler);\n }\n\n // Remove from body\n if (this.element.parentNode === document.body) {\n document.body.removeChild(this.element);\n }\n }\n\n // Static method to show lightbox\n static show(images, options = {}) {\n const lightbox = new LightboxGallery({\n images,\n ...options\n });\n\n lightbox.render().then(() => {\n lightbox.mount();\n });\n\n return lightbox;\n }\n}\n\nwindow.LightboxGallery = LightboxGallery;\n","/**\n * PDFViewer - PDF document viewer component with zoom and navigation\n * Built for the MOJO framework with PDF.js integration\n */\n\nimport View from '@core/View.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PDFViewer extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `pdf-viewer ${options.className || ''}`,\n tagName: 'div'\n });\n\n // PDF properties\n this.pdfUrl = options.pdfUrl || options.src || '';\n this.title = options.title || 'PDF Document';\n\n // PDF.js objects\n this.pdfDoc = null;\n this.currentPage = 1;\n this.totalPages = 0;\n this.pageRendering = false;\n this.pageNumPending = null;\n\n // Zoom and display state\n this.scale = 1.0;\n this.minScale = 0.25;\n this.maxScale = 5.0;\n this.scaleStep = 0.25;\n this.fitMode = 'page'; // 'page', 'width', 'auto'\n\n // Canvas and context\n this.canvas = null;\n this.ctx = null;\n\n // Options\n this.showControls = options.showControls !== false;\n this.allowZoom = options.allowZoom !== false;\n this.allowNavigation = options.allowNavigation !== false;\n this.showPageNumbers = options.showPageNumbers !== false;\n\n // Loading state\n this.isLoaded = false;\n this.isLoading = false;\n\n // PDF.js worker path - can be customized\n this.pdfjsWorkerPath = options.pdfjsWorkerPath || 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.js';\n this.pdfjsCMapUrl = options.pdfjsCMapUrl || 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/cmaps/';\n\n // Elements\n this.canvasContainer = null;\n this.controlsElement = null;\n this.statusElement = null;\n this.pageInput = null;\n }\n\n async getTemplate() {\n return `\n <div class=\"pdf-viewer-container\">\n {{#showControls}}\n <div class=\"pdf-viewer-toolbar\" data-container=\"toolbar\">\n <div class=\"btn-toolbar\" role=\"toolbar\">\n <!-- Navigation Controls -->\n {{#allowNavigation}}\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Navigation\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"first-page\" title=\"First Page\">\n <i class=\"bi bi-chevron-double-left\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"prev-page\" title=\"Previous Page\">\n <i class=\"bi bi-chevron-left\"></i>\n </button>\n \n {{#showPageNumbers}}\n <div class=\"input-group input-group-sm\" style=\"width: 120px;\">\n <input type=\"number\" class=\"form-control text-center page-input\" min=\"1\" value=\"1\" data-change-action=\"page-input\">\n <span class=\"input-group-text page-total\">/ 0</span>\n </div>\n {{/showPageNumbers}}\n \n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"next-page\" title=\"Next Page\">\n <i class=\"bi bi-chevron-right\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"last-page\" title=\"Last Page\">\n <i class=\"bi bi-chevron-double-right\"></i>\n </button>\n </div>\n {{/allowNavigation}}\n\n <!-- Zoom Controls -->\n {{#allowZoom}}\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Zoom\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"zoom-out\" title=\"Zoom Out\">\n <i class=\"bi bi-zoom-out\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"zoom-in\" title=\"Zoom In\">\n <i class=\"bi bi-zoom-in\"></i>\n </button>\n \n <div class=\"btn-group\" role=\"group\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm dropdown-toggle\" data-bs-toggle=\"dropdown\" title=\"Fit\">\n <i class=\"bi bi-arrows-fullscreen\"></i>\n </button>\n <ul class=\"dropdown-menu\">\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"fit-page\">Fit Page</a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"fit-width\">Fit Width</a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"actual-size\">Actual Size</a></li>\n </ul>\n </div>\n </div>\n {{/allowZoom}}\n\n <!-- Utility Controls -->\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Utilities\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"download\" title=\"Download\">\n <i class=\"bi bi-download\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"print\" title=\"Print\">\n <i class=\"bi bi-printer\"></i>\n </button>\n </div>\n </div>\n </div>\n {{/showControls}}\n\n <!-- PDF Content Area -->\n <div class=\"pdf-viewer-content\" data-container=\"content\">\n <div class=\"pdf-canvas-container\" data-container=\"canvasContainer\">\n <canvas class=\"pdf-canvas\" data-container=\"canvas\"></canvas>\n </div>\n\n <div class=\"pdf-viewer-overlay\">\n <div class=\"pdf-viewer-loading\">\n <div class=\"spinner-border text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading PDF...</span>\n </div>\n <div class=\"mt-2\">Loading PDF...</div>\n </div>\n </div>\n\n <div class=\"pdf-viewer-error\" style=\"display: none;\">\n <div class=\"alert alert-danger\" role=\"alert\">\n <i class=\"bi bi-exclamation-triangle\"></i>\n <strong>Error:</strong> <span class=\"error-message\">Failed to load PDF</span>\n </div>\n </div>\n </div>\n\n <!-- Status Bar -->\n <div class=\"pdf-viewer-status\" data-container=\"status\">\n <small class=\"text-muted\">\n <span class=\"current-page\">0</span> of <span class=\"total-pages\">0</span> pages |\n <span class=\"zoom-level\">100%</span> |\n <span class=\"document-title\">{{title}}</span>\n </small>\n </div>\n </div>\n `;\n }\n\n get() {\n return {\n pdfUrl: this.pdfUrl,\n title: this.title,\n showControls: this.showControls,\n allowZoom: this.allowZoom,\n allowNavigation: this.allowNavigation,\n showPageNumbers: this.showPageNumbers\n };\n }\n\n async onAfterRender() {\n // Cache DOM elements\n this.canvas = this.element.querySelector('.pdf-canvas');\n this.canvasContainer = this.element.querySelector('.pdf-canvas-container');\n this.controlsElement = this.element.querySelector('.pdf-viewer-toolbar');\n this.statusElement = this.element.querySelector('.pdf-viewer-status');\n this.pageInput = this.element.querySelector('.page-input');\n this.overlayElement = this.element.querySelector('.pdf-viewer-overlay');\n this.errorElement = this.element.querySelector('.pdf-viewer-error');\n\n if (this.canvas) {\n this.ctx = this.canvas.getContext('2d');\n }\n// Set up essential event listeners (keyboard, resize)\nthis.setupEssentialEventListeners();\n\n// Initialize PDF.js and load PDF\nawait this.initializePDFJS();\nif (this.pdfUrl) {\n await this.loadPDF();\n}\n}\n\n\n\n setupEssentialEventListeners() {\n // Essential events that can't be handled by EventDelegate\n const keydownHandler = (e) => this.handleKeyDown(e);\n document.addEventListener('keydown', keydownHandler);\n\n // Canvas resize observer for fit mode\n let resizeObserver = null;\n if (this.canvasContainer) {\n resizeObserver = new ResizeObserver(() => {\n if (this.fitMode !== 'auto') {\n this.applyFitMode();\n }\n });\n resizeObserver.observe(this.canvasContainer);\n }\n\n // Store listeners for cleanup\n this._essentialListeners = [\n { el: document, type: 'keydown', fn: keydownHandler }\n ];\n this._resizeObserver = resizeObserver;\n }\n\n async initializePDFJS() {\n try {\n // Load PDF.js if not already loaded\n if (typeof window.pdfjsLib === 'undefined') {\n await this.loadPDFJSLibrary();\n }\n\n // Configure PDF.js\n window.pdfjsLib.GlobalWorkerOptions.workerSrc = this.pdfjsWorkerPath;\n \n return true;\n } catch (error) {\n console.error('Failed to initialize PDF.js:', error);\n this.showError('Failed to initialize PDF viewer');\n return false;\n }\n }\n\n async loadPDFJSLibrary() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.min.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n }\n\n // Action Handlers\n async handleActionFirstPage() {\n await this.goToPage(1);\n }\n\n async handleActionPrevPage() {\n await this.goToPage(this.currentPage - 1);\n }\n\n async handleActionNextPage() {\n await this.goToPage(this.currentPage + 1);\n }\n\n async handleActionLastPage() {\n await this.goToPage(this.totalPages);\n }\n\n async onChangePageInput(event, element) {\n const pageNumber = parseInt(element.value, 10);\n if (pageNumber >= 1 && pageNumber <= this.totalPages) {\n await this.goToPage(pageNumber);\n } else {\n element.value = this.currentPage;\n }\n }\n\n async handleActionZoomIn() {\n this.setScale(this.scale + this.scaleStep);\n }\n\n async handleActionZoomOut() {\n this.setScale(this.scale - this.scaleStep);\n }\n\n async handleActionFitPage() {\n this.setFitMode('page');\n }\n\n async handleActionFitWidth() {\n this.setFitMode('width');\n }\n\n async handleActionActualSize() {\n this.setScale(1.0);\n this.fitMode = 'auto';\n }\n\n async handleActionDownload() {\n this.downloadPDF();\n }\n\n async handleActionPrint() {\n window.print();\n }\n\n // PDF Loading\n async loadPDF() {\n if (!this.pdfUrl || !window.pdfjsLib) {\n this.showError('PDF URL or PDF.js library not available');\n return false;\n }\n\n this.isLoading = true;\n this.showLoading();\n\n try {\n const loadingTask = window.pdfjsLib.getDocument({\n url: this.pdfUrl,\n cMapUrl: this.pdfjsCMapUrl,\n cMapPacked: true\n });\n\n this.pdfDoc = await loadingTask.promise;\n this.totalPages = this.pdfDoc.numPages;\n this.currentPage = 1;\n\n // Update UI\n this.updatePageControls();\n this.updateStatus();\n\n // Render first page\n await this.renderPage(1);\n\n this.isLoaded = true;\n this.isLoading = false;\n this.element.classList.add('loaded');\n this.hideLoading();\n\n // Apply initial fit mode\n this.applyFitMode();\n\n // Emit loaded event via EventBus\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:loaded', { \n viewer: this, \n pdfUrl: this.pdfUrl,\n totalPages: this.totalPages\n });\n }\n\n return true;\n\n } catch (error) {\n console.error('Error loading PDF:', error);\n this.isLoading = false;\n this.showError('Failed to load PDF document');\n \n // Emit error event via EventBus\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:error', { \n viewer: this, \n pdfUrl: this.pdfUrl,\n error: error.message\n });\n }\n \n return false;\n }\n }\n\n async renderPage(pageNumber) {\n if (this.pageRendering) {\n this.pageNumPending = pageNumber;\n return;\n }\n\n if (!this.pdfDoc || !this.canvas || !this.ctx) {\n return;\n }\n\n this.pageRendering = true;\n this.currentPage = pageNumber;\n\n try {\n const page = await this.pdfDoc.getPage(pageNumber);\n const viewport = page.getViewport({ scale: this.scale });\n\n // Set canvas dimensions\n this.canvas.height = viewport.height;\n this.canvas.width = viewport.width;\n\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Render page\n const renderContext = {\n canvasContext: this.ctx,\n viewport: viewport\n };\n\n const renderTask = page.render(renderContext);\n await renderTask.promise;\n\n this.pageRendering = false;\n\n // If there was a pending page render request\n if (this.pageNumPending !== null) {\n const pendingPage = this.pageNumPending;\n this.pageNumPending = null;\n await this.renderPage(pendingPage);\n }\n\n this.updatePageControls();\n this.updateStatus();\n\n // Emit page changed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:page-changed', { \n viewer: this, \n currentPage: this.currentPage,\n totalPages: this.totalPages\n });\n }\n\n } catch (error) {\n console.error('Error rendering page:', error);\n this.pageRendering = false;\n this.showError('Failed to render PDF page');\n }\n }\n\n // Navigation\n async goToPage(pageNumber) {\n if (!this.pdfDoc || pageNumber < 1 || pageNumber > this.totalPages) {\n return;\n }\n\n await this.renderPage(pageNumber);\n }\n\n // Zoom and Fit\n setScale(scale) {\n const oldScale = this.scale;\n this.scale = Math.max(this.minScale, Math.min(this.maxScale, scale));\n this.fitMode = 'auto';\n \n if (this.isLoaded) {\n this.renderPage(this.currentPage);\n }\n\n // Emit scale change event\n const eventBus = this.getApp()?.events;\n if (eventBus && oldScale !== this.scale) {\n eventBus.emit('pdfviewer:scale-changed', { \n viewer: this, \n oldScale, \n newScale: this.scale \n });\n }\n }\n\n setFitMode(mode) {\n const oldMode = this.fitMode;\n this.fitMode = mode;\n this.applyFitMode();\n\n // Emit fit mode change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:fit-mode-changed', { \n viewer: this, \n oldMode, \n newMode: mode \n });\n }\n }\n\n applyFitMode() {\n if (!this.isLoaded || !this.pdfDoc || !this.canvasContainer) {\n return;\n }\n\n this.pdfDoc.getPage(this.currentPage).then(page => {\n const containerRect = this.canvasContainer.getBoundingClientRect();\n const viewport = page.getViewport({ scale: 1 });\n\n let newScale;\n if (this.fitMode === 'page') {\n const scaleX = (containerRect.width - 40) / viewport.width;\n const scaleY = (containerRect.height - 40) / viewport.height;\n newScale = Math.min(scaleX, scaleY);\n } else if (this.fitMode === 'width') {\n newScale = (containerRect.width - 40) / viewport.width;\n } else {\n return; // auto mode, don't change scale\n }\n\n this.scale = Math.max(this.minScale, Math.min(this.maxScale, newScale));\n this.renderPage(this.currentPage);\n });\n }\n\n // Event Handlers\n handleKeyDown(e) {\n // Only handle if PDF viewer is focused or no input is focused\n if (e.target.tagName === 'INPUT' && e.target !== this.pageInput) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'PageUp':\n e.preventDefault();\n this.goToPage(this.currentPage - 1);\n break;\n case 'ArrowRight':\n case 'PageDown':\n e.preventDefault();\n this.goToPage(this.currentPage + 1);\n break;\n case 'Home':\n e.preventDefault();\n this.goToPage(1);\n break;\n case 'End':\n e.preventDefault();\n this.goToPage(this.totalPages);\n break;\n case '+':\n case '=':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setScale(this.scale + this.scaleStep);\n }\n break;\n case '-':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setScale(this.scale - this.scaleStep);\n }\n break;\n case '0':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setFitMode('page');\n }\n break;\n }\n }\n\n // UI Updates\n updatePageControls() {\n // Update page input\n if (this.pageInput) {\n this.pageInput.value = this.currentPage;\n }\n\n // Update page total display\n const pageTotalElement = this.element.querySelector('.page-total');\n if (pageTotalElement) {\n pageTotalElement.textContent = `/ ${this.totalPages}`;\n }\n\n // Update navigation buttons\n const firstBtn = this.element.querySelector('[data-action=\"first-page\"]');\n const prevBtn = this.element.querySelector('[data-action=\"prev-page\"]');\n const nextBtn = this.element.querySelector('[data-action=\"next-page\"]');\n const lastBtn = this.element.querySelector('[data-action=\"last-page\"]');\n\n if (firstBtn) firstBtn.disabled = this.currentPage <= 1;\n if (prevBtn) prevBtn.disabled = this.currentPage <= 1;\n if (nextBtn) nextBtn.disabled = this.currentPage >= this.totalPages;\n if (lastBtn) lastBtn.disabled = this.currentPage >= this.totalPages;\n\n // Update zoom buttons\n const zoomInBtn = this.element.querySelector('[data-action=\"zoom-in\"]');\n const zoomOutBtn = this.element.querySelector('[data-action=\"zoom-out\"]');\n\n if (zoomInBtn) zoomInBtn.disabled = this.scale >= this.maxScale;\n if (zoomOutBtn) zoomOutBtn.disabled = this.scale <= this.minScale;\n }\n\n updateStatus() {\n if (!this.statusElement) return;\n\n const currentPageElement = this.statusElement.querySelector('.current-page');\n const totalPagesElement = this.statusElement.querySelector('.total-pages');\n const zoomLevelElement = this.statusElement.querySelector('.zoom-level');\n\n if (currentPageElement) {\n currentPageElement.textContent = this.currentPage;\n }\n if (totalPagesElement) {\n totalPagesElement.textContent = this.totalPages;\n }\n if (zoomLevelElement) {\n zoomLevelElement.textContent = `${Math.round(this.scale * 100)}%`;\n }\n }\n\n // Utility Methods\n showLoading() {\n if (this.overlayElement) {\n this.overlayElement.style.display = 'flex';\n }\n }\n\n hideLoading() {\n if (this.overlayElement) {\n this.overlayElement.style.display = 'none';\n }\n }\n\n showError(message) {\n this.hideLoading();\n \n if (this.errorElement) {\n const errorMessageElement = this.errorElement.querySelector('.error-message');\n if (errorMessageElement) {\n errorMessageElement.textContent = message;\n }\n this.errorElement.style.display = 'block';\n }\n\n console.error('PDF Viewer Error:', message);\n }\n\n downloadPDF() {\n if (!this.pdfUrl) return;\n\n const link = document.createElement('a');\n link.href = this.pdfUrl;\n link.download = this.title + '.pdf';\n link.target = '_blank';\n link.click();\n }\n\n // Public API\n setPDF(pdfUrl, title = '') {\n const oldPdfUrl = this.pdfUrl;\n this.pdfUrl = pdfUrl;\n this.title = title || 'PDF Document';\n this.isLoaded = false;\n this.element.classList.remove('loaded');\n \n if (this.pdfDoc) {\n this.pdfDoc.destroy();\n this.pdfDoc = null;\n }\n \n this.currentPage = 1;\n this.totalPages = 0;\n this.scale = 1.0;\n \n if (pdfUrl) {\n this.loadPDF();\n }\n\n // Emit PDF changed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:pdf-changed', { \n viewer: this, \n oldPdfUrl, \n newPdfUrl: pdfUrl \n });\n }\n }\n\n getCurrentPage() {\n return this.currentPage;\n }\n\n getTotalPages() {\n return this.totalPages;\n }\n\n getCurrentScale() {\n return this.scale;\n }\n\n async onBeforeDestroy() {\n // Clean up PDF.js resources\n if (this.pdfDoc) {\n this.pdfDoc.destroy();\n this.pdfDoc = null;\n }\n\n this.pageRendering = false;\n this.pageNumPending = null;\n\n // Clean up essential event listeners\n if (this._essentialListeners) {\n this._essentialListeners.forEach(({ el, type, fn }) => {\n if (el) el.removeEventListener(type, fn);\n });\n this._essentialListeners = null;\n }\n\n // Clean up resize observer\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = null;\n }\n\n // Emit destroy event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:destroyed', { viewer: this });\n }\n }\n\n // Static method to show PDF in a fullscreen dialog\n static async showDialog(pdfUrl, options = {}) {\n const {\n title = 'PDF Viewer',\n size = 'fullscreen',\n showControls = true,\n allowZoom = true,\n allowNavigation = true,\n showPageNumbers = true,\n ...dialogOptions\n } = options;\n\n const viewer = new PDFViewer({\n pdfUrl,\n title,\n showControls,\n allowZoom,\n allowNavigation,\n showPageNumbers\n });\n\n const dialog = new Dialog({\n title,\n body: viewer,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n { \n text: 'Download', \n action: 'download', \n class: 'btn btn-outline-primary' \n },\n { \n text: 'Close', \n action: 'close', \n class: 'btn btn-secondary',\n dismiss: true\n }\n ],\n ...dialogOptions\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(viewer);\n });\n\n dialog.on('action:download', () => {\n viewer.downloadPDF();\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PDFViewer-Dr72gJt1.js","sources":["../../src/extensions/lightbox/LightboxGallery.js","../../src/extensions/lightbox/PDFViewer.js"],"sourcesContent":["/**\n * LightboxGallery - Simple fullscreen image gallery\n * Clean, minimal lightbox for viewing single images or galleries\n */\n\nimport View from '@core/View.js';\n\nexport default class LightboxGallery extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `lightbox-gallery ${options.className || ''}`,\n tagName: 'div'\n });\n\n // Handle single image or array of images and normalize to objects\n const rawImages = Array.isArray(options.images) ? options.images : [options.images || options.src].filter(Boolean);\n this.images = rawImages.map(img => {\n if (typeof img === 'string') {\n return { src: img, alt: '' };\n }\n return { src: img.src, alt: img.alt || '' };\n });\n this.currentIndex = options.startIndex || 0;\n this.showNavigation = options.showNavigation !== false && this.images.length > 1;\n this.showCounter = options.showCounter !== false && this.images.length > 1;\n this.allowKeyboard = options.allowKeyboard !== false;\n this.closeOnBackdrop = options.closeOnBackdrop !== false;\n this.fitToScreen = options.fitToScreen !== false; // Start in fit-to-screen mode\n\n // Bind keyboard handler for cleanup\n this._keyboardHandler = this.handleKeyboard.bind(this);\n\n // Set template properties directly on view instance\n this.updateTemplateProperties();\n }\n\n updateTemplateProperties() {\n this.currentImage = this.images[this.currentIndex] || { src: '', alt: '' };\n this.currentNumber = this.currentIndex + 1;\n this.total = this.images.length;\n this.isFirst = this.currentIndex === 0;\n this.isLast = this.currentIndex === this.images.length - 1;\n this.imageStyle = this.fitToScreen\n ? 'width: 90vw; max-height: 100%; object-fit: contain; user-select: none; cursor: zoom-in;'\n : 'max-width: none; max-height: none; user-select: none; cursor: zoom-out;';\n this.containerStyle = this.fitToScreen\n ? ''\n : 'overflow: auto;';\n this.modeIndicator = this.fitToScreen ? 'Fit to Screen' : 'Original Size';\n }\n\n async getTemplate() {\n const currentImage = this.images[this.currentIndex];\n const hasMultiple = this.images.length > 1;\n\n return `\n <div class=\"lightbox-overlay position-fixed top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center\"\n style=\"background: rgba(0,0,0,0.9); z-index: 9999;\"\n data-action=\"backdrop-click\">\n\n <!-- Close button -->\n <button type=\"button\" class=\"btn-close btn-close-white position-absolute top-0 end-0 m-4\"\n data-action=\"close\"\n style=\"z-index: 10001;\"\n title=\"Close\"></button>\n\n <!-- Counter -->\n {{#showCounter}}\n <div class=\"lightbox-counter position-absolute top-0 start-50 translate-middle-x mt-4 text-white\"\n style=\"z-index: 10001; font-size: 1.1rem;\">\n {{currentNumber}} of {{total}}\n </div>\n {{/showCounter}}\n\n <!-- Mode Indicator -->\n <div class=\"lightbox-mode-indicator position-absolute bottom-0 start-50 translate-middle-x mb-4 text-white bg-dark bg-opacity-75 px-3 py-2 rounded\"\n style=\"z-index: 10001; font-size: 0.9rem;\">\n {{modeIndicator}} • Click image to toggle\n </div>\n\n <!-- Navigation -->\n {{#showNavigation}}\n <button type=\"button\" class=\"btn btn-light btn-lg position-absolute start-0 top-50 translate-middle-y ms-4\"\n data-action=\"prev\"\n style=\"z-index: 10001;\"\n title=\"Previous\"\n {{#isFirst}}disabled{{/isFirst}}>\n <i class=\"bi bi-chevron-left\"></i>\n </button>\n\n <button type=\"button\" class=\"btn btn-light btn-lg position-absolute end-0 top-50 translate-middle-y me-4\"\n data-action=\"next\"\n style=\"z-index: 10001;\"\n title=\"Next\"\n {{#isLast}}disabled{{/isLast}}>\n <i class=\"bi bi-chevron-right\"></i>\n </button>\n {{/showNavigation}}\n\n <!-- Image container -->\n <div class=\"lightbox-image-container w-100 h-100 d-flex align-items-center justify-content-center p-5\"\n style=\"{{containerStyle}}\">\n {{#currentImage}}\n <img src=\"{{src}}\"\n alt=\"{{alt}}\"\n class=\"lightbox-image img-fluid\"\n style=\"{{imageStyle}}\"\n data-action=\"image-click\">\n {{/currentImage}}\n </div>\n\n <!-- Loading spinner -->\n <div class=\"lightbox-loading position-absolute top-50 start-50 translate-middle text-white\"\n style=\"display: none;\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n </div>\n `;\n }\n\n\n\n async onAfterRender() {\n // Add to body for fullscreen\n document.body.appendChild(this.element);\n document.body.style.overflow = 'hidden';\n\n // Set up keyboard navigation\n if (this.allowKeyboard) {\n document.addEventListener('keydown', this._keyboardHandler);\n }\n\n // Preload next/previous images\n this.preloadAdjacentImages();\n }\n\n // Action handlers\n async handleActionClose() {\n this.close();\n }\n\n async handleActionBackdropClick(e) {\n // Only close if clicked on backdrop, not image\n if (this.closeOnBackdrop && e.target === e.currentTarget) {\n this.close();\n }\n }\n\n async handleActionPrev() {\n this.showPrevious();\n }\n\n async handleActionNext() {\n this.showNext();\n }\n\n async handleActionImageClick() {\n this.toggleImageMode();\n }\n\n // Navigation methods\n showPrevious() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n showNext() {\n if (this.currentIndex < this.images.length - 1) {\n this.currentIndex++;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n goToImage(index) {\n if (index >= 0 && index < this.images.length && index !== this.currentIndex) {\n this.currentIndex = index;\n this.updateImage();\n this.preloadAdjacentImages();\n }\n }\n\n // Update image without full re-render\n async updateImage() {\n const currentImage = this.images[this.currentIndex];\n const imgElement = this.element.querySelector('.lightbox-image');\n const counterElement = this.element.querySelector('.lightbox-counter');\n const prevBtn = this.element.querySelector('[data-action=\"prev\"]');\n const nextBtn = this.element.querySelector('[data-action=\"next\"]');\n\n if (imgElement) {\n // Show loading\n this.showLoading();\n\n // Update image\n imgElement.src = currentImage.src;\n imgElement.alt = currentImage.alt;\n\n // Wait for image to load\n await this.waitForImageLoad(imgElement);\n\n // Hide loading\n this.hideLoading();\n }\n\n // Update counter\n if (counterElement) {\n counterElement.textContent = `${this.currentIndex + 1} of ${this.images.length}`;\n }\n\n // Update navigation buttons\n if (prevBtn) {\n prevBtn.disabled = this.currentIndex === 0;\n }\n if (nextBtn) {\n nextBtn.disabled = this.currentIndex === this.images.length - 1;\n }\n\n // Update template properties\n this.updateTemplateProperties();\n\n // Update image display mode\n this.updateImageDisplay();\n\n // Emit event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:image-changed', {\n gallery: this,\n index: this.currentIndex,\n image: currentImage\n });\n }\n }\n\n showLoading() {\n const loading = this.element.querySelector('.lightbox-loading');\n if (loading) {\n loading.style.display = 'block';\n }\n }\n\n hideLoading() {\n const loading = this.element.querySelector('.lightbox-loading');\n if (loading) {\n loading.style.display = 'none';\n }\n }\n\n waitForImageLoad(imgElement) {\n return new Promise((resolve) => {\n if (imgElement.complete) {\n resolve();\n } else {\n imgElement.onload = resolve;\n imgElement.onerror = resolve; // Still resolve on error\n }\n });\n }\n\n // Preload adjacent images for smooth navigation\n preloadAdjacentImages() {\n const preloadIndexes = [];\n\n // Previous image\n if (this.currentIndex > 0) {\n preloadIndexes.push(this.currentIndex - 1);\n }\n\n // Next image\n if (this.currentIndex < this.images.length - 1) {\n preloadIndexes.push(this.currentIndex + 1);\n }\n\n preloadIndexes.forEach(index => {\n const image = this.images[index];\n\n // Create image element to trigger browser caching\n const preloadImg = new Image();\n preloadImg.src = image.src;\n });\n }\n\n // Keyboard navigation\n handleKeyboard(e) {\n switch (e.key) {\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n case 'ArrowLeft':\n e.preventDefault();\n this.showPrevious();\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.showNext();\n break;\n case 'Home':\n e.preventDefault();\n this.goToImage(0);\n break;\n case 'End':\n e.preventDefault();\n this.goToImage(this.images.length - 1);\n break;\n }\n }\n\n // Toggle between fit-to-screen and original size\n toggleImageMode() {\n this.fitToScreen = !this.fitToScreen;\n this.updateTemplateProperties();\n this.updateImageDisplay();\n\n // Emit mode change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:mode-changed', {\n gallery: this,\n fitToScreen: this.fitToScreen\n });\n }\n }\n\n // Update image display without full re-render\n updateImageDisplay() {\n const imgElement = this.element.querySelector('.lightbox-image');\n const containerElement = this.element.querySelector('.lightbox-image-container');\n const indicatorElement = this.element.querySelector('.lightbox-mode-indicator');\n\n if (imgElement) {\n if (this.fitToScreen) {\n imgElement.style.maxWidth = '100%';\n imgElement.style.maxHeight = '100%';\n imgElement.style.objectFit = 'contain';\n imgElement.style.cursor = 'zoom-in';\n } else {\n imgElement.style.maxWidth = 'none';\n imgElement.style.maxHeight = 'none';\n imgElement.style.objectFit = 'none';\n imgElement.style.cursor = 'zoom-out';\n }\n imgElement.style.userSelect = 'none';\n }\n\n if (containerElement) {\n containerElement.style.overflow = this.fitToScreen ? '' : 'auto';\n }\n\n if (indicatorElement) {\n indicatorElement.textContent = `${this.modeIndicator} • Click image to toggle`;\n }\n }\n\n // Close lightbox\n close() {\n // Emit close event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('lightbox:closed', { gallery: this });\n }\n\n this.destroy();\n }\n\n async onBeforeDestroy() {\n // Restore body overflow\n document.body.style.overflow = '';\n\n // Remove keyboard listener\n if (this.allowKeyboard) {\n document.removeEventListener('keydown', this._keyboardHandler);\n }\n\n // Remove from body\n if (this.element.parentNode === document.body) {\n document.body.removeChild(this.element);\n }\n }\n\n // Static method to show lightbox\n static show(images, options = {}) {\n const lightbox = new LightboxGallery({\n images,\n ...options\n });\n\n lightbox.render().then(() => {\n lightbox.mount();\n });\n\n return lightbox;\n }\n}\n\nwindow.LightboxGallery = LightboxGallery;\n","/**\n * PDFViewer - PDF document viewer component with zoom and navigation\n * Built for the MOJO framework with PDF.js integration\n */\n\nimport View from '@core/View.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PDFViewer extends View {\n constructor(options = {}) {\n super({\n ...options,\n className: `pdf-viewer ${options.className || ''}`,\n tagName: 'div'\n });\n\n // PDF properties\n this.pdfUrl = options.pdfUrl || options.src || '';\n this.title = options.title || 'PDF Document';\n\n // PDF.js objects\n this.pdfDoc = null;\n this.currentPage = 1;\n this.totalPages = 0;\n this.pageRendering = false;\n this.pageNumPending = null;\n\n // Zoom and display state\n this.scale = 1.0;\n this.minScale = 0.25;\n this.maxScale = 5.0;\n this.scaleStep = 0.25;\n this.fitMode = 'page'; // 'page', 'width', 'auto'\n\n // Canvas and context\n this.canvas = null;\n this.ctx = null;\n\n // Options\n this.showControls = options.showControls !== false;\n this.allowZoom = options.allowZoom !== false;\n this.allowNavigation = options.allowNavigation !== false;\n this.showPageNumbers = options.showPageNumbers !== false;\n\n // Loading state\n this.isLoaded = false;\n this.isLoading = false;\n\n // PDF.js worker path - can be customized\n this.pdfjsWorkerPath = options.pdfjsWorkerPath || 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.js';\n this.pdfjsCMapUrl = options.pdfjsCMapUrl || 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/cmaps/';\n\n // Elements\n this.canvasContainer = null;\n this.controlsElement = null;\n this.statusElement = null;\n this.pageInput = null;\n }\n\n async getTemplate() {\n return `\n <div class=\"pdf-viewer-container\">\n {{#showControls}}\n <div class=\"pdf-viewer-toolbar\" data-container=\"toolbar\">\n <div class=\"btn-toolbar\" role=\"toolbar\">\n <!-- Navigation Controls -->\n {{#allowNavigation}}\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Navigation\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"first-page\" title=\"First Page\">\n <i class=\"bi bi-chevron-double-left\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"prev-page\" title=\"Previous Page\">\n <i class=\"bi bi-chevron-left\"></i>\n </button>\n \n {{#showPageNumbers}}\n <div class=\"input-group input-group-sm\" style=\"width: 120px;\">\n <input type=\"number\" class=\"form-control text-center page-input\" min=\"1\" value=\"1\" data-change-action=\"page-input\">\n <span class=\"input-group-text page-total\">/ 0</span>\n </div>\n {{/showPageNumbers}}\n \n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"next-page\" title=\"Next Page\">\n <i class=\"bi bi-chevron-right\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"last-page\" title=\"Last Page\">\n <i class=\"bi bi-chevron-double-right\"></i>\n </button>\n </div>\n {{/allowNavigation}}\n\n <!-- Zoom Controls -->\n {{#allowZoom}}\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Zoom\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"zoom-out\" title=\"Zoom Out\">\n <i class=\"bi bi-zoom-out\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"zoom-in\" title=\"Zoom In\">\n <i class=\"bi bi-zoom-in\"></i>\n </button>\n \n <div class=\"btn-group\" role=\"group\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm dropdown-toggle\" data-bs-toggle=\"dropdown\" title=\"Fit\">\n <i class=\"bi bi-arrows-fullscreen\"></i>\n </button>\n <ul class=\"dropdown-menu\">\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"fit-page\">Fit Page</a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"fit-width\">Fit Width</a></li>\n <li><a class=\"dropdown-item\" href=\"#\" data-action=\"actual-size\">Actual Size</a></li>\n </ul>\n </div>\n </div>\n {{/allowZoom}}\n\n <!-- Utility Controls -->\n <div class=\"btn-group me-2\" role=\"group\" aria-label=\"Utilities\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"download\" title=\"Download\">\n <i class=\"bi bi-download\"></i>\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm\" data-action=\"print\" title=\"Print\">\n <i class=\"bi bi-printer\"></i>\n </button>\n </div>\n </div>\n </div>\n {{/showControls}}\n\n <!-- PDF Content Area -->\n <div class=\"pdf-viewer-content\" data-container=\"content\">\n <div class=\"pdf-canvas-container\" data-container=\"canvasContainer\">\n <canvas class=\"pdf-canvas\" data-container=\"canvas\"></canvas>\n </div>\n\n <div class=\"pdf-viewer-overlay\">\n <div class=\"pdf-viewer-loading\">\n <div class=\"spinner-border text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading PDF...</span>\n </div>\n <div class=\"mt-2\">Loading PDF...</div>\n </div>\n </div>\n\n <div class=\"pdf-viewer-error\" style=\"display: none;\">\n <div class=\"alert alert-danger\" role=\"alert\">\n <i class=\"bi bi-exclamation-triangle\"></i>\n <strong>Error:</strong> <span class=\"error-message\">Failed to load PDF</span>\n </div>\n </div>\n </div>\n\n <!-- Status Bar -->\n <div class=\"pdf-viewer-status\" data-container=\"status\">\n <small class=\"text-muted\">\n <span class=\"current-page\">0</span> of <span class=\"total-pages\">0</span> pages |\n <span class=\"zoom-level\">100%</span> |\n <span class=\"document-title\">{{title}}</span>\n </small>\n </div>\n </div>\n `;\n }\n\n get() {\n return {\n pdfUrl: this.pdfUrl,\n title: this.title,\n showControls: this.showControls,\n allowZoom: this.allowZoom,\n allowNavigation: this.allowNavigation,\n showPageNumbers: this.showPageNumbers\n };\n }\n\n async onAfterRender() {\n // Cache DOM elements\n this.canvas = this.element.querySelector('.pdf-canvas');\n this.canvasContainer = this.element.querySelector('.pdf-canvas-container');\n this.controlsElement = this.element.querySelector('.pdf-viewer-toolbar');\n this.statusElement = this.element.querySelector('.pdf-viewer-status');\n this.pageInput = this.element.querySelector('.page-input');\n this.overlayElement = this.element.querySelector('.pdf-viewer-overlay');\n this.errorElement = this.element.querySelector('.pdf-viewer-error');\n\n if (this.canvas) {\n this.ctx = this.canvas.getContext('2d');\n }\n// Set up essential event listeners (keyboard, resize)\nthis.setupEssentialEventListeners();\n\n// Initialize PDF.js and load PDF\nawait this.initializePDFJS();\nif (this.pdfUrl) {\n await this.loadPDF();\n}\n}\n\n\n\n setupEssentialEventListeners() {\n // Essential events that can't be handled by EventDelegate\n const keydownHandler = (e) => this.handleKeyDown(e);\n document.addEventListener('keydown', keydownHandler);\n\n // Canvas resize observer for fit mode\n let resizeObserver = null;\n if (this.canvasContainer) {\n resizeObserver = new ResizeObserver(() => {\n if (this.fitMode !== 'auto') {\n this.applyFitMode();\n }\n });\n resizeObserver.observe(this.canvasContainer);\n }\n\n // Store listeners for cleanup\n this._essentialListeners = [\n { el: document, type: 'keydown', fn: keydownHandler }\n ];\n this._resizeObserver = resizeObserver;\n }\n\n async initializePDFJS() {\n try {\n // Load PDF.js if not already loaded\n if (typeof window.pdfjsLib === 'undefined') {\n await this.loadPDFJSLibrary();\n }\n\n // Configure PDF.js\n window.pdfjsLib.GlobalWorkerOptions.workerSrc = this.pdfjsWorkerPath;\n \n return true;\n } catch (error) {\n console.error('Failed to initialize PDF.js:', error);\n this.showError('Failed to initialize PDF viewer');\n return false;\n }\n }\n\n async loadPDFJSLibrary() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.min.js';\n script.onload = resolve;\n script.onerror = reject;\n document.head.appendChild(script);\n });\n }\n\n // Action Handlers\n async handleActionFirstPage() {\n await this.goToPage(1);\n }\n\n async handleActionPrevPage() {\n await this.goToPage(this.currentPage - 1);\n }\n\n async handleActionNextPage() {\n await this.goToPage(this.currentPage + 1);\n }\n\n async handleActionLastPage() {\n await this.goToPage(this.totalPages);\n }\n\n async onChangePageInput(event, element) {\n const pageNumber = parseInt(element.value, 10);\n if (pageNumber >= 1 && pageNumber <= this.totalPages) {\n await this.goToPage(pageNumber);\n } else {\n element.value = this.currentPage;\n }\n }\n\n async handleActionZoomIn() {\n this.setScale(this.scale + this.scaleStep);\n }\n\n async handleActionZoomOut() {\n this.setScale(this.scale - this.scaleStep);\n }\n\n async handleActionFitPage() {\n this.setFitMode('page');\n }\n\n async handleActionFitWidth() {\n this.setFitMode('width');\n }\n\n async handleActionActualSize() {\n this.setScale(1.0);\n this.fitMode = 'auto';\n }\n\n async handleActionDownload() {\n this.downloadPDF();\n }\n\n async handleActionPrint() {\n window.print();\n }\n\n // PDF Loading\n async loadPDF() {\n if (!this.pdfUrl || !window.pdfjsLib) {\n this.showError('PDF URL or PDF.js library not available');\n return false;\n }\n\n this.isLoading = true;\n this.showLoading();\n\n try {\n const loadingTask = window.pdfjsLib.getDocument({\n url: this.pdfUrl,\n cMapUrl: this.pdfjsCMapUrl,\n cMapPacked: true\n });\n\n this.pdfDoc = await loadingTask.promise;\n this.totalPages = this.pdfDoc.numPages;\n this.currentPage = 1;\n\n // Update UI\n this.updatePageControls();\n this.updateStatus();\n\n // Render first page\n await this.renderPage(1);\n\n this.isLoaded = true;\n this.isLoading = false;\n this.element.classList.add('loaded');\n this.hideLoading();\n\n // Apply initial fit mode\n this.applyFitMode();\n\n // Emit loaded event via EventBus\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:loaded', { \n viewer: this, \n pdfUrl: this.pdfUrl,\n totalPages: this.totalPages\n });\n }\n\n return true;\n\n } catch (error) {\n console.error('Error loading PDF:', error);\n this.isLoading = false;\n this.showError('Failed to load PDF document');\n \n // Emit error event via EventBus\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:error', { \n viewer: this, \n pdfUrl: this.pdfUrl,\n error: error.message\n });\n }\n \n return false;\n }\n }\n\n async renderPage(pageNumber) {\n if (this.pageRendering) {\n this.pageNumPending = pageNumber;\n return;\n }\n\n if (!this.pdfDoc || !this.canvas || !this.ctx) {\n return;\n }\n\n this.pageRendering = true;\n this.currentPage = pageNumber;\n\n try {\n const page = await this.pdfDoc.getPage(pageNumber);\n const viewport = page.getViewport({ scale: this.scale });\n\n // Set canvas dimensions\n this.canvas.height = viewport.height;\n this.canvas.width = viewport.width;\n\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n // Render page\n const renderContext = {\n canvasContext: this.ctx,\n viewport: viewport\n };\n\n const renderTask = page.render(renderContext);\n await renderTask.promise;\n\n this.pageRendering = false;\n\n // If there was a pending page render request\n if (this.pageNumPending !== null) {\n const pendingPage = this.pageNumPending;\n this.pageNumPending = null;\n await this.renderPage(pendingPage);\n }\n\n this.updatePageControls();\n this.updateStatus();\n\n // Emit page changed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:page-changed', { \n viewer: this, \n currentPage: this.currentPage,\n totalPages: this.totalPages\n });\n }\n\n } catch (error) {\n console.error('Error rendering page:', error);\n this.pageRendering = false;\n this.showError('Failed to render PDF page');\n }\n }\n\n // Navigation\n async goToPage(pageNumber) {\n if (!this.pdfDoc || pageNumber < 1 || pageNumber > this.totalPages) {\n return;\n }\n\n await this.renderPage(pageNumber);\n }\n\n // Zoom and Fit\n setScale(scale) {\n const oldScale = this.scale;\n this.scale = Math.max(this.minScale, Math.min(this.maxScale, scale));\n this.fitMode = 'auto';\n \n if (this.isLoaded) {\n this.renderPage(this.currentPage);\n }\n\n // Emit scale change event\n const eventBus = this.getApp()?.events;\n if (eventBus && oldScale !== this.scale) {\n eventBus.emit('pdfviewer:scale-changed', { \n viewer: this, \n oldScale, \n newScale: this.scale \n });\n }\n }\n\n setFitMode(mode) {\n const oldMode = this.fitMode;\n this.fitMode = mode;\n this.applyFitMode();\n\n // Emit fit mode change event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:fit-mode-changed', { \n viewer: this, \n oldMode, \n newMode: mode \n });\n }\n }\n\n applyFitMode() {\n if (!this.isLoaded || !this.pdfDoc || !this.canvasContainer) {\n return;\n }\n\n this.pdfDoc.getPage(this.currentPage).then(page => {\n const containerRect = this.canvasContainer.getBoundingClientRect();\n const viewport = page.getViewport({ scale: 1 });\n\n let newScale;\n if (this.fitMode === 'page') {\n const scaleX = (containerRect.width - 40) / viewport.width;\n const scaleY = (containerRect.height - 40) / viewport.height;\n newScale = Math.min(scaleX, scaleY);\n } else if (this.fitMode === 'width') {\n newScale = (containerRect.width - 40) / viewport.width;\n } else {\n return; // auto mode, don't change scale\n }\n\n this.scale = Math.max(this.minScale, Math.min(this.maxScale, newScale));\n this.renderPage(this.currentPage);\n });\n }\n\n // Event Handlers\n handleKeyDown(e) {\n // Only handle if PDF viewer is focused or no input is focused\n if (e.target.tagName === 'INPUT' && e.target !== this.pageInput) {\n return;\n }\n\n switch (e.key) {\n case 'ArrowLeft':\n case 'PageUp':\n e.preventDefault();\n this.goToPage(this.currentPage - 1);\n break;\n case 'ArrowRight':\n case 'PageDown':\n e.preventDefault();\n this.goToPage(this.currentPage + 1);\n break;\n case 'Home':\n e.preventDefault();\n this.goToPage(1);\n break;\n case 'End':\n e.preventDefault();\n this.goToPage(this.totalPages);\n break;\n case '+':\n case '=':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setScale(this.scale + this.scaleStep);\n }\n break;\n case '-':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setScale(this.scale - this.scaleStep);\n }\n break;\n case '0':\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n this.setFitMode('page');\n }\n break;\n }\n }\n\n // UI Updates\n updatePageControls() {\n // Update page input\n if (this.pageInput) {\n this.pageInput.value = this.currentPage;\n }\n\n // Update page total display\n const pageTotalElement = this.element.querySelector('.page-total');\n if (pageTotalElement) {\n pageTotalElement.textContent = `/ ${this.totalPages}`;\n }\n\n // Update navigation buttons\n const firstBtn = this.element.querySelector('[data-action=\"first-page\"]');\n const prevBtn = this.element.querySelector('[data-action=\"prev-page\"]');\n const nextBtn = this.element.querySelector('[data-action=\"next-page\"]');\n const lastBtn = this.element.querySelector('[data-action=\"last-page\"]');\n\n if (firstBtn) firstBtn.disabled = this.currentPage <= 1;\n if (prevBtn) prevBtn.disabled = this.currentPage <= 1;\n if (nextBtn) nextBtn.disabled = this.currentPage >= this.totalPages;\n if (lastBtn) lastBtn.disabled = this.currentPage >= this.totalPages;\n\n // Update zoom buttons\n const zoomInBtn = this.element.querySelector('[data-action=\"zoom-in\"]');\n const zoomOutBtn = this.element.querySelector('[data-action=\"zoom-out\"]');\n\n if (zoomInBtn) zoomInBtn.disabled = this.scale >= this.maxScale;\n if (zoomOutBtn) zoomOutBtn.disabled = this.scale <= this.minScale;\n }\n\n updateStatus() {\n if (!this.statusElement) return;\n\n const currentPageElement = this.statusElement.querySelector('.current-page');\n const totalPagesElement = this.statusElement.querySelector('.total-pages');\n const zoomLevelElement = this.statusElement.querySelector('.zoom-level');\n\n if (currentPageElement) {\n currentPageElement.textContent = this.currentPage;\n }\n if (totalPagesElement) {\n totalPagesElement.textContent = this.totalPages;\n }\n if (zoomLevelElement) {\n zoomLevelElement.textContent = `${Math.round(this.scale * 100)}%`;\n }\n }\n\n // Utility Methods\n showLoading() {\n if (this.overlayElement) {\n this.overlayElement.style.display = 'flex';\n }\n }\n\n hideLoading() {\n if (this.overlayElement) {\n this.overlayElement.style.display = 'none';\n }\n }\n\n showError(message) {\n this.hideLoading();\n \n if (this.errorElement) {\n const errorMessageElement = this.errorElement.querySelector('.error-message');\n if (errorMessageElement) {\n errorMessageElement.textContent = message;\n }\n this.errorElement.style.display = 'block';\n }\n\n console.error('PDF Viewer Error:', message);\n }\n\n downloadPDF() {\n if (!this.pdfUrl) return;\n\n const link = document.createElement('a');\n link.href = this.pdfUrl;\n link.download = this.title + '.pdf';\n link.target = '_blank';\n link.click();\n }\n\n // Public API\n setPDF(pdfUrl, title = '') {\n const oldPdfUrl = this.pdfUrl;\n this.pdfUrl = pdfUrl;\n this.title = title || 'PDF Document';\n this.isLoaded = false;\n this.element.classList.remove('loaded');\n \n if (this.pdfDoc) {\n this.pdfDoc.destroy();\n this.pdfDoc = null;\n }\n \n this.currentPage = 1;\n this.totalPages = 0;\n this.scale = 1.0;\n \n if (pdfUrl) {\n this.loadPDF();\n }\n\n // Emit PDF changed event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:pdf-changed', { \n viewer: this, \n oldPdfUrl, \n newPdfUrl: pdfUrl \n });\n }\n }\n\n getCurrentPage() {\n return this.currentPage;\n }\n\n getTotalPages() {\n return this.totalPages;\n }\n\n getCurrentScale() {\n return this.scale;\n }\n\n async onBeforeDestroy() {\n // Clean up PDF.js resources\n if (this.pdfDoc) {\n this.pdfDoc.destroy();\n this.pdfDoc = null;\n }\n\n this.pageRendering = false;\n this.pageNumPending = null;\n\n // Clean up essential event listeners\n if (this._essentialListeners) {\n this._essentialListeners.forEach(({ el, type, fn }) => {\n if (el) el.removeEventListener(type, fn);\n });\n this._essentialListeners = null;\n }\n\n // Clean up resize observer\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n this._resizeObserver = null;\n }\n\n // Emit destroy event\n const eventBus = this.getApp()?.events;\n if (eventBus) {\n eventBus.emit('pdfviewer:destroyed', { viewer: this });\n }\n }\n\n // Static method to show PDF in a fullscreen dialog\n static async showDialog(pdfUrl, options = {}) {\n const {\n title = 'PDF Viewer',\n size = 'fullscreen',\n showControls = true,\n allowZoom = true,\n allowNavigation = true,\n showPageNumbers = true,\n ...dialogOptions\n } = options;\n\n const viewer = new PDFViewer({\n pdfUrl,\n title,\n showControls,\n allowZoom,\n allowNavigation,\n showPageNumbers\n });\n\n const dialog = new Dialog({\n title,\n body: viewer,\n size,\n centered: true,\n backdrop: 'static',\n keyboard: true,\n buttons: [\n { \n text: 'Download', \n action: 'download', \n class: 'btn btn-outline-primary' \n },\n { \n text: 'Close', \n action: 'close', \n class: 'btn btn-secondary',\n dismiss: true\n }\n ],\n ...dialogOptions\n });\n\n // Render and mount\n await dialog.render();\n document.body.appendChild(dialog.element);\n await dialog.mount();\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n dialog.on('hidden', () => {\n dialog.destroy();\n resolve(viewer);\n });\n\n dialog.on('action:download', () => {\n viewer.downloadPDF();\n });\n\n dialog.on('action:close', () => {\n dialog.hide();\n });\n });\n }\n}"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const t=new class{constructor(){this.formatters=/* @__PURE__ */new Map,this.registerBuiltInFormatters()}escapeHtml(t){if(null==t)return"";const e={"&":"&","<":"<",">":">",'"':""","'":"'"};return String(t).replace(/[&<>"']/g,t=>e[t])}registerBuiltInFormatters(){this.register("date",this.date.bind(this)),this.register("time",this.time.bind(this)),this.register("datetime",this.datetime.bind(this)),this.register("datetime_tz",this.datetime_tz.bind(this)),this.register("datatime_tz",this.datetime_tz.bind(this)),this.register("date_range",this.date_range.bind(this)),this.register("datetime_range",this.datetime_range.bind(this)),this.register("relative",this.relative.bind(this)),this.register("fromNow",this.relative.bind(this)),this.register("relative_short",this.relative_short.bind(this)),this.register("iso",this.iso.bind(this)),this.register("epoch",t=>{if(null==t||""===t)return t;const e=parseFloat(t);return isNaN(e)?t:1e3*e}),this.register("number",this.number.bind(this)),this.register("currency",this.currency.bind(this)),this.register("percent",this.percent.bind(this)),this.register("filesize",this.filesize.bind(this)),this.register("ordinal",this.ordinal.bind(this)),this.register("compact",this.compact.bind(this)),this.register("uppercase",t=>String(t).toUpperCase()),this.register("lowercase",t=>String(t).toLowerCase()),this.register("upper",t=>String(t).toUpperCase()),this.register("lower",t=>String(t).toLowerCase()),this.register("capitalize",this.capitalize.bind(this)),this.register("caps",this.capitalize.bind(this)),this.register("truncate",this.truncate.bind(this)),this.register("truncate_middle",this.truncate_middle.bind(this)),this.register("slug",this.slug.bind(this)),this.register("initials",this.initials.bind(this)),this.register("mask",this.mask.bind(this)),this.register("hex",this.hex.bind(this)),this.register("tohex",this.hex.bind(this)),this.register("unhex",this.unhex.bind(this)),this.register("fromhex",this.unhex.bind(this)),this.register("email",this.email.bind(this)),this.register("phone",this.phone.bind(this)),this.register("url",this.url.bind(this)),this.register("badge",this.badge.bind(this)),this.register("badgeClass",this.badgeClass.bind(this)),this.register("status",this.status.bind(this)),this.register("status_text",this.status_text.bind(this)),this.register("status_icon",this.status_icon.bind(this)),this.register("boolean",this.boolean.bind(this)),this.register("bool",this.boolean.bind(this)),this.register("yesno",t=>this.boolean(t,"Yes","No")),this.register("yesnoicon",this.yesnoicon.bind(this)),this.register("icon",this.icon.bind(this)),this.register("avatar",this.avatar.bind(this)),this.register("image",this.image.bind(this)),this.register("tooltip",this.tooltip.bind(this)),this.register("linkify",this.linkify.bind(this)),this.register("clipboard",this.clipboard.bind(this)),this.register("default",this.default.bind(this)),this.register("equals",this.equals.bind(this)),this.register("json",this.json.bind(this)),this.register("raw",t=>t),this.register("custom",(t,e)=>"function"==typeof e?e(t):t),this.register("iter",this.iter.bind(this)),this.register("keys",t=>t&&"object"==typeof t&&!Array.isArray(t)?Object.keys(t):null),this.register("values",t=>t&&"object"==typeof t&&!Array.isArray(t)?Object.values(t):null),this.register("plural",this.plural.bind(this)),this.register("list",this.formatList.bind(this)),this.register("duration",this.duration.bind(this)),this.register("hash",this.hash.bind(this)),this.register("stripHtml",this.stripHtml.bind(this)),this.register("highlight",this.highlight.bind(this)),this.register("nl2br",this.nl2br.bind(this)),this.register("code",this.code.bind(this)),this.register("pre",t=>`<pre class="bg-light p-2 rounded border">${this.escapeHtml(String(t))}</pre>`)}relative_short(t){return this.relative(t,!0)}linkify(t,e={}){if(null==t)return"";const r=String(t),s=this.escapeHtml(r),n={urls:!0,emails:!0,target:"_blank",rel:"noopener noreferrer"},i=e&&"object"==typeof e?{...n,...e}:n;let a=s;if(!1!==i.urls){const t=/(^|\s)((?:https?:\/\/|www\.)[^\s<]+)/gi;a=a.replace(t,(t,e,r)=>`${e}<a href="${r.startsWith("www.")?`https://${r}`:r}" target="${i.target}" rel="${i.rel}">${r}</a>`)}if(!1!==i.emails){const t=/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;a=a.replace(t,t=>`<a href="mailto:${t}">${t}</a>`)}return a}clipboard(t,e="text"){if(null==t)return"";const r=String(t),s=this.escapeHtml(r);return`\n <span class="mojo-clipboard d-inline-flex align-items-center">\n ${"icon-only"!==e?`<span class="font-monospace">${s}</span>`:""}\n ${`\n <button type="button"\n class="btn btn-sm btn-outline-secondary ms-1 p-0 border-0 bg-transparent"\n title="Copy"\n data-bs-toggle="tooltip"\n data-action="copy-to-clipboard"\n data-clipboard="${s}">\n <i class="bi bi-clipboard"></i>\n </button>`.trim()}\n </span>\n `}nl2br(t){return null==t?"":this.escapeHtml(String(t)).replace(/\r\n|\r|\n/g,"<br>")}code(t,e=""){return null==t?"":`<pre class="bg-light p-2 rounded border"><code class="${e?`language-${this.escapeHtml(String(e))}`:""}">${this.escapeHtml(String(t))}</code></pre>`}register(t,e){if("function"!=typeof e)throw new Error("Formatter must be a function, got "+typeof e);return this.formatters.set(t.toLowerCase(),e),this}apply(t,e,...r){try{const s=this.formatters.get(t.toLowerCase());return s?s(e,...r):(console.warn(`Formatter '${t}' not found`),e)}catch(s){return console.error(`Error in formatter '${t}':`,s),e}}pipe(t,e,r=null){return e?this.parsePipeString(e,r).reduce((t,e)=>this.apply(e.name,t,...e.args),t):t}parsePipeString(t,e=null){const r=[],s=t.split("|").map(t=>t.trim());for(const n of s){const t=this.parseFormatter(n,e);t&&r.push(t)}return r}parseFormatter(t,e=null){const r=t.match(/^([a-zA-Z_]\w*)\s*\((.*)\)$/);if(r){const[,t,s]=r;return{name:t,args:s?this.parseArguments(s,e):[]}}const s=t.match(/^([a-zA-Z_]\w*)(?::(.+))?$/);if(s){const[,t,r]=s;return{name:t,args:r?this.parseColonArguments(r,e):[]}}return null}parseArguments(t,e=null){const r=[];let s="",n=!1,i=null,a=0;for(let o=0;o<t.length;o++){const l=t[o];n||'"'!==l&&"'"!==l?n&&l===i&&"\\"!==t[o-1]?(n=!1,i=null,s+=l):n||"{"!==l?n||"}"!==l?n||0!==a||","!==l?s+=l:(r.push(this.parseValue(s.trim(),e)),s=""):(a--,s+=l):(a++,s+=l):(n=!0,i=l,s+=l)}return s.trim()&&r.push(this.parseValue(s.trim(),e)),r}parseColonArguments(t,e=null){const r=[];let s="",n=!1,i=null;for(let a=0;a<t.length;a++){const o=t[a];n||'"'!==o&&"'"!==o?n&&o===i&&"\\"!==t[a-1]?(n=!1,i=null,s+=o):n||":"!==o?s+=o:(r.push(this.parseValue(s.trim(),e)),s=""):(n=!0,i=o,s+=o)}return s.trim()&&r.push(this.parseValue(s.trim(),e)),r}parseValue(t,e=null){if(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))return t.slice(1,-1);if("true"===t)return!0;if("false"===t)return!1;if("null"===t)return null;if("undefined"!==t){if(!isNaN(t)&&""!==t)return Number(t);if(t.startsWith("{")&&t.endsWith("}"))try{return JSON.parse(t)}catch(r){}if(e&&this.isIdentifier(t)){if(!t.includes(".")&&Object.prototype.hasOwnProperty.call(e,t))return e[t];if(e.get&&"function"==typeof e.get){const r=e.get(t);if(void 0!==r)return r}if(e.getContextValue&&"function"==typeof e.getContextValue){const r=e.getContextValue(t);if(void 0!==r)return r}if(t.includes(".")){const r=window.MOJOUtils||("undefined"!=typeof require?require("./MOJOUtils.js").default:null);if(r){const s=r.getNestedValue(e,t);if(void 0!==s)return s}}}return t}}isIdentifier(t){return/^[a-zA-Z_$][a-zA-Z0-9_$]*(\.[a-zA-Z_$][a-zA-Z0-9_$]*)*$/.test(t)}date(t,e="MM/DD/YYYY"){if(!t)return"";let r;if((t=this.normalizeEpoch(t))instanceof Date)r=t;else if("string"==typeof t)if(/^\d{4}-\d{2}-\d{2}$/.test(t)){const[e,s,n]=t.split("-").map(Number);r=new Date(e,s-1,n)}else r=new Date(t);else r=new Date(t);if(isNaN(r.getTime()))return String(t);const s={YYYY:r.getFullYear(),YY:String(r.getFullYear()).slice(-2),MMMM:r.toLocaleDateString("en-US",{month:"long"}),MMM:r.toLocaleDateString("en-US",{month:"short"}),MM:String(r.getMonth()+1).padStart(2,"0"),M:r.getMonth()+1,dddd:r.toLocaleDateString("en-US",{weekday:"long"}),ddd:r.toLocaleDateString("en-US",{weekday:"short"}),DD:String(r.getDate()).padStart(2,"0"),D:r.getDate()};let n=e;const i=new RegExp(`(${Object.keys(s).join("|")})`,"g");return n=n.replace(i,t=>s[t]||t),n}time(t,e="HH:mm:ss"){if(!t)return"";const r=(t=this.normalizeEpoch(t))instanceof Date?t:new Date(t);if(isNaN(r.getTime()))return String(t);const s=r.getHours(),n={HH:String(s).padStart(2,"0"),H:s,hh:String(s%12||12).padStart(2,"0"),h:s%12||12,mm:String(r.getMinutes()).padStart(2,"0"),m:r.getMinutes(),ss:String(r.getSeconds()).padStart(2,"0"),s:r.getSeconds(),A:s>=12?"PM":"AM",a:s>=12?"pm":"am"};let i=e;const a=Object.keys(n).sort((t,e)=>e.length-t.length);for(const o of a)i=i.replace(new RegExp(o,"g"),n[o]);return i}datetime(t,e="MM/DD/YYYY",r="HH:mm:ss"){t=this.normalizeEpoch(t);const s=this.date(t,e),n=this.time(t,r);return s&&n?`${s} ${n}`:""}datetime_tz(t,e="MM/DD/YYYY",r="HH:mm:ss",s={}){if(!t)return"";const n=(t=this.normalizeEpoch(t))instanceof Date?t:new Date(t);if(isNaN(n.getTime()))return String(t);const i=s&&s.locale||"en-US",a=s&&s.timeZone?s.timeZone:void 0,o=()=>{let t="";try{const r=new Intl.DateTimeFormat(i,{hour:"2-digit",minute:"2-digit",timeZoneName:"short",...a?{timeZone:a}:{}}).formatToParts(n).find(t=>"timeZoneName"===t.type);if(t=r?r.value:"",t&&/^GMT[+-]/i.test(t))try{const e=new Intl.DateTimeFormat(i,{timeStyle:"short",timeZoneName:"short",...a?{timeZone:a}:{}}).formatToParts(n).find(t=>"timeZoneName"===t.type);e&&e.value&&!/^GMT[+-]/i.test(e.value)&&(t=e.value)}catch(e){}if(t&&/\s/.test(t)){const e=t.split(/\s+/).map(t=>t[0]).join("").toUpperCase();e.length>=2&&e.length<=4&&(t=e)}}catch(e){t=""}return t};if(!a){const t=this.date(n,e),s=this.time(n,r),i=o();return t&&s?`${t} ${s} ${i}`.trim():""}const l=new Intl.DateTimeFormat(i,{timeZone:a,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}).formatToParts(n),h=t=>{const e=l.find(e=>e.type===t);return e?e.value:""},c=h("year"),u=h("month"),d=h("day"),p=h("hour"),g=h("minute"),f=h("second"),m=u?String(parseInt(u,10)):"",w=d?String(parseInt(d,10)):"",b=p?String(parseInt(p,10)):"",y=p?parseInt(p,10)%12||12:"",v=p?parseInt(p,10)>=12?"PM":"AM":"",$=v?v.toLowerCase():"",C=new Intl.DateTimeFormat(i,{timeZone:a,month:"long"}).format(n),S=new Intl.DateTimeFormat(i,{timeZone:a,month:"short"}).format(n),x=new Intl.DateTimeFormat(i,{timeZone:a,weekday:"long"}).format(n),T=new Intl.DateTimeFormat(i,{timeZone:a,weekday:"short"}).format(n),A={YYYY:c,YY:c?c.slice(-2):"",MMMM:C,MMM:S,MM:u,M:m,dddd:x,ddd:T,DD:d,D:w},_={HH:p,H:b,hh:""!==y?String(y).padStart(2,"0"):"",h:""!==y?String(y):"",mm:g,m:g?String(parseInt(g,10)):"",ss:f,s:f?String(parseInt(f,10)):"",A:v,a:$},M=(t,e)=>{if(!t)return"";const r=new RegExp(`(${Object.keys(e).sort((t,e)=>e.length-t.length).join("|")})`,"g");return t.replace(r,t=>e[t]??t)},D=M(e,A),E=M(r,_),k=o();return D&&E?`${D} ${E} ${k}`.trim():""}normalizeEpoch(t){if("number"!=typeof t&&(t=Number(t)),isNaN(t))return"";if(t<1e11)return 1e3*t;if(t>1e12&&t<1e13)return t;throw new Error("Value doesn't look like epoch seconds or ms")}date_range(t,e=null,r="MM/DD/YYYY"){if(!t)return"";const s=e||/* @__PURE__ */new Date,n=this.date(t,r),i=this.date(s,r);return n&&i?`${n} - ${i}`:""}datetime_range(t,e=null,r="MM/DD/YYYY",s="HH:mm"){if(!t)return"";const n=e||/* @__PURE__ */new Date,i=this.datetime(t,r,s),a=this.datetime(n,r,s);return i&&a?`${i} - ${a}`:""}relative(t,e=!1){if(!t)return"";const r=(t=this.normalizeEpoch(t))instanceof Date?t:new Date(t);if(isNaN(r.getTime()))return String(t);const s=/* @__PURE__ */new Date-r,n=Math.floor(s/1e3),i=Math.floor(n/60),a=Math.floor(i/60),o=Math.floor(a/24);if(e)return o>365?Math.floor(o/365)+"y":o>30?Math.floor(o/30)+"mo":o>7?Math.floor(o/7)+"w":o>0?o+"d":a>0?a+"h":i>0?i+"m":"now";if(o>365){const t=Math.floor(o/365);return t+" year"+(t>1?"s":"")+" ago"}if(o>30){const t=Math.floor(o/30);return t+" month"+(t>1?"s":"")+" ago"}if(o>7){const t=Math.floor(o/7);return t+" week"+(t>1?"s":"")+" ago"}return 1===o?"yesterday":o>0?o+" days ago":a>0?a+" hour"+(a>1?"s":"")+" ago":i>0?i+" minute"+(i>1?"s":"")+" ago":n>30?n+" seconds ago":"just now"}iso(t,e=!1){if(!t)return"";const r=(t=this.normalizeEpoch(t))instanceof Date?t:new Date(t);return isNaN(r.getTime())?String(t):e?r.toISOString().split("T")[0]:r.toISOString()}number(t,e=2,r="en-US"){const s=parseFloat(t);return isNaN(s)?String(t):s.toLocaleString(r,{minimumFractionDigits:e,maximumFractionDigits:e})}currency(t,e="$",r=2){const s=parseInt(t);if(isNaN(s))return String(t);const n=Math.abs(s).toString(),i=s<0?"-":"";let a,o,l;return n.length<=2?(a="0",o=n.padStart(2,"0")):(a=n.slice(0,-2),o=n.slice(-2)),a=a.replace(/\B(?=(\d{3})+(?!\d))/g,","),0===r?(parseInt(o)>=50&&(a=(parseInt(a.replace(/,/g,""))+1).toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")),l=a):l=2===r?`${a}.${o}`:`${a}.${o.slice(0,r).padEnd(r,"0")}`,i+e+l}percent(t,e=0,r=!0){const s=parseFloat(t);if(isNaN(s))return String(t);const n=r?100*s:s;return this.number(n,e)+"%"}filesize(t,e=!1,r=1){const s=parseInt(t);if(isNaN(s))return String(t);const n=e?["B","KiB","MiB","GiB","TiB"]:["B","KB","MB","GB","TB"],i=e?1024:1e3;let a=s,o=0;for(;a>=i&&o<n.length-1;)a/=i,o++;const l=0===o?0:r;return`${a.toFixed(l)} ${n[o]}`}ordinal(t,e=!1){const r=parseInt(t);if(isNaN(r))return String(t);const s=r%10,n=r%100;let i="th";return 1===s&&11!==n?i="st":2===s&&12!==n?i="nd":3===s&&13!==n&&(i="rd"),e?i:r+i}compact(t,e=1){const r=parseFloat(t);if(isNaN(r))return String(t);const s=Math.abs(r),n=r<0?"-":"";return s>=1e9?n+(s/1e9).toFixed(e)+"B":s>=1e6?n+(s/1e6).toFixed(e)+"M":s>=1e3?n+(s/1e3).toFixed(e)+"K":String(r)}capitalize(t,e=!0){const r=String(t);return r?e?r.replace(/\b\w/g,t=>t.toUpperCase()):r.charAt(0).toUpperCase()+r.slice(1):""}truncate(t,e=50,r="..."){const s=String(t);return s.length<=e?s:s.substring(0,e)+r}truncate_middle(t,e=8,r="***"){const s=String(t);if(s.length<=e)return s;const n=Math.floor(e/2);return`${s.substring(0,n)}${r}${s.substring(s.length-n)}`}slug(t,e="-"){return String(t).toLowerCase().replace(/[^\w\s-]/g,"").replace(/\s+/g,e).replace(new RegExp(`${e}+`,"g"),e).replace(new RegExp(`^${e}|${e}$`,"g"),"")}initials(t,e=2){return String(t).split(/\s+/).filter(t=>t.length>0).slice(0,e).map(t=>t.charAt(0).toUpperCase()).join("")}mask(t,e="*",r=4){const s=String(t);return s.length<=r?s:e.repeat(Math.max(0,s.length-r))+s.slice(-r)}email(t,e={}){const r=String(t).trim();return r?!1===e.link?r:`<a href="mailto:${r}${e.subject?`?subject=${encodeURIComponent(e.subject)}`:""}${e.body?`&body=${encodeURIComponent(e.body)}`:""}"${e.class?` class="${e.class}"`:""}>${r}</a>`:""}phone(t,e="US",r=!0){let s=String(t).replace(/\D/g,""),n=s;return"US"===e&&(10===s.length?n=`(${s.slice(0,3)}) ${s.slice(3,6)}-${s.slice(6)}`:11===s.length&&"1"===s[0]&&(n=`+1 (${s.slice(1,4)}) ${s.slice(4,7)}-${s.slice(7)}`)),r?`<a href="tel:${s}">${n}</a>`:n}url(t,e=null,r=!0){let s=String(t).trim();return s?(/^https?:\/\//.test(s)||(s="https://"+s),`<a href="${s}"${r?' target="_blank"':""}${r?' rel="noopener noreferrer"':""}>${e||s}</a>`):""}badge(t,e="auto"){if(Array.isArray(t))return t.map(t=>this.badge(t,e)).join(" ");const r=String(t),s="auto"===e?this.inferBadgeType(r):e;return`<span class="badge ${s?`bg-${s}`:"bg-secondary"}">${r}</span>`}badgeClass(t,e="auto"){const r=String(t),s="auto"===e?this.inferBadgeType(r):e;return s?`bg-${s}`:"bg-secondary"}inferBadgeType(t){const e=t.toLowerCase();return["active","success","complete","completed","approved","done","true","on","yes"].includes(e)?"success":["error","failed","rejected","deleted","cancelled","false","off","no","declined"].includes(e)?"danger":["warning","pending","review","processing","uploading"].includes(e)?"warning":["info","new","draft"].includes(e)?"info":(["inactive","disabled","archived","suspended"].includes(e),"secondary")}status(t){return this._status(t)}status_icon(t){return this._status(t,{},{},!1,!0)}status_text(t){return this._status(t,{},{},!0,!1)}_status(t,e={},r={},s=!1,n=!1){const i=String(t).toLowerCase(),a=e[i]||{active:"bi bi-check-circle-fill",approved:"bi bi-check-circle-fill",declined:"bi bi-x-circle-fill",inactive:"bi bi-pause-circle-fill",pending:"bi bi-clock-fill",success:"bi bi-check-circle-fill",error:"bi bi-exclamation-triangle-fill",warning:"bi bi-exclamation-triangle-fill"}[i]||"";let o="";!s&&a&&(o=`<i class="${a}"></i>`);let l="";return n||(l=t),`<span class="text-${r[i]||{active:"success",approved:"success",declined:"danger",inactive:"secondary",pending:"warning",success:"success",error:"danger",warning:"warning"}[i]||"secondary"}">${o}${o?" ":""}${l}</span>`}boolean(t,e="True",r="False",s=!1){const n=t?e:r;return s?`<span class="text-${t?"success":"danger"}">${n}</span>`:n}icon(t,e={}){const r=e[String(t).toLowerCase()]||"";return r?`<i class="${r}"></i>`:""}yesnoicon(t,e="bi bi-check-circle-fill text-success",r="bi bi-x-circle-fill text-danger"){return t?`<i class="${e}"></i>`:`<i class="${r}"></i>`}image(t,e="thumbnail",r="img-fluid",s=""){const n=this._extractImageUrl(t,e);return n?`<img src="${n}" class="${r}" alt="${s}" />`:""}avatar(t,e="md",r="rounded-circle",s=""){const n=this._extractImageUrl(t,"square_sm")||"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2NlZDRkYSI+PHBhdGggZD0iTTEyIDEyYzIuMjEgMCA0LTEuNzkgNC00cy0xLjc5LTQtNC00LTQgMS43OS00IDQgMS43OSA0IDQgNHptMCAyYy0yLjY3IDAtOCAxLjM0LTggNHYyaDE2di0yYzAtMi42Ni01LjMzLTQtOC00eiIvPjwvc3ZnPg==",i={xs:"width: 1.5rem; height: 1.5rem;",sm:"width: 2rem; height: 2rem;",md:"width: 3rem; height: 3rem;",lg:"width: 4rem; height: 4rem;",xl:"width: 5rem; height: 5rem;"},a=i[e]||i.md;return`<img src="${n}" class="${`object-fit-cover ${r}`.trim()}" style="${a}" alt="${s}" />`}tooltip(t,e="",r="top",s=""){if(null==t)return"";const n=String(t);return`<span data-bs-toggle="tooltip" data-bs-placement="${r}" ${"html"===s?'data-bs-html="true"':""} data-bs-title="${"html"===s?e:this.escapeHtml(e)}">${n}</span>`}_extractImageUrl(t,e="thumbnail"){if(!t)return null;if("string"==typeof t)return t;if("object"==typeof t){if(t.attributes&&(t=t.attributes),"thumbnail"===e&&t.thumbnail&&"string"==typeof t.thumbnail)return t.thumbnail;if(t.renditions&&"object"==typeof t.renditions){const r=t.renditions[e];if(r&&r.url)return r.url;const s=Object.values(t.renditions);if(s.length>0&&s[0].url)return s[0].url}if(t.url)return t.url}return null}default(t,e=""){return null==t||""===t?e:t}equals(t,e,r,s=""){return t==e?r:s}plural(t,e,r=null,s=!0){if(null==t||null==e)return s?`${t} ${e}`:e||"";const n=parseInt(t);if(isNaN(n))return s?`${t} ${e}`:e||"";const i=1===Math.abs(n)?e:r||e+"s";return s?`${n} ${i}`:i}formatList(t,e={}){if(!Array.isArray(t))return String(t);const{conjunction:r="and",limit:s=null,moreText:n="others"}=e;if(0===t.length)return"";if(1===t.length)return String(t[0]);let i=t.slice(),a=!1;if(s&&t.length>s&&(i=t.slice(0,s),a=!0),a){const e=t.length-s;return`${i.join(", ")}, ${r} ${e} ${n}`}return 2===i.length?`${i[0]} ${r} ${i[1]}`:`${i.slice(0,-1).join(", ")}, ${r} ${i[i.length-1]}`}duration(t,e={}){const{short:r=!1,precision:s=2}=e;if(null==t)return"";const n=parseInt(t);if(isNaN(n))return String(t);const i=[{name:"day",short:"d",value:864e5},{name:"hour",short:"h",value:36e5},{name:"minute",short:"m",value:6e4},{name:"second",short:"s",value:1e3}];if(0===n)return r?"0s":"0 seconds";const a=Math.abs(n),o=n<0?"-":"",l=[];let h=a;for(const c of i)if(h>=c.value){const t=Math.floor(h/c.value);h%=c.value;const e=r?c.short:1===t?c.name:c.name+"s";if(l.push(r?`${t}${e}`:`${t} ${e}`),l.length>=s)break}return 0===l.length?r?`${Math.round(a)}ms`:`${Math.round(a)} milliseconds`:o+(r?l.join(""):l.join(" "))}hash(t,e=8,r="",s="..."){if(null==t)return"";const n=String(t);return n.length<=e?r+n:r+n.substring(0,e)+s}stripHtml(t){return null==t?"":String(t).replace(/<[^>]*>/g,"")}highlight(t,e,r="highlight"){if(null==t||!e)return String(t||"");const s=String(e).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`(${s})`,"gi");return String(t).replace(n,`<mark class="${r}">$1</mark>`)}hex(t,e=!1,r=!1){if(null==t)return"";let s="";const n=t=>Array.from(t).map(t=>t.toString(16).padStart(2,"0")).join("");if("number"==typeof t){let e=Math.abs(Math.trunc(t)).toString(16);e.length%2&&(e="0"+e),s=e}else s=t instanceof Uint8Array?n(t):t instanceof ArrayBuffer?n(new Uint8Array(t)):Array.isArray(t)&&t.every(t=>"number"==typeof t)?n(Uint8Array.from(t.map(t=>255&t))):n((new TextEncoder).encode(String(t)));return e&&(s=s.toUpperCase()),(r?"0x":"")+s}unhex(t){if(null==t)return"";let e=String(t).trim();if((e.startsWith("0x")||e.startsWith("0X"))&&(e=e.slice(2)),e=e.replace(/\s+/g,""),0===e.length)return"";e.length%2!=0&&(e="0"+e);const r=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2){const s=parseInt(e.slice(n,n+2),16);if(Number.isNaN(s))return String(t);r[n/2]=s}try{return(new TextDecoder).decode(r)}catch(s){let t="";for(const e of r)t+=String.fromCharCode(e);return t}}json(t,e=2){try{return JSON.stringify(t,null,e)}catch(r){return String(t)}}has(t){return this.formatters.has(t.toLowerCase())}unregister(t){return this.formatters.delete(t.toLowerCase())}listFormatters(){return Array.from(this.formatters.keys()).sort()}iter(t){return null==t?[]:Array.isArray(t)?t:"object"==typeof t?Object.entries(t).map(([t,e])=>({key:t,value:e})):[{key:"0",value:t}]}};window.dataFormatter=t;class MOJOUtils{static getContextData(e,r){if(!r||null==e)return;let s=r,n="",i=0,a=-1;for(let t=0;t<r.length;t++){const e=r[t];if("("===e)i++;else if(")"===e)i--;else if("|"===e&&0===i){a=t;break}}a>-1&&(s=r.substring(0,a).trim(),n=r.substring(a+1).trim());const o=this.getNestedValue(e,s);return n?t.pipe(o,n,e):o}static getNestedValue(t,e){if(!e||null==t)return;if(!e.includes(".")){if(e in t){const r=t[e];return"function"==typeof r?r.call(t):r}return}const r=e.split(".");let s=t;for(let n=0;n<r.length;n++){const e=r[n];if(null==s)return;if(0===n){if(!s.hasOwnProperty(e))return;{const r=s[e];s="function"==typeof r?r.call(t):r}}else{if(s&&"function"==typeof s.getContextValue){const t=r.slice(n).join(".");return s.getContextValue(t)}if(Array.isArray(s)&&!isNaN(e))s=s[parseInt(e)];else if(s.hasOwnProperty(e))s=s[e];else{if("function"!=typeof s[e])return;s=s[e].call(s)}}}return s}static isNullOrUndefined(t){return null==t}static deepClone(t){if(null===t||"object"!=typeof t)return t;if(t instanceof Date)return new Date(t.getTime());if(t instanceof Array)return t.map(t=>this.deepClone(t));if(t instanceof Object){const e={};for(const r in t)t.hasOwnProperty(r)&&(e[r]=this.deepClone(t[r]));return e}}static deepMerge(t,...e){if(!e.length)return t;const r=e.shift();if(this.isObject(t)&&this.isObject(r))for(const s in r)this.isObject(r[s])?(t[s]||Object.assign(t,{[s]:{}}),this.deepMerge(t[s],r[s])):Object.assign(t,{[s]:r[s]});return this.deepMerge(t,...e)}static isObject(t){return t&&"object"==typeof t&&!Array.isArray(t)}static debounce(t,e){let r;return function(...s){clearTimeout(r),r=setTimeout(()=>{clearTimeout(r),t(...s)},e)}}static throttle(t,e){let r;return function(...s){r||(t.apply(this,s),r=!0,setTimeout(()=>r=!1,e))}}static generateId(t=""){const e=Date.now().toString(36),r=Math.random().toString(36).substr(2,9);return t?`${t}_${e}_${r}`:`${e}_${r}`}static escapeHtml(t){const e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,t=>e[t])}static checkPasswordStrength(t){if(!t||"string"!=typeof t)return{score:0,strength:"invalid",feedback:["Password must be a non-empty string"],details:{length:0,hasLowercase:!1,hasUppercase:!1,hasNumbers:!1,hasSpecialChars:!1,hasCommonPatterns:!1,isCommonPassword:!1}};const e=[],r={length:t.length,hasLowercase:/[a-z]/.test(t),hasUppercase:/[A-Z]/.test(t),hasNumbers:/[0-9]/.test(t),hasSpecialChars:/[^a-zA-Z0-9]/.test(t),hasCommonPatterns:!1,isCommonPassword:!1};let s=0;t.length<6?e.push("Password should be at least 6 characters long"):t.length<8?(s+=1,e.push("Consider using at least 8 characters for better security")):t.length<12?s+=3:s+=4,r.hasLowercase?s+=1:e.push("Include lowercase letters"),r.hasUppercase?s+=1:e.push("Include uppercase letters"),r.hasNumbers?s+=1:e.push("Include numbers"),r.hasSpecialChars?s+=2:e.push("Include special characters (!@#$%^&* etc.)");const n=[/123/,/abc/i,/qwerty/i,/asdf/i,/(.)\1{2,}/,/password/i,/admin/i,/user/i,/login/i];for(const a of n)if(a.test(t)){r.hasCommonPatterns=!0,s-=1,e.push("Avoid common patterns and dictionary words");break}let i;return["123456","password","123456789","12345678","12345","1234567","1234567890","qwerty","abc123","111111","123123","admin","letmein","welcome","monkey","password123","123qwe","qwerty123","000000","dragon","sunshine","princess","azerty","1234","iloveyou","trustno1","superman","shadow","master","jennifer"].includes(t.toLowerCase())&&(r.isCommonPassword=!0,s=Math.max(0,s-3),e.push("This password is too common and easily guessed")),i=s<2?"very-weak":s<4?"weak":s<6?"fair":s<8?"good":"strong",s>=7&&0===e.length?e.push("Strong password! Consider using a password manager."):s>=5&&e.length<=1&&e.push("Good password strength. Consider adding more variety."),{score:Math.max(0,s),strength:i,feedback:e,details:r}}static generatePassword(t={}){const e={length:12,includeLowercase:!0,includeUppercase:!0,includeNumbers:!0,includeSpecialChars:!0,customChars:"",excludeAmbiguous:!1,...t};if(e.length<4)throw new Error("Password length must be at least 4 characters");let r="abcdefghijklmnopqrstuvwxyz",s="ABCDEFGHIJKLMNOPQRSTUVWXYZ",n="0123456789",i="!@#$%^&*()_+-=[]{}|;:,.<>?";e.excludeAmbiguous&&(r=r.replace(/[il]/g,""),s=s.replace(/[IOL]/g,""),n=n.replace(/[01]/g,""),i=i.replace(/[|]/g,""));let a="";const o=[];if(e.customChars?a=e.customChars:(e.includeLowercase&&(a+=r,o.push(r[Math.floor(Math.random()*r.length)])),e.includeUppercase&&(a+=s,o.push(s[Math.floor(Math.random()*s.length)])),e.includeNumbers&&(a+=n,o.push(n[Math.floor(Math.random()*n.length)])),e.includeSpecialChars&&(a+=i,o.push(i[Math.floor(Math.random()*i.length)]))),!a)throw new Error("No character types selected for password generation");let l="";for(const h of o)l+=h;for(let h=l.length;h<e.length;h++)l+=a[Math.floor(Math.random()*a.length)];return l.split("").sort(()=>Math.random()-.5).join("")}static parseQueryString(t){const e={},r=new URLSearchParams(t);for(const[s,n]of r.entries())e[s]=n;return e}static toQueryString(t){return new URLSearchParams(t).toString()}static wrapData(t,e=null,r=3){return t&&"object"==typeof t?t instanceof Date||t instanceof RegExp||t instanceof Error||r<=0||"function"==typeof t.getContextValue?t:Array.isArray(t)?t.map(t=>t&&"object"==typeof t&&!t.getContextValue?new DataWrapper(t,e):t):new DataWrapper(t,e):t}}class DataWrapper{constructor(t,e=null){if(Object.defineProperty(this,"_data",{value:t,writable:!1,enumerable:!1,configurable:!1}),Object.defineProperty(this,"_rootContext",{value:e,writable:!1,enumerable:!1,configurable:!1}),t&&"object"==typeof t)for(const r in t)if(t.hasOwnProperty(r)){const s=t[r];this[r]=MOJOUtils.wrapData(s,e)}}getContextValue(e){let r,s=e,n="",i=0,a=-1;for(let t=0;t<e.length;t++){const r=e[t];if("("===r)i++;else if(")"===r)i--;else if("|"===r&&0===i){a=t;break}}return a>-1&&(s=e.substring(0,a).trim(),n=e.substring(a+1).trim()),r=s in this&&"_data"!==s&&"_rootContext"!==s?this[s]:MOJOUtils.getNestedValue(this._data,s),n&&void 0!==r?t.pipe(r,n,this._rootContext||this._data):r}has(t){return this._data&&this._data.hasOwnProperty(t)}toJSON(){return this._data}}MOJOUtils.DataWrapper=DataWrapper,"undefined"!=typeof window&&(window.utils=MOJOUtils);const e=Object.prototype.toString,r=Array.isArray||function(t){return"[object Array]"===e.call(t)},s=function(t){return"function"==typeof t},n=function(t){return null!=t&&"object"==typeof t},i=function(t){const e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,function(t){return e[t]})};class Scanner{constructor(t){this.string=t,this.tail=t,this.pos=0}eos(){return""===this.tail}scan(t){const e=this.tail.match(t);if(!e||0!==e.index)return"";const r=e[0];return this.tail=this.tail.substring(r.length),this.pos+=r.length,r}scanUntil(t){const e=this.tail.search(t);let r;switch(e){case-1:r=this.tail,this.tail="";break;case 0:r="";break;default:r=this.tail.substring(0,e),this.tail=this.tail.substring(e)}return this.pos+=r.length,r}}class Context{constructor(t,e){this.view=t,this.cache={".":this.view},this.parent=e,this.view?._cacheId||this.view&&"object"==typeof this.view&&(this.view._cacheId=Math.random().toString(36).substring(2))}push(t){return new Context(t,this)}lookup(t){if(this.renderCache&&this.view?._cacheId){const e=`${this.view._cacheId}:${t}`;if(this.renderCache.has(e))return this.renderCache.get(e)}if("."===t)return this.view;if(t&&t.startsWith(".")){let e=t.substring(1),i=!1;if(e.endsWith("|iter")&&(e=e.substring(0,e.length-5),i=!0),this.view&&"object"==typeof this.view){let t;if("function"==typeof this.view.getContextValue)try{t=this.view.getContextValue(e),void 0!==t&&s(t)&&(t=t.call(this.view))}catch(l){t=void 0}return void 0===t&&e in this.view&&(t=this.view[e],s(t)&&(t=t.call(this.view))),r(t)?i?t:t.length>0:n(t)?i?Object.entries(t).map(([t,e])=>({key:t,value:e})):Object.keys(t).length>0:t}return}const e=this.cache;let i;if(e.hasOwnProperty(t))i=e[t];else{let r,s,n,h=this,c=!1;for(;h;){if(h.view&&"function"==typeof h.view.getContextValue)try{r=h.view.getContextValue(t),void 0!==r&&(c=!0)}catch(l){c=!1}if(!c)if(t.indexOf(".")>0)for(r=h.view,s=t.split("."),n=0;null!=r&&n<s.length;)if(r&&"function"==typeof r.getContextValue&&n<s.length)try{const t=s.slice(n).join(".");r=r.getContextValue(t),n=s.length,void 0!==r&&(c=!0)}catch(l){n===s.length-1&&(c=a(r,s[n])||o(r,s[n])),r=r[s[n++]]}else n===s.length-1&&(c=a(r,s[n])||o(r,s[n])),r=r[s[n++]];else r=h.view[t],c=a(h.view,t);if(c){i=r;break}h=h.parent}e[t]=i}if(s(i)&&(i=i.call(this.view)),this.renderCache&&this.view?._cacheId){const e=`${this.view._cacheId}:${t}`;this.renderCache.set(e,i)}return i}}function a(t,e){return null!=t&&"object"==typeof t&&e in t}function o(t,e){return null!=t&&"object"!=typeof t&&t.hasOwnProperty&&t.hasOwnProperty(e)}class Writer{constructor(){this.templateCache=/* @__PURE__ */new Map}clearCache(){this.templateCache.clear()}parse(t,e){const r=t+":"+(e=e||["{{","}}"]).join(":");let s=this.templateCache.get(r);return null==s&&(s=this.parseTemplate(t,e),this.templateCache.set(r,s)),s}parseTemplate(t,e){if(!t)return[];const r=e[0],s=e[1],n=new Scanner(t),i=[];let a,o,h,c,u;const d=new RegExp(l(r)+"\\s*"),p=new RegExp("\\s*"+l(s)),g=new RegExp("\\s*"+l("}"+s));for(;!n.eos();){if(a=n.pos,h=n.scanUntil(d),h)for(let t=0;t<h.length;++t)c=h.charAt(t),i.push(["text",c]);if(!n.scan(d))break;if(o=n.scan(/[#^\/>{&=!]/),o||(o="name"),n.scan(/\s*/),"="===o?(h=n.scanUntil(/\s*=/),n.scan(/\s*=/),n.scanUntil(p)):"{"===o?(h=n.scanUntil(g),n.scan(g),o="&"):h=n.scanUntil(p),n.scan(p),"#"===o||"^"===o)u=[o,h,a,n.pos],i.push(u);else if("/"===o){let t;for(let e=i.length-1;e>=0;--e)if(("#"===i[e][0]||"^"===i[e][0])&&i[e][1]===h){t=i[e];break}t&&4===t.length&&t.push(n.pos),i.push([o,h,a,n.pos])}else i.push([o,h,a,n.pos])}return this.nestSections(this.squashTokens(i))}squashTokens(t){const e=[];let r,s;for(let n=0;n<t.length;++n)r=t[n],r&&("text"===r[0]&&s&&"text"===s[0]?(s[1]+=r[1],s[3]=r[3]):(e.push(r),s=r));return e}nestSections(t){const e=[];let r=e;const s=[];for(let n=0;n<t.length;++n){const i=t[n];switch(i[0]){case"#":case"^":const t=[i[0],i[1],i[2],i[3],[],i[4]||null];r.push(t),s.push(t),r=t[4];break;case"/":const n=s.pop();n&&(n[5]=i[2],r=s.length>0?s[s.length-1][4]:e);break;default:r.push(i)}}return e}render(t,e,r,s){const n=this.getConfigTags(s)||["{{","}}"],i=this.parse(t,n),a=/* @__PURE__ */new Map;return this.renderTokens(i,new Context(e),r,t,s,a)}renderTokens(t,e,n,a,o,l){l&&!e.renderCache&&(e.renderCache=l);let h="";for(let c=0;c<t.length;++c){const u=t[c];let d;switch(u[0]){case"#":if(d=e.lookup(u[1]),!d)continue;const t=u[4];if(!t||!r(t)){console.warn(`MUSTACHE WARNING - Section ${u[1]} has no child tokens:`,u);continue}if(r(d))for(let r=0;r<d.length;++r){const s=e.push(d[r]);e.renderCache&&(s.renderCache=e.renderCache),h+=this.renderTokens(t,s,n,a,o,l)}else if("object"==typeof d||"string"==typeof d||"number"==typeof d){const r=e.push(d);e.renderCache&&(r.renderCache=e.renderCache),h+=this.renderTokens(t,r,n,a,o,l)}else if(s(d)){const t=null==a?null:a.slice(u[3],u[5]);d=d.call(e.view,t,t=>this.render(t,e.view,n,o)),null!=d&&(h+=d)}else d&&(h+=this.renderTokens(t,e,n,a,o,l));break;case"^":if(d=e.lookup(u[1]),!d||r(d)&&0===d.length){const t=u[4];t&&r(t)&&(h+=this.renderTokens(t,e,n,a,o,l))}break;case">":if(!n)continue;d=s(n)?n(u[1]):n[u[1]],null!=d&&(h+=this.render(d,e.view,n,o));break;case"&":d=e.lookup(u[1]),null!=d&&(h+=d);break;case"name":d=e.lookup(u[1]),null!=d&&(h+=i(d));break;case"text":h+=u[1]}}return h}getConfigTags(t){return n(t)&&r(t.tags)?t.tags:null}}function l(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}const h=new Writer,c={name:"MOJO Mustache",version:"1.0.0",tags:["{{","}}"],Scanner:Scanner,Context:Context,Writer:Writer,escape:i,clearCache:()=>h.clearCache(),parse:(t,e)=>h.parse(t,e),render(t,e,r,s){if("string"!=typeof t)throw new TypeError('Invalid template! Template should be a "string"');return e&&"object"==typeof e&&!e.getContextValue&&"function"!=typeof e.toJSON&&(e=MOJOUtils.wrapData(e)),h.render(t,e,r,s)}};class EventDelegate{constructor(t){this.view=t,this.domListeners=[],this.debounceTimers=/* @__PURE__ */new Map}bind(t){if(this.unbind(),!t)return;const e=async t=>{const e=t.target.closest("[data-action]");if(e&&this.shouldHandle(e,t)){const r=e.getAttribute("data-action");if(this.hideTooltip(e),await this.dispatch(r,t,e))return t.preventDefault(),t.stopPropagation(),void(t.handledByChild=!0)}const r=t.target.closest("a[href], [data-page]");if(r&&!r.hasAttribute("data-action")&&this.shouldHandle(r,t)){if(t.ctrlKey||t.metaKey||t.shiftKey||1===t.button)return;if("A"===r.tagName){const t=r.getAttribute("href");if(t&&"#"!==t&&!t.startsWith("#")&&(this.view.isExternalLink(t)||r.hasAttribute("data-external")))return}this.hideTooltip(r),t.preventDefault(),t.stopPropagation(),t.handledByChild=!0,r.hasAttribute("data-page")?await this.view.handlePageNavigation(r):await this.view.handleHrefNavigation(r)}},r=t=>{const e=t.target.closest("[data-change-action]");if(!e||!this.shouldHandle(e,t))return;const r=e.getAttribute("data-change-action");this.dispatchChange(r,t,e).then(e=>{e&&(t.stopPropagation(),t.handledByChild=!0)})},s=t=>{const e=t.target.closest("[data-change-action]");if(!e||!this.shouldHandle(e,t))return;if(!t.target.matches('[data-filter="live-search"]'))return;const r=e.getAttribute("data-change-action"),s=parseInt(e.getAttribute("data-filter-debounce"))||300,n=`${r}-${e.getAttribute("data-container")||"default"}`;this.debounceTimers.has(n)&&clearTimeout(this.debounceTimers.get(n));const i=setTimeout(()=>{this.debounceTimers.delete(n),this.dispatchChange(r,t,e).then(e=>{e&&(t.stopPropagation(),t.handledByChild=!0)})},s);this.debounceTimers.set(n,i)},n=t=>{if(t.target.matches('[data-filter="search"]'))return;const e=t.target.closest("[data-keydown-action]")||t.target.closest("[data-change-action]");if(!e||!this.shouldHandle(e,t))return;let r=["Enter"];if(e.getAttribute("data-change-keys")&&(r=e.getAttribute("data-change-keys").split(",").map(t=>t.trim())),r.includes("*")||r.includes(t.key)){const r=e.getAttribute("data-keydown-action")||e.getAttribute("data-change-action");this.dispatch(r,t,e).then(e=>{e&&(t.preventDefault(),t.stopPropagation(),t.handledByChild=!0)})}},i=t=>{const e=t.target.closest("form[data-action]");if(!e||!this.shouldHandle(e,t))return;t.preventDefault();const r=e.getAttribute("data-action");this.dispatch(r,t,e)};t.addEventListener("click",e),t.addEventListener("change",r),t.addEventListener("input",s),t.addEventListener("keydown",n),t.addEventListener("submit",i),this.domListeners.push({el:t,type:"click",fn:e},{el:t,type:"change",fn:r},{el:t,type:"input",fn:s},{el:t,type:"keydown",fn:n},{el:t,type:"submit",fn:i})}unbind(){for(const{el:t,type:e,fn:r}of this.domListeners)t.removeEventListener(e,r);this.domListeners=[];for(const t of this.debounceTimers.values())clearTimeout(t);this.debounceTimers.clear()}hideDropdown(t){const e=t.closest(".dropdown-menu").closest(".dropdown");if(!e)return;const r=e.querySelector('[data-bs-toggle="dropdown"]');if(r&&window.bootstrap?.Dropdown){const t=window.bootstrap.Dropdown.getInstance(r);t?.hide()}}hideTooltip(t){if(t&&window.bootstrap?.Tooltip){const e=window.bootstrap.Tooltip.getInstance(t);e&&e.dispose()}}hideAllTooltips(){window.bootstrap?.Tooltip&&document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(t=>{const e=window.bootstrap.Tooltip.getInstance(t);e&&e.hide()})}async dispatch(t,e,r){const s=this.view,n=t=>t.includes("-")?t.split("-").map(t=>t[0].toUpperCase()+t.slice(1)).join(""):t[0].toUpperCase()+t.slice(1),i=`handleAction${n(t)}`;if("function"==typeof s[i])try{return e.preventDefault(),await s[i](e,r),!0}catch(l){return console.error(`Error in action ${t}:`,l),s.handleActionError(t,l,e,r),!0}const a=`onAction${n(t)}`;if("function"==typeof s[a])try{return!!(await s[a](e,r))&&(!!r.closest(".dropdown-menu")&&this.hideDropdown(r),e.preventDefault(),e.stopPropagation(),!0)}catch(l){return console.error(`Error in action ${t}:`,l),s.handleActionError(t,l,e,r),!0}const o=`onPassThruAction${n(t)}`;if("function"==typeof s[o])try{return await s[o](e,r),!1}catch(l){return console.error(`Error in action ${t}:`,l),s.handleActionError(t,l,e,r),!0}if("function"==typeof s.onActionDefault)try{return await s.onActionDefault(t,e,r)}catch(l){return console.error(`Error in default action handler for ${t}:`,l),s.handleActionError(t,l,e,r),!0}return s.emit?.(`action:${t}`,{action:t,event:e,element:r}),!1}async dispatchChange(t,e,r){const s=this.view,n=`onChange${i=t,i.includes("-")?i.split("-").map(t=>t[0].toUpperCase()+t.slice(1)).join(""):i[0].toUpperCase()+i.slice(1)}`;var i;if("function"==typeof s[n])try{return await s[n](e,r),!0}catch(a){return console.error(`Error in onChange ${t}:`,a),s.handleActionError?.(t,a,e,r),!0}return await this.dispatch(t,e,r)}shouldHandle(t,e){return!!this.owns(t)||!(!this.contains(t)||e.handledByChild)}owns(t){const e=this.view.element;if(!e||!e.contains(t))return!1;for(const r of Object.values(this.view.children))if(r.element&&r.element.contains(t))return!1;return!0}contains(t){return!!this.view.element&&this.view.element.contains(t)}}const u={on(t,e,r){this._listeners||(this._listeners={}),this._listeners[t]||(this._listeners[t]=[]);const s={callback:e,context:r,fn:r?e.bind(r):e};return this._listeners[t].push(s),this},off(t,e,r){return this._listeners&&this._listeners[t]?(e?(this._listeners[t]=this._listeners[t].filter(t=>t.callback!==e||3===arguments.length&&t.context!==r),0===this._listeners[t].length&&delete this._listeners[t]):delete this._listeners[t],this):this},once(t,e,r){const s=(...n)=>{this.off(t,s),(r?e.bind(r):e).apply(r||this,n)};return this.on(t,s),this},emit(t,...e){if(!this._listeners||!this._listeners[t])return this;const r=this._listeners[t].slice();for(const n of r)try{n.fn.apply(n.context||this,e)}catch(s){console&&console.error&&console.error(`Error in ${t} event handler:`,s)}return this}};"undefined"!=typeof window&&(window.Mustache=c);class View{constructor(t={}){this.tagName=t.tagName??"div",this.className=t.className??"mojo-view",this.style=t.style??null,this.id=t.id??View._genId(),this.containerId=t.containerId??null,this.container=t.container??null,"string"==typeof this.container&&(this.containerId=this.container,this.container=null),this.parent=t.parent??null,this.children=t.children??{},this.template=t.template||t.templateUrl||"",this.data=t.data??{},this.isRendering=!1,this.lastRenderTime=0,this.mounted=!1,this.debug=t.debug??!1,this.app=t.app??null,this.cacheTemplate=t.cacheTemplate??!0,this.enableTooltips=t.enableTooltips??!1,this.options={...t},this.element=this._ensureElement(),this.events=new EventDelegate(this),t.model&&this.setModel(t.model)}async onInit(){}async onInitView(){this.initialized||(this.initialized=!0,await this.onInit())}async onBeforeRender(){}async onAfterRender(){}async onBeforeMount(){}async onAfterMount(){}async onBeforeUnmount(){}async onAfterUnmount(){}async onBeforeDestroy(){}async onAfterDestroy(){}setModel(t={}){let e=t!==this.model;if(!e)return this;this.model&&this.model.off&&this.model.off("change",this._onModelChange,this),this.model=t,this.model&&this.model.on&&this.model.on("change",this._onModelChange,this);for(const r in this.children){const e=this.children[r];e&&"function"==typeof e.setModel&&e.setModel(t)}return e&&this._onModelChange(),this}_onModelChange(){this.isMounted()&&this.render()}setTemplate(t){return this.template=t??"",this}addChild(t){try{if(!t||"object"!=typeof t)return this;t.parent=this,this.getApp()&&(t.app=this.app),this.children[t.id]=t}catch(e){View._warn("addChild error",e)}return t}removeChild(t){try{const e="string"==typeof t?t:t&&t.id;if(!e)return this;const r=this.children[e];r&&(Promise.resolve(r.destroy()).catch(t=>View._warn("removeChild destroy error",t)),delete this.children[e])}catch(e){View._warn("removeChild error",e)}return this}getChild(t){return this.children[t]}async updateData(t,e=!1){return Object.assign(this.data,t),e&&this.isMounted()&&await this.render(),this}toggleClass(t,e){return void 0===e&&(e=!this.element.classList.contains(t)),this.element.classList.toggle(t,e),this}addClass(t){return this.element.classList.add(t),this}setClass(t){return this.element.className=t,this}removeClass(t){return this.element.classList.remove(t),this}canRender(){if(this.isRendering)return!1;const t=Date.now();if(this.options.renderCooldown>0&&t-this.lastRenderTime<this.options.renderCooldown)return View._warn(`View ${this.id}: Render called too quickly, cooldown active`),!1;if(this.options.noAppend&&this.parent){if(!this.parent.contains(this.containerId||this.container))return!1;if(this.containerId&&!document.getElementById(this.containerId))return!1;if(this.container&&!document.contains(this.container))return!1}return!0}async render(t=!0,e=null){const r=Date.now();if(!this.canRender())return this;this.isRendering=!0,this.lastRenderTime=r;try{this.initialized||await this.onInitView(),this.unbindEvents(),await this.onBeforeRender(),this.getViewData&&(this.data=await this.getViewData());const r=await this.renderTemplate();this.element.innerHTML=r,t&&!this.isMounted()&&await this.mount(e),await this._renderChildren(),await this.onAfterRender(),this.bindEvents()}catch(s){View._warn(`Render error in ${this.id}`,s)}finally{this.isRendering=!1}return this}async _renderChildren(){for(const t in this.children){const e=this.children[t];e&&(e.parent=this,await Promise.resolve(e.render()).catch(e=>View._warn(`Child render error (${t})`,e)))}}async _unmountChildren(){for(const t in this.children){const e=this.children[t];e&&e.unbindEvents()}}isMounted(){return this.element?.isConnected}getChildElementById(t,e=null){const r=t.startsWith("#")?t.substring(1):t;return e?e.querySelector(`#${r}`):this.element.querySelector(`#${r}`)}getChildElement(t){if(t.startsWith("#"))return this.getChildElementById(t);let e=this.element?.querySelector(`[data-container="${t}"]`);return e||this.getChildElementById(t)}getContainer(){return this.replaceById?this.parent?this.parent.getChildElementById(this.id):null:this.containerId?this.parent?this.parent.getChildElement(this.containerId):this.getChildElementById(this.containerId,document.body):null}async mount(t=null){await this.onBeforeMount(),t||(t=this.getContainer()),!this.containerId||t?(t&&this.replaceById?t.replaceWith(this.element):t?t.replaceChildren(this.element):!this.containerId&&this.parent?this.parent.element.appendChild(this.element):this.containerId||this.parent||!this.options.allowAppendToBody?console.error(`Container not found for ${this.containerId}`):document.body.appendChild(this.element),await this.onAfterMount(),this.mounted=!0):console.error(`Container not found for ${this.containerId}`)}async unmount(){this.element&&this.element.parentNode&&(await this.onBeforeUnmount(),await this._unmountChildren(),this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.events.unbind(),await this.onAfterUnmount(),this.mounted=!1)}async destroy(){try{this.events.unbind();for(const t in this.children){const e=this.children[t];e&&await Promise.resolve(e.destroy()).catch(e=>View._warn(`Child destroy error (${t})`,e))}this.mounted=!1,this.element&&this.element.parentNode&&(await this.onBeforeDestroy(),this.element.parentNode&&this.element.parentNode.removeChild(this.element),await this.onAfterDestroy())}catch(t){View._warn(`Destroy error in ${this.id}`,t)}}_ensureElement(){try{if(this.element&&this.element.tagName?.toLowerCase()===this.tagName)return this._syncAttrs(),this.element;const t=document.createElement(this.tagName);return this.element=t,this.el=t,this._syncAttrs(),t}catch(t){View._warn("ensureElement error",t);const e=document.createElement("div");return e.id=this.id||View._genId(),e}}_syncAttrs(){try{if(!this.element)return;this.id&&(this.element.id=this.id),this.element.className=this.className||"",null==this.style?this.element.removeAttribute("style"):this.element.style.cssText=String(this.style)}catch(t){View._warn("_syncAttrs error",t)}}bindEvents(){this.events.bind(this.element),this.enableTooltips&&this.initializeTooltips()}unbindEvents(){this.events.unbind(),this.enableTooltips&&this.disposeTooltips()}async renderTemplate(){const t=await this.getTemplate();if(!t)return"";const e=this.getPartials();return c.render(t,this,e)}renderTemplateString(t,e,r){return c.render(t,e,r)}getPartials(){return{}}async getTemplate(){if(this._templateCache&&this.cacheTemplate)return this._templateCache;const t=this.template||this.templateUrl;if(!t)throw new Error("Template not found");let e="";if("string"==typeof t)if(t.includes("<")||t.includes("{"))e=t;else try{let r=t;this.app||(this.app=this.getApp()),!this.app||!this.app.basePath||r.startsWith("/")||r.startsWith("http://")||r.startsWith("https://")||(r=`${this.app.basePath.endsWith("/")?this.app.basePath.slice(0,-1):this.app.basePath}/${r}`);const s=await fetch(r);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);e=await s.text()}catch(r){View._warn(`Failed to load template from ${t}: ${r}`),this.showError?.(`Failed to load template from ${t}: ${r.message}`)}else"function"==typeof t&&(e=await this.template(this.data,this.state));return this.cacheTemplate&&e&&(this._templateCache=e),e}getContextValue(t){const e=MOJOUtils.getContextData(this,t);return t&&t.startsWith("data.")&&e&&"object"==typeof e?MOJOUtils.wrapData(e,this):t&&t.startsWith("model.")&&"model"!==t&&e&&"object"==typeof e&&"function"!=typeof e.getContextValue?MOJOUtils.wrapData(e,null):e}async handlePageNavigation(t){const e=t.getAttribute("data-page"),r=t.getAttribute("data-params");let s={};if(r)try{s=JSON.parse(r)}catch(a){console.warn("Invalid JSON in data-params:",r)}const n=this.getApp();if(n)return void n.showPage(e,s);const i=this.findRouter();i&&"function"==typeof i.navigateToPage?await i.navigateToPage(e,s):console.error(`No router found for page navigation to '${e}'`)}async handleHrefNavigation(t){const e=t.getAttribute("href");if(this.isExternalLink(e)||t.hasAttribute("data-external"))return;const r=this.findRouter();if(r){if(r.options&&"param"===r.options.mode&&e.startsWith("?")){const t="/"+e;return void(await r.navigate(t))}if(r.options&&"hash"===r.options.mode&&e.startsWith("#"))return void(await r.navigate(e));const t=this.hrefToRoutePath(e);await r.navigate(t)}else console.warn("No router found for navigation, using default behavior"),window.location.href=e}isExternalLink(t){return!t||(t.startsWith("/")&&this.getApp()?!t.startsWith(this.findRouter().basePath):t.startsWith("#")||t.startsWith("mailto:")||t.startsWith("tel:")||t.startsWith("http://")||t.startsWith("https://")||t.startsWith("//"))}hrefToRoutePath(t){if(t.startsWith("/")){const e=this.findRouter();if(e&&e.options&&e.options.base){const r=e.options.base;if(t.startsWith(r))return t.substring(r.length)||"/"}return t}return t.startsWith("./")?t.substring(2):t}findRouter(){return this.getApp(),this.app?.router||null}getApp(){if(this.app)return this.app;const t=[window.__app__,window.MOJO?.app,window.APP,window.app,window.WebApp,window.matchUUID?window[window.matchUUID]():window[window.matchUUID]];return this.app=t.find(t=>t&&"function"==typeof t.showPage)||null,this.app}handleActionError(t,e,r,s){this.showError(`Action '${t}' failed: ${e}`,r,s)}escapeHtml(t){if("string"!=typeof t)return t;const e=document.createElement("div");return e.textContent=t,e.innerHTML}contains(t){if("string"==typeof t){if(!this.element)return!1;t=document.getElementById(t)}return!!t&&this.element.contains(t)}initializeTooltips(){this.element&&window.bootstrap?.Tooltip&&(this.disposeTooltips(),[...this.element.querySelectorAll('[data-bs-toggle="tooltip"]')].map(t=>{const e=t.getAttribute("data-tooltip-theme"),r=t.getAttribute("data-tooltip-size");let s="";e&&(s+=`tooltip-${e} `),r&&(s+=`tooltip-${r}`);const n={},i=s.trim();return i&&(n.customClass=i),new window.bootstrap.Tooltip(t,n)}))}disposeTooltips(){this.element&&window.bootstrap?.Tooltip&&this.element.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(t=>{const e=window.bootstrap.Tooltip.getInstance(t);e&&e.dispose()})}async showError(t){console.error(`View ${this.id} error:`,t);const e=this.getApp?this.getApp():this.app||null;e&&"function"==typeof e.showError?await e.showError(t):alert(`Error: ${t}`)}async showSuccess(t){this.debug&&this.id;const e=this.getApp?this.getApp():this.app||null;e&&"function"==typeof e.showSuccess?await e.showSuccess(t):alert(`Success: ${t}`)}async showInfo(t){this.id;const e=this.getApp?this.getApp():this.app||null;e&&"function"==typeof e.showInfo?await e.showInfo(t):alert(`Info: ${t}`)}async showWarning(t){console.warn(`View ${this.id} warning:`,t);const e=this.getApp?this.getApp():this.app||null;e&&"function"==typeof e.showWarning?await e.showWarning(t):alert(`Warning: ${t}`)}async onActionCopyToClipboard(t,e){try{const t=e?.closest("[data-clipboard]")||e,r=t?.getAttribute("data-clipboard")||"";if(!r)return!0;if(navigator.clipboard&&window.isSecureContext)await navigator.clipboard.writeText(r);else{const t=document.createElement("textarea");t.value=r,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}const s=e.querySelector("i"),n=s&&s.className;return s&&(s.className="bi bi-check",setTimeout(()=>{s.className=n},1e3)),!0}catch(r){return console.warn("Copy to clipboard failed:",r),!0}}static _genId(){return`view_${Math.random().toString(36).substr(2,9)}`}static _warn(t,e){try{e?console.warn(`[View] ${t}:`,e):console.warn(`[View] ${t}`)}catch{}}}Object.assign(View.prototype,u);const d=new class{constructor(){this.config={baseURL:"",timeout:3e4,headers:{"Content-Type":"application/json",Accept:"application/json"},trackDevice:!0,duidHeader:"X-Mojo-UID",duidTransport:"header"},this.interceptors={request:[],response:[]},this.duid=null,this.config.trackDevice&&this._initializeDuid()}_initializeDuid(){const t="mojo_device_uid";try{let e=localStorage.getItem(t);e?this.duid=e:(this.duid=this._generateDuid(),localStorage.setItem(t,this.duid))}catch(e){console.error("Could not access localStorage to get/set DUID.",e),this.duid=this._generateDuid()}}_generateDuid(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}configure(t){t.baseUrl&&(t.baseURL=t.baseUrl);const e=this.config.trackDevice;this.config={...this.config,...t,headers:{...this.config.headers,...t.headers}},this.config.trackDevice&&!e&&this._initializeDuid()}addInterceptor(t,e){this.interceptors[t]&&this.interceptors[t].push(e)}buildUrl(t){return t.startsWith("http://")||t.startsWith("https://")?t:`${this.config.baseURL.endsWith("/")?this.config.baseURL.slice(0,-1):this.config.baseURL}${t.startsWith("/")?t:`/${t}`}`}categorizeError(t,e=0){if("TypeError"===t.name&&t.message.includes("fetch"))return{reason:"not_reachable",message:"Service is not reachable - please check your connection"};if("AbortError"===t.name)return{reason:"cancelled",message:"Request was cancelled"};if("TimeoutError"===t.name||t.message.includes("timeout"))return{reason:"timed_out",message:"Request timed out - please try again"};if(e>=400){if(400===e)return{reason:"bad_request",message:"Invalid request data"};if(401===e)return{reason:"unauthorized",message:"Authentication required"};if(403===e)return{reason:"forbidden",message:"Access denied"};if(404===e)return{reason:"not_found",message:"Resource not found"};if(409===e)return{reason:"conflict",message:"Resource conflict"};if(422===e)return{reason:"validation_error",message:"Validation failed"};if(429===e)return{reason:"rate_limited",message:"Too many requests - please wait"};if(e>=500)return{reason:"server_error",message:"Server error - please try again later"};if(e>=400)return{reason:"client_error",message:"Request error"}}return t.message.includes("CORS")?{reason:"cors_error",message:"Cross-origin request blocked"}:t.message.includes("DNS")||t.message.includes("ENOTFOUND")?{reason:"dns_error",message:"Unable to resolve server address"}:{reason:"unknown_error",message:`Network error: ${t.message}`}}buildQueryString(t={}){const e=new URLSearchParams;Object.entries(t).forEach(([t,r])=>{null!=r&&(Array.isArray(r)?r.forEach(r=>e.append(`${t}[]`,r)):e.append(t,r))});const r=e.toString();return r?`?${r}`:""}async processRequestInterceptors(t){let e={...t};for(const s of this.interceptors.request)try{e=await s(e)}catch(r){throw console.error("Request interceptor error:",r),r}return e}async processResponseInterceptors(t,e){let r={success:t.ok,status:t.status,statusText:t.statusText,headers:Object.fromEntries(t.headers.entries()),data:null,errors:null,message:null,reason:null};try{const e=t.headers.get("content-type");if(e&&e.includes("application/json")){const e=await t.json();if(r.data=e,!t.ok){const s=this.categorizeError(new Error("HTTP Error"),t.status);r.errors=e.errors||{},r.message=e.message||s.message,r.reason=s.reason}}else if(r.data=await t.text(),!t.ok){const e=this.categorizeError(new Error("HTTP Error"),t.status);r.message=e.message,r.reason=e.reason}}catch(s){r.errors={parse:"Failed to parse response"},r.message="Invalid response format"}for(const n of this.interceptors.response)try{r=await n(r,e)}catch(s){console.error("Response interceptor error:",s)}return r}async request(t,e,r=null,s={},n={}){let i={method:t.toUpperCase(),url:this.buildUrl(e)+this.buildQueryString(s),headers:{...this.config.headers,...n.headers},data:r,options:{timeout:this.config.timeout,...n}};if(i=await this.processRequestInterceptors(i),this.config.trackDevice&&this.duid)if("header"===this.config.duidTransport)i.headers[this.config.duidHeader]=this.duid;else if("GET"===i.method){const t=new URL(i.url);t.searchParams.append("duid",this.duid),i.url=t.toString()}else!i.data||"object"!=typeof i.data||i.data instanceof FormData||(i.data.duid=this.duid);const a={method:i.method,headers:i.headers},o=[];i.options.timeout&&o.push(AbortSignal.timeout(i.options.timeout)),i.options.signal&&o.push(i.options.signal),o.length>1?a.signal=AbortSignal.any?AbortSignal.any(o):o[0]:1===o.length&&(a.signal=o[0]),i.data&&["POST","PUT","PATCH"].includes(i.method)&&(i.data instanceof FormData?(a.body=i.data,delete a.headers["Content-Type"]):"object"==typeof i.data?a.body=JSON.stringify(i.data):a.body=i.data);try{const t=await fetch(i.url,a);return await this.processResponseInterceptors(t,i)}catch(l){if("AbortError"===l.name)throw l;const t=this.categorizeError(l),e={success:!1,status:0,statusText:"Network Error",headers:{},data:null,errors:{network:l.message},message:t.message,reason:t.reason},r={ok:!1,status:0,statusText:"Network Error",headers:new Headers,json:async()=>({}),text:async()=>""};return await this.processResponseInterceptors(r,i),e}}async GET(t,e={},r={}){return this.request("GET",t,null,e,r)}async POST(t,e={},r={},s={}){return this.request("POST",t,e,r,s)}async PUT(t,e={},r={},s={}){return this.request("PUT",t,e,r,s)}async PATCH(t,e={},r={},s={}){return this.request("PATCH",t,e,r,s)}async DELETE(t,e={},r={}){return this.request("DELETE",t,null,e,r)}async download(t,e={},r={}){const s={method:"GET",url:this.buildUrl(t)+this.buildQueryString(e),headers:{...this.config.headers,Accept:"*/*",...r.headers},options:{...r}};delete s.headers["Content-Type"];try{const t=await fetch(s.url,{method:s.method,headers:s.headers,signal:s.options.signal});if(!t.ok)throw new Error(`Download failed: ${t.status} ${t.statusText}`);const e=t.headers.get("content-disposition");let n=r.filename||"download";if(e){const t=e.match(/filename="?(.+)"?/);t&&t.length>1&&(n=t[1])}const i=t.body.getReader(),a=new ReadableStream({start:t=>function e(){return i.read().then(({done:r,value:s})=>{if(!r)return t.enqueue(s),e();t.close()})}()}),o=await new Response(a).blob(),l=window.URL.createObjectURL(o),h=document.createElement("a");return h.style.display="none",h.href=l,h.download=n,document.body.appendChild(h),h.click(),window.URL.revokeObjectURL(l),h.remove(),{success:!0,message:"Download initiated"}}catch(n){return console.error("Download error:",n),{success:!1,message:n.message}}}async downloadBlob(t,e={},r={}){const s={method:"GET",url:this.buildUrl(t)+this.buildQueryString(e),headers:{...this.config.headers,Accept:"*/*",...r.headers},options:{...r}};delete s.headers["Content-Type"];try{const t=await fetch(s.url,{method:s.method,headers:s.headers,signal:s.options.signal});if(!t.ok)throw new Error(`Download failed: ${t.status} ${t.statusText}`);const e=await t.blob(),n=t.headers.get("content-disposition");let i=r.filename||"download";if(n){const t=n.match(/filename="?(.+)"?/);t&&t.length>1&&(i=t[1])}const a=window.URL.createObjectURL(e),o=document.createElement("a");return o.style.display="none",o.href=a,o.download=i,document.body.appendChild(o),o.click(),window.URL.revokeObjectURL(a),o.remove(),{success:!0,message:"Download initiated"}}catch(n){return console.error("Download error:",n),{success:!1,message:n.message}}}async upload(t,e,r={}){return new Promise((s,n)=>{if(!(e instanceof File))return void n(new Error("Only single File objects are supported for legacy backend compatibility"));const i=new XMLHttpRequest;r.onProgress&&"function"==typeof r.onProgress&&(i.upload.onprogress=r.onProgress),i.onload=function(){i.status>=200&&i.status<300?s({data:i.response,status:i.status,statusText:i.statusText,xhr:i}):n(new Error(`Upload failed: ${i.status} ${i.statusText}`))},i.onerror=function(){n(new Error("Upload failed: Network error"))},i.ontimeout=function(){n(new Error("Upload failed: Timeout"))},i.open("PUT",t),i.setRequestHeader("Content-Type",e.type),r.timeout&&(i.timeout=r.timeout),i.send(e)})}async uploadMultipart(t,e,r={},s={}){const n=new FormData;if(e instanceof FileList)Array.from(e).forEach((t,e)=>{n.append(`file_${e}`,t)});else if(e instanceof File)n.append("file",e);else if(e instanceof FormData)return this.POST(t,e,{},s);return Object.entries(r).forEach(([t,e])=>{n.append(t,e)}),this.POST(t,n,{},s)}setAuthToken(t,e="Bearer"){t?this.config.headers.Authorization=`${e} ${t}`:delete this.config.headers.Authorization}clearAuth(){delete this.config.headers.Authorization}isRetryableError(t){return["not_reachable","timed_out","server_error","dns_error"].includes(t.reason)}requiresAuth(t){return"unauthorized"===t.reason}isNetworkError(t){return["not_reachable","timed_out","cancelled","cors_error","dns_error"].includes(t.reason)}getUserMessage(t){return t.message?t.message:{not_reachable:"Unable to connect to the server. Please check your internet connection.",timed_out:"The request took too long. Please try again.",cancelled:"The request was cancelled.",unauthorized:"Please log in to continue.",forbidden:"You don't have permission to perform this action.",not_found:"The requested resource was not found.",validation_error:"Please check your input and try again.",rate_limited:"Too many requests. Please wait a moment before trying again.",server_error:"Server error. Please try again later.",cors_error:"Access blocked by security policy.",dns_error:"Unable to reach the server.",unknown_error:"An unexpected error occurred."}[t.reason]||"An error occurred. Please try again."}};exports.DataWrapper=DataWrapper,exports.EventDelegate=EventDelegate,exports.EventEmitter=u,exports.MOJOUtils=MOJOUtils,exports.Mustache=c,exports.View=View,exports.dataFormatter=t,exports.rest=d;
|
|
2
|
+
//# sourceMappingURL=Rest-29RtA7pe.js.map
|