From 0137a4b4f922ad2583991b32c5e965639d1184b0 Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Sat, 3 Jan 2026 16:18:53 +0100 Subject: [PATCH 01/10] Adds HR tab and website builder prototype Introduces new HR section in employee profile with documents, certifications, and courses management Adds initial website builder interface with block-based design system and theming capabilities Enhances settings and indstillinger pages with new module configurations --- .claude/settings.local.json | 3 +- wwwroot/poc-employee.html | 357 ++- wwwroot/poc-indstillinger.html | 55 + wwwroot/poc-website-builder.html | 3633 ++++++++++++++++++++++++++++++ 4 files changed, 4009 insertions(+), 39 deletions(-) create mode 100644 wwwroot/poc-website-builder.html diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 3200db8..ada38c0 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -21,7 +21,8 @@ "WebFetch(domain:unpkg.com)", "Bash(node -e:*)", "Bash(ls:*)", - "Bash(find:*)" + "Bash(find:*)", + "WebFetch(domain:www.elegantthemes.com)" ], "deny": [], "ask": [] diff --git a/wwwroot/poc-employee.html b/wwwroot/poc-employee.html index 4c5e5f6..a829540 100644 --- a/wwwroot/poc-employee.html +++ b/wwwroot/poc-employee.html @@ -2154,6 +2154,118 @@ height: 14px; fill: currentColor; } + + /* ========================================== + HR TAB - DOCUMENTS + ========================================== */ + swp-document-list { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 16px; + } + + swp-document-item { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + background: var(--color-background-alt); + border-radius: 6px; + border: 1px solid var(--color-border); + } + + swp-document-icon { + font-size: 20px; + } + + swp-document-info { + flex: 1; + } + + swp-document-name { + display: block; + font-weight: 500; + color: var(--color-text); + } + + swp-document-meta { + display: block; + font-size: 12px; + color: var(--color-text-secondary); + margin-top: 2px; + } + + swp-document-actions { + display: flex; + gap: 8px; + } + + /* ========================================== + HR TAB - COURSES + ========================================== */ + swp-course-section { + margin-bottom: 20px; + } + + swp-course-section:last-of-type { + margin-bottom: 0; + } + + swp-course-section-title { + display: block; + font-size: 12px; + font-weight: 600; + color: var(--color-text-secondary); + margin-bottom: 8px; + } + + swp-course-list { + display: flex; + flex-direction: column; + gap: 6px; + } + + swp-course-item { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 14px; + background: var(--color-background-alt); + border-radius: 6px; + } + + swp-course-item.upcoming { + background: color-mix(in srgb, var(--color-teal) 8%, white); + border: 1px solid color-mix(in srgb, var(--color-teal) 20%, white); + } + + swp-course-info { + flex: 1; + } + + swp-course-name { + display: block; + font-size: 14px; + font-weight: 500; + color: var(--color-text); + } + + swp-course-meta { + display: block; + font-size: 12px; + color: var(--color-text-secondary); + margin-top: 2px; + } + + swp-course-status { + font-size: 11px; + font-weight: 500; + padding: 4px 10px; + border-radius: 12px; + background: color-mix(in srgb, var(--color-teal) 15%, white); + color: var(--color-teal); + } @@ -2225,6 +2337,7 @@ Arbejdstid Services Løn + HR Statistik @@ -2481,44 +2594,6 @@ - -
- - Planlagt fravær - - - 23. dec – 2. jan 2026 - Ferie - - - 14. feb 2025 - Fri - - - 7. apr – 11. apr 2025 - Ferie - - - - - - Ferie-saldo - - - Optjente feriedage - 25 dage - - - Brugte feriedage - 12 dage - - - Resterende - 13 dage - - - -
+ +
+ +
+ + + Kontrakt & Dokumenter + + + + + Kontrakttype + + + + + + Opsigelsesvarsel + + + + + + Kontraktudløb + — (ingen udløb) + + + + + + + 📄 + + Ansættelseskontrakt.pdf + Uploadet 1. aug 2019 + + + Vis + + + + 📄 + + Tillæg - Lønforhøjelse 2023.pdf + Uploadet 15. jan 2023 + + + Vis + + + + + + + Upload dokument + + +
+ + +
+ + + Certificeringer + + + 🎓 + + Balayage Specialist + Udløber: 15. juni 2026 + + Gyldig + + + 🎓 + + Farvecertificering (Wella) + Udløber: 1. marts 2025 + + Udløber snart + + + + + Tilføj certificering + + + + + + Kurser + + + Gennemførte kurser + + + + Avanceret balayage teknikker + Wella Academy · Marts 2024 + + + + + Kundeservice & mersalg + SalonUp · November 2023 + + + + + + + Planlagte kurser + + + + Olaplex certificering + Olaplex DK · 15. februar 2026 + + Tilmeldt + + + + + + + Tilføj kursus + + +
+
+ + +
+ + Ferie-saldo + + + Optjente feriedage + 25 dage + + + Brugte feriedage + 12 dage + + + Resterende + 13 dage + + + + + + Fravær & Sygdom + + + Sygefravær 2025 + 3 dage + + + Sygefravær 2024 + 7 dage + + + Børns sygdom 2025 + 1 dag + + + Barsel + — (ingen planlagt) + + + +
+ + + + Planlagt fravær + + + 23. dec – 2. jan 2026 + Ferie + + + 14. feb 2025 + Fri + + + 7. apr – 11. apr 2025 + Ferie + + + + + Tilføj fravær + + +
+ diff --git a/wwwroot/poc-indstillinger.html b/wwwroot/poc-indstillinger.html index a2bbfa0..6fe4e3c 100644 --- a/wwwroot/poc-indstillinger.html +++ b/wwwroot/poc-indstillinger.html @@ -1467,6 +1467,10 @@ transition: all 150ms ease; } + swp-module-card.full-width { + grid-column: 1 / -1; + } + swp-module-card:hover { border-color: var(--color-teal); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); @@ -3134,6 +3138,57 @@ Tak for din handel! Indstillinger + + + + + + + + + Website Builder + Byg din salons hjemmeside med drag-and-drop blokke. Vælg mellem færdige designs, tilpas farver og fonte, og integrer din booking. + + + + Til + Fra + + + + + + +149 kr/md + Ny + + Åbn Builder + + + + + + + + + + + HR & Dokumenter + Komplet medarbejderstyring: Kontrakter, certificeringer, kurser, ferie-saldo, sygefravær og barsel. Upload dokumenter og få påmindelser om udløbsdatoer. + + + + Til + Fra + + + + + + Inkluderet + + Indstillinger + + diff --git a/wwwroot/poc-website-builder.html b/wwwroot/poc-website-builder.html new file mode 100644 index 0000000..5fd5fdd --- /dev/null +++ b/wwwroot/poc-website-builder.html @@ -0,0 +1,3633 @@ + + + + + + Website Builder - Salon OS + + + + + + + + + + + + + + + Website Builder + + + + + + + + + + + + + + + + + + + + + + + + + Preview + + + + Gem + + + + Publicer + + + + + + + + + + + + Blokke + + + + Design + + + + + + + Layout + + + + Hero + + + + Kolonner + + + + Spacer + + + + Divider + + + + + + Indhold + + + + Tekst + + + + Ydelser + + + + Team + + + + Galleri + + + + Anmeldelser + + + + CTA Banner + + + + Prisliste + + + + FAQ + + + + + + Kontakt & Booking + + + + Kontakt + + + + Åbningstider + + + + Book tid + + + + Kort + + + + Social + + + + + + + + Farveskema + + + + + Typografi + + + Velkommen til salonen + Poppins — Moderne & venlig + + + Velkommen til salonen + Playfair Display — Elegant & klassisk + + + Velkommen til salonen + Inter — Ren & professionel + + + Velkommen til salonen + Montserrat — Bold & stilfuld + + + + Sociale medier + + + Instagram + + + + Facebook + + + + TikTok + + + + LinkedIn + + + + + + + + + + + + + + + + + + + + Indstillinger + + + + Indhold + Styling + + + + + +

Vælg en blok for at redigere

+
+
+
+
+
+ + + + From 4ead6bb54424d297eab9f469f812e6d4302c125f Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Sat, 3 Jan 2026 16:43:35 +0100 Subject: [PATCH 02/10] Adds waitlist UI with drawer and responsive styles Implements a new waitlist component with mini card, drawer, and interactive functionality Introduces: - Waitlist mini card with badge - Drawer overlay with detailed waitlist entries - Responsive CSS for various waitlist UI elements - Interactive JavaScript for opening/closing drawer and handling actions --- wwwroot/css/dashboard.css | 288 +++++++++++++++++++++++++++++++++++++ wwwroot/poc-dashboard.html | 225 +++++++++++++++++++++++++++++ 2 files changed, 513 insertions(+) diff --git a/wwwroot/css/dashboard.css b/wwwroot/css/dashboard.css index 81b78bf..b03b55f 100644 --- a/wwwroot/css/dashboard.css +++ b/wwwroot/css/dashboard.css @@ -867,3 +867,291 @@ swp-date-display i { grid-template-columns: 1fr; } } + +/* ========================================== + WAITLIST MINI CARD + ========================================== */ +swp-waitlist-card { + display: flex; + align-items: center; + gap: 12px; + padding: 16px; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + cursor: pointer; + transition: all 0.15s ease; +} + +swp-waitlist-card:hover { + border-color: var(--color-teal); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +swp-waitlist-icon { + position: relative; + font-size: 24px; + color: var(--color-text-secondary); +} + +swp-waitlist-badge { + position: absolute; + top: -8px; + right: -8px; + min-width: 20px; + height: 20px; + padding: 0 6px; + background: var(--color-teal); + color: white; + font-size: 11px; + font-weight: 600; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; +} + +swp-waitlist-label { + font-size: 14px; + font-weight: 500; + color: var(--color-text); +} + +/* ========================================== + WAITLIST DRAWER + ========================================== */ +swp-drawer-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.3); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + z-index: 999; +} + +swp-drawer-overlay.visible { + opacity: 1; + visibility: visible; +} + +swp-waitlist-drawer { + position: fixed; + top: 0; + right: 0; + width: 420px; + height: 100vh; + background: var(--color-surface); + border-left: 1px solid var(--color-border); + box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1); + transform: translateX(100%); + transition: transform 0.3s ease; + z-index: 1000; + display: flex; + flex-direction: column; +} + +swp-waitlist-drawer.open { + transform: translateX(0); +} + +swp-drawer-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + border-bottom: 1px solid var(--color-border); +} + +swp-drawer-title { + font-size: 16px; + font-weight: 600; + color: var(--color-text); + display: flex; + align-items: center; + gap: 8px; +} + +swp-drawer-title swp-count { + font-size: 14px; + font-weight: 500; + color: var(--color-text-secondary); +} + +swp-drawer-close { + width: 32px; + height: 32px; + border-radius: 6px; + background: var(--color-background-alt); + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: var(--color-text-secondary); + transition: all 0.15s ease; +} + +swp-drawer-close:hover { + background: var(--color-background-hover); + color: var(--color-text); +} + +swp-drawer-close i { + font-size: 18px; +} + +swp-drawer-body { + flex: 1; + overflow-y: auto; + padding: 16px; +} + +swp-waitlist-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +swp-waitlist-item { + display: flex; + flex-direction: column; + gap: 12px; + padding: 16px; + background: var(--color-background-alt); + border-radius: 8px; + border: 1px solid var(--color-border); +} + +swp-waitlist-customer { + display: flex; + align-items: center; + gap: 12px; +} + +swp-waitlist-customer swp-avatar { + width: 40px; + height: 40px; + border-radius: 50%; + background: var(--color-teal); + color: white; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + font-weight: 600; + flex-shrink: 0; +} + +swp-waitlist-customer-info { + flex: 1; +} + +swp-waitlist-name { + font-size: 14px; + font-weight: 600; + color: var(--color-text); +} + +swp-waitlist-phone { + font-size: 12px; + color: var(--color-text-secondary); +} + +swp-waitlist-service { + font-size: 13px; + font-weight: 500; + color: var(--color-teal); + padding: 6px 10px; + background: color-mix(in srgb, var(--color-teal) 10%, transparent); + border-radius: 4px; + display: inline-block; +} + +swp-waitlist-meta { + display: flex; + flex-direction: column; + gap: 6px; +} + +swp-waitlist-periods { + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; +} + +swp-waitlist-periods swp-label { + font-size: 12px; + color: var(--color-text-secondary); +} + +swp-waitlist-period-tag { + font-size: 11px; + padding: 3px 8px; + background: var(--color-background); + border-radius: 4px; + color: var(--color-text); +} + +swp-waitlist-dates { + display: flex; + align-items: center; + gap: 16px; +} + +swp-waitlist-date { + font-size: 11px; + color: var(--color-text-secondary); + display: flex; + align-items: center; + gap: 4px; +} + +swp-waitlist-date i { + font-size: 12px; +} + +swp-waitlist-date.expires { + color: var(--color-text-secondary); +} + +swp-waitlist-date.expires.soon { + color: var(--color-amber); + font-weight: 500; +} + +swp-waitlist-actions { + display: flex; + gap: 8px; + padding-top: 8px; + border-top: 1px solid var(--color-border); +} + +swp-waitlist-actions swp-btn { + flex: 1; + justify-content: center; + padding: 8px 12px; + font-size: 12px; +} + +swp-waitlist-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 48px 24px; + text-align: center; +} + +swp-waitlist-empty i { + font-size: 48px; + color: var(--color-border); + margin-bottom: 16px; +} + +swp-waitlist-empty span { + font-size: 14px; + color: var(--color-text-secondary); +} diff --git a/wwwroot/poc-dashboard.html b/wwwroot/poc-dashboard.html index dda530a..a4b3f63 100644 --- a/wwwroot/poc-dashboard.html +++ b/wwwroot/poc-dashboard.html @@ -392,6 +392,15 @@ + + + + + 4 + + På venteliste + + @@ -472,6 +481,178 @@ + + + + + + + + Venteliste (4) + + + + + + + + + + + EC + + Emma Christensen + +45 12 34 56 78 + + + Dameklip + Farve + + + Ønsker: + Mandag-Onsdag + Formiddag + + + + + Tilmeldt: 2. jan 2026 + + + + Udløber: 16. jan 2026 + + + + + + + Kontakt + + + + Book nu + + + + + + + + MS + + Mikkel Sørensen + +45 23 45 67 89 + + + Herreklip + + + Ønsker: + Weekend + + + + + Tilmeldt: 30. dec 2025 + + + + Udløber: 6. jan 2026 + + + + + + + Kontakt + + + + Book nu + + + + + + + + LA + + Lise Andersen + +45 34 56 78 90 + + + Balayage + + + Ønsker: + Tirsdag-Torsdag + Eftermiddag + + + + + Tilmeldt: 28. dec 2025 + + + + Udløber: 11. jan 2026 + + + + + + + Kontakt + + + + Book nu + + + + + + + + PH + + Peter Hansen + +45 45 67 89 01 + + + Herreklip + Skæg + + + Ønsker: + Fleksibel + + + + + Tilmeldt: 27. dec 2025 + + + + Udløber: 10. jan 2026 + + + + + + + Kontakt + + + + Book nu + + + + + + + From a4fc82222925fbc4a5fa260221b63b4240d6810d Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Sat, 3 Jan 2026 18:57:57 +0100 Subject: [PATCH 03/10] Adds barcode scanner for product checkout Implements client-side barcode scanning functionality with: - Scan button and input handling - Mock product database for EAN code lookup - Dynamic cart item addition - Visual feedback for scanning states Enhances product checkout experience with quick product entry --- wwwroot/poc-checkout.html | 325 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) diff --git a/wwwroot/poc-checkout.html b/wwwroot/poc-checkout.html index c843b6f..102861a 100644 --- a/wwwroot/poc-checkout.html +++ b/wwwroot/poc-checkout.html @@ -943,6 +943,96 @@ border-color: #ccc; } + /* ========================================== + BARCODE SCANNER + ========================================== */ + .scan-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + width: 100%; + padding: 14px 20px; + margin-top: 12px; + font-size: 13px; + font-weight: 600; + color: var(--color-teal); + background: color-mix(in srgb, var(--color-teal) 8%, white); + border: 2px dashed var(--color-teal); + border-radius: 6px; + cursor: pointer; + transition: all 200ms ease; + } + + .scan-btn:hover { + background: color-mix(in srgb, var(--color-teal) 15%, white); + border-style: solid; + } + + .scan-btn.scanning { + border-color: #1976d2; + color: #1976d2; + background: color-mix(in srgb, #1976d2 8%, white); + animation: pulse-border 1.5s ease-in-out infinite; + } + + @keyframes pulse-border { + 0%, 100% { border-color: #1976d2; } + 50% { border-color: #64b5f6; } + } + + .scan-btn svg { + width: 18px; + height: 18px; + fill: currentColor; + } + + .scanner-input-hidden { + position: absolute; + left: -9999px; + opacity: 0; + } + + /* Debug codes in sidebar */ + .debug-codes { + display: flex; + flex-direction: column; + gap: 4px; + padding: 12px 16px; + border-top: 1px solid var(--color-border); + font-size: 11px; + color: var(--color-text-secondary); + } + + .debug-codes strong { + color: var(--color-text); + margin-bottom: 4px; + font-size: 10px; + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .debug-codes div { + display: flex; + align-items: center; + gap: 6px; + } + + .debug-codes code { + font-family: var(--font-mono); + font-size: 10px; + background: var(--color-surface); + padding: 2px 6px; + border-radius: 3px; + cursor: pointer; + user-select: all; + } + + .debug-codes code:hover { + background: var(--color-teal); + color: white; + } + @@ -992,6 +1082,13 @@
Styling
Olaplex
+
+ Test EAN-koder: +
5012345678900 Olaplex No.4
+
8710447489109 Redken Shampoo
+
3474636610143 Kérastase
+
0000000000000 Ukendt
+
@@ -1176,6 +1273,14 @@
+ + + + + @@ -1653,6 +1758,226 @@ document.addEventListener('keydown', e => { if (e.key === 'Escape') closePanel(); }); + + // ========================================== + // BARCODE SCANNER + // ========================================== + + // Mock product database for scanning + const scanProducts = { + '5012345678900': { + name: 'Olaplex No.4 Bond Maintenance Shampoo', + price: 299, + size: '250ml' + }, + '8710447489109': { + name: 'Redken All Soft Shampoo', + price: 249, + size: '300ml' + }, + '3474636610143': { + name: 'Kérastase Elixir Ultime', + price: 425, + size: '100ml' + }, + '0850018802239': { + name: 'Olaplex No.7 Bonding Oil', + price: 319, + size: '30ml' + } + }; + + // Scanner elements + const scanButton = document.getElementById('scanButton'); + const scannerInput = document.getElementById('scannerInput'); + + let isScanning = false; + let scannedCode = ''; + let scanTimeout = null; + + // Start scanning + scanButton.addEventListener('click', () => { + if (isScanning) return; + + isScanning = true; + scannedCode = ''; + scanButton.classList.add('scanning'); + scanButton.innerHTML = ` + + SCANNING... + `; + scannerInput.value = ''; + scannerInput.focus(); + }); + + // Handle scanner input + scannerInput.addEventListener('input', (e) => { + scannedCode = e.target.value; + + if (scanTimeout) clearTimeout(scanTimeout); + + // After 200ms of no input, consider scan complete + scanTimeout = setTimeout(() => { + if (scannedCode.length >= 8) { + processScannedCode(scannedCode); + } + }, 200); + }); + + // Handle Enter key from scanner + scannerInput.addEventListener('keydown', (e) => { + if (e.key === 'Enter' || e.key === 'Tab') { + e.preventDefault(); + if (scannedCode.length >= 8) { + clearTimeout(scanTimeout); + processScannedCode(scannedCode); + } + } + }); + + // Handle blur - reset if no code scanned + scannerInput.addEventListener('blur', () => { + if (isScanning && scannedCode.length === 0) { + setTimeout(() => { + if (isScanning && scannedCode.length === 0) { + resetScanner(); + } + }, 300); + } + }); + + // Reset scanner to ready state + function resetScanner() { + isScanning = false; + scannedCode = ''; + scanButton.classList.remove('scanning'); + scanButton.innerHTML = ` + + SCAN PRODUKT + `; + } + + // Process scanned code + async function processScannedCode(code) { + // Show loading state + scanButton.innerHTML = ` + + HENTER... + `; + + // Simulate API delay + await new Promise(r => setTimeout(r, 600)); + + // Look up product + const foundProduct = scanProducts[code] || null; + + if (foundProduct) { + // Add to cart + addScannedProductToCart(foundProduct, code); + + // Show success briefly + scanButton.style.borderColor = '#43a047'; + scanButton.style.color = '#43a047'; + scanButton.innerHTML = ` + + TILFØJET! + `; + + setTimeout(() => { + scanButton.style.borderColor = ''; + scanButton.style.color = ''; + resetScanner(); + }, 800); + } else { + // Show not found + scanButton.style.borderColor = '#f59e0b'; + scanButton.style.color = '#f59e0b'; + scanButton.innerHTML = ` + + IKKE FUNDET + `; + + setTimeout(() => { + scanButton.style.borderColor = ''; + scanButton.style.color = ''; + resetScanner(); + }, 1500); + } + } + + // Add scanned product to cart visually + function addScannedProductToCart(product, ean) { + const cartSectionItems = document.querySelector('.cart-section:last-of-type .cart-section-items'); + + const newItem = document.createElement('div'); + newItem.className = 'cart-item'; + newItem.setAttribute('onclick', 'toggleCartItem(this)'); + newItem.setAttribute('data-base-price', product.price); + newItem.innerHTML = ` +
+
+ + 1 + +
+
+
${product.name}
+
${product.size}
+
+
+
${product.price} kr
+
${product.price} kr
+
-0 kr rabat
+
+ +
+
+
+
+
Pris
+ +
+
+
Rabat
+
+ +
+ + +
+
+
+
+
+ `; + + // Insert at end of items list + cartSectionItems.appendChild(newItem); + + // Flash the new item + newItem.style.animation = 'flash 0.5s ease'; + + // Re-attach discount type handlers + newItem.querySelectorAll('.discount-type-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + e.stopPropagation(); + toggleDiscountType(btn); + }); + }); + } + + // Add animations + const scannerStyle = document.createElement('style'); + scannerStyle.textContent = ` + @keyframes flash { + 0% { background-color: rgba(0, 137, 123, 0.2); } + 100% { background-color: transparent; } + } + @keyframes spin { + to { transform: rotate(360deg); } + } + `; + document.head.appendChild(scannerStyle); From 35b15294e3279f3d84fbfe612bb466c3a6c05d7b Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Mon, 5 Jan 2026 17:38:39 +0100 Subject: [PATCH 04/10] Removes poc-booking.html from wwwroot Cleans up redundant HTML file from project directory Eliminates an unused proof-of-concept booking page template --- wwwroot/poc-booking.html | 1806 ---------------------- wwwroot/poc-checkout.html | 520 ++++++- wwwroot/poc-dashboard copy.html | 1385 ----------------- wwwroot/poc-indstillinger.html | 587 ++++++++ wwwroot/poc-layout copy.html | 2509 ------------------------------- 5 files changed, 1105 insertions(+), 5702 deletions(-) delete mode 100644 wwwroot/poc-booking.html delete mode 100644 wwwroot/poc-dashboard copy.html delete mode 100644 wwwroot/poc-layout copy.html diff --git a/wwwroot/poc-booking.html b/wwwroot/poc-booking.html deleted file mode 100644 index 4de81c9..0000000 --- a/wwwroot/poc-booking.html +++ /dev/null @@ -1,1806 +0,0 @@ - - - - - - Book tid - KARINA KNUDSEN® - - - - - - - - - - - - - SB - -

KARINA KNUDSEN®

-

Amager Strandvej 22f, 2300 Kbh S

-
-
- - - - - - - -

Vælg ydelse

-

Vælg hvad du vil have lavet

-
- Rediger - -
- - -
-
-
-
- - - - - - -

Vælg medarbejder

-

Valgfrit

-
- Rediger - -
- - -
-
-
-
- - - - - - -

Vælg dato og tid

-

Find en ledig tid

-
- Rediger - -
- - -
-
-
-
- - - - - - -

Dine oplysninger

-

Kontaktinformation

-
- Rediger - -
- - - - - Fornavn - - - - Efternavn - - - - Telefon - - - - Email - - - - Noter (valgfrit) - - - - - -
-
-
- - - - Din booking - - - - Vælg en ydelse for at starte - - - - - - - - - - - Book tid - - -
- - - - Videre - - - - - - - - -

Booking bekræftet!

-

Du modtager en bekræftelse på email og SMS. Vi glæder os til at se dig!

-
-
- - - - - diff --git a/wwwroot/poc-checkout.html b/wwwroot/poc-checkout.html index 102861a..210d46f 100644 --- a/wwwroot/poc-checkout.html +++ b/wwwroot/poc-checkout.html @@ -1033,6 +1033,326 @@ color: white; } + /* ========================================== + RECEIPT + ========================================== */ + .receipt-container { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.3); + z-index: 10; + display: flex; + justify-content: center; + padding-top: 20px; + opacity: 0; + visibility: hidden; + transition: opacity 300ms ease, visibility 300ms ease; + overflow-y: auto; + } + + .receipt-container.visible { + opacity: 1; + visibility: visible; + } + + .receipt { + width: 280px; + background: #fff; + font-family: 'Courier New', monospace; + font-size: 12px; + color: #000; + padding: 20px 16px; + box-shadow: 0 4px 20px rgba(0,0,0,0.3); + transform: translateY(-100%); + transition: transform 500ms cubic-bezier(0.34, 1.56, 0.64, 1); + position: relative; + margin-bottom: 20px; + } + + .receipt-container.visible .receipt { + transform: translateY(0); + } + + /* Torn paper effect at bottom */ + .receipt::after { + content: ''; + position: absolute; + bottom: -10px; + left: 0; + right: 0; + height: 10px; + background: linear-gradient(135deg, #fff 25%, transparent 25%), + linear-gradient(-135deg, #fff 25%, transparent 25%); + background-size: 10px 10px; + } + + .receipt-header { + text-align: center; + padding-bottom: 12px; + border-bottom: 1px dashed #000; + margin-bottom: 12px; + } + + .receipt-logo { + font-size: 18px; + font-weight: bold; + letter-spacing: 2px; + margin-bottom: 4px; + } + + .receipt-address { + font-size: 10px; + line-height: 1.4; + } + + .receipt-info { + display: flex; + justify-content: space-between; + font-size: 10px; + padding: 8px 0; + border-bottom: 1px dashed #000; + margin-bottom: 12px; + } + + .receipt-items { + margin-bottom: 12px; + } + + .receipt-item { + display: flex; + justify-content: space-between; + padding: 4px 0; + font-size: 11px; + } + + .receipt-item-name { + flex: 1; + padding-right: 8px; + } + + .receipt-item-qty { + width: 30px; + text-align: center; + } + + .receipt-item-price { + width: 70px; + text-align: right; + font-family: 'JetBrains Mono', monospace; + } + + .receipt-divider { + border-top: 1px dashed #000; + margin: 8px 0; + } + + .receipt-totals { + margin-bottom: 12px; + } + + .receipt-total-row { + display: flex; + justify-content: space-between; + padding: 3px 0; + font-size: 11px; + } + + .receipt-total-row.grand { + font-size: 14px; + font-weight: bold; + padding: 8px 0; + border-top: 2px solid #000; + border-bottom: 2px solid #000; + margin: 8px 0; + } + + .receipt-payment { + font-size: 10px; + padding: 8px 0; + border-bottom: 1px dashed #000; + } + + .receipt-payment-row { + display: flex; + justify-content: space-between; + padding: 2px 0; + } + + .receipt-footer { + text-align: center; + padding-top: 12px; + font-size: 10px; + } + + .receipt-footer-msg { + font-size: 12px; + font-weight: bold; + margin-bottom: 8px; + } + + .receipt-qr { + margin: 12px auto 8px; + display: flex; + justify-content: center; + } + + .receipt-qr svg { + border: 2px solid #000; + } + + .receipt-id { + font-size: 9px; + letter-spacing: 1px; + } + + .receipt-close { + position: absolute; + top: 8px; + right: 8px; + width: 24px; + height: 24px; + border: none; + background: #f0f0f0; + border-radius: 50%; + cursor: pointer; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + } + + .receipt-close:hover { + background: #e0e0e0; + } + + .receipt-actions { + display: flex; + gap: 8px; + margin-top: 16px; + padding-top: 12px; + border-top: 1px solid #e0e0e0; + } + + .receipt-actions button { + flex: 1; + padding: 8px; + font-size: 11px; + border-radius: 4px; + cursor: pointer; + font-family: var(--font-family); + } + + .receipt-actions .btn-print { + background: #000; + color: #fff; + border: none; + } + + .receipt-actions .btn-close { + background: #fff; + border: 1px solid #ccc; + color: #333; + } + + /* ========================================== + PRINT STYLES + ========================================== */ + @media print { + /* White background */ + html, body { + background: white !important; + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + } + + /* Hide everything by default */ + .demo-trigger, + .overlay, + .header, + .sidebar, + .cart-area, + .payment-total, + .payment-methods, + .payment-input-section, + .registered-payments, + .payment-footer { + display: none !important; + } + + /* Reset panel positioning */ + .panel { + position: static !important; + width: 100% !important; + transform: none !important; + box-shadow: none !important; + background: white !important; + } + + .main { + display: block !important; + } + + .payment-panel { + display: block !important; + position: static !important; + border: none !important; + background: white !important; + } + + /* Show receipt */ + .receipt-container { + display: flex !important; + justify-content: center !important; + visibility: visible !important; + opacity: 1 !important; + position: static !important; + background: white !important; + padding: 0 !important; + } + + .receipt { + display: block !important; + margin: 0 !important; + box-shadow: none !important; + transform: none !important; + text-align: left !important; + } + + /* Preserve item layout */ + .receipt-item { + display: flex !important; + justify-content: space-between !important; + text-align: left !important; + } + + .receipt-item-name { + text-align: left !important; + } + + .receipt-item-price { + text-align: right !important; + } + + .receipt-total-row { + display: flex !important; + justify-content: space-between !important; + } + + /* Hide buttons in receipt */ + .receipt-close, + .receipt-actions { + display: none !important; + } + + /* Remove torn paper effect */ + .receipt::after { + display: none; + } + } + @@ -1303,7 +1623,178 @@ -
+
+ +
+
+ + +
+ +
+ Østergade 42, 1. sal
+ 1100 København K
+ Tlf: 33 12 34 56
+ CVR: 12345678 +
+
+ +
+
+
Dato: 16-12-2025
+
Tid: 14:32
+
+
+
Kvit: #4521
+
Kasse: 1
+
+
+ +
+
+ Vare + Antal + Pris +
+
+ Dameklip + 1 + 725,00 +
+
+ Gloss langt hår + 1 + 900,00 +
+
+ Olaplex No. 3 + 1 + 300,00 +
+
+ India mask 250ml + 2 + 350,00 +
+
+ +
+ +
+
+ Subtotal + 1.820,00 +
+
+ Moms (25%) + 455,00 +
+
+ TOTAL + 2.275,00 DKK +
+
+ +
+
+ Betalt med Kort + 2.275,00 +
+
+ + + +
+ + +
+
+
2.275 kr
Total at betale
@@ -1369,7 +1860,7 @@
- +
@@ -1978,6 +2469,31 @@ } `; document.head.appendChild(scannerStyle); + + // ========================================== + // RECEIPT + // ========================================== + + function showReceipt() { + const receiptContainer = document.getElementById('receiptContainer'); + receiptContainer.classList.add('visible'); + } + + function hideReceipt() { + const receiptContainer = document.getElementById('receiptContainer'); + receiptContainer.classList.remove('visible'); + } + + // Close receipt on Escape key + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + const receiptContainer = document.getElementById('receiptContainer'); + if (receiptContainer.classList.contains('visible')) { + hideReceipt(); + e.stopPropagation(); + } + } + }); diff --git a/wwwroot/poc-dashboard copy.html b/wwwroot/poc-dashboard copy.html deleted file mode 100644 index 5f93f61..0000000 --- a/wwwroot/poc-dashboard copy.html +++ /dev/null @@ -1,1385 +0,0 @@ - - - - - - Dashboard - Salon OS - - - - - - - - - Dashboard - - - - - Mandag, 30. december 2024 - - - - Ny booking - - - - - - - - - 12 - Bookinger i dag - - - 4 gennemført, 2 i gang - - - - 8.450 kr - Forventet omsætning - - - +12% vs. gennemsnit - - - - 78% - Belægningsgrad - - - God kapacitet - - - - 3 - Kræver opmærksomhed - - - - - - - - - - - - AI Analyse - - - Godt i gang! 4 af 12 bookinger er gennemført. 2 er i gang nu, og 6 venter. - Forventet omsætning: 8.450 kr – allerede realiseret 2.150 kr. - Tip: Ida Rasmussen (11:30) har ikke bekræftet – overvej at sende en påmindelse. - - - - - - - - - - Dagens bookinger - - Se alle - - - - - Nu: 10:45 - - - - - - - 08:00 - 08:30 - - - - Herreklip - Thomas Berg - - - MH - Maria - - Gennemført - - - - - 08:30 - 09:00 - - - - Dameklip - Katrine Holm - - - AS - Anna - - Gennemført - - - - - 09:00 - 09:30 - - - - Skægtrimning - Mikkel Skov - - - PK - Peter - - Gennemført - - - - - 09:00 - 10:30 - - - - Dameklip + Farve - Sofie Nielsen - - - AS - Anna - - Gennemført - - - - - - 10:30 - 11:00 - - - - Herreklip - Jonas Petersen - - - MH - Maria - - I gang - - - - - 10:00 - 11:00 - - - - Føn + Styling - Rikke Dam - - - LJ - Louise - - I gang - - - - - - 11:00 - 12:00 - - - - Balayage - Emma Christensen - - - AS - Anna - - Bekræftet - - - - - 11:30 - 12:00 - - - - Dameklip - Ida Rasmussen - - - MH - Maria - - Afventer - - - - - 13:00 - 14:00 - - - - Farve + Føn - Louise Andersen - - - AS - Anna - - Bekræftet - - - - - 14:00 - 14:30 - - - - Herreklip - Anders Møller - - - PK - Peter - - Bekræftet - - - - - 15:30 - 16:30 - - - - Extensions - Julie Lund - - - LJ - Louise - - Bekræftet - - - - - - - - - - Opmærksomheder - - - - - - - - - - Aflyst booking - Mette Hansen aflyste kl. 15:00 – tid nu ledig - - Fyld tid - - - - - - - - Ubekræftet booking - Ida Rasmussen har ikke bekræftet kl. 11:30 - - Send påmindelse - - - - - - - - Gavekort udløber snart - GC-D2R4-6TY9 udløber om 3 uger (200 DKK) - - Se gavekort - - - - - - - - - - - - - Notifikationer - - Marker alle som læst - - - - - - - - - - Ny booking fra Emma Christensen til Balayage - - For 15 min. siden - - - - - - - - - - Ny anmeldelse – 5 stjerner fra Sofie Nielsen - - For 1 time siden - - - - - - - - - - Aflysning – Mette Hansen aflyste kl. 15:00 - - For 2 timer siden - - - - - - - - - - Bekræftet – Louise Andersen bekræftede kl. 13:00 - - I går kl. 18:30 - - - - - - - - - - - Denne uge - - - - - - 47 - Bookinger - - - 38.200 kr - Omsætning - - - 8 - Nye kunder - - - 72% - Gns. belægning - - - - - - - - - - Medarbejdere - - - - - - AS - - Anna Sørensen - Ledig til kl. 11:00 (Balayage) - - Ledig - - - - MH - - Maria Hansen - Herreklip med Jonas - - Optaget - - - - LJ - - Louise Jensen - Føn + Styling med Rikke - - Optaget - - - - PK - - Peter Kristensen - Ledig til kl. 14:00 - - Ledig - - - - - - - - - - diff --git a/wwwroot/poc-indstillinger.html b/wwwroot/poc-indstillinger.html index 6fe4e3c..8cb0bd3 100644 --- a/wwwroot/poc-indstillinger.html +++ b/wwwroot/poc-indstillinger.html @@ -1684,6 +1684,181 @@ swp-btn.primary.purple:hover { background: color-mix(in srgb, var(--color-purple) 85%, black); } + + /* ========================================== + TRACKING TAB + ========================================== */ + swp-tab-content[data-tab="tracking"] { + display: none; + } + + swp-tab-content[data-tab="tracking"].active { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + } + + .tracking-card { + margin-bottom: 0; + } + + .tracking-card.full-width, + .code-preview-card { + grid-column: 1 / -1; + } + + .tracking-card swp-card-header { + display: flex; + justify-content: space-between; + align-items: center; + } + + .tracking-card[data-tracker] swp-card-content { + transition: opacity 200ms ease, max-height 300ms ease; + } + + .tracking-card[data-tracker].disabled swp-card-content { + opacity: 0.5; + pointer-events: none; + } + + swp-tracking-hint { + display: flex; + align-items: center; + gap: 8px; + margin-top: 12px; + padding: 10px 12px; + background: color-mix(in srgb, var(--color-blue) 8%, transparent); + border-radius: 6px; + font-size: 12px; + color: var(--color-text-secondary); + } + + swp-tracking-hint i { + font-size: 16px; + color: var(--color-blue); + } + + swp-tracking-hint.privacy { + background: color-mix(in srgb, var(--color-green) 8%, transparent); + } + + swp-tracking-hint.privacy i { + color: var(--color-green); + } + + swp-script-section { + display: flex; + flex-direction: column; + gap: 8px; + margin-bottom: 16px; + } + + swp-script-section:last-child { + margin-bottom: 0; + } + + swp-script-label { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + font-weight: 500; + color: var(--color-text); + } + + swp-script-label i { + font-size: 16px; + color: var(--color-text-secondary); + } + + .script-textarea { + width: 100%; + min-height: 100px; + padding: 12px; + font-family: var(--font-mono); + font-size: 12px; + line-height: 1.5; + color: var(--color-text); + background: var(--color-background); + border: 1px solid var(--color-border); + border-radius: 6px; + resize: vertical; + } + + .script-textarea::placeholder { + color: var(--color-text-secondary); + } + + .script-textarea:focus { + outline: none; + border-color: var(--color-teal); + } + + .code-preview-card { + margin-top: 24px; + border: 2px dashed var(--color-teal); + background: color-mix(in srgb, var(--color-teal) 3%, var(--color-surface)); + } + + .code-preview-card swp-card-header { + display: flex; + justify-content: space-between; + align-items: center; + } + + .code-preview-card swp-card-title { + color: var(--color-teal); + } + + swp-code-info { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 12px; + font-size: 12px; + color: var(--color-text-secondary); + } + + swp-code-info i { + font-size: 16px; + color: var(--color-teal); + } + + .code-preview { + margin: 0; + padding: 16px; + background: var(--color-background); + border: 1px solid var(--color-border); + border-radius: 6px; + overflow-x: auto; + max-height: 400px; + overflow-y: auto; + } + + .code-preview code { + font-family: var(--font-mono); + font-size: 11px; + line-height: 1.6; + color: var(--color-text); + white-space: pre; + } + + .code-preview .comment { + color: var(--color-green); + } + + .code-preview .tag { + color: var(--color-blue); + } + + .code-preview .attr { + color: var(--color-purple); + } + + .code-preview .string { + color: var(--color-teal); + } @@ -1735,6 +1910,10 @@ Moduler + + + Tracking + + + + + + + + Meta Pixel (Facebook) + + + Ja + Nej + + + + + + Pixel ID + 123456789012345 + + + + + Bruges til Facebook og Instagram annoncering og remarketing + + + + + + + + + + Google Analytics (GA4) + + + Ja + Nej + + + + + + Measurement ID + G-ABC123XYZ + + + + + Google Analytics 4 til website trafik og brugeradfærd + + + + + + + + + + Google Tag Manager + + + Ja + Nej + + + + + + Container ID + GTM-XXXXXXX + + + + + Central styring af alle tracking-tags + + + + + + + + + + Plausible Analytics + + + Ja + Nej + + + + + + Domæne + minside.dk + + + + + Privacy-venlig analytics uden cookies - GDPR compliant + + + + + + + + + + Fathom Analytics + + + Ja + Nej + + + + + + Site ID + ABCDEFGH + + + + + Privacy-venlig analytics uden cookies - GDPR compliant + + + + + + + + + + Matomo + + + Ja + Nej + + + + + + Server URL + https://matomo.minside.dk + + + Site ID + 1 + + + + + Self-hosted analytics - fuld kontrol over dine data + + + + + + + + + + Brugerdefinerede Scripts + + + + + + + Scripts i <head> + + + + + + + Scripts før </body> + + + + + + + + + + + + Genereret Kode + + + + + + Denne kode indsættes automatisk i <head> på din online booking side + +
+
+
+
+ @@ -3699,6 +4086,206 @@ Vil du ændre din tid? {booking_link} // Initial state updateOnlinePaymentVisibility(); } + + // ========================================== + // TRACKING TAB + // ========================================== + + function initTrackingToggles() { + document.querySelectorAll('.tracking-card swp-toggle-slider').forEach(slider => { + slider.querySelectorAll('swp-toggle-option').forEach((option, index) => { + option.addEventListener('click', () => { + slider.dataset.value = index === 0 ? 'yes' : 'no'; + const card = slider.closest('.tracking-card'); + + if (slider.dataset.value === 'no') { + card.classList.add('disabled'); + } else { + card.classList.remove('disabled'); + } + + updateTrackingPreview(); + }); + }); + }); + } + + function updateTrackingPreview() { + const preview = document.getElementById('trackingCodePreview'); + if (!preview) return; + + let code = ''; + + // Meta Pixel + const metaCard = document.querySelector('[data-tracker="meta"]'); + if (metaCard && metaCard.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const pixelId = document.getElementById('metaPixelId')?.textContent?.trim() || ''; + if (pixelId) { + code += `<!-- Meta Pixel --> +<script> + !function(f,b,e,v,n,t,s) + {if(f.fbq)return;n=f.fbq=function(){n.callMethod? + n.callMethod.apply(n,arguments):n.queue.push(arguments)}; + if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; + n.queue=[];t=b.createElement(e);t.async=!0; + t.src=v;s=b.getElementsByTagName(e)[0]; + s.parentNode.insertBefore(t,s)}(window, document,'script', + 'https://connect.facebook.net/en_US/fbevents.js'); + fbq('init', '${pixelId}'); + fbq('track', 'PageView'); +</script> + +`; + } + } + + // Google Analytics + const ga4Card = document.querySelector('[data-tracker="ga4"]'); + if (ga4Card && ga4Card.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const measurementId = document.getElementById('ga4Id')?.textContent?.trim() || ''; + if (measurementId) { + code += `<!-- Google Analytics (GA4) --> +<script async src="https://www.googletagmanager.com/gtag/js?id=${measurementId}"></script> +<script> + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', '${measurementId}'); +</script> + +`; + } + } + + // Google Tag Manager + const gtmCard = document.querySelector('[data-tracker="gtm"]'); + if (gtmCard && gtmCard.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const containerId = document.getElementById('gtmId')?.textContent?.trim() || ''; + if (containerId) { + code += `<!-- Google Tag Manager --> +<script> + (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': + new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], + j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= + 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); + })(window,document,'script','dataLayer','${containerId}'); +</script> + +`; + } + } + + // Plausible + const plausibleCard = document.querySelector('[data-tracker="plausible"]'); + if (plausibleCard && plausibleCard.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const domain = document.getElementById('plausibleDomain')?.textContent?.trim() || ''; + if (domain) { + code += `<!-- Plausible Analytics --> +<script defer data-domain="${domain}" src="https://plausible.io/js/script.js"></script> + +`; + } + } + + // Fathom + const fathomCard = document.querySelector('[data-tracker="fathom"]'); + if (fathomCard && fathomCard.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const siteId = document.getElementById('fathomSiteId')?.textContent?.trim() || ''; + if (siteId) { + code += `<!-- Fathom Analytics --> +<script src="https://cdn.usefathom.com/script.js" data-site="${siteId}" defer></script> + +`; + } + } + + // Matomo + const matomoCard = document.querySelector('[data-tracker="matomo"]'); + if (matomoCard && matomoCard.querySelector('swp-toggle-slider').dataset.value === 'yes') { + const serverUrl = document.getElementById('matomoUrl')?.textContent?.trim() || ''; + const siteId = document.getElementById('matomoSiteId')?.textContent?.trim() || ''; + if (serverUrl && siteId) { + code += `<!-- Matomo Analytics --> +<script> + var _paq = window._paq = window._paq || []; + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + (function() { + var u="${serverUrl}/"; + _paq.push(['setTrackerUrl', u+'matomo.php']); + _paq.push(['setSiteId', '${siteId}']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); + })(); +</script> + +`; + } + } + + // Custom Head Scripts + const customHead = document.getElementById('customHeadScripts')?.value?.trim() || ''; + if (customHead) { + code += `<!-- Custom Scripts --> +${escapeHtml(customHead)} + +`; + } + + if (code) { + preview.querySelector('code').innerHTML = code.trim(); + } else { + preview.querySelector('code').innerHTML = '<!-- Ingen aktive tracking-koder -->'; + } + } + + function escapeHtml(text) { + return text + .replace(/&/g, '&') + .replace(//g, '>'); + } + + function copyTrackingCode() { + const preview = document.getElementById('trackingCodePreview'); + if (!preview) return; + + // Get plain text version (strip HTML tags) + const code = preview.querySelector('code').innerHTML + .replace(/]*>/g, '') + .replace(/<\/span>/g, '') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&'); + + navigator.clipboard.writeText(code).then(() => { + const btn = document.querySelector('.code-preview-card swp-btn'); + const originalText = btn.innerHTML; + btn.innerHTML = ' Kopieret!'; + btn.style.color = 'var(--color-green)'; + setTimeout(() => { + btn.innerHTML = originalText; + btn.style.color = ''; + }, 2000); + }); + } + + // Initialize tracking preview on page load + document.addEventListener('DOMContentLoaded', () => { + // Initialize tracking toggles + initTrackingToggles(); + + // Update preview + updateTrackingPreview(); + + // Set initial disabled state for cards + document.querySelectorAll('.tracking-card[data-tracker]').forEach(card => { + const toggle = card.querySelector('swp-toggle-slider'); + if (toggle && toggle.dataset.value === 'no') { + card.classList.add('disabled'); + } + }); + }); diff --git a/wwwroot/poc-layout copy.html b/wwwroot/poc-layout copy.html deleted file mode 100644 index a24a9a2..0000000 --- a/wwwroot/poc-layout copy.html +++ /dev/null @@ -1,2509 +0,0 @@ - - - - - - Salon OS - - - - - - - - - - - Salon OS - - - - - - - - - Dashboard - - - Dashboard - - - - Kalender - - - - Kasse - - - - - - Data - - - Produkter & Lager - - - - Leverandører - - - - Kunder - - - - Medarbejdere - - - - - - Analyse - - - Statistik & Rapporter - - - - - - System - - - Indstillinger - - - - Abonnement & Konto - - - - - - - - Lås skærm - - - - - - - - - - ⌘K - - - - - - - 3 - - - - - - - MJ - - Maria Jensen - Administrator - - - - - - - - - - Dashboard - - Vælg et menupunkt i venstre side for at navigere til den ønskede sektion. -

- Prøv f.eks. Produkter & Lager eller Leverandører. -
-
-
-
- - - - - - Min profil - - - - - - - - MJ - Maria Jensen - Administrator - maria@salon.dk - - - - Konto - - - Rediger profil - - - - - Skift adgangskode - - - - - Notifikationer - 3 ulæste - - - - Mine opgaver - 2 i dag - - - - - Udseende - - - - - - - - - - - - Support - - - Hjælp & Support - - - - - Om Salon OS - v2.1.0 - - - - - - - - Log ud - - - - - - - - Notifikationer - - Marker alle læst - - - - - - - - - - - - - - Ny booking - Maria Hansen har booket klipning kl. 14:00 - For 5 min siden - - - - - - - - - - Kunde feedback - 5 stjerner fra Jonas Petersen - For 15 min siden - - - - - - - - - - Misset opkald - +45 12 34 56 78 - For 1 time siden - - - - - - - - - - Ny mail - Fra: leverandoer@produkt.dk - Ordrebekræftelse - For 2 timer siden - - - - - - - - - - Ny besked i chat - Kunde: "Hej, kan jeg ændre min tid?" - For 3 timer siden - - - - - - - - - - Påmindelse - Bestil varer fra Wella inden fredag - I går - - - - - - - - - - - - Mine opgaver - - - - - - - - - - - - - I dag - 3 - - - - - - - - Ring til leverandør om ordre - - - - 10:00 - - - - - - - - - - Bestil shampoo fra Wella - - - - - - - - Opdater prisliste for 2025 - - - - Høj - - - - - - - - - - - - Denne uge - 2 - - - - - - - - Rengør og vedligehold udstyr - - - - Onsdag - - - - - - - - - - Medarbejdersamtale med Jonas - - - - Fredag - - - - 14:00 - - - - - - - - - - - - - - - - - - - Ny opgave - - - - - - Opgave - - - - - - - Dato - - - - Tid - - - - - - - Prioritet - - - - - - Synlighed - - - - Kun mig - - - - Alle - - - - - - - Noter - - - - - - Annuller - Gem opgave - - - - - - - - - - Skærm låst - Indtast PIN for at fortsætte - - Låst kl. 14:32 - - - - - - - - - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - - 0 - - - - - - Indtast 4 cifre for at låse op - - - - - - - - - From fac7754d7aad46227e1bb490a921b3d150145728 Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Wed, 7 Jan 2026 22:12:25 +0100 Subject: [PATCH 05/10] Refactors design system documentation and layout Updates design system documentation with comprehensive component overview Enhances UI layout across multiple pages with consistent styling and new components Adds support for charts, pagination, and responsive design elements Improves overall system documentation and visual consistency --- .workbench/image.png | Bin 64812 -> 148742 bytes .workbench/spec-salary.html | 564 ++++++++++++++ docs/design-system.md | 221 ++++++ package-lock.json | 8 +- package.json | 2 +- wwwroot/poc-employee.html | 348 +++++++-- wwwroot/poc-gavekort-detail.html | 24 +- wwwroot/poc-gavekort.html | 34 +- wwwroot/poc-indstillinger.html | 112 +++ wwwroot/poc-konto.html | 204 +---- wwwroot/poc-layout.html | 2 +- wwwroot/poc-loenspecifikation.html | 533 +++++++++++++ wwwroot/poc-medarbejdere.html | 588 +++++++++++++++ wwwroot/poc-salg.html | 1133 ++++++++++++++++++++++++++++ 14 files changed, 3492 insertions(+), 281 deletions(-) create mode 100644 .workbench/spec-salary.html create mode 100644 docs/design-system.md create mode 100644 wwwroot/poc-loenspecifikation.html create mode 100644 wwwroot/poc-medarbejdere.html create mode 100644 wwwroot/poc-salg.html diff --git a/.workbench/image.png b/.workbench/image.png index cbecbe406b2b8056954972914fa92984782ece31..196aaeb37233f1d3dafa6942351da2cac2fb6762 100644 GIT binary patch literal 148742 zcmd?RRajih7A*_}m*CL2dw|A*yGtMt+zAj|gKKbi4Fvb#1lKekoZ#*f9D?gz*=J{; z>~r7$|KUFI(Y;pHtf^y;s_L-UiqdGvgvd}(P-wC;5-Lzou;frsaIT0jz$fUAVc(#j z$f0B zhC*}b%5J(Dh1HNm!^j3Rf5(AlHb#TCNU4E~W_GZkLlaZxDjvwuw3pj(EfhHF#kOG_gl!~P_TJmdNz#zeV!b2O$3bh z@4>;aB4FeItY^^B|1*xiU&sG`1pEK-(9E)^?`GB19f{Ctt5B&?U!A&n7v0U>dP`|lD(su5pQmJJVU&=n3&ypP~!ni}|i zrs7>!->Pl^*>Mrgu5YbZH7I|T>!*f*2MZ`a>*h5wI zS}z%YN>lBbA1AEDymm1Q{?kJdZmmgu z_H^^cWq$Cq4{|2-QnmDUVz#IxuxC{)q6EM||HssgBp9jbm5M96frBtOlyoq4TXjFu zBLEH9KJD)cLQ;9oB)`-q!JRHi(=|WD61m;?aG*=xd=(e|yx+%=C3yYO{F#{Zs2f$? z1|MeRVmyN+RqkbUf4!!MZryP#DM|8X=ZjF|dc|*teaQ)fGPU(>4$d6k zc07_?_?Nuj=7K72*+js%cfR`SD@)wOm|nI14nKMj(DFjZBLz32CZqMJLC3zn=SN1% z!#zL4>~kh>&bc2`N&XHFzejOHz-D1T*uC&?QYOs_#0{&P+1d1tmYY<_K@V5LMAZb| zUS~P1RUMQkhLMM1_Axo-tnD4M=A3(5>~?u_N3)XtnCVJ^hMa^^n>XE=cm{rdMJ*6z zezb@~$tm00rPVZ4?J$1HzqCD)oRW55Qs?O|jvYBLyFBh~#&jrj7koTpBARvYwJ!~h z-wDwECla&aV3RebE0$92EEvLiMaVJzthl#Z5(Dg>VMNaNoKnTaEFUV$HXHw3LMP@q z+wPWr7ce#*&{61{oDwZ{h2njBT`)Cpb9~$}V?952{}JJN%rM;3haDle8wM`79~G~% zmVBNXdW-VcW*>J+^B;_(ZVTRwF0sao0pICdk@2T=+wWl;OJA+rX?fO66f(OCpDYe` zC|b@HE48_vt!lVFzZ;h13=u4P=Y|~SMQ)oIqp0#cSndGOPW--=@H`QbNneax{l&*C zB@*BDxbYU@mV(WfZ_(`9Tt`ol}_yzW`FN*lV9+CVU^d}|YPs}b>vE^p_qR(}JHZM))UvVZ zNmU%>s?Rpu@J!wAbvxZmC`CM(jgP|S2_;vh#Z&~y>s+>4=sTFP1bMUCp*H%QJ@z}! zH4xMc?n`|#EPff+?rHG8b!%heN{XeY<+{$!-AiNgYk5gThMAY(umw{%Er^UXI@7tu zl#J$k_LEicXZI6D#NM0AkWb9;X=dy>FnOYHP9Lk)ej;9@|5m1-XtuV&$IL-z&ch!a zganL&C--*P%jZ7}yo)rjSPEDgeVgsf2jx3#at60{8X~|;Yjr(zyeSE5N5oo-4Su20pX^eClTc8`cTaK=Ryh#n73?(@ks z-kBZ|p_XP1_5#^?>Q-*;N#r)wP(q_ET}sKPcGi57)yuQ=VQy3UHm{3}jd3`+vwr3o zo$1}gBvalk>$~d`R||t-%0tBYx*dsdeFw@s<%Ue5PW z0k=C?s#~W0II7bV$j@MKH-Sd}$0xm){L!k{9R#R|f9E>GHjGBKlC4EDQ}x_6?THuq zcQJ;uG7(Sz%cd?6TdN!dUR9%L#qE(PFG-HlJyUCU`l50u zr5O201KR1R&}iF!<$loRmOAavN1Xni1AxFQz5ihGf_ z^kfZ-+}jpn;p=O2tDx&O%deP`J4YIv_4qXshrnzfazz+5Wth`?(NvAzb#Qq4j_=gP zTFZ_%Y>}hf`1MnsCW~;j0uQ3U;e`So1~v6ELJd}rqdQC^Rgm)`C9Guh{I zcMU6^hUSCMjJy-rboAFJJZ8!x(@{wkgqGX4T6R3#$vWiMIU`jtL#kOW0yq0(VLq-h zM|t_6Bqh707Ia8ytT7NhX&Cl$W@3-9_KZ%Sqq@C9s;U;aZk-4uD^3Q5do01 z8Rajg1elB|K`Wk2np+)Q+8(PnS?xF!puMCfJ=mWxOUE$tu6#A!4f31)^J&wKdBRCa zN9_|#!G_lWiehg4?}1qWJ^uA>o)PF>t2m&0Ig9W@VV^Fo^~=aa?E|tj0=lYvV%lFMCs6si}7E0eElIb$a8 z9DMG+7jtQhg-?S+X5*J$hxQLF)N(G0tADM=RJe<5nJBP7bL8hXY9ZEm|7DTkrBX+u z2FGbq+ED*MUnJF}>7aa(Rt=aOk!<$t`%f)caa!>D>Eu9|5zdjQ!p3-3MNfYKCii(v z3zl6%i1B3d3~gb8furkLj7b0nYKK(E{!yP&`;(jm{p?R#3Jilqe#*GI#7YA`=dny< zB6kBJYJT6h-p2y>?Qs0<4bq5G+LkuLzRf6@k=*F!(VVK<+;GM-Ol)87b_Zt;#r3V< zY8FZFh8pI7!%1YpKn{K&I5GI`De!(wZ?*(Vd-*E4+!+*@?Aiv3G%-=T#19BllFMu9 zW9*?u6|6ag5tIzg8LaV7t=RpyNL%$?yT7`wc?c5_`W2-)xIXYqE{$aET^zbS*tmyU zqso&Lh06rS&~k}UPl~Zffqks#p_kG7?P18c8!Zl3ITe8=(k%oyckKIiD1wb7>Y}*)M zGx45!y^RYQkOh>ibG+uE=e(qvmMPKNoCwsA<;hl$m_=3n*_QNX@>YJm z@b+9>easG$CCRoW4TAv4M6qO`p6@8vu*>QZedu7lx4i}bi%uYAEir8aJg_M`cx z9ZFs{EZoQwyZOlj0b08UjnTt}{HLRaMc?zq#7~AT+N{1jJ|?4&#);0+D`V0r7i`33 zL=-lHuf)6Y&g&y0v!>Zf9<7I>-;$bHSNbGN>t|94_uhr%A)(r9$*VP%j#dHP#1`)kGg~%gh^Yk zks6%x&qL<| zX^tCpU}34|0z~tJNOLy1)g|qW;1$Zwg>%zek>RHUFm*K1wfx65yNnA_v292vVj^mQWY4(p+sfymRhX!}n1W^kaKBasC z`;T9*u98V^Gf+x>J*Bi6vIbWCp7)srEySF&CT4%D<=UE#9CX>&_cx$gb&<%fdy}8| zX8q@iXV}3~JYE+z>N}Ko$FVvWX=sWbqQrXH3l5)30`SVJgFL-@j+e-5Ink&0<1p8~ zrN&#S_w%0$7;h_x)6u{^RD<8O>Ii)eW#zvxe$# zF{v1ES5Gz&Tz2Wc!{)L5oHyT1w-W;sMhz(}7aZQPbGR>*zkUtgRKoki@>`ITQl&Y! zjp>YV!~XSIJDb}dLSgO}Ru&(excQ^cRWehWe(2=Ced*wduW#S-t*n*H@@>btQb!B% z{wBeQT}MNVRzjv)q;hxrZ3~$9)F2G^T5ArsNo#tarda!kNx@Cjigp?rV!xw)!#}?= zj)7a}ST7t~KtFyrFI}aU0%-!q!h+j`T@;9t! zu+$924t@ul=W=wNS$RbKSVrWM@3eDyMsq?Uia2zdQepF z1@@K2{A)rs#mIfLOgF=pp>n645y2u_%c$K%O4z({&GJuAkB^>9G0uJ4Yvl-i{nXfp zxWrUC@;6BgEpIoUzV|{yLca#G{-^&0$0F7yep_Hskc>NtaBR@|R>pHdIA4}}n5#Pt zuXEk1;VOF#ulK!g<~E5Bor%eZmpd8H&5~W}sESF1ySg9oa!b$-`HZMK7yGB({!EIY z$*}=@H+i^-NfMdCZK(nEy!`t}o)&W@2q;xyx#_9R*X!)j^D+ka*lJYJPr`p(&aU=P zV#5#7>(;{fZL{uh3Nlr@^{`jM5<=9oeaQ|bo&;*^z;7D+r2to=B+PumI*B@UXKWea z8_W_7TA{4-EsNmp8vET;1O2+W|JOw?fWeqY@XB7@;*!Nvq@F`8{Rw@IWUKxeU;}7< z?QQhnA^m}9uvFNjy09?6-}Q+6dNwd$NA&YqRkL%9;iqTcMvnb0B3l^z`JO14E6bcW z&_Tc}Y8a6UZuXe}kRiK*FkiL`nr@(R*s6AqX<&dU=FU`79z8_C?0#^-JP7!|`z0v9 z<-aJGZYTHZ=I?_S^haDWh%eMNXbT5Rt+JecRN@2UYyQvpn)tAIp9d4ZpwyWjki)<* zQ@z&FPyeK+Sktb`An=Q;b<Oe`^PL zXI2Igpr>ff@K^glAEta8$czAPfwyJM=1}bM^n;;w{u3rd_n);wlVgY*<}?ei>Gd|L zEa_+4?Vj#z|FUAmEz5Zp4Pvm=Gq%5*wO{c2B`FM`1At%v=z$KclIP}`$I0bGL}}J~YJjjO@_P|EaevzIAy z)&iVg*pIV1qNE?ZXW9ULm*vweOOsa{DBSQiBxJsv^bc{gf%L_qGxcQk4-i(ghs)!z6b zmaYlFw0~Il!`H(PBElG`ExxigcMf)A7D@NBL}u>g_b1je+n@PF_JcF%Olf* z?W)G)&vsWCL>nrky?aspaa@A~#@O70_cO-FreiAv?$mz7V1E7@`J6#(fMM%i;IQ1WeUaliED(?L>faGbEQ|HmP# zMBa)QGZsLv(@zb81V|$W=ON$Haa0pbFElP?($6sQz2|0X!)Ge=yMCEDNwY|#_ODfn zki-4*y0!JB|-!uvwL4O-srzuVvVqqM^9q_xtOxHy^ze& z$4V~(f1-%-kCPLQFEshYtbBy&KG0v#&q+Ca0{2gf2Lc!hkyAQb2{AY|Nzka#>#W$s z|7WCsmZWb%L6zt6NQ85#-&pwEIIb33x_m2V!|-k)*1i$*yLWRoE;dNaY)qaVJrNZz zsX)^qB$wgKVwbvGN{X^4_yS_?M~Xyo}w zt@PE|;>OrQ@JlBdaBC4z0$vQR$W$Zxav`_(G2YoBX#CqxL_Ua&B1wUt{X>fUwRk8X zRe=#d7@`g-g&{!yQU~w}kXk^{bLQpslGjaVG;LqL8puWE5^<`em!Q;!<<*Jnx-Ce) zO_@Hfp#6>yP_h6A^>{$2Q{=8E;Nxnsd6b8}?{rtOhzFa;RQ2}tA1Oxy1FWcc%;T(K zdgnw2^ebRHVA?1eo8tlk0Dg$DI+x3VIVP3c6!nmC8+n!l` z8v1P~XS?e23eJ7gdctXOVY+;`tFM1R?4Bk*3L4A{s1h=G|7bdO+{n|oe7?fQuG(zn zHu|GP&9?CxGU(~@eBw2gcsl9gPwWZ7GfoCrW6Oi4yW<>)#n92v zClR~di!M~v);;{v#{1OULM@Bu;yR%IY?Xm(#C}DPZj>y^{cJ+AP-Pb1I*t)l4iy&m zzZgLkHqh`yd$D|#=(3a+)Xh?+CeD27j#;@sReffLu0<;5%C_&eM?}hC5i_=lO?wz_ z(EmX}@TI>+mV;~are;)DYaSk?ss!WWObi}EABFmKvo@ocG5Zsa628mT_GV}qyGWnk z>*=KbwZ*Yj1gAVLh)Ud5$nm6(qwms|j?jK5d5x8r$7SyvBD}(`O6a~T?QH3KdL1q7 zee{duB#S;?;A2;vcYm=Mnj{A9C0%LX-~D)1snF`{bzJye=7-e|h?EwoV3=S3WAXSE z`t!%}{;`u~Dl=AHkK@fu&*wF9ChPsvaXD+!&)dHx8Gr}~h1@a`(XWYSwhipeVx!Isp^6g~)AOcoLpg;dUxXJorr&zdf&l6- z;D9-=iVDnjqGy7`O`v4Qessi6B5%g+yO(RX^KO<*baAt7<;8Hvu9n0`TUQrA?6PL1 zt~2;LrG|EAa{q|HK<%O=BqMHp6BiO=(AvVuUh69G_(_;T$Gx+#497pG+2Hz8kV@P@ zz$ff;Ds}3t&%=N$m0hT{B%!k~29wNwzdRwN8gP|Xdo zj^lGwuCTAi2?g6lr4N#15Uh;0#T|D<1N%5IgV3OWE?36 zj}FJ|1U4Xz=I}*$<&3NghB}7c!wwy&f(C9xA}6aWA>_OT!L#82>XfCvUForO);~?T z8g^sJJAHAwuy^vxb(;?KrZV!jw{&Nc2bw9?hEC>s?Dts!~n;PS5?0Kv{dT%)E?qeG;dEg)3IA zaUg*0(V=aeKH2cZya3@UgOJSgu<361L&+qwN>|J$djej?HtvblA2x)7LYLduamwm+ z@eMLj$4xur>HVV)Ul1&2ruSOz`eWKn`@R(Qjb`#+%%AFcD!M%dYY2;go6j49jQ*%y zV??mIumSq_rOZlchM|57w*<8b3+XhOyvOGVX>BKHLL38R2KyHX?jl;JZy0RRww~}< z*2-{P-i~9c9J8EvJ+}%QkRk_pA(nmH8P>@OrvZBIKDuAq(%Zxf8ebHaJ!r+dp&2)n zPI>E(V#j~(;&yY8v$WuHuzWd7lwv$n(SCXooo8m8G+qffHkhR3^ay}Z zQk5Gz_!y0D_ebCRV{aF|oha8{Mr?Qa;wRze z!|G=gMklBgtshsJtauC2A&HB5-KvqZIEh6U5ZCCa@y8)CFoOu5RQNo`P`S@=?@XU zHd6uXY@K5$)JPpx<~NT>oLlPV&oJ+s1RBK==?0k$;em_E*=igvavKQy#pKzpmawWx zR#L~0oQ6@-nyUg91Vvpv*X);_u<=N}-EpkZsNSbd#!7;kj8WhR(25!%!90gzjB3Zp zS!PE1QFfGC0Z^a0hGUwvd3~LZ&0e0`mh#sxKTWW*3TP93}FP}VMO{v_t^iV zC@73wHW>ZFY)M}el4DkaZ=Lah@ZU(fu}vyE38>Wr^086P_EsIrWW)|SKMJN+)4#?3 zs2M{sFViqc4l0Oi>A0|USIg|hj0C87D)C?G<#zRZ$Ob~kS$|waH*fEyEdirV)6*Qs zvF|mc#O{##P2V%R!O0{fDU)LVHE0Mu=rt zyH5?VZzcM%*^!yKF3rc?d3ENzr3wv2gf$MOT zg9x7`(!*b}$ik3AX<2I+k?1K?xU~ONM?+=I8!pzt%Ie_xquhB@< zCd#n8L8jojRY;$20)}~jVdJp!u>kiAJo`CHuGWI{tqro%sh=zJd;p$1@W=(lb4ESi z%Qkd^B5j6&{wIGKdSjkYiw=vcF~a4IXM5~q#M&s&ZyvI6v1AD_(h1c`fxCHZZ%{9y zKIw1uX}p&Nk&m(eI{%X-{X7$JlO%LS?*|Bg!1atTr1H+ro&gRtd?h?gdu&EFr|Kxn zv5CWA9fuq%4fiK=AflTH4!vep0{Cr=Xh>MwFz=US!%+7wo4W7RkOPl1V|L|Jk~{<1 zx>#l%^sGu-ddBj-pFjR@v?2wTu@1Hj$4kBP5HQtyf`1Qp0R@>Gi@+ zlO)1`5}ylI0C^b-_IGVQXM;gnXt;H&58$l3y`CZCJv(g{#H^PoCpvHZlRAS3K`&Dl z1V%&qs0wJ~0EL8}^cw!3QJ{cSPYdJYi*pzso=HEo9lKi(jR^&r{UA(O_}>Fgz*9gw zhYP&y^I!^Q{X+`io2viEURbS{T-_r=Kc0O!`Sz_HcJh_NH=wXO9bB{!ajPKU=Bmarl`8|Uo3G*5$8S#ByT+TQL61Kegr%KCu zN@xCZ5%9byn)h$N_+?Q+Sisj$PK*)i1uuKIj+O$X+r7@d){EQSrGFAm+bC?K1Mz3^ zIBzH3c!9Ty(lNGZKoc8E0#$9bu8XK_-X47?2ULzx)NY@q&nyiXzFIGJvL&iTHW=2V0B)vT5-*3mqp6tC$ z`EIU>=?Vp*hmnkghW$rOzfO!)fzw$(Y>gG4cYVMg6e3QCY&0=&S~1@3_!$=JG)?fO zrhiUIXb%B0eEDMo>HV0CW*ubx2T4I(AOwF@Kvgb|N@bhlv2Ix0*Xf#y-`?RVgZFYP z@gt4{I?%to?gsr)Pw0{TO6>%O=6mMETQ<%*fqL$KHCYevs)sy#D^^*;16(Z)H^cG? zbfkHe6*LY=7j@%fXy*KQOCy{oS87Q|F4~aS0d8$HCGqcOpBt<*t2p>$8e`s;MiWK# zN>?6sq%<%mwVy9um%2pY949&QSGrA1Ub9Fd4Va;?Jk7NfL(Hz)?-TGR>Se|k+uiO} zu3IWIbH+ajyd^qWjNgn1ys;;vrOtA{e0Gbq!8=~L#humSI;(gM7A#x{QfqO0H=6Qt z;>%+7&2rzUf)-wP!kqBCj(J|ZpFpSf*1ntm&y~XZeF-VM^T*q=)mkw}i~#Su>30tv z(dH7n9Qs^DVXsFw-u7}#cN)p~(?E4|I(=%Fl;a?t8pK9jT0M}R89vA|$;8YG*M!IMiM_?o_V?R5 z)lWd7##4&?BboUrVvOr__K0_;_wl{FXRfK2=?QUeyDt;KcjR{d z5}$TWUZJ;4ZhN-<>J{5ZF<-UQzp#uAACIlU_pGOBb-S}@JJ~bXfMfHNi@$oMTJqJM zVfLOjR>q$Vk+Ry50EAIBFZpOo;d%bQc!vwkwj07MrM&Ug8-7n$)tWK?-q~f$QSn^t zLK1akzc(=$%P6+3?Y#@#~Wlv-6J{)fU&41lZg1aU6|q&$lsmT$w5J1Lq-1yV`%c% zP%yG(U*nNS>93`#EA!5X(=bsz_xlqV{2>>?swe79;fIfbc@4vEf!|eo_1;(r_1PVwuk9d8gp>tgOtBXIbIAr+CQ0&&Ylsmi$$&;PIgw(7p-g)^K)% zBoCObssbtap4ZjVqH){jx0O%bB8|s)>pS>EG7d=+-kD0&vxQ>3WWWl3QEaeom+wLDbVL;*^D-%K6OWq!z622pIL&4^%azSaRxk{1>8cVMvrl5fN>Rs*| z@B{MPRiXT0z{Z+Y8cb-ZQ0|<{HWz8Mzx1Y0Rg?(2x zTN8%zRN`IyuHGvqXWM42Cx@PiEqq(mQ(io>lJ?80HyK@5KecKLSV;sflx|NJ1CjXa z^6$6T?mEb^TdXDoJ!4wwSl(|!WNrvvqy4wQ{c^%-bZBa(OuizXvxu5E#Ifk|2p!sLNp8s!HNv#4WUX$w&2qVbk7LfSJ1Y6Xym>0Z? zs{>rqm$Yh)A|3Yx?b#_7f{D!k1_M(ex=mI+Kz#PBhARJepkJeYN7wKZ*(za5cm17l-gaNBx0EP=#Q~ zK><%h8%TffEx@EAqrk4_F2Q6Y=AS?r3IpT?+`@o=;_k)%1GN9*A~GqU{Kq+p9jN}L z2y*cCudRhgyGXkK?#BPMJi%XgKg?clNc~$*!xI3&g6>y9O21F7{=FaJ5e$VWHJaTU z^*_p4rGoNjyY67i#Q3B60>(T?1r(7f8b$O!oC!oay9jn;K$U>(-+}@V8NsiU038vY z=l4P5U-|@QYxKsPorTRinKKsozg|K1%VY$3Uu>rSUsqm&0J)TT@tO`I2_4=oY<&Co z7b0uG#5m6x;Qz-C4XnU84aasdbbs&+zwQP6|F-~<70k%_v%T`5`Ka`WnRkC*rGfg} z98fU-@t9bYzqal_4ge1|;91sfO*tF!K8S&*r-hp8UblD{Kh7U?*6GykCvELVlqO6m z%|DctL}NARRlHKyGYEU1$TdaFpIpkE{N}SaNdA?TsZG>Er3yhZ^)dO-skb z($7)d&vYwJx(1#FS5Kxorjfsj+WO3_QE16Du4$>wQe;6q!4z3Qt3O>5abwcwSeN1G zK7WO5Tw;-@n_1DKkHxAqWBod&cd{m96m1H4vhd_g%6l&ABhE}yO>B)%-cfIyTR_U7 zDn!~GgFVjP*r8;!ul9J)q>F-Y2>*A7eOu8MNGX_6@q<$s7E;hgz zGp)@lj}6WOC#Q)G%x!%pq5~EqyA}UAk;kA(B}1>C8GD_knel=Nt5UkDhI9WYlVotJ zDylr|3*=xRzWcN8P~?`SI&Z^z$hppu(`i@AX*qMv|Pt*o-n z<1NnNAoQ%06$(j}OJ({xx=s2In|!Rhl^Qd-r)i~G`SP{?to0_8M!kt{4+Cn>R$(X% z8g!+$#9=Kuic|O3Mgo!vIYDmKTZse-_(#M_YF(O^{wm3L-eX9N!}#Q5mrsCxqEtu5Hd2)^G`6s2G`2p6 z7xX4eSfBL_PJQHygSE6*LQ3{?4;tY>Kfd4_itBbq*LbS8;enGldf|8!4JgJ%sxN+q3$);n zh|C98t03XDRNYhj{H%g&3phMifk{RV3zdxSYlh}PW!|@z@ExsmG$!wwSlF1*W!c(R z8!q`eI}S0@NUWR7e(IYJte&jZ4Q33C$CoLSxsH{KJs-aSj5y3F8Bwe) z>2D`}m?1T;KXm3#ApN$~F;EU>sWd~WSfHOr?mZ%In4;Bo;s8apIp%n(DvHjE$_wP+ zzci5NSloq8ob-=&;PlpD-GqZ5Bv zi9)EXcde*S zZ4DP>4&;?_-?i3P+5i7|0{X%myGVza3W?^SuD$#4t5(lg8GbTEZ()*K3# z>nCIS$fL!J=^986!opWM+b&4$pd5D1*)R8B%a8mdTI?p%SG8<`qupZ8S|1*wLE)yA zRnBW-fU73Tg!Pe6ytG;3sg|xs{N<~#cFf*he#oA*81WnCGdJc&G-axt##o*dgaFU2 zGeem{QVUGxVvHBtn@(?I=U-3Ko$K}YkFWwS4Bkq)u#U6kzXD0CMZ0+8QzvzM;pg(o zv`vvMUefLOVm##d4p;|uf2Q%ftuCHKcX$;#y+(r5N?^et&9IQ1Zwg9(^{UKH;%&)X z_7;$pN$n#qC_unr!cF_i7ZHP$+TkevpFsQh0&e;gdx16L*Ya>`;n5Ub_2m|U&C(sk z#5u=eiFg|=W2C4g3H2fo7hXVC_@0S>URc@fIMp{DGhQntfIIIxP7@?*J9)>h`qJdN zVxFdhhvaSxV2rW`M%arwhx9!OAnH=(Gz}@&hS2vxp)+DmVFx@ZOyZo-r*@j&+3#`v zgMw1$MHoZWh`e5K!6ntu$sNVxEc6I2u>gh9jA0-+61z8`#51(RKZgpxae`jO8-KA^ z*Jd5^dO)0GCFs)FX*?i@E8H4A_|hW(JMJ|7kQ$KN%Lj6-abE>RytWx*3{=4i<<(Tn znb5SxV%G-z`HRXT=8#!r+AmL#noAytD`zy{f|Me66Ugu~6q{^8BJp}vsP-fTUM{0< z)nK%V-Q)79M@P)LDX_yuDVQdVM$vp{Yi`!C^hSigVHvm>sg1aI4A})KCsCbikAA1Epjs9yOZ3WDZcbBt|29=61CK;y z1jQ2K?l^1lkaS&`+K9R{Yx1)Bi)S>7`d?!(qH4RIUSaTZ? z-BKYYkrYB*DVYmxtaXo7-*(Lec$j?DsaW^@FDHoK@YlG1Hv}ZCbM~yx*uEspVvLMi zrg+7;@5bTjolHdQH5dTys2@OEt?Mr-RbY)J%kv~EnD#SF#J8N;PL|0aU+JNHC5T&J zfXPXDn8zrcf`g99RGSuuCv6(_I)h%KWEbB#m#6}rS7V@3>G|#y*$U&=0i3*E| zS?rF67Woi@Sc&%K^wyZDc|3J}yzWRUBR!p5 z7>4>o(!x$v^Lym>?VpEBy1bQm0KHI8y-n1FMJu$?N=I8dM<2zxIq_7({#Dux2Y)AYc;~NbCS?V==w==iFjzJRfWTq1-eah zaFE`wJYT|B<-LuWjVlM=26EkIMbYqqDU;>pK44S?oMyIgvpwl!xA=BRQ<8AUx_= z%rY%W!p%Azz&x8R{aM%nTB3XHg`1^%GTX}ily zv6t-M))u*GRtBkyvE#;!xvnLJ6St$hf0wAv!Six2F#K*8wfIxB#5;~$&daXz!ghPp z&x-~3pf*|%06%AJ)wL`|+EI1@2b#0b3+rAZCONXg55Q~1bI-u-R;UpK^}9kS#VNMY z@*D#*kq_(4lYjgQjRUSI2@NS>4`vyos;n~54NI#_+-Btosly>8Hn|?hSxmb(5qW2z zUyF>9Xg-EQgInd>K)^?P3?kF6Mg|#jc2ZQe1lGQwMs`YGme}LmfzM)|1;xbQOh?ra z-;r2f91U5m^@TOFw+@Uar{!Ekjk(4-epjvkJceBvbZH%$E@nwx=$LV)7mAQq0xiy+ z`a;9jnT}Vg5~&w})ji+vd96XqR;RLJ(I|&4=J9_?{OO>(U!AlT;n@v~%DG>AtWdWo z1;-Eo^j?Q=z}&EuHFY-e*LdTPM6R{rv5PGnp&YjWibF zqJkbT)GP$x8!ehMJ#%i!pMc8BSk_>}TOkTIYkN^QwmfVea$w8B(wTSotwof~SCSsl zC@U$hWMMx#O><)_1^b;aFATq0DW|^l_rfO$#oAx3!$^_T3|FZZ6#y-rYxg&)7!9B} zr~_eoHhI;ZzV?^tu>6RpCo^iGDuXVpV>`t9axG-iP&Qjm=9s?=fK=_;@Pu5F_VG+g z$=G-5M^Y(qJ2Mq%s#zsd#@bOx%s%7gP>ypSp&T|MZn)sY!&V0IFm433~8|w{kXFmk0R1l*V0uTsRo zMtc=wNF2W-1JT^ClHLE)P%TJt1KbCccnLw=n>M`fDgq#z6q^#_LweL8)8;W?!dZSc zYTq9AIM{@cmYo}x+9gWn_G;B8hxZP~Odz23U*a^RE+JkHh)dj{91bv=3;<4p@uVYy6qfoG;LL zs;7cdQXL*R>b*u-i|b|@z>Hx#o2-j>`-0)Ha?Al=HQMLY(8Qg25=j}8gen9j^YDi58jy)C|iP2{BK}xb{X$r{Il8QLM1k%KtB;)#adz-?V zYT$5%(_ABMw|CsA)mkLp(xo=}iX_pzq^BP6*t1H>`D*1HmAGu>P~`El#7I0~mUHBd z!hVCi$*}fQ)z=kA`M)v*#519=#~}`AY2U;@e(=K2_(lr{MDT#07yi`87rv4WlSuoE z{WPW~oJUOq6t@Ap)cO(qhjn9gqCXn#i1D>g$D&d6vH&ZVu|ooY{8z=-TT{#J4sLB< zBf*E;X_1*=QFu7(1n#UDV@Cp4I_ptE@#&oz1T=Dz3xM6nk{OEx6ew4MzL~~tkD31( zq7K{~I8C2u1=N<$g{Hz%{Q40G#Q4L4xbZ!dEvVl3-`mBng4F10fedj8G-U%i!5>>^ z^nTS80OI-mG|Z=`SkI3AQm!z>tY+DqL?9{Z3J*Je;t2#oln21KmGt-ZF zJ=eceH&!HHx8IUIQDFTtGBEXuR`wyhdtVt4Nr`^EP0{VjJDVyzu89 z!>`p+j^7s6^Kf<8dsjGK^xgx%_%JX@?hD*vN|dmzVCOObPCq*5>V+9kxwgu(ZT(z6 z(aEpaU&IHXNBm4DBdOG_y-y^mNn4eiOtDz#?RXB}I4hlK-AN!WMfW<$x93REXL_;rOxV!NTjfsmXbM6{HhDSL4qIU-Wu3ud*M%@pv=76sa#IYVqhI+ zoldc20)Bkuc7WX1a?nb?F6pM{R>A!TP|&Qt{G5nLYQp`NS`99BGze9I(5W-0rd9?! zD2#z%{l^s`GJHsKBOaDb)`M1<@0!PMn6#s4gL#8F!RR0iq^d`bmwlfTCLkW%=2{7dIw3 z(4{VA-^|Bg4(}~h9Q!-Pq#ld8GrJvQXADyNnZ)jnvS)GUwRz!l)b&`sPule#TB0l$u9vQkDTbyoMVVYg}COfK>%4k->(Xi$hbE7{IRO0Jl^>X3`U#N@%(-(Vgvt0+EX$mwz@{sM*D@0j zQMqa{BugO~Y?BDge7&PU~vX)$WeDXw*Dl-5S z1b?Xw)#9XJF>O*$82nEI#J}srYNIedHU^`8|29b6GsJiZcinCrwNhkX>QNGvd#HE} zG!b{e0-Bi|{7p!Z@>*K$~_ z>^5d+CPqFmCG#R_Yb{t}zRQBJcMYi;Nsc zU@{Nb0aI(3|6zWKZmKMbP#80Dl?xsl&sf+eMl-P&YevXRi==&eT{d&cX8k>RqBylx zETWB;uVJgdF?A-Xxs~Ea1$Y$eERmuGv_nOfqsCH7vF8c({`;_W&8Z~EtLKaL$n++) ze;LvdWuy73E6Q}FVt)jLEpsrC6L64}>1W8uL_DD9KlPdfz^JckwGlDl(>3#m3N2E zHH*Y}J>_{yT2+$y$3L&q@W^dy1vMLFly$Bi#6_FdFjubx|$+sGPsbiQ=_-xW4(n#5pB-Tuu`QC&|>0|v(t!XR3cP$5|KzOnA7Wu$w!hyNB)AH5(!mVR! z{A~`qX)BIjQFG>~&)k3#&x3~_NcW-T!8PP?2SSNYEf!KPxvS`WPWo-c9ohH(6yY1k z0;`uNbPDw_I5=GudZP^nOmGvVSi(~hOqpUanJZP5LU97rbmk1TDkl^nziM~{Y5dhQjQS@RI$3JL+&x0ZeN#ZDo z0k7GaeGnA;PKSU_l)?kH18wFE*B@f(hNQxbrf`pptO-FqQ+CT1`pqAtzC7%O-lbAj z{~TWW%R2sdL+xMGsa?HXxApf}UM%$Q5HObyms)_;`Io2r|JG`8Uv$mAJ>9OAHx|QK zy7;`*bMiw!d*N(zrz869*POG3=Zl)X#mW*sQonx??Dv+!UWs2_@ifw}?&7-28?UbB ztd5v~Z&8y2kQVlfqWo$T^6XHq5kHH*#6IqE(phTCYPA8CcAsHSDEFPGYaecL`EGj& z6=83+|KXYdA7Yy0dFlGT{gPN8cE|4^<(F*^S;^I8v3GxLyT41e#bgx4-)@|EcsSrf ziihbU9$jq41{8kV-2Y~IG=Re({Ap+33RIO>#uiF9Y1 z^^U;hHoS#e03p=dtdR*y$WSvN3JX(>ZIxiVa21fG{B*yA;w z4mZ&|<#vgbCiJ?r%!zOzI_W4IRpr*^6{{hNmlDfIU;Q>R?7k0$rJTO0S90+==~JcQ9bRy?Ul^%r@H;96ktK~YUDAgf`hF>&h*zJTJjabDRKv&+<;fAiNv*=rlp5-2RZECmJ?xQ-jPWN zLx!Aq6)w4FuB8Y*4qOhZc(D`Od+vB$GkNyy+sC%uNr?R1_B&1PbCH)K0FvlJ+!}M%LO*u9tZ`MKO#EkM%;2&@ zYXWEKq!OHlz&nD{#|3;fh$D^&zb*8~A7qLpJ{R79ImqHGmN;sQ88ga2Cz_&|vc?|1 zLi#4B2ow>=7`t*!7jd_%;ehNYi>`ajvW{p$dzN<}^Qz2=F$50uhEsqw6!SFkTFajsk@7zHrW_x?tUgjFwzP*PVwfF~C!op4At zsXH#ngws2iv=EaNNA6@VVXU>rKduyGYD=mm;Xuj$3T35XX8RqD68;{d)_qvf_{5`IQpnnF4k5*0@9q zs=3%jk$V>TX+T*m`fNCX8kj42YBjvyy&$rw;i)MCHF8H!4JnjqfZw|w>e#QtiSeq| z&hqs87g@(%b~iIBg_LfL1;Z8m$~vS!mXhIBI~zQc)rm2^4V=2A{nei1a5DsGNt1%0 zxEcndFimKlFn39tVNAV=8L&=pn~_KBF1oUi^g(Pm7oBSVHe!*8Wqc3H>T2IAHn73E z8I*V~dr>WAQO}_mjQCSFCE{C=J~qs;*P@`wYHkdaE%pc<>MgY|_|+wcDG-;3yj$A{ zCsaphlFK9GJaELwkYqJP+*u=lEv>@>$uJ!G88*2ZbGB`!s4$=!xL;`Eh`iHOA6J_kvcB*D20=HPIwOA;!&G;r-wnV3({~ z;01B@o4zIYdYkxUBBJD4`VCc`RcT}0f93$uZ{`Yh2{&6s;{+j7b_hB-I@~e9vRyqNy#sUR5(+ zvRs6dS(HVxFzv<(Kj%1F1hfL2Acx&lc7(EQAo43gi0$wWuc z@KIuKsDh$K+w*cj!wZCteUg0?osLilIZf<8khb&NYySjjyK<_vQaFj0v6DFd6a^=W zAvth??1L|GT*DpCJJsIU+O8zU3_4EpIH{X{8`kGw?(S5eyB%F_z5mR}AQhMiju5f=Jvy|{wgf-S=Uo5ND3>Vu9YbH9@rT{nb8#kjQt zaI}q9Ss=3^le}wdC2Bu7mwG}^ji7{z3W#Oh81VrQvo+j-2-G?NP4Hn$bL~HkKctCd zI$5pU@c3n(If+d$)u1IcgmS1Lu{Gl&l_gQhfI-8JXSlHwiIpUWP>aUyE^UV?pASDc zc>o87?dsTsI^3>6ka1@PPDM_ZWq26*pD~#My}peqVJ8H&T?ZV`!1VYUFlA1{XzB1Y z!Q)AoPOhE-Ap?1B&wm^_)Imtj;f^#G7`YbeFa&hgPSv7lR_Tx(QFEL3d++F;- zk!ByM3g8B*(q))3{6zdRpttH6TuqtR2puvCj_|T0)yjeSCWh{0;(u@ji!rvf1QPsK z^Uf2VzoUm`A+8$&CT5OvQBOs;8{znjo6_oQtk9pGkxyjG5RBm5>8^>I;~a}Irh?ur z5|h3fC73OKIniH8k6T1fZ6_6Ud;+xbRza6!oGi3zQt-&=&@U7JJLXDLTsgoyk&re? zG1IibMp`Lm+oOE5aIEtBsmL}_Sjis|YH8-bJ4>hlD@&E#kherR1up^@QZEV?Zl##= zkg`R_{0m1z`&ERI{N0-??x4$tY|?Nw^N$XV_!k_xAN=M)HFVKu6QFV^;Oa}SOZh<8 zY?ljXxVn27c{{9G4Vl9b@n3cYPO}Jw2$9pgo;G(;l&v=NWmIXNSl^vE{3U=c+lvrZ z#>ebhi6?F0#=BR`!aL9P?LWbV>dfS$Ue+W#xijL(eVGO#or1z7B!C{{cJPwJCb;e?WS(NJ{-_%@Q6;52$2KxNY0O*8wpkf1+3j+mM@TUC_onNz3xpbZG;KMz~XVIQ$_chxlfa7swRB*|=>pktswOhpe^+*4n z9f?f+?e^aE7rB((48tyH zOd!n`C?_mWFstW9!3Cn>)8+|efh>feJ=_;w&>6SGE1u?O9mkYQA+4*aLJ4CCRcZ-6 zI=qgZh?e?Kf7~Mak5r3-W|PSrgr8l>$mTeXql@Lc`86rwRNOEnfBPKcmTKU4Ql8d4 z`xcfIs1vfQm4stsVR59RU<&M(0G~dbE}A9^VBFu!+V@t6W-0zM+T#Pue#dbvTs=Nb{n#k(N7q!;0h0+q5+c4xr(p6m0%a7e z`Y=~GqcEHZhZ9gYK@@4*ENpkwr#5fBp?Sp$npybXE+f_3uzYw2I?v9f`v6_Eq9zMd zpUjw)R>mSq30)K8yESzIiKv%K6rB-yL>7}JW5Nj~ib{i1;}bHs0)hJWSiKWMGKDmA zwydGbq^`kY@Pb(5{t{Ff#xYuX9S{PZYVH+}ntWCwMt|@F*Lwq1v*WMF7+sHWiKW}X#yu{H%3=yYd}#|+*On#k`_V~;69$3w zPA9dJ6mS71BD7Z8N4=oVm%JkXjAq`D268fAl2$MNT;*HpGBVK= z31P2Wc;4>JUlp`JME{*a3VFBy6eYVA9uc@wiRJH3%CvMQP9ZtoYH3{gN*{b3<;`^yp{~UT1^5F@ zcFFY`I=o|B=A{s4(>2#O{azYVrpsz+gQf4*w84NI@l9NV@nlQ=cepAbxZ&Z~=I*fV z*ZpgmpRIZ7imY!U2}X0u`4pTA15}Lt7C-_; zg->y?f+9dws=o}#ux)sFsUS=?Y#BIXhVb)<&n*|h6pLo-(f{ zm@xDi+OT0fNw{_w8%>!ikVSE&>_$QTqXB4WN=eu_Qh<0iu}EcC44en8Aw@Rgy2vH! zLkw1+-(+7>{6aJ&c?K#k#=th@_wN20#(bP%aw=%J!x^J*6_hEZ-REQC#c%?Ra zB#&$CfgJJJ>!DyC7~1Z=H(YDUVF6c`k^b)Y9?M!8`{_%mh9cVQVh6i$DF2GW1)Nfh zsxC~=5+GXHf@M#4iEwxOqyoN z%9+Mm=)}CQ4skOCVtT%K!0rDlPylt!+LD&jfXLH$hgf3)s*76Mh*py(iD^s^aI_76 zqOb`vK^3B(q!2S1+=XudmwAkuRjM8LyCO-Q0h@wertVwP+v+)ko`Lo;S@E z1CPI`ZxzsQ)-A<{^0KXsebBX?-k3|}0RiXzFlr8l0uV`d_;gnW)B4Uw%lkH5@XnR9f5K5pJdPj%}W-86AKIG;5o9$pOm;R7-?6 zj80XioXW=OzKk}gxJ!kyw(7_h;2uH;JI1Ao#1 zxCiiki13Kg4Y;)M6tKvF&4h*t!O{CQPQGK~!)L24SgW7sR)FA0+O0V*F`Mb4FYX?j3U##BJ@FilpLZl zKds~YJaXr)`(U~m(8 zv-`LY+*hN*JT195SAnIw-v?H?FC;7cM3p`Ty^EH)|BQockKi?e-@DhiN4-N@`==vi z@5_j8urgKD7sy^n15jjQLNflZ-rhw!M%M9T5Q_+QnOGleru-?8F=Fe?A>%1nefXr8 zU|}&)pw)3}<`caLC8-g0 zE(W38wLhLw&g**+&(y~y8T01t)#r40PUfDvQrFx=RN8g>lz!j40c(24vKK2E|FdG3 zq1G&5ky;Fj@B&muCR>OvWr{-oXH7+ayq2co6rh_xSXoox0oXteK7a$~G4*MTWw7Ex zU16hmp*r1g;PsBtrlkUvFJr+hVMVVa3+AJ7NhT;JAO zHf7~DtJ_x^iR@*`uuC;-Uy%=H(l1MoCG97Mny@!h{S;`MyDv?U#;8n+L|5#yE3ROJrS!MnC4WH13R-jkI$N% zsZ7+fFwaZOa^g!i&+!&D}Y7cXuE|uO88>8quxurDVV4UK?WDK{4z}uSfx1 zco7|4-jKJ1}qqPkUmL+QaSWj)qkh`dvxJzzZ#lcW_yWl&VN>9(m0%a|^5*-$6 zvOMXR9PtOz01s~UEv_AqsF}dW0XcW^Da`DVHijtP)c9UphQ^V1S-nD~iMZ^pK~nS2IvEpKd*?rS{>EE(D-s1uq4F8aXY1HC%0d zo@UY!Xc)}3s5TP1>_XqW;+CDwk*YutN5G=2VVOi>GPRaIkw7rGHhidhg`9i|EJ1Zj zV*p)?I?5|c6*2*yS<&Aut~+3+{desU^5&uEp^Z1d?}NYXVmSrgm~;af5Iy?=fqR}Y zRy9-v)WQP-=z|gkpuX6VwUuG(#t@w1KiJJ4VqhRwZ#6~CgrBN4kTNg9oCt{Wo!|O! zRr~;!$BYQtOYZQ*f@_YOcJ|-TmAFJsjDzBYSTNS6ac@pJ$n>__XC2N43=l?w$Q#Q|R9u?CpvLSB z7!oGLmQ*ZF_xAr(p|uu+731P^IEupP)qiKY+*R&l@- zR?9CLetykcfmp8oTd{1Bros~eJGZ8g|4n9Og|#|rm#Y@AopO-3=Syh@iY}lY<4w6} ze1IS%lgjVdyO|l4VD9fT$z|V=*N=uVJF^LkuAO+R{$s_~J zYM|2nSMJD?(DNTvV~iAd=X2AGz?8)Gj&iE`zP#WCdeTyV_^(mXj5z+qX^!gt&HgME z!=aP}aHBrOe_ris&?$p0q?@%-=q&MMzdr@GM|Fut4UW2G*pT#}xs@}F z>gvp@p7-F^|EPd#usd-)I}l$XrZCun`oT)$yh&YtK=&()q*z_~Bkwwv*u6U|j(`rY z&v=`(lp_0ZD;<9TK=zN876UI@68~-bv=&XF!i!j`w1Wto zncy;#w?4)OT)jc$@)yV@T8;`RdUt{Hj*NYhSKiX|TharB`pFic2rGN_jt(KReeF>i z@rOR2^R80`JjH}Lb}1^>W;|Ihe9IpANb3yiq4`A5Au5sGWRnf6RK7A*K#tE=!82%7 z%@YY<6&H-k)dSI_FHp>l8{Ri4%>I^LJsCnS@2_)GJaGEcfk>d~Vx>;upAqNlTPcM3 zZ?c}4l#z7e5_+*gk7WV&2)W!F@ZHDu1RepsXJh2o@lA0r4#YVIJQ!PH=Gs*Rc?h#) z%n^=pb;Pl~h>K+~q%ZWusNfk2z~F%Ka)niD(w$oe{B1~O6I?>`XTDULV8*=OeD1`aX+z)WipdI5k zDT6Qh(71sh*=U549^H^NQ1aeHQb_IiQYd zhs=Y&-DrP6S9HqC+i@-6e_Gz}8njXzGvp}%%{Raj-OOW4t6heZU|j+{jIlZt?!PU&!^{Wu*R5+YfmE#)#@MWcexhKcQ z4UDQ}Gll;vSn&@9%co6RCyGFMjA}d?Gra==ODJI@e#7K|yak%dCOsLOl$|qv8Rn|T zC`Bbt#eX_w%I+e10PQ71HdBBUfyq(~?CMO`QE58PDys-+uhvsQg%qRVnJ}b&BVFKXd~xv=1ESwY)| zmE6AR|24h=#!#M7%{wL$xw3<<9hyZC#z^^zSSj1kQ;UM`++yhr@GZOPP-Q1l)0nTB zy&;x~3m7gI#xpb2Aqj@vui}3o8F4`8s{MY%lY*_7`7-AiR;MXr2K0aI^|d}5MJ8y} zdn3^ExVp`Yg`3K~?7CF}5d^448lZ*&fL+Q(?r~gk5$iTOA5p%V>nk-)iEe&I7bx#n z9j75fK*G4Uv}6T++0-~? zxqLW95>frN^fsmxYI8`cRzR5V^soB;LABUTYWDT{`R)EwW|?RIE*6H44?2HgBC#Nis9|KTll$$huv=TE)goPZd4`t2pGxmI75 z{mibkv{L2g-QTdVteG>`ZTW?Ub(es%?xnk12X3AMb~L1pgAT!33v?g%SYbw84^W0C zeQ~GW6Q+#O&laB#a(A;ca%I{fC^i==3bkbMwrF~_>f;~geK2x{jb_j;*Tq!Uk5aXj zqQXXjCLc}V;~09wan5RqIgu^a(+O~+lqRk)8l=J@KCECK^}wcP^G>>u1A8GI+klXm ze_mWSLStwD?I?*-L(TxbqjcV{M=l%HuSJgI@+RB`=@uG(fB!!kpN3|WBFvq)C$gV^ylj?9^;7tdLO$NZ`kwUh;`)d(C8BYqqkU#^rxgQ=3 zSE8`iT(XXUvna9Q3f?b|23)l{npgcLy#M8~_&THP*;-Sa4M%E-P5uK-Ja1~IN~w11 zD1b*_lV;YgwBW7?=>ytaX-Osl!tu*N-Ya$F+&k z5)IvV8%us*NwJHBzWHcJ?aP_KM*jR9Bl|ds?3az&m-ZdjSLD{&Y;Q~clMsyDQ8g^> zjP?~B(sK%a>6Rr51wj9+I1aOtP=~A*jgy{&azuJ+o+hyHm}CPq&!h^8tC1Nb-qk=I*&1MCn>0}f67?`Y;kCf@`IU7H># zzkN~xf5{7#Eda49skHrTyl!ns5E9b8yKARcDU7|}nf`L?UoZ8g_2j-eT`4XMP9*;N z%k9^t{1jcNIwGOIz?P(3YdAFF>TKnSdTN48VS>_tCGXGkQteUO(Lx+`z#jU6_5vVM`j$aA+`36Z zKru4rhq%89c6x=Qh?tgsLt!>Mgd{%I_dEwIleg1veV|R%SXgt&+*Q$IX(xM#ZHa;? z7J7a?mzFRYUj5MTWBq&1ZTWY?nVhD0$#T&MVqIxj!U4`=lZ*Oy-JM+B2h5?JFR+ru z&wD!BPWq};m;00he7p)=M)Q?50b?Cz1r-l31e@rSQ0b3nMyr)T6sQ zQi%*VDz3L>*j`*06xgSVba>{RUrbgIKioyZ!`90{*U7I^L79h+N=E*tDXme8U!aDX zh^Z@8i|L#m2B6#4#LO?KSPihqTA5JuamSvJ@wwp0;AGry_K}-M7l4!YP09JaD>g9o z+4&PNQYdt=)>;&ZCFf3!!+%ICtpa{4h7Vv-An<4ao6l(Q%d^#LjkaC)=Zh2FSD~fx zo~x-|trV0d-tPe(uH}A}kmopZshR)94cLn?!l>`!C*hsQ#?|YzTL%e)iQnv5mwoqbrS6Os0B^U59D9NS zU$!~ie)~*{q}c!Rv58&pH8Xgn$#MO1Pc@GO6hcQ*LI)F9Ur1GIiYkEB22L|oZ!jdS`!^5iSu zgJQ!C`PqL(zBJ{|;AZC3y7(OFn;V~by4!<;e+-^p`6=KKAh zHmU|ktKXgLs6W(N;P+xS#Nu~h8y@q-3xn-VzLcqIcRvYvhAQ89Ze1qcr>$pRY;?@l z`po~kuXu|oNQHBE8m9h!{-|3yl_}ZgWBm?h2pni?bRi+LIvp0d-Ky-kGQIyd9do;~ zoBTQz;+v;qxwX3_k$%&DPnaE0Kgb>RlAOs!c%KaKpgV31@W^%U9ZauHr7z9@$*?-8 zaxHj!d60a*te?L7i0LXKH~8v~E8yxx;_haSq@%{PMbvMLUcLQfbYDM@E_$+*&~*05 zO8stcz_i0<{ja4a;b7wZg-5_`3u-QN^QUR6*&MovOo?by8vQ;tJ+%3`29yF=FIXCG z7V0~i-@LxL^hgMfR}J__=>B1)F3u(#hmjuw2$c19g`ZA<9l27W0l^%=T}icWY+zOL z3Iar9YrB*`9*+lEiLf=WH3gPHkH4tHK~P7Td^@g|#S=l8yXt?Lfh8@a7LaW+(t(^z z$yTg3H>7Yhgex#*7RVkNFa_EuoZAy25pds~jouf$^>6&Lr{vn7!@^63sm0-K6jyee zjSr94hp=~im**2aTqJkL@8|d~4r#P$$-jIi{nG(Wo7zpfEz99w+5Sgu_OZ9;=X+A> zW_7sfNOMK*0YwdrRMD`2b>YK)z*_qj+{Ee1$$u~5b8v3a=ad<>cpvC6B?E86^4G*; z8GCF#L+HGZgnB{oz7x>X(ojJ$xHU=dFi5H8~^l(EF;GlI8aUa4z0Syr{ZXx!#=FzYiy5ts4bc6}jtyzpM>unfx*c|o{j+Jth^~q4NMR5Y>QtcB8d6-6H+_Y(dhI$7 z;ZTQyBW}5evpm$53vO6+X@ChWe3sFt~@;g+bJqoj)Q%4KNur~Y{;(OC^`Xedr#!lV8BneC}`YIU< z)P7;=Pec3^;}o`@Jz!aP)PQ)9`+E`|WRa3cE#@k>d8tGA4WlZJ_1bG`AERQtD###iED_rAdT4#?g4o{k{Wt zu_I5#PD%+cHDUjW+?nNIq>!l%*Ptg}+VA3gH><1bDe2vb5Tj8zv|h^R4Nq?#%gRZsizyv6Y`NQv@OrqFr!gvko;;4C&wsIxgl!es`p_$1s` zp@ufI9UN`a8fJ>Ebl{Y0-yu!baMt`aP+@DpxWp~nJX1zOctZ_NV>?~VPk!}Hq+_lq zpS$f*?v_{Uw-FC&JS^?lHl=U4YrLMZxOmWENv}Sg%@;ZezYLHlAJe2w4h5+o{*K7U zy$Mq~)-7o-H@!|mRxx9;!Zg-4FVW?Xx{lDUW3p#b`{3x`a3=!?W-;@xUa=LXISz$F z)NewEP3K#)-ppZvMq3@^x+7Zyu3q_{&UAlTw1Yy(DPtHJQ&txUNjc$`O{0;TXkbCS%idc(95P`6!9M~tRe^ym+<*|2ml zp+apL>#(bScwUf%F_j2z=#PDYTD1~?PJ>i(Aw!-TAbes2t`jSZY@^9!#nB zRJ6w7YM1?@`+l@EDrVNP*j4`>&wwt0%2VGgFKm&WCkqU^SgB}5T^pSrTisiBlvXsG zmhv~&tJGUZjZv}gH3_R$PB`@Z;EN-Y$>=h)jAPb>$694xm+qAPIG~N@uPr}-y9Ix+ zJ7bj9kn(j#x37vQf$^*tQ5%azQC*o`Rys3kCH6}vb~BF{p1n~NQkuN_QL5}{=OfUNcvs-d z1Y4H!v2hN)BfQ^f8S;^}QzUmKxL>}%io%Rq{p*Y0>zqJxImja_bu=Uxsn5v!@&}aL zkH@w*%P02Ed~EVhBLxG#yc;?Rr4l>p(&SYwZ@v31W~d3&JW?y#2ND z8jNB6m9d6c5D4u%Xy7s3>U1B0sHop#2ukXUw&fe&J2P6^7T**V7BHSTt^t;KdB1`r z6|F7W@1T6MDk8bV_aiI0exskr>ok!;N1eRkOds6zazy9rpW-pbWF{YX_YS!W1$QRY zg9T`X!^SY^5KvIzQ?2x|9>|u3f$mW<#x@81&<{^MzAF$D5|;2= z3m=r!M@_d?@qbtV&(ISv7`+QqflR12>v02xXoYF}Zx~}Ru7kpvWHIM*E(tbz4;0hT z{BeM@B5P-0;Nv8^XC%1RkDjiuNfQ&q2%{cFm-qBbC1ax{n8>p}>kQ`y$Cz!FqS&k< zdW$~yzgaty|KOkbt{k4cZ(8apv!WRewxhb8mB@~jKl7%K9>3*&BG%jTjQ+CIZOha- zu5F|9hmc~2u#51i--Kx!wEpG!xcZ&bHeajR620$s5YNr`fq;(uqBH*b+}*p3(F42 zrLBD5N)o?A72iFbm$cMTdV{`)WNekC@`&%3r|4Qowy6p5KBDQ?gtyNp&d+B(EBOw= zE5zF~)RgyFcK_O`C)^YAC4R{|uREtXpt=Q|HYHuoV=gDX8Lsz{f*;IVZ+30mbj#7O z-*wg^iO6HX8W@GwOd*oUos@hLQ^wZmG4G1IS%|cQ+!gfVBoRV5;P6#VINm}BUmwA4 zdOKD?mJIQejaL{Uzw}E)G*zAc3T1@|I1`uG8?&vJF}X{>1Vc|GT(|S)uDgtX*g@e~ z`<@`U=qD7zZ;U$n$4HcS^uNQcX{tpon%8cRh0sZK9K{o`JKZGj7G;XLdFON7CdVLdgR)hOAEOXW8610HgP4&Aq=8~J*GR2(Ju|?4!mt*hW#j}((_(m zZDGP)cBL+{+nMGL%s-$hL>FWN;dA z)5INc3G%kVjxFq#X{MMR`t7ViHkiFB7zcxBz|v?Q1HCV z$gSyZ^4#wg{Q#Pm2}GWU6X|aVCn*XFN=JboY~eZWA+Y8Glt+On@MXk!q2`twK2QX@ zHySmX@u%!$X-Y0qKx#6Fum>zsp}ofe8Q7t&jiE@!?Ad-n)=u&QcHFSj~hs zo184P8m^Cl6LB?Q_@VD4N<@Qc3$TOg&%~S+j%eDb@H)1Wu5oa6NV|PRqbox0tp~qS zU81is`K!K>wW7lQNJ^9)XFLHX8ibhIVF8W;!4JbRq#9q zKN7gbL`BC;1CI^sJ!oQ=?&HEK^GMrdkL}az#~wOQhDn^5OHhtiI9l2oI96WxphX79 zr^*eHIwhz_l^DVJv5(3FaUu(63D{_3GG2fCeftP)j8Mol6&I8x%Z zR$b)USFPG9L}aCXQP|c?y0&u{?fc7+fOLIG4C2cC?|OA`R40@6k(uZXzFxf6E^xQP z#}&fU*^A_gSPS!KUUbmLiGvF@6QEsf3swMb;4ODC}-5xxQE3Rhj*5(ss^oe3L0}H zj?h>bm^6@M(n>d=Ns9R-?c}Lxi%l`!@gc=1qbP3wFS4aq!HQFUbHezci`RKDF%TbJ zR{Z8`4`M!&Bt9qhZKefELmQxWu@MmrNbnf|u01XsxcNa4jt}~Hr+=Bq(wB(78hJzPn{v<0s%2Y!HJ_U?lh<6f{4C~w}v?9Nq4SvlM;Cy1y;|qxpE&W zT`Fj$KRSi=_#lp!s%R|wletc~=(&K70UI`3vwA{c*kj$!*BT(D7f#Ez&rP1#{ZaIz zMbx89+tD>W(xhS=vQ9(=`ot?^iLFq9Y;A*38u&!x7TD`l-S1>Ya6CN3vmc{I@@S(F zL2-7mNo#D>?%J$~ejU$`8gfc~`dGK90P&R?O8Lwb0=O zXJ0H#m`eCvIZOFT?Z``sO4=!gP~(Xx4Mtu)?!EO1_jUA+K8fgrV||T#3*En*w_(?K zckyU7vbwUuG5wOaUg~S2fpVDe8SC|&ssio{*PY-pFB$Dcv+3Wew+5JiwzjV-X&osd0`<<-xUhCxzljD3E? z!7mZ7VK|_Ln3%wPLUmJD7BrO`?a$V;Y%w@BEOkWEo0C82J8@5w%geX<`_k#-0* zBYO!hsK`lqsb}cvhjEaMDp$tt$&Jpnfqn`ZEtl|Wk=P2c5^yx&nbh)MO_ICkvf;9R zS}cU27j&;X@7lo9)0j0isiZO4^155zz9WjoDL#4j$qy7Y-v36&ECkmC8)pVNLtucF zL-r;xSC@iK$1xB0h8v5VxTMbtEdKwitfOY zK-yL1y)YBd=p$Je8z zVvXHpy>Mq+d?Dbhm~OW}@=~o!7#SEGvda_g?^u}dL7d9#fM_)9Kx7}qg?HI-#o;sH zhjOlTD=T=BciYKl8n01=n}vIV4EM2Tu?h5Dm*KArj5JU+hRff{1^4# zG<)C|@IR>PJKLBG9EHYxgcn|bjx(IO1Gpuoqy7AjbBE)@Z*h;mGaIC@4FaL7LG*u^ zG;^Xh)sa#S$SHkmrWO86SzAdwxgi}EAsll?@4_!jz{EzW0AI#rHO2x-Y^0E=q0l|x zC=>GaFB|kg)$0#>Boh#&K7<@4_-d{B{F1X4A@y|INc{yMO4Dz{Dc=jHuNJbTm9gbFM<|#PY1exc4;b+48)8^G@Xbblj zYhj&ql9_^$<56PgzDGVCF7oBzXagrH4tdl{Wt|fF?117`So<}I7UmD9Car;qSVB2ZU2D@+3KfE|?+aZKr^ zyoc0#xvVLsccL$USQ|KjSb!=n7wy-(-RHFPSCLkcJ@E!_w*bR!MYFm!_; zAl)HIcc*j-NT(p(o$teM?|sgB_djx7T+U*xXRUSD_j5ny3v zuG-7MV~x-JVtaA6fZ{!6P>v&wGxNSPt-!e?0VTW7(z{5cUiJ%KBGWqn#fu6vf_TxW z{HQI`Lirv1?S{Hoq3Y=Ao_k1pK+1zrSR_4@jN&eLrIWJL(-NZU`EDP0g5@1jzYh&s zNC1T`E&$vK$sQlm_Oo zMuKxj*uRo_P;$KS`iZizlgh^o_g#pwKuImJbB&hOoj%QwSV?5?&TSO$ye#52LXDFu z#p~wk5?jG}RXNzBV;QpVX<(8Xo_J}eMONECAw0ZiMRy_1+3Gy*T-}PKE3PVOO{kT4 zHSx$k-BXrMw6ejPyy~N$Dg*VZu1UYfpD|(3jK1im$!o>1f^oKxI-)SKQiKVz(P(#^ zL29`{T}%twxuSp~+l`L&KN~rr^l_?J zx>%T~Y(IhGi-rVjEg3aGx8b7^{g+r=l~pR&qFn8z_r5EcV5gzg59BK;FJ}D)g4U-+1R(i42s`ULWOezY_E9he8@bYtTF*_KHNe+6ttIqn_ z&?%i#0DR{Rx0bdWkl@Bv<@f*(c>AGoZ=v!q=LMD&dbel^I!T~%${-vk+OOto8b&5qmJ;MR~c`0?r|Ux)8$un3>F8cO)=w!u5>(bP`tvMS2XZX(cx3LQA@8> z5a^bI$SY~EY|DYU5jmqCB+ptAwRyviB6#=RgW&W?_B&X=?u z<9AS8=@Y#7V?!mil?RvQ_IgMOk&eV;-rN^qqlKA&60_p}h`#-%^p^=`V>eagx-UsY z(STyzX7|d)pFZ%Zo;y-S&5Z-5NCuR+79-Q>Vkq=4U2#uZC zLWb>lWDn%P>Jp|)w~ur}bfLOR(ZDb#{Nm&KS0lz6{Q=#c$Ur07P+#x}PiHK2Xv1qP zcASc&20_E99drI7Kov^Wf;|23S|)eq_QoG3Lawuu4v+ zwZcq=$PMcI-JLhTleTYUjiKx|gL|{Uze{w>v*7#rl)a>+DYV?dEpV z;59d;hq!(*m*^+w#b!^6e23xT~E0(KbX9Yze#GlYJBDMSXo%O z(r|vr`-7Sf(|2tzQ+EAnllo(p$FXrqemu=_$dPwLo!23?8bYLq@2&nVZp80k@zO;> zmGfRg2swrL+xy{Hj~T+z9)C!lsQW<2ocPq~f|sd!LQ(`+D8+0wGjzWd_c)D~B#q00 zG);lB!G#W*K9?E8V4DHinb(vg)5}1SpQkr~bxMDct*edBQi~&%y26j808=rD!Klypf;JQTj+9j8#>>L20)%sS8KZK8oUx0UncVFMF(P?9wmF?im&Z~yqvZ;| zfT8Y(;xdtWl@8t)n^T%|1F>-2M?$xlvl|GcF+PZ(EM`D0oT9m=QuV-%sl3m9$^{yY zXE%mKt~>B(YLa>{a5B>62wBSsNV**FpbVt(;q#C8J8ml0Vidi@yV8v9xcb|eV{H*2 zlqy`yY*(GM%ac#7=d_%N!+dF;``J}p#rI0yXZcoL{xNcBos*bK21Ri6{mu!nrg>jQ+G${}dG7!}w;shR$y>q|#3U#a@ zb}7OKBJ)H2XX6im;^#!_RW4=7M{e1CRYh66B|2!m45DcrrQ+>;vTQ|lvju4%nVDIc z;=`U*4L&0QqnEVf#!Pjc+@K!zny+-2YgQ4qgR})X7RFxq7VH-3OkkxmGBp#ee4d1m zbk3>LC%X#y&yheLq`D_2ASFJNsA{Sm6GsAl|KJ|%`rY31Q}c9Y>@TKybo7vgfe$+z z88@0dk9})*h%pAI9+4}O5o=#@PDCEA@AzMgk%6-C_{M}Xu#HtEj_vFBTi`atYGsj6 zK(D-otXP)6Rgen6_c69{drK&q7+>a>|0Gm)R%!YbL+!rfTYQnbYYF+tNP0E3+%1A| zisX7kj1~OlBXIimTnI^8auQbN#gAZO(y}osHEt#^m==x@WKdLfVv*j~F&8o%e1HK~ zWonJHWT>XYF|yBxgxNt-)d9~uz98WAyRD!c+q=Z{;__n;&^o8KwMxk6qMwl1Z#jZd z+M&d?#9h#BL0N^h6f6^}0HPcwM(%uO-?C==`@TE~`K>EHn{;Vy2e~;V@;f;j)LqO_ zC-E}m#Jqbd%hFDoHo8%_`AFGGD4|H)={F2IAW;I7!uL@>7CIdX>>yb3wWx}-63;4v z(y86=@u^+@7Q7(7T6`j@&`d0UYBliwyYT{MM#{(5s?$?Hyzue!tQ z_&-ZR&by1M?_NO&RP_|YNkOYjCg{b|J|`k!N#oMhDdB$UG>_RI0nZ6M+MHs)@;pGj zv{BV-AWTNpDyX{+a0jVcLkd-(5Tk;e$}YomC7XX|6e?{$dp#6TV7%Z9_b`mXoX+g* zYKn}w@mmaAEi3lHnHVzC-XOELHMmZ;{_8bHU3qix=tloPJ6Y8X9dxF)67jW z$U`1Y)AVVDXNE=>bNL7XjBYD|gl`3b0@hjDRYCBQysR@zDesuzC6up*DmM(MspGqx z6Im)qrc<^VF9God{DS445J!!E>-X2#E49%%)Ts$X>fOoT*#^Nl!-dnCGO#t9KcWeM z9Hf4R?_7iIn!}FOH(o=WmqpVnSxaff&I3QG?j|-YmDQ~LUD6V(51WPK8z)sy{&-`W zCKpxSx8wbHKTu%Wn5qU$3zY<4@@tFC7`81k$v_xjnMM^5RdDr6P${(rl<(yxL2*+P zCVL;8*~aAXUHkQ%n(vvGf#+%rRg=;y@{4DABBt&B=IMS)X*szO$wb^Lzt~y05_JGB zw;u|pZ~wQIaY!p}@@?Nm?`Czo&+eYV^`dtsE<6w4X{GtoMM*AO+9ARmPGRo&<-X_G zTOW&EZk*fRB;k|s!l%>gf!99_9Ou!&KldmBS?+lBJSN)r;Z?iW3bn|euT43Af0j{? z?uLK2of>2cKOCOEulR{9h0p=AX#rjYBI5RKztsFc-a<+iFW903uFeJ8pD2~YIzIyEgd(0KWwcmjEs zTOy1>oPn=klZo1Qhjf3&a`sL7_%ub&@X z@hCU>9q|n$l}-sMnMouQ#1z{_E1$6_sXe|3ECG!<@)&XR4B_o@>;l&OoJiMArI#I~ z>;^v!`=#D-+!}JgL!_;`$Dt=|1sU(t@txG-$K!J(9Mwz{^~fs6AT;(nc}rMLf&QWo zC_9AbLcNiD@Td7GrsvT)42BE21oPurLKq0tKhz%d61jT}WcENs?~D~B&9Fxv)Pw-{ z3X@6lCA5{uuA4jbmi$AkS80_REyY|(P{SzYUp!taSscX{_y*%raE_^4yZ(V=cbmhR z)Cj%hFu)x~zPayjhCg3rER`cthFn2i?7PRp4VYasGH!DAN{Y&YoXF2iDmt;^xu42_ zJD?I$ZlU=Swh1jm-rrSlO%`Y9762wNXE`jMz>PC39xE8YLnN4gA2D{ckthKDd}3^F z?((_Hv(V+Tncvgo$e;c%*9Eu(rvfODA&gKZ%nh@se`nja7=F9$B{qzo9Gd4Y|gWsplq&=cq`hPvzNK=8^>ow?bb3#mE;E8{g)#0?XOj47JyxFkC zo@KVYljEDZja^bWuSh`u&8nz^5>rJBksVyk!( zipE??9!Xq7j7EvZeoS3~dmclIGYOS}pCuDdJdtJ=p+6{cntREIm_jfILy&qZtEA{` zBUb0G!W9$VR4>RX2(2Y8t%b9d+G>v&69K*z)}Xl>%D59!_{u~pzR9A;$KEd+3?s1&HN+k<5p##9DaNSLX-OEB_q~5F4}<_}0kQlizZ=3M164P0 zJr113HdU5!_c%jy!Ld{uK^yiY(I|~buU*dH#xwj?g1Wy99QcmABjzP3fD3JikKF*H zgARNEDc0!@`;kKar8|0yrsN~t?>c^Fcoa^sDH$leya8L&2>Kp>^U6$wXJewf&zoJw zdyNOof@%VXJB((4H|wrmNz7ARP8zms<3}LLKhdQ;_*8Cj@?D9_m$?}}d!{Q>@upVQ zgilYlj#eEFh_={mb2@1*Bq_0^bW&>g=x3h&sYVm#$X8svPF+mF?=R1k3x0-@qFTvXNgFlP1@;{{o7j$m7t{_9eN@<2>8)Z8Z zYB6u0h|w65;T-rj|K#<&buU9k1?M%`-_$5hZRh_JN*@C%Z>6v@##lQtHBH%Y*LC8- z;pu_=*wKRLI&uRpGYA#Nrs^NcCmaJ1ihRxs1DwslcLvJ z+K^^hZgV=3K{J5vF}q#8D>$E~W1FM1ZvCf05Eu?I(oK&ae)De=uDUW0SN$3ysP(EB z^Cymwi{%a_+JUhB4KE-eB_vGezkJb=g-e&NSxT3$6QSp+t{tuICiX{G9F~0n&Ylt9 z<51-TjSEnt?iDrDP$8zE{%>8nSH}3wX~IA)oTH(fHwm*v1T`$fj%|!OX7EI{^Z+?l+$hfiM+Tf=w+|*8lbNj z;IguPM-tGY1}1cY8Xqj*kQgDHIW>_8S2}TF`Wbby!#nE$Nu(T#|E(X9OgJW=CIglI zVv5p;&9#>vuzO+pRRRyKLmdg!hk*pV*NzSbueN_zFxK_%?pekDktTpbt&G>mxp49# zPO0O@{l4Xo;agnP$rs`jsm;@jONql2XpK@hSX zsHYxV9?s3JfNBo9&*M3=qSy-n&Tv<`XF*90B>DrNH|qp8Wgl}5AL;u*Ke|>+e=4bf zOhWs7Nl)Eun>DDC5qY}%tpf6k-j9uc-*Jo>)LHMzE)y8z_z=?!~QjPnOO^hNaUiMldC8e@0po9$d ztFbx{7|5q6sdAg%W3r*{u*w83HO+`~x+|I;!gP4sin=BkSs7tyaDo`K+Rrk{OIGeXoKkJ0xM*olj;z5Nr2e!!)#=V5Cj zYRdH5$qQAi)bWrz6S}+EPb`StU=|jPUCvlC@ol)eA)n*-L;XfOvD##r;alK$slQeZ z`xnE;=+*phLpIFQSrBhou1CTqm62t@}OH*QQU z=p$_H>^04D#|*~^9&F9ETNK6E7`@HAtAVK#S`mO??HUd+2Nf$pmXNA*aBi0(NW32a z8Tr4$__4-poMpq}#5gMz{w? zR1+DCS!gn-w5HmBZvX7*WiH}^`-lKTf%5IKz z&9uXm6;xD-%}b;UjISDCl7Yot))h3h%pEHkGZijE- zIV11;S9P#em6@=Djo%VVXJ0jp^Wh?xeiu)yAV997yJ3WY-`cioVM1atpo8n0=EzLQ z7lrne)%_x|;S#fvTqqlBmS*gsh_o08R&en>%&ZOKYodR2`*Ua(>`!jIW8OOa!BdZN z6NQNKW(uH4I1$nwhbv`iKxcBQBYFD6xYHALppa0}j(9ptnhAt$ESWd(PRDwTl~~Ti zt4@FPqP^%E0)J>O4B_Izy9K(fk%y(hrpEPyFTdo#z+p8rU7SQcT15%G;J=mlYjlDM zN3-Z`N|&gG*i`(EirSc7ueWOj9$DNZl4 zTED#Zz0K!G&GQHxgj=RDArcppl<~-uiC-mP4mH0fG_XD04bSOR*5PG_(#Fp952mOC z_0<^8cV);wK5T+<)HRX#wk*n!-^czoWN=QAHDjbJL$hSu{%V}+s3!+PnW4E2uOi9` zjj#tQdiW!gFLg1EaCoX!%rM7d|45ZY#}5MN4N$y5VXh{y&It8$7e&Lcl{YKEE9a=) zU_-Tr-2QoSzN<7(<QG+xc0+0j zGzR-2I%LYMh3TDwD~P?q0ok1X)5nM6_pk|l|NcKTyFyS7>P9p@A`F&1uQ_Uoq;~}Y zgxHFI#~bZ;X?hqtRL0#jgXYzdf>xF(1YN@9xZuUz@JL{SCj`Z3J&qlj(qW1YHYgLA z_JpLMNtJ}z(;e)O+e}lkn}*+>(E7g*c7bp`N$P$SYH{h_+CwjfbXxoq3mmaY2=Q#E-=SW3I-iDIuyN z4f0xLt@vDSRLcVGP|CY+edCI7gJHA$CNHal2`vHNtBe5##6d1Bw-`EFa@7<;8imh! zU(Ky}IaB@t8(;4GR8E_(^b*!<7x)k!^MiK;sh15vT#kM2k2Q;S)s~gUgly(_P6SCX zPko1`>n0}6>>Hr=(^1`;UE37i`hDWU92tlXHMA3;W=UN!JkTGtOutkibSF36h6~Dp zdL4OInE=IlSYjS~HkgYz$4(f%GpxL*ZilImts=N@YDzaDk--P*$OG9Il?r=_?2Ex z1?JHAh1@)bpR02u_sl~9AIhI0rj5)MXxo6yN`_b25sB0Xu1`zuwC1J(AA|Y`rchMe zvY5IC*u7+no`cXD3w#uGAfnPN8nNfCNP}%qPwB_rid#eYQ6s_*1Lkn}G0w%s+_J+k zX*5FDLsO9W(***t9kKH|v*LyGKq=+|j}@|9k5jAdYfu=jgmeDdKv`(6L=sYyTdB z3-q03`o?50L9T>izK+hoS_~k{U!cHF$ty^whfyf=cb+B`WX1f45f60MzLEV^Q%t}& z0P12D4dTgBR!hi~F3eS={t5zEs-Z}B;u_I&p`>Bq>D3n)iVw4uhjeOsDr$)nIVdo9 z(1?viGtSrCK*KD3Ha#S9Qx>%a;0wN_ax^D!bEa0EQSF;cbGasbq~?%54>vrYhlO7 zeLU^xujgTwvC>`^3vIu%DPE#D4#y zUJi!zaZ#;31FQnqXvzeV=LO{tN9;oJwVXW)p!aXY%GOji=!8c(2s;_Au6Rp0CzuZh zbE3hwuQP)z$|;K$QV1#CVvs-y`BB$i1b8j~2FU)kvtowAFL+QMGlt+1agexL+z0c8 zJN@x!;+pV;g(dML=V#yIDuEUJ3|%@C>RPLqUFA2-!arxp{_mt!y~PGGCOVOK zrgLE>M|o`q|AqpeS4ZS#`1rhaJa}4!=U{dV_E-djF8C*SOtGiXIp_xrIGyZ4zx2wV zK{GZ}zn~x~H#|#rS1$nhQwd~{Y6vGpV~^FKp`)86kYIjcH<2X6G?3-;wdfCg$-IIhwjL?M-WfTo_z?>$@V{S)w?hI1< znH=QTf!>}fE)_JG%ePTWUt^X~0pG)YZN%_B%cu()IukG#98IX)6YyOQBP6)!Wq5C% zBFj+&y+xUw$uKllj=@avZ6S~t^*aC{pJoqp8AiS{39?WhK5dK~sQwpnaA;BIwhx>< zLM#XNS#*>je9+TU^gDKX*f;|6z8&8 zN=k50fP?}~3&2+&g{Gx!&<|lM1M+&e0>KgkTpz9d$qmLc#RN&=QEd9X_1oeH)s4>o zl?Yz4VBSM4&jd@@jK~@HyIWs{dw{<6Q{xZ^T!#p&-uq$TuErE2q()!L#Ld~8&R*(b z-b-PARk13lWqR{H3?#e3d?6n2>R9 zWb=aO?c&f4`?|UDz4thbq;hbG5jLc53r1 z{IxFhh2N3%OFD;>Mb2SY5i_XsyAq=$6?Jy-7BIQ{c|@meDCLFU>Ept(<>@k4HRAwQ zO3xUBWesOj#{g&}d52v?&+jD~l>5<_!@DAoaku(jQdVKq3ah*mIw_%lj_;EN@MuPm zBGAqYKlu|+T?wIn_1J zMTBgDl6$asV(>7vLzQp~w%febFV+Q-Rm-WI#)mZcZ z$>QJkTUVK9Qq+ypQa3{IyF4c*{MCq6vReg^c?5SBC9fFO00o!F8ppw z20cSnH9&V97I8m#S58s5u3Qp%-k4XFHE;B092%?oHZHyjfgU~!xqloZ+>DPC-Px{R zoNxfug~trP$Ug0eG+30^e_zZ%pkKU!%qZ0{w3umLF;%Py^S!079mOK5r-8Df;EP>9 z9&ohO>dw=^Blmz-o?DZssN9f}jNe3B5P-b*sPx<<|5AtHS+k?$HPhe&uge7zDpv7G zAfbA0PG}R)&&#DTqc{9gAYMr!`YQG#-Rl?l-PY_4RFZZy&p;?U7mjXWCtF~W()a}5 z6iLRMD47_?#NQ@W2}1!H9We@-S_NtO$u{2qn?_kfL@O2e%CLy$ooi}qu6C6yrRWxS z0tS1UBC5P*v^r#32e*iFvffXiV0V_mOG-P8AIbFr{ab}KBSDkKt3)~(*=NNjpXGGX zOlVs;0$hWK>CF zE}(>DeMrs|`S4GtmKBB(_pP#~MI!RtMGdipt|iO3?kbC_-78GnFX9qqxV(W69D_TU zDst-NoYkFdA&+naw!KRcn|`4=TBKt#S#4boc=Omm*%^eAt`WyFnjH`g?xG#B*&f=t zw`zV(5I+vZg#pyd>O*5#=P~mR$F_yV#+78hBcS^f72A6nWGTFrs#rnJ;4QgF;RN+G z^|&%WDUT>t90nvuiF$N~yfh^$-c9GYU7Buw@3y9mJ*AISr)9K?)S_k-tN-Q&aTgCb zXOL-|l_ql*6v#7R=8h$mxf=n5=&EuS2k%nSXVjTK(v9nGdrfLFNp&Uee*pA|zEQxx z1a1QKu-KmP&U9vtf>-Zs!HfM6fIFMqRb{UrV75h(LP+^O7~SbZl5ygv&vs2cccE%T zyQ*i#j_@Y)S#?^fA>D{G5@#XBQPpvG4M>T_zd)`c0MJx(cAiu*%wGKJY#SB+_rbt< zgnuK}^3F#t4z8H1|B`v<1yj7kJbI)pe%%KFj8T^oQ2MW-A7%m=x)JB|YF_~T4$xed zlIL(GL+lX}=zX!r0SZBPlS1Z^b9m~qd3A|hMh_l@`1HLBU}nd(Vlz^&!-4X*qns{g zxM9CtTHi20NE_W-00N+1H9c@+Ebv2CH5Ug6h*IIz?o5GL_eP^B!jU+KF;h9jNhZnP zFYqQDNM8zy%>~FRNp-VU`F`6sjr)TMpWm;JSTj{H2p}>_Y6-r59tYw)^*s(q zd+`k2@{YJQdyPU#B#Py*O(g1&7zTz3IbaP(#CfU+ZZS$3M++&ESg@p=E`okPmm!&s z`&Es`w+*<-=MP~kOom{a_K2_GU@Mm%`)IQYiqhKT@du93+T%ft`sScX-R-n3paYOd zbsjX#cz|Th{jCyflLfP^oT=JW3uB97Uc~_EPJcCAwMSA}cp;;?e>mIH2S9i)O=8L2 zNyr~R%7_6_+Ou{gV~SVUFE9E)C~y z4iSZA16o;CsM(DC9Iz7Ps0QQj~6x=E;oZJ)hBRB{lFYkuXR_#SIb zx~5*}xp-tH4&=vTatI~FYTtXpE1!8JkbmJj+qw|P`SLU9z%^R;z!4zC5gPj(+Nh}) zRvrc*ppP;xNe)>8Km{|$pficf>96@nZMTWS^&Cuk&s%p{RXw=DO+Y5)5sA`Dn)KAO zXa@NFa-L1Cpxu7}eeVj~nweh~1s$=+jM~qTeo?ovNd+#m!gJ&pDaO47EM%~TxQ5Nf z0cbN_3OJQ!DEs;KT~mZChOyZ_01|D&R$&AOggME7u=!&B%p@Rb3f z2P%dFT>sS33>F+;h2?k3TNq{sB64&t-sXh7MQdO!B3m z7PyIoXQI|Z#R*f(J@V=c`Aznd>apiJO5Q;;P~5~y7@*smvH-jkg`|y|VmZ%@ZpSn$ zX{4Yuc_oDc7$uZ6tCl^#|82wkvu{iXd?O5A!s`!~_!2UNC=Dm~fGZW{%DLuH)VE=( z$4_^fu^K4(nDMm;{nk&@H)wISuC%&d-kw!Pj7)VJqGopmP@zsfzf;UTJs^|5;RsKBNmnxsrdZ>+U#OOs< z{+O47H1c-)o^}C1x@PahE!q9j`}p<10^?-a@9C%^w$os(52*)QU-EiHHS-pOmzvk;^9QF6TBA(y zFF{iscTT_S!vaEw_U@AlvQ8a*tOYpL@G1zdRWwH^X8lu#fV%s&ev@oiXIk(WwK8_u zQJ&j1U=^7;aca!eZMa{pO%a9{Z^z}%hQ&>&CopriJOg6jhMAoAVG{u;-IvYB5$}k2 ziJpZ$RfD`=FZYpHUvDpNS=P>o@4TSVg&w>UsWWGMZfA%}4v$mOv*?px<#6_?T}r)@ zv4F%jXL#$U^SE(YM-HdBn`aL121OF|sZwj*Gi5?Z~GlK7KQ z7m|!(QREFCBj-;&Yj4`3 zK!-GF-pu>bpM_#%s*PzT!?)hG8Wy5|vJPM8kcaB_v0PgJP&N66s!+FH!x{3hHK&WcU8NZT&ocqBHBO zo%A|@rsFbXSe>!38u$UUkS|FVx6!>47K`_vi{x=rd9omq=5!`TFb3875cbmQx~ zOa_@3W^7vYm{|x(l|Dm-2xZ7v>$2H+3vzPs)XWC~z9({O-ayA-J7x}7f5sld24{1f z`^A>HM%MWGYy~3dUe0Q>X-35Yu$}hb`LM#kVq2a1-+{h&mHBcM#Lp-{Kl!yDCSz3z zVTySLm{EP>21Q*~F)d|&n4Xca&c1B32YPj*C!rm;in?lX)`&wuGXCcbi0FWyr5jUk zkOb-lN82>a+|)@c+@{+>UtzVx0E@prpzsFT<7q&sPOREy-Ue{^(}Wkc-?j=*D}@eg zf~}r@tN>U^42)m8)N6W24JwvkY0#8fO}tA#PPjT*Kb6C(@GN5iH&nQLoWb+U?Ov-YllF)NTzC|0cjB@NY^d6_>wY5u00GC-o zS_Xl8t*jcJVS?uK9$>da)#=UTJ-8VGE*I!Za%}>(?^`h&&smo3I@3!Ig(HW`=r;k) zW0h%Ci1I*2kf(b8b|78SHHPp8ORE6bqUdcn&A_L`IaS~r;ZQLB%koc!el3M(y4pqZe$bMXfA3^CSCZMG5-zVGt#@?tLE`pmkYy~k5; zo5F~X$(&Iq8iW;WK*XXI29M~iX%`z1V0CN-q$edIw+H|yd=X^ODZ9tv{=lSaaLtv= zoVh($0$_h?fw{+e(tuJ4lybXS#Y`>OWpwZgbBj8ezF3Vv5=8sI8ha( z{r1k?P}S6#U@PVqrhr@$=vrDkP8P{_feiX};%Gu>Gmypv;~}cy4z7|YL+*$lES}LX zEsw7PVwBxk#3`tSq%@`n2ndjJuz|SDRR~L}v^J|K_>{abN;~=`NW%IJP?I8UsQLo1 z8L#^+lyE1L1`$$ec?q===z5WX`rUR^e$Za^!6#qZyuMK+aC+1T>+3BMT~$vbz;tzM z7^tgJ#8KrM0LA}{yc%Nr>YBNrQXXKRr?m8r!&QBh>;#iey~&O`mev&)imqs;r9<47 zT!Zz3PVeL&6qot8zRL4_l$Qg-Q7X80m8wAkE|8Z1i&_d@w`fa`;9Lq|4?7uTov`ze zzXEhw56*Kme=v(U!fcQm151x1ZHGLV`sIDG;7hcyirb@f{ujoYd#nNLLbp4SLi%I|wi zL(j|Hk4%utDeD86V)azOe+-K%(dC%?Cl|}u6PA`9mrAlQ&gd)O^9HjZs!>5!Xp`NXG~ynW3b!6E(k7{jZbJB_Xze>LegrD#+{p z6;?xheUb1>#o_~CwrrWoYKwH)!+F8{Co3~j#Jqc?w{mJ3>Ho&*&gGQnss6>&t&9H; zPY2v^vL4A6e8Nh)F76&rov8ulDuT*}9KpX^gI$T_XTXYPU>N#q(a2yzW4%UBUt6ED ztL5dBjFnC*k_JSSLkF?u4?tTNnvt7Ggtf)L7P17S*(Dv%Rlz)M)D zDZ0v8%QE+MPp|$?J~ctBrkfTFU;c(s%cs6`s{+Kgqq}O}o%?|R@0Q7j*BzURF93nM zBDA+)Xyuuz=3Gd;cn_#SMOdSK@q;f9bIdSS^d=hXS95a%6a*^l*r?g-!0A^5z*v8R)0F2|T&ep-U^_&sk#x&=d*2k@ePlUkmW^eX; zXcEAH-?Rz?k_2T1mCQwewGgaVx>Yqca$0Q7AEa zP9}j*1m*(&?C$c|xp~W0sW8B$T;sT2Z>6E|DV#lr4NVNrBo*?(Lxs7;ghrrI#y4^J zT7EB*`VZqKmkDdy)M_aYjj~ONh%WbUCx;PAW!^OK=9XZ5Bnx>|HaQiy*V_C0( zui5!vbXPiJ&#FAKvx?Yuhr?OuIg`xm0WwJo=?H#GR;)gnTH=}?2|&uc$9h{Ck~4Bl z7RhVE(nVAh*xVo{Z8=@cyGm`hYNa@$s*8>>M#)&0{V81v$S-XW`)QAw^_ryT__rvxporsF z$V?8RSMNw-P)blxj2X%EQmbqD08*YIhY6gE50$B&5hMqmf!!#(K{K*Jn0`j3Z?GRN z6b+2p}lAGoOS`*axk+F z*ytql{mlOi0Z~T+Dhutd)+bwwr|J2%KqTM%U^g;f`nm@Gd4G8%poDK{i;%$oz5`2o z$se>o9NE~|F132r7ZB7L{b!bE(5fYC-q%D$Gzm5h3H6S90Y z2cG(8wEYCsFPhQs{5XN&?X#JWi+6Vb#%GAxzt2%58iL!AUHOksdKoF12D;=HUrJw7 zFtunl(pJ2|1AjyPb$n>=H!(Mx*4SE8Q>7T#tAC$47Yu7fyu_Y;13l_MYeST0-Q%uL z5+qM;qPFdwX!J!p;9V z$q)47OS6Eh_Hk)l@YPU-T?8WpkpioPC?lb)b;e^YSHc;)w0d4_-M_S8U+rd+|IgO? zSBgTN_7100%X+~xWc+(APy>|%g&4VwiWb4|?%ivtE_8GoAq4_ru*`p3Kd8)|eaFZr(_`czT{KLMN z!|HSYbN@QPbmNj(hE?WenU<|VKx{it8^dq%G-OiI^#4Yi9@8Z^q4D1|&aMoPU3&naIDa+3nTX z@aqNYZjbJz+nHH!a)jIfQ4y+A!KPV%xQ)@t`CX6S+L-@2hEN1tZT+KV%Nl{;i(rD| zb2t0Lxp8hJU9qf6RPsi+jroxvV8qQ8{c1e;ZvT(y-JQS|bu9aHdZN}Her#?WuP%?m z6#dkI+`5*$RDPkuXIJS44Oj-IfhDB9{|iGvVj5cN!nZ}NN&6?@iH-L^H@T0>zcFYU zILp~iWsko+B*+ng-R%ga8Sj8;+`SeQocd>~y5wny<3%b`er@vxl-osizSlK1@MjB=&YEc&PjSl^1Fk-GD$Kg^j@{R{P*-a!LlXIu}Q1Hw`^WK(_;jUj>f`=2CR;yulG@H-?;VQK?-@^ zziOhVD(z|<$OZ}t6^OyZjo%FaWzWZ{5$X?17t=manVIty|84?o+1{w!2G#EA`;UHx zt%k-$2R(Sw9ch!%`~$R}kT5#n0ic2bB(N=C@uAu)pw}KkagNiojOs~!e`oJ$IGqzg ze0K`erCz+1I$F{H0@r=z-MWY4Da-oFr{m6_eJU^LQ-AcDv0|}gOu`2u&x)6iw7+2* zJw%Qcv+#XeGx`soSnt)ab%ezX`N7zyxwAdRb`OQKml^wAS0)a~!utaU{-s{L2*1sf zh_wVyhf1D4Zn}X%Q}Vt&pw=lk==g|_%~X6bBBYO^hDa>kb^Gy#inXUa|iaTMjkYX z<152WEPoX#;Q58R53RZX^ZY2$Aa#dbTB`4MQ*8O4jjLZPV&hQ!<6Y+7zov2zXN)O+tnj{mn2%zg z@}EoI;s*U(%k8u)kCGY1bc#9)RGSyAvWHz~D09(+?9j6y=uTK-&- zwxaa|^$Sx@7ud%SFSKRv#QT$%?~yYqt^j@qL zbF47?9Sk|Mo2nD{#Q5Fy4HH-Fdk*>A>!FCCJI5?e;h6SHbOA4cHq)TUc6tlnHD~vP zNZ*|exN{^dE$-K)$?aDigw&@vIrf;Bg|rZ1w8f9w=^ymIPYdV^wgU70Il5PQJza>? zl(wQoogw(>QRXq4nI`Cdd*yb^I&oTr$EnO1}M3yK+-`VCd)ESnL>%?&c>f zJB%amr}OCxI~|`&4TN66Rsi>l%`I+0$U4sL0h1{G!$kFGH%b@I{bOUs%;S#yB~x|V zD*EbS{SeVlg$bv$y!UVqGM>$ZHzzaPlZW~1i%BumqUNf*JS?MS-bJ+w6alE;Ls|cf zk0XM@fA1BxXXE*f7k9|$PTQZ%b#u8dJ?-<_&j2jdQihktY5ifrSUlc=Derd-^GY{O zhta7MGWg&ox|;BXvxgPJ-S*~`CbgFGFCxwBhgTXajZ}{*pJ-9RyUQ0#==^G)I80uu zZtsj8?3^mOovxzeV60B;cy5N34y>T26toXfG$zLj|oEgYJ`Q~945H4YkIe_G%}|FnLREhO>aJCLXLrMD5e+ckRB zv4<6Q5vo1u?87hcg?!nsnskH>9@&aLq~kzWh>3C+2?-}b23-7`A%eq7nk zoTo_~L-8fm!4f!-(*kr;+~Hqq{A-ko(`U!GG{K}nq?CV&agL-P#YWo3bvRbEnBb-S z(c|FgGalF8ICh_iBVHG!=HkEBheG%b#%hPIKYn8ufRtR47$F7D#@W4O*%>`l{|HD|@ZXH-Hb9CS}X|bz+x|29=~!&8#*JJxmc{gzW$5O1E4LlBCl9 zK}0YyxOvzldn*`Y`TJ|}Mgmk&RIQ+cGvIa6-@zJ!?@n?yz4|V1{}LIjhN@(c<*{7~3$b+ceyaYh_uYN)Z4r{< z+E)tS+|q|~+*X<-8NTGgv-T(Q>HZORx5JOVsU(E#^dnpH4Q5U+D4-3^s|6+VStDLM z%x;)^?+^Qz?%+#jrkRrz7kRa|Cl>xx$5z>oY#1%-w*7$92)~(;8lZ&_*?SL|7e?wp zQ!)hOh>p#a8!~+^DdgGo5dGZ9x^9)n&uigolmf_LRVm+Oh7{q*30f?@Xv@Ct7)p`% zE7mH0@XQmb92b$<`!|Hf$xCvcXKN2@}D!@jSX?!@Z?R*`MdwH7?%1Y zSSMu)6qWi)4d(`l7GH;G)*32&}l(YM!bv)Jh@k?B1InN8LtX z>EgleMX zQCj=jxE0D9uM+Ap-Yaj9*r0g7L`+S*5?VfPz-m4Sxzeva4eqeVEt*cs)$4Q-UlcLK z`Qxd%(zzEc!Za*lzpE?&I_8esA;@>@vC9}kAPa=y?&^Go!1vB>u?Ew_?YzldH6&;c z&Z$J6ae@$kP1qc&#h3aal_TaCcU7k@*gC>~$Tr@3m(k_flGA;qrPQR;mgbakZ>|xu zTHYHy@92t!aFG`OC?{vbnX|%$RVwYQu8G0UZ*-FQE zw=TM{oSEu4ydd@FtGpt8eK;6KBa<{jc{_#0nhZnVZ=okaE`fD{-i}la;kh>lABV@X zfG}K-HYAu5$`iU|$`X{*VXwFpWolUxEbl?(S9pN)bY7L(-nru{xc7(k?Z)BXRW&Dp zS+k7C33#daprQb`q!2$(?XieRB{>qKwfbXn}aaw`*cO%o`;aX+Oy5 zC(igDGqf)qPM}#u4haim+aFu;m)n?@2^3qxRL3z5=MGHbeHwcytOYQypvRlRymZpw zj#)b8zt%_z{7y$iUN49)OZjhcqz|3MEbh!afh^*l=U5T2^uo;XreqsWUt zRb~r5uyno{u)c-}KH&oSbD^cF^a^=5MVE^+5PJQGk~j{sFVrLTDOEE#g=>k7>RFGG zFMA^WY1V-SG=!qgg)EMv#s2mk+v_jgjA@Y>(!RtIcR^^3vp)^27bbRx^8!3fccOU*A{>( zNRzP^R>vBccgJvxgRXg9w+;qfZB;xsMYzZyk$c7;kKT2CeB#AUYD~#NyXSO7RU+** zBgfV9YZ5W0J-NVKVKDOON3T+Iz`;06&BO;=rJni*^6DqPvGpxRELbS3*G;rGyr+q& zUK=tqT&T?}tIdxbZU*tl;07D)C-Xh{cIjp3R9vXfV;ny0tYmB8lON{S-^mx8|9YMM z>Ep@X7}=BaS+AT3m)Gd9NhKUyy(b!UOHP!swAC3}xiEp(MWwDZP9Eh4cpM%dw@(#Q zu6i+!?mK=q-hgsDsV3A}U0pWrlqi&0xv;r(%cEYW53ZqqlW zg*?1@Dj%U`)P%nDtv&e$_gEp4px&uM;zf|;=5nKEj>D+|ouZN#*;nQL7nD}zZZ27Gl?^@vK zj16W8;zFxPB@sCR22!J?Wkb4c+(sH-tDPKfOvP+$g3@X=aFnLgMBkk=z3W7S3In&D z&J4!4lbC>hunwf?eT4Ut6O<8f$i}3uaeRzoCRY6pG11GKu0Rh~!nhGTCEaMN_N6rs z|9Q2?UEHZgxvA!D0{LiQnMYkaqyKj)A?=O%c=q05MDOi5OwLDV67pUG&Zg>vd*y`= zH%x~L!Li!C$IhSNJ%Rer#fNUE?B`yFV@n)65B=Wha`}*_?mm%8Xr@E8zR35r*64#j zzpvV>D@C3?{btEWcNIPy8*hN%`046dxlq(ErI&xYYmn~y@Tv)_M3&mCGMUT;f4b&3 z0dE6KR6Dj|CNuS`NQnJ`K*)9Iq*2eeM{SaQP96XO*;DZ_E9`faJ9!khr;AIOh9BN@ z3*ORM)VfFHbDoFzwgb;0b|z7A6m9Ij6)lzS(-yX?b(kxQRuCp?tR6Uj8vCxwn$E0F z=yWSyMC#7W{LIVDS~D_ z?QHg32M4$jr11UoGf4I>?ZmtK!!gItHLgmQD{~#@Kt8Yfsu0v)c(e5~KU$#KilLCZ zve7U=WZx6Pio4U$CBZ`R64_(#7n9+Rv%?F;d5gEc^9%70K(^$M+kB|7AT}QJ?jG7Q zNSF`x=D2jUKUjLnd5X5Ig$Cf=a@Xq3swQa-A(Zp4eBrqRY&%=5zR6UT>YlkmH+wr5 zB9|wjFE8`8fIrTA>}NTb7T};f|0x_k)ZZ-z#(?-_kc-ViR@TK5g3Q74Qg{n}Z# z)5#QJL9r0?G_KaBo*(^D85OTVVfR9=s|kQF3G9POr{iHvOG?(?vsnKLU;2UG-*$2% z^jx_-p?hLqP32jGvzc&Q{>PXW|H*M!q=DYUEq;r(VpX=b9;&x3#FOG0?>ACWSKw(x*)h)s`R3w+kaRbQR()WAg3l)Tiv6ZH4Y`+|_rt@1MN=9U40Lh)6u%Fz&l-ik#qO z%Ke?3hy6Ca(ysy??)S>Bt20I1ktBQeSO%m#i%cV2M8)sDnt}IML(5SA1@@B-<`!TL zIh$F!Q~b{R26${av#=M+}C}0sP(4zZF5?Shr^Ri*g%~A&yKI0+NO#VOFG-iQ-_I=_by@ilHt)a z>RtEj9mQ?d!#Dg_#|vz87WF}!CkplQoLC)>R9@l6HinePu3~FwlaKWDLKA*ZHL@gK zBcZLpo^{;lWJj$N;-VwfDA?c$RI2v92y7Ek2|~Oe-QUa8xSE%Ti;DV&>H9%*9vftU zuueE>GpECJ%0lzUT#l7I3TtHLnye*K&sB4sP%D_Fa0>&V8tx>E{|IOvZX9y4Rn?6= zBe;qb_u+1BoiA>Om*?ox>YlH3`BcAA9R7-ZUDGEIJ4H{QtXxgCE2iT$jK*BaNErN2{q9Q1)tQAI?2D5Z4z(LRTv)`S;YiCG<`C@*< zi_9(&RGhsi=#xx3e(@-r{}Ln}>sAj0pstv)i_cou?C}uN0-kR+iQ}*86PEsU4-y1W zStESE?mP3xaPZ;)MS^+N^UC8d#l%=eXP@$yRK2CNI~nLzh~%2SfV&2IDigpq2rGU1 z%Ldn&r%AJ#a9Rh9TkD*=>4kA;+q2+fsXQwq>clZIgj%Pjg5Hw+waK(7Sd^>XoGmWm z^MyL5acVmv?^6W@xTvQYJ|fm%9Wnf2sf-nisst?UmSdoF%@Q(*{`e`B0JXsL2UG_* zM8Ky-+TXv5weTJl{7dY;awn70^=1_vVQk&piMXwq7~n-fiuQY+PjxX!b_(^9j~^_$ zlyv`Wih@@Rz#D@3AJG-ptkJo~rb>^q^>$!ptnaJ^_)1H2Qxu`uDFc(*>Z+RQk9zu_ z>YJQ^2D9zk97TA{Mt<;GKir zLxDJGiUI*e$?|O+mM#6-{OcSt(fXPF3K_&_4o{4JXZ{qz2tI5_)HTD`&pkl`IaLb?I==Njs;f4i@bL`2_CVa08K-oD$)%F(yQvuLr9hlCyd5X4iQQKYV z6&=#VAaE}Xc%jdD%5e;3_r|g2C_KS+hVON9w8R4tb)jsX`pwv1ZUc>MW0aam$jDOP zFZ94WhC^8Y>eU6<_8PoX2HA6Y34$Xav-YxR-=DMT2DsoZGXE)svyV@9VR8r8r?(#V zWkOmDsp16gll6SY_9v&o`I8XTN-6jr5tMKmGS&3Z*DheaIY*mIvO2o&d4M%{iGl5` zcwncMw<30~5cmPSMPiH%2AjXIK96gbKz{OrcJ#;QpZ!yBs<;`UjSmMU_AXx_O_EU1 z+i7(CR8Z^5c>Zp{csw+6_7;F>E$Rpz%;HXP_vPQ+p{zD!q`=LAJu!%cL+JiuZnS8e zsX}N1zy9v{+JOVSehtF{at~4{RGL6fL(S?3iOWSPzj+R@wXlfRd;*5|ClfcuChviZ zBJ)Ub(SeTSFDnLVBf`Y@+Z(JUBQ+;V>}%LAM&Y;b5+3>iK_#Z3VJs~ICx#1DD=wD` zf8HsmIL0+l>%>mX>AnM^$oLC3C`kGXjOmwoobMzLV`bAo%tLX7@f#7?7&IoLf{w-R z;lHc-uv3WS5BNV#&j;K3D?j8XN~m=zzx|{5CYt~3KCsJS6kVMFX;LT&)l2T@UKUhj zAaEWURqV{zLxxYK0S4n4f$j2e9sRor1A^<2rYxx#fcW+P&t3#ry9pHZvB2@7Svd5_ zSAX-tpBm2DLzyXogmd)+#g2arFL?VsB-YQZfM2Ryx>&6M5!9(@cERCqF#KSTG3>(8 zK)H`#L2nBEP4~C}`{PK9HmZ@)Owx=Ojl!X$asK~%2geS@QFavXAkc{v2JDfdbCiCp zdVwMuXGD5$VH5QP`GX~wXp{?(lei&4yR^^@8MTY}zc;Y9{&PMc0%dGVEdM3Mtfk2O z6K+5!AYr)W^leZ*d68l|p)tNd(oze8%ZrEJRV1<$v6#&qzHiJP=OV?_g40Wi^#7pu zAEDe6g5chH5q=1ab2$j9rt`D4GP*G5{)y1`d{8$eRy3Vly%!R^p}yCUQ97T|bpw^^kkqDT0Uik;3rj7b;Bb0lPGo zm=9txkp2Hb?>H2_+9%-19mB>xQ1AYECgZ$a1Cu*d6gACa0(KwxkOE*fNE|>sb+)A$7P{Z1&nZy=!7H z3NZn=CYj4qh71&Gte5q0pIS17`xqQBx{c0lae?!IK8sZ+&AK&_(MKCndo>b}IdWGO zf!e6S_o_IMnt$w9fAd|+agSQJ5%RPB8yC02ykB7yV*j{nWxXhE6A3jUuwbyExzE+5 z+#KO`9?PnYqQ?l&#Y9DIuxMB#xq(xzw5)V4gSZ6#x#t#_-}9T({C?*moeT$8$MoXh zv`X2#g4G4mv*xvxMO|&uvKOXoR>ihS`eDY|B=#Sd>KoGc4Ic$oRSGtrM0qV^Q!5uz zk@#;Gx!=>rN@T5f1(|Ar44>L${7tYdD+v8A}JzR#_Y0<#B!q-#I?U^mZrcAJ0~h&gR(+&E*Q< z$4C}&oET(hD(4QH6MOksK2?~&f-^fPE_rgs7~8T>?Z0>y@=EqXdyZ0oICf;^5AU`8 z6QRvEWKglJU`+e9#-(NAnjT#RDX-yxLQ{k1+v3UCqZ{kb6>AkB-at&*;E|}8G*@Jo z(wex&_&JeGjYVDkcz=U0traFPGfuMRm|ZpI#@*PGqotw;CJHRz8P8|>kAKPvevMkvSLEbhn%CtIQ>ESc8(T&tET{t9 z{GD?gF4_Ywl|kMgNYGzpf&`OQy)1cq8p>c`eYDJO;x5ZWl;S89E@nr~0&v(`Zo-kt zZnSkheyDHsbRT}l6{(t8t9QR#!_{ok?KBl6Z#mkG6cI-?vg&FD+SU znfj7^hpp6A`g-mz%7wuw{V)%+EzH2fyIB zU(CwS+nt|M2*ikB5U2HGLNb_8*7WMiinWj?N8&0zFj%Ia`63WF0NeINx(L zYlaCXlD_s^@*;XB5MKSgcGdhIBbDKAjz71DmAa7c*lhPT3X7d^Rk<^JG#Fv@!&wVv z!FGd&G+dL6XXktd46?vc8Y?=SeC40G5j|&41q(d7dnWFRA;fdxzE>4kuXi{z+kM>@ zYWtoz{-60=_;o2mF76>^zZnQP{e-dZShbJc~LD;}+M$xm|8Vb3XpnzNGGj>;P- z;6(W7Nx#6MUuN_gC`#3A*PnxWzn%QJ6)nLQ?%Bgn)pbJSo)FiDtIG@axG1+#zD<*m z_GggNDEchd?+pqkiI?uFLRb*Ec-iHv#X8VcKYn=I~3 zt-N4u=E)Z_`j}h=^&2`Y`B*Ou96FKUm`io9fuj?wjedxl39{Dk!iz+quzx1)WM1x{ zSOVP6GEz^NgH9+uFup$h@f6G34Yw>d{sZwwk>*~*qq*<8AU>oHeRtKn>`gcAroBf^ zhxOmNk1rx%k&qLZf1fO54kk=L)_duPa2KoEd06=_zj9b zcU=&~ji!hCiM_xMuDW#Gbu}G2^t3DalcdYk~OO?lPrctj>o!kV%P{CQw<>X)0 zI9lxnMHL$AvPD`(gJt|;+hglj&wE<1H+;wCa}7(yYpom8ZySHRltbVXO^oQKeBhn1 z;E#-_TW@kRQlv=)O)#$=gmpm;M|6!l<$sZl*KDJtVlE7gzXY*Y?91g5n!C@@awiuC zNyATCqPJXmEnNiV{s_WMeq_Z{!JB=*9AUW>OJ^y%pX&<$E?X^aiGF=lL7~w{tfWry zjW3}}3kVkMMu7&tk-Z0ZTx`>yWuf|fhP z=xt)SbmT$KdGQSz2NEbaGf42F(8memCgQqUzplL^#@+lOv4TZc<=eChT1KdrB&Yk2 z{Un6*MI{7Xcvzx@#BJ|qb4AdwHvZVuuf02?*+T*~bCi_m7LEUG?k-*NPFfW(^3pP^ z%kg0i)8nJo5(^+^{La07v}D0RJS-=FGrs28K7#Z*;6QgXRPW{$IimW~-eJFLN3kx! zEFac=UjJJToDMh!B(0v$C>~ij^C-{!1eKi7hTb!(2|w;E$RxQBVlVCnPPY_EJG;42 zgV4_;rbTX-O)q2u*cseHafhuh7N3t`6tC@NHi8CR-w+y~UVPj;ChxRa0OpMMC_k~K z)2w+~e&&WA!@x5?zjT;-HhLI*t2%3a9>YHI{nJ0exZ$}Zrj4tF#`(T7O8?EF_~&_z z$1Fq?u6)$zXPa_vf`EayU;F0;{c}UE;o=Na zL3=VD*S^WKN{gY*W(Vm*p&`b36cLU?2dl`Pz*m-BJgWYW{Ssyb|AN;6E-cOqq5Y$j zvXsBrJTCBGU{n?hIj~BJ_Fs6(XECtl_9df=;DNLO3H%2bxoqkLf?=2Wzrd&l=6?gb zTwU@^w7{^dO5#7zJIbVh+vOncZ|#!h{BQ3IS93bS;40wve=+7O*pR=nD@*>1jT3}$ zzkCP8_n-K$C;()vxr-_jhlU<7^1nBjhGswpbs_w(w*MQbZZ6I2;tX^GDF06)L%_7@ zIVQvc;59>6`rqEm7Sc5=z!h%vf9n!L65dn+p;q#FUUqSSk?tRlz^*B8N0;Y|E3yhWG1|2KqVzSF-=t1U6s65Cs9wl?YPcF}(hTh$G?cIMk)t+Sw z?Z^As5HqCfEPUu-a!X&~A;th(nhe^=dD_?vQk+?YKn>KN5u9!Y_668Se9%TnH4yg% zN-x1+WbTAMt7&=MPEzT>|(v%8m*6rc)uMqzh8Sl2x4PtarfKKux)x@hatK( z>@PI+1Ci|)_Ea=V<3-`c$j}nwvrjj{HY>5oH+GAOW8q6m7oE1@qjw_-M7YL*@Uj9f z8s-gLZ$m%UNy+O#ihRRY4+%r~DZ8NI)0rLvI52>kiuv@PHFN_F@2>$h)c z(XvUh0(~Rb`_~YDr&$Yr$p>-6F!)-89LunNU;;kM+Aa8EZlz@Eo&{%dNGJ?uyaLH* zy2z-Xf(k_5;7H?-GlWkBhQGPGrqqeAa|L z7U!72QsxhsvT2A5KW%bcTj*SE;5bcrj|pd~%~)k1g5W)5G|Q-z1Ni&3*%T{_BAU`M@ceQaD88B`7G`qIe*LCeDsRwohNexU zOQ3a;LY0`~RPOx17bgHajhsc2X8ZA|TBs3`${#VS)&y8i{{sF-acd_6*Q*4-d#R}5xPh`uFN=X$!rw(;Qo*Z+~GCd=NvxLt??Ox zU-Ejria`|3ZX`@)H)X5VwnQvS6GcL(Q@~rGTcqb{=wFS!aOj7SZxw&?V4bX#s*GrC zmAof%Ic(mQe*Jbd*o%n<%3FNpZhNyCd9~$+%zjEVhb)A%X?Ay-nbmSwTcmc1?|G%L ziP*a@Ygws zO6la)`&4B{PR&25t~Z;Gj<>D^p-{Ddw(`9cq0QVKm`D}IJ`_fl@V+|}i_Si0G=x{g z_XUxTwdi|`))S|fty4B`AUta?heu=hZn)sKb~-f76q{EuUXTtUhsPUv*6C~r$urMS z#Qc`*(L`R1PGZ4gHGoQgyDG(gsgY{ov_o|d7^|-PM(2ic%Je5Gv8&}XnegXD`Dz$F zBeFmB>|YaK`H2WN6Z%}O9Sp>VU3|#NjExGblPtN9WiNQABp`cZR{t@e?)K^?#ASvY zHI-`uR%(eVdnN~Yv4O&kwk?G(WlysJnO!ydE4(kVTTxusy<{z3cl=fEb-nMngypkE z%myhB0xu1_2I8!1dy#Y4@JGKt6&SMANe7Ek-i-9GU#q4VJEz6oHTA8)$njjXN@v+r z4(W=p9~Gd$oqjsPnCK4_ze^mE`ixx(CIl@4U~XWVY*Brt?HCX9%YAyW1XG&1Z-Ns1 zrQ1|?9H+V*dy@RMR1~{B3D_g=T{H4F10G>M<;$-Sfh@R9#GzO}qeb>zV_UCZ^6N>Z zA-0lfDi?B=Gfz;S$5Gpf0!cOK!5iNc0BJ#$h$%#tr&+upn9f;+CerMe3y zltOIw)7Dna`0_foz<<8OvwE2Xr1)%#oV=C3Ll53%F)$*V}%Bb_-_`TtWl)bvN#JSmjwc-@Zm9 zRYa7<(K|+MKa~uch4>m$^kznq5l>yeHn;J+7N;F2sl%bAdIXW2x``|=FSj&@#pv;h zD&M6`_EoyosJ3R?;kC^#W{U4gI`3m=2Bohqe8CaMJpmgMLnl~Xe9d$t{>Zo39DPvZ zjQ`mD^u6qARy#qtbiDzSrrqaYk^14{R}OFa*YAT$b}x66AF27#5jb?xp^e*%{J{LV z@Yyna%wK9r{IKB0{Ml&m=LM2r9?Fu3F5i>6rC~m3s7NOrJ#P=%*=i$}z>&mh|Fv z0X)b1D3d^8F3@yuiR!NKg~Nrfk#(H4Zz2u0a4NOm(y%1ku|95h7wa!9a{Z1qYv8^0 z>-bCW1Ij?CR`Thuw*xvSKKHJ!>-gbNAsr}G`37vP-e|p|)paY}ws_UZ;!C(QNj{Vr zlK>lA%v*39{OGRXkYORVqIl|FR{r%WnM)5?Z-)=BgQ$?3KFd`V*bZglDF|GW1c~2G z>In*2k_*&QS30m6N!Ulwg@`M1gDLT8G0K~_$z!N3JH}C%tlTF36Lq(fH1p>}RwT28u6h zQ+bh3WmCk2$oyC70G8NiflG#whu;m)a`1hr7F$vr5cL#U>jdu^1ZB45vfqe&D_}+z z+24B0*rhe>!t*j&x}x|vxhwZh>0a*D6MgOc?fd)R0-wlOV$2pq;3Ve#k&S!fkVPBC zJpF#4gg+*~ntBrVatHIV8-@IQH$3Q16TDFjtL@>Fi!WRh-5`?9&)J{uOblMUk$U}l z!n{;NqojCZL403VBmQH2OJ786UvaHEovOVZhzt1_8=ugqbMQh|9AWOw=-%On49l<| z>Oz?D9>@|E-uxOXmW9k~md0|cOXb&@Xi;-c*?tz{O_ASU2EAZsla!saB@Ki@NkOeS za_pHS>K_<5tJ5y;L!29KG)pa1TWc>WEyb24PMFd*cWlouzRIPu*9_}_QBxSsUE*8W zU|!;t5VA)4bM-^YZ$8WN>7Ts}Bz+5rMcfE-@U`@7)K7Y3XE}ojojoL`I&qYDmg!|A zjxu@}M@Kce9gE*Ysy+&R?9US{^Sd}4r?ZAZ15T$l;bt>RlvBBvzv!DKF9mTu(s-O$|g&Mmd|k(gu38sustnNY3s3=x4j1`=a`yLXf4JRwrVJ$NF|?DP;SI z>g#R=W4=wB(ZBo7W@KN2;n8fBW&Sl4OKvdl?X4VAkqS?5vA9NfaVloIJ(ib)?UF}w zhSO*=h5wp-F_n=3@5c6+5#=XFCe);R2R+=Fa`szpNqbHYHn!oLbw!WCWaf`&BotyW z2v!I+WpO04w_RVc5a!r8ke<3Dh}6@qq?7NNbBf(eMHR=DMYAOR)@JW~EWW8!s#$6> zJ^F+2@++fmKf0Cfn}tBOUUd^PHJ1i#5mviwL~L48gj~`buDx#wQszjx3)4Bhbwk9X&d=Yf80~5 zu+j8##`zW2g1r?w)2XV-H21G5=VGl%!tlgTF9L>{%pA>>_6=4UXY~mY9pJWOdO4P! zp!l`!qVo8f-tysS&sA&qyl!GgsQ9%rsZS6bV)x}2UOC&x^@!S>lkbHK^u(_YkTfc= zB7+c2gQ_h9HMXt2?E^pN>`-!2!C`&7(#hN*@gEn`Tf3fE&=>i=jY;V7iK26>kjfGH zS#Im-9*Y@?(Wl|d_zFy{5t#JHN({c472&E21W-P1{VBb#D*kBwpbeY zyZ->n>8toSW2dKrg(y&QpP)jl`=lsmk`e~40~;bP=*{lXBgg=)R?zET7l*ij`*9ww zx3!8RLPqds!UGR*llWWI6}Vo72fhEgP(lQHJsx`f=Xb0#KtOthEQpsz)Zlu7R0mWj z&4g$$xgcQy16bJzYR{8&j?KqV0VtvNlwlY`0YV}KY|m)^Hn%^PME5|4;E%Bz+-K2_ z?Tq9&iVPTC1X%18c7H=Q?N7bZ>Bco%Ft7hMYeM)S1DYt|)I|oHhRV3sShaE;22~1! zR38pvEExYc5Zl{Mz~BPLpsZwt+S^PTe(j-?RvfUpf}CLCMSY>>z9QimLx+RhfCCY> z1qXXr7O(~{4#XPTqsBQDj4eIXve)fFG22)-Q#4i6d}sM&tS zz_$b%==J)yFu_2210r<2Xx+{zJ6_pltAPddB!bH4-j8#N1T}>nL;;FM2@7n%Fo95a zTMZ$IYe74>qJ%`Bu#;3ec*I3iNIV$3_(S8VRSv4adk02{Mzv54E#p_HA>M#N;ei;y zOYOQ26D;sAsKd2=1eI|i62Kr3Mh1gp5*8B9S5Os(7u>SnKm#HgDnYbgm?99wrQy){ zPesD(hsJbYFeD&0+EH(TkOk2|Rpg4{ae_K21sk@+^J}jX3Zgn9U;EX2n(|6r>&?`-!^O(^2iY2W-<{&umt%s{dO=fZ1Me6A zzE}SxnpyJngaOSr$ELtk*K#Ajz!HC}##6hU#^yP~NH-EqEX_pOU&J%y6?Hp{ns4#* zmwO!i4L!$Yn$6FEBz+>oY0|2&UQ|t*J6Tj?wZ?;3-y-nLeEzo?RW>OQS{n#1<<)CC z%7wbyeoWsPb&ZcBskH64LdQ;SX5=x%&_ABWX(>xlwb_rmkMBqtrXTDKfdhl>%%{P7 zZ8?9L@l-K40U_6nf@(shHQ$nG;K+MpmBOYIfaQdm-->@pt!i3Z*)hYtdX>}X#YCUl z!6~H1_E}0b^}wJBFlZ@m6ry`GQY>8uZx1{zD1r1TBL-YGb=I=yILC239S-W{uewW7 z%#0?_g!%zy{2eW4!>un@tkfkgE1i%h5MR#dd|5 zqNmZFS3SI|oxEw`Rc)3%MxR(Wt=cFc5_%VgBII&5ek=%=eV?JLOcf;#3z~kr*SI@eG{$SWphEfStmj87elq2Bs^iC(ItFUbiP~S( z5@hjA;-x5J2~?<#U5Z{%KB+1fDx3^`kvfTqq(Eu=IAN?ED|Y&OL5WXI;tRbCyM;O9 z`NR5+sHU|uJo}9d&th$Zvsj$STn8lGk5=xlBO?mU1V2tTFhAe={7o#BV=p#9TgkgzN7d_p)`sa%+bM)vVC#d{T5w1XfSq6j)W$VA9b-+C!(gXR6?_2(}? zIXvvS%YJV==cGka(pjP>18<#U5Pz-gEL;@tnr+Z;^`v9jbzWK5t_O;LvNfYr+>k{d zF)`rIrRkr^YZ1!_o8lJa-hM8j@3H>!`29CVkA~;D4ljsHm7kt1a)q)o(lZy$FAm{g z4?K^heI7;R=*~;3Vv!@=Yk~0Oy^G`=*GMu`|?t)O>}LeBV z-(WYWPbtN?%)e4irYd7~hpcN-wT!uohv`^(1(%G6?T;Ber>pBeyynxd)sKx!hS!u| z?LggVe}8VMt$IsW=JdI^y>u*)0TpRymxb9PXM5qWW7%6wo%ax5Sy;B%X1r$XLgcwx z+ye1&jr@>EW^3R;$(v*N!pZsj-lVqN9a%24g z*NcDo*n9B~FZE}|RU3FRSGXd`m8BP@OTtqjcp;r&igQ^r{Tc;dqjvLiae)>GV_N>v zNIP{7Z(c%PtcRpr8RIY3VkYYGW?iA-u?sFwrV>Ph8nxJ=IirSshE>0YH{XKTtrKGn*SWclNCO@FVSn3fo5 zTzAtxIF=BXHnEq^@JCE&W6n@as(YzU~F(Iwz#C}r7Nq)W+u-Rv)YZW z{_^9LAzQVh8nul1S^%BaKoYUZj$AjZk+Y$zAoCXU28`AxWwz$yDll5uA;=RZ%-B?B zAP@>p59z{Ud9}1cI}{7*_$+Pl0?S_>-R*5-pJ_vKW3C6VKJWYDYH2Cnsy!-kf1$N3 z{Va9&bk2#{r7>f?OJ4yGT^94?j)f}~X>@ER=>L%8R=U*lE3^IdFgI9o&Y`0I)1Bthx` zLIA3e;eIAY1aKdp}Xt5GVkKOPHYAj?3_B_vivJI3OFtAFH z2JqEr571W=3g43wC0>C6NFf~rzpF%&5<$_oXjV7`+8^sD2ig*=L#WqACszhoBG> zN=_*_A?-Xw+^GKnlb_{I)w{Fbu^w@vc9~Q;;(Y@3OTeRIgM|EnIT{YNYg3x+5fpbv zr9ng^`QGA~{tRzZjOnuMod&n>^;FG){KqHh#Fo;_%F8%2`B?(^Za5<*8e9c3p( zUtKouHwLcF%R_o!6JKM2Gl2lb$tIpqhEo%Si4Q<@zz{I7P{Yvo>SSel_2HtsD|Iw| zqB>Afp0=~Uu7CG)gX+#r%;c4=WC5WejUe4P4>wR=s8J5pzQ_@dy}~InuW&iSdN6Vb zgK@+o2pG@n>nN+tUqsx&MIWFhj0A$LYx3!=RHzc|7vxNtmw#AjQBjHa^alrdiXwIZ zhvw3NJH(9PZv)Mth*Ci%`=>;1JC*E%y}A5@Ds|(+G`(quibVD!v~;XP9qm3$eS`-$ z3ISQzuayVY$ts={0Vw&?(1svIx2Q1>)IVdx`L3MIxKS7L!8VUkLq7YPVy9sF0~2h# zSO8b%rGEyvVh2hdXo2&IKgmjm)uM#zj#BCmrqorKx@>^h0!EUc9bGgL9(rRSm7N_> z5Yhu8Q{&5U(hE{$@k7F)6@&sV*_*3kkM#0nczO`}P`lc_gA?yY^v>S9UUd-3(vKF> zf{oQBo8<`RMAG0f%D}5C48mtgNd4H)`hKC!&erNAxn~+LDlX^n69~XHt896yfB4<1 zKg0np0}8KwHe46ZF1~>wREXt`RiSFabsc^}brUY`tQ18+_$-=*92q2?_nGr>2nX7% z58ABw;B-G|_h}7tRRs2}u+-)E#gegzFMt=`Q36@fE&zH5lHoyxq!lLvBrh}ZSWXcE zz-k38I=i0s4k1IkG=X#}!bPe~1YB2zUZ>|p%wmOFY4a^)oYX~bq zxv{~K_UnFbR)=*H*>7O9%|uLu*Teq$IoU`o_GQAaBMy!;r|XEdZ_$auYiCOkg`+-* z?!`V!h(3F&b3Z%N!DgLbo%ts61-sSrg!DgYsc6oIzJ=@>=|u6_Y-QlZHQ$sEoP_=Z zV5vT*8KW5Y@)UC;uf4gF<&=zcL6)OPzDc|sbKw<(%*sf#i-c;7vmD=aUxz-gkcrys zC}X}(3rji;`Vb**n9Ww8C(bNTQ7p4Me%Xu(E*2J&=L-SHz#!~;R$8Y}wOL3MNj%>B zvspK*;W|ZG3|St>QG;G*jacsKZ#0=$%0F)CMa&A-dmooroJ^2tmACDs8m>zDd|?v# zUAuA8fxPV)8rUr|oXi`d>$Zewx^K})j(YpUd~+f;1rOFo_d{6+@?%wAR7K8U{W|f_ z(=9V)E!lqUEn}|YmwfB=7R)32wQi!sA+qQZ_6#PxIQxW-cujg$VA|PI@bQ~6_^?Pi6{*Y${}7bv+PJe8<MnYL%tAti|*aJqGEQKLCkg-I8aIC3EmC}D6 z8Oz+mO|nLUh^(`u^9~oi;fFIJ#cv08Y*eX^(rz;#ig0iWIRo=irM}!RUW+a;u0>~f z_|F(HgGRnc2CzA*I%dq&ZR-cvGxf83T(gULDeQ&4VN?g$s!BZ30F}1V!>Ed0jCOv) zBy~*IBkSPh=8plMC5NTOx@DR2#ux4|yT%qgd_b0^F#A7xqOHx&G^Mn#q%G*pwg z8G%gW`oexMnr?PMzt4!3$Db@Jh*%g%#h3A-ec0T4qe0nnFLj1lm3|7dKVk|+d0iBi zri4$8xJeYpePU=+p78#cHv}L#=w{=CQ@92^%S`tn1bSns6uexdE_0sqBt}|V(wy>T zFar7H#V#OnxaSnjnwlxd++H;b+dP4#gg~wxI#Esek8M1!;*y97PDSRLFZU9%p6u;d z%9CJNl}cNCE9>3xk~GW}pQNJqxa}wqSazPWJZ|`5*$pNsj1&YCA#)HvFbC!JzvR4` zPVp6>-ZiLWNNvBy{dj$PpklRWfmP5|B-l2jFgqK*|Fl76lBBH?mUciMAPR8AQh6`Dg3t=$=XS z9~^#>LyWA`q>KqpjZ|=IyoopF$=#8p_TDZ^U{*neOvs|NhX6h?!zz{Xk0;jwv-f#( zA-X`MRfFe#@ql3$%e+t5*79PIZbY+q{X_MR9v4ppOHo>YQvk;ahZ!(&-vBGqZT~mnIz|^R*{==HW z+cosSlsZ7yl;@PnAmFO^DTV-! zFW^%Q@q+L|8@9rYL#?MxugG1E3?8~J$sZ++Ik!V05o(Q(zOQJG7$xM9bADI@yV-=)Nm3(`=YOoJO7k-jQiEc7Hs8c{wwkA0E$4MB4oURR z@1@_L)aN&hX9?djnz*NzThCG*a_Q@|NK>&Lvqx`#d8atOn2CgLDNU*2tv*U=X~hXWXXXu z`>4dT^EUzhnkn+!WmXiHwuGUWf9X&8H4btwype)Zfzq-a#a$mZM~cdjhWrDSZ|FV> z?H$R5&cjA1KfU5?Se*h?NQIT=v5bCd%dluY;icmB{F?D8EpZ*6I%&tU^5%n#SEo1z zBSCDLz5>L4T7EiccK;(E1_*jh^7{ZY7!Pm8n@?m`E0FP-YFP9%&Kn zWSZ&HiHA`DwdtE3Q+t*hN#A>I-Ay<=yXg>XjBz3rB?>+=L&1yo&LeyM!W7G}cbHZu z2!R4GNZ=xpeCGts2u@WPXz1ol3gz-yO5gKjd$5`0RG-Gf+C{E;vyRV-ye4>7o99sO z$nL9EEwhF%m2R9^5>*YI6e&6BA>liCMGW`lb-zYCQ@H#u9=;^(+guPLo5;*6)<#GoY}3<5XYL{J-Zi(6wE zoN|oGb4FUT5$T>LyFZ5w*Xgk5%wO3Vg|dlXKh_@5?5x{=mCZQF96V`BciK1LcxaMmEzn8wk+X~z!yxme z->$!)T|Uj%!k3?HyN1N%zE*dPH{40Xe8mgf(nBP|CA5&^ zhEI*(>o@^lFj;P@A$+ODFp3%HYcoN{i{rY~u4QRW*u+y-sY7A&_2-M`1J7a~hrK%@ zxzyyjr&f@0)82p^4-tOf_$yVFo`=2D3IR1FLzAEzs47|)c^=lL8X98-Q0ehr4JcTh zI8LLOmdi~3vNuA?n+nzC`>4~nWkQ;zZ0$DpAYF-M)!D;_?t)tmbkX$Jfo|vqQP#?V zmf;0Ux_V9NB^cl5-?;2zu|cyO2C?(TA~UGDoiPo3|5|Nn|A3U>FJ>1mnn{&mkRc_{xXAvkz3xGmZR{Tx&mhZ^qB&g--*xKlLz>aAnCtW;}ZO08_(1n)^Q`=h@$>@wnNCQd%M&8tRmg z%hQ6gw&ZPbA8?eE*(nqS*(zQYaz zp)!}-ZC0tMO~mdtPS+hIx1R@467B3qLo#YtB|;oXis^M7=QjH$NzccI^jy^PjZ?zr zqHewQ!ClOkH0vKvCFzp(fbxjPxg~!keK%+(T!kh7qh9YP?KBtSnH0S=G5y^ zIcFb*7(;BcSWs5Fod&Kq$Z+2d842K+G{7+_Vjw_bKFqn(zI}PI{Y{d|CyJiqZw1{C zaI``jC$Jt`j3qDK6{lQ#rtiOA%g2IEvo_UC7?Y8g`Es8dkMN%&Fu$rvJ59Kn+Eudn zP~J-#KwEwx&O|0j2r2vvAOo2;QiM;q1ONtM20q%s#~ttvC?edy*ZR_6f5_d^J2<5G z{S`_{e_Hr~(yRe$%$J`!KlYP6^gi;CxZ2zFYGZgplnbm5Be6uBh{j$2>a$+W+cui2 zrUwlw&wTyQKfx?2aVaTpKcSI^>YEdqErpji#?N#bkjBRT{=IQn`*+*4)o>;!90KdL z{4#(v+&qH`g$Vj|x=p@RUnK42yqsIRdSkFBf~2QK4ETtS$b?AQF7;2X;2$%)6D{tc zG`{5k->;}SgAF!}Pnw}h5mDqzG53m(v8DEYn3qE{61>Lwy^r0^?VT~88tHak828+- z^M-ayO!3dB&0?dBu0@LkDDggHMxNEIb`n7MZaCr9f3FuB z_>|LV$K<@z2tX!|o|@nYw!XcZJ+&cTQ6jSWTte)SybzZ=Sh~CIa|0nJJM*`(ekQEIS8##w^N1VxNKlDDpjx&LsE*nEI9?O5vkhBef-eH7g`<&%( zEWg79SFY>vjf{)NeA8dj)S+h|MKsk0YhzpQcz`sjN3CQ#IbJUC5%pj&i3(5MD7D_8|IbaIICe}kR4^1`nl!6 zbPyW_9;y0esY%($=^S>3{|&t07#UE1)zrV;z7+j6_}QksFjSO}p=OjCq6nqgght+nEy;ey^k`=O8C#uGsvZeCEA>xq0yBjW zoWQsf>QZrMW3{@Edcrh}E<33uE*6jkS>;^V8L}7VLDf>vXIV$N6VByKj@>b6P?U%9 zwsI+Nr6#?s!In=Y^|?6Pu1=NK+<`g9%(-M_77t0N-9@>}mJNWlJ_B)4zS$T|%C8XD z!8Mk|3NdZV^M7kL^;6NJf-eF0xDQ0s?jqAe#@v~S8h4&TC}p6QlQc!LldE#dOz&9@ z>HO+L%7lTE0!e8ToqQB}kzPSm9srvKTlxF5V=aDWR8NjV;HG*8C@v>Z^R$E46OoU@ zL6dbb`O*bp1uupcs(BoA&{=MT7r+Rgq@k|QunP-L2NvqB@O+?QO28KEEW~#yKY6nx zuB72FPu?gD>aCi|Srvd1&ohMRr-n6}=b=hZ&g9K-Ds+T7a~PmS3qYlw{8?ET%-TQx z@(n384bFb=2E6^uTlNXcwdWGaLxHSH0DSu75KjX$yMZw~o*W*Y)!i^AG^S{M`-B|C z4iD1;&;R(RWv+Kg2=$4?{3rLXTqgj~4D8&{Cb9VT9$~Sk_g_9$p#mGwCV=^5v7WLUcsPr@RddNe9~b zhOza;#D?LQUjY_*32;JGIvug=l;4rxlkxEN;6JfND>kCrL!;BfW{HHIlQ0$|0$>1V zVqiq%NznvBtdKa*CVoy{^DJB=2wNbW!34?54(UFeFJ#j-W+1-$25|I-yzJWx^Q=F> z@Vhl6XyLN6c`xvxWC9Q$$h#veYU&Grys{trhh-lofEG_sY#G=x8vjF^Q;lcs<+9T2 zswdbCV0F}+vdiVMhI`?tf+K$_Z44lQ*$QvP#4QSC_NBrL5To{NE@wFXwGI0pf^kE6j)&;QLt@Un%cxV#x~AA5 z0Rb%aS)Xl5$?yPKCRw?m)TY@^M~N6TxPK=JZ2f*}nk(hbP1d;l4UV9|2hf=!gEj(h zloaq=+~B|W9W9RhZ2tskz#Moi-oOh71bT;)f4$kqKUf3Jc}z^+I1K7d)#l<%xWS!; z?6g6FSTR>*nsHO!vv^ti+*mOQ{ahF=MFv2cYZM# zM?qnHYW@SBSRUyGbRb+-R&5+(!TO^Y4bbCP2J$X>t1dIPD*>6OE!S`jj}_Ke>dBf` zDVE$%+j3WB$9>uNK;(1)w@f9{wUAXOwq`L=dfy)b@$B>x&y!tDBkYk7@;=(t6arsW zFt~|#{9u7c_8Lis=R%)1jM9(U|Piyl9N;K zn{JOMlI|zcLg+3K7Rq`+CV$60Cmv+YVf?;n>c8=47fsVUO`w!d3x9d zkuWW}$yLt7Eaou8Z0vO=GHD|z z%rihs*AYV6d_o!9BBWvApBVk0-%;dVAVXVWxPKZ#|FyhEPy{%{(IWk+X%?!=5N!^7 z2GqY%@u5{K=-vTQTkm5`0iX8^<=&tEGb-c{CQcv1>P#rYtyHF9g2ejWB>n$=n%#>4jwM&8qcen z{QwB>A2tsv)vn;7ZfF?ad(-ov`EK_f*s2!xNr;J4iaI~H4R%yPBNtCl7kINf5}cfx z+BC=S28e!tVL5kotg>>*+{P7R_dq|lck9f|rd)UKm&=}=<~e>IUf$Q~Q)Q>H0-{(D zCNCitbq*rmDNx`w+y)Hk?i0IlJ=}3_;2fKlx0aJISwDmS^Zbvu)n@DFP#QWP5x;9y zLxU$xSVlPP^z{oje7Pd4O(qK%Cj+$cA@8<5p2d|j#{tByk=|{{20#-2OBPZ(f$SKO zt(%<&kE@U!0I>Cx8f5N8PDN#CT&)VzG<%)NyerLw2F&nicX_pTcDmVVQsXT6*nQkS z@(kX(m9Ui%&jAfE8@|UVwy59|gKd_w(eAS8@Kl3| z$#MowOP$jEN}IFHGq(?@{2Ax?Mf7G#OTp!$kam6^_2%n-FN7vXa4uRdXPv^ll4o9)HUfJf-2sU4z&$Np-3 z@r^JES`9`6qeTyT=j`8YVTQz& zUJh=3Wq;Vbe19iK=nK2?4ESj^-DsWJ>;#-ssBSjRGj4Q}S5sDEENLBfSi|saxOM^q zz|(FcCnhFv?(nNeTWk9ZZ8MugCMLhqF&~zvv;LLq453qlqqUQLWL@Y@I6$?{lT@)1 zVWp<8UEVE~q9uYG0oCQuKs-F31Qn-NNYgHD!VIu>B3%%Q`04|&%!;p9=jX@ zJ2LPpNrzz`Q5i1}S2-W$3xG6um`dtrt__T@STMQy>p`o)7D%0YHs_)b-%&cT{0Lzb z&|V)^SqV7LrUCcc2kXbBt);ECvEyyH2W}3o8Ga6z+lOHj4PaANtEr*RH7Q;6FkO`r zfpZ|{Lj!F{KD%((Pc^1+&_(eWXiMkD12)+3CS)k3K@is$Jmu=ybbEDt$J`YSxvy3Y8jyw zZPQmD z);Od)g9(^PjzZQOgpjCbdzSg1i6(lz_Zy8~vcd~frZr`8`niDMfUVB}q zBlfsCRXTd@wXer;bY!UIvF!v>ja@HE+Y(TPFVvD>*xR^Aun4;my zPAToBUmG1p6zv(jM^5oT#Oj8s=CBLe)&3GI!SQ#teG=-dGL?(4S)zA8z^#Mt+Ge;I zBdB5aH<;8J29PcsG~qm%xZi1r473d+cI9i)ar1Jo`VMh?!UhZV=f$JPqqEvAt)2a8 zspVnF;)k=mM^2>9&E;vET`-rTz?%nI5Lggww0_%swzrQbT_X|Dw&y0JOBy#B0XBNw z=7NO*HDh_Hj1pd%OK;}82 z`vk~nhMVRmNOiybL53EbTxUQW0|ck&@ZEs2myTEurEddU3_l^^)ZR-RlXhD~(Q@Ks z$Y(Hs=eG&&p6@~B;|s{=;JftgfB|(gy>_ZW9RGZuKUF>68Ep?vuZ78 z*K-SUop0uE4nC)$7T+PSe_14Hp5bPi2{6VC@u4jG^1dc2A>|SHc3yO{;5g;N&&LF?h`37itELn(6tgHv>^!=;bXBc$S^uaU$}J%8Q*sMK6djj|{{0-GC_vz~tJJb9 z%DkT2Wrww(+v^6&UOD;F%Xr=0N^PHvUjzHqC5;2e&m43s0uz0K3<9f0$ne2a-Lt-G zU6rQhVb{|h72Vx`XYv~mZ2nerzkjER8f0R{gfz2WSo0v*fRTn=?8e9Ge#g4IBvp>${N{6^NZL}Y&;YP$7RmKw zDQoDUhY5mJLAs3#z|Q(vU)L37xL?!rY+|B;|5|!!`<@{U+|$O4FBE=5LYUI%)MQeD z2UzLP8@VAq6E^KVt+Hi{$H&vUq#?|om7TarhmI(DUw`Pgw0>PcW#j29(-|n@n!?zn zkZY^vs_C`S)4W5gaoT6z#jnbw_%?@=7UKd>FWln`%4f?J5@gq16#8j_p`Q#RYAC(9R6*`gueswO&QCW7Q1$JiN|LI_%}?j z5GP$-d8pw<+?1|IwjyKKhh*fbcQ;J^^`ycG&B}a*yCzm)es;r{r>ax$2iSV-EH8I% z>&@S*=i+fWzjKS#MN^i4s?h54+3PeMnwd{GIbWDfeZY?uXOccoOI@eBiAJ?h-xxxD zbBL48jUJ~2n+jNx5{j)gXhnwEdpvcMw@J198uoqlaWIru*8;C zx?>rV;?J4G8*8)^!A?_e4!kaTW%+U5dPYl-AO>%KnSTr;`60=IY9n2cTau*3-xydT zNW4{S(i7X#M}1+rNg15SiO1E(!O2_shzR_$LpIi8z*}*1{*BHPznZ*cR5IoZ zJ;Kp=HloXIxuS4TU~Y@3rOk2F7|V1ZWULi$!mf*Q%Hr(;?Kb0(M8|^x2xoW1GQxgpCWpx>vce>P|Gw?0elx`%0P1QD$F&LZr3%6 zRlluyxpCTz&Exx$BW<%C*3Dd=fa9O^lEHUs7IMbSfhHXFOa5Mpv{BitszFSaJkxTZpGnwg?A{ z_ys7aGz_&T*$xVgUjJTzyOnT7ZlkJfJR!0e)hOS3rI_@`T)mks2iBZ;CnRUh9p!|! z!uRFPF3E4>$Mv^$1z4MHCJ~&&vkR#=TY8hGqj{PzE|!y$13DkZKcfyt=iqYSO;e!L z0^MP({wEfrO32A`a-U_<#QDs&in-$YhJqh#mslu0IEVYY?A-&EVi3QhZuGRZ4`_lqv^H?4;!kb zMnmNWBSQ*o+AXZ9CT!l4Sl0|ji7}36-uN#~Pe=95x|{mHPo~{_bEoliQVb3;RN4q^ zA86Ff$JFAl_f}Z*bNJsL7l-^gYv?TQ-yyPZVj27%M1yrsEpxY`nkUE*XD!*$8RMd{ z+nxKc-jeyfkh43{-gEW(oz3p7W;*V|*IbPPWrs&vKGFo5g)s zZp(>@Xn$E2r*N{W-n}3v`{0h%Xr&4RKvt%YsFR<68J!0&?2Eo&x=c;uNv` zyFyN0eeMeS74&2>{enC3Fk}l%3eP6c#^OVvV z7rhJMMbc~wn&d1|pyb9wzn>cKQrnu=A0|)-_HuyT%Q{kACQC`9X7$v{GBLVRXNqq2X%bf?DT(3vLyGrvi)PjxzAR%-}HwYZ$u2_ zO1wv`HKp~K&Wltk=Y-?B+d_Ox{ki5rLhnYc$@k?x!;}NV9v*#?w2LhnX#=IMXZ7ep zdw)r1u_uq+jkuoMnh0@USLiLyxpZyYfp>0mc*to+RgUJu*} zi_nO?c?VvI$sgg`y5F_y4bS~#p3!|2RV2=r4B92aQES0-<9u_Sr(dArkjm%sD#Aeo zr6Gj+~OK63LAxl{7S*R{&l!NQTVkSjvoPTNV z=FlCl)tKGv6y6`!J0X+N3F{`L^%<{M;tJopv9iUPunuMb5MYa^wGly94kk)cikziW zhK1R)8H4yihAV0*z9PbG;I50e6$)vSDLIOLkkwx9C0OqGe<0)J?gb88CFf*fQ-0Y6ru08 znb`)(Y|?`-ZqaIk(IhC~r$izaaIO#eoaQ6M2wxTL>oI) zy>E)&`?)*WO0<*S(X|UUSwY8-1({6H0L&D62?0 zr2k%}I^s-*_yOgMWTE%b=Tz4`l?mDfZy1-G72EQz3igxpmgL548i|y71Lg1L!>qex z^)Uvt`^LYFR$fLwaG=A$Vw(P{`JNvF*LR3hrh>AG^?El%5mR^b7IuW~1Q(tkb=}G` z&LfXy;h9o}}`GjwQ+wD9UBao5SO+!@# zyKn;aI5BQqK2^<0i9aMI?rr7TU0hLf&!6Pf!iXc4v-$Y$5v>adR^FXHUd1t1 zKU|;G^0d|7dS+2I`u=e8yOmpcrKpgezBUx*Tr8D|lvr9)j5V1-6LqWqP^ zRgRQY%=yQu?}ixaue=A!YZ%+`rbU4v6=IJTd+K(OZfP~7B$_i9w-6O!?Z zx6|e|3;;yD(>)|gOYUNIMH)y_>y8s=iX~oTyAgo&zT&|o8GbQ|0;7ETPteDg(Mfto z0s$;z$ssir63><|Sc<};SXZlum#!py3~g@TL5AN|mmsA)QE{;F-o6E9$UjLs9N;p! zU3IiPOd+Q+c0dmc_g9;9=v*#cHoV>drg7JFYg1>VN7d$)0u&wMk%1i9WtS_pPE;;8#WV4VR`5cf4RZz-YgcU`rQCyYpO!<-c~De&IgB1xtusy|fJ3`Hv*|hRIW)yZ2XKzNt9z z=q`MF?i_9awgrGPT5gV(bLS7|^+6??k4{c^Qw`w&uj?)uGbeNm9^OWQv5Rgn_dlfy zg*P;lTkDQJGx-znumQVgsdiCU=rU>gM6R2UcU&X10fz+!z+=B$q5;X6>-ne0{o9Uv z-z?v(sFFXIzjiqP1-^~|R1J{uLNh-H7hg^jva`5h{%Q_p$Y7V_*Lww6pirg;Kp#^F z*rEpi3iW80{)!(0SlUZ1-FM4bVWk=D0_UdKj}{?N*j*D)Q|Z1W3Fk6u02;sace|-g z@=*VQP^Q)mfN>xI$On6$@)b=@H4Tm(0N(&$KT~1wcMz-t0JZ?t0H95}=s%fkR+Q4+ zQ&Bb^>3QKQkPtc2>G-BT;jh3NRk`(|)OvE3u~1yzT=lqrCHfaJwS`gbUWG^&GCt5T zgi-dS7(mD{kJeQ_+ud5eIPv@+5PFfYj4QR)_kDBo?;Oc3e^*qyXTXowrq{%iRa}9{ z*X+d1NMO4?)ZhtQp961#E$mu%oX*g?rf*=}tv&StU=@sp4S7NeSHX_S$!Gbb69@ps z9u^VZIeEjvTc4joAB%=OMgwSVfL;fHf436G4-%FE(C-scG3p;8t>3VZ*NGS4i=T^!u-Q%RtmfmAr?#V zW2sP%usJ*M3W*LB@x^O{u<$4lyUPk>_=*^|Lmm8<37!ew>|c(Q0iait2Eo&{C{Ht# z`HrMAP(Z0g0SJL6<>E|Ry!`)2oQ4wol}DUO^8E_5J{J=Ef0uu}H^KPuR4bAW6bMD8 z)lHOd`KPJgi(3A}27M|%SDU(m4x}OptOzgC>#K1;9lw#@FfK%Uy##B_l4J=J{?M6^MXF!1t(2t4?Ud~ z3!zo@+W1@uXq18|oE6YHQu70B&%%}mZGreC0r0fwr1G1;EQIdXZ%^+_o5Dak+5ifH z*2rV^^?(EP*(ZG$2U-Gv0kT7mpH9XJye#7)E^IVI3V2d}$O*TWF%S%L=@g>};{{@dCj0Db}EK5a>XM~{LK1gT56&LgT5 zg{ycR+zmsaXgqFjzCAX~kn(V@GYCoEte6lA?g$$Ee?o)?xrF5-go$uJ|KTYmlu2rA zA;?c8`T|`C02lF$wjkH)0F}Zh=o)h+UT8uzy4CH82Y*aF(y1X&40A#Ua4cb>gPwfF zU;^46fB~3LpF^tr0^mvnD20`#nKjTQ^8qW^SD?mA3zPfjNVXmmsYfTR8KIx9$rH=)yKjl%LAB!=`X};Q^Qj@iC_<0KYUro&_wa@ znsq+O@!-vKdmILa%Hv~)<}IV7)7`AJ+|tNfcaGgmGxl(Uh^pM1;dc`A2%+u}p8Ew)Rn7D^!1X$Z^Fc%E7#W z7^aG6DU9};=>@>LldevZ#YOAj0pLgh=}1P;1aV$Zg=)!Ru(Ri_75ce3j0&j}%1zZT zif7wvw8hzH*(D+2dOTM?r&#%ErNuWjr$}llrcr%K`wqw)P;UHRi3%W3VSI!b(h#EP zwprfnyuALv(*c<0yeeN;+sGeju=R4(CDYYIwST|*AO$9qQ`cd1ejDH;o2Rn-X_=-?#nfZC;Oq!lxipT`F=Um zlm>oTNCT4jPJdU&7Z{Aqm*w5f>wnO-%kj9V$sn=87pueP{btSIg_z%CMD)9R0Wlun zQD_ACO&fIA8z38QXBBw~v7Ex`I3e7y-a8gz%-^-JuhPZyHnF}h3g;2DV|$(_brY^h z43p3JN%4E=y^VC)+KF3iSxRR?P%7K%%v60D!rjM=l#*smP`M=O=F&>4sj6^?$8Jr- zjQqn9WhoOJ7;~L~|LP^2Gs)w1MYB>+xJf3f=Ut)eHYFbzOUURz2u0#6tsGxZEv_(# zcBDYH;|EH6HYWW2cj-OCa~&bM$YbFM>m{!w*@^-M0ho35eEv}e)z*v>ze(Ppbj$G| zx?}1p0cNe0qt01zSk)vGk9{WEb;GIg-Uw}*%hi}^7v%}P&@B8MjgDzS{uHD5Mw;L{ zx%$++*AwY*QVYJB2_3KmU&lV&F_2KXDWi({VwBD8f2xWATd0CZ_PJ=xfc-R{%=^<& zIt4_P4wFt4G}W=bjwo_q8BUfB6Jx^SDCFl2b_Zi;<*o3g|IrnaA(MJ{*BSoU-D0kr zAWQRhnF+Brsy{nMk-2Y7LRCVjBs z)YjYLvs)B+=_pydw|EpfnsAodyJ@yHrFKyEcb8c6wGk_&XOXIOCnfXL9heM+DXk4& zwWGns#a6Gq!5Pl5E6PSvF3PrzuhmZz$2R$yRPUFry@_a5VZ$Xh@t$3!N-d^3k^^2G zE}C*|s^KfIjmJ)#%qNAtBF3$Xx1T?}=p0x%1k!-Yx$_{>HUS@KIFj@+eSzLctr%cH z+K0_p{(DJJaf-7+Ut~fRuC|Zv`P?mvA^r3}`An?K4I`z#F=O9k&yicrutuN61#LfP z$9pVrVoya8qZ}C>a-@k38i@xT)LUn21vVMHWXSjBbW9bl!TYoBozK{gDsiUKrA<>u z!?yipwoSb&X8WWo^IP#%YF!;vQ$l2$I1x+W}=nGbL zaXGbxyN0 zVX6#Wc-j>{%H(u_*xX_Rb&GqM&`UXSHk#JRZs6C=aoZtjb!?7ON$=x&j}~n#QcrH= zl6uMZR$t263ouR|j!`6%VIvMKM?N2F!~N$H&hNBQtslNWx{+qSBBlfWR1juONDklm zAyT9K62`6LQFifJP0CIo*#Ox__K*Q&ucB9@ZfAySCMG3xihGtk(OvUk{& zHCsAZQ%0H7zA>F`{Y_1|uM~U*U#3dJM_l=7{3YhuKUNl@`oI%!i&3x>GLuyXJ zy|sERQ4kr&82a1pE&SH*$C%&W6>AfCHV$MMVNA-%?>S{1XB2%<4o&R87C{9r0`caVmt!uf-bvbN z2$z|_!07!let8$U!DVyuFWgl;<@^Vt@6_*54-p9$sf%0_A*D}#3^

bA{8_7 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 literal 64812 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 diff --git a/.workbench/spec-salary.html b/.workbench/spec-salary.html new file mode 100644 index 0000000..41ee387 --- /dev/null +++ b/.workbench/spec-salary.html @@ -0,0 +1,564 @@ + + + + + + Lønspecifikation – Januar 2026 (2 sider) + + + + + + +

+
+
+

Lønspecifikation

+

Periode: Januar 2026

+
+ +
+
Medarbejdernr.: EMP-001
+
+ Medarbejder:Emma Larsen + Afdeling:Frisør + Ansættelse:Fuldtid (37 t/uge) +
+
+
+ +
+
+
Bruttoløn (Januar 2026)
+

34.063,50 kr

+
+
+
Side 1: Overblik
+
+ Kort opsummering til udlevering.
+ Detaljer findes på side 2. +
+
+
+ +
+
+
+

Samlet lønopgørelse

+ Alle beløb i DKK +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
LøndelBeløb
Grundløn inkl. overarbejde29.322,50 kr
Provision i alt3.685,00 kr
Tillæg i alt1.056,00 kr
Bruttoløn34.063,50 kr
+

+ (Hvis du senere vil have skat/AM-bidrag/nettoløn med, kan det tilføjes som ekstra blok her.) +

+
+
+ +
+
+

Saldi

+ Ved periodens slut +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
TypeOptjentAfholdtRest
Ferie (dage)18,56,012,5
Afspadsering (timer)12,04,08,0
+

Saldi er opgjort som angivet på lønspecifikationen.

+
+
+
+ +
+
+

Hurtigt resumé

+ Det vigtigste +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NøglepunktVærdi
Normaltimer148,0 t
Overarbejde7,0 t
Provision (services + produkter)3.685,00 kr
Tillæg (aften + lørdag + søndag)1.056,00 kr
+
+
+ +
+
Side 1/2 · Overblik
+
Lønspecifikation · Januar 2026
+
+ +
+ + +
+
+

Lønspecifikation – Detaljer

+

Periode: Januar 2026 · Medarbejder: Emma Larsen

+
+ +
+
Bruttoløn: 34.063,50 kr
+
+ Ansættelse:Fuldtid (37 t/uge) + Afdeling:Frisør + Medarb.nr.:EMP-001 +
+
+
+ +
+
+

Arbejdstid pr. uge

+ Normal + overtid +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UgeNormaltimerOvertidBeløb
Uge 1 (30. dec – 5. jan)37,0 t2,0 t7.400,00 kr
Uge 2 (6. – 12. jan)37,0 t3,5 t7.816,25 kr
Uge 3 (13. – 19. jan)37,0 t0,0 t6.845,00 kr
Uge 4 (20. – 26. jan)37,0 t1,5 t7.261,25 kr
I alt148,0 t7,0 t29.322,50 kr
+

+ Satser: Normal 185,00 kr/time. Overtid (50%) 277,50 kr/time. +

+
+
+ +
+
+

Provision

+ Services & produkter +
+
+

+ Services: 15% af omsætning over minimum (220 kr/time).
+ Produkter: 10% af salg. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UgeService prov.Produkt prov.I alt
Uge 1573,00 kr210,00 kr783,00 kr
Uge 2883,50 kr320,00 kr1.203,50 kr
Uge 3459,00 kr180,00 kr639,00 kr
Uge 4769,50 kr290,00 kr1.059,50 kr
I alt2.685,00 kr1.000,00 kr3.685,00 kr
+
+
+ +
+
+

Tillæg & fravær

+ Opsummering +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TillægTimerBeløb
Aftentillæg (hverdage 18–21)12,0336,00 kr
Lørdagstillæg (før kl. 14)16,0720,00 kr
Søndagstillæg0,00,00 kr
Tillæg i alt1.056,00 kr
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FraværDageBeløb
Ferie med løn00,00 kr
Sygdom00,00 kr
Barns sygedag00,00 kr
+

Ingen fravær registreret i perioden.

+
+
+
+
+ +
+
Side 2/2 · Detaljer
+
Lønspecifikation · Januar 2026
+
+ +
+ Tip: I Chrome/Edge: Ctrl/Cmd + P → Destination: Gem som PDF → slå “Headers and footers” fra. +
+
+ + diff --git a/docs/design-system.md b/docs/design-system.md new file mode 100644 index 0000000..6acead2 --- /dev/null +++ b/docs/design-system.md @@ -0,0 +1,221 @@ +# SWP Design System - UI/UX Dokumentation + +## Oversigt + +Dette dokument beskriver det komponent-baserede design system udviklet til Salon OS SaaS platformen gennem POC-udvikling. Systemet består af **150+ custom HTML elementer** med `swp-` prefix. + +--- + +## Design Principper + +- **Custom Elements**: Alle komponenter bruger semantiske `swp-*` tags +- **CSS Variables**: Theming via `--color-*` variabler (light/dark mode) +- **Responsive**: Mobile-first med grid breakpoints +- **Konsistent spacing**: 4px base unit (4, 8, 12, 16, 20, 24px) + +--- + +## Farvepalette (CSS Variables) + +```css +--color-surface: #fff / #1e1e1e +--color-background: #f5f5f5 / #121212 +--color-border: #e0e0e0 / #333 +--color-text: #333 / #e0e0e0 +--color-text-secondary: #666 / #999 +--color-teal: #00897b (primary) +--color-blue: #1976d2 +--color-green: #43a047 (success) +--color-amber: #f59e0b (warning) +--color-red: #e53935 (error) +--color-purple: #8b5cf6 +``` + +--- + +## Typografi + +```css +--font-family: 'Poppins', sans-serif +--font-mono: 'JetBrains Mono', monospace +``` + +| Størrelse | Brug | +|-----------|------| +| 22px | Stat values | +| 16px | Page titles | +| 14px | Body text | +| 13px | Table cells, inputs | +| 12px | Labels, hints | +| 11px | Table headers (uppercase) | + +--- + +## Komponent-katalog + +### 1. Layout & Container + +| Element | Beskrivelse | +|---------|-------------| +| `swp-page` | Hovedpage wrapper | +| `swp-page-container` | Max-width container (1400px) | +| `swp-card` | Kortkomponent med border og shadow | +| `swp-card-header` | Kortheader med titel | +| `swp-drawer` | Slide-in panel fra højre | +| `swp-drawer-overlay` | Mørk overlay bag drawer | +| `swp-two-columns` | To-kolonne layout | + +### 2. Navigation + +| Element | Beskrivelse | +|---------|-------------| +| `swp-topbar` | Sticky header bar | +| `swp-topbar-left/right` | Flex containers i topbar | +| `swp-page-title` | Sidetitel i topbar | +| `swp-back-link` | Tilbage-navigation med ikon | +| `swp-tabs` | Tab navigation | +| `swp-tab` | Enkelt tab | + +### 3. Formularer + +| Element | Beskrivelse | +|---------|-------------| +| `swp-form-field` | Wrapper for label + input | +| `swp-form-label` | Form label | +| `swp-form-input` | Input wrapper | +| `swp-form-row` | Horisontal gruppe af felter | +| `swp-form-hint` | Hjælpetekst under felt | +| `swp-toggle-slider` | On/off toggle | +| `swp-edit-section` | Redigerbar sektion | +| `swp-edit-row` | Label + værdi row | + +### 4. Tabeller + +| Element | Beskrivelse | +|---------|-------------| +| `swp-table` | Hovedtabel container | +| `swp-table-header` | Header row (grid) | +| `swp-table-body` | Body container | +| `swp-table-row` | Data row (grid) | +| `swp-th` | Header cell | +| `swp-td` | Data cell | +| `swp-table-footer` | Footer med pagination | +| `swp-row-arrow` | Klik-indikator pil | + +### 5. Statistik + +| Element | Beskrivelse | +|---------|-------------| +| `swp-stats-bar` | Grid af stat cards | +| `swp-stat-card` | Enkelt statistik kort | +| `swp-stat-value` | Stor tal (mono font) | +| `swp-stat-label` | Beskrivelse under tal | +| `swp-stat-change` | Ændring indikator (+/-) | + +### 6. Søgning & Filtrering + +| Element | Beskrivelse | +|---------|-------------| +| `swp-filter-bar` | Filterpanel | +| `swp-search-input` | Søgefelt med ikon | +| `swp-filter-group` | Label + select/input | +| `swp-filter-label` | Filter label | + +### 7. Badges & Status + +| Element | Beskrivelse | Klasser | +|---------|-------------|---------| +| `swp-status-badge` | Status indikator | `.paid`, `.pending`, `.credited` | +| `swp-payment-badge` | Betalingsmetode | `.card`, `.cash`, `.mobilepay` | +| `swp-tag` | Inline tag | `.vip`, `.new` | + +### 8. Buttons + +| Element | Beskrivelse | Klasser | +|---------|-------------|---------| +| `swp-btn` | Standard button | `.primary`, `.secondary`, `.danger` | + +### 9. Charts (swp-charting) + +| Element | Beskrivelse | +|---------|-------------| +| `swp-chart-card` | Chart wrapper kort | +| `swp-chart-header` | Titel + hint | +| `swp-chart-container` | Canvas container | + +### 10. Specialiserede Komponenter + +#### Kunde +- `swp-customer-avatar` - Rund avatar +- `swp-customer-cell` - Navn + telefon +- `swp-customer-header` - Profil header + +#### Medarbejder +- `swp-employee-avatar` - Medarbejder billede +- `swp-employee-name` - Navn display + +#### Faktura +- `swp-invoice-cell` - Fakturanummer +- `swp-datetime-cell` - Dato + tid +- `swp-amount-cell` - Beløb (højre-justeret) + +#### Produkt +- `swp-variants-table` - Variant liste +- `swp-stock-display` - Lagerstatus +- `swp-margin-display` - Avance visning + +#### Booking/AI +- `swp-gap-card` - Ledigt hul kort +- `swp-suggestion-item` - AI forslag +- `swp-optimization-score` - Score cirkel + +--- + +## Pagination + +```html + + + 1 + 2 + ... + + +``` + +--- + +## Ikoner + +Bruger **Phosphor Icons** via CDN: +```html + + + + +``` + +--- + +## POC Filer (Reference) + +| Fil | Domæne | +|-----|--------| +| `poc-salg.html` | Salgsoversigt, fakturaer | +| `poc-customer-list.html` | Kundeliste | +| `poc-customer-detail.html` | Kundeprofil | +| `poc-employee.html` | Medarbejderprofil | +| `poc-produkt.html` | Produktdetaljer | +| `poc-gavekort.html` | Fordelskort | +| `poc-kasseafstemninger.html` | Kasseafstemning | +| `poc-rapport.html` | Rapporter | +| `poc-indstillinger.html` | Indstillinger | + +--- + +## Næste Skridt: .NET Core Implementation + +Når design systemet er dokumenteret, er næste fase at implementere: +1. Backend API endpoints +2. Database modeller +3. Razor/Blazor komponenter baseret på swp-* elementer diff --git a/package-lock.json b/package-lock.json index d0ad451..6bc1f15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@novadi/core": "^0.6.0", "@rollup/rollup-win32-x64-msvc": "^4.52.2", - "@sevenweirdpeople/swp-charting": "^0.2.1", + "@sevenweirdpeople/swp-charting": "^0.2.2", "dayjs": "^1.11.19", "fuse.js": "^7.1.0", "json-diff-ts": "^4.8.2", @@ -1177,9 +1177,9 @@ ] }, "node_modules/@sevenweirdpeople/swp-charting": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@sevenweirdpeople/swp-charting/-/swp-charting-0.2.1.tgz", - "integrity": "sha512-QtY77Dyv4Vs/rWfBVSDTmuxgD4L8tGu4pmTF0l3i8HDwK6qtT2wEtH35UHD1RDFE1VtOGcnU0/dTdqjNWCqzxA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@sevenweirdpeople/swp-charting/-/swp-charting-0.2.2.tgz", + "integrity": "sha512-q9p7TOSMAq6I0t6jGEWpmjR7l2H8q8G0TnXbIpDutCz5a2JEqMDFe0NGBGcCwze2rvvRnRvCz8P2zGMQlHmphw==", "license": "MIT" }, "node_modules/@types/chai": { diff --git a/package.json b/package.json index 36c19f2..8e2f69f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "@novadi/core": "^0.6.0", "@rollup/rollup-win32-x64-msvc": "^4.52.2", - "@sevenweirdpeople/swp-charting": "^0.2.1", + "@sevenweirdpeople/swp-charting": "^0.2.2", "dayjs": "^1.11.19", "fuse.js": "^7.1.0", "json-diff-ts": "^4.8.2", diff --git a/wwwroot/poc-employee.html b/wwwroot/poc-employee.html index a829540..36b7cbf 100644 --- a/wwwroot/poc-employee.html +++ b/wwwroot/poc-employee.html @@ -2266,6 +2266,152 @@ background: color-mix(in srgb, var(--color-teal) 15%, white); color: var(--color-teal); } + + /* ========================================== + RATES DRAWER + ========================================== */ + swp-drawer-overlay { + display: none; + position: fixed; + inset: 0; + background: rgba(0,0,0,0.3); + z-index: 999; + } + + swp-drawer-overlay.open { + display: block; + } + + swp-rates-drawer { + display: none; + position: fixed; + top: 0; + right: 0; + bottom: 0; + width: 420px; + background: var(--color-surface); + box-shadow: -4px 0 20px rgba(0,0,0,0.15); + z-index: 1000; + flex-direction: column; + } + + swp-rates-drawer.open { + display: flex; + } + + swp-drawer-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + border-bottom: 1px solid var(--color-border); + } + + swp-drawer-title { + font-size: 16px; + font-weight: 600; + } + + swp-drawer-close { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; + cursor: pointer; + color: var(--color-text-secondary); + transition: all 150ms ease; + } + + swp-drawer-close:hover { + background: var(--color-background); + color: var(--color-text); + } + + swp-drawer-body { + flex: 1; + overflow-y: auto; + padding: 16px 20px; + } + + swp-rate-row { + display: grid; + grid-template-columns: 28px 1fr 100px; + align-items: center; + gap: 12px; + padding: 12px 0; + border-bottom: 1px solid var(--color-border); + } + + swp-rate-row:last-child { + border-bottom: none; + } + + swp-rate-row input[type="checkbox"] { + width: 18px; + height: 18px; + accent-color: var(--color-teal); + } + + swp-rate-label { + font-size: 14px; + } + + swp-rate-label.disabled { + opacity: 0.4; + } + + swp-rate-input { + display: flex; + align-items: center; + gap: 4px; + font-size: 13px; + color: var(--color-text-secondary); + } + + swp-rate-input input { + width: 70px; + padding: 6px 8px; + border: 1px solid var(--color-border); + border-radius: 4px; + font-size: 13px; + font-family: var(--font-mono); + text-align: right; + } + + swp-rate-input.disabled input { + opacity: 0.4; + background: var(--color-background); + } + + .btn-link { + background: none; + border: none; + color: var(--color-teal); + font-size: 13px; + cursor: pointer; + padding: 0; + } + + .btn-link:hover { + text-decoration: underline; + } + + swp-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; + } + + swp-card-header swp-section-label { + margin-bottom: 0; + } + + .mono { + font-family: var(--font-mono); + } @@ -2650,35 +2796,24 @@
- Grundløn + + Satser + + - Timeløn - 185 kr/time + Normal (timeløn) + 131,49 kr - Overarbejde - 150% + Overarbejde (100%) + 280,50 kr - Weekendtillæg - 25% + Ferie m. løn + 140,25 kr - - ATP-bidrag - - Ja - Nej - - - - Pension (arbejdsgiver) - - Ja - Nej - - @@ -2686,56 +2821,74 @@ Minimum pr. time - 220 kr + 220 kr På services - 15% + 15% På produktsalg - 15% + 15% + + + + + + Tillæg + + + 8-21 Hverdage + 28,03 kr + + + 8-21 Lørdage + 56,02 kr + + + Søndag + 112,07 kr
- Lønhistorik + Lønspecifikationer - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + +
DatoÆndringNy værdiPeriodeBruttoløn
01.01.2025Lønforhøjelse185 kr/timeJanuar 202634.063,50 krVis
01.01.2024Lønforhøjelse175 kr/timeDecember 202531.845,00 krVis
01.07.2023Provision ændret12%November 202533.290,25 krVis
01.01.2023Lønforhøjelse165 kr/timeOktober 202532.156,75 krVis
01.08.2019Ansættelse145 kr/timeSeptember 202534.520,00 krVis
@@ -3884,5 +4037,114 @@ }); + + + + + Lønsatser + + + + + + Grundsatser + + + Normal (timeløn) + kr + + + + Overarbejde (100%) + kr + + + + Kursus/skole + kr + + + + Afspadsering + kr + + + + Fri m. løn + kr + + + + Ferie m. løn + kr + + + + Kontor + kr + + + + Barns 1. sygedag + kr + + + + Barns hospitalsindlæggelse + kr + + + + Barsel + kr + + +
+ Tillæg + + + 8-21 Hverdage (udenfor arbejdstid) + kr + + + + 8-21 Lørdage (udenfor arbejdstid) + kr + + + + Søndag + kr + +
+ +
+ Provisionsberegning + + + Provision på produktsalg + % + + + + Provision på servicesalg + % + +
+
+
+ + + diff --git a/wwwroot/poc-gavekort-detail.html b/wwwroot/poc-gavekort-detail.html index 970c620..7bf7a98 100644 --- a/wwwroot/poc-gavekort-detail.html +++ b/wwwroot/poc-gavekort-detail.html @@ -3,7 +3,7 @@ - Gavekort GC-A7X2-9KM4 - Salon OS + Fordelskort FK-A7X2-9KM4 - Salon OS + + + + +
+
+
+

Lønspecifikation

+

Periode: Januar 2026

+
+ +
+
Medarbejdernr.: EMP-001
+
+ Medarbejder:Emma Larsen + Afdeling:Frisør + Ansættelse:Fuldtid (37 t/uge) +
+
+
+ +
+
+
Bruttoløn (Januar 2026)
+

34.063,50 kr

+
+
+ +
+
+
+

Samlet lønopgørelse

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
LøndelBeløb
Grundløn inkl. overarbejde29.322,50 kr
Provision i alt3.685,00 kr
Tillæg i alt1.056,00 kr
Bruttoløn34.063,50 kr
+
+
+ +
+
+

Saldi

+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
TypeOptjentAfholdtRest
Ferie (dage)18,56,012,5
Afspadsering (timer)12,04,08,0
+

Saldi er opgjort som angivet på lønspecifikationen.

+
+
+
+ +
+
+

Hurtigt resumé

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NøglepunktVærdi
Normaltimer148,0 t
Overarbejde7,0 t
Provision (services + produkter)3.685,00 kr
Tillæg (aften + lørdag + søndag)1.056,00 kr
+
+
+ +
+
Overblik
+
Lønspecifikation · Januar 2026
+
+ +
+ + +
+
+

Arbejdstid pr. uge

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UgeNormaltimerOvertidBeløb
Uge 1 (30. dec – 5. jan)37,0 t2,0 t7.400,00 kr
Uge 2 (6. – 12. jan)37,0 t3,5 t7.816,25 kr
Uge 3 (13. – 19. jan)37,0 t0,0 t6.845,00 kr
Uge 4 (20. – 26. jan)37,0 t1,5 t7.261,25 kr
I alt148,0 t7,0 t29.322,50 kr
+

+ Satser: Normal 185,00 kr/time. Overtid (50%) 277,50 kr/time. +

+
+
+ +
+
+

Provision

+
+
+

+ Services: 15% af omsætning over minimum (220 kr/time).
+ Produkter: 10% af salg. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UgeService prov.Produkt prov.I alt
Uge 1573,00 kr210,00 kr783,00 kr
Uge 2883,50 kr320,00 kr1.203,50 kr
Uge 3459,00 kr180,00 kr639,00 kr
Uge 4769,50 kr290,00 kr1.059,50 kr
I alt2.685,00 kr1.000,00 kr3.685,00 kr
+
+
+ +
+
+

Tillæg & fravær

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TillægTimerBeløb
Aftentillæg (hverdage 18–21)12,0336,00 kr
Lørdagstillæg (før kl. 14)16,0720,00 kr
Søndagstillæg0,00,00 kr
Tillæg i alt1.056,00 kr
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FraværDageBeløb
Ferie med løn00,00 kr
Sygdom00,00 kr
Barns sygedag00,00 kr
+

Ingen fravær registreret i perioden.

+
+
+
+
+ +
+
Detaljer
+
Lønspecifikation · Januar 2026
+
+ +
+ + diff --git a/wwwroot/poc-medarbejdere.html b/wwwroot/poc-medarbejdere.html new file mode 100644 index 0000000..5a4a7c5 --- /dev/null +++ b/wwwroot/poc-medarbejdere.html @@ -0,0 +1,588 @@ + + + + + + Medarbejdere - Salon OS + + + + + + + + + + + + +

Medarbejdere

+

Administrer brugere, roller og rettigheder

+
+
+ + + + + 4 + Aktive medarbejdere + + + 1 + Afventer invitation + + + 4 + Roller defineret + + + + + + + + Brugere + + + + Roller + + + + + + + + 5 af 8 brugere + + + + + + + Inviter bruger + + + + + + + + Bruger + Rolle + Status + Sidst aktiv + + + + + + + + + MJ + + Maria Jensen + maria@salonbeauty.dk + + + + + Ejer + + + + + Aktiv + + + I dag, 14:32 + + + + + + + + + + + + + + AS + + Anna Sørensen + anna@salonbeauty.dk + + + + + Admin + + + + + Aktiv + + + I dag, 12:15 + + + + + + + + + + + + + + + + + LP + + Louise Pedersen + louise@salonbeauty.dk + + + + + Leder + + + + + Aktiv + + + I går, 17:45 + + + + + + + + + + + + + + + + + KN + + Katrine Nielsen + katrine@salonbeauty.dk + + + + + Medarbejder + + + + + Aktiv + + + 27. dec, 09:30 + + + + + + + + + + + + + + + + + SH + + Sofie Hansen + sofie@salonbeauty.dk + + + + + Medarbejder + + + + + Invitation sendt + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RettighedEjerAdminLederMedarbejder
+ + + Kalender + +
+ + + Medarbejdere + +
+ + + Kunder + +
+ + + Rapporter & Økonomi + +
+
+
+ +
+ + + + + diff --git a/wwwroot/poc-salg.html b/wwwroot/poc-salg.html new file mode 100644 index 0000000..75f91ee --- /dev/null +++ b/wwwroot/poc-salg.html @@ -0,0 +1,1133 @@ + + + + + + Salg - Salon OS + + + + + + + + + Salg + + + + + Eksporter + + + + + + + + + 12.450 kr + Omsætning i dag + + + 187.230 kr + Omsætning denne måned + + + 18 + Antal salg i dag + + + 692 kr + Gns. ordreværdi + + + + + + + + Omsætning pr. måned + Sidste 12 måneder + + + + + + Betalingsmetoder + Fordeling + + + + + + + + + + + + + Fra + + + + Til + + + + Status + + + + Betaling + + + + + + + + Faktura + Dato/tid + Kunde + Medarbejder + Ydelser + Beløb + Betaling + Status + + + + + + + #1847 + + + + + 6. jan 2025 + 14:32 + + + + + Maria Hansen + +45 23 45 67 89 + + + Louise P. + + + Dameklip, Farve + + 1 produkt + + + 1.450 kr + Kort + + + + + + + + #1846 + + + + + 6. jan 2025 + 13:15 + + + + + Jonas Petersen + +45 31 22 44 55 + + + Karina K. + + + Herreklip + + + 350 kr + MobilePay + + + + + + + + #1845 + + + + + 6. jan 2025 + 11:45 + + + + + Sofie Larsen + +45 42 33 55 66 + + + Louise P. + + + Balayage, Klip + + 2 produkter + + + 2.850 kr + Faktura + Afventer + + + + + + + #1844 + + + + + 6. jan 2025 + 10:30 + + + + + Anne Nielsen + +45 51 62 73 84 + + + Mette J. + + + Dameklip, Vask + + + 550 kr + Fordelskort + + + + + + + + #1843 + + + + + 6. jan 2025 + 09:15 + + + + + Peter Andersen + +45 61 72 83 94 + + + Karina K. + + + Herreklip, Skægtrim + + + 450 kr + Kontant + + + + + + + + #1842 + + + + + 5. jan 2025 + 16:45 + + + + + Camilla Holm + +45 71 82 93 04 + + + Louise P. + + + Extensions + + 1 produkt + + + 3.200 kr + Kort + + + + + + + + #1841 + + + + + 5. jan 2025 + 15:00 + + + + + Mikkel Jensen + +45 81 92 03 14 + + + Mette J. + + + Dameklip + + + -450 kr + Kort + Krediteret + + + + + + + #1840 + + + + + 5. jan 2025 + 13:30 + + + + + Louise Eriksen + +45 91 02 13 24 + + + Karina K. + + + Highlights, Klip, Kur + + + 1.950 kr + Kort + + + + + + Viser 1-8 af 1.847 fakturaer + + + 1 + 2 + 3 + ... + 231 + + + + + + + + + From d7f3c55a2ace9f2b233e6fb6bc2c182a7710d31e Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Thu, 8 Jan 2026 15:44:11 +0100 Subject: [PATCH 06/10] Restructures project with feature-based organization Refactors project structure to support modular, feature-driven development Introduces comprehensive language localization support Adds menu management with role-based access control Implements dynamic sidebar and theme switching capabilities Enhances project scalability and maintainability --- .workbench/projectstructure.txt | 86 ++++++ Program.cs | 20 -- .../CalendarServer.csproj | 1 + app/Controllers/HomeController.cs | 12 + .../Language/Models/SupportedCulture.cs | 8 + .../Language/Services/ILocalizationService.cs | 10 + .../Services/JsonLocalizationService.cs | 48 ++++ .../Language/TagHelpers/LocalizeTagHelper.cs | 30 ++ app/Features/Language/Translations/da.json | 33 +++ app/Features/Language/Translations/en.json | 33 +++ app/Features/Menu/Models/MenuGroup.cs | 12 + app/Features/Menu/Models/MenuItem.cs | 15 + app/Features/Menu/Models/UserRole.cs | 11 + app/Features/Menu/Services/IMenuService.cs | 14 + app/Features/Menu/Services/MockMenuService.cs | 187 +++++++++++++ app/Features/Menu/SideMenuViewComponent.cs | 35 +++ app/Features/Menu/SideMenuViewModel.cs | 12 + app/Program.cs | 29 ++ app/Views/Home/Index.cshtml | 91 ++++++ .../Shared/Components/SideMenu/Default.cshtml | 39 +++ .../Shared/Components/_ProfileDrawer.cshtml | 49 ++++ app/Views/Shared/Components/_SideMenu.cshtml | 78 ++++++ app/Views/Shared/Components/_TopBar.cshtml | 26 ++ app/Views/Shared/_Layout.cshtml | 38 +++ app/Views/_ViewImports.cshtml | 3 + app/Views/_ViewStart.cshtml | 3 + app/build.js | 24 ++ app/wwwroot/css/app-layout.css | 50 ++++ app/wwwroot/css/base.css | 118 ++++++++ app/wwwroot/css/design-system.css | 163 +++++++++++ app/wwwroot/css/drawers.css | 258 ++++++++++++++++++ app/wwwroot/css/page.css | 204 ++++++++++++++ app/wwwroot/css/sidebar.css | 246 +++++++++++++++++ app/wwwroot/css/stats.css | 258 ++++++++++++++++++ app/wwwroot/css/topbar.css | 180 ++++++++++++ app/wwwroot/fonts/Poppins-Black.woff | Bin 0 -> 64180 bytes app/wwwroot/fonts/Poppins-BlackItalic.woff | Bin 0 -> 71488 bytes app/wwwroot/fonts/Poppins-Bold.woff | Bin 0 -> 65572 bytes app/wwwroot/fonts/Poppins-BoldItalic.woff | Bin 0 -> 74912 bytes app/wwwroot/fonts/Poppins-ExtraBold.woff | Bin 0 -> 65520 bytes .../fonts/Poppins-ExtraBoldItalic.woff | Bin 0 -> 74608 bytes app/wwwroot/fonts/Poppins-ExtraLight.woff | Bin 0 -> 66456 bytes .../fonts/Poppins-ExtraLightItalic.woff | Bin 0 -> 76392 bytes app/wwwroot/fonts/Poppins-Italic.woff | Bin 0 -> 76316 bytes app/wwwroot/fonts/Poppins-Light.woff | Bin 0 -> 66392 bytes app/wwwroot/fonts/Poppins-LightItalic.woff | Bin 0 -> 76520 bytes app/wwwroot/fonts/Poppins-Medium.woff | Bin 0 -> 65760 bytes app/wwwroot/fonts/Poppins-MediumItalic.woff | Bin 0 -> 74920 bytes app/wwwroot/fonts/Poppins-Regular.woff | Bin 0 -> 66464 bytes app/wwwroot/fonts/Poppins-SemiBold.woff | Bin 0 -> 66236 bytes app/wwwroot/fonts/Poppins-SemiBoldItalic.woff | Bin 0 -> 75592 bytes app/wwwroot/fonts/Poppins-Thin.woff | Bin 0 -> 62572 bytes app/wwwroot/fonts/Poppins-ThinItalic.woff | Bin 0 -> 72444 bytes app/wwwroot/ts/app.ts | 58 ++++ app/wwwroot/ts/modules/drawers.ts | 226 +++++++++++++++ app/wwwroot/ts/modules/lockscreen.ts | 182 ++++++++++++ app/wwwroot/ts/modules/search.ts | 106 +++++++ app/wwwroot/ts/modules/sidebar.ts | 96 +++++++ app/wwwroot/ts/modules/theme.ts | 120 ++++++++ app/wwwroot/ts/tsconfig.json | 22 ++ 60 files changed, 3214 insertions(+), 20 deletions(-) create mode 100644 .workbench/projectstructure.txt delete mode 100644 Program.cs rename CalendarServer.csproj => app/CalendarServer.csproj (76%) create mode 100644 app/Controllers/HomeController.cs create mode 100644 app/Features/Language/Models/SupportedCulture.cs create mode 100644 app/Features/Language/Services/ILocalizationService.cs create mode 100644 app/Features/Language/Services/JsonLocalizationService.cs create mode 100644 app/Features/Language/TagHelpers/LocalizeTagHelper.cs create mode 100644 app/Features/Language/Translations/da.json create mode 100644 app/Features/Language/Translations/en.json create mode 100644 app/Features/Menu/Models/MenuGroup.cs create mode 100644 app/Features/Menu/Models/MenuItem.cs create mode 100644 app/Features/Menu/Models/UserRole.cs create mode 100644 app/Features/Menu/Services/IMenuService.cs create mode 100644 app/Features/Menu/Services/MockMenuService.cs create mode 100644 app/Features/Menu/SideMenuViewComponent.cs create mode 100644 app/Features/Menu/SideMenuViewModel.cs create mode 100644 app/Program.cs create mode 100644 app/Views/Home/Index.cshtml create mode 100644 app/Views/Shared/Components/SideMenu/Default.cshtml create mode 100644 app/Views/Shared/Components/_ProfileDrawer.cshtml create mode 100644 app/Views/Shared/Components/_SideMenu.cshtml create mode 100644 app/Views/Shared/Components/_TopBar.cshtml create mode 100644 app/Views/Shared/_Layout.cshtml create mode 100644 app/Views/_ViewImports.cshtml create mode 100644 app/Views/_ViewStart.cshtml create mode 100644 app/build.js create mode 100644 app/wwwroot/css/app-layout.css create mode 100644 app/wwwroot/css/base.css create mode 100644 app/wwwroot/css/design-system.css create mode 100644 app/wwwroot/css/drawers.css create mode 100644 app/wwwroot/css/page.css create mode 100644 app/wwwroot/css/sidebar.css create mode 100644 app/wwwroot/css/stats.css create mode 100644 app/wwwroot/css/topbar.css create mode 100644 app/wwwroot/fonts/Poppins-Black.woff create mode 100644 app/wwwroot/fonts/Poppins-BlackItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-Bold.woff create mode 100644 app/wwwroot/fonts/Poppins-BoldItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-ExtraBold.woff create mode 100644 app/wwwroot/fonts/Poppins-ExtraBoldItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-ExtraLight.woff create mode 100644 app/wwwroot/fonts/Poppins-ExtraLightItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-Italic.woff create mode 100644 app/wwwroot/fonts/Poppins-Light.woff create mode 100644 app/wwwroot/fonts/Poppins-LightItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-Medium.woff create mode 100644 app/wwwroot/fonts/Poppins-MediumItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-Regular.woff create mode 100644 app/wwwroot/fonts/Poppins-SemiBold.woff create mode 100644 app/wwwroot/fonts/Poppins-SemiBoldItalic.woff create mode 100644 app/wwwroot/fonts/Poppins-Thin.woff create mode 100644 app/wwwroot/fonts/Poppins-ThinItalic.woff create mode 100644 app/wwwroot/ts/app.ts create mode 100644 app/wwwroot/ts/modules/drawers.ts create mode 100644 app/wwwroot/ts/modules/lockscreen.ts create mode 100644 app/wwwroot/ts/modules/search.ts create mode 100644 app/wwwroot/ts/modules/sidebar.ts create mode 100644 app/wwwroot/ts/modules/theme.ts create mode 100644 app/wwwroot/ts/tsconfig.json diff --git a/.workbench/projectstructure.txt b/.workbench/projectstructure.txt new file mode 100644 index 0000000..8507e45 --- /dev/null +++ b/.workbench/projectstructure.txt @@ -0,0 +1,86 @@ + + +Organizing Project Folder Structure: Function-Based vs Feature-Based +Ina Lopez +Ina Lopez + +Follow +2 min read +· +Sep 3, 2024 +12 + + + + +When setting up a project, one of the most crucial decisions is how to organize the folder structure. The structure you choose can significantly impact productivity, scalability, and collaboration among developers. Two common approaches are function-based and feature-based organization. Both have their advantages, and the choice between them often depends on the size of the project and the number of developers involved. + +Function-Based Organization + +In a function-based folder structure, directories are organized based on the functions they provide. This is a popular approach, especially for smaller projects or teams. The idea is to group similar functionalities together, making it easy to locate specific files or components. + +For example, in a React project, the src directory might look like this: + +src/ +├── components/ +├── hooks/ +├── utils/ + +Each folder contains files related to a specific function. Components, hooks, reducers, and utilities are neatly separated, making it easy to find and manage related code. This structure works well when the codebase is relatively small and developers need to quickly find and reuse functions. + +Pros: + +Easy to find similar functions. +Encourages reuse of components and utilities. +Clean and straightforward structure. +Cons: + +As the project grows, it can become difficult to manage. +Dependencies between different folders can increase complexity. +Not ideal for teams working on different features simultaneously. +Feature-Based Organization +In larger projects with many developers, a feature-based folder structure can be more effective. Instead of organizing files by function, the top-level directories in the src folder are based on features or modules of the application. This approach allows teams to work on separate features independently without interfering with other parts of the codebase. + +Get Ina Lopez’s stories in your inbox +Join Medium for free to get updates from this writer. + +Enter your email +Subscribe +For example, a feature-based structure might look like this: + +src/ +├─ signup/ +│ ├── components/ +│ ├── hooks/ +│ └── utils/ +├─ checkout/ +│ ├── components/ +│ ├── hooks/ +│ └── utils/ +├─ dashboard/ +│ ├── components/ +│ ├── hooks/ +│ └── utils/ +└─ profile/ +├── components/ +├── hooks/ +└── utils/ + +Each folder contains all the components, hooks, reducers, and utilities specific to that feature. This structure makes it easier for developers to focus on specific features, reduces conflicts, and simplifies the onboarding process for new team members. + +Pros: + +Better suited for larger projects with multiple developers. +Encourages modularity and separation of concerns. +Easier to manage and scale as the project grows. +Reduces the risk of conflicts between different teams. +Cons: + +Some duplication of code across features is possible. +Finding reusable components can be more challenging. +Can be overwhelming if the project has too many small features. +Conclusion +Choosing the right folder structure depends on your project’s size and team dynamics. Function-based organization is ideal for small to medium projects with fewer developers, offering simplicity and ease of reuse. However, as your project grows and more developers are involved, a feature-based approach becomes more effective, enabling modularity, better collaboration, and easier scaling. + +For some projects, a hybrid approach might work best, combining both methods to balance flexibility and organization. Ultimately, the key is to select a structure that supports the current and future needs of your project and team. + \ No newline at end of file diff --git a/Program.cs b/Program.cs deleted file mode 100644 index 10cbdaa..0000000 --- a/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.FileProviders; - -var builder = WebApplication.CreateBuilder(args); - -var app = builder.Build(); - -// Configure static files to serve from current directory -app.UseStaticFiles(new StaticFileOptions -{ - FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")), - RequestPath = "" -}); - -// Fallback to index.html for SPA routing -app.MapFallbackToFile("index.html"); - -app.Run("http://localhost:8000"); \ No newline at end of file diff --git a/CalendarServer.csproj b/app/CalendarServer.csproj similarity index 76% rename from CalendarServer.csproj rename to app/CalendarServer.csproj index 2447542..9aa2a08 100644 --- a/CalendarServer.csproj +++ b/app/CalendarServer.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + CalendarServer \ No newline at end of file diff --git a/app/Controllers/HomeController.cs b/app/Controllers/HomeController.cs new file mode 100644 index 0000000..efc173f --- /dev/null +++ b/app/Controllers/HomeController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CalendarServer.Controllers; + +public class HomeController : Controller +{ + public IActionResult Index() + { + ViewData["Title"] = "Dashboard"; + return View(); + } +} diff --git a/app/Features/Language/Models/SupportedCulture.cs b/app/Features/Language/Models/SupportedCulture.cs new file mode 100644 index 0000000..3525c5e --- /dev/null +++ b/app/Features/Language/Models/SupportedCulture.cs @@ -0,0 +1,8 @@ +namespace CalendarServer.Features.Language.Models; + +public class SupportedCulture +{ + public required string Code { get; set; } + public required string Name { get; set; } + public required string NativeName { get; set; } +} diff --git a/app/Features/Language/Services/ILocalizationService.cs b/app/Features/Language/Services/ILocalizationService.cs new file mode 100644 index 0000000..430e50e --- /dev/null +++ b/app/Features/Language/Services/ILocalizationService.cs @@ -0,0 +1,10 @@ +using CalendarServer.Features.Language.Models; + +namespace CalendarServer.Features.Language.Services; + +public interface ILocalizationService +{ + string Get(string key, string? culture = null); + string CurrentCulture { get; } + IEnumerable GetSupportedCultures(); +} diff --git a/app/Features/Language/Services/JsonLocalizationService.cs b/app/Features/Language/Services/JsonLocalizationService.cs new file mode 100644 index 0000000..7b90bca --- /dev/null +++ b/app/Features/Language/Services/JsonLocalizationService.cs @@ -0,0 +1,48 @@ +using System.Text.Json; +using CalendarServer.Features.Language.Models; + +namespace CalendarServer.Features.Language.Services; + +public class JsonLocalizationService : ILocalizationService +{ + private readonly string _translationsPath; + + public JsonLocalizationService(IWebHostEnvironment env) + { + _translationsPath = Path.Combine(env.ContentRootPath, "Features", "Language", "Translations"); + } + + public string CurrentCulture => "en"; + + public string Get(string key, string? culture = null) + { + culture ??= CurrentCulture; + var filePath = Path.Combine(_translationsPath, $"{culture}.json"); + + if (!File.Exists(filePath)) + return key; + + var json = File.ReadAllText(filePath); + var doc = JsonDocument.Parse(json); + + var parts = key.Split('.'); + JsonElement current = doc.RootElement; + + foreach (var part in parts) + { + if (!current.TryGetProperty(part, out current)) + return key; + } + + return current.GetString() ?? key; + } + + public IEnumerable GetSupportedCultures() + { + return new List + { + new() { Code = "da", Name = "Danish", NativeName = "Dansk" }, + new() { Code = "en", Name = "English", NativeName = "English" } + }; + } +} diff --git a/app/Features/Language/TagHelpers/LocalizeTagHelper.cs b/app/Features/Language/TagHelpers/LocalizeTagHelper.cs new file mode 100644 index 0000000..73f0fe9 --- /dev/null +++ b/app/Features/Language/TagHelpers/LocalizeTagHelper.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; +using CalendarServer.Features.Language.Services; + +namespace CalendarServer.Features.Language.TagHelpers; + +[HtmlTargetElement(Attributes = "localize")] +public class LocalizeTagHelper : TagHelper +{ + private readonly ILocalizationService _localize; + + public LocalizeTagHelper(ILocalizationService localize) + { + _localize = localize; + } + + [HtmlAttributeName("localize")] + public string Key { get; set; } = string.Empty; + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + var translated = _localize.Get(Key); + + if (!string.IsNullOrEmpty(translated) && translated != Key) + { + output.Content.SetContent(translated); + } + + output.Attributes.RemoveAll("localize"); + } +} diff --git a/app/Features/Language/Translations/da.json b/app/Features/Language/Translations/da.json new file mode 100644 index 0000000..c569ae6 --- /dev/null +++ b/app/Features/Language/Translations/da.json @@ -0,0 +1,33 @@ +{ + "menu": { + "home": "Dashboard", + "calendar": "Kalender", + "pos": "Kasse", + "products": "Produkter & Lager", + "suppliers": "Leverandører", + "customers": "Kunder", + "employees": "Medarbejdere", + "reports": "Statistik & Rapporter", + "settings": "Indstillinger", + "account": "Abonnement & Konto" + }, + "groups": { + "dashboard": "Dashboard", + "data": "Data", + "analytics": "Analyse", + "system": "System" + }, + "common": { + "save": "Gem", + "cancel": "Annuller", + "search": "Søg", + "close": "Luk", + "delete": "Slet", + "edit": "Rediger", + "add": "Tilføj" + }, + "sidebar": { + "lockScreen": "Lås skærm", + "appName": "Salon OS" + } +} diff --git a/app/Features/Language/Translations/en.json b/app/Features/Language/Translations/en.json new file mode 100644 index 0000000..a66a7b7 --- /dev/null +++ b/app/Features/Language/Translations/en.json @@ -0,0 +1,33 @@ +{ + "menu": { + "home": "Dashboard", + "calendar": "Calendar", + "pos": "Point of Sale", + "products": "Products & Inventory", + "suppliers": "Suppliers", + "customers": "Customers", + "employees": "Employees", + "reports": "Statistics & Reports", + "settings": "Settings", + "account": "Subscription & Account" + }, + "groups": { + "dashboard": "Dashboard", + "data": "Data", + "analytics": "Analytics", + "system": "System" + }, + "common": { + "save": "Save", + "cancel": "Cancel", + "search": "Search", + "close": "Close", + "delete": "Delete", + "edit": "Edit", + "add": "Add" + }, + "sidebar": { + "lockScreen": "Lock screen", + "appName": "Salon OS" + } +} diff --git a/app/Features/Menu/Models/MenuGroup.cs b/app/Features/Menu/Models/MenuGroup.cs new file mode 100644 index 0000000..f2f3eb0 --- /dev/null +++ b/app/Features/Menu/Models/MenuGroup.cs @@ -0,0 +1,12 @@ +namespace CalendarServer.Features.Menu.Models; + +/// +/// Represents a group of menu items (e.g., "Dashboard", "Data", "System"). +/// +public class MenuGroup +{ + public required string Id { get; set; } + public required string Label { get; set; } + public int SortOrder { get; set; } + public List Items { get; set; } = new(); +} diff --git a/app/Features/Menu/Models/MenuItem.cs b/app/Features/Menu/Models/MenuItem.cs new file mode 100644 index 0000000..04e8172 --- /dev/null +++ b/app/Features/Menu/Models/MenuItem.cs @@ -0,0 +1,15 @@ +namespace CalendarServer.Features.Menu.Models; + +/// +/// Represents a single menu item in the sidebar. +/// +public class MenuItem +{ + public required string Id { get; set; } + public required string Label { get; set; } + public required string Icon { get; set; } + public required string Url { get; set; } + public UserRole MinimumRole { get; set; } = UserRole.Staff; + public int SortOrder { get; set; } + public bool IsActive { get; set; } +} diff --git a/app/Features/Menu/Models/UserRole.cs b/app/Features/Menu/Models/UserRole.cs new file mode 100644 index 0000000..1adc056 --- /dev/null +++ b/app/Features/Menu/Models/UserRole.cs @@ -0,0 +1,11 @@ +namespace CalendarServer.Features.Menu.Models; + +/// +/// User roles for menu visibility. Higher value = more access. +/// +public enum UserRole +{ + Staff = 0, + Manager = 1, + Admin = 2 +} diff --git a/app/Features/Menu/Services/IMenuService.cs b/app/Features/Menu/Services/IMenuService.cs new file mode 100644 index 0000000..3cbccb5 --- /dev/null +++ b/app/Features/Menu/Services/IMenuService.cs @@ -0,0 +1,14 @@ +using CalendarServer.Features.Menu.Models; + +namespace CalendarServer.Features.Menu.Services; + +/// +/// Service for retrieving menu structure based on user role. +/// +public interface IMenuService +{ + /// + /// Get menu groups filtered by user role. + /// + List GetMenuForRole(UserRole role, string? currentUrl = null); +} diff --git a/app/Features/Menu/Services/MockMenuService.cs b/app/Features/Menu/Services/MockMenuService.cs new file mode 100644 index 0000000..4b90217 --- /dev/null +++ b/app/Features/Menu/Services/MockMenuService.cs @@ -0,0 +1,187 @@ +using CalendarServer.Features.Menu.Models; +using CalendarServer.Features.Language.Services; + +namespace CalendarServer.Features.Menu.Services; + +/// +/// Mock implementation of IMenuService with hardcoded menu data. +/// +public class MockMenuService : IMenuService +{ + private readonly ILocalizationService _localize; + + public MockMenuService(ILocalizationService localize) + { + _localize = localize; + } + + public List GetMenuForRole(UserRole role, string? currentUrl = null) + { + var allGroups = GetAllMenuGroups(); + + return allGroups + .Select(g => new MenuGroup + { + Id = g.Id, + Label = _localize.Get($"groups.{g.Id}"), + SortOrder = g.SortOrder, + Items = g.Items + .Where(i => role >= i.MinimumRole) + .Select(i => new MenuItem + { + Id = i.Id, + Label = _localize.Get($"menu.{i.Id}"), + Icon = i.Icon, + Url = i.Url, + MinimumRole = i.MinimumRole, + SortOrder = i.SortOrder, + IsActive = currentUrl != null && i.Url.Equals(currentUrl, StringComparison.OrdinalIgnoreCase) + }) + .OrderBy(i => i.SortOrder) + .ToList() + }) + .Where(g => g.Items.Any()) + .OrderBy(g => g.SortOrder) + .ToList(); + } + + private static List GetAllMenuGroups() + { + return new List + { + // DASHBOARD GROUP + new MenuGroup + { + Id = "dashboard", + Label = "Dashboard", + SortOrder = 1, + Items = new List + { + new MenuItem + { + Id = "home", + Label = "Dashboard", + Icon = "ph-squares-four", + Url = "/", + MinimumRole = UserRole.Staff, + SortOrder = 1 + }, + new MenuItem + { + Id = "calendar", + Label = "Kalender", + Icon = "ph-calendar", + Url = "/poc-calendar.html", + MinimumRole = UserRole.Staff, + SortOrder = 2 + }, + new MenuItem + { + Id = "pos", + Label = "Kasse", + Icon = "ph-device-mobile", + Url = "/pos", + MinimumRole = UserRole.Staff, + SortOrder = 3 + } + } + }, + + // DATA GROUP + new MenuGroup + { + Id = "data", + Label = "Data", + SortOrder = 2, + Items = new List + { + new MenuItem + { + Id = "products", + Label = "Produkter & Lager", + Icon = "ph-package", + Url = "/poc-produkter.html", + MinimumRole = UserRole.Manager, + SortOrder = 1 + }, + new MenuItem + { + Id = "suppliers", + Label = "Leverandører", + Icon = "ph-truck", + Url = "/poc-leverandoerer.html", + MinimumRole = UserRole.Manager, + SortOrder = 2 + }, + new MenuItem + { + Id = "customers", + Label = "Kunder", + Icon = "ph-users", + Url = "/customers", + MinimumRole = UserRole.Staff, + SortOrder = 3 + }, + new MenuItem + { + Id = "employees", + Label = "Medarbejdere", + Icon = "ph-user", + Url = "/poc-medarbejdere.html", + MinimumRole = UserRole.Manager, + SortOrder = 4 + } + } + }, + + // ANALYSE GROUP + new MenuGroup + { + Id = "analytics", + Label = "Analyse", + SortOrder = 3, + Items = new List + { + new MenuItem + { + Id = "reports", + Label = "Statistik & Rapporter", + Icon = "ph-chart-bar", + Url = "/reports", + MinimumRole = UserRole.Manager, + SortOrder = 1 + } + } + }, + + // SYSTEM GROUP + new MenuGroup + { + Id = "system", + Label = "System", + SortOrder = 4, + Items = new List + { + new MenuItem + { + Id = "settings", + Label = "Indstillinger", + Icon = "ph-gear", + Url = "/poc-indstillinger.html", + MinimumRole = UserRole.Admin, + SortOrder = 1 + }, + new MenuItem + { + Id = "account", + Label = "Abonnement & Konto", + Icon = "ph-credit-card", + Url = "/poc-konto.html", + MinimumRole = UserRole.Admin, + SortOrder = 2 + } + } + } + }; + } +} diff --git a/app/Features/Menu/SideMenuViewComponent.cs b/app/Features/Menu/SideMenuViewComponent.cs new file mode 100644 index 0000000..a14de55 --- /dev/null +++ b/app/Features/Menu/SideMenuViewComponent.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Mvc; +using CalendarServer.Features.Menu.Models; +using CalendarServer.Features.Menu.Services; + +namespace CalendarServer.Features.Menu; + +/// +/// ViewComponent for rendering the side menu based on user role. +/// +public class SideMenuViewComponent : ViewComponent +{ + private readonly IMenuService _menuService; + + public SideMenuViewComponent(IMenuService menuService) + { + _menuService = menuService; + } + + public IViewComponentResult Invoke(UserRole? role = null) + { + // Default to Admin for demo (in real app, get from auth) + var userRole = role ?? UserRole.Admin; + + var currentUrl = HttpContext.Request.Path.Value; + var groups = _menuService.GetMenuForRole(userRole, currentUrl); + + var viewModel = new SideMenuViewModel + { + Groups = groups, + CurrentUserRole = userRole + }; + + return View(viewModel); + } +} diff --git a/app/Features/Menu/SideMenuViewModel.cs b/app/Features/Menu/SideMenuViewModel.cs new file mode 100644 index 0000000..84cef10 --- /dev/null +++ b/app/Features/Menu/SideMenuViewModel.cs @@ -0,0 +1,12 @@ +using CalendarServer.Features.Menu.Models; + +namespace CalendarServer.Features.Menu; + +/// +/// ViewModel for the side menu partial view. +/// +public class SideMenuViewModel +{ + public required List Groups { get; set; } + public UserRole CurrentUserRole { get; set; } +} diff --git a/app/Program.cs b/app/Program.cs new file mode 100644 index 0000000..53c699f --- /dev/null +++ b/app/Program.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using CalendarServer.Features.Menu.Services; +using CalendarServer.Features.Language.Services; + +var builder = WebApplication.CreateBuilder(args); + +// Add MVC services +builder.Services.AddControllersWithViews(); + +// Register application services +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +var app = builder.Build(); + +// Serve static files from wwwroot +app.UseStaticFiles(); + +// Configure routing +app.UseRouting(); + +// Map MVC routes +app.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + +app.Run("http://localhost:8000"); \ No newline at end of file diff --git a/app/Views/Home/Index.cshtml b/app/Views/Home/Index.cshtml new file mode 100644 index 0000000..714eaec --- /dev/null +++ b/app/Views/Home/Index.cshtml @@ -0,0 +1,91 @@ +@{ + ViewData["Title"] = "Dashboard"; +} + + + + + + 12 + Bookinger i dag + + + 4 gennemført, 2 i gang + + + + 8.450 kr + Forventet omsætning + + + +12% vs. gennemsnit + + + + 78% + Belægningsgrad + + + God kapacitet + + + + 4 + Kræver opmærksomhed + + + + + + + + + + + + AI Analyse + + + Godt i gang! 4 af 12 bookinger er gennemført. 2 er i gang nu, og 6 venter. + Forventet omsætning: 8.450 kr – allerede realiseret 2.150 kr. + + + + + + + + + + Dagens bookinger + + Se alle + + +

Booking oversigt kommer her...

+
+
+
+ + + + + + Hurtige handlinger + + + + + + Ny booking + + + + Ny kunde + + + + + +
+
diff --git a/app/Views/Shared/Components/SideMenu/Default.cshtml b/app/Views/Shared/Components/SideMenu/Default.cshtml new file mode 100644 index 0000000..12087b5 --- /dev/null +++ b/app/Views/Shared/Components/SideMenu/Default.cshtml @@ -0,0 +1,39 @@ +@model CalendarServer.Features.Menu.SideMenuViewModel + + + + + Salon OS + + + + + + + @foreach (var group in Model.Groups) + { + + @group.Label + @foreach (var item in group.Items) + { +
+ + @item.Label + + } + + } + + + + + + Lås skærm + + + + + + diff --git a/app/Views/Shared/Components/_ProfileDrawer.cshtml b/app/Views/Shared/Components/_ProfileDrawer.cshtml new file mode 100644 index 0000000..9e42620 --- /dev/null +++ b/app/Views/Shared/Components/_ProfileDrawer.cshtml @@ -0,0 +1,49 @@ + + + Profil + + + + + + + + MJ + Maria Jensen + maria@salon.dk + + + + + + + + Min profil + + + + Indstillinger + + + + + + + + + Mørk tilstand + + + + + + + + + + + + Log ud + + + diff --git a/app/Views/Shared/Components/_SideMenu.cshtml b/app/Views/Shared/Components/_SideMenu.cshtml new file mode 100644 index 0000000..0e0d210 --- /dev/null +++ b/app/Views/Shared/Components/_SideMenu.cshtml @@ -0,0 +1,78 @@ + + + + Salon OS + + + + + + + + + Dashboard + + + Dashboard + + + + Kalender + + + + Kasse + + + + + + Data + + + Produkter & Lager + + + + Leverandører + + + + Kunder + + + + Medarbejdere + + + + + + Analyse + + + Statistik & Rapporter + + + + + + System + + + Indstillinger + + + + Abonnement & Konto + + + + + + + + Lås skærm + + + diff --git a/app/Views/Shared/Components/_TopBar.cshtml b/app/Views/Shared/Components/_TopBar.cshtml new file mode 100644 index 0000000..41b140a --- /dev/null +++ b/app/Views/Shared/Components/_TopBar.cshtml @@ -0,0 +1,26 @@ + + + + + ⌘K + + + + + + + 3 + + + + + + + MJ + + Maria Jensen + Administrator + + + + diff --git a/app/Views/Shared/_Layout.cshtml b/app/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..337b9c7 --- /dev/null +++ b/app/Views/Shared/_Layout.cshtml @@ -0,0 +1,38 @@ + + + + + + @ViewData["Title"] - Salon OS + + + + + + + + + + + + + + @await RenderSectionAsync("Styles", required: false) + + + + @await Component.InvokeAsync("SideMenu") + @await Html.PartialAsync("Components/_TopBar") + + + @RenderBody() + + + + @await Html.PartialAsync("Components/_ProfileDrawer") + + + + @await RenderSectionAsync("Scripts", required: false) + + diff --git a/app/Views/_ViewImports.cshtml b/app/Views/_ViewImports.cshtml new file mode 100644 index 0000000..584d299 --- /dev/null +++ b/app/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using CalendarServer +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, CalendarServer diff --git a/app/Views/_ViewStart.cshtml b/app/Views/_ViewStart.cshtml new file mode 100644 index 0000000..820a2f6 --- /dev/null +++ b/app/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/app/build.js b/app/build.js new file mode 100644 index 0000000..4aa944e --- /dev/null +++ b/app/build.js @@ -0,0 +1,24 @@ +import * as esbuild from 'esbuild'; + +async function build() { + try { + await esbuild.build({ + entryPoints: ['wwwroot/ts/app.ts'], + bundle: true, + outfile: 'wwwroot/js/app.js', + format: 'esm', + sourcemap: 'inline', + target: 'es2020', + minify: false, + keepNames: true, + platform: 'browser' + }); + + console.log('App bundle created: wwwroot/js/app.js'); + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +build(); diff --git a/app/wwwroot/css/app-layout.css b/app/wwwroot/css/app-layout.css new file mode 100644 index 0000000..2f57b74 --- /dev/null +++ b/app/wwwroot/css/app-layout.css @@ -0,0 +1,50 @@ +/** + * App Layout - Main Grid Structure + * + * Definerer den overordnede app-struktur med sidebar og main content + */ + +/* =========================================== + MAIN APP GRID + =========================================== */ +swp-app-layout { + display: grid; + grid-template-columns: var(--side-menu-width) 1fr; + grid-template-rows: var(--topbar-height) 1fr; + height: 100vh; + transition: grid-template-columns var(--transition-normal); +} + +/* =========================================== + COLLAPSED MENU STATE + =========================================== */ +swp-app-layout.menu-collapsed { + grid-template-columns: var(--side-menu-width-collapsed) 1fr; +} + +/* =========================================== + MAIN CONTENT AREA + =========================================== */ +swp-main-content { + display: block; + overflow-y: auto; + background: var(--color-background); +} + +/* =========================================== + DRAWER OVERLAY + =========================================== */ +swp-drawer-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + z-index: var(--z-overlay); + opacity: 0; + visibility: hidden; + transition: opacity var(--transition-normal), visibility var(--transition-normal); +} + +swp-drawer-overlay.active { + opacity: 1; + visibility: visible; +} diff --git a/app/wwwroot/css/base.css b/app/wwwroot/css/base.css new file mode 100644 index 0000000..00669dc --- /dev/null +++ b/app/wwwroot/css/base.css @@ -0,0 +1,118 @@ +/** + * Base Styles - Reset & Global Elements + * + * Normalization og grundlæggende styling + */ + +/* =========================================== + FONT FACES + =========================================== */ +@font-face { + font-family: 'Poppins'; + src: url('../fonts/Poppins-Regular.woff') format('woff'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('../fonts/Poppins-Medium.woff') format('woff'); + font-weight: 500; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('../fonts/Poppins-SemiBold.woff') format('woff'); + font-weight: 600; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Poppins'; + src: url('../fonts/Poppins-Bold.woff') format('woff'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +/* =========================================== + RESET + =========================================== */ +*, +*::before, +*::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, +body { + height: 100%; +} + +/* =========================================== + BASE ELEMENTS + =========================================== */ +body { + font-family: var(--font-family); + font-size: var(--font-size-base); + color: var(--color-text); + background: var(--color-background); + line-height: var(--line-height-normal); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Links */ +a { + color: var(--color-teal); + text-decoration: none; + transition: color var(--transition-fast); +} + +a:hover { + text-decoration: underline; +} + +/* Lists */ +ul, ol { + list-style: none; +} + +/* Images */ +img { + max-width: 100%; + height: auto; + display: block; +} + +/* Buttons */ +button { + font-family: inherit; + cursor: pointer; +} + +/* Inputs */ +input, +textarea, +select { + font-family: inherit; + font-size: inherit; +} + +/* Focus visible */ +:focus-visible { + outline: 2px solid var(--color-teal); + outline-offset: 2px; +} + +/* Selection */ +::selection { + background: var(--color-teal-light); + color: var(--color-text); +} diff --git a/app/wwwroot/css/design-system.css b/app/wwwroot/css/design-system.css new file mode 100644 index 0000000..beb61ec --- /dev/null +++ b/app/wwwroot/css/design-system.css @@ -0,0 +1,163 @@ +/** + * SWP Design System - CSS Variables + * + * Dette er den centrale definition af alle design tokens. + * Alle farver, fonts og layout-variabler defineres her. + */ + +/* =========================================== + COLOR PALETTE - Light Mode (Default) + =========================================== */ +:root { + /* Surfaces */ + --color-surface: #fff; + --color-background: #f5f5f5; + --color-background-hover: #f0f0f0; + --color-background-alt: #fafafa; + + /* Borders */ + --color-border: #e0e0e0; + --color-border-light: #f0f0f0; + + /* Text */ + --color-text: #333; + --color-text-secondary: #666; + --color-text-muted: #999; + + /* Brand Colors */ + --color-teal: #00897b; + --color-teal-light: color-mix(in srgb, var(--color-teal) 10%, transparent); + + /* Semantic Colors */ + --color-blue: #1976d2; + --color-green: #43a047; + --color-amber: #f59e0b; + --color-red: #e53935; + --color-purple: #8b5cf6; +} + +/* =========================================== + COLOR PALETTE - Dark Mode (System) + =========================================== */ +@media (prefers-color-scheme: dark) { + :root:not(.light-mode) { + --color-surface: #1e1e1e; + --color-background: #121212; + --color-background-hover: #2a2a2a; + --color-background-alt: #1a1a1a; + + --color-border: #333; + --color-border-light: #2a2a2a; + + --color-text: #e0e0e0; + --color-text-secondary: #999; + --color-text-muted: #666; + + --color-teal: #26a69a; + --color-blue: #42a5f5; + --color-green: #66bb6a; + --color-amber: #ffb74d; + --color-red: #ef5350; + --color-purple: #a78bfa; + } +} + +/* =========================================== + COLOR PALETTE - Dark Mode (Manual) + =========================================== */ +:root.dark-mode { + --color-surface: #1e1e1e; + --color-background: #121212; + --color-background-hover: #2a2a2a; + --color-background-alt: #1a1a1a; + + --color-border: #333; + --color-border-light: #2a2a2a; + + --color-text: #e0e0e0; + --color-text-secondary: #999; + --color-text-muted: #666; + + --color-teal: #26a69a; + --color-blue: #42a5f5; + --color-green: #66bb6a; + --color-amber: #ffb74d; + --color-red: #ef5350; + --color-purple: #a78bfa; +} + +/* =========================================== + TYPOGRAPHY + =========================================== */ +:root { + --font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-mono: 'JetBrains Mono', monospace; + + /* Font Sizes */ + --font-size-xs: 11px; + --font-size-sm: 12px; + --font-size-base: 14px; + --font-size-md: 13px; + --font-size-lg: 16px; + --font-size-xl: 22px; + + /* Line Heights */ + --line-height-tight: 1.25; + --line-height-normal: 1.5; + --line-height-relaxed: 1.75; +} + +/* =========================================== + SPACING + =========================================== */ +:root { + --spacing-1: 4px; + --spacing-2: 8px; + --spacing-3: 12px; + --spacing-4: 16px; + --spacing-5: 20px; + --spacing-6: 24px; + --spacing-8: 32px; +} + +/* =========================================== + LAYOUT + =========================================== */ +:root { + --side-menu-width: 240px; + --side-menu-width-collapsed: 64px; + --topbar-height: 56px; + --page-max-width: 1400px; + --border-radius: 6px; + --border-radius-lg: 8px; +} + +/* =========================================== + TRANSITIONS + =========================================== */ +:root { + --transition-fast: 150ms ease; + --transition-normal: 200ms ease; + --transition-slow: 300ms ease; +} + +/* =========================================== + Z-INDEX LAYERS + =========================================== */ +:root { + --z-dropdown: 100; + --z-sticky: 200; + --z-overlay: 900; + --z-drawer: 1000; + --z-modal: 1100; + --z-tooltip: 1200; +} + +/* =========================================== + SHADOWS + =========================================== */ +:root { + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); + --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15); +} diff --git a/app/wwwroot/css/drawers.css b/app/wwwroot/css/drawers.css new file mode 100644 index 0000000..2805da5 --- /dev/null +++ b/app/wwwroot/css/drawers.css @@ -0,0 +1,258 @@ +/** + * Drawers - Slide-in Panels + * + * Profile drawer, notifications drawer, etc. + */ + +/* =========================================== + BASE DRAWER + =========================================== */ +swp-profile-drawer, +swp-notification-drawer, +swp-todo-drawer { + position: fixed; + top: 0; + right: 0; + width: 320px; + height: 100vh; + background: var(--color-surface); + border-left: 1px solid var(--color-border); + box-shadow: var(--shadow-lg); + z-index: var(--z-drawer); + display: flex; + flex-direction: column; + transform: translateX(100%); + transition: transform var(--transition-normal); +} + +swp-profile-drawer.active, +swp-notification-drawer.active, +swp-todo-drawer.active { + transform: translateX(0); +} + +/* =========================================== + DRAWER HEADER + =========================================== */ +swp-drawer-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--spacing-4) var(--spacing-5); + border-bottom: 1px solid var(--color-border); + flex-shrink: 0; +} + +swp-drawer-title { + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); +} + +swp-drawer-close { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border: none; + background: transparent; + border-radius: var(--border-radius); + cursor: pointer; + color: var(--color-text-secondary); + transition: all var(--transition-fast); +} + +swp-drawer-close:hover { + background: var(--color-background-hover); + color: var(--color-text); +} + +swp-drawer-close i { + font-size: 20px; +} + +/* =========================================== + DRAWER CONTENT + =========================================== */ +swp-drawer-content { + flex: 1; + overflow-y: auto; + padding: var(--spacing-5); +} + +swp-drawer-divider { + height: 1px; + background: var(--color-border); + margin: var(--spacing-4) 0; +} + +/* =========================================== + PROFILE SECTION + =========================================== */ +swp-profile-section { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: var(--spacing-4) 0; +} + +swp-profile-avatar-large { + width: 64px; + height: 64px; + border-radius: 50%; + background: var(--color-teal); + color: white; + font-size: 24px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: var(--spacing-3); +} + +swp-profile-name-large { + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); + margin-bottom: var(--spacing-1); +} + +swp-profile-email { + font-size: var(--font-size-sm); + color: var(--color-text-secondary); +} + +/* =========================================== + DRAWER MENU + =========================================== */ +swp-drawer-menu { + display: flex; + flex-direction: column; + gap: var(--spacing-1); +} + +swp-drawer-menu-item { + display: flex; + align-items: center; + gap: var(--spacing-3); + padding: var(--spacing-3) var(--spacing-3); + border-radius: var(--border-radius); + cursor: pointer; + transition: background var(--transition-fast); + color: var(--color-text); +} + +swp-drawer-menu-item:hover { + background: var(--color-background-hover); +} + +swp-drawer-menu-item i { + font-size: 20px; + color: var(--color-text-secondary); +} + +/* =========================================== + THEME TOGGLE + =========================================== */ +swp-theme-toggle { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--spacing-3); + border-radius: var(--border-radius); + background: var(--color-background); +} + +swp-theme-label { + display: flex; + align-items: center; + gap: var(--spacing-3); + color: var(--color-text); +} + +swp-theme-label i { + font-size: 20px; + color: var(--color-text-secondary); +} + +swp-toggle-switch { + position: relative; + width: 44px; + height: 24px; +} + +swp-toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +swp-toggle-slider { + position: absolute; + cursor: pointer; + inset: 0; + background: var(--color-border); + border-radius: 12px; + transition: background var(--transition-fast); +} + +swp-toggle-slider::before { + content: ''; + position: absolute; + width: 18px; + height: 18px; + left: 3px; + bottom: 3px; + background: white; + border-radius: 50%; + transition: transform var(--transition-fast); +} + +swp-toggle-switch input:checked + swp-toggle-slider { + background: var(--color-teal); +} + +swp-toggle-switch input:checked + swp-toggle-slider::before { + transform: translateX(20px); +} + +/* =========================================== + DRAWER FOOTER + =========================================== */ +swp-drawer-footer { + padding: var(--spacing-4) var(--spacing-5); + border-top: 1px solid var(--color-border); + flex-shrink: 0; +} + +swp-drawer-action { + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-2); + width: 100%; + padding: var(--spacing-3); + font-size: var(--font-size-base); + font-family: var(--font-family); + color: var(--color-text-secondary); + background: transparent; + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + cursor: pointer; + transition: all var(--transition-fast); +} + +swp-drawer-action:hover { + background: var(--color-background-hover); +} + +swp-drawer-action.logout:hover { + color: var(--color-red); + border-color: var(--color-red); +} + +swp-drawer-action i { + font-size: 18px; +} diff --git a/app/wwwroot/css/page.css b/app/wwwroot/css/page.css new file mode 100644 index 0000000..cf4b9c7 --- /dev/null +++ b/app/wwwroot/css/page.css @@ -0,0 +1,204 @@ +/** + * Page Layout - Content Area Structure + * + * Page container, headers, cards og grid layouts + */ + +/* =========================================== + PAGE CONTAINER + =========================================== */ +swp-page-container { + display: block; + max-width: var(--page-max-width); + margin: 0 auto; + padding: var(--spacing-6); +} + +/* =========================================== + PAGE HEADER + =========================================== */ +swp-page-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + margin-bottom: var(--spacing-6); +} + +swp-page-title h1 { + font-size: 24px; + font-weight: 600; + color: var(--color-text); + margin-bottom: var(--spacing-1); +} + +swp-page-title p { + font-size: var(--font-size-base); + color: var(--color-text-secondary); +} + +swp-page-actions { + display: flex; + gap: var(--spacing-2); +} + +/* =========================================== + CARDS + =========================================== */ +swp-card { + display: block; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-lg); + margin-bottom: var(--spacing-5); +} + +swp-card-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--spacing-4) var(--spacing-5); + border-bottom: 1px solid var(--color-border); +} + +swp-card-title { + display: flex; + align-items: center; + gap: var(--spacing-2); + font-size: var(--font-size-base); + font-weight: 600; + color: var(--color-text); +} + +swp-card-title i { + font-size: 20px; + color: var(--color-text-secondary); +} + +swp-card-action { + font-size: var(--font-size-md); + color: var(--color-teal); + cursor: pointer; + transition: opacity var(--transition-fast); +} + +swp-card-action:hover { + opacity: 0.8; +} + +swp-card-content { + padding: var(--spacing-5); +} + +/* =========================================== + DASHBOARD GRID + =========================================== */ +swp-dashboard-grid { + display: grid; + grid-template-columns: 1fr 350px; + gap: var(--spacing-5); +} + +swp-main-column { + display: flex; + flex-direction: column; +} + +swp-side-column { + display: flex; + flex-direction: column; +} + +/* =========================================== + AI INSIGHT + =========================================== */ +swp-ai-insight { + display: block; + padding: var(--spacing-4) var(--spacing-5); + background: linear-gradient(135deg, + color-mix(in srgb, var(--color-purple) 8%, transparent), + color-mix(in srgb, var(--color-teal) 8%, transparent) + ); + border-radius: var(--border-radius); +} + +swp-ai-header { + display: flex; + align-items: center; + gap: var(--spacing-2); + margin-bottom: var(--spacing-2); + font-size: var(--font-size-sm); + font-weight: 500; + color: var(--color-purple); +} + +swp-ai-header i { + font-size: 16px; +} + +swp-ai-text { + font-size: var(--font-size-base); + color: var(--color-text); + line-height: var(--line-height-relaxed); +} + +/* =========================================== + QUICK ACTIONS + =========================================== */ +swp-quick-actions { + display: flex; + flex-direction: column; + gap: var(--spacing-2); +} + +swp-quick-action-btn { + display: flex; + align-items: center; + gap: var(--spacing-2); + padding: var(--spacing-3); + font-size: var(--font-size-base); + font-family: var(--font-family); + color: var(--color-text); + background: var(--color-background); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + cursor: pointer; + transition: all var(--transition-fast); +} + +swp-quick-action-btn:hover { + background: var(--color-background-hover); + border-color: var(--color-teal); + color: var(--color-teal); +} + +swp-quick-action-btn i { + font-size: 18px; +} + +/* =========================================== + RESPONSIVE + =========================================== */ +@media (max-width: 1200px) { + swp-dashboard-grid { + grid-template-columns: 1fr; + } + + swp-side-column { + order: -1; + } +} + +@media (max-width: 768px) { + swp-page-container { + padding: var(--spacing-4); + } + + swp-page-header { + flex-direction: column; + gap: var(--spacing-4); + } + + swp-page-actions { + width: 100%; + } +} diff --git a/app/wwwroot/css/sidebar.css b/app/wwwroot/css/sidebar.css new file mode 100644 index 0000000..cc9354e --- /dev/null +++ b/app/wwwroot/css/sidebar.css @@ -0,0 +1,246 @@ +/** + * Sidebar - Side Menu Component + * + * Navigation sidebar med collapse-funktionalitet + */ + +/* =========================================== + SIDE MENU CONTAINER + =========================================== */ +swp-side-menu { + grid-row: 1 / -1; + display: flex; + flex-direction: column; + background: var(--color-surface); + border-right: 1px solid var(--color-border); + overflow-y: auto; + overflow-x: hidden; +} + +/* =========================================== + HEADER + =========================================== */ +swp-side-menu-header { + display: flex; + align-items: center; + gap: 10px; + height: var(--topbar-height); + padding: 0 var(--spacing-4); + border-bottom: 1px solid var(--color-border); + flex-shrink: 0; +} + +swp-side-menu-header > i { + font-size: 26px; + color: var(--color-teal); +} + +swp-side-menu-logo { + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); +} + +/* Toggle Button */ +swp-menu-toggle { + margin-left: auto; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + border: none; + background: transparent; + border-radius: var(--border-radius); + cursor: pointer; + color: var(--color-text-secondary); + transition: all var(--transition-fast); +} + +swp-menu-toggle:hover { + background: var(--color-background-hover); + color: var(--color-text); +} + +swp-menu-toggle i { + font-size: 18px; + color: inherit; + transition: transform var(--transition-normal); +} + +/* =========================================== + NAVIGATION + =========================================== */ +swp-side-menu-nav { + flex: 1; + padding: var(--spacing-3) 0; + overflow-y: auto; +} + +swp-side-menu-group { + display: block; + margin-bottom: var(--spacing-2); +} + +swp-side-menu-label { + display: block; + padding: var(--spacing-2) var(--spacing-4) 6px; + font-size: var(--font-size-xs); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--color-text-secondary); +} + +/* =========================================== + MENU ITEMS + =========================================== */ +swp-side-menu-item, +a[is="swp-side-menu-item"] { + display: flex; + align-items: center; + gap: var(--spacing-3); + padding: 10px var(--spacing-4); + color: var(--color-text); + cursor: pointer; + transition: all var(--transition-fast); + border-left: 3px solid transparent; + text-decoration: none; +} + +swp-side-menu-item:hover, +a[is="swp-side-menu-item"]:hover { + background: var(--color-background-hover); + text-decoration: none; +} + +swp-side-menu-item[data-active="true"], +a[is="swp-side-menu-item"][data-active="true"] { + background: var(--color-teal-light); + border-left-color: var(--color-teal); + color: var(--color-teal); + font-weight: 500; +} + +swp-side-menu-item i, +a[is="swp-side-menu-item"] i { + font-size: 20px; + flex-shrink: 0; +} + +/* =========================================== + FOOTER + =========================================== */ +swp-side-menu-footer { + display: flex; + flex-direction: column; + gap: var(--spacing-2); + padding: var(--spacing-3) var(--spacing-4); + border-top: 1px solid var(--color-border); + margin-top: auto; + flex-shrink: 0; +} + +swp-side-menu-action { + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-2); + padding: 10px; + font-size: var(--font-size-md); + color: var(--color-text-secondary); + background: transparent; + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + cursor: pointer; + transition: all var(--transition-fast); + font-family: var(--font-family); +} + +swp-side-menu-action:hover { + background: var(--color-background-hover); +} + +swp-side-menu-action.lock:hover { + color: var(--color-amber); + border-color: var(--color-amber); +} + +swp-side-menu-action.logout:hover { + color: var(--color-red); + border-color: var(--color-red); +} + +swp-side-menu-action i { + font-size: 18px; +} + +/* =========================================== + COLLAPSED STATE + =========================================== */ +swp-app-layout.menu-collapsed swp-side-menu { + overflow: visible; +} + +swp-app-layout.menu-collapsed swp-side-menu-logo, +swp-app-layout.menu-collapsed swp-side-menu-label, +swp-app-layout.menu-collapsed swp-side-menu-item span, +swp-app-layout.menu-collapsed swp-side-menu-action span, +swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] span { + display: none; +} + +swp-app-layout.menu-collapsed swp-side-menu-header { + justify-content: center; + padding: 0; +} + +swp-app-layout.menu-collapsed swp-menu-toggle { + margin-left: 0; +} + +swp-app-layout.menu-collapsed swp-menu-toggle i { + transform: rotate(180deg); +} + +swp-app-layout.menu-collapsed swp-side-menu-item, +swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] { + justify-content: center; + padding: var(--spacing-3); + border-left: none; +} + +swp-app-layout.menu-collapsed swp-side-menu-item[data-active="true"], +swp-app-layout.menu-collapsed a[is="swp-side-menu-item"][data-active="true"] { + border-left: none; + border-radius: var(--border-radius-lg); + margin: 0 var(--spacing-2); +} + +swp-app-layout.menu-collapsed swp-side-menu-action { + justify-content: center; + padding: var(--spacing-3); +} + +swp-app-layout.menu-collapsed swp-side-menu-footer { + padding: var(--spacing-3) var(--spacing-2); +} + +/* =========================================== + TOOLTIP (Collapsed State) + =========================================== */ +.swp-menu-tooltip { + position: fixed; + margin: 0; + padding: 6px var(--spacing-3); + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + font-size: var(--font-size-md); + font-family: var(--font-family); + color: var(--color-text); + white-space: nowrap; + box-shadow: var(--shadow-md); + pointer-events: none; + z-index: var(--z-tooltip); +} diff --git a/app/wwwroot/css/stats.css b/app/wwwroot/css/stats.css new file mode 100644 index 0000000..2d50a5f --- /dev/null +++ b/app/wwwroot/css/stats.css @@ -0,0 +1,258 @@ +/** + * Stats - Statistics Components + * + * Stat bars, cards, values og trends + */ + +/* =========================================== + STATS CONTAINER (Grid/Bar/Row) + =========================================== */ +swp-stats-bar, +swp-stats-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: var(--spacing-4); + margin-bottom: var(--spacing-5); +} + +swp-stats-row { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--spacing-4); + margin-bottom: var(--spacing-5); +} + +/* =========================================== + STAT CARD + =========================================== */ +swp-stat-card { + display: flex; + flex-direction: column; + background: var(--color-surface); + border-radius: var(--border-radius-lg); + padding: var(--spacing-4) var(--spacing-5); + border: 1px solid var(--color-border); +} + +swp-stat-box { + display: flex; + flex-direction: column; + gap: var(--spacing-1); + padding: var(--spacing-4); + background: var(--color-surface); + border-radius: var(--border-radius); + border: 1px solid var(--color-border); +} + +/* =========================================== + STAT VALUE + =========================================== */ +swp-stat-value { + display: block; + font-size: 22px; + font-weight: 600; + font-family: var(--font-mono); + color: var(--color-text); + line-height: var(--line-height-tight); +} + +/* Larger variant for emphasis */ +swp-stat-card swp-stat-value, +swp-stat-box swp-stat-value { + font-size: 22px; + font-weight: 600; + font-family: var(--font-mono); + color: var(--color-text); +} + +/* =========================================== + STAT LABEL + =========================================== */ +swp-stat-label { + display: block; + font-size: var(--font-size-sm); + color: var(--color-text-secondary); + margin-top: var(--spacing-1); +} + +swp-stat-box swp-stat-label { + font-size: 11px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--color-text-secondary); +} + +/* =========================================== + STAT SUBTITLE + =========================================== */ +swp-stat-subtitle { + display: block; + font-size: 11px; + color: var(--color-text-muted); + margin-top: var(--spacing-1); +} + +/* =========================================== + STAT TREND / CHANGE + =========================================== */ +swp-stat-trend, +swp-stat-change { + display: inline-flex; + align-items: center; + gap: var(--spacing-1); + font-size: var(--font-size-xs); + margin-top: var(--spacing-2); +} + +swp-stat-trend i, +swp-stat-change i { + font-size: 14px; +} + +/* Trend Up (positive) */ +swp-stat-trend.up, +swp-stat-change.positive { + color: var(--color-green); +} + +/* Trend Down (negative) */ +swp-stat-trend.down, +swp-stat-change.negative { + color: var(--color-red); +} + +/* Neutral trend */ +swp-stat-trend.neutral { + color: var(--color-text-secondary); +} + +/* =========================================== + COLOR MODIFIERS + =========================================== */ + +/* Highlight (Primary/Teal) */ +swp-stat-card.highlight swp-stat-value, +swp-stat-box.highlight swp-stat-value, +swp-stat-card.teal swp-stat-value { + color: var(--color-teal); +} + +/* Success (Green) */ +swp-stat-card.success swp-stat-value { + color: var(--color-green); +} + +/* Warning (Amber) */ +swp-stat-card.warning swp-stat-value, +swp-stat-card.amber swp-stat-value { + color: var(--color-amber); +} + +/* Danger (Red) */ +swp-stat-card.danger swp-stat-value, +swp-stat-card.negative swp-stat-value, +swp-stat-card.red swp-stat-value { + color: var(--color-red); +} + +/* Purple */ +swp-stat-card.purple swp-stat-value { + color: var(--color-purple); +} + +/* =========================================== + HIGHLIGHT CARD (Filled Background) + =========================================== */ +swp-stat-card.highlight.filled { + background: linear-gradient(135deg, var(--color-teal) 0%, #00695c 100%); + color: white; + border-color: transparent; +} + +swp-stat-card.highlight.filled swp-stat-value { + color: white; +} + +swp-stat-card.highlight.filled swp-stat-label { + color: rgba(255, 255, 255, 0.8); +} + +swp-stat-card.highlight.filled swp-stat-change { + color: rgba(255, 255, 255, 0.9); +} + +/* =========================================== + QUICK STATS (Compact Variant) + =========================================== */ +swp-quick-stats { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: var(--spacing-3); +} + +swp-quick-stat { + display: flex; + flex-direction: column; + text-align: center; + padding: var(--spacing-3); + background: var(--color-background); + border-radius: var(--border-radius); +} + +swp-quick-stat swp-stat-value { + font-size: 18px; +} + +swp-quick-stat swp-stat-label { + font-size: 11px; + margin-top: var(--spacing-1); +} + +/* =========================================== + STAT ITEM (Inline Variant) + =========================================== */ +swp-stat-item { + display: flex; + flex-direction: column; + gap: 2px; + padding: var(--spacing-2) var(--spacing-3); + background: var(--color-background); + border-radius: var(--border-radius); +} + +swp-stat-item swp-stat-value { + font-size: 16px; + font-weight: 600; +} + +swp-stat-item swp-stat-value.mono { + font-family: var(--font-mono); +} + +swp-stat-item swp-stat-label { + font-size: 11px; + margin-top: 0; +} + +/* =========================================== + RESPONSIVE + =========================================== */ +@media (max-width: 1200px) { + swp-stats-bar, + swp-stats-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 768px) { + swp-stats-bar, + swp-stats-grid, + swp-stats-row { + grid-template-columns: 1fr; + } + + swp-quick-stats { + grid-template-columns: repeat(2, 1fr); + } +} diff --git a/app/wwwroot/css/topbar.css b/app/wwwroot/css/topbar.css new file mode 100644 index 0000000..6c9d182 --- /dev/null +++ b/app/wwwroot/css/topbar.css @@ -0,0 +1,180 @@ +/** + * Topbar - App Header Bar + * + * Search, notifications og profil-menu + */ + +/* =========================================== + TOPBAR CONTAINER + =========================================== */ +swp-app-topbar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 var(--spacing-5); + background: var(--color-surface); + border-bottom: 1px solid var(--color-border); + position: sticky; + top: 0; + z-index: var(--z-sticky); +} + +/* =========================================== + SEARCH + =========================================== */ +swp-topbar-search { + display: flex; + align-items: center; + gap: 10px; + padding: var(--spacing-2) var(--spacing-3); + background: var(--color-background); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + width: 320px; + transition: border-color var(--transition-fast); +} + +swp-topbar-search:focus-within { + border-color: var(--color-teal); +} + +swp-topbar-search i { + font-size: 18px; + color: var(--color-text-secondary); + flex-shrink: 0; +} + +swp-topbar-search input { + flex: 1; + border: none; + outline: none; + background: transparent; + font-size: var(--font-size-md); + font-family: var(--font-family); + color: var(--color-text); +} + +swp-topbar-search input::placeholder { + color: var(--color-text-secondary); +} + +swp-topbar-search kbd { + font-size: var(--font-size-xs); + font-family: var(--font-mono); + padding: 2px 6px; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: 4px; + color: var(--color-text-secondary); +} + +/* =========================================== + ACTIONS + =========================================== */ +swp-topbar-actions { + display: flex; + align-items: center; + gap: var(--spacing-2); +} + +/* Action Buttons */ +swp-topbar-btn { + display: flex; + align-items: center; + justify-content: center; + width: 38px; + height: 38px; + border: none; + background: transparent; + border-radius: var(--border-radius); + cursor: pointer; + transition: background var(--transition-fast); + position: relative; + color: var(--color-text-secondary); +} + +swp-topbar-btn:hover { + background: var(--color-background-hover); +} + +swp-topbar-btn i { + font-size: 22px; +} + +/* Notification Badge */ +swp-notification-badge { + position: absolute; + top: 6px; + right: 6px; + min-width: 16px; + height: 16px; + padding: 0 4px; + font-size: 10px; + font-weight: 600; + background: var(--color-red); + color: white; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; +} + +/* Divider */ +swp-topbar-divider { + width: 1px; + height: 24px; + background: var(--color-border); + margin: 0 var(--spacing-2); +} + +/* =========================================== + PROFILE TRIGGER + =========================================== */ +swp-topbar-profile { + display: flex; + align-items: center; + gap: 10px; + padding: 6px var(--spacing-3) 6px 6px; + background: transparent; + border: 1px solid transparent; + border-radius: var(--border-radius); + cursor: pointer; + transition: all var(--transition-fast); +} + +swp-topbar-profile:hover { + background: var(--color-background-hover); + border-color: var(--color-border); +} + +swp-profile-avatar { + width: 32px; + height: 32px; + border-radius: 50%; + background: var(--color-teal); + color: white; + font-size: var(--font-size-sm); + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; +} + +swp-profile-info { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +swp-profile-name { + font-size: var(--font-size-md); + font-weight: 500; + color: var(--color-text); + line-height: var(--line-height-tight); +} + +swp-profile-role { + font-size: var(--font-size-xs); + color: var(--color-text-secondary); + line-height: var(--line-height-tight); +} diff --git a/app/wwwroot/fonts/Poppins-Black.woff b/app/wwwroot/fonts/Poppins-Black.woff new file mode 100644 index 0000000000000000000000000000000000000000..65f380175b9d3cd42633b343cb8085a8f6ffe802 GIT binary patch literal 64180 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 literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-BlackItalic.woff b/app/wwwroot/fonts/Poppins-BlackItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..63eb02ed84faa517c6ba1a4b13705bc3f24f4bc5 GIT binary patch literal 71488 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

9K%Zl#e3n1is0?= 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 zva�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�%vp}NZo1%zLOYHS6-MB zmHCZG0Sx+z%E7zt5)gE}4m^r=z)$2(q65MePx1G%UJ;pI?VIdnT~YG(4?mi!BqMh^ zeaQ(F7RJw~@^HGK4F%b9lm+00C^{izCP=yx*Y4~7ji=iMUPE(`bUxsE0h

z?mM-XxR`+81%l@jSB1^OmCO?DqhigZ*vX;B z81`}F#OV|HdF(cc1V%F&gbdC?Mi`~LFt~1Rn#_&uBJA&%vpaR+&gx+7R!DD?V?iDFX>E&YL=>;eL6eS+a ztyiqpgKuK}h2G}udB?}o`i!Ju%NE{e;AQ_5K4)J|G)$Ef;5iu2f^;$->=SzstxHrg zqb-Ip$(hXY*9FcN)+^TQ!RM2^6K%--6jJkByG(02%4 zBM5%fj$=u z7nCT79qOgb@o$A0xCyxhn~lZY+1}b->=R78xCD?S=OrBf2laKkvy5q>jL41Z$0e&# zoIjr^#?m2t;>bl}o1ge50Rr(J5?`Y(S{BH+BDV~z+Cx*oXkjvv(#IGkuL`7(yG&rD zdqzu|A#&?LGR>ZEVt3OPmQJq*55Wlt`o}(uGB^(<+g(FYCjz z7WlzA5n$@ag@Gz>I{M-nA1TdHO9~P#FNd;Rp{+U1=OZtMeXuayTj47V`YNLy4Q
x5)GWGs9zNPRE`hFaBY$CdOUcJWgx3wX* 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�|fBCXI~E?Zr~x>pQGwGhL^{pFe{KX1vcf_bUTrvd3wtY4#X>FU*8v!ZYz z_fCCDUb%x)7bX`q{)^ujdlM~Pxv`Iqx!Ek2%j)6_+i%n0DA#yUzDecUg=g}4Jw?w* zV;%SEV!-hCCX^8~06NvctDVxs5Qo9*X=TtwK$OoZ@hSa#1Yopce}#x{)b0+-VR{xA;-8dBEO2x-H(?&v!-O@bWCW1%urBYYEv35nLozKG%6UlJhs^(IaQ} zjOA%wEIttQIZ0 zGBw+MmWfo$R07^OdhSsqeaci~&}&O>Dw!0(C!LyclJ=gaRJSwc*t7V z^;+QS9mLL%d{<~|J?zb%-qi>}SNO{vF#nLgPl&cpjKVGT^FHg%lCGRkD42xEXyEFJAQ-C8vV@@GnAC`&-!k4T$hW#PCojD}Wx=gs< z)yX~BelYKlOxF}_S6UuQ9}}B5)`6!POD=Yn6ruV2oI-Rc9m;-nSGIdyNap$wJ55Vn zvXHznk3z#6A!Z1P-@g|P2#DhUE*l^ZpcbG3pl4tK;Ar3r5FwCikS&likXKMBP&7~? zP$p0zP%F?_(0b4n&=)XrFgLI@up4l6aAI(JaB*;D@FMUB2rLK{h-`={NEApu$Pma5 z$WtgBC{?H=sBWlZXc}lO=sf5(=x-Pi7(bXnn0HtjSS{E>*flszIAJ(1xNdkPcmw!E z_#F5O_!js9_!;;O_!Ibh1P+8?ghGTBgabr)L^(uP#Ad`Z#786`Bse52BwnQ7NZCl` zNax7-$O6c&$hF89y5P}gR6PgiL5`Gg=5a|)w5@iyV5-kv85i1iL5jznF5hoJ& z5TB4xlCYAvku;F3kiwHnlg5#blD?8bk@1sxkQI<^lAV%0kV}%QksFcQlQ&cFQXEoR zP!3U1QAJXnQ8QEL(%{l~(Y(@H(N58E(*fu%=zr7OGJrFLGTbvdFfKAFGPN`FGdHqO zur#s~vL^fj{uRYW%vQ=y%YMLN%Q4Hb$tlg*#W}{s!o|;3&ehD#z|GCw#XZKo#J$IT z#r?{o&a=p?!fU{5&FjuP#V5+A$fwI!%Gb!(%QwkS!ym<;!oMXTAkZg>ENCQHErcwD zFGMZGCL|@4AapMDCJZjDDV!yIB|C2k?^BEBg> zBw;JjF9{>5E!ivuE@dP&BuyplFMTefB2y>RB{L?oB(o=TCG#o^CW|ENE_)-VF1IW% zEMKaCq`<8ZqA;gOspz1%s06PhrPQvBqO7CbqXMoXuTrhjt_rQ{r+TKQtu~-eq8_R~ zq5-dAuTiZDqlu$wuGykFqJ^ZTp!G)^SUXJnUPnu3P-j7BN0&}FU-w>5K`%`oSYJ-R z&w$dP%J7$AxZ(D1$=@AD@;s8;>bZR?h}694|Ak zHg7aQ@PO+;k-*fz`5@w;tYE6(!r;3Q zi4c{LicqLfr_k*%max=tyl~g>`3RDTKM~)NHj#5tv{8A{6w%=^s4<=~C$R#tfY|pq z*|>^$x_Hj`lUZ0<;aPvPowG-BNONp++H*;AgK~HC zH1f*xvGSerrwb?x5(?f5)eEPKn2WND28$kwK8rDnC5p?7n~Tp&m`Zp{oJu-MMoJz^ znM!#}JxYg4mrD0auS!45pvut7@XDyltjmha9?NCQ!^<}-SSoZXf-1@@W-9J0F)R5h zjVog-TPqK%5UY5qEUJ>L2C8nW3999)y{pTsS8E_@*lJX3ENaqfPHUNJ-D^W?b89nGd1{<~;;Tt&{ zbsL=;!y20!ryAEA@0(zoaGKbgWScyivYKX^o|;*k#hT5UJ)2XT>zhZLx0`R8zgiGl zh+61dxLd4RGFk>&?pw)P#acsJOIin8Pg}p+VA}-R4BMjHI@`|Le%krkwc5SfW7;d) zhuYWMuR0hyxI270{-vd(zGJ@=ty8(vtuwN7w+pOGt1GN4x2v|RwHvYC@MtCyztSFd2NY_DdoNv}h%Pj7B-Wp8WmVDD`2X76e5 zL+?)?Y#&FTNS{KVPM>+7bDw`-df$5Aao=6vS3h(=dOugccYk<)Qh#oLMSn~GzyQtw z#Q@6y|A6#>+JNDJ^?=(z;6U%dHW(2(4a){yCtu}(3>~Q*U z@o@cc_wf6O#E8m>{)p9x>qy{8%t-1;!AQ+W*T~^0)F|30(J0@j)~MTP;%Lrj=jhVt z)#&RO*ckPg)|ly--gaK%=pIm$@u;F_XNxY z`ULTW(uCeb%`#1?8N58>BPgt&m`<5<|OGP<0Q|d#H7lk!KBrs+hovW z++_OX;Nu=`|0l) zm>KjL;u-oGt{Kr8r5XJh>lu%kfSH(?%$bszzL~?BpIO9N*V)k7U zhq=PJg?Z?Cl6kIqm3hN?i+P9ni1~&2`}yw$!Uc{6xdqdO^o8Puj)nP!?SPh0#@=l5SFlgSPstuZ#gKpq;)6&oFhG&KGH7$iJ+@FH(=Zj7z{1@g z!TWxaeGV^l4WH-oc+wGUpws;=*4O?TmK+Gqmmtu91d=M{8~uKmZ&Z_%cDy>#oE02I zJdfIynpkG;70$pEV&nXqvOpd6SdH6RW9pa%|fbIo`6O-@z?rkiSi*t%8
*m53;Hz;5$vP?T{x!ymHPjZI5m&E3lBM@pKl*(}ImvG{?QHo;q2-Nt@bH_G8 zvjqJ@R8s(>9HtHr2cy-(X%VjrW_hyAv06z?lf7-$s3i z^2X}>&uUMX(S!|UY7j~JYkBnxh)J>Vd+|^8OIgEWGVG^tD`nLb$rEmw;|0BU;*cK% zR>(f_slEyc&V`h(C?_w}J5}QL{Ow++3*b)8!io8Rl2v++lTpX>AkL9RM-$2EeS;nL3EF150ybYxaCF=gChjZlFqSgkS%!y1Qv3k zh@!P0Ca5|#%GS2xigw6O-}4Q(i+}9-y8D1WQ+T*|l9xV&DCtzt2KpUVRGI;I%BrO=HdI!e^^HM^VDe2o2zOLaEF8N<&$+KboWmkp zq)}(%gq9TbRWoypJ)9OTTVPyIyK*{B=+09!jH2xV=$P?krCLYs5l2SYW}W|xD%H0$ z#0!k@KtCDBt8fTi$PhhAW`+P*hMg6Qh6Nl1#6&yyStI@`JXE5D5>zghC2Ph6dw*&{ zG)wu*nlEIs&`Z@vQg_zUVL#rC9gNe0)T+EB#a3fqZZxv0!IaB7#2TLa+;lB*K}f`D zRkNRRPTN7Yq3hPSo5q@(N{Krwt}O8-Y_#K95p$_XZ+KfCO-jQx2)C{*kj>_1t4~Yw zag0Kg92`XwQJN`97u~Wx9KJED)Pv2-bYowH4V}*hik_zd$z< z*T+(*#;l=8EM5#dQxtFGkib^IWBq3)Lvv|8HN<`5K8}YE{X#<^J|%D0dkYDU$oEfw z^E3xUz&~NeZ#K&cygn!e#TN+%u;0_J2^R^9r<>-tpweA)%CW}@%FOT!Z4b*(u}>qlnK{G{BZ95n)Zx`1yW}_UAkS>cUkad zKxl1N{2i@6hzZqFR^aR@Ce9fR^Iq!5a(l*ae;Q|rJ!v)3U+fQ9B|)U|R1@<(jT%4)zZR{venxpxF*OUjq$x|W zd^%A~<|1pta$>ut1i4xVo?N;kNTWJqVf=0QD?Iv1!8)^3wpe;fNz)k`1bsVt)zy7# z297I+O66{u3~Ffva%kY;&}G5^w7*8Wnlqg3P4eVf$0cJg@~d@^N&SJn?yU;ER8n#^PM?)A*eI}@%y z((#L`X@ir?2G0)4UL^KusTn5?qwpe=Ok-0tCXS+2!@$d9MlN~lDY#Y|LCQe@H%wCs z98X~q;PY$dgu8NENA4^GZzDVA?$C8bHXv+}ngvI+s`QlQ#YE<27#2x8B=jtFrZ)3)^fiQs8%hPqzjcIZB~#$)Ac+a0CI1`-+(@2 z3VYKXqj*a_iI?{fuJz(*S(tXM+J&?F*lfsh8CWgRSEr(Neh$`s?4P)dRZp+!ie=Eu zzCw1`F9!A~!si<-9Hi0msAvJ)eq*7WaK1=r)T`*(Ka@dGxv-@&cdXswdb1}ykRBW?#T57O6;`}q3sL`~u z#TVNOd&zV86?QJ3aGvzzfmyzFjhvK~HwRXBOkt1j;T*NS)D-lL`=P#yF`dqqal61$ zs0kN}vWOrF{|F}VGhTA3e8#ahAlUyEj(5aeGgMjE6*th|Gp7mN|MZGo*~!qb;Bp!Q zf`t8*{AC6<&Xryv?&JpfMPgGYY=lwXtXqh$N)m|y55bkFvG8=evYC6sYTBZF{Rk?6 zUQBTz_wvavLIM~el%u*&j6FU`c7d5f-Y)jEnK0sa>AjuvgJ?k#3$pqqdbB z$wCm(Hi0YE^sG}qyn8A`&K$%y$2dYzwcmRCqs*WY(AKxS#1JN?h^f-U;{P(yY0r^1 z9k!_vS7-cA)C~V@MWm}4r0v%BZ>NWt7X>uuF2A(JH3uikx|Vj9*AsJYg7rvSkBQ&| z+?DGqH`4%(nHcxsyA|!dL46yDh~?sRlK$!*Vw3K&%!Mq3vQ7FN`>|)!2)m$ zAd)VtiCb)@-t2rwfRcxawbU+D$}~gELBl(<-lVaE+7h8R*Z&;f017{A=_JmQ2H4rAtw@9I&Uv#c4LonY{2^U=`x=68oaSQi zmiJR%Oi4VDgJ-jrDL()J6xP<$#reU!<;hj?s{0pN2MB^bI>Igynws#+bQXmcj~X9G zJw0oxK0oOi>Lt6ZEe|1j{Y8v#?3k~z|BkzJKip@+#YX+H-3QZZ}80jBSWcqkM zUYac4pZ3k4H6o16oMrDOx%azoaIwIuc%(o~(Y|zxb;ruBlP4aDGB;A$IrihDKBWetK-opJj=LdWADl zi&>a2tV;+!9Q;0MhBdPRhA)R~bOZO|h5e>L?r7CQp3QvoDu-03Wmf0#JXl-IL>Q-W z%s%}_5X~%s!~|VeFw~-{D~F7x^1axKSkH20x2arG$O|5t4;Eu_-KC)=egOLn^$fMp%yh=PdHg6x6cRP>F zQdsz?9vCbX}gnw+hTJ0)*Pe$%evgFje8Q_4`aS<t++sCT-BPxdRLWAI<7~)BmzFK2Y-{Lu|Ee@6yVVF* z1{P4qx_$q^^Vzi#4tk3(2s?7dFWrWVDKQqwdX zZSn{GU_sVmy{+V|MDUyJYQib?4`lUr3=~VkD`Zb=!njPYYMCIf@wyo8V@1@WH{)4v zlc=H7{9CJk9?dh=XxS9^X_LX9tJY9+QVam3;`QLM3K7@nhy01ilUq`l+f_seMUqAm zlO;M~g%Lf9zK$!Yst1tCE>Vfvx$?wTP2ha|Qh@b|epS*dc0r!QE&!m=TrS4*9{C zq6+OA#=%>c?+^clSvpcQu1JFfo;OryCgJ9;^kXR2qnnuUCu51(#X=GiQ|Q?|LIe3ws{zPO}Qq(J8u`Z(N5=_Ff8m$z`R240ndBO$M_Jm;VzJJ%{$#x6%m*8JzWMtgH zPF*jbTv-Es5d4;kux}3uAsy_DpC966s)xY)m^Cqn@GECchKIsr@8JX0aZ*EDgQxqe zo(-RO-vxbG0v=)4zAn2A5{BR7?_0&+v#<{_q@>~|97$!Jzi$X;V9XySb?2Rg`2mW? z5t7ipH`Mp`mdny|3`q!-0lF0BEw0hI<3A=U9Vva(7ijBksy!X$b|TcCwCUGOrYC8| z%F(lyZYG0a3-GQ?>x~8aOTSox%#VG?bQVRe7~{kSNB|!j3dO73G#|V-7WlxIcu~X7%B+{m0v{LZm z*u=zp8l?G+9bdlrs&|}g{B_@R=r1z+1CM0MJequMr!DwLf}@Lqe{`yoDT^O#H@n}T zlCg1ObpcsdH&1q2&8|Ei@zCHs0}qe3CccRgk5tbRB)9J|5&f+^3Z{(ZgpbQ2y&nRE zK8lxdKVmJ>O6i!sYCM^F$lSMe(k+csD#8gdJ&N#>25_1$%Sp8G%JTV{R%g6&xw0}z zMSLJDFRL}Ts)EyRaoU1E9-QYGMW6R8F3BYH{OrHK1$UHxHovnz0f0|D+J)K5akp1~ z%1(Z%IVel`u(_@Kb`k5-AzPsGU(EEspHk8!JiOWm%+#deKP5uK-!E6*H_{wBICHWx@DysU(5S1#8`Uzn{Z0Q0E^iDh>FU{`yU^qaH~dnr6{1;kAafq=1M>)q=e-G=)Z_g`Sq_UOA#V~0we{ubq zyTP&8#?^M&&@OH?DTzl@jV+pMsfw^z-Q4PbRJ@ih+jO>5rR6PI!EJf%!I zr|kWWzsP@3@gJ1!^IOjp?VK@R!_G`M&VinwtyUYaP3V6M&k~lN7f-ksYc9~u;WMw@^JVjW{(GDg!E3sv2`5!zV&u_{ zW}Z;A+=F&weWOQO zbGiWavs5VoM-;{o1FXn)_nL;to*bT^QOh4(o)J2~Pckub&a}p)g!=4+u_I*17LPn3 zT4}Y-4vai%e%qcN5X&Y{ooUzQGx8z^wq+>fi0I~5C2xQh9OI8U14F)5o^okH zo=FHb>ky}${IExGeoFWNe+%pfw zM;$|ENVZxu@PfW+=D}U9)A&8+mq|f{jmGO-#)Y3^)=jq&oJW9Oj?IdaG{A$sAz8T} zJpZ65SE;N$?>)PZ^oU*e9&Zq=$;W?%v~dcuc#lC(^*}*I2ZiSM87e{Jf+hv;9wKq_ zeu{koEd&(-f8_7sol1oC7Ob1d@5$ALpniQ5+{?v}c5|Ro{jH`n2&4Uj{T=jVypgaf z($jT&0?xsU#CCkKFYBHffKz9UD$qr1) zVKtG`Y z7US_0R4N2%d0s_-Oz8b1h9n*_|=1vGRG1SpM~FqWrm@_44Jn z-<16A?b>WaDOm+!Y+h(HHt(?f^a}buKwbfpXsp~s_0ar+7H)l(Xjwo04~0Mb#$-%o3(;orTIe5PxN zIr3hqJ1opzq%S>!B}ba}5h!iM)oY?Hg&cp3t3CX$xPvgG3aNx6pLYgE#Sg*^21sdd z$Q+k!F20mbIr?wQE&T7Ke>^mgDqhxVOim!4Nu#nK1lWk_36SzV(M83E^h5^q8FUsTyYOeg(0&hcqEkay zJ-Id6SPbCC#g%hZY!XA#mx|t#Lz@mn)Hp;L_NOL`c;s3>jIN2+n^vLXPG9ha|5AyW|MisV;viCaCS+8p${x*g7&D-0HX0u`&a!FaF0)T$n4SH<{Ouud^41*AL};mDdl@vzM*bs}FzpC+p|e?+|_}Vxw|G4`vIS55vi# z!b#LNd%RZD(hv#_d(Ls_eB-CQynH0&f{-?(Oea43D`8KuWKrQbo9=@KBS zG91p>;>Pdbc+0LWcxairUZPMU&EyE|ol{FMmYF(zIVS(oBUYddnOkMIS78}m^bQY$ zMybhg56+^M!JXUstp(0 z0j-IWL{pQ~6!+v;^<}#@pBb$lF={oioC{laT<`u^>!HWi00jfG*%L-a{Uj8^TDn6!kT$Hybl-?1xDT&po(nN1=a%WL65CJ@yeBK4!7?z27) zV#Z(PwUxN2t+mOLrU$H_`+@%S*V9>I20(X@@g{g$N1D4Uv>H}y9p6s^S18g8t31!w z!HxHf#@M1brecjO8e*<%`@>#I)^rMiYWGo)BeNl2nsm^QM)XOkk zD?7ba`S?uCw$Gp|S|Qk6D!n?OIsY=W;kW}>Mo99j6!?|Irbs&?g^XD1bK4-|K#KS| z*@m)m!LxEbe*|8&n8v+@%(bPZaUSfgZ^Qk;{DGSLbI$@5H!Jhm&C9N16?Oc}s>xp$ z1%d^xpnRX(MH3T2ek^a@A;0ybdNuZM=wH1_zjt`|A4op8V|y#_+|AHX$2lTZcoX}V zRU*`|wvFxocK&t!0{z^SilowWAuQJK@*iYLRqE1U#8X+`a85O+gqe zNZ(E*UiDjhBC3Et%gT_WV*1k?G!st}YY7MR6&h2H4`^+0rJ>xs;?K08rEy<6e>HDAXrv$O*Kd(#yusb2EC0W41Eq$44p(QhT5;z1!bakk4FGh zs;|}VD3C-Chj#MEVNY#u-N6BUxbPdVk>_ui9$nvsLGf>>N*9J6tE-zOU9?dnoKWq( z$guj1&AZq1mp+1sMx3p&ey!~%G|i_Q+SF^!!6UTjC_5}6(no$_?a132D4Yn%JT)uKE2|Y#r-&Da|vqUypB0Gt{D5==l0FLFNY}SB&Sb; zn0H!_F!0d79peN|1I>Vk#fdUWWhf$J*HCmiBp3_Ae#{5Zd+zc0+#6gyZr9%W38z(8 z&t+YcrJm$(#NBh=hNMbSigChjL!(r5Bhi*okBM9}g5Dq?Y~p1WR~3osd-p+!fhZ4J zEhX*C_^i3H9K2X)Ef27s@A>UPNBt+yb6iNk@s176^LSn4O%3aJV&;FG$D5Z?ZG%dJm`0hJpaQxz66KfR4Z_36X7H$LF4t z6^EtiPJe&;r@jKBD~K0%l`VLmX*frYm#psY7EA7}=}doa%8hk&>8JwqXVZ`_sZgio z*joJ_i$2_#NDh|1%t-@X0eh`qTky&!{oyYZH&-y>+mDgmNFE|gTJ!atWrG$9>w|iX zjL_cBZI?Bt2B5e#>zs-`BsYfs@+DNUUU+6wt513&y{9S}P0GnIfQDD_xn(+o`pxFN zJo|P51By5W>CEk(i@5~6p}EOqrXZF|0N!6=s4N#@f*OOxLI)&b9(IHj*7HT(ccF+O z?CtvCZ;`l#GC&3Pm#}D4xyF?nBb{c8kA;cJ84gwjl`M`r?u;_?7)8aMH^4I;CjMc) z6miM`1wFy}n9-;fg;0wbI4PLUiTw$!VN9$_>;&0(R8zo##0k9i2JZ-FbvJkneZNNo zg62YG3>{yzT65bDqrE}RV-(}AgaS@4-`>oS7S1OW`=za(uq^wil}aIe_g~&FV$*)d zz5OA(0~=6<&ID&w=HZcVm-mN?Aot$&<*S`rHPC8i8Qp6O=Pw2=_9+)8mAL64`Klih zFnNl$XLmcrq?>YcJ@L}6qTdUxbiwA*mNrQ?!vd;&Fd#vbAzARcS~dxtK4T(+{Yh?& zpScv4Oo`{Om_#7a(m(cpE;<`i=4|ZmPog=GLs5X{$zfEE&+j&bm5479Ybq-r<+kVg zM4FrDlGXH~)vT{GD$f*a?vjlEP6KOJGJF}`*FqMF3iA;SzTCQMvPQ=cuVjX@gD_9ueEBIaV~N#4PM*`W#Kp6L z4sKVfkg?HIiGbEef7DeRVBMU1f+KU+5mPn(p znUI*SV5pK>kc>=&5IuFo7`4_0 ze+vy9`Y@yR?LxYL!1K_Nwo|4p3bhu;v1{TA_G@>|w2IwOH3qKG2njgp(1_;7!!^%+ zThv5Wc#*Lc)@y^4nU>Os?Lae`Yy(;ybax~z*(F9Rze$h>+TwWh!SJhx>k{)I03B3= z>Ydi1u9y<7nxtJ{O21DXpHw4pFM|d2Hi{ce-}9nlvG4iKB=Can-5sl6*#C*>Rw2{~ zyED@V)Uga#qMpc#0#<3914O;f*Z7_1g&+P=Lo{9iIjgwj&-dnLo|mvil=wS_ysDK+ zq4KW<%+Va-T*5=qQgL=}vD_c?D@Sz|PNfP!tTOXT=3 zrBD6#8K32SSaC?((GZxlh7rR1jKi@`yRkS(5O7fl1#K+C9xgCQgnscenXb-#`<8yK zAr}_jj=iRS_Ji(ycvZ+#GCaf^N#;p7GE{~80XLeY(P*yXGDWv!Wfm7hTs!0czMRdh zQvx#j*?!b%T>>$R1QtK9hrlAv!N(2}d#?J51-th2S%iiCuI+HpUJD)YIn8opj7p7s zk^q`KZ;|7DT+$zVsF}WHH$7{95D#bA1b1al^RKhFYJx*RCY@&i0EiP;Cb1ZUiBWZ_1bs)6#939)G;vUyDT9vk#>G5RR2F++K_+kM z2B1O)nrN>`sGw$4Y)*+nZ)>wM{Pk3~d9VQ^O!{fBZK{fg{;#`|TN zACpLfu`Ub(2j_#Zu9y@EyXxv;M!0htH7RirloWyaMWB>i8SuNh1UX2D7@`*qD=Z=74=to;w`GD9%_i;TrrS~Q;0}Bk zEhIwrY0y6rQnB8f_mBhj+=cu0 zLI#SMMQwh5;zip!st!JV$`iTGoL1!-$^|JzXEcd}!afB)2aCt$Yjb7YdJPjeu>iq6 zs9?E5uF&d*e54#Z=ahmLm1vu}QpXU(C;cp$CEVcd0%~;~4^k?gx($9JwyXUWlF+t< zz7y#}y@c0}jT7);SO>{ELqZt|*X!2w84U#6xuX-?+-$20wpWikA-JjF9#wegoti z=t1xLW91P~pjKVaY!)#i8t5K(+l;-_Z>+ktC&3aCLl)^J#l1n0D*L&Bxu5okH}0~a z#ZtlC|0MFrGlqndUTD0LgiDJ3pxq7t-@9+jjYq!Dzu~>F7r^&`>q{G_m*pz5cH5>m z&aK0|&l0oOeKyXQBmWVKuCm`7kD7s%7sl}+NFjwzg}<=1BMyO*e=T;$+w6?VLG&zl zUhtX{^+*pX8q<0nfBG~Ui;Vp?j{vnP6|*423yG(K6^ONd#EJ=%qD1-kotebfffzcI zo8xx^vwRDo z2gYYmN05DoMq?1pX4%PLO07t&*0C+7FmK1S(e&Rhf7<%{oIO4!A+e-gJ`{}>A`3QA z+Sh&NX~Mnpvvb=Bi`H?+Cy36{WC?KyV@Hz=!sFGo#K{sdOYk?zlYJx zqNn4gpsgBqNmH%P1jMln)ipwl#xgUh$Z;ay4%IO&p;N^aQr!PlCvZ$BDzocX`xOa_ zaEM0s1RX3~{Uz@2Saz#=3KwdqY3LUq!{}C)c?Jg74ASKUB(~nTm7d9O=b?_L% z0T%b*3S3`iTkI^UOizuSLqGCakj<}d3Y>w3M)s}~OD7CwOc)q~9#fR_oldcW4=%e9 z#^cy;_$eq~T0m4!MBLA45puhuu0m&hHl5o1z$pt;tR!+3QZIjT?P4ii374Uotnp=N zb*700T3l{{l}rSY>(H0CRKjJ*O#eMxNBQ3~_$1`VG(@Q_;+w%FQ%|Op{O`w$kO0!4 zp12?p^pAlK$VZ1Qw+1LjLo3qlQOlIf7OKrrTm+w#{yfMM2*D|MAsX+uO~yo>+Io@h0*AmiDES!hW9}v^5VN>hoIX*f8X689K>5j+gWR$wP7t>m z;`{LvC!7eg5PBW;L?_Wl49`ds+L?I zqr! z{JT2Nly2T~BvznNOmtKq4{UPE>EAG#`{ACd7ODzDvqs+z^S$>EOO(K63TLNKRcyIT zs%)rhSQcl`kMOqz%qh7t=(8=FdEKL_+#H^dbzRZib%!x`bkh1rkvW8UbVEyEzP+=^ z;-3o-(vJRs8J(_r((Fh#s87^%Fvn_{5!HlSB<<8D347<0`am_vF|X+J z01#<|Is#9cb6TNC9=K@l0FBrg59|zg#tR3_BNJ9CJ9NSi=FqQ3c;ML12$|VvM*29H zSj^4U&5SP`FizA@qsM57#;7p0<8;Z^bybRm1@I7i6lR5*i{Dzx2FsQy6lsAK_719g zZ)KCP!dKBq3$g(N<^i0GGg` zoldf5kzAS(Lm%cQb%7{XY1YZu+E{rJ499RvWc{(tnI~0KOt$hJjutZ~fcYmOr%VQ< zikKT|eP>Wp38iPaWtH^dNL2pGjx)m>hRRpwCeUwAQfvvFpueChF4hFk4O0&d57U3b zMFo((&C{>h2@e>W^;1+~+A}g+zpO~eACpKERZM`ro# z9;lk5@EqQSD>~1VZdrfT?3L@G0P+$i6MzHULx0W}{Cs6d06DjLY&4mUB(Dy*mv zm@?H+7z(u7URAndl^!iWPSd2~D9^f_BaXRQHfvS&@&spLTUmulCR3T1`hIBqbIETx zu^iTD;|yfMaz1hFIdaJDc&d1K?v5%R{mCS3pUf`2h5YTs=R$1f?yhNMK*RM6pO+UG zZ)%)^L6_Ca9dT>pP_nzMt&HW1_dCc}Zdf*9=ELj`&Sx%f+{w%PUE34c3oH6PB>k&N zbo!;jW%im3`T%`XkUR2}%f+dsR|qpE2^mx9bFo6cox>pgP|$888}%RlHz=1-gn5i! zpKc0MMKHrB!g+cLGjhW4_4b_jr9NdEcxKd47ttt07MFha+w6nq0otai}^%<)SUgy`NbI&T^P?g2HhLM_Uqi7 zKK;y80uUD7aV)TpBZ6NJ)zIsb&W$dPn(LoEjW|X=$q&iHlSvhGMS>*qSHYj4L>h^O zP#){1sd8-mpM~RgN0H8{XyuYUOQiHwX%b2LBVa>RK?#0Z{#@WGj-c*cRGdfePC7Zd z8A~d%%(BWlow%M;gv6ESD#-UZIMPD;vjIx0m}o>hxl!}`|I36yvYC+o7jEF>{3-g( zl*+Sjbk?{;sHDJOlKxn?W7mZXSR!E?0OFKOn@V}~xGeZgu1Hve?lY<&>Yzu{6P7Ld zAB5mzWZ+Rp%RC5cP(sO7l|rAGQVboV?r||(NV*!VMR}%++VDJ6g5PmzBDj4*0t(6D zKQY%qIdl=riPgj|;_ysk7Ng+OXB01rq?qUiLwURr0nV&1q6avO_he+|&s{5}PfRt% zVov=0w{baMOuCv%Yzeg5tWsl4>aJ!O1O0seOk$w9)smXx=_cN-96@^=x5Eet$~r^b z+QA8u*xmnObRsYZXSyat6vil36^RfWosD+!cE9RUAOOQ1PZ}#(2*7@Ark_)XQLyV` zE(=;;nxUoT42Yfljarl0?yEG?FSS>>x?_>y22K@dE|+karYDtu2B&z6~U#@!zX=khr$Gs8ox3m3~W zYq$(*FCJw$D_9_RH+urNF|1Pe3=aqH3$nPB$x}&jxKv^o+HNr_xax{{Ga6LeFt6bG zZGR4O*~X@**m_8aMsEi> zVh+RnM@M7OOwC&;OHH8dh~caQ*YPTHVfdepxn@KDMpxv#v=|b7HcN=tx|5R3?6$JQ zp_z!a_>M3wP6+W@fbh)O(0i!IyiPa7IJ3jGPSMjl1x)DRo15;c;Idmgx|$i^_B_ub z7&ZhtkZHP|!K-FxTj@_Y{H`rD>E#h4Yw^Ko0kfMK3>3^0=4?S2w{t?={)|q&X5!pB zw|aMUp2M>oAtmQ#JEBN|+QL@)UfHriYH)H46t!1v8r;ifJ4T;pY*bN?Jf6*Y1pdNE z0@PvwjMoD%$WItIRyf%KcW7aKpU05NvYAoN1B;|9ToQ<54M<{kX0SZ?sQn)(16E8_ zq6}E{s4BV|z;6+@ELvDaa(5g4(eV`humpQY&1=%Exm>$F8o1KJ@Q)35S$_t&<#6K7 zfp@VmE^so^+*qqTKY3g<^tt@Ze6B5bIUmjU+0F$8LVps{5a1psihP{GrXcI;PU>XCx{Pb@?~Xf1e}$?;bX z>h!}^TaHf48#;+n#fxpq+eN-e|G1~RnW_rilHjn~oQoFDgj+>MjbCJAQTvVkam?v$ z%=vuCc^lCij@kGhS@-#(UQZyH-|;xijF&BumR!5;@Jv{@26pgoo$2ha-70&Z{Nc&0D&t@pc zY@#UojUU*kMv5^?4FdjVxX%R>t}F5m^?SsUS+nW4xYwttEgSlW=)WLuL7|*@7l>39 zE{E_dK`6wT3R22=KMT3q9{nuLl%p?#)Q;$v=A%^Ug; z7|hAnkpBm34%`STiz*rdMV#F6m1PGvOe{;Anlh2g*;*~5+xLpH{B30(mftA$t$>UR z*|!)@dm#zGv1eCNyP5ECr6bgW(1Dp~^59NzKDybYVWZ})_rNN^oTB;H_(4~G#7!r; zo?n2@*i>|+hI9TkyvhQR#J`V2Z4pU@^zlJXdogZjvWv}}_A;iO9ev)r*aI%*diN0q z4?FkK=5@Gp|85BIqf~Y0EZcz2+44Sx5lf!dq<5>eW|i5OM5P><50vx|QD8nNnIz`M#aWmop{%`Ew& zqnmRQ1>!Apy|hbfGI<#;$a|t*gX5ITIONkY8rz)m%56a|KyUDV96Varpi!B}>Kr%} zv>v?Wq4VWoMmTyoEXbMH7aV})2uJSekos3I-E7=OevComqc`$421MevmEN%64w+8Y`(5-<(cbZCi{mb%0 zhoN=u1W~mqlLmY+)lGsqIbK^^eu!+HqCzq0#ezuB>H85EKD?&m8WCZ)O8&1bQ38$< zLG~(2?~s&Rio3Ivie}@ba4FE+tXY{xqmyN~d8d(Huu>-T%=g-AWisE)Ij7?VZUaQ7 zXz_{^hsH4{`aI|Ijiz?ADo6Y{JiBvx)rxspD-U9poO+8VChiItqF?-hpC0X!F{@dj zS~8!dTdlJg=J$lvKEjAmJ3=Blh}?;DIU0d(Z}d_*d^?)KMSb$Z<^8)bg$}*d8w-+l zwtGka%FmB}g_X^m7b4N%G}kwBud~AQ@;!ua$(|5HMrsXO8zPnh-h0eaP%)@0+qHTx zrYy_o%HuPuLSPB+cM}%_yR~(EdXi;j>8kKcu&~^!QAHtyLXGfO$L(L3!g8bekWK^c zvQ^#wRQ|G}ey!u~VfIE1etWT~uMd(OpXvMx4SxGDD zVeBUJIa|>gwHw)5&dhgS8~h&j96AI0XZ~dfQ%`^?uJln)atSH_vW_RVxSeye%oS;; zPV#Kf-EgVs^WztUQ2L7-_{WfPwK^KJ8!hRQ4M43iS(JKXGP*S6uG^S{Ew>Heo4tes z2rFJ3u3K7MP&|T&&<|1cOgO+~VAfoboaUc3YxlCj?J)~tcl2Sxz)MQGOaVkq1sBc> zx6nWBt*_yg=T|nczSZUduxRb-MGM#LUb%e}L*FL$YmS@IyQ&q5PKX%_`oyuJanTYT zq=)r6czt*r9^{`u<6|TBA-R({8-pu?a!^v*$?sG`An*vcs(_hG!v{p-GJE7@OWLje z4AJOM{8~7pYHH(3yulf@anKiW{ZdY1u8HBUZnfC#g50rpr}CJ3Wm!@0PW45*B4+$P zRjQS{HjavQnlP0LHX?* zF|04?%ottIdnodH&@^crR|r~E#}KcsJGfB-wkA`M60x-IfY)M+k>gx6Yd*(}NG|T< z9}awDGAWcMql%S_Et>_zYg7|1JPv$mRIp1b_AkHUSk64sNCa1m+mVH|5?<~~J0-Od z%k1r)5C^mdmLN!2%o#o9=r;bt^bZK{qc(@|KGo(`+p`wr+c3d59c2hUx_)G2J+r{7 zj7ls;4@L$@+CW6l6gH3VX@9D8^O`GCB>tFLJC_9qGqovy^di5E{&9B$GIRB;89-(( zWa50;9OH)95D!|5O1QTIAc=m&k!UgLWWFO?$6&)Vaeg^`J(<3M4nO2NxYZLQD*hn$ zx$3q_=1x*rhrboZS6kQ;upmD5Kxg#WsSROY7K_+&mdmw~zjQOOuygh51S$ZPC28ma6DX(T|jELwwO89}bU{9CBsl z?t09WArF@yCf*N&N6DG>sCApVe=>fofy?sfpD{NiKL)%Q?(CKMC*kB}==330l4bgb zLcSlizC6fHURazs)t%zrDB&ZYheF1J?(}1Hn1(rW_EcU8!zJlhr{glIT|(;6|SlAb;^|s zaw}FA0yqF4BDvBZLQ3!o8%7IOsOUr_a|~&aAiLF?S--EjWnZ1sVz(7b zj?0ys>tbp0+4B}C6rFjst8#N!)#gEZ7Wsno1pbw6wPk0+oxI@MpN%X^e%M|I8c?lT zGwIFy1hc6jf@6$r2tT{?aZkU0x!<3gN3YAS$jfs29xB~7x9vbJx{{w?N}nkUyiO0V z_vZ@jMrH=~mAF^W6X{HhE9te>uP+MS(;s-fq8KP^+Up(VaZ)ua!Sks4m@(XAN)69~ zVANzte&Yt)1I#7)p4_5`^6yQnvK1}LH0o`cWxLwx`^m@eyHjSdXE|ZcA}GD(C3MxG zOp()*>uQs!y7MYm6)>WsA9m_=&P-h=o0a(x)yYx>Z+%5YpCX4dvSg>2Q#%Vh)VaE) zrEXty^S(N(!Dw04LH|s?On;cmT&9zoHOPK*<&urXqRl<)%L-PrW9n;@s}|;UZx%yW zn_lO!Gb3vEyybyEc|5kDpHzq<7&lQAIkq@r!L)M6RE@`U0@k50G`^~|hve0JT3Qa& zt?8g?ejPKgYr(vs4RB-~hQQgpJXcnJJ}T?HuGqC|ZmL0)-TSH?A;A14t!Wq z1d@weYn|nB>FU^gr!z0l=_p{O`abzYgj6Bv(@GUi7RVo-ERS`pwm%@LuoN%K(rL_g zDAk|HSLjc2b6jpH*)*rtYIQNtqrB8DJ+1k4&VWqr>nY5dD^)GZU%XM22Zg%TW3y*x zLvhmQGqv-D4x`SFY|7&#Q#l}1wE+h-oS(yOWRT?WCT>C5_;i(iXyd*ua+$`ke#^F@ z)mQT#BJEn0#%>x|C(lsp9-{0TmBwKlShuXXn0}sIF!VgQDP-#nLO?HteB{7xSz-z0W+p}*+>t#(jE}i)yo?WAa#IIb}*HT2kOtua} z;uQ?-)r|?l@&a#}TAd_HnJp9~r52R5m3Q>|)-;xOXQbroC$K<}D4zTk)P$>`u zq6jLv2!i3n6T{A`p1Q_@pt`rzWtGQfU~Bdm*@2?JB6c(+E=fqyXCij4vVX5Iq{Q_s zm)+>7&uMeoj7BRXbCo(PYwiw4<}Z-TwmzR>O_ycn*froTO==to1a(c>M!J5r)!FKG zwMf!R3=&zIM44Q)fE9M&9kYA|<+SOoNavp-PeW>3IF>j1^|sS1Q)KP^ypF0`Z?PyP zSwwB%ch01i>uHoPy%k^4wNiWpQqmT9qV9h8iWF!)R1zZ|+b-Nv~YpS6sU)Cu?Nn4x~xn zqZ3p9@RJ6NTP((^G&M7r4X)V?u7oumr@Tv{HUXE?V3N^C>w6oUvP&e%iDGIuue+&p z$&mw#kG0qBZ;hvq@jKA62*8)cIar;B{jSyXW(z@Dnk>D!x_GY9kRlPyi4mlTN~;$( zELl~yyKCN-A|F(%GCvR%-0m%jk%qJidKu`%)D$BXea(!zXrjT%_NOGHf#|HAw=j1^ zQf4XX&axUaJ#Z|N=;P$+CpXTPXBRsSCTD0&p!nG_nOD(}NtawHlV{J*akXTqR+Ql} zpbuE=TDwcv%KD@6ytk1*x)}MR4l);KNz-`Wa@w6_DQaizz+O&!CRvQzzvq3)Y0n~y zLfO{WIqfde7HYqr(_TOpgxdX__CnGVZ0G%j(_T!Lg?7v<5W2g5X7#za^)v9)j()K? z_3Wetx2XB90v6hR=Z>edt0C-m^iTYGf#cJcA(M!*tO&=wb*paT{o}Y^i-O7KqA0UH z@-*nwY|Qw4s8GQ)+UfKVvoho3p@Q?#j)zk7IoDCYm{oz86MXRha9A`$Jbsb2 zYU*>Ncr0J$3&?LV-WP?Q(N0)l1~`l(R*^O2M6W`3QrPi2LFdEtD`6+B{8`Rimeca} z6%E7kRI?+GN2ij9G$wfJ>L|T6bleI-Tk69PSS4rq-FC!Y(@;)bQIZ%Qw@OPIiDAxL z0rB`@s~}Rl7wzAL?UZ5cdK7jfczb;stUAB9*v-_TVl2)J`8BxrY7CBURaf z>-j^0|3lY*l^f|-+St-`8nwb`U{C+)Ar$@EgJqbFmbJe6jJYKc2Fjw(jcXTluaA%C zpwAH}+Yu*L=>61jIKg$^r(|a8`^zvhiAj7|`+Z>DzUb_v;S0?$N8s5oekdVR3jXlM z2$ud;8pc!D&1P_bLAId!a z1DfKeal{*Dfg?MQzQx2t(7d6;$+NAx%sl*3#a1x1g(-ctk@ptF-!)e8D)NFEyy2xX zxyug8a4)T>aNg*jQ(#B?N~`8Dm92t%$i3lsqG)ymQx!5KVGx_%P@$(TjwnbsTiEG1 zZ-{;!TLx|^Cysb@;lQ^bUh_FP>x;v2e-T!Cf;;4kRLG_rh6yL%l8)d&GLiyDZGJLD!sa3cx(X0g=Q%eqydU>A&zA+jVN;6KL zx0<{~UF>$txGC)$349GR<;-(NTsh$|zKNlVt8LQ|77Zl8T^tTG2aZ=AP8kRiyV#xM z%1p<^ZfMTGc)#E{{llL6+PDf&c|*Vr)AyKgsE@mbf~2eAR)F4qWc|kaWm!%Kqm&i> zNm($B{7#4oELSPQgPFKIM6Pf_npuLSOl73`Ym?@31UZkM$1`)Tr+UNP-_DgDzNQLQ zN=ENg5oYcww&`Drj-wSd&6(=0@SIuV{L<*}C4gWFd~Yc+@6t|cr-7PWWw8 zUJiCXE1Ym#3Z4qZ20EyHZti|lbVoVbrX=q#9ZwB!U~0k$+Q*$kuqEK&{ReGI{y9@+ z(FC`T${E03Pmw&`ZZc;b*|=rH#?2!mn{QCbaq5-}V zQdBilI}qLL=iV>HTQg~G8^I#ZZ27=b0w=nzWfY>;rYmKmk&Vw9*@}8m)5u6LqShjL zcC!&R*ok+d{=@qM#h`gpRuh<7352jc~3qX@9y_tL1RHyZgdx3L>1ul3v&!1~0D26`4Hz;Pr5pwt{?zv=Y(fRF(yXS&$ z#tRVA&rQvR;77QNKAiNXrYC0-Y;s?@a3L$d4i2We_@{TAW!JV z@9+rulDR^|hCJQyq02*lZuwFVML$0cYt@0oq(|i4#mu=733w{p{moxdIvs}}=2{)u z&?}}lhMZ!Ou}}Ow@>`U{iH@0__R^c^DB8Tv(@-aS^K<%Crd1_JABu7vjeFJrebv9CMD-K7TQTur(^=CZvWeKfH^OA5<|LYvIgU z;hgd1E)EwN2eockYuQ?HLo`Nal@-lfp3t0s1NkfHrdBmmm4)SarGQJG`}h@;T=dh{ zpbUe$V*0Ox^h2HFL@6`oAo>|3-gQXJin`^d!NRB<#MD)7GbgNH!06VsppZGj8LIgr zS9zRziJRdEnzA-zhGE|W7J z#6RJ^)pH>acDyr)>ELq0VS+>dUo=Wvrc4GIH6DA+(q^CQ$;oo&uj$mlt?{LYZU@IL zsp8$@RFPD#pugMXP*-GUR>o0rrCGIQMa=b=1PIBmVn))Fhzt>j^Cpb%B(fV`lb&F- z1|?;MqJx(_V@XabxB5lk1|SQHiV+>Y{Tbil#XpWb7Z184XeYUL>@#%gu7*X`(Z445 zqIkeYWKZO7lFLPth3KXzkHBZdpbxK2qp{w4TUw2ywAbx+R9&-KMqf!@v+R}RVyXCA zDmUZK*c=B~XESJRP+y zPuRopDBOGNXG|JDe#^7{CDk*aO*s3;^`cc3Q&ETI`ZoD(gk1B_Xx_3r}wvTHU|-veoK}?wy;K>gZRftLg8qep#wgNk0Lb>96cc zi$*G!k&UBOK#{g~_t28ni*uJPTGk5*{~}!?PW#0TGF6(&sDoAjo+c)L3u#It?3}fU zJ7w_76F$=!O32@KoXS76c$?4e@YOl_@MdWGzeD-yDpiKpCsj0*w4uVSjUDx_qBuc} z&+2pMj*M&(rKX547mG4$>e0U6U&#$Y~U z$>0|2zNKg5^K@pr-soWLAsWMXhCJSdK6k4$eXb9W;O}PftZI$Tq1{N3jIYk0jkE8O zKF5sjv-3rFJZ5*CUc)#Z{sD!0pknnklU#LY+a?0D4|W4J&7*|yG>=J+9N~t*lR-x~ z(`=pU9=wHA=fdtAx!woGa3=T#L#XE=i3a_y-9Z%Drk>{P`o{{IWbm_<9F)vdeg~!}1huok_ zirCw{WG$V<=UmP`_s(VK(vP}hj;24}9^93G53RUM(U~0`DIgeLmj+J>3;!PalmdYH z6lZMCqTME6_)SN?(A34*Y|cPNWZchoo{_hE7OycJ%V5KCc-JNAw`omIeSY4kpZDJA zMigZMsnv~q=}u>u}Y{Tn>vz?c;_@1D%>MzqxsZQ=N07>b6I z$Be`TV6k{oWN{enkK`3Yl=0M7{Bz-(^U| z8L>CS`@I1tP9b2J@fEdgtvQWz%#NZ?%u}&n6i>w!d*OoQ(CDu>7P4c3B+Gx!ov?K88sG9 zh;%u{98r3ZLm|SH6ySaHX-+Fe(CT(aB~}m(M^?EhehG){8dqc9=-a&7<>H*bEXtGBdjnY&JrzJDa}bdWGk9@39&y(D(tuH89#Z@PTUA3f$#dnBYUZ`m_AF! z)#V#G88avg?!XUnWbrT>_{lS9qdY7OZYphRaYRq58AI|QaXl)u4?o$t(CAB#aN^RV z;hql_hOLu%^%>At9hUPXb&ZxJtVnUYqDiH&*iej8jF?6Q7 zIrLvq&?p-{!P~aHftSzj3G%XgJj}+c5sm7T&EwjS$z4V?Q=&Wj zn3<&T)ry{XrtGrz9kW#}iQ^vQz)iL^RdyAC=d0dUYCC($gV5y{rByf!vpd+DWurNq zeWx3n>nrDH=$#>!it>|U*y>i{C9QJU>SYlXH3V-#9vK_CCeljIoY$GhXS9 zt*0sS(N_=DFOOF?&r}vsbmC^}iyMWtMKk1mGQC&@`9=33N5-}@=X&N5Zy4Zp)p+!~ z;!wP5=86$LBp%Jg(&5C$^$l%P%4h0OIc{QInvT%TFp+4pX=4Kw*Inuu-;R!5Id17F zb98hXWQ-FDMTe(_$40!zQU2OMxT5jL9SMHaThtzB5Niw9C2|+b z#K23umoRoLa2;m=-f$1h=L#NU$i@Rmd;>f~lOim>@fj|WD2Qk)Zb|5ymMRQw>#mrR zF08$uLArc1JXsN)UXeN~!8OqlVe{9_UJ}j$|F0Mk7Pt#@Fc~x~T+$dD_R<7NBaU*A zKQc8(XbApymhL%wdtrV2|07Rt{^?xO;_@lE!sE0D+T&76YH+smh}6%MGg`+^k5Qj=b}1 zYA-Sc7u6tv?qN!KnAD4da}`@76WY&cB)W)Y+}S#F?xrs<84<3TIHe{hGHpo> zF+EkWNhAY2u-vMX8YBc9uvTz|5WVW;BDjBGVEzRWh3}K!qI;;ii9zn_izIRBLW#EA z>Z40V@P6A9={1hZWggHmy~Ykj)7OCl9Iyrc$rTKD#f1R#l$hzIlNY|s?usrS z{w{Rp+6ZmCAIfLSi4YwG%2oVb?N1G}ybf@9^^P9rUq%1O0fYuV!wSzqhKB1q!iK74 zVH%F_St~@RN?^>1>P*i}$EOB~MksV)7+`ePYRNb=p3$3xb&~={1HZ#zb~tiWCAa!Q zdAsP?(Z%6;27V$!Y1@b#E{B)sM(`84t^>BF8o24E<}0R#u}|$D1gn`o3TZT8%?X=W z)20|BZlHKHc+7&gj6>@dPX%+zqK@}M=#)j^TRa`ck6S229D}c#%DaS>S=&)`4N*-~ zXCJi@UiswtMt=K*yPmS#!f__V${kO6YAc5mgJ~8lK0Y!6 zZ)5qx1TF+85P}w-mz(}(r|EgZ_hU!B&&eBcpVO2~3Ld%R*oXKUr`MwHYs{Vj$Dj0} z`zA(@z} z3zsL2xeL7yhMSI`W3ZTb{-~gHQOZnI#N$Xke3)ZYLLv83j7-OOIwdgmi;&l|fGfQj zi)<=zY`6(cU^V`b!N4hR8Zuoo-!7XiO-xHzy(Q)mo?fo7S(Q=) z{}JJ#{<^jPHbv4_juk7mwG@xO&+FK6l1>TEiQ~zs$?@dMPLaZDG+U*q^H=5$RIM#c zR&iJ}`ylG<7hFz=cZ{&-a;>f`lhY2gC zYq;(}OZT-3PX&6rA+XRoD|KlZeSKyoxFuAArAWMMY2ya}+*%b&0{uIcthhaip<-vK z?h4K*+R+I{^CY(bg{o+C3)u4Pp`F7;my1m~4Xb?hJXoMM@PXYfGsXbrk%hZByM}Y; zC9`C}*UKc8mBHBIeY9`yBg!VDth=ve-uoQ!KWvvO2RODi~leN2-D z(v(8T2t7xl91)^>(-4d=6h~T^q(c6Dxo=4p6C(xStyu%6Jv`{wo))EVZ1mD?77IBP zt>#~4p{i_S?K4n}R)6ufXEO7FHV8z*qqh-_94lFm409aZWFXs4(2l1>@oVU4_B zu6c?>g$%v?IhT5j5HS#TdJxMn2GX4xS%sb>M4ar6G_JfDcwnhxe}@g# zHBCTN)-mN&eG9yl#=;bQIG9EL+!z}`N`1?9)D3!z6?4SzgAk);h9`2~ z0Np6Au+?XUd*nPzHe-7*J0qXev;2I{E8ZzpWCg9|%_!D`QFnCAj$wM~qq7A3n>pAW z0F2skLLa#J2@-up;B|4C)mD{WwQN@ygeN7|;lh-L3x0QoT&p&*sJdGar5bP^)sjUr z$C;pHw6EYmCvqZBz-7%yfg}@8yd{rsF+jwYC8$QKi`|HqmjVsqQmd&nt#Iz7r`$+^ zF*7P#+cV@U1?O}d&e$x%nQypuaqX?g;F*E}odkYIZU@G#E@IZtd8@@_QnooX1cRfg z4B6lY!PWL=u#dBrcGQtPDw_0v1?KK|wV;I+%lQgOpO+|tQf`{j%4&$B7p!%7^%HN!SDVk576i7Z~)$AXkE+ zi-~Ba^uu*Dv$NFVpF8y`icaV9O|AlWuo=DjtKE@ohM0(1vC`^|015xcBxQm*JZ!XGDYx_=J65k zHhZQwmPgk$q-vb2^$5;&dIEmLjpgI^Eal=Vw1l)O=$kSZWH(8`UM80n8~qMFeDQ4* zYjL^HoPWTZX<@Dyrk@Gjoris(FVGs};MPeGJ6MG*iA2IJ>MoQZg%!Xy=A;jEetN-% z!LBU*V0r7-;-YP>bGMWUNh(*S0P&*=-akfts+R?2IXh~yEy`B}cv)Y$+hnkntgS3t zRg}}6Pt~C6?)0;gE0e|9m5-N-uSgcL>p7xO1KwlT7V28!GHmni#e2XdL`_&$N-zce zQIfa13G4{&#bwqP3)d}+%9N-n|KgQ`C*gideGNK@e{okBgSh^B_wYmx@f{P@%TXD2 zBbQfPxqB(f6;*~#QAa7-4SzF)u_qBh^<$U_o!pZRO)|2+8vEaNTO5xB7?+oXAw&oK2Cw|ch= zkaOlPVcCn>8kcsh&6|O0d9R{TCGVxBqQj{v!Snk|*ebK&N`%Jm58kXujiGiAID*@Q zd4`P$t-?VrMQ0ht%9nyx2`cPH=AOmuPNk+Nzj|9u>83i1OeA-yUlRf_tJnz98FW5b zIvG@@xz4LszARv`UX)1Ca8IF3-+Q>LCu3^N9)RI_s7U{rkiNZHIBqhdgk!us<&q$fUbbx2S6 zsJ#}|@-adm*+&#bMsZkv=nL0$@q*v6JVM`V+aFD9%*^gmSMOry#ja{~S9Vw7=)=5D zdWq^KL79&(L6aS%)p)FmvjTe6_^e+kmFv`%?3^f5X)>Wfdr5Lda%y%ZpPlOum5L81 zi}TTp$KDG;ev7QHpQs7n73Xpwmf$-Ig+>u)FMOgU<|NDc1k5?CA6i*bwUK3{X{|c9 zCEGG9zASK@Tm$b^Ts9QYg_$iezRqI&hQ)$HmX~aYsv=(i0KQ!@+)68OS^};Ackxpp zKbdHkzYg((k6lm2QxuN4*^{8orgq%@{5i1k>dgZ^{;EAJSM@`hg1J8D?3loOa<$sJ zZrRlVAv-*`d0`4(s#XO4gxO=bTKoc--y~nLJF|*qEX%6)=L;CNW>r;aRAiFCUA)`iEk!jA@g=^B#=s3> zqk{a*LX#bjggr6W!mJ@RI};7|h&2RdW0;I_5m7}n&Ctt?m@4A&DlZf1U+F3IZ*JA3 zn_VV7<6s&LW|uibyQ8FXh-GL`wXE7$+AiT~TSg1`hKpn2%=F1uO>i;IIhiKpVz&EO z7ArEOIhm;V%c(Ht@T&hW#2s84!go^)GiMEbn}HwjFJ`-G(~)?-R&Fv(#j3ci#4%T9 zzE~s}qklw5cm~huiu4I~t`RFH=Q%USXplErMn-VhFkx`9C3GW8Sj<^5k>Abx0nWQD zWCg1t{cf%txR+i}aK0l93b{_MMt3p{RxFoQ3}Q!Uqe@%7Se70y2sDt}wWh&6(ET20 zePmcsXmBeeGY(Aks?{jhF$ z`Er(#jx9>JIk1ZNIoc!+%;l2L^{yrJ2XZoVr+q&D2;XzJiNi;&O87m*XP(Baum%{;|6d{T`w? zyppIE{C|gszVc6B1I=P;?#2OlgYm)soJ>&~^*Cf?UEk#s87cKCODG%^;8BZi^~Vzn>Efv4>B6f3{R3AQd2c}Oy+mpF zndPaOoFR_vjd1K3m$j*|Vi6Fr2u`A-!f^ckJ*vuJCA^V2-Uy~}6)?z2*!I%*ob+z& zG6aq|(C?)m<`eV}bnFlLwYvhnc!Mb{w`(*6$z{&DiysWqh0Yk=fU5#VKV=k27&>2M zKs#Vu;;3ToDI=Nt!i?tj z)b^GuyGae~(0E>%w}d0cop87Hs*iIkIoV`-4yHIftt?IDN;G3Ujl4eWPUPPpx>ulT zb~&UHN5fx+wLi$T<0$8IoPB22!%}R+Cg&2kal8ZYG9M*8;C+q)or>Wiu#__--v$yN zRCmI7hfW3G!C1$la^onc6Z4D1oT9Z=NwdazrN2|cXoo({ggTO&P>_?3hf09Fwo?pe zXdj>y<^|h0c6drYLQ8uXfN*lQ1gE(EHJ3HP%NP9*)ox?`?VZ%qL2sLO!8PBaaM_J9Ou?bxQO{F2aSi5IR+NHVC07n+T|~< zpSNt%G5a?&WG@N+g9eSB%VB2l;l0T_yCTQz`${H26^p%a(B_2Cu4B;Bnh6(CNK}VM zrqMXy0JPQExunJ^=gzWY!OQ+*2FAIdNOa48U^&<)634{SFFY8e-I}F}y!T%t8|MSZ zq~BFYRf6DJk%>9M=v6=DBpZ2U^CJ-2Q}M%f0YErBS*wof5^xw5`olb&Sz+92EFm}N z!YQy11CzJ$%CM(!F*U@0RNqIX;0gfy3s43jIC8ijlo=kQKLX`pM^-Z|MxW{EGJ^}E z5AGvfcfIf`*l^9pL3nMZV35P|ETv^#-!*|MaCzqJ82V*!xmRUWOVz5tdqGZdfZkPu zJfcEHdXzEF7tsG!NYj;OjTWuc@76NjLK-u6OcF z1`c!0siH2phZk6Y*_e7WkLz=9L&%tIt`&>Iq|bXRbk@s11CIkwpUGV7w}MD>z;ysW z2^j7x>}Jx)c5p`!YW@e#K&+K><^a|fM)M<-oy~#puZC8@LS&+|I8pWL0jmBxd8_)~({=zEY6%wd2K zMh0>9YH-4y<8qENZDo)`?>!7rLWwtz{)szvExp{G#!5UtR@^&6pZDiF?!7nPWxfNG zjUtGv(Jc^6{-$;#fJE*gK!4^r!J2fPl4bXp`vQ93BadKepa zqV9gpPlWNsA&9yw&vz6h#9px^I%>sXQR|QIlj%8?GHm)qOCoWdZzH=IhK9goa_Jpc>K#PngUI!!!9B!y+k}FVSxd^E3YV`PUeR>%D?$6T*N1IgVsuVia9Y-QR;+NiCSE0m z)|y#r$aOii+4G71s5gntoZXqxx&k*?xx+uKtI#wVQC0j@9`Cl?rlZ_wt@2IOTh)VRMDXF0NvymWee`9u^ zIJC`>I4%elk@&X`2!tJ|Ub9UoD2*oX>^(XC#p(>162xCj=Knkng8r zwRY6SSKe`q3xVCxV2wUCGBR>_OyNBOW6Lebizo{_{W3#i;EObTdUPbFX-^{sDUG5V z&aHEEGs{PJ^K!zL?6xF9lIfoD(=q_n3cL$h^Jyvt8nb6Inj1dy||=~4OGoM}$0GUtsh<2}Coxyb5)mK>7giNw*kTP72UnR0@Nr|
WO*@d$~-nR+Sm4%9_QJHTWEWvrGP2a4iH#eC;2JHTzxu0bu?*Fs?Z zn9}>mZzoo`n-PIHX&R;49sj=0GwH+in{G)+$}$V>Vg-W zwX6)5xZAtd6qRs;o^ray3c+}7vw@|-`^|)FaD|?5FZF-s#~roQop2448LnHav23e6 z_`vK$*OZ*jju}0~<#g_HkkFKOJ^4QU69NF|S2VKuI8RolYxjEd^vp-U@__(oujM;* zOIO4`%S>kxX9I@1EwtU@>nf=2qXKWaRnt=);1Z3hyovf6rluQLh)h8zmGZbcHx0GuYgkDe zehP;1i|o;syp+ZQi6pRqucm(r!}4cEBhTp*G;?okBLpRo!g``@<|zJ|(9Wp^^JsJ| zf6HJ>tTKHPe$vtcU4o`*?mX+NlcY_~B8%w9(R2>v5$yzVGfOjLM~uOIQE6Ot~5zX~$OQmSDAsovngZZTuk5NXrGI~n)L&! zc``3zr^J&r{d|ayh2!qS|Il?BZkoW%l~OC>Ka!-k3aR5gxBgXKs=*?myrx@{~+9c}H~uK>rZ!l;qU>aEiC% zG1`HvJaT9MjOdTdM(}sw(;`A$MpValuf0(!P98nOKMYe8s5)x!(8!))QASjnjfNzT z9^=0pd2G&tND^ou)txiWFwe|2=3eE-Upq;nd9xpI8@MCW;#IcT(8X>SU4qOhv&|*z zYf(!izh0>n-|~h%f{TdLzUjwj=4?(egu;uQA-puU@#tRg&WedTx-;iLa?r7^>QL-o zap@LP61DIPU&mg;y(}B>jH+ndiRb$3yakJ3I{xBEeAmPqcKw6pDnm3bGIN~1iMQ=i zO!Om+L3!&%#LB57pzw^Z4k`I1tq1O8E}tJn3ym6g^ta^wObaEjgt~2q-@mgH!ULud zgrQPeyCu`>vDZ;LRMd|jutkFT8cdLGct{%d-=aWsK+R$h$?h8pCuYIZdXj6lf^y~ zY(ABDD~<-I&+pHGr7)+kck(=|Dk)XzG)FR*TJ6g;+U6FI?&6)CJnx#SPA#xUV=vu; z60tao{tCXqvmi3#AC6(im`xvKGHR8jS8&eX*`_Y)Yui>-xOrZ|VrAJZGqQc(oAz{*w@S`AD=%+KwbIRd>aS`AO$T8vTmT?#^-=QVnaA;NiU znJ8&pm11E5OKI6Mg(5BR3U4ak>+A*!*mT;S_QutZ&)N+5g2@cUnqFs-x&@HKD)67#Y(cGyhU}kUVX&>1V zeP%A%pQy9euF20^Q(xn=wigGkrf%MG@-3Y_Dak0cc-&^EG|H6hX`NlPrkoM6otb?{ zq$#pgk;i1p)-d;Z!9Cr7LBHC_R>4mZrG{_lx?Lf~!E_@VI!)w+*<`qk(4_AR5!`)X z{h=%FhZo?4uUWZS>#CWp^B#YT%YI$?Jkl zwthp++ENN)?MnPj7S=`mz)4>#ncg)4ZGRBOjPr*O=_0 z+ivp)uOesU9Y+xSc?c;1anup3n=y*61gkkRDkEW4#u(;Y&TD@P9Ze`6RQ!A2yRYXJ z`uZ!YR^}M&{mBRB10}5@|9Zvn%CZRv1Qf3z`q`Pgc;?j4zyrX86t?b9&QvUN0^r#+H*;2DL~Ara zCm=&6oVVFuGElTLi>I9%_$Re~Y99M!tD3pqK%}FHBUTDp;5U&4*5V2+A}#mA2;+1% zmw?X%S!L{R)-qq4v&>hv>-AR(OIV9*aGV^sxFFt6TGOR!t5t)HZ$gE$C980OSiLgs zm~l}dYj9ol_K?Aq*rCAV)P2N9$Vh)IF`4BR1iV5T^Tw}Kl3WuoN5$&N${|7 zve)M`M%1Bunu9i&6(2$yly;}(H8Ayw_$?Pt{z=xB1Gm@%Umdo^g0r4%aBv!sK}oKq zYG)Iy>jaJ(EpRuT{-q+Fx3kn&)Dl`f5q|1dGv!Q(;o1KiXF3D<=;5N=08mgkb z|LV8LzUs;5?ANx{8CZ%wS>~jQ!7WEsQidLUCi5hu!bZ4>vap-H@YL6;HIq|Duv8Ju z@q7`KG&Wv3Or_vt=i{D!|8l=SH;-PIU6GgN^gUF%ZSK-*6)eeuXD)UiimAP2f!FEb z_5NI;-8fo@=x5fKz7qH9c_N*O;lyjJUtbjDg#IsLg#K?uF;LdD*E`DNr0NZrEtJ8y zi#H3O&2fiIS18dMwOXhvGnKJ_&C_*&SAS+zr*;}iZ&F`1FmTw~HmS7f^Sl&Xiy7^T zbLbLso!cn1xe;waHRfDoNZwqM@5wECDF5EHDqGQ_Oqh;M&u>C>s_(n=mmBKotiRQy zQ!ha}ueaE88@OV)~cL43d%MaA>a{BgoI7N>x^9$;*l6NG*n$swkAQgtFSJ=4x*w z;esD1Jq)NVYGN6OAr-a>{>N9)gVf8l~k_{ z@pdC(ZJ?qEBp0{VI?LnI)%_8CB2>ujNd89RC@%x92PEkX+J7FCdzGL%O16nL4mtda zBp%MS0$7zUcAQzadDy>DuIlhKu7O4`=HmCS0{LnMT%PHNEU_=SJuJ@VoBmxe;4$Ix z*tPpV8ETa@S0&w1lH(7K!wFm)oyokE6GWtsGYwVYcrR>5PB75Hz1K3(#XoW>6+CjG zF-R%-Mi5DO@v9KchfA@;6P5J;1f8Hx%mbFC4b^6p5Gukn&cXC@v@!dNs|r<%@)+89 zd821v18dP9BHbRM=nZ$BIWt5C+Bw|BdHdLx=5H8ll=40P~e0$mV`8d6%+TgigLB=oW9q#ZQE0F36Ek((}taqG_GP?ML(EfeZ71FmJAx_L1wtPflFyc6*cz zGvKYrBNP<{GM1T#G-0K(GyE)L+)CN-%U(2ZGEmJ!4o_i<>y0RY9W=Ikaaq%ng-G7l zjIJ8X(gSyJR@1-|`(kib7v&dV6}UI9*kcIIV`w!QabtSqXeM!Qyop=@u!9(Vwc^Qx zRYD6I5mDCBUw$oLkk1qe{p1Qn54bu!saKY7V?}nRrn}}Nq8mEV+fdi17Q{ND{AxU@A#iy z{Arkj4Uo6}IqWWn)yX*DyTeeqznU4pIGXsM`HhGy3ab7W zhH-!)UR5(Qj`^s9J%gI};R^Q4!*?XLmoU0qW_dU(&XmTR?1Bnm1G{J0=K;W=)f*-q zZ{dOq1LN#dHRhaFW`(PF0-bD2Clq{mlEj(`g2y9pnYXw5!^T75v`nd=`_QHcO%}G~0h3fytjf0+7&X2CG zp4(B~UzR@J2&51C95cS11O6U)5eH?DynKU8Bk!KjWgAo7u>ncs+^Ioe3O_~nw&p~~ znNBZ9rkMVx9DpfBpNSyvFR-xwUy}YPgr5lgc z_mG>iiRh$D<|%|tj>?;wJ8QllzmI#*y(!U{jl78a!udJB9>1WPdNg<~_xNqx8wZzi z+5e?K*At0P_PA`^o2j|y_8?k$6LV{S#J$clFtkE84dup`R?Dpn6UEXVfY{`>hAT7Z z?xdF{6o#RqOsy~1*ee-Zi@nl$C?^@Y!-a{Qe&(ygceuuD!$euQdf~z~ob--nv3Jsn z<8jfgfl|piz=VkExbodul%I1EdEu3QrWf`kMSpl_ zL#XH|bL_p*e1XoQgjjICRuu$n;F8_Y?Gn*W#MlIYe1xor!6Az$uk5 znDE*lOc+EOLH_R1%A_yzTfOuk`N$*?;pACSInagbPT(lV4Jpqga#3v8!JT_EXFxq! zs)fUk&^_TAvu7j1nUV_!k^to{^wKNHk{K1M5T!)r5nWIgQM>}r9bV{ehMC(L_Qx>J zcu_7L!-JE|UNT1ii!2FVGZyuBF-$J^GBNB!+>5Z1^Jaz@o8HssVJ{zFHS^=76*i*S z_$Qe<8yk|IQ!mMxLACrybC2q5Fd?>e1s(z3{b;U31kWYU^vHz4{m9uX@AHuK^AXeh zOdv7oaap&YskI>iPlbDUg_Fd;_N=f{8(3><(CS}6lt!(~IqeV-!5{(GrKstEuvO+B zzef!6tztlY2;^7W$gNDlLmc%WpR54aox*Fwj5s17Bj`uWn0~?<(Sz2Aj!nt`&`iS8 znu~8H{D>~yI>9hTl|@@ES}LQmM6ZLFa3QuXa8Hzssj2G`N2L+_R9N28RSInwYC}VW z_YK|D_49Ab?CMz#1XhDZUsRu2Z)v~2)8o<`TkCJ6*HU-TpV+rvNX>w;!m4dfy*L+= zozm|eZcmCyPfN>aEce!E!FH*Ttq0cuh?;lW?)@D5z8M&;~0V*x+j@5aH1$|u2uU|b+)F;xLJImI9-&OoZ6F` zl$4q-iV?)bRyEe;l&V33B(cJ?U}b*X9ME2hMa<`)Fhp0K}*OUG;AIxonERC zks>*eOC<8(&f0w_2bYa}l(1YQzW8E_lS@%*V5qou;l2(SZ!RpBx4Vk_WqfIWanYdP zKTy1MtpRuE<(yLg2^0<0l=b_-6{J;f%Dnd*g{E&) z3WY?ZWU#Ah%0T>+`hlQ`t-ww&b7?;ukso<+#2olO)U{CS#V^~rsHbxw|8`Q8nkwE& z<#ude)1y>tHLV26{1tGA=!7FS6`?zG`%4SE-Q?wz*JKWPa;g^eWv>vIFz#DqfLyl}A zuO;mUlVk7p7e&%^v9)vaq9%P#%0qXNTDeqSWy+{n);~9&egl+c4|f!>0u?EE(p5`k zCa=9_1ld{_4tik))NV+Bpfu`#mq2&=3-YeBMfC zj{S=Os67DN^{^EZ#>yM9#?c+5I`|A2xVIDBL5ednI~W~OI$9pvcIcX-Y1Mu zqt*E5vf89`maVHR+jD)F#zc_Jdq^iw#P0qPoZ*@3T>{SSKH$+-JGhoKYYjH;oBiT> z{$wN;xtJ$%w78REqp^S~uTJm#Z z9rX{WAqrL|#N%T>5dgK{Lj99~W-}Sfgk5YUS_i3xL@G#zu*x=Y6Ddhgm!^^r>K!h- z&r{k~V~nY-qW;-k4;NLfTBg?Xa^1<-fn=Z8S4)tn=NG5|I%hLw-(03U`@mLUv*;aZ z6n;<9yefS{dp!?xOa*%9CeG4%GW7HmWfhz() z?T2A|6ncz^Aawsx=qHA@!Uk|T;yaOlv)rmTdviUWEQeC*aheKqY8q?ZaW$pmB9Lif zlhPA;!@SfqmpyJ+441ePf<*6q0ln8V;mzX7-^`WD{3Tc_@v|eTsBWls&2Fy{D1!o8 z+RO+j%Oq0CxYUSh+p^2KavEc*e?EtFLImZcB^02Vl^6K$*iZQLKT`k1pHt)t=5w~4 zPYyf5yJYpT86OoFWIA&v84=X@aBPcZ zo;wMjI{|;k&k@@|3tCrTtVO|C3!&tgxO;+gHf5Nr1|MbY`s2WSMe3YnsZ^d$-y;^M zN*)1g`>K~`_ra*@eX4`LiZm7bUY)m;e+?yp>e7|2gw|RZ+p{irssD?@Jh*6MDw3J~ z6HEmTo3z^LUZ1mh`vaMdA0ytYqF-a)yLDiGo7p+ZJLwzAcI2;dqBZTf9~yik3>AWl z7IN3Z50U~Y6TNKQa?+?)T1&DwZrL|nxv2`=0elX#qxGtrY^FjK7?6FTqk`MJH5QZB zYFWNy@qlYtwHXEyg`3uR+hyh|Hn3rR=LZpW#av&KqxqqN%fH*P1dD=JevOtN%6y!F)47=_G&WqzF6`9plxya`x;^+sco#eM{6+#|2en78_ zdLRkDnTd)B&LI=>16`)UZ1Wa&UsjMqf3=r$w8U`_nAHKYXqOI@@}=-tNs~sVk|kW3 z)V-{5zIgaZKleCEi?s#30N0Wx@_t=Lj+PQxnG+>wH2+4PK{;gZ*|=yC&kVzzy_b=z zN@a4r3~p^?RrN1wOV-UP^mX-=tS(vo$Wk`A`2(#ZUu&XY!NJXeHR-7maomd8Rdr?c zWNPA)*0TB5O}zS%er_OxD-}_4==o$Yt1q64Xe%?c`a+MF)ZN|wxU1D&yIjx-m)K5z z$DONr$!#|*Oq!iL*V0nQE~%YYGz5EW=cN$ooE{@Otbcs|os$4i~Mw@oiDKDBSd>TS5U?xzp&Qd^JpBquEFX>MeDTM+8) z7tq^~g!MMw8Ppx}wzrp@I&#^C*{Cn!XTRo&+Kw$rN?6=;g6-+*yD^tM9#2e&nVwKb z5R)F(5heb|Df-=OjtJR~{`6O#_{_~o31^#H*nY0PE7(sVPl71ovd8VH;=iZve)P@} z+|j=-@+4<&ON?LI+k}0p>+cNqvCbmQVM*2No`sw@TfY_=oo3<*K?XmCj8cZKw z%gexhhLkppTb-Ln0PPci2z~e42jMyg8uo;FHU~d;jI% zEW-Wn2X;X4pNY(4nir1h2fJitSer%Tt88h{&onPff3LT{5(zDojc=a&0CVGuko{e4_{G% z`xaVwTJ9*qzEu}(*6>C z@*wX0Vek+*%rmv$e|ZexEnML;1bg4i^iC4JWB&z} zWxI=t+~n7^7W^)dl54Z&<=L!x%wJnbKR8Y?r|X3Tks{O@)$re&@dsvuH3|D?Q<|^f zfABe!&)SP{=1TY$hH$v&kN$bw=$~7N{)yCDX6H10!_D%izwAW|Bzg3wQ*gWaJu($mK;_=4G!v!h4@*pTn>1sjS#klfCYc@B^MH zLr}B0jK0S0-ltT^j`rk%=D9KJmilJz<$+X7M@`XUH?O%xIMkP!xMvnAvbI*h6!h9z zHu`!+nn)J6k>C^QWB;c7!BLeP8j2I@?d(P1w2tIj>QPhC*DwNdT&ERPftTb zFZmdK;03UqzTOP|+Ek!`?cLq5eZM6|B1s|F&!6AgI)A~udjf^zYby%!6>^1wzMW}Y zu%I7$4}867?Q8h&g_I`zt_9 z|MeAWAN|hrFVgQUPW~EnfcCFb;MjN_4MTTcRrA+~{y?YB^r0)k^FfXhFG2k!YVS=Ro z%|!2n4$jdS;x(pEF=uuz#S?SZ_>2T&Ka3TD=c#9yegV`g@I3v~iy)4A=Hg|%t;|d` z5`4|=z8FDH4GP!Q6XF+ax%WR%~ zcTtab>rRtRr!eSF0I6B2G%FZsx#5??MwfgZ;7&q0Z%+yYTLbqe4Gpi)Ied7_ zUEnEt?#V4%!1nhcwO#OUmXe-dd=#F$ z38fWq#usc?DV=(dTJPxHSh&9NmaTiPUcXuRRFB5Ue%L2n@d+D*AgzDEeq8o}J>0xpie0|5Os_ybuKI7^!DhZ^S|`+@8te?U}a z!Li~-NcR8*`nOY;Wz(`ud%<16S$w(3rqsaXO4fyTbrpS?OMs zm$%66X_QFk7uF7Vy#uw|a?Y7FuxE|dNdMVx)H$6xg9A#*45gGq{+X4Mmw5-G0FxCO z6EDZK(SEx+wc6gh*}tywrY-BQY+9Sod%D+T)6GzlYH~aEB}7wmEFJn^wZxmx@RM{kt<0byS4&2TbO_3%D`)6A^hh%b&CG!i6}R86(~^vWwgy+USx`dieG2+}o1{sd>C7Se?V0~*=!ZCR~>iG8`N{`Lb~ zm+~JGRF_xF(`E8!N#F3?twAT?r{NU~2FRK>lqRWCEh}7>AD}|!2hvRcl`o`$P`PCo~dP=*Ppqc-!#g#l0_sqUYkWHByf@Tbtq0QbmLBkMuvZw4|`GByX@X zJ-u~b&FW=o2_3?O43Vv~Xz|qzo8R7b;yG|Tx#NrDFMyP5X|+vOl;yO`inAa$v!M9? zMxKT8k7ca6Pz&5ZOBsdW-xm!32f!Zy@m@!L-TL+9*+3DP_4U{220r*Vd*R>ACd7mS z%Ui2X!smHev1_%-Y}(UJ=G5#Mrtb!GS8Xrx(o1!Q+NCcTb!*pwh24eo`^mFC9sYT9 z{7PjJy`@N{*$YQo1$Fv;@=Zd@*uu$+q^UaYSaINV#s?{7w(^#ia$8x-2N|aithl2C z{NnBfN46R*JuNN07UR|<3+`S?kcjG+$+M8pl;F4_s*_o>n&bvA-9LZ9{cGsI07=!7 zCGF+qq z;G?1slJZTpZ3{Y<+s=bElCH};2JY@+xZX1)Q}nbf=w5W>rJN;2kZ(-GV=TQOiFrR{ z75(H)w<=_MS?$?pb2{naYoZc1K>3%|`@;5~=VeS7K= z#Lq!`JGh+Q0y~CSj^H?)XU9RU1qSm%|M_qx`vP^&W1Q{|#WiM_>N)R#v9#?K||kbMhb zCCIuL&OHZbU*JX6)&R9+d5+(o z18$<1_g+y^arqK(6YPNp-|`LY0s0P7(hb$}<2z2g|HH)};p03oilz?%kUphj?S;?4 z|3lS<|L3JY@~_^d|9a@dxkI0D)+F+)Y! zSQ`2E*vIG%jMwmXV2kCYmzYmt$qvAy8c=)yQwe}~f&A>?lA}DS z@L21{ml;o5(dx3iR>`?@lD6Ek)kWZFz7_cZ`CxcorNh`5c(2jusNCP-^%wfQMSdTe z$s=h}d8{e(wxyjvFKLaGhusK>fGk`fxc_EIZyLJ?uNEUZXOm$z z%gBZbWHUuy#j|U(MDHimt*e-~x2Ae;>%2YHZ)WQBP63FKIPJE)1=*1B&b^i8yW1=# zcyxdOXf;|+iHKDA9p{SJ4JZ-2Ljaa{o-Zuiy*Vvm)@+r6>;zZS>%i4_^H;40_XD|# zp_2YP(h3D*p$McAXwa~&@_0Bnv9J*=Zj+oV*xkGD*0{5ROhccf4G-wOLD7&ojG}zh zw7Y)WN~vPF8p)?)U*%u0h=Oa=Hgt}k@uVOFtmQ_lCF8ZmtUc$l*j(q%Wpw3{-o0z+ zXMsJ_=gXu&fZ7o-IN_h8su>BC6J=irZgxuoyIGF?+TL^IvRsz1-0Z-6WEO*af>-&2 zc=VUz@V`t+WkOA43j1*fOFpi$q>DMd1o}R@KUG2wVlECrE|`^`)pcZ^ZoK8(xm*7B zyDz`_1`@mWGx{6)FXKMOR~#SXtAGst&aUwPCB1}Zf;6~d5rwLoQoFaFb6Ksfb6Hj- zp?O|^uS~HdpY-k-V&r6Zx$N`@!S7^NtiESU*8Lg`e=3gY^vuTU!q{G#qL*<@ih{Z?;(o)fnmlJJBC3%*!n-%*`ugEC~H0 zv>-XrEC`})5(_dfjcY+-9c;%ABYhuL*ch@P4ArpzVaRtPA;U8s8Nj3{^Sxqy`4aEB zbN&V8>&wB>BBQa$Z!#8vmHTV`xudUv#+vGV^YZfxb8~YGutdQr*mFFh8||8-#R13{ zdws=z=xB}Rz3=k>L}v9fYax{095RRX38r=mLO#K7H&yUn;+a)xGKZ(IDbKUAcFnHX zQ+&NLE#2WRY$?cDSuJ#T<;WDGL{Vydf~+jhJvVbzr&I}7bx~Y`s5>Ahx z%Rp{ApWd0fWbJEii`7MD1>S>tvUdnn(jPF21DH3%)s@@>dl0}kr??ph0935})vG_A zeg9do1x-l+$B3Xdl35X60=4m)&l+1kz52DHdB1A+GyQ{B`e8DQz6xxhuLK(j_HW5` zWLAWiFtV)qljmRiY+1`EFTZ}|2+)GrM~=XKg>RW`+C};&@+kZpA@W@S{G*RHt^0(& z^`k@Iz|LO<{?T(lOQtjVJoxyR@W~j~H}{~xtA=krsu3Mr%06k#kB4 z8`!j&ZMaS2g(kS$+KsxbWC2RcdP|e zl76C!JPI|yTTHxya+6~ZlbK`-v-awk7vK#8#1P&l2*omuCc$aJrp~t2+qbW7>)a$b zJeL><k8IZ~|JGCKx6Qu-I@Z4fPw&gxyMO=QtbHJs z{uo#o9#)QR1`f)L_mH5yO@Ugu@;vh&<)s$}z6STgr!vMeNH6(+Yz=i?DD{giqk&b$ z2>IfJ2tosw{luKX+Lc=cuTh4?6lp=x%}!5IcuQTg(|bgtlFKz3nZCu_nz?4aKP5R; zsZ~@BXEulnxJ`21{JhL+X|q8tH!%Mgj$+AGU>6mSbLGzUfcipjK#hqPUcdl4* zM^|81<-V@Y{gsvbJK@)|-2Rf5jS2S(GDLE69{LWqOm3Z*NYhSiA=Thxf)C}1Go^0y zbyrKvlk?^kqOV&X!~YS;7C%6~4_+kr>{-}W9QBKB8!jFhPaEM+_4 z;btybjY?*$9Y^-bY}H1%gfoLF#6dqPcyRIJ2iL4Qxp?u(HH)vRtGjA(_m#}or|tHo z2fO%NPd7LHHq$9d%Ou|k$#vyD3jzamSIl2fbm$s0`Mlxjl~mboIS+|Z)Nk6-c1{Oiu-&Z-I$(XGE39- zH<^g#q=DRk_JT#sGUg7g|KQ-AG2hC_53HyJ+1*dxmi95ECPO<6-*QJ=w`3@_OFV)`o_H3h@5g)zxyiUF2^l zwQ0Qy=Do9__6)&Zv>`5p=!hnFk|UR!?OfcxptilrY?xo))6PFmiDKi`sx-Ao46Y*g z*5x}3XH&5zWtOMJpOG+I?o&wQ6C+=t#|I4R#Pk& z=9}o-miGL+uTrZUH>mOo3iFnWMElXWrh*>gYw{JeM}X#K>igG|O>5~p{z;&@y8t{( zo@c%FWR6XVn7Z!nqM~khHvGES4H7gNu;6iehL)_D>u}7?&YtIV&db(7z@tW|)4+aR zaON6OZM`5Nj~iTl(t zo${kL0JDm_*~ZF;oV&A|V_+$XLDfv2v0kONcq-6J#2h`wG*B zb~xZpxrRKA_N+c2z9VjkY^MZa?JtDd&lB%)+K-3Y-yv@2w4Vs|e}Q<4)BaWH`CkzK zB5oi^W^PhyPfgb=4}k zr$GM}*ys-#u2l3t&>o3~d;_4a9?UjfcPCMq7+x`M>XSf~Yw4cE3 z3|B3vUCPjm`gsBOpA^}S`bX_!7hroH(?4!MKlUAJ{{ptRGX3LzE{uJQq{BooucFMe zl)FmYS$+T!t(_8Z+YvvnVtIYRX+O@iLZv%| z+7LDz#(RXshwPcoC`9v+yxHP_I~1E2x!3eroNy;#%Odycz+Y0o(Yx#0L3!%ehOD{{ z65jPv1-C3pa)+|E!yguw5* zte)evpTO;mOzuGK$lFH!yo3Ash`52XbCN)a$9GPk6>&vwoxHYW_Z4{OMAu&kHz{}S z?8iGN0A*+YK>h>Do*=O3xS0o|#}`W5K>s{Dc*Iab-dyclUa@kByoX9p7Kx>r>*u5- z>J&;dICsO<%|pJ*LNK(nHg|z%eV;^}o+6efH#fw_D^lb}i-ArBZydYc)ncD((=akb z8CR+S^7tV-YSc@7#8CsQo71lyr4dY}2u zwDS_k9Ky`R9GnboFlEine42|RkWz-uf^eLr=3XF-?bRh$o9Q=T&~ z?bY;-f~ujyH$a}vlsk*Qn9rt2fgm-@?&unZx$Z`jolTC~ObrcYYsD@m!)vnM=l8J* zWyA;l50wAbkRP*Fk9Y!EJ(Oog()%@*>KTHFY^MZa?PlE0NcAYEJs!7{9s3csu3-AbJzV%JfisBkMqn6Cm^d04oX7?v z^x&X=N_-+A$&KwSMU4kr<{oaT+1==Lr=<3JmDSXciIb=CXZ z+xJ$anB=mGM4eKaRvAkt=jZ34|6_Z&4e8I9NCNK=H-#k7ha~m~EXg;bwNrwyb~A2g zBzZrlosZk0er_6XjmNEwejY)3s3%fLEqMaP$8l&^$;0gF@ZooG=ykA^CPDA(&cwZd*24#h)#qv zLF>&^c)j^oh|WqR|Btc!@8mpxBJ})QK*f1JKJ@%s#QU7*UkE+_I&2?*-W+@$w(mvH zBZLZi{%QRD^TZ9Tm8P2UxLcy`(-Dm0?Qx+@HZl309hK8i?=8EAUO(B^9k{BfW{ORZM(~SOgjz5j`@7GxW_7Oy+ zuM5Wy$~}BFz~lNA`}~*=jFD&Y^H86NzhRqaXLdXB^Fr8uh=_^eW514k?8sHmYS`=xG4|o_YFn z*uIhNmX#tN zA8YdUZ!ttGPF!E-DGP&X4HcHu&S%7md&B#_us2_5<5w%>^ft=w0soWji?bDM2=#<# z$tTDfzl^Q%g7L_bN5J;aLy_f^?3*!CEGdW;OXg@R!i{ZZ)bbhzJvRDjG1fx#mw5Mi z4!i#x_IKxAYk*W_hBdg5Po9 z$P0TTxEK8q`^th+)&z%Sg2wk{Jido_4T1B5gE|XYqLb$c!WQI2%G9rvO?_tU(x? zCkjL7aU?X3)cXXE4YV^Myx!<<@%Z4L@SeUh`mR1##lv>^XCcjuvdydiqV`-SMZ9)&B#w`bRmv zzZZJ`UE;ma^8-{t@Ojui!dm^YpQ!(k@8DHCn0A6YbKI3%Ez*X;2mgyut=ewik`wdi zpIGAU(Sp~;0^bEOgy8X`dv5hARpg@kR<68np-SbsmHzY6rLCd?pMUsip8X z30KiT(l|`=(>oDN@(xKuy{9Y+STgWJS$>#4V?;&T1WX0R=|6<8kc$~BGLEvK=M>`g zFU02yAwFLxj&t}lV?Igh^&UpI5MmQa<#jBTN6^ysb z6qie3JA?9o&*S!oVLR?0QS&;c<|n^KmB~@={Je{IenY( z(~NbwnHYcmtI+emAU@+f-x7Qtw!g=D{=Lxi?-D0D&ld!rhwZoG=M4yR8+`t4;z5E$ z&#TF;WEOrNwu5D30oabPv($62{TFO55eyO6!FGg}K^pT{Hns+E)Izz$7ecwj^TZj3 z9vtJEgE1~_zm4Na?bPSQ17pIGDw{l=`X-4DwVMYz%A5LOeWL^&1nk!>Vx)E z2n{C?RV7us2Y)4`yh`-`sl3GoXS$ETEYdY^&fe*}Vcq6Vv0n7Z-(mIw_=! zu{4;jsR@fp*9_2QEyzuq9%Ht!Bt%ydq>II$r;H=exlt8Dql2yW$mhhM^wG~a9(FSQ z3`VOdqTLCX;v_I*778X--|>M&n^7%F);e6i zs@BG3263u9F@6qAIr)9A77N19ljKtHIJD7XE~?At4q>{4+Qf!@u`VMiEnY8ND%-~X zsEb)bKGTqp5EE;^llkgEe06~jsRE1@f>T=p|Lxt}aJ+YO-;HF~AOHAA=6z7EB{{_&-c|JbW{{`YdoQ%uyP)6h(B9D_1;fL}$?<^%E_Jttz%)U@$ zo)osf#Ifbandfou2RP63@$<0vRg5HyKn%GaJRC%xkn02QfQRqCoBf1ZKK=={eDv4& z6C0dA8hl0yo=^Dx_4WHkbI4+QS z`1NPho(J2_u-!@hj%?$tfJnYM)bGGT<|j@s8m1T27sG=aW`?&@5~K}ANRiOP9Ow3t z+dob{pYq{{Dd$r^2Di-))R0flK05oyA7`TzANX$&n$;&l2f<mGa9+WUGQ?R?n@my#m;OAcU^As+2#K?X=2Imav zBwq`jcPE|n!56^}7NmjBs6!uX6#7v%jPpcB2OWc80GZsSj{z_;09TZ6bAw-%Cx4i6 z=D_YJlvOz(w_0^-*MTz`A10UE^aUx`Jq}=Wms)6eoH;^yVC~}6Il}IteayK^rMz1> zCqcMasYW(?>>?#5&m+_czDWWuA?P2r$V&QM57Dk-8~$p|D}=LT3G&jS)v_gc{=|aLECL3Bbx0I_#?j z*@q6D?}h&X1B|)yH?{Y+>kUR-JBW83t*kui8Uf0jrN#cGxg&a&(#YB(lno+Leu*UH zU>UUr3RcJ0oZs2q-I>40dDAiLy6P1-wY1!{g21O0-y+{d_iqxsuyZvcH4?i| zLNV))NKKj_UUvKZ=9>mr-qJ!F%IYdNWEY=u&#TJ=al*N`4z7B5>B8e3#b&J0 zh4wbwdmEHZ8lelG7C?)c2mTZtKBcPJSyyhHQ&p;xR^;rzs^OX?6~m>VPcOA+8st_d zSai4+?z8iIlTY8a``IP=n>%`J4gM_W+;W0sHOGH97 zgN!nI)MO0(#pizoR$BRoKR|%H^Qxl{j(l_bl_+0^ag-rk;$P@|W(^n{3ss>Y$-9u< z4&vKLDhAo)l(A2!XQ-nrFIq}y)Jp*MOyKLqw|Dpe|7vgtb#$~0q`T+e93a1d{i}!v zsCaS?l67WiKNzP;I9U=Nt|ZQ_N6nO~ChzNawY!H~mGeDa{ji)}$$W!ik&k}Lk(6!{ zNu*K<7?jH-8LniJT}IAX)b5*WZ8h2#x54k37IW60#3F@KmYyb+rKL-y8R;2}<#`)M z9KF<2L=v*RZXq1{@u*|v-W78alhXNZaeG(Ho|7b{+Ns4bycm6o2{Nc!v?D@vlZVMp z!a)8D##uu6l_2gx=$ABdC3zE(f^pSwBygb|wMXr9lj`bUl!ADAZS}J1ns-X+@4>az z%Shj;`A;la^2Gd8OPDxh><{2$R1pA58%VU!t^(K#ki7iEE3f=O_kmmJWnkyiPd!6d z+(=A(-sfY?Eb~_F%gpoNGf%(%^wZBg)o>%K0{322Q|WRPIq`K#f z2iC~cf%muv)Y5!btJi0-`Y^VDTuU((jempuozKBWWU+dn1iYxek&rzzlEUnpdnFG@ z{_k~M(de_Y>txf}v-CRlsYP&p7|9~|R1*7Ca@ZSz_VuTk zmu9q_AdBE%sm9+-G9Epy=O7K%bATO8sONy*x^v&wrO#AXRLRq%Y!wIj8{|)GRxBKZ z^&8aY47o{%$kp0P$KCpS^WqnNn6m_Qzt8}7>f46Y}HJSMOIKFUHBk`(D8 z=I~~b8KmnK7NHPFYRUVNKOzl}P8eIx{ryKgnipyEJ^Um1EQoHkz?v3a!C&CJ>@a5i zfSON`JSI{C==Tq)`6vS7?2g${L`-fDWxE0XOZG`lJoy2NQ7J`f?fhzH^MN3lC&At5 zNlAFG-iS9m3;&w)o?rqovKP)9#Sw4+2KL3Fp)4QM!te{b`Zv@m4UZ2A*YfxvklD{|5;y6Wjm*cmb7@%T7~K6o&u9#kgX`dz=t+Vu*r~azH8<69g|Hw%97fk(1J% zw#Gv-?V;E=@Ch6_a_GPZ@Y#&<%g##lBuvcC-s@Zcy0m+BSJEZ@)VQJvgFi>PbEMmv zavp=^Jg!wG&J+LSOlqj#&gam#ozLq|^wrt)PT!m_XkA_Bi%~rG-FZsO<6oRF<9UBw z(N*1YzNR11FTGK!j!u-Rp}y)m)<@QR^)yhd=lY}^y`d*WGPU$TB`qppJ<_fYw5=Lc zteZchu8W_OG0?geSY)cj*}&!+5lPi1_ax|jl#-hGM|u@<8>q1=*i0!jt7q6DJ~4IJ zee&jXpV&+4daMy#57k|iK9)LF$<2jI_FJXs13W4e7j9SAKFT6W;tE};Y=+!nh&?3A zR$0r$kLdhCX~=4$X7oMOl8A@AGHZ=aPs6lE;Tw0tWMZ-s`YmhTX$5Wf?~L#cd`hvl z3v=R5;Wlm5&HtF|oUPitZ7Q~s&Dxf&*q$v|#l}!>ScUVZRV}eHblnopNxN&0iEW^I zp6!JC4fc}rPKZp?a}RHt*bM$EUfE`XI>SylH@q{^&|}uMdqx}|8*10=g|)bUmwOHT z{@f1QhuY9-`2CrUXJptWeh)7VFDKj|?!&pd5Y^gM6J>Uy3mte>#kb-wgAMV` z&ivfi)rNSdaK?G)@Anixr;cd&+%3HhoNFEH{}%tR4Cu*Q!O!6mn_k#s)DH0)_0>PD zy{3x*cmZvg1$0`;_s6fiK%}X!blrWskv47DA*3M`2n&QRUFp(56SfJo1d_Dt?k>M| zcXxMpcXxO9{m;yumo|I;Jty<|UYofy@9}sA2+Y5KZ-yrLfBrd>0FaP@(ZMS8pckvL z25Yen$6!5<#c?!jth7JQe?kr{U>%2A+v$;n{c&o{Q(<`FH_dh!^3-cnMyL zm*M4j1zw3);njEzUW?b^^>_o`h&SQQcnjW&x8d!02i}Qy;oW!--i!C){rCVrh!5ez z_y|6VkKyC^1U`vR;nVmGK8w%c^Y{Y3h%e#G_zJ#?ui@+X2EK`J;oJBQzKieS`}hHV zh#%p{_z8ZBpW)~D1%8QN;n(;Lev9AX_xJ<;h(F=a_zV7uzv1ur2mXnF;otZV{!2he zL`)7=6J zTAwzc4QV6Vm^PtJX*1fKwxBI(Ds4p#)JRR#Ow(vOwa^TjNwa8c+J?5J?Pz=2fp#Px z`Kgrx)JC(Zor2UsA(}&Bicpj~DMmX{oD!6zE=ti{+L_Wck9MJ5X*b%P=F=XOp#{`U zS<2Bu>Y-lB)1I`5`lz1@RHVhUgi16(Wvb914bdbwT8 z$!qc2ybiC+>+$-$0dL3~@y5IfZ_1nT=DY=O$y0eNZs104;%1)4)47Fb@Jyb?Tk|%& zEpNx$^A5Zt``FK|9N;#d&FviI4i51g4s(Q~+{rQCiQ}B$BzJL&=km^+=6Spe@5;OJ z?mVCO;0!O|Zq9O!7jh5xa-R3(Mcl{zT;L)v<|SO>0WNce2YHBxc_}aBy?Aflhxg_E zcz-^C59EXRU_OKo<-_=JK7xk8lj13Wvjk@D6+r=fD;4GyDX;dscxlaPbQ z;0bsZo`R?08TcF)!i(@6JP+4G4}1qFz$@?)ybQhYC43D>z@CtYMbHm@P=NEG2uolw zlwbfVP=-Mmf-hhgmcdfk3-*D%;WjuQ_Je(4e>ecXf^Xms{vV&lr}G(nCZ7d=!#{jB zp9B9Q@VR^*pO45F@P&L4U(A>ArFd>h}+ckrEj7vIhI@V$H=-wz+ahx`CP$Pe+u{0KkFkMZOD1V717@zZb}T+h$& zv-})C&oA(c{1U&+ukfqz5q!+A@$38szsYa$+x!l{%kS~~`~iQ+AMwZh34h9;@#p*n ze+hT;SNt`9!{5Ru@F`rv-|_eS1OLcB@z4AVyaw;{uka?k1#iQ9@H)H;XYz0SJO9Cd z@?ZQn|HJ<};Gjbe!wqmF+yb}4LvRz^3=hMB@BkbJSHdH358MlPIgV51cpNVr?NmE8 zaGFyKXTa(3tyAZWfs5fpI14U?Iz_3fexF{VzeCH84lTR1>@wqE++)VLF~Y_Ohjmh$DK+_>Mt0R| zuS~0@T|p(x@l~lIsF!KivOTEBXuEc_YT0UHAuU4^OY1S2^m+7XT!DZx)F|<&E=Zar zQyVZTMw(De+c9JNwe%Yq(L-7faXp0fkka8q(2NP~FoUtfVV_quK41A2L-VDpIm14W z-p;VuiWx)0(%Z1kQ!N@ZCK>TzAFFgnm#`{u^!^>aePy-k6VUFE-oJ6D9ld3YiB9b zpYf^&D~rk*wZObwsi@}aEadd=hKgP__Lg!v6`EbFlr-{#I+n-}d)1g5%oP;d@;$v} z6^!N!IY*WEPgKh+SWwCh<}>Adu`rPDDO6=uKbg90v9h2qXLMDmvN)HkQw`=b1*0b} zQ|k}qv*q4Gv9M=R%~l#W;u3pIwpcFbvfcSocb{%6o?G0jKR-)zeVKvYdgV|kmoj=u zb8vBUg9H_o*)C>#P#A3&cdMAKHY+4%$jwR%lS##DO&bUVv_sR)jLHN_TVUr4*mP^! zq?mYP*6SD3Z_S7xEeH!zl9LEpCd6%Fz2UIk^RRTMZWOy~%a9GkOrXjfl1I)+8SToD z6Y|Ib=?}j#S|uT5jF3%8E6CA!HN>kA#;akIqNXq@sWMAI62*{s%(!CW@*Bf1M#PM1 zGltEWGT}r}kT5>~FCeh>G0BqqK#QQXp+$`q!*&h7ltio<5i>0a3sN#)O1b5k zsHf3PsQfxtsi^B+u2M2X!aDR;tqKIxtm5<4iqH*@$gtdE`pCRSB*meRMI2Gfh#QDl zN7{9yts`X}u8+FT*C+(V42c<3nBuk9Cq7~sr4>}5uv0-(`uX5 z!k~48tV1qeGATEf2%V!$OS?rCzypNV0Xk2&s=o zWqlDramkb-Tvt?YP>YCVS}0d7DbEW9<+mbkh03TAA#Wr~1+B+E*pu=JQE;o}F`-3J z5~AW)%ZeQnTYv7X2unfC7DU7!aSQCkan}wDQi6m;6S9sLX;(-i`T`5nLa7X>4_&o^ zJh7Aria#J`z?xBkU$Xsfw%>*$g0vuIf_ljsp$dp6B6MwOA}WU;)h8^r{%mOkg~_B) z?s8>Ix*UoTaaSa4g}OpQmE$VASU_?EZjtn>g)K7uxhn1|w>&CUYENRv#Fj_C7HSru z>+y?6o!@E|L&a4(`bIl>ebV{{QUlT2?t@E^q3SyETvsn>= z%?S%qf`omU3HfR?%|ohMD|1CexNjYs{ zy-NxLf~Y_rgogVL=oeczAwq7Gh_tCGD~XD`%3UKONDIP(l*}NFD+-L2mOj#|V$8@p z^(aH~!txtS~D^x)$$D^%55fM zLlHOGrSz?sFsGQ1qmiyf$epG{P!d97%1;K0lBRcLMcfrqD0hRQ$}u$oK~xZve0iE` zVHffXA`*_c#TH>fN|4Z{L3wf16hs7RL0DkA3Ww!X)$cGWbiVsP@3GlI zS5D3JchpK)%Sod$C0wt6Fj}#;e+9EvOkFfdf$yux}wPy&90c{is`Osam5T*%yh*pD;gVI z(dddMS2Vj~nk%NeqQw<6TrtxX?#xXMu4r^clPj8CG0j^kGs4=|Y_Xi_?#>m;wcR7q6X?$9(ySn$=E;=3ZFb_E z(9!y zo7HL=@OIc0^Fr}Aw^+{bgfrcha?aCdV7-3JR!>;^>oah|swt;W4W6h}6;`O4Hr=wt z6P2ohfw$9kRutN-Hp|)doxPPpPo`Aq@5@xm^~Dt}Ph8e1t+3AY7Rwo)xU5qWBqVoW z#oRW_*}|44%Vtkfipqj6In#=qX_wonrjE*$tr%2wmGXt2s)`=#yGHe1S<&)#xhF2H zo2!4;tMo7I%MI5Jt)SB@=%vfGXP)e5nL+Km<@d(2|J)n1TP*{IO^q`xXIc6z{X&1M zuyvMaZcizrb~YrKD=Q8e)XdH1bEVusexPQ^Rl2URP1Oqnp0pG$H4yLYnU=Ghwo0j} zjiv^_&oW@x*w`#=YN^Q$l-0dk&Sj0Ksi8&KINfqqU2eF$FVjDDV4$I~w!7HhpE0s- zajujvW?gq*v0&ubfn0xnxmmxYq8G5%IGHM291?qy%%P7`ZBXW#;8u)e)n)U8`E1VU ziJ8U4fpV$1xHs2t7azN%QY`2Catq6{hA~U}M`M}K*x3brBN-E2&+?@DTwh;)u{vR6 z{U7p&9A*Fj00962|Nj6FcmZQzWME+6VSoT81`Y-Z26+Z%1|=Y5W~gMS0+O{r$jmSa z2$`8;nBswCI#UjiEM_WZUus4U8h%#s}%_bc5q1V@4Qc%x(!bvnOmdr>?}j zjE|e%k~-2AltWL@ELtMtrL%OAZqi+P$Tf1k^p$=xKnBZDxm!laXt_uJAT#AL zd0d{5C#|bQ{eNQh!SkmUN86>!u*9&4C-XFZm>)NpZSow>SHP>e&`ws&6`bNqt_nh~ z=JULdlU!$dDHpp1?-fn_Nqhb<2N~9p@}{w{HgJQ8B&4OZGifi`)`hOpOHW8|J)%eC zMj0qW7`!*!#j_I|4VGB^P=d#NPtkhR7P=QCOM*6Tn-sO9by>;8uePU zE%m&ul$QCsc`u6DD(yX6%RB;Fsb$q!T$M$anyn&ei73RGIJ4=KY}hdq*(?>#Tpl&xaxY|55bQ;suR|8SOa>{p6^RgGP(#2$8nrd@Py zoKc+r;{S$hVm>Bs6H6<3%kXU}A&z}6>rAhcoy7Wp6cLA`WUc9ivV%CTveIJm<a-@@Vk2jZV<)wI*^oi$6|9H=MXIt0Hpm^W- z&2j%bZkUXY-zVealjGCk(dpW0})XKL?8YX&cb8V|xi6Poia}(nd6ScGUOiWKas@H4Z z#C*M32NUy>Xn|pUwB7K{Xp3P{RARV1dcp9MXfd(WM#ZMDimoBnF#6Ce{i2&ZCcVyM z(v~H|qph$X0B2Wljs)jeaE=0JH*j8Okyl5%oH_j!m|KH6-~ak>=3uN>5>z;6tiX2< zN4X`u!K+G~a!XL}sO!CQt#Yrv?%p84SyJg|4c|)7_1zt<+6lls!w=GvExra>wSHbb zirh>;ukQ9!1o_S{`8Zv-bkZzsuvZFMixJ<&PZ2AHWfA(51N{o;42Gl5r*W1G(N2pj zf@O+hEDLz4qi*nAS?U<{Mtm<+Rfk=Mm_W(7l^b=Q-zz zT?YPE(JI4TelG3dcEhoToud-q2+JA(@7vhD4mbW)dWYfHzz@^gzxVs!)@;{ue`1rT zZ7urYH{AEX;Qrh9+W+PE*%cSR(60I)-)O(}uQX!JDYkwSE#iqyrxGR)rjprxE-m@7 z$;6mTK9NisXOT@KpG7{0w1P2*B=8v|nT_+urcWQ~FM|Y=M#eWz7!#W?K3_~$`h>Ch zf(g?&U*wR9O_#>`BIg=siwS0nPZpmlK2dz0=p8yj$C%uwlXaRttdHw#ea>XHF4VL2FIFWNkw}SH_=Zp>;E`>d5 zXtN1;J2`&}dYR`2pFpp0jJ@Dhg+n|h?BUfW{_2+CjHA8`{krruLl^g-#5y#DllN7$qEcEdgCgMMn)^)xuoP?q5bV9xN4>26f` z8Y+1MHBWHeX53lB%xI0-$DteD(iNuXrk9(ZlXiw%5Fa2HH=^^v+yxzIkCPN^OiSxb-eG+(jf&Zkl#X{(z*hzxVgZW!$~Eb?w^N6K=< z+&ln=0f_ty>gk5vN5cLk?(sy_!o0ns38q)N&U>Qf{{m>#`oRDIcmai(4|vbz8voz# z`}5sjGov-L+3?*AqnVjCiy0PTjU;JFXf6K|Gb73AI8MjuIF6%85|ZR!k|aq|Ns?5O zBuOesl2nq4-*es9=en;?zw0``-}SxreqPV_dG7nUpZodq`CR*g0AewNyWo}fC>wyp z%G+!6P~dbJ1|b9hmo6a=fQLxLII4#RxE#qyMH-q0deCtcVo?_fxC}{XgvLlmvp^3) z1fo#~@u-hPG(-xTAdC!T4jW!O0f+viqeqOzmjOLBe9WXOoDJxCrxS27s3V4rsbVOg zaZbmwK~Tp|99_fYppL7)eFD?}q!Vf;Fe|9lqpPdf#@BHps+bql2@`VLu`sB$!)hk7 zShE(7dPo2uAOvtq)duvD%M9ho|$DU5^l^#x?lfEK-Z?Zw~Ja?++gfp9x>gh|5UHXqi!vQJT>|qblRRjM*8>{Bff}R5?vTQ)D9_#ps3p z7z`rhNH9(58l&DueT>SCt~Dw*>g!W9GSM7aXpLO7Lq`+`A_!|%lC*yhc(@nclzS>) zp}Ed$0=zlEF9vvv&*C@}odI;g)kr}v^g%O} zyH9i5J^F`u5X8M|{SYL$mzx~Z(r*dwJ1$2yDo}~Bn4Fe{>6nH2Sc=tYxoJgdrD^5Z zh;7)FHVFH07{_r27Z_qZlhaEWW*Zi;guT@8VxeK$!LhttwuwQh8x{xRB3d(QI*jhMk9=5qwPko8og%p zy3r1!w~Tfhy>0Z4(O#o>joveQ-)NuF2S)piJ~TRD^pVj)qmPX~F*L z35a>v0>D&fn87M<#l+?&HnJIH+k*tvQvPE{tUO6boT(P5)cjgA<7W^`0Z5cNNwr2Q}wSs0D+ zC_xP-qbKYv*G)!i3}!z*AemAu)iPBsxYJeO4f3kJhrD&(nb3jInTY-o(<0xC%8!~B zofKUdeK7iD%$}HYv4diNud}Ppg}6{$%ecI_%DDM)E8}*@or$|pH&izsjZuVBlwkk{ zqY`6KgQ=K~nV9XOU5KSvfwkCx&De$=*p2sa0Ecl5CvcjP`n0J;7o3ELThSS(v@F4I zt{j8T6nL&j4m~Y%8Pc*nBeYzF&-JPDh12Hv(rGJv<+L@9JI%q@PV;cWX?uLdHG@nFv7^FL&C4Nlsg{q0>AjJMF+mP7Byr<4AW}#3oL!Vl#~? ztTAOe?ZW07S(eVvLp0)%$QEkXQv0^jj6@(6E+-Zq<@2f5SwBqYH~L{92JD90cS z#R!bUWZZ|Dn1cmaij`Q8&DaiG0UXCEoW*%uWQeg$U=kZM%$CeyKHVN?50>#cxLZ^6 z{$E|E?tIu^r$@Bx&PQE2)YTVhS;8f*9OlZ${afV;|5ka@k9&=OtE|h(?ax=X#jrC#4we|yy5 zJHb0YxDPQLBQO>T~sSOfA1u%dd3jUZyv9p`-uD(+UfD z3LdJQ?f3pp`oZ5x$2H!sHQp0C#y6U&Z#CZ28t++Mg&%e7pLFb>HR^L3^)DLrdEFBy zbq9RsbPdnw38f`E13Yezha}|IodE z$!T+e(=4IW*5WzMk&x5265%vgBAvFAD5vcu+G)PTI_)5FP79^3(~c7Fv`FeXy-E_C zc9Qx|J4*wnT_n+Ii6lAgE)AWQia6~fb)2ryo5z1XNHW~arIFgEsBNm+HionM-?yNo zL7a6Hr>&%^(`;#`^9XCy8R|7t<7%$Hv($GB_1)5GS4nr;E3iL${f~XE&l_n24;9W& zj+P~o>&ly5y}c`kxUvv><47xwtF^|`R&$!?G*9w1cLkceD>bf;8ds4F%iK(vt`Hy{Vb~^GNtc-=Tlhcjcd*7U37QJ*K3?1Ctlc__&H`=}{ss?ooaOIYmb$uVO;D=y$gua& zc19D8zEBdxpdYRWa05o_|Hvky5hh_WGV!4MWZ`A^X@OVWrzLi~Pb=(mpKL?|NJass zVi}Gyo_Ue_qcUIFN%l-S@J{yfkzgjdtjOYq1O~_;=pV z2mD^O)+^a*A~Mkeh3KeHO??~3JS@N}ti~Fw#|Hj|_sJl+$+s>v>qbuF&j zqgalounAlEPZ{9%jo*Zw?3&(Q}kDhD{v*QLML=VS9HhK z=!xFwgNLyQi?J3@;~6}U&3KV7NMmUtEqqTle>8SlS8urYubJ|4ph+$62#3d!;Nm0G`ar}a3Dw{a}*;&@KtR&M8h{wAr?O0uOu zihP>{vuUC>SFwWs;X|Cq=ee0L@gR@zyyQyIh~laFyRmv9?D;D`K#UrR_Lq@gsDX3|kQNoVQh`VQD}0rQd6ZxAXI>Cbk|jmbBwb3SxAc)RxmNo7 zBZX}wN65x;oF>?aVP>!;JFyG9vnP9TC~s#qC-YwZiw|->mvR~3<$L^yAM-OF=Qljb zZ}}a6l}L$|I#O4{k|$S6H|Yl*DQdHgl;N~FKF2Y9i8J^CXYnI`!X?&Y0#7m+ymFChzZt(pNGXI%6lW*`Xe#QkxGlq%! z_T7Zdn8_^WvK>o#Bdd4^mvc3r=CjJTqEUjom?*i zp(90}wvn3azCVvYSeNl^$o9-<2NtrJCA^x~us4Tr2H)ULp5_^zWbM zwsBeqC-EC2n8v0Y&L_Es>-fF&_4`&@-zzlMiwv=V|K&xAk;|l5Z}t%4k%eLm^lio< zXhWp<-w&|wbM*UE|NBn%eOvv$vHyLheV?n}rzsQB5VXe3kpw^h#A)6{ zBS;JWuO534gJgtJj0)5`59_cQuj$i&C=M7kA4rh|}Rt=UUrHzwHif z8-ZZk7{6_lwv9%x?JmFVPHh{DU|Y4{Hcs2dYa0=g32=3#8l%BJ#UKg|k&Y&4ie?BS z1Hp_45_SLN1AZn29x~Av&|fgx;B%=!e+Vd3qBIbvt~4qvN+OI*bo8IOtKpuV zdY_$u-et_wC(U@y(K~so-YtJfUA=?#X`{D&nU2;_hRJZbEij)gsE17Cpb*_qhJhH0 zQK-Q*%*0$Q!V0Wcy8-sAPleIVMuUxRF&btx%4nR?D@Jb^?KFDRXqV9*qeDK`v-h8N zn#EFk|5=6=*cdn=Sx5+Zp-?Cy6d8&NMTcTSv7tJlxKQ0te5hV1Ayhxq07Qa3BunIR zd0N)V2Kmv8@#=fmcssmLy(8XH?{n`sENh%&zbHQljmBDvq$*HrBX zVxU$bwSiihObXPBWpbdFD|ZKKVVM%BCCWX4TBJ;MN+bo=EEXaUI;GZ?k+*Xos2T;)VX z0RRC2004>Y0N{UnAj`?$_WxUi6(z)e?aY3a5dQ~2F=3HkKA6DonEMw3kZ6#YV)Al| zzcMcX0H{m=0F*2fDGx+3MP(rXKtv1x03;az0Me`*r+XtgMS7;+z>B}UzrWDii1mUs zwAQx+0Du+-001@t008L^JBfER)pxY}^~dpR^Z()^m|D62>d}6=n*jiT7wZ&ocCTi} z`bNM0)PC*Q{sW{j!w0ip;jb+2cTDmhz~n>hnpr!!{VtRO000sP002R{P9C-1%GU7L z4zB7q#IGEJB5Vbq)>_}~cP@ZUzdVBf03-#F-bUZr7y#hmHwF;H@BHEd%U+x9Y#p5d z0G`5reboQ}5DweoYFzyHodRQ~SN~PK(1quD0ssa+{q+H`^r_DHpMF`eM*1t~D-CiU zL>~YM0Q?vKTYkR<2-bH2fDvTiSI%oMphac>PK5!xm;=!K&Yfku&*`v4-0gn{Vl0XKkvRG@}Ywak{9VjyBP?0bQtjWJ%5sUq@} z7`c?qB85bp6siKkRMbl-^n@YoK0J3kDG{^a(%+_jHXpJ(vK?)X(`}RAHBt;wtLWGR!EQ27k$s4k8dq5 zd}BZWW3CBhud@w=ESc{S*~GbgnWA{ss0M14g=7~3bwRa~FX8p8)q1;zdL#?J271mJ zXeB)r=%!c5&zx|}zSjzGU&BIO%jQ~u9eKfVWGkf4Q|%WvULzZBTZK;lA>dNZw&L}u zL2A)xyCz+3Q^(!n=qWvNPxxTJL9b4~$Ze#aC7tA!11&-O(7x8m<*L1^6xxu=xAxt4 zzmf~<(RMe9^jM>$Vwx#0g}u|3-HbeIZWpR=n9Nn<2me?ZXHT5fIUn2vS_tY%c&Jgz zp;Z;z7`icc&oT2|PVho~+cIjW8j-z~S*;x)`tX}(X=GhY`RICvLS<|X%r1qtsvftt z#5~_vlU2CUBWSjoMR1I+xb#v6t)*;2KUW&N3F5x=J`aUsW1o=U2;H>UNt#vA{Y2e4ekFcJ8-8o(BT^)B4Fd|5ND`YWYP z#`IG6a`xWryzoW$LB<%1q*=Z^_6~aG)unlo+JWek+0l;=`~D8r(a$c@hFK(>q&xl8 zqv1@h+J(Bli9BOm=~Pip44x}bJ#Cz#Q0ezcK66*FgI=vH`OQt)*D8Fkb66-q ztGiI|*rw9GO?NkOMbIM4i$1ffd3l0(!^cf!mEf%T55M zD|+YWyU*Bf!IDCx6$U3Xp+1l=b6dtWOkQcIRua=k_DI~FEx0*y%EF-un%;=1SZSw~ zku7PL1F5aFK2^Fkx*E22D zmTTQ_+BDjRGN6Ykr-Gpqor?md+i>e)uhp*dl=X+y3pGVyCiq+P-^Jh}(gK@^70knU{ZDWgMwdz{h+{J1vEE4^_-o?MwPL86t$}B` zY901&E_iKYqmq6`D<v+8=rWOT{4S*>k5&!eeVm#7aXi%8wZ1uCCV-MjHWs zKf-eFerYGP^@!K2)#5tf<)R(Q7Qgn|{ue5*nyOtq<6y;ESH(J2l}r0a?@w1s>TPUq zj2#mvHk5Lie*rg@^`>*ciAjjk1>jhm*u1A$`c0Asrj-1|Vs8?#E4}3AI4G3-ZU9sM zP-TifUQFFr0ZP(U{Oh<02lTrdUTuR{{Wh`Q7}^q_UIeCnDA#BOn3uk>l4&cH;U8_b zFgNn0yQr(7wn00X+tE32ubUh_{8`bwac{e$?p6|#fe7~){G=$|ec!wqSwx)>*1hcT z*^q7J-9@^{68k54wtY$tj`UV}p*8}l`H-K%rzcUhLwxw&L?Zt{wZp#?SS9OwMtl&o zqu`YLy9=$h4P`lWt~PO+8+=tYJK{VRDQA@MrcyrbB!*6v_9$ISb zoxA7g_Hp2VovA+I;KJNYjhI^Ao>#4Lp#2yLR+8 z%IH0fHvTnO<-Z4;QtVv6z&`5-KXW_R=N4q=)3Y#rOXg$xX_u#2_ik6u@=m=%tm_y* zv!7C)5_z?j&FYlsFV@CxRafZwm8{QvnYQSlZfd$L#k(?zx_)I&V}5xcwngk7j1ADUwKg0I&)!LqXFc1iElZYg(NE+SQ+ zASAdl7VkPMlpxPE!8&V%;Aqn)x!P?U#QU(q#?}ur|_d;2XcIC?MJwn zeanr-{bps>NXJ4}=B$VS%;t1kQIk6e0#_`qbj+A?aHbA z>~M#X-n?wB0;)rFXv!0>cBDKk1ap#TTlP=%Qj9DGk7?+6mI!n|0DLew?MFrUR&nsvr@;U<;99n z+C_lRwUSaJ=+Bx%O@?`A2IBeX48WB(=Fj{epz>*}#NWNqoTj|8G7i}7&pV$`svnH% zp5KNun_yHDaQZ4EGWFk1O}QzSgI5F@_-M{2CA5RZL#f|K4fPZkMydt65_5Ty06UPz zjxpz4?-5rJb9%~a=o6g%Q)HuiZ!AH zB2kM)l;lzf0%3av8CuthpQpc`1XTV(Hp$BxzAMcJepiYA;S zlBLzDQ57gz@3V{~S|;Og#!zz)!)a3{69Qgaa#Kkp;=R%-=_jb~scOXw+6jp?3WVO+ zlg5HpL#|f+SMI>J2W2~hTkD~3cC{~u@j63a?g04)b-aQ!yrSf8DWCV4FGm2qV(4#4 zyZZ&bqW^G2+1i1K-O--Q$KKrXV%-AAE2TN z4BWf|o8FR77XW9U3bA|4LW2|jgCGuY`Ykk%OM=s#@0I1fer+S}=*5t=40CiiCl=_gd)=;w66sr@Y)(Ale=AKf@Uxt25 z=|Pzo#?VIh#6u3lFbAj)&e02=A;c&q^&nSA&;d(dyu_Ao$Y2_zz3R?v*Set0 zwLvzjmbzp?Swn8QhBtilAR?dt9)8FG{_GBB z+CcV0enK%oSwK}nJwua2D??{NPs5PF7{J8A?7))1y1+KV-oTN;1;KT}gTS-G+rf7s zU?aFA)FX5uj3F!`>>*qsydi=jA|mP`b|ao3Q6L2&wIahI^B_kc_aT3x@S+5xte^s+ zQlpxq7NDM?5u!<=MWfB5W1-8V2cq|3AYw>h1YtB{9Ak1}CS#sq;b2icNn@#D z*<tLH;+hDukz~k`YNa5(>jN$_0BH+^DKHwqY zvEzy3<>Le3v*Nqr2jX`U;1ehl)Dhefd=Wwtq7o7kY7mAIE)qc!=@S(bEfSLwn-dR^ zfRX$mkt2yDSs{fXl_xDAts%oBqbB1Z6CtZ2`ykgLk0oEE;GnRjn4|=tRHBThT%f|H zvY;BIdZQ+$HlZ${zM`S0QK!kFIi}^Hb)~JP!=qEDOQ)NlhoU#6A7Y?jU}X?ukYgxk zU___GA1ds%rgqtL^B)TNAq@QGzWSV4=6s(k+)QL2!bghiEOoc3v zthVfmoT{9moUL4-+`K%yyqLVAeA8dhzdCI&g%>3ZSD=a%3O=I-VG=8@{jJ{h} z>-Fv(O1TQ?q}oI>ksB{>)#iE5)d4)6i6Nz8<-me7Gxge9JC+I9o!l` z5<(Z!70MRc8io=^5S9^+8crBa8{Qb97@-?s8F3J)7ug>r5w#a}6>S)88+{vN7_%Ac z9{Ug{8CMh!9giMQ98Vw59WNH&mY|j}pXi>rnZ%LQoiv`zpPZk9n&OnQl8Te+o(7%P zlrEZHl!26iml2%_nCYDPo@Jc1o9&x@nWLH0ohy{vnyOS>#=` zU(8e7R)SFCRti;$R_a?CS^89_S~gbBU0znfS&>yyR*72~SGilISM{%&qT06xq(;A{ zu9m#kv9`O8x-Pixr(U_fs{W(Fz2UhrrU|9VylJ2rqdC5LzeTfUq*b-mu+_G;_aD-~ zpnunG@@)(4RPD7La2?hi8=bP9{as95{oO3xRoxpsFg>I_!ac4%=e?A@roAn_uYH_- zk$ug5r~MTD2L1W{cLQVtdIRMH*Mppc>4PIffJ5>_DMMewmc!K}FeBC@StAo8Z=)om z@}u6Pm7{B8kYn6q)?>M23*!*uJmdD`CF2_tNE6}{J`+t77n4MjLX#?!VUs6Q!c*~6 zxl_GU`_mxP*wd8LjML)NYSR(ZnbSivFf)`h`ZI+yt+NQTa{ilOMpk}S*;eIO<5rti zw^nc0;MOSC_|}xx%GX-fVbJ@h@|J^DTFJ+VEzy^g(+y@kDwUTR#LTsmBO zUxr^MU*=y{U9MgpUfy1bU1ePLUAH^T%X^7+#uZG+)&)G z+z8xA->BUf-q_xF-h|#H+~nQV+;rTG-pt-?-dx-~-y+e>8dYe~fu7 zd>np!djfufc|v;upTgQp0h%0=)R5bujk z_q_JFs_E!0cGY%U(Y`$k_i+0rd6+&V0R{}@NAR;l0&!>kjGz#?L1`CP9VA8gm$hBc zFD{<<*YXeOp7_7A*$W4eS+VCpMFJ<~etCbDLNq84p?no|g?LqLFj4%wm+}}mSlj$- z0J5$z8NgEFnY5GXg~}(JcQ*TllJ)PSqB1g&$BYT8T~kA3_%F}B@nUTa*5ndKPU$9b z%eF;J)r+e3`{LkiSSaVe9SKNOy-XnF0SWKC0rL{_ApW<@aZ@yi5El2cZn&ROqvR09 z@_Dc#ef=1(L3GOEWy=P2+OoN+LzFmh!9+1(e@>C0w09sSs)u*@gomWMsTSnd#Y%3}=-Q|{|KRf@RJvud=eV*?~3iICn?mhLl1?@e4q;4HEowDPk}kL z1-+F+CP|=lv^>F;#H(YTQ8iB}M(-+`FBnT;oHmv)l&QHib*xY@=HHhNS6jt-w6Bo<)M}+L=C~;Jby>eM}<1gFDZRWa|)-@f#0_YeE>Czt~pdOkg zZA&Fzp?a;um{%`pURc;`>F`Oxyy2+qWOEP3;tHyvo8n^c@J6KAS%x;gYgGqMIW@#Uu%Ei7c@ls#ukC|1J|AhB!Enlg(DxLuB0G?3S? z`7{za7;r&Fqt2NQ*R_D)M7Jd@**-3^#)(bD&&YGf2@o3&WFy=vX2c85B^JOnY*l0d zQ}^K368UCdqFpP~K~mkp`A5A?Tsv<1^RXX#L7--BTW!;^uKfOV6$6@_S@ufQj*YZ8 z+%*cpSC0~1QxAlGBEr$nJM!BN!(aQX!GmI4pK>KQi_=LXv{~sd#$V+HvO*=}>!@&5 z>BB40)wR;I>iPBv$IE4wY#qDsyh`Q#2pW0QQBX87`;>uvlr=ARGfy_Zi@sBZ(0WtH zzY?=(NiGMdicANGH;6uw$hVn>LkaQOh^lxM!2v9RZKC3wQ>g86(6sud`$%jebJNK4 zs`GW5iMe1KM+S*FhFg(!HmQF(qZ`6=vBpBBAitWMjKj>sB=fa81g1upERQ?u761 zn8FCCtgGeIf#{|g+T0>1Qqz~Nsx_JYV>P{_u@k;WO$B^8-V(m-{BtWj!;S8`9Uqj8 zMZDirDp~TiEvg;dJuqe;H1m*@B#)r~$gC@Gz;pVx3sHo9dZB0H;!}UCabyhc?<-4` z=s(1ZWvLM|m7UAlevydD7_A>CL&*UX6qJZVHfTRtQrO?Tx6f`T9FTNMA!Ut_Eqne=edjfPvSqPzBK`dMQ7_QVz$rB_S+-WcQS{65BG^#yOn!w?WEGln&b+lHbNsp60o;z69=>DbU2qOW}$2d zeshfQ1+B)2F4x(NLqc&B2=#jUaJ8jO)9TGHFo3k}JlS+K4k!?Q3ud$FY2e(NMZ-hX zF}02y(c7YxY+B~c3P9P<2>! z4Gkz2vpek&(jGh11<91SfN|xovigS5l3TUC%h4U^{zTHo82* z--yqMry8SPHXe37KKrp(I3pZFf;4kZu;vu;M}P>56i+QVp#C<5rx7Beb*aRk|mR1}5-zv^Gm>+55L z`@ASUDCI)OT zb&8qHs$osK96g?E+#@bpIUlXCTecxvm^r0PWT?g1!}7I`8L*{hAZ|#)SE`(%l`(L< zN$9&~X&W+NexsTrEw66$ih5hTxmEqRItH?|!o@-?n#Rc9kMv`WT74VUMiA#;uM}OG zw;N%goZc`6FvW1Vd=uJrMP)7hAp15YQl@dPv1{+ZR;q}&jHJ6?KVxY`ZCdi;5fx~{ zlf2jJJZH7v!qYWfqjZ-db|R^gDf9EyxX{{^>@Qt#3~2J&K=wq}os}qGS&C2KLv9-# z+`OxXKr4^FzwD&;wGFW-UM3{yLyb#uN$Q>UFg6u7#O11GWst8?iGCG#0i_-ujxg%~ zlmd=9#xFKLowUi6EJdS6Wizy{B@!(KM?9pNLt0}UuBHiQh#rm$qQMOqMXK}Sw&pVr z5sVZw14CLG6d}7OkiwrO!{Tjni68zf#1_7{OL+-#PO~&O5_CtL+9Qu>Te2g?k_Ne} z9%oO}lSLc8Zi2gy@o$E2ZxK*nnm>*nRi}nDZ&t%~(JaZgLNrJV9&LGO59gWoa-wCr zHlsnYgaQIYtIMS%m2}pwRcXOP5RF{Qn+IyB7p<|f?Nh-ER;cN9MG5Fc>l?E<6mCpU zAt%z#^6)cvKvVeJWgP^Pm zlyp8#jC4#$+_~n|cp_QX@lSy4@pa<9<9QLKx{B4z1*f=jWY|Ya4{m9or@;L&D03uV zB2oS?W^6nte`*WNd;{sp3(Hkm;gMLXIL0tUE(;_6;Ro@Q`}aQDs(PjRMt+Nn4K=OS z-%7^X_0kF)><_-y@>OiJa0I_(v|9{5M+k!)p@0D;#zrNIWQJNS{Z#wKI}i@WMh*}S!=61;hyZyY=Yh=_$NI*5zX+WYcRd!{`OABI#a&#k^3-DejODW7bG@}EP-134dwYPYFBV?4)515~A(t)gH29_3KwHJ|X3?8k zs|%L+*DR$?eT;%ar!1Ls!7?QS(ZHFsz8*I(jlWa|QnaHD4RaeXOo^kU5QdKyrZ>Y< zeLoyXb-S_@c}fMjqne&#_zccDTYaf1ug8GZ^%YtS^;hy9G0K%HCs8JypRl1Dg;;J) z*{Wq$*Q9oFzA`nCGutYSAn+i4%{vj zgyE6*BCEaURp9l_Wp7)!+Mw+Phe}u!=6R4PvFQqwRBb_Yh6cUK9L@%r*%B*zZCs8G zeJ~i*lQPErH$T6_7CUX6-Y^zSq1$1W^QgJld4i9p38Zm~6_}gBd;*#nO^aO5xcs{Y zKy(d#UXlVQr=P_b`st6Xb*!4Raj?15;+LK;S63S`nM&DrA|YZJP3v@y2|ho){mt!^ac zY<%rrSaJm*FpJW+OPS~=>2);(q_|&L;L#}4krq~JHWtj(a5@Wk;;!2NNbkeeZ(C7n zXq42mRnfxLU>oKvWz(;W%{xTIjygg$pHwbwzVk=8v4)08F9_V(gl!-=)8Sn}{h?wg zrb~#$0$fohgk7Jhdrpul_5m-zh#JCY$oJSJvPox2S3-t{< z?sHlza3+^(fmk}R#ngxuz=E_?gZ|Mu{-Rx{oy>f@&J&pkn8yq(V&39u(BD~I?WXRe zs|J*r{9B4T6LlhkreiO9bfw7ze|F~aGQUq7YVNPLxI}^4ZA;`l`4Kw50PZOuQsg5( zF6)sq)#f^=@3eky8MnT<$VgNyk{;~s3}C6A_!CTRux|Dl5nu{4gqZ8l!O{%nBnD?H zPz*Jf)t;J!uh#4ZoZQylEJ$SJV;s;{x6pb*)SxR#&8pI+++*=EE}MOR5TSsdGRq|- z`i(fH!fR}b_FB+k1UA9Rh6SOhmMD=upGqwM^Xj)jG(Acs6$oc(LI9f{EfJaBjBV-} z?9k}EfahOjYH4ik3WkXzo$EF$%olb!Yzf;%O7`*WDDK8f12YQBrfQ!umPFX-@z8K6 zq)LXh-MwgZrLHTFWwzoJJ!Hdi3k}kdVW6yzLdHk;2x%Tq+(EWGDax!t-b0Qr$W0c>JGU7I z?{!tI=%HNofWzqVex6p7LgKd5} zqB-4I*PP;1v^PsJmm2N76&_u6EjBh4m4vDLB8PheH|PvhDch=L=wJ(6DJ3rl11fU0 zs=`bp@1sM&&LKB}q7G^b5Tx)L8+C;3gSvnHvWau_?W*2u8SAWwl3gU+vzl78COQT; zv+<3c{Z5DwF2^NfEX(^mnOjA8t8qR57R%POtl&>r-iZuXZ=_!-{CJT;g`Ep*E*&A= z_)=a=2qIp0+mU^UfT?`rByZMLv{|EUIx;Ii*b8%8RB^{jsXUI5RWn9gqmWPBt<*{J zIy%H5Jb0fckz%KC(fX&K-h&YXYs~*h*#G@|m*G=bV(xu5Z1Y6W5dA4_aEJ0yJ*~w~ z+u{+?SY3m|t|7H>=y*60<_aA)p4Q}g8>AXWzl-pjI^?j_6BjXe-opq@q{jvqy`eSK z86D5}pE{gG)>3!K6jaS!V-k@3xX|WI`sb`^Jp(~G)<%Rhx`- zM(fUYd^XWM{A|(IP%~3g0V^Iw8hOu!jXHjhllRq%OyMP3O*%2GG5^i?#(xhd?5YZL zpH3G{=k-H!!|+t=S>}+6E7{_7#8S@k5_;{2mr9>z42jWOW?(Rh5^TJxOrzjJ$9(Pz zTuMy6qu;E}#lyxKZe)j{*_*WrMoR)0fIJArVxvb!!Hf4|cc6=y{`yuqhU~UE5#1x+ z88ng_2fuI6&;E_Q&td6q_zf1jccl4-X22j!l|tp;DO%@bu>ufAiO#ojz&s75N%>(CMNqE6`z z|BWGLT>uRM)wSsMO$JOc?HWhOs?O2z6Kmjz*eIy-iIP&{Bc^=_n?how1*?P9QEsD8 z3WRY0*F7bku>p*`Zq(fV7%FdI9|poNta;>ZYfZs%Y5wyYuDZfRy*sb&ell7GoNXt% zUX+{DxXB}1VchJFtAH)8a?jq2ovat;m{Q~P><3a^Z} zjD!2%!XzYcZ;N187%5i72bE0))i2+sB|sw&@~M(=&P(UwQ61Bah80Fzc>Zp;Z_$qM z+MZV+M|W;7^gbDb$Rq^(mwe19*IVs_K_ukWZJI8fkJ~ru7Mb*GD3DR7&||#Jw95+a zpWzr4(it-`zqBqmsVUAY`}~0PDR+U?c>;2NmRaVc{s8tn29_eW5m>k<*OG?qdd~@Q z8nWOtvSA7t0SjteN*39}jNP{x>Bc#06Z5_*nTF~7)cO`qj_~bhBd9*i^`M8Q={-Z7 zG7jzyxUI1^X~$dR19Fbbh~`$@+$|FHW_9BMU;WPPznzptX;7vu<9)vAWEL`dckfLf zGOndfWA#REt*uw*Mus@cJn6QaQdyohnpsfR;cb`p2}iNC>2qWwRo|bEF1hDq;s3Ph z9DPzak*0WCooj5~4*oQ1o~Df;Lc}GbWF^!6uv|H%K|M4rjfLW4XKd+={EG+BYs-Ga zHEoRiB&ftCn>kazZa}bmXxwI`lV;|%hiO2xX6pA_wi3O-<fqA2LbfP~k?@HUUjtEd~&g})Z zV-10DQodI0bekR}v+_dAsZo15?lW9i3xBOKIQ_#iUi9VJyZghGhtKR-ZVyjaXz* z+^17}vdt%{3q2rFs9Dg7o^=|;j8)#jno#g3^$77v!u~Wt%eeJPl>=25>c-(aN#5wn zCUv`@<9+)uDDEhhDz!w*uzNMyfbme#Y#!yrjw7DV0K+G{j*PXmPalJByTR;cXEf}O zbygYM-_ci>;5%T%at=>M%P8PCMra(g{nn@$OdP1Ec|@xKX2)grD#t9n7slgk3>~$P z6LX9mLTXJHH7_Ci?d}#C(k9R?EKhk1h<_o?P03)r&yiBgiyScQBRBhpJG0oh!f-ps z#~HQN)s?Y6Fw)HRy!sihTz!Krog4ZH;wB6=e<30WIw2MiHCO&6`q7i!eXkhgsX=4U z{Bw!7-)BQs>&Xv8X~jRYU6YSWc{RJSBjI0g?FjqE+gK)vE54wQOhKtkg59tf7(k^` z-WsmpFL@(wheqLQV<;8(?3VREi--4(e4Ut(lw_c9#M%h}&2=|q3tXp9vu5;MuPSMx z=HSK>o+r-*SFr@k0>Ko$edD(|5DflL8F0#QJKi1yfXSbAy3#Dl}KJw z^pH=`f=fjx*WYJc60Ui@t|mn3>r`jy2%=pY0}~Wk#n~P3?iZW=`A|Sw4E8jdPC7t( zc6`oijLsQR1?Ou$dqfUki5|#0*GL?oJo%P3>;wI0S)JAZpU81Vx}>gbk`r7fwoXZy z_|6RT5SoE&8dd;SAhGC7!1p6X!RkxH)Mz>>fzzkRw_o-)^nNa5w8A10RlUb$X@a={ zXq7(1O83@iaRX|#tS_BbR|wrrtUxT&P)@QEoyW=pszS1%HqGQlh=U?sJFB|#FjS*M zZR-4yM(5|x`!-Lt&VlFZLqddRx42bfne@JgHbh^h5j1q@+cSt~znq}a8Wy}&bY=${ z4wVj$WL*%Uqw3-i_&fiRQFLY0i z2*`l6)_SSa+xseQ0lw1Y3trmB6=Y^d|AsbLEis?|Mq5Fvodm=4^#aoro8!#n$fQg% zo)Xu-j}ZP+CcAp_#nx0=W-F0uja8~cl6FqZIaJ0r5erugHVS%s6AD~sR?TBG- zHlBmipM*14VRZ~*I1m$x!faN4?Dg;1snkc%0zQisDyG46q|RnPHLMx5(>UDe-Q^dy zC8nJu<}G{pt**?zUV`OG+>a@G+9^V7o9@kj_ZaH=N0(@MLG*G=zFFRm4`&c-5uC(N z403$j-VQ{nWGA%7K202q?$J`Fg@MQ>sncc!RqM0gWblZZm{048^X4*)kx}MBd}RdO zsQrD0eJ&<;Cr(fB8~NqFBM}BPUh&@F*gid(6CQbQYfn#dcXOM=iqLy?^K)%S_*?UH zXF~Dwa&LP1Q>AkPD))3}XI%Gl)xoWiy^z1W(7)Gs-&i-{dqnwnqJ81=PCoW>=Vo4Z z!=71$q`#Aq^kr8gL`{xBBes}21%||x7KDT((z3c(JQXtGq8p*XKM-9p5r}cuga1_$ zl;(-LrSB(n<(Y-c8+LxE36928s=`sW8opjn8Oydl5U6Gn`xTg)+}zIDx`i zbVasn&v&+U`+`!I!vac>prDk$Toc8vI=c)OK6i$O%*7L+ax_LF#J+>QZ*FIk*P!cC zUY_yLC7iI)Yo&v;My|j+pD!w9tfv{XtJOTODSJeA8<^{>7Ajy~D=+ML z?|R(g69J3$5J$a6+!#g>}H_%=^@rK=S2?1u#Wr+Yc0)Cb@3*}qk+EAxbZ-lIz ztU8;drb{klLi#;e$LLFlaKtGA-R==roe~gyV7q~TM>D*0D__2}@;DqKzODsvo;Mee z_Y~Ur(G$E>2Tej!7o;?MFN#F;(wHEi=1xhsmNB24=WlR+hwp8v@-0Cnj{AUIZbmE{2&Yc(MW6`@Y!PnR63I;+mpCjyVyZ6 zQ>~>*V%n+nXNi6j1t--|LtUL~?I%JvYlfT2V8*L!gNJes!SyE=Q_CIIC5sNqd2FO6 zR0=|A@0_6=D)+7H;SBO|41;Otc1)JrQ-JVB)D=dbgLEF4a)*s69*EgHdOn)aue1IX zbr6BZ!)T$$Cxf8;>(`VcXeRn0Bla(hrvRpUPRJl_Rp62=1}Qb~N$7QuEkET&z4t@< z>*rRTVW3k_pjP2*&DYZq{~PZEK*KOM?dh%_{lL)uu0D5oM0DSfw_ffi%$tMxyCe2* zRX5a^qr(pH=8ML)C-O^I=*RY$_l@kkH|h)Tptq~t&YCh!a4q6b5kWo)M1pU2j1C1} z;?4GU2geoIygmc;VQXTHv6yFuOb(2B$wXt29|(Yk9n_7evyv(?(vhyPDM&6BCig!# z>$!XHL*6_BZVU>ccHjr{iC(5=6@uyebCm{8Fm~x}jyL2YKnRF{XUO=`MaG@v8n5eX zUmJ~j_lE&^WV`#t!;MuvyL};CAjbWp zkL;v0orV43t#YAZR7|1Qj+4IpWbFOF2mFvn>|`U+f%%7J_JFUAr!-^7#&qN^yo?@) z8Imw~rT=>Ey_nyypV`(8e%(3+BLSZoZ*9cXz5(ag4eYNKl_7G1GO^7yw%N zz}P-t0^+}_Y$cOpycJdTDr3CvX>tD4jI^Mjw+1}G5&7;7RZ3zj2*;zlHEu2Isj@_T zo}`wvCL2v6h{dqPwUW;eOsQ2)4r&}hs&TwwoNEH{a(dJP&1TJ|%B{rO!(cPX%Rjcxhl&pQY0RM$A!HV2yKzD5n}?ift#% zW;aZF$Vt)Z=ad&550Ljz(^1s<$GjhyZuCo+rw&^z^Ae~nLVZ(wQj`pD!#b@q*$Z?8 z{+@!x)$3&oxDY-r6CX7Ck?!JdXyUoIBTp(~^Qd`xq5pD6HszP>(_GCssvRrrBTg7_20 zlT?u;+49aDfE+z~+tg#<7Jw%y-W1X`96$aM=X&~P))F%m(#OB`WJzeYOi4A#>9V38 zD<-C%{OBcdW|!h1;2#OPgM!z$|1i`=`Od(K2KprRvRdg^`K!azF=*omwww>o8^N;$ zN5Xz|eNhJOep>rMF!m=X^9WAji%#%;RWlsjB?iJ;V(eboL4+Dg8kihot1hwgD&yx= zBzp_23_Q=Wx?(7n!OE@R7PKJGJ63&O|SC%fz8o!q;a?byE` zW4oHmmO+F={kK6nWcRzl;7^3Z?$F-z9QA@Y@}BHZ6fwdHNX7ZLl*{Z7C%r4;Yj_>6 z>H-ZtOZI&RBkspnhY1G2?bi#b`{d|30i*iyM8%8=4d-v(H_DjxJLEmi{kXfPQp~VR zkAtC9Nvad<@Xv)A-wG`S>lU&hBH|B>z%C#cnyVmtq)E&OD~%wbcw681&UY8d^{!Gz zyl@(_MB;e%ZBJpod4t8J*kPi0)=~2egm9~j&R{Rx6Ud|o=M2nEGOU#*y+cZgr*?C_ zN3mIvi(@!8;Wv2GiWwuFNRB|X?19ifNvV9GXfIr% zGa8#E3f1Zz##UAnq&lIZxo1Z1Ru1=|4X~DG^%O@&Ya{kdvBH8%Rbu2n6X3VSDKy7on~pp37idpE87QL znGv&RZfF+w>V`k3e?qccw+RK0_a}S>eb~fJw3=$XC~{Fy(X`jbs-XX>(1T8jda{8X z0d0NV^Mi>st+3N8Q=!McZvfp#72x@@yG6X!f>t=%@fP|;6R2Yb7CNB@Wz^j}FRAZ4 zE%^TIUnDm(3!h7Fdk8ewOr@YyMHZhkuYRA)&T8S@1?Li)tO#~*aeHKAp+;x`ribBB zD1!leSDVd5>C+4$0gctEk{q_Ufi1$6^^ruwB~ahzWyUOb*fwwzU0O2s zT{6BBuouyz7GsiT6UI9?2RU>SQo{9IG*u zTrWxU2?I`c!Q#B|36#xR@CIHtP|vvm?w`AKFCMF-zBzctU|0VS06##$zknYb2cOa! znzFmO`>jDBvj+vhZgT}i1^4O%x1uXlng2gE&ZhMyw3$&~HBBZk0~rs_1Wk3Xu3W40mI264!IT$tPY9>kzfx zMJL=L91m1NG|oY-qFIhPUCgS4{~W%hHFxKAEuvM&mt;HiO0gqXi0G6RNeevU`o#+` zqEpX#hl%PkO+0=#d+KEs3IKBfM;?22G*F;JYu$JzIskK=Y`j2O2r{Se8CYYApMfQQ z!2BjknJin>j)DCnULwSgnmv8{#iMY_ZgEbKZ?`~Ev(99@1rD2yn=BN)WhqP+IBIr3 z_R7MwCWfGOmiPe`q}DEpVsU$$h; z>_N4WVfT9%2p7~&i>sY{o7qU3@rufh|?nTzPOS1B2&xmIp zSn>E0euV9YY*e^sOxqBcCCv6B*7plpOA8lgYv;w;VlvJiX{#H2=EXyOD`tqby|Cl; z{d7lzf*)>6fVh>VcE0hp$wrv@2i@}RF7pq(O>J{wqY)>6&c)tZxY%1EZ~@nh;kQP3 zjh*@3tKfxmlT9m|aQN0^k1(HsixbT%(Ky@-$U1z!#^Z1^pbN}56xYEI#XYGr-ggqL z`FKvFN}7rJXeuE0n%h9-96`Ad+fhWA9$t04CKM#eCzxxo{lr6LCHnoNoZ{k10DdSaKT3C?zW3f@dic3>3W^g$bx9OF zF%_!Yy~lq3`t=u?mz7V2>xxl~5J`~CmDpBeCNhbf>Gs0eLw4W6A-luPL+s|hyr?2& z*lz#uWAU)v?roMUH*dbiw5)1c=x!&Dm7RQ(*@$gK1-K^I{Dn}QK)e86<;s2*uuHRY zz>HD6kPT@*5tBAKmu%jA6_Pd?X-T2H6VKu(S&~6@6fsYi&l$|1@2~ zvz>uuG0WM5;4iN45JyipoH2HA@@IcT)JY=%d=l>@O+30CBv{Z8V@&Kdfm<&YGsnLI z;9<^wmcIDX#q4JJWW#diHO_L@vWGp4h}_BhaJ+90rgwTUiu}cg%p9@5$>uU}2S55Z*Eg}dvJBiDAno+=TN6qhFyee(eJR*TVuKeM$d5;^<` zVNNrgUyN{?-}TtTyH{?VBS<)Z!13I6;g0^)VZsE-TE5_Whz~tcxeSDJ+q^O$8sUo; z8opbY?r(r7*Fiw=hVZj4sFYXd-?PbG+ncw@l0AV6(n}dyr%Z)@PUPYZSwPjAo4;t0M zs>0%RW^9rhydq|jt5}=|{t+|9g}{G$a*A(wfNzS+?F`D(HpeY+K?~MIKgE&4%IK|= zjzA`a0VMJ9O$+G`F8290i7M$-*z@|;lfet8+)ZGsI)SN}1rFa13W?ezNgUlZ)3fSBR6+{9mcJ!66hKkM zCin!3C6?3%SFn3#%pp(AtY2`5c`lw(e;>}K$Kk~+7k`0cimO)HZrr^224nVAV*SR? z<2m&KS1iJqvle<04w*y|QJeZ?`=K_%lYGnI@w}p#WiZ1?{?j<&oY^vn%t?HcprUtH zlOPeb31Z7qUd$SZ_~~gJ{rL%Jt#K01Ot%SgF~BdTun9KcxD4#g;nU=YTLK?XVgFO3 zgTyGYi#YcGgj(|>7R7FrID^>vKg~%GH^aw?gS=uaziW~1Xo8XG;0 zqru_p@sIPPZm&tlQMYs!;=Yb!vZtc6@h5^t6#t*#enjycBxBl%0b(tpcXD~tqFJa* zv6PJ~(NuLT{Olm0%&}fNG*EUIR-8lh(c{ zHE!J2oU%On%Ar&q0Q#W6HdcVU}rv(`YnZB{6ulr}jEvH#4D<3n`nBAV;wpPL{)-wN{LUVeOzKj-6m!rSk zY0dVN)d!ggK9bx?(}#UbY}K{K#ENDS?~DscA^prH^h_O;$y>E-s`%p$K${II7tuNH zUnI`BP!C>+WtUH^p296&BXUij&YZk>f9*T}d@lX``~;i;ixYJ*!U4lF?j^MPoTXm7K`e3R3xLDsE)eD3SGuO8IS`N=0xJ$ulFWT3@JHpu=O${% z1Us)OUAI7MUB5$gA@sZ1Wytk13}~+mJ2NjD?va4Rbn#4; zE+g~UO6ZgdCGVibbLgt%I+;)aY({79^!1?6V&0#4PZwI`uU57!KREvLskP{fpE1d` zHPiJ1iPf2(nY6c#h0P`h^T*T&3decEMfir$Nc0h_`O*O{w%VGo>KR;y5z&-=Ki(!^MV>hCrRXIO@TRm9`n(}>sn)TcC)W}X?~kw{6!wF z{Mbiia`j~9XEJ~0Gr%E>tuV)GV0c(@@@5iYRTkCPlB$wM=D!6vA%s72*d}cQchau- zQ@qw5MK0lO2T}m6Mt2GV2;LaKVffLq4pf(K{A`_}$={a=6;s9e#>ISc#Om~^MN?Zt zt)|5mSALS@`rci(|ESR%VZP%P^Ao2yW7AoCFy0;fs+P@p6pPPp#BVW z96J^(<@-v~Do%ci@o*8DJUp-+Vg86rQ|!60-f*Q*STGYJi_$S7T)b~GA}IDZqpP$i zB`RDn@GH~#@gCgct`2FsOXpLg*f*mP63(R=Qp{|%jC)rLpv~k7P8URiy~b1j7=*Ip zIxrFQu}oO`xX)1XcuA+uoV+tT5HUC>%t<~mqFL#f8cyQh{H*l&xGy@wey8jxpB&=n zuqA@N33n-s-WUdm5x!32Et-8xQ|t%sG^67pJBfDgxa)^V)bY;Y3NcqKDS!altnU2j z1f(~O|Fk8i!qv141xHW(K?^2vm1e(d;zk}7Yq?PAiBX=$$CYm`muO|Q*_kBRzqh*r z!F7kx2lZjj`p*<+aT4*5Sd!#my@<~>$V@Jn-HbB3zDvKx>AM|UBa|SVk}n<@ zzq!BH5Ak6| zX47_sR9ySVo~~pPJULG{*GwBnu+YR5BiGkrU3jqEUAusFg^j<(Bh7qWU_zF}$j!aj5^$v?K3AaC*v�L!XzJccl)}!A)V8S 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ɲSD;H&r=zK(C;oA?&Kjql*Q_#VEGAK-`h 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 H00000VkJh! literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-ExtraLight.woff b/app/wwwroot/fonts/Poppins-ExtraLight.woff new file mode 100644 index 0000000000000000000000000000000000000000..8eb40950af11a1a66a7c97b0a4b1f0feddfbb334 GIT binary patch literal 66456 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 z%0D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 MO#lD@0RR910KBVow*UYD literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-Regular.woff b/app/wwwroot/fonts/Poppins-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..609eb3dc3732cb8064bb2c6c38d11be30e29ee2b GIT binary patch literal 66464 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%0ALzO^bCpDN!m3v&^;(pdW`7QgE*M{ks;-? zk)J#euW@Og@DQ2$l+E~!ktgr}G1y6{?imYpXkXcL4q!4P(9&I|wbU4h7wyjX-wV%F zWRc`p{5hsFtpyLl)+8Pc&CNEx^AB$z{sMugkI$z(O5)zW&Swj@ zgtJ<-kn6M5gz?HXocLo63*eHdv*FcaEysyB#NL2{=hXlfVaJ8;!+~9n!=L3$hu6)$ zZiT>q(0_xAS3^>E!Ruk^;B2g;V!*&j01yZ< z&lu8DBuO%EzJ?b-qXwnx#{<5(4zX?M5w^}oO+#}qc0tA)-sQAUM{ep4{%MqRLT_se zA2Yuu+1f!tP2XpSYKxy8)t2J49q-J{o_J$XFyhdmX(wZ1Vy8d~mN>grnfJUG7qX}` zPzukRf%fO2v^)N61p=Q#fk1HC_%(~Vnik!W0Js+e8$UlC9Y4QQ`J^M8h8fCQhqU>F zS~5gr&jAsjE$pqFchBwaeDe1aO=c-&&JPOd(BxIcwW5s+7G$3Ue$Vil$0tW^Iw&QQ zglIY`385kN+D~1hR!R2$ufdsZd`jf9O+{(-018(NF`FV4!@_Dho_k!(yI)hg+yTAn zAM9}jd9s+Ld}!1t#XObk3`fVVeF{*e5H{P2zG*)xS*8A>3?6PyPIe4`{hTSKyy$D? z`^Ms+D^%nisUlJ*xeppYkPkn!Pi=+a!R2e{*B6U-*N17AcG!TQ0lg4kF@Ah&Fou$X zyT1ZGW|Wk`c7+9ZM?dUBtxAFde+Q1{&9gjX-QQh2TYgM)Dk1d=3GNOE2!h!{h^4?5Myv1%fPyYNlJcxRV@P~*mHd+y@My0@;n*O5Pl z_V%DXrDYHRsnXGqH!zULRN=VT;V;W~UqSUfUmJd5u;;i)sMA~MK^%%bLtu|Z>{3&; ztiFkj^Fg?vlQOoGx8KDES?Kn~*8`(A;m(yda|Tr7{MwJWYT@Tsuoe{;4^h+5rAx+z zR}p&2eZ0K&X=v}Q9wko2y-%_s1DWq8i@e%DZl;__ym;LlQc*c6|3M9tj& zTs{lShhn{U#I^V&Bi=8H%rYDNxtcr-nly{GfQkVbCQsg!McBzQISUy8i*n@lz}K^% z=qEBSLz?l=DU4~6(bxb+3NiK~Cg( zNi%x9cLWPEWFO)b)YYkFaycG4V+?qXINc|OZ&#L$!Hx&`RXO#uZDllt{CFs*#tx%N z`SmFkYBY)URu1#sv>$)-s)CG_Muv*E$t~{E|4GZ5kclqtOv`)kt32S+rO(hmX*5hs zXHbv_J6mTvad4sC7$J_7ko?4`{6fi2OG!w2vw6~{i-*dioPBM&o=)auLM`C9LzvaD zgs_H$AO=l=E&}S5=R@{ya4WT#0^^O)e{}D1t!*YGtJW^4`3?V$G8nRIaVw;4SEWfR zYS1M&v-d`QZajXZsCsE{(UF99xHw2DW^x4YxoCP(irB#ptu>yjk?ZuhZapV#zjmbloREa9s0{=Xo4#++6B@a zIQ>f>g>*V6; zd21H;`OMh?iG-1uiByvH+2{iABW#DhpZOPJ7b}@X)r8LL3R`)ccjykggL58*kENNO z_2*y0i{5d|UK%r*YS@A3Vjy-r^I{*778r0MJlQgTgrq=D^No0&dY4*^MOS$}-gZ+o zs*)l^WXAj>a>{A)S|YERte`H(XzKYZR`+mjKtFgQ?8)h_G2kS06h7zyU@HEOvL8G( zrGI=O6Mx(>OOP)+J<5_}nQXRrX{nf?6o2*{*}Dkasfa%w4+?5|v`Iuz88djpTn_m9 z89$TrnI9L9afN>8p^gt*W`u|)DU1lg)ckmT=drdJMUTW%FvtvSb4D>qJku%!OiI@3 zu=dRwOuEQ5_r@N#eGcKDD=#3jTIqzO+4cU2v*@TZDPb(K@^9P0gnMtK46-W~7S6J& z!7whY*K9~__oNSC*xj%tcBux^=;w>mOxRuMbN_T>BI%XHLzzY>KH8pg+qt1jtJS4} z_g!zC&cu{kbUQ=U#5S0N%=@bhn4`@u%Sb(r10%$ltSTBRY*%^R!Lo0E*x%J-EMz2K zHKdnD7!adHf7D3%O$AD|+Zn4Zxk^hr8o)NIK2rBn@<7Fm_I&@jkKUcC-9X$4bB!$V zQ07yf?>n%T3?{%sv&B@)n4HK!O|$jSH|bT8D7Pk+1-lGu9(AW_gt@(UbsPAXbETrB zDrr%Z3req|A5R0Ld|%vaqjUzVnJ zlGBz^NQ_v5K?zcJ`-i|CK6|=Y0@jD6Jreqh^zo(o2d3lo-j{h%Z+M@RX0X~-9buO} z-;VCaQHaiLo;Pgp1%xXlN#)vh#CXBmoKf>OItF*z6#PqU-OZPHZEO?+Uxogc{VZgB zls}FQQiVzHF~Cyyn`~T;vFs{*gF0E=zUsUYRBKxqa$~JRib0>{v>F_7Fa^u_()PyQ zMP~B`IkOs8wVQb{wz@xCZZyh6VmRkkSSd!GpHx!HvfC5{)c9TP8?Cp`PT~mJ$#s1v zg|?a-!*C(d%omPuv<-arVpDz^f|S-b#(6=3lf^V8xkR@uuhWg4TbSs#FLgil#<8AN z_Mo@)M#B9vtI{LO)Bi0|adS^x&-r>iRVB&MUof2#fQJlU&LpN0%9S)25|zap(%?9M7CG_#eJnV+3z=J1%g729i0vwQ!JQ?Wz&N^7Vqmm+kWoCWRdpQ31H?(Bn;~c-R?od@>3d zZ}VM2ywhQTA9V3~ObQ=mkVCPDRY6&=3=@fJkJEC0gH z0Nr3vVjte(&`!d1k9?N-Zxa`V+$g9Pg_8P<-JH4e4a$woYr{JhBlvy-g~1Pl!O{H$ zD=O@+SC$Ce$;dc7(B^IykCU@?B|Xs#&@$yKW594#X15UEH3nB-tWR+4=)SDhuGv^D zg^ZjWDvMX)QeSj9)$4tmFVXYMJZJ)Ga{>K7zL<_4tex>oCrk!N?a+HUa7TEp{?ttk zy+CT0YkSbNI+j7J`UMLp&ksj7PNUhcU>2sSqv=Y}5j#1B_}dc2{UCh3 z_@Ns_W{HoucDSgK3i|qr{8vV=!J!!=YcB6__0FKn{?xsfCY5qLWu@K?M=Py^n(fm9 zipQ1q_|Dka(cH5KIr2|QFUk-&Qfx&}XKD&=K2;rQf1XF-^U8893M^{u$uEH;hkEMn zMTP>el1xixg9_XwcYG4o(weH`>w_KMMcA=p5T;<@V@}`>eFj#a7&0gi>V84`FU%0b z!4($)cvVa-MSo7DgeV@^M|Wi+6W&+2QMQuX8#yiF{fyGaq^ozwD2;1p`K(^MQ~Q3Q z>@}@tlN=cO*iieyn=8<3N{;i`IHxSU3s|RSTO)e|LgiUW?uHop7`ICLH`TG!iYZJn zUhD8XgLY^M5Iz)gf(w^ODnCMpU@py2+~=l;;`F2Nc0!K+3$W~jvaet4CT_OoBDywk z*!G2=Gh*%dpp{0#@aO@&?ML5x0PUFjzjw?-Hb9y=ZxQ+KtKB(DOX65q7+NsTzs)Dr z3WBq5_3W3~@RnkeM>qK_Z0*ep$J4I^+h zuznTUf*ywWCSqF6C%LRrnrlzcZAYl2ubMV5)_gqBdMYRCQdpN4Mtm87Dg+7&@W$$_=}n};z3$SX!)viyQj*0X-miu!jZRSAbxe!m!kHHKO1d|G z*t{YHfyhxkEkILJx`aV>umRx6GNhVEP0>|ZQ*khx2G4d4AC}F3Bvf#SRO501Xy11G z$@oSKGYO3r{V1<@L*2}CD=~dS3pY& zq4_qd-|KBk8zV(#5+I_M8AVx`o}pux8|RJaMf^nmjJBn*vP@)YvY4_dpke3B^cQP}qRCJ_OHf&$}YiPr?9#rBaL=1Wc* zJ{J050_Fhj^NWtI7x(a1;0uY>PGRQO_9%V-o&}Rhyw*q%zfElf1LMz2u@6q{;Gh-# zBQHs@;^pwxuO?L5!o(Ajlh~|!Qu@0Iv}o0VNtfPOr!Dd4R3553ok_s1(uI`R57UF|ps``_rQ~J&$2{1nN>NA(c@Lp&apXOy8Ti0_Q zdJPpEE8ZT>IfpVu`1zan`Revt3(u9CD4Bf)d|Mls<1HSFg+sEzBp4WPhypa1V-Uwt z++qdXuzNy7RqU_9XhbLlsY~Y|9(EA9$=Iag}zg3gm)Pp2?0!j@p))*(J z>oeijA4x;A8za>ODy#6#ZJF8Yq4-i$$=#XYIyJ=9qSQ}Q-tuD=z#S(dCs-^?@>2t2y^>DdJVW=Apo9GRB$pgB0@yf=(ONY~EM zvTK2_VJl&K2d81l%`g#WW4l>;80>=Au+v7*B)YmC(d9F|{__X*hnyaDi&kBUWM`BKK`*Zjah-^Dgk1h=- z&N)yNrCP8^wU9)QrX}x$eC7H=TiO|W31V`D0niRph1dFyQj=>H$!N5FxvR(D=QEu1+L#l-4GpjxSqTK-XJjn#mhl z%;SVU4bqt0IM;U=(+hAN{%U%?MS$Prnp%ZiFL$&ay2msxpwxC`z>5zQ{s4T*hT^`i zijv^hP?pj89rpQgDrKFsm3OMTO2$C%vGhdEQ4t*rKgLe;r}}CYE>zJ~{vQB>Kz+Y7 z71ZzH7DQBlc+wILtj8Hrpys&7TgZOou^PTVS{ORy1;LUE@jC|AaYJs^%^h-M;N|Q# z8QM-g_LtQS8l7)t(auJ2^z&<6D37hPh#MHrrwVw)}x$b zc*##Qa#U^Nv$n~`Mi9Iv@bN%G0m}R(CsFmG%L@F=85m)T0)ZOS94j2hN8dc^(4*X7 z44|E!ePI>&eh|{=CIw+3nxoVWQdBRncowrOX9Tq;k50DJARbRkvQLT13`JTy&p!X+ zXExiNfeR6XinjCs#qr38`4pBb$LxYgj_*SmRqN5ZDK4k}GH2y1N4!;GpUoGkLXfI> zanm`>&ne_PvE{siLXd3K&s|Gxho@ghycye*Gn*yAIh`~c0Ei;j9a@@TZI0*!X_OgR z)E{TrT+P9IFu%f$_>_7Tp(Lza-H(O+gaYg*aPe=b;o68x8FfvrSXwKdyIP$UIJG2@ z)T{%4V?aXFZ*t59D;^EC%hYq-@YJ*3sjAt6bEq?X8!VvXcFad9Atf|~gO61DKeNKZ zn*3ACR+uV}n;RDWG}0-qSu8`W9=?hAF(F=>iM|D**o6ly343$X0w%l1gS9brNmW!$HY1zHY%I=L>**(X)Yyms_ zA-Xh2x+Ka7(#$$Pk~AejUv513fz6l*pTQL$6@-!S5N*U@*jgW5USW9=z{*M#YWKJ; z1A_0;J`*he70I~&Eud{l&7CmO2s#-O6I@Co=v=bEZL?x(4&vzo*Ku;N5@JJVyImu_0Ftt)-t#|>ZMuP2=N@OWa^$`o6;Iy*GpAAuW;BE4!gHu>v_@a z20~1*4A@dZLxgp}G5t~BYKfyi@Ml^O=RN%JbmHtvkTJJhSV6X>aju=Q8*`4lSEbx? zg!*)r>G#=l*;ot0IPLrYgjc=_{J-FP`dxPH|4#y-KH)~4T@nAy)<88AjUlt4qr zO%aPjjF`RoH!jH5y4?g~EE-pRIOD=VVS9qvLX{-9o1ycS7g1?i6uwNig@-S7I~pXl za~%3dZR$9WtMz@cddmRX{!w*QM~qiuF2(mZ^bnKBS&L0Iul+>Zz@hPsJdF42<}KX@ zV54EKCfrNOoW|+DAT_9IP0REt=p*;jcXQ%csKVQ-SZm8%Bl$im`G)jCT3J%&Gkn35 z532$9u{P00c>gDRxL}MUypM@-#=+#KLu}1JC`^9rTSNpN@3yT%32qH)K=kNDrulF=; z%F7t@xHg$0CByGHHqnxnJ5|@VDcRwgJ_U(`{Ni{n+YGnap;h~k)Phq@6d~Rt&oi4;wJlSq976<&kl$t%^lv(AJ*?f|7I=DiWqsRP zt0pyx(uGEQxb$DWo+2N(@nI` zSs4~tATE#77FJ9}p%`(Y@qqUcx_U_o_2GPl6!Z#l8J?ja{R?140HPzd}=8t)Wi@(6SN)kgW8C6YB;) z1+qx_U}+SDiYP247&zd|TI=@iGE+12iQ@If?&skn$NtEPV&^NP1CxE~?i$u0n720x z7UJ5{)Wzd_tZQI2CZ>bV`?1_Ug}5~n9-?PX-R8ye%UK0J$KmUR;Hmws>4TQKaV<$5 zoo_-spRvwSH<(6sQm4k`2{}ZFa zCw0xp9<)WR=s9oN6UcZ8V8E384BKi@g%$t>O~$#dL2F>p*BSU5GJE!c1n?;?4musn z8Nj)9LeDVH^#!Ph5t8ElDrJKikTmrFXn1DfKcZ_9zfQ#K0I@#WUeWOh0H?r&d?6HK z4?2<{;zGBQgp_N3sfZqXcQhd9$%Q(-H-*YZvVqgfqwX+eWG*Bp`{T}_pj`H?5heAL zh{mxu5`JP0u@y@ydbRnIyyICt7cVd2u}GEcHNA;czD}()woG&njzyB%31{6ASnF#K ze8@`e%dz^+)C#(;(Ddv!*4(Q1rQ!=s4R+nKRZ+$EU}IMkBR02bSD4sX{i4sDS%@a0 zn;4J0i}Zh*UW}BKbM}}-ukrSk;wi%dYW2mjH)fTJ+!nYI$tJ&OtLxIE+c^1z>@%sV zj(6&nmQo@6&O$n`hi9Lja1pIYuO`AXd;b^76wwdU!ikdb5nUV1{WY&yO{o@|cE^6_ zO}aP1gSlC7Ba;$5dTpeXV1r}v@)5-)d_qfTdQPrTNNdm%5t30a^4+%(2Z@W1C#EZj zIsUmAS%`%=`osOGB1V64@zJBdfgSORu9h(*<@qM*lKkH<#8Z?fWAYy;I{drCDXUw) ze0>WY9R6-tTyQw#RWv&nn!Qw@t0{B{3Q*{XMxmzC*B=r(vdEYLoUPR19Lm%jWK2nf zqP8puh8IM!o=uYt5)O$g$m@Ks(^HPHH)A!80ML-Zs5QG5p_!-s*{hZw-%;I8s z#QRBnCIx(kKReL+d|K9|Pv4uG(W&MSx^U*bX*YL5Y3rbMBqhVA0M5V_EXUw{yIrMr z*k?DB+J@!g;?kJfaNgO$*3{$|P;Uj9U&d`EG1`waXSsw1k15CRJlqnY<2bA2$SK53 zM#v(f44Utu-gbT4>Wmgyh>8o39b)+OjIXZt_60mN>*SvvdMI#7kl$N-6rm|oxi~vF zf>PT}6-QXkVdoJl$nc{~kjPY-!`zlI_2mc%mU3f$Gd{1cB@pUecWA75=%FcX|S=}7Ak9PL&2)C7+3wEV+r-41be1ir0$ zQH!sY<9uLrji7T7#Xh%(>-)_i`o5gweFWF{)Drcf(O^X81*~O@r15jpXFL&%>~BpQ zth0_}WVDCs`-y?qhs@T2wCPuQTCew~gC%r8q!xQBdtKDCoFH)eOs^^`o|VMERBGv8 zLv_Bgj5@*(gNnjsF%lw+m8>lOEBqVE7F7_{NDKU7*`kOBE<8!Z*9|UP6mc0K%_g(j zjPgZ2>tj`Ie2Yh3pOM#(?}FIhHhn5%^;*}jY-pRZYEzN|&*Kt8ovc83mqiSBRdV)^ zP888sMK}Y9(ZCRE1zVhSG0>QBE6>UV^PUglnO!?986j@}5%1Dk2-oahQ+(dSqQRb9 zL`~u1N1i-F_L_d&-$qHb8ilcCyxTu6)O7RZ6SFKZO7l}GIBX3dHHc5-a3hBp1t%^brF9gP|p|!@7@8z>~D2ryR$@@Bd`tYmIGkNG{mPvLFTy#QsIdWxL z1a50vX{CQEmc&ZGk||csj@_@kvD1TBxG{Z{*KPn$66|?;++IPbL!<->!0ds$xo5t^ zBq4Z|*}vVEOHl*By#yb_dyvPu;GM9kZZS{+P**C))0clPKfLA)VH5W9=r)1JIevEX z+Rbb`iu;8Gue}bf60AN5KE`L5l!Rptf~{o1@_Q=PoM_|YAYRQplA^d_U<*F`FZliN z^dHU6a%sJ@#Z>Q05w6_W1f0}Y5#VXMnmv&&n00m}+ncE8L-A;WFW4%IDvo+2|A?d$ zv|i68AB1i!3BJHc17p`}?InX-G3i1ONE=1q0(23sQcsg_?_4c{IgxH)Q&*4jNT;r| z90^iyuqT5Kd^6juJ~C(5y{z6n$Jvt8u!mR^qIdJ&SxcZ+jw8Wo_ySw|RC3m!-7rL# zAcVgM3m!}>1UCe(sVbUww6~jWZSm}twzXPq_?<1lY^N@$OQL`3axj!-2vhJqoh|&F zQB=}YN>=uHi@Nz%pvO1g?!GlWw?}0d(a+Xt(6q0Lt5?X)fk%b1h3~^{sxK**_)Q!u zMv2NAx6u8#XdX~!WA1b~Gse}*2|0yR{QrtqGNypH$Bh_oYjh`j)u>`db%nh@;eQgq zN~6t=sy2&ja~M(doK-?uFDjKt+ttdp)OdT%af^kDi-&H5$yI8~3u-1^RjZmXgxiTI zazR3gTyIV=9W)Wz-t_cAvtd*ltYK_C!W*&P+m=gKg%u2aN(iLRI;s%Xc5MGOp zMcNB6RzXVW!fZp-VT@dnOenxcLEDj()nhQsR`qN#nVXi!O*HmTKPk+KcqLFz!(lA6XI@6Tk*RYkQ&ggJV z3~-cf+?JFS>M^o1+<# z*;|~1XHM_rU-2YwNp*Vy%Anelv9D|x0dU!5uhNezyB?v>CG=17E_Vu?7p?`gWB9;qP_bDXmR0?K-2g-$gyZ zT~I|5$Hs;0u@2so>I+_mu*zWb=xmL{^sQC5+(h46b<>^fZ8@S5d}hiP>JQFVJDE!d z_kq(z{tmooWWO(KgJ;)S!u054)`j0*?uEUonBA> zd*BqB##2tAtK*zvs;4!x-7gf5ZsR;4LX^RcP65#YHH^n2=wnCYe&Km|lqz8XCw+*e zuf{h%nnL(Rx;xLEfLND#tOnIrji=qt{Y#e`sjr0 zi*st{os?fX_ZGp*Vv*ZJGut;BJ1~iOW$zjnyoxm@%8qh`A>tJUB5Ojog>#>r9gqgk z_LOOh;PbgxkvFLMH=L>PwdBkV;R0G;j0^19MxlyF7MzZJZ#cMQmON2vgLw0FkKn|} zw}>x~;nSF&%H1hW2vIC`MLL=l*bfMsxNY`iUDh7B$$j-rKYFSP9 zvPfONrHM|@oRu2c8sGEj+43&>@JZ?8vm&96O$ygj@pk*{@_cuywOsA3LZ?fdGXALC zVGsP(rc~PKg_-qyzvfw0EzBi?>$M-BE-52wLf7l)w1zL#{{21#3u|3d_Sh_`V0uir z{V>LT)zs>OtMj4m-ZcXa_DUa3>1CJDlwR^UQgOU8n^ZyhRbYzbQ7of;emf|vK!C+{ zv>hziKRcGOXgR)1Xg~bQSRZTrFxm(kKhErh89a7%slcmLZTQVIf=_w!G{YkLJGOrv z*k41)w7DzI!sWz7vz5K`!h<|vN6>?FtzC6dltN>|&4&XmOu27RBHY#)CEjbOjZ%XQ zm;d$+@?$>C)i|z=W+W`Ld|_S|W{Qmhd5nQD1scbmUgL1g#nG7BA4nN>^;0&MF&WH_ z6&vi)inQky<4gt166ZUzUQP_+$q>TNJXPD#zD307Rv3c=THlV?D_3mm zjc`?^byOv|Vx@yu*YDUv!aO##?Q8Xoh1_7N88$YR^21y^Wtc!f*<^Z~lvsi`VydmKk3kSNJC(@I`F6Ug=UbH|=$9k_!7PE`l7ht?2 zyazRiGJ|fSB@$YBUOCLUFHSXQe+s_H-95f8Zf6wsdH2Z`1sr5fZc)Um$(#IJLik?W zo;G{eoJ($xE*@7Q_1?N?l$M+uz&P-Q9f3NzEhp!+{f8cA6|| zt@-rLYN`)@^6f$JgUw=U@H!@T0bq2Q8hnn4-HLvrr6W1D$2d4OX1Cu>Kup7{I5v=n zQNeETM|yh#ulO!lGSKJi>}@jWwC3}-Z$HnZ)frFUq^5e|=RchKSijHP-|zMHgCFd* zhy;7xP+DqN?a;b)L$zJ0sl5h<4yxDXs_BVHzOl_9*Hl}trmpMRUezM6X|8NGZSlBw*11k;Poc(yCDc3ZsIVc? zx1p`E$xYADJ0|vS$j&RN&cVKCRZC6%CKK{Kz1#F#?SVrZdqDF}i%X+}q^ko~HVtYc4AAAm>}tCDT;vYfs;#r~L4xw@$NL8oelqV$Nko z)n`|E|UReM)EHuNIbR=;+^brLdn{XNCT_F1jXmc~`{LMiobdq4{Y=y7iJ1peJ7k+dll^uIV@zjtEC)aoU< zrPAD-0iA;$@Os;1ZR{R<;HC{dz`f7x(&!;+Ye^7$YmiomTWe~(V#cRg0qsE@b!EA&A$FVZ%dC^YWB3dbU2kZiiAC+ zqVyM)Ar;UXI#N>oX8%OosNMd9(^*$n@3uU<%5E_^%S?H+rJ){zw0B}9hy?sHL>~L% zNKq1dR!$Mp!q?n~E#|QelOy#uYwhIvvBAmHU^DbK>Wv=9z(j{c!~D=>@0%ECSWk_@ z{a4%x31?}VvB~PrE5_eFU5(X-s``r$R=yOcgJMYUVD>GVQB_5<&F0K zi9z>9YBQWT=MI+gQ(}rXG|BS0ZcbaH`5RS&*pD&J+Py+n_I^ zy3fontZ1y!w!|lTswGHw6ooY|M%q;WQu?S-fies0`t$HH_!-{6h^{S&_=4*E#b{Ib z?JTReZ5nCptr3^YNiFHKH@0ae9iVRyztPsvapGp*DfNvuTcdTS$4t55yGJ%dL2rk* zUnec8F3n#On*lYZrrK(E89F}N$22Yzp+<94t*2WxS>HI3mbupB9#;(8?N zscofHi?E!wqks6%OP%gUtXFrA?A?$Q2Mf#P`5Pt;1Il_`mA1NMX>7tWbG_fC?UGve zdb{=-HzEZaZwH;5&ot;rXGc)KuErI4Z1ay7r*Yh%L|aMm2%+g+QYJ%#(Q0$Hlos2Q z8rz!3vY3I<%ZeqzfoU{VSW~F>Yf7qyn+@%W>Fa|7 zK@D0gY71Il_hFBCjBP~wqV6PISR!+4r;<0$e@kJM z(LSCl3&U9tzYT#Mb0r>g2a1+QL&kj3ihTTMphe0EXQ25U-<;JXW`@1x|8gK&Ud5hB z*|#?f`kN2@S{0^L_sw0{sRPrp2%o+<`UicnMVFx~xz!vOW;<0uNFx;KD z)3+`~Z3?)An*%R5Byq1R(L?BCK>s%1xV?+He^(CRr2-*1`LhYNBR z|M~oh0np9A-xBk;3G*k#_$UH|U(5Obl*g3P=eo~a@qb}cn*TC=AINcY%H9k3AH1`R zxr|m05&maCee7${pOm-#9C_tE5C&c#6PT@#K0hvUXdB3~--&C}zef-PX8%($U&TM% zxh!-$joZe)8k_gMXTr4gEj{#Wx1C#7cnxqLRJz=OD#454TZZTEvUhg1`YpTHTY59> zZlR}<&YSlS3YqGA?Ed;B-V4&sUzrZmHEW&b9I>6`3e9cjOJp@uQ*OFha4PlatfApo zkmE@zCqL3{T>w*g2xZ@DLy?)`sunHJ7FHnc&;c*10Jr-B;m)2l{hjFr+t0rEgs-~R zX{+%C4_SeK!5!HJsy6Y#Et;_r?vh2N=YqX1m$RjA^SY@Cy{A&oT=rnBw8x2CTefU6xM@A@=oOCc zKx+C?aDR-I?P{i~I4j#Is({Jn4kNC{Rn$h-3A<*6*-I4(B>c-2QL(f=lROc!S1dC1 z?eSaliHfjOlMBC?J@>f4yP0#0J16G69`g)i_G0g;^Z3srMx-xEF!zL^@ZbVx3P;z6 zaS(GEB?~_>xX>}dPyxTsKLE(a0{u8!VOby+h(7H6TJq!xQR;~eOb9}G5$;~#l1o%1 zZ1)tOc3c&V#fUzDkrX9_Y|hSXIDwJ&Wd#qg1z;FrYqoj&1_UAo zldQ$nFxZ*CKf?ZUbO$4RwcJ0q-0i__PP(pbz$Z9#I9ShiP7&L^dzo^zcKd9hT7sqM zE=-Xu4E3x4H7f3YqHv043AzglaN@vfx)kjekldwXZZ2v)A=hjPR0v+?gU}wR)~@NH zeieW|At_el>x|sBD9}P%zXuHE4H!yEH?WzcIWLs0{V1d4Tn>Vbi_K6 zR>(tEuRH-N7e-068l|y$+&?gu>r~DVbPVoNgm>V!Q zWcOJDs$&5zpPareH|qzqJAWlS`IUi=Fvie zis7%Dt(4FeR)^$Vm;WPc$y>mQ&vk|#~h&nk7a z4LR5JaQ+nHUPC&QE387^wUMZgj9p&%wlq~FAhWP)zYnP^a$|M9Y5BVvPrE$AHEL61 zzKtSsTQ_h7zJXseuC2o!qNdfAD*Z(#&%I!+d&+C;7!E}?V{Qb$B5wFMMJ%2X1^>hv ze=+$L+wQiVIl23M2QH1k$eN+yEnror|2g>J;a5inC;Mixj82QAIr0s0Crp*px6=#F zKp(pRvK%~!IM6dT{dif3e%?&*-~sxuuWKDzwVNVdYBxF7I<*Sw#^{5;R6me%M}4{T zWmcoX5}B8tmfBJJ#BZedZN>nv#Aqu%`VV_?BF-t{;9}t@gPd-+InP|?YD{ugH8#7O zfTN_Ms>o7*U{ez%h7X>1HTbu+R%6Rhmj?a@{+L}%Zgcl_*jF#fELLjDPgpf#9~wuX zzXvcKB232|6r!jAD2|Jk`j34;ya;;k`5cHJK_n^Nz3oAgOtU26_3d`@IxL&|NZ3d| zmYj2U_%KnL+(@SmVaXIz`@1!{t)?Jj)ye*@txlQJIW$nwSyVWzb_OcR$1l407CO6Xu#4%f?=HCUqJd zy!3n+TUlK!H^?jHYLAWj=CUG5n_K0GCF3kL?mEzCw_l3&jFqKhagt0)Dh{V}&ZbT@ zF%I^xUTSml#3re6>~yn2okxV-z$Va1II(4pSUnR8j7eqgiWJh3UOv{)685f0l2Abp zi&`v$doWr-La4Enc|1l(cpxy3C-U zUV6dR?QVrE@1rGSx`fZu8x6E7tL?NZzjS$Jb#;eY)s~dpp&b~Z)tCBLnSe~aFg@#e z>dxGZD{{pK7p9W>8dF(NUIIls5{kzq&B7th~3uZ|BHc2TiQJSCAfDfubB|?dBX_4ZEm6I1NQ|{;i6hgWh{O zn?1d2T0QIA){b}jsZ+?Y_n*E=X{uG;2mUzSBG%TFRZ8KZ>5V|4>l^KKHMfj&24#AzL-| z1^oNF*ENtp<#uUJwR&5tbz~RbO5NY)Hko3`7>(MZ_1oj za2wXdn&Z;L*$vX)ktNMHmAM*{8)Yh=q`Fk5J+Qfn^1}1azpAxfR%3Rm%k|l_ru5D8 zi_64bg`zbnsl&jI>F31)L2Zq?u2`G>6utJhU{vL|gq3KH;K?lhf>o6wqCXQ8biYkQ zDOtPPMo)@(_iC4|V`7P5TNiK!zJlLT33hv!x3C+&^Q@SAaeB|XCMkP!OH{sZDiCh%1di_RfLibvLU8xP zNu2Y`L?X~Qof;O)9nATe)zvlgNMVP!KUy9TOG6loGr~4*tPvN-J@R$Nvgo#*~tt18Cbich>T zN3mHQ7CehMkCk%2B>`Z5i*p@MV^2vp=Qg{% zP`sf$4DlVdQ}FZw8vSh;pzmM#G9!mc4WJXEu%*D+)>$h@Xm3jJ!SsGE`p2;Est%p3 zIVIIz!JJ4z=R++`29tw9dBQdV# z681!Iv~y+QL&aO{_^iR1&=Y2bsKyw_A2_>yW6Jan!5>kr(Jxsp!VjCZ=x`*=aw4M- zn^Es`#4;#9GtO8z7e043m+EL_ABl|WgSYd^_occkHcy`<@Sk-DrDo}mbQo>PDn1V> z$@F0~>aU>^Cj_rx{BlkBzH4O4=Wd+6!mGn+`z|eec0T;$*e`<5rgyOfhE&(wV&=Bc z^j+eRtuuD-Y%k6~T8PHbO!NZeMcu~budsXPCaLvb@Ch$JSX1vl=8w6IOIRPfhUH>T z=6Z8&iVdAILo(JN8N0)i*tgMqS$WdFo<08-cGH?DoD=@WFJIi()3>Uv1v`>^4b?3v zUn8=+RN9^zS}nA>13LN=wKTyK)7SIp<*reyk|3!oePT(wTHht9lxQlxw+F7|Ngn6n zKE?Z99-?#M+;8-8h?ETGkHM$W62rCs#v`Ha!6PA#VbXC&e~k$+Y2srlj>?53v@YH6P1)YQ>q6mOJgowk z{+Ukw2tC5gz#jN{c7bp7%xy9-jxRl1&N4N-@126rE;3qmMy1ZASe=rRVyLpm4L1%2 zH@*XxBKOS7pEX}0emq2XcwMQ*v$d$qTu6faD_)lF#7hy&JVSMPFx!Y-k@o3)AWR3_xV>*D}pMuXQ9ZyD38yY8m9r?4sw>r&j+w;+&l1FZeNZ=8P4Oo z@{Q^|HTpuzalgz5}seRAMD_zGRi4Vq9;B38B9HHtd6aNqQL zmUXUzpTN|-l<&B@ttnXoa+wd6bE6Bm<;^MLH>a{o%sq(bK74CC-|`+G@5diphM1gt zLITamf^jDY&c}jTH~>91$rBS7iAEL`u6(!1!ha8i%;jgWws>c2ztM?2)$xgK(K>UA zZ&eETvgh{I%dp}sUOo{N=fmvef87lItqThzy7I8Pvl~gk&*~0;g<7-_jz5SGzteL! zKcHV&G>Z!Kr){jbLL&Z!<+X4YAT7MEQZ;W(AH%9Zaa6OYp&1Sz*cM_n7NCBi6e6FSn3*|f!HV~IUMcD9?mGIu zD18<#cr2acFDh=ZUe12REJjHghWTMQvd`f~no%6EP%s~V`d)$&g=^N4ckq`qY2YTo zA6Z;qfR}W^;KCEvhl~Xa@cTLhS@8>|jK&$N_(;R!CXPiNE}A|TfVg+v{3Nm({t1iG zYg`zm7nSm)yojU|Q4o7W6EMVis1DpHoDO340++C?Ln{ zLC)A=`M)!_a@7yLZ^8c)e;Fw&shM~8t(})ecI@QHzH9IfNq9BZxsy9`s2Nt0m2a-( zY$*aW}G%J1@_8m%=Jx*|y6eZEx&=OBFGP_wC$pT%gMt!PTu zFtvdM>JJRw@fI$AW-Qnbc;}~u=pn{KEZFfexNzatFi+8YlxFaKj&E7QAk^zm8$PHq)%yvv*D= z@bJEEi`M)F5WnH9h!R53zxjvL`NKH9S5y@h{>#^HJ`UJil}dBSF5Jzu#RE6XPbaM~e@O@ca6}b`DKE%kt`EI8R=VyV8 ztFSTbN;-?ZhR4voo{5w^1baMFIB}S{iS9L)mAUuOom`>f^CYe6ZbWzm`lf&{!gz^! z2&1Gsh~a4aImgc&&Vdx;e8^lTbLU<+w;;zce|dNGtJz!T-iopzl##ix3?2vetzmMA zq2&-q+Y38d|2y!Sus5>Bh$M^!WFe#_fMpT!R?aAQ(8PrrmgQ8FPQyrPa4d?D;;N2b zotFi&WbS^-2IIoa&hH{tXo9|o#}A70(M?tJ%kFw4w!$MvSaTGXDR_agOTilrnJQk6 z@cZ5)U#GUP02h*+2!T-0HNU&g6jJRAtCJ{i`qm&i`jlWvy<>^I+4PoFcj}gflnD#O z?j7DlOQU^Q+OE1YByV!Lpas`;X=Z0u3N~k`4%=+xFJA$9NkzrtGol~si}Nxw2RAHh zUgFZ(o0{xe*V1N@rr+e8P-^7G;>Y-wusg|Kxqo`2VC^{%Q;Oi+`KF{ir#w#BZ!gic z*IIm=Ru-^ElF(QcHmW6O{(z-+KQ!?So6 zz`n&5r}D4eyiuTkca#cTv^FJhx4S{@Toy97Yx<3 z6rup1hDpkXNpoM%Kh!0_vY(|E{#rYxx9|2?H`Xssf`;2ZASujw_9vkm2vLqrM&IgotsNA1?cVN1)hdr1o}OCXCB^@jkY7pdpTD= zfmKDeiUO|`<@e#cup7^eleHkaVwMDA=o3TJchtKTwJSjC?k+eL<>b)DwUsofe`ih) zq2Nm+bvm!$ogreqf~zoouZXA)%@0MDSLmMWRl$sqeIilrom{_B@X+Du&z#Om^?sY;_pYoH}Vz5fX!ptt2SoK;{)aucpssUpk^Mcm;eB@w|f1>AYR z^P^-B>UvU>`|XHG;n~xx8)zy4wa{@tgIc4t#5|K|76V?1U zfj@`@qwXw`VPV3VxRz%9z*333Z)Bt3=IIyIs}hFm`U6L6&G5`fRWlnbk`vc{XQxVw z^HlmH-!*iA3;9(t5luVrC>9XX2zh^&AU1c;lEly6@4)MD-@c4=pNbyN3#X?YOx?>u zhZ9bOBEi}li_7qkmey-m)1}d|d_wQju?gcbZo+Zgr&d{e7U3Gqj0Fy<(nDN%{Krxe zD`BTmS&2#z2Z=;J|HR+i5yq}No}A&EuoCRBw{Bgn>7hkhAJAKtFWcj%5ArlRoZ#L$ z=Xl!PdPb}&NyjAe&k;QndVycD?6%+!76@kiMb|QP->$G8c0N_nz#SvNA#+7CnbeWK0=<2D4M2s~H?) z-|u@0)de1DGP&&Z93Gk27&CZGT2Iegfp+?)B(F*5m+8>vHCTnIyaUx$p7bua`{;Tl z^bFp=>2oB>4)ZZIZ^4D{Nz}>#{YtIVp}U!>7>sGn$9Id+Rq3aQYv{_s!Y-ndwM~a` zH4g=0i5xK~s^{{=dI2n7?A^+YjtF8y0|Jl3)4(z&d=#O-5-@9UU~f}O;OdkPld&r; z-0zQX?Zf7YWzPQiVTQYZ*K9@XspKr(FX4=Uj4(yPQ7IQS82Frt@FgCk3INbpH%s)V z$L_%-laB=o5xsSTNyVF;mxf@gmd7kh@%Lhy=M2bUiP}+DQZh5c(VP!nz}1`aSg`r4 z0(|0DOy~&5ob{3>T)8Mt!cS5b@J~_-8!aA3P{oYLyo`#aOuv-eYSjCaGh3z64^YC+ zjy29m+`V0;)TlGF!|&w5=R2~9V!Y<@*V^KF_#oIKK-}6Z+>6)V?#UI)tV&mXa6m3Q zb`;YNUJz4XC%5Xr51|Y3NN2So;#g!CTz0rhxfQR=tlZIf;8oeVU@km514+?25PT73 zscs)z#^)*K)1&u<^7PR{3-@rRR24EysP&<2;$=K|ml>mXuY}nE1J=LbUPm_G&olGa zfCUC@Zow|r)BI$=4~1{7JB&bNQM=v2k()kt3B%=^T?yt|sxYb34C`NcezJ#Ma^II| ztvegVrii+hW7RBiyIPNkRk#9|Z;HF0B<2)EeJxQ>^d8R|jHlInqlqu5o}F5_e8k!F z9v26|Zn1G@{F2X18N5rvx6fNGU2$i_9xYTE0 zZw-yfN4f7RG;&s4H#|~8Bb>>wy37LJb)lGHP6XsZGhMM6Ores^O-9aqkY8jL^s$$O z1|D1!-_*9YPMe%WDUw?C)H9grV6ox4{|nw<-no zCBr3iM|q4G--uH~)Z)94=grJTRna2;)#I#Fz`yJ>MjV!-LtJtL=sM=ayufbcE*wer z8SNtp;2+pwIQByL1)uzj*%7aE^!GgENxW03XtXen1a+9Z*mL%tqEbQ@c2CjlHASrB zP@T-brh#?CM8ZP4SydF1BorL*J~h%kR+YQa?b>2CZLV+Kq5)bt?LQoQM3^)EOIfS7 z(3}bqs0U;|nMX=}ox}PS{`GE!QNPaaSf{tG*8z4q_ljULB3xm&1uevnEFy?_E`u?z?{8x+RJb`3oA_dxW6NT` zJn{;z64hNZEr`f5KBKeW6oKjRix-AM1;EzoSK^Eq$7Ou9D*YiGrzA1lAlA4;V`Tj7 zkvai4jLQAqCzw+G9*3yOqSHC8ZSJa-yGIyqE6U4Ci)zzAVq)S%!`ag}30vO#^NTfh zy|f{)A2I2cQr|GcN`_bMFX-LMu)AEhJSF-2Oh-`#Q^p_oaRq;x%O9#tY^{nD@IH|o z+=b73tl@5nmEd*-xIfq)tYw0cpB?;>k1PO{{P;jcLBR<2<6C2`<7qi#wYDu*^Co+F zURH6DB@L`jjRCRN3K})@3EUYCP_#tWCU-I7!B8}5l|-SLa-qT_OSDT;Q+_Nguhxm? z1rt$~&E-`{M8Q~~jKvador@(}JnzSkCE_MT*({K#etmlO0%BP_nCRFioTz5eL{jm> z;#vqxw2qY@t7HGhx}*Y+ak?brbT1!8CQ8B-smcLYWRF)(l9nzO(yZZ7a+aewLLvHqZ)_63mLs#b1)eUD%>jYO&9kj8?K~{sB37U=xnNRMLQQzcJZoUn9UZT}2 zY7ESTGS(>cI?12ypQR-IAl6oSYkpu2hr9*xD>kZG`@v*ZK0;bkjjX+uXyRiO=Ca3K zA6t^d!zRqK8WZG;zo+@pejkD;sJzL!V^)U6zMUyGUUc>9s>F=IT6kG%9s(!?(t?~m z#Bp`dk9VP!vlq)&mR8Cb4!iA@^bNBBu(!&7j+m3sOn%F-reXGOv0w6#;1|T99N9=a z(Gr{)pa3Wq;BxUi{&K)W{nQ7>o*3}ew4~-tIv7TKccd!X`^1vum4Oy`X?lLA?}-30 zm(Mf$=){wp;qyi62hg*{Fu1-rU#ety?X*?;5wA3-jUXeOQv>qBl$g_Cy`&sMN@$6? z`Sg@q;V`m2NtGORkrUjt--lAQ?v44GTUyxlZF82pfhnJ~VGV>UL~CfTnaYo}xZ&iL zx<+SbSg~t`_09B>HZ-|J2s%b0t!X%u!-LE|*BMbY;DSA%Krz%dk4TJOlRVDtZnfJ7=;IunV-Zw? zwbC20l{WKMd>nlU{)J|_j8GF6!p)C9B298$lo1|+M9>r1U^1)Bty4W6lS^}ljEpcw z_at_-t+i@WRtIX~otgRlo6lO0qmX~il>+a+n0{YzIm7pw1{`hJ<2H;;Y+^%@IWDdM zXCHsT@rMi}<=E(BVfOe~fVn&&o8_YJ#89+YV1Xbit){QngrwQKUJAA5m26Yd}I z(fss_tIK3$3*x8KcXKE|EqGa!1^KBcrG5sr`c||w_PQH8`iymI>8hmkm5qIKxJsm# zMCNqA2dyPHA+CCevE#1Sw*bds>kHs9d$*O%&BW5{3Y(kpx?__wV?1kBv6svp%lk6A zRIavFaD~elc!%72>}75+PmSN+89hBySP*fPE5yM{f7CzOA!fAnN%$?kd8d^hAuOKV zg@A}p^1z4TJT8DW41*YkGc`Y`klj6c1g{L`gks*CHu+^^kx2>JC47XJeb2v_2FR>! z>!&Ue{PjrSso(4yFAZ$ub_sb|_hvOqFkM@sa#L`R5XYyRaJ6R{VOa1cPL8Zuj1!+W zcr^5UUCfQMV9*K@QAjfVrRf6@ARDSoOIlN{9wW3kF+Gy5;FbhG}z4Vdn6T*XoierGcS zzl5~^fo^A`x##hY08=f=iaDKUFa%ib@ldcA0Ei-n0MGAlP8+gXH<*RD%nr-n1COq^ zT8A?NcRd4k&`!TgrmObJQBLIBT8`3w`asaUpS zaIAj|)^#aSOSlOi(H~;57vP3TmCK73cK`V-#@rGb3Gf(=dG^@hElgZ6{q-~CriJ1H z>Q#<+et^K^|4RcCDjYcyJyg&z^1wOTSMjLk;Vi9zi_!6s(EkS`yL|Oq{zJlL|Lf>J zmz4D8r9eAnUwDA|^ATm!v6kuxdstjPmm4lp1$nGr%R4f_pOyIsd^h&D`$mhN;TVDM zr{#D1ZVdRqV^xy)1nPyxAnmby+l&kBAQW*0#{(03Q=ih2IQ374_?93KLae3#z&<%$ zTgM-EE`32(SdRjPLE{VZqPQ4*RsBck8G$Eed3`UlAm}+AeF{7t#KXTRm}32oV~!yA zaS7`I(607*`N^T-9_6q8E%kN&8hf zkIypvVR~+t_sM`3JSmnYucTfCPqKbh;8&JWF7M#qY#dzIyx}Ham~}y>i?|Vw=8J@n zI(9`u$DI;}_$9o-=VT?U!h4$-!^Gh=qDu&%uRM%mia6p`2+&0Hn)kr$+UlI%1n#FA z;3E$|Jbg6C6$l45@!3I490@uCEg|+t@H@sC<`EJ?8#Sg`)Uk%&`G{kd($$NtUheIS zTC|+W72(^mj2LPDzkB%nGX1PhhWLdy%)8qfd&?|i_tR*oK;xf~Lr?Fo1}^5Lj}t@- zd-6vZWYiJbhhH8#B9E}1i;A!;-fx-DUw z&o`vadX!&l5qjzf^-+XLz~*O!24pG92nmiaBi-rC;~;)cT88Ikvi2c9kMA5`Pj3&m zuI(A!@W)vLa4e^|e-pDgOudCRhShZtcm+it0t*%NKU;cTqIF?{C4d#W&yU`@8P`>(3(jmqc@rtd9tB|k(nGD_ORN~H_oexFoqPHYWnnzK5cwzVwY=w z;106-oQLPpKmcKCd1q~{NswJ)tffyburi9FZy)L;)-3KmMI^oGYf?z=KI$!tf|sJ) zvS{d6L0D%9U!N3x26`=8)!ra&NX;D3o4Zqvt&e$TF*h%&M(ZrC;cJzBTt#Q>E6b#c zXg4v&UI;(KH4Mjz?U8X@$1RTIzn?Mo!tnbUk55FgcOCbgjSEX`QFl1v+wEey@J#3+ zMk3yBx3Jib_cpkgt^?jAH+|#X=BCZ3$JA<~OUXJAuh1dD`qscp%++ve1${N#Pz!f8 zTvMYSgIkI#@eO#Bin=I5ao35gu3h++xbz+aeM?-?oBJpG!Pwke;)Hi&iLe$vp4s{k z!$nF0>jEg~}=Z3U&8N)T@+Sc>U;?dn2&{Y9%hAD)fRtNjN$%jHw+O_8BN~dg1D>|Vi<=8XAv3EzqvDz^$olz7_iZ<8j8lKo%ON661UT6$E z*R^=!*@Qm~JMtySV~%{ecR4^^t=SSyr_^m}+5Ot-WZ_BoMLq>)*yw8WM`1-St5Bk= z>Fw0B{DWZtS0ts8vn>nMBQ5!#hGo%q>u= zG9N~| zeUJ8opCVs>UAMOt0J5_`%23wGwfc>A`<<+v*n)TcBko%$701n)a7)NB0;{gJE{eIR z*Y_qBZLPobSiSJvkWG!%OO_@zv_v7^Y%DFile2Mu#8tfbxu4@%pyaZUt@zN|n!-OG zpzCRR_gLZ#GK(!T6YU;zcVfw#n(B=B=^^smtQ?h3eCAd;80TLnY1!k26^bbQ7&WMd zqKGY?*g1(SY_i^+h_0mFPpqBmtN%aYQ4yuOo9JwuZg1Pg+<@~xa6dLQycw?Q>V6hJ z5axe7ERLoNPF%D!_N`r>9#&)=(0g0>9yC|veXZkHSrI)MZ{_cC4QtGXsCw&`HKrEq ztal!}L#RQ!U!l8QiZym~OH?0BRznwP#5}wt%tAc4qt}xBpG?ZF;Z-FU$A_9_gI`>7 z#I`UaY&}~U;zY@vL5evZPa`Fywv|wZPrI~FtXgi6L|KhjcwJ_3KqPDkyV29%B34Fm zGm3BK-?2%=>_hY-gx3O5)A2LHuLgB>lv6LhH7i!=tLEn|=JJK_sO)d6sE*Dqdub($ ztKW?HHL>S=c=1rd{}KSrfg=hx;|)m5Itv8QqL0GaN?(0-b6W1YI<#$d%q~2KlF2|k zMk59{uGrm3&A8R#jlx(}nL>xrrIif0^c!aPiq*n*aQ&mU&>bu69WIhfj6cApGE(^~ z;X4>l>RoeUG#1<3#*RdVzqe;q;&eB8b}HK2y6NXRP}0F>_+*rMWwXorP8J3CKCa=P z_!WMMvGzD?2L4C(BHw@UC7aD(fUWNSV;{u8!{Nu37v>1xdcm^7jud@6wvLZyKK`&W zY|Rp0jZa(cJ1bUSZM8-A;=3Ak?TJ>~v`+Z&;a8rY=$$=q#exJQa=?KD(F%mIf!On~ z#n4&I;l=0u7w_oL1&|7T^XvgkDFJSZGIa8m)QoO5duivN2?em9N{)m>NHVVu9r2XWvwyOb)(vaCq}-T9qQ|&FjrAlt%`6}J4wfVA`?D+ zJVb0-AodH%jux^L=D4MhfY|4Ae>n1`72^$?e?M8&jV`H>Zc?f?wbpMk&MzLcENygX z=(6W3X=BxZJJOvNE-M`v)?26a+NnD2+Ia+4RVGtY8>$=1${VDm9$AB*x!G3uH|()C zFL;J;VOfM@Y=wUdJHKaCn=R4Yi`wp0s9w;qfbh4&QBM7zrLadag*Fq1v1K#nf;VxD zyvU6CA_qIvqxH|5OV6(otd!+jqOjXwt*=UGsM&w)XTewVCfHXfin8)Y+9PtU&dtXe zcXkKm2tK8*AZnxR_VB^*hzGV5hZsgI^L8Y-<)iXvWR2L6sv0*so2D`{I~2fq>@&g7 z(+~JW02I1al7_1Odhmw`TR$kXOTz`M<49NY3vWR)wL`yBROXgMsPo3wq{$&F3By9C zG{RTdVg)z%aD(6~Y=Rp$6UuR3AVO~72osNzWB9v!2=nghD6X9eR*wM zmytDOVYsUw%gpH3vP6HSVG!c4+2ZRxP?J1;eqirmC6)$O@|)O8FKQjZQyC z4ptMji#qES#z<~>QIdYVK3LXdWsTYy9-O0DS$Kt+|3*-H>*YM7+Yhin!U>TY--D9wo;BKx{!OnT6ztUk}r`Jtdr;G^=iv82S zkzbti@EMgcNe+dhr_a?V%aTQ#^2_pcQ#4}@d3bK$U7cSc?{<5-EmFF=3DJ#Cl+$;# zloNhpf*=y-AO_}S13AdRLfded?Wo&pcbn*==9B28`Gsv$7LBHk^a|vCCi#tQ%w~<5#VcmDV;= z@7&k(M!iSeuF-W$RQjK(H)5-+Yn5_~f+-T~s8-j>lUJV-_jS5(#j3)zVrj24@7&Xu zT~*v?6gO5?HHej7=~nPKbtIA%`3TuJ; zxOAW}QprialFu{BFlU<-C*|2a3D+s@Db%xY&ATHD4CjplJ@l4DyOPlC8SK}lKnmw7v7Wp%Y*%Yt#6ccYIR*wmG02?Uf>8! z!@o^Sh0iK9Q(bk?#%oYhu%tHZ4}HP~&-OGv1#kr`O~ z?d93;TDXJ=BH8zIH3u6P#>j+K9TWza=>#-zMKn{P7!UI1C|H<=b%~iR^0iww3J*

Dy49x}&xA2(v*=pfu~x*SGiehhbf2-p2e@ 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

gDX>1MRV;)ByD0Iqodfpvbxlg-+ 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

ZX|l!?anAz?=p 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ɲSD;H&r= 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 vYkO$_aJd-` drawer?.classList.remove('active')); + + this.overlay?.classList.remove('active'); + document.body.style.overflow = ''; + this.activeDrawer = null; + } + + /** + * Open profile drawer + */ + openProfile(): void { + this.open('profile'); + } + + /** + * Open notification drawer + */ + openNotification(): void { + this.open('notification'); + } + + /** + * Open todo drawer (slides on top of profile) + */ + openTodo(): void { + this.todoDrawer?.classList.add('active'); + } + + /** + * Close todo drawer + */ + closeTodo(): void { + this.todoDrawer?.classList.remove('active'); + this.closeNewTodo(); + } + + /** + * Open new todo drawer + */ + openNewTodo(): void { + this.newTodoDrawer?.classList.add('active'); + } + + /** + * Close new todo drawer + */ + closeNewTodo(): void { + this.newTodoDrawer?.classList.remove('active'); + } + + /** + * Mark all notifications as read + */ + markAllNotificationsRead(): void { + if (!this.notificationDrawer) return; + + const unreadItems = this.notificationDrawer.querySelectorAll( + 'swp-notification-item[data-unread="true"]' + ); + unreadItems.forEach(item => item.removeAttribute('data-unread')); + + const badge = document.querySelector('swp-notification-badge'); + if (badge) { + badge.style.display = 'none'; + } + } + + private getDrawer(name: DrawerName): HTMLElement | null { + switch (name) { + case 'profile': return this.profileDrawer; + case 'notification': return this.notificationDrawer; + case 'todo': return this.todoDrawer; + case 'newTodo': return this.newTodoDrawer; + } + } + + private setupListeners(): void { + // Profile drawer triggers + document.getElementById('profileTrigger') + ?.addEventListener('click', () => this.openProfile()); + document.getElementById('drawerClose') + ?.addEventListener('click', () => this.close('profile')); + + // Notification drawer triggers + document.getElementById('notificationsBtn') + ?.addEventListener('click', () => this.openNotification()); + document.getElementById('notificationDrawerClose') + ?.addEventListener('click', () => this.close('notification')); + document.getElementById('markAllRead') + ?.addEventListener('click', () => this.markAllNotificationsRead()); + + // Todo drawer triggers + document.getElementById('openTodoDrawer') + ?.addEventListener('click', () => this.openTodo()); + document.getElementById('todoDrawerBack') + ?.addEventListener('click', () => this.closeTodo()); + + // New todo drawer triggers + document.getElementById('addTodoBtn') + ?.addEventListener('click', () => this.openNewTodo()); + document.getElementById('newTodoDrawerBack') + ?.addEventListener('click', () => this.closeNewTodo()); + document.getElementById('cancelNewTodo') + ?.addEventListener('click', () => this.closeNewTodo()); + document.getElementById('saveNewTodo') + ?.addEventListener('click', () => this.closeNewTodo()); + + // Overlay click closes all + this.overlay?.addEventListener('click', () => this.closeAll()); + + // Escape key closes all + document.addEventListener('keydown', (e: KeyboardEvent) => { + if (e.key === 'Escape') this.closeAll(); + }); + + // Todo interactions + this.todoDrawer?.addEventListener('click', (e) => this.handleTodoClick(e)); + + // Visibility options + document.addEventListener('click', (e) => this.handleVisibilityClick(e)); + } + + private handleTodoClick(e: Event): void { + const target = e.target as HTMLElement; + const todoItem = target.closest('swp-todo-item'); + const checkbox = target.closest('swp-todo-checkbox'); + + if (checkbox && todoItem) { + const isCompleted = todoItem.dataset.completed === 'true'; + if (isCompleted) { + todoItem.removeAttribute('data-completed'); + } else { + todoItem.dataset.completed = 'true'; + } + } + + // Toggle section collapse + const sectionHeader = target.closest('swp-todo-section-header'); + if (sectionHeader) { + const section = sectionHeader.closest('swp-todo-section'); + section?.classList.toggle('collapsed'); + } + } + + private handleVisibilityClick(e: Event): void { + const target = e.target as HTMLElement; + const option = target.closest('swp-visibility-option'); + + if (option) { + document.querySelectorAll('swp-visibility-option') + .forEach(o => o.classList.remove('active')); + option.classList.add('active'); + } + } +} diff --git a/app/wwwroot/ts/modules/lockscreen.ts b/app/wwwroot/ts/modules/lockscreen.ts new file mode 100644 index 0000000..f6a5878 --- /dev/null +++ b/app/wwwroot/ts/modules/lockscreen.ts @@ -0,0 +1,182 @@ +/** + * Lock Screen Controller + * + * Handles PIN-based lock screen functionality + */ + +import { DrawerController } from './drawers'; + +export class LockScreenController { + private static readonly CORRECT_PIN = '1234'; // Demo PIN + + private lockScreen: HTMLElement | null = null; + private pinInput: HTMLElement | null = null; + private pinKeypad: HTMLElement | null = null; + private lockTimeEl: HTMLElement | null = null; + private pinDigits: NodeListOf | null = null; + private currentPin = ''; + private drawers: DrawerController | null = null; + + constructor(drawers?: DrawerController) { + this.drawers = drawers ?? null; + this.lockScreen = document.getElementById('lockScreen'); + this.pinInput = document.getElementById('pinInput'); + this.pinKeypad = document.getElementById('pinKeypad'); + this.lockTimeEl = document.getElementById('lockTime'); + this.pinDigits = this.pinInput?.querySelectorAll('swp-pin-digit') ?? null; + + this.setupListeners(); + } + + /** + * Check if lock screen is active + */ + get isActive(): boolean { + return this.lockScreen?.classList.contains('active') ?? false; + } + + /** + * Show the lock screen + */ + show(): void { + this.drawers?.closeAll(); + + if (this.lockScreen) { + this.lockScreen.classList.add('active'); + document.body.style.overflow = 'hidden'; + } + + this.currentPin = ''; + this.updateDisplay(); + + // Update lock time + if (this.lockTimeEl) { + this.lockTimeEl.textContent = `Låst kl. ${this.formatTime()}`; + } + } + + /** + * Hide the lock screen + */ + hide(): void { + if (this.lockScreen) { + this.lockScreen.classList.remove('active'); + document.body.style.overflow = ''; + } + + this.currentPin = ''; + this.updateDisplay(); + } + + private formatTime(): string { + const now = new Date(); + const hours = now.getHours().toString().padStart(2, '0'); + const minutes = now.getMinutes().toString().padStart(2, '0'); + return `${hours}:${minutes}`; + } + + private updateDisplay(): void { + if (!this.pinDigits) return; + + this.pinDigits.forEach((digit, index) => { + digit.classList.remove('filled', 'error'); + if (index < this.currentPin.length) { + digit.textContent = '•'; + digit.classList.add('filled'); + } else { + digit.textContent = ''; + } + }); + } + + private showError(): void { + if (!this.pinDigits) return; + + this.pinDigits.forEach(digit => digit.classList.add('error')); + + // Shake animation + this.pinInput?.classList.add('shake'); + + setTimeout(() => { + this.currentPin = ''; + this.updateDisplay(); + this.pinInput?.classList.remove('shake'); + }, 500); + } + + private verify(): void { + if (this.currentPin === LockScreenController.CORRECT_PIN) { + this.hide(); + } else { + this.showError(); + } + } + + private addDigit(digit: string): void { + if (this.currentPin.length >= 4) return; + + this.currentPin += digit; + this.updateDisplay(); + + // Auto-verify when 4 digits entered + if (this.currentPin.length === 4) { + setTimeout(() => this.verify(), 200); + } + } + + private removeDigit(): void { + if (this.currentPin.length === 0) return; + this.currentPin = this.currentPin.slice(0, -1); + this.updateDisplay(); + } + + private clearPin(): void { + this.currentPin = ''; + this.updateDisplay(); + } + + private setupListeners(): void { + // Keypad click handler + this.pinKeypad?.addEventListener('click', (e) => this.handleKeypadClick(e)); + + // Keyboard input + document.addEventListener('keydown', (e) => this.handleKeyboard(e)); + + // Lock button in sidebar + document.querySelector('swp-side-menu-action.lock') + ?.addEventListener('click', () => this.show()); + } + + private handleKeypadClick(e: Event): void { + const target = e.target as HTMLElement; + const key = target.closest('swp-pin-key'); + + if (!key) return; + + const digit = key.dataset.digit; + const action = key.dataset.action; + + if (digit) { + this.addDigit(digit); + } else if (action === 'backspace') { + this.removeDigit(); + } else if (action === 'clear') { + this.clearPin(); + } + } + + private handleKeyboard(e: KeyboardEvent): void { + if (!this.isActive) return; + + // Prevent default to avoid other interactions + e.preventDefault(); + + if (e.key >= '0' && e.key <= '9') { + this.addDigit(e.key); + } else if (e.key === 'Backspace') { + this.removeDigit(); + } else if (e.key === 'Escape') { + this.clearPin(); + } + } +} diff --git a/app/wwwroot/ts/modules/search.ts b/app/wwwroot/ts/modules/search.ts new file mode 100644 index 0000000..d6eac21 --- /dev/null +++ b/app/wwwroot/ts/modules/search.ts @@ -0,0 +1,106 @@ +/** + * Search Controller + * + * Handles global search functionality and keyboard shortcuts + */ + +export class SearchController { + private input: HTMLInputElement | null = null; + private container: HTMLElement | null = null; + + constructor() { + this.input = document.getElementById('globalSearch') as HTMLInputElement | null; + this.container = document.querySelector('swp-topbar-search'); + + this.setupListeners(); + } + + /** + * Get current search value + */ + get value(): string { + return this.input?.value ?? ''; + } + + /** + * Set search value + */ + set value(val: string) { + if (this.input) { + this.input.value = val; + } + } + + /** + * Focus the search input + */ + focus(): void { + this.input?.focus(); + } + + /** + * Blur the search input + */ + blur(): void { + this.input?.blur(); + } + + /** + * Clear the search input + */ + clear(): void { + this.value = ''; + } + + private setupListeners(): void { + // Keyboard shortcuts + document.addEventListener('keydown', (e) => this.handleKeyboard(e)); + + // Input handlers + if (this.input) { + this.input.addEventListener('input', (e) => this.handleInput(e)); + + // Prevent form submission if wrapped in form + const form = this.input.closest('form'); + form?.addEventListener('submit', (e) => this.handleSubmit(e)); + } + } + + private handleKeyboard(e: KeyboardEvent): void { + // Cmd/Ctrl + K to focus search + if ((e.metaKey || e.ctrlKey) && e.key === 'k') { + e.preventDefault(); + this.focus(); + return; + } + + // Escape to blur search when focused + if (e.key === 'Escape' && document.activeElement === this.input) { + this.blur(); + } + } + + private handleInput(e: Event): void { + const target = e.target as HTMLInputElement; + const query = target.value.trim(); + + // Emit custom event for search + document.dispatchEvent(new CustomEvent('app:search', { + detail: { query }, + bubbles: true + })); + } + + private handleSubmit(e: Event): void { + e.preventDefault(); + + const query = this.value.trim(); + if (!query) return; + + // Emit custom event for search submit + document.dispatchEvent(new CustomEvent('app:search-submit', { + detail: { query }, + bubbles: true + })); + } +} diff --git a/app/wwwroot/ts/modules/sidebar.ts b/app/wwwroot/ts/modules/sidebar.ts new file mode 100644 index 0000000..ddb0a2b --- /dev/null +++ b/app/wwwroot/ts/modules/sidebar.ts @@ -0,0 +1,96 @@ +/** + * Sidebar Controller + * + * Handles sidebar collapse/expand and tooltip functionality + */ + +export class SidebarController { + private menuToggle: HTMLElement | null = null; + private appLayout: HTMLElement | null = null; + private menuTooltip: HTMLElement | null = null; + + constructor() { + this.menuToggle = document.getElementById('menuToggle'); + this.appLayout = document.querySelector('swp-app-layout'); + this.menuTooltip = document.getElementById('menuTooltip'); + + this.setupListeners(); + this.setupTooltips(); + this.restoreState(); + } + + /** + * Check if sidebar is collapsed + */ + get isCollapsed(): boolean { + return this.appLayout?.classList.contains('menu-collapsed') ?? false; + } + + /** + * Toggle sidebar collapsed state + */ + toggle(): void { + if (!this.appLayout) return; + + this.appLayout.classList.toggle('menu-collapsed'); + localStorage.setItem('sidebar-collapsed', String(this.isCollapsed)); + } + + /** + * Collapse the sidebar + */ + collapse(): void { + this.appLayout?.classList.add('menu-collapsed'); + localStorage.setItem('sidebar-collapsed', 'true'); + } + + /** + * Expand the sidebar + */ + expand(): void { + this.appLayout?.classList.remove('menu-collapsed'); + localStorage.setItem('sidebar-collapsed', 'false'); + } + + private setupListeners(): void { + this.menuToggle?.addEventListener('click', () => this.toggle()); + } + + private setupTooltips(): void { + if (!this.menuTooltip) return; + + const menuItems = document.querySelectorAll('swp-side-menu-item[data-tooltip]'); + + menuItems.forEach(item => { + item.addEventListener('mouseenter', () => this.showTooltip(item)); + item.addEventListener('mouseleave', () => this.hideTooltip()); + }); + } + + private showTooltip(item: HTMLElement): void { + if (!this.isCollapsed || !this.menuTooltip) return; + + const rect = item.getBoundingClientRect(); + const tooltipText = item.dataset.tooltip; + + if (!tooltipText) return; + + this.menuTooltip.textContent = tooltipText; + this.menuTooltip.style.left = `${rect.right + 8}px`; + this.menuTooltip.style.top = `${rect.top + rect.height / 2}px`; + this.menuTooltip.style.transform = 'translateY(-50%)'; + this.menuTooltip.showPopover(); + } + + private hideTooltip(): void { + this.menuTooltip?.hidePopover(); + } + + private restoreState(): void { + if (!this.appLayout) return; + + if (localStorage.getItem('sidebar-collapsed') === 'true') { + this.appLayout.classList.add('menu-collapsed'); + } + } +} diff --git a/app/wwwroot/ts/modules/theme.ts b/app/wwwroot/ts/modules/theme.ts new file mode 100644 index 0000000..b14e4b5 --- /dev/null +++ b/app/wwwroot/ts/modules/theme.ts @@ -0,0 +1,120 @@ +/** + * Theme Controller + * + * Handles dark/light mode switching and system preference detection + */ + +export type Theme = 'light' | 'dark' | 'system'; + +export class ThemeController { + private static readonly STORAGE_KEY = 'theme-preference'; + private static readonly DARK_CLASS = 'dark-mode'; + private static readonly LIGHT_CLASS = 'light-mode'; + + private root: HTMLElement; + private themeOptions: NodeListOf; + + constructor() { + this.root = document.documentElement; + this.themeOptions = document.querySelectorAll('swp-theme-option'); + + this.applyTheme(this.current); + this.updateUI(); + this.setupListeners(); + } + + /** + * Get the current theme setting + */ + get current(): Theme { + const stored = localStorage.getItem(ThemeController.STORAGE_KEY) as Theme | null; + if (stored === 'dark' || stored === 'light' || stored === 'system') { + return stored; + } + return 'system'; + } + + /** + * Check if dark mode is currently active + */ + get isDark(): boolean { + return this.root.classList.contains(ThemeController.DARK_CLASS) || + (this.systemPrefersDark && !this.root.classList.contains(ThemeController.LIGHT_CLASS)); + } + + /** + * Check if system prefers dark mode + */ + get systemPrefersDark(): boolean { + return window.matchMedia('(prefers-color-scheme: dark)').matches; + } + + /** + * Set theme and persist preference + */ + set(theme: Theme): void { + localStorage.setItem(ThemeController.STORAGE_KEY, theme); + this.applyTheme(theme); + this.updateUI(); + } + + /** + * Toggle between light and dark themes + */ + toggle(): void { + this.set(this.isDark ? 'light' : 'dark'); + } + + private applyTheme(theme: Theme): void { + this.root.classList.remove(ThemeController.DARK_CLASS, ThemeController.LIGHT_CLASS); + + if (theme === 'dark') { + this.root.classList.add(ThemeController.DARK_CLASS); + } else if (theme === 'light') { + this.root.classList.add(ThemeController.LIGHT_CLASS); + } + // 'system' leaves both classes off, letting CSS media query handle it + } + + private updateUI(): void { + if (!this.themeOptions) return; + + const darkActive = this.isDark; + + this.themeOptions.forEach(option => { + const theme = option.dataset.theme as Theme; + const isActive = (theme === 'dark' && darkActive) || (theme === 'light' && !darkActive); + option.classList.toggle('active', isActive); + }); + } + + private setupListeners(): void { + // Theme option clicks + this.themeOptions.forEach(option => { + option.addEventListener('click', (e) => this.handleOptionClick(e)); + }); + + // System theme changes + window.matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', () => this.handleSystemChange()); + } + + private handleOptionClick(e: Event): void { + const target = e.target as HTMLElement; + const option = target.closest('swp-theme-option'); + + if (option) { + const theme = option.dataset.theme as Theme; + if (theme) { + this.set(theme); + } + } + } + + private handleSystemChange(): void { + // Only react to system changes if we're using system preference + if (this.current === 'system') { + this.updateUI(); + } + } +} diff --git a/app/wwwroot/ts/tsconfig.json b/app/wwwroot/ts/tsconfig.json new file mode 100644 index 0000000..87d8c61 --- /dev/null +++ b/app/wwwroot/ts/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": false, + "outDir": "../js/app", + "rootDir": ".", + "sourceMap": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"] + }, + "include": [ + "./**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} From 12e7594f30228ce9c9536cef653e699c679235fc Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Mon, 26 Jan 2026 17:52:42 +0100 Subject: [PATCH 07/10] Removes CalendarServer app and adds sales landing page Deletes .NET server-side project structure and replaces it with a static HTML sales page for Plantempus Removes server-side components including: - Language and localization services - Menu and user role models - Controllers and routing configuration Adds comprehensive marketing landing page with responsive design and interactive sections --- app/CalendarServer.csproj | 10 - app/Controllers/HomeController.cs | 12 - .../Language/Models/SupportedCulture.cs | 8 - .../Language/Services/ILocalizationService.cs | 10 - .../Services/JsonLocalizationService.cs | 48 - .../Language/TagHelpers/LocalizeTagHelper.cs | 30 - app/Features/Language/Translations/da.json | 33 - app/Features/Language/Translations/en.json | 33 - app/Features/Menu/Models/MenuGroup.cs | 12 - app/Features/Menu/Models/MenuItem.cs | 15 - app/Features/Menu/Models/UserRole.cs | 11 - app/Features/Menu/Services/IMenuService.cs | 14 - app/Features/Menu/Services/MockMenuService.cs | 187 -- app/Features/Menu/SideMenuViewComponent.cs | 35 - app/Features/Menu/SideMenuViewModel.cs | 12 - app/Program.cs | 29 - app/Views/Home/Index.cshtml | 91 - .../Shared/Components/SideMenu/Default.cshtml | 39 - .../Shared/Components/_ProfileDrawer.cshtml | 49 - app/Views/Shared/Components/_SideMenu.cshtml | 78 - app/Views/Shared/Components/_TopBar.cshtml | 26 - app/Views/Shared/_Layout.cshtml | 38 - app/Views/_ViewImports.cshtml | 3 - app/Views/_ViewStart.cshtml | 3 - app/build.js | 24 - app/wwwroot/css/app-layout.css | 50 - app/wwwroot/css/base.css | 118 - app/wwwroot/css/design-system.css | 163 -- app/wwwroot/css/drawers.css | 258 --- app/wwwroot/css/page.css | 204 -- app/wwwroot/css/sidebar.css | 246 --- app/wwwroot/css/stats.css | 258 --- app/wwwroot/css/topbar.css | 180 -- app/wwwroot/fonts/Poppins-Black.woff | Bin 64180 -> 0 bytes app/wwwroot/fonts/Poppins-BlackItalic.woff | Bin 71488 -> 0 bytes app/wwwroot/fonts/Poppins-Bold.woff | Bin 65572 -> 0 bytes app/wwwroot/fonts/Poppins-BoldItalic.woff | Bin 74912 -> 0 bytes app/wwwroot/fonts/Poppins-ExtraBold.woff | Bin 65520 -> 0 bytes .../fonts/Poppins-ExtraBoldItalic.woff | Bin 74608 -> 0 bytes app/wwwroot/fonts/Poppins-ExtraLight.woff | Bin 66456 -> 0 bytes .../fonts/Poppins-ExtraLightItalic.woff | Bin 76392 -> 0 bytes app/wwwroot/fonts/Poppins-Italic.woff | Bin 76316 -> 0 bytes app/wwwroot/fonts/Poppins-Light.woff | Bin 66392 -> 0 bytes app/wwwroot/fonts/Poppins-LightItalic.woff | Bin 76520 -> 0 bytes app/wwwroot/fonts/Poppins-Medium.woff | Bin 65760 -> 0 bytes app/wwwroot/fonts/Poppins-MediumItalic.woff | Bin 74920 -> 0 bytes app/wwwroot/fonts/Poppins-Regular.woff | Bin 66464 -> 0 bytes app/wwwroot/fonts/Poppins-SemiBold.woff | Bin 66236 -> 0 bytes app/wwwroot/fonts/Poppins-SemiBoldItalic.woff | Bin 75592 -> 0 bytes app/wwwroot/fonts/Poppins-Thin.woff | Bin 62572 -> 0 bytes app/wwwroot/fonts/Poppins-ThinItalic.woff | Bin 72444 -> 0 bytes app/wwwroot/ts/app.ts | 58 - app/wwwroot/ts/modules/drawers.ts | 226 -- app/wwwroot/ts/modules/lockscreen.ts | 182 -- app/wwwroot/ts/modules/search.ts | 106 - app/wwwroot/ts/modules/sidebar.ts | 96 - app/wwwroot/ts/modules/theme.ts | 120 -- app/wwwroot/ts/tsconfig.json | 22 - wwwroot/plantempus-sales.html | 1896 +++++++++++++++++ wwwroot/poc-indstillinger.html | 66 + 60 files changed, 1962 insertions(+), 3137 deletions(-) delete mode 100644 app/CalendarServer.csproj delete mode 100644 app/Controllers/HomeController.cs delete mode 100644 app/Features/Language/Models/SupportedCulture.cs delete mode 100644 app/Features/Language/Services/ILocalizationService.cs delete mode 100644 app/Features/Language/Services/JsonLocalizationService.cs delete mode 100644 app/Features/Language/TagHelpers/LocalizeTagHelper.cs delete mode 100644 app/Features/Language/Translations/da.json delete mode 100644 app/Features/Language/Translations/en.json delete mode 100644 app/Features/Menu/Models/MenuGroup.cs delete mode 100644 app/Features/Menu/Models/MenuItem.cs delete mode 100644 app/Features/Menu/Models/UserRole.cs delete mode 100644 app/Features/Menu/Services/IMenuService.cs delete mode 100644 app/Features/Menu/Services/MockMenuService.cs delete mode 100644 app/Features/Menu/SideMenuViewComponent.cs delete mode 100644 app/Features/Menu/SideMenuViewModel.cs delete mode 100644 app/Program.cs delete mode 100644 app/Views/Home/Index.cshtml delete mode 100644 app/Views/Shared/Components/SideMenu/Default.cshtml delete mode 100644 app/Views/Shared/Components/_ProfileDrawer.cshtml delete mode 100644 app/Views/Shared/Components/_SideMenu.cshtml delete mode 100644 app/Views/Shared/Components/_TopBar.cshtml delete mode 100644 app/Views/Shared/_Layout.cshtml delete mode 100644 app/Views/_ViewImports.cshtml delete mode 100644 app/Views/_ViewStart.cshtml delete mode 100644 app/build.js delete mode 100644 app/wwwroot/css/app-layout.css delete mode 100644 app/wwwroot/css/base.css delete mode 100644 app/wwwroot/css/design-system.css delete mode 100644 app/wwwroot/css/drawers.css delete mode 100644 app/wwwroot/css/page.css delete mode 100644 app/wwwroot/css/sidebar.css delete mode 100644 app/wwwroot/css/stats.css delete mode 100644 app/wwwroot/css/topbar.css delete mode 100644 app/wwwroot/fonts/Poppins-Black.woff delete mode 100644 app/wwwroot/fonts/Poppins-BlackItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Bold.woff delete mode 100644 app/wwwroot/fonts/Poppins-BoldItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-ExtraBold.woff delete mode 100644 app/wwwroot/fonts/Poppins-ExtraBoldItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-ExtraLight.woff delete mode 100644 app/wwwroot/fonts/Poppins-ExtraLightItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Italic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Light.woff delete mode 100644 app/wwwroot/fonts/Poppins-LightItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Medium.woff delete mode 100644 app/wwwroot/fonts/Poppins-MediumItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Regular.woff delete mode 100644 app/wwwroot/fonts/Poppins-SemiBold.woff delete mode 100644 app/wwwroot/fonts/Poppins-SemiBoldItalic.woff delete mode 100644 app/wwwroot/fonts/Poppins-Thin.woff delete mode 100644 app/wwwroot/fonts/Poppins-ThinItalic.woff delete mode 100644 app/wwwroot/ts/app.ts delete mode 100644 app/wwwroot/ts/modules/drawers.ts delete mode 100644 app/wwwroot/ts/modules/lockscreen.ts delete mode 100644 app/wwwroot/ts/modules/search.ts delete mode 100644 app/wwwroot/ts/modules/sidebar.ts delete mode 100644 app/wwwroot/ts/modules/theme.ts delete mode 100644 app/wwwroot/ts/tsconfig.json create mode 100644 wwwroot/plantempus-sales.html diff --git a/app/CalendarServer.csproj b/app/CalendarServer.csproj deleted file mode 100644 index 9aa2a08..0000000 --- a/app/CalendarServer.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - net8.0 - enable - enable - CalendarServer - - - \ No newline at end of file diff --git a/app/Controllers/HomeController.cs b/app/Controllers/HomeController.cs deleted file mode 100644 index efc173f..0000000 --- a/app/Controllers/HomeController.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace CalendarServer.Controllers; - -public class HomeController : Controller -{ - public IActionResult Index() - { - ViewData["Title"] = "Dashboard"; - return View(); - } -} diff --git a/app/Features/Language/Models/SupportedCulture.cs b/app/Features/Language/Models/SupportedCulture.cs deleted file mode 100644 index 3525c5e..0000000 --- a/app/Features/Language/Models/SupportedCulture.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace CalendarServer.Features.Language.Models; - -public class SupportedCulture -{ - public required string Code { get; set; } - public required string Name { get; set; } - public required string NativeName { get; set; } -} diff --git a/app/Features/Language/Services/ILocalizationService.cs b/app/Features/Language/Services/ILocalizationService.cs deleted file mode 100644 index 430e50e..0000000 --- a/app/Features/Language/Services/ILocalizationService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using CalendarServer.Features.Language.Models; - -namespace CalendarServer.Features.Language.Services; - -public interface ILocalizationService -{ - string Get(string key, string? culture = null); - string CurrentCulture { get; } - IEnumerable GetSupportedCultures(); -} diff --git a/app/Features/Language/Services/JsonLocalizationService.cs b/app/Features/Language/Services/JsonLocalizationService.cs deleted file mode 100644 index 7b90bca..0000000 --- a/app/Features/Language/Services/JsonLocalizationService.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json; -using CalendarServer.Features.Language.Models; - -namespace CalendarServer.Features.Language.Services; - -public class JsonLocalizationService : ILocalizationService -{ - private readonly string _translationsPath; - - public JsonLocalizationService(IWebHostEnvironment env) - { - _translationsPath = Path.Combine(env.ContentRootPath, "Features", "Language", "Translations"); - } - - public string CurrentCulture => "en"; - - public string Get(string key, string? culture = null) - { - culture ??= CurrentCulture; - var filePath = Path.Combine(_translationsPath, $"{culture}.json"); - - if (!File.Exists(filePath)) - return key; - - var json = File.ReadAllText(filePath); - var doc = JsonDocument.Parse(json); - - var parts = key.Split('.'); - JsonElement current = doc.RootElement; - - foreach (var part in parts) - { - if (!current.TryGetProperty(part, out current)) - return key; - } - - return current.GetString() ?? key; - } - - public IEnumerable GetSupportedCultures() - { - return new List - { - new() { Code = "da", Name = "Danish", NativeName = "Dansk" }, - new() { Code = "en", Name = "English", NativeName = "English" } - }; - } -} diff --git a/app/Features/Language/TagHelpers/LocalizeTagHelper.cs b/app/Features/Language/TagHelpers/LocalizeTagHelper.cs deleted file mode 100644 index 73f0fe9..0000000 --- a/app/Features/Language/TagHelpers/LocalizeTagHelper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; -using CalendarServer.Features.Language.Services; - -namespace CalendarServer.Features.Language.TagHelpers; - -[HtmlTargetElement(Attributes = "localize")] -public class LocalizeTagHelper : TagHelper -{ - private readonly ILocalizationService _localize; - - public LocalizeTagHelper(ILocalizationService localize) - { - _localize = localize; - } - - [HtmlAttributeName("localize")] - public string Key { get; set; } = string.Empty; - - public override void Process(TagHelperContext context, TagHelperOutput output) - { - var translated = _localize.Get(Key); - - if (!string.IsNullOrEmpty(translated) && translated != Key) - { - output.Content.SetContent(translated); - } - - output.Attributes.RemoveAll("localize"); - } -} diff --git a/app/Features/Language/Translations/da.json b/app/Features/Language/Translations/da.json deleted file mode 100644 index c569ae6..0000000 --- a/app/Features/Language/Translations/da.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "menu": { - "home": "Dashboard", - "calendar": "Kalender", - "pos": "Kasse", - "products": "Produkter & Lager", - "suppliers": "Leverandører", - "customers": "Kunder", - "employees": "Medarbejdere", - "reports": "Statistik & Rapporter", - "settings": "Indstillinger", - "account": "Abonnement & Konto" - }, - "groups": { - "dashboard": "Dashboard", - "data": "Data", - "analytics": "Analyse", - "system": "System" - }, - "common": { - "save": "Gem", - "cancel": "Annuller", - "search": "Søg", - "close": "Luk", - "delete": "Slet", - "edit": "Rediger", - "add": "Tilføj" - }, - "sidebar": { - "lockScreen": "Lås skærm", - "appName": "Salon OS" - } -} diff --git a/app/Features/Language/Translations/en.json b/app/Features/Language/Translations/en.json deleted file mode 100644 index a66a7b7..0000000 --- a/app/Features/Language/Translations/en.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "menu": { - "home": "Dashboard", - "calendar": "Calendar", - "pos": "Point of Sale", - "products": "Products & Inventory", - "suppliers": "Suppliers", - "customers": "Customers", - "employees": "Employees", - "reports": "Statistics & Reports", - "settings": "Settings", - "account": "Subscription & Account" - }, - "groups": { - "dashboard": "Dashboard", - "data": "Data", - "analytics": "Analytics", - "system": "System" - }, - "common": { - "save": "Save", - "cancel": "Cancel", - "search": "Search", - "close": "Close", - "delete": "Delete", - "edit": "Edit", - "add": "Add" - }, - "sidebar": { - "lockScreen": "Lock screen", - "appName": "Salon OS" - } -} diff --git a/app/Features/Menu/Models/MenuGroup.cs b/app/Features/Menu/Models/MenuGroup.cs deleted file mode 100644 index f2f3eb0..0000000 --- a/app/Features/Menu/Models/MenuGroup.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace CalendarServer.Features.Menu.Models; - -///

-/// Represents a group of menu items (e.g., "Dashboard", "Data", "System"). -/// -public class MenuGroup -{ - public required string Id { get; set; } - public required string Label { get; set; } - public int SortOrder { get; set; } - public List Items { get; set; } = new(); -} diff --git a/app/Features/Menu/Models/MenuItem.cs b/app/Features/Menu/Models/MenuItem.cs deleted file mode 100644 index 04e8172..0000000 --- a/app/Features/Menu/Models/MenuItem.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CalendarServer.Features.Menu.Models; - -/// -/// Represents a single menu item in the sidebar. -/// -public class MenuItem -{ - public required string Id { get; set; } - public required string Label { get; set; } - public required string Icon { get; set; } - public required string Url { get; set; } - public UserRole MinimumRole { get; set; } = UserRole.Staff; - public int SortOrder { get; set; } - public bool IsActive { get; set; } -} diff --git a/app/Features/Menu/Models/UserRole.cs b/app/Features/Menu/Models/UserRole.cs deleted file mode 100644 index 1adc056..0000000 --- a/app/Features/Menu/Models/UserRole.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace CalendarServer.Features.Menu.Models; - -/// -/// User roles for menu visibility. Higher value = more access. -/// -public enum UserRole -{ - Staff = 0, - Manager = 1, - Admin = 2 -} diff --git a/app/Features/Menu/Services/IMenuService.cs b/app/Features/Menu/Services/IMenuService.cs deleted file mode 100644 index 3cbccb5..0000000 --- a/app/Features/Menu/Services/IMenuService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using CalendarServer.Features.Menu.Models; - -namespace CalendarServer.Features.Menu.Services; - -/// -/// Service for retrieving menu structure based on user role. -/// -public interface IMenuService -{ - /// - /// Get menu groups filtered by user role. - /// - List GetMenuForRole(UserRole role, string? currentUrl = null); -} diff --git a/app/Features/Menu/Services/MockMenuService.cs b/app/Features/Menu/Services/MockMenuService.cs deleted file mode 100644 index 4b90217..0000000 --- a/app/Features/Menu/Services/MockMenuService.cs +++ /dev/null @@ -1,187 +0,0 @@ -using CalendarServer.Features.Menu.Models; -using CalendarServer.Features.Language.Services; - -namespace CalendarServer.Features.Menu.Services; - -/// -/// Mock implementation of IMenuService with hardcoded menu data. -/// -public class MockMenuService : IMenuService -{ - private readonly ILocalizationService _localize; - - public MockMenuService(ILocalizationService localize) - { - _localize = localize; - } - - public List GetMenuForRole(UserRole role, string? currentUrl = null) - { - var allGroups = GetAllMenuGroups(); - - return allGroups - .Select(g => new MenuGroup - { - Id = g.Id, - Label = _localize.Get($"groups.{g.Id}"), - SortOrder = g.SortOrder, - Items = g.Items - .Where(i => role >= i.MinimumRole) - .Select(i => new MenuItem - { - Id = i.Id, - Label = _localize.Get($"menu.{i.Id}"), - Icon = i.Icon, - Url = i.Url, - MinimumRole = i.MinimumRole, - SortOrder = i.SortOrder, - IsActive = currentUrl != null && i.Url.Equals(currentUrl, StringComparison.OrdinalIgnoreCase) - }) - .OrderBy(i => i.SortOrder) - .ToList() - }) - .Where(g => g.Items.Any()) - .OrderBy(g => g.SortOrder) - .ToList(); - } - - private static List GetAllMenuGroups() - { - return new List - { - // DASHBOARD GROUP - new MenuGroup - { - Id = "dashboard", - Label = "Dashboard", - SortOrder = 1, - Items = new List - { - new MenuItem - { - Id = "home", - Label = "Dashboard", - Icon = "ph-squares-four", - Url = "/", - MinimumRole = UserRole.Staff, - SortOrder = 1 - }, - new MenuItem - { - Id = "calendar", - Label = "Kalender", - Icon = "ph-calendar", - Url = "/poc-calendar.html", - MinimumRole = UserRole.Staff, - SortOrder = 2 - }, - new MenuItem - { - Id = "pos", - Label = "Kasse", - Icon = "ph-device-mobile", - Url = "/pos", - MinimumRole = UserRole.Staff, - SortOrder = 3 - } - } - }, - - // DATA GROUP - new MenuGroup - { - Id = "data", - Label = "Data", - SortOrder = 2, - Items = new List - { - new MenuItem - { - Id = "products", - Label = "Produkter & Lager", - Icon = "ph-package", - Url = "/poc-produkter.html", - MinimumRole = UserRole.Manager, - SortOrder = 1 - }, - new MenuItem - { - Id = "suppliers", - Label = "Leverandører", - Icon = "ph-truck", - Url = "/poc-leverandoerer.html", - MinimumRole = UserRole.Manager, - SortOrder = 2 - }, - new MenuItem - { - Id = "customers", - Label = "Kunder", - Icon = "ph-users", - Url = "/customers", - MinimumRole = UserRole.Staff, - SortOrder = 3 - }, - new MenuItem - { - Id = "employees", - Label = "Medarbejdere", - Icon = "ph-user", - Url = "/poc-medarbejdere.html", - MinimumRole = UserRole.Manager, - SortOrder = 4 - } - } - }, - - // ANALYSE GROUP - new MenuGroup - { - Id = "analytics", - Label = "Analyse", - SortOrder = 3, - Items = new List - { - new MenuItem - { - Id = "reports", - Label = "Statistik & Rapporter", - Icon = "ph-chart-bar", - Url = "/reports", - MinimumRole = UserRole.Manager, - SortOrder = 1 - } - } - }, - - // SYSTEM GROUP - new MenuGroup - { - Id = "system", - Label = "System", - SortOrder = 4, - Items = new List - { - new MenuItem - { - Id = "settings", - Label = "Indstillinger", - Icon = "ph-gear", - Url = "/poc-indstillinger.html", - MinimumRole = UserRole.Admin, - SortOrder = 1 - }, - new MenuItem - { - Id = "account", - Label = "Abonnement & Konto", - Icon = "ph-credit-card", - Url = "/poc-konto.html", - MinimumRole = UserRole.Admin, - SortOrder = 2 - } - } - } - }; - } -} diff --git a/app/Features/Menu/SideMenuViewComponent.cs b/app/Features/Menu/SideMenuViewComponent.cs deleted file mode 100644 index a14de55..0000000 --- a/app/Features/Menu/SideMenuViewComponent.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using CalendarServer.Features.Menu.Models; -using CalendarServer.Features.Menu.Services; - -namespace CalendarServer.Features.Menu; - -/// -/// ViewComponent for rendering the side menu based on user role. -/// -public class SideMenuViewComponent : ViewComponent -{ - private readonly IMenuService _menuService; - - public SideMenuViewComponent(IMenuService menuService) - { - _menuService = menuService; - } - - public IViewComponentResult Invoke(UserRole? role = null) - { - // Default to Admin for demo (in real app, get from auth) - var userRole = role ?? UserRole.Admin; - - var currentUrl = HttpContext.Request.Path.Value; - var groups = _menuService.GetMenuForRole(userRole, currentUrl); - - var viewModel = new SideMenuViewModel - { - Groups = groups, - CurrentUserRole = userRole - }; - - return View(viewModel); - } -} diff --git a/app/Features/Menu/SideMenuViewModel.cs b/app/Features/Menu/SideMenuViewModel.cs deleted file mode 100644 index 84cef10..0000000 --- a/app/Features/Menu/SideMenuViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using CalendarServer.Features.Menu.Models; - -namespace CalendarServer.Features.Menu; - -/// -/// ViewModel for the side menu partial view. -/// -public class SideMenuViewModel -{ - public required List Groups { get; set; } - public UserRole CurrentUserRole { get; set; } -} diff --git a/app/Program.cs b/app/Program.cs deleted file mode 100644 index 53c699f..0000000 --- a/app/Program.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using CalendarServer.Features.Menu.Services; -using CalendarServer.Features.Language.Services; - -var builder = WebApplication.CreateBuilder(args); - -// Add MVC services -builder.Services.AddControllersWithViews(); - -// Register application services -builder.Services.AddScoped(); -builder.Services.AddScoped(); - -var app = builder.Build(); - -// Serve static files from wwwroot -app.UseStaticFiles(); - -// Configure routing -app.UseRouting(); - -// Map MVC routes -app.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - -app.Run("http://localhost:8000"); \ No newline at end of file diff --git a/app/Views/Home/Index.cshtml b/app/Views/Home/Index.cshtml deleted file mode 100644 index 714eaec..0000000 --- a/app/Views/Home/Index.cshtml +++ /dev/null @@ -1,91 +0,0 @@ -@{ - ViewData["Title"] = "Dashboard"; -} - - - - - - 12 - Bookinger i dag - - - 4 gennemført, 2 i gang - - - - 8.450 kr - Forventet omsætning - - - +12% vs. gennemsnit - - - - 78% - Belægningsgrad - - - God kapacitet - - - - 4 - Kræver opmærksomhed - - - - - - - - - - - - AI Analyse - - - Godt i gang! 4 af 12 bookinger er gennemført. 2 er i gang nu, og 6 venter. - Forventet omsætning: 8.450 kr – allerede realiseret 2.150 kr. - - - - - - - - - - Dagens bookinger - - Se alle - - -

Booking oversigt kommer her...

-
-
-
- - - - - - Hurtige handlinger - - - - - - Ny booking - - - - Ny kunde - - - - - -
-
diff --git a/app/Views/Shared/Components/SideMenu/Default.cshtml b/app/Views/Shared/Components/SideMenu/Default.cshtml deleted file mode 100644 index 12087b5..0000000 --- a/app/Views/Shared/Components/SideMenu/Default.cshtml +++ /dev/null @@ -1,39 +0,0 @@ -@model CalendarServer.Features.Menu.SideMenuViewModel - - - - - Salon OS - - - - - - - @foreach (var group in Model.Groups) - { - - @group.Label - @foreach (var item in group.Items) - { -
- - @item.Label - - } - - } - - - - - - Lås skærm - - - - - - diff --git a/app/Views/Shared/Components/_ProfileDrawer.cshtml b/app/Views/Shared/Components/_ProfileDrawer.cshtml deleted file mode 100644 index 9e42620..0000000 --- a/app/Views/Shared/Components/_ProfileDrawer.cshtml +++ /dev/null @@ -1,49 +0,0 @@ - - - Profil - - - - - - - - MJ - Maria Jensen - maria@salon.dk - - - - - - - - Min profil - - - - Indstillinger - - - - - - - - - Mørk tilstand - - - - - - - - - - - - Log ud - - - diff --git a/app/Views/Shared/Components/_SideMenu.cshtml b/app/Views/Shared/Components/_SideMenu.cshtml deleted file mode 100644 index 0e0d210..0000000 --- a/app/Views/Shared/Components/_SideMenu.cshtml +++ /dev/null @@ -1,78 +0,0 @@ - - - - Salon OS - - - - - - - - - Dashboard - - - Dashboard - - - - Kalender - - - - Kasse - - - - - - Data - - - Produkter & Lager - - - - Leverandører - - - - Kunder - - - - Medarbejdere - - - - - - Analyse - - - Statistik & Rapporter - - - - - - System - - - Indstillinger - - - - Abonnement & Konto - - - - - - - - Lås skærm - - - diff --git a/app/Views/Shared/Components/_TopBar.cshtml b/app/Views/Shared/Components/_TopBar.cshtml deleted file mode 100644 index 41b140a..0000000 --- a/app/Views/Shared/Components/_TopBar.cshtml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - ⌘K - - - - - - - 3 - - - - - - - MJ - - Maria Jensen - Administrator - - - - diff --git a/app/Views/Shared/_Layout.cshtml b/app/Views/Shared/_Layout.cshtml deleted file mode 100644 index 337b9c7..0000000 --- a/app/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - @ViewData["Title"] - Salon OS - - - - - - - - - - - - - - @await RenderSectionAsync("Styles", required: false) - - - - @await Component.InvokeAsync("SideMenu") - @await Html.PartialAsync("Components/_TopBar") - - - @RenderBody() - - - - @await Html.PartialAsync("Components/_ProfileDrawer") - - - - @await RenderSectionAsync("Scripts", required: false) - - diff --git a/app/Views/_ViewImports.cshtml b/app/Views/_ViewImports.cshtml deleted file mode 100644 index 584d299..0000000 --- a/app/Views/_ViewImports.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using CalendarServer -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@addTagHelper *, CalendarServer diff --git a/app/Views/_ViewStart.cshtml b/app/Views/_ViewStart.cshtml deleted file mode 100644 index 820a2f6..0000000 --- a/app/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/app/build.js b/app/build.js deleted file mode 100644 index 4aa944e..0000000 --- a/app/build.js +++ /dev/null @@ -1,24 +0,0 @@ -import * as esbuild from 'esbuild'; - -async function build() { - try { - await esbuild.build({ - entryPoints: ['wwwroot/ts/app.ts'], - bundle: true, - outfile: 'wwwroot/js/app.js', - format: 'esm', - sourcemap: 'inline', - target: 'es2020', - minify: false, - keepNames: true, - platform: 'browser' - }); - - console.log('App bundle created: wwwroot/js/app.js'); - } catch (error) { - console.error('Build failed:', error); - process.exit(1); - } -} - -build(); diff --git a/app/wwwroot/css/app-layout.css b/app/wwwroot/css/app-layout.css deleted file mode 100644 index 2f57b74..0000000 --- a/app/wwwroot/css/app-layout.css +++ /dev/null @@ -1,50 +0,0 @@ -/** - * App Layout - Main Grid Structure - * - * Definerer den overordnede app-struktur med sidebar og main content - */ - -/* =========================================== - MAIN APP GRID - =========================================== */ -swp-app-layout { - display: grid; - grid-template-columns: var(--side-menu-width) 1fr; - grid-template-rows: var(--topbar-height) 1fr; - height: 100vh; - transition: grid-template-columns var(--transition-normal); -} - -/* =========================================== - COLLAPSED MENU STATE - =========================================== */ -swp-app-layout.menu-collapsed { - grid-template-columns: var(--side-menu-width-collapsed) 1fr; -} - -/* =========================================== - MAIN CONTENT AREA - =========================================== */ -swp-main-content { - display: block; - overflow-y: auto; - background: var(--color-background); -} - -/* =========================================== - DRAWER OVERLAY - =========================================== */ -swp-drawer-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - z-index: var(--z-overlay); - opacity: 0; - visibility: hidden; - transition: opacity var(--transition-normal), visibility var(--transition-normal); -} - -swp-drawer-overlay.active { - opacity: 1; - visibility: visible; -} diff --git a/app/wwwroot/css/base.css b/app/wwwroot/css/base.css deleted file mode 100644 index 00669dc..0000000 --- a/app/wwwroot/css/base.css +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Base Styles - Reset & Global Elements - * - * Normalization og grundlæggende styling - */ - -/* =========================================== - FONT FACES - =========================================== */ -@font-face { - font-family: 'Poppins'; - src: url('../fonts/Poppins-Regular.woff') format('woff'); - font-weight: 400; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('../fonts/Poppins-Medium.woff') format('woff'); - font-weight: 500; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('../fonts/Poppins-SemiBold.woff') format('woff'); - font-weight: 600; - font-style: normal; - font-display: swap; -} - -@font-face { - font-family: 'Poppins'; - src: url('../fonts/Poppins-Bold.woff') format('woff'); - font-weight: 700; - font-style: normal; - font-display: swap; -} - -/* =========================================== - RESET - =========================================== */ -*, -*::before, -*::after { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -html, -body { - height: 100%; -} - -/* =========================================== - BASE ELEMENTS - =========================================== */ -body { - font-family: var(--font-family); - font-size: var(--font-size-base); - color: var(--color-text); - background: var(--color-background); - line-height: var(--line-height-normal); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -/* Links */ -a { - color: var(--color-teal); - text-decoration: none; - transition: color var(--transition-fast); -} - -a:hover { - text-decoration: underline; -} - -/* Lists */ -ul, ol { - list-style: none; -} - -/* Images */ -img { - max-width: 100%; - height: auto; - display: block; -} - -/* Buttons */ -button { - font-family: inherit; - cursor: pointer; -} - -/* Inputs */ -input, -textarea, -select { - font-family: inherit; - font-size: inherit; -} - -/* Focus visible */ -:focus-visible { - outline: 2px solid var(--color-teal); - outline-offset: 2px; -} - -/* Selection */ -::selection { - background: var(--color-teal-light); - color: var(--color-text); -} diff --git a/app/wwwroot/css/design-system.css b/app/wwwroot/css/design-system.css deleted file mode 100644 index beb61ec..0000000 --- a/app/wwwroot/css/design-system.css +++ /dev/null @@ -1,163 +0,0 @@ -/** - * SWP Design System - CSS Variables - * - * Dette er den centrale definition af alle design tokens. - * Alle farver, fonts og layout-variabler defineres her. - */ - -/* =========================================== - COLOR PALETTE - Light Mode (Default) - =========================================== */ -:root { - /* Surfaces */ - --color-surface: #fff; - --color-background: #f5f5f5; - --color-background-hover: #f0f0f0; - --color-background-alt: #fafafa; - - /* Borders */ - --color-border: #e0e0e0; - --color-border-light: #f0f0f0; - - /* Text */ - --color-text: #333; - --color-text-secondary: #666; - --color-text-muted: #999; - - /* Brand Colors */ - --color-teal: #00897b; - --color-teal-light: color-mix(in srgb, var(--color-teal) 10%, transparent); - - /* Semantic Colors */ - --color-blue: #1976d2; - --color-green: #43a047; - --color-amber: #f59e0b; - --color-red: #e53935; - --color-purple: #8b5cf6; -} - -/* =========================================== - COLOR PALETTE - Dark Mode (System) - =========================================== */ -@media (prefers-color-scheme: dark) { - :root:not(.light-mode) { - --color-surface: #1e1e1e; - --color-background: #121212; - --color-background-hover: #2a2a2a; - --color-background-alt: #1a1a1a; - - --color-border: #333; - --color-border-light: #2a2a2a; - - --color-text: #e0e0e0; - --color-text-secondary: #999; - --color-text-muted: #666; - - --color-teal: #26a69a; - --color-blue: #42a5f5; - --color-green: #66bb6a; - --color-amber: #ffb74d; - --color-red: #ef5350; - --color-purple: #a78bfa; - } -} - -/* =========================================== - COLOR PALETTE - Dark Mode (Manual) - =========================================== */ -:root.dark-mode { - --color-surface: #1e1e1e; - --color-background: #121212; - --color-background-hover: #2a2a2a; - --color-background-alt: #1a1a1a; - - --color-border: #333; - --color-border-light: #2a2a2a; - - --color-text: #e0e0e0; - --color-text-secondary: #999; - --color-text-muted: #666; - - --color-teal: #26a69a; - --color-blue: #42a5f5; - --color-green: #66bb6a; - --color-amber: #ffb74d; - --color-red: #ef5350; - --color-purple: #a78bfa; -} - -/* =========================================== - TYPOGRAPHY - =========================================== */ -:root { - --font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - --font-mono: 'JetBrains Mono', monospace; - - /* Font Sizes */ - --font-size-xs: 11px; - --font-size-sm: 12px; - --font-size-base: 14px; - --font-size-md: 13px; - --font-size-lg: 16px; - --font-size-xl: 22px; - - /* Line Heights */ - --line-height-tight: 1.25; - --line-height-normal: 1.5; - --line-height-relaxed: 1.75; -} - -/* =========================================== - SPACING - =========================================== */ -:root { - --spacing-1: 4px; - --spacing-2: 8px; - --spacing-3: 12px; - --spacing-4: 16px; - --spacing-5: 20px; - --spacing-6: 24px; - --spacing-8: 32px; -} - -/* =========================================== - LAYOUT - =========================================== */ -:root { - --side-menu-width: 240px; - --side-menu-width-collapsed: 64px; - --topbar-height: 56px; - --page-max-width: 1400px; - --border-radius: 6px; - --border-radius-lg: 8px; -} - -/* =========================================== - TRANSITIONS - =========================================== */ -:root { - --transition-fast: 150ms ease; - --transition-normal: 200ms ease; - --transition-slow: 300ms ease; -} - -/* =========================================== - Z-INDEX LAYERS - =========================================== */ -:root { - --z-dropdown: 100; - --z-sticky: 200; - --z-overlay: 900; - --z-drawer: 1000; - --z-modal: 1100; - --z-tooltip: 1200; -} - -/* =========================================== - SHADOWS - =========================================== */ -:root { - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); - --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1); - --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.15); -} diff --git a/app/wwwroot/css/drawers.css b/app/wwwroot/css/drawers.css deleted file mode 100644 index 2805da5..0000000 --- a/app/wwwroot/css/drawers.css +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Drawers - Slide-in Panels - * - * Profile drawer, notifications drawer, etc. - */ - -/* =========================================== - BASE DRAWER - =========================================== */ -swp-profile-drawer, -swp-notification-drawer, -swp-todo-drawer { - position: fixed; - top: 0; - right: 0; - width: 320px; - height: 100vh; - background: var(--color-surface); - border-left: 1px solid var(--color-border); - box-shadow: var(--shadow-lg); - z-index: var(--z-drawer); - display: flex; - flex-direction: column; - transform: translateX(100%); - transition: transform var(--transition-normal); -} - -swp-profile-drawer.active, -swp-notification-drawer.active, -swp-todo-drawer.active { - transform: translateX(0); -} - -/* =========================================== - DRAWER HEADER - =========================================== */ -swp-drawer-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--spacing-4) var(--spacing-5); - border-bottom: 1px solid var(--color-border); - flex-shrink: 0; -} - -swp-drawer-title { - font-size: var(--font-size-lg); - font-weight: 600; - color: var(--color-text); -} - -swp-drawer-close { - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border: none; - background: transparent; - border-radius: var(--border-radius); - cursor: pointer; - color: var(--color-text-secondary); - transition: all var(--transition-fast); -} - -swp-drawer-close:hover { - background: var(--color-background-hover); - color: var(--color-text); -} - -swp-drawer-close i { - font-size: 20px; -} - -/* =========================================== - DRAWER CONTENT - =========================================== */ -swp-drawer-content { - flex: 1; - overflow-y: auto; - padding: var(--spacing-5); -} - -swp-drawer-divider { - height: 1px; - background: var(--color-border); - margin: var(--spacing-4) 0; -} - -/* =========================================== - PROFILE SECTION - =========================================== */ -swp-profile-section { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: var(--spacing-4) 0; -} - -swp-profile-avatar-large { - width: 64px; - height: 64px; - border-radius: 50%; - background: var(--color-teal); - color: white; - font-size: 24px; - font-weight: 600; - display: flex; - align-items: center; - justify-content: center; - margin-bottom: var(--spacing-3); -} - -swp-profile-name-large { - font-size: var(--font-size-lg); - font-weight: 600; - color: var(--color-text); - margin-bottom: var(--spacing-1); -} - -swp-profile-email { - font-size: var(--font-size-sm); - color: var(--color-text-secondary); -} - -/* =========================================== - DRAWER MENU - =========================================== */ -swp-drawer-menu { - display: flex; - flex-direction: column; - gap: var(--spacing-1); -} - -swp-drawer-menu-item { - display: flex; - align-items: center; - gap: var(--spacing-3); - padding: var(--spacing-3) var(--spacing-3); - border-radius: var(--border-radius); - cursor: pointer; - transition: background var(--transition-fast); - color: var(--color-text); -} - -swp-drawer-menu-item:hover { - background: var(--color-background-hover); -} - -swp-drawer-menu-item i { - font-size: 20px; - color: var(--color-text-secondary); -} - -/* =========================================== - THEME TOGGLE - =========================================== */ -swp-theme-toggle { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--spacing-3); - border-radius: var(--border-radius); - background: var(--color-background); -} - -swp-theme-label { - display: flex; - align-items: center; - gap: var(--spacing-3); - color: var(--color-text); -} - -swp-theme-label i { - font-size: 20px; - color: var(--color-text-secondary); -} - -swp-toggle-switch { - position: relative; - width: 44px; - height: 24px; -} - -swp-toggle-switch input { - opacity: 0; - width: 0; - height: 0; -} - -swp-toggle-slider { - position: absolute; - cursor: pointer; - inset: 0; - background: var(--color-border); - border-radius: 12px; - transition: background var(--transition-fast); -} - -swp-toggle-slider::before { - content: ''; - position: absolute; - width: 18px; - height: 18px; - left: 3px; - bottom: 3px; - background: white; - border-radius: 50%; - transition: transform var(--transition-fast); -} - -swp-toggle-switch input:checked + swp-toggle-slider { - background: var(--color-teal); -} - -swp-toggle-switch input:checked + swp-toggle-slider::before { - transform: translateX(20px); -} - -/* =========================================== - DRAWER FOOTER - =========================================== */ -swp-drawer-footer { - padding: var(--spacing-4) var(--spacing-5); - border-top: 1px solid var(--color-border); - flex-shrink: 0; -} - -swp-drawer-action { - display: flex; - align-items: center; - justify-content: center; - gap: var(--spacing-2); - width: 100%; - padding: var(--spacing-3); - font-size: var(--font-size-base); - font-family: var(--font-family); - color: var(--color-text-secondary); - background: transparent; - border: 1px solid var(--color-border); - border-radius: var(--border-radius); - cursor: pointer; - transition: all var(--transition-fast); -} - -swp-drawer-action:hover { - background: var(--color-background-hover); -} - -swp-drawer-action.logout:hover { - color: var(--color-red); - border-color: var(--color-red); -} - -swp-drawer-action i { - font-size: 18px; -} diff --git a/app/wwwroot/css/page.css b/app/wwwroot/css/page.css deleted file mode 100644 index cf4b9c7..0000000 --- a/app/wwwroot/css/page.css +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Page Layout - Content Area Structure - * - * Page container, headers, cards og grid layouts - */ - -/* =========================================== - PAGE CONTAINER - =========================================== */ -swp-page-container { - display: block; - max-width: var(--page-max-width); - margin: 0 auto; - padding: var(--spacing-6); -} - -/* =========================================== - PAGE HEADER - =========================================== */ -swp-page-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - margin-bottom: var(--spacing-6); -} - -swp-page-title h1 { - font-size: 24px; - font-weight: 600; - color: var(--color-text); - margin-bottom: var(--spacing-1); -} - -swp-page-title p { - font-size: var(--font-size-base); - color: var(--color-text-secondary); -} - -swp-page-actions { - display: flex; - gap: var(--spacing-2); -} - -/* =========================================== - CARDS - =========================================== */ -swp-card { - display: block; - background: var(--color-surface); - border: 1px solid var(--color-border); - border-radius: var(--border-radius-lg); - margin-bottom: var(--spacing-5); -} - -swp-card-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--spacing-4) var(--spacing-5); - border-bottom: 1px solid var(--color-border); -} - -swp-card-title { - display: flex; - align-items: center; - gap: var(--spacing-2); - font-size: var(--font-size-base); - font-weight: 600; - color: var(--color-text); -} - -swp-card-title i { - font-size: 20px; - color: var(--color-text-secondary); -} - -swp-card-action { - font-size: var(--font-size-md); - color: var(--color-teal); - cursor: pointer; - transition: opacity var(--transition-fast); -} - -swp-card-action:hover { - opacity: 0.8; -} - -swp-card-content { - padding: var(--spacing-5); -} - -/* =========================================== - DASHBOARD GRID - =========================================== */ -swp-dashboard-grid { - display: grid; - grid-template-columns: 1fr 350px; - gap: var(--spacing-5); -} - -swp-main-column { - display: flex; - flex-direction: column; -} - -swp-side-column { - display: flex; - flex-direction: column; -} - -/* =========================================== - AI INSIGHT - =========================================== */ -swp-ai-insight { - display: block; - padding: var(--spacing-4) var(--spacing-5); - background: linear-gradient(135deg, - color-mix(in srgb, var(--color-purple) 8%, transparent), - color-mix(in srgb, var(--color-teal) 8%, transparent) - ); - border-radius: var(--border-radius); -} - -swp-ai-header { - display: flex; - align-items: center; - gap: var(--spacing-2); - margin-bottom: var(--spacing-2); - font-size: var(--font-size-sm); - font-weight: 500; - color: var(--color-purple); -} - -swp-ai-header i { - font-size: 16px; -} - -swp-ai-text { - font-size: var(--font-size-base); - color: var(--color-text); - line-height: var(--line-height-relaxed); -} - -/* =========================================== - QUICK ACTIONS - =========================================== */ -swp-quick-actions { - display: flex; - flex-direction: column; - gap: var(--spacing-2); -} - -swp-quick-action-btn { - display: flex; - align-items: center; - gap: var(--spacing-2); - padding: var(--spacing-3); - font-size: var(--font-size-base); - font-family: var(--font-family); - color: var(--color-text); - background: var(--color-background); - border: 1px solid var(--color-border); - border-radius: var(--border-radius); - cursor: pointer; - transition: all var(--transition-fast); -} - -swp-quick-action-btn:hover { - background: var(--color-background-hover); - border-color: var(--color-teal); - color: var(--color-teal); -} - -swp-quick-action-btn i { - font-size: 18px; -} - -/* =========================================== - RESPONSIVE - =========================================== */ -@media (max-width: 1200px) { - swp-dashboard-grid { - grid-template-columns: 1fr; - } - - swp-side-column { - order: -1; - } -} - -@media (max-width: 768px) { - swp-page-container { - padding: var(--spacing-4); - } - - swp-page-header { - flex-direction: column; - gap: var(--spacing-4); - } - - swp-page-actions { - width: 100%; - } -} diff --git a/app/wwwroot/css/sidebar.css b/app/wwwroot/css/sidebar.css deleted file mode 100644 index cc9354e..0000000 --- a/app/wwwroot/css/sidebar.css +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Sidebar - Side Menu Component - * - * Navigation sidebar med collapse-funktionalitet - */ - -/* =========================================== - SIDE MENU CONTAINER - =========================================== */ -swp-side-menu { - grid-row: 1 / -1; - display: flex; - flex-direction: column; - background: var(--color-surface); - border-right: 1px solid var(--color-border); - overflow-y: auto; - overflow-x: hidden; -} - -/* =========================================== - HEADER - =========================================== */ -swp-side-menu-header { - display: flex; - align-items: center; - gap: 10px; - height: var(--topbar-height); - padding: 0 var(--spacing-4); - border-bottom: 1px solid var(--color-border); - flex-shrink: 0; -} - -swp-side-menu-header > i { - font-size: 26px; - color: var(--color-teal); -} - -swp-side-menu-logo { - font-size: var(--font-size-lg); - font-weight: 600; - color: var(--color-text); -} - -/* Toggle Button */ -swp-menu-toggle { - margin-left: auto; - width: 28px; - height: 28px; - display: flex; - align-items: center; - justify-content: center; - border: none; - background: transparent; - border-radius: var(--border-radius); - cursor: pointer; - color: var(--color-text-secondary); - transition: all var(--transition-fast); -} - -swp-menu-toggle:hover { - background: var(--color-background-hover); - color: var(--color-text); -} - -swp-menu-toggle i { - font-size: 18px; - color: inherit; - transition: transform var(--transition-normal); -} - -/* =========================================== - NAVIGATION - =========================================== */ -swp-side-menu-nav { - flex: 1; - padding: var(--spacing-3) 0; - overflow-y: auto; -} - -swp-side-menu-group { - display: block; - margin-bottom: var(--spacing-2); -} - -swp-side-menu-label { - display: block; - padding: var(--spacing-2) var(--spacing-4) 6px; - font-size: var(--font-size-xs); - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; - color: var(--color-text-secondary); -} - -/* =========================================== - MENU ITEMS - =========================================== */ -swp-side-menu-item, -a[is="swp-side-menu-item"] { - display: flex; - align-items: center; - gap: var(--spacing-3); - padding: 10px var(--spacing-4); - color: var(--color-text); - cursor: pointer; - transition: all var(--transition-fast); - border-left: 3px solid transparent; - text-decoration: none; -} - -swp-side-menu-item:hover, -a[is="swp-side-menu-item"]:hover { - background: var(--color-background-hover); - text-decoration: none; -} - -swp-side-menu-item[data-active="true"], -a[is="swp-side-menu-item"][data-active="true"] { - background: var(--color-teal-light); - border-left-color: var(--color-teal); - color: var(--color-teal); - font-weight: 500; -} - -swp-side-menu-item i, -a[is="swp-side-menu-item"] i { - font-size: 20px; - flex-shrink: 0; -} - -/* =========================================== - FOOTER - =========================================== */ -swp-side-menu-footer { - display: flex; - flex-direction: column; - gap: var(--spacing-2); - padding: var(--spacing-3) var(--spacing-4); - border-top: 1px solid var(--color-border); - margin-top: auto; - flex-shrink: 0; -} - -swp-side-menu-action { - display: flex; - align-items: center; - justify-content: center; - gap: var(--spacing-2); - padding: 10px; - font-size: var(--font-size-md); - color: var(--color-text-secondary); - background: transparent; - border: 1px solid var(--color-border); - border-radius: var(--border-radius); - cursor: pointer; - transition: all var(--transition-fast); - font-family: var(--font-family); -} - -swp-side-menu-action:hover { - background: var(--color-background-hover); -} - -swp-side-menu-action.lock:hover { - color: var(--color-amber); - border-color: var(--color-amber); -} - -swp-side-menu-action.logout:hover { - color: var(--color-red); - border-color: var(--color-red); -} - -swp-side-menu-action i { - font-size: 18px; -} - -/* =========================================== - COLLAPSED STATE - =========================================== */ -swp-app-layout.menu-collapsed swp-side-menu { - overflow: visible; -} - -swp-app-layout.menu-collapsed swp-side-menu-logo, -swp-app-layout.menu-collapsed swp-side-menu-label, -swp-app-layout.menu-collapsed swp-side-menu-item span, -swp-app-layout.menu-collapsed swp-side-menu-action span, -swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] span { - display: none; -} - -swp-app-layout.menu-collapsed swp-side-menu-header { - justify-content: center; - padding: 0; -} - -swp-app-layout.menu-collapsed swp-menu-toggle { - margin-left: 0; -} - -swp-app-layout.menu-collapsed swp-menu-toggle i { - transform: rotate(180deg); -} - -swp-app-layout.menu-collapsed swp-side-menu-item, -swp-app-layout.menu-collapsed a[is="swp-side-menu-item"] { - justify-content: center; - padding: var(--spacing-3); - border-left: none; -} - -swp-app-layout.menu-collapsed swp-side-menu-item[data-active="true"], -swp-app-layout.menu-collapsed a[is="swp-side-menu-item"][data-active="true"] { - border-left: none; - border-radius: var(--border-radius-lg); - margin: 0 var(--spacing-2); -} - -swp-app-layout.menu-collapsed swp-side-menu-action { - justify-content: center; - padding: var(--spacing-3); -} - -swp-app-layout.menu-collapsed swp-side-menu-footer { - padding: var(--spacing-3) var(--spacing-2); -} - -/* =========================================== - TOOLTIP (Collapsed State) - =========================================== */ -.swp-menu-tooltip { - position: fixed; - margin: 0; - padding: 6px var(--spacing-3); - background: var(--color-surface); - border: 1px solid var(--color-border); - border-radius: var(--border-radius); - font-size: var(--font-size-md); - font-family: var(--font-family); - color: var(--color-text); - white-space: nowrap; - box-shadow: var(--shadow-md); - pointer-events: none; - z-index: var(--z-tooltip); -} diff --git a/app/wwwroot/css/stats.css b/app/wwwroot/css/stats.css deleted file mode 100644 index 2d50a5f..0000000 --- a/app/wwwroot/css/stats.css +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Stats - Statistics Components - * - * Stat bars, cards, values og trends - */ - -/* =========================================== - STATS CONTAINER (Grid/Bar/Row) - =========================================== */ -swp-stats-bar, -swp-stats-grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: var(--spacing-4); - margin-bottom: var(--spacing-5); -} - -swp-stats-row { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: var(--spacing-4); - margin-bottom: var(--spacing-5); -} - -/* =========================================== - STAT CARD - =========================================== */ -swp-stat-card { - display: flex; - flex-direction: column; - background: var(--color-surface); - border-radius: var(--border-radius-lg); - padding: var(--spacing-4) var(--spacing-5); - border: 1px solid var(--color-border); -} - -swp-stat-box { - display: flex; - flex-direction: column; - gap: var(--spacing-1); - padding: var(--spacing-4); - background: var(--color-surface); - border-radius: var(--border-radius); - border: 1px solid var(--color-border); -} - -/* =========================================== - STAT VALUE - =========================================== */ -swp-stat-value { - display: block; - font-size: 22px; - font-weight: 600; - font-family: var(--font-mono); - color: var(--color-text); - line-height: var(--line-height-tight); -} - -/* Larger variant for emphasis */ -swp-stat-card swp-stat-value, -swp-stat-box swp-stat-value { - font-size: 22px; - font-weight: 600; - font-family: var(--font-mono); - color: var(--color-text); -} - -/* =========================================== - STAT LABEL - =========================================== */ -swp-stat-label { - display: block; - font-size: var(--font-size-sm); - color: var(--color-text-secondary); - margin-top: var(--spacing-1); -} - -swp-stat-box swp-stat-label { - font-size: 11px; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.5px; - color: var(--color-text-secondary); -} - -/* =========================================== - STAT SUBTITLE - =========================================== */ -swp-stat-subtitle { - display: block; - font-size: 11px; - color: var(--color-text-muted); - margin-top: var(--spacing-1); -} - -/* =========================================== - STAT TREND / CHANGE - =========================================== */ -swp-stat-trend, -swp-stat-change { - display: inline-flex; - align-items: center; - gap: var(--spacing-1); - font-size: var(--font-size-xs); - margin-top: var(--spacing-2); -} - -swp-stat-trend i, -swp-stat-change i { - font-size: 14px; -} - -/* Trend Up (positive) */ -swp-stat-trend.up, -swp-stat-change.positive { - color: var(--color-green); -} - -/* Trend Down (negative) */ -swp-stat-trend.down, -swp-stat-change.negative { - color: var(--color-red); -} - -/* Neutral trend */ -swp-stat-trend.neutral { - color: var(--color-text-secondary); -} - -/* =========================================== - COLOR MODIFIERS - =========================================== */ - -/* Highlight (Primary/Teal) */ -swp-stat-card.highlight swp-stat-value, -swp-stat-box.highlight swp-stat-value, -swp-stat-card.teal swp-stat-value { - color: var(--color-teal); -} - -/* Success (Green) */ -swp-stat-card.success swp-stat-value { - color: var(--color-green); -} - -/* Warning (Amber) */ -swp-stat-card.warning swp-stat-value, -swp-stat-card.amber swp-stat-value { - color: var(--color-amber); -} - -/* Danger (Red) */ -swp-stat-card.danger swp-stat-value, -swp-stat-card.negative swp-stat-value, -swp-stat-card.red swp-stat-value { - color: var(--color-red); -} - -/* Purple */ -swp-stat-card.purple swp-stat-value { - color: var(--color-purple); -} - -/* =========================================== - HIGHLIGHT CARD (Filled Background) - =========================================== */ -swp-stat-card.highlight.filled { - background: linear-gradient(135deg, var(--color-teal) 0%, #00695c 100%); - color: white; - border-color: transparent; -} - -swp-stat-card.highlight.filled swp-stat-value { - color: white; -} - -swp-stat-card.highlight.filled swp-stat-label { - color: rgba(255, 255, 255, 0.8); -} - -swp-stat-card.highlight.filled swp-stat-change { - color: rgba(255, 255, 255, 0.9); -} - -/* =========================================== - QUICK STATS (Compact Variant) - =========================================== */ -swp-quick-stats { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: var(--spacing-3); -} - -swp-quick-stat { - display: flex; - flex-direction: column; - text-align: center; - padding: var(--spacing-3); - background: var(--color-background); - border-radius: var(--border-radius); -} - -swp-quick-stat swp-stat-value { - font-size: 18px; -} - -swp-quick-stat swp-stat-label { - font-size: 11px; - margin-top: var(--spacing-1); -} - -/* =========================================== - STAT ITEM (Inline Variant) - =========================================== */ -swp-stat-item { - display: flex; - flex-direction: column; - gap: 2px; - padding: var(--spacing-2) var(--spacing-3); - background: var(--color-background); - border-radius: var(--border-radius); -} - -swp-stat-item swp-stat-value { - font-size: 16px; - font-weight: 600; -} - -swp-stat-item swp-stat-value.mono { - font-family: var(--font-mono); -} - -swp-stat-item swp-stat-label { - font-size: 11px; - margin-top: 0; -} - -/* =========================================== - RESPONSIVE - =========================================== */ -@media (max-width: 1200px) { - swp-stats-bar, - swp-stats-grid { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (max-width: 768px) { - swp-stats-bar, - swp-stats-grid, - swp-stats-row { - grid-template-columns: 1fr; - } - - swp-quick-stats { - grid-template-columns: repeat(2, 1fr); - } -} diff --git a/app/wwwroot/css/topbar.css b/app/wwwroot/css/topbar.css deleted file mode 100644 index 6c9d182..0000000 --- a/app/wwwroot/css/topbar.css +++ /dev/null @@ -1,180 +0,0 @@ -/** - * Topbar - App Header Bar - * - * Search, notifications og profil-menu - */ - -/* =========================================== - TOPBAR CONTAINER - =========================================== */ -swp-app-topbar { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0 var(--spacing-5); - background: var(--color-surface); - border-bottom: 1px solid var(--color-border); - position: sticky; - top: 0; - z-index: var(--z-sticky); -} - -/* =========================================== - SEARCH - =========================================== */ -swp-topbar-search { - display: flex; - align-items: center; - gap: 10px; - padding: var(--spacing-2) var(--spacing-3); - background: var(--color-background); - border: 1px solid var(--color-border); - border-radius: var(--border-radius); - width: 320px; - transition: border-color var(--transition-fast); -} - -swp-topbar-search:focus-within { - border-color: var(--color-teal); -} - -swp-topbar-search i { - font-size: 18px; - color: var(--color-text-secondary); - flex-shrink: 0; -} - -swp-topbar-search input { - flex: 1; - border: none; - outline: none; - background: transparent; - font-size: var(--font-size-md); - font-family: var(--font-family); - color: var(--color-text); -} - -swp-topbar-search input::placeholder { - color: var(--color-text-secondary); -} - -swp-topbar-search kbd { - font-size: var(--font-size-xs); - font-family: var(--font-mono); - padding: 2px 6px; - background: var(--color-surface); - border: 1px solid var(--color-border); - border-radius: 4px; - color: var(--color-text-secondary); -} - -/* =========================================== - ACTIONS - =========================================== */ -swp-topbar-actions { - display: flex; - align-items: center; - gap: var(--spacing-2); -} - -/* Action Buttons */ -swp-topbar-btn { - display: flex; - align-items: center; - justify-content: center; - width: 38px; - height: 38px; - border: none; - background: transparent; - border-radius: var(--border-radius); - cursor: pointer; - transition: background var(--transition-fast); - position: relative; - color: var(--color-text-secondary); -} - -swp-topbar-btn:hover { - background: var(--color-background-hover); -} - -swp-topbar-btn i { - font-size: 22px; -} - -/* Notification Badge */ -swp-notification-badge { - position: absolute; - top: 6px; - right: 6px; - min-width: 16px; - height: 16px; - padding: 0 4px; - font-size: 10px; - font-weight: 600; - background: var(--color-red); - color: white; - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; -} - -/* Divider */ -swp-topbar-divider { - width: 1px; - height: 24px; - background: var(--color-border); - margin: 0 var(--spacing-2); -} - -/* =========================================== - PROFILE TRIGGER - =========================================== */ -swp-topbar-profile { - display: flex; - align-items: center; - gap: 10px; - padding: 6px var(--spacing-3) 6px 6px; - background: transparent; - border: 1px solid transparent; - border-radius: var(--border-radius); - cursor: pointer; - transition: all var(--transition-fast); -} - -swp-topbar-profile:hover { - background: var(--color-background-hover); - border-color: var(--color-border); -} - -swp-profile-avatar { - width: 32px; - height: 32px; - border-radius: 50%; - background: var(--color-teal); - color: white; - font-size: var(--font-size-sm); - font-weight: 600; - display: flex; - align-items: center; - justify-content: center; -} - -swp-profile-info { - display: flex; - flex-direction: column; - align-items: flex-start; -} - -swp-profile-name { - font-size: var(--font-size-md); - font-weight: 500; - color: var(--color-text); - line-height: var(--line-height-tight); -} - -swp-profile-role { - font-size: var(--font-size-xs); - color: var(--color-text-secondary); - line-height: var(--line-height-tight); -} diff --git a/app/wwwroot/fonts/Poppins-Black.woff b/app/wwwroot/fonts/Poppins-Black.woff deleted file mode 100644 index 65f380175b9d3cd42633b343cb8085a8f6ffe802..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64180 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 diff --git a/app/wwwroot/fonts/Poppins-BlackItalic.woff b/app/wwwroot/fonts/Poppins-BlackItalic.woff deleted file mode 100644 index 63eb02ed84faa517c6ba1a4b13705bc3f24f4bc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71488 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

9K%Zl#e3n1is0?= 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 zva�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�%vp}NZo1%zLOYHS6-MB zmHCZG0Sx+z%E7zt5)gE}4m^r=z)$2(q65MePx1G%UJ;pI?VIdnT~YG(4?mi!BqMh^ zeaQ(F7RJw~@^HGK4F%b9lm+00C^{izCP=yx*Y4~7ji=iMUPE(`bUxsE0h

z?mM-XxR`+81%l@jSB1^OmCO?DqhigZ*vX;B z81`}F#OV|HdF(cc1V%F&gbdC?Mi`~LFt~1Rn#_&uBJA&%vpaR+&gx+7R!DD?V?iDFX>E&YL=>;eL6eS+a ztyiqpgKuK}h2G}udB?}o`i!Ju%NE{e;AQ_5K4)J|G)$Ef;5iu2f^;$->=SzstxHrg zqb-Ip$(hXY*9FcN)+^TQ!RM2^6K%--6jJkByG(02%4 zBM5%fj$=u z7nCT79qOgb@o$A0xCyxhn~lZY+1}b->=R78xCD?S=OrBf2laKkvy5q>jL41Z$0e&# zoIjr^#?m2t;>bl}o1ge50Rr(J5?`Y(S{BH+BDV~z+Cx*oXkjvv(#IGkuL`7(yG&rD zdqzu|A#&?LGR>ZEVt3OPmQJq*55Wlt`o}(uGB^(<+g(FYCjz z7WlzA5n$@ag@Gz>I{M-nA1TdHO9~P#FNd;Rp{+U1=OZtMeXuayTj47V`YNLy4Q
x5)GWGs9zNPRE`hFaBY$CdOUcJWgx3wX* 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�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�L!XzJccl)}!A)V8S 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ɲSD;H&r=zK(C;oA?&Kjql*Q_#VEGAK-`h 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 H00000VkJh! diff --git a/app/wwwroot/fonts/Poppins-ExtraLight.woff b/app/wwwroot/fonts/Poppins-ExtraLight.woff deleted file mode 100644 index 8eb40950af11a1a66a7c97b0a4b1f0feddfbb334..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66456 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 z%0D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 MO#lD@0RR910KBVow*UYD diff --git a/app/wwwroot/fonts/Poppins-Regular.woff b/app/wwwroot/fonts/Poppins-Regular.woff deleted file mode 100644 index 609eb3dc3732cb8064bb2c6c38d11be30e29ee2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66464 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%0ALzO^bCpDN!m3v&^;(pdW`7QgE*M{ks;-? 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

Dy49x}&xA2(v*=pfu~x*SGiehhbf2-p2e@ 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

gDX>1MRV;)ByD0Iqodfpvbxlg-+ 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

ZX|l!?anAz?=p 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ɲSD;H&r= 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 vYkO$_aJd-` drawer?.classList.remove('active')); - - this.overlay?.classList.remove('active'); - document.body.style.overflow = ''; - this.activeDrawer = null; - } - - /** - * Open profile drawer - */ - openProfile(): void { - this.open('profile'); - } - - /** - * Open notification drawer - */ - openNotification(): void { - this.open('notification'); - } - - /** - * Open todo drawer (slides on top of profile) - */ - openTodo(): void { - this.todoDrawer?.classList.add('active'); - } - - /** - * Close todo drawer - */ - closeTodo(): void { - this.todoDrawer?.classList.remove('active'); - this.closeNewTodo(); - } - - /** - * Open new todo drawer - */ - openNewTodo(): void { - this.newTodoDrawer?.classList.add('active'); - } - - /** - * Close new todo drawer - */ - closeNewTodo(): void { - this.newTodoDrawer?.classList.remove('active'); - } - - /** - * Mark all notifications as read - */ - markAllNotificationsRead(): void { - if (!this.notificationDrawer) return; - - const unreadItems = this.notificationDrawer.querySelectorAll( - 'swp-notification-item[data-unread="true"]' - ); - unreadItems.forEach(item => item.removeAttribute('data-unread')); - - const badge = document.querySelector('swp-notification-badge'); - if (badge) { - badge.style.display = 'none'; - } - } - - private getDrawer(name: DrawerName): HTMLElement | null { - switch (name) { - case 'profile': return this.profileDrawer; - case 'notification': return this.notificationDrawer; - case 'todo': return this.todoDrawer; - case 'newTodo': return this.newTodoDrawer; - } - } - - private setupListeners(): void { - // Profile drawer triggers - document.getElementById('profileTrigger') - ?.addEventListener('click', () => this.openProfile()); - document.getElementById('drawerClose') - ?.addEventListener('click', () => this.close('profile')); - - // Notification drawer triggers - document.getElementById('notificationsBtn') - ?.addEventListener('click', () => this.openNotification()); - document.getElementById('notificationDrawerClose') - ?.addEventListener('click', () => this.close('notification')); - document.getElementById('markAllRead') - ?.addEventListener('click', () => this.markAllNotificationsRead()); - - // Todo drawer triggers - document.getElementById('openTodoDrawer') - ?.addEventListener('click', () => this.openTodo()); - document.getElementById('todoDrawerBack') - ?.addEventListener('click', () => this.closeTodo()); - - // New todo drawer triggers - document.getElementById('addTodoBtn') - ?.addEventListener('click', () => this.openNewTodo()); - document.getElementById('newTodoDrawerBack') - ?.addEventListener('click', () => this.closeNewTodo()); - document.getElementById('cancelNewTodo') - ?.addEventListener('click', () => this.closeNewTodo()); - document.getElementById('saveNewTodo') - ?.addEventListener('click', () => this.closeNewTodo()); - - // Overlay click closes all - this.overlay?.addEventListener('click', () => this.closeAll()); - - // Escape key closes all - document.addEventListener('keydown', (e: KeyboardEvent) => { - if (e.key === 'Escape') this.closeAll(); - }); - - // Todo interactions - this.todoDrawer?.addEventListener('click', (e) => this.handleTodoClick(e)); - - // Visibility options - document.addEventListener('click', (e) => this.handleVisibilityClick(e)); - } - - private handleTodoClick(e: Event): void { - const target = e.target as HTMLElement; - const todoItem = target.closest('swp-todo-item'); - const checkbox = target.closest('swp-todo-checkbox'); - - if (checkbox && todoItem) { - const isCompleted = todoItem.dataset.completed === 'true'; - if (isCompleted) { - todoItem.removeAttribute('data-completed'); - } else { - todoItem.dataset.completed = 'true'; - } - } - - // Toggle section collapse - const sectionHeader = target.closest('swp-todo-section-header'); - if (sectionHeader) { - const section = sectionHeader.closest('swp-todo-section'); - section?.classList.toggle('collapsed'); - } - } - - private handleVisibilityClick(e: Event): void { - const target = e.target as HTMLElement; - const option = target.closest('swp-visibility-option'); - - if (option) { - document.querySelectorAll('swp-visibility-option') - .forEach(o => o.classList.remove('active')); - option.classList.add('active'); - } - } -} diff --git a/app/wwwroot/ts/modules/lockscreen.ts b/app/wwwroot/ts/modules/lockscreen.ts deleted file mode 100644 index f6a5878..0000000 --- a/app/wwwroot/ts/modules/lockscreen.ts +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Lock Screen Controller - * - * Handles PIN-based lock screen functionality - */ - -import { DrawerController } from './drawers'; - -export class LockScreenController { - private static readonly CORRECT_PIN = '1234'; // Demo PIN - - private lockScreen: HTMLElement | null = null; - private pinInput: HTMLElement | null = null; - private pinKeypad: HTMLElement | null = null; - private lockTimeEl: HTMLElement | null = null; - private pinDigits: NodeListOf | null = null; - private currentPin = ''; - private drawers: DrawerController | null = null; - - constructor(drawers?: DrawerController) { - this.drawers = drawers ?? null; - this.lockScreen = document.getElementById('lockScreen'); - this.pinInput = document.getElementById('pinInput'); - this.pinKeypad = document.getElementById('pinKeypad'); - this.lockTimeEl = document.getElementById('lockTime'); - this.pinDigits = this.pinInput?.querySelectorAll('swp-pin-digit') ?? null; - - this.setupListeners(); - } - - /** - * Check if lock screen is active - */ - get isActive(): boolean { - return this.lockScreen?.classList.contains('active') ?? false; - } - - /** - * Show the lock screen - */ - show(): void { - this.drawers?.closeAll(); - - if (this.lockScreen) { - this.lockScreen.classList.add('active'); - document.body.style.overflow = 'hidden'; - } - - this.currentPin = ''; - this.updateDisplay(); - - // Update lock time - if (this.lockTimeEl) { - this.lockTimeEl.textContent = `Låst kl. ${this.formatTime()}`; - } - } - - /** - * Hide the lock screen - */ - hide(): void { - if (this.lockScreen) { - this.lockScreen.classList.remove('active'); - document.body.style.overflow = ''; - } - - this.currentPin = ''; - this.updateDisplay(); - } - - private formatTime(): string { - const now = new Date(); - const hours = now.getHours().toString().padStart(2, '0'); - const minutes = now.getMinutes().toString().padStart(2, '0'); - return `${hours}:${minutes}`; - } - - private updateDisplay(): void { - if (!this.pinDigits) return; - - this.pinDigits.forEach((digit, index) => { - digit.classList.remove('filled', 'error'); - if (index < this.currentPin.length) { - digit.textContent = '•'; - digit.classList.add('filled'); - } else { - digit.textContent = ''; - } - }); - } - - private showError(): void { - if (!this.pinDigits) return; - - this.pinDigits.forEach(digit => digit.classList.add('error')); - - // Shake animation - this.pinInput?.classList.add('shake'); - - setTimeout(() => { - this.currentPin = ''; - this.updateDisplay(); - this.pinInput?.classList.remove('shake'); - }, 500); - } - - private verify(): void { - if (this.currentPin === LockScreenController.CORRECT_PIN) { - this.hide(); - } else { - this.showError(); - } - } - - private addDigit(digit: string): void { - if (this.currentPin.length >= 4) return; - - this.currentPin += digit; - this.updateDisplay(); - - // Auto-verify when 4 digits entered - if (this.currentPin.length === 4) { - setTimeout(() => this.verify(), 200); - } - } - - private removeDigit(): void { - if (this.currentPin.length === 0) return; - this.currentPin = this.currentPin.slice(0, -1); - this.updateDisplay(); - } - - private clearPin(): void { - this.currentPin = ''; - this.updateDisplay(); - } - - private setupListeners(): void { - // Keypad click handler - this.pinKeypad?.addEventListener('click', (e) => this.handleKeypadClick(e)); - - // Keyboard input - document.addEventListener('keydown', (e) => this.handleKeyboard(e)); - - // Lock button in sidebar - document.querySelector('swp-side-menu-action.lock') - ?.addEventListener('click', () => this.show()); - } - - private handleKeypadClick(e: Event): void { - const target = e.target as HTMLElement; - const key = target.closest('swp-pin-key'); - - if (!key) return; - - const digit = key.dataset.digit; - const action = key.dataset.action; - - if (digit) { - this.addDigit(digit); - } else if (action === 'backspace') { - this.removeDigit(); - } else if (action === 'clear') { - this.clearPin(); - } - } - - private handleKeyboard(e: KeyboardEvent): void { - if (!this.isActive) return; - - // Prevent default to avoid other interactions - e.preventDefault(); - - if (e.key >= '0' && e.key <= '9') { - this.addDigit(e.key); - } else if (e.key === 'Backspace') { - this.removeDigit(); - } else if (e.key === 'Escape') { - this.clearPin(); - } - } -} diff --git a/app/wwwroot/ts/modules/search.ts b/app/wwwroot/ts/modules/search.ts deleted file mode 100644 index d6eac21..0000000 --- a/app/wwwroot/ts/modules/search.ts +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Search Controller - * - * Handles global search functionality and keyboard shortcuts - */ - -export class SearchController { - private input: HTMLInputElement | null = null; - private container: HTMLElement | null = null; - - constructor() { - this.input = document.getElementById('globalSearch') as HTMLInputElement | null; - this.container = document.querySelector('swp-topbar-search'); - - this.setupListeners(); - } - - /** - * Get current search value - */ - get value(): string { - return this.input?.value ?? ''; - } - - /** - * Set search value - */ - set value(val: string) { - if (this.input) { - this.input.value = val; - } - } - - /** - * Focus the search input - */ - focus(): void { - this.input?.focus(); - } - - /** - * Blur the search input - */ - blur(): void { - this.input?.blur(); - } - - /** - * Clear the search input - */ - clear(): void { - this.value = ''; - } - - private setupListeners(): void { - // Keyboard shortcuts - document.addEventListener('keydown', (e) => this.handleKeyboard(e)); - - // Input handlers - if (this.input) { - this.input.addEventListener('input', (e) => this.handleInput(e)); - - // Prevent form submission if wrapped in form - const form = this.input.closest('form'); - form?.addEventListener('submit', (e) => this.handleSubmit(e)); - } - } - - private handleKeyboard(e: KeyboardEvent): void { - // Cmd/Ctrl + K to focus search - if ((e.metaKey || e.ctrlKey) && e.key === 'k') { - e.preventDefault(); - this.focus(); - return; - } - - // Escape to blur search when focused - if (e.key === 'Escape' && document.activeElement === this.input) { - this.blur(); - } - } - - private handleInput(e: Event): void { - const target = e.target as HTMLInputElement; - const query = target.value.trim(); - - // Emit custom event for search - document.dispatchEvent(new CustomEvent('app:search', { - detail: { query }, - bubbles: true - })); - } - - private handleSubmit(e: Event): void { - e.preventDefault(); - - const query = this.value.trim(); - if (!query) return; - - // Emit custom event for search submit - document.dispatchEvent(new CustomEvent('app:search-submit', { - detail: { query }, - bubbles: true - })); - } -} diff --git a/app/wwwroot/ts/modules/sidebar.ts b/app/wwwroot/ts/modules/sidebar.ts deleted file mode 100644 index ddb0a2b..0000000 --- a/app/wwwroot/ts/modules/sidebar.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Sidebar Controller - * - * Handles sidebar collapse/expand and tooltip functionality - */ - -export class SidebarController { - private menuToggle: HTMLElement | null = null; - private appLayout: HTMLElement | null = null; - private menuTooltip: HTMLElement | null = null; - - constructor() { - this.menuToggle = document.getElementById('menuToggle'); - this.appLayout = document.querySelector('swp-app-layout'); - this.menuTooltip = document.getElementById('menuTooltip'); - - this.setupListeners(); - this.setupTooltips(); - this.restoreState(); - } - - /** - * Check if sidebar is collapsed - */ - get isCollapsed(): boolean { - return this.appLayout?.classList.contains('menu-collapsed') ?? false; - } - - /** - * Toggle sidebar collapsed state - */ - toggle(): void { - if (!this.appLayout) return; - - this.appLayout.classList.toggle('menu-collapsed'); - localStorage.setItem('sidebar-collapsed', String(this.isCollapsed)); - } - - /** - * Collapse the sidebar - */ - collapse(): void { - this.appLayout?.classList.add('menu-collapsed'); - localStorage.setItem('sidebar-collapsed', 'true'); - } - - /** - * Expand the sidebar - */ - expand(): void { - this.appLayout?.classList.remove('menu-collapsed'); - localStorage.setItem('sidebar-collapsed', 'false'); - } - - private setupListeners(): void { - this.menuToggle?.addEventListener('click', () => this.toggle()); - } - - private setupTooltips(): void { - if (!this.menuTooltip) return; - - const menuItems = document.querySelectorAll('swp-side-menu-item[data-tooltip]'); - - menuItems.forEach(item => { - item.addEventListener('mouseenter', () => this.showTooltip(item)); - item.addEventListener('mouseleave', () => this.hideTooltip()); - }); - } - - private showTooltip(item: HTMLElement): void { - if (!this.isCollapsed || !this.menuTooltip) return; - - const rect = item.getBoundingClientRect(); - const tooltipText = item.dataset.tooltip; - - if (!tooltipText) return; - - this.menuTooltip.textContent = tooltipText; - this.menuTooltip.style.left = `${rect.right + 8}px`; - this.menuTooltip.style.top = `${rect.top + rect.height / 2}px`; - this.menuTooltip.style.transform = 'translateY(-50%)'; - this.menuTooltip.showPopover(); - } - - private hideTooltip(): void { - this.menuTooltip?.hidePopover(); - } - - private restoreState(): void { - if (!this.appLayout) return; - - if (localStorage.getItem('sidebar-collapsed') === 'true') { - this.appLayout.classList.add('menu-collapsed'); - } - } -} diff --git a/app/wwwroot/ts/modules/theme.ts b/app/wwwroot/ts/modules/theme.ts deleted file mode 100644 index b14e4b5..0000000 --- a/app/wwwroot/ts/modules/theme.ts +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Theme Controller - * - * Handles dark/light mode switching and system preference detection - */ - -export type Theme = 'light' | 'dark' | 'system'; - -export class ThemeController { - private static readonly STORAGE_KEY = 'theme-preference'; - private static readonly DARK_CLASS = 'dark-mode'; - private static readonly LIGHT_CLASS = 'light-mode'; - - private root: HTMLElement; - private themeOptions: NodeListOf; - - constructor() { - this.root = document.documentElement; - this.themeOptions = document.querySelectorAll('swp-theme-option'); - - this.applyTheme(this.current); - this.updateUI(); - this.setupListeners(); - } - - /** - * Get the current theme setting - */ - get current(): Theme { - const stored = localStorage.getItem(ThemeController.STORAGE_KEY) as Theme | null; - if (stored === 'dark' || stored === 'light' || stored === 'system') { - return stored; - } - return 'system'; - } - - /** - * Check if dark mode is currently active - */ - get isDark(): boolean { - return this.root.classList.contains(ThemeController.DARK_CLASS) || - (this.systemPrefersDark && !this.root.classList.contains(ThemeController.LIGHT_CLASS)); - } - - /** - * Check if system prefers dark mode - */ - get systemPrefersDark(): boolean { - return window.matchMedia('(prefers-color-scheme: dark)').matches; - } - - /** - * Set theme and persist preference - */ - set(theme: Theme): void { - localStorage.setItem(ThemeController.STORAGE_KEY, theme); - this.applyTheme(theme); - this.updateUI(); - } - - /** - * Toggle between light and dark themes - */ - toggle(): void { - this.set(this.isDark ? 'light' : 'dark'); - } - - private applyTheme(theme: Theme): void { - this.root.classList.remove(ThemeController.DARK_CLASS, ThemeController.LIGHT_CLASS); - - if (theme === 'dark') { - this.root.classList.add(ThemeController.DARK_CLASS); - } else if (theme === 'light') { - this.root.classList.add(ThemeController.LIGHT_CLASS); - } - // 'system' leaves both classes off, letting CSS media query handle it - } - - private updateUI(): void { - if (!this.themeOptions) return; - - const darkActive = this.isDark; - - this.themeOptions.forEach(option => { - const theme = option.dataset.theme as Theme; - const isActive = (theme === 'dark' && darkActive) || (theme === 'light' && !darkActive); - option.classList.toggle('active', isActive); - }); - } - - private setupListeners(): void { - // Theme option clicks - this.themeOptions.forEach(option => { - option.addEventListener('click', (e) => this.handleOptionClick(e)); - }); - - // System theme changes - window.matchMedia('(prefers-color-scheme: dark)') - .addEventListener('change', () => this.handleSystemChange()); - } - - private handleOptionClick(e: Event): void { - const target = e.target as HTMLElement; - const option = target.closest('swp-theme-option'); - - if (option) { - const theme = option.dataset.theme as Theme; - if (theme) { - this.set(theme); - } - } - } - - private handleSystemChange(): void { - // Only react to system changes if we're using system preference - if (this.current === 'system') { - this.updateUI(); - } - } -} diff --git a/app/wwwroot/ts/tsconfig.json b/app/wwwroot/ts/tsconfig.json deleted file mode 100644 index 87d8c61..0000000 --- a/app/wwwroot/ts/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "bundler", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "declaration": false, - "outDir": "../js/app", - "rootDir": ".", - "sourceMap": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"] - }, - "include": [ - "./**/*.ts" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/wwwroot/plantempus-sales.html b/wwwroot/plantempus-sales.html new file mode 100644 index 0000000..9439cd8 --- /dev/null +++ b/wwwroot/plantempus-sales.html @@ -0,0 +1,1896 @@ + + + + + + + Plantempus - Din salon digitaliseret og optimeret + + + + + + + +

+ + +
+
+
+ + Til professionelle frisører og skønhedssaloner +
+

Mere tid til det du er god til

+

+ Plantempus tager sig af booking, administration og papirarbejde - så du kan fokusere på dine kunder og dit håndværk. +

+ +
+
+ + +
+
+
10t
+
Mere tid til kunder om ugen
+
+
+
0 kr
+
I tabte bookinger
+
+
+
24/7
+
Kunderne kan selv booke
+
+
+
5 min
+
At lukke kassen dagligt
+
+
+ + +
+
+
+
For professionelle frisører
+

Gør det du elsker - ikke papirarbejde

+
+ +
+

+ Du blev frisør for at klippe hår - ikke for at sidde med papirarbejde. + Plantempus håndterer booking, påmindelser og løn automatisk. + Kunderne booker selv online. Du får tid til det du er god til. +

+

+ 10 timer mere om ugen til dine kunder. + Ingen dobbeltbookinger. Ingen glemte påmindelser. Ingen timer ved Excel. + Bare en fyldt kalender og tilfredse kunder. +

+

+ Gratis i 14 dage. + Ingen binding. Intet kreditkort. +

+
+
+
+ + +
+
+
+
Kernefunktionalitet
+

Alt hvad din salon har brug for - i ét system

+

+ Fra online booking til lønudbetaling. Plantempus dækker hele din forretning. +

+
+ +
+
+
+ +
+

Booking der kører sig selv

+

+ Kunderne booker selv online når det passer dem - også klokken 22 om aftenen. + Systemet sender selv påmindelser, så du slipper for no-shows. +

+
+ +
+
+ +
+

Husk hver kunde

+

+ Gem farveformler, noter og præferencer direkte i systemet. + Næste gang kunden kommer, har du alt ved hånden - selv om det er 6 måneder siden. +

+
+ +
+
+ +
+

Nem betaling

+

+ Tag imod kort, kontant, MobilePay og gavekort - alt sammen i samme system. + Scan stregkoder på produkter og de kommer automatisk med på kvitteringen. +

+
+ +
+
+ +
+

Styr på medarbejdere

+

+ Planlæg vagter, hold styr på ferie og sygedage. + Løn og provision bliver beregnet automatisk - eksporter direkte til dit lønsystem. +

+
+ +
+
+ +
+

Nemt kassearbejde

+

+ Luk kassen på 5 minutter i stedet for 30. + Systemet tæller op for dig og viser hvor meget der skal være i skuffen. +

+
+ +
+
+ +
+

Se hvordan det går

+

+ Simpelt dashboard der viser hvad du tjener, hvilke kunder der kommer tilbage, + og hvor meget hver medarbejder omsætter for. Ingen komplicerede rapporter. +

+
+
+
+
+ + +
+
+
+
+
+ + Smart hjælp +
+

Systemet arbejder for dig - ikke omvendt

+

+ Plantempus gør det tunge arbejde. Det foreslår de bedste tider til dine kunder (så de ikke ringer midt i en klipning), + giver dig besked når du har huller i kalenderen der kan fyldes, og husker hvilke produkter dine kunder plejer at købe. + Det er som at have en ekstra medarbejder - der aldrig har fri. +

+
+
+
10t
+
Mere tid til kunder/uge
+
+
+
0
+
Glemte påmindelser
+
+
+
+8
+
Ekstra kunder/uge
+
+
+
+
+ AI Dashboard +
+
+
+
+ + +
+
+
+
Alt du har brug for
+

Ét system der klarer det hele

+

+ Fra booking til løn. Fra kundejournal til kasseafstemning. Alt samlet ét sted. +

+
+ +
+ +
+
+
+ +
+

Booking & Kalender

+
+
    +
  • Kunderne booker selv online
  • +
  • Forslag til ledige tider
  • +
  • Venteliste når I er fyldt op
  • +
  • Flyt bookinger med træk-og-slip
  • +
  • Book flere medarbejdere til samme kunde
  • +
  • Automatiske påmindelser
  • +
+
+ + +
+
+
+ +
+

Kunde-management

+
+
    +
  • Alle kunder ét sted
  • +
  • Marker VIP-kunder og stamkunder
  • +
  • Gem noter og observationer
  • +
  • Farveformler der følger med
  • +
  • Link familie-medlemmer
  • +
  • Håndter marketing-tilladelser
  • +
+
+ + +
+
+
+ +
+

Medarbejdere

+
+
    +
  • Planlæg vagter for hele ugen
  • +
  • Løn regnes automatisk ud
  • +
  • Gem kontrakter og dokumenter
  • +
  • Hold styr på ferie og sygdom
  • +
  • Påmindelser om certificeringer
  • +
  • Se hvem der tjener mest
  • +
+
+ + +
+
+
+ +
+

Økonomi & Kasse

+
+
    +
  • Tag imod kort, kontant, MobilePay
  • +
  • Sælg og administrer gavekort
  • +
  • Kasseafstemning på 5 minutter
  • +
  • Del betalingen på flere metoder
  • +
  • Print eller email kvitteringer
  • +
  • Scan produkter ind
  • +
+
+ + +
+
+
+ +
+

Smart hjælp

+
+
    +
  • Foreslår de bedste booking-tider
  • +
  • Finder huller i din kalender
  • +
  • Advarer når kunder er ved at stoppe
  • +
  • Anbefaler produkter til kunder
  • +
  • Viser hvad der sælger bedst
  • +
  • Giver dig overblik hver dag
  • +
+
+ + +
+
+
+ +
+

Ting der sker selv

+
+
    +
  • SMS går automatisk ud
  • +
  • Emails når noget ændres
  • +
  • Send løn direkte til revisor
  • +
  • Kvitteringer til sygeforsikring
  • +
  • Synk med din telefon-kalender
  • +
  • Kvitteringer printes eller sendes
  • +
+
+ + +
+
+
+ +
+

Virker med det du har

+
+
    +
  • Intect, Proløn, Zenegy og flere
  • +
  • Sender til "danmark" sygeforsikring
  • +
  • Tæl besøgende på hjemmesiden
  • +
  • Beskyt kundernes privatliv
  • +
  • Synk med Google/Apple kalender
  • +
  • Kan kobles til andre systemer
  • +
+
+ + +
+
+
+ +
+

Gør det til dit eget

+
+
    +
  • Slå funktioner til og fra
  • +
  • Dit logo og dine farver
  • +
  • Skriv dine egne beskeder
  • +
  • Sæt åbningstider og helligdage
  • +
  • Flere saloner i samme system
  • +
  • Mørkt tema til aftenvagter
  • +
+
+
+
+
+ + +
+
+
+
Resultater
+

Det virker i praksis

+

+ Tal fra saloner der allerede bruger Plantempus +

+
+ +
+
+
10t
+
Mere tid til kunder hver uge
+
+
+
95%
+
Kunder møder op (ingen no-shows)
+
+
+
8
+
Ekstra kunder om ugen
+
+
+
0 kr
+
Tabte bookinger om måneden
+
+
+
+
+ + +
+
+
+
Fordele
+

Hvorfor vælge Plantempus?

+
+ +
+
+
+ +
+
+

Start i dag

+

+ Intet at installere. Ingen kompliceret opsætning. + Du kan være klar til at modtage bookinger samme dag du starter. +

+
+
+ +
+
+ +
+
+

Ingen overraskelser

+

+ Fast pris hver måned. Ingen skjulte gebyrer. Ubegrænsede bookinger og SMS inkluderet. + Du betaler kun for antallet af medarbejdere. +

+
+
+ +
+
+ +
+
+

Sikkerhed & GDPR

+

+ Dine data er krypteret og hostet sikkert i EU. Fuld GDPR-compliance, + automatisk backup og 99.9% uptime garanti. +

+
+
+ +
+
+ +
+
+

Hjælp når du har brug for det

+

+ Skriv eller ring på dansk til folk der kender til frisørbranchen. + Vi svarer hurtigt og forklarer tingene i et sprog du forstår. +

+
+
+ +
+
+ +
+
+

Virker på mobilen

+

+ Kunderne booker fra deres telefon. Du kan tjekke kalenderen og ændre bookinger fra din tablet. + Intet kræver at du sidder ved en computer. +

+
+
+ +
+
+ +
+
+

Bliver bedre hele tiden

+

+ Nye funktioner tilføjes løbende uden du skal betale mere. + Vi lytter til hvad I har brug for og bygger det ind. +

+
+
+
+
+
+ + +
+
+
+
Priser
+

Vælg den plan der passer til dig

+

+ Alle planer inkluderer 14 dages gratis prøveperiode. Ingen binding. Opsig når som helst. +

+
+ +
+ +
+

Basis

+

1-3 brugere

+
+ 299 + kr/md +
+
    +
  • Op til 3 brugere
  • +
  • Online booking
  • +
  • Kalender & aftalestyring
  • +
  • Kundekartotek
  • +
  • SMS-påmindelser
  • +
  • Email-notifikationer
  • +
  • Basis rapporter
  • +
  • Email support
  • +
+ +
+ + + + + +
+

Enterprise

+

8+ brugere

+
+ Kontakt os +
+
    +
  • Ubegrænset brugere
  • +
  • Alt fra Pro
  • +
  • Flere lokationer
  • +
  • Tilpasset integration
  • +
  • Dedikeret kontaktperson
  • +
  • SLA & uptime garanti
  • +
  • On-premise option
  • +
  • 24/7 prioriteret support
  • +
+ +
+
+
+
+ + +
+
+
+
Sammenligning
+

Plantempus vs. Traditionelle Systemer

+

+ Se forskellen på et system bygget til moderne saloner +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeaturePlantempusAndre systemer
Avanceret kundesøgning
Detaljerede statistikker med grafer
Farveformler & håranalyser
Automatisk lønberegning med provision
Multi-payment checkout (flere metoder)
Kasseafstemning
Stregkodescanner med produkt-genkendelse
Smart tidsforslag til kunder
Moderne, hurtig grænseflade
Eksport til 5+ lønsystemer
+
+ ✓ = Inkluderet · △ = Begrænset · — = Ikke tilgængelig +
+
+
+
+ + +
+
+
+
Se det rigtige system
+

Ikke bare infographics - det her er rigtigt

+

+ Vi er stolte af vores UX og performance. Se hvordan systemet faktisk ser ud. +

+
+ +
+
+

+ + Dashboard med rigtige data +

+

+ Se dagens omsætning, bookinger og medarbejder-status på ét blik. Ikke bare tal - visuelle grafer der giver mening. +

+ + Se live demo + +
+ +
+

+ + Kunde-søgning der virker +

+

+ Find kunder på navn, telefon, email - med det samme. Filtrér på VIP, stamkunder eller nye kunder. Hurtigt og præcist. +

+ + Se live demo + +
+ +
+

+ + Kundeprofiler med detaljer +

+

+ Farveformler, håranalyser, præferencer og købs-historie. Alt organiseret og nemt at finde. +

+ + Se live demo + +
+ +
+

+ + Løn & Provision +

+

+ Se præcis hvad hver medarbejder har tjent. Eksportér direkte til Intect, Proløn eller Zenegy med et klik. +

+ + Se live demo + +
+
+ +
+

+ + Alle demos er interaktive - klik og prøv dem +

+

+ Ikke mock-ups. Ikke static billeder. Det her er det rigtige system i aktion. +

+
+
+
+ + +
+
+
+
Performance & Design
+

Bygget med omtanke - mærkes i hverdagen

+
+ +
+
+
+ +
+
+

Lynhurtigt

+

+ Under 1 sekund load-tid. Ingen langsomme overgang + +er. + Systemet reagerer med det samme - som det skal være. +

+
+
+ +
+
+ +
+
+

Gennemtænkt UX

+

+ Hver knap, hver farve, hver animation er testet. + Designet så det er intuitivt - også for den der ikke er teknisk. +

+
+
+ +
+
+ +
+
+

Statistik der giver mening

+

+ Ikke bare tal på en side. Visuelle grafer, trends og indsigter. + Se med det samme hvad der virker og hvad der ikke gør. +

+
+
+ +
+
+ +
+
+

Moderne design

+

+ Ikke et system fra 2010. Rent, moderne interface der matcher + det professionelle udtryk din salon har. +

+
+
+
+
+
+ + +
+
+
+
Kundeudtalelser
+

Hvad siger vores brugere?

+
+ +
+
+
+ "Nu har jeg faktisk tid til at snakke med mine kunder i stedet for at rende efter telefonen. + Bookinger sker automatisk, påmindelser går selv ud, og jeg kan se hele ugen med et blik. Det er befriende." +
+
+
KK
+
+
Karina Knudsen
+
Ejer, KARINA KNUDSEN®
+
+
+
+ +
+
+ "Mine kunder elsker at de kan booke online klokken 22 om aftenen når de lige kommer i tanke om det. + Og jeg slipper for at svare på telefonen hele dagen. Win-win." +
+
+
MH
+
+
Maria Hansen
+
Salonchef, Salon Bellezza
+
+
+
+ +
+
+ "Før brugte jeg en hel formiddag hver måned på løn. Nu tager det 10 minutter. + Systemet har styr på hvem der har arbejdet hvornår, og sender det hele til min revisor." +
+
+
AS
+
+
Anna Sørensen
+
Økonomiansvarlig, Beauty Studio
+
+
+
+
+
+
+ + +
+
+

Klar til at optimere din salon?

+

Start din gratis 14-dages prøveperiode i dag. Ingen kreditkort påkrævet.

+ +
+
+ + + + + + + + +
  • Om os \ No newline at end of file diff --git a/wwwroot/poc-indstillinger.html b/wwwroot/poc-indstillinger.html index 2654706..107979b 100644 --- a/wwwroot/poc-indstillinger.html +++ b/wwwroot/poc-indstillinger.html @@ -3064,6 +3064,72 @@ Tak for din handel! + + + + + + + + AI Kundeanalyse + Forstå dine kunders adfærd og forbliv proaktiv. AI'en analyserer bookingmønstre, forudser hvornår kunder har brug for en tid, og identificerer kunder der er ved at falde fra. + + + + Til + Fra + + + + + + + Booking-prediktion baseret på historik + + + + Churn-detektion – se hvem der er ved at falde fra + + + + Service-præference analyse pr. kunde + + + + Sæson-korrektion i forudsigelser + + + + Win-back kampagner for inaktive kunder + + + + Automatisk personlig beskedgenerering + + + + + -34% + Færre tabte kunder + + + +18% + Genbookinger + + + 3.8x + ROI på kampagner + + + + + +79 kr/md + Beta + + Prøv gratis i 14 dage + + + From ceb44446f02d3388299329bfcec90167f77fca52 Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Wed, 28 Jan 2026 15:24:03 +0100 Subject: [PATCH 08/10] Sets up calendar package with core infrastructure Adds core calendar package components including: - Base services for events, resources, and settings - Calendar app and orchestrator - Build and bundling configuration - IndexedDB storage setup Prepares foundational architecture for calendar functionality --- .claude/settings.local.json | 9 +- .gitignore | 2 + packages/calendar/build.js | 47 + packages/calendar/package-lock.json | 167 + packages/calendar/package.json | 57 + packages/calendar/src/CompositionRoot.ts | 163 + packages/calendar/src/constants/CoreEvents.ts | 71 + .../calendar/src/core/BaseGroupingRenderer.ts | 91 + packages/calendar/src/core/CalendarApp.ts | 201 + packages/calendar/src/core/CalendarEvents.ts | 28 + .../calendar/src/core/CalendarOrchestrator.ts | 124 + packages/calendar/src/core/DateService.ts | 195 + packages/calendar/src/core/EntityResolver.ts | 48 + packages/calendar/src/core/EventBus.ts | 174 + packages/calendar/src/core/FilterTemplate.ts | 149 + .../calendar/src/core/HeaderDrawerManager.ts | 70 + packages/calendar/src/core/IEntityResolver.ts | 15 + packages/calendar/src/core/IGridConfig.ts | 7 + .../calendar/src/core/IGroupingRenderer.ts | 15 + packages/calendar/src/core/IGroupingStore.ts | 4 + .../calendar/src/core/ITimeFormatConfig.ts | 7 + .../calendar/src/core/NavigationAnimator.ts | 64 + packages/calendar/src/core/RenderBuilder.ts | 15 + packages/calendar/src/core/ScrollManager.ts | 42 + packages/calendar/src/core/ViewConfig.ts | 21 + .../src/extensions/audit/AuditService.ts | 167 + .../src/extensions/audit/AuditStore.ts | 27 + .../calendar/src/extensions/audit/index.ts | 14 + .../src/extensions/bookings/BookingService.ts | 75 + .../src/extensions/bookings/BookingStore.ts | 18 + .../calendar/src/extensions/bookings/index.ts | 18 + .../extensions/customers/CustomerService.ts | 46 + .../src/extensions/customers/CustomerStore.ts | 17 + .../src/extensions/customers/index.ts | 18 + .../departments/DepartmentRenderer.ts | 25 + .../departments/DepartmentService.ts | 25 + .../extensions/departments/DepartmentStore.ts | 13 + .../src/extensions/departments/index.ts | 22 + .../schedules/ResourceScheduleService.ts | 84 + .../schedules/ScheduleOverrideService.ts | 100 + .../schedules/ScheduleOverrideStore.ts | 21 + .../src/extensions/schedules/index.ts | 17 + .../src/extensions/teams/TeamRenderer.ts | 25 + .../src/extensions/teams/TeamService.ts | 44 + .../src/extensions/teams/TeamStore.ts | 13 + .../calendar/src/extensions/teams/index.ts | 22 + .../src/features/date/DateRenderer.ts | 68 + packages/calendar/src/features/date/index.ts | 1 + .../src/features/event/EventLayoutEngine.ts | 279 + .../src/features/event/EventLayoutTypes.ts | 35 + .../src/features/event/EventRenderer.ts | 434 ++ packages/calendar/src/features/event/index.ts | 1 + .../headerdrawer/HeaderDrawerLayoutEngine.ts | 135 + .../headerdrawer/HeaderDrawerRenderer.ts | 419 ++ .../src/features/headerdrawer/index.ts | 2 + .../src/features/resource/ResourceRenderer.ts | 69 + .../calendar/src/features/resource/index.ts | 1 + .../src/features/schedule/ScheduleRenderer.ts | 106 + .../calendar/src/features/schedule/index.ts | 1 + .../src/features/timeaxis/TimeAxisRenderer.ts | 10 + packages/calendar/src/index.ts | 164 + .../calendar/src/managers/DragDropManager.ts | 581 ++ .../src/managers/EdgeScrollManager.ts | 140 + .../src/managers/EventPersistenceManager.ts | 102 + .../calendar/src/managers/ResizeManager.ts | 290 + .../src/repositories/IApiRepository.ts | 33 + .../calendar/src/storage/BaseEntityService.ts | 181 + .../calendar/src/storage/IEntityService.ts | 40 + packages/calendar/src/storage/IStore.ts | 18 + .../calendar/src/storage/IndexedDBContext.ts | 108 + packages/calendar/src/storage/SyncPlugin.ts | 64 + .../src/storage/events/EventSerialization.ts | 32 + .../src/storage/events/EventService.ts | 84 + .../calendar/src/storage/events/EventStore.ts | 37 + .../src/storage/resources/ResourceService.ts | 55 + .../src/storage/resources/ResourceStore.ts | 17 + .../src/storage/settings/SettingsService.ts | 83 + .../src/storage/settings/SettingsStore.ts | 16 + .../storage/viewconfigs/ViewConfigService.ts | 18 + .../storage/viewconfigs/ViewConfigStore.ts | 10 + packages/calendar/src/types/AuditTypes.ts | 46 + packages/calendar/src/types/CalendarTypes.ts | 170 + packages/calendar/src/types/DragTypes.ts | 76 + packages/calendar/src/types/ResizeTypes.ts | 15 + packages/calendar/src/types/ScheduleTypes.ts | 27 + packages/calendar/src/types/SettingsTypes.ts | 78 + packages/calendar/src/types/SwpEvent.ts | 79 + packages/calendar/src/utils/PositionUtils.ts | 55 + packages/calendar/tsconfig.json | 21 + test-package/build.js | 23 + test-package/dist/bundle.js | 5289 +++++++++++++++++ test-package/dist/css/calendar.css | 877 +++ test-package/index.html | 41 + test-package/package-lock.json | 654 ++ test-package/package.json | 21 + test-package/src/index.ts | 139 + test-package/tsconfig.json | 17 + 97 files changed, 13858 insertions(+), 1 deletion(-) create mode 100644 packages/calendar/build.js create mode 100644 packages/calendar/package-lock.json create mode 100644 packages/calendar/package.json create mode 100644 packages/calendar/src/CompositionRoot.ts create mode 100644 packages/calendar/src/constants/CoreEvents.ts create mode 100644 packages/calendar/src/core/BaseGroupingRenderer.ts create mode 100644 packages/calendar/src/core/CalendarApp.ts create mode 100644 packages/calendar/src/core/CalendarEvents.ts create mode 100644 packages/calendar/src/core/CalendarOrchestrator.ts create mode 100644 packages/calendar/src/core/DateService.ts create mode 100644 packages/calendar/src/core/EntityResolver.ts create mode 100644 packages/calendar/src/core/EventBus.ts create mode 100644 packages/calendar/src/core/FilterTemplate.ts create mode 100644 packages/calendar/src/core/HeaderDrawerManager.ts create mode 100644 packages/calendar/src/core/IEntityResolver.ts create mode 100644 packages/calendar/src/core/IGridConfig.ts create mode 100644 packages/calendar/src/core/IGroupingRenderer.ts create mode 100644 packages/calendar/src/core/IGroupingStore.ts create mode 100644 packages/calendar/src/core/ITimeFormatConfig.ts create mode 100644 packages/calendar/src/core/NavigationAnimator.ts create mode 100644 packages/calendar/src/core/RenderBuilder.ts create mode 100644 packages/calendar/src/core/ScrollManager.ts create mode 100644 packages/calendar/src/core/ViewConfig.ts create mode 100644 packages/calendar/src/extensions/audit/AuditService.ts create mode 100644 packages/calendar/src/extensions/audit/AuditStore.ts create mode 100644 packages/calendar/src/extensions/audit/index.ts create mode 100644 packages/calendar/src/extensions/bookings/BookingService.ts create mode 100644 packages/calendar/src/extensions/bookings/BookingStore.ts create mode 100644 packages/calendar/src/extensions/bookings/index.ts create mode 100644 packages/calendar/src/extensions/customers/CustomerService.ts create mode 100644 packages/calendar/src/extensions/customers/CustomerStore.ts create mode 100644 packages/calendar/src/extensions/customers/index.ts create mode 100644 packages/calendar/src/extensions/departments/DepartmentRenderer.ts create mode 100644 packages/calendar/src/extensions/departments/DepartmentService.ts create mode 100644 packages/calendar/src/extensions/departments/DepartmentStore.ts create mode 100644 packages/calendar/src/extensions/departments/index.ts create mode 100644 packages/calendar/src/extensions/schedules/ResourceScheduleService.ts create mode 100644 packages/calendar/src/extensions/schedules/ScheduleOverrideService.ts create mode 100644 packages/calendar/src/extensions/schedules/ScheduleOverrideStore.ts create mode 100644 packages/calendar/src/extensions/schedules/index.ts create mode 100644 packages/calendar/src/extensions/teams/TeamRenderer.ts create mode 100644 packages/calendar/src/extensions/teams/TeamService.ts create mode 100644 packages/calendar/src/extensions/teams/TeamStore.ts create mode 100644 packages/calendar/src/extensions/teams/index.ts create mode 100644 packages/calendar/src/features/date/DateRenderer.ts create mode 100644 packages/calendar/src/features/date/index.ts create mode 100644 packages/calendar/src/features/event/EventLayoutEngine.ts create mode 100644 packages/calendar/src/features/event/EventLayoutTypes.ts create mode 100644 packages/calendar/src/features/event/EventRenderer.ts create mode 100644 packages/calendar/src/features/event/index.ts create mode 100644 packages/calendar/src/features/headerdrawer/HeaderDrawerLayoutEngine.ts create mode 100644 packages/calendar/src/features/headerdrawer/HeaderDrawerRenderer.ts create mode 100644 packages/calendar/src/features/headerdrawer/index.ts create mode 100644 packages/calendar/src/features/resource/ResourceRenderer.ts create mode 100644 packages/calendar/src/features/resource/index.ts create mode 100644 packages/calendar/src/features/schedule/ScheduleRenderer.ts create mode 100644 packages/calendar/src/features/schedule/index.ts create mode 100644 packages/calendar/src/features/timeaxis/TimeAxisRenderer.ts create mode 100644 packages/calendar/src/index.ts create mode 100644 packages/calendar/src/managers/DragDropManager.ts create mode 100644 packages/calendar/src/managers/EdgeScrollManager.ts create mode 100644 packages/calendar/src/managers/EventPersistenceManager.ts create mode 100644 packages/calendar/src/managers/ResizeManager.ts create mode 100644 packages/calendar/src/repositories/IApiRepository.ts create mode 100644 packages/calendar/src/storage/BaseEntityService.ts create mode 100644 packages/calendar/src/storage/IEntityService.ts create mode 100644 packages/calendar/src/storage/IStore.ts create mode 100644 packages/calendar/src/storage/IndexedDBContext.ts create mode 100644 packages/calendar/src/storage/SyncPlugin.ts create mode 100644 packages/calendar/src/storage/events/EventSerialization.ts create mode 100644 packages/calendar/src/storage/events/EventService.ts create mode 100644 packages/calendar/src/storage/events/EventStore.ts create mode 100644 packages/calendar/src/storage/resources/ResourceService.ts create mode 100644 packages/calendar/src/storage/resources/ResourceStore.ts create mode 100644 packages/calendar/src/storage/settings/SettingsService.ts create mode 100644 packages/calendar/src/storage/settings/SettingsStore.ts create mode 100644 packages/calendar/src/storage/viewconfigs/ViewConfigService.ts create mode 100644 packages/calendar/src/storage/viewconfigs/ViewConfigStore.ts create mode 100644 packages/calendar/src/types/AuditTypes.ts create mode 100644 packages/calendar/src/types/CalendarTypes.ts create mode 100644 packages/calendar/src/types/DragTypes.ts create mode 100644 packages/calendar/src/types/ResizeTypes.ts create mode 100644 packages/calendar/src/types/ScheduleTypes.ts create mode 100644 packages/calendar/src/types/SettingsTypes.ts create mode 100644 packages/calendar/src/types/SwpEvent.ts create mode 100644 packages/calendar/src/utils/PositionUtils.ts create mode 100644 packages/calendar/tsconfig.json create mode 100644 test-package/build.js create mode 100644 test-package/dist/bundle.js create mode 100644 test-package/dist/css/calendar.css create mode 100644 test-package/index.html create mode 100644 test-package/package-lock.json create mode 100644 test-package/package.json create mode 100644 test-package/src/index.ts create mode 100644 test-package/tsconfig.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json index ada38c0..84b43fa 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -22,7 +22,14 @@ "Bash(node -e:*)", "Bash(ls:*)", "Bash(find:*)", - "WebFetch(domain:www.elegantthemes.com)" + "WebFetch(domain:www.elegantthemes.com)", + "Bash(npm publish:*)", + "Bash(npm init:*)", + "Bash(node dist/bundle.js:*)", + "Bash(node build.js:*)", + "Bash(npm ls:*)", + "Bash(npm view:*)", + "Bash(npm update:*)" ], "deny": [], "ask": [] diff --git a/.gitignore b/.gitignore index a0905c1..de20219 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ Thumbs.db *.userosscache *.sln.docstates js/ + +packages/calendar/dist/ diff --git a/packages/calendar/build.js b/packages/calendar/build.js new file mode 100644 index 0000000..0570894 --- /dev/null +++ b/packages/calendar/build.js @@ -0,0 +1,47 @@ +import * as esbuild from 'esbuild'; +import { NovadiUnplugin } from '@novadi/core/unplugin'; +import * as fs from 'fs'; +import * as path from 'path'; + +const entryPoints = [ + 'src/index.ts', + 'src/extensions/teams/index.ts', + 'src/extensions/departments/index.ts', + 'src/extensions/bookings/index.ts', + 'src/extensions/customers/index.ts', + 'src/extensions/schedules/index.ts', + 'src/extensions/audit/index.ts' +]; + +async function build() { + await esbuild.build({ + entryPoints, + bundle: true, + outdir: 'dist', + format: 'esm', + platform: 'browser', + external: ['@novadi/core', 'dayjs'], + splitting: true, + sourcemap: true, + target: 'es2020', + plugins: [NovadiUnplugin.esbuild({ debug: false, enableAutowiring: true })] + }); + + console.log('Build complete: dist/'); + + // Bundle CSS + const cssDir = 'dist/css'; + if (!fs.existsSync(cssDir)) { + fs.mkdirSync(cssDir, { recursive: true }); + } + const cssFiles = [ + '../../wwwroot/css/calendar-base.css', + '../../wwwroot/css/calendar-layout.css', + '../../wwwroot/css/calendar-events.css' + ]; + const bundledCss = cssFiles.map(f => fs.readFileSync(f, 'utf8')).join('\n'); + fs.writeFileSync(path.join(cssDir, 'calendar.css'), bundledCss); + console.log('CSS bundled: dist/css/calendar.css'); +} + +build(); diff --git a/packages/calendar/package-lock.json b/packages/calendar/package-lock.json new file mode 100644 index 0000000..c00dabb --- /dev/null +++ b/packages/calendar/package-lock.json @@ -0,0 +1,167 @@ +{ + "name": "@plantempus/calendar", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@plantempus/calendar", + "version": "0.1.0", + "dependencies": { + "dayjs": "^1.11.0" + }, + "peerDependencies": { + "@novadi/core": "^0.6.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@novadi/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@novadi/core/-/core-0.6.0.tgz", + "integrity": "sha512-CU1134Nd7ULMg9OQbID5oP+FLtrMkNiLJ17+dmy4jjmPDcPK/dVzKTFxvJmbBvEfZEc9WtmkmJjqw11ABU7Jxw==", + "license": "MIT", + "peer": true, + "dependencies": { + "unplugin": "^2.3.10" + }, + "optionalDependencies": { + "@rollup/rollup-win32-x64-msvc": "^4.52.5" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT", + "peer": true + } + } +} diff --git a/packages/calendar/package.json b/packages/calendar/package.json new file mode 100644 index 0000000..8c83e0f --- /dev/null +++ b/packages/calendar/package.json @@ -0,0 +1,57 @@ +{ + "name": "calendar", + "version": "0.1.6", + "description": "Calendar library", + "author": "SWP", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./teams": { + "import": "./dist/extensions/teams/index.js", + "types": "./dist/extensions/teams/index.d.ts" + }, + "./departments": { + "import": "./dist/extensions/departments/index.js", + "types": "./dist/extensions/departments/index.d.ts" + }, + "./bookings": { + "import": "./dist/extensions/bookings/index.js", + "types": "./dist/extensions/bookings/index.d.ts" + }, + "./customers": { + "import": "./dist/extensions/customers/index.js", + "types": "./dist/extensions/customers/index.d.ts" + }, + "./schedules": { + "import": "./dist/extensions/schedules/index.js", + "types": "./dist/extensions/schedules/index.d.ts" + }, + "./audit": { + "import": "./dist/extensions/audit/index.js", + "types": "./dist/extensions/audit/index.d.ts" + }, + "./styles": "./dist/css/calendar.css" + }, + "files": [ + "dist" + ], + "scripts": { + "build": "node build.js && npm run build:types", + "build:types": "tsc --emitDeclarationOnly --outDir dist" + }, + "peerDependencies": { + "@novadi/core": "^0.6.0" + }, + "dependencies": { + "dayjs": "^1.11.0" + }, + "devDependencies": { + "esbuild": "^0.24.0", + "typescript": "^5.0.0" + } +} diff --git a/packages/calendar/src/CompositionRoot.ts b/packages/calendar/src/CompositionRoot.ts new file mode 100644 index 0000000..e2b429a --- /dev/null +++ b/packages/calendar/src/CompositionRoot.ts @@ -0,0 +1,163 @@ +import { Container, Builder } from '@novadi/core'; + +// Core +import { EventBus } from './core/EventBus'; +import { DateService } from './core/DateService'; +import { CalendarOrchestrator } from './core/CalendarOrchestrator'; +import { CalendarApp } from './core/CalendarApp'; +import { TimeAxisRenderer } from './features/timeaxis/TimeAxisRenderer'; +import { ScrollManager } from './core/ScrollManager'; +import { HeaderDrawerManager } from './core/HeaderDrawerManager'; +import { ITimeFormatConfig } from './core/ITimeFormatConfig'; +import { IGridConfig } from './core/IGridConfig'; + +// Types +import { IEventBus, ICalendarEvent, ISync, IResource } from './types/CalendarTypes'; +import { TenantSetting } from './types/SettingsTypes'; +import { ViewConfig } from './core/ViewConfig'; + +// Renderers +import { IRenderer } from './core/IGroupingRenderer'; +import { DateRenderer } from './features/date/DateRenderer'; +import { ResourceRenderer } from './features/resource/ResourceRenderer'; +import { EventRenderer } from './features/event/EventRenderer'; +import { ScheduleRenderer } from './features/schedule/ScheduleRenderer'; +import { HeaderDrawerRenderer } from './features/headerdrawer/HeaderDrawerRenderer'; + +// Storage +import { IndexedDBContext, IDBConfig, defaultDBConfig } from './storage/IndexedDBContext'; +import { IStore } from './storage/IStore'; +import { IEntityService } from './storage/IEntityService'; +import { EventStore } from './storage/events/EventStore'; +import { EventService } from './storage/events/EventService'; +import { ResourceStore } from './storage/resources/ResourceStore'; +import { ResourceService } from './storage/resources/ResourceService'; +import { SettingsStore } from './storage/settings/SettingsStore'; +import { SettingsService } from './storage/settings/SettingsService'; +import { ViewConfigStore } from './storage/viewconfigs/ViewConfigStore'; +import { ViewConfigService } from './storage/viewconfigs/ViewConfigService'; + +// Managers +import { DragDropManager } from './managers/DragDropManager'; +import { EdgeScrollManager } from './managers/EdgeScrollManager'; +import { ResizeManager } from './managers/ResizeManager'; +import { EventPersistenceManager } from './managers/EventPersistenceManager'; + +/** + * Default configuration values + */ +export const defaultTimeFormatConfig: ITimeFormatConfig = { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + use24HourFormat: true, + locale: 'da-DK', + dateFormat: 'locale', + showSeconds: false +}; + +export const defaultGridConfig: IGridConfig = { + hourHeight: 64, + dayStartHour: 6, + dayEndHour: 18, + snapInterval: 15, + gridStartThresholdMinutes: 30 +}; + +/** + * Calendar configuration options + */ +export interface ICalendarOptions { + timeConfig?: ITimeFormatConfig; + gridConfig?: IGridConfig; + dbConfig?: IDBConfig; +} + +/** + * Creates a configured DI container with all core calendar services registered. + * Call this to get a ready-to-use container for the calendar. + * + * @param options - Optional calendar configuration options + * @returns Configured Container instance + */ +export function createCalendarContainer(options?: ICalendarOptions): Container { + const container = new Container(); + const builder = container.builder(); + + registerCoreServices(builder, options); + + return builder.build(); +} + +/** + * Registers all core calendar services with the DI container builder. + * Use this when you need to customize the container or add extensions. + * + * @param builder - ContainerBuilder to register services with + * @param options - Optional calendar configuration options + */ +export function registerCoreServices( + builder: Builder, + options?: ICalendarOptions +): void { + const timeConfig = options?.timeConfig ?? defaultTimeFormatConfig; + const gridConfig = options?.gridConfig ?? defaultGridConfig; + const dbConfig = options?.dbConfig ?? defaultDBConfig; + // Configuration instances + builder.registerInstance(timeConfig).as(); + builder.registerInstance(gridConfig).as(); + builder.registerInstance(dbConfig).as(); + + // Core - EventBus (singleton pattern via dual registration) + builder.registerType(EventBus).as(); + builder.registerType(EventBus).as(); + + // Core Services + builder.registerType(DateService).as(); + + // Storage infrastructure + builder.registerType(IndexedDBContext).as(); + + // Core Stores (for IndexedDB schema creation via IStore[] array injection) + builder.registerType(EventStore).as(); + builder.registerType(ResourceStore).as(); + builder.registerType(SettingsStore).as(); + builder.registerType(ViewConfigStore).as(); + + // Core Entity Services (polymorphic via IEntityService) + builder.registerType(EventService).as>(); + builder.registerType(EventService).as>(); + builder.registerType(EventService).as(); + + builder.registerType(ResourceService).as>(); + builder.registerType(ResourceService).as>(); + builder.registerType(ResourceService).as(); + + builder.registerType(SettingsService).as>(); + builder.registerType(SettingsService).as>(); + builder.registerType(SettingsService).as(); + + builder.registerType(ViewConfigService).as>(); + builder.registerType(ViewConfigService).as>(); + builder.registerType(ViewConfigService).as(); + + // Core Renderers + builder.registerType(EventRenderer).as(); + builder.registerType(ScheduleRenderer).as(); + builder.registerType(HeaderDrawerRenderer).as(); + builder.registerType(TimeAxisRenderer).as(); + + // Grouping Renderers (registered as IRenderer[] for CalendarOrchestrator) + builder.registerType(DateRenderer).as(); + builder.registerType(ResourceRenderer).as(); + + // Core Managers + builder.registerType(ScrollManager).as(); + builder.registerType(HeaderDrawerManager).as(); + builder.registerType(DragDropManager).as(); + builder.registerType(EdgeScrollManager).as(); + builder.registerType(ResizeManager).as(); + builder.registerType(EventPersistenceManager).as(); + + // Orchestrator and App + builder.registerType(CalendarOrchestrator).as(); + builder.registerType(CalendarApp).as(); +} diff --git a/packages/calendar/src/constants/CoreEvents.ts b/packages/calendar/src/constants/CoreEvents.ts new file mode 100644 index 0000000..7363138 --- /dev/null +++ b/packages/calendar/src/constants/CoreEvents.ts @@ -0,0 +1,71 @@ +/** + * CoreEvents - Consolidated essential events for the calendar + */ +export const CoreEvents = { + // Lifecycle events + INITIALIZED: 'core:initialized', + READY: 'core:ready', + DESTROYED: 'core:destroyed', + + // View events + VIEW_CHANGED: 'view:changed', + VIEW_RENDERED: 'view:rendered', + + // Navigation events + DATE_CHANGED: 'nav:date-changed', + NAVIGATION_COMPLETED: 'nav:navigation-completed', + + // Data events + DATA_LOADING: 'data:loading', + DATA_LOADED: 'data:loaded', + DATA_ERROR: 'data:error', + + // Grid events + GRID_RENDERED: 'grid:rendered', + GRID_CLICKED: 'grid:clicked', + + // Event management + EVENT_CREATED: 'event:created', + EVENT_UPDATED: 'event:updated', + EVENT_DELETED: 'event:deleted', + EVENT_SELECTED: 'event:selected', + + // Event drag-drop + EVENT_DRAG_START: 'event:drag-start', + EVENT_DRAG_MOVE: 'event:drag-move', + EVENT_DRAG_END: 'event:drag-end', + EVENT_DRAG_CANCEL: 'event:drag-cancel', + EVENT_DRAG_COLUMN_CHANGE: 'event:drag-column-change', + + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: 'event:drag-enter-header', + EVENT_DRAG_MOVE_HEADER: 'event:drag-move-header', + EVENT_DRAG_LEAVE_HEADER: 'event:drag-leave-header', + + // Event resize + EVENT_RESIZE_START: 'event:resize-start', + EVENT_RESIZE_END: 'event:resize-end', + + // Edge scroll + EDGE_SCROLL_TICK: 'edge-scroll:tick', + EDGE_SCROLL_STARTED: 'edge-scroll:started', + EDGE_SCROLL_STOPPED: 'edge-scroll:stopped', + + // System events + ERROR: 'system:error', + + // Sync events + SYNC_STARTED: 'sync:started', + SYNC_COMPLETED: 'sync:completed', + SYNC_FAILED: 'sync:failed', + + // Entity events - for audit and sync + ENTITY_SAVED: 'entity:saved', + ENTITY_DELETED: 'entity:deleted', + + // Audit events + AUDIT_LOGGED: 'audit:logged', + + // Rendering events + EVENTS_RENDERED: 'events:rendered' +} as const; diff --git a/packages/calendar/src/core/BaseGroupingRenderer.ts b/packages/calendar/src/core/BaseGroupingRenderer.ts new file mode 100644 index 0000000..60c9abf --- /dev/null +++ b/packages/calendar/src/core/BaseGroupingRenderer.ts @@ -0,0 +1,91 @@ +import { IRenderer, IRenderContext } from './IGroupingRenderer'; + +/** + * Entity must have id + */ +export interface IGroupingEntity { + id: string; +} + +/** + * Configuration for a grouping renderer + */ +export interface IGroupingRendererConfig { + elementTag: string; // e.g., 'swp-team-header' + idAttribute: string; // e.g., 'teamId' -> data-team-id + colspanVar: string; // e.g., '--team-cols' +} + +/** + * Abstract base class for grouping renderers + * + * Handles: + * - Fetching entities by IDs + * - Calculating colspan from parentChildMap + * - Creating header elements + * - Appending to container + * + * Subclasses override: + * - renderHeader() for custom content + * - getDisplayName() for entity display text + */ +export abstract class BaseGroupingRenderer implements IRenderer { + abstract readonly type: string; + protected abstract readonly config: IGroupingRendererConfig; + + /** + * Fetch entities from service + */ + protected abstract getEntities(ids: string[]): Promise; + + /** + * Get display name for entity + */ + protected abstract getDisplayName(entity: T): string; + + /** + * Main render method - handles common logic + */ + async render(context: IRenderContext): Promise { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) return; + + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter['date']?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter(id => childIds.includes(id)).length; + const colspan = childCount * dateCount; + + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + + // Allow subclass to customize header content + this.renderHeader(entity, header, context); + + context.headerContainer.appendChild(header); + } + } + + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + protected renderHeader(entity: T, header: HTMLElement, _context: IRenderContext): void { + header.textContent = this.getDisplayName(entity); + } + + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + protected createHeader(entity: T, context: IRenderContext): HTMLElement { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +} diff --git a/packages/calendar/src/core/CalendarApp.ts b/packages/calendar/src/core/CalendarApp.ts new file mode 100644 index 0000000..246b257 --- /dev/null +++ b/packages/calendar/src/core/CalendarApp.ts @@ -0,0 +1,201 @@ +import { CalendarOrchestrator } from './CalendarOrchestrator'; +import { TimeAxisRenderer } from '../features/timeaxis/TimeAxisRenderer'; +import { NavigationAnimator } from './NavigationAnimator'; +import { DateService } from './DateService'; +import { ScrollManager } from './ScrollManager'; +import { HeaderDrawerManager } from './HeaderDrawerManager'; +import { ViewConfig } from './ViewConfig'; +import { DragDropManager } from '../managers/DragDropManager'; +import { EdgeScrollManager } from '../managers/EdgeScrollManager'; +import { ResizeManager } from '../managers/ResizeManager'; +import { EventPersistenceManager } from '../managers/EventPersistenceManager'; +import { HeaderDrawerRenderer } from '../features/headerdrawer/HeaderDrawerRenderer'; +import { SettingsService } from '../storage/settings/SettingsService'; +import { ViewConfigService } from '../storage/viewconfigs/ViewConfigService'; +import { IWorkweekPreset } from '../types/SettingsTypes'; +import { IEventBus } from '../types/CalendarTypes'; +import { + CalendarEvents, + RenderPayload, + WorkweekChangePayload, + ViewUpdatePayload +} from './CalendarEvents'; + +export class CalendarApp { + private animator!: NavigationAnimator; + private container!: HTMLElement; + private dayOffset = 0; + private currentViewId = 'simple'; + private workweekPreset: IWorkweekPreset | null = null; + private groupingOverrides: Map = new Map(); + + constructor( + private orchestrator: CalendarOrchestrator, + private timeAxisRenderer: TimeAxisRenderer, + private dateService: DateService, + private scrollManager: ScrollManager, + private headerDrawerManager: HeaderDrawerManager, + private dragDropManager: DragDropManager, + private edgeScrollManager: EdgeScrollManager, + private resizeManager: ResizeManager, + private headerDrawerRenderer: HeaderDrawerRenderer, + private eventPersistenceManager: EventPersistenceManager, + private settingsService: SettingsService, + private viewConfigService: ViewConfigService, + private eventBus: IEventBus + ) {} + + async init(container: HTMLElement): Promise { + this.container = container; + + // Load settings + const gridSettings = await this.settingsService.getGridSettings(); + if (!gridSettings) { + throw new Error('GridSettings not found'); + } + + this.workweekPreset = await this.settingsService.getDefaultWorkweekPreset(); + + // Create NavigationAnimator with DOM elements + this.animator = new NavigationAnimator( + container.querySelector('swp-header-track') as HTMLElement, + container.querySelector('swp-content-track') as HTMLElement, + container.querySelector('swp-header-drawer') + ); + + // Render time axis from settings + this.timeAxisRenderer.render( + container.querySelector('#time-axis') as HTMLElement, + gridSettings.dayStartHour, + gridSettings.dayEndHour + ); + + // Init managers + this.scrollManager.init(container); + this.headerDrawerManager.init(container); + this.dragDropManager.init(container); + this.resizeManager.init(container); + + const scrollableContent = container.querySelector('swp-scrollable-content') as HTMLElement; + this.edgeScrollManager.init(scrollableContent); + + // Setup command event listeners + this.setupEventListeners(); + + // Emit ready status + this.emitStatus('ready'); + } + + private setupEventListeners(): void { + // Navigation commands via EventBus + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_PREV, () => { + this.handleNavigatePrev(); + }); + + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_NEXT, () => { + this.handleNavigateNext(); + }); + + // Drawer toggle via EventBus + this.eventBus.on(CalendarEvents.CMD_DRAWER_TOGGLE, () => { + this.headerDrawerManager.toggle(); + }); + + // Render command via EventBus + this.eventBus.on(CalendarEvents.CMD_RENDER, (e: Event) => { + const { viewId } = (e as CustomEvent).detail; + this.handleRenderCommand(viewId); + }); + + // Workweek change via EventBus + this.eventBus.on(CalendarEvents.CMD_WORKWEEK_CHANGE, (e: Event) => { + const { presetId } = (e as CustomEvent).detail; + this.handleWorkweekChange(presetId); + }); + + // View update via EventBus + this.eventBus.on(CalendarEvents.CMD_VIEW_UPDATE, (e: Event) => { + const { type, values } = (e as CustomEvent).detail; + this.handleViewUpdate(type, values); + }); + } + + private async handleRenderCommand(viewId: string): Promise { + this.currentViewId = viewId; + await this.render(); + this.emitStatus('rendered', { viewId }); + } + + private async handleNavigatePrev(): Promise { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset -= step; + await this.animator.slide('right', () => this.render()); + this.emitStatus('rendered', { viewId: this.currentViewId }); + } + + private async handleNavigateNext(): Promise { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset += step; + await this.animator.slide('left', () => this.render()); + this.emitStatus('rendered', { viewId: this.currentViewId }); + } + + private async handleWorkweekChange(presetId: string): Promise { + const preset = await this.settingsService.getWorkweekPreset(presetId); + if (preset) { + this.workweekPreset = preset; + await this.render(); + this.emitStatus('rendered', { viewId: this.currentViewId }); + } + } + + private async handleViewUpdate(type: string, values: string[]): Promise { + this.groupingOverrides.set(type, values); + await this.render(); + this.emitStatus('rendered', { viewId: this.currentViewId }); + } + + private async render(): Promise { + const storedConfig = await this.viewConfigService.getById(this.currentViewId); + if (!storedConfig) { + this.emitStatus('error', { message: `ViewConfig not found: ${this.currentViewId}` }); + return; + } + + // Populate date values based on workweek preset and day offset + const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5]; + const periodDays = this.workweekPreset?.periodDays ?? 7; + + // For single-day navigation (periodDays=1), show consecutive days from offset + // For week navigation (periodDays=7), show workDays from the week containing offset + const dates = periodDays === 1 + ? this.dateService.getDatesFromOffset(this.dayOffset, workDays.length) + : this.dateService.getWorkDaysFromOffset(this.dayOffset, workDays); + + // Clone config and apply overrides + const viewConfig: ViewConfig = { + ...storedConfig, + groupings: storedConfig.groupings.map(g => { + // Apply date values + if (g.type === 'date') { + return { ...g, values: dates }; + } + // Apply grouping overrides + const override = this.groupingOverrides.get(g.type); + if (override) { + return { ...g, values: override }; + } + return g; + }) + }; + + await this.orchestrator.render(viewConfig, this.container); + } + + private emitStatus(status: string, detail?: object): void { + this.container.dispatchEvent(new CustomEvent(`calendar:status:${status}`, { + detail, + bubbles: true + })); + } +} diff --git a/packages/calendar/src/core/CalendarEvents.ts b/packages/calendar/src/core/CalendarEvents.ts new file mode 100644 index 0000000..4cf553e --- /dev/null +++ b/packages/calendar/src/core/CalendarEvents.ts @@ -0,0 +1,28 @@ +/** + * CalendarEvents - Command and status events for CalendarApp + */ +export const CalendarEvents = { + // Command events (host → calendar) + CMD_NAVIGATE_PREV: 'calendar:cmd:navigate:prev', + CMD_NAVIGATE_NEXT: 'calendar:cmd:navigate:next', + CMD_DRAWER_TOGGLE: 'calendar:cmd:drawer:toggle', + CMD_RENDER: 'calendar:cmd:render', + CMD_WORKWEEK_CHANGE: 'calendar:cmd:workweek:change', + CMD_VIEW_UPDATE: 'calendar:cmd:view:update' +} as const; + +/** + * Payload interfaces for CalendarEvents + */ +export interface RenderPayload { + viewId: string; +} + +export interface WorkweekChangePayload { + presetId: string; +} + +export interface ViewUpdatePayload { + type: string; + values: string[]; +} diff --git a/packages/calendar/src/core/CalendarOrchestrator.ts b/packages/calendar/src/core/CalendarOrchestrator.ts new file mode 100644 index 0000000..933e8a5 --- /dev/null +++ b/packages/calendar/src/core/CalendarOrchestrator.ts @@ -0,0 +1,124 @@ +import { IRenderer, IRenderContext } from './IGroupingRenderer'; +import { buildPipeline } from './RenderBuilder'; +import { EventRenderer } from '../features/event/EventRenderer'; +import { ScheduleRenderer } from '../features/schedule/ScheduleRenderer'; +import { HeaderDrawerRenderer } from '../features/headerdrawer/HeaderDrawerRenderer'; +import { ViewConfig, GroupingConfig } from './ViewConfig'; +import { FilterTemplate } from './FilterTemplate'; +import { DateService } from './DateService'; +import { IEntityService } from '../storage/IEntityService'; +import { ISync } from '../types/CalendarTypes'; + +export class CalendarOrchestrator { + constructor( + private allRenderers: IRenderer[], + private eventRenderer: EventRenderer, + private scheduleRenderer: ScheduleRenderer, + private headerDrawerRenderer: HeaderDrawerRenderer, + private dateService: DateService, + private entityServices: IEntityService[] + ) {} + + async render(viewConfig: ViewConfig, container: HTMLElement): Promise { + const headerContainer = container.querySelector('swp-calendar-header') as HTMLElement; + const columnContainer = container.querySelector('swp-day-columns') as HTMLElement; + if (!headerContainer || !columnContainer) { + throw new Error('Missing swp-calendar-header or swp-day-columns'); + } + + // Byg filter fra viewConfig + const filter: Record = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + + // Byg FilterTemplate fra viewConfig groupings (kun de med idProperty) + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + + // Resolve belongsTo relations (e.g., team.resourceIds) + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + + const context: IRenderContext = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + + // Clear + headerContainer.innerHTML = ''; + columnContainer.innerHTML = ''; + + // Sæt data-levels attribut for CSS grid-row styling + const levels = viewConfig.groupings.map(g => g.type).join(' '); + headerContainer.dataset.levels = levels; + + // Vælg renderers baseret på groupings types + const activeRenderers = this.selectRenderers(viewConfig); + + // Byg og kør pipeline + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + + // Render schedule unavailable zones (før events) + await this.scheduleRenderer.render(container, filter); + + // Render timed events in grid (med filterTemplate til matching) + await this.eventRenderer.render(container, filter, filterTemplate); + + // Render allDay events in header drawer (med filterTemplate til matching) + await this.headerDrawerRenderer.render(container, filter, filterTemplate); + } + + private selectRenderers(viewConfig: ViewConfig): IRenderer[] { + const types = viewConfig.groupings.map(g => g.type); + // Sortér renderers i samme rækkefølge som viewConfig.groupings + return types + .map(type => this.allRenderers.find(r => r.type === type)) + .filter((r): r is IRenderer => r !== undefined); + } + + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + private async resolveBelongsTo( + groupings: GroupingConfig[], + filter: Record + ): Promise<{ parentChildMap?: Record; childType?: string }> { + // Find grouping with belongsTo + const childGrouping = groupings.find(g => g.belongsTo); + if (!childGrouping?.belongsTo) return {}; + + // Parse belongsTo: 'team.resourceIds' + const [entityType, property] = childGrouping.belongsTo.split('.'); + if (!entityType || !property) return {}; + + // Get parent IDs from filter + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) return {}; + + // Find service dynamisk baseret på entityType (ingen hardcoded type check) + const service = this.entityServices.find(s => + s.entityType.toLowerCase() === entityType + ); + if (!service) return {}; + + // Hent alle entities og filtrer på parentIds + const allEntities = await service.getAll(); + const entities = allEntities.filter(e => + parentIds.includes((e as unknown as Record).id as string) + ); + + // Byg parent-child map + const map: Record = {}; + for (const entity of entities) { + const entityRecord = entity as unknown as Record; + const children = (entityRecord[property] as string[]) || []; + map[entityRecord.id as string] = children; + } + + return { parentChildMap: map, childType: childGrouping.type }; + } +} diff --git a/packages/calendar/src/core/DateService.ts b/packages/calendar/src/core/DateService.ts new file mode 100644 index 0000000..1d3c44d --- /dev/null +++ b/packages/calendar/src/core/DateService.ts @@ -0,0 +1,195 @@ +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +import isoWeek from 'dayjs/plugin/isoWeek'; +import { ITimeFormatConfig } from './ITimeFormatConfig'; + +// Enable dayjs plugins +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.extend(isoWeek); + +export class DateService { + private timezone: string; + private baseDate: dayjs.Dayjs; + + constructor(private config: ITimeFormatConfig, baseDate?: Date) { + this.timezone = config.timezone; + // Allow setting a fixed base date for demo/testing purposes + this.baseDate = baseDate ? dayjs(baseDate) : dayjs(); + } + + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date: Date): void { + this.baseDate = dayjs(date); + } + + /** + * Get the current base date (either fixed or today) + */ + getBaseDate(): Date { + return this.baseDate.toDate(); + } + + parseISO(isoString: string): Date { + return dayjs(isoString).toDate(); + } + + getDayName(date: Date, format: 'short' | 'long' = 'short'): string { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + + /** + * Get dates starting from a day offset + * @param dayOffset - Day offset from base date + * @param count - Number of consecutive days to return + * @returns Array of date strings in YYYY-MM-DD format + */ + getDatesFromOffset(dayOffset: number, count: number): string[] { + const startDate = this.baseDate.add(dayOffset, 'day'); + return Array.from({ length: count }, (_, i) => + startDate.add(i, 'day').format('YYYY-MM-DD') + ); + } + + /** + * Get specific weekdays from the week containing the offset date + * @param dayOffset - Day offset from base date + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkDaysFromOffset(dayOffset: number, workDays: number[]): string[] { + // Get the date at offset, then find its week's Monday + const targetDate = this.baseDate.add(dayOffset, 'day'); + const monday = targetDate.startOf('week').add(1, 'day'); + + return workDays.map(isoDay => { + // ISO: 1=Monday, 7=Sunday → days from Monday: 0-6 + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, 'day').format('YYYY-MM-DD'); + }); + } + + // Legacy methods for backwards compatibility + getWeekDates(weekOffset = 0, days = 7): string[] { + return this.getDatesFromOffset(weekOffset * 7, days); + } + + getWorkWeekDates(weekOffset: number, workDays: number[]): string[] { + return this.getWorkDaysFromOffset(weekOffset * 7, workDays); + } + + // ============================================ + // FORMATTING + // ============================================ + + formatTime(date: Date, showSeconds = false): string { + const pattern = showSeconds ? 'HH:mm:ss' : 'HH:mm'; + return dayjs(date).format(pattern); + } + + formatTimeRange(start: Date, end: Date): string { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + + formatDate(date: Date): string { + return dayjs(date).format('YYYY-MM-DD'); + } + + getDateKey(date: Date): string { + return this.formatDate(date); + } + + // ============================================ + // COLUMN KEY + // ============================================ + + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments: Record): string { + // Always put date first if present, then other segments alphabetically + const date = segments.date; + const others = Object.entries(segments) + .filter(([k]) => k !== 'date') + .sort(([a], [b]) => a.localeCompare(b)) + .map(([, v]) => v); + + return date ? [date, ...others].join(':') : others.join(':'); + } + + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey: string): { date: string; resource?: string } { + const parts = columnKey.split(':'); + return { + date: parts[0], + resource: parts[1] + }; + } + + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey: string): string { + return columnKey.split(':')[0]; + } + + // ============================================ + // TIME CALCULATIONS + // ============================================ + + timeToMinutes(timeString: string): number { + const parts = timeString.split(':').map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + + minutesToTime(totalMinutes: number): string { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return dayjs().hour(hours).minute(minutes).format('HH:mm'); + } + + getMinutesSinceMidnight(date: Date): number { + const d = dayjs(date); + return d.hour() * 60 + d.minute(); + } + + // ============================================ + // UTC CONVERSIONS + // ============================================ + + toUTC(localDate: Date): string { + return dayjs.tz(localDate, this.timezone).utc().toISOString(); + } + + fromUTC(utcString: string): Date { + return dayjs.utc(utcString).tz(this.timezone).toDate(); + } + + // ============================================ + // DATE CREATION + // ============================================ + + createDateAtTime(baseDate: Date | string, timeString: string): Date { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return dayjs(baseDate).startOf('day').hour(hours).minute(minutes).toDate(); + } + + getISOWeekDay(date: Date | string): number { + return dayjs(date).isoWeekday(); // 1=Monday, 7=Sunday + } +} diff --git a/packages/calendar/src/core/EntityResolver.ts b/packages/calendar/src/core/EntityResolver.ts new file mode 100644 index 0000000..7161c30 --- /dev/null +++ b/packages/calendar/src/core/EntityResolver.ts @@ -0,0 +1,48 @@ +import { IEntityResolver } from './IEntityResolver'; + +/** + * EntityResolver - Resolves entities from pre-loaded cache + * + * Entities must be loaded before use (typically at render time). + * This allows synchronous lookups during filtering. + */ +export class EntityResolver implements IEntityResolver { + private cache: Map>> = new Map(); + + /** + * Load entities into cache for a given type + * @param entityType - The entity type (e.g., 'resource') + * @param entities - Array of entities with 'id' property + */ + load(entityType: string, entities: T[]): void { + const typeCache = new Map>(); + for (const entity of entities) { + // Cast to Record for storage while preserving original data + typeCache.set(entity.id, entity as unknown as Record); + } + this.cache.set(entityType, typeCache); + } + + /** + * Resolve an entity by type and ID + */ + resolve(entityType: string, id: string): Record | undefined { + const typeCache = this.cache.get(entityType); + if (!typeCache) return undefined; + return typeCache.get(id); + } + + /** + * Clear all cached entities + */ + clear(): void { + this.cache.clear(); + } + + /** + * Clear cache for a specific entity type + */ + clearType(entityType: string): void { + this.cache.delete(entityType); + } +} diff --git a/packages/calendar/src/core/EventBus.ts b/packages/calendar/src/core/EventBus.ts new file mode 100644 index 0000000..469a73e --- /dev/null +++ b/packages/calendar/src/core/EventBus.ts @@ -0,0 +1,174 @@ +import { IEventLogEntry, IListenerEntry, IEventBus } from '../types/CalendarTypes'; + +/** + * Central event dispatcher for calendar using DOM CustomEvents + * Provides logging and debugging capabilities + */ +export class EventBus implements IEventBus { + private eventLog: IEventLogEntry[] = []; + private debug: boolean = false; + private listeners: Set = new Set(); + + // Log configuration for different categories + private logConfig: { [key: string]: boolean } = { + calendar: true, + grid: true, + event: true, + scroll: true, + navigation: true, + view: true, + default: true + }; + + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void { + document.addEventListener(eventType, handler, options); + + // Track for cleanup + this.listeners.add({ eventType, handler, options }); + + // Return unsubscribe function + return () => this.off(eventType, handler); + } + + /** + * Subscribe to an event once + */ + once(eventType: string, handler: EventListener): () => void { + return this.on(eventType, handler, { once: true }); + } + + /** + * Unsubscribe from an event + */ + off(eventType: string, handler: EventListener): void { + document.removeEventListener(eventType, handler); + + // Remove from tracking + for (const listener of this.listeners) { + if (listener.eventType === eventType && listener.handler === handler) { + this.listeners.delete(listener); + break; + } + } + } + + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType: string, detail: unknown = {}): boolean { + // Validate eventType + if (!eventType) { + return false; + } + + const event = new CustomEvent(eventType, { + detail: detail ?? {}, + bubbles: true, + cancelable: true + }); + + // Log event with grouping + if (this.debug) { + this.logEventWithGrouping(eventType, detail); + } + + this.eventLog.push({ + type: eventType, + detail: detail ?? {}, + timestamp: Date.now() + }); + + // Emit on document (only DOM events now) + return !document.dispatchEvent(event); + } + + /** + * Log event with console grouping + */ + private logEventWithGrouping(eventType: string, _detail: unknown): void { + // Extract category from event type (e.g., 'calendar:datechanged' → 'calendar') + const category = this.extractCategory(eventType); + + // Only log if category is enabled + if (!this.logConfig[category]) { + return; + } + + // Get category emoji and color (used for future console styling) + this.getCategoryStyle(category); + } + + /** + * Extract category from event type + */ + private extractCategory(eventType: string): string { + if (!eventType) { + return 'unknown'; + } + + if (eventType.includes(':')) { + return eventType.split(':')[0]; + } + + // Fallback: try to detect category from event name patterns + const lowerType = eventType.toLowerCase(); + if (lowerType.includes('grid') || lowerType.includes('rendered')) return 'grid'; + if (lowerType.includes('event') || lowerType.includes('sync')) return 'event'; + if (lowerType.includes('scroll')) return 'scroll'; + if (lowerType.includes('nav') || lowerType.includes('date')) return 'navigation'; + if (lowerType.includes('view')) return 'view'; + + return 'default'; + } + + /** + * Get styling for different categories + */ + private getCategoryStyle(category: string): { emoji: string; color: string } { + const styles: { [key: string]: { emoji: string; color: string } } = { + calendar: { emoji: '📅', color: '#2196F3' }, + grid: { emoji: '📊', color: '#4CAF50' }, + event: { emoji: '📌', color: '#FF9800' }, + scroll: { emoji: '📜', color: '#9C27B0' }, + navigation: { emoji: '🧭', color: '#F44336' }, + view: { emoji: '👁', color: '#00BCD4' }, + default: { emoji: '📢', color: '#607D8B' } + }; + + return styles[category] || styles.default; + } + + /** + * Configure logging for specific categories + */ + setLogConfig(config: { [key: string]: boolean }): void { + this.logConfig = { ...this.logConfig, ...config }; + } + + /** + * Get current log configuration + */ + getLogConfig(): { [key: string]: boolean } { + return { ...this.logConfig }; + } + + /** + * Get event history + */ + getEventLog(eventType?: string): IEventLogEntry[] { + if (eventType) { + return this.eventLog.filter(e => e.type === eventType); + } + return this.eventLog; + } + + /** + * Enable/disable debug mode + */ + setDebug(enabled: boolean): void { + this.debug = enabled; + } +} diff --git a/packages/calendar/src/core/FilterTemplate.ts b/packages/calendar/src/core/FilterTemplate.ts new file mode 100644 index 0000000..00451b1 --- /dev/null +++ b/packages/calendar/src/core/FilterTemplate.ts @@ -0,0 +1,149 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { DateService } from './DateService'; +import { IEntityResolver } from './IEntityResolver'; + +/** + * Field definition for FilterTemplate + */ +interface IFilterField { + idProperty: string; + derivedFrom?: string; +} + +/** + * Parsed dot-notation reference + */ +interface IDotNotation { + entityType: string; // e.g., 'resource' + property: string; // e.g., 'teamId' + foreignKey: string; // e.g., 'resourceId' +} + +/** + * FilterTemplate - Bygger nøgler til event-kolonne matching + * + * ViewConfig definerer hvilke felter (idProperties) der indgår i kolonnens nøgle. + * Samme template bruges til at bygge nøgle for både kolonne og event. + * + * Supports dot-notation for hierarchical relations: + * - 'resource.teamId' → looks up event.resourceId → resource entity → teamId + * + * Princip: Kolonnens nøgle-template bestemmer hvad der matches på. + * + * @see docs/filter-template.md + */ +export class FilterTemplate { + private fields: IFilterField[] = []; + + constructor( + private dateService: DateService, + private entityResolver?: IEntityResolver + ) {} + + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty: string, derivedFrom?: string): this { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + private parseDotNotation(idProperty: string): IDotNotation | null { + if (!idProperty.includes('.')) return null; + const [entityType, property] = idProperty.split('.'); + return { + entityType, + property, + foreignKey: entityType + 'Id' // Convention: resource → resourceId + }; + } + + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + private getDatasetKey(idProperty: string): string { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; // 'teamId' + } + return idProperty; + } + + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column: HTMLElement): string { + return this.fields + .map(f => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ''; + }) + .join(':'); + } + + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event: ICalendarEvent): string { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const eventRecord = event as any; + return this.fields + .map(f => { + // Check for dot-notation (e.g., 'resource.teamId') + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + + if (f.derivedFrom) { + // Udled værdi (f.eks. date fra start) + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ''); + } + return String(eventRecord[f.idProperty] || ''); + }) + .join(':'); + } + + /** + * Resolve dot-notation reference via EntityResolver + */ + private resolveDotNotation(eventRecord: Record, dotNotation: IDotNotation): string { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ''; + } + + // Get foreign key value from event (e.g., resourceId) + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) return ''; + + // Resolve entity + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) return ''; + + // Return property value from entity + return String(entity[dotNotation.property] || ''); + } + + /** + * Match event mod kolonne + */ + matches(event: ICalendarEvent, column: HTMLElement): boolean { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +} diff --git a/packages/calendar/src/core/HeaderDrawerManager.ts b/packages/calendar/src/core/HeaderDrawerManager.ts new file mode 100644 index 0000000..445bb23 --- /dev/null +++ b/packages/calendar/src/core/HeaderDrawerManager.ts @@ -0,0 +1,70 @@ +export class HeaderDrawerManager { + private drawer!: HTMLElement; + private expanded = false; + private currentRows = 0; + private readonly rowHeight = 25; + private readonly duration = 200; + + init(container: HTMLElement): void { + this.drawer = container.querySelector('swp-header-drawer')!; + + if (!this.drawer) console.error('HeaderDrawerManager: swp-header-drawer not found'); + } + + toggle(): void { + this.expanded ? this.collapse() : this.expand(); + } + + /** + * Expand drawer to single row (legacy support) + */ + expand(): void { + this.expandToRows(1); + } + + /** + * Expand drawer to fit specified number of rows + */ + expandToRows(rowCount: number): void { + const targetHeight = rowCount * this.rowHeight; + const currentHeight = this.expanded ? this.currentRows * this.rowHeight : 0; + + // Skip if already at target + if (this.expanded && this.currentRows === rowCount) return; + + this.currentRows = rowCount; + this.expanded = true; + this.animate(currentHeight, targetHeight); + } + + collapse(): void { + if (!this.expanded) return; + const currentHeight = this.currentRows * this.rowHeight; + this.expanded = false; + this.currentRows = 0; + this.animate(currentHeight, 0); + } + + private animate(from: number, to: number): void { + const keyframes = [ + { height: `${from}px` }, + { height: `${to}px` } + ]; + const options: KeyframeAnimationOptions = { + duration: this.duration, + easing: 'ease', + fill: 'forwards' + }; + + // Kun animér drawer - ScrollManager synkroniserer header-spacer via ResizeObserver + this.drawer.animate(keyframes, options); + } + + isExpanded(): boolean { + return this.expanded; + } + + getRowCount(): number { + return this.currentRows; + } +} diff --git a/packages/calendar/src/core/IEntityResolver.ts b/packages/calendar/src/core/IEntityResolver.ts new file mode 100644 index 0000000..b825c0f --- /dev/null +++ b/packages/calendar/src/core/IEntityResolver.ts @@ -0,0 +1,15 @@ +/** + * IEntityResolver - Resolves entities by type and ID + * + * Used by FilterTemplate to resolve dot-notation references like 'resource.teamId' + * where the value needs to be looked up from a related entity. + */ +export interface IEntityResolver { + /** + * Resolve an entity by type and ID + * @param entityType - The entity type (e.g., 'resource', 'booking', 'customer') + * @param id - The entity ID + * @returns The entity record or undefined if not found + */ + resolve(entityType: string, id: string): Record | undefined; +} diff --git a/packages/calendar/src/core/IGridConfig.ts b/packages/calendar/src/core/IGridConfig.ts new file mode 100644 index 0000000..03c6a2f --- /dev/null +++ b/packages/calendar/src/core/IGridConfig.ts @@ -0,0 +1,7 @@ +export interface IGridConfig { + hourHeight: number; // pixels per hour + dayStartHour: number; // e.g. 6 + dayEndHour: number; // e.g. 18 + snapInterval: number; // minutes, e.g. 15 + gridStartThresholdMinutes?: number; // threshold for GRID grouping (default 10) +} diff --git a/packages/calendar/src/core/IGroupingRenderer.ts b/packages/calendar/src/core/IGroupingRenderer.ts new file mode 100644 index 0000000..a1bc507 --- /dev/null +++ b/packages/calendar/src/core/IGroupingRenderer.ts @@ -0,0 +1,15 @@ +import { GroupingConfig } from './ViewConfig'; + +export interface IRenderContext { + headerContainer: HTMLElement; + columnContainer: HTMLElement; + filter: Record; // { team: ['alpha'], resource: ['alice', 'bob'], date: [...] } + groupings?: GroupingConfig[]; // Full grouping configs (for hideHeader etc.) + parentChildMap?: Record; // { team1: ['EMP001', 'EMP002'], team2: ['EMP003', 'EMP004'] } + childType?: string; // The type of the child grouping (e.g., 'resource' when team has belongsTo) +} + +export interface IRenderer { + readonly type: string; + render(context: IRenderContext): void | Promise; +} diff --git a/packages/calendar/src/core/IGroupingStore.ts b/packages/calendar/src/core/IGroupingStore.ts new file mode 100644 index 0000000..8abc837 --- /dev/null +++ b/packages/calendar/src/core/IGroupingStore.ts @@ -0,0 +1,4 @@ +export interface IGroupingStore { + readonly type: string; + getByIds(ids: string[]): T[]; +} diff --git a/packages/calendar/src/core/ITimeFormatConfig.ts b/packages/calendar/src/core/ITimeFormatConfig.ts new file mode 100644 index 0000000..1a401d5 --- /dev/null +++ b/packages/calendar/src/core/ITimeFormatConfig.ts @@ -0,0 +1,7 @@ +export interface ITimeFormatConfig { + timezone: string; + use24HourFormat: boolean; + locale: string; + dateFormat: 'locale' | 'technical'; + showSeconds: boolean; +} diff --git a/packages/calendar/src/core/NavigationAnimator.ts b/packages/calendar/src/core/NavigationAnimator.ts new file mode 100644 index 0000000..cf173ad --- /dev/null +++ b/packages/calendar/src/core/NavigationAnimator.ts @@ -0,0 +1,64 @@ +export class NavigationAnimator { + constructor( + private headerTrack: HTMLElement, + private contentTrack: HTMLElement, + private headerDrawer: HTMLElement | null + ) {} + + async slide(direction: 'left' | 'right', renderFn: () => Promise): Promise { + const out = direction === 'left' ? '-100%' : '100%'; + const into = direction === 'left' ? '100%' : '-100%'; + + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + + private async animateOut(translate: string): Promise { + const animations = [ + this.headerTrack.animate( + [{ transform: 'translateX(0)' }, { transform: `translateX(${translate})` }], + { duration: 200, easing: 'ease-in' } + ).finished, + this.contentTrack.animate( + [{ transform: 'translateX(0)' }, { transform: `translateX(${translate})` }], + { duration: 200, easing: 'ease-in' } + ).finished + ]; + + if (this.headerDrawer) { + animations.push( + this.headerDrawer.animate( + [{ transform: 'translateX(0)' }, { transform: `translateX(${translate})` }], + { duration: 200, easing: 'ease-in' } + ).finished + ); + } + + await Promise.all(animations); + } + + private async animateIn(translate: string): Promise { + const animations = [ + this.headerTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: 'translateX(0)' }], + { duration: 200, easing: 'ease-out' } + ).finished, + this.contentTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: 'translateX(0)' }], + { duration: 200, easing: 'ease-out' } + ).finished + ]; + + if (this.headerDrawer) { + animations.push( + this.headerDrawer.animate( + [{ transform: `translateX(${translate})` }, { transform: 'translateX(0)' }], + { duration: 200, easing: 'ease-out' } + ).finished + ); + } + + await Promise.all(animations); + } +} diff --git a/packages/calendar/src/core/RenderBuilder.ts b/packages/calendar/src/core/RenderBuilder.ts new file mode 100644 index 0000000..68f0ee3 --- /dev/null +++ b/packages/calendar/src/core/RenderBuilder.ts @@ -0,0 +1,15 @@ +import { IRenderer, IRenderContext } from './IGroupingRenderer'; + +export interface Pipeline { + run(context: IRenderContext): Promise; +} + +export function buildPipeline(renderers: IRenderer[]): Pipeline { + return { + async run(context: IRenderContext) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} diff --git a/packages/calendar/src/core/ScrollManager.ts b/packages/calendar/src/core/ScrollManager.ts new file mode 100644 index 0000000..bb4f490 --- /dev/null +++ b/packages/calendar/src/core/ScrollManager.ts @@ -0,0 +1,42 @@ +export class ScrollManager { + private scrollableContent!: HTMLElement; + private timeAxisContent!: HTMLElement; + private calendarHeader!: HTMLElement; + private headerDrawer!: HTMLElement; + private headerViewport!: HTMLElement; + private headerSpacer!: HTMLElement; + private resizeObserver!: ResizeObserver; + + init(container: HTMLElement): void { + this.scrollableContent = container.querySelector('swp-scrollable-content')!; + this.timeAxisContent = container.querySelector('swp-time-axis-content')!; + this.calendarHeader = container.querySelector('swp-calendar-header')!; + this.headerDrawer = container.querySelector('swp-header-drawer')!; + this.headerViewport = container.querySelector('swp-header-viewport')!; + this.headerSpacer = container.querySelector('swp-header-spacer')!; + + this.scrollableContent.addEventListener('scroll', () => this.onScroll()); + + // Synkroniser header-spacer højde med header-viewport + this.resizeObserver = new ResizeObserver(() => this.syncHeaderSpacerHeight()); + this.resizeObserver.observe(this.headerViewport); + this.syncHeaderSpacerHeight(); + } + + private syncHeaderSpacerHeight(): void { + // Kopier den faktiske computed height direkte fra header-viewport + const computedHeight = getComputedStyle(this.headerViewport).height; + this.headerSpacer.style.height = computedHeight; + } + + private onScroll(): void { + const { scrollTop, scrollLeft } = this.scrollableContent; + + // Synkroniser time-axis vertikalt + this.timeAxisContent.style.transform = `translateY(-${scrollTop}px)`; + + // Synkroniser header og drawer horisontalt + this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`; + this.headerDrawer.style.transform = `translateX(-${scrollLeft}px)`; + } +} diff --git a/packages/calendar/src/core/ViewConfig.ts b/packages/calendar/src/core/ViewConfig.ts new file mode 100644 index 0000000..8ecd79b --- /dev/null +++ b/packages/calendar/src/core/ViewConfig.ts @@ -0,0 +1,21 @@ +import { ISync } from '../types/CalendarTypes'; + +export interface ViewTemplate { + id: string; + name: string; + groupingTypes: string[]; +} + +export interface ViewConfig extends ISync { + id: string; // templateId (e.g. 'day', 'simple', 'resource') + groupings: GroupingConfig[]; +} + +export interface GroupingConfig { + type: string; + values: string[]; + idProperty?: string; // Property-navn på event (f.eks. 'resourceId') - kun for event matching + derivedFrom?: string; // Hvis feltet udledes fra anden property (f.eks. 'date' fra 'start') + belongsTo?: string; // Parent-child relation (f.eks. 'team.resourceIds') + hideHeader?: boolean; // Skjul header-rækken for denne grouping (f.eks. dato i day-view) +} diff --git a/packages/calendar/src/extensions/audit/AuditService.ts b/packages/calendar/src/extensions/audit/AuditService.ts new file mode 100644 index 0000000..ccdb2b4 --- /dev/null +++ b/packages/calendar/src/extensions/audit/AuditService.ts @@ -0,0 +1,167 @@ +import { BaseEntityService } from '../../storage/BaseEntityService'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; +import { IAuditEntry, IAuditLoggedPayload } from '../../types/AuditTypes'; +import { EntityType, IEventBus, IEntitySavedPayload, IEntityDeletedPayload } from '../../types/CalendarTypes'; +import { CoreEvents } from '../../constants/CoreEvents'; + +/** + * AuditService - Entity service for audit entries + * + * RESPONSIBILITIES: + * - Store audit entries in IndexedDB + * - Listen for ENTITY_SAVED/ENTITY_DELETED events + * - Create audit entries for all entity changes + * - Emit AUDIT_LOGGED after saving (for SyncManager to listen) + * + * OVERRIDE PATTERN: + * - Overrides save() to NOT emit events (prevents infinite loops) + * - AuditService saves audit entries without triggering more audits + * + * EVENT CHAIN: + * Entity change → ENTITY_SAVED/DELETED → AuditService → AUDIT_LOGGED → SyncManager + */ +export class AuditService extends BaseEntityService { + readonly storeName = 'audit'; + readonly entityType: EntityType = 'Audit'; + + // Hardcoded userId for now - will come from session later + private static readonly DEFAULT_USER_ID = '00000000-0000-0000-0000-000000000001'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + this.setupEventListeners(); + } + + /** + * Setup listeners for ENTITY_SAVED and ENTITY_DELETED events + */ + private setupEventListeners(): void { + // Listen for entity saves (create/update) + this.eventBus.on(CoreEvents.ENTITY_SAVED, (event: Event) => { + const detail = (event as CustomEvent).detail; + this.handleEntitySaved(detail); + }); + + // Listen for entity deletes + this.eventBus.on(CoreEvents.ENTITY_DELETED, (event: Event) => { + const detail = (event as CustomEvent).detail; + this.handleEntityDeleted(detail); + }); + } + + /** + * Handle ENTITY_SAVED event - create audit entry + */ + private async handleEntitySaved(payload: IEntitySavedPayload): Promise { + // Don't audit audit entries (prevent infinite loops) + if (payload.entityType === 'Audit') return; + + const auditEntry: IAuditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: payload.operation, + userId: AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: payload.changes, + synced: false, + syncStatus: 'pending' + }; + + await this.save(auditEntry); + } + + /** + * Handle ENTITY_DELETED event - create audit entry + */ + private async handleEntityDeleted(payload: IEntityDeletedPayload): Promise { + // Don't audit audit entries (prevent infinite loops) + if (payload.entityType === 'Audit') return; + + const auditEntry: IAuditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: 'delete', + userId: AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: { id: payload.entityId }, // For delete, just store the ID + synced: false, + syncStatus: 'pending' + }; + + await this.save(auditEntry); + } + + /** + * Override save to NOT trigger ENTITY_SAVED event + * Instead, emits AUDIT_LOGGED for SyncManager to listen + * + * This prevents infinite loops: + * - BaseEntityService.save() emits ENTITY_SAVED + * - AuditService listens to ENTITY_SAVED and creates audit + * - If AuditService.save() also emitted ENTITY_SAVED, it would loop + */ + async save(entity: IAuditEntry): Promise { + const serialized = this.serialize(entity); + + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + + request.onsuccess = () => { + // Emit AUDIT_LOGGED instead of ENTITY_SAVED + const payload: IAuditLoggedPayload = { + auditId: entity.id, + entityType: entity.entityType, + entityId: entity.entityId, + operation: entity.operation, + timestamp: entity.timestamp + }; + this.eventBus.emit(CoreEvents.AUDIT_LOGGED, payload); + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to save audit entry ${entity.id}: ${request.error}`)); + }; + }); + } + + /** + * Override delete to NOT trigger ENTITY_DELETED event + * Audit entries should never be deleted (compliance requirement) + */ + async delete(_id: string): Promise { + throw new Error('Audit entries cannot be deleted (compliance requirement)'); + } + + /** + * Get pending audit entries (for sync) + */ + async getPendingAudits(): Promise { + return this.getBySyncStatus('pending'); + } + + /** + * Get audit entries for a specific entity + */ + async getByEntityId(entityId: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('entityId'); + const request = index.getAll(entityId); + + request.onsuccess = () => { + const entries = request.result as IAuditEntry[]; + resolve(entries); + }; + + request.onerror = () => { + reject(new Error(`Failed to get audit entries for entity ${entityId}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/extensions/audit/AuditStore.ts b/packages/calendar/src/extensions/audit/AuditStore.ts new file mode 100644 index 0000000..769b3b9 --- /dev/null +++ b/packages/calendar/src/extensions/audit/AuditStore.ts @@ -0,0 +1,27 @@ +import { IStore } from '../../storage/IStore'; + +/** + * AuditStore - IndexedDB store configuration for audit entries + * + * Stores all entity changes for: + * - Compliance and audit trail + * - Sync tracking with backend + * - Change history + * + * Indexes: + * - syncStatus: For finding pending entries to sync + * - synced: Boolean flag for quick sync queries + * - entityId: For getting all audits for a specific entity + * - timestamp: For chronological queries + */ +export class AuditStore implements IStore { + readonly storeName = 'audit'; + + create(db: IDBDatabase): void { + const store = db.createObjectStore(this.storeName, { keyPath: 'id' }); + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + store.createIndex('synced', 'synced', { unique: false }); + store.createIndex('entityId', 'entityId', { unique: false }); + store.createIndex('timestamp', 'timestamp', { unique: false }); + } +} diff --git a/packages/calendar/src/extensions/audit/index.ts b/packages/calendar/src/extensions/audit/index.ts new file mode 100644 index 0000000..48100e1 --- /dev/null +++ b/packages/calendar/src/extensions/audit/index.ts @@ -0,0 +1,14 @@ +export { AuditService } from './AuditService'; +export { AuditStore } from './AuditStore'; +export type { IAuditEntry, IAuditLoggedPayload } from '../../types/AuditTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IStore } from '../../storage/IStore'; +import { AuditStore } from './AuditStore'; +import { AuditService } from './AuditService'; + +export function registerAudit(builder: Builder): void { + builder.registerType(AuditStore).as(); + builder.registerType(AuditService).as(); +} diff --git a/packages/calendar/src/extensions/bookings/BookingService.ts b/packages/calendar/src/extensions/bookings/BookingService.ts new file mode 100644 index 0000000..d12eb57 --- /dev/null +++ b/packages/calendar/src/extensions/bookings/BookingService.ts @@ -0,0 +1,75 @@ +import { IBooking, EntityType, IEventBus, BookingStatus } from '../../types/CalendarTypes'; +import { BookingStore } from './BookingStore'; +import { BaseEntityService } from '../../storage/BaseEntityService'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; + +/** + * BookingService - CRUD operations for bookings in IndexedDB + */ +export class BookingService extends BaseEntityService { + readonly storeName = BookingStore.STORE_NAME; + readonly entityType: EntityType = 'Booking'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + protected serialize(booking: IBooking): unknown { + return { + ...booking, + createdAt: booking.createdAt.toISOString() + }; + } + + protected deserialize(data: unknown): IBooking { + const raw = data as Record; + return { + ...raw, + createdAt: new Date(raw.createdAt as string) + } as IBooking; + } + + /** + * Get bookings for a customer + */ + async getByCustomer(customerId: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('customerId'); + const request = index.getAll(customerId); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const bookings = data.map(item => this.deserialize(item)); + resolve(bookings); + }; + + request.onerror = () => { + reject(new Error(`Failed to get bookings for customer ${customerId}: ${request.error}`)); + }; + }); + } + + /** + * Get bookings by status + */ + async getByStatus(status: BookingStatus): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('status'); + const request = index.getAll(status); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const bookings = data.map(item => this.deserialize(item)); + resolve(bookings); + }; + + request.onerror = () => { + reject(new Error(`Failed to get bookings with status ${status}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/extensions/bookings/BookingStore.ts b/packages/calendar/src/extensions/bookings/BookingStore.ts new file mode 100644 index 0000000..5e64ad3 --- /dev/null +++ b/packages/calendar/src/extensions/bookings/BookingStore.ts @@ -0,0 +1,18 @@ +import { IStore } from '../../storage/IStore'; + +/** + * BookingStore - IndexedDB ObjectStore definition for bookings + */ +export class BookingStore implements IStore { + static readonly STORE_NAME = 'bookings'; + readonly storeName = BookingStore.STORE_NAME; + + create(db: IDBDatabase): void { + const store = db.createObjectStore(BookingStore.STORE_NAME, { keyPath: 'id' }); + + store.createIndex('customerId', 'customerId', { unique: false }); + store.createIndex('status', 'status', { unique: false }); + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + store.createIndex('createdAt', 'createdAt', { unique: false }); + } +} diff --git a/packages/calendar/src/extensions/bookings/index.ts b/packages/calendar/src/extensions/bookings/index.ts new file mode 100644 index 0000000..4bfe7d2 --- /dev/null +++ b/packages/calendar/src/extensions/bookings/index.ts @@ -0,0 +1,18 @@ +export { BookingService } from './BookingService'; +export { BookingStore } from './BookingStore'; +export type { IBooking, BookingStatus, IBookingService } from '../../types/CalendarTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IStore } from '../../storage/IStore'; +import { IEntityService } from '../../storage/IEntityService'; +import type { IBooking, ISync } from '../../types/CalendarTypes'; +import { BookingStore } from './BookingStore'; +import { BookingService } from './BookingService'; + +export function registerBookings(builder: Builder): void { + builder.registerType(BookingStore).as(); + builder.registerType(BookingService).as>(); + builder.registerType(BookingService).as>(); + builder.registerType(BookingService).as(); +} diff --git a/packages/calendar/src/extensions/customers/CustomerService.ts b/packages/calendar/src/extensions/customers/CustomerService.ts new file mode 100644 index 0000000..d1225e1 --- /dev/null +++ b/packages/calendar/src/extensions/customers/CustomerService.ts @@ -0,0 +1,46 @@ +import { ICustomer, EntityType, IEventBus } from '../../types/CalendarTypes'; +import { CustomerStore } from './CustomerStore'; +import { BaseEntityService } from '../../storage/BaseEntityService'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; + +/** + * CustomerService - CRUD operations for customers in IndexedDB + */ +export class CustomerService extends BaseEntityService { + readonly storeName = CustomerStore.STORE_NAME; + readonly entityType: EntityType = 'Customer'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + /** + * Search customers by name (case-insensitive contains) + */ + async searchByName(query: string): Promise { + const all = await this.getAll(); + const lowerQuery = query.toLowerCase(); + return all.filter(c => c.name.toLowerCase().includes(lowerQuery)); + } + + /** + * Find customer by phone + */ + async getByPhone(phone: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('phone'); + const request = index.get(phone); + + request.onsuccess = () => { + const data = request.result; + resolve(data ? (data as ICustomer) : null); + }; + + request.onerror = () => { + reject(new Error(`Failed to find customer by phone ${phone}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/extensions/customers/CustomerStore.ts b/packages/calendar/src/extensions/customers/CustomerStore.ts new file mode 100644 index 0000000..b53cd7e --- /dev/null +++ b/packages/calendar/src/extensions/customers/CustomerStore.ts @@ -0,0 +1,17 @@ +import { IStore } from '../../storage/IStore'; + +/** + * CustomerStore - IndexedDB ObjectStore definition for customers + */ +export class CustomerStore implements IStore { + static readonly STORE_NAME = 'customers'; + readonly storeName = CustomerStore.STORE_NAME; + + create(db: IDBDatabase): void { + const store = db.createObjectStore(CustomerStore.STORE_NAME, { keyPath: 'id' }); + + store.createIndex('name', 'name', { unique: false }); + store.createIndex('phone', 'phone', { unique: false }); + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + } +} diff --git a/packages/calendar/src/extensions/customers/index.ts b/packages/calendar/src/extensions/customers/index.ts new file mode 100644 index 0000000..6d47df5 --- /dev/null +++ b/packages/calendar/src/extensions/customers/index.ts @@ -0,0 +1,18 @@ +export { CustomerService } from './CustomerService'; +export { CustomerStore } from './CustomerStore'; +export type { ICustomer } from '../../types/CalendarTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IStore } from '../../storage/IStore'; +import { IEntityService } from '../../storage/IEntityService'; +import type { ICustomer, ISync } from '../../types/CalendarTypes'; +import { CustomerStore } from './CustomerStore'; +import { CustomerService } from './CustomerService'; + +export function registerCustomers(builder: Builder): void { + builder.registerType(CustomerStore).as(); + builder.registerType(CustomerService).as>(); + builder.registerType(CustomerService).as>(); + builder.registerType(CustomerService).as(); +} diff --git a/packages/calendar/src/extensions/departments/DepartmentRenderer.ts b/packages/calendar/src/extensions/departments/DepartmentRenderer.ts new file mode 100644 index 0000000..16bb161 --- /dev/null +++ b/packages/calendar/src/extensions/departments/DepartmentRenderer.ts @@ -0,0 +1,25 @@ +import { BaseGroupingRenderer, IGroupingRendererConfig } from '../../core/BaseGroupingRenderer'; +import { DepartmentService } from './DepartmentService'; +import { IDepartment } from '../../types/CalendarTypes'; + +export class DepartmentRenderer extends BaseGroupingRenderer { + readonly type = 'department'; + + protected readonly config: IGroupingRendererConfig = { + elementTag: 'swp-department-header', + idAttribute: 'departmentId', + colspanVar: '--department-cols' + }; + + constructor(private departmentService: DepartmentService) { + super(); + } + + protected getEntities(ids: string[]): Promise { + return this.departmentService.getByIds(ids); + } + + protected getDisplayName(entity: IDepartment): string { + return entity.name; + } +} diff --git a/packages/calendar/src/extensions/departments/DepartmentService.ts b/packages/calendar/src/extensions/departments/DepartmentService.ts new file mode 100644 index 0000000..4b4c8b9 --- /dev/null +++ b/packages/calendar/src/extensions/departments/DepartmentService.ts @@ -0,0 +1,25 @@ +import { IDepartment, EntityType, IEventBus } from '../../types/CalendarTypes'; +import { DepartmentStore } from './DepartmentStore'; +import { BaseEntityService } from '../../storage/BaseEntityService'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; + +/** + * DepartmentService - CRUD operations for departments in IndexedDB + */ +export class DepartmentService extends BaseEntityService { + readonly storeName = DepartmentStore.STORE_NAME; + readonly entityType: EntityType = 'Department'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + /** + * Get departments by IDs + */ + async getByIds(ids: string[]): Promise { + if (ids.length === 0) return []; + const results = await Promise.all(ids.map(id => this.get(id))); + return results.filter((d): d is IDepartment => d !== null); + } +} diff --git a/packages/calendar/src/extensions/departments/DepartmentStore.ts b/packages/calendar/src/extensions/departments/DepartmentStore.ts new file mode 100644 index 0000000..0e9c6a3 --- /dev/null +++ b/packages/calendar/src/extensions/departments/DepartmentStore.ts @@ -0,0 +1,13 @@ +import { IStore } from '../../storage/IStore'; + +/** + * DepartmentStore - IndexedDB ObjectStore definition for departments + */ +export class DepartmentStore implements IStore { + static readonly STORE_NAME = 'departments'; + readonly storeName = DepartmentStore.STORE_NAME; + + create(db: IDBDatabase): void { + db.createObjectStore(DepartmentStore.STORE_NAME, { keyPath: 'id' }); + } +} diff --git a/packages/calendar/src/extensions/departments/index.ts b/packages/calendar/src/extensions/departments/index.ts new file mode 100644 index 0000000..d50130a --- /dev/null +++ b/packages/calendar/src/extensions/departments/index.ts @@ -0,0 +1,22 @@ +export { DepartmentRenderer } from './DepartmentRenderer'; +export { DepartmentService } from './DepartmentService'; +export { DepartmentStore } from './DepartmentStore'; +export type { IDepartment } from '../../types/CalendarTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IRenderer } from '../../core/IGroupingRenderer'; +import { IStore } from '../../storage/IStore'; +import { IEntityService } from '../../storage/IEntityService'; +import type { IDepartment, ISync } from '../../types/CalendarTypes'; +import { DepartmentStore } from './DepartmentStore'; +import { DepartmentService } from './DepartmentService'; +import { DepartmentRenderer } from './DepartmentRenderer'; + +export function registerDepartments(builder: Builder): void { + builder.registerType(DepartmentStore).as(); + builder.registerType(DepartmentService).as>(); + builder.registerType(DepartmentService).as>(); + builder.registerType(DepartmentService).as(); + builder.registerType(DepartmentRenderer).as(); +} diff --git a/packages/calendar/src/extensions/schedules/ResourceScheduleService.ts b/packages/calendar/src/extensions/schedules/ResourceScheduleService.ts new file mode 100644 index 0000000..a548865 --- /dev/null +++ b/packages/calendar/src/extensions/schedules/ResourceScheduleService.ts @@ -0,0 +1,84 @@ +import { ITimeSlot } from '../../types/ScheduleTypes'; +import { ResourceService } from '../../storage/resources/ResourceService'; +import { ScheduleOverrideService } from './ScheduleOverrideService'; +import { DateService } from '../../core/DateService'; + +/** + * ResourceScheduleService - Get effective schedule for a resource on a date + * + * Logic: + * 1. Check for override on this date + * 2. Fall back to default schedule for the weekday + */ +export class ResourceScheduleService { + constructor( + private resourceService: ResourceService, + private overrideService: ScheduleOverrideService, + private dateService: DateService + ) {} + + /** + * Get effective schedule for a resource on a specific date + * + * @param resourceId - Resource ID + * @param date - Date string "YYYY-MM-DD" + * @returns ITimeSlot or null (fri/closed) + */ + async getScheduleForDate(resourceId: string, date: string): Promise { + // 1. Check for override + const override = await this.overrideService.getOverride(resourceId, date); + if (override) { + return override.schedule; + } + + // 2. Use default schedule for weekday + const resource = await this.resourceService.get(resourceId); + if (!resource || !resource.defaultSchedule) { + return null; + } + + const weekDay = this.dateService.getISOWeekDay(date); + return resource.defaultSchedule[weekDay] || null; + } + + /** + * Get schedules for multiple dates + * + * @param resourceId - Resource ID + * @param dates - Array of date strings "YYYY-MM-DD" + * @returns Map of date -> ITimeSlot | null + */ + async getSchedulesForDates(resourceId: string, dates: string[]): Promise> { + const result = new Map(); + + // Get resource once + const resource = await this.resourceService.get(resourceId); + + // Get all overrides in date range + const overrides = dates.length > 0 + ? await this.overrideService.getByDateRange(resourceId, dates[0], dates[dates.length - 1]) + : []; + + // Build override map + const overrideMap = new Map(overrides.map(o => [o.date, o.schedule])); + + // Resolve each date + for (const date of dates) { + // Check override first + if (overrideMap.has(date)) { + result.set(date, overrideMap.get(date)!); + continue; + } + + // Fall back to default + if (resource?.defaultSchedule) { + const weekDay = this.dateService.getISOWeekDay(date); + result.set(date, resource.defaultSchedule[weekDay] || null); + } else { + result.set(date, null); + } + } + + return result; + } +} diff --git a/packages/calendar/src/extensions/schedules/ScheduleOverrideService.ts b/packages/calendar/src/extensions/schedules/ScheduleOverrideService.ts new file mode 100644 index 0000000..184e354 --- /dev/null +++ b/packages/calendar/src/extensions/schedules/ScheduleOverrideService.ts @@ -0,0 +1,100 @@ +import { IScheduleOverride } from '../../types/ScheduleTypes'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; +import { ScheduleOverrideStore } from './ScheduleOverrideStore'; + +/** + * ScheduleOverrideService - CRUD for schedule overrides + * + * Provides access to date-specific schedule overrides for resources. + */ +export class ScheduleOverrideService { + private context: IndexedDBContext; + + constructor(context: IndexedDBContext) { + this.context = context; + } + + private get db(): IDBDatabase { + return this.context.getDatabase(); + } + + /** + * Get override for a specific resource and date + */ + async getOverride(resourceId: string, date: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readonly'); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index('resourceId_date'); + const request = index.get([resourceId, date]); + + request.onsuccess = () => { + resolve(request.result || null); + }; + + request.onerror = () => { + reject(new Error(`Failed to get override for ${resourceId} on ${date}: ${request.error}`)); + }; + }); + } + + /** + * Get all overrides for a resource + */ + async getByResource(resourceId: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readonly'); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index('resourceId'); + const request = index.getAll(resourceId); + + request.onsuccess = () => { + resolve(request.result || []); + }; + + request.onerror = () => { + reject(new Error(`Failed to get overrides for ${resourceId}: ${request.error}`)); + }; + }); + } + + /** + * Get overrides for a date range + */ + async getByDateRange(resourceId: string, startDate: string, endDate: string): Promise { + const all = await this.getByResource(resourceId); + return all.filter(o => o.date >= startDate && o.date <= endDate); + } + + /** + * Save an override + */ + async save(override: IScheduleOverride): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readwrite'); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.put(override); + + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to save override ${override.id}: ${request.error}`)); + }; + }); + } + + /** + * Delete an override + */ + async delete(id: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], 'readwrite'); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.delete(id); + + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to delete override ${id}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/extensions/schedules/ScheduleOverrideStore.ts b/packages/calendar/src/extensions/schedules/ScheduleOverrideStore.ts new file mode 100644 index 0000000..0fe4f09 --- /dev/null +++ b/packages/calendar/src/extensions/schedules/ScheduleOverrideStore.ts @@ -0,0 +1,21 @@ +import { IStore } from '../../storage/IStore'; + +/** + * ScheduleOverrideStore - IndexedDB ObjectStore for schedule overrides + * + * Stores date-specific schedule overrides for resources. + * Indexes: resourceId, date, compound (resourceId + date) + */ +export class ScheduleOverrideStore implements IStore { + static readonly STORE_NAME = 'scheduleOverrides'; + readonly storeName = ScheduleOverrideStore.STORE_NAME; + + create(db: IDBDatabase): void { + const store = db.createObjectStore(ScheduleOverrideStore.STORE_NAME, { keyPath: 'id' }); + + store.createIndex('resourceId', 'resourceId', { unique: false }); + store.createIndex('date', 'date', { unique: false }); + store.createIndex('resourceId_date', ['resourceId', 'date'], { unique: true }); + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + } +} diff --git a/packages/calendar/src/extensions/schedules/index.ts b/packages/calendar/src/extensions/schedules/index.ts new file mode 100644 index 0000000..e8a94f0 --- /dev/null +++ b/packages/calendar/src/extensions/schedules/index.ts @@ -0,0 +1,17 @@ +export { ScheduleOverrideService } from './ScheduleOverrideService'; +export { ScheduleOverrideStore } from './ScheduleOverrideStore'; +export { ResourceScheduleService } from './ResourceScheduleService'; +export type { IScheduleOverride, ITimeSlot, IWeekSchedule, WeekDay } from '../../types/ScheduleTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IStore } from '../../storage/IStore'; +import { ScheduleOverrideStore } from './ScheduleOverrideStore'; +import { ScheduleOverrideService } from './ScheduleOverrideService'; +import { ResourceScheduleService } from './ResourceScheduleService'; + +export function registerSchedules(builder: Builder): void { + builder.registerType(ScheduleOverrideStore).as(); + builder.registerType(ScheduleOverrideService).as(); + builder.registerType(ResourceScheduleService).as(); +} diff --git a/packages/calendar/src/extensions/teams/TeamRenderer.ts b/packages/calendar/src/extensions/teams/TeamRenderer.ts new file mode 100644 index 0000000..090d8c9 --- /dev/null +++ b/packages/calendar/src/extensions/teams/TeamRenderer.ts @@ -0,0 +1,25 @@ +import { BaseGroupingRenderer, IGroupingRendererConfig } from '../../core/BaseGroupingRenderer'; +import { TeamService } from './TeamService'; +import { ITeam } from '../../types/CalendarTypes'; + +export class TeamRenderer extends BaseGroupingRenderer { + readonly type = 'team'; + + protected readonly config: IGroupingRendererConfig = { + elementTag: 'swp-team-header', + idAttribute: 'teamId', + colspanVar: '--team-cols' + }; + + constructor(private teamService: TeamService) { + super(); + } + + protected getEntities(ids: string[]): Promise { + return this.teamService.getByIds(ids); + } + + protected getDisplayName(entity: ITeam): string { + return entity.name; + } +} diff --git a/packages/calendar/src/extensions/teams/TeamService.ts b/packages/calendar/src/extensions/teams/TeamService.ts new file mode 100644 index 0000000..655dd1f --- /dev/null +++ b/packages/calendar/src/extensions/teams/TeamService.ts @@ -0,0 +1,44 @@ +import { ITeam, EntityType, IEventBus } from '../../types/CalendarTypes'; +import { TeamStore } from './TeamStore'; +import { BaseEntityService } from '../../storage/BaseEntityService'; +import { IndexedDBContext } from '../../storage/IndexedDBContext'; + +/** + * TeamService - CRUD operations for teams in IndexedDB + * + * Teams define which resources belong together for hierarchical grouping. + * Extends BaseEntityService for standard entity operations. + */ +export class TeamService extends BaseEntityService { + readonly storeName = TeamStore.STORE_NAME; + readonly entityType: EntityType = 'Team'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + /** + * Get teams by IDs + */ + async getByIds(ids: string[]): Promise { + if (ids.length === 0) return []; + const results = await Promise.all(ids.map(id => this.get(id))); + return results.filter((t): t is ITeam => t !== null); + } + + /** + * Build reverse lookup: resourceId → teamId + */ + async buildResourceToTeamMap(): Promise> { + const teams = await this.getAll(); + const map: Record = {}; + + for (const team of teams) { + for (const resourceId of team.resourceIds) { + map[resourceId] = team.id; + } + } + + return map; + } +} diff --git a/packages/calendar/src/extensions/teams/TeamStore.ts b/packages/calendar/src/extensions/teams/TeamStore.ts new file mode 100644 index 0000000..af515e0 --- /dev/null +++ b/packages/calendar/src/extensions/teams/TeamStore.ts @@ -0,0 +1,13 @@ +import { IStore } from '../../storage/IStore'; + +/** + * TeamStore - IndexedDB ObjectStore definition for teams + */ +export class TeamStore implements IStore { + static readonly STORE_NAME = 'teams'; + readonly storeName = TeamStore.STORE_NAME; + + create(db: IDBDatabase): void { + db.createObjectStore(TeamStore.STORE_NAME, { keyPath: 'id' }); + } +} diff --git a/packages/calendar/src/extensions/teams/index.ts b/packages/calendar/src/extensions/teams/index.ts new file mode 100644 index 0000000..f9d231e --- /dev/null +++ b/packages/calendar/src/extensions/teams/index.ts @@ -0,0 +1,22 @@ +export { TeamRenderer } from './TeamRenderer'; +export { TeamService } from './TeamService'; +export { TeamStore } from './TeamStore'; +export type { ITeam } from '../../types/CalendarTypes'; + +// DI registration helper +import type { Builder } from '@novadi/core'; +import { IRenderer } from '../../core/IGroupingRenderer'; +import { IStore } from '../../storage/IStore'; +import { IEntityService } from '../../storage/IEntityService'; +import type { ITeam, ISync } from '../../types/CalendarTypes'; +import { TeamStore } from './TeamStore'; +import { TeamService } from './TeamService'; +import { TeamRenderer } from './TeamRenderer'; + +export function registerTeams(builder: Builder): void { + builder.registerType(TeamStore).as(); + builder.registerType(TeamService).as>(); + builder.registerType(TeamService).as>(); + builder.registerType(TeamService).as(); + builder.registerType(TeamRenderer).as(); +} diff --git a/packages/calendar/src/features/date/DateRenderer.ts b/packages/calendar/src/features/date/DateRenderer.ts new file mode 100644 index 0000000..4f1cfad --- /dev/null +++ b/packages/calendar/src/features/date/DateRenderer.ts @@ -0,0 +1,68 @@ +import { IRenderer, IRenderContext } from '../../core/IGroupingRenderer'; +import { DateService } from '../../core/DateService'; + +export class DateRenderer implements IRenderer { + readonly type = 'date'; + + constructor(private dateService: DateService) {} + + render(context: IRenderContext): void { + const dates = context.filter['date'] || []; + const resourceIds = context.filter['resource'] || []; + + // Check if date headers should be hidden (e.g., in day view) + const dateGrouping = context.groupings?.find(g => g.type === 'date'); + const hideHeader = dateGrouping?.hideHeader === true; + + // Render dates for HVER resource (eller 1 gang hvis ingen resources) + const iterations = resourceIds.length || 1; + let columnCount = 0; + + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; // undefined hvis ingen resources + + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + + // Build columnKey for uniform identification + const segments: Record = { date: dateStr }; + if (resourceId) segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + + // Header + const header = document.createElement('swp-day-header'); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = 'true'; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, 'short')} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + + // Column + const column = document.createElement('swp-day-column'); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ''; + context.columnContainer.appendChild(column); + + columnCount++; + } + } + + // Set grid columns on container + const container = context.columnContainer.closest('swp-calendar-container'); + if (container) { + (container as HTMLElement).style.setProperty('--grid-columns', String(columnCount)); + } + } +} diff --git a/packages/calendar/src/features/date/index.ts b/packages/calendar/src/features/date/index.ts new file mode 100644 index 0000000..7bf37b3 --- /dev/null +++ b/packages/calendar/src/features/date/index.ts @@ -0,0 +1 @@ +export { DateRenderer } from './DateRenderer'; diff --git a/packages/calendar/src/features/event/EventLayoutEngine.ts b/packages/calendar/src/features/event/EventLayoutEngine.ts new file mode 100644 index 0000000..0b10905 --- /dev/null +++ b/packages/calendar/src/features/event/EventLayoutEngine.ts @@ -0,0 +1,279 @@ +/** + * EventLayoutEngine - Simplified stacking/grouping algorithm + * + * Supports two layout modes: + * - GRID: Events starting at same time rendered side-by-side + * - STACKING: Overlapping events with margin-left offset (15px per level) + * + * No prev/next chains, single-pass greedy algorithm + */ + +import { ICalendarEvent } from '../../types/CalendarTypes'; +import { IGridConfig } from '../../core/IGridConfig'; +import { calculateEventPosition } from '../../utils/PositionUtils'; +import { IColumnLayout, IGridGroupLayout, IStackedEventLayout } from './EventLayoutTypes'; + +/** + * Check if two events overlap (strict - touching at boundary = NOT overlapping) + * This matches Scenario 8: end===start is NOT overlap + */ +export function eventsOverlap(a: ICalendarEvent, b: ICalendarEvent): boolean { + return a.start < b.end && a.end > b.start; +} + +/** + * Check if two events are within threshold for grid grouping. + * This includes: + * 1. Start-to-start: Events start within threshold of each other + * 2. End-to-start: One event starts within threshold before another ends + */ +function eventsWithinThreshold(a: ICalendarEvent, b: ICalendarEvent, thresholdMinutes: number): boolean { + const thresholdMs = thresholdMinutes * 60 * 1000; + + // Start-to-start: both events start within threshold + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) return true; + + // End-to-start: one event starts within threshold before the other ends + // B starts within threshold before A ends + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) return true; + + // A starts within threshold before B ends + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) return true; + + return false; +} + +/** + * Check if all events in a group start within threshold of each other + */ +function allStartWithinThreshold(events: ICalendarEvent[], thresholdMinutes: number): boolean { + if (events.length <= 1) return true; + + // Find earliest and latest start times + let earliest = events[0].start.getTime(); + let latest = events[0].start.getTime(); + + for (const event of events) { + const time = event.start.getTime(); + if (time < earliest) earliest = time; + if (time > latest) latest = time; + } + + const diffMinutes = (latest - earliest) / (1000 * 60); + return diffMinutes <= thresholdMinutes; +} + +/** + * Find groups of overlapping events (connected by overlap chain) + * Events are grouped if they overlap with any event in the group + */ +function findOverlapGroups(events: ICalendarEvent[]): ICalendarEvent[][] { + if (events.length === 0) return []; + + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = new Set(); + const groups: ICalendarEvent[][] = []; + + for (const event of sorted) { + if (used.has(event.id)) continue; + + // Start a new group with this event + const group: ICalendarEvent[] = [event]; + used.add(event.id); + + // Expand group by finding all connected events (via overlap) + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) continue; + + // Check if candidate overlaps with any event in group + const connects = group.some(member => eventsOverlap(member, candidate)); + + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + + groups.push(group); + } + + return groups; +} + +/** + * Find grid candidates within a group - events connected via threshold chain + * Uses V1 logic: events are connected if within threshold (no overlap requirement) + */ +function findGridCandidates( + events: ICalendarEvent[], + thresholdMinutes: number +): ICalendarEvent[][] { + if (events.length === 0) return []; + + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = new Set(); + const groups: ICalendarEvent[][] = []; + + for (const event of sorted) { + if (used.has(event.id)) continue; + + const group: ICalendarEvent[] = [event]; + used.add(event.id); + + // Expand by threshold chain (V1 logic: no overlap requirement, just threshold) + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) continue; + + const connects = group.some(member => + eventsWithinThreshold(member, candidate, thresholdMinutes) + ); + + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + + groups.push(group); + } + + return groups; +} + +/** + * Calculate stack levels for overlapping events using greedy algorithm + * For each event: level = max(overlapping already-processed events) + 1 + */ +function calculateStackLevels(events: ICalendarEvent[]): Map { + const levels = new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + + for (const event of sorted) { + let maxOverlappingLevel = -1; + + // Find max level among overlapping events already processed + for (const [id, level] of levels) { + const other = events.find(e => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + + levels.set(event.id, maxOverlappingLevel + 1); + } + + return levels; +} + +/** + * Allocate events to columns for GRID layout using greedy algorithm + * Non-overlapping events can share a column to minimize total columns + */ +function allocateColumns(events: ICalendarEvent[]): ICalendarEvent[][] { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns: ICalendarEvent[][] = []; + + for (const event of sorted) { + // Find first column where event doesn't overlap with existing events + let placed = false; + for (const column of columns) { + const canFit = !column.some(e => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + + // No suitable column found, create new one + if (!placed) { + columns.push([event]); + } + } + + return columns; +} + +/** + * Main entry point: Calculate complete layout for a column's events + * + * Algorithm: + * 1. Find overlap groups (events connected by overlap chain) + * 2. For each overlap group, find grid candidates (events within threshold chain) + * 3. If all events in overlap group form a single grid candidate → GRID mode + * 4. Otherwise → STACKING mode with calculated levels + */ +export function calculateColumnLayout( + events: ICalendarEvent[], + config: IGridConfig +): IColumnLayout { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + + const result: IColumnLayout = { + grids: [], + stacked: [] + }; + + if (events.length === 0) return result; + + // Find all overlapping event groups + const overlapGroups = findOverlapGroups(events); + + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + // Single event - no grouping needed + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + + // Within this overlap group, find grid candidates (threshold-connected subgroups) + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + + // Check if the ENTIRE overlap group forms a single grid candidate + // This happens when all events are connected via threshold chain + const largestGridCandidate = gridSubgroups.reduce((max, g) => + g.length > max.length ? g : max, gridSubgroups[0]); + + if (largestGridCandidate.length === overlapGroup.length) { + // All events in overlap group are connected via threshold chain → GRID mode + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => + e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + // Not all events connected via threshold → STACKING mode + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + + return result; +} diff --git a/packages/calendar/src/features/event/EventLayoutTypes.ts b/packages/calendar/src/features/event/EventLayoutTypes.ts new file mode 100644 index 0000000..c887eaf --- /dev/null +++ b/packages/calendar/src/features/event/EventLayoutTypes.ts @@ -0,0 +1,35 @@ +import { ICalendarEvent } from '../../types/CalendarTypes'; + +/** + * Stack link metadata stored on event elements + * Simplified from V1: No prev/next chains - only stackLevel needed for rendering + */ +export interface IStackLink { + stackLevel: number; +} + +/** + * Layout result for a stacked event (overlapping events with margin offset) + */ +export interface IStackedEventLayout { + event: ICalendarEvent; + stackLevel: number; +} + +/** + * Layout result for a grid group (simultaneous events side-by-side) + */ +export interface IGridGroupLayout { + events: ICalendarEvent[]; + columns: ICalendarEvent[][]; // Events grouped by column (non-overlapping within column) + stackLevel: number; // Stack level for entire group (if nested in another event) + position: { top: number }; // Top position of earliest event in pixels +} + +/** + * Complete layout result for a column's events + */ +export interface IColumnLayout { + grids: IGridGroupLayout[]; + stacked: IStackedEventLayout[]; +} diff --git a/packages/calendar/src/features/event/EventRenderer.ts b/packages/calendar/src/features/event/EventRenderer.ts new file mode 100644 index 0000000..6cc1b96 --- /dev/null +++ b/packages/calendar/src/features/event/EventRenderer.ts @@ -0,0 +1,434 @@ +import { ICalendarEvent, IEventBus, IEventUpdatedPayload } from '../../types/CalendarTypes'; +import { EventService } from '../../storage/events/EventService'; +import { DateService } from '../../core/DateService'; +import { IGridConfig } from '../../core/IGridConfig'; +import { calculateEventPosition, snapToGrid, pixelsToMinutes } from '../../utils/PositionUtils'; +import { CoreEvents } from '../../constants/CoreEvents'; +import { IDragColumnChangePayload, IDragMovePayload, IDragEndPayload, IDragLeaveHeaderPayload } from '../../types/DragTypes'; +import { calculateColumnLayout } from './EventLayoutEngine'; +import { IGridGroupLayout } from './EventLayoutTypes'; +import { FilterTemplate } from '../../core/FilterTemplate'; + +/** + * EventRenderer - Renders calendar events to the DOM + * + * CLEAN approach: + * - Only data-id attribute on event element + * - innerHTML contains only visible content + * - Event data retrieved via EventService when needed + */ +export class EventRenderer { + private container: HTMLElement | null = null; + + constructor( + private eventService: EventService, + private dateService: DateService, + private gridConfig: IGridConfig, + private eventBus: IEventBus + ) { + this.setupListeners(); + } + + /** + * Setup listeners for drag-drop and update events + */ + private setupListeners(): void { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = (e as CustomEvent).detail; + this.handleColumnChange(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = (e as CustomEvent).detail; + this.updateDragTimestamp(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = (e as CustomEvent).detail; + this.handleEventUpdated(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragEnd(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragLeaveHeader(payload); + }); + } + + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + private handleDragEnd(payload: IDragEndPayload): void { + if (payload.target === 'header') { + // Event was dropped in header drawer - remove from grid + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + + /** + * Handle header item leaving header - create swp-event in grid + */ + private handleDragLeaveHeader(payload: IDragLeaveHeaderPayload): void { + // Only handle when source is header (header item dragged to grid) + if (payload.source !== 'header') return; + if (!payload.targetColumn || !payload.start || !payload.end) return; + + // Turn header item into ghost (stays visible but faded) + if (payload.element) { + payload.element.classList.add('drag-ghost'); + payload.element.style.opacity = '0.3'; + payload.element.style.pointerEvents = 'none'; + } + + // Create event object from header item data + const event: ICalendarEvent = { + id: payload.eventId, + title: payload.title || '', + description: '', + start: payload.start, + end: payload.end, + type: 'customer', + allDay: false, + syncStatus: 'pending' + }; + + // Create swp-event element using existing method + const element = this.createEventElement(event); + + // Add to target column + let eventsLayer = payload.targetColumn.querySelector('swp-events-layer'); + if (!eventsLayer) { + eventsLayer = document.createElement('swp-events-layer'); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + + // Mark as dragging so DragDropManager can continue with it + element.classList.add('dragging'); + } + + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + private async handleEventUpdated(payload: IEventUpdatedPayload): Promise { + // Re-render source column (if different from target) + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + + // Re-render target column + await this.rerenderColumn(payload.targetColumnKey); + } + + /** + * Re-render a single column with fresh data from IndexedDB + */ + private async rerenderColumn(columnKey: string): Promise { + const column = this.findColumn(columnKey); + if (!column) return; + + // Read date and resourceId directly from column attributes (columnKey is opaque) + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + + if (!date) return; + + // Get date range for this day + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + + // Fetch events from IndexedDB + const events = resourceId + ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) + : await this.eventService.getByDateRange(startDate, endDate); + + // Filter to timed events and match date exactly + const timedEvents = events.filter(event => + !event.allDay && this.dateService.getDateKey(event.start) === date + ); + + // Get or create events layer + let eventsLayer = column.querySelector('swp-events-layer'); + if (!eventsLayer) { + eventsLayer = document.createElement('swp-events-layer'); + column.appendChild(eventsLayer); + } + + // Clear existing events + eventsLayer.innerHTML = ''; + + // Calculate layout with stacking/grouping + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + + // Render GRID groups + layout.grids.forEach(grid => { + const groupEl = this.renderGridGroup(grid); + eventsLayer!.appendChild(groupEl); + }); + + // Render STACKED events + layout.stacked.forEach(item => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer!.appendChild(eventEl); + }); + } + + /** + * Find a column element by columnKey + */ + private findColumn(columnKey: string): HTMLElement | null { + if (!this.container) return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`) as HTMLElement; + } + + /** + * Handle event moving to a new column during drag + */ + private handleColumnChange(payload: IDragColumnChangePayload): void { + const eventsLayer = payload.newColumn.querySelector('swp-events-layer'); + if (!eventsLayer) return; + + // Move element to new column + eventsLayer.appendChild(payload.element); + + // Preserve Y position + payload.element.style.top = `${payload.currentY}px`; + } + + /** + * Update timestamp display during drag (snapped to grid) + */ + private updateDragTimestamp(payload: IDragMovePayload): void { + const timeEl = payload.element.querySelector('swp-event-time'); + if (!timeEl) return; + + // Snap position to grid interval + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + + // Calculate new start time + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = (this.gridConfig.dayStartHour * 60) + minutesFromGridStart; + + // Keep original duration (from element height) + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + + // Create Date objects for consistent formatting via DateService + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + + /** + * Convert minutes since midnight to a Date object (today) + */ + private minutesToDate(minutes: number): Date { + const date = new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container: HTMLElement, filter: Record, filterTemplate: FilterTemplate): Promise { + // Store container reference for later re-renders + this.container = container; + + const visibleDates = filter['date'] || []; + + if (visibleDates.length === 0) return; + + // Get date range for query + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + + // Fetch events from IndexedDB + const events = await this.eventService.getByDateRange(startDate, endDate); + + // Find day columns + const dayColumns = container.querySelector('swp-day-columns'); + if (!dayColumns) return; + + const columns = dayColumns.querySelectorAll('swp-day-column'); + + // Render events into each column based on FilterTemplate matching + columns.forEach(column => { + const columnEl = column as HTMLElement; + + // Use FilterTemplate for matching - only fields in template are checked + const columnEvents = events.filter(event => filterTemplate.matches(event, columnEl)); + + // Get or create events layer + let eventsLayer = column.querySelector('swp-events-layer'); + if (!eventsLayer) { + eventsLayer = document.createElement('swp-events-layer'); + column.appendChild(eventsLayer); + } + + // Clear existing events + eventsLayer.innerHTML = ''; + + // Filter to timed events only + const timedEvents = columnEvents.filter(event => !event.allDay); + + // Calculate layout with stacking/grouping + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + + // Render GRID groups (simultaneous events side-by-side) + layout.grids.forEach(grid => { + const groupEl = this.renderGridGroup(grid); + eventsLayer!.appendChild(groupEl); + }); + + // Render STACKED events (overlapping with margin offset) + layout.stacked.forEach(item => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer!.appendChild(eventEl); + }); + }); + } + + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + private createEventElement(event: ICalendarEvent): HTMLElement { + const element = document.createElement('swp-event'); + + // Data attributes for SwpEvent compatibility + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + + // Calculate position + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + + // Color class based on event type + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + + // Visible content only + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ''} + `; + + return element; + } + + /** + * Get color class based on metadata.color or event type + */ + private getColorClass(event: ICalendarEvent): string { + // Check metadata.color first + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + + // Fallback to type-based color + const typeColors: Record = { + 'customer': 'is-blue', + 'vacation': 'is-green', + 'break': 'is-amber', + 'meeting': 'is-purple', + 'blocked': 'is-red' + }; + return typeColors[event.type] || 'is-blue'; + } + + /** + * Escape HTML to prevent XSS + */ + private escapeHtml(text: string): string { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + private renderGridGroup(layout: IGridGroupLayout): HTMLElement { + const group = document.createElement('swp-event-group'); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + + // Stack level styling for entire group (if nested in another event) + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + + // Calculate the height needed for the group (tallest event) + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + + // Create wrapper div for each column + layout.columns.forEach(columnEvents => { + const wrapper = document.createElement('div'); + wrapper.style.position = 'relative'; + + columnEvents.forEach(event => { + const eventEl = this.createEventElement(event); + // Position relative to group top + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = 'absolute'; + eventEl.style.left = '0'; + eventEl.style.right = '0'; + wrapper.appendChild(eventEl); + }); + + group.appendChild(wrapper); + }); + + return group; + } + + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + private renderStackedEvent(event: ICalendarEvent, stackLevel: number): HTMLElement { + const element = this.createEventElement(event); + + // Add stack metadata for drag-drop and other features + element.dataset.stackLink = JSON.stringify({ stackLevel }); + + // Visual styling based on stack level + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + + return element; + } +} diff --git a/packages/calendar/src/features/event/index.ts b/packages/calendar/src/features/event/index.ts new file mode 100644 index 0000000..7b8f118 --- /dev/null +++ b/packages/calendar/src/features/event/index.ts @@ -0,0 +1 @@ +export { EventRenderer } from './EventRenderer'; diff --git a/packages/calendar/src/features/headerdrawer/HeaderDrawerLayoutEngine.ts b/packages/calendar/src/features/headerdrawer/HeaderDrawerLayoutEngine.ts new file mode 100644 index 0000000..b407a58 --- /dev/null +++ b/packages/calendar/src/features/headerdrawer/HeaderDrawerLayoutEngine.ts @@ -0,0 +1,135 @@ +/** + * HeaderDrawerLayoutEngine - Calculates row placement for header items + * + * Prevents visual overlap by assigning items to different rows when + * they occupy the same columns. Uses a track-based algorithm similar + * to V1's AllDayLayoutEngine. + * + * Each row can hold multiple items as long as they don't overlap in columns. + * When an item spans columns that are already occupied, it's placed in the + * next available row. + */ + +export interface IHeaderItemLayout { + itemId: string; + gridArea: string; // "row / col-start / row+1 / col-end" + startColumn: number; + endColumn: number; + row: number; +} + +export interface IHeaderItemInput { + id: string; + columnStart: number; // 0-based column index + columnEnd: number; // 0-based end column (inclusive) +} + +export class HeaderDrawerLayoutEngine { + private tracks: boolean[][] = []; + private columnCount: number; + + constructor(columnCount: number) { + this.columnCount = columnCount; + this.reset(); + } + + /** + * Reset tracks for new layout calculation + */ + reset(): void { + this.tracks = [new Array(this.columnCount).fill(false)]; + } + + /** + * Calculate layout for all items + * Items should be sorted by start column for optimal packing + */ + calculateLayout(items: IHeaderItemInput[]): IHeaderItemLayout[] { + this.reset(); + const layouts: IHeaderItemLayout[] = []; + + for (const item of items) { + const row = this.findAvailableRow(item.columnStart, item.columnEnd); + + // Mark columns as occupied in this row + for (let col = item.columnStart; col <= item.columnEnd; col++) { + this.tracks[row][col] = true; + } + + // gridArea format: "row / col-start / row+1 / col-end" + // CSS grid uses 1-based indices + layouts.push({ + itemId: item.id, + gridArea: `${row + 1} / ${item.columnStart + 1} / ${row + 2} / ${item.columnEnd + 2}`, + startColumn: item.columnStart, + endColumn: item.columnEnd, + row: row + 1 // 1-based for CSS + }); + } + + return layouts; + } + + /** + * Calculate layout for a single new item + * Useful for real-time drag operations + */ + calculateSingleLayout(item: IHeaderItemInput): IHeaderItemLayout { + const row = this.findAvailableRow(item.columnStart, item.columnEnd); + + // Mark columns as occupied + for (let col = item.columnStart; col <= item.columnEnd; col++) { + this.tracks[row][col] = true; + } + + return { + itemId: item.id, + gridArea: `${row + 1} / ${item.columnStart + 1} / ${row + 2} / ${item.columnEnd + 2}`, + startColumn: item.columnStart, + endColumn: item.columnEnd, + row: row + 1 + }; + } + + /** + * Find the first row where all columns in range are available + */ + private findAvailableRow(startCol: number, endCol: number): number { + for (let row = 0; row < this.tracks.length; row++) { + if (this.isRowAvailable(row, startCol, endCol)) { + return row; + } + } + + // Add new row if all existing rows are occupied + this.tracks.push(new Array(this.columnCount).fill(false)); + return this.tracks.length - 1; + } + + /** + * Check if columns in range are all available in given row + */ + private isRowAvailable(row: number, startCol: number, endCol: number): boolean { + for (let col = startCol; col <= endCol; col++) { + if (this.tracks[row][col]) { + return false; + } + } + return true; + } + + /** + * Get the number of rows currently in use + */ + getRowCount(): number { + return this.tracks.length; + } + + /** + * Update column count (e.g., when view changes) + */ + setColumnCount(count: number): void { + this.columnCount = count; + this.reset(); + } +} diff --git a/packages/calendar/src/features/headerdrawer/HeaderDrawerRenderer.ts b/packages/calendar/src/features/headerdrawer/HeaderDrawerRenderer.ts new file mode 100644 index 0000000..1b528cd --- /dev/null +++ b/packages/calendar/src/features/headerdrawer/HeaderDrawerRenderer.ts @@ -0,0 +1,419 @@ +import { IEventBus, ICalendarEvent } from '../../types/CalendarTypes'; +import { IGridConfig } from '../../core/IGridConfig'; +import { CoreEvents } from '../../constants/CoreEvents'; +import { HeaderDrawerManager } from '../../core/HeaderDrawerManager'; +import { EventService } from '../../storage/events/EventService'; +import { DateService } from '../../core/DateService'; +import { FilterTemplate } from '../../core/FilterTemplate'; +import { + IDragEnterHeaderPayload, + IDragMoveHeaderPayload, + IDragLeaveHeaderPayload, + IDragEndPayload +} from '../../types/DragTypes'; + +/** + * Layout information for a header item + */ +interface IHeaderItemLayout { + event: ICalendarEvent; + columnKey: string; // Opaque column identifier + row: number; // 1-indexed + colStart: number; // 1-indexed + colEnd: number; // exclusive +} + +/** + * HeaderDrawerRenderer - Handles rendering of items in the header drawer + * + * Listens to drag events from DragDropManager and creates/manages + * swp-header-item elements in the header drawer. + * + * Uses subgrid for column alignment with parent swp-calendar-header. + * Position items via gridArea for explicit row/column placement. + */ +export class HeaderDrawerRenderer { + private currentItem: HTMLElement | null = null; + private container: HTMLElement | null = null; + private sourceElement: HTMLElement | null = null; + private wasExpandedBeforeDrag = false; + private filterTemplate: FilterTemplate | null = null; + + constructor( + private eventBus: IEventBus, + private gridConfig: IGridConfig, + private headerDrawerManager: HeaderDrawerManager, + private eventService: EventService, + private dateService: DateService + ) { + this.setupListeners(); + } + + /** + * Render allDay events into the header drawer with row stacking + * @param filterTemplate - Template for matching events to columns + */ + async render(container: HTMLElement, filter: Record, filterTemplate: FilterTemplate): Promise { + // Store filterTemplate for buildColumnKeyFromEvent + this.filterTemplate = filterTemplate; + + const drawer = container.querySelector('swp-header-drawer'); + if (!drawer) return; + + const visibleDates = filter['date'] || []; + if (visibleDates.length === 0) return; + + // Get column keys from DOM for correct multi-resource positioning + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) return; + + // Fetch events for date range + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + + const events = await this.eventService.getByDateRange(startDate, endDate); + + // Filter to allDay events only (allDay !== false) + const allDayEvents = events.filter(event => event.allDay !== false); + + // Clear existing items + drawer.innerHTML = ''; + + if (allDayEvents.length === 0) return; + + // Calculate layout with row stacking using columnKeys + const layouts = this.calculateLayout(allDayEvents, visibleColumnKeys); + const rowCount = Math.max(1, ...layouts.map(l => l.row)); + + // Render each item with layout + layouts.forEach(layout => { + const item = this.createHeaderItem(layout); + drawer.appendChild(item); + }); + + // Expand drawer to fit all rows + this.headerDrawerManager.expandToRows(rowCount); + } + + /** + * Create a header item element from layout + */ + private createHeaderItem(layout: IHeaderItemLayout): HTMLElement { + const { event, columnKey, row, colStart, colEnd } = layout; + + const item = document.createElement('swp-header-item'); + item.dataset.eventId = event.id; + item.dataset.itemType = 'event'; + item.dataset.start = event.start.toISOString(); + item.dataset.end = event.end.toISOString(); + item.dataset.columnKey = columnKey; + item.textContent = event.title; + + // Color class + const colorClass = this.getColorClass(event); + if (colorClass) item.classList.add(colorClass); + + // Grid position from layout + item.style.gridArea = `${row} / ${colStart} / ${row + 1} / ${colEnd}`; + + return item; + } + + /** + * Calculate layout for all events with row stacking + * Uses track-based algorithm to find available rows for overlapping events + */ + private calculateLayout(events: ICalendarEvent[], visibleColumnKeys: string[]): IHeaderItemLayout[] { + // tracks[row][col] = occupied + const tracks: boolean[][] = [new Array(visibleColumnKeys.length).fill(false)]; + const layouts: IHeaderItemLayout[] = []; + + for (const event of events) { + // Build columnKey from event fields (only place we need to construct it) + const columnKey = this.buildColumnKeyFromEvent(event); + const startCol = visibleColumnKeys.indexOf(columnKey); + const endColumnKey = this.buildColumnKeyFromEvent(event, event.end); + const endCol = visibleColumnKeys.indexOf(endColumnKey); + if (startCol === -1 && endCol === -1) continue; + + // Clamp til synlige kolonner + const colStart = Math.max(0, startCol); + const colEnd = (endCol !== -1 ? endCol : visibleColumnKeys.length - 1) + 1; + + // Find ledig række + const row = this.findAvailableRow(tracks, colStart, colEnd); + + // Marker som optaget + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + + layouts.push({ event, columnKey, row: row + 1, colStart: colStart + 1, colEnd: colEnd + 1 }); + } + + return layouts; + } + + /** + * Build columnKey from event using FilterTemplate + * Uses the same template that columns use for matching + */ + private buildColumnKeyFromEvent(event: ICalendarEvent, date?: Date): string { + if (!this.filterTemplate) { + // Fallback if no template - shouldn't happen in normal flow + const dateStr = this.dateService.getDateKey(date || event.start); + return dateStr; + } + + // For multi-day events, we need to override the date in the event + if (date && date.getTime() !== event.start.getTime()) { + // Create temporary event with overridden start for key generation + const tempEvent = { ...event, start: date }; + return this.filterTemplate.buildKeyFromEvent(tempEvent); + } + + return this.filterTemplate.buildKeyFromEvent(event); + } + + /** + * Find available row for event spanning columns [colStart, colEnd) + */ + private findAvailableRow(tracks: boolean[][], colStart: number, colEnd: number): number { + for (let row = 0; row < tracks.length; row++) { + let available = true; + for (let c = colStart; c < colEnd; c++) { + if (tracks[row][c]) { available = false; break; } + } + if (available) return row; + } + // Ny række + tracks.push(new Array(tracks[0].length).fill(false)); + return tracks.length - 1; + } + + /** + * Get color class based on event metadata or type + */ + private getColorClass(event: ICalendarEvent): string { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors: Record = { + 'customer': 'is-blue', + 'vacation': 'is-green', + 'break': 'is-amber', + 'meeting': 'is-purple', + 'blocked': 'is-red' + }; + return typeColors[event.type] || 'is-blue'; + } + + /** + * Setup event listeners for drag events + */ + private setupListeners(): void { + this.eventBus.on(CoreEvents.EVENT_DRAG_ENTER_HEADER, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragEnter(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE_HEADER, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragMove(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragLeave(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = (e as CustomEvent).detail; + this.handleDragEnd(payload); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => { + this.cleanup(); + }); + } + + /** + * Handle drag entering header zone - create preview item + */ + private handleDragEnter(payload: IDragEnterHeaderPayload): void { + this.container = document.querySelector('swp-header-drawer'); + if (!this.container) return; + + // Remember if drawer was already expanded + this.wasExpandedBeforeDrag = this.headerDrawerManager.isExpanded(); + + // Expand to at least 1 row if collapsed, otherwise keep current height + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.expandToRows(1); + } + + // Store reference to source element + this.sourceElement = payload.element; + + // Create header item + const item = document.createElement('swp-header-item'); + item.dataset.eventId = payload.eventId; + item.dataset.itemType = payload.itemType; + item.dataset.duration = String(payload.duration); + item.dataset.columnKey = payload.sourceColumnKey; + item.textContent = payload.title; + + // Apply color class if present + if (payload.colorClass) { + item.classList.add(payload.colorClass); + } + + // Add dragging state + item.classList.add('dragging'); + + // Initial placement (duration determines column span) + // gridArea format: "row / col-start / row+1 / col-end" + const col = payload.sourceColumnIndex + 1; + const endCol = col + payload.duration; + item.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + + this.container.appendChild(item); + this.currentItem = item; + + // Hide original element while in header + payload.element.style.visibility = 'hidden'; + } + + /** + * Handle drag moving within header - update column position + */ + private handleDragMove(payload: IDragMoveHeaderPayload): void { + if (!this.currentItem) return; + + // Update column position + const col = payload.columnIndex + 1; + const duration = parseInt(this.currentItem.dataset.duration || '1', 10); + const endCol = col + duration; + + this.currentItem.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + + // Update columnKey to new position + this.currentItem.dataset.columnKey = payload.columnKey; + } + + /** + * Handle drag leaving header - cleanup for grid→header drag only + */ + private handleDragLeave(payload: IDragLeaveHeaderPayload): void { + // Only cleanup for grid→header drag (when grid event leaves header back to grid) + // For header→grid drag, the header item stays as ghost until drop + if (payload.source === 'grid') { + this.cleanup(); + } + // For header source, do nothing - ghost stays until EVENT_DRAG_END + } + + /** + * Handle drag end - finalize based on drop target + */ + private handleDragEnd(payload: IDragEndPayload): void { + if (payload.target === 'header') { + // Grid→Header: Finalize the header item (it stays in header) + if (this.currentItem) { + this.currentItem.classList.remove('dragging'); + this.recalculateDrawerLayout(); + this.currentItem = null; + this.sourceElement = null; + } + } else { + // Header→Grid: Remove ghost header item and recalculate + const ghost = document.querySelector(`swp-header-item.drag-ghost[data-event-id="${payload.swpEvent.eventId}"]`); + ghost?.remove(); + this.recalculateDrawerLayout(); + } + } + + /** + * Recalculate layout for all items currently in the drawer + * Called after drop to reposition items and adjust height + */ + private recalculateDrawerLayout(): void { + const drawer = document.querySelector('swp-header-drawer'); + if (!drawer) return; + + const items = Array.from(drawer.querySelectorAll('swp-header-item')) as HTMLElement[]; + if (items.length === 0) return; + + // Get visible column keys for correct multi-resource positioning + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) return; + + // Build layout data from DOM items - use columnKey directly (opaque matching) + const itemData = items.map(item => ({ + element: item, + columnKey: item.dataset.columnKey || '', + duration: parseInt(item.dataset.duration || '1', 10) + })); + + // Calculate new layout using track algorithm + const tracks: boolean[][] = [new Array(visibleColumnKeys.length).fill(false)]; + + for (const item of itemData) { + // Direct columnKey matching - no parsing or construction needed + const startCol = visibleColumnKeys.indexOf(item.columnKey); + if (startCol === -1) continue; + + const colStart = startCol; + const colEnd = Math.min(startCol + item.duration, visibleColumnKeys.length); + + const row = this.findAvailableRow(tracks, colStart, colEnd); + + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + + // Update element position + item.element.style.gridArea = `${row + 1} / ${colStart + 1} / ${row + 2} / ${colEnd + 1}`; + } + + // Update drawer height + const rowCount = tracks.length; + this.headerDrawerManager.expandToRows(rowCount); + } + + /** + * Get visible column keys from DOM (preserves order for multi-resource views) + * Uses filterTemplate.buildKeyFromColumn() for consistent key format with events + */ + private getVisibleColumnKeysFromDOM(): string[] { + if (!this.filterTemplate) return []; + const columns = document.querySelectorAll('swp-day-column'); + const columnKeys: string[] = []; + columns.forEach(col => { + const columnKey = this.filterTemplate!.buildKeyFromColumn(col as HTMLElement); + if (columnKey) columnKeys.push(columnKey); + }); + return columnKeys; + } + + /** + * Cleanup preview item and restore source visibility + */ + private cleanup(): void { + // Remove preview item + this.currentItem?.remove(); + this.currentItem = null; + + // Restore source element visibility + if (this.sourceElement) { + this.sourceElement.style.visibility = ''; + this.sourceElement = null; + } + + // Collapse drawer if it wasn't expanded before drag + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.collapse(); + } + } +} diff --git a/packages/calendar/src/features/headerdrawer/index.ts b/packages/calendar/src/features/headerdrawer/index.ts new file mode 100644 index 0000000..7b19757 --- /dev/null +++ b/packages/calendar/src/features/headerdrawer/index.ts @@ -0,0 +1,2 @@ +export { HeaderDrawerRenderer } from './HeaderDrawerRenderer'; +export { HeaderDrawerLayoutEngine, type IHeaderItemLayout, type IHeaderItemInput } from './HeaderDrawerLayoutEngine'; diff --git a/packages/calendar/src/features/resource/ResourceRenderer.ts b/packages/calendar/src/features/resource/ResourceRenderer.ts new file mode 100644 index 0000000..2bf565f --- /dev/null +++ b/packages/calendar/src/features/resource/ResourceRenderer.ts @@ -0,0 +1,69 @@ +import { IRenderContext } from '../../core/IGroupingRenderer'; +import { BaseGroupingRenderer, IGroupingRendererConfig } from '../../core/BaseGroupingRenderer'; +import { ResourceService } from '../../storage/resources/ResourceService'; +import { IResource } from '../../types/CalendarTypes'; + +export class ResourceRenderer extends BaseGroupingRenderer { + readonly type = 'resource'; + + protected readonly config: IGroupingRendererConfig = { + elementTag: 'swp-resource-header', + idAttribute: 'resourceId', + colspanVar: '--resource-cols' + }; + + constructor(private resourceService: ResourceService) { + super(); + } + + protected getEntities(ids: string[]): Promise { + return this.resourceService.getByIds(ids); + } + + protected getDisplayName(entity: IResource): string { + return entity.displayName; + } + + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context: IRenderContext): Promise { + const resourceIds = context.filter['resource'] || []; + const dateCount = context.filter['date']?.length || 1; + + // Determine render order based on parentChildMap + // If parentChildMap exists, render resources grouped by parent (e.g., team) + // Otherwise, render in filter order + let orderedResourceIds: string[]; + + if (context.parentChildMap) { + // Render resources in parent-child order + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + + const resources = await this.getEntities(orderedResourceIds); + + // Create a map for quick lookup to preserve order + const resourceMap = new Map(resources.map(r => [r.id, r])); + + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) continue; + + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +} diff --git a/packages/calendar/src/features/resource/index.ts b/packages/calendar/src/features/resource/index.ts new file mode 100644 index 0000000..3bbd0d9 --- /dev/null +++ b/packages/calendar/src/features/resource/index.ts @@ -0,0 +1 @@ +export { ResourceRenderer } from './ResourceRenderer'; diff --git a/packages/calendar/src/features/schedule/ScheduleRenderer.ts b/packages/calendar/src/features/schedule/ScheduleRenderer.ts new file mode 100644 index 0000000..d1d3349 --- /dev/null +++ b/packages/calendar/src/features/schedule/ScheduleRenderer.ts @@ -0,0 +1,106 @@ +import { ResourceScheduleService } from '../../extensions/schedules/ResourceScheduleService'; +import { DateService } from '../../core/DateService'; +import { IGridConfig } from '../../core/IGridConfig'; +import { ITimeSlot } from '../../types/ScheduleTypes'; + +/** + * ScheduleRenderer - Renders unavailable time zones in day columns + * + * Creates visual indicators for times outside the resource's working hours: + * - Before work start (e.g., 06:00 - 09:00) + * - After work end (e.g., 17:00 - 18:00) + * - Full day if resource is off (schedule = null) + */ +export class ScheduleRenderer { + constructor( + private scheduleService: ResourceScheduleService, + private dateService: DateService, + private gridConfig: IGridConfig + ) {} + + /** + * Render unavailable zones for visible columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and 'resource' arrays + */ + async render(container: HTMLElement, filter: Record): Promise { + const dates = filter['date'] || []; + const resourceIds = filter['resource'] || []; + + if (dates.length === 0) return; + + // Find day columns + const dayColumns = container.querySelector('swp-day-columns'); + if (!dayColumns) return; + + const columns = dayColumns.querySelectorAll('swp-day-column'); + + for (const column of columns) { + const date = (column as HTMLElement).dataset.date; + const resourceId = (column as HTMLElement).dataset.resourceId; + + if (!date || !resourceId) continue; + + // Get or create unavailable layer + let unavailableLayer = column.querySelector('swp-unavailable-layer'); + if (!unavailableLayer) { + unavailableLayer = document.createElement('swp-unavailable-layer'); + column.insertBefore(unavailableLayer, column.firstChild); + } + + // Clear existing + unavailableLayer.innerHTML = ''; + + // Get schedule for this resource/date + const schedule = await this.scheduleService.getScheduleForDate(resourceId, date); + + // Render unavailable zones + this.renderUnavailableZones(unavailableLayer as HTMLElement, schedule); + } + } + + /** + * Render unavailable time zones based on schedule + */ + private renderUnavailableZones(layer: HTMLElement, schedule: ITimeSlot | null): void { + const dayStartMinutes = this.gridConfig.dayStartHour * 60; + const dayEndMinutes = this.gridConfig.dayEndHour * 60; + const minuteHeight = this.gridConfig.hourHeight / 60; + + if (schedule === null) { + // Full day unavailable + const zone = this.createUnavailableZone(0, (dayEndMinutes - dayStartMinutes) * minuteHeight); + layer.appendChild(zone); + return; + } + + const workStartMinutes = this.dateService.timeToMinutes(schedule.start); + const workEndMinutes = this.dateService.timeToMinutes(schedule.end); + + // Before work start + if (workStartMinutes > dayStartMinutes) { + const top = 0; + const height = (workStartMinutes - dayStartMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + + // After work end + if (workEndMinutes < dayEndMinutes) { + const top = (workEndMinutes - dayStartMinutes) * minuteHeight; + const height = (dayEndMinutes - workEndMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + } + + /** + * Create an unavailable zone element + */ + private createUnavailableZone(top: number, height: number): HTMLElement { + const zone = document.createElement('swp-unavailable-zone'); + zone.style.top = `${top}px`; + zone.style.height = `${height}px`; + return zone; + } +} diff --git a/packages/calendar/src/features/schedule/index.ts b/packages/calendar/src/features/schedule/index.ts new file mode 100644 index 0000000..c6ca514 --- /dev/null +++ b/packages/calendar/src/features/schedule/index.ts @@ -0,0 +1 @@ +export { ScheduleRenderer } from './ScheduleRenderer'; diff --git a/packages/calendar/src/features/timeaxis/TimeAxisRenderer.ts b/packages/calendar/src/features/timeaxis/TimeAxisRenderer.ts new file mode 100644 index 0000000..80279be --- /dev/null +++ b/packages/calendar/src/features/timeaxis/TimeAxisRenderer.ts @@ -0,0 +1,10 @@ +export class TimeAxisRenderer { + render(container: HTMLElement, startHour = 6, endHour = 20): void { + container.innerHTML = ''; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement('swp-hour-marker'); + marker.textContent = `${hour.toString().padStart(2, '0')}:00`; + container.appendChild(marker); + } + } +} diff --git a/packages/calendar/src/index.ts b/packages/calendar/src/index.ts new file mode 100644 index 0000000..a0bee9c --- /dev/null +++ b/packages/calendar/src/index.ts @@ -0,0 +1,164 @@ +// === CORE === + +// App +export { CalendarApp } from './core/CalendarApp'; +export { CalendarOrchestrator } from './core/CalendarOrchestrator'; +export { CalendarEvents } from './core/CalendarEvents'; +export type { + RenderPayload, + WorkweekChangePayload, + ViewUpdatePayload +} from './core/CalendarEvents'; + +// Infrastructure +export { EventBus } from './core/EventBus'; +export { DateService } from './core/DateService'; +export { ViewTemplate, ViewConfig, GroupingConfig } from './core/ViewConfig'; +export { IRenderer, IRenderContext } from './core/IGroupingRenderer'; +export { IGroupingStore } from './core/IGroupingStore'; +export { BaseGroupingRenderer, IGroupingRendererConfig } from './core/BaseGroupingRenderer'; +export { buildPipeline, Pipeline } from './core/RenderBuilder'; +export { NavigationAnimator } from './core/NavigationAnimator'; +export { ScrollManager } from './core/ScrollManager'; +export { HeaderDrawerManager } from './core/HeaderDrawerManager'; +export { FilterTemplate } from './core/FilterTemplate'; +export { EntityResolver } from './core/EntityResolver'; +export type { IEntityResolver } from './core/IEntityResolver'; + +// Configuration interfaces +export type { ITimeFormatConfig } from './core/ITimeFormatConfig'; +export type { IGridConfig } from './core/IGridConfig'; + +// Core Features +export { DateRenderer } from './features/date'; +export { ResourceRenderer } from './features/resource'; +export { EventRenderer } from './features/event'; +export { eventsOverlap, calculateColumnLayout } from './features/event/EventLayoutEngine'; +export type { + IStackLink, + IStackedEventLayout, + IGridGroupLayout, + IColumnLayout +} from './features/event/EventLayoutTypes'; +export { TimeAxisRenderer } from './features/timeaxis/TimeAxisRenderer'; +export { HeaderDrawerRenderer, HeaderDrawerLayoutEngine } from './features/headerdrawer'; +export { ScheduleRenderer } from './features/schedule'; + +// Core Storage +export { IndexedDBContext, defaultDBConfig } from './storage/IndexedDBContext'; +export type { IDBConfig } from './storage/IndexedDBContext'; +export { BaseEntityService } from './storage/BaseEntityService'; +export type { IEntityService } from './storage/IEntityService'; +export type { IStore } from './storage/IStore'; +export { SyncPlugin } from './storage/SyncPlugin'; + +// Event storage +export { EventService } from './storage/events/EventService'; +export { EventStore } from './storage/events/EventStore'; +export { EventSerialization } from './storage/events/EventSerialization'; + +// Resource storage +export { ResourceService } from './storage/resources/ResourceService'; +export { ResourceStore } from './storage/resources/ResourceStore'; + +// Settings storage +export { SettingsService } from './storage/settings/SettingsService'; +export { SettingsStore } from './storage/settings/SettingsStore'; + +// ViewConfig storage +export { ViewConfigService } from './storage/viewconfigs/ViewConfigService'; +export { ViewConfigStore } from './storage/viewconfigs/ViewConfigStore'; + +// Core Managers +export { DragDropManager } from './managers/DragDropManager'; +export { EdgeScrollManager } from './managers/EdgeScrollManager'; +export { ResizeManager } from './managers/ResizeManager'; +export { EventPersistenceManager } from './managers/EventPersistenceManager'; + +// Position utilities +export { + calculateEventPosition, + minutesToPixels, + pixelsToMinutes, + snapToGrid +} from './utils/PositionUtils'; +export type { EventPosition } from './utils/PositionUtils'; + +// Types +export type { + ICalendarEvent, + IResource, + IEventBus, + ISync, + SyncStatus, + EntityType, + CalendarEventType, + ResourceType, + ITeam, + IDepartment, + IBooking, + BookingStatus, + IBookingService, + ICustomer, + IDataEntity, + IEventLogEntry, + IListenerEntry, + IEntitySavedPayload, + IEntityDeletedPayload, + IEventUpdatedPayload +} from './types/CalendarTypes'; + +export type { + TenantSetting, + IGridSettings, + IWorkweekPreset +} from './types/SettingsTypes'; + +export type { + IScheduleOverride, + ITimeSlot, + IWeekSchedule, + WeekDay +} from './types/ScheduleTypes'; + +// Drag types +export type { + IMousePosition, + IDragStartPayload, + IDragMovePayload, + IDragEndPayload, + IDragCancelPayload, + IDragColumnChangePayload, + IDragEnterHeaderPayload, + IDragMoveHeaderPayload, + IDragLeaveHeaderPayload +} from './types/DragTypes'; + +// Resize types +export type { + IResizeStartPayload, + IResizeEndPayload +} from './types/ResizeTypes'; + +// Audit types +export type { + IAuditEntry, + IAuditLoggedPayload +} from './types/AuditTypes'; + +export { SwpEvent } from './types/SwpEvent'; + +// Core Events constants +export { CoreEvents } from './constants/CoreEvents'; + +// Repository interface (for custom implementations) +export type { IApiRepository } from './repositories/IApiRepository'; + +// DI helpers +export { + createCalendarContainer, + registerCoreServices, + defaultTimeFormatConfig, + defaultGridConfig +} from './CompositionRoot'; +export type { ICalendarOptions } from './CompositionRoot'; diff --git a/packages/calendar/src/managers/DragDropManager.ts b/packages/calendar/src/managers/DragDropManager.ts new file mode 100644 index 0000000..4bf50b9 --- /dev/null +++ b/packages/calendar/src/managers/DragDropManager.ts @@ -0,0 +1,581 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { IGridConfig } from '../core/IGridConfig'; +import { CoreEvents } from '../constants/CoreEvents'; +import { snapToGrid } from '../utils/PositionUtils'; +import { + IMousePosition, + IDragStartPayload, + IDragMovePayload, + IDragEndPayload, + IDragCancelPayload, + IDragColumnChangePayload, + IDragEnterHeaderPayload, + IDragMoveHeaderPayload, + IDragLeaveHeaderPayload +} from '../types/DragTypes'; +import { SwpEvent } from '../types/SwpEvent'; + +interface DragState { + eventId: string; + element: HTMLElement; + ghostElement: HTMLElement | null; // Null for header items + startY: number; + mouseOffset: IMousePosition; + columnElement: HTMLElement | null; // Null when starting from header + currentColumn: HTMLElement | null; // Null when in header + targetY: number; + currentY: number; + animationId: number; + sourceColumnKey: string; // Source column key (where drag started) + dragSource: 'grid' | 'header'; // Where drag originated +} + +/** + * DragDropManager - Handles drag-drop for calendar events + * + * Strategy: Drag original element, leave ghost-clone in place + * - mousedown: Store initial state, wait for movement + * - mousemove (>5px): Create ghost, start dragging original + * - mouseup: Snap to grid, remove ghost, emit drag:end + * - cancel: Animate back to startY, remove ghost + */ +export class DragDropManager { + private dragState: DragState | null = null; + private mouseDownPosition: IMousePosition | null = null; + private pendingElement: HTMLElement | null = null; + private pendingMouseOffset: IMousePosition | null = null; + private container: HTMLElement | null = null; + private inHeader = false; + + private readonly DRAG_THRESHOLD = 5; + private readonly INTERPOLATION_FACTOR = 0.3; + + constructor( + private eventBus: IEventBus, + private gridConfig: IGridConfig + ) { + this.setupScrollListener(); + } + + private setupScrollListener(): void { + this.eventBus.on(CoreEvents.EDGE_SCROLL_TICK, (e) => { + if (!this.dragState) return; + const { scrollDelta } = (e as CustomEvent<{ scrollDelta: number }>).detail; + + // Element skal flytte med scroll for at forblive under musen + // (elementets top er relativ til kolonnen, som scroller med viewport) + this.dragState.targetY += scrollDelta; + this.dragState.currentY += scrollDelta; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + }); + } + + /** + * Initialize drag-drop on a container element + */ + init(container: HTMLElement): void { + this.container = container; + container.addEventListener('pointerdown', this.handlePointerDown); + document.addEventListener('pointermove', this.handlePointerMove); + document.addEventListener('pointerup', this.handlePointerUp); + } + + private handlePointerDown = (e: PointerEvent): void => { + const target = e.target as HTMLElement; + + // Ignore if clicking on resize handle + if (target.closest('swp-resize-handle')) return; + + // Match both swp-event and swp-header-item + const eventElement = target.closest('swp-event') as HTMLElement; + const headerItem = target.closest('swp-header-item') as HTMLElement; + const draggable = eventElement || headerItem; + + if (!draggable) return; + + // Store for potential drag + this.mouseDownPosition = { x: e.clientX, y: e.clientY }; + this.pendingElement = draggable; + + // Calculate mouse offset within element + const rect = draggable.getBoundingClientRect(); + this.pendingMouseOffset = { + x: e.clientX - rect.left, + y: e.clientY - rect.top + }; + + // Capture pointer for reliable tracking + draggable.setPointerCapture(e.pointerId); + }; + + private handlePointerMove = (e: PointerEvent): void => { + // Not in potential drag state + if (!this.mouseDownPosition || !this.pendingElement) { + // Already dragging - update target + if (this.dragState) { + this.updateDragTarget(e); + } + return; + } + + // Check threshold + const deltaX = Math.abs(e.clientX - this.mouseDownPosition.x); + const deltaY = Math.abs(e.clientY - this.mouseDownPosition.y); + const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + + if (distance < this.DRAG_THRESHOLD) return; + + // Start drag + this.initializeDrag(this.pendingElement, this.pendingMouseOffset!, e); + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + }; + + private handlePointerUp = (_e: PointerEvent): void => { + // Clear pending state + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + + if (!this.dragState) return; + + // Stop animation + cancelAnimationFrame(this.dragState.animationId); + + // Handle based on drag source and target + if (this.dragState.dragSource === 'header') { + // Header item drag end + this.handleHeaderItemDragEnd(); + } else { + // Grid event drag end + this.handleGridEventDragEnd(); + } + + // Cleanup + this.dragState.element.classList.remove('dragging'); + this.dragState = null; + this.inHeader = false; + }; + + /** + * Handle drag end for header items + */ + private handleHeaderItemDragEnd(): void { + if (!this.dragState) return; + + // If dropped in grid (not in header), the swp-event was already created + // by EventRenderer listening to EVENT_DRAG_LEAVE_HEADER + // Just emit drag:end for persistence + + if (!this.inHeader && this.dragState.currentColumn) { + // Dropped in grid - emit drag:end with the new swp-event element + const gridEvent = this.dragState.currentColumn.querySelector( + `swp-event[data-event-id="${this.dragState.eventId}"]` + ) as HTMLElement; + + if (gridEvent) { + const columnKey = this.dragState.currentColumn.dataset.columnKey || ''; + const date = this.dragState.currentColumn.dataset.date || ''; + const swpEvent = SwpEvent.fromElement(gridEvent, columnKey, date, this.gridConfig); + + const payload: IDragEndPayload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: 'grid' + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + } + // If still in header, no persistence needed (stayed in header) + } + + /** + * Handle drag end for grid events + */ + private handleGridEventDragEnd(): void { + if (!this.dragState || !this.dragState.columnElement) return; + + // Snap to grid + const snappedY = snapToGrid(this.dragState.currentY, this.gridConfig); + this.dragState.element.style.top = `${snappedY}px`; + + // Remove ghost + this.dragState.ghostElement?.remove(); + + // Get columnKey and date from target column + const columnKey = this.dragState.columnElement.dataset.columnKey || ''; + const date = this.dragState.columnElement.dataset.date || ''; + + // Create SwpEvent from element (reads top/height/eventId from element) + const swpEvent = SwpEvent.fromElement( + this.dragState.element, + columnKey, + date, + this.gridConfig + ); + + // Emit drag:end + const payload: IDragEndPayload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: this.inHeader ? 'header' : 'grid' + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + + private initializeDrag(element: HTMLElement, mouseOffset: IMousePosition, e: PointerEvent): void { + const eventId = element.dataset.eventId || ''; + const isHeaderItem = element.tagName.toLowerCase() === 'swp-header-item'; + const columnElement = element.closest('swp-day-column') as HTMLElement; + + // For grid events, we need a column + if (!isHeaderItem && !columnElement) return; + + if (isHeaderItem) { + // Header item drag initialization + this.initializeHeaderItemDrag(element, mouseOffset, eventId); + } else { + // Grid event drag initialization + this.initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId); + } + } + + /** + * Initialize drag for a header item (allDay event) + */ + private initializeHeaderItemDrag(element: HTMLElement, mouseOffset: IMousePosition, eventId: string): void { + // Mark as dragging + element.classList.add('dragging'); + + // Initialize drag state for header item + this.dragState = { + eventId, + element, + ghostElement: null, // No ghost for header items + startY: 0, + mouseOffset, + columnElement: null, + currentColumn: null, + targetY: 0, + currentY: 0, + animationId: 0, + sourceColumnKey: '', // Will be set from header item data + dragSource: 'header' + }; + + // Start in header mode + this.inHeader = true; + } + + /** + * Initialize drag for a grid event + */ + private initializeGridEventDrag(element: HTMLElement, mouseOffset: IMousePosition, e: PointerEvent, columnElement: HTMLElement, eventId: string): void { + // Calculate absolute Y position using getBoundingClientRect + const elementRect = element.getBoundingClientRect(); + const columnRect = columnElement.getBoundingClientRect(); + const startY = elementRect.top - columnRect.top; + + // If event is inside a group, move it to events-layer for correct positioning during drag + const group = element.closest('swp-event-group'); + if (group) { + const eventsLayer = columnElement.querySelector('swp-events-layer'); + if (eventsLayer) { + eventsLayer.appendChild(element); + } + } + + // Set consistent positioning for drag (works for both grouped and stacked events) + element.style.position = 'absolute'; + element.style.top = `${startY}px`; + element.style.left = '2px'; + element.style.right = '2px'; + element.style.marginLeft = '0'; // Reset stacking margin + + // Create ghost clone + const ghostElement = element.cloneNode(true) as HTMLElement; + ghostElement.classList.add('drag-ghost'); + ghostElement.style.opacity = '0.3'; + ghostElement.style.pointerEvents = 'none'; + + // Insert ghost before original + element.parentNode?.insertBefore(ghostElement, element); + + // Setup element for dragging + element.classList.add('dragging'); + + // Calculate initial target from mouse position + const targetY = e.clientY - columnRect.top - mouseOffset.y; + + // Initialize drag state + this.dragState = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement, + currentColumn: columnElement, + targetY: Math.max(0, targetY), + currentY: startY, + animationId: 0, + sourceColumnKey: columnElement.dataset.columnKey || '', + dragSource: 'grid' + }; + + // Emit drag:start + const payload: IDragStartPayload = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_START, payload); + + // Start animation loop + this.animateDrag(); + } + + private updateDragTarget(e: PointerEvent): void { + if (!this.dragState) return; + + // Check header zone first + this.checkHeaderZone(e); + + // Skip normal grid handling if in header + if (this.inHeader) return; + + // Check for column change + const columnAtPoint = this.getColumnAtPoint(e.clientX); + + // For header items entering grid, set initial column + if (this.dragState.dragSource === 'header' && columnAtPoint && !this.dragState.currentColumn) { + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + + if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn && this.dragState.currentColumn) { + const payload: IDragColumnChangePayload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + previousColumn: this.dragState.currentColumn, + newColumn: columnAtPoint, + currentY: this.dragState.currentY + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, payload); + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + + // Skip grid position updates if no column yet + if (!this.dragState.columnElement) return; + + const columnRect = this.dragState.columnElement.getBoundingClientRect(); + const targetY = e.clientY - columnRect.top - this.dragState.mouseOffset.y; + + this.dragState.targetY = Math.max(0, targetY); + + // Start animation if not running + if (!this.dragState.animationId) { + this.animateDrag(); + } + } + + /** + * Check if pointer is in header zone and emit appropriate events + */ + private checkHeaderZone(e: PointerEvent): void { + if (!this.dragState) return; + + const headerViewport = document.querySelector('swp-header-viewport'); + if (!headerViewport) return; + + const rect = headerViewport.getBoundingClientRect(); + const isInHeader = e.clientY < rect.bottom; + + if (isInHeader && !this.inHeader) { + // Entered header (from grid) + this.inHeader = true; + + if (this.dragState.dragSource === 'grid' && this.dragState.columnElement) { + const payload: IDragEnterHeaderPayload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + sourceColumnIndex: this.getColumnIndex(this.dragState.columnElement), + sourceColumnKey: this.dragState.columnElement.dataset.columnKey || '', + title: this.dragState.element.querySelector('swp-event-title')?.textContent || '', + colorClass: [...this.dragState.element.classList].find(c => c.startsWith('is-')), + itemType: 'event', + duration: 1 + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_ENTER_HEADER, payload); + } + // For header source re-entering header, just update inHeader flag + } else if (!isInHeader && this.inHeader) { + // Left header (entering grid) + this.inHeader = false; + + const targetColumn = this.getColumnAtPoint(e.clientX); + + if (this.dragState.dragSource === 'header') { + // Header item leaving header → create swp-event in grid + const payload: IDragLeaveHeaderPayload = { + eventId: this.dragState.eventId, + source: 'header', + element: this.dragState.element, + targetColumn: targetColumn || undefined, + start: this.dragState.element.dataset.start ? new Date(this.dragState.element.dataset.start) : undefined, + end: this.dragState.element.dataset.end ? new Date(this.dragState.element.dataset.end) : undefined, + title: this.dragState.element.textContent || '', + colorClass: [...this.dragState.element.classList].find(c => c.startsWith('is-')) + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + + // Re-attach to the new swp-event created by EventRenderer + if (targetColumn) { + const newElement = targetColumn.querySelector( + `swp-event[data-event-id="${this.dragState.eventId}"]` + ) as HTMLElement; + + if (newElement) { + this.dragState.element = newElement; + this.dragState.columnElement = targetColumn; + this.dragState.currentColumn = targetColumn; + + // Start animation for the new element + this.animateDrag(); + } + } + } else { + // Grid event leaving header → restore to grid + const payload: IDragLeaveHeaderPayload = { + eventId: this.dragState.eventId, + source: 'grid' + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + } + } else if (isInHeader) { + // Moving within header + const column = this.getColumnAtX(e.clientX); + if (column) { + const payload: IDragMoveHeaderPayload = { + eventId: this.dragState.eventId, + columnIndex: this.getColumnIndex(column), + columnKey: column.dataset.columnKey || '' + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE_HEADER, payload); + } + } + } + + /** + * Get column index (0-based) for a column element + */ + private getColumnIndex(column: HTMLElement | null): number { + if (!this.container || !column) return 0; + const columns = Array.from(this.container.querySelectorAll('swp-day-column')); + return columns.indexOf(column); + } + + /** + * Get column at X coordinate (alias for getColumnAtPoint) + */ + private getColumnAtX(clientX: number): HTMLElement | null { + return this.getColumnAtPoint(clientX); + } + + /** + * Find column element at given X coordinate + */ + private getColumnAtPoint(clientX: number): HTMLElement | null { + if (!this.container) return null; + + const columns = this.container.querySelectorAll('swp-day-column'); + for (const col of columns) { + const rect = col.getBoundingClientRect(); + if (clientX >= rect.left && clientX <= rect.right) { + return col as HTMLElement; + } + } + return null; + } + + private animateDrag = (): void => { + if (!this.dragState) return; + + const diff = this.dragState.targetY - this.dragState.currentY; + + // Stop animation when close enough to target + if (Math.abs(diff) <= 0.5) { + this.dragState.animationId = 0; + return; + } + + // Interpolate towards target + this.dragState.currentY += diff * this.INTERPOLATION_FACTOR; + + // Update element position + this.dragState.element.style.top = `${this.dragState.currentY}px`; + + // Emit drag:move (only if we have a column) + if (this.dragState.columnElement) { + const payload: IDragMovePayload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + currentY: this.dragState.currentY, + columnElement: this.dragState.columnElement + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE, payload); + } + + // Continue animation + this.dragState.animationId = requestAnimationFrame(this.animateDrag); + }; + + /** + * Cancel drag and animate back to start position + */ + cancelDrag(): void { + if (!this.dragState) return; + + // Stop animation + cancelAnimationFrame(this.dragState.animationId); + + const { element, ghostElement, startY, eventId } = this.dragState; + + // Animate back to start + element.style.transition = 'top 200ms ease-out'; + element.style.top = `${startY}px`; + + // Remove ghost after animation (if exists) + setTimeout(() => { + ghostElement?.remove(); + element.style.transition = ''; + element.classList.remove('dragging'); + }, 200); + + // Emit drag:cancel + const payload: IDragCancelPayload = { + eventId, + element, + startY + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_CANCEL, payload); + + this.dragState = null; + this.inHeader = false; + } +} diff --git a/packages/calendar/src/managers/EdgeScrollManager.ts b/packages/calendar/src/managers/EdgeScrollManager.ts new file mode 100644 index 0000000..d1b5584 --- /dev/null +++ b/packages/calendar/src/managers/EdgeScrollManager.ts @@ -0,0 +1,140 @@ +/** + * EdgeScrollManager - Auto-scroll when dragging near viewport edges + * + * 2-zone system: + * - Inner zone (0-50px): Fast scroll (640 px/sec) + * - Outer zone (50-100px): Slow scroll (140 px/sec) + */ + +import { IEventBus } from '../types/CalendarTypes'; +import { CoreEvents } from '../constants/CoreEvents'; + +export class EdgeScrollManager { + private scrollableContent: HTMLElement | null = null; + private timeGrid: HTMLElement | null = null; + private draggedElement: HTMLElement | null = null; + private scrollRAF: number | null = null; + private mouseY = 0; + private isDragging = false; + private isScrolling = false; + private lastTs = 0; + private rect: DOMRect | null = null; + private initialScrollTop = 0; + + private readonly OUTER_ZONE = 100; + private readonly INNER_ZONE = 50; + private readonly SLOW_SPEED = 140; + private readonly FAST_SPEED = 640; + + constructor(private eventBus: IEventBus) { + this.subscribeToEvents(); + document.addEventListener('pointermove', this.trackMouse); + } + + init(scrollableContent: HTMLElement): void { + this.scrollableContent = scrollableContent; + this.timeGrid = scrollableContent.querySelector('swp-time-grid'); + this.scrollableContent.style.scrollBehavior = 'auto'; + } + + private trackMouse = (e: PointerEvent): void => { + if (this.isDragging) { + this.mouseY = e.clientY; + } + }; + + private subscribeToEvents(): void { + this.eventBus.on(CoreEvents.EVENT_DRAG_START, (event: Event) => { + const payload = (event as CustomEvent).detail; + this.draggedElement = payload.element; + this.startDrag(); + }); + + this.eventBus.on(CoreEvents.EVENT_DRAG_END, () => this.stopDrag()); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => this.stopDrag()); + } + + private startDrag(): void { + this.isDragging = true; + this.isScrolling = false; + this.lastTs = 0; + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + + if (this.scrollRAF === null) { + this.scrollRAF = requestAnimationFrame(this.scrollTick); + } + } + + private stopDrag(): void { + this.isDragging = false; + this.setScrollingState(false); + + if (this.scrollRAF !== null) { + cancelAnimationFrame(this.scrollRAF); + this.scrollRAF = null; + } + + this.rect = null; + this.lastTs = 0; + this.initialScrollTop = 0; + } + + private calculateVelocity(): number { + if (!this.rect) return 0; + + const distTop = this.mouseY - this.rect.top; + const distBot = this.rect.bottom - this.mouseY; + + if (distTop < this.INNER_ZONE) return -this.FAST_SPEED; + if (distTop < this.OUTER_ZONE) return -this.SLOW_SPEED; + if (distBot < this.INNER_ZONE) return this.FAST_SPEED; + if (distBot < this.OUTER_ZONE) return this.SLOW_SPEED; + + return 0; + } + + private isAtBoundary(velocity: number): boolean { + if (!this.scrollableContent || !this.timeGrid || !this.draggedElement) return false; + + const atTop = this.scrollableContent.scrollTop <= 0 && velocity < 0; + const atBottom = velocity > 0 && + this.draggedElement.getBoundingClientRect().bottom >= + this.timeGrid.getBoundingClientRect().bottom; + + return atTop || atBottom; + } + + private setScrollingState(scrolling: boolean): void { + if (this.isScrolling === scrolling) return; + + this.isScrolling = scrolling; + if (scrolling) { + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STARTED, {}); + } else { + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STOPPED, {}); + } + } + + private scrollTick = (ts: number): void => { + if (!this.isDragging || !this.scrollableContent) return; + + const dt = this.lastTs ? (ts - this.lastTs) / 1000 : 0; + this.lastTs = ts; + this.rect ??= this.scrollableContent.getBoundingClientRect(); + + const velocity = this.calculateVelocity(); + + if (velocity !== 0 && !this.isAtBoundary(velocity)) { + const scrollDelta = velocity * dt; + this.scrollableContent.scrollTop += scrollDelta; + this.rect = null; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_TICK, { scrollDelta }); + this.setScrollingState(true); + } else { + this.setScrollingState(false); + } + + this.scrollRAF = requestAnimationFrame(this.scrollTick); + }; +} diff --git a/packages/calendar/src/managers/EventPersistenceManager.ts b/packages/calendar/src/managers/EventPersistenceManager.ts new file mode 100644 index 0000000..ae59df9 --- /dev/null +++ b/packages/calendar/src/managers/EventPersistenceManager.ts @@ -0,0 +1,102 @@ +/** + * EventPersistenceManager - Persists event changes to IndexedDB + * + * Listens to drag/resize events and updates IndexedDB via EventService. + * This bridges the gap between UI interactions and data persistence. + */ + +import { ICalendarEvent, IEventBus, IEventUpdatedPayload } from '../types/CalendarTypes'; +import { EventService } from '../storage/events/EventService'; +import { DateService } from '../core/DateService'; +import { CoreEvents } from '../constants/CoreEvents'; +import { IDragEndPayload } from '../types/DragTypes'; +import { IResizeEndPayload } from '../types/ResizeTypes'; + +export class EventPersistenceManager { + constructor( + private eventService: EventService, + private eventBus: IEventBus, + private dateService: DateService + ) { + this.setupListeners(); + } + + private setupListeners(): void { + this.eventBus.on(CoreEvents.EVENT_DRAG_END, this.handleDragEnd); + this.eventBus.on(CoreEvents.EVENT_RESIZE_END, this.handleResizeEnd); + } + + /** + * Handle drag end - update event position in IndexedDB + */ + private handleDragEnd = async (e: Event): Promise => { + const payload = (e as CustomEvent).detail; + const { swpEvent } = payload; + + // Get existing event to merge with + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + + // Parse resourceId from columnKey if present + const { resource } = this.dateService.parseColumnKey(swpEvent.columnKey); + + // Update and save - start/end already calculated in SwpEvent + // Set allDay based on drop target: + // - header: allDay = true + // - grid: allDay = false (converts allDay event to timed) + const updatedEvent: ICalendarEvent = { + ...event, + start: swpEvent.start, + end: swpEvent.end, + resourceId: resource ?? event.resourceId, + allDay: payload.target === 'header', + syncStatus: 'pending' + }; + + await this.eventService.save(updatedEvent); + + // Emit EVENT_UPDATED for EventRenderer to re-render affected columns + const updatePayload: IEventUpdatedPayload = { + eventId: updatedEvent.id, + sourceColumnKey: payload.sourceColumnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + + /** + * Handle resize end - update event duration in IndexedDB + */ + private handleResizeEnd = async (e: Event): Promise => { + const payload = (e as CustomEvent).detail; + const { swpEvent } = payload; + + // Get existing event to merge with + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + + // Update and save - end already calculated in SwpEvent + const updatedEvent: ICalendarEvent = { + ...event, + end: swpEvent.end, + syncStatus: 'pending' + }; + + await this.eventService.save(updatedEvent); + + // Emit EVENT_UPDATED for EventRenderer to re-render the column + // Resize stays in same column, so source and target are the same + const updatePayload: IEventUpdatedPayload = { + eventId: updatedEvent.id, + sourceColumnKey: swpEvent.columnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; +} diff --git a/packages/calendar/src/managers/ResizeManager.ts b/packages/calendar/src/managers/ResizeManager.ts new file mode 100644 index 0000000..5448def --- /dev/null +++ b/packages/calendar/src/managers/ResizeManager.ts @@ -0,0 +1,290 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { IGridConfig } from '../core/IGridConfig'; +import { pixelsToMinutes, minutesToPixels, snapToGrid } from '../utils/PositionUtils'; +import { DateService } from '../core/DateService'; +import { CoreEvents } from '../constants/CoreEvents'; +import { IResizeStartPayload, IResizeEndPayload } from '../types/ResizeTypes'; +import { SwpEvent } from '../types/SwpEvent'; + +/** + * ResizeManager - Handles resize of calendar events + * + * Step 1: Handle creation on mouseover (CSS handles visibility) + * Step 2: Pointer events + resize start + * Step 3: RAF animation for smooth height update + * Step 4: Grid snapping + timestamp update + */ + +interface ResizeState { + eventId: string; + element: HTMLElement; + handleElement: HTMLElement; + startY: number; + startHeight: number; + startDurationMinutes: number; + pointerId: number; + prevZIndex: string; + // Animation state + currentHeight: number; + targetHeight: number; + animationId: number | null; +} + +export class ResizeManager { + private container: HTMLElement | null = null; + private resizeState: ResizeState | null = null; + + private readonly Z_INDEX_RESIZING = '1000'; + private readonly ANIMATION_SPEED = 0.35; + private readonly MIN_HEIGHT_MINUTES = 15; + + constructor( + private eventBus: IEventBus, + private gridConfig: IGridConfig, + private dateService: DateService + ) {} + + /** + * Initialize resize functionality on container + */ + init(container: HTMLElement): void { + this.container = container; + + // Mouseover listener for handle creation (capture phase like V1) + container.addEventListener('mouseover', this.handleMouseOver, true); + + // Pointer listeners for resize (capture phase like V1) + document.addEventListener('pointerdown', this.handlePointerDown, true); + document.addEventListener('pointermove', this.handlePointerMove, true); + document.addEventListener('pointerup', this.handlePointerUp, true); + } + + /** + * Create resize handle element + */ + private createResizeHandle(): HTMLElement { + const handle = document.createElement('swp-resize-handle'); + handle.setAttribute('aria-label', 'Resize event'); + handle.setAttribute('role', 'separator'); + return handle; + } + + /** + * Handle mouseover - create resize handle if not exists + */ + private handleMouseOver = (e: Event): void => { + const target = e.target as HTMLElement; + const eventElement = target.closest('swp-event') as HTMLElement; + + if (!eventElement || this.resizeState) return; + + // Check if handle already exists + if (!eventElement.querySelector(':scope > swp-resize-handle')) { + const handle = this.createResizeHandle(); + eventElement.appendChild(handle); + } + }; + + /** + * Handle pointerdown - start resize if on handle + */ + private handlePointerDown = (e: PointerEvent): void => { + const handle = (e.target as HTMLElement).closest('swp-resize-handle') as HTMLElement; + if (!handle) return; + + const element = handle.parentElement as HTMLElement; + if (!element) return; + + const eventId = element.dataset.eventId || ''; + const startHeight = element.offsetHeight; + const startDurationMinutes = pixelsToMinutes(startHeight, this.gridConfig); + + // Store previous z-index + const container = element.closest('swp-event-group') as HTMLElement ?? element; + const prevZIndex = container.style.zIndex; + + // Set resize state + this.resizeState = { + eventId, + element, + handleElement: handle, + startY: e.clientY, + startHeight, + startDurationMinutes, + pointerId: e.pointerId, + prevZIndex, + // Animation state + currentHeight: startHeight, + targetHeight: startHeight, + animationId: null + }; + + // Elevate z-index + container.style.zIndex = this.Z_INDEX_RESIZING; + + // Capture pointer for smooth tracking + try { + handle.setPointerCapture(e.pointerId); + } catch (err) { + console.warn('Pointer capture failed:', err); + } + + // Add global resizing class + document.documentElement.classList.add('swp--resizing'); + + // Emit resize start event + this.eventBus.emit(CoreEvents.EVENT_RESIZE_START, { + eventId, + element, + startHeight + } as IResizeStartPayload); + + e.preventDefault(); + }; + + /** + * Handle pointermove - update target height during resize + */ + private handlePointerMove = (e: PointerEvent): void => { + if (!this.resizeState) return; + + const deltaY = e.clientY - this.resizeState.startY; + const minHeight = (this.MIN_HEIGHT_MINUTES / 60) * this.gridConfig.hourHeight; + const newHeight = Math.max(minHeight, this.resizeState.startHeight + deltaY); + + // Set target height for animation + this.resizeState.targetHeight = newHeight; + + // Start animation if not running + if (this.resizeState.animationId === null) { + this.animateHeight(); + } + }; + + /** + * RAF animation loop for smooth height interpolation + */ + private animateHeight = (): void => { + if (!this.resizeState) return; + + const diff = this.resizeState.targetHeight - this.resizeState.currentHeight; + + // Stop animation when close enough + if (Math.abs(diff) < 0.5) { + this.resizeState.animationId = null; + return; + } + + // Interpolate towards target (35% per frame like V1) + this.resizeState.currentHeight += diff * this.ANIMATION_SPEED; + this.resizeState.element.style.height = `${this.resizeState.currentHeight}px`; + + // Update timestamp display (snapped) + this.updateTimestampDisplay(); + + // Continue animation + this.resizeState.animationId = requestAnimationFrame(this.animateHeight); + }; + + /** + * Update timestamp display with snapped end time + */ + private updateTimestampDisplay(): void { + if (!this.resizeState) return; + + const timeEl = this.resizeState.element.querySelector('swp-event-time'); + if (!timeEl) return; + + // Get start time from element position + const top = parseFloat(this.resizeState.element.style.top) || 0; + const startMinutesFromGrid = pixelsToMinutes(top, this.gridConfig); + const startMinutes = (this.gridConfig.dayStartHour * 60) + startMinutesFromGrid; + + // Calculate snapped end time from current height + const snappedHeight = snapToGrid(this.resizeState.currentHeight, this.gridConfig); + const durationMinutes = pixelsToMinutes(snappedHeight, this.gridConfig); + const endMinutes = startMinutes + durationMinutes; + + // Format and update + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(endMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + + /** + * Convert minutes since midnight to Date + */ + private minutesToDate(minutes: number): Date { + const date = new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + }; + + /** + * Handle pointerup - finish resize + */ + private handlePointerUp = (e: PointerEvent): void => { + if (!this.resizeState) return; + + // Cancel any pending animation + if (this.resizeState.animationId !== null) { + cancelAnimationFrame(this.resizeState.animationId); + } + + // Release pointer capture + try { + this.resizeState.handleElement.releasePointerCapture(e.pointerId); + } catch (err) { + console.warn('Pointer release failed:', err); + } + + // Snap final height to grid + this.snapToGridFinal(); + + // Update timestamp one final time + this.updateTimestampDisplay(); + + // Restore z-index + const container = this.resizeState.element.closest('swp-event-group') as HTMLElement ?? this.resizeState.element; + container.style.zIndex = this.resizeState.prevZIndex; + + // Remove global resizing class + document.documentElement.classList.remove('swp--resizing'); + + // Get columnKey and date from parent column + const column = this.resizeState.element.closest('swp-day-column') as HTMLElement; + const columnKey = column?.dataset.columnKey || ''; + const date = column?.dataset.date || ''; + + // Create SwpEvent from element (reads top/height/eventId from element) + const swpEvent = SwpEvent.fromElement( + this.resizeState.element, + columnKey, + date, + this.gridConfig + ); + + // Emit resize end event + this.eventBus.emit(CoreEvents.EVENT_RESIZE_END, { + swpEvent + } as IResizeEndPayload); + + // Reset state + this.resizeState = null; + }; + + /** + * Snap final height to grid interval + */ + private snapToGridFinal(): void { + if (!this.resizeState) return; + + const currentHeight = this.resizeState.element.offsetHeight; + const snappedHeight = snapToGrid(currentHeight, this.gridConfig); + const minHeight = minutesToPixels(this.MIN_HEIGHT_MINUTES, this.gridConfig); + const finalHeight = Math.max(minHeight, snappedHeight); + + this.resizeState.element.style.height = `${finalHeight}px`; + this.resizeState.currentHeight = finalHeight; + } +} diff --git a/packages/calendar/src/repositories/IApiRepository.ts b/packages/calendar/src/repositories/IApiRepository.ts new file mode 100644 index 0000000..a50791f --- /dev/null +++ b/packages/calendar/src/repositories/IApiRepository.ts @@ -0,0 +1,33 @@ +import { EntityType } from '../types/CalendarTypes'; + +/** + * IApiRepository - Generic interface for backend API communication + * + * Used by DataSeeder to fetch initial data and by SyncManager for sync operations. + */ +export interface IApiRepository { + /** + * Entity type discriminator - used for runtime routing + */ + readonly entityType: EntityType; + + /** + * Send create operation to backend API + */ + sendCreate(data: T): Promise; + + /** + * Send update operation to backend API + */ + sendUpdate(id: string, updates: Partial): Promise; + + /** + * Send delete operation to backend API + */ + sendDelete(id: string): Promise; + + /** + * Fetch all entities from backend API + */ + fetchAll(): Promise; +} diff --git a/packages/calendar/src/storage/BaseEntityService.ts b/packages/calendar/src/storage/BaseEntityService.ts new file mode 100644 index 0000000..ed8d3a1 --- /dev/null +++ b/packages/calendar/src/storage/BaseEntityService.ts @@ -0,0 +1,181 @@ +import { ISync, EntityType, SyncStatus, IEventBus, IEntitySavedPayload, IEntityDeletedPayload } from '../types/CalendarTypes'; +import { IEntityService } from './IEntityService'; +import { SyncPlugin } from './SyncPlugin'; +import { IndexedDBContext } from './IndexedDBContext'; +import { CoreEvents } from '../constants/CoreEvents'; +import { diff } from 'json-diff-ts'; + +/** + * BaseEntityService - Abstract base class for all entity services + * + * PROVIDES: + * - Generic CRUD operations (get, getAll, save, delete) + * - Sync status management (delegates to SyncPlugin) + * - Serialization hooks (override in subclass if needed) + */ +export abstract class BaseEntityService implements IEntityService { + abstract readonly storeName: string; + abstract readonly entityType: EntityType; + + private syncPlugin: SyncPlugin; + private context: IndexedDBContext; + protected eventBus: IEventBus; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + this.context = context; + this.eventBus = eventBus; + this.syncPlugin = new SyncPlugin(this); + } + + protected get db(): IDBDatabase { + return this.context.getDatabase(); + } + + /** + * Serialize entity before storing in IndexedDB + */ + protected serialize(entity: T): unknown { + return entity; + } + + /** + * Deserialize data from IndexedDB back to entity + */ + protected deserialize(data: unknown): T { + return data as T; + } + + /** + * Get a single entity by ID + */ + async get(id: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.get(id); + + request.onsuccess = () => { + const data = request.result; + resolve(data ? this.deserialize(data) : null); + }; + + request.onerror = () => { + reject(new Error(`Failed to get ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + + /** + * Get all entities + */ + async getAll(): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const entities = data.map(item => this.deserialize(item)); + resolve(entities); + }; + + request.onerror = () => { + reject(new Error(`Failed to get all ${this.entityType}s: ${request.error}`)); + }; + }); + } + + /** + * Save an entity (create or update) + * Emits ENTITY_SAVED event with operation type and changes (diff for updates) + * @param entity - Entity to save + * @param silent - If true, skip event emission (used for seeding) + */ + async save(entity: T, silent = false): Promise { + const entityId = (entity as unknown as { id: string }).id; + const existingEntity = await this.get(entityId); + const isCreate = existingEntity === null; + + // Calculate changes: full entity for create, diff for update + let changes: unknown; + if (isCreate) { + changes = entity; + } else { + const existingSerialized = this.serialize(existingEntity); + const newSerialized = this.serialize(entity); + changes = diff(existingSerialized, newSerialized); + } + + const serialized = this.serialize(entity); + + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + + request.onsuccess = () => { + // Only emit event if not silent (silent used for seeding) + if (!silent) { + const payload: IEntitySavedPayload = { + entityType: this.entityType, + entityId, + operation: isCreate ? 'create' : 'update', + changes, + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_SAVED, payload); + } + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to save ${this.entityType} ${entityId}: ${request.error}`)); + }; + }); + } + + /** + * Delete an entity + * Emits ENTITY_DELETED event + */ + async delete(id: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readwrite'); + const store = transaction.objectStore(this.storeName); + const request = store.delete(id); + + request.onsuccess = () => { + const payload: IEntityDeletedPayload = { + entityType: this.entityType, + entityId: id, + operation: 'delete', + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_DELETED, payload); + resolve(); + }; + + request.onerror = () => { + reject(new Error(`Failed to delete ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + + // Sync methods - delegate to SyncPlugin + async markAsSynced(id: string): Promise { + return this.syncPlugin.markAsSynced(id); + } + + async markAsError(id: string): Promise { + return this.syncPlugin.markAsError(id); + } + + async getSyncStatus(id: string): Promise { + return this.syncPlugin.getSyncStatus(id); + } + + async getBySyncStatus(syncStatus: string): Promise { + return this.syncPlugin.getBySyncStatus(syncStatus); + } +} diff --git a/packages/calendar/src/storage/IEntityService.ts b/packages/calendar/src/storage/IEntityService.ts new file mode 100644 index 0000000..800ea62 --- /dev/null +++ b/packages/calendar/src/storage/IEntityService.ts @@ -0,0 +1,40 @@ +import { ISync, EntityType, SyncStatus } from '../types/CalendarTypes'; + +/** + * IEntityService - Generic interface for entity services with sync capabilities + * + * All entity services implement this interface to enable polymorphic operations. + */ +export interface IEntityService { + /** + * Entity type discriminator for runtime routing + */ + readonly entityType: EntityType; + + /** + * Get all entities from IndexedDB + */ + getAll(): Promise; + + /** + * Save an entity (create or update) to IndexedDB + * @param entity - Entity to save + * @param silent - If true, skip event emission (used for seeding) + */ + save(entity: T, silent?: boolean): Promise; + + /** + * Mark entity as successfully synced + */ + markAsSynced(id: string): Promise; + + /** + * Mark entity as sync error + */ + markAsError(id: string): Promise; + + /** + * Get current sync status for an entity + */ + getSyncStatus(id: string): Promise; +} diff --git a/packages/calendar/src/storage/IStore.ts b/packages/calendar/src/storage/IStore.ts new file mode 100644 index 0000000..91ac873 --- /dev/null +++ b/packages/calendar/src/storage/IStore.ts @@ -0,0 +1,18 @@ +/** + * IStore - Interface for IndexedDB ObjectStore definitions + * + * Each entity store implements this interface to define its schema. + * Enables Open/Closed Principle: IndexedDBContext works with any IStore. + */ +export interface IStore { + /** + * The name of the ObjectStore in IndexedDB + */ + readonly storeName: string; + + /** + * Create the ObjectStore with its schema (indexes, keyPath, etc.) + * Called during database upgrade (onupgradeneeded event) + */ + create(db: IDBDatabase): void; +} diff --git a/packages/calendar/src/storage/IndexedDBContext.ts b/packages/calendar/src/storage/IndexedDBContext.ts new file mode 100644 index 0000000..ab9e9ab --- /dev/null +++ b/packages/calendar/src/storage/IndexedDBContext.ts @@ -0,0 +1,108 @@ +import { IStore } from './IStore'; + +/** + * Database configuration + */ +export interface IDBConfig { + dbName: string; + dbVersion?: number; +} + +export const defaultDBConfig: IDBConfig = { + dbName: 'CalendarDB', + dbVersion: 4 +}; + +/** + * IndexedDBContext - Database connection manager + * + * RESPONSIBILITY: + * - Opens and manages IDBDatabase connection lifecycle + * - Creates object stores via injected IStore implementations + * - Provides shared IDBDatabase instance to all services + */ +export class IndexedDBContext { + private db: IDBDatabase | null = null; + private initialized: boolean = false; + private stores: IStore[]; + private config: IDBConfig; + + constructor(stores: IStore[], config: IDBConfig) { + this.stores = stores; + this.config = config; + } + + get dbName(): string { + return this.config.dbName; + } + + /** + * Initialize and open the database + */ + async initialize(): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.open(this.config.dbName, this.config.dbVersion); + + request.onerror = () => { + reject(new Error(`Failed to open IndexedDB: ${request.error}`)); + }; + + request.onsuccess = () => { + this.db = request.result; + this.initialized = true; + resolve(); + }; + + request.onupgradeneeded = (event) => { + const db = (event.target as IDBOpenDBRequest).result; + + // Create all entity stores via injected IStore implementations + this.stores.forEach(store => { + if (!db.objectStoreNames.contains(store.storeName)) { + store.create(db); + } + }); + }; + }); + } + + /** + * Check if database is initialized + */ + public isInitialized(): boolean { + return this.initialized; + } + + /** + * Get IDBDatabase instance + */ + public getDatabase(): IDBDatabase { + if (!this.db) { + throw new Error('IndexedDB not initialized. Call initialize() first.'); + } + return this.db; + } + + /** + * Close database connection + */ + close(): void { + if (this.db) { + this.db.close(); + this.db = null; + this.initialized = false; + } + } + + /** + * Delete entire database (for testing/reset) + */ + static async deleteDatabase(dbName: string = defaultDBConfig.dbName): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(dbName); + + request.onsuccess = () => resolve(); + request.onerror = () => reject(new Error(`Failed to delete database: ${request.error}`)); + }); + } +} diff --git a/packages/calendar/src/storage/SyncPlugin.ts b/packages/calendar/src/storage/SyncPlugin.ts new file mode 100644 index 0000000..7774da6 --- /dev/null +++ b/packages/calendar/src/storage/SyncPlugin.ts @@ -0,0 +1,64 @@ +import { ISync, SyncStatus } from '../types/CalendarTypes'; + +/** + * SyncPlugin - Pluggable sync functionality for entity services + * + * COMPOSITION PATTERN: + * - Encapsulates all sync-related logic in separate class + * - Composed into BaseEntityService (not inheritance) + */ +export class SyncPlugin { + constructor(private service: any) {} + + /** + * Mark entity as successfully synced + */ + async markAsSynced(id: string): Promise { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = 'synced'; + await this.service.save(entity); + } + } + + /** + * Mark entity as sync error + */ + async markAsError(id: string): Promise { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = 'error'; + await this.service.save(entity); + } + } + + /** + * Get current sync status for an entity + */ + async getSyncStatus(id: string): Promise { + const entity = await this.service.get(id); + return entity ? entity.syncStatus : null; + } + + /** + * Get entities by sync status using IndexedDB index + */ + async getBySyncStatus(syncStatus: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.service.db.transaction([this.service.storeName], 'readonly'); + const store = transaction.objectStore(this.service.storeName); + const index = store.index('syncStatus'); + const request = index.getAll(syncStatus); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const entities = data.map(item => this.service.deserialize(item)); + resolve(entities); + }; + + request.onerror = () => { + reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/storage/events/EventSerialization.ts b/packages/calendar/src/storage/events/EventSerialization.ts new file mode 100644 index 0000000..583fa79 --- /dev/null +++ b/packages/calendar/src/storage/events/EventSerialization.ts @@ -0,0 +1,32 @@ +import { ICalendarEvent } from '../../types/CalendarTypes'; + +/** + * EventSerialization - Handles Date field serialization for IndexedDB + * + * IndexedDB doesn't store Date objects directly, so we convert: + * - Date → ISO string (serialize) when writing + * - ISO string → Date (deserialize) when reading + */ +export class EventSerialization { + /** + * Serialize event for IndexedDB storage + */ + static serialize(event: ICalendarEvent): unknown { + return { + ...event, + start: event.start instanceof Date ? event.start.toISOString() : event.start, + end: event.end instanceof Date ? event.end.toISOString() : event.end + }; + } + + /** + * Deserialize event from IndexedDB storage + */ + static deserialize(data: Record): ICalendarEvent { + return { + ...data, + start: typeof data.start === 'string' ? new Date(data.start) : data.start, + end: typeof data.end === 'string' ? new Date(data.end) : data.end + } as ICalendarEvent; + } +} diff --git a/packages/calendar/src/storage/events/EventService.ts b/packages/calendar/src/storage/events/EventService.ts new file mode 100644 index 0000000..0ccd5a5 --- /dev/null +++ b/packages/calendar/src/storage/events/EventService.ts @@ -0,0 +1,84 @@ +import { ICalendarEvent, EntityType, IEventBus } from '../../types/CalendarTypes'; +import { EventStore } from './EventStore'; +import { EventSerialization } from './EventSerialization'; +import { BaseEntityService } from '../BaseEntityService'; +import { IndexedDBContext } from '../IndexedDBContext'; + +/** + * EventService - CRUD operations for calendar events in IndexedDB + * + * Extends BaseEntityService for shared CRUD and sync logic. + * Provides event-specific query methods. + */ +export class EventService extends BaseEntityService { + readonly storeName = EventStore.STORE_NAME; + readonly entityType: EntityType = 'Event'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + protected serialize(event: ICalendarEvent): unknown { + return EventSerialization.serialize(event); + } + + protected deserialize(data: unknown): ICalendarEvent { + return EventSerialization.deserialize(data as Record); + } + + /** + * Get events within a date range + */ + async getByDateRange(start: Date, end: Date): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('start'); + + const range = IDBKeyRange.lowerBound(start.toISOString()); + const request = index.getAll(range); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const events = data + .map(item => this.deserialize(item)) + .filter(event => event.start <= end); + resolve(events); + }; + + request.onerror = () => { + reject(new Error(`Failed to get events by date range: ${request.error}`)); + }; + }); + } + + /** + * Get events for a specific resource + */ + async getByResource(resourceId: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('resourceId'); + const request = index.getAll(resourceId); + + request.onsuccess = () => { + const data = request.result as unknown[]; + const events = data.map(item => this.deserialize(item)); + resolve(events); + }; + + request.onerror = () => { + reject(new Error(`Failed to get events for resource ${resourceId}: ${request.error}`)); + }; + }); + } + + /** + * Get events for a resource within a date range + */ + async getByResourceAndDateRange(resourceId: string, start: Date, end: Date): Promise { + const resourceEvents = await this.getByResource(resourceId); + return resourceEvents.filter(event => event.start >= start && event.start <= end); + } +} diff --git a/packages/calendar/src/storage/events/EventStore.ts b/packages/calendar/src/storage/events/EventStore.ts new file mode 100644 index 0000000..21c7be0 --- /dev/null +++ b/packages/calendar/src/storage/events/EventStore.ts @@ -0,0 +1,37 @@ +import { IStore } from '../IStore'; + +/** + * EventStore - IndexedDB ObjectStore definition for calendar events + */ +export class EventStore implements IStore { + static readonly STORE_NAME = 'events'; + readonly storeName = EventStore.STORE_NAME; + + /** + * Create the events ObjectStore with indexes + */ + create(db: IDBDatabase): void { + const store = db.createObjectStore(EventStore.STORE_NAME, { keyPath: 'id' }); + + // Index: start (for date range queries) + store.createIndex('start', 'start', { unique: false }); + + // Index: end (for date range queries) + store.createIndex('end', 'end', { unique: false }); + + // Index: syncStatus (for filtering by sync state) + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + + // Index: resourceId (for resource-mode filtering) + store.createIndex('resourceId', 'resourceId', { unique: false }); + + // Index: customerId (for customer-centric queries) + store.createIndex('customerId', 'customerId', { unique: false }); + + // Index: bookingId (for event-to-booking lookups) + store.createIndex('bookingId', 'bookingId', { unique: false }); + + // Compound index: startEnd (for optimized range queries) + store.createIndex('startEnd', ['start', 'end'], { unique: false }); + } +} diff --git a/packages/calendar/src/storage/resources/ResourceService.ts b/packages/calendar/src/storage/resources/ResourceService.ts new file mode 100644 index 0000000..769210c --- /dev/null +++ b/packages/calendar/src/storage/resources/ResourceService.ts @@ -0,0 +1,55 @@ +import { IResource, EntityType, IEventBus } from '../../types/CalendarTypes'; +import { ResourceStore } from './ResourceStore'; +import { BaseEntityService } from '../BaseEntityService'; +import { IndexedDBContext } from '../IndexedDBContext'; + +/** + * ResourceService - CRUD operations for resources in IndexedDB + */ +export class ResourceService extends BaseEntityService { + readonly storeName = ResourceStore.STORE_NAME; + readonly entityType: EntityType = 'Resource'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + /** + * Get all active resources + */ + async getActive(): Promise { + const all = await this.getAll(); + return all.filter(r => r.isActive !== false); + } + + /** + * Get resources by IDs + */ + async getByIds(ids: string[]): Promise { + if (ids.length === 0) return []; + + const results = await Promise.all(ids.map(id => this.get(id))); + return results.filter((r): r is IResource => r !== null); + } + + /** + * Get resources by type + */ + async getByType(type: string): Promise { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], 'readonly'); + const store = transaction.objectStore(this.storeName); + const index = store.index('type'); + const request = index.getAll(type); + + request.onsuccess = () => { + const data = request.result as IResource[]; + resolve(data); + }; + + request.onerror = () => { + reject(new Error(`Failed to get resources by type ${type}: ${request.error}`)); + }; + }); + } +} diff --git a/packages/calendar/src/storage/resources/ResourceStore.ts b/packages/calendar/src/storage/resources/ResourceStore.ts new file mode 100644 index 0000000..38e39b6 --- /dev/null +++ b/packages/calendar/src/storage/resources/ResourceStore.ts @@ -0,0 +1,17 @@ +import { IStore } from '../IStore'; + +/** + * ResourceStore - IndexedDB ObjectStore definition for resources + */ +export class ResourceStore implements IStore { + static readonly STORE_NAME = 'resources'; + readonly storeName = ResourceStore.STORE_NAME; + + create(db: IDBDatabase): void { + const store = db.createObjectStore(ResourceStore.STORE_NAME, { keyPath: 'id' }); + + store.createIndex('type', 'type', { unique: false }); + store.createIndex('syncStatus', 'syncStatus', { unique: false }); + store.createIndex('isActive', 'isActive', { unique: false }); + } +} diff --git a/packages/calendar/src/storage/settings/SettingsService.ts b/packages/calendar/src/storage/settings/SettingsService.ts new file mode 100644 index 0000000..5bc57b4 --- /dev/null +++ b/packages/calendar/src/storage/settings/SettingsService.ts @@ -0,0 +1,83 @@ +import { EntityType, IEventBus } from '../../types/CalendarTypes'; +import { + TenantSetting, + IWorkweekSettings, + IGridSettings, + ITimeFormatSettings, + IViewSettings, + IWorkweekPreset, + SettingsIds +} from '../../types/SettingsTypes'; +import { SettingsStore } from './SettingsStore'; +import { BaseEntityService } from '../BaseEntityService'; +import { IndexedDBContext } from '../IndexedDBContext'; + +/** + * SettingsService - CRUD operations for tenant settings + * + * Settings are stored as separate records per section. + * This service provides typed methods for accessing specific settings. + */ +export class SettingsService extends BaseEntityService { + readonly storeName = SettingsStore.STORE_NAME; + readonly entityType: EntityType = 'Settings'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + /** + * Get workweek settings + */ + async getWorkweekSettings(): Promise { + return this.get(SettingsIds.WORKWEEK) as Promise; + } + + /** + * Get grid settings + */ + async getGridSettings(): Promise { + return this.get(SettingsIds.GRID) as Promise; + } + + /** + * Get time format settings + */ + async getTimeFormatSettings(): Promise { + return this.get(SettingsIds.TIME_FORMAT) as Promise; + } + + /** + * Get view settings + */ + async getViewSettings(): Promise { + return this.get(SettingsIds.VIEWS) as Promise; + } + + /** + * Get workweek preset by ID + */ + async getWorkweekPreset(presetId: string): Promise { + const settings = await this.getWorkweekSettings(); + if (!settings) return null; + return settings.presets[presetId] || null; + } + + /** + * Get the default workweek preset + */ + async getDefaultWorkweekPreset(): Promise { + const settings = await this.getWorkweekSettings(); + if (!settings) return null; + return settings.presets[settings.defaultPreset] || null; + } + + /** + * Get all available workweek presets + */ + async getWorkweekPresets(): Promise { + const settings = await this.getWorkweekSettings(); + if (!settings) return []; + return Object.values(settings.presets); + } +} diff --git a/packages/calendar/src/storage/settings/SettingsStore.ts b/packages/calendar/src/storage/settings/SettingsStore.ts new file mode 100644 index 0000000..a28cc79 --- /dev/null +++ b/packages/calendar/src/storage/settings/SettingsStore.ts @@ -0,0 +1,16 @@ +import { IStore } from '../IStore'; + +/** + * SettingsStore - IndexedDB ObjectStore definition for tenant settings + * + * Single store for all settings sections. Settings are stored as one document + * per tenant with id='tenant-settings'. + */ +export class SettingsStore implements IStore { + static readonly STORE_NAME = 'settings'; + readonly storeName = SettingsStore.STORE_NAME; + + create(db: IDBDatabase): void { + db.createObjectStore(SettingsStore.STORE_NAME, { keyPath: 'id' }); + } +} diff --git a/packages/calendar/src/storage/viewconfigs/ViewConfigService.ts b/packages/calendar/src/storage/viewconfigs/ViewConfigService.ts new file mode 100644 index 0000000..03a42f7 --- /dev/null +++ b/packages/calendar/src/storage/viewconfigs/ViewConfigService.ts @@ -0,0 +1,18 @@ +import { EntityType, IEventBus } from '../../types/CalendarTypes'; +import { ViewConfig } from '../../core/ViewConfig'; +import { ViewConfigStore } from './ViewConfigStore'; +import { BaseEntityService } from '../BaseEntityService'; +import { IndexedDBContext } from '../IndexedDBContext'; + +export class ViewConfigService extends BaseEntityService { + readonly storeName = ViewConfigStore.STORE_NAME; + readonly entityType: EntityType = 'ViewConfig'; + + constructor(context: IndexedDBContext, eventBus: IEventBus) { + super(context, eventBus); + } + + async getById(id: string): Promise { + return this.get(id); + } +} diff --git a/packages/calendar/src/storage/viewconfigs/ViewConfigStore.ts b/packages/calendar/src/storage/viewconfigs/ViewConfigStore.ts new file mode 100644 index 0000000..fb02d07 --- /dev/null +++ b/packages/calendar/src/storage/viewconfigs/ViewConfigStore.ts @@ -0,0 +1,10 @@ +import { IStore } from '../IStore'; + +export class ViewConfigStore implements IStore { + static readonly STORE_NAME = 'viewconfigs'; + readonly storeName = ViewConfigStore.STORE_NAME; + + create(db: IDBDatabase): void { + db.createObjectStore(ViewConfigStore.STORE_NAME, { keyPath: 'id' }); + } +} diff --git a/packages/calendar/src/types/AuditTypes.ts b/packages/calendar/src/types/AuditTypes.ts new file mode 100644 index 0000000..3c0eb9f --- /dev/null +++ b/packages/calendar/src/types/AuditTypes.ts @@ -0,0 +1,46 @@ +import { ISync, EntityType } from './CalendarTypes'; + +/** + * IAuditEntry - Audit log entry for tracking all entity changes + * + * Used for: + * - Compliance and audit trail + * - Sync tracking with backend + * - Change history + */ +export interface IAuditEntry extends ISync { + /** Unique audit entry ID */ + id: string; + + /** Type of entity that was changed */ + entityType: EntityType; + + /** ID of the entity that was changed */ + entityId: string; + + /** Type of operation performed */ + operation: 'create' | 'update' | 'delete'; + + /** User who made the change */ + userId: string; + + /** Timestamp when change was made */ + timestamp: number; + + /** Changes made (full entity for create, diff for update, { id } for delete) */ + changes: unknown; + + /** Whether this audit entry has been synced to backend */ + synced: boolean; +} + +/** + * IAuditLoggedPayload - Event payload when audit entry is logged + */ +export interface IAuditLoggedPayload { + auditId: string; + entityType: EntityType; + entityId: string; + operation: 'create' | 'update' | 'delete'; + timestamp: number; +} diff --git a/packages/calendar/src/types/CalendarTypes.ts b/packages/calendar/src/types/CalendarTypes.ts new file mode 100644 index 0000000..c7aa21c --- /dev/null +++ b/packages/calendar/src/types/CalendarTypes.ts @@ -0,0 +1,170 @@ +/** + * Calendar Type Definitions + */ + +import { IWeekSchedule } from './ScheduleTypes'; + +export type SyncStatus = 'synced' | 'pending' | 'error'; + +export type EntityType = 'Event' | 'Booking' | 'Customer' | 'Resource' | 'Team' | 'Department' | 'Audit' | 'Settings' | 'ViewConfig'; + +/** + * CalendarEventType - Used by ICalendarEvent.type + * Note: Only 'customer' events have associated IBooking + */ +export type CalendarEventType = + | 'customer' // Customer appointment (HAS booking) + | 'vacation' // Vacation/time off (NO booking) + | 'break' // Lunch/break (NO booking) + | 'meeting' // Meeting (NO booking) + | 'blocked'; // Blocked time (NO booking) + +/** + * ISync - Interface for sync status tracking + * All syncable entities should extend this interface + */ +export interface ISync { + syncStatus: SyncStatus; +} + +/** + * IDataEntity - Wrapper for entity data with typename discriminator + */ +export interface IDataEntity { + typename: EntityType; + data: unknown; +} + +export interface ICalendarEvent extends ISync { + id: string; + title: string; + description?: string; + start: Date; + end: Date; + type: CalendarEventType; + allDay: boolean; + + // References (denormalized for IndexedDB performance) + bookingId?: string; // Reference to booking (only if type = 'customer') + resourceId?: string; // Resource who owns this time slot + customerId?: string; // Denormalized from Booking.customerId + + recurringId?: string; + metadata?: Record; +} + +// EventBus types +export interface IEventLogEntry { + type: string; + detail: unknown; + timestamp: number; +} + +export interface IListenerEntry { + eventType: string; + handler: EventListener; + options?: AddEventListenerOptions; +} + +export interface IEventBus { + on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void; + once(eventType: string, handler: EventListener): () => void; + off(eventType: string, handler: EventListener): void; + emit(eventType: string, detail?: unknown): boolean; + getEventLog(eventType?: string): IEventLogEntry[]; + setDebug(enabled: boolean): void; +} + +// Entity event payloads +export interface IEntitySavedPayload { + entityType: EntityType; + entityId: string; + operation: 'create' | 'update'; + changes: unknown; + timestamp: number; +} + +export interface IEntityDeletedPayload { + entityType: EntityType; + entityId: string; + operation: 'delete'; + timestamp: number; +} + +// Event update payload (for re-rendering columns after drag/resize) +export interface IEventUpdatedPayload { + eventId: string; + sourceColumnKey: string; // Source column key (where event came from) + targetColumnKey: string; // Target column key (where event landed) +} + +// Resource types +export type ResourceType = + | 'person' + | 'room' + | 'equipment' + | 'vehicle' + | 'custom'; + +export interface IResource extends ISync { + id: string; + name: string; + displayName: string; + type: ResourceType; + avatarUrl?: string; + color?: string; + isActive?: boolean; + defaultSchedule?: IWeekSchedule; // Default arbejdstider per ugedag + metadata?: Record; +} + +// Team types +export interface ITeam extends ISync { + id: string; + name: string; + resourceIds: string[]; +} + +// Department types +export interface IDepartment extends ISync { + id: string; + name: string; + resourceIds: string[]; +} + +// Booking types +export type BookingStatus = + | 'created' + | 'arrived' + | 'paid' + | 'noshow' + | 'cancelled'; + +export interface IBookingService { + serviceId: string; + serviceName: string; + baseDuration: number; + basePrice: number; + customPrice?: number; + resourceId: string; +} + +export interface IBooking extends ISync { + id: string; + customerId: string; + status: BookingStatus; + createdAt: Date; + services: IBookingService[]; + totalPrice?: number; + tags?: string[]; + notes?: string; +} + +// Customer types +export interface ICustomer extends ISync { + id: string; + name: string; + phone: string; + email?: string; + metadata?: Record; +} diff --git a/packages/calendar/src/types/DragTypes.ts b/packages/calendar/src/types/DragTypes.ts new file mode 100644 index 0000000..d63c1a8 --- /dev/null +++ b/packages/calendar/src/types/DragTypes.ts @@ -0,0 +1,76 @@ +/** + * DragTypes - Event payloads for drag-drop operations + */ + +import { SwpEvent } from './SwpEvent'; + +export interface IMousePosition { + x: number; + y: number; +} + +export interface IDragStartPayload { + eventId: string; + element: HTMLElement; // Original element (being dragged) + ghostElement: HTMLElement; // Ghost clone (stays in place) + startY: number; // Original Y position + mouseOffset: IMousePosition; // Click position within element + columnElement: HTMLElement; +} + +export interface IDragMovePayload { + eventId: string; + element: HTMLElement; + currentY: number; // Interpolated Y position (smooth) + columnElement: HTMLElement; +} + +export interface IDragEndPayload { + swpEvent: SwpEvent; // Wrapper with element, start, end, eventId, columnKey + sourceColumnKey: string; // Source column key (where drag started) + target: 'grid' | 'header'; // Where the event was dropped +} + +export interface IDragCancelPayload { + eventId: string; + element: HTMLElement; + startY: number; // Position to animate back to +} + +export interface IDragColumnChangePayload { + eventId: string; + element: HTMLElement; + previousColumn: HTMLElement; + newColumn: HTMLElement; + currentY: number; +} + +// Header drag payloads +export interface IDragEnterHeaderPayload { + eventId: string; + element: HTMLElement; // Original dragged element + sourceColumnIndex: number; + sourceColumnKey: string; // Opaque column identifier (for matching only) + title: string; + colorClass?: string; + itemType: 'event' | 'reminder'; + duration: number; // Antal dage (default 1) +} + +export interface IDragMoveHeaderPayload { + eventId: string; + columnIndex: number; + columnKey: string; // Opaque column identifier (for matching only) +} + +export interface IDragLeaveHeaderPayload { + eventId: string; + source: 'grid' | 'header'; // Where drag originated + // Header→grid fields (when source === 'header') + element?: HTMLElement; // Header item element + targetColumn?: HTMLElement; // Target column in grid + start?: Date; // Event start from header item + end?: Date; // Event end from header item + title?: string; + colorClass?: string; +} diff --git a/packages/calendar/src/types/ResizeTypes.ts b/packages/calendar/src/types/ResizeTypes.ts new file mode 100644 index 0000000..75caf6b --- /dev/null +++ b/packages/calendar/src/types/ResizeTypes.ts @@ -0,0 +1,15 @@ +/** + * ResizeTypes - Event payloads for resize operations + */ + +import { SwpEvent } from './SwpEvent'; + +export interface IResizeStartPayload { + eventId: string; + element: HTMLElement; + startHeight: number; +} + +export interface IResizeEndPayload { + swpEvent: SwpEvent; // Wrapper with element, start, end, eventId, resourceId +} diff --git a/packages/calendar/src/types/ScheduleTypes.ts b/packages/calendar/src/types/ScheduleTypes.ts new file mode 100644 index 0000000..65bfee7 --- /dev/null +++ b/packages/calendar/src/types/ScheduleTypes.ts @@ -0,0 +1,27 @@ +/** + * Schedule Types - Resource arbejdstider + */ + +// Genbrugelig tidsslot +export interface ITimeSlot { + start: string; // "HH:mm" + end: string; // "HH:mm" +} + +// Ugedag: 1=mandag, 7=søndag (ISO 8601) +export type WeekDay = 1 | 2 | 3 | 4 | 5 | 6 | 7; + +// Default arbejdstider per ugedag +export interface IWeekSchedule { + [day: number]: ITimeSlot | null; // null = fri den dag +} + +// Override for specifik dato +export interface IScheduleOverride { + id: string; + resourceId: string; + date: string; // "YYYY-MM-DD" + schedule: ITimeSlot | null; // null = fri den dag + breaks?: ITimeSlot[]; + syncStatus?: 'synced' | 'pending' | 'error'; +} diff --git a/packages/calendar/src/types/SettingsTypes.ts b/packages/calendar/src/types/SettingsTypes.ts new file mode 100644 index 0000000..5ae47aa --- /dev/null +++ b/packages/calendar/src/types/SettingsTypes.ts @@ -0,0 +1,78 @@ +/** + * Tenant Settings Type Definitions + * + * Settings are tenant-specific configuration that comes from the backend + * and is stored in IndexedDB for offline access. + * + * Each settings section is stored as a separate record with its own id. + */ + +import { ISync } from './CalendarTypes'; + +/** + * Workweek preset - defines which ISO weekdays to display + * ISO: 1=Monday, 7=Sunday + */ +export interface IWorkweekPreset { + id: string; + workDays: number[]; + label: string; + periodDays: number; // Navigation step in days (1 = day, 7 = week) +} + +/** + * Workweek settings - stored as separate record + */ +export interface IWorkweekSettings extends ISync { + id: 'workweek'; + presets: Record; + defaultPreset: string; + firstDayOfWeek: number; // ISO: 1=Monday +} + +/** + * Grid display settings - stored as separate record + */ +export interface IGridSettings extends ISync { + id: 'grid'; + dayStartHour: number; + dayEndHour: number; + workStartHour: number; + workEndHour: number; + hourHeight: number; + snapInterval: number; +} + +/** + * Time format settings - stored as separate record + */ +export interface ITimeFormatSettings extends ISync { + id: 'timeFormat'; + timezone: string; + locale: string; + use24HourFormat: boolean; +} + +/** + * View settings - stored as separate record + */ +export interface IViewSettings extends ISync { + id: 'views'; + availableViews: string[]; + defaultView: string; +} + +/** + * Union type for all tenant settings records + */ +export type TenantSetting = IWorkweekSettings | IGridSettings | ITimeFormatSettings | IViewSettings; + +/** + * Settings IDs as const for type safety + */ +export const SettingsIds = { + WORKWEEK: 'workweek', + GRID: 'grid', + TIME_FORMAT: 'timeFormat', + VIEWS: 'views' +} as const; diff --git a/packages/calendar/src/types/SwpEvent.ts b/packages/calendar/src/types/SwpEvent.ts new file mode 100644 index 0000000..ff8373b --- /dev/null +++ b/packages/calendar/src/types/SwpEvent.ts @@ -0,0 +1,79 @@ +import { IGridConfig } from '../core/IGridConfig'; + +/** + * SwpEvent - Wrapper class for calendar event elements + * + * Encapsulates an HTMLElement and provides computed properties + * for start/end times based on element position and grid config. + * + * Usage: + * - eventId is read from element.dataset + * - columnKey identifies the column uniformly + * - Position (top, height) is read from element.style + * - Factory method `fromElement()` calculates Date objects + */ +export class SwpEvent { + readonly element: HTMLElement; + readonly columnKey: string; + private _start: Date; + private _end: Date; + + constructor(element: HTMLElement, columnKey: string, start: Date, end: Date) { + this.element = element; + this.columnKey = columnKey; + this._start = start; + this._end = end; + } + + /** Event ID from element.dataset.eventId */ + get eventId(): string { + return this.element.dataset.eventId || ''; + } + + get start(): Date { + return this._start; + } + + get end(): Date { + return this._end; + } + + /** Duration in minutes */ + get durationMinutes(): number { + return (this._end.getTime() - this._start.getTime()) / (1000 * 60); + } + + /** Duration in milliseconds */ + get durationMs(): number { + return this._end.getTime() - this._start.getTime(); + } + + /** + * Factory: Create SwpEvent from element + columnKey + * Reads top/height from element.style to calculate start/end + * @param columnKey - Opaque column identifier (do NOT parse - use only for matching) + * @param date - Date string (YYYY-MM-DD) for time calculations + */ + static fromElement( + element: HTMLElement, + columnKey: string, + date: string, + gridConfig: IGridConfig + ): SwpEvent { + const topPixels = parseFloat(element.style.top) || 0; + const heightPixels = parseFloat(element.style.height) || 0; + + // Calculate start from top position + const startMinutesFromGrid = (topPixels / gridConfig.hourHeight) * 60; + const totalMinutes = (gridConfig.dayStartHour * 60) + startMinutesFromGrid; + + const start = new Date(date); + start.setHours(Math.floor(totalMinutes / 60), totalMinutes % 60, 0, 0); + + // Calculate end from height + const durationMinutes = (heightPixels / gridConfig.hourHeight) * 60; + const end = new Date(start.getTime() + durationMinutes * 60 * 1000); + + return new SwpEvent(element, columnKey, start, end); + } +} diff --git a/packages/calendar/src/utils/PositionUtils.ts b/packages/calendar/src/utils/PositionUtils.ts new file mode 100644 index 0000000..5c99e4b --- /dev/null +++ b/packages/calendar/src/utils/PositionUtils.ts @@ -0,0 +1,55 @@ +/** + * PositionUtils - Pixel/position calculations for calendar grid + * + * RESPONSIBILITY: Convert between time and pixel positions + * NOTE: Date formatting belongs in DateService, not here + */ + +import { IGridConfig } from '../core/IGridConfig'; + +export interface EventPosition { + top: number; // pixels from day start + height: number; // pixels +} + +/** + * Calculate pixel position for an event based on its times + */ +export function calculateEventPosition( + start: Date, + end: Date, + config: IGridConfig +): EventPosition { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + + return { top, height }; +} + +/** + * Convert minutes to pixels + */ +export function minutesToPixels(minutes: number, config: IGridConfig): number { + return (minutes / 60) * config.hourHeight; +} + +/** + * Convert pixels to minutes + */ +export function pixelsToMinutes(pixels: number, config: IGridConfig): number { + return (pixels / config.hourHeight) * 60; +} + +/** + * Snap pixel position to grid interval + */ +export function snapToGrid(pixels: number, config: IGridConfig): number { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} diff --git a/packages/calendar/tsconfig.json b/packages/calendar/tsconfig.json new file mode 100644 index 0000000..c1c4978 --- /dev/null +++ b/packages/calendar/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationDir": "./dist", + "outDir": "./dist", + "rootDir": "./src", + "sourceMap": true, + "lib": ["ES2024", "DOM", "DOM.Iterable"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/test-package/build.js b/test-package/build.js new file mode 100644 index 0000000..07cf9e7 --- /dev/null +++ b/test-package/build.js @@ -0,0 +1,23 @@ +import esbuild from 'esbuild'; +import { NovadiUnplugin } from '@novadi/core/unplugin'; +import { copyFileSync, mkdirSync } from 'fs'; + +// Ensure dist/css directory exists +mkdirSync('dist/css', { recursive: true }); + +// Copy calendar CSS +copyFileSync( + 'node_modules/calendar/dist/css/calendar.css', + 'dist/css/calendar.css' +); + +await esbuild.build({ + entryPoints: ['src/index.ts'], + bundle: true, + outfile: 'dist/bundle.js', + format: 'esm', + platform: 'browser', + plugins: [NovadiUnplugin.esbuild()] +}); + +console.log('Build complete'); diff --git a/test-package/dist/bundle.js b/test-package/dist/bundle.js new file mode 100644 index 0000000..71cc1e8 --- /dev/null +++ b/test-package/dist/bundle.js @@ -0,0 +1,5289 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports, module) { + !(function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + })(exports, (function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, w = function t2(e2, n2, r2) { + var i2; + if (!e2) return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, O = function(t2, e2) { + if (S(t2)) return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = (function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = (function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + })(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === c) return this.set(c, this.$M + r2); + if ($2 === h) return this.set(h, this.$y + r2); + if ($2 === a) return y2(1); + if ($2 === o) return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, d2 = function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, (function(t3, r3) { + return r3 || (function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + })(t3) || i2.replace(":", ""); + })); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() { + return b.m(y2, m3); + }; + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + })(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach((function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + })), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + })); + } +}); + +// node_modules/dayjs/plugin/utc.js +var require_utc = __commonJS({ + "node_modules/dayjs/plugin/utc.js"(exports, module) { + !(function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + })(exports, (function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var r = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2); + }; + var o = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else o.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = (function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + })(s2), null === s2)) return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2; + if (0 === u2) return this.utc(f2); + var r2 = this.clone(); + if (f2) return r2.$offset = u2, r2.$u = false, r2; + var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + })); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports, module) { + !(function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + })(exports, (function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = (function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + })(n2, i2); + return r2.formatToParts(o2); + }, u = function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find((function(t3) { + return "timezonename" === t3.type.toLowerCase(); + })); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) return o(t2).tz(a2); + var s2 = (function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + })(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + })); + } +}); + +// node_modules/dayjs/plugin/isoWeek.js +var require_isoWeek = __commonJS({ + "node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !(function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + })(exports, (function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + })); + } +}); + +// node_modules/@novadi/core/dist/token.js +var tokenCounter = 0; +function Token(description) { + const id = ++tokenCounter; + const sym = /* @__PURE__ */ Symbol(description ? `Token(${description})` : `Token#${id}`); + const token2 = { + symbol: sym, + description, + toString() { + return description ? `Token<${description}>` : `Token<#${id}>`; + } + }; + return token2; +} + +// node_modules/@novadi/core/dist/errors.js +var ContainerError = class extends Error { + constructor(message) { + super(message); + this.name = "ContainerError"; + } +}; +var BindingNotFoundError = class extends ContainerError { + constructor(tokenDescription, path = []) { + const pathStr = path.length > 0 ? ` + Dependency path: ${path.join(" -> ")}` : ""; + super(`Token "${tokenDescription}" is not bound or registered in the container.${pathStr}`); + this.name = "BindingNotFoundError"; + } +}; +var CircularDependencyError = class extends ContainerError { + constructor(path) { + super(`Circular dependency detected: ${path.join(" -> ")}`); + this.name = "CircularDependencyError"; + } +}; + +// node_modules/@novadi/core/dist/autowire.js +var paramNameCache = /* @__PURE__ */ new WeakMap(); +function extractParameterNames(constructor) { + const cached = paramNameCache.get(constructor); + if (cached) { + return cached; + } + const fnStr = constructor.toString(); + const match = fnStr.match(/constructor\s*\(([^)]*)\)/) || fnStr.match(/^[^(]*\(([^)]*)\)/); + if (!match || !match[1]) { + return []; + } + const params = match[1].split(",").map((param) => param.trim()).filter((param) => param.length > 0).map((param) => { + let name = param.split(/[:=]/)[0].trim(); + name = name.replace(/^((public|private|protected|readonly)\s+)+/, ""); + if (name.includes("{") || name.includes("[")) { + return null; + } + return name; + }).filter((name) => name !== null); + paramNameCache.set(constructor, params); + return params; +} +function resolveByMap(constructor, container, options) { + if (!options.map) { + throw new Error("AutoWire map strategy requires options.map to be defined"); + } + const paramNames = extractParameterNames(constructor); + const resolvedDeps = []; + for (const paramName of paramNames) { + const resolver = options.map[paramName]; + if (resolver === void 0) { + if (options.strict) { + throw new Error(`Cannot resolve parameter "${paramName}" on ${constructor.name}. Not found in autowire map. Add it to the map: .autoWire({ map: { ${paramName}: ... } })`); + } else { + resolvedDeps.push(void 0); + } + continue; + } + if (typeof resolver === "function") { + resolvedDeps.push(resolver(container)); + } else { + resolvedDeps.push(container.resolve(resolver)); + } + } + return resolvedDeps; +} +function resolveByMapResolvers(_constructor, container, options) { + if (!options.mapResolvers || options.mapResolvers.length === 0) { + return []; + } + const resolvedDeps = []; + for (let i = 0; i < options.mapResolvers.length; i++) { + const resolver = options.mapResolvers[i]; + if (resolver === void 0) { + resolvedDeps.push(void 0); + } else if (typeof resolver === "function") { + resolvedDeps.push(resolver(container)); + } else { + resolvedDeps.push(container.resolve(resolver)); + } + } + return resolvedDeps; +} +function autowire(constructor, container, options) { + const opts = { + by: "paramName", + strict: false, + ...options + }; + if (opts.mapResolvers && opts.mapResolvers.length > 0) { + return resolveByMapResolvers(constructor, container, opts); + } + if (opts.map && Object.keys(opts.map).length > 0) { + return resolveByMap(constructor, container, opts); + } + return []; +} + +// node_modules/@novadi/core/dist/builder.js +var RegistrationBuilder = class { + constructor(pending, registrations) { + this.registrations = registrations; + this.configs = []; + this.defaultLifetime = "singleton"; + this.pending = pending; + } + /** + * Bind this registration to a token or interface type + * + * @overload + * @param {Token} token - Explicit token for binding + * + * @overload + * @param {string} typeName - Interface type name (auto-generated by transformer) + */ + as(tokenOrTypeName) { + if (tokenOrTypeName && typeof tokenOrTypeName === "object" && "symbol" in tokenOrTypeName) { + const config = { + token: tokenOrTypeName, + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } else { + const config = { + token: null, + // Will be set during build() + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime, + interfaceType: tokenOrTypeName + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } + } + /** + * Register as default implementation for an interface + * Combines as() + asDefault() + */ + asDefaultInterface(typeName) { + this.as("TInterface", typeName); + return this.asDefault(); + } + /** + * Register as a keyed interface implementation + * Combines as() + keyed() + */ + asKeyedInterface(key, typeName) { + this.as("TInterface", typeName); + return this.keyed(key); + } + /** + * Register as multiple implemented interfaces + */ + asImplementedInterfaces(tokens) { + if (tokens.length === 0) { + return this; + } + if (this.configs.length > 0) { + for (const config of this.configs) { + config.lifetime = "singleton"; + config.additionalTokens = config.additionalTokens || []; + config.additionalTokens.push(...tokens); + } + return this; + } + const firstConfig = { + token: tokens[0], + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: "singleton" + }; + this.configs.push(firstConfig); + this.registrations.push(firstConfig); + for (let i = 1; i < tokens.length; i++) { + firstConfig.additionalTokens = firstConfig.additionalTokens || []; + firstConfig.additionalTokens.push(tokens[i]); + } + return this; + } + /** + * Set singleton lifetime (one instance for entire container) + */ + singleInstance() { + for (const config of this.configs) { + config.lifetime = "singleton"; + } + return this; + } + /** + * Set per-request lifetime (one instance per resolve call tree) + */ + instancePerRequest() { + for (const config of this.configs) { + config.lifetime = "per-request"; + } + return this; + } + /** + * Set transient lifetime (new instance every time) + * Alias for default behavior + */ + instancePerDependency() { + for (const config of this.configs) { + config.lifetime = "transient"; + } + return this; + } + /** + * Name this registration for named resolution + */ + named(name) { + for (const config of this.configs) { + config.name = name; + } + return this; + } + /** + * Key this registration for keyed resolution + */ + keyed(key) { + for (const config of this.configs) { + config.key = key; + } + return this; + } + /** + * Mark this as default registration + * Default registrations don't override existing ones + */ + asDefault() { + for (const config of this.configs) { + config.isDefault = true; + } + return this; + } + /** + * Only register if token not already registered + */ + ifNotRegistered() { + for (const config of this.configs) { + config.ifNotRegistered = true; + } + return this; + } + /** + * Specify parameter values for constructor (primitives and constants) + * Use this for non-DI parameters like strings, numbers, config values + */ + withParameters(parameters) { + for (const config of this.configs) { + config.parameterValues = parameters; + } + return this; + } + /** + * Enable automatic dependency injection (autowiring) + * Supports three strategies: paramName (default), map, and class + * + * @example + * ```ts + * // Strategy 1: paramName (default, requires non-minified code in dev) + * builder.registerType(EventBus).as().autoWire() + * + * // Strategy 2: map (minify-safe, explicit) + * builder.registerType(EventBus).as().autoWire({ + * map: { + * logger: (c) => c.resolveType() + * } + * }) + * + * // Strategy 3: class (requires build-time codegen) + * builder.registerType(EventBus).as().autoWire({ by: 'class' }) + * ``` + */ + autoWire(options) { + for (const config of this.configs) { + config.autowireOptions = options || { by: "paramName", strict: false }; + } + return this; + } +}; +var Builder = class { + constructor(baseContainer) { + this.baseContainer = baseContainer; + this.registrations = []; + } + /** + * Register a class constructor + */ + registerType(constructor) { + const pending = { + type: "type", + value: null, + constructor + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a pre-created instance + */ + registerInstance(instance) { + const pending = { + type: "instance", + value: instance, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a factory function + */ + register(factory) { + const pending = { + type: "factory", + value: null, + factory, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a module (function that adds multiple registrations) + */ + module(moduleFunc) { + moduleFunc(this); + return this; + } + /** + * Resolve interface type names to tokens + * @internal + */ + resolveInterfaceTokens(container) { + for (const config of this.registrations) { + if (config.interfaceType !== void 0 && !config.token) { + config.token = container.interfaceToken(config.interfaceType); + } + } + } + /** + * Identify tokens that have non-default registrations + * @internal + */ + identifyNonDefaultTokens() { + const tokensWithNonDefaults = /* @__PURE__ */ new Set(); + for (const config of this.registrations) { + if (!config.isDefault && !config.name && config.key === void 0) { + tokensWithNonDefaults.add(config.token); + } + } + return tokensWithNonDefaults; + } + /** + * Check if registration should be skipped + * @internal + */ + shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens) { + if (config.isDefault && !config.name && config.key === void 0 && tokensWithNonDefaults.has(config.token)) { + return true; + } + if (config.ifNotRegistered && registeredTokens.has(config.token)) { + return true; + } + if (config.isDefault && registeredTokens.has(config.token)) { + return true; + } + return false; + } + /** + * Create binding token for registration (named, keyed, or multi) + * @internal + */ + createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations) { + if (config.name) { + const bindingToken = Token(`__named_${config.name}`); + namedRegistrations.set(config.name, { ...config, token: bindingToken }); + return bindingToken; + } else if (config.key !== void 0) { + const keyStr = typeof config.key === "symbol" ? config.key.toString() : config.key; + const bindingToken = Token(`__keyed_${keyStr}`); + keyedRegistrations.set(config.key, { ...config, token: bindingToken }); + return bindingToken; + } else { + if (multiRegistrations.has(config.token)) { + const bindingToken = Token(`__multi_${config.token.toString()}_${multiRegistrations.get(config.token).length}`); + multiRegistrations.get(config.token).push(bindingToken); + return bindingToken; + } else { + multiRegistrations.set(config.token, [config.token]); + return config.token; + } + } + } + /** + * Register additional interfaces for a config + * @internal + */ + registerAdditionalInterfaces(container, config, bindingToken, registeredTokens) { + if (config.additionalTokens) { + for (const additionalToken of config.additionalTokens) { + container.bindFactory(additionalToken, (c) => c.resolve(bindingToken), { lifetime: config.lifetime }); + registeredTokens.add(additionalToken); + } + } + } + /** + * Build the container with all registered bindings + */ + build() { + const container = this.baseContainer.createChild(); + this.resolveInterfaceTokens(container); + const registeredTokens = /* @__PURE__ */ new Set(); + const namedRegistrations = /* @__PURE__ */ new Map(); + const keyedRegistrations = /* @__PURE__ */ new Map(); + const multiRegistrations = /* @__PURE__ */ new Map(); + const tokensWithNonDefaults = this.identifyNonDefaultTokens(); + for (const config of this.registrations) { + if (this.shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens)) { + continue; + } + const bindingToken = this.createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations); + this.applyRegistration(container, { ...config, token: bindingToken }); + registeredTokens.add(config.token); + this.registerAdditionalInterfaces(container, config, bindingToken, registeredTokens); + } + ; + container.__namedRegistrations = namedRegistrations; + container.__keyedRegistrations = keyedRegistrations; + container.__multiRegistrations = multiRegistrations; + return container; + } + /** + * Analyze constructor to detect dependencies + * @internal + */ + analyzeConstructor(constructor) { + const constructorStr = constructor.toString(); + const hasDependencies = /constructor\s*\([^)]+\)/.test(constructorStr); + return { hasDependencies }; + } + /** + * Create optimized factory for zero-dependency constructors + * @internal + */ + createOptimizedFactory(container, config, options) { + if (config.lifetime === "singleton") { + const instance = new config.constructor(); + container.bindValue(config.token, instance); + } else if (config.lifetime === "transient") { + const ctor = config.constructor; + const fastFactory = () => new ctor(); + container.fastTransientCache.set(config.token, fastFactory); + container.bindFactory(config.token, fastFactory, options); + } else { + const factory = () => new config.constructor(); + container.bindFactory(config.token, factory, options); + } + } + /** + * Create autowire factory + * @internal + */ + createAutoWireFactory(container, config, options) { + const factory = (c) => { + const resolvedDeps = autowire(config.constructor, c, config.autowireOptions); + return new config.constructor(...resolvedDeps); + }; + container.bindFactory(config.token, factory, options); + } + /** + * Create withParameters factory + * @internal + */ + createParameterFactory(container, config, options) { + const factory = () => { + const values = Object.values(config.parameterValues); + return new config.constructor(...values); + }; + container.bindFactory(config.token, factory, options); + } + /** + * Apply type registration (class constructor) + * @internal + */ + applyTypeRegistration(container, config, options) { + const { hasDependencies } = this.analyzeConstructor(config.constructor); + if (!hasDependencies && !config.autowireOptions && !config.parameterValues) { + this.createOptimizedFactory(container, config, options); + return; + } + if (config.autowireOptions) { + this.createAutoWireFactory(container, config, options); + return; + } + if (config.parameterValues) { + this.createParameterFactory(container, config, options); + return; + } + if (hasDependencies) { + const className = config.constructor.name || "UnnamedClass"; + throw new Error(`Service "${className}" has constructor dependencies but no autowiring configuration. + +Solutions: + 1. \u2B50 Use the NovaDI transformer (recommended): + - Add "@novadi/core/unplugin" to your build config + - Transformer automatically generates .autoWire() for all dependencies + + 2. Add manual autowiring: + .autoWire({ map: { /* param: resolver */ } }) + + 3. Use a factory function: + .register((c) => new ${className}(...)) + +See docs: https://github.com/janus007/NovaDI#autowire`); + } + const factory = () => new config.constructor(); + container.bindFactory(config.token, factory, options); + } + applyRegistration(container, config) { + const options = { lifetime: config.lifetime }; + switch (config.type) { + case "instance": + container.bindValue(config.token, config.value); + break; + case "factory": + container.bindFactory(config.token, config.factory, options); + break; + case "type": + this.applyTypeRegistration(container, config, options); + break; + } + } +}; + +// node_modules/@novadi/core/dist/container.js +function isDisposable(obj) { + return obj && typeof obj.dispose === "function"; +} +var ResolutionContext = class { + constructor() { + this.resolvingStack = /* @__PURE__ */ new Set(); + this.perRequestCache = /* @__PURE__ */ new Map(); + } + isResolving(token2) { + return this.resolvingStack.has(token2); + } + enterResolve(token2) { + this.resolvingStack.add(token2); + } + exitResolve(token2) { + this.resolvingStack.delete(token2); + this.path = void 0; + } + getPath() { + if (!this.path) { + this.path = Array.from(this.resolvingStack).map((t) => t.toString()); + } + return [...this.path]; + } + cachePerRequest(token2, instance) { + this.perRequestCache.set(token2, instance); + } + getPerRequest(token2) { + return this.perRequestCache.get(token2); + } + hasPerRequest(token2) { + return this.perRequestCache.has(token2); + } + /** + * Reset context for reuse in object pool + * Performance: Reusing contexts avoids heap allocations + */ + reset() { + this.resolvingStack.clear(); + this.perRequestCache.clear(); + this.path = void 0; + } +}; +var ResolutionContextPool = class { + constructor() { + this.pool = []; + this.maxSize = 10; + } + acquire() { + const context = this.pool.pop(); + if (context) { + context.reset(); + return context; + } + return new ResolutionContext(); + } + release(context) { + if (this.pool.length < this.maxSize) { + this.pool.push(context); + } + } +}; +var Container = class _Container { + constructor(parent) { + this.bindings = /* @__PURE__ */ new Map(); + this.singletonCache = /* @__PURE__ */ new Map(); + this.singletonOrder = []; + this.interfaceRegistry = /* @__PURE__ */ new Map(); + this.interfaceTokenCache = /* @__PURE__ */ new Map(); + this.fastTransientCache = /* @__PURE__ */ new Map(); + this.ultraFastSingletonCache = /* @__PURE__ */ new Map(); + this.parent = parent; + } + /** + * Bind a pre-created value to a token + */ + bindValue(token2, value) { + this.bindings.set(token2, { + type: "value", + lifetime: "singleton", + value, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a factory function to a token + */ + bindFactory(token2, factory, options) { + this.bindings.set(token2, { + type: "factory", + lifetime: options?.lifetime || "transient", + factory, + dependencies: options?.dependencies, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a class constructor to a token + */ + bindClass(token2, constructor, options) { + const binding = { + type: "class", + lifetime: options?.lifetime || "transient", + constructor, + dependencies: options?.dependencies + }; + this.bindings.set(token2, binding); + this.invalidateBindingCache(); + if (binding.lifetime === "transient" && (!binding.dependencies || binding.dependencies.length === 0)) { + this.fastTransientCache.set(token2, () => new constructor()); + } + } + /** + * Resolve a dependency synchronously + * Performance optimized with multiple fast paths + */ + resolve(token2) { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) { + return cached; + } + if (this.currentContext) { + return this.resolveWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return this.resolveWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * SPECIALIZED: Ultra-fast singleton resolve (no safety checks) + * Use ONLY when you're 100% sure the token is a registered singleton + * @internal For performance-critical paths only + */ + resolveSingletonUnsafe(token2) { + return this.ultraFastSingletonCache.get(token2) ?? this.singletonCache.get(token2); + } + /** + * SPECIALIZED: Fast transient resolve for zero-dependency classes + * Skips all context creation and circular dependency checks + * @internal For performance-critical paths only + */ + resolveTransientSimple(token2) { + const factory = this.fastTransientCache.get(token2); + if (factory) { + return factory(); + } + return this.resolve(token2); + } + /** + * SPECIALIZED: Batch resolve multiple dependencies at once + * More efficient than multiple individual resolves + */ + resolveBatch(tokens) { + const wasResolving = !!this.currentContext; + const context = this.currentContext || _Container.contextPool.acquire(); + if (!wasResolving) { + this.currentContext = context; + } + try { + const results = tokens.map((token2) => { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) + return cached; + return this.resolveWithContext(token2, context); + }); + return results; + } finally { + if (!wasResolving) { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + } + /** + * Resolve a dependency asynchronously (supports async factories) + */ + async resolveAsync(token2) { + if (this.currentContext) { + return this.resolveAsyncWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return await this.resolveAsyncWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * Try to get instance from all cache levels + * Returns undefined if not cached + * @internal + */ + tryGetFromCaches(token2) { + const ultraFast = this.ultraFastSingletonCache.get(token2); + if (ultraFast !== void 0) { + return ultraFast; + } + if (this.singletonCache.has(token2)) { + const cached = this.singletonCache.get(token2); + this.ultraFastSingletonCache.set(token2, cached); + return cached; + } + const fastFactory = this.fastTransientCache.get(token2); + if (fastFactory) { + return fastFactory(); + } + return void 0; + } + /** + * Cache instance based on lifetime strategy + * @internal + */ + cacheInstance(token2, instance, lifetime, context) { + if (lifetime === "singleton") { + this.singletonCache.set(token2, instance); + this.singletonOrder.push(token2); + this.ultraFastSingletonCache.set(token2, instance); + } else if (lifetime === "per-request" && context) { + context.cachePerRequest(token2, instance); + } + } + /** + * Validate and get binding with circular dependency check + * Returns binding or throws error + * @internal + */ + validateAndGetBinding(token2, context) { + if (context.isResolving(token2)) { + throw new CircularDependencyError([...context.getPath(), token2.toString()]); + } + const binding = this.getBinding(token2); + if (!binding) { + throw new BindingNotFoundError(token2.toString(), context.getPath()); + } + return binding; + } + /** + * Instantiate from binding synchronously + * @internal + */ + instantiateBindingSync(binding, token2, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + const result = binding.factory(this); + if (result instanceof Promise) { + throw new Error(`Async factory detected for ${token2.toString()}. Use resolveAsync() instead.`); + } + return result; + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = deps.map((dep) => this.resolveWithContext(dep, context)); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Instantiate from binding asynchronously + * @internal + */ + async instantiateBindingAsync(binding, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + return await Promise.resolve(binding.factory(this)); + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = await Promise.all(deps.map((dep) => this.resolveAsyncWithContext(dep, context))); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Create a child container that inherits bindings from this container + */ + createChild() { + return new _Container(this); + } + /** + * Dispose all singleton instances in reverse registration order + */ + async dispose() { + const errors = []; + for (let i = this.singletonOrder.length - 1; i >= 0; i--) { + const token2 = this.singletonOrder[i]; + const instance = this.singletonCache.get(token2); + if (instance && isDisposable(instance)) { + try { + await instance.dispose(); + } catch (error) { + errors.push(error); + } + } + } + this.singletonCache.clear(); + this.singletonOrder.length = 0; + } + /** + * Create a fluent builder for registering dependencies + */ + builder() { + return new Builder(this); + } + /** + * Resolve a named service + */ + resolveNamed(name) { + const namedRegistrations = this.__namedRegistrations; + if (!namedRegistrations) { + throw new Error(`Named service "${name}" not found. No named registrations exist.`); + } + const config = namedRegistrations.get(name); + if (!config) { + throw new Error(`Named service "${name}" not found`); + } + return this.resolve(config.token); + } + /** + * Resolve a keyed service + */ + resolveKeyed(key) { + const keyedRegistrations = this.__keyedRegistrations; + if (!keyedRegistrations) { + throw new Error(`Keyed service not found. No keyed registrations exist.`); + } + const config = keyedRegistrations.get(key); + if (!config) { + const keyStr = typeof key === "symbol" ? key.toString() : `"${key}"`; + throw new Error(`Keyed service ${keyStr} not found`); + } + return this.resolve(config.token); + } + /** + * Resolve all registrations for a token + */ + resolveAll(token2) { + const multiRegistrations = this.__multiRegistrations; + if (!multiRegistrations) { + return []; + } + const tokens = multiRegistrations.get(token2); + if (!tokens || tokens.length === 0) { + return []; + } + return tokens.map((t) => this.resolve(t)); + } + /** + * Get registry information for debugging/visualization + * Returns array of binding information + */ + getRegistry() { + const registry = []; + this.bindings.forEach((binding, token2) => { + registry.push({ + token: token2.description || token2.symbol.toString(), + type: binding.type, + lifetime: binding.lifetime, + dependencies: binding.dependencies?.map((d) => d.description || d.symbol.toString()) + }); + }); + return registry; + } + /** + * Get or create a token for an interface type + * Uses a type name hash as key for the interface registry + */ + interfaceToken(typeName) { + const key = typeName || `Interface_${Math.random().toString(36).substr(2, 9)}`; + if (this.interfaceRegistry.has(key)) { + return this.interfaceRegistry.get(key); + } + if (this.parent) { + const parentToken = this.parent.interfaceToken(key); + return parentToken; + } + const token2 = Token(key); + this.interfaceRegistry.set(key, token2); + return token2; + } + /** + * Resolve a dependency by interface type without explicit token + */ + resolveType(typeName) { + const key = typeName || ""; + let token2 = this.interfaceTokenCache.get(key); + if (!token2) { + token2 = this.interfaceToken(typeName); + this.interfaceTokenCache.set(key, token2); + } + return this.resolve(token2); + } + /** + * Resolve a keyed interface + */ + resolveTypeKeyed(key, _typeName) { + return this.resolveKeyed(key); + } + /** + * Resolve all registrations for an interface type + */ + resolveTypeAll(typeName) { + const token2 = this.interfaceToken(typeName); + return this.resolveAll(token2); + } + /** + * Internal: Resolve with context for circular dependency detection + */ + resolveWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = this.instantiateBindingSync(binding, token2, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Internal: Async resolve with context + */ + async resolveAsyncWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = await this.instantiateBindingAsync(binding, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Get binding from this container or parent chain + * Performance optimized: Uses flat cache to avoid recursive parent lookups + */ + getBinding(token2) { + if (!this.bindingCache) { + this.buildBindingCache(); + } + return this.bindingCache.get(token2); + } + /** + * Build flat cache of all bindings including parent chain + * This converts O(n) parent chain traversal to O(1) lookup + */ + buildBindingCache() { + this.bindingCache = /* @__PURE__ */ new Map(); + let current = this; + while (current) { + current.bindings.forEach((binding, token2) => { + if (!this.bindingCache.has(token2)) { + this.bindingCache.set(token2, binding); + } + }); + current = current.parent; + } + } + /** + * Invalidate binding cache when new bindings are added + * Called by bindValue, bindFactory, bindClass + */ + invalidateBindingCache() { + this.bindingCache = void 0; + this.ultraFastSingletonCache.clear(); + } +}; +Container.contextPool = new ResolutionContextPool(); + +// node_modules/calendar/dist/chunk-OPIZ4QQE.js +var BaseGroupingRenderer = class { + /** + * Main render method - handles common logic + */ + async render(context) { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) + return; + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter["date"]?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter((id) => childIds.includes(id)).length; + const colspan = childCount * dateCount; + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + this.renderHeader(entity, header, context); + context.headerContainer.appendChild(header); + } + } + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + renderHeader(entity, header, _context) { + header.textContent = this.getDisplayName(entity); + } + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + createHeader(entity, context) { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +}; + +// node_modules/calendar/dist/chunk-CMOI3H5F.js +var CoreEvents = { + // Lifecycle events + INITIALIZED: "core:initialized", + READY: "core:ready", + DESTROYED: "core:destroyed", + // View events + VIEW_CHANGED: "view:changed", + VIEW_RENDERED: "view:rendered", + // Navigation events + DATE_CHANGED: "nav:date-changed", + NAVIGATION_COMPLETED: "nav:navigation-completed", + // Data events + DATA_LOADING: "data:loading", + DATA_LOADED: "data:loaded", + DATA_ERROR: "data:error", + // Grid events + GRID_RENDERED: "grid:rendered", + GRID_CLICKED: "grid:clicked", + // Event management + EVENT_CREATED: "event:created", + EVENT_UPDATED: "event:updated", + EVENT_DELETED: "event:deleted", + EVENT_SELECTED: "event:selected", + // Event drag-drop + EVENT_DRAG_START: "event:drag-start", + EVENT_DRAG_MOVE: "event:drag-move", + EVENT_DRAG_END: "event:drag-end", + EVENT_DRAG_CANCEL: "event:drag-cancel", + EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change", + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header", + EVENT_DRAG_MOVE_HEADER: "event:drag-move-header", + EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header", + // Event resize + EVENT_RESIZE_START: "event:resize-start", + EVENT_RESIZE_END: "event:resize-end", + // Edge scroll + EDGE_SCROLL_TICK: "edge-scroll:tick", + EDGE_SCROLL_STARTED: "edge-scroll:started", + EDGE_SCROLL_STOPPED: "edge-scroll:stopped", + // System events + ERROR: "system:error", + // Sync events + SYNC_STARTED: "sync:started", + SYNC_COMPLETED: "sync:completed", + SYNC_FAILED: "sync:failed", + // Entity events - for audit and sync + ENTITY_SAVED: "entity:saved", + ENTITY_DELETED: "entity:deleted", + // Audit events + AUDIT_LOGGED: "audit:logged", + // Rendering events + EVENTS_RENDERED: "events:rendered" +}; +var SyncPlugin = class { + constructor(service) { + this.service = service; + } + /** + * Mark entity as successfully synced + */ + async markAsSynced(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "synced"; + await this.service.save(entity); + } + } + /** + * Mark entity as sync error + */ + async markAsError(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "error"; + await this.service.save(entity); + } + } + /** + * Get current sync status for an entity + */ + async getSyncStatus(id) { + const entity = await this.service.get(id); + return entity ? entity.syncStatus : null; + } + /** + * Get entities by sync status using IndexedDB index + */ + async getBySyncStatus(syncStatus) { + return new Promise((resolve, reject) => { + const transaction = this.service.db.transaction([this.service.storeName], "readonly"); + const store = transaction.objectStore(this.service.storeName); + const index = store.index("syncStatus"); + const request = index.getAll(syncStatus); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.service.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`)); + }; + }); + } +}; +function arrayDifference(first, second) { + const secondSet = new Set(second); + return first.filter((item) => !secondSet.has(item)); +} +function arrayIntersection(first, second) { + const secondSet = new Set(second); + return first.filter((item) => secondSet.has(item)); +} +function keyBy(arr, getKey2) { + const result = {}; + for (const item of arr) { + result[String(getKey2(item))] = item; + } + return result; +} +function diff(oldObj, newObj, options = {}) { + let { embeddedObjKeys } = options; + const { keysToSkip, treatTypeChangeAsReplace } = options; + if (embeddedObjKeys instanceof Map) { + embeddedObjKeys = new Map( + Array.from(embeddedObjKeys.entries()).map(([key, value]) => [ + key instanceof RegExp ? key : key.replace(/^\./, ""), + value + ]) + ); + } else if (embeddedObjKeys) { + embeddedObjKeys = Object.fromEntries( + Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\./, ""), value]) + ); + } + return compare(oldObj, newObj, [], [], { + embeddedObjKeys, + keysToSkip: keysToSkip ?? [], + treatTypeChangeAsReplace: treatTypeChangeAsReplace ?? true + }); +} +var getTypeOfObj = (obj) => { + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return null; + } + return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1]; +}; +var getKey = (path) => { + const left = path[path.length - 1]; + return left != null ? left : "$root"; +}; +var compare = (oldObj, newObj, path, keyPath, options) => { + let changes = []; + const currentPath = keyPath.join("."); + if (options.keysToSkip?.some((skipPath) => { + if (currentPath === skipPath) { + return true; + } + if (skipPath.includes(".") && skipPath.startsWith(currentPath + ".")) { + return false; + } + if (skipPath.includes(".")) { + const skipParts = skipPath.split("."); + const currentParts = currentPath.split("."); + if (currentParts.length >= skipParts.length) { + for (let i = 0; i < skipParts.length; i++) { + if (skipParts[i] !== currentParts[i]) { + return false; + } + } + return true; + } + } + return false; + })) { + return changes; + } + const typeOfOldObj = getTypeOfObj(oldObj); + const typeOfNewObj = getTypeOfObj(newObj); + if (options.treatTypeChangeAsReplace && typeOfOldObj !== typeOfNewObj) { + if (typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + } + if (typeOfNewObj !== "undefined") { + changes.push({ type: "ADD", key: getKey(path), value: newObj }); + } + return changes; + } + if (typeOfNewObj === "undefined" && typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + return changes; + } + if (typeOfNewObj === "Object" && typeOfOldObj === "Array") { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + return changes; + } + if (typeOfNewObj === null) { + if (typeOfOldObj !== null) { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + } + return changes; + } + switch (typeOfOldObj) { + case "Date": + if (typeOfNewObj === "Date") { + changes = changes.concat( + comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({ + ...x, + value: new Date(x.value), + oldValue: new Date(x.oldValue) + })) + ); + } else { + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + break; + case "Object": { + const diffs = compareObject(oldObj, newObj, path, keyPath, false, options); + if (diffs.length) { + if (path.length) { + changes.push({ + type: "UPDATE", + key: getKey(path), + changes: diffs + }); + } else { + changes = changes.concat(diffs); + } + } + break; + } + case "Array": + changes = changes.concat(compareArray(oldObj, newObj, path, keyPath, options)); + break; + case "Function": + break; + default: + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + return changes; +}; +var compareObject = (oldObj, newObj, path, keyPath, skipPath = false, options = {}) => { + let k; + let newKeyPath; + let newPath; + if (skipPath == null) { + skipPath = false; + } + let changes = []; + const oldObjKeys = Object.keys(oldObj); + const newObjKeys = Object.keys(newObj); + const intersectionKeys = arrayIntersection(oldObjKeys, newObjKeys); + for (k of intersectionKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const diffs = compare(oldObj[k], newObj[k], newPath, newKeyPath, options); + if (diffs.length) { + changes = changes.concat(diffs); + } + } + const addedKeys = arrayDifference(newObjKeys, oldObjKeys); + for (k of addedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "ADD", + key: getKey(newPath), + value: newObj[k] + }); + } + const deletedKeys = arrayDifference(oldObjKeys, newObjKeys); + for (k of deletedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "REMOVE", + key: getKey(newPath), + value: oldObj[k] + }); + } + return changes; +}; +var compareArray = (oldObj, newObj, path, keyPath, options) => { + if (getTypeOfObj(newObj) !== "Array") { + return [{ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }]; + } + const left = getObjectKey(options.embeddedObjKeys, keyPath); + const uniqKey = left != null ? left : "$index"; + const indexedOldObj = convertArrayToObj(oldObj, uniqKey); + const indexedNewObj = convertArrayToObj(newObj, uniqKey); + const diffs = compareObject(indexedOldObj, indexedNewObj, path, keyPath, true, options); + if (diffs.length) { + return [ + { + type: "UPDATE", + key: getKey(path), + embeddedKey: typeof uniqKey === "function" && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey, + changes: diffs + } + ]; + } else { + return []; + } +}; +var getObjectKey = (embeddedObjKeys, keyPath) => { + if (embeddedObjKeys != null) { + const path = keyPath.join("."); + if (embeddedObjKeys instanceof Map) { + for (const [key2, value] of embeddedObjKeys.entries()) { + if (key2 instanceof RegExp) { + if (path.match(key2)) { + return value; + } + } else if (path === key2) { + return value; + } + } + } + const key = embeddedObjKeys[path]; + if (key != null) { + return key; + } + } + return void 0; +}; +var convertArrayToObj = (arr, uniqKey) => { + let obj = {}; + if (uniqKey === "$value") { + arr.forEach((value) => { + obj[value] = value; + }); + } else if (uniqKey !== "$index") { + const keyFunction = typeof uniqKey === "string" ? (item) => item[uniqKey] : uniqKey; + obj = keyBy(arr, keyFunction); + } else { + for (let i = 0; i < arr.length; i++) { + const value = arr[i]; + obj[i] = value; + } + } + return obj; +}; +var comparePrimitives = (oldObj, newObj, path) => { + const changes = []; + if (oldObj !== newObj) { + changes.push({ + type: "UPDATE", + key: getKey(path), + value: newObj, + oldValue: oldObj + }); + } + return changes; +}; +var BaseEntityService = class { + constructor(context, eventBus) { + this.context = context; + this.eventBus = eventBus; + this.syncPlugin = new SyncPlugin(this); + } + get db() { + return this.context.getDatabase(); + } + /** + * Serialize entity before storing in IndexedDB + */ + serialize(entity) { + return entity; + } + /** + * Deserialize data from IndexedDB back to entity + */ + deserialize(data) { + return data; + } + /** + * Get a single entity by ID + */ + async get(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.get(id); + request.onsuccess = () => { + const data = request.result; + resolve(data ? this.deserialize(data) : null); + }; + request.onerror = () => { + reject(new Error(`Failed to get ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + /** + * Get all entities + */ + async getAll() { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get all ${this.entityType}s: ${request.error}`)); + }; + }); + } + /** + * Save an entity (create or update) + * Emits ENTITY_SAVED event with operation type and changes (diff for updates) + * @param entity - Entity to save + * @param silent - If true, skip event emission (used for seeding) + */ + async save(entity, silent = false) { + const entityId = entity.id; + const existingEntity = await this.get(entityId); + const isCreate = existingEntity === null; + let changes; + if (isCreate) { + changes = entity; + } else { + const existingSerialized = this.serialize(existingEntity); + const newSerialized = this.serialize(entity); + changes = diff(existingSerialized, newSerialized); + } + const serialized = this.serialize(entity); + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + request.onsuccess = () => { + if (!silent) { + const payload = { + entityType: this.entityType, + entityId, + operation: isCreate ? "create" : "update", + changes, + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_SAVED, payload); + } + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save ${this.entityType} ${entityId}: ${request.error}`)); + }; + }); + } + /** + * Delete an entity + * Emits ENTITY_DELETED event + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.delete(id); + request.onsuccess = () => { + const payload = { + entityType: this.entityType, + entityId: id, + operation: "delete", + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_DELETED, payload); + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to delete ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + // Sync methods - delegate to SyncPlugin + async markAsSynced(id) { + return this.syncPlugin.markAsSynced(id); + } + async markAsError(id) { + return this.syncPlugin.markAsError(id); + } + async getSyncStatus(id) { + return this.syncPlugin.getSyncStatus(id); + } + async getBySyncStatus(syncStatus) { + return this.syncPlugin.getBySyncStatus(syncStatus); + } +}; + +// node_modules/calendar/dist/index.js +var import_dayjs = __toESM(require_dayjs_min(), 1); +var import_utc = __toESM(require_utc(), 1); +var import_timezone = __toESM(require_timezone(), 1); +var import_isoWeek = __toESM(require_isoWeek(), 1); +var NavigationAnimator = class { + constructor(headerTrack, contentTrack, headerDrawer) { + this.headerTrack = headerTrack; + this.contentTrack = contentTrack; + this.headerDrawer = headerDrawer; + } + async slide(direction, renderFn) { + const out = direction === "left" ? "-100%" : "100%"; + const into = direction === "left" ? "100%" : "-100%"; + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + async animateOut(translate) { + const animations = [ + this.headerTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished, + this.contentTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished + ]; + if (this.headerDrawer) { + animations.push(this.headerDrawer.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished); + } + await Promise.all(animations); + } + async animateIn(translate) { + const animations = [ + this.headerTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished, + this.contentTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished + ]; + if (this.headerDrawer) { + animations.push(this.headerDrawer.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished); + } + await Promise.all(animations); + } +}; +var CalendarEvents = { + // Command events (host → calendar) + CMD_NAVIGATE_PREV: "calendar:cmd:navigate:prev", + CMD_NAVIGATE_NEXT: "calendar:cmd:navigate:next", + CMD_DRAWER_TOGGLE: "calendar:cmd:drawer:toggle", + CMD_RENDER: "calendar:cmd:render", + CMD_WORKWEEK_CHANGE: "calendar:cmd:workweek:change", + CMD_VIEW_UPDATE: "calendar:cmd:view:update" +}; +var CalendarApp = class { + constructor(orchestrator, timeAxisRenderer, dateService, scrollManager, headerDrawerManager, dragDropManager, edgeScrollManager, resizeManager, headerDrawerRenderer, eventPersistenceManager, settingsService, viewConfigService, eventBus) { + this.orchestrator = orchestrator; + this.timeAxisRenderer = timeAxisRenderer; + this.dateService = dateService; + this.scrollManager = scrollManager; + this.headerDrawerManager = headerDrawerManager; + this.dragDropManager = dragDropManager; + this.edgeScrollManager = edgeScrollManager; + this.resizeManager = resizeManager; + this.headerDrawerRenderer = headerDrawerRenderer; + this.eventPersistenceManager = eventPersistenceManager; + this.settingsService = settingsService; + this.viewConfigService = viewConfigService; + this.eventBus = eventBus; + this.dayOffset = 0; + this.currentViewId = "simple"; + this.workweekPreset = null; + this.groupingOverrides = /* @__PURE__ */ new Map(); + } + async init(container) { + this.container = container; + const gridSettings = await this.settingsService.getGridSettings(); + if (!gridSettings) { + throw new Error("GridSettings not found"); + } + this.workweekPreset = await this.settingsService.getDefaultWorkweekPreset(); + this.animator = new NavigationAnimator(container.querySelector("swp-header-track"), container.querySelector("swp-content-track"), container.querySelector("swp-header-drawer")); + this.timeAxisRenderer.render(container.querySelector("#time-axis"), gridSettings.dayStartHour, gridSettings.dayEndHour); + this.scrollManager.init(container); + this.headerDrawerManager.init(container); + this.dragDropManager.init(container); + this.resizeManager.init(container); + const scrollableContent = container.querySelector("swp-scrollable-content"); + this.edgeScrollManager.init(scrollableContent); + this.setupEventListeners(); + this.emitStatus("ready"); + } + setupEventListeners() { + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_PREV, () => { + this.handleNavigatePrev(); + }); + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_NEXT, () => { + this.handleNavigateNext(); + }); + this.eventBus.on(CalendarEvents.CMD_DRAWER_TOGGLE, () => { + this.headerDrawerManager.toggle(); + }); + this.eventBus.on(CalendarEvents.CMD_RENDER, (e) => { + const { viewId } = e.detail; + this.handleRenderCommand(viewId); + }); + this.eventBus.on(CalendarEvents.CMD_WORKWEEK_CHANGE, (e) => { + const { presetId } = e.detail; + this.handleWorkweekChange(presetId); + }); + this.eventBus.on(CalendarEvents.CMD_VIEW_UPDATE, (e) => { + const { type, values } = e.detail; + this.handleViewUpdate(type, values); + }); + } + async handleRenderCommand(viewId) { + this.currentViewId = viewId; + await this.render(); + this.emitStatus("rendered", { viewId }); + } + async handleNavigatePrev() { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset -= step; + await this.animator.slide("right", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleNavigateNext() { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset += step; + await this.animator.slide("left", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleWorkweekChange(presetId) { + const preset = await this.settingsService.getWorkweekPreset(presetId); + if (preset) { + this.workweekPreset = preset; + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + } + async handleViewUpdate(type, values) { + this.groupingOverrides.set(type, values); + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async render() { + const storedConfig = await this.viewConfigService.getById(this.currentViewId); + if (!storedConfig) { + this.emitStatus("error", { message: `ViewConfig not found: ${this.currentViewId}` }); + return; + } + const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5]; + const periodDays = this.workweekPreset?.periodDays ?? 7; + const dates = periodDays === 1 ? this.dateService.getDatesFromOffset(this.dayOffset, workDays.length) : this.dateService.getWorkDaysFromOffset(this.dayOffset, workDays); + const viewConfig = { + ...storedConfig, + groupings: storedConfig.groupings.map((g) => { + if (g.type === "date") { + return { ...g, values: dates }; + } + const override = this.groupingOverrides.get(g.type); + if (override) { + return { ...g, values: override }; + } + return g; + }) + }; + await this.orchestrator.render(viewConfig, this.container); + } + emitStatus(status, detail) { + this.container.dispatchEvent(new CustomEvent(`calendar:status:${status}`, { + detail, + bubbles: true + })); + } +}; +function buildPipeline(renderers) { + return { + async run(context) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} +var FilterTemplate = class { + constructor(dateService, entityResolver) { + this.dateService = dateService; + this.entityResolver = entityResolver; + this.fields = []; + } + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty, derivedFrom) { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + parseDotNotation(idProperty) { + if (!idProperty.includes(".")) + return null; + const [entityType, property] = idProperty.split("."); + return { + entityType, + property, + foreignKey: entityType + "Id" + // Convention: resource → resourceId + }; + } + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + getDatasetKey(idProperty) { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; + } + return idProperty; + } + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column) { + return this.fields.map((f) => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ""; + }).join(":"); + } + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event) { + const eventRecord = event; + return this.fields.map((f) => { + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + if (f.derivedFrom) { + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ""); + } + return String(eventRecord[f.idProperty] || ""); + }).join(":"); + } + /** + * Resolve dot-notation reference via EntityResolver + */ + resolveDotNotation(eventRecord, dotNotation) { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ""; + } + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) + return ""; + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) + return ""; + return String(entity[dotNotation.property] || ""); + } + /** + * Match event mod kolonne + */ + matches(event, column) { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +}; +var CalendarOrchestrator = class { + constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) { + this.allRenderers = allRenderers; + this.eventRenderer = eventRenderer; + this.scheduleRenderer = scheduleRenderer; + this.headerDrawerRenderer = headerDrawerRenderer; + this.dateService = dateService; + this.entityServices = entityServices; + } + async render(viewConfig, container) { + const headerContainer = container.querySelector("swp-calendar-header"); + const columnContainer = container.querySelector("swp-day-columns"); + if (!headerContainer || !columnContainer) { + throw new Error("Missing swp-calendar-header or swp-day-columns"); + } + const filter = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + headerContainer.innerHTML = ""; + columnContainer.innerHTML = ""; + const levels = viewConfig.groupings.map((g) => g.type).join(" "); + headerContainer.dataset.levels = levels; + const activeRenderers = this.selectRenderers(viewConfig); + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + await this.scheduleRenderer.render(container, filter); + await this.eventRenderer.render(container, filter, filterTemplate); + await this.headerDrawerRenderer.render(container, filter, filterTemplate); + } + selectRenderers(viewConfig) { + const types = viewConfig.groupings.map((g) => g.type); + return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0); + } + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + async resolveBelongsTo(groupings, filter) { + const childGrouping = groupings.find((g) => g.belongsTo); + if (!childGrouping?.belongsTo) + return {}; + const [entityType, property] = childGrouping.belongsTo.split("."); + if (!entityType || !property) + return {}; + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) + return {}; + const service = this.entityServices.find((s) => s.entityType.toLowerCase() === entityType); + if (!service) + return {}; + const allEntities = await service.getAll(); + const entities = allEntities.filter((e) => parentIds.includes(e.id)); + const map = {}; + for (const entity of entities) { + const entityRecord = entity; + const children = entityRecord[property] || []; + map[entityRecord.id] = children; + } + return { parentChildMap: map, childType: childGrouping.type }; + } +}; +var EventBus = class { + constructor() { + this.eventLog = []; + this.debug = false; + this.listeners = /* @__PURE__ */ new Set(); + this.logConfig = { + calendar: true, + grid: true, + event: true, + scroll: true, + navigation: true, + view: true, + default: true + }; + } + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType, handler, options) { + document.addEventListener(eventType, handler, options); + this.listeners.add({ eventType, handler, options }); + return () => this.off(eventType, handler); + } + /** + * Subscribe to an event once + */ + once(eventType, handler) { + return this.on(eventType, handler, { once: true }); + } + /** + * Unsubscribe from an event + */ + off(eventType, handler) { + document.removeEventListener(eventType, handler); + for (const listener of this.listeners) { + if (listener.eventType === eventType && listener.handler === handler) { + this.listeners.delete(listener); + break; + } + } + } + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType, detail = {}) { + if (!eventType) { + return false; + } + const event = new CustomEvent(eventType, { + detail: detail ?? {}, + bubbles: true, + cancelable: true + }); + if (this.debug) { + this.logEventWithGrouping(eventType, detail); + } + this.eventLog.push({ + type: eventType, + detail: detail ?? {}, + timestamp: Date.now() + }); + return !document.dispatchEvent(event); + } + /** + * Log event with console grouping + */ + logEventWithGrouping(eventType, _detail) { + const category = this.extractCategory(eventType); + if (!this.logConfig[category]) { + return; + } + this.getCategoryStyle(category); + } + /** + * Extract category from event type + */ + extractCategory(eventType) { + if (!eventType) { + return "unknown"; + } + if (eventType.includes(":")) { + return eventType.split(":")[0]; + } + const lowerType = eventType.toLowerCase(); + if (lowerType.includes("grid") || lowerType.includes("rendered")) + return "grid"; + if (lowerType.includes("event") || lowerType.includes("sync")) + return "event"; + if (lowerType.includes("scroll")) + return "scroll"; + if (lowerType.includes("nav") || lowerType.includes("date")) + return "navigation"; + if (lowerType.includes("view")) + return "view"; + return "default"; + } + /** + * Get styling for different categories + */ + getCategoryStyle(category) { + const styles = { + calendar: { emoji: "\u{1F4C5}", color: "#2196F3" }, + grid: { emoji: "\u{1F4CA}", color: "#4CAF50" }, + event: { emoji: "\u{1F4CC}", color: "#FF9800" }, + scroll: { emoji: "\u{1F4DC}", color: "#9C27B0" }, + navigation: { emoji: "\u{1F9ED}", color: "#F44336" }, + view: { emoji: "\u{1F441}", color: "#00BCD4" }, + default: { emoji: "\u{1F4E2}", color: "#607D8B" } + }; + return styles[category] || styles.default; + } + /** + * Configure logging for specific categories + */ + setLogConfig(config) { + this.logConfig = { ...this.logConfig, ...config }; + } + /** + * Get current log configuration + */ + getLogConfig() { + return { ...this.logConfig }; + } + /** + * Get event history + */ + getEventLog(eventType) { + if (eventType) { + return this.eventLog.filter((e) => e.type === eventType); + } + return this.eventLog; + } + /** + * Enable/disable debug mode + */ + setDebug(enabled) { + this.debug = enabled; + } +}; +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_timezone.default); +import_dayjs.default.extend(import_isoWeek.default); +var DateService = class { + constructor(config, baseDate) { + this.config = config; + this.timezone = config.timezone; + this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)(); + } + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date) { + this.baseDate = (0, import_dayjs.default)(date); + } + /** + * Get the current base date (either fixed or today) + */ + getBaseDate() { + return this.baseDate.toDate(); + } + parseISO(isoString) { + return (0, import_dayjs.default)(isoString).toDate(); + } + getDayName(date, format = "short") { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + /** + * Get dates starting from a day offset + * @param dayOffset - Day offset from base date + * @param count - Number of consecutive days to return + * @returns Array of date strings in YYYY-MM-DD format + */ + getDatesFromOffset(dayOffset, count) { + const startDate = this.baseDate.add(dayOffset, "day"); + return Array.from({ length: count }, (_, i) => startDate.add(i, "day").format("YYYY-MM-DD")); + } + /** + * Get specific weekdays from the week containing the offset date + * @param dayOffset - Day offset from base date + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkDaysFromOffset(dayOffset, workDays) { + const targetDate = this.baseDate.add(dayOffset, "day"); + const monday = targetDate.startOf("week").add(1, "day"); + return workDays.map((isoDay) => { + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, "day").format("YYYY-MM-DD"); + }); + } + // Legacy methods for backwards compatibility + getWeekDates(weekOffset = 0, days = 7) { + return this.getDatesFromOffset(weekOffset * 7, days); + } + getWorkWeekDates(weekOffset, workDays) { + return this.getWorkDaysFromOffset(weekOffset * 7, workDays); + } + // ============================================ + // FORMATTING + // ============================================ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? "HH:mm:ss" : "HH:mm"; + return (0, import_dayjs.default)(date).format(pattern); + } + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + formatDate(date) { + return (0, import_dayjs.default)(date).format("YYYY-MM-DD"); + } + getDateKey(date) { + return this.formatDate(date); + } + // ============================================ + // COLUMN KEY + // ============================================ + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments) { + const date = segments.date; + const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v); + return date ? [date, ...others].join(":") : others.join(":"); + } + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey) { + const parts = columnKey.split(":"); + return { + date: parts[0], + resource: parts[1] + }; + } + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey) { + return columnKey.split(":")[0]; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + timeToMinutes(timeString) { + const parts = timeString.split(":").map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm"); + } + getMinutesSinceMidnight(date) { + const d = (0, import_dayjs.default)(date); + return d.hour() * 60 + d.minute(); + } + // ============================================ + // UTC CONVERSIONS + // ============================================ + toUTC(localDate) { + return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString(); + } + fromUTC(utcString) { + return import_dayjs.default.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // DATE CREATION + // ============================================ + createDateAtTime(baseDate, timeString) { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate(); + } + getISOWeekDay(date) { + return (0, import_dayjs.default)(date).isoWeekday(); + } +}; +var ScrollManager = class { + init(container) { + this.scrollableContent = container.querySelector("swp-scrollable-content"); + this.timeAxisContent = container.querySelector("swp-time-axis-content"); + this.calendarHeader = container.querySelector("swp-calendar-header"); + this.headerDrawer = container.querySelector("swp-header-drawer"); + this.headerViewport = container.querySelector("swp-header-viewport"); + this.headerSpacer = container.querySelector("swp-header-spacer"); + this.scrollableContent.addEventListener("scroll", () => this.onScroll()); + this.resizeObserver = new ResizeObserver(() => this.syncHeaderSpacerHeight()); + this.resizeObserver.observe(this.headerViewport); + this.syncHeaderSpacerHeight(); + } + syncHeaderSpacerHeight() { + const computedHeight = getComputedStyle(this.headerViewport).height; + this.headerSpacer.style.height = computedHeight; + } + onScroll() { + const { scrollTop, scrollLeft } = this.scrollableContent; + this.timeAxisContent.style.transform = `translateY(-${scrollTop}px)`; + this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`; + this.headerDrawer.style.transform = `translateX(-${scrollLeft}px)`; + } +}; +var HeaderDrawerManager = class { + constructor() { + this.expanded = false; + this.currentRows = 0; + this.rowHeight = 25; + this.duration = 200; + } + init(container) { + this.drawer = container.querySelector("swp-header-drawer"); + if (!this.drawer) + console.error("HeaderDrawerManager: swp-header-drawer not found"); + } + toggle() { + this.expanded ? this.collapse() : this.expand(); + } + /** + * Expand drawer to single row (legacy support) + */ + expand() { + this.expandToRows(1); + } + /** + * Expand drawer to fit specified number of rows + */ + expandToRows(rowCount) { + const targetHeight = rowCount * this.rowHeight; + const currentHeight = this.expanded ? this.currentRows * this.rowHeight : 0; + if (this.expanded && this.currentRows === rowCount) + return; + this.currentRows = rowCount; + this.expanded = true; + this.animate(currentHeight, targetHeight); + } + collapse() { + if (!this.expanded) + return; + const currentHeight = this.currentRows * this.rowHeight; + this.expanded = false; + this.currentRows = 0; + this.animate(currentHeight, 0); + } + animate(from, to) { + const keyframes = [ + { height: `${from}px` }, + { height: `${to}px` } + ]; + const options = { + duration: this.duration, + easing: "ease", + fill: "forwards" + }; + this.drawer.animate(keyframes, options); + } + isExpanded() { + return this.expanded; + } + getRowCount() { + return this.currentRows; + } +}; +var DateRenderer = class { + constructor(dateService) { + this.dateService = dateService; + this.type = "date"; + } + render(context) { + const dates = context.filter["date"] || []; + const resourceIds = context.filter["resource"] || []; + const dateGrouping = context.groupings?.find((g) => g.type === "date"); + const hideHeader = dateGrouping?.hideHeader === true; + const iterations = resourceIds.length || 1; + let columnCount = 0; + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + const segments = { date: dateStr }; + if (resourceId) + segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + const header = document.createElement("swp-day-header"); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = "true"; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, "short")} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + const column = document.createElement("swp-day-column"); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ""; + context.columnContainer.appendChild(column); + columnCount++; + } + } + const container = context.columnContainer.closest("swp-calendar-container"); + if (container) { + container.style.setProperty("--grid-columns", String(columnCount)); + } + } +}; +var ResourceRenderer = class extends BaseGroupingRenderer { + constructor(resourceService) { + super(); + this.resourceService = resourceService; + this.type = "resource"; + this.config = { + elementTag: "swp-resource-header", + idAttribute: "resourceId", + colspanVar: "--resource-cols" + }; + } + getEntities(ids) { + return this.resourceService.getByIds(ids); + } + getDisplayName(entity) { + return entity.displayName; + } + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context) { + const resourceIds = context.filter["resource"] || []; + const dateCount = context.filter["date"]?.length || 1; + let orderedResourceIds; + if (context.parentChildMap) { + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + const resources = await this.getEntities(orderedResourceIds); + const resourceMap = new Map(resources.map((r) => [r.id, r])); + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) + continue; + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +}; +function calculateEventPosition(start, end, config) { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + return { top, height }; +} +function minutesToPixels(minutes, config) { + return minutes / 60 * config.hourHeight; +} +function pixelsToMinutes(pixels, config) { + return pixels / config.hourHeight * 60; +} +function snapToGrid(pixels, config) { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} +function eventsOverlap(a, b) { + return a.start < b.end && a.end > b.start; +} +function eventsWithinThreshold(a, b, thresholdMinutes) { + const thresholdMs = thresholdMinutes * 60 * 1e3; + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) + return true; + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) + return true; + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) + return true; + return false; +} +function findOverlapGroups(events) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsOverlap(member, candidate)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +function findGridCandidates(events, thresholdMinutes) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsWithinThreshold(member, candidate, thresholdMinutes)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +function calculateStackLevels(events) { + const levels = /* @__PURE__ */ new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + for (const event of sorted) { + let maxOverlappingLevel = -1; + for (const [id, level] of levels) { + const other = events.find((e) => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + levels.set(event.id, maxOverlappingLevel + 1); + } + return levels; +} +function allocateColumns(events) { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns = []; + for (const event of sorted) { + let placed = false; + for (const column of columns) { + const canFit = !column.some((e) => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + if (!placed) { + columns.push([event]); + } + } + return columns; +} +function calculateColumnLayout(events, config) { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + const result = { + grids: [], + stacked: [] + }; + if (events.length === 0) + return result; + const overlapGroups = findOverlapGroups(events); + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]); + if (largestGridCandidate.length === overlapGroup.length) { + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + return result; +} +var EventRenderer = class { + constructor(eventService, dateService, gridConfig, eventBus) { + this.eventService = eventService; + this.dateService = dateService; + this.gridConfig = gridConfig; + this.eventBus = eventBus; + this.container = null; + this.setupListeners(); + } + /** + * Setup listeners for drag-drop and update events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = e.detail; + this.handleColumnChange(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = e.detail; + this.updateDragTimestamp(payload); + }); + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = e.detail; + this.handleEventUpdated(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeaveHeader(payload); + }); + } + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + handleDragEnd(payload) { + if (payload.target === "header") { + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + /** + * Handle header item leaving header - create swp-event in grid + */ + handleDragLeaveHeader(payload) { + if (payload.source !== "header") + return; + if (!payload.targetColumn || !payload.start || !payload.end) + return; + if (payload.element) { + payload.element.classList.add("drag-ghost"); + payload.element.style.opacity = "0.3"; + payload.element.style.pointerEvents = "none"; + } + const event = { + id: payload.eventId, + title: payload.title || "", + description: "", + start: payload.start, + end: payload.end, + type: "customer", + allDay: false, + syncStatus: "pending" + }; + const element = this.createEventElement(event); + let eventsLayer = payload.targetColumn.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + element.classList.add("dragging"); + } + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + async handleEventUpdated(payload) { + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + await this.rerenderColumn(payload.targetColumnKey); + } + /** + * Re-render a single column with fresh data from IndexedDB + */ + async rerenderColumn(columnKey) { + const column = this.findColumn(columnKey); + if (!column) + return; + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date) + return; + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate); + const timedEvents = events.filter((event) => !event.allDay && this.dateService.getDateKey(event.start) === date); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + } + /** + * Find a column element by columnKey + */ + findColumn(columnKey) { + if (!this.container) + return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`); + } + /** + * Handle event moving to a new column during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.querySelector("swp-events-layer"); + if (!eventsLayer) + return; + eventsLayer.appendChild(payload.element); + payload.element.style.top = `${payload.currentY}px`; + } + /** + * Update timestamp display during drag (snapped to grid) + */ + updateDragTimestamp(payload) { + const timeEl = payload.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart; + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to a Date object (today) + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container, filter, filterTemplate) { + this.container = container; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const dayColumns = container.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + columns.forEach((column) => { + const columnEl = column; + const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl)); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const timedEvents = columnEvents.filter((event) => !event.allDay); + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + }); + } + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + createEventElement(event) { + const element = document.createElement("swp-event"); + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ""} + `; + return element; + } + /** + * Get color class based on metadata.color or event type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Escape HTML to prevent XSS + */ + escapeHtml(text) { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; + } + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + renderGridGroup(layout) { + const group = document.createElement("swp-event-group"); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) + maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + layout.columns.forEach((columnEvents) => { + const wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + columnEvents.forEach((event) => { + const eventEl = this.createEventElement(event); + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = "absolute"; + eventEl.style.left = "0"; + eventEl.style.right = "0"; + wrapper.appendChild(eventEl); + }); + group.appendChild(wrapper); + }); + return group; + } + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + renderStackedEvent(event, stackLevel) { + const element = this.createEventElement(event); + element.dataset.stackLink = JSON.stringify({ stackLevel }); + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + return element; + } +}; +var TimeAxisRenderer = class { + render(container, startHour = 6, endHour = 20) { + container.innerHTML = ""; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement("swp-hour-marker"); + marker.textContent = `${hour.toString().padStart(2, "0")}:00`; + container.appendChild(marker); + } + } +}; +var HeaderDrawerRenderer = class { + constructor(eventBus, gridConfig, headerDrawerManager, eventService, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.headerDrawerManager = headerDrawerManager; + this.eventService = eventService; + this.dateService = dateService; + this.currentItem = null; + this.container = null; + this.sourceElement = null; + this.wasExpandedBeforeDrag = false; + this.filterTemplate = null; + this.setupListeners(); + } + /** + * Render allDay events into the header drawer with row stacking + * @param filterTemplate - Template for matching events to columns + */ + async render(container, filter, filterTemplate) { + this.filterTemplate = filterTemplate; + const drawer = container.querySelector("swp-header-drawer"); + if (!drawer) + return; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const allDayEvents = events.filter((event) => event.allDay !== false); + drawer.innerHTML = ""; + if (allDayEvents.length === 0) + return; + const layouts = this.calculateLayout(allDayEvents, visibleColumnKeys); + const rowCount = Math.max(1, ...layouts.map((l) => l.row)); + layouts.forEach((layout) => { + const item = this.createHeaderItem(layout); + drawer.appendChild(item); + }); + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Create a header item element from layout + */ + createHeaderItem(layout) { + const { event, columnKey, row, colStart, colEnd } = layout; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = event.id; + item.dataset.itemType = "event"; + item.dataset.start = event.start.toISOString(); + item.dataset.end = event.end.toISOString(); + item.dataset.columnKey = columnKey; + item.textContent = event.title; + const colorClass = this.getColorClass(event); + if (colorClass) + item.classList.add(colorClass); + item.style.gridArea = `${row} / ${colStart} / ${row + 1} / ${colEnd}`; + return item; + } + /** + * Calculate layout for all events with row stacking + * Uses track-based algorithm to find available rows for overlapping events + */ + calculateLayout(events, visibleColumnKeys) { + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + const layouts = []; + for (const event of events) { + const columnKey = this.buildColumnKeyFromEvent(event); + const startCol = visibleColumnKeys.indexOf(columnKey); + const endColumnKey = this.buildColumnKeyFromEvent(event, event.end); + const endCol = visibleColumnKeys.indexOf(endColumnKey); + if (startCol === -1 && endCol === -1) + continue; + const colStart = Math.max(0, startCol); + const colEnd = (endCol !== -1 ? endCol : visibleColumnKeys.length - 1) + 1; + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + layouts.push({ event, columnKey, row: row + 1, colStart: colStart + 1, colEnd: colEnd + 1 }); + } + return layouts; + } + /** + * Build columnKey from event using FilterTemplate + * Uses the same template that columns use for matching + */ + buildColumnKeyFromEvent(event, date) { + if (!this.filterTemplate) { + const dateStr = this.dateService.getDateKey(date || event.start); + return dateStr; + } + if (date && date.getTime() !== event.start.getTime()) { + const tempEvent = { ...event, start: date }; + return this.filterTemplate.buildKeyFromEvent(tempEvent); + } + return this.filterTemplate.buildKeyFromEvent(event); + } + /** + * Find available row for event spanning columns [colStart, colEnd) + */ + findAvailableRow(tracks, colStart, colEnd) { + for (let row = 0; row < tracks.length; row++) { + let available = true; + for (let c = colStart; c < colEnd; c++) { + if (tracks[row][c]) { + available = false; + break; + } + } + if (available) + return row; + } + tracks.push(new Array(tracks[0].length).fill(false)); + return tracks.length - 1; + } + /** + * Get color class based on event metadata or type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Setup event listeners for drag events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_ENTER_HEADER, (e) => { + const payload = e.detail; + this.handleDragEnter(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragMove(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeave(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => { + this.cleanup(); + }); + } + /** + * Handle drag entering header zone - create preview item + */ + handleDragEnter(payload) { + this.container = document.querySelector("swp-header-drawer"); + if (!this.container) + return; + this.wasExpandedBeforeDrag = this.headerDrawerManager.isExpanded(); + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.expandToRows(1); + } + this.sourceElement = payload.element; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = payload.eventId; + item.dataset.itemType = payload.itemType; + item.dataset.duration = String(payload.duration); + item.dataset.columnKey = payload.sourceColumnKey; + item.textContent = payload.title; + if (payload.colorClass) { + item.classList.add(payload.colorClass); + } + item.classList.add("dragging"); + const col = payload.sourceColumnIndex + 1; + const endCol = col + payload.duration; + item.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.container.appendChild(item); + this.currentItem = item; + payload.element.style.visibility = "hidden"; + } + /** + * Handle drag moving within header - update column position + */ + handleDragMove(payload) { + if (!this.currentItem) + return; + const col = payload.columnIndex + 1; + const duration = parseInt(this.currentItem.dataset.duration || "1", 10); + const endCol = col + duration; + this.currentItem.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.currentItem.dataset.columnKey = payload.columnKey; + } + /** + * Handle drag leaving header - cleanup for grid→header drag only + */ + handleDragLeave(payload) { + if (payload.source === "grid") { + this.cleanup(); + } + } + /** + * Handle drag end - finalize based on drop target + */ + handleDragEnd(payload) { + if (payload.target === "header") { + if (this.currentItem) { + this.currentItem.classList.remove("dragging"); + this.recalculateDrawerLayout(); + this.currentItem = null; + this.sourceElement = null; + } + } else { + const ghost = document.querySelector(`swp-header-item.drag-ghost[data-event-id="${payload.swpEvent.eventId}"]`); + ghost?.remove(); + this.recalculateDrawerLayout(); + } + } + /** + * Recalculate layout for all items currently in the drawer + * Called after drop to reposition items and adjust height + */ + recalculateDrawerLayout() { + const drawer = document.querySelector("swp-header-drawer"); + if (!drawer) + return; + const items = Array.from(drawer.querySelectorAll("swp-header-item")); + if (items.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const itemData = items.map((item) => ({ + element: item, + columnKey: item.dataset.columnKey || "", + duration: parseInt(item.dataset.duration || "1", 10) + })); + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + for (const item of itemData) { + const startCol = visibleColumnKeys.indexOf(item.columnKey); + if (startCol === -1) + continue; + const colStart = startCol; + const colEnd = Math.min(startCol + item.duration, visibleColumnKeys.length); + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + item.element.style.gridArea = `${row + 1} / ${colStart + 1} / ${row + 2} / ${colEnd + 1}`; + } + const rowCount = tracks.length; + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Get visible column keys from DOM (preserves order for multi-resource views) + * Uses filterTemplate.buildKeyFromColumn() for consistent key format with events + */ + getVisibleColumnKeysFromDOM() { + if (!this.filterTemplate) + return []; + const columns = document.querySelectorAll("swp-day-column"); + const columnKeys = []; + columns.forEach((col) => { + const columnKey = this.filterTemplate.buildKeyFromColumn(col); + if (columnKey) + columnKeys.push(columnKey); + }); + return columnKeys; + } + /** + * Cleanup preview item and restore source visibility + */ + cleanup() { + this.currentItem?.remove(); + this.currentItem = null; + if (this.sourceElement) { + this.sourceElement.style.visibility = ""; + this.sourceElement = null; + } + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.collapse(); + } + } +}; +var ScheduleRenderer = class { + constructor(scheduleService, dateService, gridConfig) { + this.scheduleService = scheduleService; + this.dateService = dateService; + this.gridConfig = gridConfig; + } + /** + * Render unavailable zones for visible columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and 'resource' arrays + */ + async render(container, filter) { + const dates = filter["date"] || []; + const resourceIds = filter["resource"] || []; + if (dates.length === 0) + return; + const dayColumns = container.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + for (const column of columns) { + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date || !resourceId) + continue; + let unavailableLayer = column.querySelector("swp-unavailable-layer"); + if (!unavailableLayer) { + unavailableLayer = document.createElement("swp-unavailable-layer"); + column.insertBefore(unavailableLayer, column.firstChild); + } + unavailableLayer.innerHTML = ""; + const schedule = await this.scheduleService.getScheduleForDate(resourceId, date); + this.renderUnavailableZones(unavailableLayer, schedule); + } + } + /** + * Render unavailable time zones based on schedule + */ + renderUnavailableZones(layer, schedule) { + const dayStartMinutes = this.gridConfig.dayStartHour * 60; + const dayEndMinutes = this.gridConfig.dayEndHour * 60; + const minuteHeight = this.gridConfig.hourHeight / 60; + if (schedule === null) { + const zone = this.createUnavailableZone(0, (dayEndMinutes - dayStartMinutes) * minuteHeight); + layer.appendChild(zone); + return; + } + const workStartMinutes = this.dateService.timeToMinutes(schedule.start); + const workEndMinutes = this.dateService.timeToMinutes(schedule.end); + if (workStartMinutes > dayStartMinutes) { + const top = 0; + const height = (workStartMinutes - dayStartMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + if (workEndMinutes < dayEndMinutes) { + const top = (workEndMinutes - dayStartMinutes) * minuteHeight; + const height = (dayEndMinutes - workEndMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + } + /** + * Create an unavailable zone element + */ + createUnavailableZone(top, height) { + const zone = document.createElement("swp-unavailable-zone"); + zone.style.top = `${top}px`; + zone.style.height = `${height}px`; + return zone; + } +}; +var defaultDBConfig = { + dbName: "CalendarDB", + dbVersion: 4 +}; +var IndexedDBContext = class { + constructor(stores, config) { + this.db = null; + this.initialized = false; + this.stores = stores; + this.config = config; + } + get dbName() { + return this.config.dbName; + } + /** + * Initialize and open the database + */ + async initialize() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(this.config.dbName, this.config.dbVersion); + request.onerror = () => { + reject(new Error(`Failed to open IndexedDB: ${request.error}`)); + }; + request.onsuccess = () => { + this.db = request.result; + this.initialized = true; + resolve(); + }; + request.onupgradeneeded = (event) => { + const db = event.target.result; + this.stores.forEach((store) => { + if (!db.objectStoreNames.contains(store.storeName)) { + store.create(db); + } + }); + }; + }); + } + /** + * Check if database is initialized + */ + isInitialized() { + return this.initialized; + } + /** + * Get IDBDatabase instance + */ + getDatabase() { + if (!this.db) { + throw new Error("IndexedDB not initialized. Call initialize() first."); + } + return this.db; + } + /** + * Close database connection + */ + close() { + if (this.db) { + this.db.close(); + this.db = null; + this.initialized = false; + } + } + /** + * Delete entire database (for testing/reset) + */ + static async deleteDatabase(dbName = defaultDBConfig.dbName) { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(dbName); + request.onsuccess = () => resolve(); + request.onerror = () => reject(new Error(`Failed to delete database: ${request.error}`)); + }); + } +}; +var EventStore = class _EventStore { + constructor() { + this.storeName = _EventStore.STORE_NAME; + } + /** + * Create the events ObjectStore with indexes + */ + create(db) { + const store = db.createObjectStore(_EventStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("start", "start", { unique: false }); + store.createIndex("end", "end", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("customerId", "customerId", { unique: false }); + store.createIndex("bookingId", "bookingId", { unique: false }); + store.createIndex("startEnd", ["start", "end"], { unique: false }); + } +}; +EventStore.STORE_NAME = "events"; +var EventSerialization = class { + /** + * Serialize event for IndexedDB storage + */ + static serialize(event) { + return { + ...event, + start: event.start instanceof Date ? event.start.toISOString() : event.start, + end: event.end instanceof Date ? event.end.toISOString() : event.end + }; + } + /** + * Deserialize event from IndexedDB storage + */ + static deserialize(data) { + return { + ...data, + start: typeof data.start === "string" ? new Date(data.start) : data.start, + end: typeof data.end === "string" ? new Date(data.end) : data.end + }; + } +}; +var EventService = class extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = EventStore.STORE_NAME; + this.entityType = "Event"; + } + serialize(event) { + return EventSerialization.serialize(event); + } + deserialize(data) { + return EventSerialization.deserialize(data); + } + /** + * Get events within a date range + */ + async getByDateRange(start, end) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("start"); + const range = IDBKeyRange.lowerBound(start.toISOString()); + const request = index.getAll(range); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)).filter((event) => event.start <= end); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events by date range: ${request.error}`)); + }; + }); + } + /** + * Get events for a specific resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events for resource ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get events for a resource within a date range + */ + async getByResourceAndDateRange(resourceId, start, end) { + const resourceEvents = await this.getByResource(resourceId); + return resourceEvents.filter((event) => event.start >= start && event.start <= end); + } +}; +var ResourceStore = class _ResourceStore { + constructor() { + this.storeName = _ResourceStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ResourceStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("type", "type", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("isActive", "isActive", { unique: false }); + } +}; +ResourceStore.STORE_NAME = "resources"; +var ResourceService = class extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ResourceStore.STORE_NAME; + this.entityType = "Resource"; + } + /** + * Get all active resources + */ + async getActive() { + const all = await this.getAll(); + return all.filter((r) => r.isActive !== false); + } + /** + * Get resources by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((r) => r !== null); + } + /** + * Get resources by type + */ + async getByType(type) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("type"); + const request = index.getAll(type); + request.onsuccess = () => { + const data = request.result; + resolve(data); + }; + request.onerror = () => { + reject(new Error(`Failed to get resources by type ${type}: ${request.error}`)); + }; + }); + } +}; +var SettingsIds = { + WORKWEEK: "workweek", + GRID: "grid", + TIME_FORMAT: "timeFormat", + VIEWS: "views" +}; +var SettingsStore = class _SettingsStore { + constructor() { + this.storeName = _SettingsStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_SettingsStore.STORE_NAME, { keyPath: "id" }); + } +}; +SettingsStore.STORE_NAME = "settings"; +var SettingsService = class extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = SettingsStore.STORE_NAME; + this.entityType = "Settings"; + } + /** + * Get workweek settings + */ + async getWorkweekSettings() { + return this.get(SettingsIds.WORKWEEK); + } + /** + * Get grid settings + */ + async getGridSettings() { + return this.get(SettingsIds.GRID); + } + /** + * Get time format settings + */ + async getTimeFormatSettings() { + return this.get(SettingsIds.TIME_FORMAT); + } + /** + * Get view settings + */ + async getViewSettings() { + return this.get(SettingsIds.VIEWS); + } + /** + * Get workweek preset by ID + */ + async getWorkweekPreset(presetId) { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[presetId] || null; + } + /** + * Get the default workweek preset + */ + async getDefaultWorkweekPreset() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[settings.defaultPreset] || null; + } + /** + * Get all available workweek presets + */ + async getWorkweekPresets() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return []; + return Object.values(settings.presets); + } +}; +var ViewConfigStore = class _ViewConfigStore { + constructor() { + this.storeName = _ViewConfigStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_ViewConfigStore.STORE_NAME, { keyPath: "id" }); + } +}; +ViewConfigStore.STORE_NAME = "viewconfigs"; +var ViewConfigService = class extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ViewConfigStore.STORE_NAME; + this.entityType = "ViewConfig"; + } + async getById(id) { + return this.get(id); + } +}; +var SwpEvent = class _SwpEvent { + constructor(element, columnKey, start, end) { + this.element = element; + this.columnKey = columnKey; + this._start = start; + this._end = end; + } + /** Event ID from element.dataset.eventId */ + get eventId() { + return this.element.dataset.eventId || ""; + } + get start() { + return this._start; + } + get end() { + return this._end; + } + /** Duration in minutes */ + get durationMinutes() { + return (this._end.getTime() - this._start.getTime()) / (1e3 * 60); + } + /** Duration in milliseconds */ + get durationMs() { + return this._end.getTime() - this._start.getTime(); + } + /** + * Factory: Create SwpEvent from element + columnKey + * Reads top/height from element.style to calculate start/end + * @param columnKey - Opaque column identifier (do NOT parse - use only for matching) + * @param date - Date string (YYYY-MM-DD) for time calculations + */ + static fromElement(element, columnKey, date, gridConfig) { + const topPixels = parseFloat(element.style.top) || 0; + const heightPixels = parseFloat(element.style.height) || 0; + const startMinutesFromGrid = topPixels / gridConfig.hourHeight * 60; + const totalMinutes = gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const start = new Date(date); + start.setHours(Math.floor(totalMinutes / 60), totalMinutes % 60, 0, 0); + const durationMinutes = heightPixels / gridConfig.hourHeight * 60; + const end = new Date(start.getTime() + durationMinutes * 60 * 1e3); + return new _SwpEvent(element, columnKey, start, end); + } +}; +var DragDropManager = class { + constructor(eventBus, gridConfig) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dragState = null; + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + this.container = null; + this.inHeader = false; + this.DRAG_THRESHOLD = 5; + this.INTERPOLATION_FACTOR = 0.3; + this.handlePointerDown = (e) => { + const target = e.target; + if (target.closest("swp-resize-handle")) + return; + const eventElement = target.closest("swp-event"); + const headerItem = target.closest("swp-header-item"); + const draggable = eventElement || headerItem; + if (!draggable) + return; + this.mouseDownPosition = { x: e.clientX, y: e.clientY }; + this.pendingElement = draggable; + const rect = draggable.getBoundingClientRect(); + this.pendingMouseOffset = { + x: e.clientX - rect.left, + y: e.clientY - rect.top + }; + draggable.setPointerCapture(e.pointerId); + }; + this.handlePointerMove = (e) => { + if (!this.mouseDownPosition || !this.pendingElement) { + if (this.dragState) { + this.updateDragTarget(e); + } + return; + } + const deltaX = Math.abs(e.clientX - this.mouseDownPosition.x); + const deltaY = Math.abs(e.clientY - this.mouseDownPosition.y); + const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + if (distance < this.DRAG_THRESHOLD) + return; + this.initializeDrag(this.pendingElement, this.pendingMouseOffset, e); + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + }; + this.handlePointerUp = (_e) => { + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + if (this.dragState.dragSource === "header") { + this.handleHeaderItemDragEnd(); + } else { + this.handleGridEventDragEnd(); + } + this.dragState.element.classList.remove("dragging"); + this.dragState = null; + this.inHeader = false; + }; + this.animateDrag = () => { + if (!this.dragState) + return; + const diff2 = this.dragState.targetY - this.dragState.currentY; + if (Math.abs(diff2) <= 0.5) { + this.dragState.animationId = 0; + return; + } + this.dragState.currentY += diff2 * this.INTERPOLATION_FACTOR; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + if (this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + currentY: this.dragState.currentY, + columnElement: this.dragState.columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE, payload); + } + this.dragState.animationId = requestAnimationFrame(this.animateDrag); + }; + this.setupScrollListener(); + } + setupScrollListener() { + this.eventBus.on(CoreEvents.EDGE_SCROLL_TICK, (e) => { + if (!this.dragState) + return; + const { scrollDelta } = e.detail; + this.dragState.targetY += scrollDelta; + this.dragState.currentY += scrollDelta; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + }); + } + /** + * Initialize drag-drop on a container element + */ + init(container) { + this.container = container; + container.addEventListener("pointerdown", this.handlePointerDown); + document.addEventListener("pointermove", this.handlePointerMove); + document.addEventListener("pointerup", this.handlePointerUp); + } + /** + * Handle drag end for header items + */ + handleHeaderItemDragEnd() { + if (!this.dragState) + return; + if (!this.inHeader && this.dragState.currentColumn) { + const gridEvent = this.dragState.currentColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (gridEvent) { + const columnKey = this.dragState.currentColumn.dataset.columnKey || ""; + const date = this.dragState.currentColumn.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(gridEvent, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + } + } + /** + * Handle drag end for grid events + */ + handleGridEventDragEnd() { + if (!this.dragState || !this.dragState.columnElement) + return; + const snappedY = snapToGrid(this.dragState.currentY, this.gridConfig); + this.dragState.element.style.top = `${snappedY}px`; + this.dragState.ghostElement?.remove(); + const columnKey = this.dragState.columnElement.dataset.columnKey || ""; + const date = this.dragState.columnElement.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.dragState.element, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: this.inHeader ? "header" : "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + initializeDrag(element, mouseOffset, e) { + const eventId = element.dataset.eventId || ""; + const isHeaderItem = element.tagName.toLowerCase() === "swp-header-item"; + const columnElement = element.closest("swp-day-column"); + if (!isHeaderItem && !columnElement) + return; + if (isHeaderItem) { + this.initializeHeaderItemDrag(element, mouseOffset, eventId); + } else { + this.initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId); + } + } + /** + * Initialize drag for a header item (allDay event) + */ + initializeHeaderItemDrag(element, mouseOffset, eventId) { + element.classList.add("dragging"); + this.dragState = { + eventId, + element, + ghostElement: null, + // No ghost for header items + startY: 0, + mouseOffset, + columnElement: null, + currentColumn: null, + targetY: 0, + currentY: 0, + animationId: 0, + sourceColumnKey: "", + // Will be set from header item data + dragSource: "header" + }; + this.inHeader = true; + } + /** + * Initialize drag for a grid event + */ + initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId) { + const elementRect = element.getBoundingClientRect(); + const columnRect = columnElement.getBoundingClientRect(); + const startY = elementRect.top - columnRect.top; + const group = element.closest("swp-event-group"); + if (group) { + const eventsLayer = columnElement.querySelector("swp-events-layer"); + if (eventsLayer) { + eventsLayer.appendChild(element); + } + } + element.style.position = "absolute"; + element.style.top = `${startY}px`; + element.style.left = "2px"; + element.style.right = "2px"; + element.style.marginLeft = "0"; + const ghostElement = element.cloneNode(true); + ghostElement.classList.add("drag-ghost"); + ghostElement.style.opacity = "0.3"; + ghostElement.style.pointerEvents = "none"; + element.parentNode?.insertBefore(ghostElement, element); + element.classList.add("dragging"); + const targetY = e.clientY - columnRect.top - mouseOffset.y; + this.dragState = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement, + currentColumn: columnElement, + targetY: Math.max(0, targetY), + currentY: startY, + animationId: 0, + sourceColumnKey: columnElement.dataset.columnKey || "", + dragSource: "grid" + }; + const payload = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_START, payload); + this.animateDrag(); + } + updateDragTarget(e) { + if (!this.dragState) + return; + this.checkHeaderZone(e); + if (this.inHeader) + return; + const columnAtPoint = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header" && columnAtPoint && !this.dragState.currentColumn) { + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn && this.dragState.currentColumn) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + previousColumn: this.dragState.currentColumn, + newColumn: columnAtPoint, + currentY: this.dragState.currentY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, payload); + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (!this.dragState.columnElement) + return; + const columnRect = this.dragState.columnElement.getBoundingClientRect(); + const targetY = e.clientY - columnRect.top - this.dragState.mouseOffset.y; + this.dragState.targetY = Math.max(0, targetY); + if (!this.dragState.animationId) { + this.animateDrag(); + } + } + /** + * Check if pointer is in header zone and emit appropriate events + */ + checkHeaderZone(e) { + if (!this.dragState) + return; + const headerViewport = document.querySelector("swp-header-viewport"); + if (!headerViewport) + return; + const rect = headerViewport.getBoundingClientRect(); + const isInHeader = e.clientY < rect.bottom; + if (isInHeader && !this.inHeader) { + this.inHeader = true; + if (this.dragState.dragSource === "grid" && this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + sourceColumnIndex: this.getColumnIndex(this.dragState.columnElement), + sourceColumnKey: this.dragState.columnElement.dataset.columnKey || "", + title: this.dragState.element.querySelector("swp-event-title")?.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")), + itemType: "event", + duration: 1 + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_ENTER_HEADER, payload); + } + } else if (!isInHeader && this.inHeader) { + this.inHeader = false; + const targetColumn = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header") { + const payload = { + eventId: this.dragState.eventId, + source: "header", + element: this.dragState.element, + targetColumn: targetColumn || void 0, + start: this.dragState.element.dataset.start ? new Date(this.dragState.element.dataset.start) : void 0, + end: this.dragState.element.dataset.end ? new Date(this.dragState.element.dataset.end) : void 0, + title: this.dragState.element.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")) + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + if (targetColumn) { + const newElement = targetColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (newElement) { + this.dragState.element = newElement; + this.dragState.columnElement = targetColumn; + this.dragState.currentColumn = targetColumn; + this.animateDrag(); + } + } + } else { + const payload = { + eventId: this.dragState.eventId, + source: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + } + } else if (isInHeader) { + const column = this.getColumnAtX(e.clientX); + if (column) { + const payload = { + eventId: this.dragState.eventId, + columnIndex: this.getColumnIndex(column), + columnKey: column.dataset.columnKey || "" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE_HEADER, payload); + } + } + } + /** + * Get column index (0-based) for a column element + */ + getColumnIndex(column) { + if (!this.container || !column) + return 0; + const columns = Array.from(this.container.querySelectorAll("swp-day-column")); + return columns.indexOf(column); + } + /** + * Get column at X coordinate (alias for getColumnAtPoint) + */ + getColumnAtX(clientX) { + return this.getColumnAtPoint(clientX); + } + /** + * Find column element at given X coordinate + */ + getColumnAtPoint(clientX) { + if (!this.container) + return null; + const columns = this.container.querySelectorAll("swp-day-column"); + for (const col of columns) { + const rect = col.getBoundingClientRect(); + if (clientX >= rect.left && clientX <= rect.right) { + return col; + } + } + return null; + } + /** + * Cancel drag and animate back to start position + */ + cancelDrag() { + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + const { element, ghostElement, startY, eventId } = this.dragState; + element.style.transition = "top 200ms ease-out"; + element.style.top = `${startY}px`; + setTimeout(() => { + ghostElement?.remove(); + element.style.transition = ""; + element.classList.remove("dragging"); + }, 200); + const payload = { + eventId, + element, + startY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_CANCEL, payload); + this.dragState = null; + this.inHeader = false; + } +}; +var EdgeScrollManager = class { + constructor(eventBus) { + this.eventBus = eventBus; + this.scrollableContent = null; + this.timeGrid = null; + this.draggedElement = null; + this.scrollRAF = null; + this.mouseY = 0; + this.isDragging = false; + this.isScrolling = false; + this.lastTs = 0; + this.rect = null; + this.initialScrollTop = 0; + this.OUTER_ZONE = 100; + this.INNER_ZONE = 50; + this.SLOW_SPEED = 140; + this.FAST_SPEED = 640; + this.trackMouse = (e) => { + if (this.isDragging) { + this.mouseY = e.clientY; + } + }; + this.scrollTick = (ts) => { + if (!this.isDragging || !this.scrollableContent) + return; + const dt = this.lastTs ? (ts - this.lastTs) / 1e3 : 0; + this.lastTs = ts; + this.rect ?? (this.rect = this.scrollableContent.getBoundingClientRect()); + const velocity = this.calculateVelocity(); + if (velocity !== 0 && !this.isAtBoundary(velocity)) { + const scrollDelta = velocity * dt; + this.scrollableContent.scrollTop += scrollDelta; + this.rect = null; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_TICK, { scrollDelta }); + this.setScrollingState(true); + } else { + this.setScrollingState(false); + } + this.scrollRAF = requestAnimationFrame(this.scrollTick); + }; + this.subscribeToEvents(); + document.addEventListener("pointermove", this.trackMouse); + } + init(scrollableContent) { + this.scrollableContent = scrollableContent; + this.timeGrid = scrollableContent.querySelector("swp-time-grid"); + this.scrollableContent.style.scrollBehavior = "auto"; + } + subscribeToEvents() { + this.eventBus.on(CoreEvents.EVENT_DRAG_START, (event) => { + const payload = event.detail; + this.draggedElement = payload.element; + this.startDrag(); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, () => this.stopDrag()); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => this.stopDrag()); + } + startDrag() { + this.isDragging = true; + this.isScrolling = false; + this.lastTs = 0; + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + if (this.scrollRAF === null) { + this.scrollRAF = requestAnimationFrame(this.scrollTick); + } + } + stopDrag() { + this.isDragging = false; + this.setScrollingState(false); + if (this.scrollRAF !== null) { + cancelAnimationFrame(this.scrollRAF); + this.scrollRAF = null; + } + this.rect = null; + this.lastTs = 0; + this.initialScrollTop = 0; + } + calculateVelocity() { + if (!this.rect) + return 0; + const distTop = this.mouseY - this.rect.top; + const distBot = this.rect.bottom - this.mouseY; + if (distTop < this.INNER_ZONE) + return -this.FAST_SPEED; + if (distTop < this.OUTER_ZONE) + return -this.SLOW_SPEED; + if (distBot < this.INNER_ZONE) + return this.FAST_SPEED; + if (distBot < this.OUTER_ZONE) + return this.SLOW_SPEED; + return 0; + } + isAtBoundary(velocity) { + if (!this.scrollableContent || !this.timeGrid || !this.draggedElement) + return false; + const atTop = this.scrollableContent.scrollTop <= 0 && velocity < 0; + const atBottom = velocity > 0 && this.draggedElement.getBoundingClientRect().bottom >= this.timeGrid.getBoundingClientRect().bottom; + return atTop || atBottom; + } + setScrollingState(scrolling) { + if (this.isScrolling === scrolling) + return; + this.isScrolling = scrolling; + if (scrolling) { + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STARTED, {}); + } else { + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STOPPED, {}); + } + } +}; +var ResizeManager = class { + constructor(eventBus, gridConfig, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dateService = dateService; + this.container = null; + this.resizeState = null; + this.Z_INDEX_RESIZING = "1000"; + this.ANIMATION_SPEED = 0.35; + this.MIN_HEIGHT_MINUTES = 15; + this.handleMouseOver = (e) => { + const target = e.target; + const eventElement = target.closest("swp-event"); + if (!eventElement || this.resizeState) + return; + if (!eventElement.querySelector(":scope > swp-resize-handle")) { + const handle = this.createResizeHandle(); + eventElement.appendChild(handle); + } + }; + this.handlePointerDown = (e) => { + const handle = e.target.closest("swp-resize-handle"); + if (!handle) + return; + const element = handle.parentElement; + if (!element) + return; + const eventId = element.dataset.eventId || ""; + const startHeight = element.offsetHeight; + const startDurationMinutes = pixelsToMinutes(startHeight, this.gridConfig); + const container = element.closest("swp-event-group") ?? element; + const prevZIndex = container.style.zIndex; + this.resizeState = { + eventId, + element, + handleElement: handle, + startY: e.clientY, + startHeight, + startDurationMinutes, + pointerId: e.pointerId, + prevZIndex, + // Animation state + currentHeight: startHeight, + targetHeight: startHeight, + animationId: null + }; + container.style.zIndex = this.Z_INDEX_RESIZING; + try { + handle.setPointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer capture failed:", err); + } + document.documentElement.classList.add("swp--resizing"); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_START, { + eventId, + element, + startHeight + }); + e.preventDefault(); + }; + this.handlePointerMove = (e) => { + if (!this.resizeState) + return; + const deltaY = e.clientY - this.resizeState.startY; + const minHeight = this.MIN_HEIGHT_MINUTES / 60 * this.gridConfig.hourHeight; + const newHeight = Math.max(minHeight, this.resizeState.startHeight + deltaY); + this.resizeState.targetHeight = newHeight; + if (this.resizeState.animationId === null) { + this.animateHeight(); + } + }; + this.animateHeight = () => { + if (!this.resizeState) + return; + const diff2 = this.resizeState.targetHeight - this.resizeState.currentHeight; + if (Math.abs(diff2) < 0.5) { + this.resizeState.animationId = null; + return; + } + this.resizeState.currentHeight += diff2 * this.ANIMATION_SPEED; + this.resizeState.element.style.height = `${this.resizeState.currentHeight}px`; + this.updateTimestampDisplay(); + this.resizeState.animationId = requestAnimationFrame(this.animateHeight); + }; + this.handlePointerUp = (e) => { + if (!this.resizeState) + return; + if (this.resizeState.animationId !== null) { + cancelAnimationFrame(this.resizeState.animationId); + } + try { + this.resizeState.handleElement.releasePointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer release failed:", err); + } + this.snapToGridFinal(); + this.updateTimestampDisplay(); + const container = this.resizeState.element.closest("swp-event-group") ?? this.resizeState.element; + container.style.zIndex = this.resizeState.prevZIndex; + document.documentElement.classList.remove("swp--resizing"); + const column = this.resizeState.element.closest("swp-day-column"); + const columnKey = column?.dataset.columnKey || ""; + const date = column?.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.resizeState.element, columnKey, date, this.gridConfig); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_END, { + swpEvent + }); + this.resizeState = null; + }; + } + /** + * Initialize resize functionality on container + */ + init(container) { + this.container = container; + container.addEventListener("mouseover", this.handleMouseOver, true); + document.addEventListener("pointerdown", this.handlePointerDown, true); + document.addEventListener("pointermove", this.handlePointerMove, true); + document.addEventListener("pointerup", this.handlePointerUp, true); + } + /** + * Create resize handle element + */ + createResizeHandle() { + const handle = document.createElement("swp-resize-handle"); + handle.setAttribute("aria-label", "Resize event"); + handle.setAttribute("role", "separator"); + return handle; + } + /** + * Update timestamp display with snapped end time + */ + updateTimestampDisplay() { + if (!this.resizeState) + return; + const timeEl = this.resizeState.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const top = parseFloat(this.resizeState.element.style.top) || 0; + const startMinutesFromGrid = pixelsToMinutes(top, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const snappedHeight = snapToGrid(this.resizeState.currentHeight, this.gridConfig); + const durationMinutes = pixelsToMinutes(snappedHeight, this.gridConfig); + const endMinutes = startMinutes + durationMinutes; + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(endMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to Date + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Snap final height to grid interval + */ + snapToGridFinal() { + if (!this.resizeState) + return; + const currentHeight = this.resizeState.element.offsetHeight; + const snappedHeight = snapToGrid(currentHeight, this.gridConfig); + const minHeight = minutesToPixels(this.MIN_HEIGHT_MINUTES, this.gridConfig); + const finalHeight = Math.max(minHeight, snappedHeight); + this.resizeState.element.style.height = `${finalHeight}px`; + this.resizeState.currentHeight = finalHeight; + } +}; +var EventPersistenceManager = class { + constructor(eventService, eventBus, dateService) { + this.eventService = eventService; + this.eventBus = eventBus; + this.dateService = dateService; + this.handleDragEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const { resource } = this.dateService.parseColumnKey(swpEvent.columnKey); + const updatedEvent = { + ...event, + start: swpEvent.start, + end: swpEvent.end, + resourceId: resource ?? event.resourceId, + allDay: payload.target === "header", + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: payload.sourceColumnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.handleResizeEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const updatedEvent = { + ...event, + end: swpEvent.end, + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: swpEvent.columnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.setupListeners(); + } + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_END, this.handleDragEnd); + this.eventBus.on(CoreEvents.EVENT_RESIZE_END, this.handleResizeEnd); + } +}; +var defaultTimeFormatConfig = { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + use24HourFormat: true, + locale: "da-DK", + dateFormat: "locale", + showSeconds: false +}; +var defaultGridConfig = { + hourHeight: 64, + dayStartHour: 6, + dayEndHour: 18, + snapInterval: 15, + gridStartThresholdMinutes: 30 +}; +function registerCoreServices(builder, options) { + const timeConfig = options?.timeConfig ?? defaultTimeFormatConfig; + const gridConfig = options?.gridConfig ?? defaultGridConfig; + const dbConfig = options?.dbConfig ?? defaultDBConfig; + builder.registerInstance(timeConfig).as("ITimeFormatConfig"); + builder.registerInstance(gridConfig).as("IGridConfig"); + builder.registerInstance(dbConfig).as("IDBConfig"); + builder.registerType(EventBus).as("EventBus"); + builder.registerType(EventBus).as("IEventBus"); + builder.registerType(DateService).as("DateService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ITimeFormatConfig"), + void 0 + ] + }); + builder.registerType(IndexedDBContext).as("IndexedDBContext").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IStore"), + (c) => c.resolveType("IDBConfig") + ] + }); + builder.registerType(EventStore).as("IStore"); + builder.registerType(ResourceStore).as("IStore"); + builder.registerType(SettingsStore).as("IStore"); + builder.registerType(ViewConfigStore).as("IStore"); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("EventService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("ResourceService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("SettingsService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("ViewConfigService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventRenderer).as("EventRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ScheduleRenderer).as("ScheduleRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceScheduleService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(HeaderDrawerRenderer).as("HeaderDrawerRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(TimeAxisRenderer).as("TimeAxisRenderer"); + builder.registerType(DateRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(ResourceRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService") + ] + }); + builder.registerType(ScrollManager).as("ScrollManager"); + builder.registerType(HeaderDrawerManager).as("HeaderDrawerManager"); + builder.registerType(DragDropManager).as("DragDropManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(EdgeScrollManager).as("EdgeScrollManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResizeManager).as("ResizeManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(EventPersistenceManager).as("EventPersistenceManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(CalendarOrchestrator).as("CalendarOrchestrator").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IRenderer"), + (c) => c.resolveType("EventRenderer"), + (c) => c.resolveType("ScheduleRenderer"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveTypeAll("IEntityService") + ] + }); + builder.registerType(CalendarApp).as("CalendarApp").autoWire({ + mapResolvers: [ + (c) => c.resolveType("CalendarOrchestrator"), + (c) => c.resolveType("TimeAxisRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("ScrollManager"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("DragDropManager"), + (c) => c.resolveType("EdgeScrollManager"), + (c) => c.resolveType("ResizeManager"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("EventPersistenceManager"), + (c) => c.resolveType("SettingsService"), + (c) => c.resolveType("ViewConfigService"), + (c) => c.resolveType("IEventBus") + ] + }); +} + +// node_modules/calendar/dist/extensions/schedules/index.js +var ScheduleOverrideStore = class _ScheduleOverrideStore { + constructor() { + this.storeName = _ScheduleOverrideStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ScheduleOverrideStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("date", "date", { unique: false }); + store.createIndex("resourceId_date", ["resourceId", "date"], { unique: true }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + } +}; +ScheduleOverrideStore.STORE_NAME = "scheduleOverrides"; +var ScheduleOverrideService = class { + constructor(context) { + this.context = context; + } + get db() { + return this.context.getDatabase(); + } + /** + * Get override for a specific resource and date + */ + async getOverride(resourceId, date) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId_date"); + const request = index.get([resourceId, date]); + request.onsuccess = () => { + resolve(request.result || null); + }; + request.onerror = () => { + reject(new Error(`Failed to get override for ${resourceId} on ${date}: ${request.error}`)); + }; + }); + } + /** + * Get all overrides for a resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + resolve(request.result || []); + }; + request.onerror = () => { + reject(new Error(`Failed to get overrides for ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get overrides for a date range + */ + async getByDateRange(resourceId, startDate, endDate) { + const all = await this.getByResource(resourceId); + return all.filter((o) => o.date >= startDate && o.date <= endDate); + } + /** + * Save an override + */ + async save(override) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.put(override); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to save override ${override.id}: ${request.error}`)); + }; + }); + } + /** + * Delete an override + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.delete(id); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to delete override ${id}: ${request.error}`)); + }; + }); + } +}; +var ResourceScheduleService = class { + constructor(resourceService, overrideService, dateService) { + this.resourceService = resourceService; + this.overrideService = overrideService; + this.dateService = dateService; + } + /** + * Get effective schedule for a resource on a specific date + * + * @param resourceId - Resource ID + * @param date - Date string "YYYY-MM-DD" + * @returns ITimeSlot or null (fri/closed) + */ + async getScheduleForDate(resourceId, date) { + const override = await this.overrideService.getOverride(resourceId, date); + if (override) { + return override.schedule; + } + const resource = await this.resourceService.get(resourceId); + if (!resource || !resource.defaultSchedule) { + return null; + } + const weekDay = this.dateService.getISOWeekDay(date); + return resource.defaultSchedule[weekDay] || null; + } + /** + * Get schedules for multiple dates + * + * @param resourceId - Resource ID + * @param dates - Array of date strings "YYYY-MM-DD" + * @returns Map of date -> ITimeSlot | null + */ + async getSchedulesForDates(resourceId, dates) { + const result = /* @__PURE__ */ new Map(); + const resource = await this.resourceService.get(resourceId); + const overrides = dates.length > 0 ? await this.overrideService.getByDateRange(resourceId, dates[0], dates[dates.length - 1]) : []; + const overrideMap = new Map(overrides.map((o) => [o.date, o.schedule])); + for (const date of dates) { + if (overrideMap.has(date)) { + result.set(date, overrideMap.get(date)); + continue; + } + if (resource?.defaultSchedule) { + const weekDay = this.dateService.getISOWeekDay(date); + result.set(date, resource.defaultSchedule[weekDay] || null); + } else { + result.set(date, null); + } + } + return result; + } +}; +function registerSchedules(builder) { + builder.registerType(ScheduleOverrideStore).as("IStore"); + builder.registerType(ScheduleOverrideService).as("ScheduleOverrideService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext") + ] + }); + builder.registerType(ResourceScheduleService).as("ResourceScheduleService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService"), + (c) => c.resolveType("ScheduleOverrideService"), + (c) => c.resolveType("DateService") + ] + }); +} + +// src/index.ts +async function init() { + const databases = await indexedDB.databases(); + const dbExists = databases.some((db) => db.name === "CalendarTestDB"); + const container = new Container(); + const builder = container.builder(); + registerCoreServices(builder, { + dbConfig: { dbName: "CalendarTestDB", dbVersion: 4 } + }); + registerSchedules(builder); + const app = builder.build(); + console.log("Container created"); + const dbContext = app.resolveType("IndexedDBContext"); + await dbContext.initialize(); + console.log("IndexedDB initialized"); + const settingsService = app.resolveType("SettingsService"); + const viewConfigService = app.resolveType("ViewConfigService"); + const eventService = app.resolveType("EventService"); + if (dbExists) { + console.log("Database exists, skipping seed"); + } else { + console.log("Seeding data..."); + await seedData(settingsService, viewConfigService, eventService); + } + const calendarApp = app.resolveType("CalendarApp"); + const containerEl = document.querySelector("swp-calendar-container"); + await calendarApp.init(containerEl); + const eventBus = app.resolveType("EventBus"); + eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: "simple" }); + console.log("Calendar rendered"); + document.addEventListener("event:drag-end", (e) => { + console.log("event:drag-end:", e.detail); + }); + document.addEventListener("event:updated", (e) => { + console.log("event:updated:", e.detail); + }); + const persistenceManager = app.resolveType("EventPersistenceManager"); + console.log("EventPersistenceManager resolved:", persistenceManager); +} +async function seedData(settingsService, viewConfigService, eventService) { + await settingsService.save({ + id: "grid", + dayStartHour: 8, + dayEndHour: 17, + workStartHour: 9, + workEndHour: 16, + hourHeight: 64, + snapInterval: 15, + syncStatus: "synced" + }); + await settingsService.save({ + id: "workweek", + presets: { + standard: { id: "standard", label: "Standard", workDays: [1, 2, 3, 4, 5], periodDays: 7 } + }, + defaultPreset: "standard", + firstDayOfWeek: 1, + syncStatus: "synced" + }); + await viewConfigService.save({ + id: "simple", + groupings: [{ type: "date", values: [], idProperty: "date", derivedFrom: "start" }], + syncStatus: "synced" + }); + const today = /* @__PURE__ */ new Date(); + today.setHours(0, 0, 0, 0); + console.log("Event date:", today.toISOString()); + const start1 = new Date(today); + start1.setHours(9, 0, 0, 0); + const end1 = new Date(today); + end1.setHours(10, 0, 0, 0); + await eventService.save({ + id: "1", + title: "Morgenm\xF8de", + start: start1, + end: end1, + type: "meeting", + allDay: false, + syncStatus: "synced" + }); + const start2 = new Date(today); + start2.setHours(12, 0, 0, 0); + const end2 = new Date(today); + end2.setHours(13, 0, 0, 0); + await eventService.save({ + id: "2", + title: "Frokost", + start: start2, + end: end2, + type: "break", + allDay: false, + syncStatus: "synced" + }); +} +init().catch(console.error); diff --git a/test-package/dist/css/calendar.css b/test-package/dist/css/calendar.css new file mode 100644 index 0000000..5a06eed --- /dev/null +++ b/test-package/dist/css/calendar.css @@ -0,0 +1,877 @@ +/* V2 Base - Shared variables */ + +:root { + /* Grid measurements */ + --hour-height: 64px; + --time-axis-width: 60px; + --grid-columns: 7; + --day-column-min-width: 200px; + --day-start-hour: 6; + --day-end-hour: 18; + --header-height: 70px; + + /* Colors - UI */ + --color-border: #e0e0e0; + --color-surface: #fff; + --color-background: #f5f5f5; + --color-background-hover: #f0f0f0; + --color-background-alt: #fafafa; + --color-text: #333333; + --color-text-secondary: #666; + --color-primary: #1976d2; + --color-team-bg: #e3f2fd; + --color-team-text: #1565c0; + + /* Colors - Grid */ + --color-hour-line: rgba(0, 0, 0, 0.2); + --color-grid-line-light: rgba(0, 0, 0, 0.05); + --color-unavailable: rgba(0, 0, 0, 0.02); + + /* Named color palette for events (fra V1) */ + --b-color-red: #e53935; + --b-color-pink: #d81b60; + --b-color-magenta: #c200c2; + --b-color-purple: #8e24aa; + --b-color-violet: #5e35b1; + --b-color-deep-purple: #4527a0; + --b-color-indigo: #3949ab; + --b-color-blue: #1e88e5; + --b-color-light-blue: #03a9f4; + --b-color-cyan: #3bc9db; + --b-color-teal: #00897b; + --b-color-green: #43a047; + --b-color-light-green: #8bc34a; + --b-color-lime: #c0ca33; + --b-color-yellow: #fdd835; + --b-color-amber: #ffb300; + --b-color-orange: #fb8c00; + --b-color-deep-orange: #f4511e; + + /* Base mix for color-mix() function */ + --b-mix: #fff; + + /* Shadows */ + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); + --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); + + /* Transitions */ + --transition-fast: 150ms ease; +} + +* { box-sizing: border-box; margin: 0; padding: 0; } + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: var(--color-background); +} + +/* V2 Layout - Calendar structure, grid, navigation */ + +.calendar-wrapper { + height: 100vh; + display: flex; + flex-direction: column; +} + +swp-calendar { + display: grid; + grid-template-rows: auto 1fr; + height: 100%; + background: var(--color-surface); +} + +/* Nav */ +swp-calendar-nav { + display: flex; + gap: 12px; + padding: 8px 16px; + border-bottom: 1px solid var(--color-border); + align-items: center; + font-size: 13px; +} + +/* View switcher - small chips */ +swp-view-switcher { + display: flex; + gap: 4px; + background: var(--color-background-alt); + padding: 3px; + border-radius: 6px; +} + +.view-chip { + padding: 4px 10px; + border: none; + border-radius: 4px; + cursor: pointer; + background: transparent; + color: var(--color-text-secondary); + font-size: 12px; + font-weight: 500; + transition: all 0.15s ease; + + &:hover { + background: var(--color-surface); + color: var(--color-text); + } + + &.active { + background: var(--color-surface); + color: var(--color-text); + box-shadow: 0 1px 2px rgba(0,0,0,0.1); + } +} + +/* Workweek dropdown */ +.workweek-dropdown { + padding: 4px 8px; + border: 1px solid var(--color-border); + border-radius: 4px; + background: var(--color-surface); + font-size: 12px; + cursor: pointer; + + &:hover { border-color: var(--color-text-secondary); } + &:focus { outline: 2px solid var(--color-primary); outline-offset: 1px; } +} + +/* Resource selector (picker view) */ +swp-resource-selector { + &.hidden { display: none; } + + fieldset { + border: 1px solid var(--color-border); + border-radius: 6px; + padding: 6px 12px; + margin: 0; + } + + legend { + font-size: 11px; + font-weight: 500; + color: var(--color-text-secondary); + padding: 0 6px; + } + + .resource-checkboxes { + display: flex; + flex-wrap: wrap; + gap: 4px 16px; + } + + label { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + cursor: pointer; + white-space: nowrap; + + &:hover { color: var(--color-primary); } + } + + input[type="checkbox"] { + width: 14px; + height: 14px; + cursor: pointer; + } +} + +/* Navigation group */ +swp-nav-group { + display: flex; + gap: 2px; +} + +swp-nav-button { + padding: 6px 12px; + border: 1px solid var(--color-border); + border-radius: 4px; + cursor: pointer; + background: var(--color-surface); + font-size: 12px; + + &:hover { background: var(--color-background-hover); } + + &.btn-small { + padding: 4px 8px; + font-size: 11px; + } +} + +swp-week-info { + margin-left: auto; + text-align: right; + + swp-week-number { + font-weight: 600; + font-size: 12px; + display: block; + } + + swp-date-range { + font-size: 11px; + color: var(--color-text-secondary); + } +} + +/* Container */ +swp-calendar-container { + display: grid; + grid-template-columns: var(--time-axis-width) 1fr; + grid-template-rows: auto 1fr; + overflow: hidden; + height: 100%; +} + +/* Time axis */ +swp-time-axis { + grid-column: 1; + grid-row: 1 / 3; + display: grid; + grid-template-rows: auto 1fr; + border-right: 1px solid var(--color-border); + background: var(--color-surface); + overflow: hidden; + user-select: none; +} + +swp-header-spacer { + border-bottom: 1px solid var(--color-border); + background: var(--color-surface); + z-index: 1; +} + +swp-header-drawer { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + grid-row: 2; + overflow: hidden; + background: var(--color-background-alt); + border-bottom: 1px solid var(--color-border); +} + +swp-time-axis-content { + display: flex; + flex-direction: column; + position: relative; +} + +swp-hour-marker { + height: var(--hour-height); + padding: 4px 8px; + font-size: 11px; + color: var(--color-text-secondary); + text-align: right; + position: relative; + + &::after { + content: ''; + position: absolute; + top: -1px; + right: 0; + width: 5px; + height: 1px; + background: var(--color-hour-line); + } + + &:first-child::after { + display: none; + } +} + +/* Grid container */ +swp-grid-container { + grid-column: 2; + grid-row: 1 / 3; + display: grid; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: subgrid; + overflow: hidden; +} + +/* Viewport/Track for slide animation */ +swp-header-viewport { + display: grid; + grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr)); + grid-template-rows: auto auto; + min-width: calc(var(--grid-columns) * var(--day-column-min-width)); + overflow-y: scroll; + overflow-x: hidden; + + &::-webkit-scrollbar { background: transparent; } + &::-webkit-scrollbar-thumb { background: transparent; } +} + +swp-content-viewport { + overflow: hidden; + min-height: 0; + width: 100%; +} + +swp-header-track { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + grid-row: 1; +} + +swp-content-track { + display: flex; + height: 100%; + + > swp-scrollable-content { + flex: 0 0 100%; + height: 100%; + } +} + +/* Header */ +swp-calendar-header { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + grid-auto-rows: auto; + background: var(--color-surface); + + &[data-levels="date"] > swp-day-header { grid-row: 1; } + + &[data-levels="resource date"] { + > swp-resource-header { grid-row: 1; } + > swp-day-header { grid-row: 2; } + } + + &[data-levels="team resource date"] { + > swp-team-header { grid-row: 1; } + > swp-resource-header { grid-row: 2; } + > swp-day-header { grid-row: 3; } + } + + &[data-levels="department resource date"] { + > swp-department-header { grid-row: 1; } + > swp-resource-header { grid-row: 2; } + > swp-day-header { grid-row: 3; } + } +} + +swp-day-header, +swp-resource-header, +swp-team-header, +swp-department-header { + padding: 8px; + text-align: center; + border-right: 1px solid var(--color-border); + border-bottom: 1px solid var(--color-border); + user-select: none; +} + +swp-team-header { + background: var(--color-team-bg); + color: var(--color-team-text); + font-weight: 500; + grid-column: span var(--team-cols, 1); +} + +swp-department-header { + background: var(--color-team-bg); + color: var(--color-team-text); + font-weight: 500; + grid-column: span var(--department-cols, 1); +} + +swp-resource-header { + background: var(--color-background-alt); + font-size: 13px; +} + +swp-day-header { + swp-day-name { + display: block; + font-size: 11px; + color: var(--color-text-secondary); + text-transform: uppercase; + } + + swp-day-date { + display: block; + font-size: 24px; + font-weight: 300; + } + + &[data-hidden="true"] { + display: none; + } +} + +/* Scrollable content */ +swp-scrollable-content { + display: block; + overflow: auto; +} + +swp-time-grid { + display: block; + position: relative; + min-height: calc((var(--day-end-hour) - var(--day-start-hour)) * var(--hour-height)); + min-width: calc(var(--grid-columns) * var(--day-column-min-width)); + + /* Timelinjer */ + &::after { + content: ''; + position: absolute; + inset: 0; + z-index: 2; + background-image: repeating-linear-gradient( + to bottom, + transparent, + transparent calc(var(--hour-height) - 1px), + var(--color-hour-line) calc(var(--hour-height) - 1px), + var(--color-hour-line) var(--hour-height) + ); + pointer-events: none; + } +} + +/* Kvarterlinjer - 3 linjer per time (15, 30, 45 min) */ +swp-grid-lines { + display: block; + position: absolute; + inset: 0; + z-index: 1; + background-image: repeating-linear-gradient( + to bottom, + transparent 0, + transparent calc(var(--hour-height) / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 4), + transparent calc(var(--hour-height) / 4), + transparent calc(var(--hour-height) / 2 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 2 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 2), + transparent calc(var(--hour-height) / 2), + transparent calc(var(--hour-height) * 3 / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4), + transparent calc(var(--hour-height) * 3 / 4), + transparent var(--hour-height) + ); +} + +swp-day-columns { + position: absolute; + inset: 0; + display: grid; + grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr)); + min-width: calc(var(--grid-columns) * var(--day-column-min-width)); +} + +swp-day-column { + position: relative; + border-right: 1px solid var(--color-border); +} + +swp-events-layer { + position: absolute; + inset: 0; + z-index: 10; +} + +/* Unavailable time zones (outside working hours) */ +swp-unavailable-layer { + position: absolute; + inset: 0; + z-index: 5; + pointer-events: none; +} + +swp-unavailable-zone { + position: absolute; + left: 0; + right: 0; + background: var(--color-unavailable, rgba(0, 0, 0, 0.05)); + pointer-events: none; +} + +/* V2 Events - Event styling (from V1 calendar-events-css.css) */ + +/* Event base styles */ +swp-day-columns swp-event { + --b-text: var(--color-text); + + position: absolute; + border-radius: 3px; + overflow: hidden; + cursor: pointer; + transition: background-color 200ms ease, box-shadow 150ms ease, transform 150ms ease; + z-index: 10; + left: 2px; + right: 2px; + font-size: 12px; + padding: 4px 6px; + user-select: none; + + /* Color system using color-mix() */ + background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); + color: var(--b-text); + border-left: 4px solid var(--b-primary); + + /* Enable container queries for responsive layout */ + container-type: size; + container-name: event; + + /* CSS Grid layout for time, title, and description */ + display: grid; + grid-template-columns: auto 1fr; + grid-template-rows: auto 1fr; + gap: 2px 4px; + align-items: start; + + /* Dragging state */ + &.dragging { + position: absolute; + z-index: 999999; + left: 2px; + right: 2px; + width: auto; + cursor: grabbing; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + } + + /* Ghost clone (stays in original position during drag) */ + &.drag-ghost { + opacity: 0.3; + pointer-events: none; + } + + /* Hover state */ + &:hover { + background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); + } +} + +swp-day-columns swp-event:hover { + z-index: 20; +} + +/* Resize handle - actual draggable element */ +swp-resize-handle { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 15px; + cursor: ns-resize; + z-index: 25; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 150ms ease; +} + +/* Show handle on hover */ +swp-day-columns swp-event:hover swp-resize-handle { + opacity: 1; +} + +/* Handle visual indicator (grip lines) */ +swp-resize-handle::before { + content: ''; + width: 30px; + height: 4px; + background: rgba(255, 255, 255, 0.9); + border-radius: 2px; + box-shadow: + 0 -2px 0 rgba(255, 255, 255, 0.9), + 0 2px 0 rgba(255, 255, 255, 0.9), + 0 0 4px rgba(0, 0, 0, 0.2); +} + +/* Global resizing state */ +.swp--resizing { + user-select: none !important; + cursor: ns-resize !important; +} + +.swp--resizing * { + cursor: ns-resize !important; +} + +swp-day-columns swp-event-time { + grid-column: 1; + grid-row: 1; + font-size: 0.875rem; + font-weight: 500; + white-space: nowrap; +} + +swp-day-columns swp-event-title { + grid-column: 2; + grid-row: 1; + font-size: 0.875rem; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +swp-day-columns swp-event-description { + grid-column: 1 / -1; + grid-row: 2; + display: block; + font-size: 0.875rem; + opacity: 0.8; + line-height: 1.3; + overflow: hidden; + word-wrap: break-word; + + /* Ensure description fills available height for gradient effect */ + min-height: 100%; + align-self: stretch; + + /* Fade-out effect for long descriptions */ + -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%); + mask-image: linear-gradient(to bottom, black 70%, transparent 100%); +} + +/* Container queries for height-based layout */ + +/* Hide description when event is too short (< 30px) */ +@container event (height < 30px) { + swp-day-columns swp-event-description { + display: none; + } +} + +/* Full description for tall events (>= 100px) */ +@container event (height >= 100px) { + swp-day-columns swp-event-description { + max-height: none; + } +} + +/* Multi-day events */ +swp-multi-day-event { + position: relative; + height: 28px; + margin: 2px 4px; + padding: 0 8px; + border-radius: 4px; + display: flex; + align-items: center; + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; + transition: all var(--transition-fast); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + user-select: none; + + /* Color system using color-mix() */ + --b-text: var(--color-text); + background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); + color: var(--b-text); + border-left: 4px solid var(--b-primary); + + &:hover { + background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); + } + + /* Continuation indicators */ + &[data-continues-before="true"] { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: 0; + padding-left: 20px; + + &::before { + content: '\25C0'; + position: absolute; + left: 4px; + opacity: 0.6; + font-size: 0.75rem; + } + } + + &[data-continues-after="true"] { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin-right: 0; + padding-right: 20px; + + &::after { + content: '\25B6'; + position: absolute; + right: 4px; + opacity: 0.6; + font-size: 0.75rem; + } + } + + &:hover { + transform: translateY(-1px); + box-shadow: var(--shadow-sm); + } +} + +/* All-day events */ +swp-allday-event { + --b-text: var(--color-text); + background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); + color: var(--b-text); + border-left: 4px solid var(--b-primary); + cursor: pointer; + transition: background-color 200ms ease; + user-select: none; + + &:hover { + background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); + } +} + +/* Event creation preview */ +swp-event-preview { + position: absolute; + left: 8px; + right: 8px; + background: rgba(33, 150, 243, 0.1); + border: 2px dashed var(--color-primary); + border-radius: 4px; + + /* Position via CSS variables */ + top: calc(var(--preview-start) * var(--minute-height)); + height: calc(var(--preview-duration) * var(--minute-height)); +} + +/* Event filtering styles */ +/* When filter is active, all events are dimmed by default */ +swp-events-layer[data-filter-active="true"] swp-event { + opacity: 0.2; + transition: opacity 200ms ease; +} + +/* Events that match the filter stay normal */ +swp-events-layer[data-filter-active="true"] swp-event[data-matches="true"] { + opacity: 1; +} + +/* Event overlap styling */ +/* Event group container for column sharing */ +swp-event-group { + position: absolute; + display: grid; + gap: 2px; + left: 2px; + right: 2px; + z-index: 10; +} + +/* Grid column configurations */ +swp-event-group.cols-2 { + grid-template-columns: 1fr 1fr; +} + +swp-event-group.cols-3 { + grid-template-columns: 1fr 1fr 1fr; +} + +swp-event-group.cols-4 { + grid-template-columns: 1fr 1fr 1fr 1fr; +} + +/* Stack levels using margin-left */ +swp-event-group.stack-level-0 { + margin-left: 0px; +} + +swp-event-group.stack-level-1 { + margin-left: 15px; +} + +swp-event-group.stack-level-2 { + margin-left: 30px; +} + +swp-event-group.stack-level-3 { + margin-left: 45px; +} + +swp-event-group.stack-level-4 { + margin-left: 60px; +} + +/* Shadow for stacked events (level 1+) */ +swp-event[data-stack-link]:not([data-stack-link*='"stackLevel":0']), +swp-event-group[data-stack-link]:not([data-stack-link*='"stackLevel":0']) swp-event { + box-shadow: + 0 -1px 2px rgba(0, 0, 0, 0.1), + 0 1px 2px rgba(0, 0, 0, 0.1); +} + +/* Child events within grid */ +swp-event-group swp-event { + position: relative; + left: 0; + right: 0; +} + +/* All-day event transition for smooth repositioning */ +swp-allday-container swp-event.transitioning { + transition: grid-area 200ms ease-out, grid-row 200ms ease-out, grid-column 200ms ease-out; +} + +/* Color utility classes */ +.is-red { --b-primary: var(--b-color-red); } +.is-pink { --b-primary: var(--b-color-pink); } +.is-magenta { --b-primary: var(--b-color-magenta); } +.is-purple { --b-primary: var(--b-color-purple); } +.is-violet { --b-primary: var(--b-color-violet); } +.is-deep-purple { --b-primary: var(--b-color-deep-purple); } +.is-indigo { --b-primary: var(--b-color-indigo); } +.is-blue { --b-primary: var(--b-color-blue); } +.is-light-blue { --b-primary: var(--b-color-light-blue); } +.is-cyan { --b-primary: var(--b-color-cyan); } +.is-teal { --b-primary: var(--b-color-teal); } +.is-green { --b-primary: var(--b-color-green); } +.is-light-green { --b-primary: var(--b-color-light-green); } +.is-lime { --b-primary: var(--b-color-lime); } +.is-yellow { --b-primary: var(--b-color-yellow); } +.is-amber { --b-primary: var(--b-color-amber); } +.is-orange { --b-primary: var(--b-color-orange); } +.is-deep-orange { --b-primary: var(--b-color-deep-orange); } + +/* Header drawer items */ +swp-header-item { + --b-text: var(--color-text); + + /* Positioneres via style.gridArea */ + height: 22px; + margin: 1px 4px; + padding: 2px 8px; + border-radius: 3px; + font-size: 0.75rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: flex; + align-items: center; + cursor: pointer; + user-select: none; + transition: background-color 200ms ease; + + /* Color system - inverted from swp-event */ + background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)); + color: var(--b-text); + + &:hover { + background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix)); + } + + /* Dragging state */ + &.dragging { + opacity: 0.7; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + } +} diff --git a/test-package/index.html b/test-package/index.html new file mode 100644 index 0000000..fcc8084 --- /dev/null +++ b/test-package/index.html @@ -0,0 +1,41 @@ + + + + + + Calendar Package Test + + + +

    Calendar Package Test

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + diff --git a/test-package/package-lock.json b/test-package/package-lock.json new file mode 100644 index 0000000..c458173 --- /dev/null +++ b/test-package/package-lock.json @@ -0,0 +1,654 @@ +{ + "name": "test-package", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "test-package", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@novadi/core": "^0.6.0", + "calendar": "^0.1.6", + "dayjs": "^1.11.19" + }, + "devDependencies": { + "esbuild": "^0.27.2", + "typescript": "^5.9.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@novadi/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@novadi/core/-/core-0.6.0.tgz", + "integrity": "sha512-CU1134Nd7ULMg9OQbID5oP+FLtrMkNiLJ17+dmy4jjmPDcPK/dVzKTFxvJmbBvEfZEc9WtmkmJjqw11ABU7Jxw==", + "license": "MIT", + "dependencies": { + "unplugin": "^2.3.10" + }, + "optionalDependencies": { + "@rollup/rollup-win32-x64-msvc": "^4.52.5" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/calendar": { + "version": "0.1.6", + "resolved": "http://npm.jarjarbinks:4873/calendar/-/calendar-0.1.6.tgz", + "integrity": "sha512-dZKOg6gHTAexklxsBGnszTWDi0rkV68XXV9epaHxZP6RlMvys155dpitq6q3aWCGbSw8xKeTF7FTHaz5yJoT6A==", + "dependencies": { + "dayjs": "^1.11.0" + }, + "peerDependencies": { + "@novadi/core": "^0.6.0" + } + }, + "node_modules/dayjs": { + "version": "1.11.19", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", + "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" + } + } +} diff --git a/test-package/package.json b/test-package/package.json new file mode 100644 index 0000000..c0d1011 --- /dev/null +++ b/test-package/package.json @@ -0,0 +1,21 @@ +{ + "name": "test-package", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@novadi/core": "^0.6.0", + "calendar": "^0.1.6", + "dayjs": "^1.11.19" + }, + "devDependencies": { + "esbuild": "^0.27.2", + "typescript": "^5.9.3" + } +} diff --git a/test-package/src/index.ts b/test-package/src/index.ts new file mode 100644 index 0000000..43e78c8 --- /dev/null +++ b/test-package/src/index.ts @@ -0,0 +1,139 @@ +import { Container } from '@novadi/core'; +import { + registerCoreServices, + CalendarApp, + IndexedDBContext, + SettingsService, + ViewConfigService, + EventService, + EventBus, + CalendarEvents, + EventPersistenceManager +} from 'calendar'; +import { registerSchedules } from 'calendar/schedules'; + +async function init() { + // Check if database already exists + const databases = await indexedDB.databases(); + const dbExists = databases.some(db => db.name === 'CalendarTestDB'); + + const container = new Container(); + const builder = container.builder(); + registerCoreServices(builder, { + dbConfig: { dbName: 'CalendarTestDB', dbVersion: 4 } + }); + registerSchedules(builder); + const app = builder.build(); + + console.log('Container created'); + + // Initialize IndexedDB + const dbContext = app.resolveType(); + await dbContext.initialize(); + console.log('IndexedDB initialized'); + + const settingsService = app.resolveType(); + const viewConfigService = app.resolveType(); + const eventService = app.resolveType(); + + if (dbExists) { + console.log('Database exists, skipping seed'); + } else { + console.log('Seeding data...'); + await seedData(settingsService, viewConfigService, eventService); + } + + // Initialize and render + const calendarApp = app.resolveType(); + const containerEl = document.querySelector('swp-calendar-container') as HTMLElement; + await calendarApp.init(containerEl); + + const eventBus = app.resolveType(); + eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: 'simple' }); + + console.log('Calendar rendered'); + + // Debug listeners + document.addEventListener('event:drag-end', (e) => { + console.log('event:drag-end:', (e as CustomEvent).detail); + }); + document.addEventListener('event:updated', (e) => { + console.log('event:updated:', (e as CustomEvent).detail); + }); + + const persistenceManager = app.resolveType(); + console.log('EventPersistenceManager resolved:', persistenceManager); +} + +async function seedData( + settingsService: SettingsService, + viewConfigService: ViewConfigService, + eventService: EventService +) { + // Grid settings + await settingsService.save({ + id: 'grid', + dayStartHour: 8, + dayEndHour: 17, + workStartHour: 9, + workEndHour: 16, + hourHeight: 64, + snapInterval: 15, + syncStatus: 'synced' + }); + + // Workweek settings + await settingsService.save({ + id: 'workweek', + presets: { + standard: { id: 'standard', label: 'Standard', workDays: [1, 2, 3, 4, 5], periodDays: 7 } + }, + defaultPreset: 'standard', + firstDayOfWeek: 1, + syncStatus: 'synced' + }); + + // Simple view config + await viewConfigService.save({ + id: 'simple', + groupings: [{ type: 'date', values: [], idProperty: 'date', derivedFrom: 'start' }], + syncStatus: 'synced' + }); + + // Add test events + const today = new Date(); + today.setHours(0, 0, 0, 0); + console.log('Event date:', today.toISOString()); + + const start1 = new Date(today); + start1.setHours(9, 0, 0, 0); + const end1 = new Date(today); + end1.setHours(10, 0, 0, 0); + + await eventService.save({ + id: '1', + title: 'Morgenmøde', + start: start1, + end: end1, + type: 'meeting', + allDay: false, + syncStatus: 'synced' + }); + + const start2 = new Date(today); + start2.setHours(12, 0, 0, 0); + const end2 = new Date(today); + end2.setHours(13, 0, 0, 0); + + await eventService.save({ + id: '2', + title: 'Frokost', + start: start2, + end: end2, + type: 'break', + allDay: false, + syncStatus: 'synced' + }); +} + +init().catch(console.error); diff --git a/test-package/tsconfig.json b/test-package/tsconfig.json new file mode 100644 index 0000000..ebbec2c --- /dev/null +++ b/test-package/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "./dist", + "rootDir": "./src", + "lib": ["ES2024", "DOM", "DOM.Iterable"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true + }, + "include": ["src/**/*"] +} From 7db22245e26e98aec2d6bbd8ba583d7b8162aa64 Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Mon, 2 Feb 2026 23:34:17 +0100 Subject: [PATCH 09/10] Adds comprehensive README for calendar package Introduces detailed documentation for calendar library, covering: - Core features and architecture - Installation and setup guide - Event system reference - Types and configuration options - Extensibility and utilities Prepares for initial library release with thorough documentation --- packages/calendar/README.md | 620 +++++++++++++++++++++++++++++++++ packages/calendar/package.json | 2 +- 2 files changed, 621 insertions(+), 1 deletion(-) create mode 100644 packages/calendar/README.md diff --git a/packages/calendar/README.md b/packages/calendar/README.md new file mode 100644 index 0000000..5fecd34 --- /dev/null +++ b/packages/calendar/README.md @@ -0,0 +1,620 @@ +# Calendar + +Professional TypeScript calendar component with offline-first architecture, drag-and-drop functionality, and real-time synchronization capabilities. + +## Features + +- **Multiple View Modes**: Date-based (day/week/month) and resource-based (people, rooms) views +- **Drag & Drop**: Smooth event dragging with snap-to-grid, cross-column movement, and timed/all-day conversion +- **Event Resizing**: Intuitive resize handles for adjusting event duration +- **Offline-First**: IndexedDB storage with automatic background sync +- **Event-Driven Architecture**: Decoupled components via centralized EventBus +- **Dependency Injection**: Built on NovaDI for clean, testable architecture +- **Extensions**: Modular extensions for teams, departments, bookings, customers, schedules, and audit logging + +## Installation + +```bash +npm install calendar +``` + +## Quick Start (AI-Friendly Setup Guide) + +### Step 1: Create HTML Structure + +```html + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +``` + +### Step 2: Initialize Calendar + +```typescript +import { Container } from '@novadi/core'; +import { + registerCoreServices, + CalendarApp, + IndexedDBContext, + SettingsService, + ViewConfigService, + EventService, + EventBus, + CalendarEvents +} from 'calendar'; + +async function init() { + // 1. Create DI container and register services + const container = new Container(); + const builder = container.builder(); + registerCoreServices(builder, { + dbConfig: { dbName: 'MyCalendarDB', dbVersion: 1 } + }); + const app = builder.build(); + + // 2. Initialize IndexedDB + const dbContext = app.resolveType(); + await dbContext.initialize(); + + // 3. Seed required settings (first time only) + const settingsService = app.resolveType(); + const viewConfigService = app.resolveType(); + + await settingsService.save({ + id: 'grid', + dayStartHour: 8, + dayEndHour: 17, + workStartHour: 9, + workEndHour: 16, + hourHeight: 64, + snapInterval: 15, + syncStatus: 'synced' + }); + + await settingsService.save({ + id: 'workweek', + presets: { + standard: { id: 'standard', label: 'Standard', workDays: [1, 2, 3, 4, 5], periodDays: 7 } + }, + defaultPreset: 'standard', + firstDayOfWeek: 1, + syncStatus: 'synced' + }); + + await viewConfigService.save({ + id: 'simple', + groupings: [{ type: 'date', values: [], idProperty: 'date', derivedFrom: 'start' }], + syncStatus: 'synced' + }); + + // 4. Initialize CalendarApp + const calendarApp = app.resolveType(); + const containerEl = document.querySelector('swp-calendar-container') as HTMLElement; + await calendarApp.init(containerEl); + + // 5. Render a view + const eventBus = app.resolveType(); + eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: 'simple' }); +} + +init().catch(console.error); +``` + +### Step 3: Add Events + +```typescript +const eventService = app.resolveType(); + +await eventService.save({ + id: crypto.randomUUID(), + title: 'Meeting', + start: new Date('2024-01-15T09:00:00'), + end: new Date('2024-01-15T10:00:00'), + type: 'meeting', + allDay: false, + syncStatus: 'synced' +}); +``` + +--- + +## Architecture + +### Core Components + +| Component | Description | +|-----------|-------------| +| `CalendarApp` | Main application entry point | +| `CalendarOrchestrator` | Coordinates rendering pipeline | +| `EventBus` | Central event dispatcher for all inter-component communication | +| `DateService` | Date calculations and formatting | +| `IndexedDBContext` | Offline storage infrastructure | + +### Managers + +| Manager | Description | +|---------|-------------| +| `DragDropManager` | Event drag-drop with smooth animations and snap-to-grid | +| `EdgeScrollManager` | Automatic scrolling at viewport edges during drag | +| `ResizeManager` | Event resizing with visual feedback | +| `ScrollManager` | Scroll behavior and position management | +| `HeaderDrawerManager` | All-day events drawer toggle | +| `EventPersistenceManager` | Saves drag/resize changes to storage | + +### Renderers + +| Renderer | Description | +|----------|-------------| +| `DateRenderer` | Renders date-based column groupings | +| `ResourceRenderer` | Renders resource-based column groupings | +| `EventRenderer` | Renders timed events in columns | +| `ScheduleRenderer` | Renders working hours backgrounds | +| `HeaderDrawerRenderer` | Renders all-day events in header | +| `TimeAxisRenderer` | Renders time labels on the left axis | + +### Storage + +| Service | Description | +|---------|-------------| +| `EventService` / `EventStore` | Calendar event CRUD | +| `ResourceService` / `ResourceStore` | Resource management | +| `SettingsService` / `SettingsStore` | Tenant settings | +| `ViewConfigService` / `ViewConfigStore` | View configurations | + +--- + +## Events Reference + +### Lifecycle Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `core:initialized` | `CoreEvents.INITIALIZED` | - | Calendar core initialized | +| `core:ready` | `CoreEvents.READY` | - | Calendar ready for interaction | +| `core:destroyed` | `CoreEvents.DESTROYED` | - | Calendar destroyed | + +### View Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `view:changed` | `CoreEvents.VIEW_CHANGED` | `{ viewId: string }` | View type changed | +| `view:rendered` | `CoreEvents.VIEW_RENDERED` | - | View finished rendering | + +### Navigation Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `nav:date-changed` | `CoreEvents.DATE_CHANGED` | `{ date: Date }` | Current date changed | +| `nav:navigation-completed` | `CoreEvents.NAVIGATION_COMPLETED` | - | Navigation animation completed | + +### Data Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `data:loading` | `CoreEvents.DATA_LOADING` | - | Data loading started | +| `data:loaded` | `CoreEvents.DATA_LOADED` | - | Data loading completed | +| `data:error` | `CoreEvents.DATA_ERROR` | `{ error: Error }` | Data loading error | + +### Grid Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `grid:rendered` | `CoreEvents.GRID_RENDERED` | - | Grid finished rendering | +| `grid:clicked` | `CoreEvents.GRID_CLICKED` | `{ time: Date, columnKey: string }` | Grid area clicked | + +### Event Management + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `event:created` | `CoreEvents.EVENT_CREATED` | `ICalendarEvent` | Event created | +| `event:updated` | `CoreEvents.EVENT_UPDATED` | `IEventUpdatedPayload` | Event updated | +| `event:deleted` | `CoreEvents.EVENT_DELETED` | `{ eventId: string }` | Event deleted | +| `event:selected` | `CoreEvents.EVENT_SELECTED` | `{ eventId: string }` | Event selected | + +### Drag-Drop Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `event:drag-start` | `CoreEvents.EVENT_DRAG_START` | `IDragStartPayload` | Drag started | +| `event:drag-move` | `CoreEvents.EVENT_DRAG_MOVE` | `IDragMovePayload` | Dragging (throttled) | +| `event:drag-end` | `CoreEvents.EVENT_DRAG_END` | `IDragEndPayload` | Drag completed | +| `event:drag-cancel` | `CoreEvents.EVENT_DRAG_CANCEL` | `IDragCancelPayload` | Drag cancelled | +| `event:drag-column-change` | `CoreEvents.EVENT_DRAG_COLUMN_CHANGE` | `IDragColumnChangePayload` | Moved to different column | + +### Header Drag Events (Timed to All-Day Conversion) + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `event:drag-enter-header` | `CoreEvents.EVENT_DRAG_ENTER_HEADER` | `IDragEnterHeaderPayload` | Entered header area | +| `event:drag-move-header` | `CoreEvents.EVENT_DRAG_MOVE_HEADER` | `IDragMoveHeaderPayload` | Moving in header area | +| `event:drag-leave-header` | `CoreEvents.EVENT_DRAG_LEAVE_HEADER` | `IDragLeaveHeaderPayload` | Left header area | + +### Resize Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `event:resize-start` | `CoreEvents.EVENT_RESIZE_START` | `IResizeStartPayload` | Resize started | +| `event:resize-end` | `CoreEvents.EVENT_RESIZE_END` | `IResizeEndPayload` | Resize completed | + +### Edge Scroll Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `edge-scroll:tick` | `CoreEvents.EDGE_SCROLL_TICK` | `{ deltaY: number }` | Scroll tick during edge scroll | +| `edge-scroll:started` | `CoreEvents.EDGE_SCROLL_STARTED` | - | Edge scrolling started | +| `edge-scroll:stopped` | `CoreEvents.EDGE_SCROLL_STOPPED` | - | Edge scrolling stopped | + +### Sync Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `sync:started` | `CoreEvents.SYNC_STARTED` | - | Background sync started | +| `sync:completed` | `CoreEvents.SYNC_COMPLETED` | - | Background sync completed | +| `sync:failed` | `CoreEvents.SYNC_FAILED` | `{ error: Error }` | Background sync failed | + +### Entity Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `entity:saved` | `CoreEvents.ENTITY_SAVED` | `IEntitySavedPayload` | Entity saved to storage | +| `entity:deleted` | `CoreEvents.ENTITY_DELETED` | `IEntityDeletedPayload` | Entity deleted from storage | + +### Audit Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `audit:logged` | `CoreEvents.AUDIT_LOGGED` | `IAuditLoggedPayload` | Audit entry logged | + +### Rendering Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `events:rendered` | `CoreEvents.EVENTS_RENDERED` | - | Events finished rendering | + +### System Events + +| Event | Constant | Payload | Description | +|-------|----------|---------|-------------| +| `system:error` | `CoreEvents.ERROR` | `{ error: Error, context?: string }` | System error occurred | + +--- + +## Command Events (Host to Calendar) + +Use these to control the calendar from your application: + +```typescript +import { EventBus, CalendarEvents } from 'calendar'; + +const eventBus = app.resolveType(); + +// Navigate +eventBus.emit(CalendarEvents.CMD_NAVIGATE_PREV); +eventBus.emit(CalendarEvents.CMD_NAVIGATE_NEXT); + +// Render a view +eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: 'simple' }); + +// Toggle header drawer +eventBus.emit(CalendarEvents.CMD_DRAWER_TOGGLE); + +// Change workweek preset +eventBus.emit(CalendarEvents.CMD_WORKWEEK_CHANGE, { presetId: 'standard' }); + +// Update view grouping +eventBus.emit(CalendarEvents.CMD_VIEW_UPDATE, { type: 'resource', values: ['r1', 'r2'] }); +``` + +| Command | Constant | Payload | Description | +|---------|----------|---------|-------------| +| Navigate Previous | `CalendarEvents.CMD_NAVIGATE_PREV` | - | Go to previous period | +| Navigate Next | `CalendarEvents.CMD_NAVIGATE_NEXT` | - | Go to next period | +| Render View | `CalendarEvents.CMD_RENDER` | `{ viewId: string }` | Render specified view | +| Toggle Drawer | `CalendarEvents.CMD_DRAWER_TOGGLE` | - | Toggle all-day drawer | +| Change Workweek | `CalendarEvents.CMD_WORKWEEK_CHANGE` | `{ presetId: string }` | Change workweek preset | +| Update View | `CalendarEvents.CMD_VIEW_UPDATE` | `{ type: string, values: string[] }` | Update grouping values | + +--- + +## Types + +### Core Types + +```typescript +// Event types +type CalendarEventType = 'customer' | 'vacation' | 'break' | 'meeting' | 'blocked'; + +interface ICalendarEvent { + id: string; + title: string; + description?: string; + start: Date; + end: Date; + type: CalendarEventType; + allDay: boolean; + bookingId?: string; + resourceId?: string; + customerId?: string; + recurringId?: string; + syncStatus: SyncStatus; + metadata?: Record; +} + +// Resource types +type ResourceType = 'person' | 'room' | 'equipment' | 'vehicle' | 'custom'; + +interface IResource { + id: string; + name: string; + displayName: string; + type: ResourceType; + avatarUrl?: string; + color?: string; + isActive?: boolean; + defaultSchedule?: IWeekSchedule; + syncStatus: SyncStatus; +} + +// Sync status +type SyncStatus = 'synced' | 'pending' | 'error'; +``` + +### Settings Types + +```typescript +interface IGridSettings { + id: 'grid'; + dayStartHour: number; + dayEndHour: number; + workStartHour: number; + workEndHour: number; + hourHeight: number; + snapInterval: number; +} + +interface IWorkweekPreset { + id: string; + workDays: number[]; // ISO weekdays: 1=Monday, 7=Sunday + label: string; + periodDays: number; // Navigation step (1=day, 7=week) +} + +interface IWeekSchedule { + [day: number]: ITimeSlot | null; // null = off that day +} + +interface ITimeSlot { + start: string; // "HH:mm" + end: string; // "HH:mm" +} +``` + +### Drag-Drop Payloads + +```typescript +interface IDragStartPayload { + eventId: string; + element: HTMLElement; + ghostElement: HTMLElement; + startY: number; + mouseOffset: { x: number; y: number }; + columnElement: HTMLElement; +} + +interface IDragEndPayload { + swpEvent: SwpEvent; + sourceColumnKey: string; + target: 'grid' | 'header'; +} +``` + +--- + +## Extensions + +Import extensions separately to keep bundle size minimal: + +```typescript +// Teams extension +import { registerTeams, TeamService, TeamStore, TeamRenderer } from 'calendar/teams'; + +// Departments extension +import { registerDepartments, DepartmentService, DepartmentStore } from 'calendar/departments'; + +// Bookings extension +import { registerBookings, BookingService, BookingStore } from 'calendar/bookings'; + +// Customers extension +import { registerCustomers, CustomerService, CustomerStore } from 'calendar/customers'; + +// Schedules extension (working hours) +import { registerSchedules, ResourceScheduleService, ScheduleOverrideService } from 'calendar/schedules'; + +// Audit extension +import { registerAudit, AuditService, AuditStore } from 'calendar/audit'; + +// Register with container builder +const builder = container.builder(); +registerCoreServices(builder); +registerTeams(builder); +registerSchedules(builder); +// ... etc +``` + +--- + +## Configuration + +### Calendar Options + +```typescript +interface ICalendarOptions { + timeConfig?: ITimeFormatConfig; + gridConfig?: IGridConfig; + dbConfig?: IDBConfig; +} + +// Time format configuration +interface ITimeFormatConfig { + timezone: string; // e.g., 'Europe/Copenhagen' + use24HourFormat: boolean; + locale: string; // e.g., 'da-DK' + dateFormat: string; + showSeconds: boolean; +} + +// Grid configuration +interface IGridConfig { + hourHeight: number; // Pixels per hour (default: 64) + dayStartHour: number; // Grid start hour (default: 6) + dayEndHour: number; // Grid end hour (default: 18) + snapInterval: number; // Minutes to snap to (default: 15) + gridStartThresholdMinutes: number; +} + +// Database configuration +interface IDBConfig { + dbName: string; // IndexedDB database name + dbVersion: number; // Schema version +} +``` + +### Default Configuration + +```typescript +import { + defaultTimeFormatConfig, + defaultGridConfig, + defaultDBConfig +} from 'calendar'; + +// Defaults: +// timezone: Intl.DateTimeFormat().resolvedOptions().timeZone +// use24HourFormat: true +// locale: 'da-DK' +// hourHeight: 64 +// dayStartHour: 6 +// dayEndHour: 18 +// snapInterval: 15 +``` + +--- + +## Utilities + +### Position Utilities + +```typescript +import { + calculateEventPosition, + minutesToPixels, + pixelsToMinutes, + snapToGrid +} from 'calendar'; + +// Convert time to pixels +const pixels = minutesToPixels(120, 64); // 120 mins at 64px/hour = 128px + +// Snap to 15-minute grid +const snapped = snapToGrid(new Date(), 15); +``` + +### Event Layout Engine + +```typescript +import { eventsOverlap, calculateColumnLayout } from 'calendar'; + +// Check if two events overlap +const overlap = eventsOverlap(event1, event2); + +// Calculate layout for overlapping events +const layout = calculateColumnLayout(events); +``` + +--- + +## Listening to Events + +```typescript +import { EventBus, CoreEvents } from 'calendar'; + +const eventBus = app.resolveType(); + +// Subscribe to event updates +eventBus.on(CoreEvents.EVENT_UPDATED, (e: Event) => { + const { eventId, sourceColumnKey, targetColumnKey } = (e as CustomEvent).detail; + console.log(`Event ${eventId} moved from ${sourceColumnKey} to ${targetColumnKey}`); +}); + +// Subscribe to drag events +eventBus.on(CoreEvents.EVENT_DRAG_END, (e: Event) => { + const { swpEvent, target } = (e as CustomEvent).detail; + console.log(`Dropped on ${target}:`, swpEvent); +}); + +// One-time listener +eventBus.once(CoreEvents.READY, () => { + console.log('Calendar is ready!'); +}); +``` + +--- + +## CSS Customization + +The calendar uses CSS custom properties for theming. Override these in your CSS: + +```css +:root { + --calendar-hour-height: 64px; + --calendar-header-height: 48px; + --calendar-column-min-width: 120px; + --calendar-event-border-radius: 4px; +} +``` + +--- + +## Dependencies + +- `@novadi/core` - Dependency injection framework (peer dependency) +- `dayjs` - Date manipulation and formatting + +--- + +## License + +Proprietary - SWP diff --git a/packages/calendar/package.json b/packages/calendar/package.json index 8c83e0f..9a7374b 100644 --- a/packages/calendar/package.json +++ b/packages/calendar/package.json @@ -1,6 +1,6 @@ { "name": "calendar", - "version": "0.1.6", + "version": "0.1.7", "description": "Calendar library", "author": "SWP", "type": "module", From fd5ab6bc0d4d0da84b3aa4bfacf93e14612138cf Mon Sep 17 00:00:00 2001 From: "Janus C. H. Knudsen" Date: Tue, 3 Feb 2026 00:02:25 +0100 Subject: [PATCH 10/10] Some ignored filles was missing --- .gitignore | 6 +- wwwroot/js/calendar-min.js | 26 + wwwroot/js/calendar-v2.js | 1631 +++++ wwwroot/js/calendar.js | 1664 +++++ wwwroot/js/components/NavigationButtons.d.ts | 63 + wwwroot/js/components/NavigationButtons.js | 131 + .../js/components/NavigationButtons.js.map | 1 + wwwroot/js/components/ViewSelector.d.ts | 70 + wwwroot/js/components/ViewSelector.js | 130 + wwwroot/js/components/ViewSelector.js.map | 1 + wwwroot/js/components/WorkweekPresets.d.ts | 47 + wwwroot/js/components/WorkweekPresets.js | 95 + wwwroot/js/components/WorkweekPresets.js.map | 1 + wwwroot/js/configuration/CalendarConfig.d.ts | 44 + wwwroot/js/configuration/CalendarConfig.js | 90 + .../js/configuration/CalendarConfig.js.map | 1 + wwwroot/js/configuration/ConfigManager.d.ts | 11 + wwwroot/js/configuration/ConfigManager.js | 43 + wwwroot/js/configuration/ConfigManager.js.map | 1 + .../js/configuration/DateViewSettings.d.ts | 10 + wwwroot/js/configuration/DateViewSettings.js | 2 + .../js/configuration/DateViewSettings.js.map | 1 + wwwroot/js/configuration/GridSettings.d.ts | 22 + wwwroot/js/configuration/GridSettings.js | 11 + wwwroot/js/configuration/GridSettings.js.map | 1 + wwwroot/js/configuration/ICalendarConfig.d.ts | 21 + wwwroot/js/configuration/ICalendarConfig.js | 2 + .../js/configuration/ICalendarConfig.js.map | 1 + .../js/configuration/TimeFormatConfig.d.ts | 10 + wwwroot/js/configuration/TimeFormatConfig.js | 2 + .../js/configuration/TimeFormatConfig.js.map | 1 + .../js/configuration/WorkWeekSettings.d.ts | 9 + wwwroot/js/configuration/WorkWeekSettings.js | 2 + .../js/configuration/WorkWeekSettings.js.map | 1 + wwwroot/js/configurations/CalendarConfig.d.ts | 46 + wwwroot/js/configurations/CalendarConfig.js | 85 + .../js/configurations/CalendarConfig.js.map | 1 + wwwroot/js/configurations/ConfigManager.d.ts | 28 + wwwroot/js/configurations/ConfigManager.js | 80 + .../js/configurations/ConfigManager.js.map | 1 + .../js/configurations/DateViewSettings.d.ts | 10 + wwwroot/js/configurations/DateViewSettings.js | 2 + .../js/configurations/DateViewSettings.js.map | 1 + wwwroot/js/configurations/GridSettings.d.ts | 22 + wwwroot/js/configurations/GridSettings.js | 11 + wwwroot/js/configurations/GridSettings.js.map | 1 + .../js/configurations/ICalendarConfig.d.ts | 21 + wwwroot/js/configurations/ICalendarConfig.js | 2 + .../js/configurations/ICalendarConfig.js.map | 1 + .../js/configurations/TimeFormatConfig.d.ts | 10 + wwwroot/js/configurations/TimeFormatConfig.js | 2 + .../js/configurations/TimeFormatConfig.js.map | 1 + .../js/configurations/WorkWeekSettings.d.ts | 9 + wwwroot/js/configurations/WorkWeekSettings.js | 2 + .../js/configurations/WorkWeekSettings.js.map | 1 + wwwroot/js/constants/CoreEvents.d.ts | 37 + wwwroot/js/constants/CoreEvents.js | 48 + wwwroot/js/constants/CoreEvents.js.map | 1 + wwwroot/js/core/CalendarConfig.d.ts | 225 + wwwroot/js/core/CalendarConfig.js | 421 ++ wwwroot/js/core/CalendarConfig.js.map | 1 + wwwroot/js/core/EventBus.d.ts | 60 + wwwroot/js/core/EventBus.js | 158 + wwwroot/js/core/EventBus.js.map | 1 + .../js/datasources/DateColumnDataSource.d.ts | 55 + .../js/datasources/DateColumnDataSource.js | 94 + .../datasources/DateColumnDataSource.js.map | 1 + wwwroot/js/demo.js | 6489 +++++++++++++++++ wwwroot/js/edge-scroll.js | 104 + wwwroot/js/elements/SwpEventElement.d.ts | 98 + wwwroot/js/elements/SwpEventElement.js | 303 + wwwroot/js/elements/SwpEventElement.js.map | 1 + wwwroot/js/factories/CalendarTypeFactory.d.ts | 55 + wwwroot/js/factories/CalendarTypeFactory.js | 84 + .../js/factories/CalendarTypeFactory.js.map | 1 + wwwroot/js/factories/ManagerFactory.d.ts | 18 + wwwroot/js/factories/ManagerFactory.js | 60 + wwwroot/js/factories/ManagerFactory.js.map | 1 + .../all-day/AllDayCollapseService.d.ts | 45 + .../features/all-day/AllDayCollapseService.js | 168 + .../all-day/AllDayCollapseService.js.map | 1 + .../features/all-day/AllDayCoordinator.d.ts | 45 + .../js/features/all-day/AllDayCoordinator.js | 168 + .../features/all-day/AllDayCoordinator.js.map | 1 + .../js/features/all-day/AllDayDomReader.d.ts | 74 + .../js/features/all-day/AllDayDomReader.js | 175 + .../features/all-day/AllDayDomReader.js.map | 1 + .../features/all-day/AllDayDragService.d.ts | 50 + .../js/features/all-day/AllDayDragService.js | 183 + .../features/all-day/AllDayDragService.js.map | 1 + .../features/all-day/AllDayHeightService.d.ts | 26 + .../features/all-day/AllDayHeightService.js | 85 + .../all-day/AllDayHeightService.js.map | 1 + wwwroot/js/features/all-day/index.d.ts | 9 + wwwroot/js/features/all-day/index.js | 10 + wwwroot/js/features/all-day/index.js.map | 1 + .../all-day/utils/AllDayDomReader.d.ts | 74 + .../features/all-day/utils/AllDayDomReader.js | 175 + .../all-day/utils/AllDayDomReader.js.map | 1 + wwwroot/js/index.d.ts | 1 + wwwroot/js/index.js | 171 + wwwroot/js/index.js.map | 1 + wwwroot/js/interfaces/IManager.d.ts | 48 + wwwroot/js/interfaces/IManager.js | 2 + wwwroot/js/interfaces/IManager.js.map | 1 + wwwroot/js/managers/AllDayManager.d.ts | 91 + wwwroot/js/managers/AllDayManager.js | 528 ++ wwwroot/js/managers/AllDayManager.js.map | 1 + wwwroot/js/managers/CalendarManager.d.ts | 45 + wwwroot/js/managers/CalendarManager.js | 145 + wwwroot/js/managers/CalendarManager.js.map | 1 + wwwroot/js/managers/DragDropManager.d.ts | 222 + wwwroot/js/managers/DragDropManager.js | 626 ++ wwwroot/js/managers/DragDropManager.js.map | 1 + wwwroot/js/managers/DragHoverManager.d.ts | 31 + wwwroot/js/managers/DragHoverManager.js | 101 + wwwroot/js/managers/DragHoverManager.js.map | 1 + wwwroot/js/managers/EdgeScrollManager.d.ts | 30 + wwwroot/js/managers/EdgeScrollManager.js | 191 + wwwroot/js/managers/EdgeScrollManager.js.map | 1 + wwwroot/js/managers/EventFilterManager.d.ts | 32 + wwwroot/js/managers/EventFilterManager.js | 192 + wwwroot/js/managers/EventFilterManager.js.map | 1 + .../js/managers/EventLayoutCoordinator.d.ts | 78 + wwwroot/js/managers/EventLayoutCoordinator.js | 201 + .../js/managers/EventLayoutCoordinator.js.map | 1 + wwwroot/js/managers/EventManager.d.ts | 69 + wwwroot/js/managers/EventManager.js | 164 + wwwroot/js/managers/EventManager.js.map | 1 + wwwroot/js/managers/EventStackManager.d.ts | 91 + wwwroot/js/managers/EventStackManager.js | 217 + wwwroot/js/managers/EventStackManager.js.map | 1 + wwwroot/js/managers/GridManager.d.ts | 30 + wwwroot/js/managers/GridManager.js | 77 + wwwroot/js/managers/GridManager.js.map | 1 + wwwroot/js/managers/HeaderManager.d.ts | 32 + wwwroot/js/managers/HeaderManager.js | 103 + wwwroot/js/managers/HeaderManager.js.map | 1 + .../js/managers/NavigationButtonsManager.d.ts | 40 + .../js/managers/NavigationButtonsManager.js | 63 + .../managers/NavigationButtonsManager.js.map | 1 + wwwroot/js/managers/NavigationManager.d.ts | 32 + wwwroot/js/managers/NavigationManager.js | 188 + wwwroot/js/managers/NavigationManager.js.map | 1 + wwwroot/js/managers/ResizeHandleManager.d.ts | 42 + wwwroot/js/managers/ResizeHandleManager.js | 194 + .../js/managers/ResizeHandleManager.js.map | 1 + wwwroot/js/managers/ScrollManager.d.ts | 64 + wwwroot/js/managers/ScrollManager.js | 217 + wwwroot/js/managers/ScrollManager.js.map | 1 + .../managers/SimpleEventOverlapManager.d.ts | 80 + .../js/managers/SimpleEventOverlapManager.js | 399 + .../managers/SimpleEventOverlapManager.js.map | 1 + wwwroot/js/managers/ViewManager.d.ts | 23 + wwwroot/js/managers/ViewManager.js | 106 + wwwroot/js/managers/ViewManager.js.map | 1 + wwwroot/js/managers/ViewSelectorManager.d.ts | 70 + wwwroot/js/managers/ViewSelectorManager.js | 130 + .../js/managers/ViewSelectorManager.js.map | 1 + wwwroot/js/managers/WorkHoursManager.d.ts | 71 + wwwroot/js/managers/WorkHoursManager.js | 108 + wwwroot/js/managers/WorkHoursManager.js.map | 1 + .../js/managers/WorkweekPresetsManager.d.ts | 47 + wwwroot/js/managers/WorkweekPresetsManager.js | 95 + .../js/managers/WorkweekPresetsManager.js.map | 1 + wwwroot/js/renderers/AllDayEventRenderer.d.ts | 32 + wwwroot/js/renderers/AllDayEventRenderer.js | 97 + .../js/renderers/AllDayEventRenderer.js.map | 1 + wwwroot/js/renderers/ColumnRenderer.d.ts | 26 + wwwroot/js/renderers/ColumnRenderer.js | 44 + wwwroot/js/renderers/ColumnRenderer.js.map | 1 + wwwroot/js/renderers/DateHeaderRenderer.d.ts | 21 + wwwroot/js/renderers/DateHeaderRenderer.js | 35 + .../js/renderers/DateHeaderRenderer.js.map | 1 + wwwroot/js/renderers/EventRenderer.d.ts | 96 + wwwroot/js/renderers/EventRenderer.js | 296 + wwwroot/js/renderers/EventRenderer.js.map | 1 + .../js/renderers/EventRendererManager.d.ts | 55 + wwwroot/js/renderers/EventRendererManager.js | 264 + .../js/renderers/EventRendererManager.js.map | 1 + wwwroot/js/renderers/GridRenderer.d.ts | 180 + wwwroot/js/renderers/GridRenderer.js | 289 + wwwroot/js/renderers/GridRenderer.js.map | 1 + wwwroot/js/renderers/GridStyleManager.d.ts | 24 + wwwroot/js/renderers/GridStyleManager.js | 76 + wwwroot/js/renderers/GridStyleManager.js.map | 1 + wwwroot/js/renderers/HeaderRenderer.d.ts | 29 + wwwroot/js/renderers/HeaderRenderer.js | 56 + wwwroot/js/renderers/HeaderRenderer.js.map | 1 + wwwroot/js/renderers/NavigationRenderer.d.ts | 22 + wwwroot/js/renderers/NavigationRenderer.js | 68 + .../js/renderers/NavigationRenderer.js.map | 1 + wwwroot/js/renderers/WeekInfoRenderer.d.ts | 26 + wwwroot/js/renderers/WeekInfoRenderer.js | 75 + wwwroot/js/renderers/WeekInfoRenderer.js.map | 1 + .../js/repositories/ApiEventRepository.d.ts | 39 + wwwroot/js/repositories/ApiEventRepository.js | 115 + .../js/repositories/ApiEventRepository.js.map | 1 + wwwroot/js/repositories/IEventRepository.d.ts | 51 + wwwroot/js/repositories/IEventRepository.js | 2 + .../js/repositories/IEventRepository.js.map | 1 + .../IndexedDBEventRepository.d.ts | 47 + .../repositories/IndexedDBEventRepository.js | 127 + .../IndexedDBEventRepository.js.map | 1 + .../js/repositories/MockEventRepository.d.ts | 33 + .../js/repositories/MockEventRepository.js | 62 + .../repositories/MockEventRepository.js.map | 1 + wwwroot/js/storage/IndexedDBService.d.ts | 97 + wwwroot/js/storage/IndexedDBService.js | 340 + wwwroot/js/storage/IndexedDBService.js.map | 1 + wwwroot/js/storage/OperationQueue.d.ts | 55 + wwwroot/js/storage/OperationQueue.js | 96 + wwwroot/js/storage/OperationQueue.js.map | 1 + wwwroot/js/strategies/MonthViewStrategy.d.ts | 25 + wwwroot/js/strategies/MonthViewStrategy.js | 124 + .../js/strategies/MonthViewStrategy.js.map | 1 + wwwroot/js/strategies/ViewStrategy.d.ts | 58 + wwwroot/js/strategies/ViewStrategy.js | 6 + wwwroot/js/strategies/ViewStrategy.js.map | 1 + wwwroot/js/strategies/WeekViewStrategy.d.ts | 22 + wwwroot/js/strategies/WeekViewStrategy.js | 57 + wwwroot/js/strategies/WeekViewStrategy.js.map | 1 + wwwroot/js/types/CalendarTypes.d.ts | 56 + wwwroot/js/types/CalendarTypes.js | 3 + wwwroot/js/types/CalendarTypes.js.map | 1 + wwwroot/js/types/ColumnDataSource.d.ts | 17 + wwwroot/js/types/ColumnDataSource.js | 2 + wwwroot/js/types/ColumnDataSource.js.map | 1 + wwwroot/js/types/DragDropTypes.d.ts | 41 + wwwroot/js/types/DragDropTypes.js | 5 + wwwroot/js/types/DragDropTypes.js.map | 1 + wwwroot/js/types/EventPayloadMap.d.ts | 133 + wwwroot/js/types/EventPayloadMap.js | 6 + wwwroot/js/types/EventPayloadMap.js.map | 1 + wwwroot/js/types/EventTypes.d.ts | 81 + wwwroot/js/types/EventTypes.js | 5 + wwwroot/js/types/EventTypes.js.map | 1 + wwwroot/js/types/ManagerTypes.d.ts | 59 + wwwroot/js/types/ManagerTypes.js | 2 + wwwroot/js/types/ManagerTypes.js.map | 1 + wwwroot/js/utils/AllDayLayoutEngine.d.ts | 42 + wwwroot/js/utils/AllDayLayoutEngine.js | 108 + wwwroot/js/utils/AllDayLayoutEngine.js.map | 1 + wwwroot/js/utils/ColumnDetectionUtils.d.ts | 30 + wwwroot/js/utils/ColumnDetectionUtils.js | 87 + wwwroot/js/utils/ColumnDetectionUtils.js.map | 1 + wwwroot/js/utils/DateCalculator.d.ts | 149 + wwwroot/js/utils/DateCalculator.js | 260 + wwwroot/js/utils/DateCalculator.js.map | 1 + wwwroot/js/utils/DateService.d.ts | 254 + wwwroot/js/utils/DateService.js | 418 ++ wwwroot/js/utils/DateService.js.map | 1 + wwwroot/js/utils/OverlapDetector.d.ts | 33 + wwwroot/js/utils/OverlapDetector.js | 52 + wwwroot/js/utils/OverlapDetector.js.map | 1 + wwwroot/js/utils/PositionUtils.d.ts | 101 + wwwroot/js/utils/PositionUtils.js | 209 + wwwroot/js/utils/PositionUtils.js.map | 1 + wwwroot/js/utils/TimeFormatter.d.ts | 45 + wwwroot/js/utils/TimeFormatter.js | 92 + wwwroot/js/utils/TimeFormatter.js.map | 1 + wwwroot/js/utils/URLManager.d.ts | 29 + wwwroot/js/utils/URLManager.js | 76 + wwwroot/js/utils/URLManager.js.map | 1 + wwwroot/js/v2-demo.js | 6463 ++++++++++++++++ wwwroot/js/workers/SyncManager.d.ts | 78 + wwwroot/js/workers/SyncManager.js | 229 + wwwroot/js/workers/SyncManager.js.map | 1 + 268 files changed, 31970 insertions(+), 4 deletions(-) create mode 100644 wwwroot/js/calendar-min.js create mode 100644 wwwroot/js/calendar-v2.js create mode 100644 wwwroot/js/calendar.js create mode 100644 wwwroot/js/components/NavigationButtons.d.ts create mode 100644 wwwroot/js/components/NavigationButtons.js create mode 100644 wwwroot/js/components/NavigationButtons.js.map create mode 100644 wwwroot/js/components/ViewSelector.d.ts create mode 100644 wwwroot/js/components/ViewSelector.js create mode 100644 wwwroot/js/components/ViewSelector.js.map create mode 100644 wwwroot/js/components/WorkweekPresets.d.ts create mode 100644 wwwroot/js/components/WorkweekPresets.js create mode 100644 wwwroot/js/components/WorkweekPresets.js.map create mode 100644 wwwroot/js/configuration/CalendarConfig.d.ts create mode 100644 wwwroot/js/configuration/CalendarConfig.js create mode 100644 wwwroot/js/configuration/CalendarConfig.js.map create mode 100644 wwwroot/js/configuration/ConfigManager.d.ts create mode 100644 wwwroot/js/configuration/ConfigManager.js create mode 100644 wwwroot/js/configuration/ConfigManager.js.map create mode 100644 wwwroot/js/configuration/DateViewSettings.d.ts create mode 100644 wwwroot/js/configuration/DateViewSettings.js create mode 100644 wwwroot/js/configuration/DateViewSettings.js.map create mode 100644 wwwroot/js/configuration/GridSettings.d.ts create mode 100644 wwwroot/js/configuration/GridSettings.js create mode 100644 wwwroot/js/configuration/GridSettings.js.map create mode 100644 wwwroot/js/configuration/ICalendarConfig.d.ts create mode 100644 wwwroot/js/configuration/ICalendarConfig.js create mode 100644 wwwroot/js/configuration/ICalendarConfig.js.map create mode 100644 wwwroot/js/configuration/TimeFormatConfig.d.ts create mode 100644 wwwroot/js/configuration/TimeFormatConfig.js create mode 100644 wwwroot/js/configuration/TimeFormatConfig.js.map create mode 100644 wwwroot/js/configuration/WorkWeekSettings.d.ts create mode 100644 wwwroot/js/configuration/WorkWeekSettings.js create mode 100644 wwwroot/js/configuration/WorkWeekSettings.js.map create mode 100644 wwwroot/js/configurations/CalendarConfig.d.ts create mode 100644 wwwroot/js/configurations/CalendarConfig.js create mode 100644 wwwroot/js/configurations/CalendarConfig.js.map create mode 100644 wwwroot/js/configurations/ConfigManager.d.ts create mode 100644 wwwroot/js/configurations/ConfigManager.js create mode 100644 wwwroot/js/configurations/ConfigManager.js.map create mode 100644 wwwroot/js/configurations/DateViewSettings.d.ts create mode 100644 wwwroot/js/configurations/DateViewSettings.js create mode 100644 wwwroot/js/configurations/DateViewSettings.js.map create mode 100644 wwwroot/js/configurations/GridSettings.d.ts create mode 100644 wwwroot/js/configurations/GridSettings.js create mode 100644 wwwroot/js/configurations/GridSettings.js.map create mode 100644 wwwroot/js/configurations/ICalendarConfig.d.ts create mode 100644 wwwroot/js/configurations/ICalendarConfig.js create mode 100644 wwwroot/js/configurations/ICalendarConfig.js.map create mode 100644 wwwroot/js/configurations/TimeFormatConfig.d.ts create mode 100644 wwwroot/js/configurations/TimeFormatConfig.js create mode 100644 wwwroot/js/configurations/TimeFormatConfig.js.map create mode 100644 wwwroot/js/configurations/WorkWeekSettings.d.ts create mode 100644 wwwroot/js/configurations/WorkWeekSettings.js create mode 100644 wwwroot/js/configurations/WorkWeekSettings.js.map create mode 100644 wwwroot/js/constants/CoreEvents.d.ts create mode 100644 wwwroot/js/constants/CoreEvents.js create mode 100644 wwwroot/js/constants/CoreEvents.js.map create mode 100644 wwwroot/js/core/CalendarConfig.d.ts create mode 100644 wwwroot/js/core/CalendarConfig.js create mode 100644 wwwroot/js/core/CalendarConfig.js.map create mode 100644 wwwroot/js/core/EventBus.d.ts create mode 100644 wwwroot/js/core/EventBus.js create mode 100644 wwwroot/js/core/EventBus.js.map create mode 100644 wwwroot/js/datasources/DateColumnDataSource.d.ts create mode 100644 wwwroot/js/datasources/DateColumnDataSource.js create mode 100644 wwwroot/js/datasources/DateColumnDataSource.js.map create mode 100644 wwwroot/js/demo.js create mode 100644 wwwroot/js/edge-scroll.js create mode 100644 wwwroot/js/elements/SwpEventElement.d.ts create mode 100644 wwwroot/js/elements/SwpEventElement.js create mode 100644 wwwroot/js/elements/SwpEventElement.js.map create mode 100644 wwwroot/js/factories/CalendarTypeFactory.d.ts create mode 100644 wwwroot/js/factories/CalendarTypeFactory.js create mode 100644 wwwroot/js/factories/CalendarTypeFactory.js.map create mode 100644 wwwroot/js/factories/ManagerFactory.d.ts create mode 100644 wwwroot/js/factories/ManagerFactory.js create mode 100644 wwwroot/js/factories/ManagerFactory.js.map create mode 100644 wwwroot/js/features/all-day/AllDayCollapseService.d.ts create mode 100644 wwwroot/js/features/all-day/AllDayCollapseService.js create mode 100644 wwwroot/js/features/all-day/AllDayCollapseService.js.map create mode 100644 wwwroot/js/features/all-day/AllDayCoordinator.d.ts create mode 100644 wwwroot/js/features/all-day/AllDayCoordinator.js create mode 100644 wwwroot/js/features/all-day/AllDayCoordinator.js.map create mode 100644 wwwroot/js/features/all-day/AllDayDomReader.d.ts create mode 100644 wwwroot/js/features/all-day/AllDayDomReader.js create mode 100644 wwwroot/js/features/all-day/AllDayDomReader.js.map create mode 100644 wwwroot/js/features/all-day/AllDayDragService.d.ts create mode 100644 wwwroot/js/features/all-day/AllDayDragService.js create mode 100644 wwwroot/js/features/all-day/AllDayDragService.js.map create mode 100644 wwwroot/js/features/all-day/AllDayHeightService.d.ts create mode 100644 wwwroot/js/features/all-day/AllDayHeightService.js create mode 100644 wwwroot/js/features/all-day/AllDayHeightService.js.map create mode 100644 wwwroot/js/features/all-day/index.d.ts create mode 100644 wwwroot/js/features/all-day/index.js create mode 100644 wwwroot/js/features/all-day/index.js.map create mode 100644 wwwroot/js/features/all-day/utils/AllDayDomReader.d.ts create mode 100644 wwwroot/js/features/all-day/utils/AllDayDomReader.js create mode 100644 wwwroot/js/features/all-day/utils/AllDayDomReader.js.map create mode 100644 wwwroot/js/index.d.ts create mode 100644 wwwroot/js/index.js create mode 100644 wwwroot/js/index.js.map create mode 100644 wwwroot/js/interfaces/IManager.d.ts create mode 100644 wwwroot/js/interfaces/IManager.js create mode 100644 wwwroot/js/interfaces/IManager.js.map create mode 100644 wwwroot/js/managers/AllDayManager.d.ts create mode 100644 wwwroot/js/managers/AllDayManager.js create mode 100644 wwwroot/js/managers/AllDayManager.js.map create mode 100644 wwwroot/js/managers/CalendarManager.d.ts create mode 100644 wwwroot/js/managers/CalendarManager.js create mode 100644 wwwroot/js/managers/CalendarManager.js.map create mode 100644 wwwroot/js/managers/DragDropManager.d.ts create mode 100644 wwwroot/js/managers/DragDropManager.js create mode 100644 wwwroot/js/managers/DragDropManager.js.map create mode 100644 wwwroot/js/managers/DragHoverManager.d.ts create mode 100644 wwwroot/js/managers/DragHoverManager.js create mode 100644 wwwroot/js/managers/DragHoverManager.js.map create mode 100644 wwwroot/js/managers/EdgeScrollManager.d.ts create mode 100644 wwwroot/js/managers/EdgeScrollManager.js create mode 100644 wwwroot/js/managers/EdgeScrollManager.js.map create mode 100644 wwwroot/js/managers/EventFilterManager.d.ts create mode 100644 wwwroot/js/managers/EventFilterManager.js create mode 100644 wwwroot/js/managers/EventFilterManager.js.map create mode 100644 wwwroot/js/managers/EventLayoutCoordinator.d.ts create mode 100644 wwwroot/js/managers/EventLayoutCoordinator.js create mode 100644 wwwroot/js/managers/EventLayoutCoordinator.js.map create mode 100644 wwwroot/js/managers/EventManager.d.ts create mode 100644 wwwroot/js/managers/EventManager.js create mode 100644 wwwroot/js/managers/EventManager.js.map create mode 100644 wwwroot/js/managers/EventStackManager.d.ts create mode 100644 wwwroot/js/managers/EventStackManager.js create mode 100644 wwwroot/js/managers/EventStackManager.js.map create mode 100644 wwwroot/js/managers/GridManager.d.ts create mode 100644 wwwroot/js/managers/GridManager.js create mode 100644 wwwroot/js/managers/GridManager.js.map create mode 100644 wwwroot/js/managers/HeaderManager.d.ts create mode 100644 wwwroot/js/managers/HeaderManager.js create mode 100644 wwwroot/js/managers/HeaderManager.js.map create mode 100644 wwwroot/js/managers/NavigationButtonsManager.d.ts create mode 100644 wwwroot/js/managers/NavigationButtonsManager.js create mode 100644 wwwroot/js/managers/NavigationButtonsManager.js.map create mode 100644 wwwroot/js/managers/NavigationManager.d.ts create mode 100644 wwwroot/js/managers/NavigationManager.js create mode 100644 wwwroot/js/managers/NavigationManager.js.map create mode 100644 wwwroot/js/managers/ResizeHandleManager.d.ts create mode 100644 wwwroot/js/managers/ResizeHandleManager.js create mode 100644 wwwroot/js/managers/ResizeHandleManager.js.map create mode 100644 wwwroot/js/managers/ScrollManager.d.ts create mode 100644 wwwroot/js/managers/ScrollManager.js create mode 100644 wwwroot/js/managers/ScrollManager.js.map create mode 100644 wwwroot/js/managers/SimpleEventOverlapManager.d.ts create mode 100644 wwwroot/js/managers/SimpleEventOverlapManager.js create mode 100644 wwwroot/js/managers/SimpleEventOverlapManager.js.map create mode 100644 wwwroot/js/managers/ViewManager.d.ts create mode 100644 wwwroot/js/managers/ViewManager.js create mode 100644 wwwroot/js/managers/ViewManager.js.map create mode 100644 wwwroot/js/managers/ViewSelectorManager.d.ts create mode 100644 wwwroot/js/managers/ViewSelectorManager.js create mode 100644 wwwroot/js/managers/ViewSelectorManager.js.map create mode 100644 wwwroot/js/managers/WorkHoursManager.d.ts create mode 100644 wwwroot/js/managers/WorkHoursManager.js create mode 100644 wwwroot/js/managers/WorkHoursManager.js.map create mode 100644 wwwroot/js/managers/WorkweekPresetsManager.d.ts create mode 100644 wwwroot/js/managers/WorkweekPresetsManager.js create mode 100644 wwwroot/js/managers/WorkweekPresetsManager.js.map create mode 100644 wwwroot/js/renderers/AllDayEventRenderer.d.ts create mode 100644 wwwroot/js/renderers/AllDayEventRenderer.js create mode 100644 wwwroot/js/renderers/AllDayEventRenderer.js.map create mode 100644 wwwroot/js/renderers/ColumnRenderer.d.ts create mode 100644 wwwroot/js/renderers/ColumnRenderer.js create mode 100644 wwwroot/js/renderers/ColumnRenderer.js.map create mode 100644 wwwroot/js/renderers/DateHeaderRenderer.d.ts create mode 100644 wwwroot/js/renderers/DateHeaderRenderer.js create mode 100644 wwwroot/js/renderers/DateHeaderRenderer.js.map create mode 100644 wwwroot/js/renderers/EventRenderer.d.ts create mode 100644 wwwroot/js/renderers/EventRenderer.js create mode 100644 wwwroot/js/renderers/EventRenderer.js.map create mode 100644 wwwroot/js/renderers/EventRendererManager.d.ts create mode 100644 wwwroot/js/renderers/EventRendererManager.js create mode 100644 wwwroot/js/renderers/EventRendererManager.js.map create mode 100644 wwwroot/js/renderers/GridRenderer.d.ts create mode 100644 wwwroot/js/renderers/GridRenderer.js create mode 100644 wwwroot/js/renderers/GridRenderer.js.map create mode 100644 wwwroot/js/renderers/GridStyleManager.d.ts create mode 100644 wwwroot/js/renderers/GridStyleManager.js create mode 100644 wwwroot/js/renderers/GridStyleManager.js.map create mode 100644 wwwroot/js/renderers/HeaderRenderer.d.ts create mode 100644 wwwroot/js/renderers/HeaderRenderer.js create mode 100644 wwwroot/js/renderers/HeaderRenderer.js.map create mode 100644 wwwroot/js/renderers/NavigationRenderer.d.ts create mode 100644 wwwroot/js/renderers/NavigationRenderer.js create mode 100644 wwwroot/js/renderers/NavigationRenderer.js.map create mode 100644 wwwroot/js/renderers/WeekInfoRenderer.d.ts create mode 100644 wwwroot/js/renderers/WeekInfoRenderer.js create mode 100644 wwwroot/js/renderers/WeekInfoRenderer.js.map create mode 100644 wwwroot/js/repositories/ApiEventRepository.d.ts create mode 100644 wwwroot/js/repositories/ApiEventRepository.js create mode 100644 wwwroot/js/repositories/ApiEventRepository.js.map create mode 100644 wwwroot/js/repositories/IEventRepository.d.ts create mode 100644 wwwroot/js/repositories/IEventRepository.js create mode 100644 wwwroot/js/repositories/IEventRepository.js.map create mode 100644 wwwroot/js/repositories/IndexedDBEventRepository.d.ts create mode 100644 wwwroot/js/repositories/IndexedDBEventRepository.js create mode 100644 wwwroot/js/repositories/IndexedDBEventRepository.js.map create mode 100644 wwwroot/js/repositories/MockEventRepository.d.ts create mode 100644 wwwroot/js/repositories/MockEventRepository.js create mode 100644 wwwroot/js/repositories/MockEventRepository.js.map create mode 100644 wwwroot/js/storage/IndexedDBService.d.ts create mode 100644 wwwroot/js/storage/IndexedDBService.js create mode 100644 wwwroot/js/storage/IndexedDBService.js.map create mode 100644 wwwroot/js/storage/OperationQueue.d.ts create mode 100644 wwwroot/js/storage/OperationQueue.js create mode 100644 wwwroot/js/storage/OperationQueue.js.map create mode 100644 wwwroot/js/strategies/MonthViewStrategy.d.ts create mode 100644 wwwroot/js/strategies/MonthViewStrategy.js create mode 100644 wwwroot/js/strategies/MonthViewStrategy.js.map create mode 100644 wwwroot/js/strategies/ViewStrategy.d.ts create mode 100644 wwwroot/js/strategies/ViewStrategy.js create mode 100644 wwwroot/js/strategies/ViewStrategy.js.map create mode 100644 wwwroot/js/strategies/WeekViewStrategy.d.ts create mode 100644 wwwroot/js/strategies/WeekViewStrategy.js create mode 100644 wwwroot/js/strategies/WeekViewStrategy.js.map create mode 100644 wwwroot/js/types/CalendarTypes.d.ts create mode 100644 wwwroot/js/types/CalendarTypes.js create mode 100644 wwwroot/js/types/CalendarTypes.js.map create mode 100644 wwwroot/js/types/ColumnDataSource.d.ts create mode 100644 wwwroot/js/types/ColumnDataSource.js create mode 100644 wwwroot/js/types/ColumnDataSource.js.map create mode 100644 wwwroot/js/types/DragDropTypes.d.ts create mode 100644 wwwroot/js/types/DragDropTypes.js create mode 100644 wwwroot/js/types/DragDropTypes.js.map create mode 100644 wwwroot/js/types/EventPayloadMap.d.ts create mode 100644 wwwroot/js/types/EventPayloadMap.js create mode 100644 wwwroot/js/types/EventPayloadMap.js.map create mode 100644 wwwroot/js/types/EventTypes.d.ts create mode 100644 wwwroot/js/types/EventTypes.js create mode 100644 wwwroot/js/types/EventTypes.js.map create mode 100644 wwwroot/js/types/ManagerTypes.d.ts create mode 100644 wwwroot/js/types/ManagerTypes.js create mode 100644 wwwroot/js/types/ManagerTypes.js.map create mode 100644 wwwroot/js/utils/AllDayLayoutEngine.d.ts create mode 100644 wwwroot/js/utils/AllDayLayoutEngine.js create mode 100644 wwwroot/js/utils/AllDayLayoutEngine.js.map create mode 100644 wwwroot/js/utils/ColumnDetectionUtils.d.ts create mode 100644 wwwroot/js/utils/ColumnDetectionUtils.js create mode 100644 wwwroot/js/utils/ColumnDetectionUtils.js.map create mode 100644 wwwroot/js/utils/DateCalculator.d.ts create mode 100644 wwwroot/js/utils/DateCalculator.js create mode 100644 wwwroot/js/utils/DateCalculator.js.map create mode 100644 wwwroot/js/utils/DateService.d.ts create mode 100644 wwwroot/js/utils/DateService.js create mode 100644 wwwroot/js/utils/DateService.js.map create mode 100644 wwwroot/js/utils/OverlapDetector.d.ts create mode 100644 wwwroot/js/utils/OverlapDetector.js create mode 100644 wwwroot/js/utils/OverlapDetector.js.map create mode 100644 wwwroot/js/utils/PositionUtils.d.ts create mode 100644 wwwroot/js/utils/PositionUtils.js create mode 100644 wwwroot/js/utils/PositionUtils.js.map create mode 100644 wwwroot/js/utils/TimeFormatter.d.ts create mode 100644 wwwroot/js/utils/TimeFormatter.js create mode 100644 wwwroot/js/utils/TimeFormatter.js.map create mode 100644 wwwroot/js/utils/URLManager.d.ts create mode 100644 wwwroot/js/utils/URLManager.js create mode 100644 wwwroot/js/utils/URLManager.js.map create mode 100644 wwwroot/js/v2-demo.js create mode 100644 wwwroot/js/workers/SyncManager.d.ts create mode 100644 wwwroot/js/workers/SyncManager.js create mode 100644 wwwroot/js/workers/SyncManager.js.map diff --git a/.gitignore b/.gitignore index de20219..9bbe200 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Build outputs bin/ obj/ -wwwroot/js/ # Node modules node_modules/ @@ -30,6 +29,5 @@ Thumbs.db *.suo *.userosscache *.sln.docstates -js/ - -packages/calendar/dist/ + +packages/calendar/dist/ diff --git a/wwwroot/js/calendar-min.js b/wwwroot/js/calendar-min.js new file mode 100644 index 0000000..322988f --- /dev/null +++ b/wwwroot/js/calendar-min.js @@ -0,0 +1,26 @@ +var Lt=Object.create;var vt=Object.defineProperty;var $t=Object.getOwnPropertyDescriptor;var Ht=Object.getOwnPropertyNames;var Bt=Object.getPrototypeOf,Wt=Object.prototype.hasOwnProperty;var se=(o,e)=>()=>(e||o((e={exports:{}}).exports,e),e.exports);var Pt=(o,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ht(e))!Wt.call(o,r)&&r!==t&&vt(o,r,{get:()=>e[r],enumerable:!(n=$t(e,r))||n.enumerable});return o};var ie=(o,e,t)=>(t=o!=null?Lt(Bt(o)):{},Pt(e||!o||!o.__esModule?vt(t,"default",{value:o,enumerable:!0}):t,o));var Et=se((rt,st)=>{(function(o,e){typeof rt=="object"&&typeof st<"u"?st.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs=e()})(rt,function(){"use strict";var o=1e3,e=6e4,t=36e5,n="millisecond",r="second",s="minute",i="hour",a="day",c="week",d="month",g="quarter",w="year",E="date",m="Invalid Date",u=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,D=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,C={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(S){var f=["th","st","nd","rd"],h=S%100;return"["+S+(f[(h-20)%10]||f[h]||f[0])+"]"}},k=function(S,f,h){var y=String(S);return!y||y.length>=f?S:""+Array(f+1-y.length).join(h)+S},l={s:k,z:function(S){var f=-S.utcOffset(),h=Math.abs(f),y=Math.floor(h/60),p=h%60;return(f<=0?"+":"-")+k(y,2,"0")+":"+k(p,2,"0")},m:function S(f,h){if(f.date()1)return S(M[0])}else{var R=f.name;W[R]=f,p=R}return!y&&p&&(O=p),p||!y&&O},x=function(S,f){if(N(S))return S.clone();var h=typeof f=="object"?f:{};return h.date=S,h.args=arguments,new Y(h)},A=l;A.l=$,A.i=N,A.w=function(S,f){return x(S,{locale:f.$L,utc:f.$u,x:f.$x,$offset:f.$offset})};var Y=function(){function S(h){this.$L=$(h.locale,null,!0),this.parse(h),this.$x=this.$x||h.x||{},this[P]=!0}var f=S.prototype;return f.parse=function(h){this.$d=function(y){var p=y.date,T=y.utc;if(p===null)return new Date(NaN);if(A.u(p))return new Date;if(p instanceof Date)return new Date(p);if(typeof p=="string"&&!/Z$/i.test(p)){var M=p.match(u);if(M){var R=M[2]-1||0,L=(M[7]||"0").substring(0,3);return T?new Date(Date.UTC(M[1],R,M[3]||1,M[4]||0,M[5]||0,M[6]||0,L)):new Date(M[1],R,M[3]||1,M[4]||0,M[5]||0,M[6]||0,L)}}return new Date(p)}(h),this.init()},f.init=function(){var h=this.$d;this.$y=h.getFullYear(),this.$M=h.getMonth(),this.$D=h.getDate(),this.$W=h.getDay(),this.$H=h.getHours(),this.$m=h.getMinutes(),this.$s=h.getSeconds(),this.$ms=h.getMilliseconds()},f.$utils=function(){return A},f.isValid=function(){return this.$d.toString()!==m},f.isSame=function(h,y){var p=x(h);return this.startOf(y)<=p&&p<=this.endOf(y)},f.isAfter=function(h,y){return x(h){(function(o,e){typeof it=="object"&&typeof at<"u"?at.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_utc=e()})(it,function(){"use strict";var o="minute",e=/[+-]\d\d(?::?\d\d)?/g,t=/([+-]|\d\d)/g;return function(n,r,s){var i=r.prototype;s.utc=function(m){var u={date:m,utc:!0,args:arguments};return new r(u)},i.utc=function(m){var u=s(this.toDate(),{locale:this.$L,utc:!0});return m?u.add(this.utcOffset(),o):u},i.local=function(){return s(this.toDate(),{locale:this.$L,utc:!1})};var a=i.parse;i.parse=function(m){m.utc&&(this.$u=!0),this.$utils().u(m.$offset)||(this.$offset=m.$offset),a.call(this,m)};var c=i.init;i.init=function(){if(this.$u){var m=this.$d;this.$y=m.getUTCFullYear(),this.$M=m.getUTCMonth(),this.$D=m.getUTCDate(),this.$W=m.getUTCDay(),this.$H=m.getUTCHours(),this.$m=m.getUTCMinutes(),this.$s=m.getUTCSeconds(),this.$ms=m.getUTCMilliseconds()}else c.call(this)};var d=i.utcOffset;i.utcOffset=function(m,u){var D=this.$utils().u;if(D(m))return this.$u?0:D(this.$offset)?d.call(this):this.$offset;if(typeof m=="string"&&(m=function(O){O===void 0&&(O="");var W=O.match(e);if(!W)return null;var P=(""+W[0]).match(t)||["-",0,0],N=P[0],$=60*+P[1]+ +P[2];return $===0?0:N==="+"?$:-$}(m),m===null))return this;var C=Math.abs(m)<=16?60*m:m;if(C===0)return this.utc(u);var k=this.clone();if(u)return k.$offset=C,k.$u=!1,k;var l=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();return(k=this.local().add(C+l,o)).$offset=C,k.$x.$localOffset=l,k};var g=i.format;i.format=function(m){var u=m||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return g.call(this,u)},i.valueOf=function(){var m=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*m},i.isUTC=function(){return!!this.$u},i.toISOString=function(){return this.toDate().toISOString()},i.toString=function(){return this.toDate().toUTCString()};var w=i.toDate;i.toDate=function(m){return m==="s"&&this.$offset?s(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():w.call(this)};var E=i.diff;i.diff=function(m,u,D){if(m&&this.$u===m.$u)return E.call(this,m,u,D);var C=this.local(),k=s(m).local();return E.call(C,k,u,D)}}})});var St=se((ot,lt)=>{(function(o,e){typeof ot=="object"&&typeof lt<"u"?lt.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_timezone=e()})(ot,function(){"use strict";var o={year:0,month:1,day:2,hour:3,minute:4,second:5},e={};return function(t,n,r){var s,i=function(g,w,E){E===void 0&&(E={});var m=new Date(g),u=function(D,C){C===void 0&&(C={});var k=C.timeZoneName||"short",l=D+"|"+k,O=e[l];return O||(O=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:D,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:k}),e[l]=O),O}(w,E);return u.formatToParts(m)},a=function(g,w){for(var E=i(g,w),m=[],u=0;u=0&&(m[l]=parseInt(k,10))}var O=m[3],W=O===24?0:O,P=m[0]+"-"+m[1]+"-"+m[2]+" "+W+":"+m[4]+":"+m[5]+":000",N=+g;return(r.utc(P).valueOf()-(N-=N%1e3))/6e4},c=n.prototype;c.tz=function(g,w){g===void 0&&(g=s);var E,m=this.utcOffset(),u=this.toDate(),D=u.toLocaleString("en-US",{timeZone:g}),C=Math.round((u-new Date(D))/1e3/60),k=15*-Math.round(u.getTimezoneOffset()/15)-C;if(!Number(k))E=this.utcOffset(0,w);else if(E=r(D,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(k,!0),w){var l=E.utcOffset();E=E.add(m-l,"minute")}return E.$x.$timezone=g,E},c.offsetName=function(g){var w=this.$x.$timezone||r.tz.guess(),E=i(this.valueOf(),w,{timeZoneName:g}).find(function(m){return m.type.toLowerCase()==="timezonename"});return E&&E.value};var d=c.startOf;c.startOf=function(g,w){if(!this.$x||!this.$x.$timezone)return d.call(this,g,w);var E=r(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return d.call(E,g,w).tz(this.$x.$timezone,!0)},r.tz=function(g,w,E){var m=E&&w,u=E||w||s,D=a(+r(),u);if(typeof g!="string")return r(g).tz(u);var C=function(W,P,N){var $=W-60*P*1e3,x=a($,N);if(P===x)return[$,P];var A=a($-=60*(x-P)*1e3,N);return x===A?[$,x]:[W-60*Math.min(x,A)*1e3,Math.max(x,A)]}(r.utc(g,m).valueOf(),D,u),k=C[0],l=C[1],O=r(k).utcOffset(l);return O.$x.$timezone=u,O},r.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},r.tz.setDefault=function(g){s=g}}})});var wt=se((ct,dt)=>{(function(o,e){typeof ct=="object"&&typeof dt<"u"?dt.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_isoWeek=e()})(ct,function(){"use strict";var o="day";return function(e,t,n){var r=function(a){return a.add(4-a.isoWeekday(),o)},s=t.prototype;s.isoWeekYear=function(){return r(this).year()},s.isoWeek=function(a){if(!this.$utils().u(a))return this.add(7*(a-this.isoWeek()),o);var c,d,g,w,E=r(this),m=(c=this.isoWeekYear(),d=this.$u,g=(d?n.utc:n)().year(c).startOf("year"),w=4-g.isoWeekday(),g.isoWeekday()>4&&(w+=7),g.add(w,o));return E.diff(m,"week")+1},s.isoWeekday=function(a){return this.$utils().u(a)?this.day()||7:this.day(this.day()%7?a:a-7)};var i=s.startOf;s.startOf=function(a,c){var d=this.$utils(),g=!!d.u(c)||c;return d.p(a)==="isoweek"?g?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):i.bind(this)(a,c)}}})});var Ct=se((ut,ht)=>{(function(o,e){typeof ut=="object"&&typeof ht<"u"?ht.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_customParseFormat=e()})(ut,function(){"use strict";var o={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,t=/\d/,n=/\d\d/,r=/\d\d?/,s=/\d*[^-_:/,()\s\d]+/,i={},a=function(u){return(u=+u)+(u>68?1900:2e3)},c=function(u){return function(D){this[u]=+D}},d=[/[+-]\d\d:?(\d\d)?|Z/,function(u){(this.zone||(this.zone={})).offset=function(D){if(!D||D==="Z")return 0;var C=D.match(/([+-]|\d\d)/g),k=60*C[1]+(+C[2]||0);return k===0?0:C[0]==="+"?-k:k}(u)}],g=function(u){var D=i[u];return D&&(D.indexOf?D:D.s.concat(D.f))},w=function(u,D){var C,k=i.meridiem;if(k){for(var l=1;l<=24;l+=1)if(u.indexOf(k(l,0,D))>-1){C=l>12;break}}else C=u===(D?"pm":"PM");return C},E={A:[s,function(u){this.afternoon=w(u,!1)}],a:[s,function(u){this.afternoon=w(u,!0)}],Q:[t,function(u){this.month=3*(u-1)+1}],S:[t,function(u){this.milliseconds=100*+u}],SS:[n,function(u){this.milliseconds=10*+u}],SSS:[/\d{3}/,function(u){this.milliseconds=+u}],s:[r,c("seconds")],ss:[r,c("seconds")],m:[r,c("minutes")],mm:[r,c("minutes")],H:[r,c("hours")],h:[r,c("hours")],HH:[r,c("hours")],hh:[r,c("hours")],D:[r,c("day")],DD:[n,c("day")],Do:[s,function(u){var D=i.ordinal,C=u.match(/\d+/);if(this.day=C[0],D)for(var k=1;k<=31;k+=1)D(k).replace(/\[|\]/g,"")===u&&(this.day=k)}],w:[r,c("week")],ww:[n,c("week")],M:[r,c("month")],MM:[n,c("month")],MMM:[s,function(u){var D=g("months"),C=(g("monthsShort")||D.map(function(k){return k.slice(0,3)})).indexOf(u)+1;if(C<1)throw new Error;this.month=C%12||C}],MMMM:[s,function(u){var D=g("months").indexOf(u)+1;if(D<1)throw new Error;this.month=D%12||D}],Y:[/[+-]?\d+/,c("year")],YY:[n,function(u){this.year=a(u)}],YYYY:[/\d{4}/,c("year")],Z:d,ZZ:d};function m(u){var D,C;D=u,C=i&&i.formats;for(var k=(u=D.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(x,A,Y){var z=Y&&Y.toUpperCase();return A||C[Y]||o[Y]||C[z].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(S,f,h){return f||h.slice(1)})})).match(e),l=k.length,O=0;O-1)return new Date((p==="X"?1e3:1)*y);var R=m(p)(y),L=R.year,H=R.month,F=R.day,q=R.hours,ee=R.minutes,Z=R.seconds,re=R.milliseconds,j=R.zone,_=R.week,G=new Date,X=F||(L||H?1:G.getDate()),te=L||G.getFullYear(),ve=0;L&&!H||(ve=H>0?H-1:G.getMonth());var ye,Qe=q||0,Ze=ee||0,Xe=Z||0,Ke=re||0;return j?new Date(Date.UTC(te,ve,X,Qe,Ze,Xe,Ke+60*j.offset*1e3)):T?new Date(Date.UTC(te,ve,X,Qe,Ze,Xe,Ke)):(ye=new Date(te,ve,X,Qe,Ze,Xe,Ke),_&&(ye=M(ye).week(_).toDate()),ye)}catch{return new Date("")}}(W,$,P,C),this.init(),z&&z!==!0&&(this.$L=this.locale(z).$L),Y&&W!=this.format($)&&(this.$d=new Date("")),i={}}else if($ instanceof Array)for(var S=$.length,f=1;f<=S;f+=1){N[1]=$[f-1];var h=C.apply(this,N);if(h.isValid()){this.$d=h.$d,this.$L=h.$L,this.init();break}f===S&&(this.$d=new Date(""))}else l.call(this,O)}}})});var Tt=se((gt,mt)=>{(function(o,e){typeof gt=="object"&&typeof mt<"u"?mt.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_isSameOrAfter=e()})(gt,function(){"use strict";return function(o,e){e.prototype.isSameOrAfter=function(t,n){return this.isSame(t,n)||this.isAfter(t,n)}}})});var kt=se((ft,pt)=>{(function(o,e){typeof ft=="object"&&typeof pt<"u"?pt.exports=e():typeof define=="function"&&define.amd?define(e):(o=typeof globalThis<"u"?globalThis:o||self).dayjs_plugin_isSameOrBefore=e()})(ft,function(){"use strict";return function(o,e){e.prototype.isSameOrBefore=function(t,n){return this.isSame(t,n)||this.isBefore(t,n)}}})});var Nt=0;function ae(o){let e=++Nt;return{symbol:Symbol(o?`Token(${o})`:`Token#${e}`),description:o,toString(){return o?`Token<${o}>`:`Token<#${e}>`}}}var de=class extends Error{constructor(e){super(e),this.name="ContainerError"}},ue=class extends de{constructor(e,t=[]){let n=t.length>0?` + Dependency path: ${t.join(" -> ")}`:"";super(`Token "${e}" is not bound or registered in the container.${n}`),this.name="BindingNotFoundError"}},he=class extends de{constructor(e){super(`Circular dependency detected: ${e.join(" -> ")}`),this.name="CircularDependencyError"}};var yt=new WeakMap;function Ft(o){let e=yt.get(o);if(e)return e;let t=o.toString(),n=t.match(/constructor\s*\(([^)]*)\)/)||t.match(/^[^(]*\(([^)]*)\)/);if(!n||!n[1])return[];let r=n[1].split(",").map(s=>s.trim()).filter(s=>s.length>0).map(s=>{let i=s.split(/[:=]/)[0].trim();return i=i.replace(/^((public|private|protected|readonly)\s+)+/,""),i.includes("{")||i.includes("[")?null:i}).filter(s=>s!==null);return yt.set(o,r),r}function _t(o,e,t){if(!t.map)throw new Error("AutoWire map strategy requires options.map to be defined");let n=Ft(o),r=[];for(let s of n){let i=t.map[s];if(i===void 0){if(t.strict)throw new Error(`Cannot resolve parameter "${s}" on ${o.name}. Not found in autowire map. Add it to the map: .autoWire({ map: { ${s}: ... } })`);r.push(void 0);continue}typeof i=="function"?r.push(i(e)):r.push(e.resolve(i))}return r}function Yt(o,e,t){if(!t.mapResolvers||t.mapResolvers.length===0)return[];let n=[];for(let r=0;r0?Yt(o,e,n):n.map&&Object.keys(n.map).length>0?_t(o,e,n):[]}var le=class{constructor(e,t){this.registrations=t,this.configs=[],this.defaultLifetime="singleton",this.pending=e}as(e){if(e&&typeof e=="object"&&"symbol"in e){let t={token:e,type:this.pending.type,value:this.pending.value,factory:this.pending.factory,constructor:this.pending.constructor,lifetime:this.defaultLifetime};return this.configs.push(t),this.registrations.push(t),this}else{let t={token:null,type:this.pending.type,value:this.pending.value,factory:this.pending.factory,constructor:this.pending.constructor,lifetime:this.defaultLifetime,interfaceType:e};return this.configs.push(t),this.registrations.push(t),this}}asDefaultInterface(e){return this.as("TInterface",e),this.asDefault()}asKeyedInterface(e,t){return this.as("TInterface",t),this.keyed(e)}asImplementedInterfaces(e){if(e.length===0)return this;if(this.configs.length>0){for(let n of this.configs)n.lifetime="singleton",n.additionalTokens=n.additionalTokens||[],n.additionalTokens.push(...e);return this}let t={token:e[0],type:this.pending.type,value:this.pending.value,factory:this.pending.factory,constructor:this.pending.constructor,lifetime:"singleton"};this.configs.push(t),this.registrations.push(t);for(let n=1;ni.resolve(n),{lifetime:t.lifetime}),r.add(s)}build(){let e=this.baseContainer.createChild();this.resolveInterfaceTokens(e);let t=new Set,n=new Map,r=new Map,s=new Map,i=this.identifyNonDefaultTokens();for(let a of this.registrations){if(this.shouldSkipRegistration(a,i,t))continue;let c=this.createBindingToken(a,n,r,s);this.applyRegistration(e,{...a,token:c}),t.add(a.token),this.registerAdditionalInterfaces(e,a,c,t)}return e.__namedRegistrations=n,e.__keyedRegistrations=r,e.__multiRegistrations=s,e}analyzeConstructor(e){let t=e.toString();return{hasDependencies:/constructor\s*\([^)]+\)/.test(t)}}createOptimizedFactory(e,t,n){if(t.lifetime==="singleton"){let r=new t.constructor;e.bindValue(t.token,r)}else if(t.lifetime==="transient"){let r=t.constructor,s=()=>new r;e.fastTransientCache.set(t.token,s),e.bindFactory(t.token,s,n)}else{let r=()=>new t.constructor;e.bindFactory(t.token,r,n)}}createAutoWireFactory(e,t,n){let r=s=>{let i=Je(t.constructor,s,t.autowireOptions);return new t.constructor(...i)};e.bindFactory(t.token,r,n)}createParameterFactory(e,t,n){let r=()=>{let s=Object.values(t.parameterValues);return new t.constructor(...s)};e.bindFactory(t.token,r,n)}applyTypeRegistration(e,t,n){let{hasDependencies:r}=this.analyzeConstructor(t.constructor);if(!r&&!t.autowireOptions&&!t.parameterValues){this.createOptimizedFactory(e,t,n);return}if(t.autowireOptions){this.createAutoWireFactory(e,t,n);return}if(t.parameterValues){this.createParameterFactory(e,t,n);return}if(r){let i=t.constructor.name||"UnnamedClass";throw new Error(`Service "${i}" has constructor dependencies but no autowiring configuration. + +Solutions: + 1. \u2B50 Use the NovaDI transformer (recommended): + - Add "@novadi/core/unplugin" to your build config + - Transformer automatically generates .autoWire() for all dependencies + + 2. Add manual autowiring: + .autoWire({ map: { /* param: resolver */ } }) + + 3. Use a factory function: + .register((c) => new ${i}(...)) + +See docs: https://github.com/janus007/NovaDI#autowire`)}let s=()=>new t.constructor;e.bindFactory(t.token,s,n)}applyRegistration(e,t){let n={lifetime:t.lifetime};switch(t.type){case"instance":e.bindValue(t.token,t.value);break;case"factory":e.bindFactory(t.token,t.factory,n);break;case"type":this.applyTypeRegistration(e,t,n);break}}};function Vt(o){return o&&typeof o.dispose=="function"}var et=class{constructor(){this.resolvingStack=new Set,this.perRequestCache=new Map}isResolving(e){return this.resolvingStack.has(e)}enterResolve(e){this.resolvingStack.add(e)}exitResolve(e){this.resolvingStack.delete(e),this.path=void 0}getPath(){return this.path||(this.path=Array.from(this.resolvingStack).map(e=>e.toString())),[...this.path]}cachePerRequest(e,t){this.perRequestCache.set(e,t)}getPerRequest(e){return this.perRequestCache.get(e)}hasPerRequest(e){return this.perRequestCache.has(e)}reset(){this.resolvingStack.clear(),this.perRequestCache.clear(),this.path=void 0}},tt=class{constructor(){this.pool=[],this.maxSize=10}acquire(){let e=this.pool.pop();return e?(e.reset(),e):new et}release(e){this.pool.lengthnew t)}resolve(e){let t=this.tryGetFromCaches(e);if(t!==void 0)return t;if(this.currentContext)return this.resolveWithContext(e,this.currentContext);let n=o.contextPool.acquire();this.currentContext=n;try{return this.resolveWithContext(e,n)}finally{this.currentContext=void 0,o.contextPool.release(n)}}resolveSingletonUnsafe(e){return this.ultraFastSingletonCache.get(e)??this.singletonCache.get(e)}resolveTransientSimple(e){let t=this.fastTransientCache.get(e);return t?t():this.resolve(e)}resolveBatch(e){let t=!!this.currentContext,n=this.currentContext||o.contextPool.acquire();t||(this.currentContext=n);try{return e.map(s=>{let i=this.tryGetFromCaches(s);return i!==void 0?i:this.resolveWithContext(s,n)})}finally{t||(this.currentContext=void 0,o.contextPool.release(n))}}async resolveAsync(e){if(this.currentContext)return this.resolveAsyncWithContext(e,this.currentContext);let t=o.contextPool.acquire();this.currentContext=t;try{return await this.resolveAsyncWithContext(e,t)}finally{this.currentContext=void 0,o.contextPool.release(t)}}tryGetFromCaches(e){let t=this.ultraFastSingletonCache.get(e);if(t!==void 0)return t;if(this.singletonCache.has(e)){let r=this.singletonCache.get(e);return this.ultraFastSingletonCache.set(e,r),r}let n=this.fastTransientCache.get(e);if(n)return n()}cacheInstance(e,t,n,r){n==="singleton"?(this.singletonCache.set(e,t),this.singletonOrder.push(e),this.ultraFastSingletonCache.set(e,t)):n==="per-request"&&r&&r.cachePerRequest(e,t)}validateAndGetBinding(e,t){if(t.isResolving(e))throw new he([...t.getPath(),e.toString()]);let n=this.getBinding(e);if(!n)throw new ue(e.toString(),t.getPath());return n}instantiateBindingSync(e,t,n){switch(e.type){case"value":return e.value;case"factory":let r=e.factory(this);if(r instanceof Promise)throw new Error(`Async factory detected for ${t.toString()}. Use resolveAsync() instead.`);return r;case"class":let i=(e.dependencies||[]).map(a=>this.resolveWithContext(a,n));return new e.constructor(...i);case"inline-class":return new e.constructor;default:throw new Error(`Unknown binding type: ${e.type}`)}}async instantiateBindingAsync(e,t){switch(e.type){case"value":return e.value;case"factory":return await Promise.resolve(e.factory(this));case"class":let n=e.dependencies||[],r=await Promise.all(n.map(s=>this.resolveAsyncWithContext(s,t)));return new e.constructor(...r);case"inline-class":return new e.constructor;default:throw new Error(`Unknown binding type: ${e.type}`)}}createChild(){return new o(this)}async dispose(){let e=[];for(let t=this.singletonOrder.length-1;t>=0;t--){let n=this.singletonOrder[t],r=this.singletonCache.get(n);if(r&&Vt(r))try{await r.dispose()}catch(s){e.push(s)}}this.singletonCache.clear(),this.singletonOrder.length=0}builder(){return new ge(this)}resolveNamed(e){let t=this.__namedRegistrations;if(!t)throw new Error(`Named service "${e}" not found. No named registrations exist.`);let n=t.get(e);if(!n)throw new Error(`Named service "${e}" not found`);return this.resolve(n.token)}resolveKeyed(e){let t=this.__keyedRegistrations;if(!t)throw new Error("Keyed service not found. No keyed registrations exist.");let n=t.get(e);if(!n){let r=typeof e=="symbol"?e.toString():`"${e}"`;throw new Error(`Keyed service ${r} not found`)}return this.resolve(n.token)}resolveAll(e){let t=this.__multiRegistrations;if(!t)return[];let n=t.get(e);return!n||n.length===0?[]:n.map(r=>this.resolve(r))}getRegistry(){let e=[];return this.bindings.forEach((t,n)=>{e.push({token:n.description||n.symbol.toString(),type:t.type,lifetime:t.lifetime,dependencies:t.dependencies?.map(r=>r.description||r.symbol.toString())})}),e}interfaceToken(e){let t=e||`Interface_${Math.random().toString(36).substr(2,9)}`;if(this.interfaceRegistry.has(t))return this.interfaceRegistry.get(t);if(this.parent)return this.parent.interfaceToken(t);let n=ae(t);return this.interfaceRegistry.set(t,n),n}resolveType(e){let t=e||"",n=this.interfaceTokenCache.get(t);return n||(n=this.interfaceToken(e),this.interfaceTokenCache.set(t,n)),this.resolve(n)}resolveTypeKeyed(e,t){return this.resolveKeyed(e)}resolveTypeAll(e){let t=this.interfaceToken(e);return this.resolveAll(t)}resolveWithContext(e,t){let n=this.validateAndGetBinding(e,t);if(n.lifetime==="per-request"&&t.hasPerRequest(e))return t.getPerRequest(e);if(n.lifetime==="singleton"&&this.singletonCache.has(e))return this.singletonCache.get(e);t.enterResolve(e);try{let r=this.instantiateBindingSync(n,e,t);return this.cacheInstance(e,r,n.lifetime,t),r}finally{t.exitResolve(e)}}async resolveAsyncWithContext(e,t){let n=this.validateAndGetBinding(e,t);if(n.lifetime==="per-request"&&t.hasPerRequest(e))return t.getPerRequest(e);if(n.lifetime==="singleton"&&this.singletonCache.has(e))return this.singletonCache.get(e);t.enterResolve(e);try{let r=await this.instantiateBindingAsync(n,t);return this.cacheInstance(e,r,n.lifetime,t),r}finally{t.exitResolve(e)}}getBinding(e){return this.bindingCache||this.buildBindingCache(),this.bindingCache.get(e)}buildBindingCache(){this.bindingCache=new Map;let e=this;for(;e;)e.bindings.forEach((t,n)=>{this.bindingCache.has(n)||this.bindingCache.set(n,t)}),e=e.parent}invalidateBindingCache(){this.bindingCache=void 0,this.ultraFastSingletonCache.clear()}};ce.contextPool=new tt;var nt=class{constructor(){this.eventLog=[],this.debug=!1,this.listeners=new Set,this.logConfig={calendar:!0,grid:!0,event:!0,scroll:!0,navigation:!0,view:!0,default:!0}}on(e,t,n){return document.addEventListener(e,t,n),this.listeners.add({eventType:e,handler:t,options:n}),()=>this.off(e,t)}once(e,t){return this.on(e,t,{once:!0})}off(e,t){document.removeEventListener(e,t);for(let n of this.listeners)if(n.eventType===e&&n.handler===t){this.listeners.delete(n);break}}emit(e,t={}){if(!e)return!1;let n=new CustomEvent(e,{detail:t??{},bubbles:!0,cancelable:!0});return this.debug&&this.logEventWithGrouping(e,t),this.eventLog.push({type:e,detail:t??{},timestamp:Date.now()}),!document.dispatchEvent(n)}logEventWithGrouping(e,t){let n=this.extractCategory(e);if(!this.logConfig[n])return;let{emoji:r,color:s}=this.getCategoryStyle(n)}extractCategory(e){if(!e)return"unknown";if(e.includes(":"))return e.split(":")[0];let t=e.toLowerCase();return t.includes("grid")||t.includes("rendered")?"grid":t.includes("event")||t.includes("sync")?"event":t.includes("scroll")?"scroll":t.includes("nav")||t.includes("date")?"navigation":t.includes("view")?"view":"default"}getCategoryStyle(e){let t={calendar:{emoji:"\u{1F5D3}\uFE0F",color:"#2196F3"},grid:{emoji:"\u{1F4CA}",color:"#4CAF50"},event:{emoji:"\u{1F4C5}",color:"#FF9800"},scroll:{emoji:"\u{1F4DC}",color:"#9C27B0"},navigation:{emoji:"\u{1F9ED}",color:"#F44336"},view:{emoji:"\u{1F441}\uFE0F",color:"#00BCD4"},default:{emoji:"\u{1F4E2}",color:"#607D8B"}};return t[e]||t.default}setLogConfig(e){this.logConfig={...this.logConfig,...e}}getLogConfig(){return{...this.logConfig}}getEventLog(e){return e?this.eventLog.filter(t=>t.type===e):this.eventLog}setDebug(e){this.debug=e}},b=new nt;var ne={EVENT_HEIGHT:22,EVENT_GAP:2,CONTAINER_PADDING:4,MAX_COLLAPSED_ROWS:4,get SINGLE_ROW_HEIGHT(){return this.EVENT_HEIGHT+this.EVENT_GAP}},me={standard:{id:"standard",workDays:[1,2,3,4,5],totalDays:5,firstWorkDay:1},compressed:{id:"compressed",workDays:[1,2,3,4],totalDays:4,firstWorkDay:1},midweek:{id:"midweek",workDays:[3,4,5],totalDays:3,firstWorkDay:3},weekend:{id:"weekend",workDays:[6,7],totalDays:2,firstWorkDay:6},fullweek:{id:"fullweek",workDays:[1,2,3,4,5,6,7],totalDays:7,firstWorkDay:1}},K=class o{constructor(e,t,n,r,s,i,a=new Date){this.apiEndpoint="/api",this.config=e,this.gridSettings=t,this.dateViewSettings=n,this.timeFormatConfig=r,this.currentWorkWeek=s,this.currentView=i,this.selectedDate=a,o._instance=this}static getInstance(){if(!o._instance)throw new Error("Configuration has not been initialized. Call ConfigManager.load() first.");return o._instance}setSelectedDate(e){this.selectedDate=e}getWorkWeekSettings(){return me[this.currentWorkWeek]||me.standard}};K._instance=null;var I=ie(Et(),1),Mt=ie(Dt(),1),At=ie(St(),1),Rt=ie(wt(),1),bt=ie(Ct(),1),xt=ie(Tt(),1),It=ie(kt(),1);I.default.extend(Mt.default);I.default.extend(At.default);I.default.extend(Rt.default);I.default.extend(bt.default);I.default.extend(xt.default);I.default.extend(It.default);var U=class{constructor(e){this.timezone=e.timeFormatConfig.timezone}toUTC(e){return I.default.tz(e,this.timezone).utc().toISOString()}fromUTC(e){return I.default.utc(e).tz(this.timezone).toDate()}formatTime(e,t=!1){let n=t?"HH:mm:ss":"HH:mm";return(0,I.default)(e).format(n)}formatTimeRange(e,t){return`${this.formatTime(e)} - ${this.formatTime(t)}`}formatTechnicalDateTime(e){return(0,I.default)(e).format("YYYY-MM-DD HH:mm:ss")}formatDate(e){return(0,I.default)(e).format("YYYY-MM-DD")}formatMonthYear(e,t="en-US"){return e.toLocaleDateString(t,{month:"long",year:"numeric"})}formatISODate(e){return this.formatDate(e)}formatTime12(e){return(0,I.default)(e).format("h:mm A")}getDayName(e,t="short",n="da-DK"){return new Intl.DateTimeFormat(n,{weekday:t}).format(e)}formatDateRange(e,t,n={}){let{locale:r="en-US",month:s="short",day:i="numeric"}=n,a=e.getFullYear(),c=t.getFullYear(),d=new Intl.DateTimeFormat(r,{month:s,day:i,year:a!==c?"numeric":void 0});return typeof d.formatRange=="function"?d.formatRange(e,t):`${d.format(e)} - ${d.format(t)}`}timeToMinutes(e){let t=e.split(":").map(Number),n=t[0]||0,r=t[1]||0;return n*60+r}minutesToTime(e){let t=Math.floor(e/60),n=e%60;return(0,I.default)().hour(t).minute(n).format("HH:mm")}formatTimeFromMinutes(e){return this.minutesToTime(e)}getMinutesSinceMidnight(e){let t=(0,I.default)(e);return t.hour()*60+t.minute()}getDurationMinutes(e,t){let n=(0,I.default)(e);return(0,I.default)(t).diff(n,"minute")}getWeekBounds(e){let t=(0,I.default)(e);return{start:t.startOf("week").add(1,"day").toDate(),end:t.endOf("week").add(1,"day").toDate()}}addWeeks(e,t){return(0,I.default)(e).add(t,"week").toDate()}addMonths(e,t){return(0,I.default)(e).add(t,"month").toDate()}getWeekNumber(e){return(0,I.default)(e).isoWeek()}getFullWeekDates(e){let t=[];for(let n=0;n<7;n++)t.push(this.addDays(e,n));return t}getWorkWeekDates(e,t){let n=[],r=this.getWeekBounds(e),s=this.startOfDay(r.start);return t.forEach(i=>{let a=new Date(s),c=i===7?6:i-1;a.setDate(s.getDate()+c),n.push(a)}),n}createDateAtTime(e,t){let n=Math.floor(t/60),r=t%60;return(0,I.default)(e).startOf("day").hour(n).minute(r).toDate()}snapToInterval(e,t){let n=this.getMinutesSinceMidnight(e),r=Math.round(n/t)*t;return this.createDateAtTime(e,r)}isSameDay(e,t){return(0,I.default)(e).isSame(t,"day")}startOfDay(e){return(0,I.default)(e).startOf("day").toDate()}endOfDay(e){return(0,I.default)(e).endOf("day").toDate()}addDays(e,t){return(0,I.default)(e).add(t,"day").toDate()}addMinutes(e,t){return(0,I.default)(e).add(t,"minute").toDate()}parseISO(e){return(0,I.default)(e).toDate()}isValid(e){return(0,I.default)(e).isValid()}differenceInCalendarDays(e,t){let n=(0,I.default)(e).startOf("day"),r=(0,I.default)(t).startOf("day");return n.diff(r,"day")}isValidRange(e,t){return!this.isValid(e)||!this.isValid(t)?!1:e.getTime()<=t.getTime()}isWithinBounds(e){if(!this.isValid(e))return!1;let t=e.getFullYear();return t>=1900&&t<=2100}validateDate(e,t={}){if(!this.isValid(e))return{valid:!1,error:"Invalid date"};if(!this.isWithinBounds(e))return{valid:!1,error:"Date out of bounds (1900-2100)"};let n=new Date;return t.requireFuture&&e<=n?{valid:!1,error:"Date must be in the future"}:t.requirePast&&e>=n?{valid:!1,error:"Date must be in the past"}:t.minDate&&et.maxDate?{valid:!1,error:`Date must be before ${this.formatDate(t.maxDate)}`}:{valid:!0}}};var V=class o{static getDateService(){if(!o.dateService){if(!o.settings)throw new Error("TimeFormatter must be configured before use. Call TimeFormatter.configure() first.");let e={timeFormatConfig:{timezone:o.settings.timezone}};o.dateService=new U(e)}return o.dateService}static configure(e){o.settings=e,o.dateService=null}static convertToLocalTime(e){if(typeof e=="string")return o.getDateService().fromUTC(e);let t=e.toISOString();return o.getDateService().fromUTC(t)}static format24Hour(e){if(!o.settings)throw new Error("TimeFormatter must be configured before use. Call TimeFormatter.configure() first.");let t=o.convertToLocalTime(e);return o.getDateService().formatTime(t,o.settings.showSeconds)}static formatTime(e){return o.format24Hour(e)}static formatTimeRange(e,t){let n=o.convertToLocalTime(e),r=o.convertToLocalTime(t);return o.getDateService().formatTimeRange(n,r)}};V.settings=null;V.dateService=null;var v={INITIALIZED:"core:initialized",READY:"core:ready",DESTROYED:"core:destroyed",VIEW_CHANGED:"view:changed",VIEW_RENDERED:"view:rendered",WORKWEEK_CHANGED:"workweek:changed",NAV_BUTTON_CLICKED:"nav:button-clicked",DATE_CHANGED:"nav:date-changed",NAVIGATION_COMPLETED:"nav:navigation-completed",PERIOD_INFO_UPDATE:"nav:period-info-update",NAVIGATE_TO_EVENT:"nav:navigate-to-event",DATA_LOADING:"data:loading",DATA_LOADED:"data:loaded",DATA_ERROR:"data:error",EVENTS_FILTERED:"data:events-filtered",REMOTE_UPDATE_RECEIVED:"data:remote-update",GRID_RENDERED:"grid:rendered",GRID_CLICKED:"grid:clicked",CELL_SELECTED:"grid:cell-selected",EVENT_CREATED:"event:created",EVENT_UPDATED:"event:updated",EVENT_DELETED:"event:deleted",EVENT_SELECTED:"event:selected",ERROR:"system:error",REFRESH_REQUESTED:"system:refresh",OFFLINE_MODE_CHANGED:"system:offline-mode-changed",SYNC_STARTED:"sync:started",SYNC_COMPLETED:"sync:completed",SYNC_FAILED:"sync:failed",SYNC_RETRY:"sync:retry",FILTER_CHANGED:"filter:changed",EVENTS_RENDERED:"events:rendered"};var fe=class{constructor(e,t){this.eventBus=e,this.config=t,this.setupEventListeners(),this.syncGridCSSVariables(),this.syncWorkweekCSSVariables()}setupEventListeners(){this.eventBus.on(v.WORKWEEK_CHANGED,e=>{let{settings:t}=e.detail;this.syncWorkweekCSSVariables(t)})}syncGridCSSVariables(){let e=this.config.gridSettings;document.documentElement.style.setProperty("--hour-height",`${e.hourHeight}px`),document.documentElement.style.setProperty("--day-start-hour",e.dayStartHour.toString()),document.documentElement.style.setProperty("--day-end-hour",e.dayEndHour.toString()),document.documentElement.style.setProperty("--work-start-hour",e.workStartHour.toString()),document.documentElement.style.setProperty("--work-end-hour",e.workEndHour.toString())}syncWorkweekCSSVariables(e){let t=e||this.config.getWorkWeekSettings();document.documentElement.style.setProperty("--grid-columns",t.totalDays.toString())}static async load(){let e=await fetch("/wwwroot/data/calendar-config.json");if(!e.ok)throw new Error(`Failed to load config: ${e.statusText}`);let t=await e.json(),n={scrollbarWidth:t.scrollbar.width,scrollbarColor:t.scrollbar.color,scrollbarTrackColor:t.scrollbar.trackColor,scrollbarHoverColor:t.scrollbar.hoverColor,scrollbarBorderRadius:t.scrollbar.borderRadius,allowDrag:t.interaction.allowDrag,allowResize:t.interaction.allowResize,allowCreate:t.interaction.allowCreate,apiEndpoint:t.api.endpoint,dateFormat:t.api.dateFormat,timeFormat:t.api.timeFormat,enableSearch:t.features.enableSearch,enableTouch:t.features.enableTouch,defaultEventDuration:t.eventDefaults.defaultEventDuration,minEventDuration:t.gridSettings.snapInterval,maxEventDuration:t.eventDefaults.maxEventDuration},r=new K(n,t.gridSettings,t.dateViewSettings,t.timeFormatConfig,t.currentWorkWeek,t.currentView||"week");return V.configure(r.timeFormatConfig),r}};var Ee=class{constructor(e){this.eventBus=e}parseEventIdFromURL(){try{let t=new URLSearchParams(window.location.search).get("eventId");return t&&t.trim()!==""?t.trim():null}catch(e){return console.warn("URLManager: Failed to parse URL parameters:",e),null}}getAllQueryParams(){try{let e=new URLSearchParams(window.location.search),t={};for(let[n,r]of e.entries())t[n]=r;return t}catch(e){return console.warn("URLManager: Failed to parse URL parameters:",e),{}}}updateURL(e){try{let t=new URL(window.location.href);Object.entries(e).forEach(([n,r])=>{r===null?t.searchParams.delete(n):t.searchParams.set(n,r)}),window.history.replaceState({},"",t.toString())}catch(t){console.warn("URLManager: Failed to update URL:",t)}}hasQueryParams(){return window.location.search.length>0}};var De=class{constructor(e,t,n,r){this.eventBus=e,this.dateService=t,this.config=n,this.repository=r}async loadData(){try{await this.repository.loadEvents()}catch(e){throw console.error("Failed to load event data:",e),e}}async getEvents(e=!1){let t=await this.repository.loadEvents();return e?[...t]:t}async getEventById(e){return(await this.repository.loadEvents()).find(n=>n.id===e)}async getEventForNavigation(e){let t=await this.getEventById(e);if(!t)return null;let n=this.dateService.validateDate(t.start);return n.valid?this.dateService.isValidRange(t.start,t.end)?{event:t,eventDate:t.start}:(console.warn(`EventManager: Invalid date range for event ${e}: start must be before end`),null):(console.warn(`EventManager: Invalid event start date for event ${e}:`,n.error),null)}async navigateToEvent(e){let t=await this.getEventForNavigation(e);if(!t)return console.warn(`EventManager: Event with ID ${e} not found`),!1;let{event:n,eventDate:r}=t;return this.eventBus.emit(v.NAVIGATE_TO_EVENT,{eventId:e,event:n,eventDate:r,eventStartTime:n.start}),!0}async getEventsForPeriod(e,t){return(await this.repository.loadEvents()).filter(r=>r.start<=t&&r.end>=e)}async addEvent(e){let t=await this.repository.createEvent(e,"local");return this.eventBus.emit(v.EVENT_CREATED,{event:t}),t}async updateEvent(e,t){try{let n=await this.repository.updateEvent(e,t,"local");return this.eventBus.emit(v.EVENT_UPDATED,{event:n}),n}catch(n){return console.error(`Failed to update event ${e}:`,n),null}}async deleteEvent(e){try{return await this.repository.deleteEvent(e,"local"),this.eventBus.emit(v.EVENT_DELETED,{eventId:e}),!0}catch(t){return console.error(`Failed to delete event ${e}:`,t),!1}}async handleRemoteUpdate(e){try{await this.repository.updateEvent(e.id,e,"remote"),this.eventBus.emit(v.REMOTE_UPDATE_RECEIVED,{event:e}),this.eventBus.emit(v.EVENT_UPDATED,{event:e})}catch(t){console.error(`Failed to handle remote update for event ${e.id}:`,t)}}};var B=class{static updateColumnBoundsCache(){this.columnBoundsCache=[];let e=document.querySelectorAll("swp-day-column"),t=1;e.forEach(n=>{let r=n.getBoundingClientRect(),s=n.dataset.date;s&&this.columnBoundsCache.push({boundingClientRect:r,element:n,date:s,left:r.left,right:r.right,index:t++})}),this.columnBoundsCache.sort((n,r)=>n.left-r.left)}static getColumnBounds(e){this.columnBoundsCache.length===0&&this.updateColumnBoundsCache();let t=this.columnBoundsCache.find(n=>e.x>=n.left&&e.x<=n.right);return t||null}static getColumnBoundsByDate(e){this.columnBoundsCache.length===0&&this.updateColumnBoundsCache();let t=e.toISOString().split("T")[0];return this.columnBoundsCache.find(r=>r.date===t)||null}static getColumns(){return[...this.columnBoundsCache]}static getHeaderColumns(){let e=[],t=document.querySelectorAll("swp-calendar-header swp-day-header"),n=1;return t.forEach(r=>{let s=r.getBoundingClientRect(),i=r.dataset.date;i&&e.push({boundingClientRect:s,element:r,date:i,left:s.left,right:s.right,index:n++})}),e.sort((r,s)=>r.left-s.left),e}};B.columnBoundsCache=[];var Se=class{constructor(e,t,n,r){this.dragMouseLeaveHeaderListener=null,this.eventBus=e,this.eventManager=t,this.strategy=n,this.dateService=r,this.setupEventListeners()}async renderEvents(e){this.strategy.clearEvents(e.container);let t=await this.eventManager.getEventsForPeriod(e.startDate,e.endDate);if(t.length===0)return;let n=t.filter(r=>!r.allDay);console.log("\u{1F3AF} EventRenderingService: Event filtering",{totalEvents:t.length,timedEvents:n.length,allDayEvents:t.length-n.length}),n.length>0&&this.strategy.renderEvents(n,e.container),this.eventBus.emit(v.EVENTS_RENDERED,{events:t,container:e.container})}setupEventListeners(){this.eventBus.on(v.GRID_RENDERED,e=>{this.handleGridRendered(e)}),this.eventBus.on(v.VIEW_CHANGED,e=>{this.handleViewChanged(e)}),this.setupDragEventListeners()}handleGridRendered(e){let{container:t,startDate:n,endDate:r}=e.detail;!t||!n||!r||this.renderEvents({container:t,startDate:n,endDate:r})}handleViewChanged(e){this.clearEvents()}setupDragEventListeners(){this.setupDragStartListener(),this.setupDragMoveListener(),this.setupDragEndListener(),this.setupDragColumnChangeListener(),this.setupDragMouseLeaveHeaderListener(),this.setupDragMouseEnterColumnListener(),this.setupResizeEndListener(),this.setupNavigationCompletedListener()}setupDragStartListener(){this.eventBus.on("drag:start",e=>{let t=e.detail;t.originalElement.hasAttribute("data-allday")||t.originalElement&&this.strategy.handleDragStart&&t.columnBounds&&this.strategy.handleDragStart(t)})}setupDragMoveListener(){this.eventBus.on("drag:move",e=>{let t=e.detail;t.draggedClone.hasAttribute("data-allday")||this.strategy.handleDragMove&&this.strategy.handleDragMove(t)})}setupDragEndListener(){this.eventBus.on("drag:end",async e=>{let{originalElement:t,draggedClone:n,originalSourceColumn:r,finalPosition:s,target:i}=e.detail,a=s.column,c=s.snappedY,d=n;i==="swp-day-column"&&a&&(t&&n&&this.strategy.handleDragEnd&&this.strategy.handleDragEnd(t,n,a,c),await this.eventManager.updateEvent(d.eventId,{start:d.start,end:d.end,allDay:!1}),await this.reRenderAffectedColumns(r,a))})}setupDragColumnChangeListener(){this.eventBus.on("drag:column-change",e=>{let t=e.detail;t.draggedClone&&t.draggedClone.hasAttribute("data-allday")||this.strategy.handleColumnChange&&this.strategy.handleColumnChange(t)})}setupDragMouseLeaveHeaderListener(){this.dragMouseLeaveHeaderListener=e=>{let{targetDate:t,mousePosition:n,originalElement:r,draggedClone:s}=e.detail;s&&(s.style.display=""),console.log("\u{1F6AA} EventRendererManager: Received drag:mouseleave-header",{targetDate:t,originalElement:r,cloneElement:s})},this.eventBus.on("drag:mouseleave-header",this.dragMouseLeaveHeaderListener)}setupDragMouseEnterColumnListener(){this.eventBus.on("drag:mouseenter-column",e=>{let t=e.detail;t.draggedClone.hasAttribute("data-allday")&&(console.log("\u{1F3AF} EventRendererManager: Received drag:mouseenter-column",{targetColumn:t.targetColumn,snappedY:t.snappedY,calendarEvent:t.calendarEvent}),this.strategy.handleConvertAllDayToTimed&&this.strategy.handleConvertAllDayToTimed(t))})}setupResizeEndListener(){this.eventBus.on("resize:end",async e=>{let{eventId:t,element:n}=e.detail,r=n,s=r.start,i=r.end;await this.eventManager.updateEvent(t,{start:s,end:i}),console.log("\u{1F4DD} EventRendererManager: Updated event after resize",{eventId:t,newStart:s,newEnd:i});let a=B.getColumnBoundsByDate(s);a&&await this.renderSingleColumn(a)})}setupNavigationCompletedListener(){this.eventBus.on(v.NAVIGATION_COMPLETED,()=>{this.strategy.handleNavigationCompleted&&this.strategy.handleNavigationCompleted()})}async reRenderAffectedColumns(e,t){e&&await this.renderSingleColumn(e),t&&t.date!==e?.date&&await this.renderSingleColumn(t)}clearColumnEvents(e){let t=e.querySelectorAll("swp-event"),n=e.querySelectorAll("swp-event-group");t.forEach(r=>r.remove()),n.forEach(r=>r.remove())}async renderSingleColumn(e){let t=this.dateService.parseISO(`${e.date}T00:00:00`),n=this.dateService.parseISO(`${e.date}T23:59:59.999`),s=(await this.eventManager.getEventsForPeriod(t,n)).filter(a=>!a.allDay),i=e.element.querySelector("swp-events-layer");if(!i){console.warn("EventRendererManager: Events layer not found in column");return}this.clearColumnEvents(i),this.strategy.renderSingleColumnEvents&&this.strategy.renderSingleColumnEvents(e,s),console.log("\u{1F504} EventRendererManager: Re-rendered single column",{columnDate:e.date,eventsCount:s.length})}clearEvents(e){this.strategy.clearEvents(e)}refresh(e){this.clearEvents(e)}};var we=class{constructor(e,t){this.container=null,this.currentDate=new Date,this.currentView="week",this.gridRenderer=e,this.dateService=t,this.init()}init(){this.findElements(),this.subscribeToEvents()}getISOWeekStart(e){let t=this.dateService.getWeekBounds(e);return this.dateService.startOfDay(t.start)}getWeekEnd(e){let t=this.dateService.getWeekBounds(e);return this.dateService.endOfDay(t.end)}findElements(){this.container=document.querySelector("swp-calendar-container")}subscribeToEvents(){b.on(v.VIEW_CHANGED,e=>{let t=e.detail;this.currentView=t.currentView,this.render()}),b.on(v.REFRESH_REQUESTED,e=>{this.render()}),b.on(v.WORKWEEK_CHANGED,()=>{this.render()})}async render(){if(!this.container)return;this.gridRenderer.renderGrid(this.container,this.currentDate);let e=this.getPeriodRange(),t=this.getLayoutConfig();b.emit(v.GRID_RENDERED,{container:this.container,currentDate:this.currentDate,startDate:e.startDate,endDate:e.endDate,layoutConfig:t,columnCount:t.columnCount})}getCurrentPeriodLabel(){switch(this.currentView){case"week":case"day":let e=this.getISOWeekStart(this.currentDate),t=this.getWeekEnd(this.currentDate);return this.dateService.formatDateRange(e,t);case"month":return this.dateService.formatMonthYear(this.currentDate);default:let n=this.getISOWeekStart(this.currentDate),r=this.getWeekEnd(this.currentDate);return this.dateService.formatDateRange(n,r)}}navigateNext(){let e;switch(this.currentView){case"week":e=this.dateService.addWeeks(this.currentDate,1);break;case"month":e=this.dateService.addMonths(this.currentDate,1);break;case"day":e=this.dateService.addDays(this.currentDate,1);break;default:e=this.dateService.addWeeks(this.currentDate,1)}this.currentDate=e,b.emit(v.NAVIGATION_COMPLETED,{direction:"next",newDate:e,periodLabel:this.getCurrentPeriodLabel()}),this.render()}navigatePrevious(){let e;switch(this.currentView){case"week":e=this.dateService.addWeeks(this.currentDate,-1);break;case"month":e=this.dateService.addMonths(this.currentDate,-1);break;case"day":e=this.dateService.addDays(this.currentDate,-1);break;default:e=this.dateService.addWeeks(this.currentDate,-1)}this.currentDate=e,b.emit(v.NAVIGATION_COMPLETED,{direction:"previous",newDate:e,periodLabel:this.getCurrentPeriodLabel()}),this.render()}getDisplayDates(){switch(this.currentView){case"week":let e=this.getISOWeekStart(this.currentDate);return this.dateService.getFullWeekDates(e);case"month":return this.getMonthDates(this.currentDate);case"day":return[this.currentDate];default:let t=this.getISOWeekStart(this.currentDate);return this.dateService.getFullWeekDates(t)}}getPeriodRange(){switch(this.currentView){case"week":let e=this.getISOWeekStart(this.currentDate),t=this.getWeekEnd(this.currentDate);return{startDate:e,endDate:t};case"month":return{startDate:this.getMonthStart(this.currentDate),endDate:this.getMonthEnd(this.currentDate)};case"day":return{startDate:this.currentDate,endDate:this.currentDate};default:let n=this.getISOWeekStart(this.currentDate),r=this.getWeekEnd(this.currentDate);return{startDate:n,endDate:r}}}getLayoutConfig(){switch(this.currentView){case"week":return{columnCount:7,type:"week"};case"month":return{columnCount:7,type:"month"};case"day":return{columnCount:1,type:"day"};default:return{columnCount:7,type:"week"}}}getMonthStart(e){let t=e.getFullYear(),n=e.getMonth();return this.dateService.startOfDay(new Date(t,n,1))}getMonthEnd(e){let t=this.dateService.addMonths(e,1),n=this.getMonthStart(t);return this.dateService.endOfDay(this.dateService.addDays(n,-1))}getMonthDates(e){let t=[],n=this.getMonthStart(e),r=this.getMonthEnd(e),s=Math.ceil((r.getTime()-n.getTime())/(1e3*60*60*24))+1;for(let i=0;i{this.syncTimeAxisPosition(),this.setupScrolling()}),b.on("header:height-changed",()=>{this.updateScrollableHeight()}),b.on("header:ready",()=>{this.calendarHeader=document.querySelector("swp-calendar-header"),this.scrollableContent&&this.calendarHeader&&(this.setupHorizontalScrollSynchronization(),this.syncCalendarHeaderPosition()),this.updateScrollableHeight()}),window.addEventListener("resize",()=>{this.updateScrollableHeight()}),b.on("scroll:to-event-time",e=>{let t=e,{eventStartTime:n}=t.detail;n&&this.scrollToEventTime(n)})}setupScrolling(){this.findElements(),this.scrollableContent&&this.calendarContainer&&(this.setupResizeObserver(),this.updateScrollableHeight(),this.setupScrollSynchronization()),this.scrollableContent&&this.calendarHeader&&this.setupHorizontalScrollSynchronization()}findElements(){this.scrollableContent=document.querySelector("swp-scrollable-content"),this.calendarContainer=document.querySelector("swp-calendar-container"),this.timeAxis=document.querySelector("swp-time-axis"),this.calendarHeader=document.querySelector("swp-calendar-header")}scrollTo(e){this.scrollableContent&&(this.scrollableContent.scrollTop=e)}scrollToHour(e){let t=`${e.toString().padStart(2,"0")}:00`,n=this.positionUtils.timeToPixels(t);this.scrollTo(n)}scrollToEventTime(e){try{let t=new Date(e),n=t.getHours(),r=t.getMinutes(),s=n+r/60;this.scrollToHour(s)}catch(t){console.warn("ScrollManager: Failed to scroll to event time:",t)}}setupResizeObserver(){this.calendarContainer&&(this.resizeObserver&&this.resizeObserver.disconnect(),this.resizeObserver=new ResizeObserver(e=>{for(let t of e)this.updateScrollableHeight()}),this.resizeObserver.observe(this.calendarContainer))}updateScrollableHeight(){if(!this.scrollableContent||!this.calendarContainer)return;let e=this.calendarContainer.getBoundingClientRect(),t=document.querySelector("swp-calendar-nav"),n=t?t.getBoundingClientRect().height:0,r=document.querySelector("swp-calendar-header"),s=r?r.getBoundingClientRect().height:80,i=e.height-s,a=e.width-60;i>0&&(this.scrollableContent.style.height=`${i}px`),a>0&&(this.scrollableContent.style.width=`${a}px`)}setupScrollSynchronization(){if(!this.scrollableContent||!this.timeAxis)return;let e=null;this.scrollableContent.addEventListener("scroll",()=>{e&&cancelAnimationFrame(e),e=requestAnimationFrame(()=>{this.syncTimeAxisPosition()})})}syncTimeAxisPosition(){if(!this.scrollableContent||!this.timeAxis)return;let e=this.scrollableContent.scrollTop,t=this.timeAxis.querySelector("swp-time-axis-content");t&&(t.style.transform=`translateY(-${e}px)`,e%100)}setupHorizontalScrollSynchronization(){!this.scrollableContent||!this.calendarHeader||this.scrollableContent.addEventListener("scroll",()=>{this.syncCalendarHeaderPosition()})}syncCalendarHeaderPosition(){if(!this.scrollableContent||!this.calendarHeader)return;let e=this.scrollableContent.scrollLeft;this.calendarHeader.style.transform=`translateX(-${e}px)`,e%100}};var Te=class{constructor(e,t,n,r,s){this.animationQueue=0,this.eventBus=e,this.dateService=r,this.weekInfoRenderer=s,this.gridRenderer=n,this.currentWeek=this.getISOWeekStart(new Date),this.targetWeek=new Date(this.currentWeek),this.init()}init(){this.setupEventListeners()}getISOWeekStart(e){let t=this.dateService.getWeekBounds(e);return this.dateService.startOfDay(t.start)}setupEventListeners(){this.eventBus.on(v.INITIALIZED,()=>{this.updateWeekInfo()}),this.eventBus.on(v.FILTER_CHANGED,e=>{let t=e.detail;this.weekInfoRenderer.applyFilterToPreRenderedGrids(t)}),this.eventBus.on(v.NAV_BUTTON_CLICKED,e=>{let{action:t}=e.detail;switch(t){case"prev":this.navigateToPreviousWeek();break;case"next":this.navigateToNextWeek();break;case"today":this.navigateToToday();break}}),this.eventBus.on(v.DATE_CHANGED,e=>{let n=e.detail.currentDate;if(!n){console.warn("NavigationManager: No date provided in DATE_CHANGED event");return}let r=new Date(n),s=this.dateService.validateDate(r);if(!s.valid){console.warn("NavigationManager: Invalid date received:",s.error);return}this.navigateToDate(r)}),this.eventBus.on(v.NAVIGATE_TO_EVENT,e=>{let t=e,{eventDate:n,eventStartTime:r}=t.detail;if(!n||!r){console.warn("NavigationManager: Invalid event navigation data");return}this.navigateToEventDate(n,r)})}navigateToEventDate(e,t){let n=this.getISOWeekStart(e);this.targetWeek=new Date(n);let r=this.currentWeek.getTime(),s=n.getTime(),i=()=>{this.eventBus.emit("scroll:to-event-time",{eventStartTime:t})};rs?(this.animationQueue++,this.animateTransition("prev",n),this.eventBus.once(v.NAVIGATION_COMPLETED,i)):i()}navigateToPreviousWeek(){this.targetWeek=this.dateService.addWeeks(this.targetWeek,-1);let e=new Date(this.targetWeek);this.animationQueue++,this.animateTransition("prev",e)}navigateToNextWeek(){this.targetWeek=this.dateService.addWeeks(this.targetWeek,1);let e=new Date(this.targetWeek);this.animationQueue++,this.animateTransition("next",e)}navigateToToday(){let e=new Date,t=this.getISOWeekStart(e);this.targetWeek=new Date(t);let n=this.currentWeek.getTime(),r=t.getTime();nr&&(this.animationQueue++,this.animateTransition("prev",t))}navigateToDate(e){let t=this.getISOWeekStart(e);this.targetWeek=new Date(t);let n=this.currentWeek.getTime(),r=t.getTime();nr&&(this.animationQueue++,this.animateTransition("prev",t))}animateTransition(e,t){let n=document.querySelector("swp-calendar-container"),r=document.querySelector("swp-calendar-container swp-grid-container:not([data-prerendered])");if(!n||!r)return;document.documentElement.style.setProperty("--all-day-row-height","0px");let i;console.group("\u{1F527} NavigationManager.refactored"),console.log("Calling GridRenderer instead of NavigationRenderer"),console.log("Target week:",t),i=this.gridRenderer.createNavigationGrid(n,t),console.groupEnd(),i.style.transform="",r.style.transform="";let a=r.animate([{transform:"translateX(0)",opacity:"1"},{transform:e==="next"?"translateX(-100%)":"translateX(100%)",opacity:"0.5"}],{duration:400,easing:"ease-in-out",fill:"forwards"});i.animate([{transform:e==="next"?"translateX(100%)":"translateX(-100%)"},{transform:"translateX(0)"}],{duration:400,easing:"ease-in-out",fill:"forwards"}).addEventListener("finish",()=>{let d=n.querySelectorAll("swp-grid-container");for(let g=0;g{let n=r=>{r.preventDefault();let s=t.getAttribute("data-action");s&&this.isValidAction(s)&&this.handleNavigation(s)};t.addEventListener("click",n),this.buttonListeners.set(t,n)})}handleNavigation(e){this.eventBus.emit(v.NAV_BUTTON_CLICKED,{action:e})}isValidAction(e){return["prev","next","today"].includes(e)}};var Me=class{constructor(e,t){this.buttonListeners=new Map,this.eventBus=e,this.config=t,this.setupButtonListeners(),this.setupEventListeners()}setupButtonListeners(){document.querySelectorAll("swp-view-button[data-view]").forEach(t=>{let n=r=>{r.preventDefault();let s=t.getAttribute("data-view");s&&this.isValidView(s)&&this.changeView(s)};t.addEventListener("click",n),this.buttonListeners.set(t,n)}),this.updateButtonStates()}setupEventListeners(){this.eventBus.on(v.INITIALIZED,()=>{this.initializeView()}),this.eventBus.on(v.DATE_CHANGED,()=>{this.refreshCurrentView()})}changeView(e){if(e===this.config.currentView)return;let t=this.config.currentView;this.config.currentView=e,this.updateButtonStates(),this.eventBus.emit(v.VIEW_CHANGED,{previousView:t,currentView:e})}updateButtonStates(){document.querySelectorAll("swp-view-button[data-view]").forEach(t=>{t.getAttribute("data-view")===this.config.currentView?t.setAttribute("data-active","true"):t.removeAttribute("data-active")})}initializeView(){this.updateButtonStates(),this.emitViewRendered()}emitViewRendered(){this.eventBus.emit(v.VIEW_RENDERED,{view:this.config.currentView})}refreshCurrentView(){this.emitViewRendered()}isValidView(e){return["day","week","month"].includes(e)}};var Ae=class{constructor(e,t,n,r,s,i){this.currentView="week",this.currentDate=new Date,this.isInitialized=!1,this.eventBus=e,this.eventManager=t,this.gridManager=n,this.eventRenderer=r,this.scrollManager=s,this.config=i,this.setupEventListeners()}async initialize(){if(!this.isInitialized)try{await this.eventManager.loadData(),await this.gridManager.render(),this.scrollManager.initialize(),this.setView(this.currentView),this.setCurrentDate(this.currentDate),this.isInitialized=!0,this.eventBus.emit(v.INITIALIZED,{currentDate:this.currentDate,currentView:this.currentView})}catch(e){throw e}}setView(e){if(this.currentView===e)return;let t=this.currentView;this.currentView=e,this.eventBus.emit(v.VIEW_CHANGED,{previousView:t,currentView:e,date:this.currentDate})}setCurrentDate(e){let t=this.currentDate;this.currentDate=new Date(e),this.eventBus.emit(v.DATE_CHANGED,{previousDate:t,currentDate:this.currentDate,view:this.currentView})}setupEventListeners(){this.eventBus.on(v.WORKWEEK_CHANGED,e=>{let t=e;this.handleWorkweekChange()})}calculateCurrentPeriod(){let e=new Date(this.currentDate);switch(this.currentView){case"day":let t=new Date(e);t.setHours(0,0,0,0);let n=new Date(e);return n.setHours(23,59,59,999),{start:t.toISOString(),end:n.toISOString()};case"week":let r=new Date(e),s=r.getDay(),i=s===0?6:s-1;r.setDate(r.getDate()-i),r.setHours(0,0,0,0);let a=new Date(r);return a.setDate(a.getDate()+6),a.setHours(23,59,59,999),{start:r.toISOString(),end:a.toISOString()};case"month":let c=new Date(e.getFullYear(),e.getMonth(),1),d=new Date(e.getFullYear(),e.getMonth()+1,0,23,59,59,999);return{start:c.toISOString(),end:d.toISOString()};default:let g=new Date(e);g.setDate(g.getDate()-3),g.setHours(0,0,0,0);let w=new Date(e);return w.setDate(w.getDate()+3),w.setHours(23,59,59,999),{start:g.toISOString(),end:w.toISOString()}}}handleWorkweekChange(){this.eventBus.emit("workweek:header-update",{currentDate:this.currentDate,currentView:this.currentView})}};var Re=class extends HTMLElement{constructor(){super(),this.config=K.getInstance(),this.dateService=new U(this.config)}get eventId(){return this.dataset.eventId||""}set eventId(e){this.dataset.eventId=e}get start(){return new Date(this.dataset.start||"")}set start(e){this.dataset.start=this.dateService.toUTC(e)}get end(){return new Date(this.dataset.end||"")}set end(e){this.dataset.end=this.dateService.toUTC(e)}get title(){return this.dataset.title||""}set title(e){this.dataset.title=e}get description(){return this.dataset.description||""}set description(e){this.dataset.description=e}get type(){return this.dataset.type||"work"}set type(e){this.dataset.type=e}},Q=class extends Re{static get observedAttributes(){return["data-start","data-end","data-title","data-description","data-type"]}connectedCallback(){this.hasChildNodes()||this.render()}attributeChangedCallback(e,t,n){t!==n&&this.isConnected&&this.updateDisplay()}updatePosition(e,t){this.style.top=`${t+1}px`;let{startMinutes:n,endMinutes:r}=this.calculateTimesFromPosition(t),s=this.dateService.createDateAtTime(e,n),i=this.dateService.createDateAtTime(e,r);if(r>=1440){let a=Math.floor(r/1440);i=this.dateService.addDays(i,a)}this.start=s,this.end=i}updateHeight(e){this.style.height=`${e}px`;let t=this.config.gridSettings,{hourHeight:n,snapInterval:r}=t,s=this.start,i=e/n*60,a=Math.round(i/r)*r,c=this.dateService.addMinutes(s,a);this.end=c}createClone(){let e=this.cloneNode(!0);e.dataset.eventId=`clone-${this.eventId}`,e.style.pointerEvents="none";let t=this.querySelector("swp-event-time");if(t){let n=t.getAttribute("data-duration");n&&(e.dataset.originalDuration=n)}return e.style.height=this.style.height||`${this.getBoundingClientRect().height}px`,e}render(){let e=this.start,t=this.end,n=V.formatTimeRange(e,t),r=(t.getTime()-e.getTime())/(1e3*60);this.innerHTML=` + ${n} + ${this.title} + ${this.description?`${this.description}`:""} + `}updateDisplay(){let e=this.querySelector("swp-event-time"),t=this.querySelector("swp-event-title"),n=this.querySelector("swp-event-description");if(e&&this.dataset.start&&this.dataset.end){let r=new Date(this.dataset.start),s=new Date(this.dataset.end),i=V.formatTimeRange(r,s);e.textContent=i;let a=(s.getTime()-r.getTime())/(1e3*60);e.setAttribute("data-duration",a.toString())}if(t&&this.dataset.title&&(t.textContent=this.dataset.title),this.dataset.description){if(n)n.textContent=this.dataset.description;else if(this.description){let r=document.createElement("swp-event-description");r.textContent=this.description,this.appendChild(r)}}else n&&n.remove()}calculateTimesFromPosition(e){let t=this.config.gridSettings,{hourHeight:n,dayStartHour:r,snapInterval:s}=t,i=parseInt(this.dataset.originalDuration||this.dataset.duration||"60"),a=e/n*60,c=r*60+a,d=Math.round(c/s)*s,g=d+i;return{startMinutes:d,endMinutes:g}}static fromCalendarEvent(e){let t=document.createElement("swp-event"),n=K.getInstance(),r=new U(n);return t.dataset.eventId=e.id,t.dataset.title=e.title,t.dataset.description=e.description||"",t.dataset.start=r.toUTC(e.start),t.dataset.end=r.toUTC(e.end),t.dataset.type=e.type,t.dataset.duration=e.metadata?.duration?.toString()||"60",t}static extractCalendarEventFromElement(e){return{id:e.dataset.eventId||"",title:e.dataset.title||"",description:e.dataset.description||void 0,start:new Date(e.dataset.start||""),end:new Date(e.dataset.end||""),type:e.dataset.type||"work",allDay:!1,syncStatus:"synced",metadata:{duration:e.dataset.duration}}}},oe=class extends Re{connectedCallback(){this.textContent||(this.textContent=this.dataset.title||"Untitled")}createClone(){let e=this.cloneNode(!0);return e.dataset.eventId=`clone-${this.eventId}`,e.style.pointerEvents="none",e.style.opacity="1",e}applyGridPositioning(e,t,n){let r=`${e} / ${t} / ${e+1} / ${n+1}`;this.style.gridArea=r}static fromCalendarEvent(e){let t=document.createElement("swp-allday-event"),n=K.getInstance(),r=new U(n);return t.dataset.eventId=e.id,t.dataset.title=e.title,t.dataset.start=r.toUTC(e.start),t.dataset.end=r.toUTC(e.end),t.dataset.type=e.type,t.dataset.allday="true",t.textContent=e.title,t}};customElements.define("swp-event",Q);customElements.define("swp-allday-event",oe);var be=class{constructor(e,t){this.mouseDownPosition={x:0,y:0},this.currentMousePosition={x:0,y:0},this.mouseOffset={x:0,y:0},this.currentColumn=null,this.previousColumn=null,this.originalSourceColumn=null,this.isDragStarted=!1,this.dragThreshold=5,this.scrollableContent=null,this.scrollDeltaY=0,this.lastScrollTop=0,this.isScrollCompensating=!1,this.dragAnimationId=null,this.targetY=0,this.currentY=0,this.targetColumn=null,this.eventBus=e,this.positionUtils=t,this.init()}init(){document.body.addEventListener("mousemove",this.handleMouseMove.bind(this)),document.body.addEventListener("mousedown",this.handleMouseDown.bind(this)),document.body.addEventListener("mouseup",this.handleMouseUp.bind(this));let e=document.querySelector("swp-calendar-container");e&&(e.addEventListener("mouseleave",()=>{this.originalElement&&this.isDragStarted&&this.cancelDrag()}),e.addEventListener("mouseenter",t=>{let n=t.target;n.closest("swp-calendar-header")?this.handleHeaderMouseEnter(t):n.closest("swp-day-column")&&this.handleColumnMouseEnter(t)},!0),e.addEventListener("mouseleave",t=>{t.target.closest("swp-calendar-header")&&this.handleHeaderMouseLeave(t)},!0)),B.updateColumnBoundsCache(),window.addEventListener("resize",()=>{B.updateColumnBoundsCache()}),this.eventBus.on("navigation:completed",()=>{B.updateColumnBoundsCache()}),this.eventBus.on(v.GRID_RENDERED,t=>{this.handleGridRendered(t)}),this.eventBus.on("edgescroll:started",()=>{this.isScrollCompensating=!0,this.scrollableContent&&(this.lastScrollTop=this.scrollableContent.scrollTop)}),this.eventBus.on("edgescroll:stopped",()=>{this.isScrollCompensating=!1}),this.eventBus.on("drag:mouseenter-header",()=>{this.scrollDeltaY=0,this.lastScrollTop=0}),this.eventBus.on("drag:mouseenter-column",()=>{this.scrollDeltaY=0,this.lastScrollTop=0})}handleGridRendered(e){this.scrollableContent=document.querySelector("swp-scrollable-content"),this.scrollableContent.addEventListener("scroll",this.handleScroll.bind(this),{passive:!0})}handleMouseDown(e){this.cleanupDragState(),B.updateColumnBoundsCache();let t=e.target;if(t.closest("swp-resize-handle"))return;let n=t;for(;n&&n.tagName!=="SWP-GRID-CONTAINER"&&!(n.tagName==="SWP-EVENT"||n.tagName==="SWP-ALLDAY-EVENT");)if(n=n.parentElement,!n)return;if(n){this.originalElement=n;let r=n.getBoundingClientRect();this.mouseOffset={x:e.clientX-r.left,y:e.clientY-r.top},this.mouseDownPosition={x:e.clientX,y:e.clientY}}}handleMouseMove(e){if(e.buttons===1){if(this.currentMousePosition={x:e.clientX,y:e.clientY},!this.isDragStarted&&this.originalElement&&!this.initializeDrag(this.currentMousePosition))return;this.isDragStarted&&this.originalElement&&this.draggedClone&&(this.continueDrag(this.currentMousePosition),this.detectColumnChange(this.currentMousePosition))}}initializeDrag(e){let t=Math.abs(e.x-this.mouseDownPosition.x),n=Math.abs(e.y-this.mouseDownPosition.y);if(Math.sqrt(t*t+n*n)0&&e.forEach(t=>t.remove())}cancelDrag(){if(!this.originalElement||!this.draggedClone)return;let e=this.draggedClone.getBoundingClientRect(),t=this.originalElement.getBoundingClientRect(),n=t.left-e.left,r=t.top-e.top;this.draggedClone.style.transition="transform 300ms ease-out",this.draggedClone.style.transform=`translate(${n}px, ${r}px)`,setTimeout(()=>{this.cleanupAllClones(),this.originalElement&&(this.originalElement.style.opacity="",this.originalElement.style.cursor=""),this.eventBus.emit("drag:cancelled",{originalElement:this.originalElement,reason:"mouse-left-grid"}),this.cleanupDragState(),this.stopDragAnimation()},300)}calculateSnapPosition(e,t){let n=e-this.mouseOffset.y,r=this.positionUtils.getPositionFromCoordinate(n,t);return Math.max(0,r)}animateDrag(){if(!this.isDragStarted||!this.draggedClone||!this.targetColumn){this.dragAnimationId=null;return}let e=this.targetY-this.currentY,t=e*.3;if(Math.abs(e)>.5){this.currentY+=t;let n={originalElement:this.originalElement,draggedClone:this.draggedClone,mousePosition:this.currentMousePosition,snappedY:this.currentY,columnBounds:this.targetColumn,mouseOffset:this.mouseOffset};this.eventBus.emit("drag:move",n),this.dragAnimationId=requestAnimationFrame(()=>this.animateDrag())}else{this.currentY=this.targetY;let n={originalElement:this.originalElement,draggedClone:this.draggedClone,mousePosition:this.currentMousePosition,snappedY:this.currentY,columnBounds:this.targetColumn,mouseOffset:this.mouseOffset};this.eventBus.emit("drag:move",n),this.dragAnimationId=null}}handleScroll(){if(!this.isDragStarted||!this.draggedClone||!this.scrollableContent||!this.isScrollCompensating)return;let e=this.scrollableContent.scrollTop,t=e-this.lastScrollTop;this.scrollDeltaY+=t,this.lastScrollTop=e,this.continueDrag(this.currentMousePosition)}stopDragAnimation(){this.dragAnimationId!==null&&(cancelAnimationFrame(this.dragAnimationId),this.dragAnimationId=null)}cleanupDragState(){this.previousColumn=null,this.originalElement=null,this.draggedClone=null,this.currentColumn=null,this.originalSourceColumn=null,this.isDragStarted=!1,this.scrollDeltaY=0,this.lastScrollTop=0}detectDropTarget(e){let t=this.draggedClone;for(;t&&t!==document.body;){if(t.tagName==="SWP-ALLDAY-CONTAINER")return"swp-day-header";if(t.tagName==="SWP-DAY-COLUMN")return"swp-day-column";t=t.parentElement}return null}handleHeaderMouseEnter(e){if(!this.isDragStarted||!this.draggedClone)return;let t={x:e.clientX,y:e.clientY},n=B.getColumnBounds(t);if(n){let r=Q.extractCalendarEventFromElement(this.draggedClone),s={targetColumn:n,mousePosition:t,originalElement:this.originalElement,draggedClone:this.draggedClone,calendarEvent:r,replaceClone:i=>{this.draggedClone=i,this.dragAnimationId}};this.eventBus.emit("drag:mouseenter-header",s)}}handleColumnMouseEnter(e){if(!this.isDragStarted||!this.draggedClone||!this.draggedClone.hasAttribute("data-allday"))return;let t={x:e.clientX,y:e.clientY},n=B.getColumnBounds(t);if(!n)return;let r=this.calculateSnapPosition(t.y,n),s=Q.extractCalendarEventFromElement(this.draggedClone),i={targetColumn:n,mousePosition:t,snappedY:r,originalElement:this.originalElement,draggedClone:this.draggedClone,calendarEvent:s,replaceClone:a=>{this.draggedClone=a,this.dragAnimationId,this.stopDragAnimation()}};this.eventBus.emit("drag:mouseenter-column",i)}handleHeaderMouseLeave(e){if(!this.isDragStarted||!this.draggedClone||!this.draggedClone.hasAttribute("data-allday"))return;let t={x:e.clientX,y:e.clientY},n=B.getColumnBounds(t);if(!n)return;let r={targetDate:n.date,mousePosition:t,originalElement:this.originalElement,draggedClone:this.draggedClone};this.eventBus.emit("drag:mouseleave-header",r)}};var xe=class{constructor(e){this.weekDates=e,this.tracks=[]}calculateLayout(e){let t=[];this.tracks=[new Array(this.weekDates.length).fill(!1)];let n=e.filter(r=>this.isEventVisible(r));for(let r of n){let s=this.getEventStartDay(r),i=this.getEventEndDay(r);if(s>0&&i>0){let a=this.findAvailableTrack(s-1,i-1);for(let d=s-1;d<=i-1;d++)this.tracks[a][d]=!0;let c={calenderEvent:r,gridArea:`${a+1} / ${s} / ${a+2} / ${i+1}`,startColumn:s,endColumn:i,row:a+1,columnSpan:i-s+1};t.push(c)}}return t}findAvailableTrack(e,t){for(let n=0;n=0?s+1:0}getEventEndDay(e){let t=this.formatDate(e.end),n=this.weekDates[this.weekDates.length-1],r=t>n?n:t,s=this.weekDates.indexOf(r);return s>=0?s+1:0}isEventVisible(e){if(this.weekDates.length===0)return!1;let t=this.formatDate(e.start),n=this.formatDate(e.end),r=this.weekDates[0],s=this.weekDates[this.weekDates.length-1];return!(ns)}formatDate(e){let t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${r}`}};var Ie=class{constructor(e,t,n){this.layoutEngine=null,this.currentAllDayEvents=[],this.currentWeekDates=[],this.isExpanded=!1,this.actualRowCount=0,this.eventManager=e,this.allDayEventRenderer=t,this.dateService=n,document.documentElement.style.setProperty("--single-row-height",`${ne.EVENT_HEIGHT}px`),this.setupEventListeners()}setupEventListeners(){b.on("drag:mouseenter-header",e=>{let t=e.detail;t.draggedClone.hasAttribute("data-allday")||(console.log("\u{1F504} AllDayManager: Received drag:mouseenter-header",{targetDate:t.targetColumn,originalElementId:t.originalElement?.dataset?.eventId,originalElementTag:t.originalElement?.tagName}),this.handleConvertToAllDay(t))}),b.on("drag:mouseleave-header",e=>{let{originalElement:t,cloneElement:n}=e.detail;console.log("\u{1F6AA} AllDayManager: Received drag:mouseleave-header",{originalElementId:t?.dataset?.eventId})}),b.on("drag:start",e=>{let t=e.detail;t.draggedClone?.hasAttribute("data-allday")&&this.allDayEventRenderer.handleDragStart(t)}),b.on("drag:column-change",e=>{let t=e.detail;t.draggedClone?.hasAttribute("data-allday")&&this.handleColumnChange(t)}),b.on("drag:end",e=>{let t=e.detail;if(console.log("\u{1F3AF} AllDayManager: drag:end received",{target:t.target,originalElementTag:t.originalElement?.tagName,hasAllDayAttribute:t.originalElement?.hasAttribute("data-allday"),eventId:t.originalElement?.dataset.eventId}),t.target==="swp-day-header"&&t.originalElement?.hasAttribute("data-allday")){console.log("\u2705 AllDayManager: Handling all-day \u2192 all-day drop"),this.handleDragEnd(t);return}if(t.target==="swp-day-header"&&!t.originalElement?.hasAttribute("data-allday")){console.log("\u{1F504} AllDayManager: Timed \u2192 all-day conversion on drop"),this.handleTimedToAllDayDrop(t);return}if(t.target==="swp-day-column"&&t.originalElement?.hasAttribute("data-allday")){let n=t.originalElement.dataset.eventId;console.log("\u{1F504} AllDayManager: All-day \u2192 timed conversion",{eventId:n}),this.fadeOutAndRemove(t.originalElement);let r=this.currentAllDayEvents.filter(i=>i.id!==n),s=this.calculateAllDayEventsLayout(r,this.currentWeekDates);this.allDayEventRenderer.renderAllDayEventsForPeriod(s),this.checkAndAnimateAllDayHeight()}}),b.on("drag:cancelled",e=>{let{draggedElement:t,reason:n}=e.detail;console.log("\u{1F6AB} AllDayManager: Drag cancelled",{eventId:t?.dataset?.eventId,reason:n})}),b.on("header:ready",async e=>{let t=e.detail,n=new Date(t.headerElements.at(0).date),r=new Date(t.headerElements.at(-1).date),i=(await this.eventManager.getEventsForPeriod(n,r)).filter(c=>c.allDay),a=this.calculateAllDayEventsLayout(i,t.headerElements);this.allDayEventRenderer.renderAllDayEventsForPeriod(a),this.checkAndAnimateAllDayHeight()}),b.on(v.VIEW_CHANGED,e=>{this.allDayEventRenderer.handleViewChanged(e)})}getAllDayContainer(){return document.querySelector("swp-calendar-header swp-allday-container")}getCalendarHeader(){return document.querySelector("swp-calendar-header")}getHeaderSpacer(){return document.querySelector("swp-header-spacer")}getMaxRowFromDOM(){let e=this.getAllDayContainer();if(!e)return 0;let t=0;return e.querySelectorAll("swp-allday-event:not(.max-event-indicator):not([data-removing])").forEach(r=>{let i=parseInt(r.style.gridRow)||1;t=Math.max(t,i)}),t}getGridAreaFromDOM(e){let t=this.getAllDayContainer();return t&&t.querySelector(`[data-event-id="${e}"]`)?.style.gridArea||null}countEventsInColumnFromDOM(e){let t=this.getAllDayContainer();if(!t)return 0;let n=0;return t.querySelectorAll("swp-allday-event:not(.max-event-indicator)").forEach(s=>{let c=s.style.gridColumn.match(/(\d+)\s*\/\s*(\d+)/);if(c){let d=parseInt(c[1]),g=parseInt(c[2])-1;d<=e&&g>=e&&n++}}),n}calculateAllDayHeight(e){let t=document.documentElement,n=e*ne.SINGLE_ROW_HEIGHT,r=t.style.getPropertyValue("--all-day-row-height")||"0px",s=parseInt(r)||0,i=n-s;return{targetHeight:n,currentHeight:s,heightDifference:i}}checkAndAnimateAllDayHeight(){let e=this.getMaxRowFromDOM();console.log("\u{1F4CA} AllDayManager: Height calculation",{maxRows:e,isExpanded:this.isExpanded}),this.actualRowCount=e;let t=e;e>ne.MAX_COLLAPSED_ROWS?(this.updateChevronButton(!0),this.isExpanded?this.clearOverflowIndicators():(t=ne.MAX_COLLAPSED_ROWS,this.updateOverflowIndicators())):(this.updateChevronButton(!1),this.clearOverflowIndicators()),console.log("\u{1F3AC} AllDayManager: Will animate to",{displayRows:t,maxRows:e,willAnimate:t!==this.actualRowCount}),console.log(`\u{1F3AF} AllDayManager: Animating to ${t} rows`),this.animateToRows(t)}animateToRows(e){let{targetHeight:t,currentHeight:n,heightDifference:r}=this.calculateAllDayHeight(e);if(t===n)return;console.log(`\u{1F3AC} All-day height animation: ${n}px \u2192 ${t}px (${Math.ceil(n/ne.SINGLE_ROW_HEIGHT)} \u2192 ${e} rows)`);let s=this.getCalendarHeader(),i=this.getHeaderSpacer(),a=this.getAllDayContainer();if(!s||!a)return;let c=parseFloat(getComputedStyle(s).height),d=c+r,g=[s.animate([{height:`${c}px`},{height:`${d}px`}],{duration:150,easing:"ease-out",fill:"forwards"})];if(i){let E=document.documentElement.style.getPropertyValue("--header-height"),m=parseInt(E),u=m+n,D=m+t;g.push(i.animate([{height:`${u}px`},{height:`${D}px`}],{duration:150,easing:"ease-out"}))}Promise.all(g.map(w=>w.finished)).then(()=>{document.documentElement.style.setProperty("--all-day-row-height",`${t}px`),b.emit("header:height-changed")})}calculateAllDayEventsLayout(e,t){return this.currentAllDayEvents=e,this.currentWeekDates=t,new xe(t.map(r=>r.date)).calculateLayout(e)}handleConvertToAllDay(e){let t=this.getAllDayContainer();if(!t)return;let n=oe.fromCalendarEvent(e.calendarEvent);n.style.gridRow="1",n.style.gridColumn=e.targetColumn.index.toString(),e.draggedClone.remove(),e.replaceClone(n),t.appendChild(n),B.updateColumnBoundsCache(),this.checkAndAnimateAllDayHeight()}handleColumnChange(e){if(!this.getAllDayContainer())return;let n=B.getColumnBounds(e.mousePosition);if(n==null||!e.draggedClone)return;let r=window.getComputedStyle(e.draggedClone),s=parseInt(r.gridColumnStart)||n.index,a=(parseInt(r.gridColumnEnd)||n.index+1)-s,c=n.index,d=c+a;e.draggedClone.style.gridColumn=`${c} / ${d}`}fadeOutAndRemove(e){console.log("\u{1F5D1}\uFE0F AllDayManager: About to remove all-day event",{eventId:e.dataset.eventId,element:e.tagName}),e.setAttribute("data-removing","true"),e.style.transition="opacity 0.3s ease-out",e.style.opacity="0",setTimeout(()=>{e.remove(),console.log("\u2705 AllDayManager: All-day event removed from DOM")},300)}async handleTimedToAllDayDrop(e){if(!e.draggedClone||!e.finalPosition.column)return;let t=e.draggedClone,n=t.eventId.replace("clone-",""),r=e.finalPosition.column.date;console.log("\u{1F504} AllDayManager: Converting timed event to all-day",{eventId:n,targetDate:r});let s=new Date(r);s.setHours(t.start.getHours(),t.start.getMinutes(),0,0);let i=new Date(r);i.setHours(t.end.getHours(),t.end.getMinutes(),0,0),await this.eventManager.updateEvent(n,{start:s,end:i,allDay:!0}),this.fadeOutAndRemove(e.originalElement);let a={id:n,title:t.title,start:s,end:i,type:t.type,allDay:!0,syncStatus:"synced"},c=[...this.currentAllDayEvents,a],d=this.calculateAllDayEventsLayout(c,this.currentWeekDates);this.allDayEventRenderer.renderAllDayEventsForPeriod(d),this.checkAndAnimateAllDayHeight()}async handleDragEnd(e){if(!e.draggedClone||!e.finalPosition.column)return;let t=e.draggedClone,n=t.eventId.replace("clone-",""),r=e.finalPosition.column.date,s=this.dateService.differenceInCalendarDays(t.end,t.start),i=new Date(r);i.setHours(t.start.getHours(),t.start.getMinutes(),0,0);let a=new Date(r);a.setDate(a.getDate()+s),a.setHours(t.end.getHours(),t.end.getMinutes(),0,0),await this.eventManager.updateEvent(n,{start:i,end:a,allDay:!0}),this.fadeOutAndRemove(e.originalElement);let c=this.currentAllDayEvents.map(g=>g.id===n?{...g,start:i,end:a}:g),d=this.calculateAllDayEventsLayout(c,this.currentWeekDates);this.allDayEventRenderer.renderAllDayEventsForPeriod(d),this.checkAndAnimateAllDayHeight()}updateChevronButton(e){let t=this.getHeaderSpacer();if(!t)return;let n=t.querySelector(".allday-chevron");e&&!n?(n=document.createElement("button"),n.className="allday-chevron collapsed",n.innerHTML=` + + + + `,n.onclick=()=>this.toggleExpanded(),t.appendChild(n)):!e&&n?n.remove():n&&(n.classList.toggle("collapsed",!this.isExpanded),n.classList.toggle("expanded",this.isExpanded))}toggleExpanded(){this.isExpanded=!this.isExpanded,this.checkAndAnimateAllDayHeight(),document.querySelectorAll("swp-allday-container swp-allday-event.max-event-overflow-hide, swp-allday-container swp-allday-event.max-event-overflow-show").forEach(t=>{this.isExpanded?(t.classList.remove("max-event-overflow-hide"),t.classList.add("max-event-overflow-show")):(t.classList.remove("max-event-overflow-show"),t.classList.add("max-event-overflow-hide"))})}countEventsInColumn(e){return this.countEventsInColumnFromDOM(e.index)}updateOverflowIndicators(){let e=this.getAllDayContainer();if(!e)return;B.getColumns().forEach(n=>{let s=this.countEventsInColumn(n)-ne.MAX_COLLAPSED_ROWS;if(s>0){let i=e.querySelector(`.max-event-indicator[data-column="${n.index}"]`);if(i)i.innerHTML=`+${s+1} more`;else{let a=document.createElement("swp-allday-event");a.className="max-event-indicator",a.setAttribute("data-column",n.index.toString()),a.style.gridRow=ne.MAX_COLLAPSED_ROWS.toString(),a.style.gridColumn=n.index.toString(),a.innerHTML=`+${s+1} more`,a.onclick=c=>{c.stopPropagation(),this.toggleExpanded()},e.appendChild(a)}}})}clearOverflowIndicators(){let e=this.getAllDayContainer();e&&e.querySelectorAll(".max-event-indicator").forEach(t=>{t.remove()})}};var Oe=class{constructor(e,t){this.config=e,this.positionUtils=t,this.isResizing=!1,this.targetEl=null,this.startY=0,this.startDurationMin=0,this.animationId=null,this.currentHeight=0,this.targetHeight=0,this.pointerCaptured=!1,this.ANIMATION_SPEED=.35,this.Z_INDEX_RESIZING="1000",this.EVENT_REFRESH_THRESHOLD=.5,this.onMouseOver=r=>{let i=r.target.closest("swp-event");if(i&&!this.isResizing&&!i.querySelector(":scope > swp-resize-handle")){let a=this.createResizeHandle();i.appendChild(a)}},this.onPointerDown=r=>{let s=r.target.closest("swp-resize-handle");if(!s)return;let i=s.parentElement;this.startResizing(i,r)},this.onPointerMove=r=>{!this.isResizing||!this.targetEl||this.updateResizeHeight(r.clientY)},this.animate=()=>{if(!this.isResizing||!this.targetEl){this.animationId=null;return}let r=this.targetHeight-this.currentHeight;Math.abs(r)>this.EVENT_REFRESH_THRESHOLD?(this.currentHeight+=r*this.ANIMATION_SPEED,this.targetEl.updateHeight?.(this.currentHeight),this.animationId=requestAnimationFrame(this.animate)):this.finalizeAnimation()},this.onPointerUp=r=>{!this.isResizing||!this.targetEl||(this.cleanupAnimation(),this.snapToGrid(),this.emitResizeEndEvent(),this.cleanupResizing(r))};let n=this.config.gridSettings;this.snapMin=n.snapInterval,this.minDurationMin=this.snapMin}initialize(){this.attachGlobalListeners()}destroy(){this.removeEventListeners()}removeEventListeners(){let e=document.querySelector("swp-calendar-container");e&&e.removeEventListener("mouseover",this.onMouseOver,!0),document.removeEventListener("pointerdown",this.onPointerDown,!0),document.removeEventListener("pointermove",this.onPointerMove,!0),document.removeEventListener("pointerup",this.onPointerUp,!0)}createResizeHandle(){let e=document.createElement("swp-resize-handle");return e.setAttribute("aria-label","Resize event"),e.setAttribute("role","separator"),e}attachGlobalListeners(){let e=document.querySelector("swp-calendar-container");e&&e.addEventListener("mouseover",this.onMouseOver,!0),document.addEventListener("pointerdown",this.onPointerDown,!0),document.addEventListener("pointermove",this.onPointerMove,!0),document.addEventListener("pointerup",this.onPointerUp,!0)}startResizing(e,t){this.targetEl=e,this.isResizing=!0,this.startY=t.clientY;let n=e.offsetHeight;this.startDurationMin=Math.max(this.minDurationMin,Math.round(this.positionUtils.pixelsToMinutes(n))),this.setZIndexForResizing(e),this.capturePointer(t),document.documentElement.classList.add("swp--resizing"),t.preventDefault()}setZIndexForResizing(e){let t=e.closest("swp-event-group")??e;this.prevZ=t.style.zIndex,t.style.zIndex=this.Z_INDEX_RESIZING}capturePointer(e){try{e.target.setPointerCapture?.(e.pointerId),this.pointerCaptured=!0}catch(t){console.warn("Pointer capture failed:",t)}}updateResizeHeight(e){let t=e-this.startY,r=this.positionUtils.minutesToPixels(this.startDurationMin)+t,s=this.positionUtils.minutesToPixels(this.minDurationMin);this.targetHeight=Math.max(s,r),this.animationId==null&&(this.currentHeight=this.targetEl?.offsetHeight,this.animate())}finalizeAnimation(){this.targetEl&&(this.currentHeight=this.targetHeight,this.targetEl.updateHeight?.(this.currentHeight),this.animationId=null)}cleanupAnimation(){this.animationId!=null&&(cancelAnimationFrame(this.animationId),this.animationId=null)}snapToGrid(){if(!this.targetEl)return;let e=this.targetEl.offsetHeight,t=this.positionUtils.minutesToPixels(this.snapMin),n=Math.round(e/t)*t,r=this.positionUtils.minutesToPixels(this.minDurationMin),s=Math.max(r,n)-3;this.targetEl.updateHeight?.(s)}emitResizeEndEvent(){if(!this.targetEl)return;let t={eventId:this.targetEl.dataset.eventId||"",element:this.targetEl,finalHeight:this.targetEl.offsetHeight};b.emit("resize:end",t)}cleanupResizing(e){this.restoreZIndex(),this.releasePointer(e),this.isResizing=!1,this.targetEl=null,document.documentElement.classList.remove("swp--resizing")}restoreZIndex(){if(!this.targetEl||this.prevZ===void 0)return;let e=this.targetEl.closest("swp-event-group")??this.targetEl;e.style.zIndex=this.prevZ,this.prevZ=void 0}releasePointer(e){if(this.pointerCaptured)try{e.target.releasePointerCapture?.(e.pointerId),this.pointerCaptured=!1}catch(t){console.warn("Pointer release failed:",t)}}};var Le=class{constructor(e){this.eventBus=e,this.scrollableContent=null,this.timeGrid=null,this.draggedClone=null,this.scrollRAF=null,this.mouseY=0,this.isDragging=!1,this.isScrolling=!1,this.lastTs=0,this.rect=null,this.initialScrollTop=0,this.scrollListener=null,this.OUTER_ZONE=100,this.INNER_ZONE=50,this.SLOW_SPEED_PXS=140,this.FAST_SPEED_PXS=640,this.init()}init(){setTimeout(()=>{this.scrollableContent=document.querySelector("swp-scrollable-content"),this.timeGrid=document.querySelector("swp-time-grid"),this.scrollableContent&&(this.scrollableContent.style.scrollBehavior="auto",this.scrollListener=this.handleScroll.bind(this),this.scrollableContent.addEventListener("scroll",this.scrollListener,{passive:!0}))},100),document.body.addEventListener("mousemove",e=>{this.isDragging&&(this.mouseY=e.clientY)}),this.subscribeToEvents()}subscribeToEvents(){this.eventBus.on("drag:start",e=>{let t=e.detail;this.draggedClone=t.draggedClone,this.startDrag()}),this.eventBus.on("drag:end",()=>this.stopDrag()),this.eventBus.on("drag:cancelled",()=>this.stopDrag()),this.eventBus.on("drag:mouseenter-header",()=>{console.log("\u{1F504} EdgeScrollManager: Event converting to all-day - stopping scroll"),this.stopDrag()}),this.eventBus.on("drag:mouseenter-column",()=>{this.startDrag()})}startDrag(){console.log("\u{1F3AC} EdgeScrollManager: Starting drag"),this.isDragging=!0,this.isScrolling=!1,this.lastTs=performance.now(),this.scrollableContent&&(this.initialScrollTop=this.scrollableContent.scrollTop),this.scrollRAF===null&&(this.scrollRAF=requestAnimationFrame(e=>this.scrollTick(e)))}stopDrag(){this.isDragging=!1,this.isScrolling&&(this.isScrolling=!1,console.log("\u{1F6D1} EdgeScrollManager: Edge-scroll stopped (drag ended)"),this.eventBus.emit("edgescroll:stopped",{})),this.scrollRAF!==null&&(cancelAnimationFrame(this.scrollRAF),this.scrollRAF=null),this.rect=null,this.lastTs=0,this.initialScrollTop=0}handleScroll(){if(!this.isDragging||!this.scrollableContent)return;let e=this.scrollableContent.scrollTop,t=Math.abs(e-this.initialScrollTop);t>1&&!this.isScrolling&&(this.isScrolling=!0,console.log("\u{1F4BE} EdgeScrollManager: Edge-scroll started (actual scroll detected)",{initialScrollTop:this.initialScrollTop,currentScrollTop:e,scrollDelta:t}),this.eventBus.emit("edgescroll:started",{}))}scrollTick(e){let t=this.lastTs?(e-this.lastTs)/1e3:0;if(this.lastTs=e,!this.scrollableContent){this.stopDrag();return}this.rect||(this.rect=this.scrollableContent.getBoundingClientRect());let n=0;if(this.isDragging){let r=this.mouseY-this.rect.top,s=this.rect.bottom-this.mouseY;r=g&&n>0;w||E?(this.isScrolling&&(this.isScrolling=!1,this.initialScrollTop=this.scrollableContent.scrollTop,console.log("\u{1F6D1} EdgeScrollManager: Edge-scroll stopped (reached boundary)"),this.eventBus.emit("edgescroll:stopped",{})),this.isDragging&&(this.scrollRAF=requestAnimationFrame(m=>this.scrollTick(m)))):(this.scrollableContent.scrollTop+=n*t,this.rect=null,this.scrollRAF=requestAnimationFrame(m=>this.scrollTick(m)))}else this.isScrolling&&(this.isScrolling=!1,this.initialScrollTop=this.scrollableContent.scrollTop,console.log("\u{1F6D1} EdgeScrollManager: Edge-scroll stopped (mouse left edge)"),this.eventBus.emit("edgescroll:stopped",{})),this.isDragging?this.scrollRAF=requestAnimationFrame(r=>this.scrollTick(r)):this.stopDrag()}};var $e=class{constructor(e,t){this.headerRenderer=e,this.config=t,this.handleDragMouseEnterHeader=this.handleDragMouseEnterHeader.bind(this),this.handleDragMouseLeaveHeader=this.handleDragMouseLeaveHeader.bind(this),this.setupNavigationListener()}setupHeaderDragListeners(){console.log("\u{1F3AF} HeaderManager: Setting up drag event listeners"),b.on("drag:mouseenter-header",this.handleDragMouseEnterHeader),b.on("drag:mouseleave-header",this.handleDragMouseLeaveHeader),console.log("\u2705 HeaderManager: Drag event listeners attached")}handleDragMouseEnterHeader(e){let{targetColumn:t,mousePosition:n,originalElement:r,draggedClone:s}=e.detail;console.log("\u{1F3AF} HeaderManager: Received drag:mouseenter-header",{targetDate:t,originalElement:!!r,cloneElement:!!s})}handleDragMouseLeaveHeader(e){let{targetDate:t,mousePosition:n,originalElement:r,draggedClone:s}=e.detail;console.log("\u{1F6AA} HeaderManager: Received drag:mouseleave-header",{targetDate:t,originalElement:!!r,cloneElement:!!s})}setupNavigationListener(){b.on(v.NAVIGATION_COMPLETED,e=>{let{currentDate:t}=e.detail;this.updateHeader(t)}),b.on(v.DATE_CHANGED,e=>{let{currentDate:t}=e.detail;this.updateHeader(t)}),b.on("workweek:header-update",e=>{let{currentDate:t}=e.detail;this.updateHeader(t)})}updateHeader(e){console.log("\u{1F3AF} HeaderManager.updateHeader called",{currentDate:e,rendererType:this.headerRenderer.constructor.name});let t=document.querySelector("swp-calendar-header");if(!t){console.warn("\u274C HeaderManager: No calendar header found!");return}t.innerHTML="";let n={currentWeek:e,config:this.config};this.headerRenderer.render(t,n),this.setupHeaderDragListeners();let r={headerElements:B.getHeaderColumns()};b.emit("header:ready",r)}};var He=class{constructor(e,t){this.buttonListeners=new Map,this.eventBus=e,this.config=t,this.setupButtonListeners()}setupButtonListeners(){document.querySelectorAll("swp-preset-button[data-workweek]").forEach(t=>{let n=r=>{r.preventDefault();let s=t.getAttribute("data-workweek");s&&this.changePreset(s)};t.addEventListener("click",n),this.buttonListeners.set(t,n)}),this.updateButtonStates()}changePreset(e){if(!me[e]){console.warn(`Invalid preset ID "${e}"`);return}if(e===this.config.currentWorkWeek)return;let t=this.config.currentWorkWeek;this.config.currentWorkWeek=e;let n=me[e];this.updateButtonStates(),this.eventBus.emit(v.WORKWEEK_CHANGED,{workWeekId:e,previousWorkWeekId:t,settings:n})}updateButtonStates(){document.querySelectorAll("swp-preset-button[data-workweek]").forEach(t=>{t.getAttribute("data-workweek")===this.config.currentWorkWeek?t.setAttribute("data-active","true"):t.removeAttribute("data-active")})}};var Be=class{constructor(e,t){this.indexedDB=e,this.queue=t}async loadEvents(){return this.indexedDB.isInitialized()||(await this.indexedDB.initialize(),await this.indexedDB.seedIfEmpty()),await this.indexedDB.getAllEvents()}async createEvent(e,t="local"){let n=this.generateEventId(),s={...e,id:n,syncStatus:t==="local"?"pending":"synced"};return await this.indexedDB.saveEvent(s),t==="local"&&await this.queue.enqueue({type:"create",eventId:n,data:s,timestamp:Date.now(),retryCount:0}),s}async updateEvent(e,t,n="local"){let r=await this.indexedDB.getEvent(e);if(!r)throw new Error(`Event with ID ${e} not found`);let i={...r,...t,id:e,syncStatus:n==="local"?"pending":"synced"};return await this.indexedDB.saveEvent(i),n==="local"&&await this.queue.enqueue({type:"update",eventId:e,data:t,timestamp:Date.now(),retryCount:0}),i}async deleteEvent(e,t="local"){if(!await this.indexedDB.getEvent(e))throw new Error(`Event with ID ${e} not found`);t==="local"&&await this.queue.enqueue({type:"delete",eventId:e,data:{},timestamp:Date.now(),retryCount:0}),await this.indexedDB.deleteEvent(e)}generateEventId(){let e=Date.now(),t=Math.random().toString(36).substring(2,9);return`${e}-${t}`}};var We=class{constructor(e){this.apiEndpoint=e.apiEndpoint}async sendCreate(e){throw new Error("ApiEventRepository.sendCreate not implemented yet")}async sendUpdate(e,t){throw new Error("ApiEventRepository.sendUpdate not implemented yet")}async sendDelete(e){throw new Error("ApiEventRepository.sendDelete not implemented yet")}async fetchAll(){throw new Error("ApiEventRepository.fetchAll not implemented yet")}async initializeSignalR(){throw new Error("SignalR not implemented yet")}};var J=class o{constructor(){this.db=null,this.initialized=!1}async initialize(){return new Promise((e,t)=>{let n=indexedDB.open(o.DB_NAME,o.DB_VERSION);n.onerror=()=>{t(new Error(`Failed to open IndexedDB: ${n.error}`))},n.onsuccess=()=>{this.db=n.result,this.initialized=!0,e()},n.onupgradeneeded=r=>{let s=r.target.result;if(!s.objectStoreNames.contains(o.EVENTS_STORE)){let i=s.createObjectStore(o.EVENTS_STORE,{keyPath:"id"});i.createIndex("start","start",{unique:!1}),i.createIndex("end","end",{unique:!1}),i.createIndex("syncStatus","syncStatus",{unique:!1})}s.objectStoreNames.contains(o.QUEUE_STORE)||s.createObjectStore(o.QUEUE_STORE,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1}),s.objectStoreNames.contains(o.SYNC_STATE_STORE)||s.createObjectStore(o.SYNC_STATE_STORE,{keyPath:"key"})}})}isInitialized(){return this.initialized}ensureDB(){if(!this.db)throw new Error("IndexedDB not initialized. Call initialize() first.");return this.db}async getEvent(e){let t=this.ensureDB();return new Promise((n,r)=>{let a=t.transaction([o.EVENTS_STORE],"readonly").objectStore(o.EVENTS_STORE).get(e);a.onsuccess=()=>{let c=a.result;n(c?this.deserializeEvent(c):null)},a.onerror=()=>{r(new Error(`Failed to get event ${e}: ${a.error}`))}})}async getAllEvents(){let e=this.ensureDB();return new Promise((t,n)=>{let i=e.transaction([o.EVENTS_STORE],"readonly").objectStore(o.EVENTS_STORE).getAll();i.onsuccess=()=>{let a=i.result;t(a.map(c=>this.deserializeEvent(c)))},i.onerror=()=>{n(new Error(`Failed to get all events: ${i.error}`))}})}async saveEvent(e){let t=this.ensureDB(),n=this.serializeEvent(e);return new Promise((r,s)=>{let c=t.transaction([o.EVENTS_STORE],"readwrite").objectStore(o.EVENTS_STORE).put(n);c.onsuccess=()=>{r()},c.onerror=()=>{s(new Error(`Failed to save event ${e.id}: ${c.error}`))}})}async deleteEvent(e){let t=this.ensureDB();return new Promise((n,r)=>{let a=t.transaction([o.EVENTS_STORE],"readwrite").objectStore(o.EVENTS_STORE).delete(e);a.onsuccess=()=>{n()},a.onerror=()=>{r(new Error(`Failed to delete event ${e}: ${a.error}`))}})}async addToQueue(e){let t=this.ensureDB(),n={...e,id:`${e.type}-${e.eventId}-${Date.now()}`};return new Promise((r,s)=>{let c=t.transaction([o.QUEUE_STORE],"readwrite").objectStore(o.QUEUE_STORE).put(n);c.onsuccess=()=>{r()},c.onerror=()=>{s(new Error(`Failed to add to queue: ${c.error}`))}})}async getQueue(){let e=this.ensureDB();return new Promise((t,n)=>{let a=e.transaction([o.QUEUE_STORE],"readonly").objectStore(o.QUEUE_STORE).index("timestamp").getAll();a.onsuccess=()=>{t(a.result)},a.onerror=()=>{n(new Error(`Failed to get queue: ${a.error}`))}})}async removeFromQueue(e){let t=this.ensureDB();return new Promise((n,r)=>{let a=t.transaction([o.QUEUE_STORE],"readwrite").objectStore(o.QUEUE_STORE).delete(e);a.onsuccess=()=>{n()},a.onerror=()=>{r(new Error(`Failed to remove from queue: ${a.error}`))}})}async clearQueue(){let e=this.ensureDB();return new Promise((t,n)=>{let i=e.transaction([o.QUEUE_STORE],"readwrite").objectStore(o.QUEUE_STORE).clear();i.onsuccess=()=>{t()},i.onerror=()=>{n(new Error(`Failed to clear queue: ${i.error}`))}})}async setSyncState(e,t){let n=this.ensureDB();return new Promise((r,s)=>{let c=n.transaction([o.SYNC_STATE_STORE],"readwrite").objectStore(o.SYNC_STATE_STORE).put({key:e,value:t});c.onsuccess=()=>{r()},c.onerror=()=>{s(new Error(`Failed to set sync state ${e}: ${c.error}`))}})}async getSyncState(e){let t=this.ensureDB();return new Promise((n,r)=>{let a=t.transaction([o.SYNC_STATE_STORE],"readonly").objectStore(o.SYNC_STATE_STORE).get(e);a.onsuccess=()=>{let c=a.result;n(c?c.value:null)},a.onerror=()=>{r(new Error(`Failed to get sync state ${e}: ${a.error}`))}})}serializeEvent(e){return{...e,start:e.start instanceof Date?e.start.toISOString():e.start,end:e.end instanceof Date?e.end.toISOString():e.end}}deserializeEvent(e){return{...e,start:typeof e.start=="string"?new Date(e.start):e.start,end:typeof e.end=="string"?new Date(e.end):e.end}}close(){this.db&&(this.db.close(),this.db=null)}static async deleteDatabase(){return new Promise((e,t)=>{let n=indexedDB.deleteDatabase(o.DB_NAME);n.onsuccess=()=>{e()},n.onerror=()=>{t(new Error(`Failed to delete database: ${n.error}`))}})}async seedIfEmpty(e="data/mock-events.json"){try{let t=await this.getAllEvents();if(t.length>0){console.log(`IndexedDB already has ${t.length} events - skipping seed`);return}if(console.log("IndexedDB is empty - seeding with mock data"),!navigator.onLine){console.warn("Offline and IndexedDB empty - starting with no events");return}let n=await fetch(e);if(!n.ok)throw new Error(`Failed to fetch mock events: ${n.statusText}`);let r=await n.json();for(let s of r){let i={...s,start:new Date(s.start),end:new Date(s.end),allDay:s.allDay||!1,syncStatus:"synced"};await this.saveEvent(i)}console.log(`Seeded IndexedDB with ${r.length} mock events`)}catch(t){console.error("Failed to seed IndexedDB:",t)}}};J.DB_NAME="CalendarDB";J.DB_VERSION=1;J.EVENTS_STORE="events";J.QUEUE_STORE="operationQueue";J.SYNC_STATE_STORE="syncState";var Pe=class{constructor(e){this.indexedDB=e}async enqueue(e){await this.indexedDB.addToQueue(e)}async peek(){let e=await this.indexedDB.getQueue();return e.length>0?e[0]:null}async getAll(){return await this.indexedDB.getQueue()}async remove(e){await this.indexedDB.removeFromQueue(e)}async dequeue(){let e=await this.peek();return e&&await this.remove(e.id),e}async clear(){await this.indexedDB.clearQueue()}async size(){return(await this.getAll()).length}async isEmpty(){return await this.size()===0}async getOperationsForEvent(e){return(await this.getAll()).filter(n=>n.eventId===e)}async removeOperationsForEvent(e){let t=await this.getOperationsForEvent(e);for(let n of t)await this.remove(n.id)}async incrementRetryCount(e){let n=(await this.getAll()).find(r=>r.id===e);n&&(n.retryCount++,await this.remove(e),await this.enqueue(n))}};var Ne=class{constructor(e,t,n,r){this.isOnline=navigator.onLine,this.isSyncing=!1,this.syncInterval=5e3,this.maxRetries=5,this.intervalId=null,this.eventBus=e,this.queue=t,this.indexedDB=n,this.apiRepository=r,this.setupNetworkListeners(),this.startSync(),console.log("SyncManager initialized and started")}setupNetworkListeners(){window.addEventListener("online",()=>{this.isOnline=!0,this.eventBus.emit(v.OFFLINE_MODE_CHANGED,{isOnline:!0}),console.log("SyncManager: Network online - starting sync"),this.startSync()}),window.addEventListener("offline",()=>{this.isOnline=!1,this.eventBus.emit(v.OFFLINE_MODE_CHANGED,{isOnline:!1}),console.log("SyncManager: Network offline - pausing sync"),this.stopSync()})}startSync(){this.intervalId||(console.log("SyncManager: Starting background sync"),this.processQueue(),this.intervalId=window.setInterval(()=>{this.processQueue()},this.syncInterval))}stopSync(){this.intervalId&&(window.clearInterval(this.intervalId),this.intervalId=null,console.log("SyncManager: Stopped background sync"))}async processQueue(){if(this.isOnline&&!this.isSyncing&&!await this.queue.isEmpty()){this.isSyncing=!0;try{let e=await this.queue.getAll();this.eventBus.emit(v.SYNC_STARTED,{operationCount:e.length});for(let t of e)await this.processOperation(t);this.eventBus.emit(v.SYNC_COMPLETED,{operationCount:e.length})}catch(e){console.error("SyncManager: Queue processing error:",e),this.eventBus.emit(v.SYNC_FAILED,{error:e instanceof Error?e.message:"Unknown error"})}finally{this.isSyncing=!1}}}async processOperation(e){if(e.retryCount>=this.maxRetries){console.error(`SyncManager: Max retries exceeded for operation ${e.id}`,e),await this.queue.remove(e.id),await this.markEventAsError(e.eventId);return}try{switch(e.type){case"create":await this.apiRepository.sendCreate(e.data);break;case"update":await this.apiRepository.sendUpdate(e.eventId,e.data);break;case"delete":await this.apiRepository.sendDelete(e.eventId);break;default:console.error(`SyncManager: Unknown operation type ${e.type}`),await this.queue.remove(e.id);return}await this.queue.remove(e.id),await this.markEventAsSynced(e.eventId),console.log(`SyncManager: Successfully synced operation ${e.id}`)}catch(t){console.error(`SyncManager: Failed to sync operation ${e.id}:`,t),await this.queue.incrementRetryCount(e.id);let n=this.calculateBackoff(e.retryCount+1);this.eventBus.emit(v.SYNC_RETRY,{operationId:e.id,retryCount:e.retryCount+1,nextRetryIn:n})}}async markEventAsSynced(e){try{let t=await this.indexedDB.getEvent(e);t&&(t.syncStatus="synced",await this.indexedDB.saveEvent(t))}catch(t){console.error(`SyncManager: Failed to mark event ${e} as synced:`,t)}}async markEventAsError(e){try{let t=await this.indexedDB.getEvent(e);t&&(t.syncStatus="error",await this.indexedDB.saveEvent(t))}catch(t){console.error(`SyncManager: Failed to mark event ${e} as error:`,t)}}calculateBackoff(e){let n=Math.pow(2,e)*1e3;return Math.min(n,6e4)}async triggerManualSync(){console.log("SyncManager: Manual sync triggered"),await this.processQueue()}getSyncStatus(){return{isOnline:this.isOnline,isSyncing:this.isSyncing,isRunning:this.intervalId!==null}}destroy(){this.stopSync()}};var Fe=class{render(e,t){let{currentWeek:n,config:r}=t,s=document.createElement("swp-allday-container");e.appendChild(s);let i=r.timeFormatConfig.timezone,a=r.timeFormatConfig.locale;this.dateService=new U(r);let c=r.getWorkWeekSettings(),d=this.dateService.getWorkWeekDates(n,c.workDays),g=r.dateViewSettings.weekDays;d.slice(0,g).forEach((E,m)=>{let u=document.createElement("swp-day-header");this.dateService.isSameDay(E,new Date)&&(u.dataset.today="true");let D=this.dateService.getDayName(E,"long",a).toUpperCase();u.innerHTML=` + ${D} + ${E.getDate()} + `,u.dataset.date=this.dateService.formatISODate(E),e.appendChild(u)})}};var _e=class{constructor(e,t){this.dateService=e,this.workHoursManager=t}render(e,t){let{currentWeek:n,config:r}=t,s=r.getWorkWeekSettings(),i=this.dateService.getWorkWeekDates(n,s.workDays),a=r.dateViewSettings;i.slice(0,a.weekDays).forEach(d=>{let g=document.createElement("swp-day-column");g.dataset.date=this.dateService.formatISODate(d),this.applyWorkHoursToColumn(g,d);let w=document.createElement("swp-events-layer");g.appendChild(w),e.appendChild(g)})}applyWorkHoursToColumn(e,t){let n=this.workHoursManager.getWorkHoursForDate(t);if(n==="off")e.dataset.workHours="off";else{let r=this.workHoursManager.calculateNonWorkHoursStyle(n);r&&(e.style.setProperty("--before-work-height",`${r.beforeWorkHeight}px`),e.style.setProperty("--after-work-top",`${r.afterWorkTop}px`))}}};var Ye=class{constructor(e,t,n,r,s){this.draggedClone=null,this.originalEvent=null,this.dateService=e,this.stackManager=t,this.layoutCoordinator=n,this.config=r,this.positionUtils=s}applyDragStyling(e){e.classList.add("dragging"),e.style.removeProperty("margin-left")}handleDragStart(e){if(this.originalEvent=e.originalElement,this.draggedClone=e.draggedClone,this.draggedClone&&e.columnBounds){this.applyDragStyling(this.draggedClone);let t=e.columnBounds.element.querySelector("swp-events-layer");if(t){t.appendChild(this.draggedClone);let n=this.originalEvent.getBoundingClientRect(),r=e.columnBounds.boundingClientRect,s=n.top-r.top;this.draggedClone.style.top=`${s}px`}}this.originalEvent.style.opacity="0.3",this.originalEvent.style.userSelect="none"}handleDragMove(e){let t=e.draggedClone,n=this.dateService.parseISO(e.columnBounds.date);t.updatePosition(n,e.snappedY)}handleColumnChange(e){let t=e.newColumn.element.querySelector("swp-events-layer");if(t&&e.draggedClone.parentElement!==t){t.appendChild(e.draggedClone);let n=parseFloat(e.draggedClone.style.top)||0,r=e.draggedClone,s=this.dateService.parseISO(e.newColumn.date);r.updatePosition(s,n)}}handleConvertAllDayToTimed(e){console.log("\u{1F3AF} DateEventRenderer: Converting all-day to timed event",{eventId:e.calendarEvent.id,targetColumn:e.targetColumn.date,snappedY:e.snappedY});let t=Q.fromCalendarEvent(e.calendarEvent),n=this.calculateEventPosition(e.calendarEvent);t.style.height=`${n.height-3}px`,t.style.left="2px",t.style.right="2px",t.style.width="auto",t.style.pointerEvents="none",this.applyDragStyling(t);let r=e.targetColumn.element.querySelector("swp-events-layer");e.draggedClone.remove(),e.replaceClone(t),r.appendChild(t)}handleDragEnd(e,t,n,r){if(!t||!e){console.warn("Missing draggedClone or originalElement");return}e.tagName==="SWP-EVENT"&&this.fadeOutAndRemove(e);let s=t.dataset.eventId;s&&s.startsWith("clone-")&&(t.dataset.eventId=s.replace("clone-","")),t.classList.remove("dragging"),t.style.pointerEvents="",this.draggedClone=null,this.originalEvent=null;let i=document.querySelector(`swp-event[data-event-id="clone-${s}"]`);i&&i.remove()}handleNavigationCompleted(){}fadeOutAndRemove(e){e.style.transition="opacity 0.3s ease-out",e.style.opacity="0",setTimeout(()=>{e.remove()},300)}renderEvents(e,t){let n=e.filter(s=>!s.allDay);this.getColumns(t).forEach(s=>{let i=this.getEventsForColumn(s,n),a=s.querySelector("swp-events-layer");a&&this.renderColumnEvents(i,a)})}renderSingleColumnEvents(e,t){let n=this.getEventsForColumn(e.element,t),r=e.element.querySelector("swp-events-layer");r&&this.renderColumnEvents(n,r)}renderColumnEvents(e,t){if(e.length===0)return;let n=this.layoutCoordinator.calculateColumnLayout(e);n.gridGroups.forEach(r=>{this.renderGridGroup(r,t)}),n.stackedEvents.forEach(r=>{let s=this.renderEvent(r.event);this.stackManager.applyStackLinkToElement(s,r.stackLink),this.stackManager.applyVisualStyling(s,r.stackLink.stackLevel),t.appendChild(s)})}renderGridGroup(e,t){let n=document.createElement("swp-event-group"),r=e.columns.length;n.classList.add(`cols-${r}`),n.classList.add(`stack-level-${e.stackLevel}`),n.style.top=`${e.position.top}px`;let s={stackLevel:e.stackLevel};this.stackManager.applyStackLinkToElement(n,s),this.stackManager.applyVisualStyling(n,e.stackLevel);let i=e.events[0];e.columns.forEach(a=>{let c=this.renderGridColumn(a,i.start);n.appendChild(c)}),t.appendChild(n)}renderGridColumn(e,t){let n=document.createElement("div");return n.style.position="relative",e.forEach(r=>{let s=this.renderEventInGrid(r,t);n.appendChild(s)}),n}renderEventInGrid(e,t){let n=Q.fromCalendarEvent(e),r=this.calculateEventPosition(e),i=(e.start.getTime()-t.getTime())/(1e3*60),a=this.config.gridSettings,c=i>0?i/60*a.hourHeight:0;return n.style.position="absolute",n.style.top=`${c}px`,n.style.height=`${r.height-3}px`,n.style.left="0",n.style.right="0",n}renderEvent(e){let t=Q.fromCalendarEvent(e),n=this.calculateEventPosition(e);return t.style.position="absolute",t.style.top=`${n.top+1}px`,t.style.height=`${n.height-3}px`,t.style.left="2px",t.style.right="2px",t}calculateEventPosition(e){return this.positionUtils.calculateEventPosition(e.start,e.end)}clearEvents(e){let t="swp-event",n="swp-event-group",r=e?e.querySelectorAll(t):document.querySelectorAll(t),s=e?e.querySelectorAll(n):document.querySelectorAll(n);r.forEach(i=>i.remove()),s.forEach(i=>i.remove())}getColumns(e){let t=e.querySelectorAll("swp-day-column");return Array.from(t)}getEventsForColumn(e,t){let n=e.dataset.date;if(!n)return[];let r=this.dateService.parseISO(`${n}T00:00:00`),s=this.dateService.parseISO(`${n}T23:59:59.999`);return t.filter(a=>a.startr)}};var Ve=class{constructor(){this.container=null,this.originalEvent=null,this.draggedClone=null,this.getContainer()}getContainer(){let e=document.querySelector("swp-calendar-header");return e&&(this.container=e.querySelector("swp-allday-container"),this.container||(this.container=document.createElement("swp-allday-container"),e.appendChild(this.container))),this.container}getAllDayContainer(){return document.querySelector("swp-calendar-header swp-allday-container")}handleDragStart(e){if(this.originalEvent=e.originalElement,this.draggedClone=e.draggedClone,this.draggedClone){let t=this.getAllDayContainer();if(!t)return;this.draggedClone.style.gridColumn=this.originalEvent.style.gridColumn,this.draggedClone.style.gridRow=this.originalEvent.style.gridRow,console.log("handleDragStart:this.draggedClone",this.draggedClone),t.appendChild(this.draggedClone),this.draggedClone.classList.add("dragging"),this.draggedClone.style.zIndex="1000",this.draggedClone.style.cursor="grabbing",this.originalEvent.style.opacity="0.3",this.originalEvent.style.userSelect="none"}}renderAllDayEventWithLayout(e,t){let n=this.getContainer();if(!n)return null;let r=oe.fromCalendarEvent(e);r.applyGridPositioning(t.row,t.startColumn,t.endColumn),r.classList.add("highlight"),n.appendChild(r)}removeAllDayEvent(e){let t=this.getContainer();if(!t)return;let n=t.querySelector(`swp-allday-event[data-event-id="${e}"]`);n&&n.remove()}clearCache(){this.container=null}renderAllDayEventsForPeriod(e){this.clearAllDayEvents(),e.forEach(t=>{this.renderAllDayEventWithLayout(t.calenderEvent,t)})}clearAllDayEvents(){let e=document.querySelector("swp-allday-container");e&&e.querySelectorAll("swp-allday-event:not(.max-event-indicator)").forEach(t=>t.remove())}handleViewChanged(e){this.clearAllDayEvents()}};var ze=class{constructor(e,t,n){this.cachedGridContainer=null,this.cachedTimeAxis=null,this.dateService=t,this.columnRenderer=e,this.config=n}renderGrid(e,t,n="week"){!e||!t||(this.cachedGridContainer=e,e.children.length===0?this.createCompleteGridStructure(e,t,n):this.updateGridContent(e,t,n))}createCompleteGridStructure(e,t,n){let r=document.createDocumentFragment(),s=document.createElement("swp-header-spacer");r.appendChild(s);let i=this.createOptimizedTimeAxis();this.cachedTimeAxis=i,r.appendChild(i);let a=this.createOptimizedGridContainer(t,n);this.cachedGridContainer=a,r.appendChild(a),e.appendChild(r)}createOptimizedTimeAxis(){let e=document.createElement("swp-time-axis"),t=document.createElement("swp-time-axis-content"),n=this.config.gridSettings,r=n.dayStartHour,s=n.dayEndHour,i=document.createDocumentFragment();for(let a=r;a{let t=e,{weekNumber:n,dateRange:r}=t.detail;this.updateWeekInfoInDOM(n,r)})}updateWeekInfoInDOM(e,t){let n=document.querySelector("swp-week-number"),r=document.querySelector("swp-date-range");n&&(n.textContent=`Week ${e}`),r&&(r.textContent=t)}applyFilterToPreRenderedGrids(e){document.querySelectorAll("swp-grid-container").forEach(n=>{n.querySelectorAll("swp-events-layer").forEach(s=>{e.active?(s.setAttribute("data-filter-active","true"),s.querySelectorAll("swp-event").forEach(a=>{let c=a.getAttribute("data-event-id");c&&e.matchingIds.includes(c)?a.setAttribute("data-matches","true"):a.removeAttribute("data-matches")})):(s.removeAttribute("data-filter-active"),s.querySelectorAll("swp-event").forEach(a=>{a.removeAttribute("data-matches")}))})})}};var Ge=class{constructor(e,t){this.dateService=e,this.config=t}minutesToPixels(e){let n=this.config.gridSettings.hourHeight;return e/60*n}pixelsToMinutes(e){let n=this.config.gridSettings.hourHeight;return e/n*60}timeToPixels(e){let t=this.dateService.timeToMinutes(e),r=this.config.gridSettings.dayStartHour*60,s=t-r;return this.minutesToPixels(s)}dateToPixels(e){let t=this.dateService.getMinutesSinceMidnight(e),r=this.config.gridSettings.dayStartHour*60,s=t-r;return this.minutesToPixels(s)}pixelsToTime(e){let t=this.pixelsToMinutes(e),s=this.config.gridSettings.dayStartHour*60+t;return this.dateService.minutesToTime(s)}calculateEventPosition(e,t){let n,r;typeof e=="string"?n=this.timeToPixels(e):n=this.dateToPixels(e),typeof t=="string"?r=this.timeToPixels(t):r=this.dateToPixels(t);let s=Math.max(r-n,this.getMinimumEventHeight()),i=this.pixelsToMinutes(s);return{top:n,height:s,duration:i}}snapToGrid(e){let n=this.config.gridSettings.snapInterval,r=this.minutesToPixels(n);return Math.round(e/r)*r}snapTimeToInterval(e){let t=this.dateService.timeToMinutes(e),r=this.config.gridSettings.snapInterval,s=Math.round(t/r)*r;return this.dateService.minutesToTime(s)}calculateColumnPosition(e,t,n){let r=n/t,s=e*r,i=2,a=r-i;return{left:s+i/2,width:Math.max(a,50)}}eventsOverlap(e,t,n,r){let s=this.calculateEventPosition(e,t),i=this.calculateEventPosition(n,r),a=s.top+s.height,c=i.top+i.height;return!(a<=i.top||c<=s.top)}getPositionFromCoordinate(e,t){let n=e-t.boundingClientRect.top;return this.snapToGrid(n)}isWithinWorkHours(e){let[t]=e.split(":").map(Number),n=this.config.gridSettings;return t>=n.workStartHour&&t=n.dayStartHour&&t{let r=this.dateService.formatISODate(n),s=this.getWorkHoursForDate(n);t.set(r,s)}),t}calculateNonWorkHoursStyle(e){if(e==="off")return null;let t=this.config.gridSettings,n=t.dayStartHour,r=t.hourHeight,s=(e.start-n)*r,i=(e.end-n)*r;return{beforeWorkHeight:Math.max(0,s),afterWorkTop:Math.max(0,i)}}calculateWorkHoursStyle(e){if(e==="off")return null;let t=`${e.start.toString().padStart(2,"0")}:00`,n=`${e.end.toString().padStart(2,"0")}:00`,r=this.positionUtils.calculateEventPosition(t,n);return{top:r.top,height:r.height}}async loadWorkSchedule(e){this.workSchedule=e}getWorkSchedule(){return this.workSchedule}getDayName(e){return["sunday","monday","tuesday","wednesday","thursday","friday","saturday"][e.getDay()]}};var pe=class o{constructor(e){this.config=e}groupEventsByStartTime(e){if(e.length===0)return[];let n=this.config.gridSettings.gridStartThresholdMinutes,r=[...e].sort((i,a)=>i.start.getTime()-a.start.getTime()),s=[];for(let i of r){let a=s.find(c=>c.events.some(d=>{if(Math.abs(i.start.getTime()-d.start.getTime())/6e4<=n)return!0;let w=(d.end.getTime()-i.start.getTime())/(1e3*60);if(w>0&&w<=n)return!0;let E=(i.end.getTime()-d.start.getTime())/(1e3*60);return E>0&&E<=n}));a?a.events.push(i):s.push({events:[i],containerType:"NONE",startTime:i.start})}return s}decideContainerType(e){return e.events.length===1?"NONE":"GRID"}doEventsOverlap(e,t){return e.startt.start}createOptimizedStackLinks(e){let t=new Map;if(e.length===0)return t;let n=[...e].sort((r,s)=>r.start.getTime()-s.start.getTime());for(let r of n){let s=n.filter(a=>a!==r&&this.doEventsOverlap(r,a)),i=0;for(let a of s){let c=t.get(a.id);c&&(i=Math.max(i,c.stackLevel+1))}t.set(r.id,{stackLevel:i})}for(let r of n){let s=t.get(r.id),i=n.filter(d=>d!==r&&this.doEventsOverlap(r,d)),a=i.filter(d=>{let g=t.get(d.id);return g&&g.stackLevel===s.stackLevel-1});a.length>0&&(s.prev=a[0].id);let c=i.filter(d=>{let g=t.get(d.id);return g&&g.stackLevel===s.stackLevel+1});c.length>0&&(s.next=c[0].id)}return t}calculateMarginLeft(e){return e*o.STACK_OFFSET_PX}calculateZIndex(e){return 100+e}serializeStackLink(e){return JSON.stringify(e)}deserializeStackLink(e){try{return JSON.parse(e)}catch{return null}}applyStackLinkToElement(e,t){e.dataset.stackLink=this.serializeStackLink(t)}getStackLinkFromElement(e){let t=e.dataset.stackLink;return t?this.deserializeStackLink(t):null}applyVisualStyling(e,t){e.style.marginLeft=`${this.calculateMarginLeft(t)}px`,e.style.zIndex=`${this.calculateZIndex(t)}`}clearStackLinkFromElement(e){delete e.dataset.stackLink}clearVisualStyling(e){e.style.marginLeft="",e.style.zIndex=""}};pe.STACK_OFFSET_PX=15;var je=class{constructor(e,t,n){this.stackManager=e,this.config=t,this.positionUtils=n}calculateColumnLayout(e){if(e.length===0)return{gridGroups:[],stackedEvents:[]};let t=[],n=[],r=[],s=[...e].sort((i,a)=>i.start.getTime()-a.start.getTime());for(;s.length>0;){let i=s[0],c=this.config.gridSettings.gridStartThresholdMinutes,d=this.expandGridCandidates(i,s,c),g={events:d,containerType:"NONE",startTime:i.start};if(this.stackManager.decideContainerType(g)==="GRID"&&d.length>1){let E=this.calculateGridGroupStackLevelFromRendered(d,r),m=[...d].sort((C,k)=>C.start.getTime()-k.start.getTime())[0],u=this.positionUtils.calculateEventPosition(m.start,m.end),D=this.allocateColumns(d);t.push({events:d,stackLevel:E,position:{top:u.top+1},columns:D}),d.forEach(C=>r.push({event:C,level:E})),s=s.filter(C=>!d.includes(C))}else{let E=this.calculateStackLevelFromRendered(i,r),m=this.positionUtils.calculateEventPosition(i.start,i.end);n.push({event:i,stackLink:{stackLevel:E},position:{top:m.top+1,height:m.height-3}}),r.push({event:i,level:E}),s=s.slice(1)}}return{gridGroups:t,stackedEvents:n}}calculateGridGroupStackLevelFromRendered(e,t){let n=-1;for(let r of e)for(let s of t)this.stackManager.doEventsOverlap(r,s.event)&&(n=Math.max(n,s.level));return n+1}calculateStackLevelFromRendered(e,t){let n=-1;for(let r of t)this.stackManager.doEventsOverlap(e,r.event)&&(n=Math.max(n,r.level));return n+1}detectConflict(e,t,n){if(Math.abs(e.start.getTime()-t.start.getTime())/6e4<=n&&this.stackManager.doEventsOverlap(e,t))return!0;let s=(t.end.getTime()-e.start.getTime())/(1e3*60);if(s>0&&s<=n)return!0;let i=(e.end.getTime()-t.start.getTime())/(1e3*60);return i>0&&i<=n}expandGridCandidates(e,t,n){let r=[e],s=!0;for(;s;){s=!1;for(let i=1;ithis.stackManager.doEventsOverlap(n,a))){s.push(n),r=!0;break}r||t.push([n])}return t}};async function zt(o,e){try{let t=e.parseEventIdFromURL();t&&(console.log(`Deep linking to event ID: ${t}`),setTimeout(async()=>{await o.navigateToEvent(t)||console.warn(`Deep linking failed: Event with ID ${t} not found`)},500))}catch(t){console.warn("Deep linking failed:",t)}}async function Ot(){try{let o=await fe.load(),t=new ce().builder();b.setDebug(!0),t.registerInstance(b).as("IEventBus"),t.registerInstance(o).as("Configuration"),t.registerType(J).as("IndexedDBService"),t.registerType(Pe).as("OperationQueue").autoWire({mapResolvers:[l=>l.resolveType("IndexedDBService")]}),t.registerType(We).as("ApiEventRepository").autoWire({mapResolvers:[l=>l.resolveType("Configuration")]}),t.registerType(Be).as("IEventRepository").autoWire({mapResolvers:[l=>l.resolveType("IndexedDBService"),l=>l.resolveType("OperationQueue")]}),t.registerType(Ne).as("SyncManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("OperationQueue"),l=>l.resolveType("IndexedDBService"),l=>l.resolveType("ApiEventRepository")]}),t.registerType(Fe).as("IHeaderRenderer"),t.registerType(_e).as("IColumnRenderer").autoWire({mapResolvers:[l=>l.resolveType("DateService"),l=>l.resolveType("WorkHoursManager")]}),t.registerType(Ye).as("IEventRenderer").autoWire({mapResolvers:[l=>l.resolveType("DateService"),l=>l.resolveType("EventStackManager"),l=>l.resolveType("EventLayoutCoordinator"),l=>l.resolveType("Configuration"),l=>l.resolveType("PositionUtils")]}),t.registerType(U).as("DateService").autoWire({mapResolvers:[l=>l.resolveType("Configuration")]}),t.registerType(pe).as("EventStackManager").autoWire({mapResolvers:[l=>l.resolveType("Configuration")]}),t.registerType(je).as("EventLayoutCoordinator").autoWire({mapResolvers:[l=>l.resolveType("EventStackManager"),l=>l.resolveType("Configuration"),l=>l.resolveType("PositionUtils")]}),t.registerType(Ue).as("WorkHoursManager").autoWire({mapResolvers:[l=>l.resolveType("DateService"),l=>l.resolveType("Configuration"),l=>l.resolveType("PositionUtils")]}),t.registerType(Ee).as("URLManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus")]}),t.registerType(V).as("TimeFormatter"),t.registerType(Ge).as("PositionUtils").autoWire({mapResolvers:[l=>l.resolveType("DateService"),l=>l.resolveType("Configuration")]}),t.registerType(qe).as("WeekInfoRenderer").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("EventRenderingService")]}),t.registerType(Ve).as("AllDayEventRenderer"),t.registerType(Se).as("EventRenderingService").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("EventManager"),l=>l.resolveType("IEventRenderer"),l=>l.resolveType("DateService")]}),t.registerType(ze).as("GridRenderer").autoWire({mapResolvers:[l=>l.resolveType("IColumnRenderer"),l=>l.resolveType("DateService"),l=>l.resolveType("Configuration")]}),t.registerType(we).as("GridManager").autoWire({mapResolvers:[l=>l.resolveType("GridRenderer"),l=>l.resolveType("DateService")]}),t.registerType(Ce).as("ScrollManager").autoWire({mapResolvers:[l=>l.resolveType("PositionUtils")]}),t.registerType(Te).as("NavigationManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("EventRenderingService"),l=>l.resolveType("GridRenderer"),l=>l.resolveType("DateService"),l=>l.resolveType("WeekInfoRenderer")]}),t.registerType(ke).as("NavigationButtons").autoWire({mapResolvers:[l=>l.resolveType("IEventBus")]}),t.registerType(Me).as("ViewSelector").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("Configuration")]}),t.registerType(be).as("DragDropManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("PositionUtils")]}),t.registerType(Ie).as("AllDayManager").autoWire({mapResolvers:[l=>l.resolveType("EventManager"),l=>l.resolveType("AllDayEventRenderer"),l=>l.resolveType("DateService")]}),t.registerType(Oe).as("ResizeHandleManager").autoWire({mapResolvers:[l=>l.resolveType("Configuration"),l=>l.resolveType("PositionUtils")]}),t.registerType(Le).as("EdgeScrollManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus")]}),t.registerType($e).as("HeaderManager").autoWire({mapResolvers:[l=>l.resolveType("IHeaderRenderer"),l=>l.resolveType("Configuration")]}),t.registerType(Ae).as("CalendarManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("EventManager"),l=>l.resolveType("GridManager"),l=>l.resolveType("EventRenderingService"),l=>l.resolveType("ScrollManager"),l=>l.resolveType("Configuration")]}),t.registerType(He).as("WorkweekPresets").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("Configuration")]}),t.registerType(fe).as("ConfigManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("Configuration")]}),t.registerType(De).as("EventManager").autoWire({mapResolvers:[l=>l.resolveType("IEventBus"),l=>l.resolveType("DateService"),l=>l.resolveType("Configuration"),l=>l.resolveType("IEventRepository")]});let n=t.build(),r=n.resolveType("IEventBus"),s=n.resolveType("CalendarManager"),i=n.resolveType("EventManager"),a=n.resolveType("ResizeHandleManager"),c=n.resolveType("HeaderManager"),d=n.resolveType("DragDropManager"),g=n.resolveType("ViewSelector"),w=n.resolveType("NavigationManager"),E=n.resolveType("NavigationButtons"),m=n.resolveType("EdgeScrollManager"),u=n.resolveType("AllDayManager"),D=n.resolveType("URLManager"),C=n.resolveType("WorkweekPresets"),k=n.resolveType("ConfigManager");await s.initialize?.(),await a.initialize?.(),await zt(i,D),window.calendarDebug={eventBus:b,app:n,calendarManager:s,eventManager:i,workweekPresetsManager:C}}catch(o){throw o}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{Ot().catch(o=>{console.error("Calendar initialization failed:",o)})}):Ot().catch(o=>{console.error("Calendar initialization failed:",o)}); diff --git a/wwwroot/js/calendar-v2.js b/wwwroot/js/calendar-v2.js new file mode 100644 index 0000000..7287e63 --- /dev/null +++ b/wwwroot/js/calendar-v2.js @@ -0,0 +1,1631 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = /* @__PURE__ */ __name(function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, "m"), v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: /* @__PURE__ */ __name(function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, "t"), a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = /* @__PURE__ */ __name(function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, "S"), w = /* @__PURE__ */ __name(function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, "t"), O = /* @__PURE__ */ __name(function(t2, e2) { + if (S(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, "O"), b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + __name(M2, "M"); + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) + return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = /* @__PURE__ */ __name(function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, "l"), $2 = /* @__PURE__ */ __name(function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, "$"), y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = /* @__PURE__ */ __name(function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }, "y"); + if ($2 === c) + return this.set(c, this.$M + r2); + if ($2 === h) + return this.set(h, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = /* @__PURE__ */ __name(function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, "h"), d2 = /* @__PURE__ */ __name(function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, "d"), $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, function(t3, r3) { + return r3 || function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + }(t3) || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = /* @__PURE__ */ __name(function() { + return b.m(y2, m3); + }, "D"); + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + }); + } +}); + +// node_modules/dayjs/plugin/utc.js +var require_utc = __commonJS({ + "node_modules/dayjs/plugin/utc.js"(exports, module) { + !function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + }(exports, function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var r = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2); + }; + var o = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else + o.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) + return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) + return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + }(s2), null === s2)) + return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2; + if (0 === u2) + return this.utc(f2); + var r2 = this.clone(); + if (f2) + return r2.$offset = u2, r2.$u = false, r2; + var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) + return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + }(exports, function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = /* @__PURE__ */ __name(function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + }(n2, i2); + return r2.formatToParts(o2); + }, "a"), u = /* @__PURE__ */ __name(function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, "u"), f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) + n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { + return "timezonename" === t3.type.toLowerCase(); + }); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) + return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) + return o(t2).tz(a2); + var s2 = function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) + return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/isoWeek.js +var require_isoWeek = __commonJS({ + "node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + }(exports, function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = /* @__PURE__ */ __name(function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, "a"), d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) + return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + }); + } +}); + +// src/v2/core/RenderBuilder.ts +function buildPipeline(renderers) { + return { + async run(context) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} +__name(buildPipeline, "buildPipeline"); + +// src/v2/core/FilterTemplate.ts +var _FilterTemplate = class _FilterTemplate { + constructor(dateService, entityResolver) { + this.dateService = dateService; + this.entityResolver = entityResolver; + this.fields = []; + } + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty, derivedFrom) { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + parseDotNotation(idProperty) { + if (!idProperty.includes(".")) + return null; + const [entityType, property] = idProperty.split("."); + return { + entityType, + property, + foreignKey: entityType + "Id" + // Convention: resource → resourceId + }; + } + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + getDatasetKey(idProperty) { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; + } + return idProperty; + } + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column) { + return this.fields.map((f) => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ""; + }).join(":"); + } + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event) { + const eventRecord = event; + return this.fields.map((f) => { + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + if (f.derivedFrom) { + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ""); + } + return String(eventRecord[f.idProperty] || ""); + }).join(":"); + } + /** + * Resolve dot-notation reference via EntityResolver + */ + resolveDotNotation(eventRecord, dotNotation) { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ""; + } + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) + return ""; + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) + return ""; + return String(entity[dotNotation.property] || ""); + } + /** + * Match event mod kolonne + */ + matches(event, column) { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +}; +__name(_FilterTemplate, "FilterTemplate"); +var FilterTemplate = _FilterTemplate; + +// src/v2/core/CalendarOrchestrator.ts +var _CalendarOrchestrator = class _CalendarOrchestrator { + constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) { + this.allRenderers = allRenderers; + this.eventRenderer = eventRenderer; + this.scheduleRenderer = scheduleRenderer; + this.headerDrawerRenderer = headerDrawerRenderer; + this.dateService = dateService; + this.entityServices = entityServices; + } + async render(viewConfig, container) { + const headerContainer = container.querySelector("swp-calendar-header"); + const columnContainer = container.querySelector("swp-day-columns"); + if (!headerContainer || !columnContainer) { + throw new Error("Missing swp-calendar-header or swp-day-columns"); + } + const filter = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + headerContainer.innerHTML = ""; + columnContainer.innerHTML = ""; + const levels = viewConfig.groupings.map((g) => g.type).join(" "); + headerContainer.dataset.levels = levels; + const activeRenderers = this.selectRenderers(viewConfig); + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + await this.scheduleRenderer.render(container, filter); + await this.eventRenderer.render(container, filter, filterTemplate); + await this.headerDrawerRenderer.render(container, filter, filterTemplate); + } + selectRenderers(viewConfig) { + const types = viewConfig.groupings.map((g) => g.type); + return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0); + } + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + async resolveBelongsTo(groupings, filter) { + const childGrouping = groupings.find((g) => g.belongsTo); + if (!childGrouping?.belongsTo) + return {}; + const [entityType, property] = childGrouping.belongsTo.split("."); + if (!entityType || !property) + return {}; + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) + return {}; + const service = this.entityServices.find( + (s) => s.entityType.toLowerCase() === entityType + ); + if (!service) + return {}; + const allEntities = await service.getAll(); + const entities = allEntities.filter( + (e) => parentIds.includes(e.id) + ); + const map = {}; + for (const entity of entities) { + const entityRecord = entity; + const children = entityRecord[property] || []; + map[entityRecord.id] = children; + } + return { parentChildMap: map, childType: childGrouping.type }; + } +}; +__name(_CalendarOrchestrator, "CalendarOrchestrator"); +var CalendarOrchestrator = _CalendarOrchestrator; + +// src/v2/core/NavigationAnimator.ts +var _NavigationAnimator = class _NavigationAnimator { + constructor(headerTrack, contentTrack) { + this.headerTrack = headerTrack; + this.contentTrack = contentTrack; + } + async slide(direction, renderFn) { + const out = direction === "left" ? "-100%" : "100%"; + const into = direction === "left" ? "100%" : "-100%"; + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + async animateOut(translate) { + await Promise.all([ + this.headerTrack.animate( + [{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], + { duration: 200, easing: "ease-in" } + ).finished, + this.contentTrack.animate( + [{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], + { duration: 200, easing: "ease-in" } + ).finished + ]); + } + async animateIn(translate) { + await Promise.all([ + this.headerTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], + { duration: 200, easing: "ease-out" } + ).finished, + this.contentTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], + { duration: 200, easing: "ease-out" } + ).finished + ]); + } +}; +__name(_NavigationAnimator, "NavigationAnimator"); +var NavigationAnimator = _NavigationAnimator; + +// src/v2/features/date/DateRenderer.ts +var _DateRenderer = class _DateRenderer { + constructor(dateService) { + this.dateService = dateService; + this.type = "date"; + } + render(context) { + const dates = context.filter["date"] || []; + const resourceIds = context.filter["resource"] || []; + const dateGrouping = context.groupings?.find((g) => g.type === "date"); + const hideHeader = dateGrouping?.hideHeader === true; + const iterations = resourceIds.length || 1; + let columnCount = 0; + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + const segments = { date: dateStr }; + if (resourceId) + segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + const header = document.createElement("swp-day-header"); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = "true"; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, "short")} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + const column = document.createElement("swp-day-column"); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ""; + context.columnContainer.appendChild(column); + columnCount++; + } + } + const container = context.columnContainer.closest("swp-calendar-container"); + if (container) { + container.style.setProperty("--grid-columns", String(columnCount)); + } + } +}; +__name(_DateRenderer, "DateRenderer"); +var DateRenderer = _DateRenderer; + +// src/v2/core/DateService.ts +var import_dayjs = __toESM(require_dayjs_min(), 1); +var import_utc = __toESM(require_utc(), 1); +var import_timezone = __toESM(require_timezone(), 1); +var import_isoWeek = __toESM(require_isoWeek(), 1); +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_timezone.default); +import_dayjs.default.extend(import_isoWeek.default); +var _DateService = class _DateService { + constructor(config, baseDate) { + this.config = config; + this.timezone = config.timezone; + this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)(); + } + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date) { + this.baseDate = (0, import_dayjs.default)(date); + } + /** + * Get the current base date (either fixed or today) + */ + getBaseDate() { + return this.baseDate.toDate(); + } + parseISO(isoString) { + return (0, import_dayjs.default)(isoString).toDate(); + } + getDayName(date, format = "short") { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + getWeekDates(offset = 0, days = 7) { + const monday = this.baseDate.startOf("week").add(1, "day").add(offset, "week"); + return Array.from( + { length: days }, + (_, i) => monday.add(i, "day").format("YYYY-MM-DD") + ); + } + /** + * Get dates for specific weekdays within a week + * @param offset - Week offset from base date (0 = current week) + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkWeekDates(offset, workDays) { + const monday = this.baseDate.startOf("week").add(1, "day").add(offset, "week"); + return workDays.map((isoDay) => { + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, "day").format("YYYY-MM-DD"); + }); + } + // ============================================ + // FORMATTING + // ============================================ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? "HH:mm:ss" : "HH:mm"; + return (0, import_dayjs.default)(date).format(pattern); + } + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + formatDate(date) { + return (0, import_dayjs.default)(date).format("YYYY-MM-DD"); + } + getDateKey(date) { + return this.formatDate(date); + } + // ============================================ + // COLUMN KEY + // ============================================ + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments) { + const date = segments.date; + const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v); + return date ? [date, ...others].join(":") : others.join(":"); + } + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey) { + const parts = columnKey.split(":"); + return { + date: parts[0], + resource: parts[1] + }; + } + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey) { + return columnKey.split(":")[0]; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + timeToMinutes(timeString) { + const parts = timeString.split(":").map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm"); + } + getMinutesSinceMidnight(date) { + const d = (0, import_dayjs.default)(date); + return d.hour() * 60 + d.minute(); + } + // ============================================ + // UTC CONVERSIONS + // ============================================ + toUTC(localDate) { + return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString(); + } + fromUTC(utcString) { + return import_dayjs.default.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // DATE CREATION + // ============================================ + createDateAtTime(baseDate, timeString) { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate(); + } + getISOWeekDay(date) { + return (0, import_dayjs.default)(date).isoWeekday(); + } +}; +__name(_DateService, "DateService"); +var DateService = _DateService; + +// src/v2/utils/PositionUtils.ts +function calculateEventPosition(start, end, config) { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + return { top, height }; +} +__name(calculateEventPosition, "calculateEventPosition"); +function minutesToPixels(minutes, config) { + return minutes / 60 * config.hourHeight; +} +__name(minutesToPixels, "minutesToPixels"); +function pixelsToMinutes(pixels, config) { + return pixels / config.hourHeight * 60; +} +__name(pixelsToMinutes, "pixelsToMinutes"); +function snapToGrid(pixels, config) { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} +__name(snapToGrid, "snapToGrid"); + +// src/v2/constants/CoreEvents.ts +var CoreEvents = { + // Lifecycle events + INITIALIZED: "core:initialized", + READY: "core:ready", + DESTROYED: "core:destroyed", + // View events + VIEW_CHANGED: "view:changed", + VIEW_RENDERED: "view:rendered", + // Navigation events + DATE_CHANGED: "nav:date-changed", + NAVIGATION_COMPLETED: "nav:navigation-completed", + // Data events + DATA_LOADING: "data:loading", + DATA_LOADED: "data:loaded", + DATA_ERROR: "data:error", + // Grid events + GRID_RENDERED: "grid:rendered", + GRID_CLICKED: "grid:clicked", + // Event management + EVENT_CREATED: "event:created", + EVENT_UPDATED: "event:updated", + EVENT_DELETED: "event:deleted", + EVENT_SELECTED: "event:selected", + // Event drag-drop + EVENT_DRAG_START: "event:drag-start", + EVENT_DRAG_MOVE: "event:drag-move", + EVENT_DRAG_END: "event:drag-end", + EVENT_DRAG_CANCEL: "event:drag-cancel", + EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change", + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header", + EVENT_DRAG_MOVE_HEADER: "event:drag-move-header", + EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header", + // Event resize + EVENT_RESIZE_START: "event:resize-start", + EVENT_RESIZE_END: "event:resize-end", + // Edge scroll + EDGE_SCROLL_TICK: "edge-scroll:tick", + EDGE_SCROLL_STARTED: "edge-scroll:started", + EDGE_SCROLL_STOPPED: "edge-scroll:stopped", + // System events + ERROR: "system:error", + // Sync events + SYNC_STARTED: "sync:started", + SYNC_COMPLETED: "sync:completed", + SYNC_FAILED: "sync:failed", + // Entity events - for audit and sync + ENTITY_SAVED: "entity:saved", + ENTITY_DELETED: "entity:deleted", + // Audit events + AUDIT_LOGGED: "audit:logged", + // Rendering events + EVENTS_RENDERED: "events:rendered" +}; + +// src/v2/features/event/EventLayoutEngine.ts +function eventsOverlap(a, b) { + return a.start < b.end && a.end > b.start; +} +__name(eventsOverlap, "eventsOverlap"); +function eventsWithinThreshold(a, b, thresholdMinutes) { + const thresholdMs = thresholdMinutes * 60 * 1e3; + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) + return true; + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) + return true; + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) + return true; + return false; +} +__name(eventsWithinThreshold, "eventsWithinThreshold"); +function findOverlapGroups(events) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsOverlap(member, candidate)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findOverlapGroups, "findOverlapGroups"); +function findGridCandidates(events, thresholdMinutes) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some( + (member) => eventsWithinThreshold(member, candidate, thresholdMinutes) + ); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findGridCandidates, "findGridCandidates"); +function calculateStackLevels(events) { + const levels = /* @__PURE__ */ new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + for (const event of sorted) { + let maxOverlappingLevel = -1; + for (const [id, level] of levels) { + const other = events.find((e) => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + levels.set(event.id, maxOverlappingLevel + 1); + } + return levels; +} +__name(calculateStackLevels, "calculateStackLevels"); +function allocateColumns(events) { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns = []; + for (const event of sorted) { + let placed = false; + for (const column of columns) { + const canFit = !column.some((e) => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + if (!placed) { + columns.push([event]); + } + } + return columns; +} +__name(allocateColumns, "allocateColumns"); +function calculateColumnLayout(events, config) { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + const result = { + grids: [], + stacked: [] + }; + if (events.length === 0) + return result; + const overlapGroups = findOverlapGroups(events); + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]); + if (largestGridCandidate.length === overlapGroup.length) { + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + return result; +} +__name(calculateColumnLayout, "calculateColumnLayout"); + +// src/v2/features/event/EventRenderer.ts +var _EventRenderer = class _EventRenderer { + constructor(eventService, dateService, gridConfig, eventBus) { + this.eventService = eventService; + this.dateService = dateService; + this.gridConfig = gridConfig; + this.eventBus = eventBus; + this.container = null; + this.setupListeners(); + } + /** + * Setup listeners for drag-drop and update events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = e.detail; + this.handleColumnChange(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = e.detail; + this.updateDragTimestamp(payload); + }); + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = e.detail; + this.handleEventUpdated(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeaveHeader(payload); + }); + } + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + handleDragEnd(payload) { + if (payload.target === "header") { + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + /** + * Handle header item leaving header - create swp-event in grid + */ + handleDragLeaveHeader(payload) { + if (payload.source !== "header") + return; + if (!payload.targetColumn || !payload.start || !payload.end) + return; + if (payload.element) { + payload.element.classList.add("drag-ghost"); + payload.element.style.opacity = "0.3"; + payload.element.style.pointerEvents = "none"; + } + const event = { + id: payload.eventId, + title: payload.title || "", + description: "", + start: payload.start, + end: payload.end, + type: "customer", + allDay: false, + syncStatus: "pending" + }; + const element = this.createEventElement(event); + let eventsLayer = payload.targetColumn.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + element.classList.add("dragging"); + } + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + async handleEventUpdated(payload) { + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + await this.rerenderColumn(payload.targetColumnKey); + } + /** + * Re-render a single column with fresh data from IndexedDB + */ + async rerenderColumn(columnKey) { + const column = this.findColumn(columnKey); + if (!column) + return; + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date) + return; + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate); + const timedEvents = events.filter( + (event) => !event.allDay && this.dateService.getDateKey(event.start) === date + ); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + } + /** + * Find a column element by columnKey + */ + findColumn(columnKey) { + if (!this.container) + return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`); + } + /** + * Handle event moving to a new column during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.querySelector("swp-events-layer"); + if (!eventsLayer) + return; + eventsLayer.appendChild(payload.element); + payload.element.style.top = `${payload.currentY}px`; + } + /** + * Update timestamp display during drag (snapped to grid) + */ + updateDragTimestamp(payload) { + const timeEl = payload.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart; + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to a Date object (today) + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container, filter, filterTemplate) { + this.container = container; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const dayColumns = container.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + columns.forEach((column) => { + const columnEl = column; + const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl)); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const timedEvents = columnEvents.filter((event) => !event.allDay); + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + }); + } + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + createEventElement(event) { + const element = document.createElement("swp-event"); + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ""} + `; + return element; + } + /** + * Get color class based on metadata.color or event type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Escape HTML to prevent XSS + */ + escapeHtml(text) { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; + } + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + renderGridGroup(layout) { + const group = document.createElement("swp-event-group"); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) + maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + layout.columns.forEach((columnEvents) => { + const wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + columnEvents.forEach((event) => { + const eventEl = this.createEventElement(event); + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = "absolute"; + eventEl.style.left = "0"; + eventEl.style.right = "0"; + wrapper.appendChild(eventEl); + }); + group.appendChild(wrapper); + }); + return group; + } + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + renderStackedEvent(event, stackLevel) { + const element = this.createEventElement(event); + element.dataset.stackLink = JSON.stringify({ stackLevel }); + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + return element; + } +}; +__name(_EventRenderer, "EventRenderer"); +var EventRenderer = _EventRenderer; + +// src/v2/core/BaseGroupingRenderer.ts +var _BaseGroupingRenderer = class _BaseGroupingRenderer { + /** + * Main render method - handles common logic + */ + async render(context) { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) + return; + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter["date"]?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter((id) => childIds.includes(id)).length; + const colspan = childCount * dateCount; + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + this.renderHeader(entity, header, context); + context.headerContainer.appendChild(header); + } + } + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + renderHeader(entity, header, _context) { + header.textContent = this.getDisplayName(entity); + } + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + createHeader(entity, context) { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +}; +__name(_BaseGroupingRenderer, "BaseGroupingRenderer"); +var BaseGroupingRenderer = _BaseGroupingRenderer; + +// src/v2/features/resource/ResourceRenderer.ts +var _ResourceRenderer = class _ResourceRenderer extends BaseGroupingRenderer { + constructor(resourceService) { + super(); + this.resourceService = resourceService; + this.type = "resource"; + this.config = { + elementTag: "swp-resource-header", + idAttribute: "resourceId", + colspanVar: "--resource-cols" + }; + } + getEntities(ids) { + return this.resourceService.getByIds(ids); + } + getDisplayName(entity) { + return entity.displayName; + } + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context) { + const resourceIds = context.filter["resource"] || []; + const dateCount = context.filter["date"]?.length || 1; + let orderedResourceIds; + if (context.parentChildMap) { + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + const resources = await this.getEntities(orderedResourceIds); + const resourceMap = new Map(resources.map((r) => [r.id, r])); + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) + continue; + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +}; +__name(_ResourceRenderer, "ResourceRenderer"); +var ResourceRenderer = _ResourceRenderer; + +// src/v2/features/team/TeamRenderer.ts +var _TeamRenderer = class _TeamRenderer extends BaseGroupingRenderer { + constructor(teamService) { + super(); + this.teamService = teamService; + this.type = "team"; + this.config = { + elementTag: "swp-team-header", + idAttribute: "teamId", + colspanVar: "--team-cols" + }; + } + getEntities(ids) { + return this.teamService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_TeamRenderer, "TeamRenderer"); +var TeamRenderer = _TeamRenderer; + +// src/v2/features/timeaxis/TimeAxisRenderer.ts +var _TimeAxisRenderer = class _TimeAxisRenderer { + render(container, startHour = 6, endHour = 20) { + container.innerHTML = ""; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement("swp-hour-marker"); + marker.textContent = `${hour.toString().padStart(2, "0")}:00`; + container.appendChild(marker); + } + } +}; +__name(_TimeAxisRenderer, "TimeAxisRenderer"); +var TimeAxisRenderer = _TimeAxisRenderer; +export { + CalendarOrchestrator, + DateRenderer, + DateService, + EventRenderer, + NavigationAnimator, + ResourceRenderer, + TeamRenderer, + TimeAxisRenderer, + buildPipeline +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL2RheWpzL2RheWpzLm1pbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3V0Yy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3RpbWV6b25lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9kYXlqcy9wbHVnaW4vaXNvV2Vlay5qcyIsICIuLi8uLi9zcmMvdjIvY29yZS9SZW5kZXJCdWlsZGVyLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0ZpbHRlclRlbXBsYXRlLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL05hdmlnYXRpb25BbmltYXRvci50cyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL2NvcmUvRGF0ZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL3V0aWxzL1Bvc2l0aW9uVXRpbHMudHMiLCAiLi4vLi4vc3JjL3YyL2NvbnN0YW50cy9Db3JlRXZlbnRzLnRzIiwgIi4uLy4uL3NyYy92Mi9mZWF0dXJlcy9ldmVudC9FdmVudExheW91dEVuZ2luZS50cyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvZXZlbnQvRXZlbnRSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvdjIvY29yZS9CYXNlR3JvdXBpbmdSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvcmVzb3VyY2UvUmVzb3VyY2VSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvdGVhbS9UZWFtUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL2ZlYXR1cmVzL3RpbWVheGlzL1RpbWVBeGlzUmVuZGVyZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anM9ZSgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciB0PTFlMyxlPTZlNCxuPTM2ZTUscj1cIm1pbGxpc2Vjb25kXCIsaT1cInNlY29uZFwiLHM9XCJtaW51dGVcIix1PVwiaG91clwiLGE9XCJkYXlcIixvPVwid2Vla1wiLGM9XCJtb250aFwiLGY9XCJxdWFydGVyXCIsaD1cInllYXJcIixkPVwiZGF0ZVwiLGw9XCJJbnZhbGlkIERhdGVcIiwkPS9eKFxcZHs0fSlbLS9dPyhcXGR7MSwyfSk/Wy0vXT8oXFxkezAsMn0pW1R0XFxzXSooXFxkezEsMn0pPzo/KFxcZHsxLDJ9KT86PyhcXGR7MSwyfSk/Wy46XT8oXFxkKyk/JC8seT0vXFxbKFteXFxdXSspXXxZezEsNH18TXsxLDR9fER7MSwyfXxkezEsNH18SHsxLDJ9fGh7MSwyfXxhfEF8bXsxLDJ9fHN7MSwyfXxaezEsMn18U1NTL2csTT17bmFtZTpcImVuXCIsd2Vla2RheXM6XCJTdW5kYXlfTW9uZGF5X1R1ZXNkYXlfV2VkbmVzZGF5X1RodXJzZGF5X0ZyaWRheV9TYXR1cmRheVwiLnNwbGl0KFwiX1wiKSxtb250aHM6XCJKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyXCIuc3BsaXQoXCJfXCIpLG9yZGluYWw6ZnVuY3Rpb24odCl7dmFyIGU9W1widGhcIixcInN0XCIsXCJuZFwiLFwicmRcIl0sbj10JTEwMDtyZXR1cm5cIltcIit0KyhlWyhuLTIwKSUxMF18fGVbbl18fGVbMF0pK1wiXVwifX0sbT1mdW5jdGlvbih0LGUsbil7dmFyIHI9U3RyaW5nKHQpO3JldHVybiFyfHxyLmxlbmd0aD49ZT90OlwiXCIrQXJyYXkoZSsxLXIubGVuZ3RoKS5qb2luKG4pK3R9LHY9e3M6bSx6OmZ1bmN0aW9uKHQpe3ZhciBlPS10LnV0Y09mZnNldCgpLG49TWF0aC5hYnMoZSkscj1NYXRoLmZsb29yKG4vNjApLGk9biU2MDtyZXR1cm4oZTw9MD9cIitcIjpcIi1cIikrbShyLDIsXCIwXCIpK1wiOlwiK20oaSwyLFwiMFwiKX0sbTpmdW5jdGlvbiB0KGUsbil7aWYoZS5kYXRlKCk8bi5kYXRlKCkpcmV0dXJuLXQobixlKTt2YXIgcj0xMioobi55ZWFyKCktZS55ZWFyKCkpKyhuLm1vbnRoKCktZS5tb250aCgpKSxpPWUuY2xvbmUoKS5hZGQocixjKSxzPW4taTwwLHU9ZS5jbG9uZSgpLmFkZChyKyhzPy0xOjEpLGMpO3JldHVybisoLShyKyhuLWkpLyhzP2ktdTp1LWkpKXx8MCl9LGE6ZnVuY3Rpb24odCl7cmV0dXJuIHQ8MD9NYXRoLmNlaWwodCl8fDA6TWF0aC5mbG9vcih0KX0scDpmdW5jdGlvbih0KXtyZXR1cm57TTpjLHk6aCx3Om8sZDphLEQ6ZCxoOnUsbTpzLHM6aSxtczpyLFE6Zn1bdF18fFN0cmluZyh0fHxcIlwiKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL3MkLyxcIlwiKX0sdTpmdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dH19LGc9XCJlblwiLEQ9e307RFtnXT1NO3ZhciBwPVwiJGlzRGF5anNPYmplY3RcIixTPWZ1bmN0aW9uKHQpe3JldHVybiB0IGluc3RhbmNlb2YgX3x8ISghdHx8IXRbcF0pfSx3PWZ1bmN0aW9uIHQoZSxuLHIpe3ZhciBpO2lmKCFlKXJldHVybiBnO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgcz1lLnRvTG93ZXJDYXNlKCk7RFtzXSYmKGk9cyksbiYmKERbc109bixpPXMpO3ZhciB1PWUuc3BsaXQoXCItXCIpO2lmKCFpJiZ1Lmxlbmd0aD4xKXJldHVybiB0KHVbMF0pfWVsc2V7dmFyIGE9ZS5uYW1lO0RbYV09ZSxpPWF9cmV0dXJuIXImJmkmJihnPWkpLGl8fCFyJiZnfSxPPWZ1bmN0aW9uKHQsZSl7aWYoUyh0KSlyZXR1cm4gdC5jbG9uZSgpO3ZhciBuPVwib2JqZWN0XCI9PXR5cGVvZiBlP2U6e307cmV0dXJuIG4uZGF0ZT10LG4uYXJncz1hcmd1bWVudHMsbmV3IF8obil9LGI9djtiLmw9dyxiLmk9UyxiLnc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gTyh0LHtsb2NhbGU6ZS4kTCx1dGM6ZS4kdSx4OmUuJHgsJG9mZnNldDplLiRvZmZzZXR9KX07dmFyIF89ZnVuY3Rpb24oKXtmdW5jdGlvbiBNKHQpe3RoaXMuJEw9dyh0LmxvY2FsZSxudWxsLCEwKSx0aGlzLnBhcnNlKHQpLHRoaXMuJHg9dGhpcy4keHx8dC54fHx7fSx0aGlzW3BdPSEwfXZhciBtPU0ucHJvdG90eXBlO3JldHVybiBtLnBhcnNlPWZ1bmN0aW9uKHQpe3RoaXMuJGQ9ZnVuY3Rpb24odCl7dmFyIGU9dC5kYXRlLG49dC51dGM7aWYobnVsbD09PWUpcmV0dXJuIG5ldyBEYXRlKE5hTik7aWYoYi51KGUpKXJldHVybiBuZXcgRGF0ZTtpZihlIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gbmV3IERhdGUoZSk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUmJiEvWiQvaS50ZXN0KGUpKXt2YXIgcj1lLm1hdGNoKCQpO2lmKHIpe3ZhciBpPXJbMl0tMXx8MCxzPShyWzddfHxcIjBcIikuc3Vic3RyaW5nKDAsMyk7cmV0dXJuIG4/bmV3IERhdGUoRGF0ZS5VVEMoclsxXSxpLHJbM118fDEscls0XXx8MCxyWzVdfHwwLHJbNl18fDAscykpOm5ldyBEYXRlKHJbMV0saSxyWzNdfHwxLHJbNF18fDAscls1XXx8MCxyWzZdfHwwLHMpfX1yZXR1cm4gbmV3IERhdGUoZSl9KHQpLHRoaXMuaW5pdCgpfSxtLmluaXQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRNb250aCgpLHRoaXMuJEQ9dC5nZXREYXRlKCksdGhpcy4kVz10LmdldERheSgpLHRoaXMuJEg9dC5nZXRIb3VycygpLHRoaXMuJG09dC5nZXRNaW51dGVzKCksdGhpcy4kcz10LmdldFNlY29uZHMoKSx0aGlzLiRtcz10LmdldE1pbGxpc2Vjb25kcygpfSxtLiR1dGlscz1mdW5jdGlvbigpe3JldHVybiBifSxtLmlzVmFsaWQ9ZnVuY3Rpb24oKXtyZXR1cm4hKHRoaXMuJGQudG9TdHJpbmcoKT09PWwpfSxtLmlzU2FtZT1mdW5jdGlvbih0LGUpe3ZhciBuPU8odCk7cmV0dXJuIHRoaXMuc3RhcnRPZihlKTw9biYmbjw9dGhpcy5lbmRPZihlKX0sbS5pc0FmdGVyPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIE8odCk8dGhpcy5zdGFydE9mKGUpfSxtLmlzQmVmb3JlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuZW5kT2YoZSk8Tyh0KX0sbS4kZz1mdW5jdGlvbih0LGUsbil7cmV0dXJuIGIudSh0KT90aGlzW2VdOnRoaXMuc2V0KG4sdCl9LG0udW5peD1mdW5jdGlvbigpe3JldHVybiBNYXRoLmZsb29yKHRoaXMudmFsdWVPZigpLzFlMyl9LG0udmFsdWVPZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLmdldFRpbWUoKX0sbS5zdGFydE9mPWZ1bmN0aW9uKHQsZSl7dmFyIG49dGhpcyxyPSEhYi51KGUpfHxlLGY9Yi5wKHQpLGw9ZnVuY3Rpb24odCxlKXt2YXIgaT1iLncobi4kdT9EYXRlLlVUQyhuLiR5LGUsdCk6bmV3IERhdGUobi4keSxlLHQpLG4pO3JldHVybiByP2k6aS5lbmRPZihhKX0sJD1mdW5jdGlvbih0LGUpe3JldHVybiBiLncobi50b0RhdGUoKVt0XS5hcHBseShuLnRvRGF0ZShcInNcIiksKHI/WzAsMCwwLDBdOlsyMyw1OSw1OSw5OTldKS5zbGljZShlKSksbil9LHk9dGhpcy4kVyxNPXRoaXMuJE0sbT10aGlzLiRELHY9XCJzZXRcIisodGhpcy4kdT9cIlVUQ1wiOlwiXCIpO3N3aXRjaChmKXtjYXNlIGg6cmV0dXJuIHI/bCgxLDApOmwoMzEsMTEpO2Nhc2UgYzpyZXR1cm4gcj9sKDEsTSk6bCgwLE0rMSk7Y2FzZSBvOnZhciBnPXRoaXMuJGxvY2FsZSgpLndlZWtTdGFydHx8MCxEPSh5PGc/eSs3OnkpLWc7cmV0dXJuIGwocj9tLUQ6bSsoNi1EKSxNKTtjYXNlIGE6Y2FzZSBkOnJldHVybiAkKHYrXCJIb3Vyc1wiLDApO2Nhc2UgdTpyZXR1cm4gJCh2K1wiTWludXRlc1wiLDEpO2Nhc2UgczpyZXR1cm4gJCh2K1wiU2Vjb25kc1wiLDIpO2Nhc2UgaTpyZXR1cm4gJCh2K1wiTWlsbGlzZWNvbmRzXCIsMyk7ZGVmYXVsdDpyZXR1cm4gdGhpcy5jbG9uZSgpfX0sbS5lbmRPZj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5zdGFydE9mKHQsITEpfSxtLiRzZXQ9ZnVuY3Rpb24odCxlKXt2YXIgbixvPWIucCh0KSxmPVwic2V0XCIrKHRoaXMuJHU/XCJVVENcIjpcIlwiKSxsPShuPXt9LG5bYV09ZitcIkRhdGVcIixuW2RdPWYrXCJEYXRlXCIsbltjXT1mK1wiTW9udGhcIixuW2hdPWYrXCJGdWxsWWVhclwiLG5bdV09ZitcIkhvdXJzXCIsbltzXT1mK1wiTWludXRlc1wiLG5baV09ZitcIlNlY29uZHNcIixuW3JdPWYrXCJNaWxsaXNlY29uZHNcIixuKVtvXSwkPW89PT1hP3RoaXMuJEQrKGUtdGhpcy4kVyk6ZTtpZihvPT09Y3x8bz09PWgpe3ZhciB5PXRoaXMuY2xvbmUoKS5zZXQoZCwxKTt5LiRkW2xdKCQpLHkuaW5pdCgpLHRoaXMuJGQ9eS5zZXQoZCxNYXRoLm1pbih0aGlzLiRELHkuZGF5c0luTW9udGgoKSkpLiRkfWVsc2UgbCYmdGhpcy4kZFtsXSgkKTtyZXR1cm4gdGhpcy5pbml0KCksdGhpc30sbS5zZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5jbG9uZSgpLiRzZXQodCxlKX0sbS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXNbYi5wKHQpXSgpfSxtLmFkZD1mdW5jdGlvbihyLGYpe3ZhciBkLGw9dGhpcztyPU51bWJlcihyKTt2YXIgJD1iLnAoZikseT1mdW5jdGlvbih0KXt2YXIgZT1PKGwpO3JldHVybiBiLncoZS5kYXRlKGUuZGF0ZSgpK01hdGgucm91bmQodCpyKSksbCl9O2lmKCQ9PT1jKXJldHVybiB0aGlzLnNldChjLHRoaXMuJE0rcik7aWYoJD09PWgpcmV0dXJuIHRoaXMuc2V0KGgsdGhpcy4keStyKTtpZigkPT09YSlyZXR1cm4geSgxKTtpZigkPT09bylyZXR1cm4geSg3KTt2YXIgTT0oZD17fSxkW3NdPWUsZFt1XT1uLGRbaV09dCxkKVskXXx8MSxtPXRoaXMuJGQuZ2V0VGltZSgpK3IqTTtyZXR1cm4gYi53KG0sdGhpcyl9LG0uc3VidHJhY3Q9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5hZGQoLTEqdCxlKX0sbS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxuPXRoaXMuJGxvY2FsZSgpO2lmKCF0aGlzLmlzVmFsaWQoKSlyZXR1cm4gbi5pbnZhbGlkRGF0ZXx8bDt2YXIgcj10fHxcIllZWVktTU0tRERUSEg6bW06c3NaXCIsaT1iLnoodGhpcykscz10aGlzLiRILHU9dGhpcy4kbSxhPXRoaXMuJE0sbz1uLndlZWtkYXlzLGM9bi5tb250aHMsZj1uLm1lcmlkaWVtLGg9ZnVuY3Rpb24odCxuLGkscyl7cmV0dXJuIHQmJih0W25dfHx0KGUscikpfHxpW25dLnNsaWNlKDAscyl9LGQ9ZnVuY3Rpb24odCl7cmV0dXJuIGIucyhzJTEyfHwxMix0LFwiMFwiKX0sJD1mfHxmdW5jdGlvbih0LGUsbil7dmFyIHI9dDwxMj9cIkFNXCI6XCJQTVwiO3JldHVybiBuP3IudG9Mb3dlckNhc2UoKTpyfTtyZXR1cm4gci5yZXBsYWNlKHksKGZ1bmN0aW9uKHQscil7cmV0dXJuIHJ8fGZ1bmN0aW9uKHQpe3N3aXRjaCh0KXtjYXNlXCJZWVwiOnJldHVybiBTdHJpbmcoZS4keSkuc2xpY2UoLTIpO2Nhc2VcIllZWVlcIjpyZXR1cm4gYi5zKGUuJHksNCxcIjBcIik7Y2FzZVwiTVwiOnJldHVybiBhKzE7Y2FzZVwiTU1cIjpyZXR1cm4gYi5zKGErMSwyLFwiMFwiKTtjYXNlXCJNTU1cIjpyZXR1cm4gaChuLm1vbnRoc1Nob3J0LGEsYywzKTtjYXNlXCJNTU1NXCI6cmV0dXJuIGgoYyxhKTtjYXNlXCJEXCI6cmV0dXJuIGUuJEQ7Y2FzZVwiRERcIjpyZXR1cm4gYi5zKGUuJEQsMixcIjBcIik7Y2FzZVwiZFwiOnJldHVybiBTdHJpbmcoZS4kVyk7Y2FzZVwiZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzTWluLGUuJFcsbywyKTtjYXNlXCJkZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzU2hvcnQsZS4kVyxvLDMpO2Nhc2VcImRkZGRcIjpyZXR1cm4gb1tlLiRXXTtjYXNlXCJIXCI6cmV0dXJuIFN0cmluZyhzKTtjYXNlXCJISFwiOnJldHVybiBiLnMocywyLFwiMFwiKTtjYXNlXCJoXCI6cmV0dXJuIGQoMSk7Y2FzZVwiaGhcIjpyZXR1cm4gZCgyKTtjYXNlXCJhXCI6cmV0dXJuICQocyx1LCEwKTtjYXNlXCJBXCI6cmV0dXJuICQocyx1LCExKTtjYXNlXCJtXCI6cmV0dXJuIFN0cmluZyh1KTtjYXNlXCJtbVwiOnJldHVybiBiLnModSwyLFwiMFwiKTtjYXNlXCJzXCI6cmV0dXJuIFN0cmluZyhlLiRzKTtjYXNlXCJzc1wiOnJldHVybiBiLnMoZS4kcywyLFwiMFwiKTtjYXNlXCJTU1NcIjpyZXR1cm4gYi5zKGUuJG1zLDMsXCIwXCIpO2Nhc2VcIlpcIjpyZXR1cm4gaX1yZXR1cm4gbnVsbH0odCl8fGkucmVwbGFjZShcIjpcIixcIlwiKX0pKX0sbS51dGNPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4gMTUqLU1hdGgucm91bmQodGhpcy4kZC5nZXRUaW1lem9uZU9mZnNldCgpLzE1KX0sbS5kaWZmPWZ1bmN0aW9uKHIsZCxsKXt2YXIgJCx5PXRoaXMsTT1iLnAoZCksbT1PKHIpLHY9KG0udXRjT2Zmc2V0KCktdGhpcy51dGNPZmZzZXQoKSkqZSxnPXRoaXMtbSxEPWZ1bmN0aW9uKCl7cmV0dXJuIGIubSh5LG0pfTtzd2l0Y2goTSl7Y2FzZSBoOiQ9RCgpLzEyO2JyZWFrO2Nhc2UgYzokPUQoKTticmVhaztjYXNlIGY6JD1EKCkvMzticmVhaztjYXNlIG86JD0oZy12KS82MDQ4ZTU7YnJlYWs7Y2FzZSBhOiQ9KGctdikvODY0ZTU7YnJlYWs7Y2FzZSB1OiQ9Zy9uO2JyZWFrO2Nhc2UgczokPWcvZTticmVhaztjYXNlIGk6JD1nL3Q7YnJlYWs7ZGVmYXVsdDokPWd9cmV0dXJuIGw/JDpiLmEoJCl9LG0uZGF5c0luTW9udGg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbmRPZihjKS4kRH0sbS4kbG9jYWxlPWZ1bmN0aW9uKCl7cmV0dXJuIERbdGhpcy4kTF19LG0ubG9jYWxlPWZ1bmN0aW9uKHQsZSl7aWYoIXQpcmV0dXJuIHRoaXMuJEw7dmFyIG49dGhpcy5jbG9uZSgpLHI9dyh0LGUsITApO3JldHVybiByJiYobi4kTD1yKSxufSxtLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIGIudyh0aGlzLiRkLHRoaXMpfSxtLnRvRGF0ZT1mdW5jdGlvbigpe3JldHVybiBuZXcgRGF0ZSh0aGlzLnZhbHVlT2YoKSl9LG0udG9KU09OPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaXNWYWxpZCgpP3RoaXMudG9JU09TdHJpbmcoKTpudWxsfSxtLnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGQudG9JU09TdHJpbmcoKX0sbS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLnRvVVRDU3RyaW5nKCl9LE19KCksaz1fLnByb3RvdHlwZTtyZXR1cm4gTy5wcm90b3R5cGU9ayxbW1wiJG1zXCIscl0sW1wiJHNcIixpXSxbXCIkbVwiLHNdLFtcIiRIXCIsdV0sW1wiJFdcIixhXSxbXCIkTVwiLGNdLFtcIiR5XCIsaF0sW1wiJERcIixkXV0uZm9yRWFjaCgoZnVuY3Rpb24odCl7a1t0WzFdXT1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy4kZyhlLHRbMF0sdFsxXSl9fSkpLE8uZXh0ZW5kPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuJGl8fCh0KGUsXyxPKSx0LiRpPSEwKSxPfSxPLmxvY2FsZT13LE8uaXNEYXlqcz1TLE8udW5peD1mdW5jdGlvbih0KXtyZXR1cm4gTygxZTMqdCl9LE8uZW49RFtnXSxPLkxzPUQsTy5wPXt9LE99KSk7IiwgIiFmdW5jdGlvbih0LGkpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWkoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGkpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3V0Yz1pKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHQ9XCJtaW51dGVcIixpPS9bKy1dXFxkXFxkKD86Oj9cXGRcXGQpPy9nLGU9LyhbKy1dfFxcZFxcZCkvZztyZXR1cm4gZnVuY3Rpb24ocyxmLG4pe3ZhciB1PWYucHJvdG90eXBlO24udXRjPWZ1bmN0aW9uKHQpe3ZhciBpPXtkYXRlOnQsdXRjOiEwLGFyZ3M6YXJndW1lbnRzfTtyZXR1cm4gbmV3IGYoaSl9LHUudXRjPWZ1bmN0aW9uKGkpe3ZhciBlPW4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiEwfSk7cmV0dXJuIGk/ZS5hZGQodGhpcy51dGNPZmZzZXQoKSx0KTplfSx1LmxvY2FsPWZ1bmN0aW9uKCl7cmV0dXJuIG4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiExfSl9O3ZhciByPXUucGFyc2U7dS5wYXJzZT1mdW5jdGlvbih0KXt0LnV0YyYmKHRoaXMuJHU9ITApLHRoaXMuJHV0aWxzKCkudSh0LiRvZmZzZXQpfHwodGhpcy4kb2Zmc2V0PXQuJG9mZnNldCksci5jYWxsKHRoaXMsdCl9O3ZhciBvPXUuaW5pdDt1LmluaXQ9ZnVuY3Rpb24oKXtpZih0aGlzLiR1KXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRVVENGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRVVENNb250aCgpLHRoaXMuJEQ9dC5nZXRVVENEYXRlKCksdGhpcy4kVz10LmdldFVUQ0RheSgpLHRoaXMuJEg9dC5nZXRVVENIb3VycygpLHRoaXMuJG09dC5nZXRVVENNaW51dGVzKCksdGhpcy4kcz10LmdldFVUQ1NlY29uZHMoKSx0aGlzLiRtcz10LmdldFVUQ01pbGxpc2Vjb25kcygpfWVsc2Ugby5jYWxsKHRoaXMpfTt2YXIgYT11LnV0Y09mZnNldDt1LnV0Y09mZnNldD1mdW5jdGlvbihzLGYpe3ZhciBuPXRoaXMuJHV0aWxzKCkudTtpZihuKHMpKXJldHVybiB0aGlzLiR1PzA6bih0aGlzLiRvZmZzZXQpP2EuY2FsbCh0aGlzKTp0aGlzLiRvZmZzZXQ7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHMmJihzPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PVwiXCIpO3ZhciBzPXQubWF0Y2goaSk7aWYoIXMpcmV0dXJuIG51bGw7dmFyIGY9KFwiXCIrc1swXSkubWF0Y2goZSl8fFtcIi1cIiwwLDBdLG49ZlswXSx1PTYwKitmWzFdKyArZlsyXTtyZXR1cm4gMD09PXU/MDpcIitcIj09PW4/dTotdX0ocyksbnVsbD09PXMpKXJldHVybiB0aGlzO3ZhciB1PU1hdGguYWJzKHMpPD0xNj82MCpzOnM7aWYoMD09PXUpcmV0dXJuIHRoaXMudXRjKGYpO3ZhciByPXRoaXMuY2xvbmUoKTtpZihmKXJldHVybiByLiRvZmZzZXQ9dSxyLiR1PSExLHI7dmFyIG89dGhpcy4kdT90aGlzLnRvRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCk6LTEqdGhpcy51dGNPZmZzZXQoKTtyZXR1cm4ocj10aGlzLmxvY2FsKCkuYWRkKHUrbyx0KSkuJG9mZnNldD11LHIuJHguJGxvY2FsT2Zmc2V0PW8scn07dmFyIGg9dS5mb3JtYXQ7dS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGk9dHx8KHRoaXMuJHU/XCJZWVlZLU1NLUREVEhIOm1tOnNzW1pdXCI6XCJcIik7cmV0dXJuIGguY2FsbCh0aGlzLGkpfSx1LnZhbHVlT2Y9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiR1dGlscygpLnUodGhpcy4kb2Zmc2V0KT8wOnRoaXMuJG9mZnNldCsodGhpcy4keC4kbG9jYWxPZmZzZXR8fHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7cmV0dXJuIHRoaXMuJGQudmFsdWVPZigpLTZlNCp0fSx1LmlzVVRDPWZ1bmN0aW9uKCl7cmV0dXJuISF0aGlzLiR1fSx1LnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudG9EYXRlKCkudG9JU09TdHJpbmcoKX0sdS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRvRGF0ZSgpLnRvVVRDU3RyaW5nKCl9O3ZhciBsPXUudG9EYXRlO3UudG9EYXRlPWZ1bmN0aW9uKHQpe3JldHVyblwic1wiPT09dCYmdGhpcy4kb2Zmc2V0P24odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSkudG9EYXRlKCk6bC5jYWxsKHRoaXMpfTt2YXIgYz11LmRpZmY7dS5kaWZmPWZ1bmN0aW9uKHQsaSxlKXtpZih0JiZ0aGlzLiR1PT09dC4kdSlyZXR1cm4gYy5jYWxsKHRoaXMsdCxpLGUpO3ZhciBzPXRoaXMubG9jYWwoKSxmPW4odCkubG9jYWwoKTtyZXR1cm4gYy5jYWxsKHMsZixpLGUpfX19KSk7IiwgIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3RpbWV6b25lPWUoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgdD17eWVhcjowLG1vbnRoOjEsZGF5OjIsaG91cjozLG1pbnV0ZTo0LHNlY29uZDo1fSxlPXt9O3JldHVybiBmdW5jdGlvbihuLGksbyl7dmFyIHIsYT1mdW5jdGlvbih0LG4saSl7dm9pZCAwPT09aSYmKGk9e30pO3ZhciBvPW5ldyBEYXRlKHQpLHI9ZnVuY3Rpb24odCxuKXt2b2lkIDA9PT1uJiYobj17fSk7dmFyIGk9bi50aW1lWm9uZU5hbWV8fFwic2hvcnRcIixvPXQrXCJ8XCIraSxyPWVbb107cmV0dXJuIHJ8fChyPW5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KFwiZW4tVVNcIix7aG91cjEyOiExLHRpbWVab25lOnQseWVhcjpcIm51bWVyaWNcIixtb250aDpcIjItZGlnaXRcIixkYXk6XCIyLWRpZ2l0XCIsaG91cjpcIjItZGlnaXRcIixtaW51dGU6XCIyLWRpZ2l0XCIsc2Vjb25kOlwiMi1kaWdpdFwiLHRpbWVab25lTmFtZTppfSksZVtvXT1yKSxyfShuLGkpO3JldHVybiByLmZvcm1hdFRvUGFydHMobyl9LHU9ZnVuY3Rpb24oZSxuKXtmb3IodmFyIGk9YShlLG4pLHI9W10sdT0wO3U8aS5sZW5ndGg7dSs9MSl7dmFyIGY9aVt1XSxzPWYudHlwZSxtPWYudmFsdWUsYz10W3NdO2M+PTAmJihyW2NdPXBhcnNlSW50KG0sMTApKX12YXIgZD1yWzNdLGw9MjQ9PT1kPzA6ZCxoPXJbMF0rXCItXCIrclsxXStcIi1cIityWzJdK1wiIFwiK2wrXCI6XCIrcls0XStcIjpcIityWzVdK1wiOjAwMFwiLHY9K2U7cmV0dXJuKG8udXRjKGgpLnZhbHVlT2YoKS0odi09diUxZTMpKS82ZTR9LGY9aS5wcm90b3R5cGU7Zi50ej1mdW5jdGlvbih0LGUpe3ZvaWQgMD09PXQmJih0PXIpO3ZhciBuLGk9dGhpcy51dGNPZmZzZXQoKSxhPXRoaXMudG9EYXRlKCksdT1hLnRvTG9jYWxlU3RyaW5nKFwiZW4tVVNcIix7dGltZVpvbmU6dH0pLGY9TWF0aC5yb3VuZCgoYS1uZXcgRGF0ZSh1KSkvMWUzLzYwKSxzPTE1Ki1NYXRoLnJvdW5kKGEuZ2V0VGltZXpvbmVPZmZzZXQoKS8xNSktZjtpZighTnVtYmVyKHMpKW49dGhpcy51dGNPZmZzZXQoMCxlKTtlbHNlIGlmKG49byh1LHtsb2NhbGU6dGhpcy4kTH0pLiRzZXQoXCJtaWxsaXNlY29uZFwiLHRoaXMuJG1zKS51dGNPZmZzZXQocywhMCksZSl7dmFyIG09bi51dGNPZmZzZXQoKTtuPW4uYWRkKGktbSxcIm1pbnV0ZVwiKX1yZXR1cm4gbi4keC4kdGltZXpvbmU9dCxufSxmLm9mZnNldE5hbWU9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy4keC4kdGltZXpvbmV8fG8udHouZ3Vlc3MoKSxuPWEodGhpcy52YWx1ZU9mKCksZSx7dGltZVpvbmVOYW1lOnR9KS5maW5kKChmdW5jdGlvbih0KXtyZXR1cm5cInRpbWV6b25lbmFtZVwiPT09dC50eXBlLnRvTG93ZXJDYXNlKCl9KSk7cmV0dXJuIG4mJm4udmFsdWV9O3ZhciBzPWYuc3RhcnRPZjtmLnN0YXJ0T2Y9ZnVuY3Rpb24odCxlKXtpZighdGhpcy4keHx8IXRoaXMuJHguJHRpbWV6b25lKXJldHVybiBzLmNhbGwodGhpcyx0LGUpO3ZhciBuPW8odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSx7bG9jYWxlOnRoaXMuJEx9KTtyZXR1cm4gcy5jYWxsKG4sdCxlKS50eih0aGlzLiR4LiR0aW1lem9uZSwhMCl9LG8udHo9ZnVuY3Rpb24odCxlLG4pe3ZhciBpPW4mJmUsYT1ufHxlfHxyLGY9dSgrbygpLGEpO2lmKFwic3RyaW5nXCIhPXR5cGVvZiB0KXJldHVybiBvKHQpLnR6KGEpO3ZhciBzPWZ1bmN0aW9uKHQsZSxuKXt2YXIgaT10LTYwKmUqMWUzLG89dShpLG4pO2lmKGU9PT1vKXJldHVybltpLGVdO3ZhciByPXUoaS09NjAqKG8tZSkqMWUzLG4pO3JldHVybiBvPT09cj9baSxvXTpbdC02MCpNYXRoLm1pbihvLHIpKjFlMyxNYXRoLm1heChvLHIpXX0oby51dGModCxpKS52YWx1ZU9mKCksZixhKSxtPXNbMF0sYz1zWzFdLGQ9byhtKS51dGNPZmZzZXQoYyk7cmV0dXJuIGQuJHguJHRpbWV6b25lPWEsZH0sby50ei5ndWVzcz1mdW5jdGlvbigpe3JldHVybiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmV9LG8udHouc2V0RGVmYXVsdD1mdW5jdGlvbih0KXtyPXR9fX0pKTsiLCAiIWZ1bmN0aW9uKGUsdCl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9dCgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUodCk6KGU9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczplfHxzZWxmKS5kYXlqc19wbHVnaW5faXNvV2Vlaz10KCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGU9XCJkYXlcIjtyZXR1cm4gZnVuY3Rpb24odCxpLHMpe3ZhciBhPWZ1bmN0aW9uKHQpe3JldHVybiB0LmFkZCg0LXQuaXNvV2Vla2RheSgpLGUpfSxkPWkucHJvdG90eXBlO2QuaXNvV2Vla1llYXI9ZnVuY3Rpb24oKXtyZXR1cm4gYSh0aGlzKS55ZWFyKCl9LGQuaXNvV2Vlaz1mdW5jdGlvbih0KXtpZighdGhpcy4kdXRpbHMoKS51KHQpKXJldHVybiB0aGlzLmFkZCg3Kih0LXRoaXMuaXNvV2VlaygpKSxlKTt2YXIgaSxkLG4sbyxyPWEodGhpcyksdT0oaT10aGlzLmlzb1dlZWtZZWFyKCksZD10aGlzLiR1LG49KGQ/cy51dGM6cykoKS55ZWFyKGkpLnN0YXJ0T2YoXCJ5ZWFyXCIpLG89NC1uLmlzb1dlZWtkYXkoKSxuLmlzb1dlZWtkYXkoKT40JiYobys9Nyksbi5hZGQobyxlKSk7cmV0dXJuIHIuZGlmZih1LFwid2Vla1wiKSsxfSxkLmlzb1dlZWtkYXk9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuJHV0aWxzKCkudShlKT90aGlzLmRheSgpfHw3OnRoaXMuZGF5KHRoaXMuZGF5KCklNz9lOmUtNyl9O3ZhciBuPWQuc3RhcnRPZjtkLnN0YXJ0T2Y9ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLiR1dGlscygpLHM9ISFpLnUodCl8fHQ7cmV0dXJuXCJpc293ZWVrXCI9PT1pLnAoZSk/cz90aGlzLmRhdGUodGhpcy5kYXRlKCktKHRoaXMuaXNvV2Vla2RheSgpLTEpKS5zdGFydE9mKFwiZGF5XCIpOnRoaXMuZGF0ZSh0aGlzLmRhdGUoKS0xLSh0aGlzLmlzb1dlZWtkYXkoKS0xKSs3KS5lbmRPZihcImRheVwiKTpuLmJpbmQodGhpcykoZSx0KX19fSkpOyIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi9JR3JvdXBpbmdSZW5kZXJlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmUge1xuICBydW4oY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQaXBlbGluZShyZW5kZXJlcnM6IElSZW5kZXJlcltdKTogUGlwZWxpbmUge1xuICByZXR1cm4ge1xuICAgIGFzeW5jIHJ1bihjb250ZXh0OiBJUmVuZGVyQ29udGV4dCkge1xuICAgICAgZm9yIChjb25zdCByZW5kZXJlciBvZiByZW5kZXJlcnMpIHtcbiAgICAgICAgYXdhaXQgcmVuZGVyZXIucmVuZGVyKGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCB9IGZyb20gJy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBEYXRlU2VydmljZSB9IGZyb20gJy4vRGF0ZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJRW50aXR5UmVzb2x2ZXIgfSBmcm9tICcuL0lFbnRpdHlSZXNvbHZlcic7XHJcblxyXG4vKipcclxuICogRmllbGQgZGVmaW5pdGlvbiBmb3IgRmlsdGVyVGVtcGxhdGVcclxuICovXHJcbmludGVyZmFjZSBJRmlsdGVyRmllbGQge1xyXG4gIGlkUHJvcGVydHk6IHN0cmluZztcclxuICBkZXJpdmVkRnJvbT86IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIFBhcnNlZCBkb3Qtbm90YXRpb24gcmVmZXJlbmNlXHJcbiAqL1xyXG5pbnRlcmZhY2UgSURvdE5vdGF0aW9uIHtcclxuICBlbnRpdHlUeXBlOiBzdHJpbmc7ICAgLy8gZS5nLiwgJ3Jlc291cmNlJ1xyXG4gIHByb3BlcnR5OiBzdHJpbmc7ICAgICAvLyBlLmcuLCAndGVhbUlkJ1xyXG4gIGZvcmVpZ25LZXk6IHN0cmluZzsgICAvLyBlLmcuLCAncmVzb3VyY2VJZCdcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbHRlclRlbXBsYXRlIC0gQnlnZ2VyIG5cdTAwRjhnbGVyIHRpbCBldmVudC1rb2xvbm5lIG1hdGNoaW5nXHJcbiAqXHJcbiAqIFZpZXdDb25maWcgZGVmaW5lcmVyIGh2aWxrZSBmZWx0ZXIgKGlkUHJvcGVydGllcykgZGVyIGluZGdcdTAwRTVyIGkga29sb25uZW5zIG5cdTAwRjhnbGUuXHJcbiAqIFNhbW1lIHRlbXBsYXRlIGJydWdlcyB0aWwgYXQgYnlnZ2Ugblx1MDBGOGdsZSBmb3IgYlx1MDBFNWRlIGtvbG9ubmUgb2cgZXZlbnQuXHJcbiAqXHJcbiAqIFN1cHBvcnRzIGRvdC1ub3RhdGlvbiBmb3IgaGllcmFyY2hpY2FsIHJlbGF0aW9uczpcclxuICogLSAncmVzb3VyY2UudGVhbUlkJyBcdTIxOTIgbG9va3MgdXAgZXZlbnQucmVzb3VyY2VJZCBcdTIxOTIgcmVzb3VyY2UgZW50aXR5IFx1MjE5MiB0ZWFtSWRcclxuICpcclxuICogUHJpbmNpcDogS29sb25uZW5zIG5cdTAwRjhnbGUtdGVtcGxhdGUgYmVzdGVtbWVyIGh2YWQgZGVyIG1hdGNoZXMgcFx1MDBFNS5cclxuICpcclxuICogQHNlZSBkb2NzL2ZpbHRlci10ZW1wbGF0ZS5tZFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEZpbHRlclRlbXBsYXRlIHtcclxuICBwcml2YXRlIGZpZWxkczogSUZpbHRlckZpZWxkW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGRhdGVTZXJ2aWNlOiBEYXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgZW50aXR5UmVzb2x2ZXI/OiBJRW50aXR5UmVzb2x2ZXJcclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRpbGZcdTAwRjhqIGZlbHQgdGlsIHRlbXBsYXRlXHJcbiAgICogQHBhcmFtIGlkUHJvcGVydHkgLSBQcm9wZXJ0eS1uYXZuIChicnVnZXMgcFx1MDBFNSBiXHUwMEU1ZGUgZXZlbnQgb2cgY29sdW1uLmRhdGFzZXQpXHJcbiAgICogQHBhcmFtIGRlcml2ZWRGcm9tIC0gSHZpcyBmZWx0ZXQgdWRsZWRlcyBmcmEgYW5kZW4gcHJvcGVydHkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgKi9cclxuICBhZGRGaWVsZChpZFByb3BlcnR5OiBzdHJpbmcsIGRlcml2ZWRGcm9tPzogc3RyaW5nKTogdGhpcyB7XHJcbiAgICB0aGlzLmZpZWxkcy5wdXNoKHsgaWRQcm9wZXJ0eSwgZGVyaXZlZEZyb20gfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGRvdC1ub3RhdGlvbiBzdHJpbmcgaW50byBjb21wb25lbnRzXHJcbiAgICogQGV4YW1wbGUgJ3Jlc291cmNlLnRlYW1JZCcgXHUyMTkyIHsgZW50aXR5VHlwZTogJ3Jlc291cmNlJywgcHJvcGVydHk6ICd0ZWFtSWQnLCBmb3JlaWduS2V5OiAncmVzb3VyY2VJZCcgfVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5OiBzdHJpbmcpOiBJRG90Tm90YXRpb24gfCBudWxsIHtcclxuICAgIGlmICghaWRQcm9wZXJ0eS5pbmNsdWRlcygnLicpKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IFtlbnRpdHlUeXBlLCBwcm9wZXJ0eV0gPSBpZFByb3BlcnR5LnNwbGl0KCcuJyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBlbnRpdHlUeXBlLFxyXG4gICAgICBwcm9wZXJ0eSxcclxuICAgICAgZm9yZWlnbktleTogZW50aXR5VHlwZSArICdJZCcgLy8gQ29udmVudGlvbjogcmVzb3VyY2UgXHUyMTkyIHJlc291cmNlSWRcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgZGF0YXNldCBrZXkgZm9yIGNvbHVtbiBsb29rdXBcclxuICAgKiBGb3IgZG90LW5vdGF0aW9uICdyZXNvdXJjZS50ZWFtSWQnLCB3ZSBsb29rIGZvciAndGVhbUlkJyBpbiBkYXRhc2V0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXREYXRhc2V0S2V5KGlkUHJvcGVydHk6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkb3ROb3RhdGlvbiA9IHRoaXMucGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5KTtcclxuICAgIGlmIChkb3ROb3RhdGlvbikge1xyXG4gICAgICByZXR1cm4gZG90Tm90YXRpb24ucHJvcGVydHk7IC8vICd0ZWFtSWQnXHJcbiAgICB9XHJcbiAgICByZXR1cm4gaWRQcm9wZXJ0eTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ5ZyBuXHUwMEY4Z2xlIGZyYSBrb2xvbm5lXHJcbiAgICogTFx1MDBFNnNlciB2XHUwMEU2cmRpZXIgZnJhIGNvbHVtbi5kYXRhc2V0W2lkUHJvcGVydHldXHJcbiAgICogRm9yIGRvdC1ub3RhdGlvbiwgdXNlcyB0aGUgcHJvcGVydHkgcGFydCAocmVzb3VyY2UudGVhbUlkIFx1MjE5MiB0ZWFtSWQpXHJcbiAgICovXHJcbiAgYnVpbGRLZXlGcm9tQ29sdW1uKGNvbHVtbjogSFRNTEVsZW1lbnQpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXREYXRhc2V0S2V5KGYuaWRQcm9wZXJ0eSk7XHJcbiAgICAgICAgcmV0dXJuIGNvbHVtbi5kYXRhc2V0W2tleV0gfHwgJyc7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBCeWcgblx1MDBGOGdsZSBmcmEgZXZlbnRcclxuICAgKiBMXHUwMEU2c2VyIHZcdTAwRTZyZGllciBmcmEgZXZlbnRbaWRQcm9wZXJ0eV0gZWxsZXIgdWRsZWRlciBmcmEgZGVyaXZlZEZyb21cclxuICAgKiBGb3IgZG90LW5vdGF0aW9uLCByZXNvbHZlcyB2aWEgRW50aXR5UmVzb2x2ZXJcclxuICAgKi9cclxuICBidWlsZEtleUZyb21FdmVudChldmVudDogSUNhbGVuZGFyRXZlbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgIGNvbnN0IGV2ZW50UmVjb3JkID0gZXZlbnQgYXMgYW55O1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgLy8gQ2hlY2sgZm9yIGRvdC1ub3RhdGlvbiAoZS5nLiwgJ3Jlc291cmNlLnRlYW1JZCcpXHJcbiAgICAgICAgY29uc3QgZG90Tm90YXRpb24gPSB0aGlzLnBhcnNlRG90Tm90YXRpb24oZi5pZFByb3BlcnR5KTtcclxuICAgICAgICBpZiAoZG90Tm90YXRpb24pIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVEb3ROb3RhdGlvbihldmVudFJlY29yZCwgZG90Tm90YXRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGYuZGVyaXZlZEZyb20pIHtcclxuICAgICAgICAgIC8vIFVkbGVkIHZcdTAwRTZyZGkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gZXZlbnRSZWNvcmRbZi5kZXJpdmVkRnJvbV07XHJcbiAgICAgICAgICBpZiAoc291cmNlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGVTZXJ2aWNlLmdldERhdGVLZXkoc291cmNlVmFsdWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIFN0cmluZyhzb3VyY2VWYWx1ZSB8fCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBTdHJpbmcoZXZlbnRSZWNvcmRbZi5pZFByb3BlcnR5XSB8fCAnJyk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGRvdC1ub3RhdGlvbiByZWZlcmVuY2UgdmlhIEVudGl0eVJlc29sdmVyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXNvbHZlRG90Tm90YXRpb24oZXZlbnRSZWNvcmQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBkb3ROb3RhdGlvbjogSURvdE5vdGF0aW9uKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHlSZXNvbHZlcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oYEZpbHRlclRlbXBsYXRlOiBFbnRpdHlSZXNvbHZlciByZXF1aXJlZCBmb3IgZG90LW5vdGF0aW9uICcke2RvdE5vdGF0aW9uLmVudGl0eVR5cGV9LiR7ZG90Tm90YXRpb24ucHJvcGVydHl9J2ApO1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGZvcmVpZ24ga2V5IHZhbHVlIGZyb20gZXZlbnQgKGUuZy4sIHJlc291cmNlSWQpXHJcbiAgICBjb25zdCBmb3JlaWduSWQgPSBldmVudFJlY29yZFtkb3ROb3RhdGlvbi5mb3JlaWduS2V5XTtcclxuICAgIGlmICghZm9yZWlnbklkKSByZXR1cm4gJyc7XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBlbnRpdHlcclxuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5UmVzb2x2ZXIucmVzb2x2ZShkb3ROb3RhdGlvbi5lbnRpdHlUeXBlLCBTdHJpbmcoZm9yZWlnbklkKSk7XHJcbiAgICBpZiAoIWVudGl0eSkgcmV0dXJuICcnO1xyXG5cclxuICAgIC8vIFJldHVybiBwcm9wZXJ0eSB2YWx1ZSBmcm9tIGVudGl0eVxyXG4gICAgcmV0dXJuIFN0cmluZyhlbnRpdHlbZG90Tm90YXRpb24ucHJvcGVydHldIHx8ICcnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hdGNoIGV2ZW50IG1vZCBrb2xvbm5lXHJcbiAgICovXHJcbiAgbWF0Y2hlcyhldmVudDogSUNhbGVuZGFyRXZlbnQsIGNvbHVtbjogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmJ1aWxkS2V5RnJvbUV2ZW50KGV2ZW50KSA9PT0gdGhpcy5idWlsZEtleUZyb21Db2x1bW4oY29sdW1uKTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuL0lHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgYnVpbGRQaXBlbGluZSB9IGZyb20gJy4vUmVuZGVyQnVpbGRlcic7XHJcbmltcG9ydCB7IEV2ZW50UmVuZGVyZXIgfSBmcm9tICcuLi9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyJztcclxuaW1wb3J0IHsgU2NoZWR1bGVSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL3NjaGVkdWxlL1NjaGVkdWxlUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBIZWFkZXJEcmF3ZXJSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL2hlYWRlcmRyYXdlci9IZWFkZXJEcmF3ZXJSZW5kZXJlcic7XHJcbmltcG9ydCB7IFZpZXdDb25maWcsIEdyb3VwaW5nQ29uZmlnIH0gZnJvbSAnLi9WaWV3Q29uZmlnJztcclxuaW1wb3J0IHsgRmlsdGVyVGVtcGxhdGUgfSBmcm9tICcuL0ZpbHRlclRlbXBsYXRlJztcclxuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuL0RhdGVTZXJ2aWNlJztcclxuaW1wb3J0IHsgSUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9zdG9yYWdlL0lFbnRpdHlTZXJ2aWNlJztcclxuaW1wb3J0IHsgSVN5bmMgfSBmcm9tICcuLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDYWxlbmRhck9yY2hlc3RyYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGFsbFJlbmRlcmVyczogSVJlbmRlcmVyW10sXHJcbiAgICBwcml2YXRlIGV2ZW50UmVuZGVyZXI6IEV2ZW50UmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIHNjaGVkdWxlUmVuZGVyZXI6IFNjaGVkdWxlUmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIGhlYWRlckRyYXdlclJlbmRlcmVyOiBIZWFkZXJEcmF3ZXJSZW5kZXJlcixcclxuICAgIHByaXZhdGUgZGF0ZVNlcnZpY2U6IERhdGVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbnRpdHlTZXJ2aWNlczogSUVudGl0eVNlcnZpY2U8SVN5bmM+W11cclxuICApIHt9XHJcblxyXG4gIGFzeW5jIHJlbmRlcih2aWV3Q29uZmlnOiBWaWV3Q29uZmlnLCBjb250YWluZXI6IEhUTUxFbGVtZW50KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBoZWFkZXJDb250YWluZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWNhbGVuZGFyLWhlYWRlcicpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgY29sdW1uQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYgKCFoZWFkZXJDb250YWluZXIgfHwgIWNvbHVtbkNvbnRhaW5lcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc3dwLWNhbGVuZGFyLWhlYWRlciBvciBzd3AtZGF5LWNvbHVtbnMnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBCeWcgZmlsdGVyIGZyYSB2aWV3Q29uZmlnXHJcbiAgICBjb25zdCBmaWx0ZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBncm91cGluZyBvZiB2aWV3Q29uZmlnLmdyb3VwaW5ncykge1xyXG4gICAgICBmaWx0ZXJbZ3JvdXBpbmcudHlwZV0gPSBncm91cGluZy52YWx1ZXM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQnlnIEZpbHRlclRlbXBsYXRlIGZyYSB2aWV3Q29uZmlnIGdyb3VwaW5ncyAoa3VuIGRlIG1lZCBpZFByb3BlcnR5KVxyXG4gICAgY29uc3QgZmlsdGVyVGVtcGxhdGUgPSBuZXcgRmlsdGVyVGVtcGxhdGUodGhpcy5kYXRlU2VydmljZSk7XHJcbiAgICBmb3IgKGNvbnN0IGdyb3VwaW5nIG9mIHZpZXdDb25maWcuZ3JvdXBpbmdzKSB7XHJcbiAgICAgIGlmIChncm91cGluZy5pZFByb3BlcnR5KSB7XHJcbiAgICAgICAgZmlsdGVyVGVtcGxhdGUuYWRkRmllbGQoZ3JvdXBpbmcuaWRQcm9wZXJ0eSwgZ3JvdXBpbmcuZGVyaXZlZEZyb20pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBiZWxvbmdzVG8gcmVsYXRpb25zIChlLmcuLCB0ZWFtLnJlc291cmNlSWRzKVxyXG4gICAgY29uc3QgeyBwYXJlbnRDaGlsZE1hcCwgY2hpbGRUeXBlIH0gPSBhd2FpdCB0aGlzLnJlc29sdmVCZWxvbmdzVG8odmlld0NvbmZpZy5ncm91cGluZ3MsIGZpbHRlcik7XHJcblxyXG4gICAgY29uc3QgY29udGV4dDogSVJlbmRlckNvbnRleHQgPSB7IGhlYWRlckNvbnRhaW5lciwgY29sdW1uQ29udGFpbmVyLCBmaWx0ZXIsIGdyb3VwaW5nczogdmlld0NvbmZpZy5ncm91cGluZ3MsIHBhcmVudENoaWxkTWFwLCBjaGlsZFR5cGUgfTtcclxuXHJcbiAgICAvLyBDbGVhclxyXG4gICAgaGVhZGVyQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG4gICAgY29sdW1uQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG5cclxuICAgIC8vIFNcdTAwRTZ0IGRhdGEtbGV2ZWxzIGF0dHJpYnV0IGZvciBDU1MgZ3JpZC1yb3cgc3R5bGluZ1xyXG4gICAgY29uc3QgbGV2ZWxzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKS5qb2luKCcgJyk7XHJcbiAgICBoZWFkZXJDb250YWluZXIuZGF0YXNldC5sZXZlbHMgPSBsZXZlbHM7XHJcblxyXG4gICAgLy8gVlx1MDBFNmxnIHJlbmRlcmVycyBiYXNlcmV0IHBcdTAwRTUgZ3JvdXBpbmdzIHR5cGVzXHJcbiAgICBjb25zdCBhY3RpdmVSZW5kZXJlcnMgPSB0aGlzLnNlbGVjdFJlbmRlcmVycyh2aWV3Q29uZmlnKTtcclxuXHJcbiAgICAvLyBCeWcgb2cga1x1MDBGOHIgcGlwZWxpbmVcclxuICAgIGNvbnN0IHBpcGVsaW5lID0gYnVpbGRQaXBlbGluZShhY3RpdmVSZW5kZXJlcnMpO1xyXG4gICAgYXdhaXQgcGlwZWxpbmUucnVuKGNvbnRleHQpO1xyXG5cclxuICAgIC8vIFJlbmRlciBzY2hlZHVsZSB1bmF2YWlsYWJsZSB6b25lcyAoZlx1MDBGOHIgZXZlbnRzKVxyXG4gICAgYXdhaXQgdGhpcy5zY2hlZHVsZVJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlcik7XHJcblxyXG4gICAgLy8gUmVuZGVyIHRpbWVkIGV2ZW50cyBpbiBncmlkIChtZWQgZmlsdGVyVGVtcGxhdGUgdGlsIG1hdGNoaW5nKVxyXG4gICAgYXdhaXQgdGhpcy5ldmVudFJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG5cclxuICAgIC8vIFJlbmRlciBhbGxEYXkgZXZlbnRzIGluIGhlYWRlciBkcmF3ZXIgKG1lZCBmaWx0ZXJUZW1wbGF0ZSB0aWwgbWF0Y2hpbmcpXHJcbiAgICBhd2FpdCB0aGlzLmhlYWRlckRyYXdlclJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZWxlY3RSZW5kZXJlcnModmlld0NvbmZpZzogVmlld0NvbmZpZyk6IElSZW5kZXJlcltdIHtcclxuICAgIGNvbnN0IHR5cGVzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKTtcclxuICAgIC8vIFNvcnRcdTAwRTlyIHJlbmRlcmVycyBpIHNhbW1lIHJcdTAwRTZra2VmXHUwMEY4bGdlIHNvbSB2aWV3Q29uZmlnLmdyb3VwaW5nc1xyXG4gICAgcmV0dXJuIHR5cGVzXHJcbiAgICAgIC5tYXAodHlwZSA9PiB0aGlzLmFsbFJlbmRlcmVycy5maW5kKHIgPT4gci50eXBlID09PSB0eXBlKSlcclxuICAgICAgLmZpbHRlcigocik6IHIgaXMgSVJlbmRlcmVyID0+IHIgIT09IHVuZGVmaW5lZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGJlbG9uZ3NUbyByZWxhdGlvbnMgdG8gYnVpbGQgcGFyZW50LWNoaWxkIG1hcFxyXG4gICAqIGUuZy4sIGJlbG9uZ3NUbzogJ3RlYW0ucmVzb3VyY2VJZHMnIFx1MjE5MiB7IHRlYW0xOiBbJ0VNUDAwMScsICdFTVAwMDInXSwgdGVhbTI6IFsuLi5dIH1cclxuICAgKiBBbHNvIHJldHVybnMgdGhlIGNoaWxkVHlwZSAodGhlIGdyb3VwaW5nIHR5cGUgdGhhdCBoYXMgYmVsb25nc1RvKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUJlbG9uZ3NUbyhcclxuICAgIGdyb3VwaW5nczogR3JvdXBpbmdDb25maWdbXSxcclxuICAgIGZpbHRlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+XHJcbiAgKTogUHJvbWlzZTx7IHBhcmVudENoaWxkTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+OyBjaGlsZFR5cGU/OiBzdHJpbmcgfT4ge1xyXG4gICAgLy8gRmluZCBncm91cGluZyB3aXRoIGJlbG9uZ3NUb1xyXG4gICAgY29uc3QgY2hpbGRHcm91cGluZyA9IGdyb3VwaW5ncy5maW5kKGcgPT4gZy5iZWxvbmdzVG8pO1xyXG4gICAgaWYgKCFjaGlsZEdyb3VwaW5nPy5iZWxvbmdzVG8pIHJldHVybiB7fTtcclxuXHJcbiAgICAvLyBQYXJzZSBiZWxvbmdzVG86ICd0ZWFtLnJlc291cmNlSWRzJ1xyXG4gICAgY29uc3QgW2VudGl0eVR5cGUsIHByb3BlcnR5XSA9IGNoaWxkR3JvdXBpbmcuYmVsb25nc1RvLnNwbGl0KCcuJyk7XHJcbiAgICBpZiAoIWVudGl0eVR5cGUgfHwgIXByb3BlcnR5KSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gR2V0IHBhcmVudCBJRHMgZnJvbSBmaWx0ZXJcclxuICAgIGNvbnN0IHBhcmVudElkcyA9IGZpbHRlcltlbnRpdHlUeXBlXSB8fCBbXTtcclxuICAgIGlmIChwYXJlbnRJZHMubGVuZ3RoID09PSAwKSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gRmluZCBzZXJ2aWNlIGR5bmFtaXNrIGJhc2VyZXQgcFx1MDBFNSBlbnRpdHlUeXBlIChpbmdlbiBoYXJkY29kZWQgdHlwZSBjaGVjaylcclxuICAgIGNvbnN0IHNlcnZpY2UgPSB0aGlzLmVudGl0eVNlcnZpY2VzLmZpbmQocyA9PlxyXG4gICAgICBzLmVudGl0eVR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZW50aXR5VHlwZVxyXG4gICAgKTtcclxuICAgIGlmICghc2VydmljZSkgcmV0dXJuIHt9O1xyXG5cclxuICAgIC8vIEhlbnQgYWxsZSBlbnRpdGllcyBvZyBmaWx0cmVyIHBcdTAwRTUgcGFyZW50SWRzXHJcbiAgICBjb25zdCBhbGxFbnRpdGllcyA9IGF3YWl0IHNlcnZpY2UuZ2V0QWxsKCk7XHJcbiAgICBjb25zdCBlbnRpdGllcyA9IGFsbEVudGl0aWVzLmZpbHRlcihlID0+XHJcbiAgICAgIHBhcmVudElkcy5pbmNsdWRlcygoZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5pZCBhcyBzdHJpbmcpXHJcbiAgICApO1xyXG5cclxuICAgIC8vIEJ5ZyBwYXJlbnQtY2hpbGQgbWFwXHJcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcclxuICAgICAgY29uc3QgZW50aXR5UmVjb3JkID0gZW50aXR5IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XHJcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gKGVudGl0eVJlY29yZFtwcm9wZXJ0eV0gYXMgc3RyaW5nW10pIHx8IFtdO1xyXG4gICAgICBtYXBbZW50aXR5UmVjb3JkLmlkIGFzIHN0cmluZ10gPSBjaGlsZHJlbjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBwYXJlbnRDaGlsZE1hcDogbWFwLCBjaGlsZFR5cGU6IGNoaWxkR3JvdXBpbmcudHlwZSB9O1xyXG4gIH1cclxufVxyXG4iLCAiZXhwb3J0IGNsYXNzIE5hdmlnYXRpb25BbmltYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGhlYWRlclRyYWNrOiBIVE1MRWxlbWVudCxcclxuICAgIHByaXZhdGUgY29udGVudFRyYWNrOiBIVE1MRWxlbWVudFxyXG4gICkge31cclxuXHJcbiAgYXN5bmMgc2xpZGUoZGlyZWN0aW9uOiAnbGVmdCcgfCAncmlnaHQnLCByZW5kZXJGbjogKCkgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY29uc3Qgb3V0ID0gZGlyZWN0aW9uID09PSAnbGVmdCcgPyAnLTEwMCUnIDogJzEwMCUnO1xyXG4gICAgY29uc3QgaW50byA9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJzEwMCUnIDogJy0xMDAlJztcclxuXHJcbiAgICBhd2FpdCB0aGlzLmFuaW1hdGVPdXQob3V0KTtcclxuICAgIGF3YWl0IHJlbmRlckZuKCk7XHJcbiAgICBhd2FpdCB0aGlzLmFuaW1hdGVJbihpbnRvKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgYW5pbWF0ZU91dCh0cmFuc2xhdGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xyXG4gICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfSwgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfVxyXG4gICAgICApLmZpbmlzaGVkLFxyXG4gICAgICB0aGlzLmNvbnRlbnRUcmFjay5hbmltYXRlKFxyXG4gICAgICAgIFt7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH0sIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9XSxcclxuICAgICAgICB7IGR1cmF0aW9uOiAyMDAsIGVhc2luZzogJ2Vhc2UtaW4nIH1cclxuICAgICAgKS5maW5pc2hlZFxyXG4gICAgXSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGFuaW1hdGVJbih0cmFuc2xhdGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xyXG4gICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9LCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH1cclxuICAgICAgKS5maW5pc2hlZCxcclxuICAgICAgdGhpcy5jb250ZW50VHJhY2suYW5pbWF0ZShcclxuICAgICAgICBbeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH0sIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfV0sXHJcbiAgICAgICAgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLW91dCcgfVxyXG4gICAgICApLmZpbmlzaGVkXHJcbiAgICBdKTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuLi8uLi9jb3JlL0lHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL0RhdGVTZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlUmVuZGVyZXIgaW1wbGVtZW50cyBJUmVuZGVyZXIge1xyXG4gIHJlYWRvbmx5IHR5cGUgPSAnZGF0ZSc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZVNlcnZpY2U6IERhdGVTZXJ2aWNlKSB7fVxyXG5cclxuICByZW5kZXIoY29udGV4dDogSVJlbmRlckNvbnRleHQpOiB2b2lkIHtcclxuICAgIGNvbnN0IGRhdGVzID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXSB8fCBbXTtcclxuICAgIGNvbnN0IHJlc291cmNlSWRzID0gY29udGV4dC5maWx0ZXJbJ3Jlc291cmNlJ10gfHwgW107XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgZGF0ZSBoZWFkZXJzIHNob3VsZCBiZSBoaWRkZW4gKGUuZy4sIGluIGRheSB2aWV3KVxyXG4gICAgY29uc3QgZGF0ZUdyb3VwaW5nID0gY29udGV4dC5ncm91cGluZ3M/LmZpbmQoZyA9PiBnLnR5cGUgPT09ICdkYXRlJyk7XHJcbiAgICBjb25zdCBoaWRlSGVhZGVyID0gZGF0ZUdyb3VwaW5nPy5oaWRlSGVhZGVyID09PSB0cnVlO1xyXG5cclxuICAgIC8vIFJlbmRlciBkYXRlcyBmb3IgSFZFUiByZXNvdXJjZSAoZWxsZXIgMSBnYW5nIGh2aXMgaW5nZW4gcmVzb3VyY2VzKVxyXG4gICAgY29uc3QgaXRlcmF0aW9ucyA9IHJlc291cmNlSWRzLmxlbmd0aCB8fCAxO1xyXG4gICAgbGV0IGNvbHVtbkNvdW50ID0gMDtcclxuXHJcbiAgICBmb3IgKGxldCByID0gMDsgciA8IGl0ZXJhdGlvbnM7IHIrKykge1xyXG4gICAgICBjb25zdCByZXNvdXJjZUlkID0gcmVzb3VyY2VJZHNbcl07IC8vIHVuZGVmaW5lZCBodmlzIGluZ2VuIHJlc291cmNlc1xyXG5cclxuICAgICAgZm9yIChjb25zdCBkYXRlU3RyIG9mIGRhdGVzKSB7XHJcbiAgICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZGF0ZVNlcnZpY2UucGFyc2VJU08oZGF0ZVN0cik7XHJcblxyXG4gICAgICAgIC8vIEJ1aWxkIGNvbHVtbktleSBmb3IgdW5pZm9ybSBpZGVudGlmaWNhdGlvblxyXG4gICAgICAgIGNvbnN0IHNlZ21lbnRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBkYXRlOiBkYXRlU3RyIH07XHJcbiAgICAgICAgaWYgKHJlc291cmNlSWQpIHNlZ21lbnRzLnJlc291cmNlID0gcmVzb3VyY2VJZDtcclxuICAgICAgICBjb25zdCBjb2x1bW5LZXkgPSB0aGlzLmRhdGVTZXJ2aWNlLmJ1aWxkQ29sdW1uS2V5KHNlZ21lbnRzKTtcclxuXHJcbiAgICAgICAgLy8gSGVhZGVyXHJcbiAgICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWRheS1oZWFkZXInKTtcclxuICAgICAgICBoZWFkZXIuZGF0YXNldC5kYXRlID0gZGF0ZVN0cjtcclxuICAgICAgICBoZWFkZXIuZGF0YXNldC5jb2x1bW5LZXkgPSBjb2x1bW5LZXk7XHJcbiAgICAgICAgaWYgKHJlc291cmNlSWQpIHtcclxuICAgICAgICAgIGhlYWRlci5kYXRhc2V0LnJlc291cmNlSWQgPSByZXNvdXJjZUlkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaGlkZUhlYWRlcikge1xyXG4gICAgICAgICAgaGVhZGVyLmRhdGFzZXQuaGlkZGVuID0gJ3RydWUnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBoZWFkZXIuaW5uZXJIVE1MID0gYFxyXG4gICAgICAgICAgPHN3cC1kYXktbmFtZT4ke3RoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF5TmFtZShkYXRlLCAnc2hvcnQnKX08L3N3cC1kYXktbmFtZT5cclxuICAgICAgICAgIDxzd3AtZGF5LWRhdGU+JHtkYXRlLmdldERhdGUoKX08L3N3cC1kYXktZGF0ZT5cclxuICAgICAgICBgO1xyXG4gICAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XHJcblxyXG4gICAgICAgIC8vIENvbHVtblxyXG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1kYXktY29sdW1uJyk7XHJcbiAgICAgICAgY29sdW1uLmRhdGFzZXQuZGF0ZSA9IGRhdGVTdHI7XHJcbiAgICAgICAgY29sdW1uLmRhdGFzZXQuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUlkKSB7XHJcbiAgICAgICAgICBjb2x1bW4uZGF0YXNldC5yZXNvdXJjZUlkID0gcmVzb3VyY2VJZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29sdW1uLmlubmVySFRNTCA9ICc8c3dwLWV2ZW50cy1sYXllcj48L3N3cC1ldmVudHMtbGF5ZXI+JztcclxuICAgICAgICBjb250ZXh0LmNvbHVtbkNvbnRhaW5lci5hcHBlbmRDaGlsZChjb2x1bW4pO1xyXG5cclxuICAgICAgICBjb2x1bW5Db3VudCsrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU2V0IGdyaWQgY29sdW1ucyBvbiBjb250YWluZXJcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGNvbnRleHQuY29sdW1uQ29udGFpbmVyLmNsb3Nlc3QoJ3N3cC1jYWxlbmRhci1jb250YWluZXInKTtcclxuICAgIGlmIChjb250YWluZXIpIHtcclxuICAgICAgKGNvbnRhaW5lciBhcyBIVE1MRWxlbWVudCkuc3R5bGUuc2V0UHJvcGVydHkoJy0tZ3JpZC1jb2x1bW5zJywgU3RyaW5nKGNvbHVtbkNvdW50KSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnO1xyXG5pbXBvcnQgdXRjIGZyb20gJ2RheWpzL3BsdWdpbi91dGMnO1xyXG5pbXBvcnQgdGltZXpvbmUgZnJvbSAnZGF5anMvcGx1Z2luL3RpbWV6b25lJztcclxuaW1wb3J0IGlzb1dlZWsgZnJvbSAnZGF5anMvcGx1Z2luL2lzb1dlZWsnO1xyXG5pbXBvcnQgeyBJVGltZUZvcm1hdENvbmZpZyB9IGZyb20gJy4vSVRpbWVGb3JtYXRDb25maWcnO1xyXG5cclxuLy8gRW5hYmxlIGRheWpzIHBsdWdpbnNcclxuZGF5anMuZXh0ZW5kKHV0Yyk7XHJcbmRheWpzLmV4dGVuZCh0aW1lem9uZSk7XHJcbmRheWpzLmV4dGVuZChpc29XZWVrKTtcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlU2VydmljZSB7XHJcbiAgcHJpdmF0ZSB0aW1lem9uZTogc3RyaW5nO1xyXG4gIHByaXZhdGUgYmFzZURhdGU6IGRheWpzLkRheWpzO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogSVRpbWVGb3JtYXRDb25maWcsIGJhc2VEYXRlPzogRGF0ZSkge1xyXG4gICAgdGhpcy50aW1lem9uZSA9IGNvbmZpZy50aW1lem9uZTtcclxuICAgIC8vIEFsbG93IHNldHRpbmcgYSBmaXhlZCBiYXNlIGRhdGUgZm9yIGRlbW8vdGVzdGluZyBwdXJwb3Nlc1xyXG4gICAgdGhpcy5iYXNlRGF0ZSA9IGJhc2VEYXRlID8gZGF5anMoYmFzZURhdGUpIDogZGF5anMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldCBhIGZpeGVkIGJhc2UgZGF0ZSAodXNlZnVsIGZvciBkZW1vcyB3aXRoIHN0YXRpYyBtb2NrIGRhdGEpXHJcbiAgICovXHJcbiAgc2V0QmFzZURhdGUoZGF0ZTogRGF0ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5iYXNlRGF0ZSA9IGRheWpzKGRhdGUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBjdXJyZW50IGJhc2UgZGF0ZSAoZWl0aGVyIGZpeGVkIG9yIHRvZGF5KVxyXG4gICAqL1xyXG4gIGdldEJhc2VEYXRlKCk6IERhdGUge1xyXG4gICAgcmV0dXJuIHRoaXMuYmFzZURhdGUudG9EYXRlKCk7XHJcbiAgfVxyXG5cclxuICBwYXJzZUlTTyhpc29TdHJpbmc6IHN0cmluZyk6IERhdGUge1xyXG4gICAgcmV0dXJuIGRheWpzKGlzb1N0cmluZykudG9EYXRlKCk7XHJcbiAgfVxyXG5cclxuICBnZXREYXlOYW1lKGRhdGU6IERhdGUsIGZvcm1hdDogJ3Nob3J0JyB8ICdsb25nJyA9ICdzaG9ydCcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KHRoaXMuY29uZmlnLmxvY2FsZSwgeyB3ZWVrZGF5OiBmb3JtYXQgfSkuZm9ybWF0KGRhdGUpO1xyXG4gIH1cclxuXHJcbiAgZ2V0V2Vla0RhdGVzKG9mZnNldCA9IDAsIGRheXMgPSA3KTogc3RyaW5nW10ge1xyXG4gICAgY29uc3QgbW9uZGF5ID0gdGhpcy5iYXNlRGF0ZS5zdGFydE9mKCd3ZWVrJykuYWRkKDEsICdkYXknKS5hZGQob2Zmc2V0LCAnd2VlaycpO1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IGRheXMgfSwgKF8sIGkpID0+XHJcbiAgICAgIG1vbmRheS5hZGQoaSwgJ2RheScpLmZvcm1hdCgnWVlZWS1NTS1ERCcpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGRhdGVzIGZvciBzcGVjaWZpYyB3ZWVrZGF5cyB3aXRoaW4gYSB3ZWVrXHJcbiAgICogQHBhcmFtIG9mZnNldCAtIFdlZWsgb2Zmc2V0IGZyb20gYmFzZSBkYXRlICgwID0gY3VycmVudCB3ZWVrKVxyXG4gICAqIEBwYXJhbSB3b3JrRGF5cyAtIEFycmF5IG9mIElTTyB3ZWVrZGF5IG51bWJlcnMgKDE9TW9uZGF5LCA3PVN1bmRheSlcclxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBkYXRlIHN0cmluZ3MgaW4gWVlZWS1NTS1ERCBmb3JtYXRcclxuICAgKi9cclxuICBnZXRXb3JrV2Vla0RhdGVzKG9mZnNldDogbnVtYmVyLCB3b3JrRGF5czogbnVtYmVyW10pOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCBtb25kYXkgPSB0aGlzLmJhc2VEYXRlLnN0YXJ0T2YoJ3dlZWsnKS5hZGQoMSwgJ2RheScpLmFkZChvZmZzZXQsICd3ZWVrJyk7XHJcbiAgICByZXR1cm4gd29ya0RheXMubWFwKGlzb0RheSA9PiB7XHJcbiAgICAgIC8vIElTTzogMT1Nb25kYXksIDc9U3VuZGF5IFx1MjE5MiBkYXlzIGZyb20gTW9uZGF5OiAwLTZcclxuICAgICAgY29uc3QgZGF5c0Zyb21Nb25kYXkgPSBpc29EYXkgPT09IDcgPyA2IDogaXNvRGF5IC0gMTtcclxuICAgICAgcmV0dXJuIG1vbmRheS5hZGQoZGF5c0Zyb21Nb25kYXksICdkYXknKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBGT1JNQVRUSU5HXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgZm9ybWF0VGltZShkYXRlOiBEYXRlLCBzaG93U2Vjb25kcyA9IGZhbHNlKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHBhdHRlcm4gPSBzaG93U2Vjb25kcyA/ICdISDptbTpzcycgOiAnSEg6bW0nO1xyXG4gICAgcmV0dXJuIGRheWpzKGRhdGUpLmZvcm1hdChwYXR0ZXJuKTtcclxuICB9XHJcblxyXG4gIGZvcm1hdFRpbWVSYW5nZShzdGFydDogRGF0ZSwgZW5kOiBEYXRlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBgJHt0aGlzLmZvcm1hdFRpbWUoc3RhcnQpfSAtICR7dGhpcy5mb3JtYXRUaW1lKGVuZCl9YDtcclxuICB9XHJcblxyXG4gIGZvcm1hdERhdGUoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gZGF5anMoZGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJyk7XHJcbiAgfVxyXG5cclxuICBnZXREYXRlS2V5KGRhdGU6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0RGF0ZShkYXRlKTtcclxuICB9XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgLy8gQ09MVU1OIEtFWVxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1aWxkIGEgdW5pZm9ybSBjb2x1bW5LZXkgZnJvbSBncm91cGluZyBzZWdtZW50c1xyXG4gICAqIEhhbmRsZXMgYW55IGNvbWJpbmF0aW9uIG9mIGRhdGUsIHJlc291cmNlLCB0ZWFtLCBldGMuXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIGJ1aWxkQ29sdW1uS2V5KHsgZGF0ZTogJzIwMjUtMTItMDknIH0pIFx1MjE5MiBcIjIwMjUtMTItMDlcIlxyXG4gICAqIGJ1aWxkQ29sdW1uS2V5KHsgZGF0ZTogJzIwMjUtMTItMDknLCByZXNvdXJjZTogJ0VNUDAwMScgfSkgXHUyMTkyIFwiMjAyNS0xMi0wOTpFTVAwMDFcIlxyXG4gICAqL1xyXG4gIGJ1aWxkQ29sdW1uS2V5KHNlZ21lbnRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcclxuICAgIC8vIEFsd2F5cyBwdXQgZGF0ZSBmaXJzdCBpZiBwcmVzZW50LCB0aGVuIG90aGVyIHNlZ21lbnRzIGFscGhhYmV0aWNhbGx5XHJcbiAgICBjb25zdCBkYXRlID0gc2VnbWVudHMuZGF0ZTtcclxuICAgIGNvbnN0IG90aGVycyA9IE9iamVjdC5lbnRyaWVzKHNlZ21lbnRzKVxyXG4gICAgICAuZmlsdGVyKChba10pID0+IGsgIT09ICdkYXRlJylcclxuICAgICAgLnNvcnQoKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXHJcbiAgICAgIC5tYXAoKFssIHZdKSA9PiB2KTtcclxuXHJcbiAgICByZXR1cm4gZGF0ZSA/IFtkYXRlLCAuLi5vdGhlcnNdLmpvaW4oJzonKSA6IG90aGVycy5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQYXJzZSBhIGNvbHVtbktleSBiYWNrIGludG8gc2VnbWVudHNcclxuICAgKiBBc3N1bWVzIGZvcm1hdDogXCJkYXRlOnJlc291cmNlOi4uLlwiIG9yIGp1c3QgXCJkYXRlXCJcclxuICAgKi9cclxuICBwYXJzZUNvbHVtbktleShjb2x1bW5LZXk6IHN0cmluZyk6IHsgZGF0ZTogc3RyaW5nOyByZXNvdXJjZT86IHN0cmluZyB9IHtcclxuICAgIGNvbnN0IHBhcnRzID0gY29sdW1uS2V5LnNwbGl0KCc6Jyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBkYXRlOiBwYXJ0c1swXSxcclxuICAgICAgcmVzb3VyY2U6IHBhcnRzWzFdXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBkYXRlS2V5IGZyb20gY29sdW1uS2V5IChmaXJzdCBzZWdtZW50KVxyXG4gICAqL1xyXG4gIGdldERhdGVGcm9tQ29sdW1uS2V5KGNvbHVtbktleTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBjb2x1bW5LZXkuc3BsaXQoJzonKVswXTtcclxuICB9XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgLy8gVElNRSBDQUxDVUxBVElPTlNcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICB0aW1lVG9NaW51dGVzKHRpbWVTdHJpbmc6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBjb25zdCBwYXJ0cyA9IHRpbWVTdHJpbmcuc3BsaXQoJzonKS5tYXAoTnVtYmVyKTtcclxuICAgIGNvbnN0IGhvdXJzID0gcGFydHNbMF0gfHwgMDtcclxuICAgIGNvbnN0IG1pbnV0ZXMgPSBwYXJ0c1sxXSB8fCAwO1xyXG4gICAgcmV0dXJuIGhvdXJzICogNjAgKyBtaW51dGVzO1xyXG4gIH1cclxuXHJcbiAgbWludXRlc1RvVGltZSh0b3RhbE1pbnV0ZXM6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gNjApO1xyXG4gICAgY29uc3QgbWludXRlcyA9IHRvdGFsTWludXRlcyAlIDYwO1xyXG4gICAgcmV0dXJuIGRheWpzKCkuaG91cihob3VycykubWludXRlKG1pbnV0ZXMpLmZvcm1hdCgnSEg6bW0nKTtcclxuICB9XHJcblxyXG4gIGdldE1pbnV0ZXNTaW5jZU1pZG5pZ2h0KGRhdGU6IERhdGUpOiBudW1iZXIge1xyXG4gICAgY29uc3QgZCA9IGRheWpzKGRhdGUpO1xyXG4gICAgcmV0dXJuIGQuaG91cigpICogNjAgKyBkLm1pbnV0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBVVEMgQ09OVkVSU0lPTlNcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICB0b1VUQyhsb2NhbERhdGU6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGRheWpzLnR6KGxvY2FsRGF0ZSwgdGhpcy50aW1lem9uZSkudXRjKCkudG9JU09TdHJpbmcoKTtcclxuICB9XHJcblxyXG4gIGZyb21VVEModXRjU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHtcclxuICAgIHJldHVybiBkYXlqcy51dGModXRjU3RyaW5nKS50eih0aGlzLnRpbWV6b25lKS50b0RhdGUoKTtcclxuICB9XHJcblxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgLy8gREFURSBDUkVBVElPTlxyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIGNyZWF0ZURhdGVBdFRpbWUoYmFzZURhdGU6IERhdGUgfCBzdHJpbmcsIHRpbWVTdHJpbmc6IHN0cmluZyk6IERhdGUge1xyXG4gICAgY29uc3QgdG90YWxNaW51dGVzID0gdGhpcy50aW1lVG9NaW51dGVzKHRpbWVTdHJpbmcpO1xyXG4gICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKHRvdGFsTWludXRlcyAvIDYwKTtcclxuICAgIGNvbnN0IG1pbnV0ZXMgPSB0b3RhbE1pbnV0ZXMgJSA2MDtcclxuICAgIHJldHVybiBkYXlqcyhiYXNlRGF0ZSkuc3RhcnRPZignZGF5JykuaG91cihob3VycykubWludXRlKG1pbnV0ZXMpLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0SVNPV2Vla0RheShkYXRlOiBEYXRlIHwgc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBkYXlqcyhkYXRlKS5pc29XZWVrZGF5KCk7ICAvLyAxPU1vbmRheSwgNz1TdW5kYXlcclxuICB9XHJcbn1cclxuIiwgIi8qKlxuICogUG9zaXRpb25VdGlscyAtIFBpeGVsL3Bvc2l0aW9uIGNhbGN1bGF0aW9ucyBmb3IgY2FsZW5kYXIgZ3JpZFxuICpcbiAqIFJFU1BPTlNJQklMSVRZOiBDb252ZXJ0IGJldHdlZW4gdGltZSBhbmQgcGl4ZWwgcG9zaXRpb25zXG4gKiBOT1RFOiBEYXRlIGZvcm1hdHRpbmcgYmVsb25ncyBpbiBEYXRlU2VydmljZSwgbm90IGhlcmVcbiAqL1xuXG5pbXBvcnQgeyBJR3JpZENvbmZpZyB9IGZyb20gJy4uL2NvcmUvSUdyaWRDb25maWcnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50UG9zaXRpb24ge1xuICB0b3A6IG51bWJlcjsgICAgLy8gcGl4ZWxzIGZyb20gZGF5IHN0YXJ0XG4gIGhlaWdodDogbnVtYmVyOyAvLyBwaXhlbHNcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcGl4ZWwgcG9zaXRpb24gZm9yIGFuIGV2ZW50IGJhc2VkIG9uIGl0cyB0aW1lc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihcbiAgc3RhcnQ6IERhdGUsXG4gIGVuZDogRGF0ZSxcbiAgY29uZmlnOiBJR3JpZENvbmZpZ1xuKTogRXZlbnRQb3NpdGlvbiB7XG4gIGNvbnN0IHN0YXJ0TWludXRlcyA9IHN0YXJ0LmdldEhvdXJzKCkgKiA2MCArIHN0YXJ0LmdldE1pbnV0ZXMoKTtcbiAgY29uc3QgZW5kTWludXRlcyA9IGVuZC5nZXRIb3VycygpICogNjAgKyBlbmQuZ2V0TWludXRlcygpO1xuXG4gIGNvbnN0IGRheVN0YXJ0TWludXRlcyA9IGNvbmZpZy5kYXlTdGFydEhvdXIgKiA2MDtcbiAgY29uc3QgbWludXRlSGVpZ2h0ID0gY29uZmlnLmhvdXJIZWlnaHQgLyA2MDtcblxuICBjb25zdCB0b3AgPSAoc3RhcnRNaW51dGVzIC0gZGF5U3RhcnRNaW51dGVzKSAqIG1pbnV0ZUhlaWdodDtcbiAgY29uc3QgaGVpZ2h0ID0gKGVuZE1pbnV0ZXMgLSBzdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuXG4gIHJldHVybiB7IHRvcCwgaGVpZ2h0IH07XG59XG5cbi8qKlxuICogQ29udmVydCBtaW51dGVzIHRvIHBpeGVsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWludXRlc1RvUGl4ZWxzKG1pbnV0ZXM6IG51bWJlciwgY29uZmlnOiBJR3JpZENvbmZpZyk6IG51bWJlciB7XG4gIHJldHVybiAobWludXRlcyAvIDYwKSAqIGNvbmZpZy5ob3VySGVpZ2h0O1xufVxuXG4vKipcbiAqIENvbnZlcnQgcGl4ZWxzIHRvIG1pbnV0ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpeGVsc1RvTWludXRlcyhwaXhlbHM6IG51bWJlciwgY29uZmlnOiBJR3JpZENvbmZpZyk6IG51bWJlciB7XG4gIHJldHVybiAocGl4ZWxzIC8gY29uZmlnLmhvdXJIZWlnaHQpICogNjA7XG59XG5cbi8qKlxuICogU25hcCBwaXhlbCBwb3NpdGlvbiB0byBncmlkIGludGVydmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbmFwVG9HcmlkKHBpeGVsczogbnVtYmVyLCBjb25maWc6IElHcmlkQ29uZmlnKTogbnVtYmVyIHtcbiAgY29uc3Qgc25hcFBpeGVscyA9IG1pbnV0ZXNUb1BpeGVscyhjb25maWcuc25hcEludGVydmFsLCBjb25maWcpO1xuICByZXR1cm4gTWF0aC5yb3VuZChwaXhlbHMgLyBzbmFwUGl4ZWxzKSAqIHNuYXBQaXhlbHM7XG59XG4iLCAiLyoqXG4gKiBDb3JlRXZlbnRzIC0gQ29uc29saWRhdGVkIGVzc2VudGlhbCBldmVudHMgZm9yIHRoZSBjYWxlbmRhciBWMlxuICovXG5leHBvcnQgY29uc3QgQ29yZUV2ZW50cyA9IHtcbiAgLy8gTGlmZWN5Y2xlIGV2ZW50c1xuICBJTklUSUFMSVpFRDogJ2NvcmU6aW5pdGlhbGl6ZWQnLFxuICBSRUFEWTogJ2NvcmU6cmVhZHknLFxuICBERVNUUk9ZRUQ6ICdjb3JlOmRlc3Ryb3llZCcsXG5cbiAgLy8gVmlldyBldmVudHNcbiAgVklFV19DSEFOR0VEOiAndmlldzpjaGFuZ2VkJyxcbiAgVklFV19SRU5ERVJFRDogJ3ZpZXc6cmVuZGVyZWQnLFxuXG4gIC8vIE5hdmlnYXRpb24gZXZlbnRzXG4gIERBVEVfQ0hBTkdFRDogJ25hdjpkYXRlLWNoYW5nZWQnLFxuICBOQVZJR0FUSU9OX0NPTVBMRVRFRDogJ25hdjpuYXZpZ2F0aW9uLWNvbXBsZXRlZCcsXG5cbiAgLy8gRGF0YSBldmVudHNcbiAgREFUQV9MT0FESU5HOiAnZGF0YTpsb2FkaW5nJyxcbiAgREFUQV9MT0FERUQ6ICdkYXRhOmxvYWRlZCcsXG4gIERBVEFfRVJST1I6ICdkYXRhOmVycm9yJyxcblxuICAvLyBHcmlkIGV2ZW50c1xuICBHUklEX1JFTkRFUkVEOiAnZ3JpZDpyZW5kZXJlZCcsXG4gIEdSSURfQ0xJQ0tFRDogJ2dyaWQ6Y2xpY2tlZCcsXG5cbiAgLy8gRXZlbnQgbWFuYWdlbWVudFxuICBFVkVOVF9DUkVBVEVEOiAnZXZlbnQ6Y3JlYXRlZCcsXG4gIEVWRU5UX1VQREFURUQ6ICdldmVudDp1cGRhdGVkJyxcbiAgRVZFTlRfREVMRVRFRDogJ2V2ZW50OmRlbGV0ZWQnLFxuICBFVkVOVF9TRUxFQ1RFRDogJ2V2ZW50OnNlbGVjdGVkJyxcblxuICAvLyBFdmVudCBkcmFnLWRyb3BcbiAgRVZFTlRfRFJBR19TVEFSVDogJ2V2ZW50OmRyYWctc3RhcnQnLFxuICBFVkVOVF9EUkFHX01PVkU6ICdldmVudDpkcmFnLW1vdmUnLFxuICBFVkVOVF9EUkFHX0VORDogJ2V2ZW50OmRyYWctZW5kJyxcbiAgRVZFTlRfRFJBR19DQU5DRUw6ICdldmVudDpkcmFnLWNhbmNlbCcsXG4gIEVWRU5UX0RSQUdfQ09MVU1OX0NIQU5HRTogJ2V2ZW50OmRyYWctY29sdW1uLWNoYW5nZScsXG5cbiAgLy8gSGVhZGVyIGRyYWcgKHRpbWVkIFx1MjE5MiBoZWFkZXIgY29udmVyc2lvbilcbiAgRVZFTlRfRFJBR19FTlRFUl9IRUFERVI6ICdldmVudDpkcmFnLWVudGVyLWhlYWRlcicsXG4gIEVWRU5UX0RSQUdfTU9WRV9IRUFERVI6ICdldmVudDpkcmFnLW1vdmUtaGVhZGVyJyxcbiAgRVZFTlRfRFJBR19MRUFWRV9IRUFERVI6ICdldmVudDpkcmFnLWxlYXZlLWhlYWRlcicsXG5cbiAgLy8gRXZlbnQgcmVzaXplXG4gIEVWRU5UX1JFU0laRV9TVEFSVDogJ2V2ZW50OnJlc2l6ZS1zdGFydCcsXG4gIEVWRU5UX1JFU0laRV9FTkQ6ICdldmVudDpyZXNpemUtZW5kJyxcblxuICAvLyBFZGdlIHNjcm9sbFxuICBFREdFX1NDUk9MTF9USUNLOiAnZWRnZS1zY3JvbGw6dGljaycsXG4gIEVER0VfU0NST0xMX1NUQVJURUQ6ICdlZGdlLXNjcm9sbDpzdGFydGVkJyxcbiAgRURHRV9TQ1JPTExfU1RPUFBFRDogJ2VkZ2Utc2Nyb2xsOnN0b3BwZWQnLFxuXG4gIC8vIFN5c3RlbSBldmVudHNcbiAgRVJST1I6ICdzeXN0ZW06ZXJyb3InLFxuXG4gIC8vIFN5bmMgZXZlbnRzXG4gIFNZTkNfU1RBUlRFRDogJ3N5bmM6c3RhcnRlZCcsXG4gIFNZTkNfQ09NUExFVEVEOiAnc3luYzpjb21wbGV0ZWQnLFxuICBTWU5DX0ZBSUxFRDogJ3N5bmM6ZmFpbGVkJyxcblxuICAvLyBFbnRpdHkgZXZlbnRzIC0gZm9yIGF1ZGl0IGFuZCBzeW5jXG4gIEVOVElUWV9TQVZFRDogJ2VudGl0eTpzYXZlZCcsXG4gIEVOVElUWV9ERUxFVEVEOiAnZW50aXR5OmRlbGV0ZWQnLFxuXG4gIC8vIEF1ZGl0IGV2ZW50c1xuICBBVURJVF9MT0dHRUQ6ICdhdWRpdDpsb2dnZWQnLFxuXG4gIC8vIFJlbmRlcmluZyBldmVudHNcbiAgRVZFTlRTX1JFTkRFUkVEOiAnZXZlbnRzOnJlbmRlcmVkJ1xufSBhcyBjb25zdDtcbiIsICIvKipcclxuICogRXZlbnRMYXlvdXRFbmdpbmUgLSBTaW1wbGlmaWVkIHN0YWNraW5nL2dyb3VwaW5nIGFsZ29yaXRobSBmb3IgVjJcclxuICpcclxuICogU3VwcG9ydHMgdHdvIGxheW91dCBtb2RlczpcclxuICogLSBHUklEOiBFdmVudHMgc3RhcnRpbmcgYXQgc2FtZSB0aW1lIHJlbmRlcmVkIHNpZGUtYnktc2lkZVxyXG4gKiAtIFNUQUNLSU5HOiBPdmVybGFwcGluZyBldmVudHMgd2l0aCBtYXJnaW4tbGVmdCBvZmZzZXQgKDE1cHggcGVyIGxldmVsKVxyXG4gKlxyXG4gKiBTaW1wbGlmaWVkIGZyb20gVjE6IE5vIHByZXYvbmV4dCBjaGFpbnMsIHNpbmdsZS1wYXNzIGdyZWVkeSBhbGdvcml0aG1cclxuICovXHJcblxyXG5pbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCB9IGZyb20gJy4uLy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBJR3JpZENvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvSUdyaWRDb25maWcnO1xyXG5pbXBvcnQgeyBjYWxjdWxhdGVFdmVudFBvc2l0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbHMvUG9zaXRpb25VdGlscyc7XHJcbmltcG9ydCB7IElDb2x1bW5MYXlvdXQsIElHcmlkR3JvdXBMYXlvdXQsIElTdGFja2VkRXZlbnRMYXlvdXQgfSBmcm9tICcuL0V2ZW50TGF5b3V0VHlwZXMnO1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHR3byBldmVudHMgb3ZlcmxhcCAoc3RyaWN0IC0gdG91Y2hpbmcgYXQgYm91bmRhcnkgPSBOT1Qgb3ZlcmxhcHBpbmcpXHJcbiAqIFRoaXMgbWF0Y2hlcyBTY2VuYXJpbyA4OiBlbmQ9PT1zdGFydCBpcyBOT1Qgb3ZlcmxhcFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGV2ZW50c092ZXJsYXAoYTogSUNhbGVuZGFyRXZlbnQsIGI6IElDYWxlbmRhckV2ZW50KTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIGEuc3RhcnQgPCBiLmVuZCAmJiBhLmVuZCA+IGIuc3RhcnQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0d28gZXZlbnRzIGFyZSB3aXRoaW4gdGhyZXNob2xkIGZvciBncmlkIGdyb3VwaW5nLlxyXG4gKiBUaGlzIGluY2x1ZGVzOlxyXG4gKiAxLiBTdGFydC10by1zdGFydDogRXZlbnRzIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGQgb2YgZWFjaCBvdGhlclxyXG4gKiAyLiBFbmQtdG8tc3RhcnQ6IE9uZSBldmVudCBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgYW5vdGhlciBlbmRzXHJcbiAqL1xyXG5mdW5jdGlvbiBldmVudHNXaXRoaW5UaHJlc2hvbGQoYTogSUNhbGVuZGFyRXZlbnQsIGI6IElDYWxlbmRhckV2ZW50LCB0aHJlc2hvbGRNaW51dGVzOiBudW1iZXIpOiBib29sZWFuIHtcclxuICBjb25zdCB0aHJlc2hvbGRNcyA9IHRocmVzaG9sZE1pbnV0ZXMgKiA2MCAqIDEwMDA7XHJcblxyXG4gIC8vIFN0YXJ0LXRvLXN0YXJ0OiBib3RoIGV2ZW50cyBzdGFydCB3aXRoaW4gdGhyZXNob2xkXHJcbiAgY29uc3Qgc3RhcnRUb1N0YXJ0RGlmZiA9IE1hdGguYWJzKGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xyXG4gIGlmIChzdGFydFRvU3RhcnREaWZmIDw9IHRocmVzaG9sZE1zKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgLy8gRW5kLXRvLXN0YXJ0OiBvbmUgZXZlbnQgc3RhcnRzIHdpdGhpbiB0aHJlc2hvbGQgYmVmb3JlIHRoZSBvdGhlciBlbmRzXHJcbiAgLy8gQiBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgQSBlbmRzXHJcbiAgY29uc3QgYlN0YXJ0c0JlZm9yZUFFbmRzID0gYS5lbmQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCk7XHJcbiAgaWYgKGJTdGFydHNCZWZvcmVBRW5kcyA+IDAgJiYgYlN0YXJ0c0JlZm9yZUFFbmRzIDw9IHRocmVzaG9sZE1zKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgLy8gQSBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgQiBlbmRzXHJcbiAgY29uc3QgYVN0YXJ0c0JlZm9yZUJFbmRzID0gYi5lbmQuZ2V0VGltZSgpIC0gYS5zdGFydC5nZXRUaW1lKCk7XHJcbiAgaWYgKGFTdGFydHNCZWZvcmVCRW5kcyA+IDAgJiYgYVN0YXJ0c0JlZm9yZUJFbmRzIDw9IHRocmVzaG9sZE1zKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgYWxsIGV2ZW50cyBpbiBhIGdyb3VwIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGQgb2YgZWFjaCBvdGhlclxyXG4gKi9cclxuZnVuY3Rpb24gYWxsU3RhcnRXaXRoaW5UaHJlc2hvbGQoZXZlbnRzOiBJQ2FsZW5kYXJFdmVudFtdLCB0aHJlc2hvbGRNaW51dGVzOiBudW1iZXIpOiBib29sZWFuIHtcclxuICBpZiAoZXZlbnRzLmxlbmd0aCA8PSAxKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgLy8gRmluZCBlYXJsaWVzdCBhbmQgbGF0ZXN0IHN0YXJ0IHRpbWVzXHJcbiAgbGV0IGVhcmxpZXN0ID0gZXZlbnRzWzBdLnN0YXJ0LmdldFRpbWUoKTtcclxuICBsZXQgbGF0ZXN0ID0gZXZlbnRzWzBdLnN0YXJ0LmdldFRpbWUoKTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcclxuICAgIGNvbnN0IHRpbWUgPSBldmVudC5zdGFydC5nZXRUaW1lKCk7XHJcbiAgICBpZiAodGltZSA8IGVhcmxpZXN0KSBlYXJsaWVzdCA9IHRpbWU7XHJcbiAgICBpZiAodGltZSA+IGxhdGVzdCkgbGF0ZXN0ID0gdGltZTtcclxuICB9XHJcblxyXG4gIGNvbnN0IGRpZmZNaW51dGVzID0gKGxhdGVzdCAtIGVhcmxpZXN0KSAvICgxMDAwICogNjApO1xyXG4gIHJldHVybiBkaWZmTWludXRlcyA8PSB0aHJlc2hvbGRNaW51dGVzO1xyXG59XHJcblxyXG4vKipcclxuICogRmluZCBncm91cHMgb2Ygb3ZlcmxhcHBpbmcgZXZlbnRzIChjb25uZWN0ZWQgYnkgb3ZlcmxhcCBjaGFpbilcclxuICogRXZlbnRzIGFyZSBncm91cGVkIGlmIHRoZXkgb3ZlcmxhcCB3aXRoIGFueSBldmVudCBpbiB0aGUgZ3JvdXBcclxuICovXHJcbmZ1bmN0aW9uIGZpbmRPdmVybGFwR3JvdXBzKGV2ZW50czogSUNhbGVuZGFyRXZlbnRbXSk6IElDYWxlbmRhckV2ZW50W11bXSB7XHJcbiAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcclxuXHJcbiAgY29uc3Qgc29ydGVkID0gWy4uLmV2ZW50c10uc29ydCgoYSwgYikgPT4gYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XHJcbiAgY29uc3QgdXNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG4gIGNvbnN0IGdyb3VwczogSUNhbGVuZGFyRXZlbnRbXVtdID0gW107XHJcblxyXG4gIGZvciAoY29uc3QgZXZlbnQgb2Ygc29ydGVkKSB7XHJcbiAgICBpZiAodXNlZC5oYXMoZXZlbnQuaWQpKSBjb250aW51ZTtcclxuXHJcbiAgICAvLyBTdGFydCBhIG5ldyBncm91cCB3aXRoIHRoaXMgZXZlbnRcclxuICAgIGNvbnN0IGdyb3VwOiBJQ2FsZW5kYXJFdmVudFtdID0gW2V2ZW50XTtcclxuICAgIHVzZWQuYWRkKGV2ZW50LmlkKTtcclxuXHJcbiAgICAvLyBFeHBhbmQgZ3JvdXAgYnkgZmluZGluZyBhbGwgY29ubmVjdGVkIGV2ZW50cyAodmlhIG92ZXJsYXApXHJcbiAgICBsZXQgZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgd2hpbGUgKGV4cGFuZGVkKSB7XHJcbiAgICAgIGV4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHNvcnRlZCkge1xyXG4gICAgICAgIGlmICh1c2VkLmhhcyhjYW5kaWRhdGUuaWQpKSBjb250aW51ZTtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgY2FuZGlkYXRlIG92ZXJsYXBzIHdpdGggYW55IGV2ZW50IGluIGdyb3VwXHJcbiAgICAgICAgY29uc3QgY29ubmVjdHMgPSBncm91cC5zb21lKG1lbWJlciA9PiBldmVudHNPdmVybGFwKG1lbWJlciwgY2FuZGlkYXRlKSk7XHJcblxyXG4gICAgICAgIGlmIChjb25uZWN0cykge1xyXG4gICAgICAgICAgZ3JvdXAucHVzaChjYW5kaWRhdGUpO1xyXG4gICAgICAgICAgdXNlZC5hZGQoY2FuZGlkYXRlLmlkKTtcclxuICAgICAgICAgIGV4cGFuZGVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBncm91cHMucHVzaChncm91cCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZ3JvdXBzO1xyXG59XHJcblxyXG4vKipcclxuICogRmluZCBncmlkIGNhbmRpZGF0ZXMgd2l0aGluIGEgZ3JvdXAgLSBldmVudHMgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgY2hhaW5cclxuICogVXNlcyBWMSBsb2dpYzogZXZlbnRzIGFyZSBjb25uZWN0ZWQgaWYgd2l0aGluIHRocmVzaG9sZCAobm8gb3ZlcmxhcCByZXF1aXJlbWVudClcclxuICovXHJcbmZ1bmN0aW9uIGZpbmRHcmlkQ2FuZGlkYXRlcyhcclxuICBldmVudHM6IElDYWxlbmRhckV2ZW50W10sXHJcbiAgdGhyZXNob2xkTWludXRlczogbnVtYmVyXHJcbik6IElDYWxlbmRhckV2ZW50W11bXSB7XHJcbiAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcclxuXHJcbiAgY29uc3Qgc29ydGVkID0gWy4uLmV2ZW50c10uc29ydCgoYSwgYikgPT4gYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XHJcbiAgY29uc3QgdXNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG4gIGNvbnN0IGdyb3VwczogSUNhbGVuZGFyRXZlbnRbXVtdID0gW107XHJcblxyXG4gIGZvciAoY29uc3QgZXZlbnQgb2Ygc29ydGVkKSB7XHJcbiAgICBpZiAodXNlZC5oYXMoZXZlbnQuaWQpKSBjb250aW51ZTtcclxuXHJcbiAgICBjb25zdCBncm91cDogSUNhbGVuZGFyRXZlbnRbXSA9IFtldmVudF07XHJcbiAgICB1c2VkLmFkZChldmVudC5pZCk7XHJcblxyXG4gICAgLy8gRXhwYW5kIGJ5IHRocmVzaG9sZCBjaGFpbiAoVjEgbG9naWM6IG5vIG92ZXJsYXAgcmVxdWlyZW1lbnQsIGp1c3QgdGhyZXNob2xkKVxyXG4gICAgbGV0IGV4cGFuZGVkID0gdHJ1ZTtcclxuICAgIHdoaWxlIChleHBhbmRlZCkge1xyXG4gICAgICBleHBhbmRlZCA9IGZhbHNlO1xyXG4gICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBzb3J0ZWQpIHtcclxuICAgICAgICBpZiAodXNlZC5oYXMoY2FuZGlkYXRlLmlkKSkgY29udGludWU7XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbm5lY3RzID0gZ3JvdXAuc29tZShtZW1iZXIgPT5cclxuICAgICAgICAgIGV2ZW50c1dpdGhpblRocmVzaG9sZChtZW1iZXIsIGNhbmRpZGF0ZSwgdGhyZXNob2xkTWludXRlcylcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBpZiAoY29ubmVjdHMpIHtcclxuICAgICAgICAgIGdyb3VwLnB1c2goY2FuZGlkYXRlKTtcclxuICAgICAgICAgIHVzZWQuYWRkKGNhbmRpZGF0ZS5pZCk7XHJcbiAgICAgICAgICBleHBhbmRlZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXBzLnB1c2goZ3JvdXApO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGdyb3VwcztcclxufVxyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZSBzdGFjayBsZXZlbHMgZm9yIG92ZXJsYXBwaW5nIGV2ZW50cyB1c2luZyBncmVlZHkgYWxnb3JpdGhtXHJcbiAqIEZvciBlYWNoIGV2ZW50OiBsZXZlbCA9IG1heChvdmVybGFwcGluZyBhbHJlYWR5LXByb2Nlc3NlZCBldmVudHMpICsgMVxyXG4gKi9cclxuZnVuY3Rpb24gY2FsY3VsYXRlU3RhY2tMZXZlbHMoZXZlbnRzOiBJQ2FsZW5kYXJFdmVudFtdKTogTWFwPHN0cmluZywgbnVtYmVyPiB7XHJcbiAgY29uc3QgbGV2ZWxzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIGxldCBtYXhPdmVybGFwcGluZ0xldmVsID0gLTE7XHJcblxyXG4gICAgLy8gRmluZCBtYXggbGV2ZWwgYW1vbmcgb3ZlcmxhcHBpbmcgZXZlbnRzIGFscmVhZHkgcHJvY2Vzc2VkXHJcbiAgICBmb3IgKGNvbnN0IFtpZCwgbGV2ZWxdIG9mIGxldmVscykge1xyXG4gICAgICBjb25zdCBvdGhlciA9IGV2ZW50cy5maW5kKGUgPT4gZS5pZCA9PT0gaWQpO1xyXG4gICAgICBpZiAob3RoZXIgJiYgZXZlbnRzT3ZlcmxhcChldmVudCwgb3RoZXIpKSB7XHJcbiAgICAgICAgbWF4T3ZlcmxhcHBpbmdMZXZlbCA9IE1hdGgubWF4KG1heE92ZXJsYXBwaW5nTGV2ZWwsIGxldmVsKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldmVscy5zZXQoZXZlbnQuaWQsIG1heE92ZXJsYXBwaW5nTGV2ZWwgKyAxKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBsZXZlbHM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBbGxvY2F0ZSBldmVudHMgdG8gY29sdW1ucyBmb3IgR1JJRCBsYXlvdXQgdXNpbmcgZ3JlZWR5IGFsZ29yaXRobVxyXG4gKiBOb24tb3ZlcmxhcHBpbmcgZXZlbnRzIGNhbiBzaGFyZSBhIGNvbHVtbiB0byBtaW5pbWl6ZSB0b3RhbCBjb2x1bW5zXHJcbiAqL1xyXG5mdW5jdGlvbiBhbGxvY2F0ZUNvbHVtbnMoZXZlbnRzOiBJQ2FsZW5kYXJFdmVudFtdKTogSUNhbGVuZGFyRXZlbnRbXVtdIHtcclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuICBjb25zdCBjb2x1bW5zOiBJQ2FsZW5kYXJFdmVudFtdW10gPSBbXTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIC8vIEZpbmQgZmlyc3QgY29sdW1uIHdoZXJlIGV2ZW50IGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIGV4aXN0aW5nIGV2ZW50c1xyXG4gICAgbGV0IHBsYWNlZCA9IGZhbHNlO1xyXG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xyXG4gICAgICBjb25zdCBjYW5GaXQgPSAhY29sdW1uLnNvbWUoZSA9PiBldmVudHNPdmVybGFwKGV2ZW50LCBlKSk7XHJcbiAgICAgIGlmIChjYW5GaXQpIHtcclxuICAgICAgICBjb2x1bW4ucHVzaChldmVudCk7XHJcbiAgICAgICAgcGxhY2VkID0gdHJ1ZTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIE5vIHN1aXRhYmxlIGNvbHVtbiBmb3VuZCwgY3JlYXRlIG5ldyBvbmVcclxuICAgIGlmICghcGxhY2VkKSB7XHJcbiAgICAgIGNvbHVtbnMucHVzaChbZXZlbnRdKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBjb2x1bW5zO1xyXG59XHJcblxyXG4vKipcclxuICogTWFpbiBlbnRyeSBwb2ludDogQ2FsY3VsYXRlIGNvbXBsZXRlIGxheW91dCBmb3IgYSBjb2x1bW4ncyBldmVudHNcclxuICpcclxuICogQWxnb3JpdGhtOlxyXG4gKiAxLiBGaW5kIG92ZXJsYXAgZ3JvdXBzIChldmVudHMgY29ubmVjdGVkIGJ5IG92ZXJsYXAgY2hhaW4pXHJcbiAqIDIuIEZvciBlYWNoIG92ZXJsYXAgZ3JvdXAsIGZpbmQgZ3JpZCBjYW5kaWRhdGVzIChldmVudHMgd2l0aGluIHRocmVzaG9sZCBjaGFpbilcclxuICogMy4gSWYgYWxsIGV2ZW50cyBpbiBvdmVybGFwIGdyb3VwIGZvcm0gYSBzaW5nbGUgZ3JpZCBjYW5kaWRhdGUgXHUyMTkyIEdSSUQgbW9kZVxyXG4gKiA0LiBPdGhlcndpc2UgXHUyMTkyIFNUQUNLSU5HIG1vZGUgd2l0aCBjYWxjdWxhdGVkIGxldmVsc1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUNvbHVtbkxheW91dChcclxuICBldmVudHM6IElDYWxlbmRhckV2ZW50W10sXHJcbiAgY29uZmlnOiBJR3JpZENvbmZpZ1xyXG4pOiBJQ29sdW1uTGF5b3V0IHtcclxuICBjb25zdCB0aHJlc2hvbGRNaW51dGVzID0gY29uZmlnLmdyaWRTdGFydFRocmVzaG9sZE1pbnV0ZXMgPz8gMTA7XHJcblxyXG4gIGNvbnN0IHJlc3VsdDogSUNvbHVtbkxheW91dCA9IHtcclxuICAgIGdyaWRzOiBbXSxcclxuICAgIHN0YWNrZWQ6IFtdXHJcbiAgfTtcclxuXHJcbiAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApIHJldHVybiByZXN1bHQ7XHJcblxyXG4gIC8vIEZpbmQgYWxsIG92ZXJsYXBwaW5nIGV2ZW50IGdyb3Vwc1xyXG4gIGNvbnN0IG92ZXJsYXBHcm91cHMgPSBmaW5kT3ZlcmxhcEdyb3VwcyhldmVudHMpO1xyXG5cclxuICBmb3IgKGNvbnN0IG92ZXJsYXBHcm91cCBvZiBvdmVybGFwR3JvdXBzKSB7XHJcbiAgICBpZiAob3ZlcmxhcEdyb3VwLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAvLyBTaW5nbGUgZXZlbnQgLSBubyBncm91cGluZyBuZWVkZWRcclxuICAgICAgcmVzdWx0LnN0YWNrZWQucHVzaCh7XHJcbiAgICAgICAgZXZlbnQ6IG92ZXJsYXBHcm91cFswXSxcclxuICAgICAgICBzdGFja0xldmVsOiAwXHJcbiAgICAgIH0pO1xyXG4gICAgICBjb250aW51ZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBXaXRoaW4gdGhpcyBvdmVybGFwIGdyb3VwLCBmaW5kIGdyaWQgY2FuZGlkYXRlcyAodGhyZXNob2xkLWNvbm5lY3RlZCBzdWJncm91cHMpXHJcbiAgICBjb25zdCBncmlkU3ViZ3JvdXBzID0gZmluZEdyaWRDYW5kaWRhdGVzKG92ZXJsYXBHcm91cCwgdGhyZXNob2xkTWludXRlcyk7XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgdGhlIEVOVElSRSBvdmVybGFwIGdyb3VwIGZvcm1zIGEgc2luZ2xlIGdyaWQgY2FuZGlkYXRlXHJcbiAgICAvLyBUaGlzIGhhcHBlbnMgd2hlbiBhbGwgZXZlbnRzIGFyZSBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpblxyXG4gICAgY29uc3QgbGFyZ2VzdEdyaWRDYW5kaWRhdGUgPSBncmlkU3ViZ3JvdXBzLnJlZHVjZSgobWF4LCBnKSA9PlxyXG4gICAgICBnLmxlbmd0aCA+IG1heC5sZW5ndGggPyBnIDogbWF4LCBncmlkU3ViZ3JvdXBzWzBdKTtcclxuXHJcbiAgICBpZiAobGFyZ2VzdEdyaWRDYW5kaWRhdGUubGVuZ3RoID09PSBvdmVybGFwR3JvdXAubGVuZ3RoKSB7XHJcbiAgICAgIC8vIEFsbCBldmVudHMgaW4gb3ZlcmxhcCBncm91cCBhcmUgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgY2hhaW4gXHUyMTkyIEdSSUQgbW9kZVxyXG4gICAgICBjb25zdCBjb2x1bW5zID0gYWxsb2NhdGVDb2x1bW5zKG92ZXJsYXBHcm91cCk7XHJcbiAgICAgIGNvbnN0IGVhcmxpZXN0ID0gb3ZlcmxhcEdyb3VwLnJlZHVjZSgobWluLCBlKSA9PlxyXG4gICAgICAgIGUuc3RhcnQgPCBtaW4uc3RhcnQgPyBlIDogbWluLCBvdmVybGFwR3JvdXBbMF0pO1xyXG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZWFybGllc3Quc3RhcnQsIGVhcmxpZXN0LmVuZCwgY29uZmlnKTtcclxuXHJcbiAgICAgIHJlc3VsdC5ncmlkcy5wdXNoKHtcclxuICAgICAgICBldmVudHM6IG92ZXJsYXBHcm91cCxcclxuICAgICAgICBjb2x1bW5zLFxyXG4gICAgICAgIHN0YWNrTGV2ZWw6IDAsXHJcbiAgICAgICAgcG9zaXRpb246IHsgdG9wOiBwb3NpdGlvbi50b3AgfVxyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIE5vdCBhbGwgZXZlbnRzIGNvbm5lY3RlZCB2aWEgdGhyZXNob2xkIFx1MjE5MiBTVEFDS0lORyBtb2RlXHJcbiAgICAgIGNvbnN0IGxldmVscyA9IGNhbGN1bGF0ZVN0YWNrTGV2ZWxzKG92ZXJsYXBHcm91cCk7XHJcbiAgICAgIGZvciAoY29uc3QgZXZlbnQgb2Ygb3ZlcmxhcEdyb3VwKSB7XHJcbiAgICAgICAgcmVzdWx0LnN0YWNrZWQucHVzaCh7XHJcbiAgICAgICAgICBldmVudCxcclxuICAgICAgICAgIHN0YWNrTGV2ZWw6IGxldmVscy5nZXQoZXZlbnQuaWQpID8/IDBcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG4iLCAiaW1wb3J0IHsgSUNhbGVuZGFyRXZlbnQsIElFdmVudEJ1cywgSUV2ZW50VXBkYXRlZFBheWxvYWQgfSBmcm9tICcuLi8uLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc3RvcmFnZS9ldmVudHMvRXZlbnRTZXJ2aWNlJztcclxuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL0RhdGVTZXJ2aWNlJztcclxuaW1wb3J0IHsgSUdyaWRDb25maWcgfSBmcm9tICcuLi8uLi9jb3JlL0lHcmlkQ29uZmlnJztcclxuaW1wb3J0IHsgY2FsY3VsYXRlRXZlbnRQb3NpdGlvbiwgc25hcFRvR3JpZCwgcGl4ZWxzVG9NaW51dGVzIH0gZnJvbSAnLi4vLi4vdXRpbHMvUG9zaXRpb25VdGlscyc7XHJcbmltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XHJcbmltcG9ydCB7IElEcmFnQ29sdW1uQ2hhbmdlUGF5bG9hZCwgSURyYWdNb3ZlUGF5bG9hZCwgSURyYWdFbmRQYXlsb2FkLCBJRHJhZ0xlYXZlSGVhZGVyUGF5bG9hZCB9IGZyb20gJy4uLy4uL3R5cGVzL0RyYWdUeXBlcyc7XHJcbmltcG9ydCB7IGNhbGN1bGF0ZUNvbHVtbkxheW91dCB9IGZyb20gJy4vRXZlbnRMYXlvdXRFbmdpbmUnO1xyXG5pbXBvcnQgeyBJR3JpZEdyb3VwTGF5b3V0IH0gZnJvbSAnLi9FdmVudExheW91dFR5cGVzJztcclxuaW1wb3J0IHsgRmlsdGVyVGVtcGxhdGUgfSBmcm9tICcuLi8uLi9jb3JlL0ZpbHRlclRlbXBsYXRlJztcclxuXHJcbi8qKlxyXG4gKiBFdmVudFJlbmRlcmVyIC0gUmVuZGVycyBjYWxlbmRhciBldmVudHMgdG8gdGhlIERPTVxyXG4gKlxyXG4gKiBDTEVBTiBhcHByb2FjaDpcclxuICogLSBPbmx5IGRhdGEtaWQgYXR0cmlidXRlIG9uIGV2ZW50IGVsZW1lbnRcclxuICogLSBpbm5lckhUTUwgY29udGFpbnMgb25seSB2aXNpYmxlIGNvbnRlbnRcclxuICogLSBFdmVudCBkYXRhIHJldHJpZXZlZCB2aWEgRXZlbnRTZXJ2aWNlIHdoZW4gbmVlZGVkXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgRXZlbnRSZW5kZXJlciB7XHJcbiAgcHJpdmF0ZSBjb250YWluZXI6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZSxcclxuICAgIHByaXZhdGUgZGF0ZVNlcnZpY2U6IERhdGVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBncmlkQ29uZmlnOiBJR3JpZENvbmZpZyxcclxuICAgIHByaXZhdGUgZXZlbnRCdXM6IElFdmVudEJ1c1xyXG4gICkge1xyXG4gICAgdGhpcy5zZXR1cExpc3RlbmVycygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0dXAgbGlzdGVuZXJzIGZvciBkcmFnLWRyb3AgYW5kIHVwZGF0ZSBldmVudHNcclxuICAgKi9cclxuICBwcml2YXRlIHNldHVwTGlzdGVuZXJzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfQ09MVU1OX0NIQU5HRSwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElEcmFnQ29sdW1uQ2hhbmdlUGF5bG9hZD4pLmRldGFpbDtcclxuICAgICAgdGhpcy5oYW5kbGVDb2x1bW5DaGFuZ2UocGF5bG9hZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19NT1ZFLCAoZSkgPT4ge1xyXG4gICAgICBjb25zdCBwYXlsb2FkID0gKGUgYXMgQ3VzdG9tRXZlbnQ8SURyYWdNb3ZlUGF5bG9hZD4pLmRldGFpbDtcclxuICAgICAgdGhpcy51cGRhdGVEcmFnVGltZXN0YW1wKHBheWxvYWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX1VQREFURUQsIChlKSA9PiB7XHJcbiAgICAgIGNvbnN0IHBheWxvYWQgPSAoZSBhcyBDdXN0b21FdmVudDxJRXZlbnRVcGRhdGVkUGF5bG9hZD4pLmRldGFpbDtcclxuICAgICAgdGhpcy5oYW5kbGVFdmVudFVwZGF0ZWQocGF5bG9hZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19FTkQsIChlKSA9PiB7XHJcbiAgICAgIGNvbnN0IHBheWxvYWQgPSAoZSBhcyBDdXN0b21FdmVudDxJRHJhZ0VuZFBheWxvYWQ+KS5kZXRhaWw7XHJcbiAgICAgIHRoaXMuaGFuZGxlRHJhZ0VuZChwYXlsb2FkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0xFQVZFX0hFQURFUiwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElEcmFnTGVhdmVIZWFkZXJQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLmhhbmRsZURyYWdMZWF2ZUhlYWRlcihwYXlsb2FkKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEVWRU5UX0RSQUdfRU5EIC0gcmVtb3ZlIGVsZW1lbnQgaWYgZHJvcHBlZCBpbiBoZWFkZXJcclxuICAgKi9cclxuICBwcml2YXRlIGhhbmRsZURyYWdFbmQocGF5bG9hZDogSURyYWdFbmRQYXlsb2FkKTogdm9pZCB7XHJcbiAgICBpZiAocGF5bG9hZC50YXJnZXQgPT09ICdoZWFkZXInKSB7XHJcbiAgICAgIC8vIEV2ZW50IHdhcyBkcm9wcGVkIGluIGhlYWRlciBkcmF3ZXIgLSByZW1vdmUgZnJvbSBncmlkXHJcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmNvbnRhaW5lcj8ucXVlcnlTZWxlY3Rvcihgc3dwLWNvbnRlbnQtdmlld3BvcnQgc3dwLWV2ZW50W2RhdGEtZXZlbnQtaWQ9XCIke3BheWxvYWQuc3dwRXZlbnQuZXZlbnRJZH1cIl1gKTtcclxuICAgICAgZWxlbWVudD8ucmVtb3ZlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgaGVhZGVyIGl0ZW0gbGVhdmluZyBoZWFkZXIgLSBjcmVhdGUgc3dwLWV2ZW50IGluIGdyaWRcclxuICAgKi9cclxuICBwcml2YXRlIGhhbmRsZURyYWdMZWF2ZUhlYWRlcihwYXlsb2FkOiBJRHJhZ0xlYXZlSGVhZGVyUGF5bG9hZCk6IHZvaWQge1xyXG4gICAgLy8gT25seSBoYW5kbGUgd2hlbiBzb3VyY2UgaXMgaGVhZGVyIChoZWFkZXIgaXRlbSBkcmFnZ2VkIHRvIGdyaWQpXHJcbiAgICBpZiAocGF5bG9hZC5zb3VyY2UgIT09ICdoZWFkZXInKSByZXR1cm47XHJcbiAgICBpZiAoIXBheWxvYWQudGFyZ2V0Q29sdW1uIHx8ICFwYXlsb2FkLnN0YXJ0IHx8ICFwYXlsb2FkLmVuZCkgcmV0dXJuO1xyXG5cclxuICAgIC8vIFR1cm4gaGVhZGVyIGl0ZW0gaW50byBnaG9zdCAoc3RheXMgdmlzaWJsZSBidXQgZmFkZWQpXHJcbiAgICBpZiAocGF5bG9hZC5lbGVtZW50KSB7XHJcbiAgICAgIHBheWxvYWQuZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnLWdob3N0Jyk7XHJcbiAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gJzAuMyc7XHJcbiAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENyZWF0ZSBldmVudCBvYmplY3QgZnJvbSBoZWFkZXIgaXRlbSBkYXRhXHJcbiAgICBjb25zdCBldmVudDogSUNhbGVuZGFyRXZlbnQgPSB7XHJcbiAgICAgIGlkOiBwYXlsb2FkLmV2ZW50SWQsXHJcbiAgICAgIHRpdGxlOiBwYXlsb2FkLnRpdGxlIHx8ICcnLFxyXG4gICAgICBkZXNjcmlwdGlvbjogJycsXHJcbiAgICAgIHN0YXJ0OiBwYXlsb2FkLnN0YXJ0LFxyXG4gICAgICBlbmQ6IHBheWxvYWQuZW5kLFxyXG4gICAgICB0eXBlOiAnY3VzdG9tZXInLFxyXG4gICAgICBhbGxEYXk6IGZhbHNlLFxyXG4gICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcclxuICAgIH07XHJcblxyXG4gICAgLy8gQ3JlYXRlIHN3cC1ldmVudCBlbGVtZW50IHVzaW5nIGV4aXN0aW5nIG1ldGhvZFxyXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcclxuXHJcbiAgICAvLyBBZGQgdG8gdGFyZ2V0IGNvbHVtblxyXG4gICAgbGV0IGV2ZW50c0xheWVyID0gcGF5bG9hZC50YXJnZXRDb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xyXG4gICAgaWYgKCFldmVudHNMYXllcikge1xyXG4gICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgICAgcGF5bG9hZC50YXJnZXRDb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xyXG4gICAgfVxyXG4gICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XHJcblxyXG4gICAgLy8gTWFyayBhcyBkcmFnZ2luZyBzbyBEcmFnRHJvcE1hbmFnZXIgY2FuIGNvbnRpbnVlIHdpdGggaXRcclxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZ2dpbmcnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBFVkVOVF9VUERBVEVEIC0gcmUtcmVuZGVyIGFmZmVjdGVkIGNvbHVtbnNcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGhhbmRsZUV2ZW50VXBkYXRlZChwYXlsb2FkOiBJRXZlbnRVcGRhdGVkUGF5bG9hZCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gUmUtcmVuZGVyIHNvdXJjZSBjb2x1bW4gKGlmIGRpZmZlcmVudCBmcm9tIHRhcmdldClcclxuICAgIGlmIChwYXlsb2FkLnNvdXJjZUNvbHVtbktleSAhPT0gcGF5bG9hZC50YXJnZXRDb2x1bW5LZXkpIHtcclxuICAgICAgYXdhaXQgdGhpcy5yZXJlbmRlckNvbHVtbihwYXlsb2FkLnNvdXJjZUNvbHVtbktleSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmUtcmVuZGVyIHRhcmdldCBjb2x1bW5cclxuICAgIGF3YWl0IHRoaXMucmVyZW5kZXJDb2x1bW4ocGF5bG9hZC50YXJnZXRDb2x1bW5LZXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmUtcmVuZGVyIGEgc2luZ2xlIGNvbHVtbiB3aXRoIGZyZXNoIGRhdGEgZnJvbSBJbmRleGVkREJcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHJlcmVuZGVyQ29sdW1uKGNvbHVtbktleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmZpbmRDb2x1bW4oY29sdW1uS2V5KTtcclxuICAgIGlmICghY29sdW1uKSByZXR1cm47XHJcblxyXG4gICAgLy8gUmVhZCBkYXRlIGFuZCByZXNvdXJjZUlkIGRpcmVjdGx5IGZyb20gY29sdW1uIGF0dHJpYnV0ZXMgKGNvbHVtbktleSBpcyBvcGFxdWUpXHJcbiAgICBjb25zdCBkYXRlID0gY29sdW1uLmRhdGFzZXQuZGF0ZTtcclxuICAgIGNvbnN0IHJlc291cmNlSWQgPSBjb2x1bW4uZGF0YXNldC5yZXNvdXJjZUlkO1xyXG5cclxuICAgIGlmICghZGF0ZSkgcmV0dXJuO1xyXG5cclxuICAgIC8vIEdldCBkYXRlIHJhbmdlIGZvciB0aGlzIGRheVxyXG4gICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoZGF0ZSk7XHJcbiAgICBjb25zdCBlbmREYXRlID0gbmV3IERhdGUoZGF0ZSk7XHJcbiAgICBlbmREYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XHJcblxyXG4gICAgLy8gRmV0Y2ggZXZlbnRzIGZyb20gSW5kZXhlZERCXHJcbiAgICBjb25zdCBldmVudHMgPSByZXNvdXJjZUlkXHJcbiAgICAgID8gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlSZXNvdXJjZUFuZERhdGVSYW5nZShyZXNvdXJjZUlkLCBzdGFydERhdGUsIGVuZERhdGUpXHJcbiAgICAgIDogYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2Uoc3RhcnREYXRlLCBlbmREYXRlKTtcclxuXHJcbiAgICAvLyBGaWx0ZXIgdG8gdGltZWQgZXZlbnRzIGFuZCBtYXRjaCBkYXRlIGV4YWN0bHlcclxuICAgIGNvbnN0IHRpbWVkRXZlbnRzID0gZXZlbnRzLmZpbHRlcihldmVudCA9PlxyXG4gICAgICAhZXZlbnQuYWxsRGF5ICYmIHRoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF0ZUtleShldmVudC5zdGFydCkgPT09IGRhdGVcclxuICAgICk7XHJcblxyXG4gICAgLy8gR2V0IG9yIGNyZWF0ZSBldmVudHMgbGF5ZXJcclxuICAgIGxldCBldmVudHNMYXllciA9IGNvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICBpZiAoIWV2ZW50c0xheWVyKSB7XHJcbiAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xyXG4gICAgICBjb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENsZWFyIGV4aXN0aW5nIGV2ZW50c1xyXG4gICAgZXZlbnRzTGF5ZXIuaW5uZXJIVE1MID0gJyc7XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIGxheW91dCB3aXRoIHN0YWNraW5nL2dyb3VwaW5nXHJcbiAgICBjb25zdCBsYXlvdXQgPSBjYWxjdWxhdGVDb2x1bW5MYXlvdXQodGltZWRFdmVudHMsIHRoaXMuZ3JpZENvbmZpZyk7XHJcblxyXG4gICAgLy8gUmVuZGVyIEdSSUQgZ3JvdXBzXHJcbiAgICBsYXlvdXQuZ3JpZHMuZm9yRWFjaChncmlkID0+IHtcclxuICAgICAgY29uc3QgZ3JvdXBFbCA9IHRoaXMucmVuZGVyR3JpZEdyb3VwKGdyaWQpO1xyXG4gICAgICBldmVudHNMYXllciEuYXBwZW5kQ2hpbGQoZ3JvdXBFbCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBSZW5kZXIgU1RBQ0tFRCBldmVudHNcclxuICAgIGxheW91dC5zdGFja2VkLmZvckVhY2goaXRlbSA9PiB7XHJcbiAgICAgIGNvbnN0IGV2ZW50RWwgPSB0aGlzLnJlbmRlclN0YWNrZWRFdmVudChpdGVtLmV2ZW50LCBpdGVtLnN0YWNrTGV2ZWwpO1xyXG4gICAgICBldmVudHNMYXllciEuYXBwZW5kQ2hpbGQoZXZlbnRFbCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpbmQgYSBjb2x1bW4gZWxlbWVudCBieSBjb2x1bW5LZXlcclxuICAgKi9cclxuICBwcml2YXRlIGZpbmRDb2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiBIVE1MRWxlbWVudCB8IG51bGwge1xyXG4gICAgaWYgKCF0aGlzLmNvbnRhaW5lcikgcmV0dXJuIG51bGw7XHJcbiAgICByZXR1cm4gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3Rvcihgc3dwLWRheS1jb2x1bW5bZGF0YS1jb2x1bW4ta2V5PVwiJHtjb2x1bW5LZXl9XCJdYCkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgZXZlbnQgbW92aW5nIHRvIGEgbmV3IGNvbHVtbiBkdXJpbmcgZHJhZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlQ29sdW1uQ2hhbmdlKHBheWxvYWQ6IElEcmFnQ29sdW1uQ2hhbmdlUGF5bG9hZCk6IHZvaWQge1xyXG4gICAgY29uc3QgZXZlbnRzTGF5ZXIgPSBwYXlsb2FkLm5ld0NvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICBpZiAoIWV2ZW50c0xheWVyKSByZXR1cm47XHJcblxyXG4gICAgLy8gTW92ZSBlbGVtZW50IHRvIG5ldyBjb2x1bW5cclxuICAgIGV2ZW50c0xheWVyLmFwcGVuZENoaWxkKHBheWxvYWQuZWxlbWVudCk7XHJcblxyXG4gICAgLy8gUHJlc2VydmUgWSBwb3NpdGlvblxyXG4gICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLnRvcCA9IGAke3BheWxvYWQuY3VycmVudFl9cHhgO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIHRpbWVzdGFtcCBkaXNwbGF5IGR1cmluZyBkcmFnIChzbmFwcGVkIHRvIGdyaWQpXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVEcmFnVGltZXN0YW1wKHBheWxvYWQ6IElEcmFnTW92ZVBheWxvYWQpOiB2b2lkIHtcclxuICAgIGNvbnN0IHRpbWVFbCA9IHBheWxvYWQuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnQtdGltZScpO1xyXG4gICAgaWYgKCF0aW1lRWwpIHJldHVybjtcclxuXHJcbiAgICAvLyBTbmFwIHBvc2l0aW9uIHRvIGdyaWQgaW50ZXJ2YWxcclxuICAgIGNvbnN0IHNuYXBwZWRZID0gc25hcFRvR3JpZChwYXlsb2FkLmN1cnJlbnRZLCB0aGlzLmdyaWRDb25maWcpO1xyXG5cclxuICAgIC8vIENhbGN1bGF0ZSBuZXcgc3RhcnQgdGltZVxyXG4gICAgY29uc3QgbWludXRlc0Zyb21HcmlkU3RhcnQgPSBwaXhlbHNUb01pbnV0ZXMoc25hcHBlZFksIHRoaXMuZ3JpZENvbmZpZyk7XHJcbiAgICBjb25zdCBzdGFydE1pbnV0ZXMgPSAodGhpcy5ncmlkQ29uZmlnLmRheVN0YXJ0SG91ciAqIDYwKSArIG1pbnV0ZXNGcm9tR3JpZFN0YXJ0O1xyXG5cclxuICAgIC8vIEtlZXAgb3JpZ2luYWwgZHVyYXRpb24gKGZyb20gZWxlbWVudCBoZWlnaHQpXHJcbiAgICBjb25zdCBoZWlnaHQgPSBwYXJzZUZsb2F0KHBheWxvYWQuZWxlbWVudC5zdHlsZS5oZWlnaHQpIHx8IHRoaXMuZ3JpZENvbmZpZy5ob3VySGVpZ2h0O1xyXG4gICAgY29uc3QgZHVyYXRpb25NaW51dGVzID0gcGl4ZWxzVG9NaW51dGVzKGhlaWdodCwgdGhpcy5ncmlkQ29uZmlnKTtcclxuXHJcbiAgICAvLyBDcmVhdGUgRGF0ZSBvYmplY3RzIGZvciBjb25zaXN0ZW50IGZvcm1hdHRpbmcgdmlhIERhdGVTZXJ2aWNlXHJcbiAgICBjb25zdCBzdGFydCA9IHRoaXMubWludXRlc1RvRGF0ZShzdGFydE1pbnV0ZXMpO1xyXG4gICAgY29uc3QgZW5kID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyArIGR1cmF0aW9uTWludXRlcyk7XHJcblxyXG4gICAgdGltZUVsLnRleHRDb250ZW50ID0gdGhpcy5kYXRlU2VydmljZS5mb3JtYXRUaW1lUmFuZ2Uoc3RhcnQsIGVuZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0IG1pbnV0ZXMgc2luY2UgbWlkbmlnaHQgdG8gYSBEYXRlIG9iamVjdCAodG9kYXkpXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBtaW51dGVzVG9EYXRlKG1pbnV0ZXM6IG51bWJlcik6IERhdGUge1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBkYXRlLnNldEhvdXJzKE1hdGguZmxvb3IobWludXRlcyAvIDYwKSAlIDI0LCBtaW51dGVzICUgNjAsIDAsIDApO1xyXG4gICAgcmV0dXJuIGRhdGU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW5kZXIgZXZlbnRzIGZvciB2aXNpYmxlIGRhdGVzIGludG8gZGF5IGNvbHVtbnNcclxuICAgKiBAcGFyYW0gY29udGFpbmVyIC0gQ2FsZW5kYXIgY29udGFpbmVyIGVsZW1lbnRcclxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIHdpdGggJ2RhdGUnIGFuZCBvcHRpb25hbGx5ICdyZXNvdXJjZScgYXJyYXlzXHJcbiAgICogQHBhcmFtIGZpbHRlclRlbXBsYXRlIC0gVGVtcGxhdGUgZm9yIG1hdGNoaW5nIGV2ZW50cyB0byBjb2x1bW5zXHJcbiAgICovXHJcbiAgYXN5bmMgcmVuZGVyKGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsIGZpbHRlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+LCBmaWx0ZXJUZW1wbGF0ZTogRmlsdGVyVGVtcGxhdGUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIC8vIFN0b3JlIGNvbnRhaW5lciByZWZlcmVuY2UgZm9yIGxhdGVyIHJlLXJlbmRlcnNcclxuICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xyXG5cclxuICAgIGNvbnN0IHZpc2libGVEYXRlcyA9IGZpbHRlclsnZGF0ZSddIHx8IFtdO1xyXG5cclxuICAgIGlmICh2aXNpYmxlRGF0ZXMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgLy8gR2V0IGRhdGUgcmFuZ2UgZm9yIHF1ZXJ5XHJcbiAgICBjb25zdCBzdGFydERhdGUgPSBuZXcgRGF0ZSh2aXNpYmxlRGF0ZXNbMF0pO1xyXG4gICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1t2aXNpYmxlRGF0ZXMubGVuZ3RoIC0gMV0pO1xyXG4gICAgZW5kRGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpO1xyXG5cclxuICAgIC8vIEZldGNoIGV2ZW50cyBmcm9tIEluZGV4ZWREQlxyXG4gICAgY29uc3QgZXZlbnRzID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2Uoc3RhcnREYXRlLCBlbmREYXRlKTtcclxuXHJcbiAgICAvLyBGaW5kIGRheSBjb2x1bW5zXHJcbiAgICBjb25zdCBkYXlDb2x1bW5zID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpO1xyXG4gICAgaWYgKCFkYXlDb2x1bW5zKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgY29sdW1ucyA9IGRheUNvbHVtbnMucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKTtcclxuXHJcbiAgICAvLyBSZW5kZXIgZXZlbnRzIGludG8gZWFjaCBjb2x1bW4gYmFzZWQgb24gRmlsdGVyVGVtcGxhdGUgbWF0Y2hpbmdcclxuICAgIGNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xyXG4gICAgICBjb25zdCBjb2x1bW5FbCA9IGNvbHVtbiBhcyBIVE1MRWxlbWVudDtcclxuXHJcbiAgICAgIC8vIFVzZSBGaWx0ZXJUZW1wbGF0ZSBmb3IgbWF0Y2hpbmcgLSBvbmx5IGZpZWxkcyBpbiB0ZW1wbGF0ZSBhcmUgY2hlY2tlZFxyXG4gICAgICBjb25zdCBjb2x1bW5FdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+IGZpbHRlclRlbXBsYXRlLm1hdGNoZXMoZXZlbnQsIGNvbHVtbkVsKSk7XHJcblxyXG4gICAgICAvLyBHZXQgb3IgY3JlYXRlIGV2ZW50cyBsYXllclxyXG4gICAgICBsZXQgZXZlbnRzTGF5ZXIgPSBjb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xyXG4gICAgICBpZiAoIWV2ZW50c0xheWVyKSB7XHJcbiAgICAgICAgZXZlbnRzTGF5ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICAgICAgY29sdW1uLmFwcGVuZENoaWxkKGV2ZW50c0xheWVyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgZXZlbnRzXHJcbiAgICAgIGV2ZW50c0xheWVyLmlubmVySFRNTCA9ICcnO1xyXG5cclxuICAgICAgLy8gRmlsdGVyIHRvIHRpbWVkIGV2ZW50cyBvbmx5XHJcbiAgICAgIGNvbnN0IHRpbWVkRXZlbnRzID0gY29sdW1uRXZlbnRzLmZpbHRlcihldmVudCA9PiAhZXZlbnQuYWxsRGF5KTtcclxuXHJcbiAgICAgIC8vIENhbGN1bGF0ZSBsYXlvdXQgd2l0aCBzdGFja2luZy9ncm91cGluZ1xyXG4gICAgICBjb25zdCBsYXlvdXQgPSBjYWxjdWxhdGVDb2x1bW5MYXlvdXQodGltZWRFdmVudHMsIHRoaXMuZ3JpZENvbmZpZyk7XHJcblxyXG4gICAgICAvLyBSZW5kZXIgR1JJRCBncm91cHMgKHNpbXVsdGFuZW91cyBldmVudHMgc2lkZS1ieS1zaWRlKVxyXG4gICAgICBsYXlvdXQuZ3JpZHMuZm9yRWFjaChncmlkID0+IHtcclxuICAgICAgICBjb25zdCBncm91cEVsID0gdGhpcy5yZW5kZXJHcmlkR3JvdXAoZ3JpZCk7XHJcbiAgICAgICAgZXZlbnRzTGF5ZXIhLmFwcGVuZENoaWxkKGdyb3VwRWwpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIFJlbmRlciBTVEFDS0VEIGV2ZW50cyAob3ZlcmxhcHBpbmcgd2l0aCBtYXJnaW4gb2Zmc2V0KVxyXG4gICAgICBsYXlvdXQuc3RhY2tlZC5mb3JFYWNoKGl0ZW0gPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50RWwgPSB0aGlzLnJlbmRlclN0YWNrZWRFdmVudChpdGVtLmV2ZW50LCBpdGVtLnN0YWNrTGV2ZWwpO1xyXG4gICAgICAgIGV2ZW50c0xheWVyIS5hcHBlbmRDaGlsZChldmVudEVsKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZSBhIHNpbmdsZSBldmVudCBlbGVtZW50XHJcbiAgICpcclxuICAgKiBDTEVBTiBhcHByb2FjaDpcclxuICAgKiAtIE9ubHkgZGF0YS1pZCBmb3IgbG9va3VwXHJcbiAgICogLSBWaXNpYmxlIGNvbnRlbnQgaW4gaW5uZXJIVE1MIG9ubHlcclxuICAgKi9cclxuICBwcml2YXRlIGNyZWF0ZUV2ZW50RWxlbWVudChldmVudDogSUNhbGVuZGFyRXZlbnQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50Jyk7XHJcblxyXG4gICAgLy8gRGF0YSBhdHRyaWJ1dGVzIGZvciBTd3BFdmVudCBjb21wYXRpYmlsaXR5XHJcbiAgICBlbGVtZW50LmRhdGFzZXQuZXZlbnRJZCA9IGV2ZW50LmlkO1xyXG4gICAgaWYgKGV2ZW50LnJlc291cmNlSWQpIHtcclxuICAgICAgZWxlbWVudC5kYXRhc2V0LnJlc291cmNlSWQgPSBldmVudC5yZXNvdXJjZUlkO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGN1bGF0ZSBwb3NpdGlvblxyXG4gICAgY29uc3QgcG9zaXRpb24gPSBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQsIHRoaXMuZ3JpZENvbmZpZyk7XHJcbiAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3Bvc2l0aW9uLnRvcH1weGA7XHJcbiAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3Bvc2l0aW9uLmhlaWdodH1weGA7XHJcblxyXG4gICAgLy8gQ29sb3IgY2xhc3MgYmFzZWQgb24gZXZlbnQgdHlwZVxyXG4gICAgY29uc3QgY29sb3JDbGFzcyA9IHRoaXMuZ2V0Q29sb3JDbGFzcyhldmVudCk7XHJcbiAgICBpZiAoY29sb3JDbGFzcykge1xyXG4gICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY29sb3JDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVmlzaWJsZSBjb250ZW50IG9ubHlcclxuICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gYFxyXG4gICAgICA8c3dwLWV2ZW50LXRpbWU+JHt0aGlzLmRhdGVTZXJ2aWNlLmZvcm1hdFRpbWVSYW5nZShldmVudC5zdGFydCwgZXZlbnQuZW5kKX08L3N3cC1ldmVudC10aW1lPlxyXG4gICAgICA8c3dwLWV2ZW50LXRpdGxlPiR7dGhpcy5lc2NhcGVIdG1sKGV2ZW50LnRpdGxlKX08L3N3cC1ldmVudC10aXRsZT5cclxuICAgICAgJHtldmVudC5kZXNjcmlwdGlvbiA/IGA8c3dwLWV2ZW50LWRlc2NyaXB0aW9uPiR7dGhpcy5lc2NhcGVIdG1sKGV2ZW50LmRlc2NyaXB0aW9uKX08L3N3cC1ldmVudC1kZXNjcmlwdGlvbj5gIDogJyd9XHJcbiAgICBgO1xyXG5cclxuICAgIHJldHVybiBlbGVtZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGNvbG9yIGNsYXNzIGJhc2VkIG9uIG1ldGFkYXRhLmNvbG9yIG9yIGV2ZW50IHR5cGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldENvbG9yQ2xhc3MoZXZlbnQ6IElDYWxlbmRhckV2ZW50KTogc3RyaW5nIHtcclxuICAgIC8vIENoZWNrIG1ldGFkYXRhLmNvbG9yIGZpcnN0XHJcbiAgICBpZiAoZXZlbnQubWV0YWRhdGE/LmNvbG9yKSB7XHJcbiAgICAgIHJldHVybiBgaXMtJHtldmVudC5tZXRhZGF0YS5jb2xvcn1gO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEZhbGxiYWNrIHRvIHR5cGUtYmFzZWQgY29sb3JcclxuICAgIGNvbnN0IHR5cGVDb2xvcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XHJcbiAgICAgICdjdXN0b21lcic6ICdpcy1ibHVlJyxcclxuICAgICAgJ3ZhY2F0aW9uJzogJ2lzLWdyZWVuJyxcclxuICAgICAgJ2JyZWFrJzogJ2lzLWFtYmVyJyxcclxuICAgICAgJ21lZXRpbmcnOiAnaXMtcHVycGxlJyxcclxuICAgICAgJ2Jsb2NrZWQnOiAnaXMtcmVkJ1xyXG4gICAgfTtcclxuICAgIHJldHVybiB0eXBlQ29sb3JzW2V2ZW50LnR5cGVdIHx8ICdpcy1ibHVlJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVzY2FwZSBIVE1MIHRvIHByZXZlbnQgWFNTXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBlc2NhcGVIdG1sKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgIGRpdi50ZXh0Q29udGVudCA9IHRleHQ7XHJcbiAgICByZXR1cm4gZGl2LmlubmVySFRNTDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbmRlciBhIEdSSUQgZ3JvdXAgd2l0aCBzaWRlLWJ5LXNpZGUgY29sdW1uc1xyXG4gICAqIFVzZWQgd2hlbiBtdWx0aXBsZSBldmVudHMgc3RhcnQgYXQgdGhlIHNhbWUgdGltZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVuZGVyR3JpZEdyb3VwKGxheW91dDogSUdyaWRHcm91cExheW91dCk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50LWdyb3VwJyk7XHJcbiAgICBncm91cC5jbGFzc0xpc3QuYWRkKGBjb2xzLSR7bGF5b3V0LmNvbHVtbnMubGVuZ3RofWApO1xyXG4gICAgZ3JvdXAuc3R5bGUudG9wID0gYCR7bGF5b3V0LnBvc2l0aW9uLnRvcH1weGA7XHJcblxyXG4gICAgLy8gU3RhY2sgbGV2ZWwgc3R5bGluZyBmb3IgZW50aXJlIGdyb3VwIChpZiBuZXN0ZWQgaW4gYW5vdGhlciBldmVudClcclxuICAgIGlmIChsYXlvdXQuc3RhY2tMZXZlbCA+IDApIHtcclxuICAgICAgZ3JvdXAuc3R5bGUubWFyZ2luTGVmdCA9IGAke2xheW91dC5zdGFja0xldmVsICogMTV9cHhgO1xyXG4gICAgICBncm91cC5zdHlsZS56SW5kZXggPSBgJHsxMDAgKyBsYXlvdXQuc3RhY2tMZXZlbH1gO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENhbGN1bGF0ZSB0aGUgaGVpZ2h0IG5lZWRlZCBmb3IgdGhlIGdyb3VwICh0YWxsZXN0IGV2ZW50KVxyXG4gICAgbGV0IG1heEJvdHRvbSA9IDA7XHJcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGxheW91dC5ldmVudHMpIHtcclxuICAgICAgY29uc3QgcG9zID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihldmVudC5zdGFydCwgZXZlbnQuZW5kLCB0aGlzLmdyaWRDb25maWcpO1xyXG4gICAgICBjb25zdCBldmVudEJvdHRvbSA9IHBvcy50b3AgKyBwb3MuaGVpZ2h0O1xyXG4gICAgICBpZiAoZXZlbnRCb3R0b20gPiBtYXhCb3R0b20pIG1heEJvdHRvbSA9IGV2ZW50Qm90dG9tO1xyXG4gICAgfVxyXG4gICAgY29uc3QgZ3JvdXBIZWlnaHQgPSBtYXhCb3R0b20gLSBsYXlvdXQucG9zaXRpb24udG9wO1xyXG4gICAgZ3JvdXAuc3R5bGUuaGVpZ2h0ID0gYCR7Z3JvdXBIZWlnaHR9cHhgO1xyXG5cclxuICAgIC8vIENyZWF0ZSB3cmFwcGVyIGRpdiBmb3IgZWFjaCBjb2x1bW5cclxuICAgIGxheW91dC5jb2x1bW5zLmZvckVhY2goY29sdW1uRXZlbnRzID0+IHtcclxuICAgICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICB3cmFwcGVyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcclxuXHJcbiAgICAgIGNvbHVtbkV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcclxuICAgICAgICBjb25zdCBldmVudEVsID0gdGhpcy5jcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpO1xyXG4gICAgICAgIC8vIFBvc2l0aW9uIHJlbGF0aXZlIHRvIGdyb3VwIHRvcFxyXG4gICAgICAgIGNvbnN0IHBvcyA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcclxuICAgICAgICBldmVudEVsLnN0eWxlLnRvcCA9IGAke3Bvcy50b3AgLSBsYXlvdXQucG9zaXRpb24udG9wfXB4YDtcclxuICAgICAgICBldmVudEVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcclxuICAgICAgICBldmVudEVsLnN0eWxlLmxlZnQgPSAnMCc7XHJcbiAgICAgICAgZXZlbnRFbC5zdHlsZS5yaWdodCA9ICcwJztcclxuICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGV2ZW50RWwpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGdyb3VwLmFwcGVuZENoaWxkKHdyYXBwZXIpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIGdyb3VwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVuZGVyIGEgU1RBQ0tFRCBldmVudCB3aXRoIG1hcmdpbi1sZWZ0IG9mZnNldFxyXG4gICAqIFVzZWQgZm9yIG92ZXJsYXBwaW5nIGV2ZW50cyB0aGF0IGRvbid0IHN0YXJ0IGF0IHRoZSBzYW1lIHRpbWVcclxuICAgKi9cclxuICBwcml2YXRlIHJlbmRlclN0YWNrZWRFdmVudChldmVudDogSUNhbGVuZGFyRXZlbnQsIHN0YWNrTGV2ZWw6IG51bWJlcik6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmNyZWF0ZUV2ZW50RWxlbWVudChldmVudCk7XHJcblxyXG4gICAgLy8gQWRkIHN0YWNrIG1ldGFkYXRhIGZvciBkcmFnLWRyb3AgYW5kIG90aGVyIGZlYXR1cmVzXHJcbiAgICBlbGVtZW50LmRhdGFzZXQuc3RhY2tMaW5rID0gSlNPTi5zdHJpbmdpZnkoeyBzdGFja0xldmVsIH0pO1xyXG5cclxuICAgIC8vIFZpc3VhbCBzdHlsaW5nIGJhc2VkIG9uIHN0YWNrIGxldmVsXHJcbiAgICBpZiAoc3RhY2tMZXZlbCA+IDApIHtcclxuICAgICAgZWxlbWVudC5zdHlsZS5tYXJnaW5MZWZ0ID0gYCR7c3RhY2tMZXZlbCAqIDE1fXB4YDtcclxuICAgICAgZWxlbWVudC5zdHlsZS56SW5kZXggPSBgJHsxMDAgKyBzdGFja0xldmVsfWA7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi9JR3JvdXBpbmdSZW5kZXJlcic7XHJcblxyXG4vKipcclxuICogRW50aXR5IG11c3QgaGF2ZSBpZFxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBJR3JvdXBpbmdFbnRpdHkge1xyXG4gIGlkOiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb25maWd1cmF0aW9uIGZvciBhIGdyb3VwaW5nIHJlbmRlcmVyXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHcm91cGluZ1JlbmRlcmVyQ29uZmlnIHtcclxuICBlbGVtZW50VGFnOiBzdHJpbmc7ICAgICAgLy8gZS5nLiwgJ3N3cC10ZWFtLWhlYWRlcidcclxuICBpZEF0dHJpYnV0ZTogc3RyaW5nOyAgICAgLy8gZS5nLiwgJ3RlYW1JZCcgLT4gZGF0YS10ZWFtLWlkXHJcbiAgY29sc3BhblZhcjogc3RyaW5nOyAgICAgIC8vIGUuZy4sICctLXRlYW0tY29scydcclxufVxyXG5cclxuLyoqXHJcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGdyb3VwaW5nIHJlbmRlcmVyc1xyXG4gKlxyXG4gKiBIYW5kbGVzOlxyXG4gKiAtIEZldGNoaW5nIGVudGl0aWVzIGJ5IElEc1xyXG4gKiAtIENhbGN1bGF0aW5nIGNvbHNwYW4gZnJvbSBwYXJlbnRDaGlsZE1hcFxyXG4gKiAtIENyZWF0aW5nIGhlYWRlciBlbGVtZW50c1xyXG4gKiAtIEFwcGVuZGluZyB0byBjb250YWluZXJcclxuICpcclxuICogU3ViY2xhc3NlcyBvdmVycmlkZTpcclxuICogLSByZW5kZXJIZWFkZXIoKSBmb3IgY3VzdG9tIGNvbnRlbnRcclxuICogLSBnZXREaXNwbGF5TmFtZSgpIGZvciBlbnRpdHkgZGlzcGxheSB0ZXh0XHJcbiAqL1xyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUdyb3VwaW5nUmVuZGVyZXI8VCBleHRlbmRzIElHcm91cGluZ0VudGl0eT4gaW1wbGVtZW50cyBJUmVuZGVyZXIge1xyXG4gIGFic3RyYWN0IHJlYWRvbmx5IHR5cGU6IHN0cmluZztcclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgY29uZmlnOiBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZztcclxuXHJcbiAgLyoqXHJcbiAgICogRmV0Y2ggZW50aXRpZXMgZnJvbSBzZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldEVudGl0aWVzKGlkczogc3RyaW5nW10pOiBQcm9taXNlPFRbXT47XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBkaXNwbGF5IG5hbWUgZm9yIGVudGl0eVxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXREaXNwbGF5TmFtZShlbnRpdHk6IFQpOiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIE1haW4gcmVuZGVyIG1ldGhvZCAtIGhhbmRsZXMgY29tbW9uIGxvZ2ljXHJcbiAgICovXHJcbiAgYXN5bmMgcmVuZGVyKGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBhbGxvd2VkSWRzID0gY29udGV4dC5maWx0ZXJbdGhpcy50eXBlXSB8fCBbXTtcclxuICAgIGlmIChhbGxvd2VkSWRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICAgIGNvbnN0IGVudGl0aWVzID0gYXdhaXQgdGhpcy5nZXRFbnRpdGllcyhhbGxvd2VkSWRzKTtcclxuICAgIGNvbnN0IGRhdGVDb3VudCA9IGNvbnRleHQuZmlsdGVyWydkYXRlJ10/Lmxlbmd0aCB8fCAxO1xyXG4gICAgY29uc3QgY2hpbGRJZHMgPSBjb250ZXh0LmNoaWxkVHlwZSA/IGNvbnRleHQuZmlsdGVyW2NvbnRleHQuY2hpbGRUeXBlXSB8fCBbXSA6IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XHJcbiAgICAgIGNvbnN0IGVudGl0eUNoaWxkSWRzID0gY29udGV4dC5wYXJlbnRDaGlsZE1hcD8uW2VudGl0eS5pZF0gfHwgW107XHJcbiAgICAgIGNvbnN0IGNoaWxkQ291bnQgPSBlbnRpdHlDaGlsZElkcy5maWx0ZXIoaWQgPT4gY2hpbGRJZHMuaW5jbHVkZXMoaWQpKS5sZW5ndGg7XHJcbiAgICAgIGNvbnN0IGNvbHNwYW4gPSBjaGlsZENvdW50ICogZGF0ZUNvdW50O1xyXG5cclxuICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNvbmZpZy5lbGVtZW50VGFnKTtcclxuICAgICAgaGVhZGVyLmRhdGFzZXRbdGhpcy5jb25maWcuaWRBdHRyaWJ1dGVdID0gZW50aXR5LmlkO1xyXG4gICAgICBoZWFkZXIuc3R5bGUuc2V0UHJvcGVydHkodGhpcy5jb25maWcuY29sc3BhblZhciwgU3RyaW5nKGNvbHNwYW4pKTtcclxuXHJcbiAgICAgIC8vIEFsbG93IHN1YmNsYXNzIHRvIGN1c3RvbWl6ZSBoZWFkZXIgY29udGVudFxyXG4gICAgICB0aGlzLnJlbmRlckhlYWRlcihlbnRpdHksIGhlYWRlciwgY29udGV4dCk7XHJcblxyXG4gICAgICBjb250ZXh0LmhlYWRlckNvbnRhaW5lci5hcHBlbmRDaGlsZChoZWFkZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGN1c3RvbSBoZWFkZXIgcmVuZGVyaW5nXHJcbiAgICogRGVmYXVsdDoganVzdCBzZXRzIHRleHRDb250ZW50IHRvIGRpc3BsYXkgbmFtZVxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCByZW5kZXJIZWFkZXIoZW50aXR5OiBULCBoZWFkZXI6IEhUTUxFbGVtZW50LCBfY29udGV4dDogSVJlbmRlckNvbnRleHQpOiB2b2lkIHtcclxuICAgIGhlYWRlci50ZXh0Q29udGVudCA9IHRoaXMuZ2V0RGlzcGxheU5hbWUoZW50aXR5KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciB0byByZW5kZXIgYSBzaW5nbGUgZW50aXR5IGhlYWRlci5cclxuICAgKiBDYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgcmVuZGVyKCkgYnV0IHdhbnQgY29uc2lzdGVudCBoZWFkZXIgY3JlYXRpb24uXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZUhlYWRlcihlbnRpdHk6IFQsIGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogSFRNTEVsZW1lbnQge1xyXG4gICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNvbmZpZy5lbGVtZW50VGFnKTtcclxuICAgIGhlYWRlci5kYXRhc2V0W3RoaXMuY29uZmlnLmlkQXR0cmlidXRlXSA9IGVudGl0eS5pZDtcclxuICAgIHRoaXMucmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBjb250ZXh0KTtcclxuICAgIHJldHVybiBoZWFkZXI7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBJUmVuZGVyQ29udGV4dCB9IGZyb20gJy4uLy4uL2NvcmUvSUdyb3VwaW5nUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBCYXNlR3JvdXBpbmdSZW5kZXJlciwgSUdyb3VwaW5nUmVuZGVyZXJDb25maWcgfSBmcm9tICcuLi8uLi9jb3JlL0Jhc2VHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgUmVzb3VyY2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc3RvcmFnZS9yZXNvdXJjZXMvUmVzb3VyY2VTZXJ2aWNlJztcclxuaW1wb3J0IHsgSVJlc291cmNlIH0gZnJvbSAnLi4vLi4vdHlwZXMvQ2FsZW5kYXJUeXBlcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VSZW5kZXJlciBleHRlbmRzIEJhc2VHcm91cGluZ1JlbmRlcmVyPElSZXNvdXJjZT4ge1xyXG4gIHJlYWRvbmx5IHR5cGUgPSAncmVzb3VyY2UnO1xyXG5cclxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29uZmlnOiBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZyA9IHtcclxuICAgIGVsZW1lbnRUYWc6ICdzd3AtcmVzb3VyY2UtaGVhZGVyJyxcclxuICAgIGlkQXR0cmlidXRlOiAncmVzb3VyY2VJZCcsXHJcbiAgICBjb2xzcGFuVmFyOiAnLS1yZXNvdXJjZS1jb2xzJ1xyXG4gIH07XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVzb3VyY2VTZXJ2aWNlOiBSZXNvdXJjZVNlcnZpY2UpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZ2V0RW50aXRpZXMoaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8SVJlc291cmNlW10+IHtcclxuICAgIHJldHVybiB0aGlzLnJlc291cmNlU2VydmljZS5nZXRCeUlkcyhpZHMpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGdldERpc3BsYXlOYW1lKGVudGl0eTogSVJlc291cmNlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBlbnRpdHkuZGlzcGxheU5hbWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPdmVycmlkZSByZW5kZXIgdG8gaGFuZGxlOlxyXG4gICAqIDEuIFNwZWNpYWwgb3JkZXJpbmcgd2hlbiBwYXJlbnRDaGlsZE1hcCBleGlzdHMgKHJlc291cmNlcyBncm91cGVkIGJ5IHBhcmVudClcclxuICAgKiAyLiBEaWZmZXJlbnQgY29sc3BhbiBjYWxjdWxhdGlvbiAoanVzdCBkYXRlQ291bnQsIG5vdCBjaGlsZENvdW50ICogZGF0ZUNvdW50KVxyXG4gICAqL1xyXG4gIGFzeW5jIHJlbmRlcihjb250ZXh0OiBJUmVuZGVyQ29udGV4dCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY29uc3QgcmVzb3VyY2VJZHMgPSBjb250ZXh0LmZpbHRlclsncmVzb3VyY2UnXSB8fCBbXTtcclxuICAgIGNvbnN0IGRhdGVDb3VudCA9IGNvbnRleHQuZmlsdGVyWydkYXRlJ10/Lmxlbmd0aCB8fCAxO1xyXG5cclxuICAgIC8vIERldGVybWluZSByZW5kZXIgb3JkZXIgYmFzZWQgb24gcGFyZW50Q2hpbGRNYXBcclxuICAgIC8vIElmIHBhcmVudENoaWxkTWFwIGV4aXN0cywgcmVuZGVyIHJlc291cmNlcyBncm91cGVkIGJ5IHBhcmVudCAoZS5nLiwgdGVhbSlcclxuICAgIC8vIE90aGVyd2lzZSwgcmVuZGVyIGluIGZpbHRlciBvcmRlclxyXG4gICAgbGV0IG9yZGVyZWRSZXNvdXJjZUlkczogc3RyaW5nW107XHJcblxyXG4gICAgaWYgKGNvbnRleHQucGFyZW50Q2hpbGRNYXApIHtcclxuICAgICAgLy8gUmVuZGVyIHJlc291cmNlcyBpbiBwYXJlbnQtY2hpbGQgb3JkZXJcclxuICAgICAgb3JkZXJlZFJlc291cmNlSWRzID0gW107XHJcbiAgICAgIGZvciAoY29uc3QgY2hpbGRJZHMgb2YgT2JqZWN0LnZhbHVlcyhjb250ZXh0LnBhcmVudENoaWxkTWFwKSkge1xyXG4gICAgICAgIGZvciAoY29uc3QgY2hpbGRJZCBvZiBjaGlsZElkcykge1xyXG4gICAgICAgICAgaWYgKHJlc291cmNlSWRzLmluY2x1ZGVzKGNoaWxkSWQpKSB7XHJcbiAgICAgICAgICAgIG9yZGVyZWRSZXNvdXJjZUlkcy5wdXNoKGNoaWxkSWQpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgb3JkZXJlZFJlc291cmNlSWRzID0gcmVzb3VyY2VJZHM7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcmVzb3VyY2VzID0gYXdhaXQgdGhpcy5nZXRFbnRpdGllcyhvcmRlcmVkUmVzb3VyY2VJZHMpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBhIG1hcCBmb3IgcXVpY2sgbG9va3VwIHRvIHByZXNlcnZlIG9yZGVyXHJcbiAgICBjb25zdCByZXNvdXJjZU1hcCA9IG5ldyBNYXAocmVzb3VyY2VzLm1hcChyID0+IFtyLmlkLCByXSkpO1xyXG5cclxuICAgIGZvciAoY29uc3QgcmVzb3VyY2VJZCBvZiBvcmRlcmVkUmVzb3VyY2VJZHMpIHtcclxuICAgICAgY29uc3QgcmVzb3VyY2UgPSByZXNvdXJjZU1hcC5nZXQocmVzb3VyY2VJZCk7XHJcbiAgICAgIGlmICghcmVzb3VyY2UpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgY29uc3QgaGVhZGVyID0gdGhpcy5jcmVhdGVIZWFkZXIocmVzb3VyY2UsIGNvbnRleHQpO1xyXG4gICAgICBoZWFkZXIuc3R5bGUuZ3JpZENvbHVtbiA9IGBzcGFuICR7ZGF0ZUNvdW50fWA7XHJcbiAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBCYXNlR3JvdXBpbmdSZW5kZXJlciwgSUdyb3VwaW5nUmVuZGVyZXJDb25maWcgfSBmcm9tICcuLi8uLi9jb3JlL0Jhc2VHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgVGVhbVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9yYWdlL3RlYW1zL1RlYW1TZXJ2aWNlJztcclxuaW1wb3J0IHsgSVRlYW0gfSBmcm9tICcuLi8uLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBUZWFtUmVuZGVyZXIgZXh0ZW5kcyBCYXNlR3JvdXBpbmdSZW5kZXJlcjxJVGVhbT4ge1xyXG4gIHJlYWRvbmx5IHR5cGUgPSAndGVhbSc7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBjb25maWc6IElHcm91cGluZ1JlbmRlcmVyQ29uZmlnID0ge1xyXG4gICAgZWxlbWVudFRhZzogJ3N3cC10ZWFtLWhlYWRlcicsXHJcbiAgICBpZEF0dHJpYnV0ZTogJ3RlYW1JZCcsXHJcbiAgICBjb2xzcGFuVmFyOiAnLS10ZWFtLWNvbHMnXHJcbiAgfTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0ZWFtU2VydmljZTogVGVhbVNlcnZpY2UpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZ2V0RW50aXRpZXMoaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8SVRlYW1bXT4ge1xyXG4gICAgcmV0dXJuIHRoaXMudGVhbVNlcnZpY2UuZ2V0QnlJZHMoaWRzKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXREaXNwbGF5TmFtZShlbnRpdHk6IElUZWFtKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBlbnRpdHkubmFtZTtcclxuICB9XHJcbn1cclxuIiwgImV4cG9ydCBjbGFzcyBUaW1lQXhpc1JlbmRlcmVyIHtcclxuICByZW5kZXIoY29udGFpbmVyOiBIVE1MRWxlbWVudCwgc3RhcnRIb3VyID0gNiwgZW5kSG91ciA9IDIwKTogdm9pZCB7XHJcbiAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XHJcbiAgICBmb3IgKGxldCBob3VyID0gc3RhcnRIb3VyOyBob3VyIDw9IGVuZEhvdXI7IGhvdXIrKykge1xyXG4gICAgICBjb25zdCBtYXJrZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtaG91ci1tYXJrZXInKTtcclxuICAgICAgbWFya2VyLnRleHRDb250ZW50ID0gYCR7aG91ci50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyl9OjAwYDtcclxuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG1hcmtlcik7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUEsS0FBQyxTQUFTLEdBQUUsR0FBRTtBQUFDLGtCQUFVLE9BQU8sV0FBUyxlQUFhLE9BQU8sU0FBTyxPQUFPLFVBQVEsRUFBRSxJQUFFLGNBQVksT0FBTyxVQUFRLE9BQU8sTUFBSSxPQUFPLENBQUMsS0FBRyxJQUFFLGVBQWEsT0FBTyxhQUFXLGFB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RSxHQUFFLEdBQUU7QUFBQyxZQUFJLElBQUUsRUFBRTtBQUFVLFVBQUUsTUFBSSxTQUFTcUIsSUFBRTtBQUFDLGNBQUlDLEtBQUUsRUFBQyxNQUFLRCxJQUFFLEtBQUksTUFBRyxNQUFLLFVBQVM7QUFBRSxpQkFBTyxJQUFJLEVBQUVDLEVBQUM7QUFBQSxRQUFDLEdBQUUsRUFBRSxNQUFJLFNBQVNBLElBQUU7QUFBQyxjQUFJQyxLQUFFLEVBQUUsS0FBSyxPQUFPLEdBQUUsRUFBQyxRQUFPLEtBQUssSUFBRyxLQUFJLEtBQUUsQ0FBQztBQUFFLGlCQUFPRCxLQUFFQyxHQUFFLElBQUksS0FBSyxVQUFVLEdBQUUsQ0FBQyxJQUFFQTtBQUFBLFFBQUMsR0FBRSxFQUFFLFFBQU0sV0FBVTtBQUFDLGlCQUFPLEVBQUUsS0FBSyxPQUFPLEdBQUUsRUFBQyxRQUFPLEtBQUssSUFBRyxLQUFJLE1BQUUsQ0FBQztBQUFBLFFBQUM7QUFBRSxZQUFJLElBQUUsRUFBRTtBQUFNLFVBQUUsUUFBTSxTQUFTRixJQUFFO0FBQUMsVUFBQUEsR0FBRSxRQUFNLEtBQUssS0FBRyxPQUFJLEtBQUssT0FBTyxFQUFFLEVBQUVBLEdBQUUsT0FBTyxNQUFJLEtBQUssVUFBUUEsR0FBRSxVQUFTLEVBQUUsS0FBSyxNQUFLQSxFQUFDO0FBQUEsUUFBQztBQUFFLFlBQUksSUFBRSxFQUFFO0FBQUssVUFBRSxPQUFLLFdBQVU7QUFBQyxjQUFHLEtBQUssSUFBRztBQUFDLGdCQUFJQSxLQUFFLEtBQUs7QUFBRyxpQkFBSyxLQUFHQSxHQUFFLGVBQWUsR0FBRSxLQUFLLEtBQUdBLEdBQUUsWUFBWSxHQUFFLEtBQUssS0FBR0EsR0FBRSxXQUFXLEdBQUUsS0FBSyxLQUFHQSxHQUFFLFVBQVUsR0FBRSxLQUFLLEtBQUdBLEdBQUUsWUFBWSxHQUFFLEtBQUssS0FBR0EsR0FBRSxjQUFjLEdBQUUsS0FBSyxLQUFHQSxHQUFFLGNBQWMsR0FBRSxLQUFLLE1BQUlBLEdBQUUsbUJBQW1CO0FBQUEsVUFBQztBQUFNLGNBQUUsS0FBSyxJQUFJO0FB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QVcsR0FBRSxDQUFDO0FBQUEsUUFBQyxHQUE1QyxNQUE4QyxJQUFFLEVBQUU7QUFBVSxVQUFFLGNBQVksV0FBVTtBQUFDLGlCQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUs7QUFBQSxRQUFDLEdBQUUsRUFBRSxVQUFRLFNBQVNBLElBQUU7QUFBQyxjQUFHLENBQUMsS0FBSyxPQUFPLEVBQUUsRUFBRUEsRUFBQztBQUFFLG1CQUFPLEtBQUssSUFBSSxLQUFHQSxLQUFFLEtBQUssUUFBUSxJQUFHLENBQUM7QUFBRSxjQUFJQyxJQUFFQyxJQUFFQyxJQUFFLEdBQUUsSUFBRSxFQUFFLElBQUksR0FBRSxLQUFHRixLQUFFLEtBQUssWUFBWSxHQUFFQyxLQUFFLEtBQUssSUFBR0MsTUFBR0QsS0FBRSxFQUFFLE1BQUksR0FBRyxFQUFFLEtBQUtELEVBQUMsRUFBRSxRQUFRLE1BQU0sR0FBRSxJQUFFLElBQUVFLEdBQUUsV0FBVyxHQUFFQSxHQUFFLFdBQVcsSUFBRSxNQUFJLEtBQUcsSUFBR0EsR0FBRSxJQUFJLEdBQUUsQ0FBQztBQUFHLGlCQUFPLEVBQUUsS0FBSyxHQUFFLE1BQU0sSUFBRTtBQUFBLFFBQUMsR0FBRSxFQUFFLGFBQVcsU0FBU0MsSUFBRTtBQUFDLGlCQUFPLEtBQUssT0FBTyxFQUFFLEVBQUVBLEVBQUMsSUFBRSxLQUFLLElBQUksS0FBRyxJQUFFLEtBQUssSUFBSSxLQUFLLElBQUksSUFBRSxJQUFFQSxLQUFFQSxLQUFFLENBQUM7QUFBQSxRQUFDO0FBQUUsWUFBSSxJQUFFLEVBQUU7QUFBUSxVQUFFLFVBQVEsU0FBU0EsSUFBRUosSUFBRTtBQUFDLGNBQUlDLEtBQUUsS0FBSyxPQUFPLEdBQUVJLEtBQUUsQ0FBQyxDQUFDSixHQUFFLEVBQUVELEVBQUMsS0FBR0E7QUFBRSxpQkFBTSxjQUFZQyxHQUFFLEVBQUVHLEVBQUMsSUFBRUMsS0FBRSxLQUFLLEtBQUssS0FBSyxLQUFLLEtBQUcsS0FBSyxXQUFXLElBQUUsRUFBRSxFQUFFLFFBQVEsS0FBSyxJQUFFLEtBQUssS0FBSyxLQUFLLEtB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R0FBRyxVQUFVLElBQVU7QUFDaEUsY0FBVSxZQUFZO0FBQ3RCLGFBQVMsT0FBTyxXQUFXLFFBQVEsU0FBUyxRQUFRO0FBQ2xELFlBQU0sU0FBUyxTQUFTLGNBQWMsaUJBQWlCO0FBQ3ZELGFBQU8sY0FBYyxHQUFHLEtBQUssU0FBUyxFQUFFLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFDeEQsZ0JBQVUsWUFBWSxNQUFNO0FBQUEsSUFDOUI7QUFBQSxFQUNGO0FBQ0Y7QUFUOEI7QUFBdkIsSUFBTSxtQkFBTjsiLAogICJuYW1lcyI6IFsidCIsICJlIiwgIm4iLCAiciIsICJpIiwgInMiLCAidSIsICJhIiwgIk0iLCAibSIsICJmIiwgImwiLCAiJCIsICJ5IiwgInYiLCAiZyIsICJEIiwgIm8iLCAiZCIsICJjIiwgImgiLCAidCIsICJpIiwgImUiLCAicyIsICJmIiwgIm4iLCAidSIsICJyIiwgIm8iLCAidCIsICJuIiwgImkiLCAibyIsICJyIiwgImUiLCAidSIsICJmIiwgInMiLCAiYSIsICJ0IiwgImkiLCAiZCIsICJuIiwgImUiLCAicyIsICJkYXlqcyIsICJ1dGMiLCAidGltZXpvbmUiLCAiaXNvV2VlayJdCn0K diff --git a/wwwroot/js/calendar.js b/wwwroot/js/calendar.js new file mode 100644 index 0000000..4ebf767 --- /dev/null +++ b/wwwroot/js/calendar.js @@ -0,0 +1,1664 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = /* @__PURE__ */ __name(function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, "m"), v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: /* @__PURE__ */ __name(function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, "t"), a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = /* @__PURE__ */ __name(function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, "S"), w = /* @__PURE__ */ __name(function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, "t"), O = /* @__PURE__ */ __name(function(t2, e2) { + if (S(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, "O"), b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + __name(M2, "M"); + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) + return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = /* @__PURE__ */ __name(function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, "l"), $2 = /* @__PURE__ */ __name(function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, "$"), y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = /* @__PURE__ */ __name(function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }, "y"); + if ($2 === c) + return this.set(c, this.$M + r2); + if ($2 === h) + return this.set(h, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = /* @__PURE__ */ __name(function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, "h"), d2 = /* @__PURE__ */ __name(function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, "d"), $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, function(t3, r3) { + return r3 || function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + }(t3) || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = /* @__PURE__ */ __name(function() { + return b.m(y2, m3); + }, "D"); + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + }); + } +}); + +// node_modules/dayjs/plugin/utc.js +var require_utc = __commonJS({ + "node_modules/dayjs/plugin/utc.js"(exports, module) { + !function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + }(exports, function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var r = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2); + }; + var o = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else + o.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) + return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) + return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + }(s2), null === s2)) + return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2; + if (0 === u2) + return this.utc(f2); + var r2 = this.clone(); + if (f2) + return r2.$offset = u2, r2.$u = false, r2; + var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) + return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + }(exports, function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = /* @__PURE__ */ __name(function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + }(n2, i2); + return r2.formatToParts(o2); + }, "a"), u = /* @__PURE__ */ __name(function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, "u"), f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) + n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { + return "timezonename" === t3.type.toLowerCase(); + }); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) + return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) + return o(t2).tz(a2); + var s2 = function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) + return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/isoWeek.js +var require_isoWeek = __commonJS({ + "node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + }(exports, function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = /* @__PURE__ */ __name(function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, "a"), d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) + return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + }); + } +}); + +// src/core/RenderBuilder.ts +function buildPipeline(renderers) { + return { + async run(context) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} +__name(buildPipeline, "buildPipeline"); + +// src/core/FilterTemplate.ts +var _FilterTemplate = class _FilterTemplate { + constructor(dateService, entityResolver) { + this.dateService = dateService; + this.entityResolver = entityResolver; + this.fields = []; + } + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty, derivedFrom) { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + parseDotNotation(idProperty) { + if (!idProperty.includes(".")) + return null; + const [entityType, property] = idProperty.split("."); + return { + entityType, + property, + foreignKey: entityType + "Id" + // Convention: resource → resourceId + }; + } + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + getDatasetKey(idProperty) { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; + } + return idProperty; + } + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column) { + return this.fields.map((f) => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ""; + }).join(":"); + } + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event) { + const eventRecord = event; + return this.fields.map((f) => { + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + if (f.derivedFrom) { + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ""); + } + return String(eventRecord[f.idProperty] || ""); + }).join(":"); + } + /** + * Resolve dot-notation reference via EntityResolver + */ + resolveDotNotation(eventRecord, dotNotation) { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ""; + } + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) + return ""; + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) + return ""; + return String(entity[dotNotation.property] || ""); + } + /** + * Match event mod kolonne + */ + matches(event, column) { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +}; +__name(_FilterTemplate, "FilterTemplate"); +var FilterTemplate = _FilterTemplate; + +// src/core/CalendarOrchestrator.ts +var _CalendarOrchestrator = class _CalendarOrchestrator { + constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) { + this.allRenderers = allRenderers; + this.eventRenderer = eventRenderer; + this.scheduleRenderer = scheduleRenderer; + this.headerDrawerRenderer = headerDrawerRenderer; + this.dateService = dateService; + this.entityServices = entityServices; + } + async render(viewConfig, container) { + const headerContainer = container.querySelector("swp-calendar-header"); + const columnContainer = container.querySelector("swp-day-columns"); + if (!headerContainer || !columnContainer) { + throw new Error("Missing swp-calendar-header or swp-day-columns"); + } + const filter = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + headerContainer.innerHTML = ""; + columnContainer.innerHTML = ""; + const levels = viewConfig.groupings.map((g) => g.type).join(" "); + headerContainer.dataset.levels = levels; + const activeRenderers = this.selectRenderers(viewConfig); + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + await this.scheduleRenderer.render(container, filter); + await this.eventRenderer.render(container, filter, filterTemplate); + await this.headerDrawerRenderer.render(container, filter, filterTemplate); + } + selectRenderers(viewConfig) { + const types = viewConfig.groupings.map((g) => g.type); + return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0); + } + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + async resolveBelongsTo(groupings, filter) { + const childGrouping = groupings.find((g) => g.belongsTo); + if (!childGrouping?.belongsTo) + return {}; + const [entityType, property] = childGrouping.belongsTo.split("."); + if (!entityType || !property) + return {}; + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) + return {}; + const service = this.entityServices.find( + (s) => s.entityType.toLowerCase() === entityType + ); + if (!service) + return {}; + const allEntities = await service.getAll(); + const entities = allEntities.filter( + (e) => parentIds.includes(e.id) + ); + const map = {}; + for (const entity of entities) { + const entityRecord = entity; + const children = entityRecord[property] || []; + map[entityRecord.id] = children; + } + return { parentChildMap: map, childType: childGrouping.type }; + } +}; +__name(_CalendarOrchestrator, "CalendarOrchestrator"); +var CalendarOrchestrator = _CalendarOrchestrator; + +// src/core/NavigationAnimator.ts +var _NavigationAnimator = class _NavigationAnimator { + constructor(headerTrack, contentTrack, headerDrawer) { + this.headerTrack = headerTrack; + this.contentTrack = contentTrack; + this.headerDrawer = headerDrawer; + } + async slide(direction, renderFn) { + const out = direction === "left" ? "-100%" : "100%"; + const into = direction === "left" ? "100%" : "-100%"; + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + async animateOut(translate) { + const animations = [ + this.headerTrack.animate( + [{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], + { duration: 200, easing: "ease-in" } + ).finished, + this.contentTrack.animate( + [{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], + { duration: 200, easing: "ease-in" } + ).finished + ]; + if (this.headerDrawer) { + animations.push( + this.headerDrawer.animate( + [{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], + { duration: 200, easing: "ease-in" } + ).finished + ); + } + await Promise.all(animations); + } + async animateIn(translate) { + const animations = [ + this.headerTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], + { duration: 200, easing: "ease-out" } + ).finished, + this.contentTrack.animate( + [{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], + { duration: 200, easing: "ease-out" } + ).finished + ]; + if (this.headerDrawer) { + animations.push( + this.headerDrawer.animate( + [{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], + { duration: 200, easing: "ease-out" } + ).finished + ); + } + await Promise.all(animations); + } +}; +__name(_NavigationAnimator, "NavigationAnimator"); +var NavigationAnimator = _NavigationAnimator; + +// src/features/date/DateRenderer.ts +var _DateRenderer = class _DateRenderer { + constructor(dateService) { + this.dateService = dateService; + this.type = "date"; + } + render(context) { + const dates = context.filter["date"] || []; + const resourceIds = context.filter["resource"] || []; + const dateGrouping = context.groupings?.find((g) => g.type === "date"); + const hideHeader = dateGrouping?.hideHeader === true; + const iterations = resourceIds.length || 1; + let columnCount = 0; + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + const segments = { date: dateStr }; + if (resourceId) + segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + const header = document.createElement("swp-day-header"); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = "true"; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, "short")} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + const column = document.createElement("swp-day-column"); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ""; + context.columnContainer.appendChild(column); + columnCount++; + } + } + const container = context.columnContainer.closest("swp-calendar-container"); + if (container) { + container.style.setProperty("--grid-columns", String(columnCount)); + } + } +}; +__name(_DateRenderer, "DateRenderer"); +var DateRenderer = _DateRenderer; + +// src/core/DateService.ts +var import_dayjs = __toESM(require_dayjs_min(), 1); +var import_utc = __toESM(require_utc(), 1); +var import_timezone = __toESM(require_timezone(), 1); +var import_isoWeek = __toESM(require_isoWeek(), 1); +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_timezone.default); +import_dayjs.default.extend(import_isoWeek.default); +var _DateService = class _DateService { + constructor(config, baseDate) { + this.config = config; + this.timezone = config.timezone; + this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)(); + } + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date) { + this.baseDate = (0, import_dayjs.default)(date); + } + /** + * Get the current base date (either fixed or today) + */ + getBaseDate() { + return this.baseDate.toDate(); + } + parseISO(isoString) { + return (0, import_dayjs.default)(isoString).toDate(); + } + getDayName(date, format = "short") { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + /** + * Get dates starting from a day offset + * @param dayOffset - Day offset from base date + * @param count - Number of consecutive days to return + * @returns Array of date strings in YYYY-MM-DD format + */ + getDatesFromOffset(dayOffset, count) { + const startDate = this.baseDate.add(dayOffset, "day"); + return Array.from( + { length: count }, + (_, i) => startDate.add(i, "day").format("YYYY-MM-DD") + ); + } + /** + * Get specific weekdays from the week containing the offset date + * @param dayOffset - Day offset from base date + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkDaysFromOffset(dayOffset, workDays) { + const targetDate = this.baseDate.add(dayOffset, "day"); + const monday = targetDate.startOf("week").add(1, "day"); + return workDays.map((isoDay) => { + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, "day").format("YYYY-MM-DD"); + }); + } + // Legacy methods for backwards compatibility + getWeekDates(weekOffset = 0, days = 7) { + return this.getDatesFromOffset(weekOffset * 7, days); + } + getWorkWeekDates(weekOffset, workDays) { + return this.getWorkDaysFromOffset(weekOffset * 7, workDays); + } + // ============================================ + // FORMATTING + // ============================================ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? "HH:mm:ss" : "HH:mm"; + return (0, import_dayjs.default)(date).format(pattern); + } + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + formatDate(date) { + return (0, import_dayjs.default)(date).format("YYYY-MM-DD"); + } + getDateKey(date) { + return this.formatDate(date); + } + // ============================================ + // COLUMN KEY + // ============================================ + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments) { + const date = segments.date; + const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v); + return date ? [date, ...others].join(":") : others.join(":"); + } + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey) { + const parts = columnKey.split(":"); + return { + date: parts[0], + resource: parts[1] + }; + } + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey) { + return columnKey.split(":")[0]; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + timeToMinutes(timeString) { + const parts = timeString.split(":").map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm"); + } + getMinutesSinceMidnight(date) { + const d = (0, import_dayjs.default)(date); + return d.hour() * 60 + d.minute(); + } + // ============================================ + // UTC CONVERSIONS + // ============================================ + toUTC(localDate) { + return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString(); + } + fromUTC(utcString) { + return import_dayjs.default.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // DATE CREATION + // ============================================ + createDateAtTime(baseDate, timeString) { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate(); + } + getISOWeekDay(date) { + return (0, import_dayjs.default)(date).isoWeekday(); + } +}; +__name(_DateService, "DateService"); +var DateService = _DateService; + +// src/utils/PositionUtils.ts +function calculateEventPosition(start, end, config) { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + return { top, height }; +} +__name(calculateEventPosition, "calculateEventPosition"); +function minutesToPixels(minutes, config) { + return minutes / 60 * config.hourHeight; +} +__name(minutesToPixels, "minutesToPixels"); +function pixelsToMinutes(pixels, config) { + return pixels / config.hourHeight * 60; +} +__name(pixelsToMinutes, "pixelsToMinutes"); +function snapToGrid(pixels, config) { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} +__name(snapToGrid, "snapToGrid"); + +// src/constants/CoreEvents.ts +var CoreEvents = { + // Lifecycle events + INITIALIZED: "core:initialized", + READY: "core:ready", + DESTROYED: "core:destroyed", + // View events + VIEW_CHANGED: "view:changed", + VIEW_RENDERED: "view:rendered", + // Navigation events + DATE_CHANGED: "nav:date-changed", + NAVIGATION_COMPLETED: "nav:navigation-completed", + // Data events + DATA_LOADING: "data:loading", + DATA_LOADED: "data:loaded", + DATA_ERROR: "data:error", + // Grid events + GRID_RENDERED: "grid:rendered", + GRID_CLICKED: "grid:clicked", + // Event management + EVENT_CREATED: "event:created", + EVENT_UPDATED: "event:updated", + EVENT_DELETED: "event:deleted", + EVENT_SELECTED: "event:selected", + // Event drag-drop + EVENT_DRAG_START: "event:drag-start", + EVENT_DRAG_MOVE: "event:drag-move", + EVENT_DRAG_END: "event:drag-end", + EVENT_DRAG_CANCEL: "event:drag-cancel", + EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change", + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header", + EVENT_DRAG_MOVE_HEADER: "event:drag-move-header", + EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header", + // Event resize + EVENT_RESIZE_START: "event:resize-start", + EVENT_RESIZE_END: "event:resize-end", + // Edge scroll + EDGE_SCROLL_TICK: "edge-scroll:tick", + EDGE_SCROLL_STARTED: "edge-scroll:started", + EDGE_SCROLL_STOPPED: "edge-scroll:stopped", + // System events + ERROR: "system:error", + // Sync events + SYNC_STARTED: "sync:started", + SYNC_COMPLETED: "sync:completed", + SYNC_FAILED: "sync:failed", + // Entity events - for audit and sync + ENTITY_SAVED: "entity:saved", + ENTITY_DELETED: "entity:deleted", + // Audit events + AUDIT_LOGGED: "audit:logged", + // Rendering events + EVENTS_RENDERED: "events:rendered" +}; + +// src/features/event/EventLayoutEngine.ts +function eventsOverlap(a, b) { + return a.start < b.end && a.end > b.start; +} +__name(eventsOverlap, "eventsOverlap"); +function eventsWithinThreshold(a, b, thresholdMinutes) { + const thresholdMs = thresholdMinutes * 60 * 1e3; + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) + return true; + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) + return true; + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) + return true; + return false; +} +__name(eventsWithinThreshold, "eventsWithinThreshold"); +function findOverlapGroups(events) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsOverlap(member, candidate)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findOverlapGroups, "findOverlapGroups"); +function findGridCandidates(events, thresholdMinutes) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some( + (member) => eventsWithinThreshold(member, candidate, thresholdMinutes) + ); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findGridCandidates, "findGridCandidates"); +function calculateStackLevels(events) { + const levels = /* @__PURE__ */ new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + for (const event of sorted) { + let maxOverlappingLevel = -1; + for (const [id, level] of levels) { + const other = events.find((e) => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + levels.set(event.id, maxOverlappingLevel + 1); + } + return levels; +} +__name(calculateStackLevels, "calculateStackLevels"); +function allocateColumns(events) { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns = []; + for (const event of sorted) { + let placed = false; + for (const column of columns) { + const canFit = !column.some((e) => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + if (!placed) { + columns.push([event]); + } + } + return columns; +} +__name(allocateColumns, "allocateColumns"); +function calculateColumnLayout(events, config) { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + const result = { + grids: [], + stacked: [] + }; + if (events.length === 0) + return result; + const overlapGroups = findOverlapGroups(events); + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]); + if (largestGridCandidate.length === overlapGroup.length) { + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + return result; +} +__name(calculateColumnLayout, "calculateColumnLayout"); + +// src/features/event/EventRenderer.ts +var _EventRenderer = class _EventRenderer { + constructor(eventService, dateService, gridConfig, eventBus) { + this.eventService = eventService; + this.dateService = dateService; + this.gridConfig = gridConfig; + this.eventBus = eventBus; + this.container = null; + this.setupListeners(); + } + /** + * Setup listeners for drag-drop and update events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = e.detail; + this.handleColumnChange(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = e.detail; + this.updateDragTimestamp(payload); + }); + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = e.detail; + this.handleEventUpdated(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeaveHeader(payload); + }); + } + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + handleDragEnd(payload) { + if (payload.target === "header") { + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + /** + * Handle header item leaving header - create swp-event in grid + */ + handleDragLeaveHeader(payload) { + if (payload.source !== "header") + return; + if (!payload.targetColumn || !payload.start || !payload.end) + return; + if (payload.element) { + payload.element.classList.add("drag-ghost"); + payload.element.style.opacity = "0.3"; + payload.element.style.pointerEvents = "none"; + } + const event = { + id: payload.eventId, + title: payload.title || "", + description: "", + start: payload.start, + end: payload.end, + type: "customer", + allDay: false, + syncStatus: "pending" + }; + const element = this.createEventElement(event); + let eventsLayer = payload.targetColumn.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + element.classList.add("dragging"); + } + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + async handleEventUpdated(payload) { + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + await this.rerenderColumn(payload.targetColumnKey); + } + /** + * Re-render a single column with fresh data from IndexedDB + */ + async rerenderColumn(columnKey) { + const column = this.findColumn(columnKey); + if (!column) + return; + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date) + return; + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate); + const timedEvents = events.filter( + (event) => !event.allDay && this.dateService.getDateKey(event.start) === date + ); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + } + /** + * Find a column element by columnKey + */ + findColumn(columnKey) { + if (!this.container) + return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`); + } + /** + * Handle event moving to a new column during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.querySelector("swp-events-layer"); + if (!eventsLayer) + return; + eventsLayer.appendChild(payload.element); + payload.element.style.top = `${payload.currentY}px`; + } + /** + * Update timestamp display during drag (snapped to grid) + */ + updateDragTimestamp(payload) { + const timeEl = payload.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart; + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to a Date object (today) + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container, filter, filterTemplate) { + this.container = container; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const dayColumns = container.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + columns.forEach((column) => { + const columnEl = column; + const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl)); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const timedEvents = columnEvents.filter((event) => !event.allDay); + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + }); + } + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + createEventElement(event) { + const element = document.createElement("swp-event"); + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ""} + `; + return element; + } + /** + * Get color class based on metadata.color or event type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Escape HTML to prevent XSS + */ + escapeHtml(text) { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; + } + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + renderGridGroup(layout) { + const group = document.createElement("swp-event-group"); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) + maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + layout.columns.forEach((columnEvents) => { + const wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + columnEvents.forEach((event) => { + const eventEl = this.createEventElement(event); + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = "absolute"; + eventEl.style.left = "0"; + eventEl.style.right = "0"; + wrapper.appendChild(eventEl); + }); + group.appendChild(wrapper); + }); + return group; + } + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + renderStackedEvent(event, stackLevel) { + const element = this.createEventElement(event); + element.dataset.stackLink = JSON.stringify({ stackLevel }); + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + return element; + } +}; +__name(_EventRenderer, "EventRenderer"); +var EventRenderer = _EventRenderer; + +// src/core/BaseGroupingRenderer.ts +var _BaseGroupingRenderer = class _BaseGroupingRenderer { + /** + * Main render method - handles common logic + */ + async render(context) { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) + return; + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter["date"]?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter((id) => childIds.includes(id)).length; + const colspan = childCount * dateCount; + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + this.renderHeader(entity, header, context); + context.headerContainer.appendChild(header); + } + } + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + renderHeader(entity, header, _context) { + header.textContent = this.getDisplayName(entity); + } + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + createHeader(entity, context) { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +}; +__name(_BaseGroupingRenderer, "BaseGroupingRenderer"); +var BaseGroupingRenderer = _BaseGroupingRenderer; + +// src/features/resource/ResourceRenderer.ts +var _ResourceRenderer = class _ResourceRenderer extends BaseGroupingRenderer { + constructor(resourceService) { + super(); + this.resourceService = resourceService; + this.type = "resource"; + this.config = { + elementTag: "swp-resource-header", + idAttribute: "resourceId", + colspanVar: "--resource-cols" + }; + } + getEntities(ids) { + return this.resourceService.getByIds(ids); + } + getDisplayName(entity) { + return entity.displayName; + } + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context) { + const resourceIds = context.filter["resource"] || []; + const dateCount = context.filter["date"]?.length || 1; + let orderedResourceIds; + if (context.parentChildMap) { + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + const resources = await this.getEntities(orderedResourceIds); + const resourceMap = new Map(resources.map((r) => [r.id, r])); + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) + continue; + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +}; +__name(_ResourceRenderer, "ResourceRenderer"); +var ResourceRenderer = _ResourceRenderer; + +// src/features/team/TeamRenderer.ts +var _TeamRenderer = class _TeamRenderer extends BaseGroupingRenderer { + constructor(teamService) { + super(); + this.teamService = teamService; + this.type = "team"; + this.config = { + elementTag: "swp-team-header", + idAttribute: "teamId", + colspanVar: "--team-cols" + }; + } + getEntities(ids) { + return this.teamService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_TeamRenderer, "TeamRenderer"); +var TeamRenderer = _TeamRenderer; + +// src/features/timeaxis/TimeAxisRenderer.ts +var _TimeAxisRenderer = class _TimeAxisRenderer { + render(container, startHour = 6, endHour = 20) { + container.innerHTML = ""; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement("swp-hour-marker"); + marker.textContent = `${hour.toString().padStart(2, "0")}:00`; + container.appendChild(marker); + } + } +}; +__name(_TimeAxisRenderer, "TimeAxisRenderer"); +var TimeAxisRenderer = _TimeAxisRenderer; +export { + CalendarOrchestrator, + DateRenderer, + DateService, + EventRenderer, + NavigationAnimator, + ResourceRenderer, + TeamRenderer, + TimeAxisRenderer, + buildPipeline +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL2RheWpzL2RheWpzLm1pbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3V0Yy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3RpbWV6b25lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9kYXlqcy9wbHVnaW4vaXNvV2Vlay5qcyIsICIuLi8uLi9zcmMvY29yZS9SZW5kZXJCdWlsZGVyLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0ZpbHRlclRlbXBsYXRlLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yLnRzIiwgIi4uLy4uL3NyYy9jb3JlL05hdmlnYXRpb25BbmltYXRvci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2NvcmUvRGF0ZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3V0aWxzL1Bvc2l0aW9uVXRpbHMudHMiLCAiLi4vLi4vc3JjL2NvbnN0YW50cy9Db3JlRXZlbnRzLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9ldmVudC9FdmVudExheW91dEVuZ2luZS50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvZXZlbnQvRXZlbnRSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvY29yZS9CYXNlR3JvdXBpbmdSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvcmVzb3VyY2UvUmVzb3VyY2VSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvdGVhbS9UZWFtUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2ZlYXR1cmVzL3RpbWVheGlzL1RpbWVBeGlzUmVuZGVyZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anM9ZSgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciB0PTFlMyxlPTZlNCxuPTM2ZTUscj1cIm1pbGxpc2Vjb25kXCIsaT1cInNlY29uZFwiLHM9XCJtaW51dGVcIix1PVwiaG91clwiLGE9XCJkYXlcIixvPVwid2Vla1wiLGM9XCJtb250aFwiLGY9XCJxdWFydGVyXCIsaD1cInllYXJcIixkPVwiZGF0ZVwiLGw9XCJJbnZhbGlkIERhdGVcIiwkPS9eKFxcZHs0fSlbLS9dPyhcXGR7MSwyfSk/Wy0vXT8oXFxkezAsMn0pW1R0XFxzXSooXFxkezEsMn0pPzo/KFxcZHsxLDJ9KT86PyhcXGR7MSwyfSk/Wy46XT8oXFxkKyk/JC8seT0vXFxbKFteXFxdXSspXXxZezEsNH18TXsxLDR9fER7MSwyfXxkezEsNH18SHsxLDJ9fGh7MSwyfXxhfEF8bXsxLDJ9fHN7MSwyfXxaezEsMn18U1NTL2csTT17bmFtZTpcImVuXCIsd2Vla2RheXM6XCJTdW5kYXlfTW9uZGF5X1R1ZXNkYXlfV2VkbmVzZGF5X1RodXJzZGF5X0ZyaWRheV9TYXR1cmRheVwiLnNwbGl0KFwiX1wiKSxtb250aHM6XCJKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyXCIuc3BsaXQoXCJfXCIpLG9yZGluYWw6ZnVuY3Rpb24odCl7dmFyIGU9W1widGhcIixcInN0XCIsXCJuZFwiLFwicmRcIl0sbj10JTEwMDtyZXR1cm5cIltcIit0KyhlWyhuLTIwKSUxMF18fGVbbl18fGVbMF0pK1wiXVwifX0sbT1mdW5jdGlvbih0LGUsbil7dmFyIHI9U3RyaW5nKHQpO3JldHVybiFyfHxyLmxlbmd0aD49ZT90OlwiXCIrQXJyYXkoZSsxLXIubGVuZ3RoKS5qb2luKG4pK3R9LHY9e3M6bSx6OmZ1bmN0aW9uKHQpe3ZhciBlPS10LnV0Y09mZnNldCgpLG49TWF0aC5hYnMoZSkscj1NYXRoLmZsb29yKG4vNjApLGk9biU2MDtyZXR1cm4oZTw9MD9cIitcIjpcIi1cIikrbShyLDIsXCIwXCIpK1wiOlwiK20oaSwyLFwiMFwiKX0sbTpmdW5jdGlvbiB0KGUsbil7aWYoZS5kYXRlKCk8bi5kYXRlKCkpcmV0dXJuLXQobixlKTt2YXIgcj0xMioobi55ZWFyKCktZS55ZWFyKCkpKyhuLm1vbnRoKCktZS5tb250aCgpKSxpPWUuY2xvbmUoKS5hZGQocixjKSxzPW4taTwwLHU9ZS5jbG9uZSgpLmFkZChyKyhzPy0xOjEpLGMpO3JldHVybisoLShyKyhuLWkpLyhzP2ktdTp1LWkpKXx8MCl9LGE6ZnVuY3Rpb24odCl7cmV0dXJuIHQ8MD9NYXRoLmNlaWwodCl8fDA6TWF0aC5mbG9vcih0KX0scDpmdW5jdGlvbih0KXtyZXR1cm57TTpjLHk6aCx3Om8sZDphLEQ6ZCxoOnUsbTpzLHM6aSxtczpyLFE6Zn1bdF18fFN0cmluZyh0fHxcIlwiKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL3MkLyxcIlwiKX0sdTpmdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dH19LGc9XCJlblwiLEQ9e307RFtnXT1NO3ZhciBwPVwiJGlzRGF5anNPYmplY3RcIixTPWZ1bmN0aW9uKHQpe3JldHVybiB0IGluc3RhbmNlb2YgX3x8ISghdHx8IXRbcF0pfSx3PWZ1bmN0aW9uIHQoZSxuLHIpe3ZhciBpO2lmKCFlKXJldHVybiBnO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgcz1lLnRvTG93ZXJDYXNlKCk7RFtzXSYmKGk9cyksbiYmKERbc109bixpPXMpO3ZhciB1PWUuc3BsaXQoXCItXCIpO2lmKCFpJiZ1Lmxlbmd0aD4xKXJldHVybiB0KHVbMF0pfWVsc2V7dmFyIGE9ZS5uYW1lO0RbYV09ZSxpPWF9cmV0dXJuIXImJmkmJihnPWkpLGl8fCFyJiZnfSxPPWZ1bmN0aW9uKHQsZSl7aWYoUyh0KSlyZXR1cm4gdC5jbG9uZSgpO3ZhciBuPVwib2JqZWN0XCI9PXR5cGVvZiBlP2U6e307cmV0dXJuIG4uZGF0ZT10LG4uYXJncz1hcmd1bWVudHMsbmV3IF8obil9LGI9djtiLmw9dyxiLmk9UyxiLnc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gTyh0LHtsb2NhbGU6ZS4kTCx1dGM6ZS4kdSx4OmUuJHgsJG9mZnNldDplLiRvZmZzZXR9KX07dmFyIF89ZnVuY3Rpb24oKXtmdW5jdGlvbiBNKHQpe3RoaXMuJEw9dyh0LmxvY2FsZSxudWxsLCEwKSx0aGlzLnBhcnNlKHQpLHRoaXMuJHg9dGhpcy4keHx8dC54fHx7fSx0aGlzW3BdPSEwfXZhciBtPU0ucHJvdG90eXBlO3JldHVybiBtLnBhcnNlPWZ1bmN0aW9uKHQpe3RoaXMuJGQ9ZnVuY3Rpb24odCl7dmFyIGU9dC5kYXRlLG49dC51dGM7aWYobnVsbD09PWUpcmV0dXJuIG5ldyBEYXRlKE5hTik7aWYoYi51KGUpKXJldHVybiBuZXcgRGF0ZTtpZihlIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gbmV3IERhdGUoZSk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUmJiEvWiQvaS50ZXN0KGUpKXt2YXIgcj1lLm1hdGNoKCQpO2lmKHIpe3ZhciBpPXJbMl0tMXx8MCxzPShyWzddfHxcIjBcIikuc3Vic3RyaW5nKDAsMyk7cmV0dXJuIG4/bmV3IERhdGUoRGF0ZS5VVEMoclsxXSxpLHJbM118fDEscls0XXx8MCxyWzVdfHwwLHJbNl18fDAscykpOm5ldyBEYXRlKHJbMV0saSxyWzNdfHwxLHJbNF18fDAscls1XXx8MCxyWzZdfHwwLHMpfX1yZXR1cm4gbmV3IERhdGUoZSl9KHQpLHRoaXMuaW5pdCgpfSxtLmluaXQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRNb250aCgpLHRoaXMuJEQ9dC5nZXREYXRlKCksdGhpcy4kVz10LmdldERheSgpLHRoaXMuJEg9dC5nZXRIb3VycygpLHRoaXMuJG09dC5nZXRNaW51dGVzKCksdGhpcy4kcz10LmdldFNlY29uZHMoKSx0aGlzLiRtcz10LmdldE1pbGxpc2Vjb25kcygpfSxtLiR1dGlscz1mdW5jdGlvbigpe3JldHVybiBifSxtLmlzVmFsaWQ9ZnVuY3Rpb24oKXtyZXR1cm4hKHRoaXMuJGQudG9TdHJpbmcoKT09PWwpfSxtLmlzU2FtZT1mdW5jdGlvbih0LGUpe3ZhciBuPU8odCk7cmV0dXJuIHRoaXMuc3RhcnRPZihlKTw9biYmbjw9dGhpcy5lbmRPZihlKX0sbS5pc0FmdGVyPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIE8odCk8dGhpcy5zdGFydE9mKGUpfSxtLmlzQmVmb3JlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuZW5kT2YoZSk8Tyh0KX0sbS4kZz1mdW5jdGlvbih0LGUsbil7cmV0dXJuIGIudSh0KT90aGlzW2VdOnRoaXMuc2V0KG4sdCl9LG0udW5peD1mdW5jdGlvbigpe3JldHVybiBNYXRoLmZsb29yKHRoaXMudmFsdWVPZigpLzFlMyl9LG0udmFsdWVPZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLmdldFRpbWUoKX0sbS5zdGFydE9mPWZ1bmN0aW9uKHQsZSl7dmFyIG49dGhpcyxyPSEhYi51KGUpfHxlLGY9Yi5wKHQpLGw9ZnVuY3Rpb24odCxlKXt2YXIgaT1iLncobi4kdT9EYXRlLlVUQyhuLiR5LGUsdCk6bmV3IERhdGUobi4keSxlLHQpLG4pO3JldHVybiByP2k6aS5lbmRPZihhKX0sJD1mdW5jdGlvbih0LGUpe3JldHVybiBiLncobi50b0RhdGUoKVt0XS5hcHBseShuLnRvRGF0ZShcInNcIiksKHI/WzAsMCwwLDBdOlsyMyw1OSw1OSw5OTldKS5zbGljZShlKSksbil9LHk9dGhpcy4kVyxNPXRoaXMuJE0sbT10aGlzLiRELHY9XCJzZXRcIisodGhpcy4kdT9cIlVUQ1wiOlwiXCIpO3N3aXRjaChmKXtjYXNlIGg6cmV0dXJuIHI/bCgxLDApOmwoMzEsMTEpO2Nhc2UgYzpyZXR1cm4gcj9sKDEsTSk6bCgwLE0rMSk7Y2FzZSBvOnZhciBnPXRoaXMuJGxvY2FsZSgpLndlZWtTdGFydHx8MCxEPSh5PGc/eSs3OnkpLWc7cmV0dXJuIGwocj9tLUQ6bSsoNi1EKSxNKTtjYXNlIGE6Y2FzZSBkOnJldHVybiAkKHYrXCJIb3Vyc1wiLDApO2Nhc2UgdTpyZXR1cm4gJCh2K1wiTWludXRlc1wiLDEpO2Nhc2UgczpyZXR1cm4gJCh2K1wiU2Vjb25kc1wiLDIpO2Nhc2UgaTpyZXR1cm4gJCh2K1wiTWlsbGlzZWNvbmRzXCIsMyk7ZGVmYXVsdDpyZXR1cm4gdGhpcy5jbG9uZSgpfX0sbS5lbmRPZj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5zdGFydE9mKHQsITEpfSxtLiRzZXQ9ZnVuY3Rpb24odCxlKXt2YXIgbixvPWIucCh0KSxmPVwic2V0XCIrKHRoaXMuJHU/XCJVVENcIjpcIlwiKSxsPShuPXt9LG5bYV09ZitcIkRhdGVcIixuW2RdPWYrXCJEYXRlXCIsbltjXT1mK1wiTW9udGhcIixuW2hdPWYrXCJGdWxsWWVhclwiLG5bdV09ZitcIkhvdXJzXCIsbltzXT1mK1wiTWludXRlc1wiLG5baV09ZitcIlNlY29uZHNcIixuW3JdPWYrXCJNaWxsaXNlY29uZHNcIixuKVtvXSwkPW89PT1hP3RoaXMuJEQrKGUtdGhpcy4kVyk6ZTtpZihvPT09Y3x8bz09PWgpe3ZhciB5PXRoaXMuY2xvbmUoKS5zZXQoZCwxKTt5LiRkW2xdKCQpLHkuaW5pdCgpLHRoaXMuJGQ9eS5zZXQoZCxNYXRoLm1pbih0aGlzLiRELHkuZGF5c0luTW9udGgoKSkpLiRkfWVsc2UgbCYmdGhpcy4kZFtsXSgkKTtyZXR1cm4gdGhpcy5pbml0KCksdGhpc30sbS5zZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5jbG9uZSgpLiRzZXQodCxlKX0sbS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXNbYi5wKHQpXSgpfSxtLmFkZD1mdW5jdGlvbihyLGYpe3ZhciBkLGw9dGhpcztyPU51bWJlcihyKTt2YXIgJD1iLnAoZikseT1mdW5jdGlvbih0KXt2YXIgZT1PKGwpO3JldHVybiBiLncoZS5kYXRlKGUuZGF0ZSgpK01hdGgucm91bmQodCpyKSksbCl9O2lmKCQ9PT1jKXJldHVybiB0aGlzLnNldChjLHRoaXMuJE0rcik7aWYoJD09PWgpcmV0dXJuIHRoaXMuc2V0KGgsdGhpcy4keStyKTtpZigkPT09YSlyZXR1cm4geSgxKTtpZigkPT09bylyZXR1cm4geSg3KTt2YXIgTT0oZD17fSxkW3NdPWUsZFt1XT1uLGRbaV09dCxkKVskXXx8MSxtPXRoaXMuJGQuZ2V0VGltZSgpK3IqTTtyZXR1cm4gYi53KG0sdGhpcyl9LG0uc3VidHJhY3Q9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5hZGQoLTEqdCxlKX0sbS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxuPXRoaXMuJGxvY2FsZSgpO2lmKCF0aGlzLmlzVmFsaWQoKSlyZXR1cm4gbi5pbnZhbGlkRGF0ZXx8bDt2YXIgcj10fHxcIllZWVktTU0tRERUSEg6bW06c3NaXCIsaT1iLnoodGhpcykscz10aGlzLiRILHU9dGhpcy4kbSxhPXRoaXMuJE0sbz1uLndlZWtkYXlzLGM9bi5tb250aHMsZj1uLm1lcmlkaWVtLGg9ZnVuY3Rpb24odCxuLGkscyl7cmV0dXJuIHQmJih0W25dfHx0KGUscikpfHxpW25dLnNsaWNlKDAscyl9LGQ9ZnVuY3Rpb24odCl7cmV0dXJuIGIucyhzJTEyfHwxMix0LFwiMFwiKX0sJD1mfHxmdW5jdGlvbih0LGUsbil7dmFyIHI9dDwxMj9cIkFNXCI6XCJQTVwiO3JldHVybiBuP3IudG9Mb3dlckNhc2UoKTpyfTtyZXR1cm4gci5yZXBsYWNlKHksKGZ1bmN0aW9uKHQscil7cmV0dXJuIHJ8fGZ1bmN0aW9uKHQpe3N3aXRjaCh0KXtjYXNlXCJZWVwiOnJldHVybiBTdHJpbmcoZS4keSkuc2xpY2UoLTIpO2Nhc2VcIllZWVlcIjpyZXR1cm4gYi5zKGUuJHksNCxcIjBcIik7Y2FzZVwiTVwiOnJldHVybiBhKzE7Y2FzZVwiTU1cIjpyZXR1cm4gYi5zKGErMSwyLFwiMFwiKTtjYXNlXCJNTU1cIjpyZXR1cm4gaChuLm1vbnRoc1Nob3J0LGEsYywzKTtjYXNlXCJNTU1NXCI6cmV0dXJuIGgoYyxhKTtjYXNlXCJEXCI6cmV0dXJuIGUuJEQ7Y2FzZVwiRERcIjpyZXR1cm4gYi5zKGUuJEQsMixcIjBcIik7Y2FzZVwiZFwiOnJldHVybiBTdHJpbmcoZS4kVyk7Y2FzZVwiZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzTWluLGUuJFcsbywyKTtjYXNlXCJkZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzU2hvcnQsZS4kVyxvLDMpO2Nhc2VcImRkZGRcIjpyZXR1cm4gb1tlLiRXXTtjYXNlXCJIXCI6cmV0dXJuIFN0cmluZyhzKTtjYXNlXCJISFwiOnJldHVybiBiLnMocywyLFwiMFwiKTtjYXNlXCJoXCI6cmV0dXJuIGQoMSk7Y2FzZVwiaGhcIjpyZXR1cm4gZCgyKTtjYXNlXCJhXCI6cmV0dXJuICQocyx1LCEwKTtjYXNlXCJBXCI6cmV0dXJuICQocyx1LCExKTtjYXNlXCJtXCI6cmV0dXJuIFN0cmluZyh1KTtjYXNlXCJtbVwiOnJldHVybiBiLnModSwyLFwiMFwiKTtjYXNlXCJzXCI6cmV0dXJuIFN0cmluZyhlLiRzKTtjYXNlXCJzc1wiOnJldHVybiBiLnMoZS4kcywyLFwiMFwiKTtjYXNlXCJTU1NcIjpyZXR1cm4gYi5zKGUuJG1zLDMsXCIwXCIpO2Nhc2VcIlpcIjpyZXR1cm4gaX1yZXR1cm4gbnVsbH0odCl8fGkucmVwbGFjZShcIjpcIixcIlwiKX0pKX0sbS51dGNPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4gMTUqLU1hdGgucm91bmQodGhpcy4kZC5nZXRUaW1lem9uZU9mZnNldCgpLzE1KX0sbS5kaWZmPWZ1bmN0aW9uKHIsZCxsKXt2YXIgJCx5PXRoaXMsTT1iLnAoZCksbT1PKHIpLHY9KG0udXRjT2Zmc2V0KCktdGhpcy51dGNPZmZzZXQoKSkqZSxnPXRoaXMtbSxEPWZ1bmN0aW9uKCl7cmV0dXJuIGIubSh5LG0pfTtzd2l0Y2goTSl7Y2FzZSBoOiQ9RCgpLzEyO2JyZWFrO2Nhc2UgYzokPUQoKTticmVhaztjYXNlIGY6JD1EKCkvMzticmVhaztjYXNlIG86JD0oZy12KS82MDQ4ZTU7YnJlYWs7Y2FzZSBhOiQ9KGctdikvODY0ZTU7YnJlYWs7Y2FzZSB1OiQ9Zy9uO2JyZWFrO2Nhc2UgczokPWcvZTticmVhaztjYXNlIGk6JD1nL3Q7YnJlYWs7ZGVmYXVsdDokPWd9cmV0dXJuIGw/JDpiLmEoJCl9LG0uZGF5c0luTW9udGg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbmRPZihjKS4kRH0sbS4kbG9jYWxlPWZ1bmN0aW9uKCl7cmV0dXJuIERbdGhpcy4kTF19LG0ubG9jYWxlPWZ1bmN0aW9uKHQsZSl7aWYoIXQpcmV0dXJuIHRoaXMuJEw7dmFyIG49dGhpcy5jbG9uZSgpLHI9dyh0LGUsITApO3JldHVybiByJiYobi4kTD1yKSxufSxtLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIGIudyh0aGlzLiRkLHRoaXMpfSxtLnRvRGF0ZT1mdW5jdGlvbigpe3JldHVybiBuZXcgRGF0ZSh0aGlzLnZhbHVlT2YoKSl9LG0udG9KU09OPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaXNWYWxpZCgpP3RoaXMudG9JU09TdHJpbmcoKTpudWxsfSxtLnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGQudG9JU09TdHJpbmcoKX0sbS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLnRvVVRDU3RyaW5nKCl9LE19KCksaz1fLnByb3RvdHlwZTtyZXR1cm4gTy5wcm90b3R5cGU9ayxbW1wiJG1zXCIscl0sW1wiJHNcIixpXSxbXCIkbVwiLHNdLFtcIiRIXCIsdV0sW1wiJFdcIixhXSxbXCIkTVwiLGNdLFtcIiR5XCIsaF0sW1wiJERcIixkXV0uZm9yRWFjaCgoZnVuY3Rpb24odCl7a1t0WzFdXT1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy4kZyhlLHRbMF0sdFsxXSl9fSkpLE8uZXh0ZW5kPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuJGl8fCh0KGUsXyxPKSx0LiRpPSEwKSxPfSxPLmxvY2FsZT13LE8uaXNEYXlqcz1TLE8udW5peD1mdW5jdGlvbih0KXtyZXR1cm4gTygxZTMqdCl9LE8uZW49RFtnXSxPLkxzPUQsTy5wPXt9LE99KSk7IiwgIiFmdW5jdGlvbih0LGkpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWkoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGkpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3V0Yz1pKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHQ9XCJtaW51dGVcIixpPS9bKy1dXFxkXFxkKD86Oj9cXGRcXGQpPy9nLGU9LyhbKy1dfFxcZFxcZCkvZztyZXR1cm4gZnVuY3Rpb24ocyxmLG4pe3ZhciB1PWYucHJvdG90eXBlO24udXRjPWZ1bmN0aW9uKHQpe3ZhciBpPXtkYXRlOnQsdXRjOiEwLGFyZ3M6YXJndW1lbnRzfTtyZXR1cm4gbmV3IGYoaSl9LHUudXRjPWZ1bmN0aW9uKGkpe3ZhciBlPW4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiEwfSk7cmV0dXJuIGk/ZS5hZGQodGhpcy51dGNPZmZzZXQoKSx0KTplfSx1LmxvY2FsPWZ1bmN0aW9uKCl7cmV0dXJuIG4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiExfSl9O3ZhciByPXUucGFyc2U7dS5wYXJzZT1mdW5jdGlvbih0KXt0LnV0YyYmKHRoaXMuJHU9ITApLHRoaXMuJHV0aWxzKCkudSh0LiRvZmZzZXQpfHwodGhpcy4kb2Zmc2V0PXQuJG9mZnNldCksci5jYWxsKHRoaXMsdCl9O3ZhciBvPXUuaW5pdDt1LmluaXQ9ZnVuY3Rpb24oKXtpZih0aGlzLiR1KXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRVVENGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRVVENNb250aCgpLHRoaXMuJEQ9dC5nZXRVVENEYXRlKCksdGhpcy4kVz10LmdldFVUQ0RheSgpLHRoaXMuJEg9dC5nZXRVVENIb3VycygpLHRoaXMuJG09dC5nZXRVVENNaW51dGVzKCksdGhpcy4kcz10LmdldFVUQ1NlY29uZHMoKSx0aGlzLiRtcz10LmdldFVUQ01pbGxpc2Vjb25kcygpfWVsc2Ugby5jYWxsKHRoaXMpfTt2YXIgYT11LnV0Y09mZnNldDt1LnV0Y09mZnNldD1mdW5jdGlvbihzLGYpe3ZhciBuPXRoaXMuJHV0aWxzKCkudTtpZihuKHMpKXJldHVybiB0aGlzLiR1PzA6bih0aGlzLiRvZmZzZXQpP2EuY2FsbCh0aGlzKTp0aGlzLiRvZmZzZXQ7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHMmJihzPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PVwiXCIpO3ZhciBzPXQubWF0Y2goaSk7aWYoIXMpcmV0dXJuIG51bGw7dmFyIGY9KFwiXCIrc1swXSkubWF0Y2goZSl8fFtcIi1cIiwwLDBdLG49ZlswXSx1PTYwKitmWzFdKyArZlsyXTtyZXR1cm4gMD09PXU/MDpcIitcIj09PW4/dTotdX0ocyksbnVsbD09PXMpKXJldHVybiB0aGlzO3ZhciB1PU1hdGguYWJzKHMpPD0xNj82MCpzOnM7aWYoMD09PXUpcmV0dXJuIHRoaXMudXRjKGYpO3ZhciByPXRoaXMuY2xvbmUoKTtpZihmKXJldHVybiByLiRvZmZzZXQ9dSxyLiR1PSExLHI7dmFyIG89dGhpcy4kdT90aGlzLnRvRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCk6LTEqdGhpcy51dGNPZmZzZXQoKTtyZXR1cm4ocj10aGlzLmxvY2FsKCkuYWRkKHUrbyx0KSkuJG9mZnNldD11LHIuJHguJGxvY2FsT2Zmc2V0PW8scn07dmFyIGg9dS5mb3JtYXQ7dS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGk9dHx8KHRoaXMuJHU/XCJZWVlZLU1NLUREVEhIOm1tOnNzW1pdXCI6XCJcIik7cmV0dXJuIGguY2FsbCh0aGlzLGkpfSx1LnZhbHVlT2Y9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiR1dGlscygpLnUodGhpcy4kb2Zmc2V0KT8wOnRoaXMuJG9mZnNldCsodGhpcy4keC4kbG9jYWxPZmZzZXR8fHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7cmV0dXJuIHRoaXMuJGQudmFsdWVPZigpLTZlNCp0fSx1LmlzVVRDPWZ1bmN0aW9uKCl7cmV0dXJuISF0aGlzLiR1fSx1LnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudG9EYXRlKCkudG9JU09TdHJpbmcoKX0sdS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRvRGF0ZSgpLnRvVVRDU3RyaW5nKCl9O3ZhciBsPXUudG9EYXRlO3UudG9EYXRlPWZ1bmN0aW9uKHQpe3JldHVyblwic1wiPT09dCYmdGhpcy4kb2Zmc2V0P24odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSkudG9EYXRlKCk6bC5jYWxsKHRoaXMpfTt2YXIgYz11LmRpZmY7dS5kaWZmPWZ1bmN0aW9uKHQsaSxlKXtpZih0JiZ0aGlzLiR1PT09dC4kdSlyZXR1cm4gYy5jYWxsKHRoaXMsdCxpLGUpO3ZhciBzPXRoaXMubG9jYWwoKSxmPW4odCkubG9jYWwoKTtyZXR1cm4gYy5jYWxsKHMsZixpLGUpfX19KSk7IiwgIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3RpbWV6b25lPWUoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgdD17eWVhcjowLG1vbnRoOjEsZGF5OjIsaG91cjozLG1pbnV0ZTo0LHNlY29uZDo1fSxlPXt9O3JldHVybiBmdW5jdGlvbihuLGksbyl7dmFyIHIsYT1mdW5jdGlvbih0LG4saSl7dm9pZCAwPT09aSYmKGk9e30pO3ZhciBvPW5ldyBEYXRlKHQpLHI9ZnVuY3Rpb24odCxuKXt2b2lkIDA9PT1uJiYobj17fSk7dmFyIGk9bi50aW1lWm9uZU5hbWV8fFwic2hvcnRcIixvPXQrXCJ8XCIraSxyPWVbb107cmV0dXJuIHJ8fChyPW5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KFwiZW4tVVNcIix7aG91cjEyOiExLHRpbWVab25lOnQseWVhcjpcIm51bWVyaWNcIixtb250aDpcIjItZGlnaXRcIixkYXk6XCIyLWRpZ2l0XCIsaG91cjpcIjItZGlnaXRcIixtaW51dGU6XCIyLWRpZ2l0XCIsc2Vjb25kOlwiMi1kaWdpdFwiLHRpbWVab25lTmFtZTppfSksZVtvXT1yKSxyfShuLGkpO3JldHVybiByLmZvcm1hdFRvUGFydHMobyl9LHU9ZnVuY3Rpb24oZSxuKXtmb3IodmFyIGk9YShlLG4pLHI9W10sdT0wO3U8aS5sZW5ndGg7dSs9MSl7dmFyIGY9aVt1XSxzPWYudHlwZSxtPWYudmFsdWUsYz10W3NdO2M+PTAmJihyW2NdPXBhcnNlSW50KG0sMTApKX12YXIgZD1yWzNdLGw9MjQ9PT1kPzA6ZCxoPXJbMF0rXCItXCIrclsxXStcIi1cIityWzJdK1wiIFwiK2wrXCI6XCIrcls0XStcIjpcIityWzVdK1wiOjAwMFwiLHY9K2U7cmV0dXJuKG8udXRjKGgpLnZhbHVlT2YoKS0odi09diUxZTMpKS82ZTR9LGY9aS5wcm90b3R5cGU7Zi50ej1mdW5jdGlvbih0LGUpe3ZvaWQgMD09PXQmJih0PXIpO3ZhciBuLGk9dGhpcy51dGNPZmZzZXQoKSxhPXRoaXMudG9EYXRlKCksdT1hLnRvTG9jYWxlU3RyaW5nKFwiZW4tVVNcIix7dGltZVpvbmU6dH0pLGY9TWF0aC5yb3VuZCgoYS1uZXcgRGF0ZSh1KSkvMWUzLzYwKSxzPTE1Ki1NYXRoLnJvdW5kKGEuZ2V0VGltZXpvbmVPZmZzZXQoKS8xNSktZjtpZighTnVtYmVyKHMpKW49dGhpcy51dGNPZmZzZXQoMCxlKTtlbHNlIGlmKG49byh1LHtsb2NhbGU6dGhpcy4kTH0pLiRzZXQoXCJtaWxsaXNlY29uZFwiLHRoaXMuJG1zKS51dGNPZmZzZXQocywhMCksZSl7dmFyIG09bi51dGNPZmZzZXQoKTtuPW4uYWRkKGktbSxcIm1pbnV0ZVwiKX1yZXR1cm4gbi4keC4kdGltZXpvbmU9dCxufSxmLm9mZnNldE5hbWU9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy4keC4kdGltZXpvbmV8fG8udHouZ3Vlc3MoKSxuPWEodGhpcy52YWx1ZU9mKCksZSx7dGltZVpvbmVOYW1lOnR9KS5maW5kKChmdW5jdGlvbih0KXtyZXR1cm5cInRpbWV6b25lbmFtZVwiPT09dC50eXBlLnRvTG93ZXJDYXNlKCl9KSk7cmV0dXJuIG4mJm4udmFsdWV9O3ZhciBzPWYuc3RhcnRPZjtmLnN0YXJ0T2Y9ZnVuY3Rpb24odCxlKXtpZighdGhpcy4keHx8IXRoaXMuJHguJHRpbWV6b25lKXJldHVybiBzLmNhbGwodGhpcyx0LGUpO3ZhciBuPW8odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSx7bG9jYWxlOnRoaXMuJEx9KTtyZXR1cm4gcy5jYWxsKG4sdCxlKS50eih0aGlzLiR4LiR0aW1lem9uZSwhMCl9LG8udHo9ZnVuY3Rpb24odCxlLG4pe3ZhciBpPW4mJmUsYT1ufHxlfHxyLGY9dSgrbygpLGEpO2lmKFwic3RyaW5nXCIhPXR5cGVvZiB0KXJldHVybiBvKHQpLnR6KGEpO3ZhciBzPWZ1bmN0aW9uKHQsZSxuKXt2YXIgaT10LTYwKmUqMWUzLG89dShpLG4pO2lmKGU9PT1vKXJldHVybltpLGVdO3ZhciByPXUoaS09NjAqKG8tZSkqMWUzLG4pO3JldHVybiBvPT09cj9baSxvXTpbdC02MCpNYXRoLm1pbihvLHIpKjFlMyxNYXRoLm1heChvLHIpXX0oby51dGModCxpKS52YWx1ZU9mKCksZixhKSxtPXNbMF0sYz1zWzFdLGQ9byhtKS51dGNPZmZzZXQoYyk7cmV0dXJuIGQuJHguJHRpbWV6b25lPWEsZH0sby50ei5ndWVzcz1mdW5jdGlvbigpe3JldHVybiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmV9LG8udHouc2V0RGVmYXVsdD1mdW5jdGlvbih0KXtyPXR9fX0pKTsiLCAiIWZ1bmN0aW9uKGUsdCl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9dCgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUodCk6KGU9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczplfHxzZWxmKS5kYXlqc19wbHVnaW5faXNvV2Vlaz10KCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGU9XCJkYXlcIjtyZXR1cm4gZnVuY3Rpb24odCxpLHMpe3ZhciBhPWZ1bmN0aW9uKHQpe3JldHVybiB0LmFkZCg0LXQuaXNvV2Vla2RheSgpLGUpfSxkPWkucHJvdG90eXBlO2QuaXNvV2Vla1llYXI9ZnVuY3Rpb24oKXtyZXR1cm4gYSh0aGlzKS55ZWFyKCl9LGQuaXNvV2Vlaz1mdW5jdGlvbih0KXtpZighdGhpcy4kdXRpbHMoKS51KHQpKXJldHVybiB0aGlzLmFkZCg3Kih0LXRoaXMuaXNvV2VlaygpKSxlKTt2YXIgaSxkLG4sbyxyPWEodGhpcyksdT0oaT10aGlzLmlzb1dlZWtZZWFyKCksZD10aGlzLiR1LG49KGQ/cy51dGM6cykoKS55ZWFyKGkpLnN0YXJ0T2YoXCJ5ZWFyXCIpLG89NC1uLmlzb1dlZWtkYXkoKSxuLmlzb1dlZWtkYXkoKT40JiYobys9Nyksbi5hZGQobyxlKSk7cmV0dXJuIHIuZGlmZih1LFwid2Vla1wiKSsxfSxkLmlzb1dlZWtkYXk9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuJHV0aWxzKCkudShlKT90aGlzLmRheSgpfHw3OnRoaXMuZGF5KHRoaXMuZGF5KCklNz9lOmUtNyl9O3ZhciBuPWQuc3RhcnRPZjtkLnN0YXJ0T2Y9ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLiR1dGlscygpLHM9ISFpLnUodCl8fHQ7cmV0dXJuXCJpc293ZWVrXCI9PT1pLnAoZSk/cz90aGlzLmRhdGUodGhpcy5kYXRlKCktKHRoaXMuaXNvV2Vla2RheSgpLTEpKS5zdGFydE9mKFwiZGF5XCIpOnRoaXMuZGF0ZSh0aGlzLmRhdGUoKS0xLSh0aGlzLmlzb1dlZWtkYXkoKS0xKSs3KS5lbmRPZihcImRheVwiKTpuLmJpbmQodGhpcykoZSx0KX19fSkpOyIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi9JR3JvdXBpbmdSZW5kZXJlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmUge1xuICBydW4oY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQaXBlbGluZShyZW5kZXJlcnM6IElSZW5kZXJlcltdKTogUGlwZWxpbmUge1xuICByZXR1cm4ge1xuICAgIGFzeW5jIHJ1bihjb250ZXh0OiBJUmVuZGVyQ29udGV4dCkge1xuICAgICAgZm9yIChjb25zdCByZW5kZXJlciBvZiByZW5kZXJlcnMpIHtcbiAgICAgICAgYXdhaXQgcmVuZGVyZXIucmVuZGVyKGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCB9IGZyb20gJy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBEYXRlU2VydmljZSB9IGZyb20gJy4vRGF0ZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJRW50aXR5UmVzb2x2ZXIgfSBmcm9tICcuL0lFbnRpdHlSZXNvbHZlcic7XHJcblxyXG4vKipcclxuICogRmllbGQgZGVmaW5pdGlvbiBmb3IgRmlsdGVyVGVtcGxhdGVcclxuICovXHJcbmludGVyZmFjZSBJRmlsdGVyRmllbGQge1xyXG4gIGlkUHJvcGVydHk6IHN0cmluZztcclxuICBkZXJpdmVkRnJvbT86IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIFBhcnNlZCBkb3Qtbm90YXRpb24gcmVmZXJlbmNlXHJcbiAqL1xyXG5pbnRlcmZhY2UgSURvdE5vdGF0aW9uIHtcclxuICBlbnRpdHlUeXBlOiBzdHJpbmc7ICAgLy8gZS5nLiwgJ3Jlc291cmNlJ1xyXG4gIHByb3BlcnR5OiBzdHJpbmc7ICAgICAvLyBlLmcuLCAndGVhbUlkJ1xyXG4gIGZvcmVpZ25LZXk6IHN0cmluZzsgICAvLyBlLmcuLCAncmVzb3VyY2VJZCdcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbHRlclRlbXBsYXRlIC0gQnlnZ2VyIG5cdTAwRjhnbGVyIHRpbCBldmVudC1rb2xvbm5lIG1hdGNoaW5nXHJcbiAqXHJcbiAqIFZpZXdDb25maWcgZGVmaW5lcmVyIGh2aWxrZSBmZWx0ZXIgKGlkUHJvcGVydGllcykgZGVyIGluZGdcdTAwRTVyIGkga29sb25uZW5zIG5cdTAwRjhnbGUuXHJcbiAqIFNhbW1lIHRlbXBsYXRlIGJydWdlcyB0aWwgYXQgYnlnZ2Ugblx1MDBGOGdsZSBmb3IgYlx1MDBFNWRlIGtvbG9ubmUgb2cgZXZlbnQuXHJcbiAqXHJcbiAqIFN1cHBvcnRzIGRvdC1ub3RhdGlvbiBmb3IgaGllcmFyY2hpY2FsIHJlbGF0aW9uczpcclxuICogLSAncmVzb3VyY2UudGVhbUlkJyBcdTIxOTIgbG9va3MgdXAgZXZlbnQucmVzb3VyY2VJZCBcdTIxOTIgcmVzb3VyY2UgZW50aXR5IFx1MjE5MiB0ZWFtSWRcclxuICpcclxuICogUHJpbmNpcDogS29sb25uZW5zIG5cdTAwRjhnbGUtdGVtcGxhdGUgYmVzdGVtbWVyIGh2YWQgZGVyIG1hdGNoZXMgcFx1MDBFNS5cclxuICpcclxuICogQHNlZSBkb2NzL2ZpbHRlci10ZW1wbGF0ZS5tZFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEZpbHRlclRlbXBsYXRlIHtcclxuICBwcml2YXRlIGZpZWxkczogSUZpbHRlckZpZWxkW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGRhdGVTZXJ2aWNlOiBEYXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgZW50aXR5UmVzb2x2ZXI/OiBJRW50aXR5UmVzb2x2ZXJcclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRpbGZcdTAwRjhqIGZlbHQgdGlsIHRlbXBsYXRlXHJcbiAgICogQHBhcmFtIGlkUHJvcGVydHkgLSBQcm9wZXJ0eS1uYXZuIChicnVnZXMgcFx1MDBFNSBiXHUwMEU1ZGUgZXZlbnQgb2cgY29sdW1uLmRhdGFzZXQpXHJcbiAgICogQHBhcmFtIGRlcml2ZWRGcm9tIC0gSHZpcyBmZWx0ZXQgdWRsZWRlcyBmcmEgYW5kZW4gcHJvcGVydHkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgKi9cclxuICBhZGRGaWVsZChpZFByb3BlcnR5OiBzdHJpbmcsIGRlcml2ZWRGcm9tPzogc3RyaW5nKTogdGhpcyB7XHJcbiAgICB0aGlzLmZpZWxkcy5wdXNoKHsgaWRQcm9wZXJ0eSwgZGVyaXZlZEZyb20gfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGRvdC1ub3RhdGlvbiBzdHJpbmcgaW50byBjb21wb25lbnRzXHJcbiAgICogQGV4YW1wbGUgJ3Jlc291cmNlLnRlYW1JZCcgXHUyMTkyIHsgZW50aXR5VHlwZTogJ3Jlc291cmNlJywgcHJvcGVydHk6ICd0ZWFtSWQnLCBmb3JlaWduS2V5OiAncmVzb3VyY2VJZCcgfVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5OiBzdHJpbmcpOiBJRG90Tm90YXRpb24gfCBudWxsIHtcclxuICAgIGlmICghaWRQcm9wZXJ0eS5pbmNsdWRlcygnLicpKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IFtlbnRpdHlUeXBlLCBwcm9wZXJ0eV0gPSBpZFByb3BlcnR5LnNwbGl0KCcuJyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBlbnRpdHlUeXBlLFxyXG4gICAgICBwcm9wZXJ0eSxcclxuICAgICAgZm9yZWlnbktleTogZW50aXR5VHlwZSArICdJZCcgLy8gQ29udmVudGlvbjogcmVzb3VyY2UgXHUyMTkyIHJlc291cmNlSWRcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgZGF0YXNldCBrZXkgZm9yIGNvbHVtbiBsb29rdXBcclxuICAgKiBGb3IgZG90LW5vdGF0aW9uICdyZXNvdXJjZS50ZWFtSWQnLCB3ZSBsb29rIGZvciAndGVhbUlkJyBpbiBkYXRhc2V0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXREYXRhc2V0S2V5KGlkUHJvcGVydHk6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkb3ROb3RhdGlvbiA9IHRoaXMucGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5KTtcclxuICAgIGlmIChkb3ROb3RhdGlvbikge1xyXG4gICAgICByZXR1cm4gZG90Tm90YXRpb24ucHJvcGVydHk7IC8vICd0ZWFtSWQnXHJcbiAgICB9XHJcbiAgICByZXR1cm4gaWRQcm9wZXJ0eTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ5ZyBuXHUwMEY4Z2xlIGZyYSBrb2xvbm5lXHJcbiAgICogTFx1MDBFNnNlciB2XHUwMEU2cmRpZXIgZnJhIGNvbHVtbi5kYXRhc2V0W2lkUHJvcGVydHldXHJcbiAgICogRm9yIGRvdC1ub3RhdGlvbiwgdXNlcyB0aGUgcHJvcGVydHkgcGFydCAocmVzb3VyY2UudGVhbUlkIFx1MjE5MiB0ZWFtSWQpXHJcbiAgICovXHJcbiAgYnVpbGRLZXlGcm9tQ29sdW1uKGNvbHVtbjogSFRNTEVsZW1lbnQpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXREYXRhc2V0S2V5KGYuaWRQcm9wZXJ0eSk7XHJcbiAgICAgICAgcmV0dXJuIGNvbHVtbi5kYXRhc2V0W2tleV0gfHwgJyc7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBCeWcgblx1MDBGOGdsZSBmcmEgZXZlbnRcclxuICAgKiBMXHUwMEU2c2VyIHZcdTAwRTZyZGllciBmcmEgZXZlbnRbaWRQcm9wZXJ0eV0gZWxsZXIgdWRsZWRlciBmcmEgZGVyaXZlZEZyb21cclxuICAgKiBGb3IgZG90LW5vdGF0aW9uLCByZXNvbHZlcyB2aWEgRW50aXR5UmVzb2x2ZXJcclxuICAgKi9cclxuICBidWlsZEtleUZyb21FdmVudChldmVudDogSUNhbGVuZGFyRXZlbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgIGNvbnN0IGV2ZW50UmVjb3JkID0gZXZlbnQgYXMgYW55O1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgLy8gQ2hlY2sgZm9yIGRvdC1ub3RhdGlvbiAoZS5nLiwgJ3Jlc291cmNlLnRlYW1JZCcpXHJcbiAgICAgICAgY29uc3QgZG90Tm90YXRpb24gPSB0aGlzLnBhcnNlRG90Tm90YXRpb24oZi5pZFByb3BlcnR5KTtcclxuICAgICAgICBpZiAoZG90Tm90YXRpb24pIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVEb3ROb3RhdGlvbihldmVudFJlY29yZCwgZG90Tm90YXRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGYuZGVyaXZlZEZyb20pIHtcclxuICAgICAgICAgIC8vIFVkbGVkIHZcdTAwRTZyZGkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gZXZlbnRSZWNvcmRbZi5kZXJpdmVkRnJvbV07XHJcbiAgICAgICAgICBpZiAoc291cmNlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGVTZXJ2aWNlLmdldERhdGVLZXkoc291cmNlVmFsdWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIFN0cmluZyhzb3VyY2VWYWx1ZSB8fCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBTdHJpbmcoZXZlbnRSZWNvcmRbZi5pZFByb3BlcnR5XSB8fCAnJyk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGRvdC1ub3RhdGlvbiByZWZlcmVuY2UgdmlhIEVudGl0eVJlc29sdmVyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXNvbHZlRG90Tm90YXRpb24oZXZlbnRSZWNvcmQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBkb3ROb3RhdGlvbjogSURvdE5vdGF0aW9uKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHlSZXNvbHZlcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oYEZpbHRlclRlbXBsYXRlOiBFbnRpdHlSZXNvbHZlciByZXF1aXJlZCBmb3IgZG90LW5vdGF0aW9uICcke2RvdE5vdGF0aW9uLmVudGl0eVR5cGV9LiR7ZG90Tm90YXRpb24ucHJvcGVydHl9J2ApO1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGZvcmVpZ24ga2V5IHZhbHVlIGZyb20gZXZlbnQgKGUuZy4sIHJlc291cmNlSWQpXHJcbiAgICBjb25zdCBmb3JlaWduSWQgPSBldmVudFJlY29yZFtkb3ROb3RhdGlvbi5mb3JlaWduS2V5XTtcclxuICAgIGlmICghZm9yZWlnbklkKSByZXR1cm4gJyc7XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBlbnRpdHlcclxuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5UmVzb2x2ZXIucmVzb2x2ZShkb3ROb3RhdGlvbi5lbnRpdHlUeXBlLCBTdHJpbmcoZm9yZWlnbklkKSk7XHJcbiAgICBpZiAoIWVudGl0eSkgcmV0dXJuICcnO1xyXG5cclxuICAgIC8vIFJldHVybiBwcm9wZXJ0eSB2YWx1ZSBmcm9tIGVudGl0eVxyXG4gICAgcmV0dXJuIFN0cmluZyhlbnRpdHlbZG90Tm90YXRpb24ucHJvcGVydHldIHx8ICcnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hdGNoIGV2ZW50IG1vZCBrb2xvbm5lXHJcbiAgICovXHJcbiAgbWF0Y2hlcyhldmVudDogSUNhbGVuZGFyRXZlbnQsIGNvbHVtbjogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmJ1aWxkS2V5RnJvbUV2ZW50KGV2ZW50KSA9PT0gdGhpcy5idWlsZEtleUZyb21Db2x1bW4oY29sdW1uKTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuL0lHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgYnVpbGRQaXBlbGluZSB9IGZyb20gJy4vUmVuZGVyQnVpbGRlcic7XHJcbmltcG9ydCB7IEV2ZW50UmVuZGVyZXIgfSBmcm9tICcuLi9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyJztcclxuaW1wb3J0IHsgU2NoZWR1bGVSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL3NjaGVkdWxlL1NjaGVkdWxlUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBIZWFkZXJEcmF3ZXJSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL2hlYWRlcmRyYXdlci9IZWFkZXJEcmF3ZXJSZW5kZXJlcic7XHJcbmltcG9ydCB7IFZpZXdDb25maWcsIEdyb3VwaW5nQ29uZmlnIH0gZnJvbSAnLi9WaWV3Q29uZmlnJztcclxuaW1wb3J0IHsgRmlsdGVyVGVtcGxhdGUgfSBmcm9tICcuL0ZpbHRlclRlbXBsYXRlJztcclxuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuL0RhdGVTZXJ2aWNlJztcclxuaW1wb3J0IHsgSUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9zdG9yYWdlL0lFbnRpdHlTZXJ2aWNlJztcclxuaW1wb3J0IHsgSVN5bmMgfSBmcm9tICcuLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDYWxlbmRhck9yY2hlc3RyYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGFsbFJlbmRlcmVyczogSVJlbmRlcmVyW10sXHJcbiAgICBwcml2YXRlIGV2ZW50UmVuZGVyZXI6IEV2ZW50UmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIHNjaGVkdWxlUmVuZGVyZXI6IFNjaGVkdWxlUmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIGhlYWRlckRyYXdlclJlbmRlcmVyOiBIZWFkZXJEcmF3ZXJSZW5kZXJlcixcclxuICAgIHByaXZhdGUgZGF0ZVNlcnZpY2U6IERhdGVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbnRpdHlTZXJ2aWNlczogSUVudGl0eVNlcnZpY2U8SVN5bmM+W11cclxuICApIHt9XHJcblxyXG4gIGFzeW5jIHJlbmRlcih2aWV3Q29uZmlnOiBWaWV3Q29uZmlnLCBjb250YWluZXI6IEhUTUxFbGVtZW50KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBoZWFkZXJDb250YWluZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWNhbGVuZGFyLWhlYWRlcicpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgY29sdW1uQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYgKCFoZWFkZXJDb250YWluZXIgfHwgIWNvbHVtbkNvbnRhaW5lcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc3dwLWNhbGVuZGFyLWhlYWRlciBvciBzd3AtZGF5LWNvbHVtbnMnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBCeWcgZmlsdGVyIGZyYSB2aWV3Q29uZmlnXHJcbiAgICBjb25zdCBmaWx0ZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBncm91cGluZyBvZiB2aWV3Q29uZmlnLmdyb3VwaW5ncykge1xyXG4gICAgICBmaWx0ZXJbZ3JvdXBpbmcudHlwZV0gPSBncm91cGluZy52YWx1ZXM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQnlnIEZpbHRlclRlbXBsYXRlIGZyYSB2aWV3Q29uZmlnIGdyb3VwaW5ncyAoa3VuIGRlIG1lZCBpZFByb3BlcnR5KVxyXG4gICAgY29uc3QgZmlsdGVyVGVtcGxhdGUgPSBuZXcgRmlsdGVyVGVtcGxhdGUodGhpcy5kYXRlU2VydmljZSk7XHJcbiAgICBmb3IgKGNvbnN0IGdyb3VwaW5nIG9mIHZpZXdDb25maWcuZ3JvdXBpbmdzKSB7XHJcbiAgICAgIGlmIChncm91cGluZy5pZFByb3BlcnR5KSB7XHJcbiAgICAgICAgZmlsdGVyVGVtcGxhdGUuYWRkRmllbGQoZ3JvdXBpbmcuaWRQcm9wZXJ0eSwgZ3JvdXBpbmcuZGVyaXZlZEZyb20pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBiZWxvbmdzVG8gcmVsYXRpb25zIChlLmcuLCB0ZWFtLnJlc291cmNlSWRzKVxyXG4gICAgY29uc3QgeyBwYXJlbnRDaGlsZE1hcCwgY2hpbGRUeXBlIH0gPSBhd2FpdCB0aGlzLnJlc29sdmVCZWxvbmdzVG8odmlld0NvbmZpZy5ncm91cGluZ3MsIGZpbHRlcik7XHJcblxyXG4gICAgY29uc3QgY29udGV4dDogSVJlbmRlckNvbnRleHQgPSB7IGhlYWRlckNvbnRhaW5lciwgY29sdW1uQ29udGFpbmVyLCBmaWx0ZXIsIGdyb3VwaW5nczogdmlld0NvbmZpZy5ncm91cGluZ3MsIHBhcmVudENoaWxkTWFwLCBjaGlsZFR5cGUgfTtcclxuXHJcbiAgICAvLyBDbGVhclxyXG4gICAgaGVhZGVyQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG4gICAgY29sdW1uQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG5cclxuICAgIC8vIFNcdTAwRTZ0IGRhdGEtbGV2ZWxzIGF0dHJpYnV0IGZvciBDU1MgZ3JpZC1yb3cgc3R5bGluZ1xyXG4gICAgY29uc3QgbGV2ZWxzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKS5qb2luKCcgJyk7XHJcbiAgICBoZWFkZXJDb250YWluZXIuZGF0YXNldC5sZXZlbHMgPSBsZXZlbHM7XHJcblxyXG4gICAgLy8gVlx1MDBFNmxnIHJlbmRlcmVycyBiYXNlcmV0IHBcdTAwRTUgZ3JvdXBpbmdzIHR5cGVzXHJcbiAgICBjb25zdCBhY3RpdmVSZW5kZXJlcnMgPSB0aGlzLnNlbGVjdFJlbmRlcmVycyh2aWV3Q29uZmlnKTtcclxuXHJcbiAgICAvLyBCeWcgb2cga1x1MDBGOHIgcGlwZWxpbmVcclxuICAgIGNvbnN0IHBpcGVsaW5lID0gYnVpbGRQaXBlbGluZShhY3RpdmVSZW5kZXJlcnMpO1xyXG4gICAgYXdhaXQgcGlwZWxpbmUucnVuKGNvbnRleHQpO1xyXG5cclxuICAgIC8vIFJlbmRlciBzY2hlZHVsZSB1bmF2YWlsYWJsZSB6b25lcyAoZlx1MDBGOHIgZXZlbnRzKVxyXG4gICAgYXdhaXQgdGhpcy5zY2hlZHVsZVJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlcik7XHJcblxyXG4gICAgLy8gUmVuZGVyIHRpbWVkIGV2ZW50cyBpbiBncmlkIChtZWQgZmlsdGVyVGVtcGxhdGUgdGlsIG1hdGNoaW5nKVxyXG4gICAgYXdhaXQgdGhpcy5ldmVudFJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG5cclxuICAgIC8vIFJlbmRlciBhbGxEYXkgZXZlbnRzIGluIGhlYWRlciBkcmF3ZXIgKG1lZCBmaWx0ZXJUZW1wbGF0ZSB0aWwgbWF0Y2hpbmcpXHJcbiAgICBhd2FpdCB0aGlzLmhlYWRlckRyYXdlclJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZWxlY3RSZW5kZXJlcnModmlld0NvbmZpZzogVmlld0NvbmZpZyk6IElSZW5kZXJlcltdIHtcclxuICAgIGNvbnN0IHR5cGVzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKTtcclxuICAgIC8vIFNvcnRcdTAwRTlyIHJlbmRlcmVycyBpIHNhbW1lIHJcdTAwRTZra2VmXHUwMEY4bGdlIHNvbSB2aWV3Q29uZmlnLmdyb3VwaW5nc1xyXG4gICAgcmV0dXJuIHR5cGVzXHJcbiAgICAgIC5tYXAodHlwZSA9PiB0aGlzLmFsbFJlbmRlcmVycy5maW5kKHIgPT4gci50eXBlID09PSB0eXBlKSlcclxuICAgICAgLmZpbHRlcigocik6IHIgaXMgSVJlbmRlcmVyID0+IHIgIT09IHVuZGVmaW5lZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGJlbG9uZ3NUbyByZWxhdGlvbnMgdG8gYnVpbGQgcGFyZW50LWNoaWxkIG1hcFxyXG4gICAqIGUuZy4sIGJlbG9uZ3NUbzogJ3RlYW0ucmVzb3VyY2VJZHMnIFx1MjE5MiB7IHRlYW0xOiBbJ0VNUDAwMScsICdFTVAwMDInXSwgdGVhbTI6IFsuLi5dIH1cclxuICAgKiBBbHNvIHJldHVybnMgdGhlIGNoaWxkVHlwZSAodGhlIGdyb3VwaW5nIHR5cGUgdGhhdCBoYXMgYmVsb25nc1RvKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUJlbG9uZ3NUbyhcclxuICAgIGdyb3VwaW5nczogR3JvdXBpbmdDb25maWdbXSxcclxuICAgIGZpbHRlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+XHJcbiAgKTogUHJvbWlzZTx7IHBhcmVudENoaWxkTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+OyBjaGlsZFR5cGU/OiBzdHJpbmcgfT4ge1xyXG4gICAgLy8gRmluZCBncm91cGluZyB3aXRoIGJlbG9uZ3NUb1xyXG4gICAgY29uc3QgY2hpbGRHcm91cGluZyA9IGdyb3VwaW5ncy5maW5kKGcgPT4gZy5iZWxvbmdzVG8pO1xyXG4gICAgaWYgKCFjaGlsZEdyb3VwaW5nPy5iZWxvbmdzVG8pIHJldHVybiB7fTtcclxuXHJcbiAgICAvLyBQYXJzZSBiZWxvbmdzVG86ICd0ZWFtLnJlc291cmNlSWRzJ1xyXG4gICAgY29uc3QgW2VudGl0eVR5cGUsIHByb3BlcnR5XSA9IGNoaWxkR3JvdXBpbmcuYmVsb25nc1RvLnNwbGl0KCcuJyk7XHJcbiAgICBpZiAoIWVudGl0eVR5cGUgfHwgIXByb3BlcnR5KSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gR2V0IHBhcmVudCBJRHMgZnJvbSBmaWx0ZXJcclxuICAgIGNvbnN0IHBhcmVudElkcyA9IGZpbHRlcltlbnRpdHlUeXBlXSB8fCBbXTtcclxuICAgIGlmIChwYXJlbnRJZHMubGVuZ3RoID09PSAwKSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gRmluZCBzZXJ2aWNlIGR5bmFtaXNrIGJhc2VyZXQgcFx1MDBFNSBlbnRpdHlUeXBlIChpbmdlbiBoYXJkY29kZWQgdHlwZSBjaGVjaylcclxuICAgIGNvbnN0IHNlcnZpY2UgPSB0aGlzLmVudGl0eVNlcnZpY2VzLmZpbmQocyA9PlxyXG4gICAgICBzLmVudGl0eVR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZW50aXR5VHlwZVxyXG4gICAgKTtcclxuICAgIGlmICghc2VydmljZSkgcmV0dXJuIHt9O1xyXG5cclxuICAgIC8vIEhlbnQgYWxsZSBlbnRpdGllcyBvZyBmaWx0cmVyIHBcdTAwRTUgcGFyZW50SWRzXHJcbiAgICBjb25zdCBhbGxFbnRpdGllcyA9IGF3YWl0IHNlcnZpY2UuZ2V0QWxsKCk7XHJcbiAgICBjb25zdCBlbnRpdGllcyA9IGFsbEVudGl0aWVzLmZpbHRlcihlID0+XHJcbiAgICAgIHBhcmVudElkcy5pbmNsdWRlcygoZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5pZCBhcyBzdHJpbmcpXHJcbiAgICApO1xyXG5cclxuICAgIC8vIEJ5ZyBwYXJlbnQtY2hpbGQgbWFwXHJcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcclxuICAgICAgY29uc3QgZW50aXR5UmVjb3JkID0gZW50aXR5IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XHJcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gKGVudGl0eVJlY29yZFtwcm9wZXJ0eV0gYXMgc3RyaW5nW10pIHx8IFtdO1xyXG4gICAgICBtYXBbZW50aXR5UmVjb3JkLmlkIGFzIHN0cmluZ10gPSBjaGlsZHJlbjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBwYXJlbnRDaGlsZE1hcDogbWFwLCBjaGlsZFR5cGU6IGNoaWxkR3JvdXBpbmcudHlwZSB9O1xyXG4gIH1cclxufVxyXG4iLCAiZXhwb3J0IGNsYXNzIE5hdmlnYXRpb25BbmltYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGhlYWRlclRyYWNrOiBIVE1MRWxlbWVudCxcclxuICAgIHByaXZhdGUgY29udGVudFRyYWNrOiBIVE1MRWxlbWVudCxcclxuICAgIHByaXZhdGUgaGVhZGVyRHJhd2VyOiBIVE1MRWxlbWVudCB8IG51bGxcclxuICApIHt9XHJcblxyXG4gIGFzeW5jIHNsaWRlKGRpcmVjdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0JywgcmVuZGVyRm46ICgpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IG91dCA9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJy0xMDAlJyA6ICcxMDAlJztcclxuICAgIGNvbnN0IGludG8gPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/ICcxMDAlJyA6ICctMTAwJSc7XHJcblxyXG4gICAgYXdhaXQgdGhpcy5hbmltYXRlT3V0KG91dCk7XHJcbiAgICBhd2FpdCByZW5kZXJGbigpO1xyXG4gICAgYXdhaXQgdGhpcy5hbmltYXRlSW4oaW50byk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGFuaW1hdGVPdXQodHJhbnNsYXRlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXHJcbiAgICAgIHRoaXMuaGVhZGVyVHJhY2suYW5pbWF0ZShcclxuICAgICAgICBbeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9LCB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfV0sXHJcbiAgICAgICAgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLWluJyB9XHJcbiAgICAgICkuZmluaXNoZWQsXHJcbiAgICAgIHRoaXMuY29udGVudFRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfSwgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfVxyXG4gICAgICApLmZpbmlzaGVkXHJcbiAgICBdO1xyXG5cclxuICAgIGlmICh0aGlzLmhlYWRlckRyYXdlcikge1xyXG4gICAgICBhbmltYXRpb25zLnB1c2goXHJcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIuYW5pbWF0ZShcclxuICAgICAgICAgIFt7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH0sIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9XSxcclxuICAgICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfVxyXG4gICAgICAgICkuZmluaXNoZWRcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhd2FpdCBQcm9taXNlLmFsbChhbmltYXRpb25zKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgYW5pbWF0ZUluKHRyYW5zbGF0ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBhbmltYXRpb25zID0gW1xyXG4gICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9LCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH1cclxuICAgICAgKS5maW5pc2hlZCxcclxuICAgICAgdGhpcy5jb250ZW50VHJhY2suYW5pbWF0ZShcclxuICAgICAgICBbeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH0sIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfV0sXHJcbiAgICAgICAgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLW91dCcgfVxyXG4gICAgICApLmZpbmlzaGVkXHJcbiAgICBdO1xyXG5cclxuICAgIGlmICh0aGlzLmhlYWRlckRyYXdlcikge1xyXG4gICAgICBhbmltYXRpb25zLnB1c2goXHJcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIuYW5pbWF0ZShcclxuICAgICAgICAgIFt7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfSwgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9XSxcclxuICAgICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH1cclxuICAgICAgICApLmZpbmlzaGVkXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoYW5pbWF0aW9ucyk7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29yZS9JR3JvdXBpbmdSZW5kZXJlcic7XHJcbmltcG9ydCB7IERhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9EYXRlU2VydmljZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgRGF0ZVJlbmRlcmVyIGltcGxlbWVudHMgSVJlbmRlcmVyIHtcclxuICByZWFkb25seSB0eXBlID0gJ2RhdGUnO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGVTZXJ2aWNlOiBEYXRlU2VydmljZSkge31cclxuXHJcbiAgcmVuZGVyKGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogdm9pZCB7XHJcbiAgICBjb25zdCBkYXRlcyA9IGNvbnRleHQuZmlsdGVyWydkYXRlJ10gfHwgW107XHJcbiAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIGRhdGUgaGVhZGVycyBzaG91bGQgYmUgaGlkZGVuIChlLmcuLCBpbiBkYXkgdmlldylcclxuICAgIGNvbnN0IGRhdGVHcm91cGluZyA9IGNvbnRleHQuZ3JvdXBpbmdzPy5maW5kKGcgPT4gZy50eXBlID09PSAnZGF0ZScpO1xyXG4gICAgY29uc3QgaGlkZUhlYWRlciA9IGRhdGVHcm91cGluZz8uaGlkZUhlYWRlciA9PT0gdHJ1ZTtcclxuXHJcbiAgICAvLyBSZW5kZXIgZGF0ZXMgZm9yIEhWRVIgcmVzb3VyY2UgKGVsbGVyIDEgZ2FuZyBodmlzIGluZ2VuIHJlc291cmNlcylcclxuICAgIGNvbnN0IGl0ZXJhdGlvbnMgPSByZXNvdXJjZUlkcy5sZW5ndGggfHwgMTtcclxuICAgIGxldCBjb2x1bW5Db3VudCA9IDA7XHJcblxyXG4gICAgZm9yIChsZXQgciA9IDA7IHIgPCBpdGVyYXRpb25zOyByKyspIHtcclxuICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IHJlc291cmNlSWRzW3JdOyAvLyB1bmRlZmluZWQgaHZpcyBpbmdlbiByZXNvdXJjZXNcclxuXHJcbiAgICAgIGZvciAoY29uc3QgZGF0ZVN0ciBvZiBkYXRlcykge1xyXG4gICAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmRhdGVTZXJ2aWNlLnBhcnNlSVNPKGRhdGVTdHIpO1xyXG5cclxuICAgICAgICAvLyBCdWlsZCBjb2x1bW5LZXkgZm9yIHVuaWZvcm0gaWRlbnRpZmljYXRpb25cclxuICAgICAgICBjb25zdCBzZWdtZW50czogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgZGF0ZTogZGF0ZVN0ciB9O1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUlkKSBzZWdtZW50cy5yZXNvdXJjZSA9IHJlc291cmNlSWQ7XHJcbiAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5kYXRlU2VydmljZS5idWlsZENvbHVtbktleShzZWdtZW50cyk7XHJcblxyXG4gICAgICAgIC8vIEhlYWRlclxyXG4gICAgICAgIGNvbnN0IGhlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1kYXktaGVhZGVyJyk7XHJcbiAgICAgICAgaGVhZGVyLmRhdGFzZXQuZGF0ZSA9IGRhdGVTdHI7XHJcbiAgICAgICAgaGVhZGVyLmRhdGFzZXQuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUlkKSB7XHJcbiAgICAgICAgICBoZWFkZXIuZGF0YXNldC5yZXNvdXJjZUlkID0gcmVzb3VyY2VJZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGhpZGVIZWFkZXIpIHtcclxuICAgICAgICAgIGhlYWRlci5kYXRhc2V0LmhpZGRlbiA9ICd0cnVlJztcclxuICAgICAgICB9XHJcbiAgICAgICAgaGVhZGVyLmlubmVySFRNTCA9IGBcclxuICAgICAgICAgIDxzd3AtZGF5LW5hbWU+JHt0aGlzLmRhdGVTZXJ2aWNlLmdldERheU5hbWUoZGF0ZSwgJ3Nob3J0Jyl9PC9zd3AtZGF5LW5hbWU+XHJcbiAgICAgICAgICA8c3dwLWRheS1kYXRlPiR7ZGF0ZS5nZXREYXRlKCl9PC9zd3AtZGF5LWRhdGU+XHJcbiAgICAgICAgYDtcclxuICAgICAgICBjb250ZXh0LmhlYWRlckNvbnRhaW5lci5hcHBlbmRDaGlsZChoZWFkZXIpO1xyXG5cclxuICAgICAgICAvLyBDb2x1bW5cclxuICAgICAgICBjb25zdCBjb2x1bW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZGF5LWNvbHVtbicpO1xyXG4gICAgICAgIGNvbHVtbi5kYXRhc2V0LmRhdGUgPSBkYXRlU3RyO1xyXG4gICAgICAgIGNvbHVtbi5kYXRhc2V0LmNvbHVtbktleSA9IGNvbHVtbktleTtcclxuICAgICAgICBpZiAocmVzb3VyY2VJZCkge1xyXG4gICAgICAgICAgY29sdW1uLmRhdGFzZXQucmVzb3VyY2VJZCA9IHJlc291cmNlSWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbHVtbi5pbm5lckhUTUwgPSAnPHN3cC1ldmVudHMtbGF5ZXI+PC9zd3AtZXZlbnRzLWxheWVyPic7XHJcbiAgICAgICAgY29udGV4dC5jb2x1bW5Db250YWluZXIuYXBwZW5kQ2hpbGQoY29sdW1uKTtcclxuXHJcbiAgICAgICAgY29sdW1uQ291bnQrKztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFNldCBncmlkIGNvbHVtbnMgb24gY29udGFpbmVyXHJcbiAgICBjb25zdCBjb250YWluZXIgPSBjb250ZXh0LmNvbHVtbkNvbnRhaW5lci5jbG9zZXN0KCdzd3AtY2FsZW5kYXItY29udGFpbmVyJyk7XHJcbiAgICBpZiAoY29udGFpbmVyKSB7XHJcbiAgICAgIChjb250YWluZXIgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLnNldFByb3BlcnR5KCctLWdyaWQtY29sdW1ucycsIFN0cmluZyhjb2x1bW5Db3VudCkpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCAiaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJztcclxuaW1wb3J0IHV0YyBmcm9tICdkYXlqcy9wbHVnaW4vdXRjJztcclxuaW1wb3J0IHRpbWV6b25lIGZyb20gJ2RheWpzL3BsdWdpbi90aW1lem9uZSc7XHJcbmltcG9ydCBpc29XZWVrIGZyb20gJ2RheWpzL3BsdWdpbi9pc29XZWVrJztcclxuaW1wb3J0IHsgSVRpbWVGb3JtYXRDb25maWcgfSBmcm9tICcuL0lUaW1lRm9ybWF0Q29uZmlnJztcclxuXHJcbi8vIEVuYWJsZSBkYXlqcyBwbHVnaW5zXHJcbmRheWpzLmV4dGVuZCh1dGMpO1xyXG5kYXlqcy5leHRlbmQodGltZXpvbmUpO1xyXG5kYXlqcy5leHRlbmQoaXNvV2Vlayk7XHJcblxyXG5leHBvcnQgY2xhc3MgRGF0ZVNlcnZpY2Uge1xyXG4gIHByaXZhdGUgdGltZXpvbmU6IHN0cmluZztcclxuICBwcml2YXRlIGJhc2VEYXRlOiBkYXlqcy5EYXlqcztcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWc6IElUaW1lRm9ybWF0Q29uZmlnLCBiYXNlRGF0ZT86IERhdGUpIHtcclxuICAgIHRoaXMudGltZXpvbmUgPSBjb25maWcudGltZXpvbmU7XHJcbiAgICAvLyBBbGxvdyBzZXR0aW5nIGEgZml4ZWQgYmFzZSBkYXRlIGZvciBkZW1vL3Rlc3RpbmcgcHVycG9zZXNcclxuICAgIHRoaXMuYmFzZURhdGUgPSBiYXNlRGF0ZSA/IGRheWpzKGJhc2VEYXRlKSA6IGRheWpzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXQgYSBmaXhlZCBiYXNlIGRhdGUgKHVzZWZ1bCBmb3IgZGVtb3Mgd2l0aCBzdGF0aWMgbW9jayBkYXRhKVxyXG4gICAqL1xyXG4gIHNldEJhc2VEYXRlKGRhdGU6IERhdGUpOiB2b2lkIHtcclxuICAgIHRoaXMuYmFzZURhdGUgPSBkYXlqcyhkYXRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgY3VycmVudCBiYXNlIGRhdGUgKGVpdGhlciBmaXhlZCBvciB0b2RheSlcclxuICAgKi9cclxuICBnZXRCYXNlRGF0ZSgpOiBEYXRlIHtcclxuICAgIHJldHVybiB0aGlzLmJhc2VEYXRlLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcGFyc2VJU08oaXNvU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHtcclxuICAgIHJldHVybiBkYXlqcyhpc29TdHJpbmcpLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGF5TmFtZShkYXRlOiBEYXRlLCBmb3JtYXQ6ICdzaG9ydCcgfCAnbG9uZycgPSAnc2hvcnQnKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBuZXcgSW50bC5EYXRlVGltZUZvcm1hdCh0aGlzLmNvbmZpZy5sb2NhbGUsIHsgd2Vla2RheTogZm9ybWF0IH0pLmZvcm1hdChkYXRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBkYXRlcyBzdGFydGluZyBmcm9tIGEgZGF5IG9mZnNldFxyXG4gICAqIEBwYXJhbSBkYXlPZmZzZXQgLSBEYXkgb2Zmc2V0IGZyb20gYmFzZSBkYXRlXHJcbiAgICogQHBhcmFtIGNvdW50IC0gTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGRheXMgdG8gcmV0dXJuXHJcbiAgICogQHJldHVybnMgQXJyYXkgb2YgZGF0ZSBzdHJpbmdzIGluIFlZWVktTU0tREQgZm9ybWF0XHJcbiAgICovXHJcbiAgZ2V0RGF0ZXNGcm9tT2Zmc2V0KGRheU9mZnNldDogbnVtYmVyLCBjb3VudDogbnVtYmVyKTogc3RyaW5nW10ge1xyXG4gICAgY29uc3Qgc3RhcnREYXRlID0gdGhpcy5iYXNlRGF0ZS5hZGQoZGF5T2Zmc2V0LCAnZGF5Jyk7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKF8sIGkpID0+XHJcbiAgICAgIHN0YXJ0RGF0ZS5hZGQoaSwgJ2RheScpLmZvcm1hdCgnWVlZWS1NTS1ERCcpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHNwZWNpZmljIHdlZWtkYXlzIGZyb20gdGhlIHdlZWsgY29udGFpbmluZyB0aGUgb2Zmc2V0IGRhdGVcclxuICAgKiBAcGFyYW0gZGF5T2Zmc2V0IC0gRGF5IG9mZnNldCBmcm9tIGJhc2UgZGF0ZVxyXG4gICAqIEBwYXJhbSB3b3JrRGF5cyAtIEFycmF5IG9mIElTTyB3ZWVrZGF5IG51bWJlcnMgKDE9TW9uZGF5LCA3PVN1bmRheSlcclxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBkYXRlIHN0cmluZ3MgaW4gWVlZWS1NTS1ERCBmb3JtYXRcclxuICAgKi9cclxuICBnZXRXb3JrRGF5c0Zyb21PZmZzZXQoZGF5T2Zmc2V0OiBudW1iZXIsIHdvcmtEYXlzOiBudW1iZXJbXSk6IHN0cmluZ1tdIHtcclxuICAgIC8vIEdldCB0aGUgZGF0ZSBhdCBvZmZzZXQsIHRoZW4gZmluZCBpdHMgd2VlaydzIE1vbmRheVxyXG4gICAgY29uc3QgdGFyZ2V0RGF0ZSA9IHRoaXMuYmFzZURhdGUuYWRkKGRheU9mZnNldCwgJ2RheScpO1xyXG4gICAgY29uc3QgbW9uZGF5ID0gdGFyZ2V0RGF0ZS5zdGFydE9mKCd3ZWVrJykuYWRkKDEsICdkYXknKTtcclxuXHJcbiAgICByZXR1cm4gd29ya0RheXMubWFwKGlzb0RheSA9PiB7XHJcbiAgICAgIC8vIElTTzogMT1Nb25kYXksIDc9U3VuZGF5IFx1MjE5MiBkYXlzIGZyb20gTW9uZGF5OiAwLTZcclxuICAgICAgY29uc3QgZGF5c0Zyb21Nb25kYXkgPSBpc29EYXkgPT09IDcgPyA2IDogaXNvRGF5IC0gMTtcclxuICAgICAgcmV0dXJuIG1vbmRheS5hZGQoZGF5c0Zyb21Nb25kYXksICdkYXknKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gTGVnYWN5IG1ldGhvZHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XHJcbiAgZ2V0V2Vla0RhdGVzKHdlZWtPZmZzZXQgPSAwLCBkYXlzID0gNyk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiB0aGlzLmdldERhdGVzRnJvbU9mZnNldCh3ZWVrT2Zmc2V0ICogNywgZGF5cyk7XHJcbiAgfVxyXG5cclxuICBnZXRXb3JrV2Vla0RhdGVzKHdlZWtPZmZzZXQ6IG51bWJlciwgd29ya0RheXM6IG51bWJlcltdKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0V29ya0RheXNGcm9tT2Zmc2V0KHdlZWtPZmZzZXQgKiA3LCB3b3JrRGF5cyk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIC8vIEZPUk1BVFRJTkdcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICBmb3JtYXRUaW1lKGRhdGU6IERhdGUsIHNob3dTZWNvbmRzID0gZmFsc2UpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgcGF0dGVybiA9IHNob3dTZWNvbmRzID8gJ0hIOm1tOnNzJyA6ICdISDptbSc7XHJcbiAgICByZXR1cm4gZGF5anMoZGF0ZSkuZm9ybWF0KHBhdHRlcm4pO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0VGltZVJhbmdlKHN0YXJ0OiBEYXRlLCBlbmQ6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGAke3RoaXMuZm9ybWF0VGltZShzdGFydCl9IC0gJHt0aGlzLmZvcm1hdFRpbWUoZW5kKX1gO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0RGF0ZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcclxuICB9XHJcblxyXG4gIGdldERhdGVLZXkoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBDT0xVTU4gS0VZXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgLyoqXHJcbiAgICogQnVpbGQgYSB1bmlmb3JtIGNvbHVtbktleSBmcm9tIGdyb3VwaW5nIHNlZ21lbnRzXHJcbiAgICogSGFuZGxlcyBhbnkgY29tYmluYXRpb24gb2YgZGF0ZSwgcmVzb3VyY2UsIHRlYW0sIGV0Yy5cclxuICAgKlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScgfSkgXHUyMTkyIFwiMjAyNS0xMi0wOVwiXHJcbiAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScsIHJlc291cmNlOiAnRU1QMDAxJyB9KSBcdTIxOTIgXCIyMDI1LTEyLTA5OkVNUDAwMVwiXHJcbiAgICovXHJcbiAgYnVpbGRDb2x1bW5LZXkoc2VnbWVudHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBzdHJpbmcge1xyXG4gICAgLy8gQWx3YXlzIHB1dCBkYXRlIGZpcnN0IGlmIHByZXNlbnQsIHRoZW4gb3RoZXIgc2VnbWVudHMgYWxwaGFiZXRpY2FsbHlcclxuICAgIGNvbnN0IGRhdGUgPSBzZWdtZW50cy5kYXRlO1xyXG4gICAgY29uc3Qgb3RoZXJzID0gT2JqZWN0LmVudHJpZXMoc2VnbWVudHMpXHJcbiAgICAgIC5maWx0ZXIoKFtrXSkgPT4gayAhPT0gJ2RhdGUnKVxyXG4gICAgICAuc29ydCgoW2FdLCBbYl0pID0+IGEubG9jYWxlQ29tcGFyZShiKSlcclxuICAgICAgLm1hcCgoWywgdl0pID0+IHYpO1xyXG5cclxuICAgIHJldHVybiBkYXRlID8gW2RhdGUsIC4uLm90aGVyc10uam9pbignOicpIDogb3RoZXJzLmpvaW4oJzonKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGEgY29sdW1uS2V5IGJhY2sgaW50byBzZWdtZW50c1xyXG4gICAqIEFzc3VtZXMgZm9ybWF0OiBcImRhdGU6cmVzb3VyY2U6Li4uXCIgb3IganVzdCBcImRhdGVcIlxyXG4gICAqL1xyXG4gIHBhcnNlQ29sdW1uS2V5KGNvbHVtbktleTogc3RyaW5nKTogeyBkYXRlOiBzdHJpbmc7IHJlc291cmNlPzogc3RyaW5nIH0ge1xyXG4gICAgY29uc3QgcGFydHMgPSBjb2x1bW5LZXkuc3BsaXQoJzonKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRhdGU6IHBhcnRzWzBdLFxyXG4gICAgICByZXNvdXJjZTogcGFydHNbMV1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IGRhdGVLZXkgZnJvbSBjb2x1bW5LZXkgKGZpcnN0IHNlZ21lbnQpXHJcbiAgICovXHJcbiAgZ2V0RGF0ZUZyb21Db2x1bW5LZXkoY29sdW1uS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGNvbHVtbktleS5zcGxpdCgnOicpWzBdO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBUSU1FIENBTENVTEFUSU9OU1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHRpbWVUb01pbnV0ZXModGltZVN0cmluZzogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHBhcnRzID0gdGltZVN0cmluZy5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xyXG4gICAgY29uc3QgaG91cnMgPSBwYXJ0c1swXSB8fCAwO1xyXG4gICAgY29uc3QgbWludXRlcyA9IHBhcnRzWzFdIHx8IDA7XHJcbiAgICByZXR1cm4gaG91cnMgKiA2MCArIG1pbnV0ZXM7XHJcbiAgfVxyXG5cclxuICBtaW51dGVzVG9UaW1lKHRvdGFsTWludXRlczogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0b3RhbE1pbnV0ZXMgLyA2MCk7XHJcbiAgICBjb25zdCBtaW51dGVzID0gdG90YWxNaW51dGVzICUgNjA7XHJcbiAgICByZXR1cm4gZGF5anMoKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykuZm9ybWF0KCdISDptbScpO1xyXG4gIH1cclxuXHJcbiAgZ2V0TWludXRlc1NpbmNlTWlkbmlnaHQoZGF0ZTogRGF0ZSk6IG51bWJlciB7XHJcbiAgICBjb25zdCBkID0gZGF5anMoZGF0ZSk7XHJcbiAgICByZXR1cm4gZC5ob3VyKCkgKiA2MCArIGQubWludXRlKCk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIC8vIFVUQyBDT05WRVJTSU9OU1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHRvVVRDKGxvY2FsRGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gZGF5anMudHoobG9jYWxEYXRlLCB0aGlzLnRpbWV6b25lKS51dGMoKS50b0lTT1N0cmluZygpO1xyXG4gIH1cclxuXHJcbiAgZnJvbVVUQyh1dGNTdHJpbmc6IHN0cmluZyk6IERhdGUge1xyXG4gICAgcmV0dXJuIGRheWpzLnV0Yyh1dGNTdHJpbmcpLnR6KHRoaXMudGltZXpvbmUpLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBEQVRFIENSRUFUSU9OXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgY3JlYXRlRGF0ZUF0VGltZShiYXNlRGF0ZTogRGF0ZSB8IHN0cmluZywgdGltZVN0cmluZzogc3RyaW5nKTogRGF0ZSB7XHJcbiAgICBjb25zdCB0b3RhbE1pbnV0ZXMgPSB0aGlzLnRpbWVUb01pbnV0ZXModGltZVN0cmluZyk7XHJcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gNjApO1xyXG4gICAgY29uc3QgbWludXRlcyA9IHRvdGFsTWludXRlcyAlIDYwO1xyXG4gICAgcmV0dXJuIGRheWpzKGJhc2VEYXRlKS5zdGFydE9mKCdkYXknKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykudG9EYXRlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRJU09XZWVrRGF5KGRhdGU6IERhdGUgfCBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIGRheWpzKGRhdGUpLmlzb1dlZWtkYXkoKTsgIC8vIDE9TW9uZGF5LCA3PVN1bmRheVxyXG4gIH1cclxufVxyXG4iLCAiLyoqXG4gKiBQb3NpdGlvblV0aWxzIC0gUGl4ZWwvcG9zaXRpb24gY2FsY3VsYXRpb25zIGZvciBjYWxlbmRhciBncmlkXG4gKlxuICogUkVTUE9OU0lCSUxJVFk6IENvbnZlcnQgYmV0d2VlbiB0aW1lIGFuZCBwaXhlbCBwb3NpdGlvbnNcbiAqIE5PVEU6IERhdGUgZm9ybWF0dGluZyBiZWxvbmdzIGluIERhdGVTZXJ2aWNlLCBub3QgaGVyZVxuICovXG5cbmltcG9ydCB7IElHcmlkQ29uZmlnIH0gZnJvbSAnLi4vY29yZS9JR3JpZENvbmZpZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRQb3NpdGlvbiB7XG4gIHRvcDogbnVtYmVyOyAgICAvLyBwaXhlbHMgZnJvbSBkYXkgc3RhcnRcbiAgaGVpZ2h0OiBudW1iZXI7IC8vIHBpeGVsc1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBwaXhlbCBwb3NpdGlvbiBmb3IgYW4gZXZlbnQgYmFzZWQgb24gaXRzIHRpbWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKFxuICBzdGFydDogRGF0ZSxcbiAgZW5kOiBEYXRlLFxuICBjb25maWc6IElHcmlkQ29uZmlnXG4pOiBFdmVudFBvc2l0aW9uIHtcbiAgY29uc3Qgc3RhcnRNaW51dGVzID0gc3RhcnQuZ2V0SG91cnMoKSAqIDYwICsgc3RhcnQuZ2V0TWludXRlcygpO1xuICBjb25zdCBlbmRNaW51dGVzID0gZW5kLmdldEhvdXJzKCkgKiA2MCArIGVuZC5nZXRNaW51dGVzKCk7XG5cbiAgY29uc3QgZGF5U3RhcnRNaW51dGVzID0gY29uZmlnLmRheVN0YXJ0SG91ciAqIDYwO1xuICBjb25zdCBtaW51dGVIZWlnaHQgPSBjb25maWcuaG91ckhlaWdodCAvIDYwO1xuXG4gIGNvbnN0IHRvcCA9IChzdGFydE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuICBjb25zdCBoZWlnaHQgPSAoZW5kTWludXRlcyAtIHN0YXJ0TWludXRlcykgKiBtaW51dGVIZWlnaHQ7XG5cbiAgcmV0dXJuIHsgdG9wLCBoZWlnaHQgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IG1pbnV0ZXMgdG8gcGl4ZWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW51dGVzVG9QaXhlbHMobWludXRlczogbnVtYmVyLCBjb25maWc6IElHcmlkQ29uZmlnKTogbnVtYmVyIHtcbiAgcmV0dXJuIChtaW51dGVzIC8gNjApICogY29uZmlnLmhvdXJIZWlnaHQ7XG59XG5cbi8qKlxuICogQ29udmVydCBwaXhlbHMgdG8gbWludXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGl4ZWxzVG9NaW51dGVzKHBpeGVsczogbnVtYmVyLCBjb25maWc6IElHcmlkQ29uZmlnKTogbnVtYmVyIHtcbiAgcmV0dXJuIChwaXhlbHMgLyBjb25maWcuaG91ckhlaWdodCkgKiA2MDtcbn1cblxuLyoqXG4gKiBTbmFwIHBpeGVsIHBvc2l0aW9uIHRvIGdyaWQgaW50ZXJ2YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNuYXBUb0dyaWQocGl4ZWxzOiBudW1iZXIsIGNvbmZpZzogSUdyaWRDb25maWcpOiBudW1iZXIge1xuICBjb25zdCBzbmFwUGl4ZWxzID0gbWludXRlc1RvUGl4ZWxzKGNvbmZpZy5zbmFwSW50ZXJ2YWwsIGNvbmZpZyk7XG4gIHJldHVybiBNYXRoLnJvdW5kKHBpeGVscyAvIHNuYXBQaXhlbHMpICogc25hcFBpeGVscztcbn1cbiIsICIvKipcbiAqIENvcmVFdmVudHMgLSBDb25zb2xpZGF0ZWQgZXNzZW50aWFsIGV2ZW50cyBmb3IgdGhlIGNhbGVuZGFyXG4gKi9cbmV4cG9ydCBjb25zdCBDb3JlRXZlbnRzID0ge1xuICAvLyBMaWZlY3ljbGUgZXZlbnRzXG4gIElOSVRJQUxJWkVEOiAnY29yZTppbml0aWFsaXplZCcsXG4gIFJFQURZOiAnY29yZTpyZWFkeScsXG4gIERFU1RST1lFRDogJ2NvcmU6ZGVzdHJveWVkJyxcblxuICAvLyBWaWV3IGV2ZW50c1xuICBWSUVXX0NIQU5HRUQ6ICd2aWV3OmNoYW5nZWQnLFxuICBWSUVXX1JFTkRFUkVEOiAndmlldzpyZW5kZXJlZCcsXG5cbiAgLy8gTmF2aWdhdGlvbiBldmVudHNcbiAgREFURV9DSEFOR0VEOiAnbmF2OmRhdGUtY2hhbmdlZCcsXG4gIE5BVklHQVRJT05fQ09NUExFVEVEOiAnbmF2Om5hdmlnYXRpb24tY29tcGxldGVkJyxcblxuICAvLyBEYXRhIGV2ZW50c1xuICBEQVRBX0xPQURJTkc6ICdkYXRhOmxvYWRpbmcnLFxuICBEQVRBX0xPQURFRDogJ2RhdGE6bG9hZGVkJyxcbiAgREFUQV9FUlJPUjogJ2RhdGE6ZXJyb3InLFxuXG4gIC8vIEdyaWQgZXZlbnRzXG4gIEdSSURfUkVOREVSRUQ6ICdncmlkOnJlbmRlcmVkJyxcbiAgR1JJRF9DTElDS0VEOiAnZ3JpZDpjbGlja2VkJyxcblxuICAvLyBFdmVudCBtYW5hZ2VtZW50XG4gIEVWRU5UX0NSRUFURUQ6ICdldmVudDpjcmVhdGVkJyxcbiAgRVZFTlRfVVBEQVRFRDogJ2V2ZW50OnVwZGF0ZWQnLFxuICBFVkVOVF9ERUxFVEVEOiAnZXZlbnQ6ZGVsZXRlZCcsXG4gIEVWRU5UX1NFTEVDVEVEOiAnZXZlbnQ6c2VsZWN0ZWQnLFxuXG4gIC8vIEV2ZW50IGRyYWctZHJvcFxuICBFVkVOVF9EUkFHX1NUQVJUOiAnZXZlbnQ6ZHJhZy1zdGFydCcsXG4gIEVWRU5UX0RSQUdfTU9WRTogJ2V2ZW50OmRyYWctbW92ZScsXG4gIEVWRU5UX0RSQUdfRU5EOiAnZXZlbnQ6ZHJhZy1lbmQnLFxuICBFVkVOVF9EUkFHX0NBTkNFTDogJ2V2ZW50OmRyYWctY2FuY2VsJyxcbiAgRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFOiAnZXZlbnQ6ZHJhZy1jb2x1bW4tY2hhbmdlJyxcblxuICAvLyBIZWFkZXIgZHJhZyAodGltZWQgXHUyMTkyIGhlYWRlciBjb252ZXJzaW9uKVxuICBFVkVOVF9EUkFHX0VOVEVSX0hFQURFUjogJ2V2ZW50OmRyYWctZW50ZXItaGVhZGVyJyxcbiAgRVZFTlRfRFJBR19NT1ZFX0hFQURFUjogJ2V2ZW50OmRyYWctbW92ZS1oZWFkZXInLFxuICBFVkVOVF9EUkFHX0xFQVZFX0hFQURFUjogJ2V2ZW50OmRyYWctbGVhdmUtaGVhZGVyJyxcblxuICAvLyBFdmVudCByZXNpemVcbiAgRVZFTlRfUkVTSVpFX1NUQVJUOiAnZXZlbnQ6cmVzaXplLXN0YXJ0JyxcbiAgRVZFTlRfUkVTSVpFX0VORDogJ2V2ZW50OnJlc2l6ZS1lbmQnLFxuXG4gIC8vIEVkZ2Ugc2Nyb2xsXG4gIEVER0VfU0NST0xMX1RJQ0s6ICdlZGdlLXNjcm9sbDp0aWNrJyxcbiAgRURHRV9TQ1JPTExfU1RBUlRFRDogJ2VkZ2Utc2Nyb2xsOnN0YXJ0ZWQnLFxuICBFREdFX1NDUk9MTF9TVE9QUEVEOiAnZWRnZS1zY3JvbGw6c3RvcHBlZCcsXG5cbiAgLy8gU3lzdGVtIGV2ZW50c1xuICBFUlJPUjogJ3N5c3RlbTplcnJvcicsXG5cbiAgLy8gU3luYyBldmVudHNcbiAgU1lOQ19TVEFSVEVEOiAnc3luYzpzdGFydGVkJyxcbiAgU1lOQ19DT01QTEVURUQ6ICdzeW5jOmNvbXBsZXRlZCcsXG4gIFNZTkNfRkFJTEVEOiAnc3luYzpmYWlsZWQnLFxuXG4gIC8vIEVudGl0eSBldmVudHMgLSBmb3IgYXVkaXQgYW5kIHN5bmNcbiAgRU5USVRZX1NBVkVEOiAnZW50aXR5OnNhdmVkJyxcbiAgRU5USVRZX0RFTEVURUQ6ICdlbnRpdHk6ZGVsZXRlZCcsXG5cbiAgLy8gQXVkaXQgZXZlbnRzXG4gIEFVRElUX0xPR0dFRDogJ2F1ZGl0OmxvZ2dlZCcsXG5cbiAgLy8gUmVuZGVyaW5nIGV2ZW50c1xuICBFVkVOVFNfUkVOREVSRUQ6ICdldmVudHM6cmVuZGVyZWQnXG59IGFzIGNvbnN0O1xuIiwgIi8qKlxyXG4gKiBFdmVudExheW91dEVuZ2luZSAtIFNpbXBsaWZpZWQgc3RhY2tpbmcvZ3JvdXBpbmcgYWxnb3JpdGhtXHJcbiAqXHJcbiAqIFN1cHBvcnRzIHR3byBsYXlvdXQgbW9kZXM6XHJcbiAqIC0gR1JJRDogRXZlbnRzIHN0YXJ0aW5nIGF0IHNhbWUgdGltZSByZW5kZXJlZCBzaWRlLWJ5LXNpZGVcclxuICogLSBTVEFDS0lORzogT3ZlcmxhcHBpbmcgZXZlbnRzIHdpdGggbWFyZ2luLWxlZnQgb2Zmc2V0ICgxNXB4IHBlciBsZXZlbClcclxuICpcclxuICogTm8gcHJldi9uZXh0IGNoYWlucywgc2luZ2xlLXBhc3MgZ3JlZWR5IGFsZ29yaXRobVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IElDYWxlbmRhckV2ZW50IH0gZnJvbSAnLi4vLi4vdHlwZXMvQ2FsZW5kYXJUeXBlcyc7XHJcbmltcG9ydCB7IElHcmlkQ29uZmlnIH0gZnJvbSAnLi4vLi4vY29yZS9JR3JpZENvbmZpZyc7XHJcbmltcG9ydCB7IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24gfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcclxuaW1wb3J0IHsgSUNvbHVtbkxheW91dCwgSUdyaWRHcm91cExheW91dCwgSVN0YWNrZWRFdmVudExheW91dCB9IGZyb20gJy4vRXZlbnRMYXlvdXRUeXBlcyc7XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgdHdvIGV2ZW50cyBvdmVybGFwIChzdHJpY3QgLSB0b3VjaGluZyBhdCBib3VuZGFyeSA9IE5PVCBvdmVybGFwcGluZylcclxuICogVGhpcyBtYXRjaGVzIFNjZW5hcmlvIDg6IGVuZD09PXN0YXJ0IGlzIE5PVCBvdmVybGFwXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZXZlbnRzT3ZlcmxhcChhOiBJQ2FsZW5kYXJFdmVudCwgYjogSUNhbGVuZGFyRXZlbnQpOiBib29sZWFuIHtcclxuICByZXR1cm4gYS5zdGFydCA8IGIuZW5kICYmIGEuZW5kID4gYi5zdGFydDtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHR3byBldmVudHMgYXJlIHdpdGhpbiB0aHJlc2hvbGQgZm9yIGdyaWQgZ3JvdXBpbmcuXHJcbiAqIFRoaXMgaW5jbHVkZXM6XHJcbiAqIDEuIFN0YXJ0LXRvLXN0YXJ0OiBFdmVudHMgc3RhcnQgd2l0aGluIHRocmVzaG9sZCBvZiBlYWNoIG90aGVyXHJcbiAqIDIuIEVuZC10by1zdGFydDogT25lIGV2ZW50IHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBhbm90aGVyIGVuZHNcclxuICovXHJcbmZ1bmN0aW9uIGV2ZW50c1dpdGhpblRocmVzaG9sZChhOiBJQ2FsZW5kYXJFdmVudCwgYjogSUNhbGVuZGFyRXZlbnQsIHRocmVzaG9sZE1pbnV0ZXM6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gIGNvbnN0IHRocmVzaG9sZE1zID0gdGhyZXNob2xkTWludXRlcyAqIDYwICogMTAwMDtcclxuXHJcbiAgLy8gU3RhcnQtdG8tc3RhcnQ6IGJvdGggZXZlbnRzIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGRcclxuICBjb25zdCBzdGFydFRvU3RhcnREaWZmID0gTWF0aC5hYnMoYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XHJcbiAgaWYgKHN0YXJ0VG9TdGFydERpZmYgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBFbmQtdG8tc3RhcnQ6IG9uZSBldmVudCBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgdGhlIG90aGVyIGVuZHNcclxuICAvLyBCIHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBBIGVuZHNcclxuICBjb25zdCBiU3RhcnRzQmVmb3JlQUVuZHMgPSBhLmVuZC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKTtcclxuICBpZiAoYlN0YXJ0c0JlZm9yZUFFbmRzID4gMCAmJiBiU3RhcnRzQmVmb3JlQUVuZHMgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBBIHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBCIGVuZHNcclxuICBjb25zdCBhU3RhcnRzQmVmb3JlQkVuZHMgPSBiLmVuZC5nZXRUaW1lKCkgLSBhLnN0YXJ0LmdldFRpbWUoKTtcclxuICBpZiAoYVN0YXJ0c0JlZm9yZUJFbmRzID4gMCAmJiBhU3RhcnRzQmVmb3JlQkVuZHMgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhbGwgZXZlbnRzIGluIGEgZ3JvdXAgc3RhcnQgd2l0aGluIHRocmVzaG9sZCBvZiBlYWNoIG90aGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBhbGxTdGFydFdpdGhpblRocmVzaG9sZChldmVudHM6IElDYWxlbmRhckV2ZW50W10sIHRocmVzaG9sZE1pbnV0ZXM6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gIGlmIChldmVudHMubGVuZ3RoIDw9IDEpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBGaW5kIGVhcmxpZXN0IGFuZCBsYXRlc3Qgc3RhcnQgdGltZXNcclxuICBsZXQgZWFybGllc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xyXG4gIGxldCBsYXRlc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xyXG4gICAgY29uc3QgdGltZSA9IGV2ZW50LnN0YXJ0LmdldFRpbWUoKTtcclxuICAgIGlmICh0aW1lIDwgZWFybGllc3QpIGVhcmxpZXN0ID0gdGltZTtcclxuICAgIGlmICh0aW1lID4gbGF0ZXN0KSBsYXRlc3QgPSB0aW1lO1xyXG4gIH1cclxuXHJcbiAgY29uc3QgZGlmZk1pbnV0ZXMgPSAobGF0ZXN0IC0gZWFybGllc3QpIC8gKDEwMDAgKiA2MCk7XHJcbiAgcmV0dXJuIGRpZmZNaW51dGVzIDw9IHRocmVzaG9sZE1pbnV0ZXM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kIGdyb3VwcyBvZiBvdmVybGFwcGluZyBldmVudHMgKGNvbm5lY3RlZCBieSBvdmVybGFwIGNoYWluKVxyXG4gKiBFdmVudHMgYXJlIGdyb3VwZWQgaWYgdGhleSBvdmVybGFwIHdpdGggYW55IGV2ZW50IGluIHRoZSBncm91cFxyXG4gKi9cclxuZnVuY3Rpb24gZmluZE92ZXJsYXBHcm91cHMoZXZlbnRzOiBJQ2FsZW5kYXJFdmVudFtdKTogSUNhbGVuZGFyRXZlbnRbXVtdIHtcclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xyXG5cclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuICBjb25zdCB1c2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcbiAgY29uc3QgZ3JvdXBzOiBJQ2FsZW5kYXJFdmVudFtdW10gPSBbXTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIGlmICh1c2VkLmhhcyhldmVudC5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgIC8vIFN0YXJ0IGEgbmV3IGdyb3VwIHdpdGggdGhpcyBldmVudFxyXG4gICAgY29uc3QgZ3JvdXA6IElDYWxlbmRhckV2ZW50W10gPSBbZXZlbnRdO1xyXG4gICAgdXNlZC5hZGQoZXZlbnQuaWQpO1xyXG5cclxuICAgIC8vIEV4cGFuZCBncm91cCBieSBmaW5kaW5nIGFsbCBjb25uZWN0ZWQgZXZlbnRzICh2aWEgb3ZlcmxhcClcclxuICAgIGxldCBleHBhbmRlZCA9IHRydWU7XHJcbiAgICB3aGlsZSAoZXhwYW5kZWQpIHtcclxuICAgICAgZXhwYW5kZWQgPSBmYWxzZTtcclxuICAgICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2Ygc29ydGVkKSB7XHJcbiAgICAgICAgaWYgKHVzZWQuaGFzKGNhbmRpZGF0ZS5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiBjYW5kaWRhdGUgb3ZlcmxhcHMgd2l0aCBhbnkgZXZlbnQgaW4gZ3JvdXBcclxuICAgICAgICBjb25zdCBjb25uZWN0cyA9IGdyb3VwLnNvbWUobWVtYmVyID0+IGV2ZW50c092ZXJsYXAobWVtYmVyLCBjYW5kaWRhdGUpKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbm5lY3RzKSB7XHJcbiAgICAgICAgICBncm91cC5wdXNoKGNhbmRpZGF0ZSk7XHJcbiAgICAgICAgICB1c2VkLmFkZChjYW5kaWRhdGUuaWQpO1xyXG4gICAgICAgICAgZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBncm91cHM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kIGdyaWQgY2FuZGlkYXRlcyB3aXRoaW4gYSBncm91cCAtIGV2ZW50cyBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpblxyXG4gKiBVc2VzIFYxIGxvZ2ljOiBldmVudHMgYXJlIGNvbm5lY3RlZCBpZiB3aXRoaW4gdGhyZXNob2xkIChubyBvdmVybGFwIHJlcXVpcmVtZW50KVxyXG4gKi9cclxuZnVuY3Rpb24gZmluZEdyaWRDYW5kaWRhdGVzKFxyXG4gIGV2ZW50czogSUNhbGVuZGFyRXZlbnRbXSxcclxuICB0aHJlc2hvbGRNaW51dGVzOiBudW1iZXJcclxuKTogSUNhbGVuZGFyRXZlbnRbXVtdIHtcclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xyXG5cclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuICBjb25zdCB1c2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcbiAgY29uc3QgZ3JvdXBzOiBJQ2FsZW5kYXJFdmVudFtdW10gPSBbXTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIGlmICh1c2VkLmhhcyhldmVudC5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgIGNvbnN0IGdyb3VwOiBJQ2FsZW5kYXJFdmVudFtdID0gW2V2ZW50XTtcclxuICAgIHVzZWQuYWRkKGV2ZW50LmlkKTtcclxuXHJcbiAgICAvLyBFeHBhbmQgYnkgdGhyZXNob2xkIGNoYWluIChWMSBsb2dpYzogbm8gb3ZlcmxhcCByZXF1aXJlbWVudCwganVzdCB0aHJlc2hvbGQpXHJcbiAgICBsZXQgZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgd2hpbGUgKGV4cGFuZGVkKSB7XHJcbiAgICAgIGV4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHNvcnRlZCkge1xyXG4gICAgICAgIGlmICh1c2VkLmhhcyhjYW5kaWRhdGUuaWQpKSBjb250aW51ZTtcclxuXHJcbiAgICAgICAgY29uc3QgY29ubmVjdHMgPSBncm91cC5zb21lKG1lbWJlciA9PlxyXG4gICAgICAgICAgZXZlbnRzV2l0aGluVGhyZXNob2xkKG1lbWJlciwgY2FuZGlkYXRlLCB0aHJlc2hvbGRNaW51dGVzKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGlmIChjb25uZWN0cykge1xyXG4gICAgICAgICAgZ3JvdXAucHVzaChjYW5kaWRhdGUpO1xyXG4gICAgICAgICAgdXNlZC5hZGQoY2FuZGlkYXRlLmlkKTtcclxuICAgICAgICAgIGV4cGFuZGVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBncm91cHMucHVzaChncm91cCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZ3JvdXBzO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlIHN0YWNrIGxldmVscyBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzIHVzaW5nIGdyZWVkeSBhbGdvcml0aG1cclxuICogRm9yIGVhY2ggZXZlbnQ6IGxldmVsID0gbWF4KG92ZXJsYXBwaW5nIGFscmVhZHktcHJvY2Vzc2VkIGV2ZW50cykgKyAxXHJcbiAqL1xyXG5mdW5jdGlvbiBjYWxjdWxhdGVTdGFja0xldmVscyhldmVudHM6IElDYWxlbmRhckV2ZW50W10pOiBNYXA8c3RyaW5nLCBudW1iZXI+IHtcclxuICBjb25zdCBsZXZlbHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG4gIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xyXG4gICAgbGV0IG1heE92ZXJsYXBwaW5nTGV2ZWwgPSAtMTtcclxuXHJcbiAgICAvLyBGaW5kIG1heCBsZXZlbCBhbW9uZyBvdmVybGFwcGluZyBldmVudHMgYWxyZWFkeSBwcm9jZXNzZWRcclxuICAgIGZvciAoY29uc3QgW2lkLCBsZXZlbF0gb2YgbGV2ZWxzKSB7XHJcbiAgICAgIGNvbnN0IG90aGVyID0gZXZlbnRzLmZpbmQoZSA9PiBlLmlkID09PSBpZCk7XHJcbiAgICAgIGlmIChvdGhlciAmJiBldmVudHNPdmVybGFwKGV2ZW50LCBvdGhlcikpIHtcclxuICAgICAgICBtYXhPdmVybGFwcGluZ0xldmVsID0gTWF0aC5tYXgobWF4T3ZlcmxhcHBpbmdMZXZlbCwgbGV2ZWwpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbGV2ZWxzLnNldChldmVudC5pZCwgbWF4T3ZlcmxhcHBpbmdMZXZlbCArIDEpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGxldmVscztcclxufVxyXG5cclxuLyoqXHJcbiAqIEFsbG9jYXRlIGV2ZW50cyB0byBjb2x1bW5zIGZvciBHUklEIGxheW91dCB1c2luZyBncmVlZHkgYWxnb3JpdGhtXHJcbiAqIE5vbi1vdmVybGFwcGluZyBldmVudHMgY2FuIHNoYXJlIGEgY29sdW1uIHRvIG1pbmltaXplIHRvdGFsIGNvbHVtbnNcclxuICovXHJcbmZ1bmN0aW9uIGFsbG9jYXRlQ29sdW1ucyhldmVudHM6IElDYWxlbmRhckV2ZW50W10pOiBJQ2FsZW5kYXJFdmVudFtdW10ge1xyXG4gIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xyXG4gIGNvbnN0IGNvbHVtbnM6IElDYWxlbmRhckV2ZW50W11bXSA9IFtdO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xyXG4gICAgLy8gRmluZCBmaXJzdCBjb2x1bW4gd2hlcmUgZXZlbnQgZG9lc24ndCBvdmVybGFwIHdpdGggZXhpc3RpbmcgZXZlbnRzXHJcbiAgICBsZXQgcGxhY2VkID0gZmFsc2U7XHJcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XHJcbiAgICAgIGNvbnN0IGNhbkZpdCA9ICFjb2x1bW4uc29tZShlID0+IGV2ZW50c092ZXJsYXAoZXZlbnQsIGUpKTtcclxuICAgICAgaWYgKGNhbkZpdCkge1xyXG4gICAgICAgIGNvbHVtbi5wdXNoKGV2ZW50KTtcclxuICAgICAgICBwbGFjZWQgPSB0cnVlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTm8gc3VpdGFibGUgY29sdW1uIGZvdW5kLCBjcmVhdGUgbmV3IG9uZVxyXG4gICAgaWYgKCFwbGFjZWQpIHtcclxuICAgICAgY29sdW1ucy5wdXNoKFtldmVudF0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGNvbHVtbnM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBNYWluIGVudHJ5IHBvaW50OiBDYWxjdWxhdGUgY29tcGxldGUgbGF5b3V0IGZvciBhIGNvbHVtbidzIGV2ZW50c1xyXG4gKlxyXG4gKiBBbGdvcml0aG06XHJcbiAqIDEuIEZpbmQgb3ZlcmxhcCBncm91cHMgKGV2ZW50cyBjb25uZWN0ZWQgYnkgb3ZlcmxhcCBjaGFpbilcclxuICogMi4gRm9yIGVhY2ggb3ZlcmxhcCBncm91cCwgZmluZCBncmlkIGNhbmRpZGF0ZXMgKGV2ZW50cyB3aXRoaW4gdGhyZXNob2xkIGNoYWluKVxyXG4gKiAzLiBJZiBhbGwgZXZlbnRzIGluIG92ZXJsYXAgZ3JvdXAgZm9ybSBhIHNpbmdsZSBncmlkIGNhbmRpZGF0ZSBcdTIxOTIgR1JJRCBtb2RlXHJcbiAqIDQuIE90aGVyd2lzZSBcdTIxOTIgU1RBQ0tJTkcgbW9kZSB3aXRoIGNhbGN1bGF0ZWQgbGV2ZWxzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQ29sdW1uTGF5b3V0KFxyXG4gIGV2ZW50czogSUNhbGVuZGFyRXZlbnRbXSxcclxuICBjb25maWc6IElHcmlkQ29uZmlnXHJcbik6IElDb2x1bW5MYXlvdXQge1xyXG4gIGNvbnN0IHRocmVzaG9sZE1pbnV0ZXMgPSBjb25maWcuZ3JpZFN0YXJ0VGhyZXNob2xkTWludXRlcyA/PyAxMDtcclxuXHJcbiAgY29uc3QgcmVzdWx0OiBJQ29sdW1uTGF5b3V0ID0ge1xyXG4gICAgZ3JpZHM6IFtdLFxyXG4gICAgc3RhY2tlZDogW11cclxuICB9O1xyXG5cclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgLy8gRmluZCBhbGwgb3ZlcmxhcHBpbmcgZXZlbnQgZ3JvdXBzXHJcbiAgY29uc3Qgb3ZlcmxhcEdyb3VwcyA9IGZpbmRPdmVybGFwR3JvdXBzKGV2ZW50cyk7XHJcblxyXG4gIGZvciAoY29uc3Qgb3ZlcmxhcEdyb3VwIG9mIG92ZXJsYXBHcm91cHMpIHtcclxuICAgIGlmIChvdmVybGFwR3JvdXAubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIC8vIFNpbmdsZSBldmVudCAtIG5vIGdyb3VwaW5nIG5lZWRlZFxyXG4gICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcclxuICAgICAgICBldmVudDogb3ZlcmxhcEdyb3VwWzBdLFxyXG4gICAgICAgIHN0YWNrTGV2ZWw6IDBcclxuICAgICAgfSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFdpdGhpbiB0aGlzIG92ZXJsYXAgZ3JvdXAsIGZpbmQgZ3JpZCBjYW5kaWRhdGVzICh0aHJlc2hvbGQtY29ubmVjdGVkIHN1Ymdyb3VwcylcclxuICAgIGNvbnN0IGdyaWRTdWJncm91cHMgPSBmaW5kR3JpZENhbmRpZGF0ZXMob3ZlcmxhcEdyb3VwLCB0aHJlc2hvbGRNaW51dGVzKTtcclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGUgRU5USVJFIG92ZXJsYXAgZ3JvdXAgZm9ybXMgYSBzaW5nbGUgZ3JpZCBjYW5kaWRhdGVcclxuICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIGFsbCBldmVudHMgYXJlIGNvbm5lY3RlZCB2aWEgdGhyZXNob2xkIGNoYWluXHJcbiAgICBjb25zdCBsYXJnZXN0R3JpZENhbmRpZGF0ZSA9IGdyaWRTdWJncm91cHMucmVkdWNlKChtYXgsIGcpID0+XHJcbiAgICAgIGcubGVuZ3RoID4gbWF4Lmxlbmd0aCA/IGcgOiBtYXgsIGdyaWRTdWJncm91cHNbMF0pO1xyXG5cclxuICAgIGlmIChsYXJnZXN0R3JpZENhbmRpZGF0ZS5sZW5ndGggPT09IG92ZXJsYXBHcm91cC5sZW5ndGgpIHtcclxuICAgICAgLy8gQWxsIGV2ZW50cyBpbiBvdmVybGFwIGdyb3VwIGFyZSBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpbiBcdTIxOTIgR1JJRCBtb2RlXHJcbiAgICAgIGNvbnN0IGNvbHVtbnMgPSBhbGxvY2F0ZUNvbHVtbnMob3ZlcmxhcEdyb3VwKTtcclxuICAgICAgY29uc3QgZWFybGllc3QgPSBvdmVybGFwR3JvdXAucmVkdWNlKChtaW4sIGUpID0+XHJcbiAgICAgICAgZS5zdGFydCA8IG1pbi5zdGFydCA/IGUgOiBtaW4sIG92ZXJsYXBHcm91cFswXSk7XHJcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihlYXJsaWVzdC5zdGFydCwgZWFybGllc3QuZW5kLCBjb25maWcpO1xyXG5cclxuICAgICAgcmVzdWx0LmdyaWRzLnB1c2goe1xyXG4gICAgICAgIGV2ZW50czogb3ZlcmxhcEdyb3VwLFxyXG4gICAgICAgIGNvbHVtbnMsXHJcbiAgICAgICAgc3RhY2tMZXZlbDogMCxcclxuICAgICAgICBwb3NpdGlvbjogeyB0b3A6IHBvc2l0aW9uLnRvcCB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gTm90IGFsbCBldmVudHMgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgXHUyMTkyIFNUQUNLSU5HIG1vZGVcclxuICAgICAgY29uc3QgbGV2ZWxzID0gY2FsY3VsYXRlU3RhY2tMZXZlbHMob3ZlcmxhcEdyb3VwKTtcclxuICAgICAgZm9yIChjb25zdCBldmVudCBvZiBvdmVybGFwR3JvdXApIHtcclxuICAgICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcclxuICAgICAgICAgIGV2ZW50LFxyXG4gICAgICAgICAgc3RhY2tMZXZlbDogbGV2ZWxzLmdldChldmVudC5pZCkgPz8gMFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbiIsICJpbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCwgSUV2ZW50QnVzLCBJRXZlbnRVcGRhdGVkUGF5bG9hZCB9IGZyb20gJy4uLy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBFdmVudFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9yYWdlL2V2ZW50cy9FdmVudFNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEYXRlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvRGF0ZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJR3JpZENvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvSUdyaWRDb25maWcnO1xyXG5pbXBvcnQgeyBjYWxjdWxhdGVFdmVudFBvc2l0aW9uLCBzbmFwVG9HcmlkLCBwaXhlbHNUb01pbnV0ZXMgfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcclxuaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcclxuaW1wb3J0IHsgSURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkLCBJRHJhZ01vdmVQYXlsb2FkLCBJRHJhZ0VuZFBheWxvYWQsIElEcmFnTGVhdmVIZWFkZXJQYXlsb2FkIH0gZnJvbSAnLi4vLi4vdHlwZXMvRHJhZ1R5cGVzJztcclxuaW1wb3J0IHsgY2FsY3VsYXRlQ29sdW1uTGF5b3V0IH0gZnJvbSAnLi9FdmVudExheW91dEVuZ2luZSc7XHJcbmltcG9ydCB7IElHcmlkR3JvdXBMYXlvdXQgfSBmcm9tICcuL0V2ZW50TGF5b3V0VHlwZXMnO1xyXG5pbXBvcnQgeyBGaWx0ZXJUZW1wbGF0ZSB9IGZyb20gJy4uLy4uL2NvcmUvRmlsdGVyVGVtcGxhdGUnO1xyXG5cclxuLyoqXHJcbiAqIEV2ZW50UmVuZGVyZXIgLSBSZW5kZXJzIGNhbGVuZGFyIGV2ZW50cyB0byB0aGUgRE9NXHJcbiAqXHJcbiAqIENMRUFOIGFwcHJvYWNoOlxyXG4gKiAtIE9ubHkgZGF0YS1pZCBhdHRyaWJ1dGUgb24gZXZlbnQgZWxlbWVudFxyXG4gKiAtIGlubmVySFRNTCBjb250YWlucyBvbmx5IHZpc2libGUgY29udGVudFxyXG4gKiAtIEV2ZW50IGRhdGEgcmV0cmlldmVkIHZpYSBFdmVudFNlcnZpY2Ugd2hlbiBuZWVkZWRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBFdmVudFJlbmRlcmVyIHtcclxuICBwcml2YXRlIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGV2ZW50U2VydmljZTogRXZlbnRTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBkYXRlU2VydmljZTogRGF0ZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGdyaWRDb25maWc6IElHcmlkQ29uZmlnLFxyXG4gICAgcHJpdmF0ZSBldmVudEJ1czogSUV2ZW50QnVzXHJcbiAgKSB7XHJcbiAgICB0aGlzLnNldHVwTGlzdGVuZXJzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXR1cCBsaXN0ZW5lcnMgZm9yIGRyYWctZHJvcCBhbmQgdXBkYXRlIGV2ZW50c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgc2V0dXBMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFLCAoZSkgPT4ge1xyXG4gICAgICBjb25zdCBwYXlsb2FkID0gKGUgYXMgQ3VzdG9tRXZlbnQ8SURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLmhhbmRsZUNvbHVtbkNoYW5nZShwYXlsb2FkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkUsIChlKSA9PiB7XHJcbiAgICAgIGNvbnN0IHBheWxvYWQgPSAoZSBhcyBDdXN0b21FdmVudDxJRHJhZ01vdmVQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLnVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfVVBEQVRFRCwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElFdmVudFVwZGF0ZWRQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLmhhbmRsZUV2ZW50VXBkYXRlZChwYXlsb2FkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElEcmFnRW5kUGF5bG9hZD4pLmRldGFpbDtcclxuICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kKHBheWxvYWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfTEVBVkVfSEVBREVSLCAoZSkgPT4ge1xyXG4gICAgICBjb25zdCBwYXlsb2FkID0gKGUgYXMgQ3VzdG9tRXZlbnQ8SURyYWdMZWF2ZUhlYWRlclBheWxvYWQ+KS5kZXRhaWw7XHJcbiAgICAgIHRoaXMuaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgRVZFTlRfRFJBR19FTkQgLSByZW1vdmUgZWxlbWVudCBpZiBkcm9wcGVkIGluIGhlYWRlclxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ0VuZChwYXlsb2FkOiBJRHJhZ0VuZFBheWxvYWQpOiB2b2lkIHtcclxuICAgIGlmIChwYXlsb2FkLnRhcmdldCA9PT0gJ2hlYWRlcicpIHtcclxuICAgICAgLy8gRXZlbnQgd2FzIGRyb3BwZWQgaW4gaGVhZGVyIGRyYXdlciAtIHJlbW92ZSBmcm9tIGdyaWRcclxuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY29udGFpbmVyPy5xdWVyeVNlbGVjdG9yKGBzd3AtY29udGVudC12aWV3cG9ydCBzd3AtZXZlbnRbZGF0YS1ldmVudC1pZD1cIiR7cGF5bG9hZC5zd3BFdmVudC5ldmVudElkfVwiXWApO1xyXG4gICAgICBlbGVtZW50Py5yZW1vdmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBoZWFkZXIgaXRlbSBsZWF2aW5nIGhlYWRlciAtIGNyZWF0ZSBzd3AtZXZlbnQgaW4gZ3JpZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQ6IElEcmFnTGVhdmVIZWFkZXJQYXlsb2FkKTogdm9pZCB7XHJcbiAgICAvLyBPbmx5IGhhbmRsZSB3aGVuIHNvdXJjZSBpcyBoZWFkZXIgKGhlYWRlciBpdGVtIGRyYWdnZWQgdG8gZ3JpZClcclxuICAgIGlmIChwYXlsb2FkLnNvdXJjZSAhPT0gJ2hlYWRlcicpIHJldHVybjtcclxuICAgIGlmICghcGF5bG9hZC50YXJnZXRDb2x1bW4gfHwgIXBheWxvYWQuc3RhcnQgfHwgIXBheWxvYWQuZW5kKSByZXR1cm47XHJcblxyXG4gICAgLy8gVHVybiBoZWFkZXIgaXRlbSBpbnRvIGdob3N0IChzdGF5cyB2aXNpYmxlIGJ1dCBmYWRlZClcclxuICAgIGlmIChwYXlsb2FkLmVsZW1lbnQpIHtcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RyYWctZ2hvc3QnKTtcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAnMC4zJztcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ3JlYXRlIGV2ZW50IG9iamVjdCBmcm9tIGhlYWRlciBpdGVtIGRhdGFcclxuICAgIGNvbnN0IGV2ZW50OiBJQ2FsZW5kYXJFdmVudCA9IHtcclxuICAgICAgaWQ6IHBheWxvYWQuZXZlbnRJZCxcclxuICAgICAgdGl0bGU6IHBheWxvYWQudGl0bGUgfHwgJycsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiAnJyxcclxuICAgICAgc3RhcnQ6IHBheWxvYWQuc3RhcnQsXHJcbiAgICAgIGVuZDogcGF5bG9hZC5lbmQsXHJcbiAgICAgIHR5cGU6ICdjdXN0b21lcicsXHJcbiAgICAgIGFsbERheTogZmFsc2UsXHJcbiAgICAgIHN5bmNTdGF0dXM6ICdwZW5kaW5nJ1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBDcmVhdGUgc3dwLWV2ZW50IGVsZW1lbnQgdXNpbmcgZXhpc3RpbmcgbWV0aG9kXHJcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5jcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpO1xyXG5cclxuICAgIC8vIEFkZCB0byB0YXJnZXQgY29sdW1uXHJcbiAgICBsZXQgZXZlbnRzTGF5ZXIgPSBwYXlsb2FkLnRhcmdldENvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICBpZiAoIWV2ZW50c0xheWVyKSB7XHJcbiAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xyXG4gICAgICBwYXlsb2FkLnRhcmdldENvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XHJcbiAgICB9XHJcbiAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChlbGVtZW50KTtcclxuXHJcbiAgICAvLyBNYXJrIGFzIGRyYWdnaW5nIHNvIERyYWdEcm9wTWFuYWdlciBjYW4gY29udGludWUgd2l0aCBpdFxyXG4gICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEVWRU5UX1VQREFURUQgLSByZS1yZW5kZXIgYWZmZWN0ZWQgY29sdW1uc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRXZlbnRVcGRhdGVkKHBheWxvYWQ6IElFdmVudFVwZGF0ZWRQYXlsb2FkKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBSZS1yZW5kZXIgc291cmNlIGNvbHVtbiAoaWYgZGlmZmVyZW50IGZyb20gdGFyZ2V0KVxyXG4gICAgaWYgKHBheWxvYWQuc291cmNlQ29sdW1uS2V5ICE9PSBwYXlsb2FkLnRhcmdldENvbHVtbktleSkge1xyXG4gICAgICBhd2FpdCB0aGlzLnJlcmVuZGVyQ29sdW1uKHBheWxvYWQuc291cmNlQ29sdW1uS2V5KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZS1yZW5kZXIgdGFyZ2V0IGNvbHVtblxyXG4gICAgYXdhaXQgdGhpcy5yZXJlbmRlckNvbHVtbihwYXlsb2FkLnRhcmdldENvbHVtbktleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZS1yZW5kZXIgYSBzaW5nbGUgY29sdW1uIHdpdGggZnJlc2ggZGF0YSBmcm9tIEluZGV4ZWREQlxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVyZW5kZXJDb2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xyXG4gICAgaWYgKCFjb2x1bW4pIHJldHVybjtcclxuXHJcbiAgICAvLyBSZWFkIGRhdGUgYW5kIHJlc291cmNlSWQgZGlyZWN0bHkgZnJvbSBjb2x1bW4gYXR0cmlidXRlcyAoY29sdW1uS2V5IGlzIG9wYXF1ZSlcclxuICAgIGNvbnN0IGRhdGUgPSBjb2x1bW4uZGF0YXNldC5kYXRlO1xyXG4gICAgY29uc3QgcmVzb3VyY2VJZCA9IGNvbHVtbi5kYXRhc2V0LnJlc291cmNlSWQ7XHJcblxyXG4gICAgaWYgKCFkYXRlKSByZXR1cm47XHJcblxyXG4gICAgLy8gR2V0IGRhdGUgcmFuZ2UgZm9yIHRoaXMgZGF5XHJcbiAgICBjb25zdCBzdGFydERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcclxuICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcclxuICAgIGVuZERhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KTtcclxuXHJcbiAgICAvLyBGZXRjaCBldmVudHMgZnJvbSBJbmRleGVkREJcclxuICAgIGNvbnN0IGV2ZW50cyA9IHJlc291cmNlSWRcclxuICAgICAgPyBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeVJlc291cmNlQW5kRGF0ZVJhbmdlKHJlc291cmNlSWQsIHN0YXJ0RGF0ZSwgZW5kRGF0ZSlcclxuICAgICAgOiBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xyXG5cclxuICAgIC8vIEZpbHRlciB0byB0aW1lZCBldmVudHMgYW5kIG1hdGNoIGRhdGUgZXhhY3RseVxyXG4gICAgY29uc3QgdGltZWRFdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+XHJcbiAgICAgICFldmVudC5hbGxEYXkgJiYgdGhpcy5kYXRlU2VydmljZS5nZXREYXRlS2V5KGV2ZW50LnN0YXJ0KSA9PT0gZGF0ZVxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBHZXQgb3IgY3JlYXRlIGV2ZW50cyBsYXllclxyXG4gICAgbGV0IGV2ZW50c0xheWVyID0gY29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcclxuICAgICAgZXZlbnRzTGF5ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICAgIGNvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2xlYXIgZXhpc3RpbmcgZXZlbnRzXHJcbiAgICBldmVudHNMYXllci5pbm5lckhUTUwgPSAnJztcclxuXHJcbiAgICAvLyBDYWxjdWxhdGUgbGF5b3V0IHdpdGggc3RhY2tpbmcvZ3JvdXBpbmdcclxuICAgIGNvbnN0IGxheW91dCA9IGNhbGN1bGF0ZUNvbHVtbkxheW91dCh0aW1lZEV2ZW50cywgdGhpcy5ncmlkQ29uZmlnKTtcclxuXHJcbiAgICAvLyBSZW5kZXIgR1JJRCBncm91cHNcclxuICAgIGxheW91dC5ncmlkcy5mb3JFYWNoKGdyaWQgPT4ge1xyXG4gICAgICBjb25zdCBncm91cEVsID0gdGhpcy5yZW5kZXJHcmlkR3JvdXAoZ3JpZCk7XHJcbiAgICAgIGV2ZW50c0xheWVyIS5hcHBlbmRDaGlsZChncm91cEVsKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIFJlbmRlciBTVEFDS0VEIGV2ZW50c1xyXG4gICAgbGF5b3V0LnN0YWNrZWQuZm9yRWFjaChpdGVtID0+IHtcclxuICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XHJcbiAgICAgIGV2ZW50c0xheWVyIS5hcHBlbmRDaGlsZChldmVudEVsKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRmluZCBhIGNvbHVtbiBlbGVtZW50IGJ5IGNvbHVtbktleVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZmluZENvbHVtbihjb2x1bW5LZXk6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyKSByZXR1cm4gbnVsbDtcclxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGBzd3AtZGF5LWNvbHVtbltkYXRhLWNvbHVtbi1rZXk9XCIke2NvbHVtbktleX1cIl1gKSBhcyBIVE1MRWxlbWVudDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBldmVudCBtb3ZpbmcgdG8gYSBuZXcgY29sdW1uIGR1cmluZyBkcmFnXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBoYW5kbGVDb2x1bW5DaGFuZ2UocGF5bG9hZDogSURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkKTogdm9pZCB7XHJcbiAgICBjb25zdCBldmVudHNMYXllciA9IHBheWxvYWQubmV3Q29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgIGlmICghZXZlbnRzTGF5ZXIpIHJldHVybjtcclxuXHJcbiAgICAvLyBNb3ZlIGVsZW1lbnQgdG8gbmV3IGNvbHVtblxyXG4gICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQocGF5bG9hZC5lbGVtZW50KTtcclxuXHJcbiAgICAvLyBQcmVzZXJ2ZSBZIHBvc2l0aW9uXHJcbiAgICBwYXlsb2FkLmVsZW1lbnQuc3R5bGUudG9wID0gYCR7cGF5bG9hZC5jdXJyZW50WX1weGA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgdGltZXN0YW1wIGRpc3BsYXkgZHVyaW5nIGRyYWcgKHNuYXBwZWQgdG8gZ3JpZClcclxuICAgKi9cclxuICBwcml2YXRlIHVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZDogSURyYWdNb3ZlUGF5bG9hZCk6IHZvaWQge1xyXG4gICAgY29uc3QgdGltZUVsID0gcGF5bG9hZC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudC10aW1lJyk7XHJcbiAgICBpZiAoIXRpbWVFbCkgcmV0dXJuO1xyXG5cclxuICAgIC8vIFNuYXAgcG9zaXRpb24gdG8gZ3JpZCBpbnRlcnZhbFxyXG4gICAgY29uc3Qgc25hcHBlZFkgPSBzbmFwVG9HcmlkKHBheWxvYWQuY3VycmVudFksIHRoaXMuZ3JpZENvbmZpZyk7XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGFydCB0aW1lXHJcbiAgICBjb25zdCBtaW51dGVzRnJvbUdyaWRTdGFydCA9IHBpeGVsc1RvTWludXRlcyhzbmFwcGVkWSwgdGhpcy5ncmlkQ29uZmlnKTtcclxuICAgIGNvbnN0IHN0YXJ0TWludXRlcyA9ICh0aGlzLmdyaWRDb25maWcuZGF5U3RhcnRIb3VyICogNjApICsgbWludXRlc0Zyb21HcmlkU3RhcnQ7XHJcblxyXG4gICAgLy8gS2VlcCBvcmlnaW5hbCBkdXJhdGlvbiAoZnJvbSBlbGVtZW50IGhlaWdodClcclxuICAgIGNvbnN0IGhlaWdodCA9IHBhcnNlRmxvYXQocGF5bG9hZC5lbGVtZW50LnN0eWxlLmhlaWdodCkgfHwgdGhpcy5ncmlkQ29uZmlnLmhvdXJIZWlnaHQ7XHJcbiAgICBjb25zdCBkdXJhdGlvbk1pbnV0ZXMgPSBwaXhlbHNUb01pbnV0ZXMoaGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBEYXRlIG9iamVjdHMgZm9yIGNvbnNpc3RlbnQgZm9ybWF0dGluZyB2aWEgRGF0ZVNlcnZpY2VcclxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyk7XHJcbiAgICBjb25zdCBlbmQgPSB0aGlzLm1pbnV0ZXNUb0RhdGUoc3RhcnRNaW51dGVzICsgZHVyYXRpb25NaW51dGVzKTtcclxuXHJcbiAgICB0aW1lRWwudGV4dENvbnRlbnQgPSB0aGlzLmRhdGVTZXJ2aWNlLmZvcm1hdFRpbWVSYW5nZShzdGFydCwgZW5kKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnZlcnQgbWludXRlcyBzaW5jZSBtaWRuaWdodCB0byBhIERhdGUgb2JqZWN0ICh0b2RheSlcclxuICAgKi9cclxuICBwcml2YXRlIG1pbnV0ZXNUb0RhdGUobWludXRlczogbnVtYmVyKTogRGF0ZSB7XHJcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcclxuICAgIGRhdGUuc2V0SG91cnMoTWF0aC5mbG9vcihtaW51dGVzIC8gNjApICUgMjQsIG1pbnV0ZXMgJSA2MCwgMCwgMCk7XHJcbiAgICByZXR1cm4gZGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbmRlciBldmVudHMgZm9yIHZpc2libGUgZGF0ZXMgaW50byBkYXkgY29sdW1uc1xyXG4gICAqIEBwYXJhbSBjb250YWluZXIgLSBDYWxlbmRhciBjb250YWluZXIgZWxlbWVudFxyXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgd2l0aCAnZGF0ZScgYW5kIG9wdGlvbmFsbHkgJ3Jlc291cmNlJyBhcnJheXNcclxuICAgKiBAcGFyYW0gZmlsdGVyVGVtcGxhdGUgLSBUZW1wbGF0ZSBmb3IgbWF0Y2hpbmcgZXZlbnRzIHRvIGNvbHVtbnNcclxuICAgKi9cclxuICBhc3luYyByZW5kZXIoY29udGFpbmVyOiBIVE1MRWxlbWVudCwgZmlsdGVyOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4sIGZpbHRlclRlbXBsYXRlOiBGaWx0ZXJUZW1wbGF0ZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gU3RvcmUgY29udGFpbmVyIHJlZmVyZW5jZSBmb3IgbGF0ZXIgcmUtcmVuZGVyc1xyXG4gICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XHJcblxyXG4gICAgY29uc3QgdmlzaWJsZURhdGVzID0gZmlsdGVyWydkYXRlJ10gfHwgW107XHJcblxyXG4gICAgaWYgKHZpc2libGVEYXRlcy5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICAvLyBHZXQgZGF0ZSByYW5nZSBmb3IgcXVlcnlcclxuICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1swXSk7XHJcbiAgICBjb25zdCBlbmREYXRlID0gbmV3IERhdGUodmlzaWJsZURhdGVzW3Zpc2libGVEYXRlcy5sZW5ndGggLSAxXSk7XHJcbiAgICBlbmREYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XHJcblxyXG4gICAgLy8gRmV0Y2ggZXZlbnRzIGZyb20gSW5kZXhlZERCXHJcbiAgICBjb25zdCBldmVudHMgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xyXG5cclxuICAgIC8vIEZpbmQgZGF5IGNvbHVtbnNcclxuICAgIGNvbnN0IGRheUNvbHVtbnMgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWRheS1jb2x1bW5zJyk7XHJcbiAgICBpZiAoIWRheUNvbHVtbnMpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBjb2x1bW5zID0gZGF5Q29sdW1ucy5xdWVyeVNlbGVjdG9yQWxsKCdzd3AtZGF5LWNvbHVtbicpO1xyXG5cclxuICAgIC8vIFJlbmRlciBldmVudHMgaW50byBlYWNoIGNvbHVtbiBiYXNlZCBvbiBGaWx0ZXJUZW1wbGF0ZSBtYXRjaGluZ1xyXG4gICAgY29sdW1ucy5mb3JFYWNoKGNvbHVtbiA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbHVtbkVsID0gY29sdW1uIGFzIEhUTUxFbGVtZW50O1xyXG5cclxuICAgICAgLy8gVXNlIEZpbHRlclRlbXBsYXRlIGZvciBtYXRjaGluZyAtIG9ubHkgZmllbGRzIGluIHRlbXBsYXRlIGFyZSBjaGVja2VkXHJcbiAgICAgIGNvbnN0IGNvbHVtbkV2ZW50cyA9IGV2ZW50cy5maWx0ZXIoZXZlbnQgPT4gZmlsdGVyVGVtcGxhdGUubWF0Y2hlcyhldmVudCwgY29sdW1uRWwpKTtcclxuXHJcbiAgICAgIC8vIEdldCBvciBjcmVhdGUgZXZlbnRzIGxheWVyXHJcbiAgICAgIGxldCBldmVudHNMYXllciA9IGNvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcclxuICAgICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgICAgICBjb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDbGVhciBleGlzdGluZyBldmVudHNcclxuICAgICAgZXZlbnRzTGF5ZXIuaW5uZXJIVE1MID0gJyc7XHJcblxyXG4gICAgICAvLyBGaWx0ZXIgdG8gdGltZWQgZXZlbnRzIG9ubHlcclxuICAgICAgY29uc3QgdGltZWRFdmVudHMgPSBjb2x1bW5FdmVudHMuZmlsdGVyKGV2ZW50ID0+ICFldmVudC5hbGxEYXkpO1xyXG5cclxuICAgICAgLy8gQ2FsY3VsYXRlIGxheW91dCB3aXRoIHN0YWNraW5nL2dyb3VwaW5nXHJcbiAgICAgIGNvbnN0IGxheW91dCA9IGNhbGN1bGF0ZUNvbHVtbkxheW91dCh0aW1lZEV2ZW50cywgdGhpcy5ncmlkQ29uZmlnKTtcclxuXHJcbiAgICAgIC8vIFJlbmRlciBHUklEIGdyb3VwcyAoc2ltdWx0YW5lb3VzIGV2ZW50cyBzaWRlLWJ5LXNpZGUpXHJcbiAgICAgIGxheW91dC5ncmlkcy5mb3JFYWNoKGdyaWQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwRWwgPSB0aGlzLnJlbmRlckdyaWRHcm91cChncmlkKTtcclxuICAgICAgICBldmVudHNMYXllciEuYXBwZW5kQ2hpbGQoZ3JvdXBFbCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gUmVuZGVyIFNUQUNLRUQgZXZlbnRzIChvdmVybGFwcGluZyB3aXRoIG1hcmdpbiBvZmZzZXQpXHJcbiAgICAgIGxheW91dC5zdGFja2VkLmZvckVhY2goaXRlbSA9PiB7XHJcbiAgICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XHJcbiAgICAgICAgZXZlbnRzTGF5ZXIhLmFwcGVuZENoaWxkKGV2ZW50RWwpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGEgc2luZ2xlIGV2ZW50IGVsZW1lbnRcclxuICAgKlxyXG4gICAqIENMRUFOIGFwcHJvYWNoOlxyXG4gICAqIC0gT25seSBkYXRhLWlkIGZvciBsb29rdXBcclxuICAgKiAtIFZpc2libGUgY29udGVudCBpbiBpbm5lckhUTUwgb25seVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50OiBJQ2FsZW5kYXJFdmVudCk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnQnKTtcclxuXHJcbiAgICAvLyBEYXRhIGF0dHJpYnV0ZXMgZm9yIFN3cEV2ZW50IGNvbXBhdGliaWxpdHlcclxuICAgIGVsZW1lbnQuZGF0YXNldC5ldmVudElkID0gZXZlbnQuaWQ7XHJcbiAgICBpZiAoZXZlbnQucmVzb3VyY2VJZCkge1xyXG4gICAgICBlbGVtZW50LmRhdGFzZXQucmVzb3VyY2VJZCA9IGV2ZW50LnJlc291cmNlSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIHBvc2l0aW9uXHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcclxuICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cG9zaXRpb24udG9wfXB4YDtcclxuICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cG9zaXRpb24uaGVpZ2h0fXB4YDtcclxuXHJcbiAgICAvLyBDb2xvciBjbGFzcyBiYXNlZCBvbiBldmVudCB0eXBlXHJcbiAgICBjb25zdCBjb2xvckNsYXNzID0gdGhpcy5nZXRDb2xvckNsYXNzKGV2ZW50KTtcclxuICAgIGlmIChjb2xvckNsYXNzKSB7XHJcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjb2xvckNsYXNzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBWaXNpYmxlIGNvbnRlbnQgb25seVxyXG4gICAgZWxlbWVudC5pbm5lckhUTUwgPSBgXHJcbiAgICAgIDxzd3AtZXZlbnQtdGltZT4ke3RoaXMuZGF0ZVNlcnZpY2UuZm9ybWF0VGltZVJhbmdlKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQpfTwvc3dwLWV2ZW50LXRpbWU+XHJcbiAgICAgIDxzd3AtZXZlbnQtdGl0bGU+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQudGl0bGUpfTwvc3dwLWV2ZW50LXRpdGxlPlxyXG4gICAgICAke2V2ZW50LmRlc2NyaXB0aW9uID8gYDxzd3AtZXZlbnQtZGVzY3JpcHRpb24+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQuZGVzY3JpcHRpb24pfTwvc3dwLWV2ZW50LWRlc2NyaXB0aW9uPmAgOiAnJ31cclxuICAgIGA7XHJcblxyXG4gICAgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgY29sb3IgY2xhc3MgYmFzZWQgb24gbWV0YWRhdGEuY29sb3Igb3IgZXZlbnQgdHlwZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0Q29sb3JDbGFzcyhldmVudDogSUNhbGVuZGFyRXZlbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gQ2hlY2sgbWV0YWRhdGEuY29sb3IgZmlyc3RcclxuICAgIGlmIChldmVudC5tZXRhZGF0YT8uY29sb3IpIHtcclxuICAgICAgcmV0dXJuIGBpcy0ke2V2ZW50Lm1ldGFkYXRhLmNvbG9yfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRmFsbGJhY2sgdG8gdHlwZS1iYXNlZCBjb2xvclxyXG4gICAgY29uc3QgdHlwZUNvbG9yczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcclxuICAgICAgJ2N1c3RvbWVyJzogJ2lzLWJsdWUnLFxyXG4gICAgICAndmFjYXRpb24nOiAnaXMtZ3JlZW4nLFxyXG4gICAgICAnYnJlYWsnOiAnaXMtYW1iZXInLFxyXG4gICAgICAnbWVldGluZyc6ICdpcy1wdXJwbGUnLFxyXG4gICAgICAnYmxvY2tlZCc6ICdpcy1yZWQnXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHR5cGVDb2xvcnNbZXZlbnQudHlwZV0gfHwgJ2lzLWJsdWUnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXNjYXBlIEhUTUwgdG8gcHJldmVudCBYU1NcclxuICAgKi9cclxuICBwcml2YXRlIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgZGl2LnRleHRDb250ZW50ID0gdGV4dDtcclxuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVuZGVyIGEgR1JJRCBncm91cCB3aXRoIHNpZGUtYnktc2lkZSBjb2x1bW5zXHJcbiAgICogVXNlZCB3aGVuIG11bHRpcGxlIGV2ZW50cyBzdGFydCBhdCB0aGUgc2FtZSB0aW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZW5kZXJHcmlkR3JvdXAobGF5b3V0OiBJR3JpZEdyb3VwTGF5b3V0KTogSFRNTEVsZW1lbnQge1xyXG4gICAgY29uc3QgZ3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnQtZ3JvdXAnKTtcclxuICAgIGdyb3VwLmNsYXNzTGlzdC5hZGQoYGNvbHMtJHtsYXlvdXQuY29sdW1ucy5sZW5ndGh9YCk7XHJcbiAgICBncm91cC5zdHlsZS50b3AgPSBgJHtsYXlvdXQucG9zaXRpb24udG9wfXB4YDtcclxuXHJcbiAgICAvLyBTdGFjayBsZXZlbCBzdHlsaW5nIGZvciBlbnRpcmUgZ3JvdXAgKGlmIG5lc3RlZCBpbiBhbm90aGVyIGV2ZW50KVxyXG4gICAgaWYgKGxheW91dC5zdGFja0xldmVsID4gMCkge1xyXG4gICAgICBncm91cC5zdHlsZS5tYXJnaW5MZWZ0ID0gYCR7bGF5b3V0LnN0YWNrTGV2ZWwgKiAxNX1weGA7XHJcbiAgICAgIGdyb3VwLnN0eWxlLnpJbmRleCA9IGAkezEwMCArIGxheW91dC5zdGFja0xldmVsfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBoZWlnaHQgbmVlZGVkIGZvciB0aGUgZ3JvdXAgKHRhbGxlc3QgZXZlbnQpXHJcbiAgICBsZXQgbWF4Qm90dG9tID0gMDtcclxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgbGF5b3V0LmV2ZW50cykge1xyXG4gICAgICBjb25zdCBwb3MgPSBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQsIHRoaXMuZ3JpZENvbmZpZyk7XHJcbiAgICAgIGNvbnN0IGV2ZW50Qm90dG9tID0gcG9zLnRvcCArIHBvcy5oZWlnaHQ7XHJcbiAgICAgIGlmIChldmVudEJvdHRvbSA+IG1heEJvdHRvbSkgbWF4Qm90dG9tID0gZXZlbnRCb3R0b207XHJcbiAgICB9XHJcbiAgICBjb25zdCBncm91cEhlaWdodCA9IG1heEJvdHRvbSAtIGxheW91dC5wb3NpdGlvbi50b3A7XHJcbiAgICBncm91cC5zdHlsZS5oZWlnaHQgPSBgJHtncm91cEhlaWdodH1weGA7XHJcblxyXG4gICAgLy8gQ3JlYXRlIHdyYXBwZXIgZGl2IGZvciBlYWNoIGNvbHVtblxyXG4gICAgbGF5b3V0LmNvbHVtbnMuZm9yRWFjaChjb2x1bW5FdmVudHMgPT4ge1xyXG4gICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgIHdyYXBwZXIuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xyXG5cclxuICAgICAgY29sdW1uRXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50RWwgPSB0aGlzLmNyZWF0ZUV2ZW50RWxlbWVudChldmVudCk7XHJcbiAgICAgICAgLy8gUG9zaXRpb24gcmVsYXRpdmUgdG8gZ3JvdXAgdG9wXHJcbiAgICAgICAgY29uc3QgcG9zID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihldmVudC5zdGFydCwgZXZlbnQuZW5kLCB0aGlzLmdyaWRDb25maWcpO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUudG9wID0gYCR7cG9zLnRvcCAtIGxheW91dC5wb3NpdGlvbi50b3B9cHhgO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUubGVmdCA9ICcwJztcclxuICAgICAgICBldmVudEVsLnN0eWxlLnJpZ2h0ID0gJzAnO1xyXG4gICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZXZlbnRFbCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgZ3JvdXAuYXBwZW5kQ2hpbGQod3JhcHBlcik7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gZ3JvdXA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW5kZXIgYSBTVEFDS0VEIGV2ZW50IHdpdGggbWFyZ2luLWxlZnQgb2Zmc2V0XHJcbiAgICogVXNlZCBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzIHRoYXQgZG9uJ3Qgc3RhcnQgYXQgdGhlIHNhbWUgdGltZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVuZGVyU3RhY2tlZEV2ZW50KGV2ZW50OiBJQ2FsZW5kYXJFdmVudCwgc3RhY2tMZXZlbDogbnVtYmVyKTogSFRNTEVsZW1lbnQge1xyXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcclxuXHJcbiAgICAvLyBBZGQgc3RhY2sgbWV0YWRhdGEgZm9yIGRyYWctZHJvcCBhbmQgb3RoZXIgZmVhdHVyZXNcclxuICAgIGVsZW1lbnQuZGF0YXNldC5zdGFja0xpbmsgPSBKU09OLnN0cmluZ2lmeSh7IHN0YWNrTGV2ZWwgfSk7XHJcblxyXG4gICAgLy8gVmlzdWFsIHN0eWxpbmcgYmFzZWQgb24gc3RhY2sgbGV2ZWxcclxuICAgIGlmIChzdGFja0xldmVsID4gMCkge1xyXG4gICAgICBlbGVtZW50LnN0eWxlLm1hcmdpbkxlZnQgPSBgJHtzdGFja0xldmVsICogMTV9cHhgO1xyXG4gICAgICBlbGVtZW50LnN0eWxlLnpJbmRleCA9IGAkezEwMCArIHN0YWNrTGV2ZWx9YDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZWxlbWVudDtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuL0lHcm91cGluZ1JlbmRlcmVyJztcclxuXHJcbi8qKlxyXG4gKiBFbnRpdHkgbXVzdCBoYXZlIGlkXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHcm91cGluZ0VudGl0eSB7XHJcbiAgaWQ6IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGEgZ3JvdXBpbmcgcmVuZGVyZXJcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdyb3VwaW5nUmVuZGVyZXJDb25maWcge1xyXG4gIGVsZW1lbnRUYWc6IHN0cmluZzsgICAgICAvLyBlLmcuLCAnc3dwLXRlYW0taGVhZGVyJ1xyXG4gIGlkQXR0cmlidXRlOiBzdHJpbmc7ICAgICAvLyBlLmcuLCAndGVhbUlkJyAtPiBkYXRhLXRlYW0taWRcclxuICBjb2xzcGFuVmFyOiBzdHJpbmc7ICAgICAgLy8gZS5nLiwgJy0tdGVhbS1jb2xzJ1xyXG59XHJcblxyXG4vKipcclxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZ3JvdXBpbmcgcmVuZGVyZXJzXHJcbiAqXHJcbiAqIEhhbmRsZXM6XHJcbiAqIC0gRmV0Y2hpbmcgZW50aXRpZXMgYnkgSURzXHJcbiAqIC0gQ2FsY3VsYXRpbmcgY29sc3BhbiBmcm9tIHBhcmVudENoaWxkTWFwXHJcbiAqIC0gQ3JlYXRpbmcgaGVhZGVyIGVsZW1lbnRzXHJcbiAqIC0gQXBwZW5kaW5nIHRvIGNvbnRhaW5lclxyXG4gKlxyXG4gKiBTdWJjbGFzc2VzIG92ZXJyaWRlOlxyXG4gKiAtIHJlbmRlckhlYWRlcigpIGZvciBjdXN0b20gY29udGVudFxyXG4gKiAtIGdldERpc3BsYXlOYW1lKCkgZm9yIGVudGl0eSBkaXNwbGF5IHRleHRcclxuICovXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlR3JvdXBpbmdSZW5kZXJlcjxUIGV4dGVuZHMgSUdyb3VwaW5nRW50aXR5PiBpbXBsZW1lbnRzIElSZW5kZXJlciB7XHJcbiAgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSBjb25maWc6IElHcm91cGluZ1JlbmRlcmVyQ29uZmlnO1xyXG5cclxuICAvKipcclxuICAgKiBGZXRjaCBlbnRpdGllcyBmcm9tIHNlcnZpY2VcclxuICAgKi9cclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0RW50aXRpZXMoaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8VFtdPjtcclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGRpc3BsYXkgbmFtZSBmb3IgZW50aXR5XHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldERpc3BsYXlOYW1lKGVudGl0eTogVCk6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogTWFpbiByZW5kZXIgbWV0aG9kIC0gaGFuZGxlcyBjb21tb24gbG9naWNcclxuICAgKi9cclxuICBhc3luYyByZW5kZXIoY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGFsbG93ZWRJZHMgPSBjb250ZXh0LmZpbHRlclt0aGlzLnR5cGVdIHx8IFtdO1xyXG4gICAgaWYgKGFsbG93ZWRJZHMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKGFsbG93ZWRJZHMpO1xyXG4gICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XHJcbiAgICBjb25zdCBjaGlsZElkcyA9IGNvbnRleHQuY2hpbGRUeXBlID8gY29udGV4dC5maWx0ZXJbY29udGV4dC5jaGlsZFR5cGVdIHx8IFtdIDogW107XHJcblxyXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcclxuICAgICAgY29uc3QgZW50aXR5Q2hpbGRJZHMgPSBjb250ZXh0LnBhcmVudENoaWxkTWFwPy5bZW50aXR5LmlkXSB8fCBbXTtcclxuICAgICAgY29uc3QgY2hpbGRDb3VudCA9IGVudGl0eUNoaWxkSWRzLmZpbHRlcihpZCA9PiBjaGlsZElkcy5pbmNsdWRlcyhpZCkpLmxlbmd0aDtcclxuICAgICAgY29uc3QgY29sc3BhbiA9IGNoaWxkQ291bnQgKiBkYXRlQ291bnQ7XHJcblxyXG4gICAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xyXG4gICAgICBoZWFkZXIuZGF0YXNldFt0aGlzLmNvbmZpZy5pZEF0dHJpYnV0ZV0gPSBlbnRpdHkuaWQ7XHJcbiAgICAgIGhlYWRlci5zdHlsZS5zZXRQcm9wZXJ0eSh0aGlzLmNvbmZpZy5jb2xzcGFuVmFyLCBTdHJpbmcoY29sc3BhbikpO1xyXG5cclxuICAgICAgLy8gQWxsb3cgc3ViY2xhc3MgdG8gY3VzdG9taXplIGhlYWRlciBjb250ZW50XHJcbiAgICAgIHRoaXMucmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBjb250ZXh0KTtcclxuXHJcbiAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgY3VzdG9tIGhlYWRlciByZW5kZXJpbmdcclxuICAgKiBEZWZhdWx0OiBqdXN0IHNldHMgdGV4dENvbnRlbnQgdG8gZGlzcGxheSBuYW1lXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIHJlbmRlckhlYWRlcihlbnRpdHk6IFQsIGhlYWRlcjogSFRNTEVsZW1lbnQsIF9jb250ZXh0OiBJUmVuZGVyQ29udGV4dCk6IHZvaWQge1xyXG4gICAgaGVhZGVyLnRleHRDb250ZW50ID0gdGhpcy5nZXREaXNwbGF5TmFtZShlbnRpdHkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGVscGVyIHRvIHJlbmRlciBhIHNpbmdsZSBlbnRpdHkgaGVhZGVyLlxyXG4gICAqIENhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgdGhhdCBvdmVycmlkZSByZW5kZXIoKSBidXQgd2FudCBjb25zaXN0ZW50IGhlYWRlciBjcmVhdGlvbi5cclxuICAgKi9cclxuICBwcm90ZWN0ZWQgY3JlYXRlSGVhZGVyKGVudGl0eTogVCwgY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xyXG4gICAgaGVhZGVyLmRhdGFzZXRbdGhpcy5jb25maWcuaWRBdHRyaWJ1dGVdID0gZW50aXR5LmlkO1xyXG4gICAgdGhpcy5yZW5kZXJIZWFkZXIoZW50aXR5LCBoZWFkZXIsIGNvbnRleHQpO1xyXG4gICAgcmV0dXJuIGhlYWRlcjtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29yZS9JR3JvdXBpbmdSZW5kZXJlcic7XHJcbmltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyLCBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBSZXNvdXJjZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9yYWdlL3Jlc291cmNlcy9SZXNvdXJjZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJUmVzb3VyY2UgfSBmcm9tICcuLi8uLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVJlbmRlcmVyIGV4dGVuZHMgQmFzZUdyb3VwaW5nUmVuZGVyZXI8SVJlc291cmNlPiB7XHJcbiAgcmVhZG9ubHkgdHlwZSA9ICdyZXNvdXJjZSc7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBjb25maWc6IElHcm91cGluZ1JlbmRlcmVyQ29uZmlnID0ge1xyXG4gICAgZWxlbWVudFRhZzogJ3N3cC1yZXNvdXJjZS1oZWFkZXInLFxyXG4gICAgaWRBdHRyaWJ1dGU6ICdyZXNvdXJjZUlkJyxcclxuICAgIGNvbHNwYW5WYXI6ICctLXJlc291cmNlLWNvbHMnXHJcbiAgfTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZXNvdXJjZVNlcnZpY2U6IFJlc291cmNlU2VydmljZSkge1xyXG4gICAgc3VwZXIoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXRFbnRpdGllcyhpZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxJUmVzb3VyY2VbXT4ge1xyXG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VTZXJ2aWNlLmdldEJ5SWRzKGlkcyk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZ2V0RGlzcGxheU5hbWUoZW50aXR5OiBJUmVzb3VyY2UpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGVudGl0eS5kaXNwbGF5TmFtZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE92ZXJyaWRlIHJlbmRlciB0byBoYW5kbGU6XHJcbiAgICogMS4gU3BlY2lhbCBvcmRlcmluZyB3aGVuIHBhcmVudENoaWxkTWFwIGV4aXN0cyAocmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50KVxyXG4gICAqIDIuIERpZmZlcmVudCBjb2xzcGFuIGNhbGN1bGF0aW9uIChqdXN0IGRhdGVDb3VudCwgbm90IGNoaWxkQ291bnQgKiBkYXRlQ291bnQpXHJcbiAgICovXHJcbiAgYXN5bmMgcmVuZGVyKGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xyXG4gICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XHJcblxyXG4gICAgLy8gRGV0ZXJtaW5lIHJlbmRlciBvcmRlciBiYXNlZCBvbiBwYXJlbnRDaGlsZE1hcFxyXG4gICAgLy8gSWYgcGFyZW50Q2hpbGRNYXAgZXhpc3RzLCByZW5kZXIgcmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50IChlLmcuLCB0ZWFtKVxyXG4gICAgLy8gT3RoZXJ3aXNlLCByZW5kZXIgaW4gZmlsdGVyIG9yZGVyXHJcbiAgICBsZXQgb3JkZXJlZFJlc291cmNlSWRzOiBzdHJpbmdbXTtcclxuXHJcbiAgICBpZiAoY29udGV4dC5wYXJlbnRDaGlsZE1hcCkge1xyXG4gICAgICAvLyBSZW5kZXIgcmVzb3VyY2VzIGluIHBhcmVudC1jaGlsZCBvcmRlclxyXG4gICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSBbXTtcclxuICAgICAgZm9yIChjb25zdCBjaGlsZElkcyBvZiBPYmplY3QudmFsdWVzKGNvbnRleHQucGFyZW50Q2hpbGRNYXApKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBjaGlsZElkIG9mIGNoaWxkSWRzKSB7XHJcbiAgICAgICAgICBpZiAocmVzb3VyY2VJZHMuaW5jbHVkZXMoY2hpbGRJZCkpIHtcclxuICAgICAgICAgICAgb3JkZXJlZFJlc291cmNlSWRzLnB1c2goY2hpbGRJZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSByZXNvdXJjZUlkcztcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZXNvdXJjZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKG9yZGVyZWRSZXNvdXJjZUlkcyk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGEgbWFwIGZvciBxdWljayBsb29rdXAgdG8gcHJlc2VydmUgb3JkZXJcclxuICAgIGNvbnN0IHJlc291cmNlTWFwID0gbmV3IE1hcChyZXNvdXJjZXMubWFwKHIgPT4gW3IuaWQsIHJdKSk7XHJcblxyXG4gICAgZm9yIChjb25zdCByZXNvdXJjZUlkIG9mIG9yZGVyZWRSZXNvdXJjZUlkcykge1xyXG4gICAgICBjb25zdCByZXNvdXJjZSA9IHJlc291cmNlTWFwLmdldChyZXNvdXJjZUlkKTtcclxuICAgICAgaWYgKCFyZXNvdXJjZSkgY29udGludWU7XHJcblxyXG4gICAgICBjb25zdCBoZWFkZXIgPSB0aGlzLmNyZWF0ZUhlYWRlcihyZXNvdXJjZSwgY29udGV4dCk7XHJcbiAgICAgIGhlYWRlci5zdHlsZS5ncmlkQ29sdW1uID0gYHNwYW4gJHtkYXRlQ291bnR9YDtcclxuICAgICAgY29udGV4dC5oZWFkZXJDb250YWluZXIuYXBwZW5kQ2hpbGQoaGVhZGVyKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyLCBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBUZWFtU2VydmljZSB9IGZyb20gJy4uLy4uL3N0b3JhZ2UvdGVhbXMvVGVhbVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJVGVhbSB9IGZyb20gJy4uLy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRlYW1SZW5kZXJlciBleHRlbmRzIEJhc2VHcm91cGluZ1JlbmRlcmVyPElUZWFtPiB7XHJcbiAgcmVhZG9ubHkgdHlwZSA9ICd0ZWFtJztcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbmZpZzogSUdyb3VwaW5nUmVuZGVyZXJDb25maWcgPSB7XHJcbiAgICBlbGVtZW50VGFnOiAnc3dwLXRlYW0taGVhZGVyJyxcclxuICAgIGlkQXR0cmlidXRlOiAndGVhbUlkJyxcclxuICAgIGNvbHNwYW5WYXI6ICctLXRlYW0tY29scydcclxuICB9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRlYW1TZXJ2aWNlOiBUZWFtU2VydmljZSkge1xyXG4gICAgc3VwZXIoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXRFbnRpdGllcyhpZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxJVGVhbVtdPiB7XHJcbiAgICByZXR1cm4gdGhpcy50ZWFtU2VydmljZS5nZXRCeUlkcyhpZHMpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGdldERpc3BsYXlOYW1lKGVudGl0eTogSVRlYW0pOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGVudGl0eS5uYW1lO1xyXG4gIH1cclxufVxyXG4iLCAiZXhwb3J0IGNsYXNzIFRpbWVBeGlzUmVuZGVyZXIge1xyXG4gIHJlbmRlcihjb250YWluZXI6IEhUTUxFbGVtZW50LCBzdGFydEhvdXIgPSA2LCBlbmRIb3VyID0gMjApOiB2b2lkIHtcclxuICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcclxuICAgIGZvciAobGV0IGhvdXIgPSBzdGFydEhvdXI7IGhvdXIgPD0gZW5kSG91cjsgaG91cisrKSB7XHJcbiAgICAgIGNvbnN0IG1hcmtlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ob3VyLW1hcmtlcicpO1xyXG4gICAgICBtYXJrZXIudGV4dENvbnRlbnQgPSBgJHtob3VyLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKX06MDBgO1xyXG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobWFya2VyKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQSxLQUFDLFNBQVMsR0FBRSxHQUFFO0FBQUMsa0JBQVUsT0FBTyxXQUFTLGVBQWEsT0FBTyxTQUFPLE9BQU8sVUFBUSxFQUFFLElBQUUsY0FBWSxPQUFPLFVBQVEsT0FBTyxNQUFJLE9BQU8sQ0FBQyxLQUFHLElBQUUsZUFBYSxPQUFPLGFBQVcsYUFBVyxLQUFHLE1BQU0sUUFBTSxFQUFFO0FBQUEsSUFBQyxFQUFFLFNBQU0sV0FBVTtBQUFDO0FBQWEsVUFBSSxJQUFFLEtBQUksSUFBRSxLQUFJLElBQUUsTUFBSyxJQUFFLGVBQWMsSUFBRSxVQUFTLElBQUUsVUFBUyxJQUFFLFFBQU8sSUFBRSxPQUFNLElBQUUsUUFBTyxJQUFFLFNBQVEsSUFBRSxXQUFVLElBQUUsUUFBTyxJQUFFLFFBQU8sSUFBRSxnQkFBZSxJQUFFLDhGQUE2RixJQUFFLHVGQUFzRixJQUFFLEVBQUMsTUFBSyxNQUFLLFVBQVMsMkRBQTJELE1BQU0sR0FBRyxHQUFFLFFBQU8sd0ZBQXdGLE1BQU0sR0FBRyxHQUFFLFNBQVEsU0FBU0EsSUFBRTtBQUFDLFlBQUlDLEtBQUUsQ0FBQyxNQUFLLE1BQUssTUFBSyxJQUFJLEdBQUVDLEtBQUVGLEtBQUU7QUFBSSxlQUFNLE1BQUlBLE1BQUdDLElBQUdDLEtBQUUsTUFBSSxFQUFFLEtBQUdELEdBQUVDLEVBQUMsS0FBR0QsR0FBRSxDQUFDLEtBQUc7QUFBQSxNQUFHLEVBQUMsR0FBRSxJQUFFLGdDQUFTRCxJQUFF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QUFPLE9BQU87QUFBQSxFQUNoQjtBQUNGO0FBcEI4RDtBQUF2RCxJQUFNLGVBQU47OztBQ0pBLElBQU0sb0JBQU4sTUFBTSxrQkFBaUI7QUFBQSxFQUM1QixPQUFPLFdBQXdCLFlBQVksR0FBRyxVQUFVLElBQVU7QUFDaEUsY0FBVSxZQUFZO0FBQ3RCLGFBQVMsT0FBTyxXQUFXLFFBQVEsU0FBUyxRQUFRO0FBQ2xELFlBQU0sU0FBUyxTQUFTLGNBQWMsaUJBQWlCO0FBQ3ZELGFBQU8sY0FBYyxHQUFHLEtBQUssU0FBUyxFQUFFLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFDeEQsZ0JBQVUsWUFBWSxNQUFNO0FBQUEsSUFDOUI7QUFBQSxFQUNGO0FBQ0Y7QUFUOEI7QUFBdkIsSUFBTSxtQkFBTjsiLAogICJuYW1lcyI6IFsidCIsICJlIiwgIm4iLCAiciIsICJpIiwgInMiLCAidSIsICJhIiwgIk0iLCAibSIsICJmIiwgImwiLCAiJCIsICJ5IiwgInYiLCAiZyIsICJEIiwgIm8iLCAiZCIsICJjIiwgImgiLCAidCIsICJpIiwgImUiLCAicyIsICJmIiwgIm4iLCAidSIsICJyIiwgIm8iLCAidCIsICJuIiwgImkiLCAibyIsICJyIiwgImUiLCAidSIsICJmIiwgInMiLCAiYSIsICJ0IiwgImkiLCAiZCIsICJuIiwgImUiLCAicyIsICJkYXlqcyIsICJ1dGMiLCAidGltZXpvbmUiLCAiaXNvV2VlayJdCn0K diff --git a/wwwroot/js/components/NavigationButtons.d.ts b/wwwroot/js/components/NavigationButtons.d.ts new file mode 100644 index 0000000..75f5002 --- /dev/null +++ b/wwwroot/js/components/NavigationButtons.d.ts @@ -0,0 +1,63 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { DateService } from '../utils/DateService'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * NavigationButtons - Manages navigation button UI and navigation logic + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element + * and performs the actual navigation calculations. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-nav-button elements + * - Validates navigation actions (prev, next, today) + * - Calculates next/previous dates based on current view + * - Emits NAVIGATION_COMPLETED events with new date + * - Manages button UI listeners + * + * EVENT FLOW: + * =========== + * User clicks button → calculateNewDate() → emit NAVIGATION_COMPLETED → GridManager re-renders + */ +export declare class NavigationButtons { + private eventBus; + private buttonListeners; + private dateService; + private config; + private currentDate; + private currentView; + constructor(eventBus: IEventBus, dateService: DateService, config: Configuration); + /** + * Subscribe to events + */ + private subscribeToEvents; + /** + * Setup click listeners on all navigation buttons + */ + private setupButtonListeners; + /** + * Handle navigation action + */ + private handleNavigation; + /** + * Navigate in specified direction + */ + private navigate; + /** + * Navigate to next period + */ + private navigateNext; + /** + * Navigate to previous period + */ + private navigatePrevious; + /** + * Navigate to today + */ + private navigateToday; + /** + * Validate if string is a valid navigation action + */ + private isValidAction; +} diff --git a/wwwroot/js/components/NavigationButtons.js b/wwwroot/js/components/NavigationButtons.js new file mode 100644 index 0000000..1f53d45 --- /dev/null +++ b/wwwroot/js/components/NavigationButtons.js @@ -0,0 +1,131 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * NavigationButtons - Manages navigation button UI and navigation logic + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element + * and performs the actual navigation calculations. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-nav-button elements + * - Validates navigation actions (prev, next, today) + * - Calculates next/previous dates based on current view + * - Emits NAVIGATION_COMPLETED events with new date + * - Manages button UI listeners + * + * EVENT FLOW: + * =========== + * User clicks button → calculateNewDate() → emit NAVIGATION_COMPLETED → GridManager re-renders + */ +export class NavigationButtons { + constructor(eventBus, dateService, config) { + this.buttonListeners = new Map(); + this.currentDate = new Date(); + this.currentView = 'week'; + this.eventBus = eventBus; + this.dateService = dateService; + this.config = config; + this.setupButtonListeners(); + this.subscribeToEvents(); + } + /** + * Subscribe to events + */ + subscribeToEvents() { + // Listen for view changes + this.eventBus.on(CoreEvents.VIEW_CHANGED, (e) => { + const detail = e.detail; + this.currentView = detail.currentView; + }); + } + /** + * Setup click listeners on all navigation buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-nav-button[data-action]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const action = button.getAttribute('data-action'); + if (action && this.isValidAction(action)) { + this.handleNavigation(action); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + } + /** + * Handle navigation action + */ + handleNavigation(action) { + switch (action) { + case 'prev': + this.navigatePrevious(); + break; + case 'next': + this.navigateNext(); + break; + case 'today': + this.navigateToday(); + break; + } + } + /** + * Navigate in specified direction + */ + navigate(direction) { + const offset = direction === 'next' ? 1 : -1; + let newDate; + switch (this.currentView) { + case 'week': + newDate = this.dateService.addWeeks(this.currentDate, offset); + break; + case 'month': + newDate = this.dateService.addMonths(this.currentDate, offset); + break; + case 'day': + newDate = this.dateService.addDays(this.currentDate, offset); + break; + default: + newDate = this.dateService.addWeeks(this.currentDate, offset); + } + this.currentDate = newDate; + const payload = { + direction: direction, + newDate: newDate + }; + this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload); + } + /** + * Navigate to next period + */ + navigateNext() { + this.navigate('next'); + } + /** + * Navigate to previous period + */ + navigatePrevious() { + this.navigate('previous'); + } + /** + * Navigate to today + */ + navigateToday() { + this.currentDate = new Date(); + const payload = { + direction: 'today', + newDate: this.currentDate + }; + this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, payload); + } + /** + * Validate if string is a valid navigation action + */ + isValidAction(action) { + return ['prev', 'next', 'today'].includes(action); + } +} +//# sourceMappingURL=NavigationButtons.js.map \ No newline at end of file diff --git a/wwwroot/js/components/NavigationButtons.js.map b/wwwroot/js/components/NavigationButtons.js.map new file mode 100644 index 0000000..85a7e6d --- /dev/null +++ b/wwwroot/js/components/NavigationButtons.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NavigationButtons.js","sourceRoot":"","sources":["../../../src/components/NavigationButtons.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAKrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,iBAAiB;IAQ5B,YACE,QAAmB,EACnB,WAAwB,EACxB,MAAqB;QATf,oBAAe,GAAgC,IAAI,GAAG,EAAE,CAAC;QAGzD,gBAAW,GAAS,IAAI,IAAI,EAAE,CAAC;QAC/B,gBAAW,GAAiB,MAAM,CAAC;QAOzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,0BAA0B;QAC1B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAQ,EAAE,EAAE;YACrD,MAAM,MAAM,GAAI,CAAiB,CAAC,MAAM,CAAC;YACzC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;QAEzE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;gBACpC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBAClD,IAAI,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,MAAc;QACrC,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,MAAM;gBACT,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACxB,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,aAAa,EAAE,CAAC;gBACrB,MAAM;QACV,CAAC;IACH,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,SAA8B;QAC7C,MAAM,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,OAAa,CAAC;QAElB,QAAQ,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,KAAK,MAAM;gBACT,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAC9D,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAC/D,MAAM;YACR,KAAK,KAAK;gBACR,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAC7D,MAAM;YACR;gBACE,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAE3B,MAAM,OAAO,GAAkC;YAC7C,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,OAAO;SACjB,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAE9B,MAAM,OAAO,GAAkC;YAC7C,SAAS,EAAE,OAAO;YAClB,OAAO,EAAE,IAAI,CAAC,WAAW;SAC1B,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,MAAc;QAClC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/components/ViewSelector.d.ts b/wwwroot/js/components/ViewSelector.d.ts new file mode 100644 index 0000000..04b1853 --- /dev/null +++ b/wwwroot/js/components/ViewSelector.d.ts @@ -0,0 +1,70 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * ViewSelectorManager - Manages view selector UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-view-button elements + * - Manages current view state (day/week/month) + * - Validates view values + * - Emits VIEW_CHANGED and VIEW_RENDERED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changeView() → validate → update state → emit event → update UI + * + * IMPLEMENTATION STATUS: + * ====================== + * - Week view: FULLY IMPLEMENTED + * - Day view: NOT IMPLEMENTED (button exists but no rendering) + * - Month view: NOT IMPLEMENTED (button exists but no rendering) + * + * SUBSCRIBERS: + * ============ + * - GridRenderer: Uses view parameter (currently only supports 'week') + * - Future: DayRenderer, MonthRenderer when implemented + */ +export declare class ViewSelector { + private eventBus; + private config; + private buttonListeners; + constructor(eventBus: IEventBus, config: Configuration); + /** + * Setup click listeners on all view selector buttons + */ + private setupButtonListeners; + /** + * Setup event bus listeners + */ + private setupEventListeners; + /** + * Change the active view + */ + private changeView; + /** + * Update button states (data-active attributes) + */ + private updateButtonStates; + /** + * Initialize view on INITIALIZED event + */ + private initializeView; + /** + * Emit VIEW_RENDERED event + */ + private emitViewRendered; + /** + * Refresh current view on DATE_CHANGED event + */ + private refreshCurrentView; + /** + * Validate if string is a valid CalendarView type + */ + private isValidView; +} diff --git a/wwwroot/js/components/ViewSelector.js b/wwwroot/js/components/ViewSelector.js new file mode 100644 index 0000000..a54939c --- /dev/null +++ b/wwwroot/js/components/ViewSelector.js @@ -0,0 +1,130 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * ViewSelectorManager - Manages view selector UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-view-button elements + * - Manages current view state (day/week/month) + * - Validates view values + * - Emits VIEW_CHANGED and VIEW_RENDERED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changeView() → validate → update state → emit event → update UI + * + * IMPLEMENTATION STATUS: + * ====================== + * - Week view: FULLY IMPLEMENTED + * - Day view: NOT IMPLEMENTED (button exists but no rendering) + * - Month view: NOT IMPLEMENTED (button exists but no rendering) + * + * SUBSCRIBERS: + * ============ + * - GridRenderer: Uses view parameter (currently only supports 'week') + * - Future: DayRenderer, MonthRenderer when implemented + */ +export class ViewSelector { + constructor(eventBus, config) { + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.config = config; + this.setupButtonListeners(); + this.setupEventListeners(); + } + /** + * Setup click listeners on all view selector buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-view-button[data-view]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const view = button.getAttribute('data-view'); + if (view && this.isValidView(view)) { + this.changeView(view); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + // Initialize button states + this.updateButtonStates(); + } + /** + * Setup event bus listeners + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.INITIALIZED, () => { + this.initializeView(); + }); + this.eventBus.on(CoreEvents.DATE_CHANGED, () => { + this.refreshCurrentView(); + }); + } + /** + * Change the active view + */ + changeView(newView) { + if (newView === this.config.currentView) { + return; // No change + } + const previousView = this.config.currentView; + this.config.currentView = newView; + // Update button UI states + this.updateButtonStates(); + // Emit event for subscribers + this.eventBus.emit(CoreEvents.VIEW_CHANGED, { + previousView, + currentView: newView + }); + } + /** + * Update button states (data-active attributes) + */ + updateButtonStates() { + const buttons = document.querySelectorAll('swp-view-button[data-view]'); + buttons.forEach(button => { + const buttonView = button.getAttribute('data-view'); + if (buttonView === this.config.currentView) { + button.setAttribute('data-active', 'true'); + } + else { + button.removeAttribute('data-active'); + } + }); + } + /** + * Initialize view on INITIALIZED event + */ + initializeView() { + this.updateButtonStates(); + this.emitViewRendered(); + } + /** + * Emit VIEW_RENDERED event + */ + emitViewRendered() { + this.eventBus.emit(CoreEvents.VIEW_RENDERED, { + view: this.config.currentView + }); + } + /** + * Refresh current view on DATE_CHANGED event + */ + refreshCurrentView() { + this.emitViewRendered(); + } + /** + * Validate if string is a valid CalendarView type + */ + isValidView(view) { + return ['day', 'week', 'month'].includes(view); + } +} +//# sourceMappingURL=ViewSelector.js.map \ No newline at end of file diff --git a/wwwroot/js/components/ViewSelector.js.map b/wwwroot/js/components/ViewSelector.js.map new file mode 100644 index 0000000..291c1a2 --- /dev/null +++ b/wwwroot/js/components/ViewSelector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ViewSelector.js","sourceRoot":"","sources":["../../../src/components/ViewSelector.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/components/WorkweekPresets.d.ts b/wwwroot/js/components/WorkweekPresets.d.ts new file mode 100644 index 0000000..7b96030 --- /dev/null +++ b/wwwroot/js/components/WorkweekPresets.d.ts @@ -0,0 +1,47 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * WorkweekPresetsManager - Manages workweek preset UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Owns WORK_WEEK_PRESETS data + * - Handles button clicks on swp-preset-button elements + * - Manages current workweek preset state + * - Validates preset IDs + * - Emits WORKWEEK_CHANGED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changePreset() → validate → update state → emit event → update UI + * + * SUBSCRIBERS: + * ============ + * - ConfigManager: Updates CSS variables (--grid-columns) + * - GridManager: Re-renders grid with new column count + * - CalendarManager: Relays to header update (via workweek:header-update) + * - HeaderManager: Updates date headers + */ +export declare class WorkweekPresets { + private eventBus; + private config; + private buttonListeners; + constructor(eventBus: IEventBus, config: Configuration); + /** + * Setup click listeners on all workweek preset buttons + */ + private setupButtonListeners; + /** + * Change the active workweek preset + */ + private changePreset; + /** + * Update button states (data-active attributes) + */ + private updateButtonStates; +} diff --git a/wwwroot/js/components/WorkweekPresets.js b/wwwroot/js/components/WorkweekPresets.js new file mode 100644 index 0000000..e7e953f --- /dev/null +++ b/wwwroot/js/components/WorkweekPresets.js @@ -0,0 +1,95 @@ +import { CoreEvents } from '../constants/CoreEvents'; +import { WORK_WEEK_PRESETS } from '../configurations/CalendarConfig'; +/** + * WorkweekPresetsManager - Manages workweek preset UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Owns WORK_WEEK_PRESETS data + * - Handles button clicks on swp-preset-button elements + * - Manages current workweek preset state + * - Validates preset IDs + * - Emits WORKWEEK_CHANGED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changePreset() → validate → update state → emit event → update UI + * + * SUBSCRIBERS: + * ============ + * - ConfigManager: Updates CSS variables (--grid-columns) + * - GridManager: Re-renders grid with new column count + * - CalendarManager: Relays to header update (via workweek:header-update) + * - HeaderManager: Updates date headers + */ +export class WorkweekPresets { + constructor(eventBus, config) { + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.config = config; + this.setupButtonListeners(); + } + /** + * Setup click listeners on all workweek preset buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-preset-button[data-workweek]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const presetId = button.getAttribute('data-workweek'); + if (presetId) { + this.changePreset(presetId); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + // Initialize button states + this.updateButtonStates(); + } + /** + * Change the active workweek preset + */ + changePreset(presetId) { + if (!WORK_WEEK_PRESETS[presetId]) { + console.warn(`Invalid preset ID "${presetId}"`); + return; + } + if (presetId === this.config.currentWorkWeek) { + return; // No change + } + const previousPresetId = this.config.currentWorkWeek; + this.config.currentWorkWeek = presetId; + const settings = WORK_WEEK_PRESETS[presetId]; + // Update button UI states + this.updateButtonStates(); + // Emit event for subscribers + this.eventBus.emit(CoreEvents.WORKWEEK_CHANGED, { + workWeekId: presetId, + previousWorkWeekId: previousPresetId, + settings: settings + }); + } + /** + * Update button states (data-active attributes) + */ + updateButtonStates() { + const buttons = document.querySelectorAll('swp-preset-button[data-workweek]'); + buttons.forEach(button => { + const buttonPresetId = button.getAttribute('data-workweek'); + if (buttonPresetId === this.config.currentWorkWeek) { + button.setAttribute('data-active', 'true'); + } + else { + button.removeAttribute('data-active'); + } + }); + } +} +//# sourceMappingURL=WorkweekPresets.js.map \ No newline at end of file diff --git a/wwwroot/js/components/WorkweekPresets.js.map b/wwwroot/js/components/WorkweekPresets.js.map new file mode 100644 index 0000000..10f34a5 --- /dev/null +++ b/wwwroot/js/components/WorkweekPresets.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WorkweekPresets.js","sourceRoot":"","sources":["../../../src/components/WorkweekPresets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAiB,MAAM,kCAAkC,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,eAAe;IAK1B,YAAY,QAAmB,EAAE,MAAqB;QAF9C,oBAAe,GAAgC,IAAI,GAAG,EAAE,CAAC;QAG/D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC;QAE9E,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;gBACpC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;gBACtD,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,QAAgB;QACnC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,sBAAsB,QAAQ,GAAG,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC7C,OAAO,CAAC,YAAY;QACtB,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,QAAQ,CAAC;QAEvC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAE7C,0BAA0B;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,6BAA6B;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAC9C,UAAU,EAAE,QAAQ;YACpB,kBAAkB,EAAE,gBAAgB;YACpC,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC;QAE9E,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,cAAc,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAE5D,IAAI,cAAc,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;gBACnD,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CAEF"} \ No newline at end of file diff --git a/wwwroot/js/configuration/CalendarConfig.d.ts b/wwwroot/js/configuration/CalendarConfig.d.ts new file mode 100644 index 0000000..92b98dc --- /dev/null +++ b/wwwroot/js/configuration/CalendarConfig.d.ts @@ -0,0 +1,44 @@ +import { ICalendarConfig } from './ICalendarConfig'; +import { IGridSettings } from './GridSettings'; +import { IDateViewSettings } from './DateViewSettings'; +import { ITimeFormatConfig } from './TimeFormatConfig'; +import { IWorkWeekSettings } from './WorkWeekSettings'; +/** + * All-day event layout constants + */ +export declare const ALL_DAY_CONSTANTS: { + readonly EVENT_HEIGHT: 22; + readonly EVENT_GAP: 2; + readonly CONTAINER_PADDING: 4; + readonly MAX_COLLAPSED_ROWS: 4; + readonly SINGLE_ROW_HEIGHT: number; +}; +/** + * Work week presets + */ +export declare const WORK_WEEK_PRESETS: { + [key: string]: IWorkWeekSettings; +}; +/** + * Configuration - DTO container for all configuration + * Pure data object loaded from JSON via ConfigManager + */ +export declare class Configuration { + private static _instance; + config: ICalendarConfig; + gridSettings: IGridSettings; + dateViewSettings: IDateViewSettings; + timeFormatConfig: ITimeFormatConfig; + currentWorkWeek: string; + selectedDate: Date; + constructor(config: ICalendarConfig, gridSettings: IGridSettings, dateViewSettings: IDateViewSettings, timeFormatConfig: ITimeFormatConfig, currentWorkWeek: string, selectedDate?: Date); + /** + * Get the current Configuration instance + * Used by web components that can't use dependency injection + */ + static getInstance(): Configuration; + getWorkWeekSettings(): IWorkWeekSettings; + setWorkWeek(workWeekId: string): void; + setSelectedDate(date: Date): void; +} +export { Configuration as CalendarConfig }; diff --git a/wwwroot/js/configuration/CalendarConfig.js b/wwwroot/js/configuration/CalendarConfig.js new file mode 100644 index 0000000..8c769a3 --- /dev/null +++ b/wwwroot/js/configuration/CalendarConfig.js @@ -0,0 +1,90 @@ +/** + * All-day event layout constants + */ +export const ALL_DAY_CONSTANTS = { + EVENT_HEIGHT: 22, + EVENT_GAP: 2, + CONTAINER_PADDING: 4, + MAX_COLLAPSED_ROWS: 4, + get SINGLE_ROW_HEIGHT() { + return this.EVENT_HEIGHT + this.EVENT_GAP; // 28px + } +}; +/** + * Work week presets + */ +export const WORK_WEEK_PRESETS = { + 'standard': { + id: 'standard', + workDays: [1, 2, 3, 4, 5], + totalDays: 5, + firstWorkDay: 1 + }, + 'compressed': { + id: 'compressed', + workDays: [1, 2, 3, 4], + totalDays: 4, + firstWorkDay: 1 + }, + 'midweek': { + id: 'midweek', + workDays: [3, 4, 5], + totalDays: 3, + firstWorkDay: 3 + }, + 'weekend': { + id: 'weekend', + workDays: [6, 7], + totalDays: 2, + firstWorkDay: 6 + }, + 'fullweek': { + id: 'fullweek', + workDays: [1, 2, 3, 4, 5, 6, 7], + totalDays: 7, + firstWorkDay: 1 + } +}; +/** + * Configuration - DTO container for all configuration + * Pure data object loaded from JSON via ConfigManager + */ +export class Configuration { + constructor(config, gridSettings, dateViewSettings, timeFormatConfig, currentWorkWeek, selectedDate = new Date()) { + this.config = config; + this.gridSettings = gridSettings; + this.dateViewSettings = dateViewSettings; + this.timeFormatConfig = timeFormatConfig; + this.currentWorkWeek = currentWorkWeek; + this.selectedDate = selectedDate; + // Store as singleton instance for web components + Configuration._instance = this; + } + /** + * Get the current Configuration instance + * Used by web components that can't use dependency injection + */ + static getInstance() { + if (!Configuration._instance) { + throw new Error('Configuration has not been initialized. Call ConfigManager.load() first.'); + } + return Configuration._instance; + } + // Helper methods + getWorkWeekSettings() { + return WORK_WEEK_PRESETS[this.currentWorkWeek] || WORK_WEEK_PRESETS['standard']; + } + setWorkWeek(workWeekId) { + if (WORK_WEEK_PRESETS[workWeekId]) { + this.currentWorkWeek = workWeekId; + this.dateViewSettings.weekDays = WORK_WEEK_PRESETS[workWeekId].totalDays; + } + } + setSelectedDate(date) { + this.selectedDate = date; + } +} +Configuration._instance = null; +// Backward compatibility alias +export { Configuration as CalendarConfig }; +//# sourceMappingURL=CalendarConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/CalendarConfig.js.map b/wwwroot/js/configuration/CalendarConfig.js.map new file mode 100644 index 0000000..c9c14a2 --- /dev/null +++ b/wwwroot/js/configuration/CalendarConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarConfig.js","sourceRoot":"","sources":["../../../src/configuration/CalendarConfig.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/configuration/ConfigManager.d.ts b/wwwroot/js/configuration/ConfigManager.d.ts new file mode 100644 index 0000000..efc52f3 --- /dev/null +++ b/wwwroot/js/configuration/ConfigManager.d.ts @@ -0,0 +1,11 @@ +import { Configuration } from './CalendarConfig'; +/** + * ConfigManager - Static configuration loader + * Loads JSON and creates Configuration instance + */ +export declare class ConfigManager { + /** + * Load configuration from JSON and create Configuration instance + */ + static load(): Promise; +} diff --git a/wwwroot/js/configuration/ConfigManager.js b/wwwroot/js/configuration/ConfigManager.js new file mode 100644 index 0000000..7f90a7d --- /dev/null +++ b/wwwroot/js/configuration/ConfigManager.js @@ -0,0 +1,43 @@ +import { Configuration } from './CalendarConfig'; +import { TimeFormatter } from '../utils/TimeFormatter'; +/** + * ConfigManager - Static configuration loader + * Loads JSON and creates Configuration instance + */ +export class ConfigManager { + /** + * Load configuration from JSON and create Configuration instance + */ + static async load() { + const response = await fetch('/wwwroot/data/calendar-config.json'); + if (!response.ok) { + throw new Error(`Failed to load config: ${response.statusText}`); + } + const data = await response.json(); + // Build main config + const mainConfig = { + scrollbarWidth: data.scrollbar.width, + scrollbarColor: data.scrollbar.color, + scrollbarTrackColor: data.scrollbar.trackColor, + scrollbarHoverColor: data.scrollbar.hoverColor, + scrollbarBorderRadius: data.scrollbar.borderRadius, + allowDrag: data.interaction.allowDrag, + allowResize: data.interaction.allowResize, + allowCreate: data.interaction.allowCreate, + apiEndpoint: data.api.endpoint, + dateFormat: data.api.dateFormat, + timeFormat: data.api.timeFormat, + enableSearch: data.features.enableSearch, + enableTouch: data.features.enableTouch, + defaultEventDuration: data.eventDefaults.defaultEventDuration, + minEventDuration: data.gridSettings.snapInterval, + maxEventDuration: data.eventDefaults.maxEventDuration + }; + // Create Configuration instance + const config = new Configuration(mainConfig, data.gridSettings, data.dateViewSettings, data.timeFormatConfig, data.currentWorkWeek); + // Configure TimeFormatter + TimeFormatter.configure(config.timeFormatConfig); + return config; + } +} +//# sourceMappingURL=ConfigManager.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/ConfigManager.js.map b/wwwroot/js/configuration/ConfigManager.js.map new file mode 100644 index 0000000..0bc0010 --- /dev/null +++ b/wwwroot/js/configuration/ConfigManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ConfigManager.js","sourceRoot":"","sources":["../../../src/configuration/ConfigManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI;QACf,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,oBAAoB;QACpB,MAAM,UAAU,GAAoB;YAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;YACpC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;YACpC,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU;YAC9C,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU;YAC9C,qBAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY;YAClD,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS;YACrC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW;YACzC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW;YACzC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ;YAC9B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU;YAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU;YAC/B,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY;YACxC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW;YACtC,oBAAoB,EAAE,IAAI,CAAC,aAAa,CAAC,oBAAoB;YAC7D,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY;YAChD,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB;SACtD,CAAC;QAEF,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,aAAa,CAC9B,UAAU,EACV,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,eAAe,CACrB,CAAC;QAEF,0BAA0B;QAC1B,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAEjD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/configuration/DateViewSettings.d.ts b/wwwroot/js/configuration/DateViewSettings.d.ts new file mode 100644 index 0000000..5459f66 --- /dev/null +++ b/wwwroot/js/configuration/DateViewSettings.d.ts @@ -0,0 +1,10 @@ +import { ViewPeriod } from '../types/CalendarTypes'; +/** + * View settings for date-based calendar mode + */ +export interface IDateViewSettings { + period: ViewPeriod; + weekDays: number; + firstDayOfWeek: number; + showAllDay: boolean; +} diff --git a/wwwroot/js/configuration/DateViewSettings.js b/wwwroot/js/configuration/DateViewSettings.js new file mode 100644 index 0000000..cb2b894 --- /dev/null +++ b/wwwroot/js/configuration/DateViewSettings.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=DateViewSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/DateViewSettings.js.map b/wwwroot/js/configuration/DateViewSettings.js.map new file mode 100644 index 0000000..cf1d286 --- /dev/null +++ b/wwwroot/js/configuration/DateViewSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateViewSettings.js","sourceRoot":"","sources":["../../../src/configuration/DateViewSettings.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configuration/GridSettings.d.ts b/wwwroot/js/configuration/GridSettings.d.ts new file mode 100644 index 0000000..0db6981 --- /dev/null +++ b/wwwroot/js/configuration/GridSettings.d.ts @@ -0,0 +1,22 @@ +/** + * Grid display settings interface + */ +export interface IGridSettings { + dayStartHour: number; + dayEndHour: number; + workStartHour: number; + workEndHour: number; + hourHeight: number; + snapInterval: number; + fitToWidth: boolean; + scrollToHour: number | null; + gridStartThresholdMinutes: number; + showCurrentTime: boolean; + showWorkHours: boolean; +} +/** + * Grid settings utility functions + */ +export declare namespace GridSettingsUtils { + function isValidSnapInterval(interval: number): boolean; +} diff --git a/wwwroot/js/configuration/GridSettings.js b/wwwroot/js/configuration/GridSettings.js new file mode 100644 index 0000000..c7e399e --- /dev/null +++ b/wwwroot/js/configuration/GridSettings.js @@ -0,0 +1,11 @@ +/** + * Grid settings utility functions + */ +export var GridSettingsUtils; +(function (GridSettingsUtils) { + function isValidSnapInterval(interval) { + return [5, 10, 15, 30, 60].includes(interval); + } + GridSettingsUtils.isValidSnapInterval = isValidSnapInterval; +})(GridSettingsUtils || (GridSettingsUtils = {})); +//# sourceMappingURL=GridSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/GridSettings.js.map b/wwwroot/js/configuration/GridSettings.js.map new file mode 100644 index 0000000..f8a3c86 --- /dev/null +++ b/wwwroot/js/configuration/GridSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GridSettings.js","sourceRoot":"","sources":["../../../src/configuration/GridSettings.ts"],"names":[],"mappings":"AAiBA;;GAEG;AACH,MAAM,KAAW,iBAAiB,CAIjC;AAJD,WAAiB,iBAAiB;IAChC,SAAgB,mBAAmB,CAAC,QAAgB;QAClD,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAFe,qCAAmB,sBAElC,CAAA;AACH,CAAC,EAJgB,iBAAiB,KAAjB,iBAAiB,QAIjC"} \ No newline at end of file diff --git a/wwwroot/js/configuration/ICalendarConfig.d.ts b/wwwroot/js/configuration/ICalendarConfig.d.ts new file mode 100644 index 0000000..4c66c10 --- /dev/null +++ b/wwwroot/js/configuration/ICalendarConfig.d.ts @@ -0,0 +1,21 @@ +/** + * Main calendar configuration interface + */ +export interface ICalendarConfig { + scrollbarWidth: number; + scrollbarColor: string; + scrollbarTrackColor: string; + scrollbarHoverColor: string; + scrollbarBorderRadius: number; + allowDrag: boolean; + allowResize: boolean; + allowCreate: boolean; + apiEndpoint: string; + dateFormat: string; + timeFormat: string; + enableSearch: boolean; + enableTouch: boolean; + defaultEventDuration: number; + minEventDuration: number; + maxEventDuration: number; +} diff --git a/wwwroot/js/configuration/ICalendarConfig.js b/wwwroot/js/configuration/ICalendarConfig.js new file mode 100644 index 0000000..769ac97 --- /dev/null +++ b/wwwroot/js/configuration/ICalendarConfig.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=ICalendarConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/ICalendarConfig.js.map b/wwwroot/js/configuration/ICalendarConfig.js.map new file mode 100644 index 0000000..46eb186 --- /dev/null +++ b/wwwroot/js/configuration/ICalendarConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ICalendarConfig.js","sourceRoot":"","sources":["../../../src/configuration/ICalendarConfig.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configuration/TimeFormatConfig.d.ts b/wwwroot/js/configuration/TimeFormatConfig.d.ts new file mode 100644 index 0000000..d1f26c1 --- /dev/null +++ b/wwwroot/js/configuration/TimeFormatConfig.d.ts @@ -0,0 +1,10 @@ +/** + * Time format configuration settings + */ +export interface ITimeFormatConfig { + timezone: string; + use24HourFormat: boolean; + locale: string; + dateFormat: 'locale' | 'technical'; + showSeconds: boolean; +} diff --git a/wwwroot/js/configuration/TimeFormatConfig.js b/wwwroot/js/configuration/TimeFormatConfig.js new file mode 100644 index 0000000..31213da --- /dev/null +++ b/wwwroot/js/configuration/TimeFormatConfig.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=TimeFormatConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/TimeFormatConfig.js.map b/wwwroot/js/configuration/TimeFormatConfig.js.map new file mode 100644 index 0000000..8306905 --- /dev/null +++ b/wwwroot/js/configuration/TimeFormatConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TimeFormatConfig.js","sourceRoot":"","sources":["../../../src/configuration/TimeFormatConfig.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configuration/WorkWeekSettings.d.ts b/wwwroot/js/configuration/WorkWeekSettings.d.ts new file mode 100644 index 0000000..b971f20 --- /dev/null +++ b/wwwroot/js/configuration/WorkWeekSettings.d.ts @@ -0,0 +1,9 @@ +/** + * Work week configuration settings + */ +export interface IWorkWeekSettings { + id: string; + workDays: number[]; + totalDays: number; + firstWorkDay: number; +} diff --git a/wwwroot/js/configuration/WorkWeekSettings.js b/wwwroot/js/configuration/WorkWeekSettings.js new file mode 100644 index 0000000..1b2eefc --- /dev/null +++ b/wwwroot/js/configuration/WorkWeekSettings.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=WorkWeekSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configuration/WorkWeekSettings.js.map b/wwwroot/js/configuration/WorkWeekSettings.js.map new file mode 100644 index 0000000..52447fd --- /dev/null +++ b/wwwroot/js/configuration/WorkWeekSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WorkWeekSettings.js","sourceRoot":"","sources":["../../../src/configuration/WorkWeekSettings.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configurations/CalendarConfig.d.ts b/wwwroot/js/configurations/CalendarConfig.d.ts new file mode 100644 index 0000000..d883b53 --- /dev/null +++ b/wwwroot/js/configurations/CalendarConfig.d.ts @@ -0,0 +1,46 @@ +import { ICalendarConfig } from './ICalendarConfig'; +import { IGridSettings } from './GridSettings'; +import { IDateViewSettings } from './DateViewSettings'; +import { ITimeFormatConfig } from './TimeFormatConfig'; +import { IWorkWeekSettings } from './WorkWeekSettings'; +import { CalendarView } from '../types/CalendarTypes'; +/** + * All-day event layout constants + */ +export declare const ALL_DAY_CONSTANTS: { + readonly EVENT_HEIGHT: 22; + readonly EVENT_GAP: 2; + readonly CONTAINER_PADDING: 4; + readonly MAX_COLLAPSED_ROWS: 4; + readonly SINGLE_ROW_HEIGHT: number; +}; +/** + * Work week presets - Configuration data + */ +export declare const WORK_WEEK_PRESETS: { + [key: string]: IWorkWeekSettings; +}; +/** + * Configuration - DTO container for all configuration + * Pure data object loaded from JSON via ConfigManager + */ +export declare class Configuration { + private static _instance; + config: ICalendarConfig; + gridSettings: IGridSettings; + dateViewSettings: IDateViewSettings; + timeFormatConfig: ITimeFormatConfig; + currentWorkWeek: string; + currentView: CalendarView; + selectedDate: Date; + apiEndpoint: string; + constructor(config: ICalendarConfig, gridSettings: IGridSettings, dateViewSettings: IDateViewSettings, timeFormatConfig: ITimeFormatConfig, currentWorkWeek: string, currentView: CalendarView, selectedDate?: Date); + /** + * Get the current Configuration instance + * Used by web components that can't use dependency injection + */ + static getInstance(): Configuration; + setSelectedDate(date: Date): void; + getWorkWeekSettings(): IWorkWeekSettings; +} +export { Configuration as CalendarConfig }; diff --git a/wwwroot/js/configurations/CalendarConfig.js b/wwwroot/js/configurations/CalendarConfig.js new file mode 100644 index 0000000..89d9237 --- /dev/null +++ b/wwwroot/js/configurations/CalendarConfig.js @@ -0,0 +1,85 @@ +/** + * All-day event layout constants + */ +export const ALL_DAY_CONSTANTS = { + EVENT_HEIGHT: 22, + EVENT_GAP: 2, + CONTAINER_PADDING: 4, + MAX_COLLAPSED_ROWS: 4, + get SINGLE_ROW_HEIGHT() { + return this.EVENT_HEIGHT + this.EVENT_GAP; // 28px + } +}; +/** + * Work week presets - Configuration data + */ +export const WORK_WEEK_PRESETS = { + 'standard': { + id: 'standard', + workDays: [1, 2, 3, 4, 5], + totalDays: 5, + firstWorkDay: 1 + }, + 'compressed': { + id: 'compressed', + workDays: [1, 2, 3, 4], + totalDays: 4, + firstWorkDay: 1 + }, + 'midweek': { + id: 'midweek', + workDays: [3, 4, 5], + totalDays: 3, + firstWorkDay: 3 + }, + 'weekend': { + id: 'weekend', + workDays: [6, 7], + totalDays: 2, + firstWorkDay: 6 + }, + 'fullweek': { + id: 'fullweek', + workDays: [1, 2, 3, 4, 5, 6, 7], + totalDays: 7, + firstWorkDay: 1 + } +}; +/** + * Configuration - DTO container for all configuration + * Pure data object loaded from JSON via ConfigManager + */ +export class Configuration { + constructor(config, gridSettings, dateViewSettings, timeFormatConfig, currentWorkWeek, currentView, selectedDate = new Date()) { + this.apiEndpoint = '/api'; + this.config = config; + this.gridSettings = gridSettings; + this.dateViewSettings = dateViewSettings; + this.timeFormatConfig = timeFormatConfig; + this.currentWorkWeek = currentWorkWeek; + this.currentView = currentView; + this.selectedDate = selectedDate; + // Store as singleton instance for web components + Configuration._instance = this; + } + /** + * Get the current Configuration instance + * Used by web components that can't use dependency injection + */ + static getInstance() { + if (!Configuration._instance) { + throw new Error('Configuration has not been initialized. Call ConfigManager.load() first.'); + } + return Configuration._instance; + } + setSelectedDate(date) { + this.selectedDate = date; + } + getWorkWeekSettings() { + return WORK_WEEK_PRESETS[this.currentWorkWeek] || WORK_WEEK_PRESETS['standard']; + } +} +Configuration._instance = null; +// Backward compatibility alias +export { Configuration as CalendarConfig }; +//# sourceMappingURL=CalendarConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/CalendarConfig.js.map b/wwwroot/js/configurations/CalendarConfig.js.map new file mode 100644 index 0000000..e563232 --- /dev/null +++ b/wwwroot/js/configurations/CalendarConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarConfig.js","sourceRoot":"","sources":["../../../src/configurations/CalendarConfig.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,YAAY,EAAE,EAAE;IAChB,SAAS,EAAE,CAAC;IACZ,iBAAiB,EAAE,CAAC;IACpB,kBAAkB,EAAE,CAAC;IACrB,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO;IACpD,CAAC;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAyC;IACrE,UAAU,EAAE;QACV,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzB,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;KAChB;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,YAAY;QAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtB,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;KAChB;IACD,SAAS,EAAE;QACT,EAAE,EAAE,SAAS;QACb,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACnB,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;KAChB;IACD,SAAS,EAAE;QACT,EAAE,EAAE,SAAS;QACb,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAChB,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;KAChB;IACD,UAAU,EAAE;QACV,EAAE,EAAE,UAAU;QACd,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/B,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;KAChB;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,aAAa;IAYxB,YACE,MAAuB,EACvB,YAA2B,EAC3B,gBAAmC,EACnC,gBAAmC,EACnC,eAAuB,EACvB,WAAyB,EACzB,eAAqB,IAAI,IAAI,EAAE;QAT1B,gBAAW,GAAW,MAAM,CAAC;QAWlC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QAEjC,iDAAiD;QACjD,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC;IACjC,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,aAAa,CAAC,SAAS,CAAC;IACjC,CAAC;IAED,eAAe,CAAC,IAAU;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,mBAAmB;QACjB,OAAO,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAClF,CAAC;;AAjDc,uBAAS,GAAyB,IAAI,AAA7B,CAA8B;AAoDxD,+BAA+B;AAC/B,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/configurations/ConfigManager.d.ts b/wwwroot/js/configurations/ConfigManager.d.ts new file mode 100644 index 0000000..1123edd --- /dev/null +++ b/wwwroot/js/configurations/ConfigManager.d.ts @@ -0,0 +1,28 @@ +import { Configuration } from './CalendarConfig'; +import { IEventBus } from '../types/CalendarTypes'; +/** + * ConfigManager - Configuration loader and CSS property manager + * Loads JSON and creates Configuration instance + * Listens to events and manages CSS custom properties for dynamic styling + */ +export declare class ConfigManager { + private eventBus; + private config; + constructor(eventBus: IEventBus, config: Configuration); + /** + * Setup event listeners for dynamic CSS updates + */ + private setupEventListeners; + /** + * Sync grid-related CSS variables from configuration + */ + private syncGridCSSVariables; + /** + * Sync workweek-related CSS variables + */ + private syncWorkweekCSSVariables; + /** + * Load configuration from JSON and create Configuration instance + */ + static load(): Promise; +} diff --git a/wwwroot/js/configurations/ConfigManager.js b/wwwroot/js/configurations/ConfigManager.js new file mode 100644 index 0000000..1c75db8 --- /dev/null +++ b/wwwroot/js/configurations/ConfigManager.js @@ -0,0 +1,80 @@ +import { Configuration } from './CalendarConfig'; +import { TimeFormatter } from '../utils/TimeFormatter'; +import { CoreEvents } from '../constants/CoreEvents'; +/** + * ConfigManager - Configuration loader and CSS property manager + * Loads JSON and creates Configuration instance + * Listens to events and manages CSS custom properties for dynamic styling + */ +export class ConfigManager { + constructor(eventBus, config) { + this.eventBus = eventBus; + this.config = config; + this.setupEventListeners(); + this.syncGridCSSVariables(); + this.syncWorkweekCSSVariables(); + } + /** + * Setup event listeners for dynamic CSS updates + */ + setupEventListeners() { + // Listen to workweek changes and update CSS accordingly + this.eventBus.on(CoreEvents.WORKWEEK_CHANGED, (event) => { + const { settings } = event.detail; + this.syncWorkweekCSSVariables(settings); + }); + } + /** + * Sync grid-related CSS variables from configuration + */ + syncGridCSSVariables() { + const gridSettings = this.config.gridSettings; + document.documentElement.style.setProperty('--hour-height', `${gridSettings.hourHeight}px`); + document.documentElement.style.setProperty('--day-start-hour', gridSettings.dayStartHour.toString()); + document.documentElement.style.setProperty('--day-end-hour', gridSettings.dayEndHour.toString()); + document.documentElement.style.setProperty('--work-start-hour', gridSettings.workStartHour.toString()); + document.documentElement.style.setProperty('--work-end-hour', gridSettings.workEndHour.toString()); + } + /** + * Sync workweek-related CSS variables + */ + syncWorkweekCSSVariables(workWeekSettings) { + const settings = workWeekSettings || this.config.getWorkWeekSettings(); + document.documentElement.style.setProperty('--grid-columns', settings.totalDays.toString()); + } + /** + * Load configuration from JSON and create Configuration instance + */ + static async load() { + const response = await fetch('/wwwroot/data/calendar-config.json'); + if (!response.ok) { + throw new Error(`Failed to load config: ${response.statusText}`); + } + const data = await response.json(); + // Build main config + const mainConfig = { + scrollbarWidth: data.scrollbar.width, + scrollbarColor: data.scrollbar.color, + scrollbarTrackColor: data.scrollbar.trackColor, + scrollbarHoverColor: data.scrollbar.hoverColor, + scrollbarBorderRadius: data.scrollbar.borderRadius, + allowDrag: data.interaction.allowDrag, + allowResize: data.interaction.allowResize, + allowCreate: data.interaction.allowCreate, + apiEndpoint: data.api.endpoint, + dateFormat: data.api.dateFormat, + timeFormat: data.api.timeFormat, + enableSearch: data.features.enableSearch, + enableTouch: data.features.enableTouch, + defaultEventDuration: data.eventDefaults.defaultEventDuration, + minEventDuration: data.gridSettings.snapInterval, + maxEventDuration: data.eventDefaults.maxEventDuration + }; + // Create Configuration instance + const config = new Configuration(mainConfig, data.gridSettings, data.dateViewSettings, data.timeFormatConfig, data.currentWorkWeek, data.currentView || 'week'); + // Configure TimeFormatter + TimeFormatter.configure(config.timeFormatConfig); + return config; + } +} +//# sourceMappingURL=ConfigManager.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/ConfigManager.js.map b/wwwroot/js/configurations/ConfigManager.js.map new file mode 100644 index 0000000..71e69a0 --- /dev/null +++ b/wwwroot/js/configurations/ConfigManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ConfigManager.js","sourceRoot":"","sources":["../../../src/configurations/ConfigManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/configurations/DateViewSettings.d.ts b/wwwroot/js/configurations/DateViewSettings.d.ts new file mode 100644 index 0000000..5459f66 --- /dev/null +++ b/wwwroot/js/configurations/DateViewSettings.d.ts @@ -0,0 +1,10 @@ +import { ViewPeriod } from '../types/CalendarTypes'; +/** + * View settings for date-based calendar mode + */ +export interface IDateViewSettings { + period: ViewPeriod; + weekDays: number; + firstDayOfWeek: number; + showAllDay: boolean; +} diff --git a/wwwroot/js/configurations/DateViewSettings.js b/wwwroot/js/configurations/DateViewSettings.js new file mode 100644 index 0000000..cb2b894 --- /dev/null +++ b/wwwroot/js/configurations/DateViewSettings.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=DateViewSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/DateViewSettings.js.map b/wwwroot/js/configurations/DateViewSettings.js.map new file mode 100644 index 0000000..385c982 --- /dev/null +++ b/wwwroot/js/configurations/DateViewSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateViewSettings.js","sourceRoot":"","sources":["../../../src/configurations/DateViewSettings.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configurations/GridSettings.d.ts b/wwwroot/js/configurations/GridSettings.d.ts new file mode 100644 index 0000000..0db6981 --- /dev/null +++ b/wwwroot/js/configurations/GridSettings.d.ts @@ -0,0 +1,22 @@ +/** + * Grid display settings interface + */ +export interface IGridSettings { + dayStartHour: number; + dayEndHour: number; + workStartHour: number; + workEndHour: number; + hourHeight: number; + snapInterval: number; + fitToWidth: boolean; + scrollToHour: number | null; + gridStartThresholdMinutes: number; + showCurrentTime: boolean; + showWorkHours: boolean; +} +/** + * Grid settings utility functions + */ +export declare namespace GridSettingsUtils { + function isValidSnapInterval(interval: number): boolean; +} diff --git a/wwwroot/js/configurations/GridSettings.js b/wwwroot/js/configurations/GridSettings.js new file mode 100644 index 0000000..c7e399e --- /dev/null +++ b/wwwroot/js/configurations/GridSettings.js @@ -0,0 +1,11 @@ +/** + * Grid settings utility functions + */ +export var GridSettingsUtils; +(function (GridSettingsUtils) { + function isValidSnapInterval(interval) { + return [5, 10, 15, 30, 60].includes(interval); + } + GridSettingsUtils.isValidSnapInterval = isValidSnapInterval; +})(GridSettingsUtils || (GridSettingsUtils = {})); +//# sourceMappingURL=GridSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/GridSettings.js.map b/wwwroot/js/configurations/GridSettings.js.map new file mode 100644 index 0000000..cdfbb83 --- /dev/null +++ b/wwwroot/js/configurations/GridSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GridSettings.js","sourceRoot":"","sources":["../../../src/configurations/GridSettings.ts"],"names":[],"mappings":"AAiBA;;GAEG;AACH,MAAM,KAAW,iBAAiB,CAIjC;AAJD,WAAiB,iBAAiB;IAChC,SAAgB,mBAAmB,CAAC,QAAgB;QAClD,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAFe,qCAAmB,sBAElC,CAAA;AACH,CAAC,EAJgB,iBAAiB,KAAjB,iBAAiB,QAIjC"} \ No newline at end of file diff --git a/wwwroot/js/configurations/ICalendarConfig.d.ts b/wwwroot/js/configurations/ICalendarConfig.d.ts new file mode 100644 index 0000000..4c66c10 --- /dev/null +++ b/wwwroot/js/configurations/ICalendarConfig.d.ts @@ -0,0 +1,21 @@ +/** + * Main calendar configuration interface + */ +export interface ICalendarConfig { + scrollbarWidth: number; + scrollbarColor: string; + scrollbarTrackColor: string; + scrollbarHoverColor: string; + scrollbarBorderRadius: number; + allowDrag: boolean; + allowResize: boolean; + allowCreate: boolean; + apiEndpoint: string; + dateFormat: string; + timeFormat: string; + enableSearch: boolean; + enableTouch: boolean; + defaultEventDuration: number; + minEventDuration: number; + maxEventDuration: number; +} diff --git a/wwwroot/js/configurations/ICalendarConfig.js b/wwwroot/js/configurations/ICalendarConfig.js new file mode 100644 index 0000000..769ac97 --- /dev/null +++ b/wwwroot/js/configurations/ICalendarConfig.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=ICalendarConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/ICalendarConfig.js.map b/wwwroot/js/configurations/ICalendarConfig.js.map new file mode 100644 index 0000000..f3e954b --- /dev/null +++ b/wwwroot/js/configurations/ICalendarConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ICalendarConfig.js","sourceRoot":"","sources":["../../../src/configurations/ICalendarConfig.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configurations/TimeFormatConfig.d.ts b/wwwroot/js/configurations/TimeFormatConfig.d.ts new file mode 100644 index 0000000..d1f26c1 --- /dev/null +++ b/wwwroot/js/configurations/TimeFormatConfig.d.ts @@ -0,0 +1,10 @@ +/** + * Time format configuration settings + */ +export interface ITimeFormatConfig { + timezone: string; + use24HourFormat: boolean; + locale: string; + dateFormat: 'locale' | 'technical'; + showSeconds: boolean; +} diff --git a/wwwroot/js/configurations/TimeFormatConfig.js b/wwwroot/js/configurations/TimeFormatConfig.js new file mode 100644 index 0000000..31213da --- /dev/null +++ b/wwwroot/js/configurations/TimeFormatConfig.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=TimeFormatConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/TimeFormatConfig.js.map b/wwwroot/js/configurations/TimeFormatConfig.js.map new file mode 100644 index 0000000..c94321c --- /dev/null +++ b/wwwroot/js/configurations/TimeFormatConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TimeFormatConfig.js","sourceRoot":"","sources":["../../../src/configurations/TimeFormatConfig.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/configurations/WorkWeekSettings.d.ts b/wwwroot/js/configurations/WorkWeekSettings.d.ts new file mode 100644 index 0000000..b971f20 --- /dev/null +++ b/wwwroot/js/configurations/WorkWeekSettings.d.ts @@ -0,0 +1,9 @@ +/** + * Work week configuration settings + */ +export interface IWorkWeekSettings { + id: string; + workDays: number[]; + totalDays: number; + firstWorkDay: number; +} diff --git a/wwwroot/js/configurations/WorkWeekSettings.js b/wwwroot/js/configurations/WorkWeekSettings.js new file mode 100644 index 0000000..1b2eefc --- /dev/null +++ b/wwwroot/js/configurations/WorkWeekSettings.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=WorkWeekSettings.js.map \ No newline at end of file diff --git a/wwwroot/js/configurations/WorkWeekSettings.js.map b/wwwroot/js/configurations/WorkWeekSettings.js.map new file mode 100644 index 0000000..9fe597d --- /dev/null +++ b/wwwroot/js/configurations/WorkWeekSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WorkWeekSettings.js","sourceRoot":"","sources":["../../../src/configurations/WorkWeekSettings.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/constants/CoreEvents.d.ts b/wwwroot/js/constants/CoreEvents.d.ts new file mode 100644 index 0000000..7e98d27 --- /dev/null +++ b/wwwroot/js/constants/CoreEvents.d.ts @@ -0,0 +1,37 @@ +/** + * CoreEvents - Consolidated essential events for the calendar + * Reduces complexity from 102+ events to ~20 core events + */ +export declare const CoreEvents: { + readonly INITIALIZED: "core:initialized"; + readonly READY: "core:ready"; + readonly DESTROYED: "core:destroyed"; + readonly VIEW_CHANGED: "view:changed"; + readonly VIEW_RENDERED: "view:rendered"; + readonly WORKWEEK_CHANGED: "workweek:changed"; + readonly NAV_BUTTON_CLICKED: "nav:button-clicked"; + readonly DATE_CHANGED: "nav:date-changed"; + readonly NAVIGATION_COMPLETED: "nav:navigation-completed"; + readonly NAVIGATE_TO_EVENT: "nav:navigate-to-event"; + readonly DATA_LOADING: "data:loading"; + readonly DATA_LOADED: "data:loaded"; + readonly DATA_ERROR: "data:error"; + readonly EVENTS_FILTERED: "data:events-filtered"; + readonly REMOTE_UPDATE_RECEIVED: "data:remote-update"; + readonly GRID_RENDERED: "grid:rendered"; + readonly GRID_CLICKED: "grid:clicked"; + readonly CELL_SELECTED: "grid:cell-selected"; + readonly EVENT_CREATED: "event:created"; + readonly EVENT_UPDATED: "event:updated"; + readonly EVENT_DELETED: "event:deleted"; + readonly EVENT_SELECTED: "event:selected"; + readonly ERROR: "system:error"; + readonly REFRESH_REQUESTED: "system:refresh"; + readonly OFFLINE_MODE_CHANGED: "system:offline-mode-changed"; + readonly SYNC_STARTED: "sync:started"; + readonly SYNC_COMPLETED: "sync:completed"; + readonly SYNC_FAILED: "sync:failed"; + readonly SYNC_RETRY: "sync:retry"; + readonly FILTER_CHANGED: "filter:changed"; + readonly EVENTS_RENDERED: "events:rendered"; +}; diff --git a/wwwroot/js/constants/CoreEvents.js b/wwwroot/js/constants/CoreEvents.js new file mode 100644 index 0000000..f72a48a --- /dev/null +++ b/wwwroot/js/constants/CoreEvents.js @@ -0,0 +1,48 @@ +/** + * CoreEvents - Consolidated essential events for the calendar + * Reduces complexity from 102+ events to ~20 core events + */ +export const CoreEvents = { + // Lifecycle events (3) + INITIALIZED: 'core:initialized', + READY: 'core:ready', + DESTROYED: 'core:destroyed', + // View events (3) + VIEW_CHANGED: 'view:changed', + VIEW_RENDERED: 'view:rendered', + WORKWEEK_CHANGED: 'workweek:changed', + // Navigation events (4) + NAV_BUTTON_CLICKED: 'nav:button-clicked', + DATE_CHANGED: 'nav:date-changed', + NAVIGATION_COMPLETED: 'nav:navigation-completed', + NAVIGATE_TO_EVENT: 'nav:navigate-to-event', + // Data events (5) + DATA_LOADING: 'data:loading', + DATA_LOADED: 'data:loaded', + DATA_ERROR: 'data:error', + EVENTS_FILTERED: 'data:events-filtered', + REMOTE_UPDATE_RECEIVED: 'data:remote-update', + // Grid events (3) + GRID_RENDERED: 'grid:rendered', + GRID_CLICKED: 'grid:clicked', + CELL_SELECTED: 'grid:cell-selected', + // Event management (4) + EVENT_CREATED: 'event:created', + EVENT_UPDATED: 'event:updated', + EVENT_DELETED: 'event:deleted', + EVENT_SELECTED: 'event:selected', + // System events (3) + ERROR: 'system:error', + REFRESH_REQUESTED: 'system:refresh', + OFFLINE_MODE_CHANGED: 'system:offline-mode-changed', + // Sync events (4) + SYNC_STARTED: 'sync:started', + SYNC_COMPLETED: 'sync:completed', + SYNC_FAILED: 'sync:failed', + SYNC_RETRY: 'sync:retry', + // Filter events (1) + FILTER_CHANGED: 'filter:changed', + // Rendering events (1) + EVENTS_RENDERED: 'events:rendered' +}; +//# sourceMappingURL=CoreEvents.js.map \ No newline at end of file diff --git a/wwwroot/js/constants/CoreEvents.js.map b/wwwroot/js/constants/CoreEvents.js.map new file mode 100644 index 0000000..d32cee3 --- /dev/null +++ b/wwwroot/js/constants/CoreEvents.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CoreEvents.js","sourceRoot":"","sources":["../../../src/constants/CoreEvents.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,uBAAuB;IACvB,WAAW,EAAE,kBAAkB;IAC/B,KAAK,EAAE,YAAY;IACnB,SAAS,EAAE,gBAAgB;IAE3B,kBAAkB;IAClB,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IAEpC,wBAAwB;IACxB,kBAAkB,EAAE,oBAAoB;IACxC,YAAY,EAAE,kBAAkB;IAChC,oBAAoB,EAAE,0BAA0B;IAChD,iBAAiB,EAAE,uBAAuB;IAE1C,kBAAkB;IAClB,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,sBAAsB;IACvC,sBAAsB,EAAE,oBAAoB;IAE5C,kBAAkB;IAClB,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,oBAAoB;IAEnC,uBAAuB;IACvB,aAAa,EAAE,eAAe;IAC9B,aAAa,EAAE,eAAe;IAC9B,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAEhC,oBAAoB;IACpB,KAAK,EAAE,cAAc;IACrB,iBAAiB,EAAE,gBAAgB;IACnC,oBAAoB,EAAE,6BAA6B;IAEnD,kBAAkB;IAClB,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,gBAAgB;IAChC,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IAExB,oBAAoB;IACpB,cAAc,EAAE,gBAAgB;IAEhC,uBAAuB;IACvB,eAAe,EAAE,iBAAiB;CAC1B,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/core/CalendarConfig.d.ts b/wwwroot/js/core/CalendarConfig.d.ts new file mode 100644 index 0000000..c19e1f3 --- /dev/null +++ b/wwwroot/js/core/CalendarConfig.d.ts @@ -0,0 +1,225 @@ +import { CalendarConfig as ICalendarConfig, ViewPeriod, CalendarMode } from '../types/CalendarTypes'; +/** + * All-day event layout constants + */ +export declare const ALL_DAY_CONSTANTS: { + readonly EVENT_HEIGHT: 22; + readonly EVENT_GAP: 2; + readonly CONTAINER_PADDING: 4; + readonly MAX_COLLAPSED_ROWS: 4; + readonly SINGLE_ROW_HEIGHT: number; +}; +/** + * Layout and timing settings for the calendar grid + */ +interface GridSettings { + dayStartHour: number; + dayEndHour: number; + workStartHour: number; + workEndHour: number; + hourHeight: number; + snapInterval: number; + fitToWidth: boolean; + scrollToHour: number | null; + gridStartThresholdMinutes: number; + showCurrentTime: boolean; + showWorkHours: boolean; +} +/** + * View settings for date-based calendar mode + */ +interface DateViewSettings { + period: ViewPeriod; + weekDays: number; + firstDayOfWeek: number; + showAllDay: boolean; +} +/** + * Work week configuration settings + */ +interface WorkWeekSettings { + id: string; + workDays: number[]; + totalDays: number; + firstWorkDay: number; +} +/** + * View settings for resource-based calendar mode + */ +interface ResourceViewSettings { + maxResources: number; + showAvatars: boolean; + avatarSize: number; + resourceNameFormat: 'full' | 'short'; + showResourceDetails: boolean; + showAllDay: boolean; +} +/** + * Time format configuration settings + */ +interface TimeFormatConfig { + timezone: string; + use24HourFormat: boolean; + locale: string; + dateFormat: 'locale' | 'technical'; + showSeconds: boolean; +} +/** + * Calendar configuration management + */ +export declare class CalendarConfig { + private config; + private calendarMode; + private selectedDate; + private gridSettings; + private dateViewSettings; + private resourceViewSettings; + private currentWorkWeek; + private timeFormatConfig; + constructor(); + /** + * Load calendar type and date from URL parameters + */ + private loadCalendarType; + /** + * Load configuration from DOM data attributes + */ + private loadFromDOM; + /** + * Get a config value + */ + get(key: K): ICalendarConfig[K]; + /** + * Set a config value + */ + set(key: K, value: ICalendarConfig[K]): void; + /** + * Update multiple config values + */ + update(updates: Partial): void; + /** + * Get all config + */ + getAll(): ICalendarConfig; + /** + * Calculate derived values + */ + get minuteHeight(): number; + get totalHours(): number; + get totalMinutes(): number; + get slotsPerHour(): number; + get totalSlots(): number; + get slotHeight(): number; + /** + * Validate snap interval + */ + isValidSnapInterval(interval: number): boolean; + /** + * Get grid display settings + */ + getGridSettings(): GridSettings; + /** + * Update grid display settings + */ + updateGridSettings(updates: Partial): void; + /** + * Get date view settings + */ + getDateViewSettings(): DateViewSettings; + /** + * Update date view settings + */ + updateDateViewSettings(updates: Partial): void; + /** + * Get resource view settings + */ + getResourceViewSettings(): ResourceViewSettings; + /** + * Update resource view settings + */ + updateResourceViewSettings(updates: Partial): void; + /** + * Check if current mode is resource-based + */ + isResourceMode(): boolean; + /** + * Check if current mode is date-based + */ + isDateMode(): boolean; + /** + * Get calendar mode + */ + getCalendarMode(): CalendarMode; + /** + * Set calendar mode + */ + setCalendarMode(mode: CalendarMode): void; + /** + * Get selected date + */ + getSelectedDate(): Date | null; + /** + * Set selected date + * Note: Does not emit events - caller is responsible for event emission + */ + setSelectedDate(date: Date): void; + /** + * Get work week presets + */ + private getWorkWeekPresets; + /** + * Get current work week settings + */ + getWorkWeekSettings(): WorkWeekSettings; + /** + * Set work week preset + * Note: Does not emit events - caller is responsible for event emission + */ + setWorkWeek(workWeekId: string): void; + /** + * Get current work week ID + */ + getCurrentWorkWeek(): string; + /** + * Get time format settings + */ + getTimeFormatSettings(): TimeFormatConfig; + /** + * Update time format settings + */ + updateTimeFormatSettings(updates: Partial): void; + /** + * Set timezone (convenience method) + */ + setTimezone(timezone: string): void; + /** + * Set 12/24 hour format (convenience method) + */ + set24HourFormat(use24Hour: boolean): void; + /** + * Get configured timezone + */ + getTimezone(): string; + /** + * Get configured locale + */ + getLocale(): string; + /** + * Check if using 24-hour format + */ + is24HourFormat(): boolean; + /** + * Set date format (convenience method) + */ + setDateFormat(format: 'locale' | 'technical'): void; + /** + * Set whether to show seconds (convenience method) + */ + setShowSeconds(show: boolean): void; + /** + * Get current date format + */ + getDateFormat(): 'locale' | 'technical'; +} +export declare const calendarConfig: CalendarConfig; +export {}; diff --git a/wwwroot/js/core/CalendarConfig.js b/wwwroot/js/core/CalendarConfig.js new file mode 100644 index 0000000..010ca10 --- /dev/null +++ b/wwwroot/js/core/CalendarConfig.js @@ -0,0 +1,421 @@ +// Calendar configuration management +import { eventBus } from './EventBus'; +import { CoreEvents } from '../constants/CoreEvents'; +import { TimeFormatter } from '../utils/TimeFormatter'; +/** + * All-day event layout constants + */ +export const ALL_DAY_CONSTANTS = { + EVENT_HEIGHT: 22, // Height of single all-day event + EVENT_GAP: 2, // Gap between stacked events + CONTAINER_PADDING: 4, // Container padding (top + bottom) + get SINGLE_ROW_HEIGHT() { + return this.EVENT_HEIGHT + this.EVENT_GAP + this.CONTAINER_PADDING; // 28px + } +}; +/** + * Calendar configuration management + */ +export class CalendarConfig { + constructor() { + this.calendarMode = 'date'; + this.selectedDate = null; + this.currentWorkWeek = 'standard'; + this.config = { + // Scrollbar styling + scrollbarWidth: 16, // Width of scrollbar in pixels + scrollbarColor: '#666', // Scrollbar thumb color + scrollbarTrackColor: '#f0f0f0', // Scrollbar track color + scrollbarHoverColor: '#b53f7aff', // Scrollbar thumb hover color + scrollbarBorderRadius: 6, // Border radius for scrollbar thumb + // Interaction settings + allowDrag: true, + allowResize: true, + allowCreate: true, + // API settings + apiEndpoint: '/api/events', + dateFormat: 'YYYY-MM-DD', + timeFormat: 'HH:mm', + // Feature flags + enableSearch: true, + enableTouch: true, + // Event defaults + defaultEventDuration: 60, // Minutes + minEventDuration: 15, // Will be same as snapInterval + maxEventDuration: 480 // 8 hours + }; + // Grid display settings + this.gridSettings = { + hourHeight: 60, + dayStartHour: 0, + dayEndHour: 24, + workStartHour: 8, + workEndHour: 17, + snapInterval: 15, + showCurrentTime: true, + showWorkHours: true, + fitToWidth: false, + scrollToHour: 8 + }; + // Date view settings + this.dateViewSettings = { + period: 'week', + weekDays: 7, + firstDayOfWeek: 1, + showAllDay: true + }; + // Resource view settings + this.resourceViewSettings = { + maxResources: 10, + showAvatars: true, + avatarSize: 32, + resourceNameFormat: 'full', + showResourceDetails: true, + showAllDay: true + }; + // Time format settings - default to Denmark + this.timeFormatConfig = { + timezone: 'Europe/Copenhagen', + use24HourFormat: true, + locale: 'da-DK' + }; + // Set computed values + this.config.minEventDuration = this.gridSettings.snapInterval; + // Initialize TimeFormatter with default settings + TimeFormatter.configure(this.timeFormatConfig); + // Load calendar type from URL parameter + this.loadCalendarType(); + // Load from data attributes + this.loadFromDOM(); + } + /** + * Load calendar type and date from URL parameters + */ + loadCalendarType() { + const urlParams = new URLSearchParams(window.location.search); + const typeParam = urlParams.get('type'); + const dateParam = urlParams.get('date'); + // Set calendar mode + if (typeParam === 'resource' || typeParam === 'date') { + this.calendarMode = typeParam; + } + else { + this.calendarMode = 'date'; // Default + } + // Set selected date + if (dateParam) { + const parsedDate = new Date(dateParam); + if (!isNaN(parsedDate.getTime())) { + this.selectedDate = parsedDate; + } + else { + this.selectedDate = new Date(); + } + } + else { + this.selectedDate = new Date(); // Default to today + } + } + /** + * Load configuration from DOM data attributes + */ + loadFromDOM() { + const calendar = document.querySelector('swp-calendar'); + if (!calendar) + return; + // Read data attributes + const attrs = calendar.dataset; + // Update date view settings + if (attrs.view) + this.dateViewSettings.period = attrs.view; + if (attrs.weekDays) + this.dateViewSettings.weekDays = parseInt(attrs.weekDays); + // Update grid settings + if (attrs.snapInterval) + this.gridSettings.snapInterval = parseInt(attrs.snapInterval); + if (attrs.dayStartHour) + this.gridSettings.dayStartHour = parseInt(attrs.dayStartHour); + if (attrs.dayEndHour) + this.gridSettings.dayEndHour = parseInt(attrs.dayEndHour); + if (attrs.hourHeight) + this.gridSettings.hourHeight = parseInt(attrs.hourHeight); + if (attrs.fitToWidth !== undefined) + this.gridSettings.fitToWidth = attrs.fitToWidth === 'true'; + // Update computed values + this.config.minEventDuration = this.gridSettings.snapInterval; + } + /** + * Get a config value + */ + get(key) { + return this.config[key]; + } + /** + * Set a config value + */ + set(key, value) { + const oldValue = this.config[key]; + this.config[key] = value; + // Update computed values handled in specific update methods + // Emit config update event + eventBus.emit(CoreEvents.REFRESH_REQUESTED, { + key, + value, + oldValue + }); + } + /** + * Update multiple config values + */ + update(updates) { + Object.entries(updates).forEach(([key, value]) => { + this.set(key, value); + }); + } + /** + * Get all config + */ + getAll() { + return { ...this.config }; + } + /** + * Calculate derived values + */ + get minuteHeight() { + return this.gridSettings.hourHeight / 60; + } + get totalHours() { + return this.gridSettings.dayEndHour - this.gridSettings.dayStartHour; + } + get totalMinutes() { + return this.totalHours * 60; + } + get slotsPerHour() { + return 60 / this.gridSettings.snapInterval; + } + get totalSlots() { + return this.totalHours * this.slotsPerHour; + } + get slotHeight() { + return this.gridSettings.hourHeight / this.slotsPerHour; + } + /** + * Validate snap interval + */ + isValidSnapInterval(interval) { + return [5, 10, 15, 30, 60].includes(interval); + } + /** + * Get grid display settings + */ + getGridSettings() { + return { ...this.gridSettings }; + } + /** + * Update grid display settings + */ + updateGridSettings(updates) { + this.gridSettings = { ...this.gridSettings, ...updates }; + // Update computed values + if (updates.snapInterval) { + this.config.minEventDuration = updates.snapInterval; + } + // Grid settings changes trigger general refresh - avoid specific event + eventBus.emit(CoreEvents.REFRESH_REQUESTED, { + key: 'gridSettings', + value: this.gridSettings + }); + } + /** + * Get date view settings + */ + getDateViewSettings() { + return { ...this.dateViewSettings }; + } + /** + * Update date view settings + */ + updateDateViewSettings(updates) { + this.dateViewSettings = { ...this.dateViewSettings, ...updates }; + // Date view settings changes trigger general refresh - avoid specific event + eventBus.emit(CoreEvents.REFRESH_REQUESTED, { + key: 'dateViewSettings', + value: this.dateViewSettings + }); + } + /** + * Get resource view settings + */ + getResourceViewSettings() { + return { ...this.resourceViewSettings }; + } + /** + * Update resource view settings + */ + updateResourceViewSettings(updates) { + this.resourceViewSettings = { ...this.resourceViewSettings, ...updates }; + // Resource view settings changes trigger general refresh - avoid specific event + eventBus.emit(CoreEvents.REFRESH_REQUESTED, { + key: 'resourceViewSettings', + value: this.resourceViewSettings + }); + } + /** + * Check if current mode is resource-based + */ + isResourceMode() { + return this.calendarMode === 'resource'; + } + /** + * Check if current mode is date-based + */ + isDateMode() { + return this.calendarMode === 'date'; + } + /** + * Get calendar mode + */ + getCalendarMode() { + return this.calendarMode; + } + /** + * Set calendar mode + */ + setCalendarMode(mode) { + const oldMode = this.calendarMode; + this.calendarMode = mode; + // Emit calendar mode change event + eventBus.emit(CoreEvents.VIEW_CHANGED, { + oldType: oldMode, + newType: mode + }); + } + /** + * Get selected date + */ + getSelectedDate() { + return this.selectedDate; + } + /** + * Set selected date + */ + setSelectedDate(date) { + this.selectedDate = date; + // Emit date change event + eventBus.emit(CoreEvents.DATE_CHANGED, { + date: date + }); + } + /** + * Get work week presets + */ + getWorkWeekPresets() { + return { + 'standard': { + id: 'standard', + workDays: [1, 2, 3, 4, 5], // Monday-Friday (ISO) + totalDays: 5, + firstWorkDay: 1 + }, + 'compressed': { + id: 'compressed', + workDays: [1, 2, 3, 4], // Monday-Thursday (ISO) + totalDays: 4, + firstWorkDay: 1 + }, + 'midweek': { + id: 'midweek', + workDays: [3, 4, 5], // Wednesday-Friday (ISO) + totalDays: 3, + firstWorkDay: 3 + }, + 'weekend': { + id: 'weekend', + workDays: [6, 7], // Saturday-Sunday (ISO) + totalDays: 2, + firstWorkDay: 6 + }, + 'fullweek': { + id: 'fullweek', + workDays: [1, 2, 3, 4, 5, 6, 7], // Monday-Sunday (ISO) + totalDays: 7, + firstWorkDay: 1 + } + }; + } + /** + * Get current work week settings + */ + getWorkWeekSettings() { + const presets = this.getWorkWeekPresets(); + return presets[this.currentWorkWeek] || presets['standard']; + } + /** + * Set work week preset + */ + setWorkWeek(workWeekId) { + const presets = this.getWorkWeekPresets(); + if (presets[workWeekId]) { + this.currentWorkWeek = workWeekId; + // Update dateViewSettings to match work week + this.dateViewSettings.weekDays = presets[workWeekId].totalDays; + // Emit work week change event + eventBus.emit(CoreEvents.WORKWEEK_CHANGED, { + workWeekId: workWeekId, + settings: presets[workWeekId] + }); + } + } + /** + * Get current work week ID + */ + getCurrentWorkWeek() { + return this.currentWorkWeek; + } + /** + * Get time format settings + */ + getTimeFormatSettings() { + return { ...this.timeFormatConfig }; + } + /** + * Update time format settings + */ + updateTimeFormatSettings(updates) { + this.timeFormatConfig = { ...this.timeFormatConfig, ...updates }; + // Update TimeFormatter with new settings + TimeFormatter.configure(this.timeFormatConfig); + // Emit time format change event + eventBus.emit(CoreEvents.REFRESH_REQUESTED, { + key: 'timeFormatSettings', + value: this.timeFormatConfig + }); + } + /** + * Set timezone (convenience method) + */ + setTimezone(timezone) { + this.updateTimeFormatSettings({ timezone }); + } + /** + * Set 12/24 hour format (convenience method) + */ + set24HourFormat(use24Hour) { + this.updateTimeFormatSettings({ use24HourFormat: use24Hour }); + } + /** + * Get configured timezone + */ + getTimezone() { + return this.timeFormatConfig.timezone; + } + /** + * Check if using 24-hour format + */ + is24HourFormat() { + return this.timeFormatConfig.use24HourFormat; + } +} +// Create singleton instance +export const calendarConfig = new CalendarConfig(); +//# sourceMappingURL=CalendarConfig.js.map \ No newline at end of file diff --git a/wwwroot/js/core/CalendarConfig.js.map b/wwwroot/js/core/CalendarConfig.js.map new file mode 100644 index 0000000..d0e1710 --- /dev/null +++ b/wwwroot/js/core/CalendarConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarConfig.js","sourceRoot":"","sources":["../../../src/core/CalendarConfig.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAsB,MAAM,wBAAwB,CAAC;AAE3E;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,YAAY,EAAE,EAAE,EAAK,iCAAiC;IACtD,SAAS,EAAE,CAAC,EAAS,6BAA6B;IAClD,iBAAiB,EAAE,CAAC,EAAE,mCAAmC;IACzD,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO;IAC7E,CAAC;CACO,CAAC;AAgEX;;GAEG;AACH,MAAM,OAAO,cAAc;IAUzB;QARQ,iBAAY,GAAiB,MAAM,CAAC;QACpC,iBAAY,GAAgB,IAAI,CAAC;QAIjC,oBAAe,GAAW,UAAU,CAAC;QAI3C,IAAI,CAAC,MAAM,GAAG;YACZ,oBAAoB;YACpB,cAAc,EAAE,EAAE,EAAM,+BAA+B;YACvD,cAAc,EAAE,MAAM,EAAE,wBAAwB;YAChD,mBAAmB,EAAE,SAAS,EAAE,wBAAwB;YACxD,mBAAmB,EAAE,WAAW,EAAE,8BAA8B;YAChE,qBAAqB,EAAE,CAAC,EAAE,oCAAoC;YAE9D,uBAAuB;YACvB,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,IAAI;YAEjB,eAAe;YACf,WAAW,EAAE,aAAa;YAC1B,UAAU,EAAE,YAAY;YACxB,UAAU,EAAE,OAAO;YAEnB,gBAAgB;YAChB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;YAEjB,iBAAiB;YACjB,oBAAoB,EAAE,EAAE,EAAE,UAAU;YACpC,gBAAgB,EAAE,EAAE,EAAM,+BAA+B;YACzD,gBAAgB,EAAE,GAAG,CAAK,UAAU;SACrC,CAAC;QAEF,wBAAwB;QACxB,IAAI,CAAC,YAAY,GAAG;YAClB,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,CAAC;YAChB,WAAW,EAAE,EAAE;YACf,YAAY,EAAE,EAAE;YAChB,eAAe,EAAE,IAAI;YACrB,aAAa,EAAE,IAAI;YACnB,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,CAAC;SAChB,CAAC;QAEF,qBAAqB;QACrB,IAAI,CAAC,gBAAgB,GAAG;YACtB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,CAAC;YACX,cAAc,EAAE,CAAC;YACjB,UAAU,EAAE,IAAI;SACjB,CAAC;QAEF,yBAAyB;QACzB,IAAI,CAAC,oBAAoB,GAAG;YAC1B,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,EAAE;YACd,kBAAkB,EAAE,MAAM;YAC1B,mBAAmB,EAAE,IAAI;YACzB,UAAU,EAAE,IAAI;SACjB,CAAC;QAEF,4CAA4C;QAC5C,IAAI,CAAC,gBAAgB,GAAG;YACtB,QAAQ,EAAE,mBAAmB;YAC7B,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,OAAO;SAChB,CAAC;QAEF,sBAAsB;QACtB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;QAE9D,iDAAiD;QACjD,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE/C,wCAAwC;QACxC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,4BAA4B;QAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAExC,oBAAoB;QACpB,IAAI,SAAS,KAAK,UAAU,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACrD,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,UAAU;QACxC,CAAC;QAED,oBAAoB;QACpB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,mBAAmB;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAgB,CAAC;QACvE,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,uBAAuB;QACvB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC;QAE/B,4BAA4B;QAC5B,IAAI,KAAK,CAAC,IAAI;YAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,KAAK,CAAC,IAAkB,CAAC;QACxE,IAAI,KAAK,CAAC,QAAQ;YAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE9E,uBAAuB;QACvB,IAAI,KAAK,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACtF,IAAI,KAAK,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACtF,IAAI,KAAK,CAAC,UAAU;YAAE,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChF,IAAI,KAAK,CAAC,UAAU;YAAE,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAChF,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;YAAE,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC;QAE/F,yBAAyB;QACzB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,GAAG,CAAkC,GAAM;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,GAAG,CAAkC,GAAM,EAAE,KAAyB;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAEzB,4DAA4D;QAE5D,2BAA2B;QAC3B,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YAC1C,GAAG;YACH,KAAK;YACL,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAiC;QACtC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAC/C,IAAI,CAAC,GAAG,CAAC,GAA4B,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IAEH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;IACvE,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,QAAgB;QAClC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,OAA8B;QAC/C,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO,EAAE,CAAC;QAEzD,yBAAyB;QACzB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC;QACtD,CAAC;QAED,uEAAuE;QACvE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YAC1C,GAAG,EAAE,cAAc;YACnB,KAAK,EAAE,IAAI,CAAC,YAAY;SACzB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,sBAAsB,CAAC,OAAkC;QACvD,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,OAAO,EAAE,CAAC;QAEjE,4EAA4E;QAC5E,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YAC1C,GAAG,EAAE,kBAAkB;YACvB,KAAK,EAAE,IAAI,CAAC,gBAAgB;SAC7B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,uBAAuB;QACrB,OAAO,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,0BAA0B,CAAC,OAAsC;QAC/D,IAAI,CAAC,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,GAAG,OAAO,EAAE,CAAC;QAEzE,gFAAgF;QAChF,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YAC1C,GAAG,EAAE,sBAAsB;YAC3B,KAAK,EAAE,IAAI,CAAC,oBAAoB;SACjC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC;IACtC,CAAC;IAGD;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,IAAkB;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,kCAAkC;QAClC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE;YACrC,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,IAAU;QACxB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,yBAAyB;QACzB,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE;YACrC,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,OAAO;YACL,UAAU,EAAE;gBACV,EAAE,EAAE,UAAU;gBACd,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAE,sBAAsB;gBAC7C,SAAS,EAAE,CAAC;gBACZ,YAAY,EAAE,CAAC;aAChB;YACD,YAAY,EAAE;gBACZ,EAAE,EAAE,YAAY;gBAChB,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAE,wBAAwB;gBAC7C,SAAS,EAAE,CAAC;gBACZ,YAAY,EAAE,CAAC;aAChB;YACD,SAAS,EAAE;gBACT,EAAE,EAAE,SAAS;gBACb,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAE,yBAAyB;gBAC5C,SAAS,EAAE,CAAC;gBACZ,YAAY,EAAE,CAAC;aAChB;YACD,SAAS,EAAE;gBACT,EAAE,EAAE,SAAS;gBACb,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,wBAAwB;gBACzC,SAAS,EAAE,CAAC;gBACZ,YAAY,EAAE,CAAC;aAChB;YACD,UAAU,EAAE;gBACV,EAAE,EAAE,UAAU;gBACd,QAAQ,EAAE,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAE,sBAAsB;gBACjD,SAAS,EAAE,CAAC;gBACZ,YAAY,EAAE,CAAC;aAChB;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1C,OAAO,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,UAAkB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC;YAElC,6CAA6C;YAC7C,IAAI,CAAC,gBAAgB,CAAC,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC;YAE/D,8BAA8B;YAC9B,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;gBACzC,UAAU,EAAE,UAAU;gBACtB,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,wBAAwB,CAAC,OAAkC;QACzD,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,OAAO,EAAE,CAAC;QAEjE,yCAAyC;QACzC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE/C,gCAAgC;QAChC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;YAC1C,GAAG,EAAE,oBAAoB;YACzB,KAAK,EAAE,IAAI,CAAC,gBAAgB;SAC7B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,QAAgB;QAC1B,IAAI,CAAC,wBAAwB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,SAAkB;QAChC,IAAI,CAAC,wBAAwB,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC;IAC/C,CAAC;CAEF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/core/EventBus.d.ts b/wwwroot/js/core/EventBus.d.ts new file mode 100644 index 0000000..93273d5 --- /dev/null +++ b/wwwroot/js/core/EventBus.d.ts @@ -0,0 +1,60 @@ +import { IEventLogEntry, IEventBus } from '../types/CalendarTypes'; +/** + * Central event dispatcher for calendar using DOM CustomEvents + * Provides logging and debugging capabilities + */ +export declare class EventBus implements IEventBus { + private eventLog; + private debug; + private listeners; + private logConfig; + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void; + /** + * Subscribe to an event once + */ + once(eventType: string, handler: EventListener): () => void; + /** + * Unsubscribe from an event + */ + off(eventType: string, handler: EventListener): void; + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType: string, detail?: unknown): boolean; + /** + * Log event with console grouping + */ + private logEventWithGrouping; + /** + * Extract category from event type + */ + private extractCategory; + /** + * Get styling for different categories + */ + private getCategoryStyle; + /** + * Configure logging for specific categories + */ + setLogConfig(config: { + [key: string]: boolean; + }): void; + /** + * Get current log configuration + */ + getLogConfig(): { + [key: string]: boolean; + }; + /** + * Get event history + */ + getEventLog(eventType?: string): IEventLogEntry[]; + /** + * Enable/disable debug mode + */ + setDebug(enabled: boolean): void; +} +export declare const eventBus: EventBus; diff --git a/wwwroot/js/core/EventBus.js b/wwwroot/js/core/EventBus.js new file mode 100644 index 0000000..07b721e --- /dev/null +++ b/wwwroot/js/core/EventBus.js @@ -0,0 +1,158 @@ +/** + * Central event dispatcher for calendar using DOM CustomEvents + * Provides logging and debugging capabilities + */ +export class EventBus { + constructor() { + this.eventLog = []; + this.debug = false; + this.listeners = new Set(); + // Log configuration for different categories + this.logConfig = { + calendar: true, + grid: true, + event: true, + scroll: true, + navigation: true, + view: true, + default: true + }; + } + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType, handler, options) { + document.addEventListener(eventType, handler, options); + // Track for cleanup + this.listeners.add({ eventType, handler, options }); + // Return unsubscribe function + return () => this.off(eventType, handler); + } + /** + * Subscribe to an event once + */ + once(eventType, handler) { + return this.on(eventType, handler, { once: true }); + } + /** + * Unsubscribe from an event + */ + off(eventType, handler) { + document.removeEventListener(eventType, handler); + // Remove from tracking + for (const listener of this.listeners) { + if (listener.eventType === eventType && listener.handler === handler) { + this.listeners.delete(listener); + break; + } + } + } + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType, detail = {}) { + // Validate eventType + if (!eventType) { + return false; + } + const event = new CustomEvent(eventType, { + detail: detail ?? {}, + bubbles: true, + cancelable: true + }); + // Log event with grouping + if (this.debug) { + this.logEventWithGrouping(eventType, detail); + } + this.eventLog.push({ + type: eventType, + detail: detail ?? {}, + timestamp: Date.now() + }); + // Emit on document (only DOM events now) + return !document.dispatchEvent(event); + } + /** + * Log event with console grouping + */ + logEventWithGrouping(eventType, detail) { + // Extract category from event type (e.g., 'calendar:datechanged' → 'calendar') + const category = this.extractCategory(eventType); + // Only log if category is enabled + if (!this.logConfig[category]) { + return; + } + // Get category emoji and color + const { emoji, color } = this.getCategoryStyle(category); + // Use collapsed group to reduce visual noise + } + /** + * Extract category from event type + */ + extractCategory(eventType) { + if (!eventType) { + return 'unknown'; + } + if (eventType.includes(':')) { + return eventType.split(':')[0]; + } + // Fallback: try to detect category from event name patterns + const lowerType = eventType.toLowerCase(); + if (lowerType.includes('grid') || lowerType.includes('rendered')) + return 'grid'; + if (lowerType.includes('event') || lowerType.includes('sync')) + return 'event'; + if (lowerType.includes('scroll')) + return 'scroll'; + if (lowerType.includes('nav') || lowerType.includes('date')) + return 'navigation'; + if (lowerType.includes('view')) + return 'view'; + return 'default'; + } + /** + * Get styling for different categories + */ + getCategoryStyle(category) { + const styles = { + calendar: { emoji: '🗓️', color: '#2196F3' }, + grid: { emoji: '📊', color: '#4CAF50' }, + event: { emoji: '📅', color: '#FF9800' }, + scroll: { emoji: '📜', color: '#9C27B0' }, + navigation: { emoji: '🧭', color: '#F44336' }, + view: { emoji: '👁️', color: '#00BCD4' }, + default: { emoji: '📢', color: '#607D8B' } + }; + return styles[category] || styles.default; + } + /** + * Configure logging for specific categories + */ + setLogConfig(config) { + this.logConfig = { ...this.logConfig, ...config }; + } + /** + * Get current log configuration + */ + getLogConfig() { + return { ...this.logConfig }; + } + /** + * Get event history + */ + getEventLog(eventType) { + if (eventType) { + return this.eventLog.filter(e => e.type === eventType); + } + return this.eventLog; + } + /** + * Enable/disable debug mode + */ + setDebug(enabled) { + this.debug = enabled; + } +} +// Create singleton instance +export const eventBus = new EventBus(); +//# sourceMappingURL=EventBus.js.map \ No newline at end of file diff --git a/wwwroot/js/core/EventBus.js.map b/wwwroot/js/core/EventBus.js.map new file mode 100644 index 0000000..36bb9bc --- /dev/null +++ b/wwwroot/js/core/EventBus.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventBus.js","sourceRoot":"","sources":["../../../src/core/EventBus.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/datasources/DateColumnDataSource.d.ts b/wwwroot/js/datasources/DateColumnDataSource.d.ts new file mode 100644 index 0000000..3807ff2 --- /dev/null +++ b/wwwroot/js/datasources/DateColumnDataSource.d.ts @@ -0,0 +1,55 @@ +import { IColumnDataSource } from '../types/ColumnDataSource'; +import { DateService } from '../utils/DateService'; +import { Configuration } from '../configurations/CalendarConfig'; +import { CalendarView } from '../types/CalendarTypes'; +/** + * DateColumnDataSource - Provides date-based columns + * + * Calculates which dates to display based on: + * - Current date + * - Current view (day/week/month) + * - Workweek settings + */ +export declare class DateColumnDataSource implements IColumnDataSource { + private dateService; + private config; + private currentDate; + private currentView; + constructor(dateService: DateService, config: Configuration, currentDate: Date, currentView: CalendarView); + /** + * Get columns (dates) to display + */ + getColumns(): Date[]; + /** + * Get type of datasource + */ + getType(): 'date' | 'resource'; + /** + * Update current date + */ + setCurrentDate(date: Date): void; + /** + * Update current view + */ + setCurrentView(view: CalendarView): void; + /** + * Get dates for week view based on workweek settings + */ + private getWeekDates; + /** + * Get all dates in current month + */ + private getMonthDates; + /** + * Get ISO week start (Monday) + */ + private getISOWeekStart; + /** + * Get month start + */ + private getMonthStart; + /** + * Get month end + */ + private getMonthEnd; +} diff --git a/wwwroot/js/datasources/DateColumnDataSource.js b/wwwroot/js/datasources/DateColumnDataSource.js new file mode 100644 index 0000000..eefe010 --- /dev/null +++ b/wwwroot/js/datasources/DateColumnDataSource.js @@ -0,0 +1,94 @@ +/** + * DateColumnDataSource - Provides date-based columns + * + * Calculates which dates to display based on: + * - Current date + * - Current view (day/week/month) + * - Workweek settings + */ +export class DateColumnDataSource { + constructor(dateService, config, currentDate, currentView) { + this.dateService = dateService; + this.config = config; + this.currentDate = currentDate; + this.currentView = currentView; + } + /** + * Get columns (dates) to display + */ + getColumns() { + switch (this.currentView) { + case 'week': + return this.getWeekDates(); + case 'month': + return this.getMonthDates(); + case 'day': + return [this.currentDate]; + default: + return this.getWeekDates(); + } + } + /** + * Get type of datasource + */ + getType() { + return 'date'; + } + /** + * Update current date + */ + setCurrentDate(date) { + this.currentDate = date; + } + /** + * Update current view + */ + setCurrentView(view) { + this.currentView = view; + } + /** + * Get dates for week view based on workweek settings + */ + getWeekDates() { + const weekStart = this.getISOWeekStart(this.currentDate); + const workWeekSettings = this.config.getWorkWeekSettings(); + return this.dateService.getWorkWeekDates(weekStart, workWeekSettings.workDays); + } + /** + * Get all dates in current month + */ + getMonthDates() { + const dates = []; + const monthStart = this.getMonthStart(this.currentDate); + const monthEnd = this.getMonthEnd(this.currentDate); + const totalDays = Math.ceil((monthEnd.getTime() - monthStart.getTime()) / (1000 * 60 * 60 * 24)) + 1; + for (let i = 0; i < totalDays; i++) { + dates.push(this.dateService.addDays(monthStart, i)); + } + return dates; + } + /** + * Get ISO week start (Monday) + */ + getISOWeekStart(date) { + const weekBounds = this.dateService.getWeekBounds(date); + return this.dateService.startOfDay(weekBounds.start); + } + /** + * Get month start + */ + getMonthStart(date) { + const year = date.getFullYear(); + const month = date.getMonth(); + return this.dateService.startOfDay(new Date(year, month, 1)); + } + /** + * Get month end + */ + getMonthEnd(date) { + const nextMonth = this.dateService.addMonths(date, 1); + const firstOfNextMonth = this.getMonthStart(nextMonth); + return this.dateService.endOfDay(this.dateService.addDays(firstOfNextMonth, -1)); + } +} +//# sourceMappingURL=DateColumnDataSource.js.map \ No newline at end of file diff --git a/wwwroot/js/datasources/DateColumnDataSource.js.map b/wwwroot/js/datasources/DateColumnDataSource.js.map new file mode 100644 index 0000000..b40c024 --- /dev/null +++ b/wwwroot/js/datasources/DateColumnDataSource.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateColumnDataSource.js","sourceRoot":"","sources":["../../../src/datasources/DateColumnDataSource.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/demo.js b/wwwroot/js/demo.js new file mode 100644 index 0000000..2ab50eb --- /dev/null +++ b/wwwroot/js/demo.js @@ -0,0 +1,6489 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = /* @__PURE__ */ __name(function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, "m"), v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: /* @__PURE__ */ __name(function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, "t"), a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = /* @__PURE__ */ __name(function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, "S"), w = /* @__PURE__ */ __name(function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, "t"), O = /* @__PURE__ */ __name(function(t2, e2) { + if (S(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, "O"), b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + __name(M2, "M"); + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) + return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = /* @__PURE__ */ __name(function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, "l"), $2 = /* @__PURE__ */ __name(function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, "$"), y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = /* @__PURE__ */ __name(function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }, "y"); + if ($2 === c) + return this.set(c, this.$M + r2); + if ($2 === h) + return this.set(h, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = /* @__PURE__ */ __name(function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, "h"), d2 = /* @__PURE__ */ __name(function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, "d"), $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, function(t3, r3) { + return r3 || function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + }(t3) || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = /* @__PURE__ */ __name(function() { + return b.m(y2, m3); + }, "D"); + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + }); + } +}); + +// node_modules/dayjs/plugin/utc.js +var require_utc = __commonJS({ + "node_modules/dayjs/plugin/utc.js"(exports, module) { + !function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + }(exports, function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var r = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2); + }; + var o = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else + o.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) + return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) + return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + }(s2), null === s2)) + return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2; + if (0 === u2) + return this.utc(f2); + var r2 = this.clone(); + if (f2) + return r2.$offset = u2, r2.$u = false, r2; + var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) + return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + }(exports, function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = /* @__PURE__ */ __name(function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + }(n2, i2); + return r2.formatToParts(o2); + }, "a"), u = /* @__PURE__ */ __name(function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, "u"), f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) + n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { + return "timezonename" === t3.type.toLowerCase(); + }); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) + return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) + return o(t2).tz(a2); + var s2 = function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) + return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/isoWeek.js +var require_isoWeek = __commonJS({ + "node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + }(exports, function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = /* @__PURE__ */ __name(function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, "a"), d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) + return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + }); + } +}); + +// node_modules/@novadi/core/dist/token.js +var tokenCounter = 0; +function Token(description) { + const id = ++tokenCounter; + const sym = Symbol(description ? `Token(${description})` : `Token#${id}`); + const token2 = { + symbol: sym, + description, + toString() { + return description ? `Token<${description}>` : `Token<#${id}>`; + } + }; + return token2; +} +__name(Token, "Token"); + +// node_modules/@novadi/core/dist/errors.js +var _ContainerError = class _ContainerError extends Error { + constructor(message) { + super(message); + this.name = "ContainerError"; + } +}; +__name(_ContainerError, "ContainerError"); +var ContainerError = _ContainerError; +var _BindingNotFoundError = class _BindingNotFoundError extends ContainerError { + constructor(tokenDescription, path = []) { + const pathStr = path.length > 0 ? ` + Dependency path: ${path.join(" -> ")}` : ""; + super(`Token "${tokenDescription}" is not bound or registered in the container.${pathStr}`); + this.name = "BindingNotFoundError"; + } +}; +__name(_BindingNotFoundError, "BindingNotFoundError"); +var BindingNotFoundError = _BindingNotFoundError; +var _CircularDependencyError = class _CircularDependencyError extends ContainerError { + constructor(path) { + super(`Circular dependency detected: ${path.join(" -> ")}`); + this.name = "CircularDependencyError"; + } +}; +__name(_CircularDependencyError, "CircularDependencyError"); +var CircularDependencyError = _CircularDependencyError; + +// node_modules/@novadi/core/dist/autowire.js +var paramNameCache = /* @__PURE__ */ new WeakMap(); +function extractParameterNames(constructor) { + const cached = paramNameCache.get(constructor); + if (cached) { + return cached; + } + const fnStr = constructor.toString(); + const match = fnStr.match(/constructor\s*\(([^)]*)\)/) || fnStr.match(/^[^(]*\(([^)]*)\)/); + if (!match || !match[1]) { + return []; + } + const params = match[1].split(",").map((param) => param.trim()).filter((param) => param.length > 0).map((param) => { + let name = param.split(/[:=]/)[0].trim(); + name = name.replace(/^((public|private|protected|readonly)\s+)+/, ""); + if (name.includes("{") || name.includes("[")) { + return null; + } + return name; + }).filter((name) => name !== null); + paramNameCache.set(constructor, params); + return params; +} +__name(extractParameterNames, "extractParameterNames"); +function resolveByMap(constructor, container2, options) { + if (!options.map) { + throw new Error("AutoWire map strategy requires options.map to be defined"); + } + const paramNames = extractParameterNames(constructor); + const resolvedDeps = []; + for (const paramName of paramNames) { + const resolver = options.map[paramName]; + if (resolver === void 0) { + if (options.strict) { + throw new Error(`Cannot resolve parameter "${paramName}" on ${constructor.name}. Not found in autowire map. Add it to the map: .autoWire({ map: { ${paramName}: ... } })`); + } else { + resolvedDeps.push(void 0); + } + continue; + } + if (typeof resolver === "function") { + resolvedDeps.push(resolver(container2)); + } else { + resolvedDeps.push(container2.resolve(resolver)); + } + } + return resolvedDeps; +} +__name(resolveByMap, "resolveByMap"); +function resolveByMapResolvers(_constructor, container2, options) { + if (!options.mapResolvers || options.mapResolvers.length === 0) { + return []; + } + const resolvedDeps = []; + for (let i = 0; i < options.mapResolvers.length; i++) { + const resolver = options.mapResolvers[i]; + if (resolver === void 0) { + resolvedDeps.push(void 0); + } else if (typeof resolver === "function") { + resolvedDeps.push(resolver(container2)); + } else { + resolvedDeps.push(container2.resolve(resolver)); + } + } + return resolvedDeps; +} +__name(resolveByMapResolvers, "resolveByMapResolvers"); +function autowire(constructor, container2, options) { + const opts = { + by: "paramName", + strict: false, + ...options + }; + if (opts.mapResolvers && opts.mapResolvers.length > 0) { + return resolveByMapResolvers(constructor, container2, opts); + } + if (opts.map && Object.keys(opts.map).length > 0) { + return resolveByMap(constructor, container2, opts); + } + return []; +} +__name(autowire, "autowire"); + +// node_modules/@novadi/core/dist/builder.js +var _RegistrationBuilder = class _RegistrationBuilder { + constructor(pending, registrations) { + this.registrations = registrations; + this.configs = []; + this.defaultLifetime = "singleton"; + this.pending = pending; + } + /** + * Bind this registration to a token or interface type + * + * @overload + * @param {Token} token - Explicit token for binding + * + * @overload + * @param {string} typeName - Interface type name (auto-generated by transformer) + */ + as(tokenOrTypeName) { + if (tokenOrTypeName && typeof tokenOrTypeName === "object" && "symbol" in tokenOrTypeName) { + const config = { + token: tokenOrTypeName, + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } else { + const config = { + token: null, + // Will be set during build() + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime, + interfaceType: tokenOrTypeName + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } + } + /** + * Register as default implementation for an interface + * Combines as() + asDefault() + */ + asDefaultInterface(typeName) { + this.as("TInterface", typeName); + return this.asDefault(); + } + /** + * Register as a keyed interface implementation + * Combines as() + keyed() + */ + asKeyedInterface(key, typeName) { + this.as("TInterface", typeName); + return this.keyed(key); + } + /** + * Register as multiple implemented interfaces + */ + asImplementedInterfaces(tokens) { + if (tokens.length === 0) { + return this; + } + if (this.configs.length > 0) { + for (const config of this.configs) { + config.lifetime = "singleton"; + config.additionalTokens = config.additionalTokens || []; + config.additionalTokens.push(...tokens); + } + return this; + } + const firstConfig = { + token: tokens[0], + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: "singleton" + }; + this.configs.push(firstConfig); + this.registrations.push(firstConfig); + for (let i = 1; i < tokens.length; i++) { + firstConfig.additionalTokens = firstConfig.additionalTokens || []; + firstConfig.additionalTokens.push(tokens[i]); + } + return this; + } + /** + * Set singleton lifetime (one instance for entire container) + */ + singleInstance() { + for (const config of this.configs) { + config.lifetime = "singleton"; + } + return this; + } + /** + * Set per-request lifetime (one instance per resolve call tree) + */ + instancePerRequest() { + for (const config of this.configs) { + config.lifetime = "per-request"; + } + return this; + } + /** + * Set transient lifetime (new instance every time) + * Alias for default behavior + */ + instancePerDependency() { + for (const config of this.configs) { + config.lifetime = "transient"; + } + return this; + } + /** + * Name this registration for named resolution + */ + named(name) { + for (const config of this.configs) { + config.name = name; + } + return this; + } + /** + * Key this registration for keyed resolution + */ + keyed(key) { + for (const config of this.configs) { + config.key = key; + } + return this; + } + /** + * Mark this as default registration + * Default registrations don't override existing ones + */ + asDefault() { + for (const config of this.configs) { + config.isDefault = true; + } + return this; + } + /** + * Only register if token not already registered + */ + ifNotRegistered() { + for (const config of this.configs) { + config.ifNotRegistered = true; + } + return this; + } + /** + * Specify parameter values for constructor (primitives and constants) + * Use this for non-DI parameters like strings, numbers, config values + */ + withParameters(parameters) { + for (const config of this.configs) { + config.parameterValues = parameters; + } + return this; + } + /** + * Enable automatic dependency injection (autowiring) + * Supports three strategies: paramName (default), map, and class + * + * @example + * ```ts + * // Strategy 1: paramName (default, requires non-minified code in dev) + * builder.registerType(EventBus).as().autoWire() + * + * // Strategy 2: map (minify-safe, explicit) + * builder.registerType(EventBus).as().autoWire({ + * map: { + * logger: (c) => c.resolveType() + * } + * }) + * + * // Strategy 3: class (requires build-time codegen) + * builder.registerType(EventBus).as().autoWire({ by: 'class' }) + * ``` + */ + autoWire(options) { + for (const config of this.configs) { + config.autowireOptions = options || { by: "paramName", strict: false }; + } + return this; + } +}; +__name(_RegistrationBuilder, "RegistrationBuilder"); +var RegistrationBuilder = _RegistrationBuilder; +var _Builder = class _Builder { + constructor(baseContainer) { + this.baseContainer = baseContainer; + this.registrations = []; + } + /** + * Register a class constructor + */ + registerType(constructor) { + const pending = { + type: "type", + value: null, + constructor + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a pre-created instance + */ + registerInstance(instance) { + const pending = { + type: "instance", + value: instance, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a factory function + */ + register(factory) { + const pending = { + type: "factory", + value: null, + factory, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a module (function that adds multiple registrations) + */ + module(moduleFunc) { + moduleFunc(this); + return this; + } + /** + * Resolve interface type names to tokens + * @internal + */ + resolveInterfaceTokens(container2) { + for (const config of this.registrations) { + if (config.interfaceType !== void 0 && !config.token) { + config.token = container2.interfaceToken(config.interfaceType); + } + } + } + /** + * Identify tokens that have non-default registrations + * @internal + */ + identifyNonDefaultTokens() { + const tokensWithNonDefaults = /* @__PURE__ */ new Set(); + for (const config of this.registrations) { + if (!config.isDefault && !config.name && config.key === void 0) { + tokensWithNonDefaults.add(config.token); + } + } + return tokensWithNonDefaults; + } + /** + * Check if registration should be skipped + * @internal + */ + shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens) { + if (config.isDefault && !config.name && config.key === void 0 && tokensWithNonDefaults.has(config.token)) { + return true; + } + if (config.ifNotRegistered && registeredTokens.has(config.token)) { + return true; + } + if (config.isDefault && registeredTokens.has(config.token)) { + return true; + } + return false; + } + /** + * Create binding token for registration (named, keyed, or multi) + * @internal + */ + createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations) { + if (config.name) { + const bindingToken = Token(`__named_${config.name}`); + namedRegistrations.set(config.name, { ...config, token: bindingToken }); + return bindingToken; + } else if (config.key !== void 0) { + const keyStr = typeof config.key === "symbol" ? config.key.toString() : config.key; + const bindingToken = Token(`__keyed_${keyStr}`); + keyedRegistrations.set(config.key, { ...config, token: bindingToken }); + return bindingToken; + } else { + if (multiRegistrations.has(config.token)) { + const bindingToken = Token(`__multi_${config.token.toString()}_${multiRegistrations.get(config.token).length}`); + multiRegistrations.get(config.token).push(bindingToken); + return bindingToken; + } else { + multiRegistrations.set(config.token, [config.token]); + return config.token; + } + } + } + /** + * Register additional interfaces for a config + * @internal + */ + registerAdditionalInterfaces(container2, config, bindingToken, registeredTokens) { + if (config.additionalTokens) { + for (const additionalToken of config.additionalTokens) { + container2.bindFactory(additionalToken, (c) => c.resolve(bindingToken), { lifetime: config.lifetime }); + registeredTokens.add(additionalToken); + } + } + } + /** + * Build the container with all registered bindings + */ + build() { + const container2 = this.baseContainer.createChild(); + this.resolveInterfaceTokens(container2); + const registeredTokens = /* @__PURE__ */ new Set(); + const namedRegistrations = /* @__PURE__ */ new Map(); + const keyedRegistrations = /* @__PURE__ */ new Map(); + const multiRegistrations = /* @__PURE__ */ new Map(); + const tokensWithNonDefaults = this.identifyNonDefaultTokens(); + for (const config of this.registrations) { + if (this.shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens)) { + continue; + } + const bindingToken = this.createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations); + this.applyRegistration(container2, { ...config, token: bindingToken }); + registeredTokens.add(config.token); + this.registerAdditionalInterfaces(container2, config, bindingToken, registeredTokens); + } + ; + container2.__namedRegistrations = namedRegistrations; + container2.__keyedRegistrations = keyedRegistrations; + container2.__multiRegistrations = multiRegistrations; + return container2; + } + /** + * Analyze constructor to detect dependencies + * @internal + */ + analyzeConstructor(constructor) { + const constructorStr = constructor.toString(); + const hasDependencies = /constructor\s*\([^)]+\)/.test(constructorStr); + return { hasDependencies }; + } + /** + * Create optimized factory for zero-dependency constructors + * @internal + */ + createOptimizedFactory(container2, config, options) { + if (config.lifetime === "singleton") { + const instance = new config.constructor(); + container2.bindValue(config.token, instance); + } else if (config.lifetime === "transient") { + const ctor = config.constructor; + const fastFactory = /* @__PURE__ */ __name(() => new ctor(), "fastFactory"); + container2.fastTransientCache.set(config.token, fastFactory); + container2.bindFactory(config.token, fastFactory, options); + } else { + const factory = /* @__PURE__ */ __name(() => new config.constructor(), "factory"); + container2.bindFactory(config.token, factory, options); + } + } + /** + * Create autowire factory + * @internal + */ + createAutoWireFactory(container2, config, options) { + const factory = /* @__PURE__ */ __name((c) => { + const resolvedDeps = autowire(config.constructor, c, config.autowireOptions); + return new config.constructor(...resolvedDeps); + }, "factory"); + container2.bindFactory(config.token, factory, options); + } + /** + * Create withParameters factory + * @internal + */ + createParameterFactory(container2, config, options) { + const factory = /* @__PURE__ */ __name(() => { + const values = Object.values(config.parameterValues); + return new config.constructor(...values); + }, "factory"); + container2.bindFactory(config.token, factory, options); + } + /** + * Apply type registration (class constructor) + * @internal + */ + applyTypeRegistration(container2, config, options) { + const { hasDependencies } = this.analyzeConstructor(config.constructor); + if (!hasDependencies && !config.autowireOptions && !config.parameterValues) { + this.createOptimizedFactory(container2, config, options); + return; + } + if (config.autowireOptions) { + this.createAutoWireFactory(container2, config, options); + return; + } + if (config.parameterValues) { + this.createParameterFactory(container2, config, options); + return; + } + if (hasDependencies) { + const className = config.constructor.name || "UnnamedClass"; + throw new Error(`Service "${className}" has constructor dependencies but no autowiring configuration. + +Solutions: + 1. \u2B50 Use the NovaDI transformer (recommended): + - Add "@novadi/core/unplugin" to your build config + - Transformer automatically generates .autoWire() for all dependencies + + 2. Add manual autowiring: + .autoWire({ map: { /* param: resolver */ } }) + + 3. Use a factory function: + .register((c) => new ${className}(...)) + +See docs: https://github.com/janus007/NovaDI#autowire`); + } + const factory = /* @__PURE__ */ __name(() => new config.constructor(), "factory"); + container2.bindFactory(config.token, factory, options); + } + applyRegistration(container2, config) { + const options = { lifetime: config.lifetime }; + switch (config.type) { + case "instance": + container2.bindValue(config.token, config.value); + break; + case "factory": + container2.bindFactory(config.token, config.factory, options); + break; + case "type": + this.applyTypeRegistration(container2, config, options); + break; + } + } +}; +__name(_Builder, "Builder"); +var Builder = _Builder; + +// node_modules/@novadi/core/dist/container.js +function isDisposable(obj) { + return obj && typeof obj.dispose === "function"; +} +__name(isDisposable, "isDisposable"); +var _ResolutionContext = class _ResolutionContext { + constructor() { + this.resolvingStack = /* @__PURE__ */ new Set(); + this.perRequestCache = /* @__PURE__ */ new Map(); + } + isResolving(token2) { + return this.resolvingStack.has(token2); + } + enterResolve(token2) { + this.resolvingStack.add(token2); + } + exitResolve(token2) { + this.resolvingStack.delete(token2); + this.path = void 0; + } + getPath() { + if (!this.path) { + this.path = Array.from(this.resolvingStack).map((t) => t.toString()); + } + return [...this.path]; + } + cachePerRequest(token2, instance) { + this.perRequestCache.set(token2, instance); + } + getPerRequest(token2) { + return this.perRequestCache.get(token2); + } + hasPerRequest(token2) { + return this.perRequestCache.has(token2); + } + /** + * Reset context for reuse in object pool + * Performance: Reusing contexts avoids heap allocations + */ + reset() { + this.resolvingStack.clear(); + this.perRequestCache.clear(); + this.path = void 0; + } +}; +__name(_ResolutionContext, "ResolutionContext"); +var ResolutionContext = _ResolutionContext; +var _ResolutionContextPool = class _ResolutionContextPool { + constructor() { + this.pool = []; + this.maxSize = 10; + } + acquire() { + const context = this.pool.pop(); + if (context) { + context.reset(); + return context; + } + return new ResolutionContext(); + } + release(context) { + if (this.pool.length < this.maxSize) { + this.pool.push(context); + } + } +}; +__name(_ResolutionContextPool, "ResolutionContextPool"); +var ResolutionContextPool = _ResolutionContextPool; +var _Container = class _Container { + constructor(parent) { + this.bindings = /* @__PURE__ */ new Map(); + this.singletonCache = /* @__PURE__ */ new Map(); + this.singletonOrder = []; + this.interfaceRegistry = /* @__PURE__ */ new Map(); + this.interfaceTokenCache = /* @__PURE__ */ new Map(); + this.fastTransientCache = /* @__PURE__ */ new Map(); + this.ultraFastSingletonCache = /* @__PURE__ */ new Map(); + this.parent = parent; + } + /** + * Bind a pre-created value to a token + */ + bindValue(token2, value) { + this.bindings.set(token2, { + type: "value", + lifetime: "singleton", + value, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a factory function to a token + */ + bindFactory(token2, factory, options) { + this.bindings.set(token2, { + type: "factory", + lifetime: options?.lifetime || "transient", + factory, + dependencies: options?.dependencies, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a class constructor to a token + */ + bindClass(token2, constructor, options) { + const binding = { + type: "class", + lifetime: options?.lifetime || "transient", + constructor, + dependencies: options?.dependencies + }; + this.bindings.set(token2, binding); + this.invalidateBindingCache(); + if (binding.lifetime === "transient" && (!binding.dependencies || binding.dependencies.length === 0)) { + this.fastTransientCache.set(token2, () => new constructor()); + } + } + /** + * Resolve a dependency synchronously + * Performance optimized with multiple fast paths + */ + resolve(token2) { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) { + return cached; + } + if (this.currentContext) { + return this.resolveWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return this.resolveWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * SPECIALIZED: Ultra-fast singleton resolve (no safety checks) + * Use ONLY when you're 100% sure the token is a registered singleton + * @internal For performance-critical paths only + */ + resolveSingletonUnsafe(token2) { + return this.ultraFastSingletonCache.get(token2) ?? this.singletonCache.get(token2); + } + /** + * SPECIALIZED: Fast transient resolve for zero-dependency classes + * Skips all context creation and circular dependency checks + * @internal For performance-critical paths only + */ + resolveTransientSimple(token2) { + const factory = this.fastTransientCache.get(token2); + if (factory) { + return factory(); + } + return this.resolve(token2); + } + /** + * SPECIALIZED: Batch resolve multiple dependencies at once + * More efficient than multiple individual resolves + */ + resolveBatch(tokens) { + const wasResolving = !!this.currentContext; + const context = this.currentContext || _Container.contextPool.acquire(); + if (!wasResolving) { + this.currentContext = context; + } + try { + const results = tokens.map((token2) => { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) + return cached; + return this.resolveWithContext(token2, context); + }); + return results; + } finally { + if (!wasResolving) { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + } + /** + * Resolve a dependency asynchronously (supports async factories) + */ + async resolveAsync(token2) { + if (this.currentContext) { + return this.resolveAsyncWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return await this.resolveAsyncWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * Try to get instance from all cache levels + * Returns undefined if not cached + * @internal + */ + tryGetFromCaches(token2) { + const ultraFast = this.ultraFastSingletonCache.get(token2); + if (ultraFast !== void 0) { + return ultraFast; + } + if (this.singletonCache.has(token2)) { + const cached = this.singletonCache.get(token2); + this.ultraFastSingletonCache.set(token2, cached); + return cached; + } + const fastFactory = this.fastTransientCache.get(token2); + if (fastFactory) { + return fastFactory(); + } + return void 0; + } + /** + * Cache instance based on lifetime strategy + * @internal + */ + cacheInstance(token2, instance, lifetime, context) { + if (lifetime === "singleton") { + this.singletonCache.set(token2, instance); + this.singletonOrder.push(token2); + this.ultraFastSingletonCache.set(token2, instance); + } else if (lifetime === "per-request" && context) { + context.cachePerRequest(token2, instance); + } + } + /** + * Validate and get binding with circular dependency check + * Returns binding or throws error + * @internal + */ + validateAndGetBinding(token2, context) { + if (context.isResolving(token2)) { + throw new CircularDependencyError([...context.getPath(), token2.toString()]); + } + const binding = this.getBinding(token2); + if (!binding) { + throw new BindingNotFoundError(token2.toString(), context.getPath()); + } + return binding; + } + /** + * Instantiate from binding synchronously + * @internal + */ + instantiateBindingSync(binding, token2, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + const result = binding.factory(this); + if (result instanceof Promise) { + throw new Error(`Async factory detected for ${token2.toString()}. Use resolveAsync() instead.`); + } + return result; + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = deps.map((dep) => this.resolveWithContext(dep, context)); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Instantiate from binding asynchronously + * @internal + */ + async instantiateBindingAsync(binding, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + return await Promise.resolve(binding.factory(this)); + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = await Promise.all(deps.map((dep) => this.resolveAsyncWithContext(dep, context))); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Create a child container that inherits bindings from this container + */ + createChild() { + return new _Container(this); + } + /** + * Dispose all singleton instances in reverse registration order + */ + async dispose() { + const errors = []; + for (let i = this.singletonOrder.length - 1; i >= 0; i--) { + const token2 = this.singletonOrder[i]; + const instance = this.singletonCache.get(token2); + if (instance && isDisposable(instance)) { + try { + await instance.dispose(); + } catch (error) { + errors.push(error); + } + } + } + this.singletonCache.clear(); + this.singletonOrder.length = 0; + } + /** + * Create a fluent builder for registering dependencies + */ + builder() { + return new Builder(this); + } + /** + * Resolve a named service + */ + resolveNamed(name) { + const namedRegistrations = this.__namedRegistrations; + if (!namedRegistrations) { + throw new Error(`Named service "${name}" not found. No named registrations exist.`); + } + const config = namedRegistrations.get(name); + if (!config) { + throw new Error(`Named service "${name}" not found`); + } + return this.resolve(config.token); + } + /** + * Resolve a keyed service + */ + resolveKeyed(key) { + const keyedRegistrations = this.__keyedRegistrations; + if (!keyedRegistrations) { + throw new Error(`Keyed service not found. No keyed registrations exist.`); + } + const config = keyedRegistrations.get(key); + if (!config) { + const keyStr = typeof key === "symbol" ? key.toString() : `"${key}"`; + throw new Error(`Keyed service ${keyStr} not found`); + } + return this.resolve(config.token); + } + /** + * Resolve all registrations for a token + */ + resolveAll(token2) { + const multiRegistrations = this.__multiRegistrations; + if (!multiRegistrations) { + return []; + } + const tokens = multiRegistrations.get(token2); + if (!tokens || tokens.length === 0) { + return []; + } + return tokens.map((t) => this.resolve(t)); + } + /** + * Get registry information for debugging/visualization + * Returns array of binding information + */ + getRegistry() { + const registry = []; + this.bindings.forEach((binding, token2) => { + registry.push({ + token: token2.description || token2.symbol.toString(), + type: binding.type, + lifetime: binding.lifetime, + dependencies: binding.dependencies?.map((d) => d.description || d.symbol.toString()) + }); + }); + return registry; + } + /** + * Get or create a token for an interface type + * Uses a type name hash as key for the interface registry + */ + interfaceToken(typeName) { + const key = typeName || `Interface_${Math.random().toString(36).substr(2, 9)}`; + if (this.interfaceRegistry.has(key)) { + return this.interfaceRegistry.get(key); + } + if (this.parent) { + const parentToken = this.parent.interfaceToken(key); + return parentToken; + } + const token2 = Token(key); + this.interfaceRegistry.set(key, token2); + return token2; + } + /** + * Resolve a dependency by interface type without explicit token + */ + resolveType(typeName) { + const key = typeName || ""; + let token2 = this.interfaceTokenCache.get(key); + if (!token2) { + token2 = this.interfaceToken(typeName); + this.interfaceTokenCache.set(key, token2); + } + return this.resolve(token2); + } + /** + * Resolve a keyed interface + */ + resolveTypeKeyed(key, _typeName) { + return this.resolveKeyed(key); + } + /** + * Resolve all registrations for an interface type + */ + resolveTypeAll(typeName) { + const token2 = this.interfaceToken(typeName); + return this.resolveAll(token2); + } + /** + * Internal: Resolve with context for circular dependency detection + */ + resolveWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = this.instantiateBindingSync(binding, token2, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Internal: Async resolve with context + */ + async resolveAsyncWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = await this.instantiateBindingAsync(binding, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Get binding from this container or parent chain + * Performance optimized: Uses flat cache to avoid recursive parent lookups + */ + getBinding(token2) { + if (!this.bindingCache) { + this.buildBindingCache(); + } + return this.bindingCache.get(token2); + } + /** + * Build flat cache of all bindings including parent chain + * This converts O(n) parent chain traversal to O(1) lookup + */ + buildBindingCache() { + this.bindingCache = /* @__PURE__ */ new Map(); + let current = this; + while (current) { + current.bindings.forEach((binding, token2) => { + if (!this.bindingCache.has(token2)) { + this.bindingCache.set(token2, binding); + } + }); + current = current.parent; + } + } + /** + * Invalidate binding cache when new bindings are added + * Called by bindValue, bindFactory, bindClass + */ + invalidateBindingCache() { + this.bindingCache = void 0; + this.ultraFastSingletonCache.clear(); + } +}; +__name(_Container, "Container"); +var Container = _Container; +Container.contextPool = new ResolutionContextPool(); + +// src/features/date/DateRenderer.ts +var _DateRenderer = class _DateRenderer { + constructor(dateService) { + this.dateService = dateService; + this.type = "date"; + } + render(context) { + const dates = context.filter["date"] || []; + const resourceIds = context.filter["resource"] || []; + const dateGrouping = context.groupings?.find((g) => g.type === "date"); + const hideHeader = dateGrouping?.hideHeader === true; + const iterations = resourceIds.length || 1; + let columnCount = 0; + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + const segments = { date: dateStr }; + if (resourceId) + segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + const header = document.createElement("swp-day-header"); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = "true"; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, "short")} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + const column = document.createElement("swp-day-column"); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ""; + context.columnContainer.appendChild(column); + columnCount++; + } + } + const container2 = context.columnContainer.closest("swp-calendar-container"); + if (container2) { + container2.style.setProperty("--grid-columns", String(columnCount)); + } + } +}; +__name(_DateRenderer, "DateRenderer"); +var DateRenderer = _DateRenderer; + +// src/core/DateService.ts +var import_dayjs = __toESM(require_dayjs_min(), 1); +var import_utc = __toESM(require_utc(), 1); +var import_timezone = __toESM(require_timezone(), 1); +var import_isoWeek = __toESM(require_isoWeek(), 1); +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_timezone.default); +import_dayjs.default.extend(import_isoWeek.default); +var _DateService = class _DateService { + constructor(config, baseDate) { + this.config = config; + this.timezone = config.timezone; + this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)(); + } + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date) { + this.baseDate = (0, import_dayjs.default)(date); + } + /** + * Get the current base date (either fixed or today) + */ + getBaseDate() { + return this.baseDate.toDate(); + } + parseISO(isoString) { + return (0, import_dayjs.default)(isoString).toDate(); + } + getDayName(date, format = "short") { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + /** + * Get dates starting from a day offset + * @param dayOffset - Day offset from base date + * @param count - Number of consecutive days to return + * @returns Array of date strings in YYYY-MM-DD format + */ + getDatesFromOffset(dayOffset, count) { + const startDate = this.baseDate.add(dayOffset, "day"); + return Array.from({ length: count }, (_, i) => startDate.add(i, "day").format("YYYY-MM-DD")); + } + /** + * Get specific weekdays from the week containing the offset date + * @param dayOffset - Day offset from base date + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkDaysFromOffset(dayOffset, workDays) { + const targetDate = this.baseDate.add(dayOffset, "day"); + const monday = targetDate.startOf("week").add(1, "day"); + return workDays.map((isoDay) => { + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, "day").format("YYYY-MM-DD"); + }); + } + // Legacy methods for backwards compatibility + getWeekDates(weekOffset = 0, days = 7) { + return this.getDatesFromOffset(weekOffset * 7, days); + } + getWorkWeekDates(weekOffset, workDays) { + return this.getWorkDaysFromOffset(weekOffset * 7, workDays); + } + // ============================================ + // FORMATTING + // ============================================ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? "HH:mm:ss" : "HH:mm"; + return (0, import_dayjs.default)(date).format(pattern); + } + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + formatDate(date) { + return (0, import_dayjs.default)(date).format("YYYY-MM-DD"); + } + getDateKey(date) { + return this.formatDate(date); + } + // ============================================ + // COLUMN KEY + // ============================================ + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments) { + const date = segments.date; + const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v); + return date ? [date, ...others].join(":") : others.join(":"); + } + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey) { + const parts = columnKey.split(":"); + return { + date: parts[0], + resource: parts[1] + }; + } + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey) { + return columnKey.split(":")[0]; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + timeToMinutes(timeString) { + const parts = timeString.split(":").map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm"); + } + getMinutesSinceMidnight(date) { + const d = (0, import_dayjs.default)(date); + return d.hour() * 60 + d.minute(); + } + // ============================================ + // UTC CONVERSIONS + // ============================================ + toUTC(localDate) { + return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString(); + } + fromUTC(utcString) { + return import_dayjs.default.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // DATE CREATION + // ============================================ + createDateAtTime(baseDate, timeString) { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate(); + } + getISOWeekDay(date) { + return (0, import_dayjs.default)(date).isoWeekday(); + } +}; +__name(_DateService, "DateService"); +var DateService = _DateService; + +// src/core/BaseGroupingRenderer.ts +var _BaseGroupingRenderer = class _BaseGroupingRenderer { + /** + * Main render method - handles common logic + */ + async render(context) { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) + return; + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter["date"]?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter((id) => childIds.includes(id)).length; + const colspan = childCount * dateCount; + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + this.renderHeader(entity, header, context); + context.headerContainer.appendChild(header); + } + } + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + renderHeader(entity, header, _context) { + header.textContent = this.getDisplayName(entity); + } + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + createHeader(entity, context) { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +}; +__name(_BaseGroupingRenderer, "BaseGroupingRenderer"); +var BaseGroupingRenderer = _BaseGroupingRenderer; + +// src/features/resource/ResourceRenderer.ts +var _ResourceRenderer = class _ResourceRenderer extends BaseGroupingRenderer { + constructor(resourceService) { + super(); + this.resourceService = resourceService; + this.type = "resource"; + this.config = { + elementTag: "swp-resource-header", + idAttribute: "resourceId", + colspanVar: "--resource-cols" + }; + } + getEntities(ids) { + return this.resourceService.getByIds(ids); + } + getDisplayName(entity) { + return entity.displayName; + } + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context) { + const resourceIds = context.filter["resource"] || []; + const dateCount = context.filter["date"]?.length || 1; + let orderedResourceIds; + if (context.parentChildMap) { + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + const resources = await this.getEntities(orderedResourceIds); + const resourceMap = new Map(resources.map((r) => [r.id, r])); + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) + continue; + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +}; +__name(_ResourceRenderer, "ResourceRenderer"); +var ResourceRenderer = _ResourceRenderer; + +// src/features/team/TeamRenderer.ts +var _TeamRenderer = class _TeamRenderer extends BaseGroupingRenderer { + constructor(teamService) { + super(); + this.teamService = teamService; + this.type = "team"; + this.config = { + elementTag: "swp-team-header", + idAttribute: "teamId", + colspanVar: "--team-cols" + }; + } + getEntities(ids) { + return this.teamService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_TeamRenderer, "TeamRenderer"); +var TeamRenderer = _TeamRenderer; + +// src/features/department/DepartmentRenderer.ts +var _DepartmentRenderer = class _DepartmentRenderer extends BaseGroupingRenderer { + constructor(departmentService) { + super(); + this.departmentService = departmentService; + this.type = "department"; + this.config = { + elementTag: "swp-department-header", + idAttribute: "departmentId", + colspanVar: "--department-cols" + }; + } + getEntities(ids) { + return this.departmentService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_DepartmentRenderer, "DepartmentRenderer"); +var DepartmentRenderer = _DepartmentRenderer; + +// src/core/RenderBuilder.ts +function buildPipeline(renderers) { + return { + async run(context) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} +__name(buildPipeline, "buildPipeline"); + +// src/core/FilterTemplate.ts +var _FilterTemplate = class _FilterTemplate { + constructor(dateService, entityResolver) { + this.dateService = dateService; + this.entityResolver = entityResolver; + this.fields = []; + } + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty, derivedFrom) { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + parseDotNotation(idProperty) { + if (!idProperty.includes(".")) + return null; + const [entityType, property] = idProperty.split("."); + return { + entityType, + property, + foreignKey: entityType + "Id" + // Convention: resource → resourceId + }; + } + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + getDatasetKey(idProperty) { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; + } + return idProperty; + } + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column) { + return this.fields.map((f) => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ""; + }).join(":"); + } + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event) { + const eventRecord = event; + return this.fields.map((f) => { + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + if (f.derivedFrom) { + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ""); + } + return String(eventRecord[f.idProperty] || ""); + }).join(":"); + } + /** + * Resolve dot-notation reference via EntityResolver + */ + resolveDotNotation(eventRecord, dotNotation) { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ""; + } + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) + return ""; + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) + return ""; + return String(entity[dotNotation.property] || ""); + } + /** + * Match event mod kolonne + */ + matches(event, column) { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +}; +__name(_FilterTemplate, "FilterTemplate"); +var FilterTemplate = _FilterTemplate; + +// src/core/CalendarOrchestrator.ts +var _CalendarOrchestrator = class _CalendarOrchestrator { + constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) { + this.allRenderers = allRenderers; + this.eventRenderer = eventRenderer; + this.scheduleRenderer = scheduleRenderer; + this.headerDrawerRenderer = headerDrawerRenderer; + this.dateService = dateService; + this.entityServices = entityServices; + } + async render(viewConfig, container2) { + const headerContainer = container2.querySelector("swp-calendar-header"); + const columnContainer = container2.querySelector("swp-day-columns"); + if (!headerContainer || !columnContainer) { + throw new Error("Missing swp-calendar-header or swp-day-columns"); + } + const filter = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + headerContainer.innerHTML = ""; + columnContainer.innerHTML = ""; + const levels = viewConfig.groupings.map((g) => g.type).join(" "); + headerContainer.dataset.levels = levels; + const activeRenderers = this.selectRenderers(viewConfig); + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + await this.scheduleRenderer.render(container2, filter); + await this.eventRenderer.render(container2, filter, filterTemplate); + await this.headerDrawerRenderer.render(container2, filter, filterTemplate); + } + selectRenderers(viewConfig) { + const types = viewConfig.groupings.map((g) => g.type); + return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0); + } + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + async resolveBelongsTo(groupings, filter) { + const childGrouping = groupings.find((g) => g.belongsTo); + if (!childGrouping?.belongsTo) + return {}; + const [entityType, property] = childGrouping.belongsTo.split("."); + if (!entityType || !property) + return {}; + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) + return {}; + const service = this.entityServices.find((s) => s.entityType.toLowerCase() === entityType); + if (!service) + return {}; + const allEntities = await service.getAll(); + const entities = allEntities.filter((e) => parentIds.includes(e.id)); + const map = {}; + for (const entity of entities) { + const entityRecord = entity; + const children = entityRecord[property] || []; + map[entityRecord.id] = children; + } + return { parentChildMap: map, childType: childGrouping.type }; + } +}; +__name(_CalendarOrchestrator, "CalendarOrchestrator"); +var CalendarOrchestrator = _CalendarOrchestrator; + +// src/core/NavigationAnimator.ts +var _NavigationAnimator = class _NavigationAnimator { + constructor(headerTrack, contentTrack, headerDrawer) { + this.headerTrack = headerTrack; + this.contentTrack = contentTrack; + this.headerDrawer = headerDrawer; + } + async slide(direction, renderFn) { + const out = direction === "left" ? "-100%" : "100%"; + const into = direction === "left" ? "100%" : "-100%"; + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + async animateOut(translate) { + const animations = [ + this.headerTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished, + this.contentTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished + ]; + if (this.headerDrawer) { + animations.push(this.headerDrawer.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished); + } + await Promise.all(animations); + } + async animateIn(translate) { + const animations = [ + this.headerTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished, + this.contentTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished + ]; + if (this.headerDrawer) { + animations.push(this.headerDrawer.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished); + } + await Promise.all(animations); + } +}; +__name(_NavigationAnimator, "NavigationAnimator"); +var NavigationAnimator = _NavigationAnimator; + +// src/core/CalendarEvents.ts +var CalendarEvents = { + // Command events (host → calendar) + CMD_NAVIGATE_PREV: "calendar:cmd:navigate:prev", + CMD_NAVIGATE_NEXT: "calendar:cmd:navigate:next", + CMD_DRAWER_TOGGLE: "calendar:cmd:drawer:toggle", + CMD_RENDER: "calendar:cmd:render", + CMD_WORKWEEK_CHANGE: "calendar:cmd:workweek:change", + CMD_VIEW_UPDATE: "calendar:cmd:view:update" +}; + +// src/core/CalendarApp.ts +var _CalendarApp = class _CalendarApp { + constructor(orchestrator, timeAxisRenderer, dateService, scrollManager, headerDrawerManager, dragDropManager, edgeScrollManager, resizeManager, headerDrawerRenderer, eventPersistenceManager, settingsService, viewConfigService, eventBus) { + this.orchestrator = orchestrator; + this.timeAxisRenderer = timeAxisRenderer; + this.dateService = dateService; + this.scrollManager = scrollManager; + this.headerDrawerManager = headerDrawerManager; + this.dragDropManager = dragDropManager; + this.edgeScrollManager = edgeScrollManager; + this.resizeManager = resizeManager; + this.headerDrawerRenderer = headerDrawerRenderer; + this.eventPersistenceManager = eventPersistenceManager; + this.settingsService = settingsService; + this.viewConfigService = viewConfigService; + this.eventBus = eventBus; + this.dayOffset = 0; + this.currentViewId = "simple"; + this.workweekPreset = null; + this.groupingOverrides = /* @__PURE__ */ new Map(); + } + async init(container2) { + this.container = container2; + const gridSettings = await this.settingsService.getGridSettings(); + if (!gridSettings) { + throw new Error("GridSettings not found"); + } + this.workweekPreset = await this.settingsService.getDefaultWorkweekPreset(); + this.animator = new NavigationAnimator(container2.querySelector("swp-header-track"), container2.querySelector("swp-content-track"), container2.querySelector("swp-header-drawer")); + this.timeAxisRenderer.render(container2.querySelector("#time-axis"), gridSettings.dayStartHour, gridSettings.dayEndHour); + this.scrollManager.init(container2); + this.headerDrawerManager.init(container2); + this.dragDropManager.init(container2); + this.resizeManager.init(container2); + const scrollableContent = container2.querySelector("swp-scrollable-content"); + this.edgeScrollManager.init(scrollableContent); + this.setupEventListeners(); + this.emitStatus("ready"); + } + setupEventListeners() { + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_PREV, () => { + this.handleNavigatePrev(); + }); + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_NEXT, () => { + this.handleNavigateNext(); + }); + this.eventBus.on(CalendarEvents.CMD_DRAWER_TOGGLE, () => { + this.headerDrawerManager.toggle(); + }); + this.eventBus.on(CalendarEvents.CMD_RENDER, (e) => { + const { viewId } = e.detail; + this.handleRenderCommand(viewId); + }); + this.eventBus.on(CalendarEvents.CMD_WORKWEEK_CHANGE, (e) => { + const { presetId } = e.detail; + this.handleWorkweekChange(presetId); + }); + this.eventBus.on(CalendarEvents.CMD_VIEW_UPDATE, (e) => { + const { type, values } = e.detail; + this.handleViewUpdate(type, values); + }); + } + async handleRenderCommand(viewId) { + this.currentViewId = viewId; + await this.render(); + this.emitStatus("rendered", { viewId }); + } + async handleNavigatePrev() { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset -= step; + await this.animator.slide("right", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleNavigateNext() { + const step = this.workweekPreset?.periodDays ?? 7; + this.dayOffset += step; + await this.animator.slide("left", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleWorkweekChange(presetId) { + const preset = await this.settingsService.getWorkweekPreset(presetId); + if (preset) { + this.workweekPreset = preset; + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + } + async handleViewUpdate(type, values) { + this.groupingOverrides.set(type, values); + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async render() { + const storedConfig = await this.viewConfigService.getById(this.currentViewId); + if (!storedConfig) { + this.emitStatus("error", { message: `ViewConfig not found: ${this.currentViewId}` }); + return; + } + const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5]; + const periodDays = this.workweekPreset?.periodDays ?? 7; + const dates = periodDays === 1 ? this.dateService.getDatesFromOffset(this.dayOffset, workDays.length) : this.dateService.getWorkDaysFromOffset(this.dayOffset, workDays); + const viewConfig = { + ...storedConfig, + groupings: storedConfig.groupings.map((g) => { + if (g.type === "date") { + return { ...g, values: dates }; + } + const override = this.groupingOverrides.get(g.type); + if (override) { + return { ...g, values: override }; + } + return g; + }) + }; + await this.orchestrator.render(viewConfig, this.container); + } + emitStatus(status, detail) { + this.container.dispatchEvent(new CustomEvent(`calendar:status:${status}`, { + detail, + bubbles: true + })); + } +}; +__name(_CalendarApp, "CalendarApp"); +var CalendarApp = _CalendarApp; + +// src/features/timeaxis/TimeAxisRenderer.ts +var _TimeAxisRenderer = class _TimeAxisRenderer { + render(container2, startHour = 6, endHour = 20) { + container2.innerHTML = ""; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement("swp-hour-marker"); + marker.textContent = `${hour.toString().padStart(2, "0")}:00`; + container2.appendChild(marker); + } + } +}; +__name(_TimeAxisRenderer, "TimeAxisRenderer"); +var TimeAxisRenderer = _TimeAxisRenderer; + +// src/core/ScrollManager.ts +var _ScrollManager = class _ScrollManager { + init(container2) { + this.scrollableContent = container2.querySelector("swp-scrollable-content"); + this.timeAxisContent = container2.querySelector("swp-time-axis-content"); + this.calendarHeader = container2.querySelector("swp-calendar-header"); + this.headerDrawer = container2.querySelector("swp-header-drawer"); + this.headerViewport = container2.querySelector("swp-header-viewport"); + this.headerSpacer = container2.querySelector("swp-header-spacer"); + this.scrollableContent.addEventListener("scroll", () => this.onScroll()); + this.resizeObserver = new ResizeObserver(() => this.syncHeaderSpacerHeight()); + this.resizeObserver.observe(this.headerViewport); + this.syncHeaderSpacerHeight(); + } + syncHeaderSpacerHeight() { + const computedHeight = getComputedStyle(this.headerViewport).height; + this.headerSpacer.style.height = computedHeight; + } + onScroll() { + const { scrollTop, scrollLeft } = this.scrollableContent; + this.timeAxisContent.style.transform = `translateY(-${scrollTop}px)`; + this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`; + this.headerDrawer.style.transform = `translateX(-${scrollLeft}px)`; + } +}; +__name(_ScrollManager, "ScrollManager"); +var ScrollManager = _ScrollManager; + +// src/core/HeaderDrawerManager.ts +var _HeaderDrawerManager = class _HeaderDrawerManager { + constructor() { + this.expanded = false; + this.currentRows = 0; + this.rowHeight = 25; + this.duration = 200; + } + init(container2) { + this.drawer = container2.querySelector("swp-header-drawer"); + if (!this.drawer) + console.error("HeaderDrawerManager: swp-header-drawer not found"); + } + toggle() { + this.expanded ? this.collapse() : this.expand(); + } + /** + * Expand drawer to single row (legacy support) + */ + expand() { + this.expandToRows(1); + } + /** + * Expand drawer to fit specified number of rows + */ + expandToRows(rowCount) { + const targetHeight = rowCount * this.rowHeight; + const currentHeight = this.expanded ? this.currentRows * this.rowHeight : 0; + if (this.expanded && this.currentRows === rowCount) + return; + this.currentRows = rowCount; + this.expanded = true; + this.animate(currentHeight, targetHeight); + } + collapse() { + if (!this.expanded) + return; + const currentHeight = this.currentRows * this.rowHeight; + this.expanded = false; + this.currentRows = 0; + this.animate(currentHeight, 0); + } + animate(from, to) { + const keyframes = [ + { height: `${from}px` }, + { height: `${to}px` } + ]; + const options = { + duration: this.duration, + easing: "ease", + fill: "forwards" + }; + this.drawer.animate(keyframes, options); + } + isExpanded() { + return this.expanded; + } + getRowCount() { + return this.currentRows; + } +}; +__name(_HeaderDrawerManager, "HeaderDrawerManager"); +var HeaderDrawerManager = _HeaderDrawerManager; + +// src/demo/MockStores.ts +var _MockTeamStore = class _MockTeamStore { + constructor() { + this.type = "team"; + this.teams = [ + { id: "alpha", name: "Team Alpha" }, + { id: "beta", name: "Team Beta" } + ]; + } + getByIds(ids) { + return this.teams.filter((t) => ids.includes(t.id)); + } +}; +__name(_MockTeamStore, "MockTeamStore"); +var MockTeamStore = _MockTeamStore; +var _MockResourceStore = class _MockResourceStore { + constructor() { + this.type = "resource"; + this.resources = [ + { id: "alice", name: "Alice", teamId: "alpha" }, + { id: "bob", name: "Bob", teamId: "alpha" }, + { id: "carol", name: "Carol", teamId: "beta" }, + { id: "dave", name: "Dave", teamId: "beta" } + ]; + } + getByIds(ids) { + return this.resources.filter((r) => ids.includes(r.id)); + } +}; +__name(_MockResourceStore, "MockResourceStore"); +var MockResourceStore = _MockResourceStore; + +// src/demo/DemoApp.ts +var _DemoApp = class _DemoApp { + constructor(indexedDBContext, dataSeeder, auditService, calendarApp, dateService, resourceService, eventBus) { + this.indexedDBContext = indexedDBContext; + this.dataSeeder = dataSeeder; + this.auditService = auditService; + this.calendarApp = calendarApp; + this.dateService = dateService; + this.resourceService = resourceService; + this.eventBus = eventBus; + this.currentView = "simple"; + } + async init() { + this.dateService.setBaseDate(/* @__PURE__ */ new Date("2025-12-08")); + await this.indexedDBContext.initialize(); + console.log("[DemoApp] IndexedDB initialized"); + await this.dataSeeder.seedIfEmpty(); + console.log("[DemoApp] Data seeding complete"); + this.container = document.querySelector("swp-calendar-container"); + await this.calendarApp.init(this.container); + console.log("[DemoApp] CalendarApp initialized"); + this.setupNavigation(); + this.setupDrawerToggle(); + this.setupViewSwitching(); + this.setupWorkweekSelector(); + await this.setupResourceSelector(); + this.setupStatusListeners(); + this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: this.currentView }); + } + setupNavigation() { + document.getElementById("btn-prev").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_PREV); + }; + document.getElementById("btn-next").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_NEXT); + }; + } + setupViewSwitching() { + const chips = document.querySelectorAll(".view-chip"); + chips.forEach((chip) => { + chip.addEventListener("click", () => { + chips.forEach((c) => c.classList.remove("active")); + chip.classList.add("active"); + const view = chip.dataset.view; + if (view) { + this.currentView = view; + this.updateSelectorVisibility(); + this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: view }); + } + }); + }); + } + updateSelectorVisibility() { + const selector = document.querySelector("swp-resource-selector"); + const showSelector = this.currentView === "picker" || this.currentView === "day"; + selector?.classList.toggle("hidden", !showSelector); + } + setupDrawerToggle() { + document.getElementById("btn-drawer").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_DRAWER_TOGGLE); + }; + } + setupWorkweekSelector() { + const workweekSelect = document.getElementById("workweek-select"); + workweekSelect?.addEventListener("change", () => { + const presetId = workweekSelect.value; + this.eventBus.emit(CalendarEvents.CMD_WORKWEEK_CHANGE, { presetId }); + }); + } + async setupResourceSelector() { + const resources = await this.resourceService.getAll(); + const container2 = document.querySelector(".resource-checkboxes"); + if (!container2) + return; + container2.innerHTML = ""; + resources.forEach((r) => { + const label = document.createElement("label"); + label.innerHTML = ` + + ${r.displayName} + `; + container2.appendChild(label); + }); + container2.addEventListener("change", () => { + const checked = container2.querySelectorAll("input:checked"); + const values = Array.from(checked).map((cb) => cb.value); + this.eventBus.emit(CalendarEvents.CMD_VIEW_UPDATE, { type: "resource", values }); + }); + } + setupStatusListeners() { + this.container.addEventListener("calendar:status:ready", () => { + console.log("[DemoApp] Calendar ready"); + }); + this.container.addEventListener("calendar:status:rendered", (e) => { + console.log("[DemoApp] Calendar rendered:", e.detail.viewId); + }); + this.container.addEventListener("calendar:status:error", (e) => { + console.error("[DemoApp] Calendar error:", e.detail.message); + }); + } +}; +__name(_DemoApp, "DemoApp"); +var DemoApp = _DemoApp; + +// src/core/EventBus.ts +var _EventBus = class _EventBus { + constructor() { + this.eventLog = []; + this.debug = false; + this.listeners = /* @__PURE__ */ new Set(); + this.logConfig = { + calendar: true, + grid: true, + event: true, + scroll: true, + navigation: true, + view: true, + default: true + }; + } + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType, handler, options) { + document.addEventListener(eventType, handler, options); + this.listeners.add({ eventType, handler, options }); + return () => this.off(eventType, handler); + } + /** + * Subscribe to an event once + */ + once(eventType, handler) { + return this.on(eventType, handler, { once: true }); + } + /** + * Unsubscribe from an event + */ + off(eventType, handler) { + document.removeEventListener(eventType, handler); + for (const listener of this.listeners) { + if (listener.eventType === eventType && listener.handler === handler) { + this.listeners.delete(listener); + break; + } + } + } + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType, detail = {}) { + if (!eventType) { + return false; + } + const event = new CustomEvent(eventType, { + detail: detail ?? {}, + bubbles: true, + cancelable: true + }); + if (this.debug) { + this.logEventWithGrouping(eventType, detail); + } + this.eventLog.push({ + type: eventType, + detail: detail ?? {}, + timestamp: Date.now() + }); + return !document.dispatchEvent(event); + } + /** + * Log event with console grouping + */ + logEventWithGrouping(eventType, _detail) { + const category = this.extractCategory(eventType); + if (!this.logConfig[category]) { + return; + } + this.getCategoryStyle(category); + } + /** + * Extract category from event type + */ + extractCategory(eventType) { + if (!eventType) { + return "unknown"; + } + if (eventType.includes(":")) { + return eventType.split(":")[0]; + } + const lowerType = eventType.toLowerCase(); + if (lowerType.includes("grid") || lowerType.includes("rendered")) + return "grid"; + if (lowerType.includes("event") || lowerType.includes("sync")) + return "event"; + if (lowerType.includes("scroll")) + return "scroll"; + if (lowerType.includes("nav") || lowerType.includes("date")) + return "navigation"; + if (lowerType.includes("view")) + return "view"; + return "default"; + } + /** + * Get styling for different categories + */ + getCategoryStyle(category) { + const styles = { + calendar: { emoji: "\u{1F4C5}", color: "#2196F3" }, + grid: { emoji: "\u{1F4CA}", color: "#4CAF50" }, + event: { emoji: "\u{1F4CC}", color: "#FF9800" }, + scroll: { emoji: "\u{1F4DC}", color: "#9C27B0" }, + navigation: { emoji: "\u{1F9ED}", color: "#F44336" }, + view: { emoji: "\u{1F441}", color: "#00BCD4" }, + default: { emoji: "\u{1F4E2}", color: "#607D8B" } + }; + return styles[category] || styles.default; + } + /** + * Configure logging for specific categories + */ + setLogConfig(config) { + this.logConfig = { ...this.logConfig, ...config }; + } + /** + * Get current log configuration + */ + getLogConfig() { + return { ...this.logConfig }; + } + /** + * Get event history + */ + getEventLog(eventType) { + if (eventType) { + return this.eventLog.filter((e) => e.type === eventType); + } + return this.eventLog; + } + /** + * Enable/disable debug mode + */ + setDebug(enabled) { + this.debug = enabled; + } +}; +__name(_EventBus, "EventBus"); +var EventBus = _EventBus; + +// src/storage/IndexedDBContext.ts +var _IndexedDBContext = class _IndexedDBContext { + constructor(stores) { + this.db = null; + this.initialized = false; + this.stores = stores; + } + /** + * Initialize and open the database + */ + async initialize() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(_IndexedDBContext.DB_NAME, _IndexedDBContext.DB_VERSION); + request.onerror = () => { + reject(new Error(`Failed to open IndexedDB: ${request.error}`)); + }; + request.onsuccess = () => { + this.db = request.result; + this.initialized = true; + resolve(); + }; + request.onupgradeneeded = (event) => { + const db = event.target.result; + this.stores.forEach((store) => { + if (!db.objectStoreNames.contains(store.storeName)) { + store.create(db); + } + }); + }; + }); + } + /** + * Check if database is initialized + */ + isInitialized() { + return this.initialized; + } + /** + * Get IDBDatabase instance + */ + getDatabase() { + if (!this.db) { + throw new Error("IndexedDB not initialized. Call initialize() first."); + } + return this.db; + } + /** + * Close database connection + */ + close() { + if (this.db) { + this.db.close(); + this.db = null; + this.initialized = false; + } + } + /** + * Delete entire database (for testing/reset) + */ + static async deleteDatabase() { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(_IndexedDBContext.DB_NAME); + request.onsuccess = () => resolve(); + request.onerror = () => reject(new Error(`Failed to delete database: ${request.error}`)); + }); + } +}; +__name(_IndexedDBContext, "IndexedDBContext"); +var IndexedDBContext = _IndexedDBContext; +IndexedDBContext.DB_NAME = "CalendarDB"; +IndexedDBContext.DB_VERSION = 4; + +// src/storage/events/EventStore.ts +var _EventStore = class _EventStore { + constructor() { + this.storeName = _EventStore.STORE_NAME; + } + /** + * Create the events ObjectStore with indexes + */ + create(db) { + const store = db.createObjectStore(_EventStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("start", "start", { unique: false }); + store.createIndex("end", "end", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("customerId", "customerId", { unique: false }); + store.createIndex("bookingId", "bookingId", { unique: false }); + store.createIndex("startEnd", ["start", "end"], { unique: false }); + } +}; +__name(_EventStore, "EventStore"); +var EventStore = _EventStore; +EventStore.STORE_NAME = "events"; + +// src/storage/events/EventSerialization.ts +var _EventSerialization = class _EventSerialization { + /** + * Serialize event for IndexedDB storage + */ + static serialize(event) { + return { + ...event, + start: event.start instanceof Date ? event.start.toISOString() : event.start, + end: event.end instanceof Date ? event.end.toISOString() : event.end + }; + } + /** + * Deserialize event from IndexedDB storage + */ + static deserialize(data) { + return { + ...data, + start: typeof data.start === "string" ? new Date(data.start) : data.start, + end: typeof data.end === "string" ? new Date(data.end) : data.end + }; + } +}; +__name(_EventSerialization, "EventSerialization"); +var EventSerialization = _EventSerialization; + +// src/storage/SyncPlugin.ts +var _SyncPlugin = class _SyncPlugin { + constructor(service) { + this.service = service; + } + /** + * Mark entity as successfully synced + */ + async markAsSynced(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "synced"; + await this.service.save(entity); + } + } + /** + * Mark entity as sync error + */ + async markAsError(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "error"; + await this.service.save(entity); + } + } + /** + * Get current sync status for an entity + */ + async getSyncStatus(id) { + const entity = await this.service.get(id); + return entity ? entity.syncStatus : null; + } + /** + * Get entities by sync status using IndexedDB index + */ + async getBySyncStatus(syncStatus) { + return new Promise((resolve, reject) => { + const transaction = this.service.db.transaction([this.service.storeName], "readonly"); + const store = transaction.objectStore(this.service.storeName); + const index = store.index("syncStatus"); + const request = index.getAll(syncStatus); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.service.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`)); + }; + }); + } +}; +__name(_SyncPlugin, "SyncPlugin"); +var SyncPlugin = _SyncPlugin; + +// src/constants/CoreEvents.ts +var CoreEvents = { + // Lifecycle events + INITIALIZED: "core:initialized", + READY: "core:ready", + DESTROYED: "core:destroyed", + // View events + VIEW_CHANGED: "view:changed", + VIEW_RENDERED: "view:rendered", + // Navigation events + DATE_CHANGED: "nav:date-changed", + NAVIGATION_COMPLETED: "nav:navigation-completed", + // Data events + DATA_LOADING: "data:loading", + DATA_LOADED: "data:loaded", + DATA_ERROR: "data:error", + // Grid events + GRID_RENDERED: "grid:rendered", + GRID_CLICKED: "grid:clicked", + // Event management + EVENT_CREATED: "event:created", + EVENT_UPDATED: "event:updated", + EVENT_DELETED: "event:deleted", + EVENT_SELECTED: "event:selected", + // Event drag-drop + EVENT_DRAG_START: "event:drag-start", + EVENT_DRAG_MOVE: "event:drag-move", + EVENT_DRAG_END: "event:drag-end", + EVENT_DRAG_CANCEL: "event:drag-cancel", + EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change", + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header", + EVENT_DRAG_MOVE_HEADER: "event:drag-move-header", + EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header", + // Event resize + EVENT_RESIZE_START: "event:resize-start", + EVENT_RESIZE_END: "event:resize-end", + // Edge scroll + EDGE_SCROLL_TICK: "edge-scroll:tick", + EDGE_SCROLL_STARTED: "edge-scroll:started", + EDGE_SCROLL_STOPPED: "edge-scroll:stopped", + // System events + ERROR: "system:error", + // Sync events + SYNC_STARTED: "sync:started", + SYNC_COMPLETED: "sync:completed", + SYNC_FAILED: "sync:failed", + // Entity events - for audit and sync + ENTITY_SAVED: "entity:saved", + ENTITY_DELETED: "entity:deleted", + // Audit events + AUDIT_LOGGED: "audit:logged", + // Rendering events + EVENTS_RENDERED: "events:rendered" +}; + +// node_modules/json-diff-ts/dist/index.js +function arrayDifference(first, second) { + const secondSet = new Set(second); + return first.filter((item) => !secondSet.has(item)); +} +__name(arrayDifference, "arrayDifference"); +function arrayIntersection(first, second) { + const secondSet = new Set(second); + return first.filter((item) => secondSet.has(item)); +} +__name(arrayIntersection, "arrayIntersection"); +function keyBy(arr, getKey2) { + const result = {}; + for (const item of arr) { + result[String(getKey2(item))] = item; + } + return result; +} +__name(keyBy, "keyBy"); +function diff(oldObj, newObj, options = {}) { + let { embeddedObjKeys } = options; + const { keysToSkip, treatTypeChangeAsReplace } = options; + if (embeddedObjKeys instanceof Map) { + embeddedObjKeys = new Map( + Array.from(embeddedObjKeys.entries()).map(([key, value]) => [ + key instanceof RegExp ? key : key.replace(/^\./, ""), + value + ]) + ); + } else if (embeddedObjKeys) { + embeddedObjKeys = Object.fromEntries( + Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\./, ""), value]) + ); + } + return compare(oldObj, newObj, [], [], { + embeddedObjKeys, + keysToSkip: keysToSkip ?? [], + treatTypeChangeAsReplace: treatTypeChangeAsReplace ?? true + }); +} +__name(diff, "diff"); +var getTypeOfObj = /* @__PURE__ */ __name((obj) => { + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return null; + } + return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1]; +}, "getTypeOfObj"); +var getKey = /* @__PURE__ */ __name((path) => { + const left = path[path.length - 1]; + return left != null ? left : "$root"; +}, "getKey"); +var compare = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, options) => { + let changes = []; + const currentPath = keyPath.join("."); + if (options.keysToSkip?.some((skipPath) => { + if (currentPath === skipPath) { + return true; + } + if (skipPath.includes(".") && skipPath.startsWith(currentPath + ".")) { + return false; + } + if (skipPath.includes(".")) { + const skipParts = skipPath.split("."); + const currentParts = currentPath.split("."); + if (currentParts.length >= skipParts.length) { + for (let i = 0; i < skipParts.length; i++) { + if (skipParts[i] !== currentParts[i]) { + return false; + } + } + return true; + } + } + return false; + })) { + return changes; + } + const typeOfOldObj = getTypeOfObj(oldObj); + const typeOfNewObj = getTypeOfObj(newObj); + if (options.treatTypeChangeAsReplace && typeOfOldObj !== typeOfNewObj) { + if (typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + } + if (typeOfNewObj !== "undefined") { + changes.push({ type: "ADD", key: getKey(path), value: newObj }); + } + return changes; + } + if (typeOfNewObj === "undefined" && typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + return changes; + } + if (typeOfNewObj === "Object" && typeOfOldObj === "Array") { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + return changes; + } + if (typeOfNewObj === null) { + if (typeOfOldObj !== null) { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + } + return changes; + } + switch (typeOfOldObj) { + case "Date": + if (typeOfNewObj === "Date") { + changes = changes.concat( + comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({ + ...x, + value: new Date(x.value), + oldValue: new Date(x.oldValue) + })) + ); + } else { + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + break; + case "Object": { + const diffs = compareObject(oldObj, newObj, path, keyPath, false, options); + if (diffs.length) { + if (path.length) { + changes.push({ + type: "UPDATE", + key: getKey(path), + changes: diffs + }); + } else { + changes = changes.concat(diffs); + } + } + break; + } + case "Array": + changes = changes.concat(compareArray(oldObj, newObj, path, keyPath, options)); + break; + case "Function": + break; + default: + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + return changes; +}, "compare"); +var compareObject = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, skipPath = false, options = {}) => { + let k; + let newKeyPath; + let newPath; + if (skipPath == null) { + skipPath = false; + } + let changes = []; + const oldObjKeys = Object.keys(oldObj); + const newObjKeys = Object.keys(newObj); + const intersectionKeys = arrayIntersection(oldObjKeys, newObjKeys); + for (k of intersectionKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const diffs = compare(oldObj[k], newObj[k], newPath, newKeyPath, options); + if (diffs.length) { + changes = changes.concat(diffs); + } + } + const addedKeys = arrayDifference(newObjKeys, oldObjKeys); + for (k of addedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "ADD", + key: getKey(newPath), + value: newObj[k] + }); + } + const deletedKeys = arrayDifference(oldObjKeys, newObjKeys); + for (k of deletedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "REMOVE", + key: getKey(newPath), + value: oldObj[k] + }); + } + return changes; +}, "compareObject"); +var compareArray = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, options) => { + if (getTypeOfObj(newObj) !== "Array") { + return [{ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }]; + } + const left = getObjectKey(options.embeddedObjKeys, keyPath); + const uniqKey = left != null ? left : "$index"; + const indexedOldObj = convertArrayToObj(oldObj, uniqKey); + const indexedNewObj = convertArrayToObj(newObj, uniqKey); + const diffs = compareObject(indexedOldObj, indexedNewObj, path, keyPath, true, options); + if (diffs.length) { + return [ + { + type: "UPDATE", + key: getKey(path), + embeddedKey: typeof uniqKey === "function" && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey, + changes: diffs + } + ]; + } else { + return []; + } +}, "compareArray"); +var getObjectKey = /* @__PURE__ */ __name((embeddedObjKeys, keyPath) => { + if (embeddedObjKeys != null) { + const path = keyPath.join("."); + if (embeddedObjKeys instanceof Map) { + for (const [key2, value] of embeddedObjKeys.entries()) { + if (key2 instanceof RegExp) { + if (path.match(key2)) { + return value; + } + } else if (path === key2) { + return value; + } + } + } + const key = embeddedObjKeys[path]; + if (key != null) { + return key; + } + } + return void 0; +}, "getObjectKey"); +var convertArrayToObj = /* @__PURE__ */ __name((arr, uniqKey) => { + let obj = {}; + if (uniqKey === "$value") { + arr.forEach((value) => { + obj[value] = value; + }); + } else if (uniqKey !== "$index") { + const keyFunction = typeof uniqKey === "string" ? (item) => item[uniqKey] : uniqKey; + obj = keyBy(arr, keyFunction); + } else { + for (let i = 0; i < arr.length; i++) { + const value = arr[i]; + obj[i] = value; + } + } + return obj; +}, "convertArrayToObj"); +var comparePrimitives = /* @__PURE__ */ __name((oldObj, newObj, path) => { + const changes = []; + if (oldObj !== newObj) { + changes.push({ + type: "UPDATE", + key: getKey(path), + value: newObj, + oldValue: oldObj + }); + } + return changes; +}, "comparePrimitives"); + +// src/storage/BaseEntityService.ts +var _BaseEntityService = class _BaseEntityService { + constructor(context, eventBus) { + this.context = context; + this.eventBus = eventBus; + this.syncPlugin = new SyncPlugin(this); + } + get db() { + return this.context.getDatabase(); + } + /** + * Serialize entity before storing in IndexedDB + */ + serialize(entity) { + return entity; + } + /** + * Deserialize data from IndexedDB back to entity + */ + deserialize(data) { + return data; + } + /** + * Get a single entity by ID + */ + async get(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.get(id); + request.onsuccess = () => { + const data = request.result; + resolve(data ? this.deserialize(data) : null); + }; + request.onerror = () => { + reject(new Error(`Failed to get ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + /** + * Get all entities + */ + async getAll() { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get all ${this.entityType}s: ${request.error}`)); + }; + }); + } + /** + * Save an entity (create or update) + * Emits ENTITY_SAVED event with operation type and changes (diff for updates) + * @param entity - Entity to save + * @param silent - If true, skip event emission (used for seeding) + */ + async save(entity, silent = false) { + const entityId = entity.id; + const existingEntity = await this.get(entityId); + const isCreate = existingEntity === null; + let changes; + if (isCreate) { + changes = entity; + } else { + const existingSerialized = this.serialize(existingEntity); + const newSerialized = this.serialize(entity); + changes = diff(existingSerialized, newSerialized); + } + const serialized = this.serialize(entity); + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + request.onsuccess = () => { + if (!silent) { + const payload = { + entityType: this.entityType, + entityId, + operation: isCreate ? "create" : "update", + changes, + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_SAVED, payload); + } + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save ${this.entityType} ${entityId}: ${request.error}`)); + }; + }); + } + /** + * Delete an entity + * Emits ENTITY_DELETED event + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.delete(id); + request.onsuccess = () => { + const payload = { + entityType: this.entityType, + entityId: id, + operation: "delete", + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_DELETED, payload); + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to delete ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + // Sync methods - delegate to SyncPlugin + async markAsSynced(id) { + return this.syncPlugin.markAsSynced(id); + } + async markAsError(id) { + return this.syncPlugin.markAsError(id); + } + async getSyncStatus(id) { + return this.syncPlugin.getSyncStatus(id); + } + async getBySyncStatus(syncStatus) { + return this.syncPlugin.getBySyncStatus(syncStatus); + } +}; +__name(_BaseEntityService, "BaseEntityService"); +var BaseEntityService = _BaseEntityService; + +// src/storage/events/EventService.ts +var _EventService = class _EventService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = EventStore.STORE_NAME; + this.entityType = "Event"; + } + serialize(event) { + return EventSerialization.serialize(event); + } + deserialize(data) { + return EventSerialization.deserialize(data); + } + /** + * Get events within a date range + */ + async getByDateRange(start, end) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("start"); + const range = IDBKeyRange.lowerBound(start.toISOString()); + const request = index.getAll(range); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)).filter((event) => event.start <= end); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events by date range: ${request.error}`)); + }; + }); + } + /** + * Get events for a specific resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events for resource ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get events for a resource within a date range + */ + async getByResourceAndDateRange(resourceId, start, end) { + const resourceEvents = await this.getByResource(resourceId); + return resourceEvents.filter((event) => event.start >= start && event.start <= end); + } +}; +__name(_EventService, "EventService"); +var EventService = _EventService; + +// src/storage/resources/ResourceStore.ts +var _ResourceStore = class _ResourceStore { + constructor() { + this.storeName = _ResourceStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ResourceStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("type", "type", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("isActive", "isActive", { unique: false }); + } +}; +__name(_ResourceStore, "ResourceStore"); +var ResourceStore = _ResourceStore; +ResourceStore.STORE_NAME = "resources"; + +// src/storage/resources/ResourceService.ts +var _ResourceService = class _ResourceService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ResourceStore.STORE_NAME; + this.entityType = "Resource"; + } + /** + * Get all active resources + */ + async getActive() { + const all = await this.getAll(); + return all.filter((r) => r.isActive !== false); + } + /** + * Get resources by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((r) => r !== null); + } + /** + * Get resources by type + */ + async getByType(type) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("type"); + const request = index.getAll(type); + request.onsuccess = () => { + const data = request.result; + resolve(data); + }; + request.onerror = () => { + reject(new Error(`Failed to get resources by type ${type}: ${request.error}`)); + }; + }); + } +}; +__name(_ResourceService, "ResourceService"); +var ResourceService = _ResourceService; + +// src/storage/bookings/BookingStore.ts +var _BookingStore = class _BookingStore { + constructor() { + this.storeName = _BookingStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_BookingStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("customerId", "customerId", { unique: false }); + store.createIndex("status", "status", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("createdAt", "createdAt", { unique: false }); + } +}; +__name(_BookingStore, "BookingStore"); +var BookingStore = _BookingStore; +BookingStore.STORE_NAME = "bookings"; + +// src/storage/bookings/BookingService.ts +var _BookingService = class _BookingService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = BookingStore.STORE_NAME; + this.entityType = "Booking"; + } + serialize(booking) { + return { + ...booking, + createdAt: booking.createdAt.toISOString() + }; + } + deserialize(data) { + const raw = data; + return { + ...raw, + createdAt: new Date(raw.createdAt) + }; + } + /** + * Get bookings for a customer + */ + async getByCustomer(customerId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("customerId"); + const request = index.getAll(customerId); + request.onsuccess = () => { + const data = request.result; + const bookings = data.map((item) => this.deserialize(item)); + resolve(bookings); + }; + request.onerror = () => { + reject(new Error(`Failed to get bookings for customer ${customerId}: ${request.error}`)); + }; + }); + } + /** + * Get bookings by status + */ + async getByStatus(status) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("status"); + const request = index.getAll(status); + request.onsuccess = () => { + const data = request.result; + const bookings = data.map((item) => this.deserialize(item)); + resolve(bookings); + }; + request.onerror = () => { + reject(new Error(`Failed to get bookings with status ${status}: ${request.error}`)); + }; + }); + } +}; +__name(_BookingService, "BookingService"); +var BookingService = _BookingService; + +// src/storage/customers/CustomerStore.ts +var _CustomerStore = class _CustomerStore { + constructor() { + this.storeName = _CustomerStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_CustomerStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("name", "name", { unique: false }); + store.createIndex("phone", "phone", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + } +}; +__name(_CustomerStore, "CustomerStore"); +var CustomerStore = _CustomerStore; +CustomerStore.STORE_NAME = "customers"; + +// src/storage/customers/CustomerService.ts +var _CustomerService = class _CustomerService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = CustomerStore.STORE_NAME; + this.entityType = "Customer"; + } + /** + * Search customers by name (case-insensitive contains) + */ + async searchByName(query) { + const all = await this.getAll(); + const lowerQuery = query.toLowerCase(); + return all.filter((c) => c.name.toLowerCase().includes(lowerQuery)); + } + /** + * Find customer by phone + */ + async getByPhone(phone) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("phone"); + const request = index.get(phone); + request.onsuccess = () => { + const data = request.result; + resolve(data ? data : null); + }; + request.onerror = () => { + reject(new Error(`Failed to find customer by phone ${phone}: ${request.error}`)); + }; + }); + } +}; +__name(_CustomerService, "CustomerService"); +var CustomerService = _CustomerService; + +// src/storage/teams/TeamStore.ts +var _TeamStore = class _TeamStore { + constructor() { + this.storeName = _TeamStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_TeamStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_TeamStore, "TeamStore"); +var TeamStore = _TeamStore; +TeamStore.STORE_NAME = "teams"; + +// src/storage/teams/TeamService.ts +var _TeamService = class _TeamService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = TeamStore.STORE_NAME; + this.entityType = "Team"; + } + /** + * Get teams by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((t) => t !== null); + } + /** + * Build reverse lookup: resourceId → teamId + */ + async buildResourceToTeamMap() { + const teams = await this.getAll(); + const map = {}; + for (const team of teams) { + for (const resourceId of team.resourceIds) { + map[resourceId] = team.id; + } + } + return map; + } +}; +__name(_TeamService, "TeamService"); +var TeamService = _TeamService; + +// src/storage/departments/DepartmentStore.ts +var _DepartmentStore = class _DepartmentStore { + constructor() { + this.storeName = _DepartmentStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_DepartmentStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_DepartmentStore, "DepartmentStore"); +var DepartmentStore = _DepartmentStore; +DepartmentStore.STORE_NAME = "departments"; + +// src/storage/departments/DepartmentService.ts +var _DepartmentService = class _DepartmentService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = DepartmentStore.STORE_NAME; + this.entityType = "Department"; + } + /** + * Get departments by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((d) => d !== null); + } +}; +__name(_DepartmentService, "DepartmentService"); +var DepartmentService = _DepartmentService; + +// src/storage/settings/SettingsStore.ts +var _SettingsStore = class _SettingsStore { + constructor() { + this.storeName = _SettingsStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_SettingsStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_SettingsStore, "SettingsStore"); +var SettingsStore = _SettingsStore; +SettingsStore.STORE_NAME = "settings"; + +// src/types/SettingsTypes.ts +var SettingsIds = { + WORKWEEK: "workweek", + GRID: "grid", + TIME_FORMAT: "timeFormat", + VIEWS: "views" +}; + +// src/storage/settings/SettingsService.ts +var _SettingsService = class _SettingsService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = SettingsStore.STORE_NAME; + this.entityType = "Settings"; + } + /** + * Get workweek settings + */ + async getWorkweekSettings() { + return this.get(SettingsIds.WORKWEEK); + } + /** + * Get grid settings + */ + async getGridSettings() { + return this.get(SettingsIds.GRID); + } + /** + * Get time format settings + */ + async getTimeFormatSettings() { + return this.get(SettingsIds.TIME_FORMAT); + } + /** + * Get view settings + */ + async getViewSettings() { + return this.get(SettingsIds.VIEWS); + } + /** + * Get workweek preset by ID + */ + async getWorkweekPreset(presetId) { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[presetId] || null; + } + /** + * Get the default workweek preset + */ + async getDefaultWorkweekPreset() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[settings.defaultPreset] || null; + } + /** + * Get all available workweek presets + */ + async getWorkweekPresets() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return []; + return Object.values(settings.presets); + } +}; +__name(_SettingsService, "SettingsService"); +var SettingsService = _SettingsService; + +// src/storage/viewconfigs/ViewConfigStore.ts +var _ViewConfigStore = class _ViewConfigStore { + constructor() { + this.storeName = _ViewConfigStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_ViewConfigStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_ViewConfigStore, "ViewConfigStore"); +var ViewConfigStore = _ViewConfigStore; +ViewConfigStore.STORE_NAME = "viewconfigs"; + +// src/storage/viewconfigs/ViewConfigService.ts +var _ViewConfigService = class _ViewConfigService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ViewConfigStore.STORE_NAME; + this.entityType = "ViewConfig"; + } + async getById(id) { + return this.get(id); + } +}; +__name(_ViewConfigService, "ViewConfigService"); +var ViewConfigService = _ViewConfigService; + +// src/storage/audit/AuditStore.ts +var _AuditStore = class _AuditStore { + constructor() { + this.storeName = "audit"; + } + create(db) { + const store = db.createObjectStore(this.storeName, { keyPath: "id" }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("synced", "synced", { unique: false }); + store.createIndex("entityId", "entityId", { unique: false }); + store.createIndex("timestamp", "timestamp", { unique: false }); + } +}; +__name(_AuditStore, "AuditStore"); +var AuditStore = _AuditStore; + +// src/storage/audit/AuditService.ts +var _AuditService = class _AuditService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = "audit"; + this.entityType = "Audit"; + this.setupEventListeners(); + } + /** + * Setup listeners for ENTITY_SAVED and ENTITY_DELETED events + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.ENTITY_SAVED, (event) => { + const detail = event.detail; + this.handleEntitySaved(detail); + }); + this.eventBus.on(CoreEvents.ENTITY_DELETED, (event) => { + const detail = event.detail; + this.handleEntityDeleted(detail); + }); + } + /** + * Handle ENTITY_SAVED event - create audit entry + */ + async handleEntitySaved(payload) { + if (payload.entityType === "Audit") + return; + const auditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: payload.operation, + userId: _AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: payload.changes, + synced: false, + syncStatus: "pending" + }; + await this.save(auditEntry); + } + /** + * Handle ENTITY_DELETED event - create audit entry + */ + async handleEntityDeleted(payload) { + if (payload.entityType === "Audit") + return; + const auditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: "delete", + userId: _AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: { id: payload.entityId }, + // For delete, just store the ID + synced: false, + syncStatus: "pending" + }; + await this.save(auditEntry); + } + /** + * Override save to NOT trigger ENTITY_SAVED event + * Instead, emits AUDIT_LOGGED for SyncManager to listen + * + * This prevents infinite loops: + * - BaseEntityService.save() emits ENTITY_SAVED + * - AuditService listens to ENTITY_SAVED and creates audit + * - If AuditService.save() also emitted ENTITY_SAVED, it would loop + */ + async save(entity) { + const serialized = this.serialize(entity); + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + request.onsuccess = () => { + const payload = { + auditId: entity.id, + entityType: entity.entityType, + entityId: entity.entityId, + operation: entity.operation, + timestamp: entity.timestamp + }; + this.eventBus.emit(CoreEvents.AUDIT_LOGGED, payload); + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save audit entry ${entity.id}: ${request.error}`)); + }; + }); + } + /** + * Override delete to NOT trigger ENTITY_DELETED event + * Audit entries should never be deleted (compliance requirement) + */ + async delete(_id) { + throw new Error("Audit entries cannot be deleted (compliance requirement)"); + } + /** + * Get pending audit entries (for sync) + */ + async getPendingAudits() { + return this.getBySyncStatus("pending"); + } + /** + * Get audit entries for a specific entity + */ + async getByEntityId(entityId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("entityId"); + const request = index.getAll(entityId); + request.onsuccess = () => { + const entries = request.result; + resolve(entries); + }; + request.onerror = () => { + reject(new Error(`Failed to get audit entries for entity ${entityId}: ${request.error}`)); + }; + }); + } +}; +__name(_AuditService, "AuditService"); +var AuditService = _AuditService; +AuditService.DEFAULT_USER_ID = "00000000-0000-0000-0000-000000000001"; + +// src/repositories/MockEventRepository.ts +var _MockEventRepository = class _MockEventRepository { + constructor() { + this.entityType = "Event"; + this.dataUrl = "data/mock-events.json"; + } + /** + * Fetch all events from mock JSON file + */ + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock events: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processCalendarData(rawData); + } catch (error) { + console.error("Failed to load event data:", error); + throw error; + } + } + async sendCreate(_event) { + throw new Error("MockEventRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockEventRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockEventRepository does not support sendDelete. Mock data is read-only."); + } + processCalendarData(data) { + return data.map((event) => { + if (event.type === "customer") { + if (!event.bookingId) + console.warn(`Customer event ${event.id} missing bookingId`); + if (!event.resourceId) + console.warn(`Customer event ${event.id} missing resourceId`); + if (!event.customerId) + console.warn(`Customer event ${event.id} missing customerId`); + } + return { + id: event.id, + title: event.title, + description: event.description, + start: new Date(event.start), + end: new Date(event.end), + type: event.type, + allDay: event.allDay || false, + bookingId: event.bookingId, + resourceId: event.resourceId, + customerId: event.customerId, + recurringId: event.recurringId, + metadata: event.metadata, + syncStatus: "synced" + }; + }); + } +}; +__name(_MockEventRepository, "MockEventRepository"); +var MockEventRepository = _MockEventRepository; + +// src/repositories/MockResourceRepository.ts +var _MockResourceRepository = class _MockResourceRepository { + constructor() { + this.entityType = "Resource"; + this.dataUrl = "data/mock-resources.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock resources: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processResourceData(rawData); + } catch (error) { + console.error("Failed to load resource data:", error); + throw error; + } + } + async sendCreate(_resource) { + throw new Error("MockResourceRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockResourceRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockResourceRepository does not support sendDelete. Mock data is read-only."); + } + processResourceData(data) { + return data.map((resource) => ({ + id: resource.id, + name: resource.name, + displayName: resource.displayName, + type: resource.type, + avatarUrl: resource.avatarUrl, + color: resource.color, + isActive: resource.isActive, + defaultSchedule: resource.defaultSchedule, + metadata: resource.metadata, + syncStatus: "synced" + })); + } +}; +__name(_MockResourceRepository, "MockResourceRepository"); +var MockResourceRepository = _MockResourceRepository; + +// src/repositories/MockBookingRepository.ts +var _MockBookingRepository = class _MockBookingRepository { + constructor() { + this.entityType = "Booking"; + this.dataUrl = "data/mock-bookings.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock bookings: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processBookingData(rawData); + } catch (error) { + console.error("Failed to load booking data:", error); + throw error; + } + } + async sendCreate(_booking) { + throw new Error("MockBookingRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockBookingRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockBookingRepository does not support sendDelete. Mock data is read-only."); + } + processBookingData(data) { + return data.map((booking) => ({ + id: booking.id, + customerId: booking.customerId, + status: booking.status, + createdAt: new Date(booking.createdAt), + services: booking.services, + totalPrice: booking.totalPrice, + tags: booking.tags, + notes: booking.notes, + syncStatus: "synced" + })); + } +}; +__name(_MockBookingRepository, "MockBookingRepository"); +var MockBookingRepository = _MockBookingRepository; + +// src/repositories/MockCustomerRepository.ts +var _MockCustomerRepository = class _MockCustomerRepository { + constructor() { + this.entityType = "Customer"; + this.dataUrl = "data/mock-customers.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock customers: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processCustomerData(rawData); + } catch (error) { + console.error("Failed to load customer data:", error); + throw error; + } + } + async sendCreate(_customer) { + throw new Error("MockCustomerRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockCustomerRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockCustomerRepository does not support sendDelete. Mock data is read-only."); + } + processCustomerData(data) { + return data.map((customer) => ({ + id: customer.id, + name: customer.name, + phone: customer.phone, + email: customer.email, + metadata: customer.metadata, + syncStatus: "synced" + })); + } +}; +__name(_MockCustomerRepository, "MockCustomerRepository"); +var MockCustomerRepository = _MockCustomerRepository; + +// src/repositories/MockAuditRepository.ts +var _MockAuditRepository = class _MockAuditRepository { + constructor() { + this.entityType = "Audit"; + } + async sendCreate(entity) { + await new Promise((resolve) => setTimeout(resolve, 100)); + console.log("MockAuditRepository: Audit entry synced to backend:", { + id: entity.id, + entityType: entity.entityType, + entityId: entity.entityId, + operation: entity.operation, + timestamp: new Date(entity.timestamp).toISOString() + }); + return entity; + } + async sendUpdate(_id, _entity) { + throw new Error("Audit entries cannot be updated"); + } + async sendDelete(_id) { + throw new Error("Audit entries cannot be deleted"); + } + async fetchAll() { + return []; + } + async fetchById(_id) { + return null; + } +}; +__name(_MockAuditRepository, "MockAuditRepository"); +var MockAuditRepository = _MockAuditRepository; + +// src/repositories/MockTeamRepository.ts +var _MockTeamRepository = class _MockTeamRepository { + constructor() { + this.entityType = "Team"; + this.dataUrl = "data/mock-teams.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock teams: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processTeamData(rawData); + } catch (error) { + console.error("Failed to load team data:", error); + throw error; + } + } + async sendCreate(_team) { + throw new Error("MockTeamRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockTeamRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockTeamRepository does not support sendDelete. Mock data is read-only."); + } + processTeamData(data) { + return data.map((team) => ({ + id: team.id, + name: team.name, + resourceIds: team.resourceIds, + syncStatus: "synced" + })); + } +}; +__name(_MockTeamRepository, "MockTeamRepository"); +var MockTeamRepository = _MockTeamRepository; + +// src/repositories/MockDepartmentRepository.ts +var _MockDepartmentRepository = class _MockDepartmentRepository { + constructor() { + this.entityType = "Department"; + this.dataUrl = "data/mock-departments.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock departments: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processDepartmentData(rawData); + } catch (error) { + console.error("Failed to load department data:", error); + throw error; + } + } + async sendCreate(_department) { + throw new Error("MockDepartmentRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockDepartmentRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockDepartmentRepository does not support sendDelete. Mock data is read-only."); + } + processDepartmentData(data) { + return data.map((dept) => ({ + id: dept.id, + name: dept.name, + resourceIds: dept.resourceIds, + syncStatus: "synced" + })); + } +}; +__name(_MockDepartmentRepository, "MockDepartmentRepository"); +var MockDepartmentRepository = _MockDepartmentRepository; + +// src/repositories/MockSettingsRepository.ts +var _MockSettingsRepository = class _MockSettingsRepository { + constructor() { + this.entityType = "Settings"; + this.dataUrl = "data/tenant-settings.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load tenant settings: ${response.status} ${response.statusText}`); + } + const settings = await response.json(); + return settings.map((s) => ({ + ...s, + syncStatus: s.syncStatus || "synced" + })); + } catch (error) { + console.error("Failed to load tenant settings:", error); + throw error; + } + } + async sendCreate(_settings) { + throw new Error("MockSettingsRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockSettingsRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockSettingsRepository does not support sendDelete. Mock data is read-only."); + } +}; +__name(_MockSettingsRepository, "MockSettingsRepository"); +var MockSettingsRepository = _MockSettingsRepository; + +// src/repositories/MockViewConfigRepository.ts +var _MockViewConfigRepository = class _MockViewConfigRepository { + constructor() { + this.entityType = "ViewConfig"; + this.dataUrl = "data/viewconfigs.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load viewconfigs: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + const configs = rawData.map((config) => ({ + ...config, + syncStatus: config.syncStatus || "synced" + })); + return configs; + } catch (error) { + console.error("Failed to load viewconfigs:", error); + throw error; + } + } + async sendCreate(_config) { + throw new Error("MockViewConfigRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockViewConfigRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockViewConfigRepository does not support sendDelete. Mock data is read-only."); + } +}; +__name(_MockViewConfigRepository, "MockViewConfigRepository"); +var MockViewConfigRepository = _MockViewConfigRepository; + +// src/workers/DataSeeder.ts +var _DataSeeder = class _DataSeeder { + constructor(services, repositories) { + this.services = services; + this.repositories = repositories; + } + /** + * Seed all entity stores if they are empty + */ + async seedIfEmpty() { + console.log("[DataSeeder] Checking if database needs seeding..."); + try { + for (const service of this.services) { + const repository = this.repositories.find((repo) => repo.entityType === service.entityType); + if (!repository) { + console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`); + continue; + } + await this.seedEntity(service.entityType, service, repository); + } + console.log("[DataSeeder] Seeding complete"); + } catch (error) { + console.error("[DataSeeder] Seeding failed:", error); + throw error; + } + } + async seedEntity(entityType, service, repository) { + const existing = await service.getAll(); + if (existing.length > 0) { + console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`); + return; + } + console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`); + const data = await repository.fetchAll(); + console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`); + for (const entity of data) { + await service.save(entity, true); + } + console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`); + } +}; +__name(_DataSeeder, "DataSeeder"); +var DataSeeder = _DataSeeder; + +// src/utils/PositionUtils.ts +function calculateEventPosition(start, end, config) { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + return { top, height }; +} +__name(calculateEventPosition, "calculateEventPosition"); +function minutesToPixels(minutes, config) { + return minutes / 60 * config.hourHeight; +} +__name(minutesToPixels, "minutesToPixels"); +function pixelsToMinutes(pixels, config) { + return pixels / config.hourHeight * 60; +} +__name(pixelsToMinutes, "pixelsToMinutes"); +function snapToGrid(pixels, config) { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} +__name(snapToGrid, "snapToGrid"); + +// src/features/event/EventLayoutEngine.ts +function eventsOverlap(a, b) { + return a.start < b.end && a.end > b.start; +} +__name(eventsOverlap, "eventsOverlap"); +function eventsWithinThreshold(a, b, thresholdMinutes) { + const thresholdMs = thresholdMinutes * 60 * 1e3; + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) + return true; + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) + return true; + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) + return true; + return false; +} +__name(eventsWithinThreshold, "eventsWithinThreshold"); +function findOverlapGroups(events) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsOverlap(member, candidate)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findOverlapGroups, "findOverlapGroups"); +function findGridCandidates(events, thresholdMinutes) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsWithinThreshold(member, candidate, thresholdMinutes)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findGridCandidates, "findGridCandidates"); +function calculateStackLevels(events) { + const levels = /* @__PURE__ */ new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + for (const event of sorted) { + let maxOverlappingLevel = -1; + for (const [id, level] of levels) { + const other = events.find((e) => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + levels.set(event.id, maxOverlappingLevel + 1); + } + return levels; +} +__name(calculateStackLevels, "calculateStackLevels"); +function allocateColumns(events) { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns = []; + for (const event of sorted) { + let placed = false; + for (const column of columns) { + const canFit = !column.some((e) => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + if (!placed) { + columns.push([event]); + } + } + return columns; +} +__name(allocateColumns, "allocateColumns"); +function calculateColumnLayout(events, config) { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + const result = { + grids: [], + stacked: [] + }; + if (events.length === 0) + return result; + const overlapGroups = findOverlapGroups(events); + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]); + if (largestGridCandidate.length === overlapGroup.length) { + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + return result; +} +__name(calculateColumnLayout, "calculateColumnLayout"); + +// src/features/event/EventRenderer.ts +var _EventRenderer = class _EventRenderer { + constructor(eventService, dateService, gridConfig, eventBus) { + this.eventService = eventService; + this.dateService = dateService; + this.gridConfig = gridConfig; + this.eventBus = eventBus; + this.container = null; + this.setupListeners(); + } + /** + * Setup listeners for drag-drop and update events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = e.detail; + this.handleColumnChange(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = e.detail; + this.updateDragTimestamp(payload); + }); + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = e.detail; + this.handleEventUpdated(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeaveHeader(payload); + }); + } + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + handleDragEnd(payload) { + if (payload.target === "header") { + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + /** + * Handle header item leaving header - create swp-event in grid + */ + handleDragLeaveHeader(payload) { + if (payload.source !== "header") + return; + if (!payload.targetColumn || !payload.start || !payload.end) + return; + if (payload.element) { + payload.element.classList.add("drag-ghost"); + payload.element.style.opacity = "0.3"; + payload.element.style.pointerEvents = "none"; + } + const event = { + id: payload.eventId, + title: payload.title || "", + description: "", + start: payload.start, + end: payload.end, + type: "customer", + allDay: false, + syncStatus: "pending" + }; + const element = this.createEventElement(event); + let eventsLayer = payload.targetColumn.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + element.classList.add("dragging"); + } + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + async handleEventUpdated(payload) { + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + await this.rerenderColumn(payload.targetColumnKey); + } + /** + * Re-render a single column with fresh data from IndexedDB + */ + async rerenderColumn(columnKey) { + const column = this.findColumn(columnKey); + if (!column) + return; + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date) + return; + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate); + const timedEvents = events.filter((event) => !event.allDay && this.dateService.getDateKey(event.start) === date); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + } + /** + * Find a column element by columnKey + */ + findColumn(columnKey) { + if (!this.container) + return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`); + } + /** + * Handle event moving to a new column during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.querySelector("swp-events-layer"); + if (!eventsLayer) + return; + eventsLayer.appendChild(payload.element); + payload.element.style.top = `${payload.currentY}px`; + } + /** + * Update timestamp display during drag (snapped to grid) + */ + updateDragTimestamp(payload) { + const timeEl = payload.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart; + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to a Date object (today) + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container2, filter, filterTemplate) { + this.container = container2; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const dayColumns = container2.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + columns.forEach((column) => { + const columnEl = column; + const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl)); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const timedEvents = columnEvents.filter((event) => !event.allDay); + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + }); + } + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + createEventElement(event) { + const element = document.createElement("swp-event"); + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ""} + `; + return element; + } + /** + * Get color class based on metadata.color or event type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Escape HTML to prevent XSS + */ + escapeHtml(text) { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; + } + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + renderGridGroup(layout) { + const group = document.createElement("swp-event-group"); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) + maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + layout.columns.forEach((columnEvents) => { + const wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + columnEvents.forEach((event) => { + const eventEl = this.createEventElement(event); + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = "absolute"; + eventEl.style.left = "0"; + eventEl.style.right = "0"; + wrapper.appendChild(eventEl); + }); + group.appendChild(wrapper); + }); + return group; + } + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + renderStackedEvent(event, stackLevel) { + const element = this.createEventElement(event); + element.dataset.stackLink = JSON.stringify({ stackLevel }); + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + return element; + } +}; +__name(_EventRenderer, "EventRenderer"); +var EventRenderer = _EventRenderer; + +// src/features/schedule/ScheduleRenderer.ts +var _ScheduleRenderer = class _ScheduleRenderer { + constructor(scheduleService, dateService, gridConfig) { + this.scheduleService = scheduleService; + this.dateService = dateService; + this.gridConfig = gridConfig; + } + /** + * Render unavailable zones for visible columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and 'resource' arrays + */ + async render(container2, filter) { + const dates = filter["date"] || []; + const resourceIds = filter["resource"] || []; + if (dates.length === 0) + return; + const dayColumns = container2.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + for (const column of columns) { + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date || !resourceId) + continue; + let unavailableLayer = column.querySelector("swp-unavailable-layer"); + if (!unavailableLayer) { + unavailableLayer = document.createElement("swp-unavailable-layer"); + column.insertBefore(unavailableLayer, column.firstChild); + } + unavailableLayer.innerHTML = ""; + const schedule = await this.scheduleService.getScheduleForDate(resourceId, date); + this.renderUnavailableZones(unavailableLayer, schedule); + } + } + /** + * Render unavailable time zones based on schedule + */ + renderUnavailableZones(layer, schedule) { + const dayStartMinutes = this.gridConfig.dayStartHour * 60; + const dayEndMinutes = this.gridConfig.dayEndHour * 60; + const minuteHeight = this.gridConfig.hourHeight / 60; + if (schedule === null) { + const zone = this.createUnavailableZone(0, (dayEndMinutes - dayStartMinutes) * minuteHeight); + layer.appendChild(zone); + return; + } + const workStartMinutes = this.dateService.timeToMinutes(schedule.start); + const workEndMinutes = this.dateService.timeToMinutes(schedule.end); + if (workStartMinutes > dayStartMinutes) { + const top = 0; + const height = (workStartMinutes - dayStartMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + if (workEndMinutes < dayEndMinutes) { + const top = (workEndMinutes - dayStartMinutes) * minuteHeight; + const height = (dayEndMinutes - workEndMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + } + /** + * Create an unavailable zone element + */ + createUnavailableZone(top, height) { + const zone = document.createElement("swp-unavailable-zone"); + zone.style.top = `${top}px`; + zone.style.height = `${height}px`; + return zone; + } +}; +__name(_ScheduleRenderer, "ScheduleRenderer"); +var ScheduleRenderer = _ScheduleRenderer; + +// src/features/headerdrawer/HeaderDrawerRenderer.ts +var _HeaderDrawerRenderer = class _HeaderDrawerRenderer { + constructor(eventBus, gridConfig, headerDrawerManager, eventService, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.headerDrawerManager = headerDrawerManager; + this.eventService = eventService; + this.dateService = dateService; + this.currentItem = null; + this.container = null; + this.sourceElement = null; + this.wasExpandedBeforeDrag = false; + this.filterTemplate = null; + this.setupListeners(); + } + /** + * Render allDay events into the header drawer with row stacking + * @param filterTemplate - Template for matching events to columns + */ + async render(container2, filter, filterTemplate) { + this.filterTemplate = filterTemplate; + const drawer = container2.querySelector("swp-header-drawer"); + if (!drawer) + return; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const allDayEvents = events.filter((event) => event.allDay !== false); + drawer.innerHTML = ""; + if (allDayEvents.length === 0) + return; + const layouts = this.calculateLayout(allDayEvents, visibleColumnKeys); + const rowCount = Math.max(1, ...layouts.map((l) => l.row)); + layouts.forEach((layout) => { + const item = this.createHeaderItem(layout); + drawer.appendChild(item); + }); + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Create a header item element from layout + */ + createHeaderItem(layout) { + const { event, columnKey, row, colStart, colEnd } = layout; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = event.id; + item.dataset.itemType = "event"; + item.dataset.start = event.start.toISOString(); + item.dataset.end = event.end.toISOString(); + item.dataset.columnKey = columnKey; + item.textContent = event.title; + const colorClass = this.getColorClass(event); + if (colorClass) + item.classList.add(colorClass); + item.style.gridArea = `${row} / ${colStart} / ${row + 1} / ${colEnd}`; + return item; + } + /** + * Calculate layout for all events with row stacking + * Uses track-based algorithm to find available rows for overlapping events + */ + calculateLayout(events, visibleColumnKeys) { + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + const layouts = []; + for (const event of events) { + const columnKey = this.buildColumnKeyFromEvent(event); + const startCol = visibleColumnKeys.indexOf(columnKey); + const endColumnKey = this.buildColumnKeyFromEvent(event, event.end); + const endCol = visibleColumnKeys.indexOf(endColumnKey); + if (startCol === -1 && endCol === -1) + continue; + const colStart = Math.max(0, startCol); + const colEnd = (endCol !== -1 ? endCol : visibleColumnKeys.length - 1) + 1; + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + layouts.push({ event, columnKey, row: row + 1, colStart: colStart + 1, colEnd: colEnd + 1 }); + } + return layouts; + } + /** + * Build columnKey from event using FilterTemplate + * Uses the same template that columns use for matching + */ + buildColumnKeyFromEvent(event, date) { + if (!this.filterTemplate) { + const dateStr = this.dateService.getDateKey(date || event.start); + return dateStr; + } + if (date && date.getTime() !== event.start.getTime()) { + const tempEvent = { ...event, start: date }; + return this.filterTemplate.buildKeyFromEvent(tempEvent); + } + return this.filterTemplate.buildKeyFromEvent(event); + } + /** + * Find available row for event spanning columns [colStart, colEnd) + */ + findAvailableRow(tracks, colStart, colEnd) { + for (let row = 0; row < tracks.length; row++) { + let available = true; + for (let c = colStart; c < colEnd; c++) { + if (tracks[row][c]) { + available = false; + break; + } + } + if (available) + return row; + } + tracks.push(new Array(tracks[0].length).fill(false)); + return tracks.length - 1; + } + /** + * Get color class based on event metadata or type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Setup event listeners for drag events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_ENTER_HEADER, (e) => { + const payload = e.detail; + this.handleDragEnter(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragMove(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeave(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => { + this.cleanup(); + }); + } + /** + * Handle drag entering header zone - create preview item + */ + handleDragEnter(payload) { + this.container = document.querySelector("swp-header-drawer"); + if (!this.container) + return; + this.wasExpandedBeforeDrag = this.headerDrawerManager.isExpanded(); + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.expandToRows(1); + } + this.sourceElement = payload.element; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = payload.eventId; + item.dataset.itemType = payload.itemType; + item.dataset.duration = String(payload.duration); + item.dataset.columnKey = payload.sourceColumnKey; + item.textContent = payload.title; + if (payload.colorClass) { + item.classList.add(payload.colorClass); + } + item.classList.add("dragging"); + const col = payload.sourceColumnIndex + 1; + const endCol = col + payload.duration; + item.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.container.appendChild(item); + this.currentItem = item; + payload.element.style.visibility = "hidden"; + } + /** + * Handle drag moving within header - update column position + */ + handleDragMove(payload) { + if (!this.currentItem) + return; + const col = payload.columnIndex + 1; + const duration = parseInt(this.currentItem.dataset.duration || "1", 10); + const endCol = col + duration; + this.currentItem.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.currentItem.dataset.columnKey = payload.columnKey; + } + /** + * Handle drag leaving header - cleanup for grid→header drag only + */ + handleDragLeave(payload) { + if (payload.source === "grid") { + this.cleanup(); + } + } + /** + * Handle drag end - finalize based on drop target + */ + handleDragEnd(payload) { + if (payload.target === "header") { + if (this.currentItem) { + this.currentItem.classList.remove("dragging"); + this.recalculateDrawerLayout(); + this.currentItem = null; + this.sourceElement = null; + } + } else { + const ghost = document.querySelector(`swp-header-item.drag-ghost[data-event-id="${payload.swpEvent.eventId}"]`); + ghost?.remove(); + this.recalculateDrawerLayout(); + } + } + /** + * Recalculate layout for all items currently in the drawer + * Called after drop to reposition items and adjust height + */ + recalculateDrawerLayout() { + const drawer = document.querySelector("swp-header-drawer"); + if (!drawer) + return; + const items = Array.from(drawer.querySelectorAll("swp-header-item")); + if (items.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const itemData = items.map((item) => ({ + element: item, + columnKey: item.dataset.columnKey || "", + duration: parseInt(item.dataset.duration || "1", 10) + })); + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + for (const item of itemData) { + const startCol = visibleColumnKeys.indexOf(item.columnKey); + if (startCol === -1) + continue; + const colStart = startCol; + const colEnd = Math.min(startCol + item.duration, visibleColumnKeys.length); + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + item.element.style.gridArea = `${row + 1} / ${colStart + 1} / ${row + 2} / ${colEnd + 1}`; + } + const rowCount = tracks.length; + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Get visible column keys from DOM (preserves order for multi-resource views) + * Uses filterTemplate.buildKeyFromColumn() for consistent key format with events + */ + getVisibleColumnKeysFromDOM() { + if (!this.filterTemplate) + return []; + const columns = document.querySelectorAll("swp-day-column"); + const columnKeys = []; + columns.forEach((col) => { + const columnKey = this.filterTemplate.buildKeyFromColumn(col); + if (columnKey) + columnKeys.push(columnKey); + }); + return columnKeys; + } + /** + * Cleanup preview item and restore source visibility + */ + cleanup() { + this.currentItem?.remove(); + this.currentItem = null; + if (this.sourceElement) { + this.sourceElement.style.visibility = ""; + this.sourceElement = null; + } + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.collapse(); + } + } +}; +__name(_HeaderDrawerRenderer, "HeaderDrawerRenderer"); +var HeaderDrawerRenderer = _HeaderDrawerRenderer; + +// src/storage/schedules/ScheduleOverrideStore.ts +var _ScheduleOverrideStore = class _ScheduleOverrideStore { + constructor() { + this.storeName = _ScheduleOverrideStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ScheduleOverrideStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("date", "date", { unique: false }); + store.createIndex("resourceId_date", ["resourceId", "date"], { unique: true }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + } +}; +__name(_ScheduleOverrideStore, "ScheduleOverrideStore"); +var ScheduleOverrideStore = _ScheduleOverrideStore; +ScheduleOverrideStore.STORE_NAME = "scheduleOverrides"; + +// src/storage/schedules/ScheduleOverrideService.ts +var _ScheduleOverrideService = class _ScheduleOverrideService { + constructor(context) { + this.context = context; + } + get db() { + return this.context.getDatabase(); + } + /** + * Get override for a specific resource and date + */ + async getOverride(resourceId, date) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId_date"); + const request = index.get([resourceId, date]); + request.onsuccess = () => { + resolve(request.result || null); + }; + request.onerror = () => { + reject(new Error(`Failed to get override for ${resourceId} on ${date}: ${request.error}`)); + }; + }); + } + /** + * Get all overrides for a resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + resolve(request.result || []); + }; + request.onerror = () => { + reject(new Error(`Failed to get overrides for ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get overrides for a date range + */ + async getByDateRange(resourceId, startDate, endDate) { + const all = await this.getByResource(resourceId); + return all.filter((o) => o.date >= startDate && o.date <= endDate); + } + /** + * Save an override + */ + async save(override) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.put(override); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to save override ${override.id}: ${request.error}`)); + }; + }); + } + /** + * Delete an override + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.delete(id); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to delete override ${id}: ${request.error}`)); + }; + }); + } +}; +__name(_ScheduleOverrideService, "ScheduleOverrideService"); +var ScheduleOverrideService = _ScheduleOverrideService; + +// src/storage/schedules/ResourceScheduleService.ts +var _ResourceScheduleService = class _ResourceScheduleService { + constructor(resourceService, overrideService, dateService) { + this.resourceService = resourceService; + this.overrideService = overrideService; + this.dateService = dateService; + } + /** + * Get effective schedule for a resource on a specific date + * + * @param resourceId - Resource ID + * @param date - Date string "YYYY-MM-DD" + * @returns ITimeSlot or null (fri/closed) + */ + async getScheduleForDate(resourceId, date) { + const override = await this.overrideService.getOverride(resourceId, date); + if (override) { + return override.schedule; + } + const resource = await this.resourceService.get(resourceId); + if (!resource || !resource.defaultSchedule) { + return null; + } + const weekDay = this.dateService.getISOWeekDay(date); + return resource.defaultSchedule[weekDay] || null; + } + /** + * Get schedules for multiple dates + * + * @param resourceId - Resource ID + * @param dates - Array of date strings "YYYY-MM-DD" + * @returns Map of date -> ITimeSlot | null + */ + async getSchedulesForDates(resourceId, dates) { + const result = /* @__PURE__ */ new Map(); + const resource = await this.resourceService.get(resourceId); + const overrides = dates.length > 0 ? await this.overrideService.getByDateRange(resourceId, dates[0], dates[dates.length - 1]) : []; + const overrideMap = new Map(overrides.map((o) => [o.date, o.schedule])); + for (const date of dates) { + if (overrideMap.has(date)) { + result.set(date, overrideMap.get(date)); + continue; + } + if (resource?.defaultSchedule) { + const weekDay = this.dateService.getISOWeekDay(date); + result.set(date, resource.defaultSchedule[weekDay] || null); + } else { + result.set(date, null); + } + } + return result; + } +}; +__name(_ResourceScheduleService, "ResourceScheduleService"); +var ResourceScheduleService = _ResourceScheduleService; + +// src/types/SwpEvent.ts +var _SwpEvent = class _SwpEvent { + constructor(element, columnKey, start, end) { + this.element = element; + this.columnKey = columnKey; + this._start = start; + this._end = end; + } + /** Event ID from element.dataset.eventId */ + get eventId() { + return this.element.dataset.eventId || ""; + } + get start() { + return this._start; + } + get end() { + return this._end; + } + /** Duration in minutes */ + get durationMinutes() { + return (this._end.getTime() - this._start.getTime()) / (1e3 * 60); + } + /** Duration in milliseconds */ + get durationMs() { + return this._end.getTime() - this._start.getTime(); + } + /** + * Factory: Create SwpEvent from element + columnKey + * Reads top/height from element.style to calculate start/end + * @param columnKey - Opaque column identifier (do NOT parse - use only for matching) + * @param date - Date string (YYYY-MM-DD) for time calculations + */ + static fromElement(element, columnKey, date, gridConfig) { + const topPixels = parseFloat(element.style.top) || 0; + const heightPixels = parseFloat(element.style.height) || 0; + const startMinutesFromGrid = topPixels / gridConfig.hourHeight * 60; + const totalMinutes = gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const start = new Date(date); + start.setHours(Math.floor(totalMinutes / 60), totalMinutes % 60, 0, 0); + const durationMinutes = heightPixels / gridConfig.hourHeight * 60; + const end = new Date(start.getTime() + durationMinutes * 60 * 1e3); + return new _SwpEvent(element, columnKey, start, end); + } +}; +__name(_SwpEvent, "SwpEvent"); +var SwpEvent = _SwpEvent; + +// src/managers/DragDropManager.ts +var _DragDropManager = class _DragDropManager { + constructor(eventBus, gridConfig) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dragState = null; + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + this.container = null; + this.inHeader = false; + this.DRAG_THRESHOLD = 5; + this.INTERPOLATION_FACTOR = 0.3; + this.handlePointerDown = (e) => { + const target = e.target; + if (target.closest("swp-resize-handle")) + return; + const eventElement = target.closest("swp-event"); + const headerItem = target.closest("swp-header-item"); + const draggable = eventElement || headerItem; + if (!draggable) + return; + this.mouseDownPosition = { x: e.clientX, y: e.clientY }; + this.pendingElement = draggable; + const rect = draggable.getBoundingClientRect(); + this.pendingMouseOffset = { + x: e.clientX - rect.left, + y: e.clientY - rect.top + }; + draggable.setPointerCapture(e.pointerId); + }; + this.handlePointerMove = (e) => { + if (!this.mouseDownPosition || !this.pendingElement) { + if (this.dragState) { + this.updateDragTarget(e); + } + return; + } + const deltaX = Math.abs(e.clientX - this.mouseDownPosition.x); + const deltaY = Math.abs(e.clientY - this.mouseDownPosition.y); + const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + if (distance < this.DRAG_THRESHOLD) + return; + this.initializeDrag(this.pendingElement, this.pendingMouseOffset, e); + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + }; + this.handlePointerUp = (_e) => { + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + if (this.dragState.dragSource === "header") { + this.handleHeaderItemDragEnd(); + } else { + this.handleGridEventDragEnd(); + } + this.dragState.element.classList.remove("dragging"); + this.dragState = null; + this.inHeader = false; + }; + this.animateDrag = () => { + if (!this.dragState) + return; + const diff2 = this.dragState.targetY - this.dragState.currentY; + if (Math.abs(diff2) <= 0.5) { + this.dragState.animationId = 0; + return; + } + this.dragState.currentY += diff2 * this.INTERPOLATION_FACTOR; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + if (this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + currentY: this.dragState.currentY, + columnElement: this.dragState.columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE, payload); + } + this.dragState.animationId = requestAnimationFrame(this.animateDrag); + }; + this.setupScrollListener(); + } + setupScrollListener() { + this.eventBus.on(CoreEvents.EDGE_SCROLL_TICK, (e) => { + if (!this.dragState) + return; + const { scrollDelta } = e.detail; + this.dragState.targetY += scrollDelta; + this.dragState.currentY += scrollDelta; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + }); + } + /** + * Initialize drag-drop on a container element + */ + init(container2) { + this.container = container2; + container2.addEventListener("pointerdown", this.handlePointerDown); + document.addEventListener("pointermove", this.handlePointerMove); + document.addEventListener("pointerup", this.handlePointerUp); + } + /** + * Handle drag end for header items + */ + handleHeaderItemDragEnd() { + if (!this.dragState) + return; + if (!this.inHeader && this.dragState.currentColumn) { + const gridEvent = this.dragState.currentColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (gridEvent) { + const columnKey = this.dragState.currentColumn.dataset.columnKey || ""; + const date = this.dragState.currentColumn.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(gridEvent, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + } + } + /** + * Handle drag end for grid events + */ + handleGridEventDragEnd() { + if (!this.dragState || !this.dragState.columnElement) + return; + const snappedY = snapToGrid(this.dragState.currentY, this.gridConfig); + this.dragState.element.style.top = `${snappedY}px`; + this.dragState.ghostElement?.remove(); + const columnKey = this.dragState.columnElement.dataset.columnKey || ""; + const date = this.dragState.columnElement.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.dragState.element, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: this.inHeader ? "header" : "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + initializeDrag(element, mouseOffset, e) { + const eventId = element.dataset.eventId || ""; + const isHeaderItem = element.tagName.toLowerCase() === "swp-header-item"; + const columnElement = element.closest("swp-day-column"); + if (!isHeaderItem && !columnElement) + return; + if (isHeaderItem) { + this.initializeHeaderItemDrag(element, mouseOffset, eventId); + } else { + this.initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId); + } + } + /** + * Initialize drag for a header item (allDay event) + */ + initializeHeaderItemDrag(element, mouseOffset, eventId) { + element.classList.add("dragging"); + this.dragState = { + eventId, + element, + ghostElement: null, + // No ghost for header items + startY: 0, + mouseOffset, + columnElement: null, + currentColumn: null, + targetY: 0, + currentY: 0, + animationId: 0, + sourceColumnKey: "", + // Will be set from header item data + dragSource: "header" + }; + this.inHeader = true; + } + /** + * Initialize drag for a grid event + */ + initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId) { + const elementRect = element.getBoundingClientRect(); + const columnRect = columnElement.getBoundingClientRect(); + const startY = elementRect.top - columnRect.top; + const group = element.closest("swp-event-group"); + if (group) { + const eventsLayer = columnElement.querySelector("swp-events-layer"); + if (eventsLayer) { + eventsLayer.appendChild(element); + } + } + element.style.position = "absolute"; + element.style.top = `${startY}px`; + element.style.left = "2px"; + element.style.right = "2px"; + element.style.marginLeft = "0"; + const ghostElement = element.cloneNode(true); + ghostElement.classList.add("drag-ghost"); + ghostElement.style.opacity = "0.3"; + ghostElement.style.pointerEvents = "none"; + element.parentNode?.insertBefore(ghostElement, element); + element.classList.add("dragging"); + const targetY = e.clientY - columnRect.top - mouseOffset.y; + this.dragState = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement, + currentColumn: columnElement, + targetY: Math.max(0, targetY), + currentY: startY, + animationId: 0, + sourceColumnKey: columnElement.dataset.columnKey || "", + dragSource: "grid" + }; + const payload = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_START, payload); + this.animateDrag(); + } + updateDragTarget(e) { + if (!this.dragState) + return; + this.checkHeaderZone(e); + if (this.inHeader) + return; + const columnAtPoint = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header" && columnAtPoint && !this.dragState.currentColumn) { + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn && this.dragState.currentColumn) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + previousColumn: this.dragState.currentColumn, + newColumn: columnAtPoint, + currentY: this.dragState.currentY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, payload); + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (!this.dragState.columnElement) + return; + const columnRect = this.dragState.columnElement.getBoundingClientRect(); + const targetY = e.clientY - columnRect.top - this.dragState.mouseOffset.y; + this.dragState.targetY = Math.max(0, targetY); + if (!this.dragState.animationId) { + this.animateDrag(); + } + } + /** + * Check if pointer is in header zone and emit appropriate events + */ + checkHeaderZone(e) { + if (!this.dragState) + return; + const headerViewport = document.querySelector("swp-header-viewport"); + if (!headerViewport) + return; + const rect = headerViewport.getBoundingClientRect(); + const isInHeader = e.clientY < rect.bottom; + if (isInHeader && !this.inHeader) { + this.inHeader = true; + if (this.dragState.dragSource === "grid" && this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + sourceColumnIndex: this.getColumnIndex(this.dragState.columnElement), + sourceColumnKey: this.dragState.columnElement.dataset.columnKey || "", + title: this.dragState.element.querySelector("swp-event-title")?.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")), + itemType: "event", + duration: 1 + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_ENTER_HEADER, payload); + } + } else if (!isInHeader && this.inHeader) { + this.inHeader = false; + const targetColumn = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header") { + const payload = { + eventId: this.dragState.eventId, + source: "header", + element: this.dragState.element, + targetColumn: targetColumn || void 0, + start: this.dragState.element.dataset.start ? new Date(this.dragState.element.dataset.start) : void 0, + end: this.dragState.element.dataset.end ? new Date(this.dragState.element.dataset.end) : void 0, + title: this.dragState.element.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")) + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + if (targetColumn) { + const newElement = targetColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (newElement) { + this.dragState.element = newElement; + this.dragState.columnElement = targetColumn; + this.dragState.currentColumn = targetColumn; + this.animateDrag(); + } + } + } else { + const payload = { + eventId: this.dragState.eventId, + source: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + } + } else if (isInHeader) { + const column = this.getColumnAtX(e.clientX); + if (column) { + const payload = { + eventId: this.dragState.eventId, + columnIndex: this.getColumnIndex(column), + columnKey: column.dataset.columnKey || "" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE_HEADER, payload); + } + } + } + /** + * Get column index (0-based) for a column element + */ + getColumnIndex(column) { + if (!this.container || !column) + return 0; + const columns = Array.from(this.container.querySelectorAll("swp-day-column")); + return columns.indexOf(column); + } + /** + * Get column at X coordinate (alias for getColumnAtPoint) + */ + getColumnAtX(clientX) { + return this.getColumnAtPoint(clientX); + } + /** + * Find column element at given X coordinate + */ + getColumnAtPoint(clientX) { + if (!this.container) + return null; + const columns = this.container.querySelectorAll("swp-day-column"); + for (const col of columns) { + const rect = col.getBoundingClientRect(); + if (clientX >= rect.left && clientX <= rect.right) { + return col; + } + } + return null; + } + /** + * Cancel drag and animate back to start position + */ + cancelDrag() { + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + const { element, ghostElement, startY, eventId } = this.dragState; + element.style.transition = "top 200ms ease-out"; + element.style.top = `${startY}px`; + setTimeout(() => { + ghostElement?.remove(); + element.style.transition = ""; + element.classList.remove("dragging"); + }, 200); + const payload = { + eventId, + element, + startY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_CANCEL, payload); + this.dragState = null; + this.inHeader = false; + } +}; +__name(_DragDropManager, "DragDropManager"); +var DragDropManager = _DragDropManager; + +// src/managers/EdgeScrollManager.ts +var _EdgeScrollManager = class _EdgeScrollManager { + constructor(eventBus) { + this.eventBus = eventBus; + this.scrollableContent = null; + this.timeGrid = null; + this.draggedElement = null; + this.scrollRAF = null; + this.mouseY = 0; + this.isDragging = false; + this.isScrolling = false; + this.lastTs = 0; + this.rect = null; + this.initialScrollTop = 0; + this.OUTER_ZONE = 100; + this.INNER_ZONE = 50; + this.SLOW_SPEED = 140; + this.FAST_SPEED = 640; + this.trackMouse = (e) => { + if (this.isDragging) { + this.mouseY = e.clientY; + } + }; + this.scrollTick = (ts) => { + if (!this.isDragging || !this.scrollableContent) + return; + const dt = this.lastTs ? (ts - this.lastTs) / 1e3 : 0; + this.lastTs = ts; + this.rect ?? (this.rect = this.scrollableContent.getBoundingClientRect()); + const velocity = this.calculateVelocity(); + if (velocity !== 0 && !this.isAtBoundary(velocity)) { + const scrollDelta = velocity * dt; + this.scrollableContent.scrollTop += scrollDelta; + this.rect = null; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_TICK, { scrollDelta }); + this.setScrollingState(true); + } else { + this.setScrollingState(false); + } + this.scrollRAF = requestAnimationFrame(this.scrollTick); + }; + this.subscribeToEvents(); + document.addEventListener("pointermove", this.trackMouse); + } + init(scrollableContent) { + this.scrollableContent = scrollableContent; + this.timeGrid = scrollableContent.querySelector("swp-time-grid"); + this.scrollableContent.style.scrollBehavior = "auto"; + } + subscribeToEvents() { + this.eventBus.on(CoreEvents.EVENT_DRAG_START, (event) => { + const payload = event.detail; + this.draggedElement = payload.element; + this.startDrag(); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, () => this.stopDrag()); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => this.stopDrag()); + } + startDrag() { + this.isDragging = true; + this.isScrolling = false; + this.lastTs = 0; + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + if (this.scrollRAF === null) { + this.scrollRAF = requestAnimationFrame(this.scrollTick); + } + } + stopDrag() { + this.isDragging = false; + this.setScrollingState(false); + if (this.scrollRAF !== null) { + cancelAnimationFrame(this.scrollRAF); + this.scrollRAF = null; + } + this.rect = null; + this.lastTs = 0; + this.initialScrollTop = 0; + } + calculateVelocity() { + if (!this.rect) + return 0; + const distTop = this.mouseY - this.rect.top; + const distBot = this.rect.bottom - this.mouseY; + if (distTop < this.INNER_ZONE) + return -this.FAST_SPEED; + if (distTop < this.OUTER_ZONE) + return -this.SLOW_SPEED; + if (distBot < this.INNER_ZONE) + return this.FAST_SPEED; + if (distBot < this.OUTER_ZONE) + return this.SLOW_SPEED; + return 0; + } + isAtBoundary(velocity) { + if (!this.scrollableContent || !this.timeGrid || !this.draggedElement) + return false; + const atTop = this.scrollableContent.scrollTop <= 0 && velocity < 0; + const atBottom = velocity > 0 && this.draggedElement.getBoundingClientRect().bottom >= this.timeGrid.getBoundingClientRect().bottom; + return atTop || atBottom; + } + setScrollingState(scrolling) { + if (this.isScrolling === scrolling) + return; + this.isScrolling = scrolling; + if (scrolling) { + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STARTED, {}); + } else { + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STOPPED, {}); + } + } +}; +__name(_EdgeScrollManager, "EdgeScrollManager"); +var EdgeScrollManager = _EdgeScrollManager; + +// src/managers/ResizeManager.ts +var _ResizeManager = class _ResizeManager { + constructor(eventBus, gridConfig, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dateService = dateService; + this.container = null; + this.resizeState = null; + this.Z_INDEX_RESIZING = "1000"; + this.ANIMATION_SPEED = 0.35; + this.MIN_HEIGHT_MINUTES = 15; + this.handleMouseOver = (e) => { + const target = e.target; + const eventElement = target.closest("swp-event"); + if (!eventElement || this.resizeState) + return; + if (!eventElement.querySelector(":scope > swp-resize-handle")) { + const handle = this.createResizeHandle(); + eventElement.appendChild(handle); + } + }; + this.handlePointerDown = (e) => { + const handle = e.target.closest("swp-resize-handle"); + if (!handle) + return; + const element = handle.parentElement; + if (!element) + return; + const eventId = element.dataset.eventId || ""; + const startHeight = element.offsetHeight; + const startDurationMinutes = pixelsToMinutes(startHeight, this.gridConfig); + const container2 = element.closest("swp-event-group") ?? element; + const prevZIndex = container2.style.zIndex; + this.resizeState = { + eventId, + element, + handleElement: handle, + startY: e.clientY, + startHeight, + startDurationMinutes, + pointerId: e.pointerId, + prevZIndex, + // Animation state + currentHeight: startHeight, + targetHeight: startHeight, + animationId: null + }; + container2.style.zIndex = this.Z_INDEX_RESIZING; + try { + handle.setPointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer capture failed:", err); + } + document.documentElement.classList.add("swp--resizing"); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_START, { + eventId, + element, + startHeight + }); + e.preventDefault(); + }; + this.handlePointerMove = (e) => { + if (!this.resizeState) + return; + const deltaY = e.clientY - this.resizeState.startY; + const minHeight = this.MIN_HEIGHT_MINUTES / 60 * this.gridConfig.hourHeight; + const newHeight = Math.max(minHeight, this.resizeState.startHeight + deltaY); + this.resizeState.targetHeight = newHeight; + if (this.resizeState.animationId === null) { + this.animateHeight(); + } + }; + this.animateHeight = () => { + if (!this.resizeState) + return; + const diff2 = this.resizeState.targetHeight - this.resizeState.currentHeight; + if (Math.abs(diff2) < 0.5) { + this.resizeState.animationId = null; + return; + } + this.resizeState.currentHeight += diff2 * this.ANIMATION_SPEED; + this.resizeState.element.style.height = `${this.resizeState.currentHeight}px`; + this.updateTimestampDisplay(); + this.resizeState.animationId = requestAnimationFrame(this.animateHeight); + }; + this.handlePointerUp = (e) => { + if (!this.resizeState) + return; + if (this.resizeState.animationId !== null) { + cancelAnimationFrame(this.resizeState.animationId); + } + try { + this.resizeState.handleElement.releasePointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer release failed:", err); + } + this.snapToGridFinal(); + this.updateTimestampDisplay(); + const container2 = this.resizeState.element.closest("swp-event-group") ?? this.resizeState.element; + container2.style.zIndex = this.resizeState.prevZIndex; + document.documentElement.classList.remove("swp--resizing"); + const column = this.resizeState.element.closest("swp-day-column"); + const columnKey = column?.dataset.columnKey || ""; + const date = column?.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.resizeState.element, columnKey, date, this.gridConfig); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_END, { + swpEvent + }); + this.resizeState = null; + }; + } + /** + * Initialize resize functionality on container + */ + init(container2) { + this.container = container2; + container2.addEventListener("mouseover", this.handleMouseOver, true); + document.addEventListener("pointerdown", this.handlePointerDown, true); + document.addEventListener("pointermove", this.handlePointerMove, true); + document.addEventListener("pointerup", this.handlePointerUp, true); + } + /** + * Create resize handle element + */ + createResizeHandle() { + const handle = document.createElement("swp-resize-handle"); + handle.setAttribute("aria-label", "Resize event"); + handle.setAttribute("role", "separator"); + return handle; + } + /** + * Update timestamp display with snapped end time + */ + updateTimestampDisplay() { + if (!this.resizeState) + return; + const timeEl = this.resizeState.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const top = parseFloat(this.resizeState.element.style.top) || 0; + const startMinutesFromGrid = pixelsToMinutes(top, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const snappedHeight = snapToGrid(this.resizeState.currentHeight, this.gridConfig); + const durationMinutes = pixelsToMinutes(snappedHeight, this.gridConfig); + const endMinutes = startMinutes + durationMinutes; + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(endMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to Date + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Snap final height to grid interval + */ + snapToGridFinal() { + if (!this.resizeState) + return; + const currentHeight = this.resizeState.element.offsetHeight; + const snappedHeight = snapToGrid(currentHeight, this.gridConfig); + const minHeight = minutesToPixels(this.MIN_HEIGHT_MINUTES, this.gridConfig); + const finalHeight = Math.max(minHeight, snappedHeight); + this.resizeState.element.style.height = `${finalHeight}px`; + this.resizeState.currentHeight = finalHeight; + } +}; +__name(_ResizeManager, "ResizeManager"); +var ResizeManager = _ResizeManager; + +// src/managers/EventPersistenceManager.ts +var _EventPersistenceManager = class _EventPersistenceManager { + constructor(eventService, eventBus, dateService) { + this.eventService = eventService; + this.eventBus = eventBus; + this.dateService = dateService; + this.handleDragEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const { resource } = this.dateService.parseColumnKey(swpEvent.columnKey); + const updatedEvent = { + ...event, + start: swpEvent.start, + end: swpEvent.end, + resourceId: resource ?? event.resourceId, + allDay: payload.target === "header", + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: payload.sourceColumnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.handleResizeEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const updatedEvent = { + ...event, + end: swpEvent.end, + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: swpEvent.columnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.setupListeners(); + } + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_END, this.handleDragEnd); + this.eventBus.on(CoreEvents.EVENT_RESIZE_END, this.handleResizeEnd); + } +}; +__name(_EventPersistenceManager, "EventPersistenceManager"); +var EventPersistenceManager = _EventPersistenceManager; + +// src/CompositionRoot.ts +var defaultTimeFormatConfig = { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + use24HourFormat: true, + locale: "da-DK", + dateFormat: "locale", + showSeconds: false +}; +var defaultGridConfig = { + hourHeight: 64, + dayStartHour: 6, + dayEndHour: 18, + snapInterval: 15, + gridStartThresholdMinutes: 30 +}; +function createContainer() { + const container2 = new Container(); + const builder = container2.builder(); + builder.registerInstance(defaultTimeFormatConfig).as("ITimeFormatConfig"); + builder.registerInstance(defaultGridConfig).as("IGridConfig"); + builder.registerType(EventBus).as("EventBus"); + builder.registerType(EventBus).as("IEventBus"); + builder.registerType(DateService).as("DateService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ITimeFormatConfig"), + void 0 + ] + }); + builder.registerType(IndexedDBContext).as("IndexedDBContext").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IStore") + ] + }); + builder.registerType(EventStore).as("IStore"); + builder.registerType(ResourceStore).as("IStore"); + builder.registerType(BookingStore).as("IStore"); + builder.registerType(CustomerStore).as("IStore"); + builder.registerType(TeamStore).as("IStore"); + builder.registerType(DepartmentStore).as("IStore"); + builder.registerType(ScheduleOverrideStore).as("IStore"); + builder.registerType(AuditStore).as("IStore"); + builder.registerType(SettingsStore).as("IStore"); + builder.registerType(ViewConfigStore).as("IStore"); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("EventService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("ResourceService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("BookingService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("CustomerService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("TeamService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("DepartmentService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("SettingsService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("ViewConfigService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(MockEventRepository).as("IApiRepository"); + builder.registerType(MockEventRepository).as("IApiRepository"); + builder.registerType(MockResourceRepository).as("IApiRepository"); + builder.registerType(MockResourceRepository).as("IApiRepository"); + builder.registerType(MockBookingRepository).as("IApiRepository"); + builder.registerType(MockBookingRepository).as("IApiRepository"); + builder.registerType(MockCustomerRepository).as("IApiRepository"); + builder.registerType(MockCustomerRepository).as("IApiRepository"); + builder.registerType(MockAuditRepository).as("IApiRepository"); + builder.registerType(MockAuditRepository).as("IApiRepository"); + builder.registerType(MockTeamRepository).as("IApiRepository"); + builder.registerType(MockTeamRepository).as("IApiRepository"); + builder.registerType(MockDepartmentRepository).as("IApiRepository"); + builder.registerType(MockDepartmentRepository).as("IApiRepository"); + builder.registerType(MockSettingsRepository).as("IApiRepository"); + builder.registerType(MockSettingsRepository).as("IApiRepository"); + builder.registerType(MockViewConfigRepository).as("IApiRepository"); + builder.registerType(MockViewConfigRepository).as("IApiRepository"); + builder.registerType(AuditService).as("AuditService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DataSeeder).as("DataSeeder").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IEntityService"), + (c) => c.resolveTypeAll("IApiRepository") + ] + }); + builder.registerType(ScheduleOverrideService).as("ScheduleOverrideService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext") + ] + }); + builder.registerType(ResourceScheduleService).as("ResourceScheduleService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService"), + (c) => c.resolveType("ScheduleOverrideService"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(EventRenderer).as("EventRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ScheduleRenderer).as("ScheduleRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceScheduleService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(HeaderDrawerRenderer).as("HeaderDrawerRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(DateRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(ResourceRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService") + ] + }); + builder.registerType(TeamRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("TeamService") + ] + }); + builder.registerType(DepartmentRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("DepartmentService") + ] + }); + builder.registerType(MockTeamStore).as("IGroupingStore"); + builder.registerType(MockResourceStore).as("IGroupingStore"); + builder.registerType(CalendarOrchestrator).as("CalendarOrchestrator").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IRenderer"), + (c) => c.resolveType("EventRenderer"), + (c) => c.resolveType("ScheduleRenderer"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveTypeAll("IEntityService") + ] + }); + builder.registerType(TimeAxisRenderer).as("TimeAxisRenderer"); + builder.registerType(ScrollManager).as("ScrollManager"); + builder.registerType(HeaderDrawerManager).as("HeaderDrawerManager"); + builder.registerType(DragDropManager).as("DragDropManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(EdgeScrollManager).as("EdgeScrollManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResizeManager).as("ResizeManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(EventPersistenceManager).as("EventPersistenceManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(CalendarApp).as("CalendarApp").autoWire({ + mapResolvers: [ + (c) => c.resolveType("CalendarOrchestrator"), + (c) => c.resolveType("TimeAxisRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("ScrollManager"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("DragDropManager"), + (c) => c.resolveType("EdgeScrollManager"), + (c) => c.resolveType("ResizeManager"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("EventPersistenceManager"), + (c) => c.resolveType("SettingsService"), + (c) => c.resolveType("ViewConfigService"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DemoApp).as("DemoApp").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("DataSeeder"), + (c) => c.resolveType("AuditService"), + (c) => c.resolveType("CalendarApp"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("ResourceService"), + (c) => c.resolveType("IEventBus") + ] + }); + return builder.build(); +} +__name(createContainer, "createContainer"); + +// src/demo/index.ts +var container = createContainer(); +container.resolveType("DemoApp").init().catch(console.error); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL2RheWpzL2RheWpzLm1pbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3V0Yy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3RpbWV6b25lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9kYXlqcy9wbHVnaW4vaXNvV2Vlay5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQG5vdmFkaS9jb3JlL2Rpc3QvdG9rZW4uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2Vycm9ycy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQG5vdmFkaS9jb3JlL2Rpc3QvYXV0b3dpcmUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2J1aWxkZXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2NvbnRhaW5lci5qcyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2NvcmUvRGF0ZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2ZlYXR1cmVzL3Jlc291cmNlL1Jlc291cmNlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2ZlYXR1cmVzL3RlYW0vVGVhbVJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9kZXBhcnRtZW50L0RlcGFydG1lbnRSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvY29yZS9SZW5kZXJCdWlsZGVyLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0ZpbHRlclRlbXBsYXRlLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yLnRzIiwgIi4uLy4uL3NyYy9jb3JlL05hdmlnYXRpb25BbmltYXRvci50cyIsICIuLi8uLi9zcmMvY29yZS9DYWxlbmRhckV2ZW50cy50cyIsICIuLi8uLi9zcmMvY29yZS9DYWxlbmRhckFwcC50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvdGltZWF4aXMvVGltZUF4aXNSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvY29yZS9TY3JvbGxNYW5hZ2VyLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0hlYWRlckRyYXdlck1hbmFnZXIudHMiLCAiLi4vLi4vc3JjL2RlbW8vTW9ja1N0b3Jlcy50cyIsICIuLi8uLi9zcmMvZGVtby9EZW1vQXBwLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0V2ZW50QnVzLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL0luZGV4ZWREQkNvbnRleHQudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvZXZlbnRzL0V2ZW50U3RvcmUudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvZXZlbnRzL0V2ZW50U2VyaWFsaXphdGlvbi50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS9TeW5jUGx1Z2luLnRzIiwgIi4uLy4uL3NyYy9jb25zdGFudHMvQ29yZUV2ZW50cy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvanNvbi1kaWZmLXRzL3NyYy9oZWxwZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9qc29uLWRpZmYtdHMvc3JjL2pzb25EaWZmLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9qc29uLWRpZmYtdHMvc3JjL2pzb25Db21wYXJlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL0Jhc2VFbnRpdHlTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL2V2ZW50cy9FdmVudFNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU3RvcmUudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU2VydmljZS50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS9ib29raW5ncy9Cb29raW5nU3RvcmUudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvYm9va2luZ3MvQm9va2luZ1NlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvY3VzdG9tZXJzL0N1c3RvbWVyU3RvcmUudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvY3VzdG9tZXJzL0N1c3RvbWVyU2VydmljZS50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS90ZWFtcy9UZWFtU3RvcmUudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvdGVhbXMvVGVhbVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2UvZGVwYXJ0bWVudHMvRGVwYXJ0bWVudFN0b3JlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL2RlcGFydG1lbnRzL0RlcGFydG1lbnRTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL3NldHRpbmdzL1NldHRpbmdzU3RvcmUudHMiLCAiLi4vLi4vc3JjL3R5cGVzL1NldHRpbmdzVHlwZXMudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2Uvc2V0dGluZ3MvU2V0dGluZ3NTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL3ZpZXdjb25maWdzL1ZpZXdDb25maWdTdG9yZS50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS92aWV3Y29uZmlncy9WaWV3Q29uZmlnU2VydmljZS50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS9hdWRpdC9BdWRpdFN0b3JlLnRzIiwgIi4uLy4uL3NyYy9zdG9yYWdlL2F1ZGl0L0F1ZGl0U2VydmljZS50cyIsICIuLi8uLi9zcmMvcmVwb3NpdG9yaWVzL01vY2tFdmVudFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3JlcG9zaXRvcmllcy9Nb2NrUmVzb3VyY2VSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy9yZXBvc2l0b3JpZXMvTW9ja0Jvb2tpbmdSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy9yZXBvc2l0b3JpZXMvTW9ja0N1c3RvbWVyUmVwb3NpdG9yeS50cyIsICIuLi8uLi9zcmMvcmVwb3NpdG9yaWVzL01vY2tBdWRpdFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3JlcG9zaXRvcmllcy9Nb2NrVGVhbVJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3JlcG9zaXRvcmllcy9Nb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3JlcG9zaXRvcmllcy9Nb2NrU2V0dGluZ3NSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy9yZXBvc2l0b3JpZXMvTW9ja1ZpZXdDb25maWdSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy93b3JrZXJzL0RhdGFTZWVkZXIudHMiLCAiLi4vLi4vc3JjL3V0aWxzL1Bvc2l0aW9uVXRpbHMudHMiLCAiLi4vLi4vc3JjL2ZlYXR1cmVzL2V2ZW50L0V2ZW50TGF5b3V0RW5naW5lLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9zY2hlZHVsZS9TY2hlZHVsZVJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9oZWFkZXJkcmF3ZXIvSGVhZGVyRHJhd2VyUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2Uvc2NoZWR1bGVzL1NjaGVkdWxlT3ZlcnJpZGVTdG9yZS50cyIsICIuLi8uLi9zcmMvc3RvcmFnZS9zY2hlZHVsZXMvU2NoZWR1bGVPdmVycmlkZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3N0b3JhZ2Uvc2NoZWR1bGVzL1Jlc291cmNlU2NoZWR1bGVTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy90eXBlcy9Td3BFdmVudC50cyIsICIuLi8uLi9zcmMvbWFuYWdlcnMvRHJhZ0Ryb3BNYW5hZ2VyLnRzIiwgIi4uLy4uL3NyYy9tYW5hZ2Vycy9FZGdlU2Nyb2xsTWFuYWdlci50cyIsICIuLi8uLi9zcmMvbWFuYWdlcnMvUmVzaXplTWFuYWdlci50cyIsICIuLi8uLi9zcmMvbWFuYWdlcnMvRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIudHMiLCAiLi4vLi4vc3JjL0NvbXBvc2l0aW9uUm9vdC50cyIsICIuLi8uLi9zcmMvZGVtby9pbmRleC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiIWZ1bmN0aW9uKHQsZSl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9ZSgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoZSk6KHQ9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczp0fHxzZWxmKS5kYXlqcz1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHQ9MWUzLGU9NmU0LG49MzZlNSxyPVwibWlsbGlzZWNvbmRcIixpPVwic2Vjb25kXCIscz1cIm1pbnV0ZVwiLHU9XCJob3VyXCIsYT1cImRheVwiLG89XCJ3ZWVrXCIsYz1cIm1vbnRoXCIsZj1cInF1YXJ0ZXJcIixoPVwieWVhclwiLGQ9XCJkYXRlXCIsbD1cIkludmFsaWQgRGF0ZVwiLCQ9L14oXFxkezR9KVstL10/KFxcZHsxLDJ9KT9bLS9dPyhcXGR7MCwyfSlbVHRcXHNdKihcXGR7MSwyfSk/Oj8oXFxkezEsMn0pPzo/KFxcZHsxLDJ9KT9bLjpdPyhcXGQrKT8kLyx5PS9cXFsoW15cXF1dKyldfFl7MSw0fXxNezEsNH18RHsxLDJ9fGR7MSw0fXxIezEsMn18aHsxLDJ9fGF8QXxtezEsMn18c3sxLDJ9fFp7MSwyfXxTU1MvZyxNPXtuYW1lOlwiZW5cIix3ZWVrZGF5czpcIlN1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5XCIuc3BsaXQoXCJfXCIpLG1vbnRoczpcIkphbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXJcIi5zcGxpdChcIl9cIiksb3JkaW5hbDpmdW5jdGlvbih0KXt2YXIgZT1bXCJ0aFwiLFwic3RcIixcIm5kXCIsXCJyZFwiXSxuPXQlMTAwO3JldHVyblwiW1wiK3QrKGVbKG4tMjApJTEwXXx8ZVtuXXx8ZVswXSkrXCJdXCJ9fSxtPWZ1bmN0aW9uKHQsZSxuKXt2YXIgcj1TdHJpbmcodCk7cmV0dXJuIXJ8fHIubGVuZ3RoPj1lP3Q6XCJcIitBcnJheShlKzEtci5sZW5ndGgpLmpvaW4obikrdH0sdj17czptLHo6ZnVuY3Rpb24odCl7dmFyIGU9LXQudXRjT2Zmc2V0KCksbj1NYXRoLmFicyhlKSxyPU1hdGguZmxvb3Iobi82MCksaT1uJTYwO3JldHVybihlPD0wP1wiK1wiOlwiLVwiKSttKHIsMixcIjBcIikrXCI6XCIrbShpLDIsXCIwXCIpfSxtOmZ1bmN0aW9uIHQoZSxuKXtpZihlLmRhdGUoKTxuLmRhdGUoKSlyZXR1cm4tdChuLGUpO3ZhciByPTEyKihuLnllYXIoKS1lLnllYXIoKSkrKG4ubW9udGgoKS1lLm1vbnRoKCkpLGk9ZS5jbG9uZSgpLmFkZChyLGMpLHM9bi1pPDAsdT1lLmNsb25lKCkuYWRkKHIrKHM/LTE6MSksYyk7cmV0dXJuKygtKHIrKG4taSkvKHM/aS11OnUtaSkpfHwwKX0sYTpmdW5jdGlvbih0KXtyZXR1cm4gdDwwP01hdGguY2VpbCh0KXx8MDpNYXRoLmZsb29yKHQpfSxwOmZ1bmN0aW9uKHQpe3JldHVybntNOmMseTpoLHc6byxkOmEsRDpkLGg6dSxtOnMsczppLG1zOnIsUTpmfVt0XXx8U3RyaW5nKHR8fFwiXCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvcyQvLFwiXCIpfSx1OmZ1bmN0aW9uKHQpe3JldHVybiB2b2lkIDA9PT10fX0sZz1cImVuXCIsRD17fTtEW2ddPU07dmFyIHA9XCIkaXNEYXlqc09iamVjdFwiLFM9ZnVuY3Rpb24odCl7cmV0dXJuIHQgaW5zdGFuY2VvZiBffHwhKCF0fHwhdFtwXSl9LHc9ZnVuY3Rpb24gdChlLG4scil7dmFyIGk7aWYoIWUpcmV0dXJuIGc7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUpe3ZhciBzPWUudG9Mb3dlckNhc2UoKTtEW3NdJiYoaT1zKSxuJiYoRFtzXT1uLGk9cyk7dmFyIHU9ZS5zcGxpdChcIi1cIik7aWYoIWkmJnUubGVuZ3RoPjEpcmV0dXJuIHQodVswXSl9ZWxzZXt2YXIgYT1lLm5hbWU7RFthXT1lLGk9YX1yZXR1cm4hciYmaSYmKGc9aSksaXx8IXImJmd9LE89ZnVuY3Rpb24odCxlKXtpZihTKHQpKXJldHVybiB0LmNsb25lKCk7dmFyIG49XCJvYmplY3RcIj09dHlwZW9mIGU/ZTp7fTtyZXR1cm4gbi5kYXRlPXQsbi5hcmdzPWFyZ3VtZW50cyxuZXcgXyhuKX0sYj12O2IubD13LGIuaT1TLGIudz1mdW5jdGlvbih0LGUpe3JldHVybiBPKHQse2xvY2FsZTplLiRMLHV0YzplLiR1LHg6ZS4keCwkb2Zmc2V0OmUuJG9mZnNldH0pfTt2YXIgXz1mdW5jdGlvbigpe2Z1bmN0aW9uIE0odCl7dGhpcy4kTD13KHQubG9jYWxlLG51bGwsITApLHRoaXMucGFyc2UodCksdGhpcy4keD10aGlzLiR4fHx0Lnh8fHt9LHRoaXNbcF09ITB9dmFyIG09TS5wcm90b3R5cGU7cmV0dXJuIG0ucGFyc2U9ZnVuY3Rpb24odCl7dGhpcy4kZD1mdW5jdGlvbih0KXt2YXIgZT10LmRhdGUsbj10LnV0YztpZihudWxsPT09ZSlyZXR1cm4gbmV3IERhdGUoTmFOKTtpZihiLnUoZSkpcmV0dXJuIG5ldyBEYXRlO2lmKGUgaW5zdGFuY2VvZiBEYXRlKXJldHVybiBuZXcgRGF0ZShlKTtpZihcInN0cmluZ1wiPT10eXBlb2YgZSYmIS9aJC9pLnRlc3QoZSkpe3ZhciByPWUubWF0Y2goJCk7aWYocil7dmFyIGk9clsyXS0xfHwwLHM9KHJbN118fFwiMFwiKS5zdWJzdHJpbmcoMCwzKTtyZXR1cm4gbj9uZXcgRGF0ZShEYXRlLlVUQyhyWzFdLGksclszXXx8MSxyWzRdfHwwLHJbNV18fDAscls2XXx8MCxzKSk6bmV3IERhdGUoclsxXSxpLHJbM118fDEscls0XXx8MCxyWzVdfHwwLHJbNl18fDAscyl9fXJldHVybiBuZXcgRGF0ZShlKX0odCksdGhpcy5pbml0KCl9LG0uaW5pdD1mdW5jdGlvbigpe3ZhciB0PXRoaXMuJGQ7dGhpcy4keT10LmdldEZ1bGxZZWFyKCksdGhpcy4kTT10LmdldE1vbnRoKCksdGhpcy4kRD10LmdldERhdGUoKSx0aGlzLiRXPXQuZ2V0RGF5KCksdGhpcy4kSD10LmdldEhvdXJzKCksdGhpcy4kbT10LmdldE1pbnV0ZXMoKSx0aGlzLiRzPXQuZ2V0U2Vjb25kcygpLHRoaXMuJG1zPXQuZ2V0TWlsbGlzZWNvbmRzKCl9LG0uJHV0aWxzPWZ1bmN0aW9uKCl7cmV0dXJuIGJ9LG0uaXNWYWxpZD1mdW5jdGlvbigpe3JldHVybiEodGhpcy4kZC50b1N0cmluZygpPT09bCl9LG0uaXNTYW1lPWZ1bmN0aW9uKHQsZSl7dmFyIG49Tyh0KTtyZXR1cm4gdGhpcy5zdGFydE9mKGUpPD1uJiZuPD10aGlzLmVuZE9mKGUpfSxtLmlzQWZ0ZXI9ZnVuY3Rpb24odCxlKXtyZXR1cm4gTyh0KTx0aGlzLnN0YXJ0T2YoZSl9LG0uaXNCZWZvcmU9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5lbmRPZihlKTxPKHQpfSxtLiRnPWZ1bmN0aW9uKHQsZSxuKXtyZXR1cm4gYi51KHQpP3RoaXNbZV06dGhpcy5zZXQobix0KX0sbS51bml4PWZ1bmN0aW9uKCl7cmV0dXJuIE1hdGguZmxvb3IodGhpcy52YWx1ZU9mKCkvMWUzKX0sbS52YWx1ZU9mPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGQuZ2V0VGltZSgpfSxtLnN0YXJ0T2Y9ZnVuY3Rpb24odCxlKXt2YXIgbj10aGlzLHI9ISFiLnUoZSl8fGUsZj1iLnAodCksbD1mdW5jdGlvbih0LGUpe3ZhciBpPWIudyhuLiR1P0RhdGUuVVRDKG4uJHksZSx0KTpuZXcgRGF0ZShuLiR5LGUsdCksbik7cmV0dXJuIHI/aTppLmVuZE9mKGEpfSwkPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGIudyhuLnRvRGF0ZSgpW3RdLmFwcGx5KG4udG9EYXRlKFwic1wiKSwocj9bMCwwLDAsMF06WzIzLDU5LDU5LDk5OV0pLnNsaWNlKGUpKSxuKX0seT10aGlzLiRXLE09dGhpcy4kTSxtPXRoaXMuJEQsdj1cInNldFwiKyh0aGlzLiR1P1wiVVRDXCI6XCJcIik7c3dpdGNoKGYpe2Nhc2UgaDpyZXR1cm4gcj9sKDEsMCk6bCgzMSwxMSk7Y2FzZSBjOnJldHVybiByP2woMSxNKTpsKDAsTSsxKTtjYXNlIG86dmFyIGc9dGhpcy4kbG9jYWxlKCkud2Vla1N0YXJ0fHwwLEQ9KHk8Zz95Kzc6eSktZztyZXR1cm4gbChyP20tRDptKyg2LUQpLE0pO2Nhc2UgYTpjYXNlIGQ6cmV0dXJuICQoditcIkhvdXJzXCIsMCk7Y2FzZSB1OnJldHVybiAkKHYrXCJNaW51dGVzXCIsMSk7Y2FzZSBzOnJldHVybiAkKHYrXCJTZWNvbmRzXCIsMik7Y2FzZSBpOnJldHVybiAkKHYrXCJNaWxsaXNlY29uZHNcIiwzKTtkZWZhdWx0OnJldHVybiB0aGlzLmNsb25lKCl9fSxtLmVuZE9mPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnN0YXJ0T2YodCwhMSl9LG0uJHNldD1mdW5jdGlvbih0LGUpe3ZhciBuLG89Yi5wKHQpLGY9XCJzZXRcIisodGhpcy4kdT9cIlVUQ1wiOlwiXCIpLGw9KG49e30sblthXT1mK1wiRGF0ZVwiLG5bZF09ZitcIkRhdGVcIixuW2NdPWYrXCJNb250aFwiLG5baF09ZitcIkZ1bGxZZWFyXCIsblt1XT1mK1wiSG91cnNcIixuW3NdPWYrXCJNaW51dGVzXCIsbltpXT1mK1wiU2Vjb25kc1wiLG5bcl09ZitcIk1pbGxpc2Vjb25kc1wiLG4pW29dLCQ9bz09PWE/dGhpcy4kRCsoZS10aGlzLiRXKTplO2lmKG89PT1jfHxvPT09aCl7dmFyIHk9dGhpcy5jbG9uZSgpLnNldChkLDEpO3kuJGRbbF0oJCkseS5pbml0KCksdGhpcy4kZD15LnNldChkLE1hdGgubWluKHRoaXMuJEQseS5kYXlzSW5Nb250aCgpKSkuJGR9ZWxzZSBsJiZ0aGlzLiRkW2xdKCQpO3JldHVybiB0aGlzLmluaXQoKSx0aGlzfSxtLnNldD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLmNsb25lKCkuJHNldCh0LGUpfSxtLmdldD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpc1tiLnAodCldKCl9LG0uYWRkPWZ1bmN0aW9uKHIsZil7dmFyIGQsbD10aGlzO3I9TnVtYmVyKHIpO3ZhciAkPWIucChmKSx5PWZ1bmN0aW9uKHQpe3ZhciBlPU8obCk7cmV0dXJuIGIudyhlLmRhdGUoZS5kYXRlKCkrTWF0aC5yb3VuZCh0KnIpKSxsKX07aWYoJD09PWMpcmV0dXJuIHRoaXMuc2V0KGMsdGhpcy4kTStyKTtpZigkPT09aClyZXR1cm4gdGhpcy5zZXQoaCx0aGlzLiR5K3IpO2lmKCQ9PT1hKXJldHVybiB5KDEpO2lmKCQ9PT1vKXJldHVybiB5KDcpO3ZhciBNPShkPXt9LGRbc109ZSxkW3VdPW4sZFtpXT10LGQpWyRdfHwxLG09dGhpcy4kZC5nZXRUaW1lKCkrcipNO3JldHVybiBiLncobSx0aGlzKX0sbS5zdWJ0cmFjdD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLmFkZCgtMSp0LGUpfSxtLmZvcm1hdD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLG49dGhpcy4kbG9jYWxlKCk7aWYoIXRoaXMuaXNWYWxpZCgpKXJldHVybiBuLmludmFsaWREYXRlfHxsO3ZhciByPXR8fFwiWVlZWS1NTS1ERFRISDptbTpzc1pcIixpPWIueih0aGlzKSxzPXRoaXMuJEgsdT10aGlzLiRtLGE9dGhpcy4kTSxvPW4ud2Vla2RheXMsYz1uLm1vbnRocyxmPW4ubWVyaWRpZW0saD1mdW5jdGlvbih0LG4saSxzKXtyZXR1cm4gdCYmKHRbbl18fHQoZSxyKSl8fGlbbl0uc2xpY2UoMCxzKX0sZD1mdW5jdGlvbih0KXtyZXR1cm4gYi5zKHMlMTJ8fDEyLHQsXCIwXCIpfSwkPWZ8fGZ1bmN0aW9uKHQsZSxuKXt2YXIgcj10PDEyP1wiQU1cIjpcIlBNXCI7cmV0dXJuIG4/ci50b0xvd2VyQ2FzZSgpOnJ9O3JldHVybiByLnJlcGxhY2UoeSwoZnVuY3Rpb24odCxyKXtyZXR1cm4gcnx8ZnVuY3Rpb24odCl7c3dpdGNoKHQpe2Nhc2VcIllZXCI6cmV0dXJuIFN0cmluZyhlLiR5KS5zbGljZSgtMik7Y2FzZVwiWVlZWVwiOnJldHVybiBiLnMoZS4keSw0LFwiMFwiKTtjYXNlXCJNXCI6cmV0dXJuIGErMTtjYXNlXCJNTVwiOnJldHVybiBiLnMoYSsxLDIsXCIwXCIpO2Nhc2VcIk1NTVwiOnJldHVybiBoKG4ubW9udGhzU2hvcnQsYSxjLDMpO2Nhc2VcIk1NTU1cIjpyZXR1cm4gaChjLGEpO2Nhc2VcIkRcIjpyZXR1cm4gZS4kRDtjYXNlXCJERFwiOnJldHVybiBiLnMoZS4kRCwyLFwiMFwiKTtjYXNlXCJkXCI6cmV0dXJuIFN0cmluZyhlLiRXKTtjYXNlXCJkZFwiOnJldHVybiBoKG4ud2Vla2RheXNNaW4sZS4kVyxvLDIpO2Nhc2VcImRkZFwiOnJldHVybiBoKG4ud2Vla2RheXNTaG9ydCxlLiRXLG8sMyk7Y2FzZVwiZGRkZFwiOnJldHVybiBvW2UuJFddO2Nhc2VcIkhcIjpyZXR1cm4gU3RyaW5nKHMpO2Nhc2VcIkhIXCI6cmV0dXJuIGIucyhzLDIsXCIwXCIpO2Nhc2VcImhcIjpyZXR1cm4gZCgxKTtjYXNlXCJoaFwiOnJldHVybiBkKDIpO2Nhc2VcImFcIjpyZXR1cm4gJChzLHUsITApO2Nhc2VcIkFcIjpyZXR1cm4gJChzLHUsITEpO2Nhc2VcIm1cIjpyZXR1cm4gU3RyaW5nKHUpO2Nhc2VcIm1tXCI6cmV0dXJuIGIucyh1LDIsXCIwXCIpO2Nhc2VcInNcIjpyZXR1cm4gU3RyaW5nKGUuJHMpO2Nhc2VcInNzXCI6cmV0dXJuIGIucyhlLiRzLDIsXCIwXCIpO2Nhc2VcIlNTU1wiOnJldHVybiBiLnMoZS4kbXMsMyxcIjBcIik7Y2FzZVwiWlwiOnJldHVybiBpfXJldHVybiBudWxsfSh0KXx8aS5yZXBsYWNlKFwiOlwiLFwiXCIpfSkpfSxtLnV0Y09mZnNldD1mdW5jdGlvbigpe3JldHVybiAxNSotTWF0aC5yb3VuZCh0aGlzLiRkLmdldFRpbWV6b25lT2Zmc2V0KCkvMTUpfSxtLmRpZmY9ZnVuY3Rpb24ocixkLGwpe3ZhciAkLHk9dGhpcyxNPWIucChkKSxtPU8ociksdj0obS51dGNPZmZzZXQoKS10aGlzLnV0Y09mZnNldCgpKSplLGc9dGhpcy1tLEQ9ZnVuY3Rpb24oKXtyZXR1cm4gYi5tKHksbSl9O3N3aXRjaChNKXtjYXNlIGg6JD1EKCkvMTI7YnJlYWs7Y2FzZSBjOiQ9RCgpO2JyZWFrO2Nhc2UgZjokPUQoKS8zO2JyZWFrO2Nhc2UgbzokPShnLXYpLzYwNDhlNTticmVhaztjYXNlIGE6JD0oZy12KS84NjRlNTticmVhaztjYXNlIHU6JD1nL247YnJlYWs7Y2FzZSBzOiQ9Zy9lO2JyZWFrO2Nhc2UgaTokPWcvdDticmVhaztkZWZhdWx0OiQ9Z31yZXR1cm4gbD8kOmIuYSgkKX0sbS5kYXlzSW5Nb250aD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmVuZE9mKGMpLiREfSxtLiRsb2NhbGU9ZnVuY3Rpb24oKXtyZXR1cm4gRFt0aGlzLiRMXX0sbS5sb2NhbGU9ZnVuY3Rpb24odCxlKXtpZighdClyZXR1cm4gdGhpcy4kTDt2YXIgbj10aGlzLmNsb25lKCkscj13KHQsZSwhMCk7cmV0dXJuIHImJihuLiRMPXIpLG59LG0uY2xvbmU9ZnVuY3Rpb24oKXtyZXR1cm4gYi53KHRoaXMuJGQsdGhpcyl9LG0udG9EYXRlPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBEYXRlKHRoaXMudmFsdWVPZigpKX0sbS50b0pTT049ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pc1ZhbGlkKCk/dGhpcy50b0lTT1N0cmluZygpOm51bGx9LG0udG9JU09TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4kZC50b0lTT1N0cmluZygpfSxtLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGQudG9VVENTdHJpbmcoKX0sTX0oKSxrPV8ucHJvdG90eXBlO3JldHVybiBPLnByb3RvdHlwZT1rLFtbXCIkbXNcIixyXSxbXCIkc1wiLGldLFtcIiRtXCIsc10sW1wiJEhcIix1XSxbXCIkV1wiLGFdLFtcIiRNXCIsY10sW1wiJHlcIixoXSxbXCIkRFwiLGRdXS5mb3JFYWNoKChmdW5jdGlvbih0KXtrW3RbMV1dPWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLiRnKGUsdFswXSx0WzFdKX19KSksTy5leHRlbmQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC4kaXx8KHQoZSxfLE8pLHQuJGk9ITApLE99LE8ubG9jYWxlPXcsTy5pc0RheWpzPVMsTy51bml4PWZ1bmN0aW9uKHQpe3JldHVybiBPKDFlMyp0KX0sTy5lbj1EW2ddLE8uTHM9RCxPLnA9e30sT30pKTsiLCAiIWZ1bmN0aW9uKHQsaSl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9aSgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoaSk6KHQ9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczp0fHxzZWxmKS5kYXlqc19wbHVnaW5fdXRjPWkoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgdD1cIm1pbnV0ZVwiLGk9L1srLV1cXGRcXGQoPzo6P1xcZFxcZCk/L2csZT0vKFsrLV18XFxkXFxkKS9nO3JldHVybiBmdW5jdGlvbihzLGYsbil7dmFyIHU9Zi5wcm90b3R5cGU7bi51dGM9ZnVuY3Rpb24odCl7dmFyIGk9e2RhdGU6dCx1dGM6ITAsYXJnczphcmd1bWVudHN9O3JldHVybiBuZXcgZihpKX0sdS51dGM9ZnVuY3Rpb24oaSl7dmFyIGU9bih0aGlzLnRvRGF0ZSgpLHtsb2NhbGU6dGhpcy4kTCx1dGM6ITB9KTtyZXR1cm4gaT9lLmFkZCh0aGlzLnV0Y09mZnNldCgpLHQpOmV9LHUubG9jYWw9ZnVuY3Rpb24oKXtyZXR1cm4gbih0aGlzLnRvRGF0ZSgpLHtsb2NhbGU6dGhpcy4kTCx1dGM6ITF9KX07dmFyIHI9dS5wYXJzZTt1LnBhcnNlPWZ1bmN0aW9uKHQpe3QudXRjJiYodGhpcy4kdT0hMCksdGhpcy4kdXRpbHMoKS51KHQuJG9mZnNldCl8fCh0aGlzLiRvZmZzZXQ9dC4kb2Zmc2V0KSxyLmNhbGwodGhpcyx0KX07dmFyIG89dS5pbml0O3UuaW5pdD1mdW5jdGlvbigpe2lmKHRoaXMuJHUpe3ZhciB0PXRoaXMuJGQ7dGhpcy4keT10LmdldFVUQ0Z1bGxZZWFyKCksdGhpcy4kTT10LmdldFVUQ01vbnRoKCksdGhpcy4kRD10LmdldFVUQ0RhdGUoKSx0aGlzLiRXPXQuZ2V0VVRDRGF5KCksdGhpcy4kSD10LmdldFVUQ0hvdXJzKCksdGhpcy4kbT10LmdldFVUQ01pbnV0ZXMoKSx0aGlzLiRzPXQuZ2V0VVRDU2Vjb25kcygpLHRoaXMuJG1zPXQuZ2V0VVRDTWlsbGlzZWNvbmRzKCl9ZWxzZSBvLmNhbGwodGhpcyl9O3ZhciBhPXUudXRjT2Zmc2V0O3UudXRjT2Zmc2V0PWZ1bmN0aW9uKHMsZil7dmFyIG49dGhpcy4kdXRpbHMoKS51O2lmKG4ocykpcmV0dXJuIHRoaXMuJHU/MDpuKHRoaXMuJG9mZnNldCk/YS5jYWxsKHRoaXMpOnRoaXMuJG9mZnNldDtpZihcInN0cmluZ1wiPT10eXBlb2YgcyYmKHM9ZnVuY3Rpb24odCl7dm9pZCAwPT09dCYmKHQ9XCJcIik7dmFyIHM9dC5tYXRjaChpKTtpZighcylyZXR1cm4gbnVsbDt2YXIgZj0oXCJcIitzWzBdKS5tYXRjaChlKXx8W1wiLVwiLDAsMF0sbj1mWzBdLHU9NjAqK2ZbMV0rICtmWzJdO3JldHVybiAwPT09dT8wOlwiK1wiPT09bj91Oi11fShzKSxudWxsPT09cykpcmV0dXJuIHRoaXM7dmFyIHU9TWF0aC5hYnMocyk8PTE2PzYwKnM6cztpZigwPT09dSlyZXR1cm4gdGhpcy51dGMoZik7dmFyIHI9dGhpcy5jbG9uZSgpO2lmKGYpcmV0dXJuIHIuJG9mZnNldD11LHIuJHU9ITEscjt2YXIgbz10aGlzLiR1P3RoaXMudG9EYXRlKCkuZ2V0VGltZXpvbmVPZmZzZXQoKTotMSp0aGlzLnV0Y09mZnNldCgpO3JldHVybihyPXRoaXMubG9jYWwoKS5hZGQodStvLHQpKS4kb2Zmc2V0PXUsci4keC4kbG9jYWxPZmZzZXQ9byxyfTt2YXIgaD11LmZvcm1hdDt1LmZvcm1hdD1mdW5jdGlvbih0KXt2YXIgaT10fHwodGhpcy4kdT9cIllZWVktTU0tRERUSEg6bW06c3NbWl1cIjpcIlwiKTtyZXR1cm4gaC5jYWxsKHRoaXMsaSl9LHUudmFsdWVPZj1mdW5jdGlvbigpe3ZhciB0PXRoaXMuJHV0aWxzKCkudSh0aGlzLiRvZmZzZXQpPzA6dGhpcy4kb2Zmc2V0Kyh0aGlzLiR4LiRsb2NhbE9mZnNldHx8dGhpcy4kZC5nZXRUaW1lem9uZU9mZnNldCgpKTtyZXR1cm4gdGhpcy4kZC52YWx1ZU9mKCktNmU0KnR9LHUuaXNVVEM9ZnVuY3Rpb24oKXtyZXR1cm4hIXRoaXMuJHV9LHUudG9JU09TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50b0RhdGUoKS50b0lTT1N0cmluZygpfSx1LnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudG9EYXRlKCkudG9VVENTdHJpbmcoKX07dmFyIGw9dS50b0RhdGU7dS50b0RhdGU9ZnVuY3Rpb24odCl7cmV0dXJuXCJzXCI9PT10JiZ0aGlzLiRvZmZzZXQ/bih0aGlzLmZvcm1hdChcIllZWVktTU0tREQgSEg6bW06c3M6U1NTXCIpKS50b0RhdGUoKTpsLmNhbGwodGhpcyl9O3ZhciBjPXUuZGlmZjt1LmRpZmY9ZnVuY3Rpb24odCxpLGUpe2lmKHQmJnRoaXMuJHU9PT10LiR1KXJldHVybiBjLmNhbGwodGhpcyx0LGksZSk7dmFyIHM9dGhpcy5sb2NhbCgpLGY9bih0KS5sb2NhbCgpO3JldHVybiBjLmNhbGwocyxmLGksZSl9fX0pKTsiLCAiIWZ1bmN0aW9uKHQsZSl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9ZSgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoZSk6KHQ9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczp0fHxzZWxmKS5kYXlqc19wbHVnaW5fdGltZXpvbmU9ZSgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciB0PXt5ZWFyOjAsbW9udGg6MSxkYXk6Mixob3VyOjMsbWludXRlOjQsc2Vjb25kOjV9LGU9e307cmV0dXJuIGZ1bmN0aW9uKG4saSxvKXt2YXIgcixhPWZ1bmN0aW9uKHQsbixpKXt2b2lkIDA9PT1pJiYoaT17fSk7dmFyIG89bmV3IERhdGUodCkscj1mdW5jdGlvbih0LG4pe3ZvaWQgMD09PW4mJihuPXt9KTt2YXIgaT1uLnRpbWVab25lTmFtZXx8XCJzaG9ydFwiLG89dCtcInxcIitpLHI9ZVtvXTtyZXR1cm4gcnx8KHI9bmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoXCJlbi1VU1wiLHtob3VyMTI6ITEsdGltZVpvbmU6dCx5ZWFyOlwibnVtZXJpY1wiLG1vbnRoOlwiMi1kaWdpdFwiLGRheTpcIjItZGlnaXRcIixob3VyOlwiMi1kaWdpdFwiLG1pbnV0ZTpcIjItZGlnaXRcIixzZWNvbmQ6XCIyLWRpZ2l0XCIsdGltZVpvbmVOYW1lOml9KSxlW29dPXIpLHJ9KG4saSk7cmV0dXJuIHIuZm9ybWF0VG9QYXJ0cyhvKX0sdT1mdW5jdGlvbihlLG4pe2Zvcih2YXIgaT1hKGUsbikscj1bXSx1PTA7dTxpLmxlbmd0aDt1Kz0xKXt2YXIgZj1pW3VdLHM9Zi50eXBlLG09Zi52YWx1ZSxjPXRbc107Yz49MCYmKHJbY109cGFyc2VJbnQobSwxMCkpfXZhciBkPXJbM10sbD0yND09PWQ/MDpkLGg9clswXStcIi1cIityWzFdK1wiLVwiK3JbMl0rXCIgXCIrbCtcIjpcIityWzRdK1wiOlwiK3JbNV0rXCI6MDAwXCIsdj0rZTtyZXR1cm4oby51dGMoaCkudmFsdWVPZigpLSh2LT12JTFlMykpLzZlNH0sZj1pLnByb3RvdHlwZTtmLnR6PWZ1bmN0aW9uKHQsZSl7dm9pZCAwPT09dCYmKHQ9cik7dmFyIG4saT10aGlzLnV0Y09mZnNldCgpLGE9dGhpcy50b0RhdGUoKSx1PWEudG9Mb2NhbGVTdHJpbmcoXCJlbi1VU1wiLHt0aW1lWm9uZTp0fSksZj1NYXRoLnJvdW5kKChhLW5ldyBEYXRlKHUpKS8xZTMvNjApLHM9MTUqLU1hdGgucm91bmQoYS5nZXRUaW1lem9uZU9mZnNldCgpLzE1KS1mO2lmKCFOdW1iZXIocykpbj10aGlzLnV0Y09mZnNldCgwLGUpO2Vsc2UgaWYobj1vKHUse2xvY2FsZTp0aGlzLiRMfSkuJHNldChcIm1pbGxpc2Vjb25kXCIsdGhpcy4kbXMpLnV0Y09mZnNldChzLCEwKSxlKXt2YXIgbT1uLnV0Y09mZnNldCgpO249bi5hZGQoaS1tLFwibWludXRlXCIpfXJldHVybiBuLiR4LiR0aW1lem9uZT10LG59LGYub2Zmc2V0TmFtZT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLiR4LiR0aW1lem9uZXx8by50ei5ndWVzcygpLG49YSh0aGlzLnZhbHVlT2YoKSxlLHt0aW1lWm9uZU5hbWU6dH0pLmZpbmQoKGZ1bmN0aW9uKHQpe3JldHVyblwidGltZXpvbmVuYW1lXCI9PT10LnR5cGUudG9Mb3dlckNhc2UoKX0pKTtyZXR1cm4gbiYmbi52YWx1ZX07dmFyIHM9Zi5zdGFydE9mO2Yuc3RhcnRPZj1mdW5jdGlvbih0LGUpe2lmKCF0aGlzLiR4fHwhdGhpcy4keC4kdGltZXpvbmUpcmV0dXJuIHMuY2FsbCh0aGlzLHQsZSk7dmFyIG49byh0aGlzLmZvcm1hdChcIllZWVktTU0tREQgSEg6bW06c3M6U1NTXCIpLHtsb2NhbGU6dGhpcy4kTH0pO3JldHVybiBzLmNhbGwobix0LGUpLnR6KHRoaXMuJHguJHRpbWV6b25lLCEwKX0sby50ej1mdW5jdGlvbih0LGUsbil7dmFyIGk9biYmZSxhPW58fGV8fHIsZj11KCtvKCksYSk7aWYoXCJzdHJpbmdcIiE9dHlwZW9mIHQpcmV0dXJuIG8odCkudHooYSk7dmFyIHM9ZnVuY3Rpb24odCxlLG4pe3ZhciBpPXQtNjAqZSoxZTMsbz11KGksbik7aWYoZT09PW8pcmV0dXJuW2ksZV07dmFyIHI9dShpLT02MCooby1lKSoxZTMsbik7cmV0dXJuIG89PT1yP1tpLG9dOlt0LTYwKk1hdGgubWluKG8scikqMWUzLE1hdGgubWF4KG8scildfShvLnV0Yyh0LGkpLnZhbHVlT2YoKSxmLGEpLG09c1swXSxjPXNbMV0sZD1vKG0pLnV0Y09mZnNldChjKTtyZXR1cm4gZC4keC4kdGltZXpvbmU9YSxkfSxvLnR6Lmd1ZXNzPWZ1bmN0aW9uKCl7cmV0dXJuIEludGwuRGF0ZVRpbWVGb3JtYXQoKS5yZXNvbHZlZE9wdGlvbnMoKS50aW1lWm9uZX0sby50ei5zZXREZWZhdWx0PWZ1bmN0aW9uKHQpe3I9dH19fSkpOyIsICIhZnVuY3Rpb24oZSx0KXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz10KCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZSh0KTooZT1cInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOmV8fHNlbGYpLmRheWpzX3BsdWdpbl9pc29XZWVrPXQoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgZT1cImRheVwiO3JldHVybiBmdW5jdGlvbih0LGkscyl7dmFyIGE9ZnVuY3Rpb24odCl7cmV0dXJuIHQuYWRkKDQtdC5pc29XZWVrZGF5KCksZSl9LGQ9aS5wcm90b3R5cGU7ZC5pc29XZWVrWWVhcj1mdW5jdGlvbigpe3JldHVybiBhKHRoaXMpLnllYXIoKX0sZC5pc29XZWVrPWZ1bmN0aW9uKHQpe2lmKCF0aGlzLiR1dGlscygpLnUodCkpcmV0dXJuIHRoaXMuYWRkKDcqKHQtdGhpcy5pc29XZWVrKCkpLGUpO3ZhciBpLGQsbixvLHI9YSh0aGlzKSx1PShpPXRoaXMuaXNvV2Vla1llYXIoKSxkPXRoaXMuJHUsbj0oZD9zLnV0YzpzKSgpLnllYXIoaSkuc3RhcnRPZihcInllYXJcIiksbz00LW4uaXNvV2Vla2RheSgpLG4uaXNvV2Vla2RheSgpPjQmJihvKz03KSxuLmFkZChvLGUpKTtyZXR1cm4gci5kaWZmKHUsXCJ3ZWVrXCIpKzF9LGQuaXNvV2Vla2RheT1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy4kdXRpbHMoKS51KGUpP3RoaXMuZGF5KCl8fDc6dGhpcy5kYXkodGhpcy5kYXkoKSU3P2U6ZS03KX07dmFyIG49ZC5zdGFydE9mO2Quc3RhcnRPZj1mdW5jdGlvbihlLHQpe3ZhciBpPXRoaXMuJHV0aWxzKCkscz0hIWkudSh0KXx8dDtyZXR1cm5cImlzb3dlZWtcIj09PWkucChlKT9zP3RoaXMuZGF0ZSh0aGlzLmRhdGUoKS0odGhpcy5pc29XZWVrZGF5KCktMSkpLnN0YXJ0T2YoXCJkYXlcIik6dGhpcy5kYXRlKHRoaXMuZGF0ZSgpLTEtKHRoaXMuaXNvV2Vla2RheSgpLTEpKzcpLmVuZE9mKFwiZGF5XCIpOm4uYmluZCh0aGlzKShlLHQpfX19KSk7IiwgImxldCB0b2tlbkNvdW50ZXIgPSAwO1xuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHVuaXF1ZSB0b2tlbiBmb3IgZGVwZW5kZW5jeSBpbmplY3Rpb24uXG4gKlxuICogQHBhcmFtIGRlc2NyaXB0aW9uIE9wdGlvbmFsIGRlc2NyaXB0aW9uIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAqIEByZXR1cm5zIEEgdW5pcXVlIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBNYXAga2V5XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbnRlcmZhY2UgSUxvZ2dlciB7IGxvZyhtc2c6IHN0cmluZyk6IHZvaWQgfVxuICogY29uc3QgTG9nZ2VyVG9rZW4gPSBUb2tlbjxJTG9nZ2VyPignTG9nZ2VyJylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gVG9rZW4oZGVzY3JpcHRpb24pIHtcbiAgICBjb25zdCBpZCA9ICsrdG9rZW5Db3VudGVyO1xuICAgIGNvbnN0IHN5bSA9IFN5bWJvbChkZXNjcmlwdGlvbiA/IGBUb2tlbigke2Rlc2NyaXB0aW9ufSlgIDogYFRva2VuIyR7aWR9YCk7XG4gICAgY29uc3QgdG9rZW4gPSB7XG4gICAgICAgIHN5bWJvbDogc3ltLFxuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICA/IGBUb2tlbjwke2Rlc2NyaXB0aW9ufT5gXG4gICAgICAgICAgICAgICAgOiBgVG9rZW48IyR7aWR9PmA7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiB0b2tlbjtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB1bmlxdWUgdG9rZW4gd2l0aG91dCBhIHN0cmluZyBsaXRlcmFsLlxuICogUHJlZmVycmVkIGZvciBBdXRvZmFjLXN0eWxlIERJIHRvIGF2b2lkIHN0cmluZyBsaXRlcmFscy5cbiAqXG4gKiBAcmV0dXJucyBBIHVuaXF1ZSB0b2tlbiB0aGF0IGNhbiBiZSB1c2VkIGFzIGEgTWFwIGtleVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW50ZXJmYWNlIElMb2dnZXIgeyBsb2cobXNnOiBzdHJpbmcpOiB2b2lkIH1cbiAqIGNvbnN0IExvZ2dlclRva2VuID0gdG9rZW48SUxvZ2dlcj4oKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2tlbigpIHtcbiAgICByZXR1cm4gVG9rZW4oKTtcbn1cbiIsICIvKipcbiAqIEVycm9yIGNsYXNzZXMgZm9yIE5vdmFESSBjb250YWluZXJcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRhaW5lckVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMubmFtZSA9ICdDb250YWluZXJFcnJvcic7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIEJpbmRpbmdOb3RGb3VuZEVycm9yIGV4dGVuZHMgQ29udGFpbmVyRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHRva2VuRGVzY3JpcHRpb24sIHBhdGggPSBbXSkge1xuICAgICAgICBjb25zdCBwYXRoU3RyID0gcGF0aC5sZW5ndGggPiAwID8gYFxcbiAgRGVwZW5kZW5jeSBwYXRoOiAke3BhdGguam9pbignIC0+ICcpfWAgOiAnJztcbiAgICAgICAgc3VwZXIoYFRva2VuIFwiJHt0b2tlbkRlc2NyaXB0aW9ufVwiIGlzIG5vdCBib3VuZCBvciByZWdpc3RlcmVkIGluIHRoZSBjb250YWluZXIuJHtwYXRoU3RyfWApO1xuICAgICAgICB0aGlzLm5hbWUgPSAnQmluZGluZ05vdEZvdW5kRXJyb3InO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBDaXJjdWxhckRlcGVuZGVuY3lFcnJvciBleHRlbmRzIENvbnRhaW5lckVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwYXRoKSB7XG4gICAgICAgIHN1cGVyKGBDaXJjdWxhciBkZXBlbmRlbmN5IGRldGVjdGVkOiAke3BhdGguam9pbignIC0+ICcpfWApO1xuICAgICAgICB0aGlzLm5hbWUgPSAnQ2lyY3VsYXJEZXBlbmRlbmN5RXJyb3InO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIEF1dG9XaXJlIC0gQXV0b21hdGljIGRlcGVuZGVuY3kgaW5qZWN0aW9uIGZvciBOb3ZhRElcbiAqIFN1cHBvcnRzIHR3byBzdHJhdGVnaWVzOiBtYXBSZXNvbHZlcnMgKHRyYW5zZm9ybWVyLWdlbmVyYXRlZCkgYW5kIG1hcCAobWFudWFsIG92ZXJyaWRlKVxuICovXG4vKipcbiAqIFBlcmZvcm1hbmNlOiBDYWNoZSBleHRyYWN0ZWQgcGFyYW1ldGVyIG5hbWVzIHRvIGF2b2lkIHJlcGVhdGVkIHJlZ2V4IHBhcnNpbmdcbiAqIFdlYWtNYXAgYWxsb3dzIGdhcmJhZ2UgY29sbGVjdGlvbiB3aGVuIGNvbnN0cnVjdG9yIGlzIG5vIGxvbmdlciByZWZlcmVuY2VkXG4gKi9cbmNvbnN0IHBhcmFtTmFtZUNhY2hlID0gbmV3IFdlYWtNYXAoKTtcbi8qKlxuICogRXh0cmFjdCBwYXJhbWV0ZXIgbmFtZXMgZnJvbSBhIGNvbnN0cnVjdG9yIGZ1bmN0aW9uXG4gKiBVc2VzIHJlZ2V4IHRvIHBhcnNlIHRoZSB0b1N0cmluZygpIHJlcHJlc2VudGF0aW9uXG4gKiBQZXJmb3JtYW5jZSBvcHRpbWl6ZWQ6IFJlc3VsdHMgYXJlIGNhY2hlZCBwZXIgY29uc3RydWN0b3JcbiAqXG4gKiBOb3RlOiBPbmx5IHVzZWQgYnkgcmVzb2x2ZUJ5TWFwKCkgZm9yIG1hbnVhbCBtYXAgc3RyYXRlZ3lcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RQYXJhbWV0ZXJOYW1lcyhjb25zdHJ1Y3Rvcikge1xuICAgIC8vIENoZWNrIGNhY2hlIGZpcnN0IC0gYXZvaWRzIGV4cGVuc2l2ZSByZWdleCBwYXJzaW5nXG4gICAgY29uc3QgY2FjaGVkID0gcGFyYW1OYW1lQ2FjaGUuZ2V0KGNvbnN0cnVjdG9yKTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuICAgIC8vIEV4dHJhY3QgcGFyYW1ldGVyIG5hbWVzIChleHBlbnNpdmUgb3BlcmF0aW9uKVxuICAgIGNvbnN0IGZuU3RyID0gY29uc3RydWN0b3IudG9TdHJpbmcoKTtcbiAgICAvLyBNYXRjaCBjb25zdHJ1Y3RvciguLi5hcmdzKSBvciBjbGFzcyB7IGNvbnN0cnVjdG9yKC4uLmFyZ3MpIH1cbiAgICBjb25zdCBtYXRjaCA9IGZuU3RyLm1hdGNoKC9jb25zdHJ1Y3RvclxccypcXCgoW14pXSopXFwpLykgfHwgZm5TdHIubWF0Y2goL15bXihdKlxcKChbXildKilcXCkvKTtcbiAgICBpZiAoIW1hdGNoIHx8ICFtYXRjaFsxXSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHBhcmFtcyA9IG1hdGNoWzFdXG4gICAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAgIC5tYXAocGFyYW0gPT4gcGFyYW0udHJpbSgpKVxuICAgICAgICAuZmlsdGVyKHBhcmFtID0+IHBhcmFtLmxlbmd0aCA+IDApXG4gICAgICAgIC5tYXAocGFyYW0gPT4ge1xuICAgICAgICAvLyBSZW1vdmUgZGVmYXVsdCB2YWx1ZXMsIHR5cGUgYW5ub3RhdGlvbnMsIGFuZCBleHRyYWN0IGp1c3QgdGhlIG5hbWVcbiAgICAgICAgbGV0IG5hbWUgPSBwYXJhbS5zcGxpdCgvWzo9XS8pWzBdLnRyaW0oKTtcbiAgICAgICAgLy8gUmVtb3ZlIFR5cGVTY3JpcHQgbW9kaWZpZXJzIChwdWJsaWMsIHByaXZhdGUsIHByb3RlY3RlZCwgcmVhZG9ubHkpXG4gICAgICAgIC8vIENhbiBhcHBlYXIgbXVsdGlwbGUgdGltZXMsIGUuZy4sIFwicHVibGljIHJlYWRvbmx5IHNlcnZpY2VcIlxuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC9eKChwdWJsaWN8cHJpdmF0ZXxwcm90ZWN0ZWR8cmVhZG9ubHkpXFxzKykrLywgJycpO1xuICAgICAgICAvLyBIYW5kbGUgZGVzdHJ1Y3R1cmluZyAtIHNraXAgZm9yIG5vd1xuICAgICAgICBpZiAobmFtZS5pbmNsdWRlcygneycpIHx8IG5hbWUuaW5jbHVkZXMoJ1snKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfSlcbiAgICAgICAgLmZpbHRlcigobmFtZSkgPT4gbmFtZSAhPT0gbnVsbCk7XG4gICAgLy8gQ2FjaGUgcmVzdWx0IGZvciBmdXR1cmUgY2FsbHNcbiAgICBwYXJhbU5hbWVDYWNoZS5zZXQoY29uc3RydWN0b3IsIHBhcmFtcyk7XG4gICAgcmV0dXJuIHBhcmFtcztcbn1cbi8qKlxuICogUmVzb2x2ZSBkZXBlbmRlbmNpZXMgdXNpbmcgbWFwIHN0cmF0ZWd5XG4gKiBVc2VzIGV4cGxpY2l0IG1hcHBpbmcgZnJvbSBwYXJhbWV0ZXIgbmFtZXMgdG8gcmVzb2x2ZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQnlNYXAoY29uc3RydWN0b3IsIGNvbnRhaW5lciwgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucy5tYXApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRvV2lyZSBtYXAgc3RyYXRlZ3kgcmVxdWlyZXMgb3B0aW9ucy5tYXAgdG8gYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBwYXJhbU5hbWVzID0gZXh0cmFjdFBhcmFtZXRlck5hbWVzKGNvbnN0cnVjdG9yKTtcbiAgICBjb25zdCByZXNvbHZlZERlcHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhcmFtTmFtZSBvZiBwYXJhbU5hbWVzKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVyID0gb3B0aW9ucy5tYXBbcGFyYW1OYW1lXTtcbiAgICAgICAgaWYgKHJlc29sdmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlc29sdmUgcGFyYW1ldGVyIFwiJHtwYXJhbU5hbWV9XCIgb24gJHtjb25zdHJ1Y3Rvci5uYW1lfS4gYCArXG4gICAgICAgICAgICAgICAgICAgIGBOb3QgZm91bmQgaW4gYXV0b3dpcmUgbWFwLiBgICtcbiAgICAgICAgICAgICAgICAgICAgYEFkZCBpdCB0byB0aGUgbWFwOiAuYXV0b1dpcmUoeyBtYXA6IHsgJHtwYXJhbU5hbWV9OiAuLi4gfSB9KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2lsZW50bHkgcHVzaCB1bmRlZmluZWQgZm9yIG1pc3NpbmcgcGFyYW1ldGVyc1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgZXhwZWN0ZWQ6IHRyYW5zZm9ybWVyIGZpbHRlcnMgb3V0IHByaW1pdGl2ZSB0eXBlcyBhdCBjb21waWxlLXRpbWUsXG4gICAgICAgICAgICAgICAgLy8gc28gbWlzc2luZyBwYXJhbXMgYXJlIHR5cGljYWxseSBwcmltaXRpdmVzIHRoYXQgZG9uJ3QgbmVlZCBESSByZXNvbHV0aW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZWREZXBzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc29sdmVyIGNhbiBiZSBhIGZ1bmN0aW9uIG9yIGEgVG9rZW5cbiAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmVzb2x2ZWREZXBzLnB1c2gocmVzb2x2ZXIoY29udGFpbmVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBBc3N1bWUgaXQncyBhIFRva2VuXG4gICAgICAgICAgICByZXNvbHZlZERlcHMucHVzaChjb250YWluZXIucmVzb2x2ZShyZXNvbHZlcikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNvbHZlZERlcHM7XG59XG4vKipcbiAqIFJlc29sdmUgZGVwZW5kZW5jaWVzIHVzaW5nIG1hcFJlc29sdmVycyBhcnJheSBzdHJhdGVneVxuICogT1BUSU1BTCBQRVJGT1JNQU5DRTogTygxKSBhcnJheSBhY2Nlc3MgcGVyIHBhcmFtZXRlclxuICogTWluaWZpY2F0aW9uLXNhZmU6IFVzZXMgcG9zaXRpb24tYmFzZWQgYXJyYXlcbiAqIFJlZmFjdG9yaW5nLWZyaWVuZGx5OiBUcmFuc2Zvcm1lciByZWdlbmVyYXRlcyBhcnJheSBvbiByZWNvbXBpbGVcbiAqXG4gKiBSZXF1aXJlcyBidWlsZC10aW1lIHRyYW5zZm9ybWVyIHRvIGdlbmVyYXRlIG1hcFJlc29sdmVycyBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUJ5TWFwUmVzb2x2ZXJzKF9jb25zdHJ1Y3RvciwgY29udGFpbmVyLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zLm1hcFJlc29sdmVycyB8fCBvcHRpb25zLm1hcFJlc29sdmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCByZXNvbHZlZERlcHMgPSBbXTtcbiAgICAvLyBTaW1wbGUgTygxKSBhcnJheSBhY2Nlc3MgLSB1bHRyYSBmYXN0IVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5tYXBSZXNvbHZlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZXIgPSBvcHRpb25zLm1hcFJlc29sdmVyc1tpXTtcbiAgICAgICAgaWYgKHJlc29sdmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIHVuZGVmaW5lZCBpbmRpY2F0ZXMgcHJpbWl0aXZlIHR5cGUgb3IgcGFyYW1ldGVyIHdpdGhvdXQgRElcbiAgICAgICAgICAgIHJlc29sdmVkRGVwcy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHJlc29sdmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBSZXNvbHZlciBmdW5jdGlvbjogKGMpID0+IGMucmVzb2x2ZVR5cGUoLi4uKVxuICAgICAgICAgICAgcmVzb2x2ZWREZXBzLnB1c2gocmVzb2x2ZXIoY29udGFpbmVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBUb2tlbi1iYXNlZCByZXNvbHV0aW9uXG4gICAgICAgICAgICByZXNvbHZlZERlcHMucHVzaChjb250YWluZXIucmVzb2x2ZShyZXNvbHZlcikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNvbHZlZERlcHM7XG59XG4vKipcbiAqIE1haW4gYXV0b3dpcmUgZnVuY3Rpb24gLSBkaXNwYXRjaGVzIHRvIGFwcHJvcHJpYXRlIHN0cmF0ZWd5XG4gKiBQcmlvcml0eTogbWFwUmVzb2x2ZXJzICh0cmFuc2Zvcm1lci1nZW5lcmF0ZWQpID4gbWFwIChtYW51YWwgb3ZlcnJpZGUpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRvd2lyZShjb25zdHJ1Y3RvciwgY29udGFpbmVyLCBvcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgICAgYnk6ICdwYXJhbU5hbWUnLFxuICAgICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgICAuLi5vcHRpb25zXG4gICAgfTtcbiAgICAvLyBISUdIRVNUIFBSSU9SSVRZOiBtYXBSZXNvbHZlcnMgYXJyYXkgKHRyYW5zZm9ybWVyLWdlbmVyYXRlZCwgb3B0aW1hbCBwZXJmb3JtYW5jZSlcbiAgICAvLyBPKDEpIGFycmF5IGFjY2VzcyBwZXIgcGFyYW1ldGVyIC0gbWluaWZpY2F0aW9uLXNhZmUgYW5kIHJlZmFjdG9yaW5nLWZyaWVuZGx5XG4gICAgaWYgKG9wdHMubWFwUmVzb2x2ZXJzICYmIG9wdHMubWFwUmVzb2x2ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmVCeU1hcFJlc29sdmVycyhjb25zdHJ1Y3RvciwgY29udGFpbmVyLCBvcHRzKTtcbiAgICB9XG4gICAgLy8gRkFMTEJBQ0s6IE1hbnVhbCBtYXAgc3RyYXRlZ3kgZm9yIGV4cGxpY2l0IG92ZXJyaWRlc1xuICAgIGlmIChvcHRzLm1hcCAmJiBPYmplY3Qua2V5cyhvcHRzLm1hcCkubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZUJ5TWFwKGNvbnN0cnVjdG9yLCBjb250YWluZXIsIG9wdHMpO1xuICAgIH1cbiAgICAvLyBObyBhdXRvd2lyaW5nIGNvbmZpZ3VyZWQsIHJldHVybiBlbXB0eSBhcnJheVxuICAgIHJldHVybiBbXTtcbn1cbiIsICIvKipcbiAqIEZsdWVudCBidWlsZGVyIEFQSSBmb3IgTm92YURJIENvbnRhaW5lciAoQXV0b2ZhYy1zdHlsZSlcbiAqL1xuaW1wb3J0IHsgVG9rZW4gfSBmcm9tICcuL3Rva2VuLmpzJztcbmltcG9ydCB7IGF1dG93aXJlIH0gZnJvbSAnLi9hdXRvd2lyZS5qcyc7XG4vKipcbiAqIEZsdWVudCByZWdpc3RyYXRpb24gYnVpbGRlciByZXR1cm5lZCBhZnRlciBlYWNoIHJlZ2lzdHJhdGlvbiBtZXRob2RcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZ2lzdHJhdGlvbkJ1aWxkZXIge1xuICAgIGNvbnN0cnVjdG9yKHBlbmRpbmcsIHJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgdGhpcy5yZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9ucztcbiAgICAgICAgdGhpcy5jb25maWdzID0gW107XG4gICAgICAgIHRoaXMuZGVmYXVsdExpZmV0aW1lID0gJ3NpbmdsZXRvbic7XG4gICAgICAgIHRoaXMucGVuZGluZyA9IHBlbmRpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJpbmQgdGhpcyByZWdpc3RyYXRpb24gdG8gYSB0b2tlbiBvciBpbnRlcmZhY2UgdHlwZVxuICAgICAqXG4gICAgICogQG92ZXJsb2FkXG4gICAgICogQHBhcmFtIHtUb2tlbjxVPn0gdG9rZW4gLSBFeHBsaWNpdCB0b2tlbiBmb3IgYmluZGluZ1xuICAgICAqXG4gICAgICogQG92ZXJsb2FkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGVOYW1lIC0gSW50ZXJmYWNlIHR5cGUgbmFtZSAoYXV0by1nZW5lcmF0ZWQgYnkgdHJhbnNmb3JtZXIpXG4gICAgICovXG4gICAgYXModG9rZW5PclR5cGVOYW1lKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGFyZ3VtZW50IGlzIGEgVG9rZW4gb2JqZWN0IChoYXMgc3ltYm9sIHByb3BlcnR5KVxuICAgICAgICBpZiAodG9rZW5PclR5cGVOYW1lICYmIHR5cGVvZiB0b2tlbk9yVHlwZU5hbWUgPT09ICdvYmplY3QnICYmICdzeW1ib2wnIGluIHRva2VuT3JUeXBlTmFtZSkge1xuICAgICAgICAgICAgLy8gVG9rZW4tYmFzZWQgcmVnaXN0cmF0aW9uXG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgdG9rZW46IHRva2VuT3JUeXBlTmFtZSxcbiAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLnBlbmRpbmcudHlwZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdGhpcy5wZW5kaW5nLnZhbHVlLFxuICAgICAgICAgICAgICAgIGZhY3Rvcnk6IHRoaXMucGVuZGluZy5mYWN0b3J5LFxuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB0aGlzLnBlbmRpbmcuY29uc3RydWN0b3IsXG4gICAgICAgICAgICAgICAgbGlmZXRpbWU6IHRoaXMuZGVmYXVsdExpZmV0aW1lXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5jb25maWdzLnB1c2goY29uZmlnKTtcbiAgICAgICAgICAgIHRoaXMucmVnaXN0cmF0aW9ucy5wdXNoKGNvbmZpZyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIEludGVyZmFjZS1iYXNlZCByZWdpc3RyYXRpb24gKHR5cGVOYW1lIHN0cmluZyBvciB1bmRlZmluZWQpXG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgdG9rZW46IG51bGwsIC8vIFdpbGwgYmUgc2V0IGR1cmluZyBidWlsZCgpXG4gICAgICAgICAgICAgICAgdHlwZTogdGhpcy5wZW5kaW5nLnR5cGUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMucGVuZGluZy52YWx1ZSxcbiAgICAgICAgICAgICAgICBmYWN0b3J5OiB0aGlzLnBlbmRpbmcuZmFjdG9yeSxcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogdGhpcy5wZW5kaW5nLmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgICAgIGxpZmV0aW1lOiB0aGlzLmRlZmF1bHRMaWZldGltZSxcbiAgICAgICAgICAgICAgICBpbnRlcmZhY2VUeXBlOiB0b2tlbk9yVHlwZU5hbWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3MucHVzaChjb25maWcpO1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RyYXRpb25zLnB1c2goY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGFzIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIGFuIGludGVyZmFjZVxuICAgICAqIENvbWJpbmVzIGFzKCkgKyBhc0RlZmF1bHQoKVxuICAgICAqL1xuICAgIGFzRGVmYXVsdEludGVyZmFjZSh0eXBlTmFtZSkge1xuICAgICAgICB0aGlzLmFzKFwiVEludGVyZmFjZVwiLCB0eXBlTmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmFzRGVmYXVsdCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhcyBhIGtleWVkIGludGVyZmFjZSBpbXBsZW1lbnRhdGlvblxuICAgICAqIENvbWJpbmVzIGFzKCkgKyBrZXllZCgpXG4gICAgICovXG4gICAgYXNLZXllZEludGVyZmFjZShrZXksIHR5cGVOYW1lKSB7XG4gICAgICAgIHRoaXMuYXMoXCJUSW50ZXJmYWNlXCIsIHR5cGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMua2V5ZWQoa2V5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYXMgbXVsdGlwbGUgaW1wbGVtZW50ZWQgaW50ZXJmYWNlc1xuICAgICAqL1xuICAgIGFzSW1wbGVtZW50ZWRJbnRlcmZhY2VzKHRva2Vucykge1xuICAgICAgICBpZiAodG9rZW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGV4aXN0aW5nIGNvbmZpZ3MgKGZyb20gcHJldmlvdXMgYXMoKSBjYWxscyksIGFkZCB0aGVzZSBhcyBhZGRpdGlvbmFsIGludGVyZmFjZXNcbiAgICAgICAgaWYgKHRoaXMuY29uZmlncy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBBZGQgYWxsIHRva2VucyBhcyBhZGRpdGlvbmFsIGludGVyZmFjZXMgdG8gZXhpc3RpbmcgY29uZmlnc1xuICAgICAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLmxpZmV0aW1lID0gJ3NpbmdsZXRvbic7IC8vIGFzSW1wbGVtZW50ZWRJbnRlcmZhY2VzIGRlZmF1bHRzIHRvIHNpbmdsZXRvblxuICAgICAgICAgICAgICAgIGNvbmZpZy5hZGRpdGlvbmFsVG9rZW5zID0gY29uZmlnLmFkZGl0aW9uYWxUb2tlbnMgfHwgW107XG4gICAgICAgICAgICAgICAgY29uZmlnLmFkZGl0aW9uYWxUb2tlbnMucHVzaCguLi50b2tlbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm8gZXhpc3RpbmcgY29uZmlncywgY3JlYXRlIG5ldyBvbmUgd2l0aCBmaXJzdCB0b2tlblxuICAgICAgICBjb25zdCBmaXJzdENvbmZpZyA9IHtcbiAgICAgICAgICAgIHRva2VuOiB0b2tlbnNbMF0sXG4gICAgICAgICAgICB0eXBlOiB0aGlzLnBlbmRpbmcudHlwZSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnBlbmRpbmcudmFsdWUsXG4gICAgICAgICAgICBmYWN0b3J5OiB0aGlzLnBlbmRpbmcuZmFjdG9yeSxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB0aGlzLnBlbmRpbmcuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBsaWZldGltZTogJ3NpbmdsZXRvbidcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jb25maWdzLnB1c2goZmlyc3RDb25maWcpO1xuICAgICAgICB0aGlzLnJlZ2lzdHJhdGlvbnMucHVzaChmaXJzdENvbmZpZyk7XG4gICAgICAgIC8vIEFkZGl0aW9uYWwgdG9rZW5zIHJlZmVyZW5jZSB0aGUgc2FtZSByZWdpc3RyYXRpb25cbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGZpcnN0Q29uZmlnLmFkZGl0aW9uYWxUb2tlbnMgPSBmaXJzdENvbmZpZy5hZGRpdGlvbmFsVG9rZW5zIHx8IFtdO1xuICAgICAgICAgICAgZmlyc3RDb25maWcuYWRkaXRpb25hbFRva2Vucy5wdXNoKHRva2Vuc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBzaW5nbGV0b24gbGlmZXRpbWUgKG9uZSBpbnN0YW5jZSBmb3IgZW50aXJlIGNvbnRhaW5lcilcbiAgICAgKi9cbiAgICBzaW5nbGVJbnN0YW5jZSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcubGlmZXRpbWUgPSAnc2luZ2xldG9uJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHBlci1yZXF1ZXN0IGxpZmV0aW1lIChvbmUgaW5zdGFuY2UgcGVyIHJlc29sdmUgY2FsbCB0cmVlKVxuICAgICAqL1xuICAgIGluc3RhbmNlUGVyUmVxdWVzdCgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcubGlmZXRpbWUgPSAncGVyLXJlcXVlc3QnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdHJhbnNpZW50IGxpZmV0aW1lIChuZXcgaW5zdGFuY2UgZXZlcnkgdGltZSlcbiAgICAgKiBBbGlhcyBmb3IgZGVmYXVsdCBiZWhhdmlvclxuICAgICAqL1xuICAgIGluc3RhbmNlUGVyRGVwZW5kZW5jeSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcubGlmZXRpbWUgPSAndHJhbnNpZW50JztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmFtZSB0aGlzIHJlZ2lzdHJhdGlvbiBmb3IgbmFtZWQgcmVzb2x1dGlvblxuICAgICAqL1xuICAgIG5hbWVkKG5hbWUpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcubmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEtleSB0aGlzIHJlZ2lzdHJhdGlvbiBmb3Iga2V5ZWQgcmVzb2x1dGlvblxuICAgICAqL1xuICAgIGtleWVkKGtleSkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5rZXkgPSBrZXk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1hcmsgdGhpcyBhcyBkZWZhdWx0IHJlZ2lzdHJhdGlvblxuICAgICAqIERlZmF1bHQgcmVnaXN0cmF0aW9ucyBkb24ndCBvdmVycmlkZSBleGlzdGluZyBvbmVzXG4gICAgICovXG4gICAgYXNEZWZhdWx0KCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5pc0RlZmF1bHQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPbmx5IHJlZ2lzdGVyIGlmIHRva2VuIG5vdCBhbHJlYWR5IHJlZ2lzdGVyZWRcbiAgICAgKi9cbiAgICBpZk5vdFJlZ2lzdGVyZWQoKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMuY29uZmlncykge1xuICAgICAgICAgICAgY29uZmlnLmlmTm90UmVnaXN0ZXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgcGFyYW1ldGVyIHZhbHVlcyBmb3IgY29uc3RydWN0b3IgKHByaW1pdGl2ZXMgYW5kIGNvbnN0YW50cylcbiAgICAgKiBVc2UgdGhpcyBmb3Igbm9uLURJIHBhcmFtZXRlcnMgbGlrZSBzdHJpbmdzLCBudW1iZXJzLCBjb25maWcgdmFsdWVzXG4gICAgICovXG4gICAgd2l0aFBhcmFtZXRlcnMocGFyYW1ldGVycykge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5wYXJhbWV0ZXJWYWx1ZXMgPSBwYXJhbWV0ZXJzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbmFibGUgYXV0b21hdGljIGRlcGVuZGVuY3kgaW5qZWN0aW9uIChhdXRvd2lyaW5nKVxuICAgICAqIFN1cHBvcnRzIHRocmVlIHN0cmF0ZWdpZXM6IHBhcmFtTmFtZSAoZGVmYXVsdCksIG1hcCwgYW5kIGNsYXNzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYHRzXG4gICAgICogLy8gU3RyYXRlZ3kgMTogcGFyYW1OYW1lIChkZWZhdWx0LCByZXF1aXJlcyBub24tbWluaWZpZWQgY29kZSBpbiBkZXYpXG4gICAgICogYnVpbGRlci5yZWdpc3RlclR5cGUoRXZlbnRCdXMpLmFzPElFdmVudEJ1cz4oKS5hdXRvV2lyZSgpXG4gICAgICpcbiAgICAgKiAvLyBTdHJhdGVneSAyOiBtYXAgKG1pbmlmeS1zYWZlLCBleHBsaWNpdClcbiAgICAgKiBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXM8SUV2ZW50QnVzPigpLmF1dG9XaXJlKHtcbiAgICAgKiAgIG1hcDoge1xuICAgICAqICAgICBsb2dnZXI6IChjKSA9PiBjLnJlc29sdmVUeXBlPElMb2dnZXI+KClcbiAgICAgKiAgIH1cbiAgICAgKiB9KVxuICAgICAqXG4gICAgICogLy8gU3RyYXRlZ3kgMzogY2xhc3MgKHJlcXVpcmVzIGJ1aWxkLXRpbWUgY29kZWdlbilcbiAgICAgKiBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXM8SUV2ZW50QnVzPigpLmF1dG9XaXJlKHsgYnk6ICdjbGFzcycgfSlcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhdXRvV2lyZShvcHRpb25zKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMuY29uZmlncykge1xuICAgICAgICAgICAgY29uZmlnLmF1dG93aXJlT3B0aW9ucyA9IG9wdGlvbnMgfHwgeyBieTogJ3BhcmFtTmFtZScsIHN0cmljdDogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEZsdWVudCBidWlsZGVyIGZvciBDb250YWluZXIgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgY2xhc3MgQnVpbGRlciB7XG4gICAgY29uc3RydWN0b3IoYmFzZUNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLmJhc2VDb250YWluZXIgPSBiYXNlQ29udGFpbmVyO1xuICAgICAgICB0aGlzLnJlZ2lzdHJhdGlvbnMgPSBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBjbGFzcyBjb25zdHJ1Y3RvclxuICAgICAqL1xuICAgIHJlZ2lzdGVyVHlwZShjb25zdHJ1Y3Rvcikge1xuICAgICAgICBjb25zdCBwZW5kaW5nID0ge1xuICAgICAgICAgICAgdHlwZTogJ3R5cGUnLFxuICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgICBjb25zdHJ1Y3RvclxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IFJlZ2lzdHJhdGlvbkJ1aWxkZXIocGVuZGluZywgdGhpcy5yZWdpc3RyYXRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBwcmUtY3JlYXRlZCBpbnN0YW5jZVxuICAgICAqL1xuICAgIHJlZ2lzdGVySW5zdGFuY2UoaW5zdGFuY2UpIHtcbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdpbnN0YW5jZScsXG4gICAgICAgICAgICB2YWx1ZTogaW5zdGFuY2UsXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogdW5kZWZpbmVkXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgUmVnaXN0cmF0aW9uQnVpbGRlcihwZW5kaW5nLCB0aGlzLnJlZ2lzdHJhdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGZhY3RvcnkgZnVuY3Rpb25cbiAgICAgKi9cbiAgICByZWdpc3RlcihmYWN0b3J5KSB7XG4gICAgICAgIGNvbnN0IHBlbmRpbmcgPSB7XG4gICAgICAgICAgICB0eXBlOiAnZmFjdG9yeScsXG4gICAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgICAgIGZhY3RvcnksXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogdW5kZWZpbmVkXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgUmVnaXN0cmF0aW9uQnVpbGRlcihwZW5kaW5nLCB0aGlzLnJlZ2lzdHJhdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIG1vZHVsZSAoZnVuY3Rpb24gdGhhdCBhZGRzIG11bHRpcGxlIHJlZ2lzdHJhdGlvbnMpXG4gICAgICovXG4gICAgbW9kdWxlKG1vZHVsZUZ1bmMpIHtcbiAgICAgICAgbW9kdWxlRnVuYyh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgaW50ZXJmYWNlIHR5cGUgbmFtZXMgdG8gdG9rZW5zXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcmVzb2x2ZUludGVyZmFjZVRva2Vucyhjb250YWluZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5yZWdpc3RyYXRpb25zKSB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLmludGVyZmFjZVR5cGUgIT09IHVuZGVmaW5lZCAmJiAhY29uZmlnLnRva2VuKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLnRva2VuID0gY29udGFpbmVyLmludGVyZmFjZVRva2VuKGNvbmZpZy5pbnRlcmZhY2VUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZGVudGlmeSB0b2tlbnMgdGhhdCBoYXZlIG5vbi1kZWZhdWx0IHJlZ2lzdHJhdGlvbnNcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBpZGVudGlmeU5vbkRlZmF1bHRUb2tlbnMoKSB7XG4gICAgICAgIGNvbnN0IHRva2Vuc1dpdGhOb25EZWZhdWx0cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5yZWdpc3RyYXRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIWNvbmZpZy5pc0RlZmF1bHQgJiYgIWNvbmZpZy5uYW1lICYmIGNvbmZpZy5rZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRva2Vuc1dpdGhOb25EZWZhdWx0cy5hZGQoY29uZmlnLnRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdG9rZW5zV2l0aE5vbkRlZmF1bHRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiByZWdpc3RyYXRpb24gc2hvdWxkIGJlIHNraXBwZWRcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBzaG91bGRTa2lwUmVnaXN0cmF0aW9uKGNvbmZpZywgdG9rZW5zV2l0aE5vbkRlZmF1bHRzLCByZWdpc3RlcmVkVG9rZW5zKSB7XG4gICAgICAgIC8vIFNraXAgZGVmYXVsdCByZWdpc3RyYXRpb25zIGlmIHRoZXJlJ3MgYSBub24tZGVmYXVsdCBmb3IgdGhlIHNhbWUgdG9rZW5cbiAgICAgICAgaWYgKGNvbmZpZy5pc0RlZmF1bHQgJiYgIWNvbmZpZy5uYW1lICYmIGNvbmZpZy5rZXkgPT09IHVuZGVmaW5lZCAmJiB0b2tlbnNXaXRoTm9uRGVmYXVsdHMuaGFzKGNvbmZpZy50b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEhhbmRsZSBpZk5vdFJlZ2lzdGVyZWRcbiAgICAgICAgaWYgKGNvbmZpZy5pZk5vdFJlZ2lzdGVyZWQgJiYgcmVnaXN0ZXJlZFRva2Vucy5oYXMoY29uZmlnLnRva2VuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSGFuZGxlIGFzRGVmYXVsdFxuICAgICAgICBpZiAoY29uZmlnLmlzRGVmYXVsdCAmJiByZWdpc3RlcmVkVG9rZW5zLmhhcyhjb25maWcudG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBiaW5kaW5nIHRva2VuIGZvciByZWdpc3RyYXRpb24gKG5hbWVkLCBrZXllZCwgb3IgbXVsdGkpXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY3JlYXRlQmluZGluZ1Rva2VuKGNvbmZpZywgbmFtZWRSZWdpc3RyYXRpb25zLCBrZXllZFJlZ2lzdHJhdGlvbnMsIG11bHRpUmVnaXN0cmF0aW9ucykge1xuICAgICAgICBpZiAoY29uZmlnLm5hbWUpIHtcbiAgICAgICAgICAgIC8vIE5hbWVkIHJlZ2lzdHJhdGlvbiBnZXRzIHVuaXF1ZSB0b2tlblxuICAgICAgICAgICAgY29uc3QgYmluZGluZ1Rva2VuID0gVG9rZW4oYF9fbmFtZWRfJHtjb25maWcubmFtZX1gKTtcbiAgICAgICAgICAgIG5hbWVkUmVnaXN0cmF0aW9ucy5zZXQoY29uZmlnLm5hbWUsIHsgLi4uY29uZmlnLCB0b2tlbjogYmluZGluZ1Rva2VuIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb2tlbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb25maWcua2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIEtleWVkIHJlZ2lzdHJhdGlvbiBnZXRzIHVuaXF1ZSB0b2tlblxuICAgICAgICAgICAgY29uc3Qga2V5U3RyID0gdHlwZW9mIGNvbmZpZy5rZXkgPT09ICdzeW1ib2wnID8gY29uZmlnLmtleS50b1N0cmluZygpIDogY29uZmlnLmtleTtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRpbmdUb2tlbiA9IFRva2VuKGBfX2tleWVkXyR7a2V5U3RyfWApO1xuICAgICAgICAgICAga2V5ZWRSZWdpc3RyYXRpb25zLnNldChjb25maWcua2V5LCB7IC4uLmNvbmZpZywgdG9rZW46IGJpbmRpbmdUb2tlbiB9KTtcbiAgICAgICAgICAgIHJldHVybiBiaW5kaW5nVG9rZW47XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBNdWx0aS1yZWdpc3RyYXRpb24gaGFuZGxpbmdcbiAgICAgICAgICAgIGlmIChtdWx0aVJlZ2lzdHJhdGlvbnMuaGFzKGNvbmZpZy50b2tlbikpIHtcbiAgICAgICAgICAgICAgICAvLyBTdWJzZXF1ZW50IHJlZ2lzdHJhdGlvbiBmb3IgdGhpcyB0b2tlblxuICAgICAgICAgICAgICAgIGNvbnN0IGJpbmRpbmdUb2tlbiA9IFRva2VuKGBfX211bHRpXyR7Y29uZmlnLnRva2VuLnRvU3RyaW5nKCl9XyR7bXVsdGlSZWdpc3RyYXRpb25zLmdldChjb25maWcudG9rZW4pLmxlbmd0aH1gKTtcbiAgICAgICAgICAgICAgICBtdWx0aVJlZ2lzdHJhdGlvbnMuZ2V0KGNvbmZpZy50b2tlbikucHVzaChiaW5kaW5nVG9rZW4pO1xuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5nVG9rZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBGaXJzdCByZWdpc3RyYXRpb24gZm9yIHRoaXMgdG9rZW4sIHVzZSB0aGUgb3JpZ2luYWwgdG9rZW5cbiAgICAgICAgICAgICAgICBtdWx0aVJlZ2lzdHJhdGlvbnMuc2V0KGNvbmZpZy50b2tlbiwgW2NvbmZpZy50b2tlbl0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcudG9rZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYWRkaXRpb25hbCBpbnRlcmZhY2VzIGZvciBhIGNvbmZpZ1xuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHJlZ2lzdGVyQWRkaXRpb25hbEludGVyZmFjZXMoY29udGFpbmVyLCBjb25maWcsIGJpbmRpbmdUb2tlbiwgcmVnaXN0ZXJlZFRva2Vucykge1xuICAgICAgICBpZiAoY29uZmlnLmFkZGl0aW9uYWxUb2tlbnMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgYWRkaXRpb25hbFRva2VuIG9mIGNvbmZpZy5hZGRpdGlvbmFsVG9rZW5zKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgZmFjdG9yeSB0aGF0IHJlc29sdmVzIHRoZSBiaW5kaW5nIHRva2VuXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGFkZGl0aW9uYWxUb2tlbiwgKGMpID0+IGMucmVzb2x2ZShiaW5kaW5nVG9rZW4pLCB7IGxpZmV0aW1lOiBjb25maWcubGlmZXRpbWUgfSk7XG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJlZFRva2Vucy5hZGQoYWRkaXRpb25hbFRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBCdWlsZCB0aGUgY29udGFpbmVyIHdpdGggYWxsIHJlZ2lzdGVyZWQgYmluZGluZ3NcbiAgICAgKi9cbiAgICBidWlsZCgpIHtcbiAgICAgICAgLy8gQ3JlYXRlIG5ldyBjb250YWluZXIgaW5oZXJpdGluZyBmcm9tIGJhc2VcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5iYXNlQ29udGFpbmVyLmNyZWF0ZUNoaWxkKCk7XG4gICAgICAgIC8vIFByZS1wcm9jZXNzOiByZXNvbHZlIGludGVyZmFjZSB0eXBlcyB0byB0b2tlbnNcbiAgICAgICAgdGhpcy5yZXNvbHZlSW50ZXJmYWNlVG9rZW5zKGNvbnRhaW5lcik7XG4gICAgICAgIC8vIFRyYWNrIHdoYXQncyBiZWVuIHJlZ2lzdGVyZWQgZm9yIGlmTm90UmVnaXN0ZXJlZCBjaGVja3NcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJlZFRva2VucyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3QgbmFtZWRSZWdpc3RyYXRpb25zID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBrZXllZFJlZ2lzdHJhdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG11bHRpUmVnaXN0cmF0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLy8gUHJlLXByb2Nlc3M6IGlkZW50aWZ5IHRva2VucyB0aGF0IGhhdmUgbm9uLWRlZmF1bHQgcmVnaXN0cmF0aW9uc1xuICAgICAgICBjb25zdCB0b2tlbnNXaXRoTm9uRGVmYXVsdHMgPSB0aGlzLmlkZW50aWZ5Tm9uRGVmYXVsdFRva2VucygpO1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLnJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHJlZ2lzdHJhdGlvbiBzaG91bGQgYmUgc2tpcHBlZFxuICAgICAgICAgICAgaWYgKHRoaXMuc2hvdWxkU2tpcFJlZ2lzdHJhdGlvbihjb25maWcsIHRva2Vuc1dpdGhOb25EZWZhdWx0cywgcmVnaXN0ZXJlZFRva2VucykpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENyZWF0ZSBiaW5kaW5nIHRva2VuIChuYW1lZCwga2V5ZWQsIG9yIG11bHRpKVxuICAgICAgICAgICAgY29uc3QgYmluZGluZ1Rva2VuID0gdGhpcy5jcmVhdGVCaW5kaW5nVG9rZW4oY29uZmlnLCBuYW1lZFJlZ2lzdHJhdGlvbnMsIGtleWVkUmVnaXN0cmF0aW9ucywgbXVsdGlSZWdpc3RyYXRpb25zKTtcbiAgICAgICAgICAgIC8vIEFwcGx5IHJlZ2lzdHJhdGlvbiB0byBjb250YWluZXIgdXNpbmcgdGhlIGJpbmRpbmcgdG9rZW5cbiAgICAgICAgICAgIHRoaXMuYXBwbHlSZWdpc3RyYXRpb24oY29udGFpbmVyLCB7IC4uLmNvbmZpZywgdG9rZW46IGJpbmRpbmdUb2tlbiB9KTtcbiAgICAgICAgICAgIC8vIE1hcmsgb3JpZ2luYWwgdG9rZW4gYXMgcmVnaXN0ZXJlZFxuICAgICAgICAgICAgcmVnaXN0ZXJlZFRva2Vucy5hZGQoY29uZmlnLnRva2VuKTtcbiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIGFkZGl0aW9uYWwgaW50ZXJmYWNlc1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RlckFkZGl0aW9uYWxJbnRlcmZhY2VzKGNvbnRhaW5lciwgY29uZmlnLCBiaW5kaW5nVG9rZW4sIHJlZ2lzdGVyZWRUb2tlbnMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEF0dGFjaCBtZXRhZGF0YSBmb3IgbmFtZWQva2V5ZWQgcmVzb2x1dGlvblxuICAgICAgICA7XG4gICAgICAgIGNvbnRhaW5lci5fX25hbWVkUmVnaXN0cmF0aW9ucyA9IG5hbWVkUmVnaXN0cmF0aW9ucztcbiAgICAgICAgY29udGFpbmVyLl9fa2V5ZWRSZWdpc3RyYXRpb25zID0ga2V5ZWRSZWdpc3RyYXRpb25zO1xuICAgICAgICBjb250YWluZXIuX19tdWx0aVJlZ2lzdHJhdGlvbnMgPSBtdWx0aVJlZ2lzdHJhdGlvbnM7XG4gICAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFuYWx5emUgY29uc3RydWN0b3IgdG8gZGV0ZWN0IGRlcGVuZGVuY2llc1xuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGFuYWx5emVDb25zdHJ1Y3Rvcihjb25zdHJ1Y3Rvcikge1xuICAgICAgICBjb25zdCBjb25zdHJ1Y3RvclN0ciA9IGNvbnN0cnVjdG9yLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGhhc0RlcGVuZGVuY2llcyA9IC9jb25zdHJ1Y3RvclxccypcXChbXildK1xcKS8udGVzdChjb25zdHJ1Y3RvclN0cik7XG4gICAgICAgIHJldHVybiB7IGhhc0RlcGVuZGVuY2llcyB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgb3B0aW1pemVkIGZhY3RvcnkgZm9yIHplcm8tZGVwZW5kZW5jeSBjb25zdHJ1Y3RvcnNcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjcmVhdGVPcHRpbWl6ZWRGYWN0b3J5KGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChjb25maWcubGlmZXRpbWUgPT09ICdzaW5nbGV0b24nKSB7XG4gICAgICAgICAgICAvLyBTaW5nbGV0b246IENyZWF0ZSBpbnN0YW5jZSBkaXJlY3RseSAoZmFzdGVzdCBwYXRoIC0gbm8gZmFjdG9yeSBvdmVyaGVhZClcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IGNvbmZpZy5jb25zdHJ1Y3RvcigpO1xuICAgICAgICAgICAgY29udGFpbmVyLmJpbmRWYWx1ZShjb25maWcudG9rZW4sIGluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb25maWcubGlmZXRpbWUgPT09ICd0cmFuc2llbnQnKSB7XG4gICAgICAgICAgICAvLyBUcmFuc2llbnQgRmFzdCBQYXRoOiBSZWdpc3RlciBpbiBmYXN0IHRyYW5zaWVudCBjYWNoZVxuICAgICAgICAgICAgY29uc3QgY3RvciA9IGNvbmZpZy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIGNvbnN0IGZhc3RGYWN0b3J5ID0gKCkgPT4gbmV3IGN0b3IoKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5mYXN0VHJhbnNpZW50Q2FjaGUuc2V0KGNvbmZpZy50b2tlbiwgZmFzdEZhY3RvcnkpO1xuICAgICAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgZmFzdEZhY3RvcnksIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gUGVyLXJlcXVlc3Q6IFVzZSBzaW1wbGUgZmFjdG9yeSB3aXRob3V0IGF1dG93aXJlIG92ZXJoZWFkXG4gICAgICAgICAgICBjb25zdCBmYWN0b3J5ID0gKCkgPT4gbmV3IGNvbmZpZy5jb25zdHJ1Y3RvcigpO1xuICAgICAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgZmFjdG9yeSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGF1dG93aXJlIGZhY3RvcnlcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjcmVhdGVBdXRvV2lyZUZhY3RvcnkoY29udGFpbmVyLCBjb25maWcsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IChjKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZERlcHMgPSBhdXRvd2lyZShjb25maWcuY29uc3RydWN0b3IsIGMsIGNvbmZpZy5hdXRvd2lyZU9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb25maWcuY29uc3RydWN0b3IoLi4ucmVzb2x2ZWREZXBzKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgZmFjdG9yeSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB3aXRoUGFyYW1ldGVycyBmYWN0b3J5XG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY3JlYXRlUGFyYW1ldGVyRmFjdG9yeShjb250YWluZXIsIGNvbmZpZywgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gT2JqZWN0LnZhbHVlcyhjb25maWcucGFyYW1ldGVyVmFsdWVzKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY29uZmlnLmNvbnN0cnVjdG9yKC4uLnZhbHVlcyk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnRhaW5lci5iaW5kRmFjdG9yeShjb25maWcudG9rZW4sIGZhY3RvcnksIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBseSB0eXBlIHJlZ2lzdHJhdGlvbiAoY2xhc3MgY29uc3RydWN0b3IpXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgYXBwbHlUeXBlUmVnaXN0cmF0aW9uKGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHsgaGFzRGVwZW5kZW5jaWVzIH0gPSB0aGlzLmFuYWx5emVDb25zdHJ1Y3Rvcihjb25maWcuY29uc3RydWN0b3IpO1xuICAgICAgICAvLyBGYXN0IHBhdGg6IE5vIGRlcGVuZGVuY2llcyBhbmQgbm8gc3BlY2lhbCBjb25maWdcbiAgICAgICAgaWYgKCFoYXNEZXBlbmRlbmNpZXMgJiYgIWNvbmZpZy5hdXRvd2lyZU9wdGlvbnMgJiYgIWNvbmZpZy5wYXJhbWV0ZXJWYWx1ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlT3B0aW1pemVkRmFjdG9yeShjb250YWluZXIsIGNvbmZpZywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gQXV0b1dpcmUgcGF0aFxuICAgICAgICBpZiAoY29uZmlnLmF1dG93aXJlT3B0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVBdXRvV2lyZUZhY3RvcnkoY29udGFpbmVyLCBjb25maWcsIG9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHdpdGhQYXJhbWV0ZXJzIHBhdGhcbiAgICAgICAgaWYgKGNvbmZpZy5wYXJhbWV0ZXJWYWx1ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlUGFyYW1ldGVyRmFjdG9yeShjb250YWluZXIsIGNvbmZpZywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gRXJyb3I6IENvbnN0cnVjdG9yIGhhcyBkZXBlbmRlbmNpZXMgYnV0IG5vIGNvbmZpZ1xuICAgICAgICBpZiAoaGFzRGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBjb25maWcuY29uc3RydWN0b3IubmFtZSB8fCAnVW5uYW1lZENsYXNzJztcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmljZSBcIiR7Y2xhc3NOYW1lfVwiIGhhcyBjb25zdHJ1Y3RvciBkZXBlbmRlbmNpZXMgYnV0IG5vIGF1dG93aXJpbmcgY29uZmlndXJhdGlvbi5cXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgU29sdXRpb25zOlxcbmAgK1xuICAgICAgICAgICAgICAgIGAgIDEuIFx1MkI1MCBVc2UgdGhlIE5vdmFESSB0cmFuc2Zvcm1lciAocmVjb21tZW5kZWQpOlxcbmAgK1xuICAgICAgICAgICAgICAgIGAgICAgIC0gQWRkIFwiQG5vdmFkaS9jb3JlL3VucGx1Z2luXCIgdG8geW91ciBidWlsZCBjb25maWdcXG5gICtcbiAgICAgICAgICAgICAgICBgICAgICAtIFRyYW5zZm9ybWVyIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVzIC5hdXRvV2lyZSgpIGZvciBhbGwgZGVwZW5kZW5jaWVzXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCAgMi4gQWRkIG1hbnVhbCBhdXRvd2lyaW5nOlxcbmAgK1xuICAgICAgICAgICAgICAgIGAgICAgIC5hdXRvV2lyZSh7IG1hcDogeyAvKiBwYXJhbTogcmVzb2x2ZXIgKi8gfSB9KVxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGAgIDMuIFVzZSBhIGZhY3RvcnkgZnVuY3Rpb246XFxuYCArXG4gICAgICAgICAgICAgICAgYCAgICAgLnJlZ2lzdGVyKChjKSA9PiBuZXcgJHtjbGFzc05hbWV9KC4uLikpXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYFNlZSBkb2NzOiBodHRwczovL2dpdGh1Yi5jb20vamFudXMwMDcvTm92YURJI2F1dG93aXJlYCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm8gZGVwZW5kZW5jaWVzIC0gY3JlYXRlIHNpbXBsZSBmYWN0b3J5XG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSAoKSA9PiBuZXcgY29uZmlnLmNvbnN0cnVjdG9yKCk7XG4gICAgICAgIGNvbnRhaW5lci5iaW5kRmFjdG9yeShjb25maWcudG9rZW4sIGZhY3RvcnksIG9wdGlvbnMpO1xuICAgIH1cbiAgICBhcHBseVJlZ2lzdHJhdGlvbihjb250YWluZXIsIGNvbmZpZykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0geyBsaWZldGltZTogY29uZmlnLmxpZmV0aW1lIH07XG4gICAgICAgIHN3aXRjaCAoY29uZmlnLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2luc3RhbmNlJzpcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYmluZFZhbHVlKGNvbmZpZy50b2tlbiwgY29uZmlnLnZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2ZhY3RvcnknOlxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5iaW5kRmFjdG9yeShjb25maWcudG9rZW4sIGNvbmZpZy5mYWN0b3J5LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3R5cGUnOlxuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlUeXBlUmVnaXN0cmF0aW9uKGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcmUgZGVwZW5kZW5jeSBpbmplY3Rpb24gY29udGFpbmVyIGZvciBOb3ZhRElcbiAqL1xuaW1wb3J0IHsgVG9rZW4gfSBmcm9tICcuL3Rva2VuLmpzJztcbmltcG9ydCB7IEJpbmRpbmdOb3RGb3VuZEVycm9yLCBDaXJjdWxhckRlcGVuZGVuY3lFcnJvciB9IGZyb20gJy4vZXJyb3JzLmpzJztcbmltcG9ydCB7IEJ1aWxkZXIgfSBmcm9tICcuL2J1aWxkZXIuanMnO1xuZnVuY3Rpb24gaXNEaXNwb3NhYmxlKG9iaikge1xuICAgIHJldHVybiBvYmogJiYgdHlwZW9mIG9iai5kaXNwb3NlID09PSAnZnVuY3Rpb24nO1xufVxuLyoqXG4gKiBSZXNvbHV0aW9uIGNvbnRleHQgdHJhY2tzIHRoZSBjdXJyZW50IGRlcGVuZGVuY3kgcmVzb2x1dGlvbiBwYXRoXG4gKiBmb3IgY2lyY3VsYXIgZGVwZW5kZW5jeSBkZXRlY3Rpb24gYW5kIHBlci1yZXF1ZXN0IHNjb3BpbmdcbiAqL1xuY2xhc3MgUmVzb2x1dGlvbkNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnJlc29sdmluZ1N0YWNrID0gbmV3IFNldCgpO1xuICAgICAgICB0aGlzLnBlclJlcXVlc3RDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgaXNSZXNvbHZpbmcodG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2aW5nU3RhY2suaGFzKHRva2VuKTtcbiAgICB9XG4gICAgZW50ZXJSZXNvbHZlKHRva2VuKSB7XG4gICAgICAgIHRoaXMucmVzb2x2aW5nU3RhY2suYWRkKHRva2VuKTtcbiAgICAgICAgLy8gUGVyZm9ybWFuY2U6IERvbid0IGJ1aWxkIHBhdGggdW5sZXNzIHdlIG5lZWQgaXQgKG9ubHkgdXNlZCBpbiBlcnJvciBtZXNzYWdlcylcbiAgICAgICAgLy8gVGhpcyBhdm9pZHMgZXhwZW5zaXZlIHRva2VuLnRvU3RyaW5nKCkgY2FsbHMgb24gZXZlcnkgcmVzb2x2ZVxuICAgIH1cbiAgICBleGl0UmVzb2x2ZSh0b2tlbikge1xuICAgICAgICB0aGlzLnJlc29sdmluZ1N0YWNrLmRlbGV0ZSh0b2tlbik7XG4gICAgICAgIC8vIFBlcmZvcm1hbmNlOiBDbGVhciBsYXp5IHBhdGggY2FjaGUgd2hlbiBleGl0aW5nXG4gICAgICAgIHRoaXMucGF0aCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZ2V0UGF0aCgpIHtcbiAgICAgICAgLy8gUGVyZm9ybWFuY2U6IEJ1aWxkIHBhdGggb24tZGVtYW5kIG9ubHkgd2hlbiBuZWVkZWQgKHR5cGljYWxseSBmb3IgZXJyb3IgbWVzc2FnZXMpXG4gICAgICAgIGlmICghdGhpcy5wYXRoKSB7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBBcnJheS5mcm9tKHRoaXMucmVzb2x2aW5nU3RhY2spLm1hcCh0ID0+IHQudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFsuLi50aGlzLnBhdGhdO1xuICAgIH1cbiAgICBjYWNoZVBlclJlcXVlc3QodG9rZW4sIGluc3RhbmNlKSB7XG4gICAgICAgIHRoaXMucGVyUmVxdWVzdENhY2hlLnNldCh0b2tlbiwgaW5zdGFuY2UpO1xuICAgIH1cbiAgICBnZXRQZXJSZXF1ZXN0KHRva2VuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlclJlcXVlc3RDYWNoZS5nZXQodG9rZW4pO1xuICAgIH1cbiAgICBoYXNQZXJSZXF1ZXN0KHRva2VuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlclJlcXVlc3RDYWNoZS5oYXModG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNldCBjb250ZXh0IGZvciByZXVzZSBpbiBvYmplY3QgcG9vbFxuICAgICAqIFBlcmZvcm1hbmNlOiBSZXVzaW5nIGNvbnRleHRzIGF2b2lkcyBoZWFwIGFsbG9jYXRpb25zXG4gICAgICovXG4gICAgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMucmVzb2x2aW5nU3RhY2suY2xlYXIoKTtcbiAgICAgICAgdGhpcy5wZXJSZXF1ZXN0Q2FjaGUuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5wYXRoID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cbi8qKlxuICogT2JqZWN0IHBvb2wgZm9yIFJlc29sdXRpb25Db250ZXh0IGluc3RhbmNlc1xuICogUGVyZm9ybWFuY2U6IFJldXNpbmcgY29udGV4dHMgcmVkdWNlcyBoZWFwIGFsbG9jYXRpb25zIGFuZCBHQyBwcmVzc3VyZVxuICovXG5jbGFzcyBSZXNvbHV0aW9uQ29udGV4dFBvb2wge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnBvb2wgPSBbXTtcbiAgICAgICAgdGhpcy5tYXhTaXplID0gMTA7XG4gICAgfVxuICAgIGFjcXVpcmUoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnBvb2wucG9wKCk7XG4gICAgICAgIGlmIChjb250ZXh0KSB7XG4gICAgICAgICAgICAvLyBSZXNldCBleGlzdGluZyBjb250ZXh0IGZvciByZXVzZVxuICAgICAgICAgICAgY29udGV4dC5yZXNldCgpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ3JlYXRlIG5ldyBpZiBwb29sIGVtcHR5XG4gICAgICAgIHJldHVybiBuZXcgUmVzb2x1dGlvbkNvbnRleHQoKTtcbiAgICB9XG4gICAgcmVsZWFzZShjb250ZXh0KSB7XG4gICAgICAgIGlmICh0aGlzLnBvb2wubGVuZ3RoIDwgdGhpcy5tYXhTaXplKSB7XG4gICAgICAgICAgICB0aGlzLnBvb2wucHVzaChjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPdGhlcndpc2UgbGV0IGl0IGJlIEdDJ2RcbiAgICB9XG59XG4vKipcbiAqIERlcGVuZGVuY3kgSW5qZWN0aW9uIENvbnRhaW5lclxuICpcbiAqIE1hbmFnZXMgcmVnaXN0cmF0aW9uIGFuZCByZXNvbHV0aW9uIG9mIGRlcGVuZGVuY2llcyB3aXRoIHN1cHBvcnQgZm9yOlxuICogLSBNdWx0aXBsZSBiaW5kaW5nIHR5cGVzICh2YWx1ZSwgZmFjdG9yeSwgY2xhc3MpXG4gKiAtIExpZmV0aW1lIG1hbmFnZW1lbnQgKHNpbmdsZXRvbiwgdHJhbnNpZW50LCBwZXItcmVxdWVzdClcbiAqIC0gQ2hpbGQgY29udGFpbmVycyB3aXRoIGluaGVyaXRhbmNlXG4gKiAtIENpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0aW9uXG4gKiAtIEF1dG9tYXRpYyBkaXNwb3NhbFxuICovXG5leHBvcnQgY2xhc3MgQ29udGFpbmVyIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQpIHtcbiAgICAgICAgdGhpcy5iaW5kaW5ncyA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5zaW5nbGV0b25DYWNoZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5zaW5nbGV0b25PcmRlciA9IFtdO1xuICAgICAgICB0aGlzLmludGVyZmFjZVJlZ2lzdHJ5ID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLmludGVyZmFjZVRva2VuQ2FjaGUgPSBuZXcgTWFwKCk7IC8vIFBlcmZvcm1hbmNlOiBDYWNoZSBmb3IgcmVzb2x2ZVR5cGUoKSBsb29rdXBzXG4gICAgICAgIHRoaXMuZmFzdFRyYW5zaWVudENhY2hlID0gbmV3IE1hcCgpOyAvLyBQZXJmb3JtYW5jZTogRmFzdCBwYXRoIGZvciBzaW1wbGUgdHJhbnNpZW50c1xuICAgICAgICB0aGlzLnVsdHJhRmFzdFNpbmdsZXRvbkNhY2hlID0gbmV3IE1hcCgpOyAvLyBQZXJmb3JtYW5jZTogVWx0cmEtZmFzdCBzaW5nbGV0b24tb25seSBjYWNoZVxuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIHByZS1jcmVhdGVkIHZhbHVlIHRvIGEgdG9rZW5cbiAgICAgKi9cbiAgICBiaW5kVmFsdWUodG9rZW4sIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmluZGluZ3Muc2V0KHRva2VuLCB7XG4gICAgICAgICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgICAgICAgbGlmZXRpbWU6ICdzaW5nbGV0b24nLFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmludmFsaWRhdGVCaW5kaW5nQ2FjaGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGZhY3RvcnkgZnVuY3Rpb24gdG8gYSB0b2tlblxuICAgICAqL1xuICAgIGJpbmRGYWN0b3J5KHRva2VuLCBmYWN0b3J5LCBvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuYmluZGluZ3Muc2V0KHRva2VuLCB7XG4gICAgICAgICAgICB0eXBlOiAnZmFjdG9yeScsXG4gICAgICAgICAgICBsaWZldGltZTogb3B0aW9ucz8ubGlmZXRpbWUgfHwgJ3RyYW5zaWVudCcsXG4gICAgICAgICAgICBmYWN0b3J5LFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBvcHRpb25zPy5kZXBlbmRlbmNpZXMsXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmludmFsaWRhdGVCaW5kaW5nQ2FjaGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNsYXNzIGNvbnN0cnVjdG9yIHRvIGEgdG9rZW5cbiAgICAgKi9cbiAgICBiaW5kQ2xhc3ModG9rZW4sIGNvbnN0cnVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB7XG4gICAgICAgICAgICB0eXBlOiAnY2xhc3MnLFxuICAgICAgICAgICAgbGlmZXRpbWU6IG9wdGlvbnM/LmxpZmV0aW1lIHx8ICd0cmFuc2llbnQnLFxuICAgICAgICAgICAgY29uc3RydWN0b3IsXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXM6IG9wdGlvbnM/LmRlcGVuZGVuY2llc1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmJpbmRpbmdzLnNldCh0b2tlbiwgYmluZGluZyk7XG4gICAgICAgIHRoaXMuaW52YWxpZGF0ZUJpbmRpbmdDYWNoZSgpO1xuICAgICAgICAvLyBQZXJmb3JtYW5jZTogUHJlLWNvbXBpbGUgZmFzdCB0cmFuc2llbnQgZmFjdG9yeSBmb3IgemVyby1kZXBlbmRlbmN5IGNsYXNzZXNcbiAgICAgICAgaWYgKGJpbmRpbmcubGlmZXRpbWUgPT09ICd0cmFuc2llbnQnICYmICghYmluZGluZy5kZXBlbmRlbmNpZXMgfHwgYmluZGluZy5kZXBlbmRlbmNpZXMubGVuZ3RoID09PSAwKSkge1xuICAgICAgICAgICAgdGhpcy5mYXN0VHJhbnNpZW50Q2FjaGUuc2V0KHRva2VuLCAoKSA9PiBuZXcgY29uc3RydWN0b3IoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzb2x2ZSBhIGRlcGVuZGVuY3kgc3luY2hyb25vdXNseVxuICAgICAqIFBlcmZvcm1hbmNlIG9wdGltaXplZCB3aXRoIG11bHRpcGxlIGZhc3QgcGF0aHNcbiAgICAgKi9cbiAgICByZXNvbHZlKHRva2VuKSB7XG4gICAgICAgIC8vIFRyeSBhbGwgY2FjaGUgbGV2ZWxzIGZpcnN0ICh1bHRyYS1mYXN0LCBzaW5nbGV0b24sIGZhc3QgdHJhbnNpZW50KVxuICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnRyeUdldEZyb21DYWNoZXModG9rZW4pO1xuICAgICAgICBpZiAoY2FjaGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgd2UncmUgYWxyZWFkeSByZXNvbHZpbmcgKGNhbGxlZCBmcm9tIHdpdGhpbiBhIGZhY3RvcnkpLCByZXVzZSB0aGUgY29udGV4dFxuICAgICAgICBpZiAodGhpcy5jdXJyZW50Q29udGV4dCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVdpdGhDb250ZXh0KHRva2VuLCB0aGlzLmN1cnJlbnRDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDb21wbGV4IHJlc29sdXRpb24gd2l0aCBwb29sZWQgY29udGV4dFxuICAgICAgICBjb25zdCBjb250ZXh0ID0gQ29udGFpbmVyLmNvbnRleHRQb29sLmFjcXVpcmUoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlV2l0aENvbnRleHQodG9rZW4sIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIENvbnRhaW5lci5jb250ZXh0UG9vbC5yZWxlYXNlKGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNQRUNJQUxJWkVEOiBVbHRyYS1mYXN0IHNpbmdsZXRvbiByZXNvbHZlIChubyBzYWZldHkgY2hlY2tzKVxuICAgICAqIFVzZSBPTkxZIHdoZW4geW91J3JlIDEwMCUgc3VyZSB0aGUgdG9rZW4gaXMgYSByZWdpc3RlcmVkIHNpbmdsZXRvblxuICAgICAqIEBpbnRlcm5hbCBGb3IgcGVyZm9ybWFuY2UtY3JpdGljYWwgcGF0aHMgb25seVxuICAgICAqL1xuICAgIHJlc29sdmVTaW5nbGV0b25VbnNhZmUodG9rZW4pIHtcbiAgICAgICAgLy8gRGlyZWN0IHJldHVybiwgbm8gY2hlY2tzIC0gbWF4aW11bSBzcGVlZFxuICAgICAgICByZXR1cm4gdGhpcy51bHRyYUZhc3RTaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pID8/IHRoaXMuc2luZ2xldG9uQ2FjaGUuZ2V0KHRva2VuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU1BFQ0lBTElaRUQ6IEZhc3QgdHJhbnNpZW50IHJlc29sdmUgZm9yIHplcm8tZGVwZW5kZW5jeSBjbGFzc2VzXG4gICAgICogU2tpcHMgYWxsIGNvbnRleHQgY3JlYXRpb24gYW5kIGNpcmN1bGFyIGRlcGVuZGVuY3kgY2hlY2tzXG4gICAgICogQGludGVybmFsIEZvciBwZXJmb3JtYW5jZS1jcml0aWNhbCBwYXRocyBvbmx5XG4gICAgICovXG4gICAgcmVzb2x2ZVRyYW5zaWVudFNpbXBsZSh0b2tlbikge1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0gdGhpcy5mYXN0VHJhbnNpZW50Q2FjaGUuZ2V0KHRva2VuKTtcbiAgICAgICAgaWYgKGZhY3RvcnkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWN0b3J5KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmFsbGJhY2sgdG8gcmVndWxhciByZXNvbHZlIGlmIG5vdCBpbiBmYXN0IGNhY2hlXG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmUodG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTUEVDSUFMSVpFRDogQmF0Y2ggcmVzb2x2ZSBtdWx0aXBsZSBkZXBlbmRlbmNpZXMgYXQgb25jZVxuICAgICAqIE1vcmUgZWZmaWNpZW50IHRoYW4gbXVsdGlwbGUgaW5kaXZpZHVhbCByZXNvbHZlc1xuICAgICAqL1xuICAgIHJlc29sdmVCYXRjaCh0b2tlbnMpIHtcbiAgICAgICAgLy8gUmV1c2Ugc2luZ2xlIGNvbnRleHQgZm9yIGFsbCByZXNvbHV0aW9uc1xuICAgICAgICBjb25zdCB3YXNSZXNvbHZpbmcgPSAhIXRoaXMuY3VycmVudENvbnRleHQ7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmN1cnJlbnRDb250ZXh0IHx8IENvbnRhaW5lci5jb250ZXh0UG9vbC5hY3F1aXJlKCk7XG4gICAgICAgIGlmICghd2FzUmVzb2x2aW5nKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IHRva2Vucy5tYXAodG9rZW4gPT4ge1xuICAgICAgICAgICAgICAgIC8vIFRyeSBhbGwgY2FjaGUgbGV2ZWxzIGZpcnN0XG4gICAgICAgICAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy50cnlHZXRGcm9tQ2FjaGVzKHRva2VuKTtcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgICAgICAgICAgICAgLy8gRnVsbCByZXNvbHZlIHdpdGggc2hhcmVkIGNvbnRleHRcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlV2l0aENvbnRleHQodG9rZW4sIGNvbnRleHQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmICghd2FzUmVzb2x2aW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Q29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBDb250YWluZXIuY29udGV4dFBvb2wucmVsZWFzZShjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEgZGVwZW5kZW5jeSBhc3luY2hyb25vdXNseSAoc3VwcG9ydHMgYXN5bmMgZmFjdG9yaWVzKVxuICAgICAqL1xuICAgIGFzeW5jIHJlc29sdmVBc3luYyh0b2tlbikge1xuICAgICAgICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHJlc29sdmluZyAoY2FsbGVkIGZyb20gd2l0aGluIGEgZmFjdG9yeSksIHJldXNlIHRoZSBjb250ZXh0XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDb250ZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlQXN5bmNXaXRoQ29udGV4dCh0b2tlbiwgdGhpcy5jdXJyZW50Q29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTmV3IHRvcC1sZXZlbCByZXNvbHZlXG4gICAgICAgIC8vIFBlcmZvcm1hbmNlOiBVc2UgcG9vbGVkIGNvbnRleHQgdG8gYXZvaWQgaGVhcCBhbGxvY2F0aW9uXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBDb250YWluZXIuY29udGV4dFBvb2wuYWNxdWlyZSgpO1xuICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlc29sdmVBc3luY1dpdGhDb250ZXh0KHRva2VuLCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBDb250YWluZXIuY29udGV4dFBvb2wucmVsZWFzZShjb250ZXh0KTsgLy8gUmV0dXJuIHRvIHBvb2wgZm9yIHJldXNlXG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJ5IHRvIGdldCBpbnN0YW5jZSBmcm9tIGFsbCBjYWNoZSBsZXZlbHNcbiAgICAgKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiBub3QgY2FjaGVkXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgdHJ5R2V0RnJvbUNhY2hlcyh0b2tlbikge1xuICAgICAgICAvLyBMZXZlbCAxOiBVbHRyYS1mYXN0IHNpbmdsZXRvbiBjYWNoZSAoemVybyBvdmVyaGVhZClcbiAgICAgICAgY29uc3QgdWx0cmFGYXN0ID0gdGhpcy51bHRyYUZhc3RTaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pO1xuICAgICAgICBpZiAodWx0cmFGYXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB1bHRyYUZhc3Q7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTGV2ZWwgMjogUmVndWxhciBzaW5nbGV0b24gY2FjaGVcbiAgICAgICAgaWYgKHRoaXMuc2luZ2xldG9uQ2FjaGUuaGFzKHRva2VuKSkge1xuICAgICAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5zaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pO1xuICAgICAgICAgICAgLy8gUHJvbW90ZSB0byB1bHRyYS1mYXN0IGNhY2hlIGZvciBuZXh0IHRpbWVcbiAgICAgICAgICAgIHRoaXMudWx0cmFGYXN0U2luZ2xldG9uQ2FjaGUuc2V0KHRva2VuLCBjYWNoZWQpO1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBMZXZlbCAzOiBGYXN0IHRyYW5zaWVudCBjYWNoZSAobm8gZGVwZW5kZW5jaWVzKVxuICAgICAgICBjb25zdCBmYXN0RmFjdG9yeSA9IHRoaXMuZmFzdFRyYW5zaWVudENhY2hlLmdldCh0b2tlbik7XG4gICAgICAgIGlmIChmYXN0RmFjdG9yeSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhc3RGYWN0b3J5KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FjaGUgaW5zdGFuY2UgYmFzZWQgb24gbGlmZXRpbWUgc3RyYXRlZ3lcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjYWNoZUluc3RhbmNlKHRva2VuLCBpbnN0YW5jZSwgbGlmZXRpbWUsIGNvbnRleHQpIHtcbiAgICAgICAgaWYgKGxpZmV0aW1lID09PSAnc2luZ2xldG9uJykge1xuICAgICAgICAgICAgdGhpcy5zaW5nbGV0b25DYWNoZS5zZXQodG9rZW4sIGluc3RhbmNlKTtcbiAgICAgICAgICAgIHRoaXMuc2luZ2xldG9uT3JkZXIucHVzaCh0b2tlbik7XG4gICAgICAgICAgICAvLyBBbHNvIGFkZCB0byB1bHRyYS1mYXN0IGNhY2hlXG4gICAgICAgICAgICB0aGlzLnVsdHJhRmFzdFNpbmdsZXRvbkNhY2hlLnNldCh0b2tlbiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGxpZmV0aW1lID09PSAncGVyLXJlcXVlc3QnICYmIGNvbnRleHQpIHtcbiAgICAgICAgICAgIGNvbnRleHQuY2FjaGVQZXJSZXF1ZXN0KHRva2VuLCBpbnN0YW5jZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVmFsaWRhdGUgYW5kIGdldCBiaW5kaW5nIHdpdGggY2lyY3VsYXIgZGVwZW5kZW5jeSBjaGVja1xuICAgICAqIFJldHVybnMgYmluZGluZyBvciB0aHJvd3MgZXJyb3JcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICB2YWxpZGF0ZUFuZEdldEJpbmRpbmcodG9rZW4sIGNvbnRleHQpIHtcbiAgICAgICAgLy8gQ2hlY2sgY2lyY3VsYXIgZGVwZW5kZW5jeVxuICAgICAgICBpZiAoY29udGV4dC5pc1Jlc29sdmluZyh0b2tlbikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDaXJjdWxhckRlcGVuZGVuY3lFcnJvcihbLi4uY29udGV4dC5nZXRQYXRoKCksIHRva2VuLnRvU3RyaW5nKCldKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBiaW5kaW5nID0gdGhpcy5nZXRCaW5kaW5nKHRva2VuKTtcbiAgICAgICAgaWYgKCFiaW5kaW5nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQmluZGluZ05vdEZvdW5kRXJyb3IodG9rZW4udG9TdHJpbmcoKSwgY29udGV4dC5nZXRQYXRoKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiaW5kaW5nO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnN0YW50aWF0ZSBmcm9tIGJpbmRpbmcgc3luY2hyb25vdXNseVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGluc3RhbnRpYXRlQmluZGluZ1N5bmMoYmluZGluZywgdG9rZW4sIGNvbnRleHQpIHtcbiAgICAgICAgc3dpdGNoIChiaW5kaW5nLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZy52YWx1ZTtcbiAgICAgICAgICAgIGNhc2UgJ2ZhY3RvcnknOlxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGJpbmRpbmcuZmFjdG9yeSh0aGlzKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jIGZhY3RvcnkgZGV0ZWN0ZWQgZm9yICR7dG9rZW4udG9TdHJpbmcoKX0uIFVzZSByZXNvbHZlQXN5bmMoKSBpbnN0ZWFkLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICAgICAgICAgIGNvbnN0IGRlcHMgPSBiaW5kaW5nLmRlcGVuZGVuY2llcyB8fCBbXTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZERlcHMgPSBkZXBzLm1hcChkZXAgPT4gdGhpcy5yZXNvbHZlV2l0aENvbnRleHQoZGVwLCBjb250ZXh0KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nLmNvbnN0cnVjdG9yKC4uLnJlc29sdmVkRGVwcyk7XG4gICAgICAgICAgICBjYXNlICdpbmxpbmUtY2xhc3MnOlxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYmluZGluZy5jb25zdHJ1Y3RvcigpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gYmluZGluZyB0eXBlOiAke2JpbmRpbmcudHlwZX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnN0YW50aWF0ZSBmcm9tIGJpbmRpbmcgYXN5bmNocm9ub3VzbHlcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBhc3luYyBpbnN0YW50aWF0ZUJpbmRpbmdBc3luYyhiaW5kaW5nLCBjb250ZXh0KSB7XG4gICAgICAgIHN3aXRjaCAoYmluZGluZy50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICd2YWx1ZSc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmcudmFsdWU7XG4gICAgICAgICAgICBjYXNlICdmYWN0b3J5JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKGJpbmRpbmcuZmFjdG9yeSh0aGlzKSk7XG4gICAgICAgICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgICAgICAgICAgY29uc3QgZGVwcyA9IGJpbmRpbmcuZGVwZW5kZW5jaWVzIHx8IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkRGVwcyA9IGF3YWl0IFByb21pc2UuYWxsKGRlcHMubWFwKGRlcCA9PiB0aGlzLnJlc29sdmVBc3luY1dpdGhDb250ZXh0KGRlcCwgY29udGV4dCkpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmcuY29uc3RydWN0b3IoLi4ucmVzb2x2ZWREZXBzKTtcbiAgICAgICAgICAgIGNhc2UgJ2lubGluZS1jbGFzcyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nLmNvbnN0cnVjdG9yKCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBiaW5kaW5nIHR5cGU6ICR7YmluZGluZy50eXBlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIGNoaWxkIGNvbnRhaW5lciB0aGF0IGluaGVyaXRzIGJpbmRpbmdzIGZyb20gdGhpcyBjb250YWluZXJcbiAgICAgKi9cbiAgICBjcmVhdGVDaGlsZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb250YWluZXIodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3Bvc2UgYWxsIHNpbmdsZXRvbiBpbnN0YW5jZXMgaW4gcmV2ZXJzZSByZWdpc3RyYXRpb24gb3JkZXJcbiAgICAgKi9cbiAgICBhc3luYyBkaXNwb3NlKCkge1xuICAgICAgICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgICAgICAgLy8gRGlzcG9zZSBpbiByZXZlcnNlIG9yZGVyXG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLnNpbmdsZXRvbk9yZGVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9IHRoaXMuc2luZ2xldG9uT3JkZXJbaV07XG4gICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuc2luZ2xldG9uQ2FjaGUuZ2V0KHRva2VuKTtcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZSAmJiBpc0Rpc3Bvc2FibGUoaW5zdGFuY2UpKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgaW5zdGFuY2UuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBkaXNwb3Npbmcgb3RoZXIgaW5zdGFuY2VzIGV2ZW4gaWYgb25lIGZhaWxzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENsZWFyIGNhY2hlc1xuICAgICAgICB0aGlzLnNpbmdsZXRvbkNhY2hlLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuc2luZ2xldG9uT3JkZXIubGVuZ3RoID0gMDtcbiAgICAgICAgLy8gTm90ZTogV2UgZG9uJ3QgdGhyb3cgZXJyb3JzIHRvIGFsbG93IGFsbCBkaXNwb3NhbHMgdG8gY29tcGxldGVcbiAgICAgICAgLy8gSW4gcHJvZHVjdGlvbiwgeW91IG1pZ2h0IHdhbnQgdG8gbG9nIHRoZXNlIGVycm9yc1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBmbHVlbnQgYnVpbGRlciBmb3IgcmVnaXN0ZXJpbmcgZGVwZW5kZW5jaWVzXG4gICAgICovXG4gICAgYnVpbGRlcigpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBCdWlsZGVyKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEgbmFtZWQgc2VydmljZVxuICAgICAqL1xuICAgIHJlc29sdmVOYW1lZChuYW1lKSB7XG4gICAgICAgIGNvbnN0IG5hbWVkUmVnaXN0cmF0aW9ucyA9IHRoaXMuX19uYW1lZFJlZ2lzdHJhdGlvbnM7XG4gICAgICAgIGlmICghbmFtZWRSZWdpc3RyYXRpb25zKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5hbWVkIHNlcnZpY2UgXCIke25hbWV9XCIgbm90IGZvdW5kLiBObyBuYW1lZCByZWdpc3RyYXRpb25zIGV4aXN0LmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IG5hbWVkUmVnaXN0cmF0aW9ucy5nZXQobmFtZSk7XG4gICAgICAgIGlmICghY29uZmlnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5hbWVkIHNlcnZpY2UgXCIke25hbWV9XCIgbm90IGZvdW5kYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZShjb25maWcudG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEga2V5ZWQgc2VydmljZVxuICAgICAqL1xuICAgIHJlc29sdmVLZXllZChrZXkpIHtcbiAgICAgICAgY29uc3Qga2V5ZWRSZWdpc3RyYXRpb25zID0gdGhpcy5fX2tleWVkUmVnaXN0cmF0aW9ucztcbiAgICAgICAgaWYgKCFrZXllZFJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgS2V5ZWQgc2VydmljZSBub3QgZm91bmQuIE5vIGtleWVkIHJlZ2lzdHJhdGlvbnMgZXhpc3QuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uZmlnID0ga2V5ZWRSZWdpc3RyYXRpb25zLmdldChrZXkpO1xuICAgICAgICBpZiAoIWNvbmZpZykge1xuICAgICAgICAgICAgY29uc3Qga2V5U3RyID0gdHlwZW9mIGtleSA9PT0gJ3N5bWJvbCcgPyBrZXkudG9TdHJpbmcoKSA6IGBcIiR7a2V5fVwiYDtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgS2V5ZWQgc2VydmljZSAke2tleVN0cn0gbm90IGZvdW5kYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZShjb25maWcudG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGFsbCByZWdpc3RyYXRpb25zIGZvciBhIHRva2VuXG4gICAgICovXG4gICAgcmVzb2x2ZUFsbCh0b2tlbikge1xuICAgICAgICBjb25zdCBtdWx0aVJlZ2lzdHJhdGlvbnMgPSB0aGlzLl9fbXVsdGlSZWdpc3RyYXRpb25zO1xuICAgICAgICBpZiAoIW11bHRpUmVnaXN0cmF0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRva2VucyA9IG11bHRpUmVnaXN0cmF0aW9ucy5nZXQodG9rZW4pO1xuICAgICAgICBpZiAoIXRva2VucyB8fCB0b2tlbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRva2Vucy5tYXAoKHQpID0+IHRoaXMucmVzb2x2ZSh0KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCByZWdpc3RyeSBpbmZvcm1hdGlvbiBmb3IgZGVidWdnaW5nL3Zpc3VhbGl6YXRpb25cbiAgICAgKiBSZXR1cm5zIGFycmF5IG9mIGJpbmRpbmcgaW5mb3JtYXRpb25cbiAgICAgKi9cbiAgICBnZXRSZWdpc3RyeSgpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0cnkgPSBbXTtcbiAgICAgICAgdGhpcy5iaW5kaW5ncy5mb3JFYWNoKChiaW5kaW5nLCB0b2tlbikgPT4ge1xuICAgICAgICAgICAgcmVnaXN0cnkucHVzaCh7XG4gICAgICAgICAgICAgICAgdG9rZW46IHRva2VuLmRlc2NyaXB0aW9uIHx8IHRva2VuLnN5bWJvbC50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHR5cGU6IGJpbmRpbmcudHlwZSxcbiAgICAgICAgICAgICAgICBsaWZldGltZTogYmluZGluZy5saWZldGltZSxcbiAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXM6IGJpbmRpbmcuZGVwZW5kZW5jaWVzPy5tYXAoZCA9PiBkLmRlc2NyaXB0aW9uIHx8IGQuc3ltYm9sLnRvU3RyaW5nKCkpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZWdpc3RyeTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IG9yIGNyZWF0ZSBhIHRva2VuIGZvciBhbiBpbnRlcmZhY2UgdHlwZVxuICAgICAqIFVzZXMgYSB0eXBlIG5hbWUgaGFzaCBhcyBrZXkgZm9yIHRoZSBpbnRlcmZhY2UgcmVnaXN0cnlcbiAgICAgKi9cbiAgICBpbnRlcmZhY2VUb2tlbih0eXBlTmFtZSkge1xuICAgICAgICAvLyBHZW5lcmF0ZSBhIHVuaXF1ZSBrZXkgZm9yIHRoaXMgaW50ZXJmYWNlIHR5cGVcbiAgICAgICAgLy8gSW4gcHJvZHVjdGlvbiwgdGhpcyB3b3VsZCBiZSByZXBsYWNlZCBieSBhIFRTIHRyYW5zZm9ybWVyXG4gICAgICAgIGNvbnN0IGtleSA9IHR5cGVOYW1lIHx8IGBJbnRlcmZhY2VfJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwgOSl9YDtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdG9rZW4gYWxyZWFkeSBleGlzdHMgaW4gdGhpcyBjb250YWluZXJcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJmYWNlUmVnaXN0cnkuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVyZmFjZVJlZ2lzdHJ5LmdldChrZXkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENoZWNrIHBhcmVudCBjb250YWluZXIgKHJlY3Vyc2l2ZWx5IHRocm91Z2ggcGFyZW50IGNoYWluKVxuICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNoZWNrIHRocm91Z2ggZW50aXJlIHBhcmVudCBjaGFpblxuICAgICAgICAgICAgY29uc3QgcGFyZW50VG9rZW4gPSB0aGlzLnBhcmVudC5pbnRlcmZhY2VUb2tlbihrZXkpO1xuICAgICAgICAgICAgLy8gSWYgcGFyZW50IGNyZWF0ZWQgYSBuZXcgdG9rZW4sIGRvbid0IGNyZWF0ZSBhbm90aGVyIG9uZVxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudFRva2VuO1xuICAgICAgICB9XG4gICAgICAgIC8vIENyZWF0ZSBuZXcgdG9rZW4gKG9ubHkgaWYgbm8gcGFyZW50IGV4aXN0cylcbiAgICAgICAgY29uc3QgdG9rZW4gPSBUb2tlbihrZXkpO1xuICAgICAgICB0aGlzLmludGVyZmFjZVJlZ2lzdHJ5LnNldChrZXksIHRva2VuKTtcbiAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEgZGVwZW5kZW5jeSBieSBpbnRlcmZhY2UgdHlwZSB3aXRob3V0IGV4cGxpY2l0IHRva2VuXG4gICAgICovXG4gICAgcmVzb2x2ZVR5cGUodHlwZU5hbWUpIHtcbiAgICAgICAgLy8gUGVyZm9ybWFuY2U6IENhY2hlIHRva2VuIGxvb2t1cHMgdG8gYXZvaWQgcmVwZWF0ZWQgaW50ZXJmYWNlUmVnaXN0cnkgYWNjZXNzXG4gICAgICAgIGNvbnN0IGtleSA9IHR5cGVOYW1lIHx8ICcnO1xuICAgICAgICBsZXQgdG9rZW4gPSB0aGlzLmludGVyZmFjZVRva2VuQ2FjaGUuZ2V0KGtleSk7XG4gICAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgICAgIHRva2VuID0gdGhpcy5pbnRlcmZhY2VUb2tlbih0eXBlTmFtZSk7XG4gICAgICAgICAgICB0aGlzLmludGVyZmFjZVRva2VuQ2FjaGUuc2V0KGtleSwgdG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmUodG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEga2V5ZWQgaW50ZXJmYWNlXG4gICAgICovXG4gICAgcmVzb2x2ZVR5cGVLZXllZChrZXksIF90eXBlTmFtZSkge1xuICAgICAgICAvLyBGb3Iga2V5ZWQgaW50ZXJmYWNlcywgd2UgdXNlIHRoZSBleGlzdGluZyByZXNvbHZlS2V5ZWQgbWVjaGFuaXNtXG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVLZXllZChrZXkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGFsbCByZWdpc3RyYXRpb25zIGZvciBhbiBpbnRlcmZhY2UgdHlwZVxuICAgICAqL1xuICAgIHJlc29sdmVUeXBlQWxsKHR5cGVOYW1lKSB7XG4gICAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5pbnRlcmZhY2VUb2tlbih0eXBlTmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVBbGwodG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogUmVzb2x2ZSB3aXRoIGNvbnRleHQgZm9yIGNpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0aW9uXG4gICAgICovXG4gICAgcmVzb2x2ZVdpdGhDb250ZXh0KHRva2VuLCBjb250ZXh0KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGFuZCBnZXQgYmluZGluZyAod2l0aCBjaXJjdWxhciBkZXBlbmRlbmN5IGNoZWNrKVxuICAgICAgICBjb25zdCBiaW5kaW5nID0gdGhpcy52YWxpZGF0ZUFuZEdldEJpbmRpbmcodG9rZW4sIGNvbnRleHQpO1xuICAgICAgICAvLyBDaGVjayBwZXItcmVxdWVzdCBjYWNoZVxuICAgICAgICBpZiAoYmluZGluZy5saWZldGltZSA9PT0gJ3Blci1yZXF1ZXN0JyAmJiBjb250ZXh0Lmhhc1BlclJlcXVlc3QodG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5nZXRQZXJSZXF1ZXN0KHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDaGVjayBzaW5nbGV0b24gY2FjaGUgKGxvY2FsIGNvbnRhaW5lciBvbmx5KVxuICAgICAgICBpZiAoYmluZGluZy5saWZldGltZSA9PT0gJ3NpbmdsZXRvbicgJiYgdGhpcy5zaW5nbGV0b25DYWNoZS5oYXModG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIC8vIE1hcmsgYXMgcmVzb2x2aW5nXG4gICAgICAgIGNvbnRleHQuZW50ZXJSZXNvbHZlKHRva2VuKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEluc3RhbnRpYXRlIGZyb20gYmluZGluZ1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmluc3RhbnRpYXRlQmluZGluZ1N5bmMoYmluZGluZywgdG9rZW4sIGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQ2FjaGUgYmFzZWQgb24gbGlmZXRpbWVcbiAgICAgICAgICAgIHRoaXMuY2FjaGVJbnN0YW5jZSh0b2tlbiwgaW5zdGFuY2UsIGJpbmRpbmcubGlmZXRpbWUsIGNvbnRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgY29udGV4dC5leGl0UmVzb2x2ZSh0b2tlbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEFzeW5jIHJlc29sdmUgd2l0aCBjb250ZXh0XG4gICAgICovXG4gICAgYXN5bmMgcmVzb2x2ZUFzeW5jV2l0aENvbnRleHQodG9rZW4sIGNvbnRleHQpIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgYW5kIGdldCBiaW5kaW5nICh3aXRoIGNpcmN1bGFyIGRlcGVuZGVuY3kgY2hlY2spXG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLnZhbGlkYXRlQW5kR2V0QmluZGluZyh0b2tlbiwgY29udGV4dCk7XG4gICAgICAgIC8vIENoZWNrIHBlci1yZXF1ZXN0IGNhY2hlXG4gICAgICAgIGlmIChiaW5kaW5nLmxpZmV0aW1lID09PSAncGVyLXJlcXVlc3QnICYmIGNvbnRleHQuaGFzUGVyUmVxdWVzdCh0b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmdldFBlclJlcXVlc3QodG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIC8vIENoZWNrIHNpbmdsZXRvbiBjYWNoZSAobG9jYWwgY29udGFpbmVyIG9ubHkpXG4gICAgICAgIGlmIChiaW5kaW5nLmxpZmV0aW1lID09PSAnc2luZ2xldG9uJyAmJiB0aGlzLnNpbmdsZXRvbkNhY2hlLmhhcyh0b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNpbmdsZXRvbkNhY2hlLmdldCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTWFyayBhcyByZXNvbHZpbmdcbiAgICAgICAgY29udGV4dC5lbnRlclJlc29sdmUodG9rZW4pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gSW5zdGFudGlhdGUgZnJvbSBiaW5kaW5nIGFzeW5jaHJvbm91c2x5XG4gICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IHRoaXMuaW5zdGFudGlhdGVCaW5kaW5nQXN5bmMoYmluZGluZywgY29udGV4dCk7XG4gICAgICAgICAgICAvLyBDYWNoZSBiYXNlZCBvbiBsaWZldGltZVxuICAgICAgICAgICAgdGhpcy5jYWNoZUluc3RhbmNlKHRva2VuLCBpbnN0YW5jZSwgYmluZGluZy5saWZldGltZSwgY29udGV4dCk7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBjb250ZXh0LmV4aXRSZXNvbHZlKHRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYmluZGluZyBmcm9tIHRoaXMgY29udGFpbmVyIG9yIHBhcmVudCBjaGFpblxuICAgICAqIFBlcmZvcm1hbmNlIG9wdGltaXplZDogVXNlcyBmbGF0IGNhY2hlIHRvIGF2b2lkIHJlY3Vyc2l2ZSBwYXJlbnQgbG9va3Vwc1xuICAgICAqL1xuICAgIGdldEJpbmRpbmcodG9rZW4pIHtcbiAgICAgICAgLy8gQnVpbGQgZmxhdCBjYWNoZSBvbiBmaXJzdCBhY2Nlc3NcbiAgICAgICAgaWYgKCF0aGlzLmJpbmRpbmdDYWNoZSkge1xuICAgICAgICAgICAgdGhpcy5idWlsZEJpbmRpbmdDYWNoZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmRpbmdDYWNoZS5nZXQodG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCdWlsZCBmbGF0IGNhY2hlIG9mIGFsbCBiaW5kaW5ncyBpbmNsdWRpbmcgcGFyZW50IGNoYWluXG4gICAgICogVGhpcyBjb252ZXJ0cyBPKG4pIHBhcmVudCBjaGFpbiB0cmF2ZXJzYWwgdG8gTygxKSBsb29rdXBcbiAgICAgKi9cbiAgICBidWlsZEJpbmRpbmdDYWNoZSgpIHtcbiAgICAgICAgdGhpcy5iaW5kaW5nQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIFRyYXZlcnNlIHBhcmVudCBjaGFpbiBhbmQgZmxhdHRlbiBhbGwgYmluZGluZ3NcbiAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzO1xuICAgICAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgICAgICAgY3VycmVudC5iaW5kaW5ncy5mb3JFYWNoKChiaW5kaW5nLCB0b2tlbikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENoaWxkIGJpbmRpbmdzIG92ZXJyaWRlIHBhcmVudCBiaW5kaW5ncyAoZmlyc3Qgd2lucylcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYmluZGluZ0NhY2hlLmhhcyh0b2tlbikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iaW5kaW5nQ2FjaGUuc2V0KHRva2VuLCBiaW5kaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZhbGlkYXRlIGJpbmRpbmcgY2FjaGUgd2hlbiBuZXcgYmluZGluZ3MgYXJlIGFkZGVkXG4gICAgICogQ2FsbGVkIGJ5IGJpbmRWYWx1ZSwgYmluZEZhY3RvcnksIGJpbmRDbGFzc1xuICAgICAqL1xuICAgIGludmFsaWRhdGVCaW5kaW5nQ2FjaGUoKSB7XG4gICAgICAgIHRoaXMuYmluZGluZ0NhY2hlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnVsdHJhRmFzdFNpbmdsZXRvbkNhY2hlLmNsZWFyKCk7IC8vIENsZWFyIHVsdHJhLWZhc3QgY2FjaGUgd2hlbiBiaW5kaW5ncyBjaGFuZ2VcbiAgICB9XG59XG5Db250YWluZXIuY29udGV4dFBvb2wgPSBuZXcgUmVzb2x1dGlvbkNvbnRleHRQb29sKCk7IC8vIFBlcmZvcm1hbmNlOiBQb29sZWQgY29udGV4dHMgcmVkdWNlIGFsbG9jYXRpb25zXG4iLCAiZXhwb3J0IGNsYXNzIERhdGVSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3IoZGF0ZVNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLnR5cGUgPSAnZGF0ZSc7XG4gICAgfVxuICAgIHJlbmRlcihjb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IGRhdGVzID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXSB8fCBbXTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VJZHMgPSBjb250ZXh0LmZpbHRlclsncmVzb3VyY2UnXSB8fCBbXTtcbiAgICAgICAgLy8gQ2hlY2sgaWYgZGF0ZSBoZWFkZXJzIHNob3VsZCBiZSBoaWRkZW4gKGUuZy4sIGluIGRheSB2aWV3KVxuICAgICAgICBjb25zdCBkYXRlR3JvdXBpbmcgPSBjb250ZXh0Lmdyb3VwaW5ncz8uZmluZChnID0+IGcudHlwZSA9PT0gJ2RhdGUnKTtcbiAgICAgICAgY29uc3QgaGlkZUhlYWRlciA9IGRhdGVHcm91cGluZz8uaGlkZUhlYWRlciA9PT0gdHJ1ZTtcbiAgICAgICAgLy8gUmVuZGVyIGRhdGVzIGZvciBIVkVSIHJlc291cmNlIChlbGxlciAxIGdhbmcgaHZpcyBpbmdlbiByZXNvdXJjZXMpXG4gICAgICAgIGNvbnN0IGl0ZXJhdGlvbnMgPSByZXNvdXJjZUlkcy5sZW5ndGggfHwgMTtcbiAgICAgICAgbGV0IGNvbHVtbkNvdW50ID0gMDtcbiAgICAgICAgZm9yIChsZXQgciA9IDA7IHIgPCBpdGVyYXRpb25zOyByKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc291cmNlSWQgPSByZXNvdXJjZUlkc1tyXTsgLy8gdW5kZWZpbmVkIGh2aXMgaW5nZW4gcmVzb3VyY2VzXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRhdGVTdHIgb2YgZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5kYXRlU2VydmljZS5wYXJzZUlTTyhkYXRlU3RyKTtcbiAgICAgICAgICAgICAgICAvLyBCdWlsZCBjb2x1bW5LZXkgZm9yIHVuaWZvcm0gaWRlbnRpZmljYXRpb25cbiAgICAgICAgICAgICAgICBjb25zdCBzZWdtZW50cyA9IHsgZGF0ZTogZGF0ZVN0ciB9O1xuICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZUlkKVxuICAgICAgICAgICAgICAgICAgICBzZWdtZW50cy5yZXNvdXJjZSA9IHJlc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5kYXRlU2VydmljZS5idWlsZENvbHVtbktleShzZWdtZW50cyk7XG4gICAgICAgICAgICAgICAgLy8gSGVhZGVyXG4gICAgICAgICAgICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWRheS1oZWFkZXInKTtcbiAgICAgICAgICAgICAgICBoZWFkZXIuZGF0YXNldC5kYXRlID0gZGF0ZVN0cjtcbiAgICAgICAgICAgICAgICBoZWFkZXIuZGF0YXNldC5jb2x1bW5LZXkgPSBjb2x1bW5LZXk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmRhdGFzZXQucmVzb3VyY2VJZCA9IHJlc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChoaWRlSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlci5kYXRhc2V0LmhpZGRlbiA9ICd0cnVlJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaGVhZGVyLmlubmVySFRNTCA9IGBcclxuICAgICAgICAgIDxzd3AtZGF5LW5hbWU+JHt0aGlzLmRhdGVTZXJ2aWNlLmdldERheU5hbWUoZGF0ZSwgJ3Nob3J0Jyl9PC9zd3AtZGF5LW5hbWU+XHJcbiAgICAgICAgICA8c3dwLWRheS1kYXRlPiR7ZGF0ZS5nZXREYXRlKCl9PC9zd3AtZGF5LWRhdGU+XHJcbiAgICAgICAgYDtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmhlYWRlckNvbnRhaW5lci5hcHBlbmRDaGlsZChoZWFkZXIpO1xuICAgICAgICAgICAgICAgIC8vIENvbHVtblxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbHVtbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1kYXktY29sdW1uJyk7XG4gICAgICAgICAgICAgICAgY29sdW1uLmRhdGFzZXQuZGF0ZSA9IGRhdGVTdHI7XG4gICAgICAgICAgICAgICAgY29sdW1uLmRhdGFzZXQuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xuICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbi5kYXRhc2V0LnJlc291cmNlSWQgPSByZXNvdXJjZUlkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb2x1bW4uaW5uZXJIVE1MID0gJzxzd3AtZXZlbnRzLWxheWVyPjwvc3dwLWV2ZW50cy1sYXllcj4nO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuY29sdW1uQ29udGFpbmVyLmFwcGVuZENoaWxkKGNvbHVtbik7XG4gICAgICAgICAgICAgICAgY29sdW1uQ291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBTZXQgZ3JpZCBjb2x1bW5zIG9uIGNvbnRhaW5lclxuICAgICAgICBjb25zdCBjb250YWluZXIgPSBjb250ZXh0LmNvbHVtbkNvbnRhaW5lci5jbG9zZXN0KCdzd3AtY2FsZW5kYXItY29udGFpbmVyJyk7XG4gICAgICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1ncmlkLWNvbHVtbnMnLCBTdHJpbmcoY29sdW1uQ291bnQpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJpbXBvcnQgZGF5anMgZnJvbSAnZGF5anMnO1xuaW1wb3J0IHV0YyBmcm9tICdkYXlqcy9wbHVnaW4vdXRjJztcbmltcG9ydCB0aW1lem9uZSBmcm9tICdkYXlqcy9wbHVnaW4vdGltZXpvbmUnO1xuaW1wb3J0IGlzb1dlZWsgZnJvbSAnZGF5anMvcGx1Z2luL2lzb1dlZWsnO1xuLy8gRW5hYmxlIGRheWpzIHBsdWdpbnNcbmRheWpzLmV4dGVuZCh1dGMpO1xuZGF5anMuZXh0ZW5kKHRpbWV6b25lKTtcbmRheWpzLmV4dGVuZChpc29XZWVrKTtcbmV4cG9ydCBjbGFzcyBEYXRlU2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29uZmlnLCBiYXNlRGF0ZSkge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy50aW1lem9uZSA9IGNvbmZpZy50aW1lem9uZTtcbiAgICAgICAgLy8gQWxsb3cgc2V0dGluZyBhIGZpeGVkIGJhc2UgZGF0ZSBmb3IgZGVtby90ZXN0aW5nIHB1cnBvc2VzXG4gICAgICAgIHRoaXMuYmFzZURhdGUgPSBiYXNlRGF0ZSA/IGRheWpzKGJhc2VEYXRlKSA6IGRheWpzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBhIGZpeGVkIGJhc2UgZGF0ZSAodXNlZnVsIGZvciBkZW1vcyB3aXRoIHN0YXRpYyBtb2NrIGRhdGEpXG4gICAgICovXG4gICAgc2V0QmFzZURhdGUoZGF0ZSkge1xuICAgICAgICB0aGlzLmJhc2VEYXRlID0gZGF5anMoZGF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBiYXNlIGRhdGUgKGVpdGhlciBmaXhlZCBvciB0b2RheSlcbiAgICAgKi9cbiAgICBnZXRCYXNlRGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmFzZURhdGUudG9EYXRlKCk7XG4gICAgfVxuICAgIHBhcnNlSVNPKGlzb1N0cmluZykge1xuICAgICAgICByZXR1cm4gZGF5anMoaXNvU3RyaW5nKS50b0RhdGUoKTtcbiAgICB9XG4gICAgZ2V0RGF5TmFtZShkYXRlLCBmb3JtYXQgPSAnc2hvcnQnKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50bC5EYXRlVGltZUZvcm1hdCh0aGlzLmNvbmZpZy5sb2NhbGUsIHsgd2Vla2RheTogZm9ybWF0IH0pLmZvcm1hdChkYXRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGRhdGVzIHN0YXJ0aW5nIGZyb20gYSBkYXkgb2Zmc2V0XG4gICAgICogQHBhcmFtIGRheU9mZnNldCAtIERheSBvZmZzZXQgZnJvbSBiYXNlIGRhdGVcbiAgICAgKiBAcGFyYW0gY291bnQgLSBOdW1iZXIgb2YgY29uc2VjdXRpdmUgZGF5cyB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJucyBBcnJheSBvZiBkYXRlIHN0cmluZ3MgaW4gWVlZWS1NTS1ERCBmb3JtYXRcbiAgICAgKi9cbiAgICBnZXREYXRlc0Zyb21PZmZzZXQoZGF5T2Zmc2V0LCBjb3VudCkge1xuICAgICAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLmJhc2VEYXRlLmFkZChkYXlPZmZzZXQsICdkYXknKTtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IGNvdW50IH0sIChfLCBpKSA9PiBzdGFydERhdGUuYWRkKGksICdkYXknKS5mb3JtYXQoJ1lZWVktTU0tREQnKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBzcGVjaWZpYyB3ZWVrZGF5cyBmcm9tIHRoZSB3ZWVrIGNvbnRhaW5pbmcgdGhlIG9mZnNldCBkYXRlXG4gICAgICogQHBhcmFtIGRheU9mZnNldCAtIERheSBvZmZzZXQgZnJvbSBiYXNlIGRhdGVcbiAgICAgKiBAcGFyYW0gd29ya0RheXMgLSBBcnJheSBvZiBJU08gd2Vla2RheSBudW1iZXJzICgxPU1vbmRheSwgNz1TdW5kYXkpXG4gICAgICogQHJldHVybnMgQXJyYXkgb2YgZGF0ZSBzdHJpbmdzIGluIFlZWVktTU0tREQgZm9ybWF0XG4gICAgICovXG4gICAgZ2V0V29ya0RheXNGcm9tT2Zmc2V0KGRheU9mZnNldCwgd29ya0RheXMpIHtcbiAgICAgICAgLy8gR2V0IHRoZSBkYXRlIGF0IG9mZnNldCwgdGhlbiBmaW5kIGl0cyB3ZWVrJ3MgTW9uZGF5XG4gICAgICAgIGNvbnN0IHRhcmdldERhdGUgPSB0aGlzLmJhc2VEYXRlLmFkZChkYXlPZmZzZXQsICdkYXknKTtcbiAgICAgICAgY29uc3QgbW9uZGF5ID0gdGFyZ2V0RGF0ZS5zdGFydE9mKCd3ZWVrJykuYWRkKDEsICdkYXknKTtcbiAgICAgICAgcmV0dXJuIHdvcmtEYXlzLm1hcChpc29EYXkgPT4ge1xuICAgICAgICAgICAgLy8gSVNPOiAxPU1vbmRheSwgNz1TdW5kYXkgXHUyMTkyIGRheXMgZnJvbSBNb25kYXk6IDAtNlxuICAgICAgICAgICAgY29uc3QgZGF5c0Zyb21Nb25kYXkgPSBpc29EYXkgPT09IDcgPyA2IDogaXNvRGF5IC0gMTtcbiAgICAgICAgICAgIHJldHVybiBtb25kYXkuYWRkKGRheXNGcm9tTW9uZGF5LCAnZGF5JykuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBMZWdhY3kgbWV0aG9kcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICBnZXRXZWVrRGF0ZXMod2Vla09mZnNldCA9IDAsIGRheXMgPSA3KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERhdGVzRnJvbU9mZnNldCh3ZWVrT2Zmc2V0ICogNywgZGF5cyk7XG4gICAgfVxuICAgIGdldFdvcmtXZWVrRGF0ZXMod2Vla09mZnNldCwgd29ya0RheXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0V29ya0RheXNGcm9tT2Zmc2V0KHdlZWtPZmZzZXQgKiA3LCB3b3JrRGF5cyk7XG4gICAgfVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gRk9STUFUVElOR1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgZm9ybWF0VGltZShkYXRlLCBzaG93U2Vjb25kcyA9IGZhbHNlKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm4gPSBzaG93U2Vjb25kcyA/ICdISDptbTpzcycgOiAnSEg6bW0nO1xuICAgICAgICByZXR1cm4gZGF5anMoZGF0ZSkuZm9ybWF0KHBhdHRlcm4pO1xuICAgIH1cbiAgICBmb3JtYXRUaW1lUmFuZ2Uoc3RhcnQsIGVuZCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5mb3JtYXRUaW1lKHN0YXJ0KX0gLSAke3RoaXMuZm9ybWF0VGltZShlbmQpfWA7XG4gICAgfVxuICAgIGZvcm1hdERhdGUoZGF0ZSkge1xuICAgICAgICByZXR1cm4gZGF5anMoZGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG4gICAgfVxuICAgIGdldERhdGVLZXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xuICAgIH1cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIENPTFVNTiBLRVlcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGEgdW5pZm9ybSBjb2x1bW5LZXkgZnJvbSBncm91cGluZyBzZWdtZW50c1xuICAgICAqIEhhbmRsZXMgYW55IGNvbWJpbmF0aW9uIG9mIGRhdGUsIHJlc291cmNlLCB0ZWFtLCBldGMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGJ1aWxkQ29sdW1uS2V5KHsgZGF0ZTogJzIwMjUtMTItMDknIH0pIFx1MjE5MiBcIjIwMjUtMTItMDlcIlxuICAgICAqIGJ1aWxkQ29sdW1uS2V5KHsgZGF0ZTogJzIwMjUtMTItMDknLCByZXNvdXJjZTogJ0VNUDAwMScgfSkgXHUyMTkyIFwiMjAyNS0xMi0wOTpFTVAwMDFcIlxuICAgICAqL1xuICAgIGJ1aWxkQ29sdW1uS2V5KHNlZ21lbnRzKSB7XG4gICAgICAgIC8vIEFsd2F5cyBwdXQgZGF0ZSBmaXJzdCBpZiBwcmVzZW50LCB0aGVuIG90aGVyIHNlZ21lbnRzIGFscGhhYmV0aWNhbGx5XG4gICAgICAgIGNvbnN0IGRhdGUgPSBzZWdtZW50cy5kYXRlO1xuICAgICAgICBjb25zdCBvdGhlcnMgPSBPYmplY3QuZW50cmllcyhzZWdtZW50cylcbiAgICAgICAgICAgIC5maWx0ZXIoKFtrXSkgPT4gayAhPT0gJ2RhdGUnKVxuICAgICAgICAgICAgLnNvcnQoKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgICAgICAgICAubWFwKChbLCB2XSkgPT4gdik7XG4gICAgICAgIHJldHVybiBkYXRlID8gW2RhdGUsIC4uLm90aGVyc10uam9pbignOicpIDogb3RoZXJzLmpvaW4oJzonKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGFyc2UgYSBjb2x1bW5LZXkgYmFjayBpbnRvIHNlZ21lbnRzXG4gICAgICogQXNzdW1lcyBmb3JtYXQ6IFwiZGF0ZTpyZXNvdXJjZTouLi5cIiBvciBqdXN0IFwiZGF0ZVwiXG4gICAgICovXG4gICAgcGFyc2VDb2x1bW5LZXkoY29sdW1uS2V5KSB7XG4gICAgICAgIGNvbnN0IHBhcnRzID0gY29sdW1uS2V5LnNwbGl0KCc6Jyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRlOiBwYXJ0c1swXSxcbiAgICAgICAgICAgIHJlc291cmNlOiBwYXJ0c1sxXVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IGRhdGVLZXkgZnJvbSBjb2x1bW5LZXkgKGZpcnN0IHNlZ21lbnQpXG4gICAgICovXG4gICAgZ2V0RGF0ZUZyb21Db2x1bW5LZXkoY29sdW1uS2V5KSB7XG4gICAgICAgIHJldHVybiBjb2x1bW5LZXkuc3BsaXQoJzonKVswXTtcbiAgICB9XG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBUSU1FIENBTENVTEFUSU9OU1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdGltZVRvTWludXRlcyh0aW1lU3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHBhcnRzID0gdGltZVN0cmluZy5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xuICAgICAgICBjb25zdCBob3VycyA9IHBhcnRzWzBdIHx8IDA7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBwYXJ0c1sxXSB8fCAwO1xuICAgICAgICByZXR1cm4gaG91cnMgKiA2MCArIG1pbnV0ZXM7XG4gICAgfVxuICAgIG1pbnV0ZXNUb1RpbWUodG90YWxNaW51dGVzKSB7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0b3RhbE1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSB0b3RhbE1pbnV0ZXMgJSA2MDtcbiAgICAgICAgcmV0dXJuIGRheWpzKCkuaG91cihob3VycykubWludXRlKG1pbnV0ZXMpLmZvcm1hdCgnSEg6bW0nKTtcbiAgICB9XG4gICAgZ2V0TWludXRlc1NpbmNlTWlkbmlnaHQoZGF0ZSkge1xuICAgICAgICBjb25zdCBkID0gZGF5anMoZGF0ZSk7XG4gICAgICAgIHJldHVybiBkLmhvdXIoKSAqIDYwICsgZC5taW51dGUoKTtcbiAgICB9XG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBVVEMgQ09OVkVSU0lPTlNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHRvVVRDKGxvY2FsRGF0ZSkge1xuICAgICAgICByZXR1cm4gZGF5anMudHoobG9jYWxEYXRlLCB0aGlzLnRpbWV6b25lKS51dGMoKS50b0lTT1N0cmluZygpO1xuICAgIH1cbiAgICBmcm9tVVRDKHV0Y1N0cmluZykge1xuICAgICAgICByZXR1cm4gZGF5anMudXRjKHV0Y1N0cmluZykudHoodGhpcy50aW1lem9uZSkudG9EYXRlKCk7XG4gICAgfVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gREFURSBDUkVBVElPTlxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgY3JlYXRlRGF0ZUF0VGltZShiYXNlRGF0ZSwgdGltZVN0cmluZykge1xuICAgICAgICBjb25zdCB0b3RhbE1pbnV0ZXMgPSB0aGlzLnRpbWVUb01pbnV0ZXModGltZVN0cmluZyk7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0b3RhbE1pbnV0ZXMgLyA2MCk7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSB0b3RhbE1pbnV0ZXMgJSA2MDtcbiAgICAgICAgcmV0dXJuIGRheWpzKGJhc2VEYXRlKS5zdGFydE9mKCdkYXknKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykudG9EYXRlKCk7XG4gICAgfVxuICAgIGdldElTT1dlZWtEYXkoZGF0ZSkge1xuICAgICAgICByZXR1cm4gZGF5anMoZGF0ZSkuaXNvV2Vla2RheSgpOyAvLyAxPU1vbmRheSwgNz1TdW5kYXlcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBncm91cGluZyByZW5kZXJlcnNcbiAqXG4gKiBIYW5kbGVzOlxuICogLSBGZXRjaGluZyBlbnRpdGllcyBieSBJRHNcbiAqIC0gQ2FsY3VsYXRpbmcgY29sc3BhbiBmcm9tIHBhcmVudENoaWxkTWFwXG4gKiAtIENyZWF0aW5nIGhlYWRlciBlbGVtZW50c1xuICogLSBBcHBlbmRpbmcgdG8gY29udGFpbmVyXG4gKlxuICogU3ViY2xhc3NlcyBvdmVycmlkZTpcbiAqIC0gcmVuZGVySGVhZGVyKCkgZm9yIGN1c3RvbSBjb250ZW50XG4gKiAtIGdldERpc3BsYXlOYW1lKCkgZm9yIGVudGl0eSBkaXNwbGF5IHRleHRcbiAqL1xuZXhwb3J0IGNsYXNzIEJhc2VHcm91cGluZ1JlbmRlcmVyIHtcbiAgICAvKipcbiAgICAgKiBNYWluIHJlbmRlciBtZXRob2QgLSBoYW5kbGVzIGNvbW1vbiBsb2dpY1xuICAgICAqL1xuICAgIGFzeW5jIHJlbmRlcihjb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IGFsbG93ZWRJZHMgPSBjb250ZXh0LmZpbHRlclt0aGlzLnR5cGVdIHx8IFtdO1xuICAgICAgICBpZiAoYWxsb3dlZElkcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGVudGl0aWVzID0gYXdhaXQgdGhpcy5nZXRFbnRpdGllcyhhbGxvd2VkSWRzKTtcbiAgICAgICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XG4gICAgICAgIGNvbnN0IGNoaWxkSWRzID0gY29udGV4dC5jaGlsZFR5cGUgPyBjb250ZXh0LmZpbHRlcltjb250ZXh0LmNoaWxkVHlwZV0gfHwgW10gOiBbXTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eUNoaWxkSWRzID0gY29udGV4dC5wYXJlbnRDaGlsZE1hcD8uW2VudGl0eS5pZF0gfHwgW107XG4gICAgICAgICAgICBjb25zdCBjaGlsZENvdW50ID0gZW50aXR5Q2hpbGRJZHMuZmlsdGVyKGlkID0+IGNoaWxkSWRzLmluY2x1ZGVzKGlkKSkubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgY29sc3BhbiA9IGNoaWxkQ291bnQgKiBkYXRlQ291bnQ7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xuICAgICAgICAgICAgaGVhZGVyLmRhdGFzZXRbdGhpcy5jb25maWcuaWRBdHRyaWJ1dGVdID0gZW50aXR5LmlkO1xuICAgICAgICAgICAgaGVhZGVyLnN0eWxlLnNldFByb3BlcnR5KHRoaXMuY29uZmlnLmNvbHNwYW5WYXIsIFN0cmluZyhjb2xzcGFuKSk7XG4gICAgICAgICAgICAvLyBBbGxvdyBzdWJjbGFzcyB0byBjdXN0b21pemUgaGVhZGVyIGNvbnRlbnRcbiAgICAgICAgICAgIHRoaXMucmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGN1c3RvbSBoZWFkZXIgcmVuZGVyaW5nXG4gICAgICogRGVmYXVsdDoganVzdCBzZXRzIHRleHRDb250ZW50IHRvIGRpc3BsYXkgbmFtZVxuICAgICAqL1xuICAgIHJlbmRlckhlYWRlcihlbnRpdHksIGhlYWRlciwgX2NvbnRleHQpIHtcbiAgICAgICAgaGVhZGVyLnRleHRDb250ZW50ID0gdGhpcy5nZXREaXNwbGF5TmFtZShlbnRpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgdG8gcmVuZGVyIGEgc2luZ2xlIGVudGl0eSBoZWFkZXIuXG4gICAgICogQ2FuIGJlIHVzZWQgYnkgc3ViY2xhc3NlcyB0aGF0IG92ZXJyaWRlIHJlbmRlcigpIGJ1dCB3YW50IGNvbnNpc3RlbnQgaGVhZGVyIGNyZWF0aW9uLlxuICAgICAqL1xuICAgIGNyZWF0ZUhlYWRlcihlbnRpdHksIGNvbnRleHQpIHtcbiAgICAgICAgY29uc3QgaGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmNvbmZpZy5lbGVtZW50VGFnKTtcbiAgICAgICAgaGVhZGVyLmRhdGFzZXRbdGhpcy5jb25maWcuaWRBdHRyaWJ1dGVdID0gZW50aXR5LmlkO1xuICAgICAgICB0aGlzLnJlbmRlckhlYWRlcihlbnRpdHksIGhlYWRlciwgY29udGV4dCk7XG4gICAgICAgIHJldHVybiBoZWFkZXI7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyIH0gZnJvbSAnLi4vLi4vY29yZS9CYXNlR3JvdXBpbmdSZW5kZXJlcic7XG5leHBvcnQgY2xhc3MgUmVzb3VyY2VSZW5kZXJlciBleHRlbmRzIEJhc2VHcm91cGluZ1JlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihyZXNvdXJjZVNlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5yZXNvdXJjZVNlcnZpY2UgPSByZXNvdXJjZVNlcnZpY2U7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyZXNvdXJjZSc7XG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgZWxlbWVudFRhZzogJ3N3cC1yZXNvdXJjZS1oZWFkZXInLFxuICAgICAgICAgICAgaWRBdHRyaWJ1dGU6ICdyZXNvdXJjZUlkJyxcbiAgICAgICAgICAgIGNvbHNwYW5WYXI6ICctLXJlc291cmNlLWNvbHMnXG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldEVudGl0aWVzKGlkcykge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNvdXJjZVNlcnZpY2UuZ2V0QnlJZHMoaWRzKTtcbiAgICB9XG4gICAgZ2V0RGlzcGxheU5hbWUoZW50aXR5KSB7XG4gICAgICAgIHJldHVybiBlbnRpdHkuZGlzcGxheU5hbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHJlbmRlciB0byBoYW5kbGU6XG4gICAgICogMS4gU3BlY2lhbCBvcmRlcmluZyB3aGVuIHBhcmVudENoaWxkTWFwIGV4aXN0cyAocmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50KVxuICAgICAqIDIuIERpZmZlcmVudCBjb2xzcGFuIGNhbGN1bGF0aW9uIChqdXN0IGRhdGVDb3VudCwgbm90IGNoaWxkQ291bnQgKiBkYXRlQ291bnQpXG4gICAgICovXG4gICAgYXN5bmMgcmVuZGVyKGNvbnRleHQpIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VJZHMgPSBjb250ZXh0LmZpbHRlclsncmVzb3VyY2UnXSB8fCBbXTtcbiAgICAgICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XG4gICAgICAgIC8vIERldGVybWluZSByZW5kZXIgb3JkZXIgYmFzZWQgb24gcGFyZW50Q2hpbGRNYXBcbiAgICAgICAgLy8gSWYgcGFyZW50Q2hpbGRNYXAgZXhpc3RzLCByZW5kZXIgcmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50IChlLmcuLCB0ZWFtKVxuICAgICAgICAvLyBPdGhlcndpc2UsIHJlbmRlciBpbiBmaWx0ZXIgb3JkZXJcbiAgICAgICAgbGV0IG9yZGVyZWRSZXNvdXJjZUlkcztcbiAgICAgICAgaWYgKGNvbnRleHQucGFyZW50Q2hpbGRNYXApIHtcbiAgICAgICAgICAgIC8vIFJlbmRlciByZXNvdXJjZXMgaW4gcGFyZW50LWNoaWxkIG9yZGVyXG4gICAgICAgICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2hpbGRJZHMgb2YgT2JqZWN0LnZhbHVlcyhjb250ZXh0LnBhcmVudENoaWxkTWFwKSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY2hpbGRJZCBvZiBjaGlsZElkcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2VJZHMuaW5jbHVkZXMoY2hpbGRJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWRSZXNvdXJjZUlkcy5wdXNoKGNoaWxkSWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb3JkZXJlZFJlc291cmNlSWRzID0gcmVzb3VyY2VJZHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzb3VyY2VzID0gYXdhaXQgdGhpcy5nZXRFbnRpdGllcyhvcmRlcmVkUmVzb3VyY2VJZHMpO1xuICAgICAgICAvLyBDcmVhdGUgYSBtYXAgZm9yIHF1aWNrIGxvb2t1cCB0byBwcmVzZXJ2ZSBvcmRlclxuICAgICAgICBjb25zdCByZXNvdXJjZU1hcCA9IG5ldyBNYXAocmVzb3VyY2VzLm1hcChyID0+IFtyLmlkLCByXSkpO1xuICAgICAgICBmb3IgKGNvbnN0IHJlc291cmNlSWQgb2Ygb3JkZXJlZFJlc291cmNlSWRzKSB7XG4gICAgICAgICAgICBjb25zdCByZXNvdXJjZSA9IHJlc291cmNlTWFwLmdldChyZXNvdXJjZUlkKTtcbiAgICAgICAgICAgIGlmICghcmVzb3VyY2UpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXIgPSB0aGlzLmNyZWF0ZUhlYWRlcihyZXNvdXJjZSwgY29udGV4dCk7XG4gICAgICAgICAgICBoZWFkZXIuc3R5bGUuZ3JpZENvbHVtbiA9IGBzcGFuICR7ZGF0ZUNvdW50fWA7XG4gICAgICAgICAgICBjb250ZXh0LmhlYWRlckNvbnRhaW5lci5hcHBlbmRDaGlsZChoZWFkZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyIH0gZnJvbSAnLi4vLi4vY29yZS9CYXNlR3JvdXBpbmdSZW5kZXJlcic7XG5leHBvcnQgY2xhc3MgVGVhbVJlbmRlcmVyIGV4dGVuZHMgQmFzZUdyb3VwaW5nUmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKHRlYW1TZXJ2aWNlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMudGVhbVNlcnZpY2UgPSB0ZWFtU2VydmljZTtcbiAgICAgICAgdGhpcy50eXBlID0gJ3RlYW0nO1xuICAgICAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgICAgICAgIGVsZW1lbnRUYWc6ICdzd3AtdGVhbS1oZWFkZXInLFxuICAgICAgICAgICAgaWRBdHRyaWJ1dGU6ICd0ZWFtSWQnLFxuICAgICAgICAgICAgY29sc3BhblZhcjogJy0tdGVhbS1jb2xzJ1xuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXRFbnRpdGllcyhpZHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVhbVNlcnZpY2UuZ2V0QnlJZHMoaWRzKTtcbiAgICB9XG4gICAgZ2V0RGlzcGxheU5hbWUoZW50aXR5KSB7XG4gICAgICAgIHJldHVybiBlbnRpdHkubmFtZTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQmFzZUdyb3VwaW5nUmVuZGVyZXIgfSBmcm9tICcuLi8uLi9jb3JlL0Jhc2VHcm91cGluZ1JlbmRlcmVyJztcbmV4cG9ydCBjbGFzcyBEZXBhcnRtZW50UmVuZGVyZXIgZXh0ZW5kcyBCYXNlR3JvdXBpbmdSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3IoZGVwYXJ0bWVudFNlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5kZXBhcnRtZW50U2VydmljZSA9IGRlcGFydG1lbnRTZXJ2aWNlO1xuICAgICAgICB0aGlzLnR5cGUgPSAnZGVwYXJ0bWVudCc7XG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgZWxlbWVudFRhZzogJ3N3cC1kZXBhcnRtZW50LWhlYWRlcicsXG4gICAgICAgICAgICBpZEF0dHJpYnV0ZTogJ2RlcGFydG1lbnRJZCcsXG4gICAgICAgICAgICBjb2xzcGFuVmFyOiAnLS1kZXBhcnRtZW50LWNvbHMnXG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldEVudGl0aWVzKGlkcykge1xuICAgICAgICByZXR1cm4gdGhpcy5kZXBhcnRtZW50U2VydmljZS5nZXRCeUlkcyhpZHMpO1xuICAgIH1cbiAgICBnZXREaXNwbGF5TmFtZShlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eS5uYW1lO1xuICAgIH1cbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gYnVpbGRQaXBlbGluZShyZW5kZXJlcnMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBhc3luYyBydW4oY29udGV4dCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCByZW5kZXJlciBvZiByZW5kZXJlcnMpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJlci5yZW5kZXIoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufVxuIiwgIi8qKlxuICogRmlsdGVyVGVtcGxhdGUgLSBCeWdnZXIgblx1MDBGOGdsZXIgdGlsIGV2ZW50LWtvbG9ubmUgbWF0Y2hpbmdcbiAqXG4gKiBWaWV3Q29uZmlnIGRlZmluZXJlciBodmlsa2UgZmVsdGVyIChpZFByb3BlcnRpZXMpIGRlciBpbmRnXHUwMEU1ciBpIGtvbG9ubmVucyBuXHUwMEY4Z2xlLlxuICogU2FtbWUgdGVtcGxhdGUgYnJ1Z2VzIHRpbCBhdCBieWdnZSBuXHUwMEY4Z2xlIGZvciBiXHUwMEU1ZGUga29sb25uZSBvZyBldmVudC5cbiAqXG4gKiBTdXBwb3J0cyBkb3Qtbm90YXRpb24gZm9yIGhpZXJhcmNoaWNhbCByZWxhdGlvbnM6XG4gKiAtICdyZXNvdXJjZS50ZWFtSWQnIFx1MjE5MiBsb29rcyB1cCBldmVudC5yZXNvdXJjZUlkIFx1MjE5MiByZXNvdXJjZSBlbnRpdHkgXHUyMTkyIHRlYW1JZFxuICpcbiAqIFByaW5jaXA6IEtvbG9ubmVucyBuXHUwMEY4Z2xlLXRlbXBsYXRlIGJlc3RlbW1lciBodmFkIGRlciBtYXRjaGVzIHBcdTAwRTUuXG4gKlxuICogQHNlZSBkb2NzL2ZpbHRlci10ZW1wbGF0ZS5tZFxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyVGVtcGxhdGUge1xuICAgIGNvbnN0cnVjdG9yKGRhdGVTZXJ2aWNlLCBlbnRpdHlSZXNvbHZlcikge1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuZW50aXR5UmVzb2x2ZXIgPSBlbnRpdHlSZXNvbHZlcjtcbiAgICAgICAgdGhpcy5maWVsZHMgPSBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGlsZlx1MDBGOGogZmVsdCB0aWwgdGVtcGxhdGVcbiAgICAgKiBAcGFyYW0gaWRQcm9wZXJ0eSAtIFByb3BlcnR5LW5hdm4gKGJydWdlcyBwXHUwMEU1IGJcdTAwRTVkZSBldmVudCBvZyBjb2x1bW4uZGF0YXNldClcbiAgICAgKiBAcGFyYW0gZGVyaXZlZEZyb20gLSBIdmlzIGZlbHRldCB1ZGxlZGVzIGZyYSBhbmRlbiBwcm9wZXJ0eSAoZi5la3MuIGRhdGUgZnJhIHN0YXJ0KVxuICAgICAqL1xuICAgIGFkZEZpZWxkKGlkUHJvcGVydHksIGRlcml2ZWRGcm9tKSB7XG4gICAgICAgIHRoaXMuZmllbGRzLnB1c2goeyBpZFByb3BlcnR5LCBkZXJpdmVkRnJvbSB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhcnNlIGRvdC1ub3RhdGlvbiBzdHJpbmcgaW50byBjb21wb25lbnRzXG4gICAgICogQGV4YW1wbGUgJ3Jlc291cmNlLnRlYW1JZCcgXHUyMTkyIHsgZW50aXR5VHlwZTogJ3Jlc291cmNlJywgcHJvcGVydHk6ICd0ZWFtSWQnLCBmb3JlaWduS2V5OiAncmVzb3VyY2VJZCcgfVxuICAgICAqL1xuICAgIHBhcnNlRG90Tm90YXRpb24oaWRQcm9wZXJ0eSkge1xuICAgICAgICBpZiAoIWlkUHJvcGVydHkuaW5jbHVkZXMoJy4nKSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjb25zdCBbZW50aXR5VHlwZSwgcHJvcGVydHldID0gaWRQcm9wZXJ0eS5zcGxpdCgnLicpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW50aXR5VHlwZSxcbiAgICAgICAgICAgIHByb3BlcnR5LFxuICAgICAgICAgICAgZm9yZWlnbktleTogZW50aXR5VHlwZSArICdJZCcgLy8gQ29udmVudGlvbjogcmVzb3VyY2UgXHUyMTkyIHJlc291cmNlSWRcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGRhdGFzZXQga2V5IGZvciBjb2x1bW4gbG9va3VwXG4gICAgICogRm9yIGRvdC1ub3RhdGlvbiAncmVzb3VyY2UudGVhbUlkJywgd2UgbG9vayBmb3IgJ3RlYW1JZCcgaW4gZGF0YXNldFxuICAgICAqL1xuICAgIGdldERhdGFzZXRLZXkoaWRQcm9wZXJ0eSkge1xuICAgICAgICBjb25zdCBkb3ROb3RhdGlvbiA9IHRoaXMucGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5KTtcbiAgICAgICAgaWYgKGRvdE5vdGF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gZG90Tm90YXRpb24ucHJvcGVydHk7IC8vICd0ZWFtSWQnXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlkUHJvcGVydHk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJ5ZyBuXHUwMEY4Z2xlIGZyYSBrb2xvbm5lXG4gICAgICogTFx1MDBFNnNlciB2XHUwMEU2cmRpZXIgZnJhIGNvbHVtbi5kYXRhc2V0W2lkUHJvcGVydHldXG4gICAgICogRm9yIGRvdC1ub3RhdGlvbiwgdXNlcyB0aGUgcHJvcGVydHkgcGFydCAocmVzb3VyY2UudGVhbUlkIFx1MjE5MiB0ZWFtSWQpXG4gICAgICovXG4gICAgYnVpbGRLZXlGcm9tQ29sdW1uKGNvbHVtbikge1xuICAgICAgICByZXR1cm4gdGhpcy5maWVsZHNcbiAgICAgICAgICAgIC5tYXAoZiA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmdldERhdGFzZXRLZXkoZi5pZFByb3BlcnR5KTtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW4uZGF0YXNldFtrZXldIHx8ICcnO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJzonKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQnlnIG5cdTAwRjhnbGUgZnJhIGV2ZW50XG4gICAgICogTFx1MDBFNnNlciB2XHUwMEU2cmRpZXIgZnJhIGV2ZW50W2lkUHJvcGVydHldIGVsbGVyIHVkbGVkZXIgZnJhIGRlcml2ZWRGcm9tXG4gICAgICogRm9yIGRvdC1ub3RhdGlvbiwgcmVzb2x2ZXMgdmlhIEVudGl0eVJlc29sdmVyXG4gICAgICovXG4gICAgYnVpbGRLZXlGcm9tRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgY29uc3QgZXZlbnRSZWNvcmQgPSBldmVudDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmllbGRzXG4gICAgICAgICAgICAubWFwKGYgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGRvdC1ub3RhdGlvbiAoZS5nLiwgJ3Jlc291cmNlLnRlYW1JZCcpXG4gICAgICAgICAgICBjb25zdCBkb3ROb3RhdGlvbiA9IHRoaXMucGFyc2VEb3ROb3RhdGlvbihmLmlkUHJvcGVydHkpO1xuICAgICAgICAgICAgaWYgKGRvdE5vdGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZURvdE5vdGF0aW9uKGV2ZW50UmVjb3JkLCBkb3ROb3RhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZi5kZXJpdmVkRnJvbSkge1xuICAgICAgICAgICAgICAgIC8vIFVkbGVkIHZcdTAwRTZyZGkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IGV2ZW50UmVjb3JkW2YuZGVyaXZlZEZyb21dO1xuICAgICAgICAgICAgICAgIGlmIChzb3VyY2VWYWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF0ZUtleShzb3VyY2VWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcoc291cmNlVmFsdWUgfHwgJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhldmVudFJlY29yZFtmLmlkUHJvcGVydHldIHx8ICcnKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKCc6Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgZG90LW5vdGF0aW9uIHJlZmVyZW5jZSB2aWEgRW50aXR5UmVzb2x2ZXJcbiAgICAgKi9cbiAgICByZXNvbHZlRG90Tm90YXRpb24oZXZlbnRSZWNvcmQsIGRvdE5vdGF0aW9uKSB7XG4gICAgICAgIGlmICghdGhpcy5lbnRpdHlSZXNvbHZlcikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBGaWx0ZXJUZW1wbGF0ZTogRW50aXR5UmVzb2x2ZXIgcmVxdWlyZWQgZm9yIGRvdC1ub3RhdGlvbiAnJHtkb3ROb3RhdGlvbi5lbnRpdHlUeXBlfS4ke2RvdE5vdGF0aW9uLnByb3BlcnR5fSdgKTtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgICAgICAvLyBHZXQgZm9yZWlnbiBrZXkgdmFsdWUgZnJvbSBldmVudCAoZS5nLiwgcmVzb3VyY2VJZClcbiAgICAgICAgY29uc3QgZm9yZWlnbklkID0gZXZlbnRSZWNvcmRbZG90Tm90YXRpb24uZm9yZWlnbktleV07XG4gICAgICAgIGlmICghZm9yZWlnbklkKVxuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICAvLyBSZXNvbHZlIGVudGl0eVxuICAgICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmVudGl0eVJlc29sdmVyLnJlc29sdmUoZG90Tm90YXRpb24uZW50aXR5VHlwZSwgU3RyaW5nKGZvcmVpZ25JZCkpO1xuICAgICAgICBpZiAoIWVudGl0eSlcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgLy8gUmV0dXJuIHByb3BlcnR5IHZhbHVlIGZyb20gZW50aXR5XG4gICAgICAgIHJldHVybiBTdHJpbmcoZW50aXR5W2RvdE5vdGF0aW9uLnByb3BlcnR5XSB8fCAnJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1hdGNoIGV2ZW50IG1vZCBrb2xvbm5lXG4gICAgICovXG4gICAgbWF0Y2hlcyhldmVudCwgY29sdW1uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkS2V5RnJvbUV2ZW50KGV2ZW50KSA9PT0gdGhpcy5idWlsZEtleUZyb21Db2x1bW4oY29sdW1uKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgYnVpbGRQaXBlbGluZSB9IGZyb20gJy4vUmVuZGVyQnVpbGRlcic7XG5pbXBvcnQgeyBGaWx0ZXJUZW1wbGF0ZSB9IGZyb20gJy4vRmlsdGVyVGVtcGxhdGUnO1xuZXhwb3J0IGNsYXNzIENhbGVuZGFyT3JjaGVzdHJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcihhbGxSZW5kZXJlcnMsIGV2ZW50UmVuZGVyZXIsIHNjaGVkdWxlUmVuZGVyZXIsIGhlYWRlckRyYXdlclJlbmRlcmVyLCBkYXRlU2VydmljZSwgZW50aXR5U2VydmljZXMpIHtcbiAgICAgICAgdGhpcy5hbGxSZW5kZXJlcnMgPSBhbGxSZW5kZXJlcnM7XG4gICAgICAgIHRoaXMuZXZlbnRSZW5kZXJlciA9IGV2ZW50UmVuZGVyZXI7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVSZW5kZXJlciA9IHNjaGVkdWxlUmVuZGVyZXI7XG4gICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyUmVuZGVyZXIgPSBoZWFkZXJEcmF3ZXJSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLmVudGl0eVNlcnZpY2VzID0gZW50aXR5U2VydmljZXM7XG4gICAgfVxuICAgIGFzeW5jIHJlbmRlcih2aWV3Q29uZmlnLCBjb250YWluZXIpIHtcbiAgICAgICAgY29uc3QgaGVhZGVyQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1jYWxlbmRhci1oZWFkZXInKTtcbiAgICAgICAgY29uc3QgY29sdW1uQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpO1xuICAgICAgICBpZiAoIWhlYWRlckNvbnRhaW5lciB8fCAhY29sdW1uQ29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc3dwLWNhbGVuZGFyLWhlYWRlciBvciBzd3AtZGF5LWNvbHVtbnMnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCeWcgZmlsdGVyIGZyYSB2aWV3Q29uZmlnXG4gICAgICAgIGNvbnN0IGZpbHRlciA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwaW5nIG9mIHZpZXdDb25maWcuZ3JvdXBpbmdzKSB7XG4gICAgICAgICAgICBmaWx0ZXJbZ3JvdXBpbmcudHlwZV0gPSBncm91cGluZy52YWx1ZXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnlnIEZpbHRlclRlbXBsYXRlIGZyYSB2aWV3Q29uZmlnIGdyb3VwaW5ncyAoa3VuIGRlIG1lZCBpZFByb3BlcnR5KVxuICAgICAgICBjb25zdCBmaWx0ZXJUZW1wbGF0ZSA9IG5ldyBGaWx0ZXJUZW1wbGF0ZSh0aGlzLmRhdGVTZXJ2aWNlKTtcbiAgICAgICAgZm9yIChjb25zdCBncm91cGluZyBvZiB2aWV3Q29uZmlnLmdyb3VwaW5ncykge1xuICAgICAgICAgICAgaWYgKGdyb3VwaW5nLmlkUHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJUZW1wbGF0ZS5hZGRGaWVsZChncm91cGluZy5pZFByb3BlcnR5LCBncm91cGluZy5kZXJpdmVkRnJvbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzb2x2ZSBiZWxvbmdzVG8gcmVsYXRpb25zIChlLmcuLCB0ZWFtLnJlc291cmNlSWRzKVxuICAgICAgICBjb25zdCB7IHBhcmVudENoaWxkTWFwLCBjaGlsZFR5cGUgfSA9IGF3YWl0IHRoaXMucmVzb2x2ZUJlbG9uZ3NUbyh2aWV3Q29uZmlnLmdyb3VwaW5ncywgZmlsdGVyKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHsgaGVhZGVyQ29udGFpbmVyLCBjb2x1bW5Db250YWluZXIsIGZpbHRlciwgZ3JvdXBpbmdzOiB2aWV3Q29uZmlnLmdyb3VwaW5ncywgcGFyZW50Q2hpbGRNYXAsIGNoaWxkVHlwZSB9O1xuICAgICAgICAvLyBDbGVhclxuICAgICAgICBoZWFkZXJDb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIGNvbHVtbkNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgLy8gU1x1MDBFNnQgZGF0YS1sZXZlbHMgYXR0cmlidXQgZm9yIENTUyBncmlkLXJvdyBzdHlsaW5nXG4gICAgICAgIGNvbnN0IGxldmVscyA9IHZpZXdDb25maWcuZ3JvdXBpbmdzLm1hcChnID0+IGcudHlwZSkuam9pbignICcpO1xuICAgICAgICBoZWFkZXJDb250YWluZXIuZGF0YXNldC5sZXZlbHMgPSBsZXZlbHM7XG4gICAgICAgIC8vIFZcdTAwRTZsZyByZW5kZXJlcnMgYmFzZXJldCBwXHUwMEU1IGdyb3VwaW5ncyB0eXBlc1xuICAgICAgICBjb25zdCBhY3RpdmVSZW5kZXJlcnMgPSB0aGlzLnNlbGVjdFJlbmRlcmVycyh2aWV3Q29uZmlnKTtcbiAgICAgICAgLy8gQnlnIG9nIGtcdTAwRjhyIHBpcGVsaW5lXG4gICAgICAgIGNvbnN0IHBpcGVsaW5lID0gYnVpbGRQaXBlbGluZShhY3RpdmVSZW5kZXJlcnMpO1xuICAgICAgICBhd2FpdCBwaXBlbGluZS5ydW4oY29udGV4dCk7XG4gICAgICAgIC8vIFJlbmRlciBzY2hlZHVsZSB1bmF2YWlsYWJsZSB6b25lcyAoZlx1MDBGOHIgZXZlbnRzKVxuICAgICAgICBhd2FpdCB0aGlzLnNjaGVkdWxlUmVuZGVyZXIucmVuZGVyKGNvbnRhaW5lciwgZmlsdGVyKTtcbiAgICAgICAgLy8gUmVuZGVyIHRpbWVkIGV2ZW50cyBpbiBncmlkIChtZWQgZmlsdGVyVGVtcGxhdGUgdGlsIG1hdGNoaW5nKVxuICAgICAgICBhd2FpdCB0aGlzLmV2ZW50UmVuZGVyZXIucmVuZGVyKGNvbnRhaW5lciwgZmlsdGVyLCBmaWx0ZXJUZW1wbGF0ZSk7XG4gICAgICAgIC8vIFJlbmRlciBhbGxEYXkgZXZlbnRzIGluIGhlYWRlciBkcmF3ZXIgKG1lZCBmaWx0ZXJUZW1wbGF0ZSB0aWwgbWF0Y2hpbmcpXG4gICAgICAgIGF3YWl0IHRoaXMuaGVhZGVyRHJhd2VyUmVuZGVyZXIucmVuZGVyKGNvbnRhaW5lciwgZmlsdGVyLCBmaWx0ZXJUZW1wbGF0ZSk7XG4gICAgfVxuICAgIHNlbGVjdFJlbmRlcmVycyh2aWV3Q29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKTtcbiAgICAgICAgLy8gU29ydFx1MDBFOXIgcmVuZGVyZXJzIGkgc2FtbWUgclx1MDBFNmtrZWZcdTAwRjhsZ2Ugc29tIHZpZXdDb25maWcuZ3JvdXBpbmdzXG4gICAgICAgIHJldHVybiB0eXBlc1xuICAgICAgICAgICAgLm1hcCh0eXBlID0+IHRoaXMuYWxsUmVuZGVyZXJzLmZpbmQociA9PiByLnR5cGUgPT09IHR5cGUpKVxuICAgICAgICAgICAgLmZpbHRlcigocikgPT4gciAhPT0gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzb2x2ZSBiZWxvbmdzVG8gcmVsYXRpb25zIHRvIGJ1aWxkIHBhcmVudC1jaGlsZCBtYXBcbiAgICAgKiBlLmcuLCBiZWxvbmdzVG86ICd0ZWFtLnJlc291cmNlSWRzJyBcdTIxOTIgeyB0ZWFtMTogWydFTVAwMDEnLCAnRU1QMDAyJ10sIHRlYW0yOiBbLi4uXSB9XG4gICAgICogQWxzbyByZXR1cm5zIHRoZSBjaGlsZFR5cGUgKHRoZSBncm91cGluZyB0eXBlIHRoYXQgaGFzIGJlbG9uZ3NUbylcbiAgICAgKi9cbiAgICBhc3luYyByZXNvbHZlQmVsb25nc1RvKGdyb3VwaW5ncywgZmlsdGVyKSB7XG4gICAgICAgIC8vIEZpbmQgZ3JvdXBpbmcgd2l0aCBiZWxvbmdzVG9cbiAgICAgICAgY29uc3QgY2hpbGRHcm91cGluZyA9IGdyb3VwaW5ncy5maW5kKGcgPT4gZy5iZWxvbmdzVG8pO1xuICAgICAgICBpZiAoIWNoaWxkR3JvdXBpbmc/LmJlbG9uZ3NUbylcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgLy8gUGFyc2UgYmVsb25nc1RvOiAndGVhbS5yZXNvdXJjZUlkcydcbiAgICAgICAgY29uc3QgW2VudGl0eVR5cGUsIHByb3BlcnR5XSA9IGNoaWxkR3JvdXBpbmcuYmVsb25nc1RvLnNwbGl0KCcuJyk7XG4gICAgICAgIGlmICghZW50aXR5VHlwZSB8fCAhcHJvcGVydHkpXG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIC8vIEdldCBwYXJlbnQgSURzIGZyb20gZmlsdGVyXG4gICAgICAgIGNvbnN0IHBhcmVudElkcyA9IGZpbHRlcltlbnRpdHlUeXBlXSB8fCBbXTtcbiAgICAgICAgaWYgKHBhcmVudElkcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIC8vIEZpbmQgc2VydmljZSBkeW5hbWlzayBiYXNlcmV0IHBcdTAwRTUgZW50aXR5VHlwZSAoaW5nZW4gaGFyZGNvZGVkIHR5cGUgY2hlY2spXG4gICAgICAgIGNvbnN0IHNlcnZpY2UgPSB0aGlzLmVudGl0eVNlcnZpY2VzLmZpbmQocyA9PiBzLmVudGl0eVR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZW50aXR5VHlwZSk7XG4gICAgICAgIGlmICghc2VydmljZSlcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgLy8gSGVudCBhbGxlIGVudGl0aWVzIG9nIGZpbHRyZXIgcFx1MDBFNSBwYXJlbnRJZHNcbiAgICAgICAgY29uc3QgYWxsRW50aXRpZXMgPSBhd2FpdCBzZXJ2aWNlLmdldEFsbCgpO1xuICAgICAgICBjb25zdCBlbnRpdGllcyA9IGFsbEVudGl0aWVzLmZpbHRlcihlID0+IHBhcmVudElkcy5pbmNsdWRlcyhlLmlkKSk7XG4gICAgICAgIC8vIEJ5ZyBwYXJlbnQtY2hpbGQgbWFwXG4gICAgICAgIGNvbnN0IG1hcCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5UmVjb3JkID0gZW50aXR5O1xuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBlbnRpdHlSZWNvcmRbcHJvcGVydHldIHx8IFtdO1xuICAgICAgICAgICAgbWFwW2VudGl0eVJlY29yZC5pZF0gPSBjaGlsZHJlbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBwYXJlbnRDaGlsZE1hcDogbWFwLCBjaGlsZFR5cGU6IGNoaWxkR3JvdXBpbmcudHlwZSB9O1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgTmF2aWdhdGlvbkFuaW1hdG9yIHtcbiAgICBjb25zdHJ1Y3RvcihoZWFkZXJUcmFjaywgY29udGVudFRyYWNrLCBoZWFkZXJEcmF3ZXIpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJUcmFjayA9IGhlYWRlclRyYWNrO1xuICAgICAgICB0aGlzLmNvbnRlbnRUcmFjayA9IGNvbnRlbnRUcmFjaztcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIgPSBoZWFkZXJEcmF3ZXI7XG4gICAgfVxuICAgIGFzeW5jIHNsaWRlKGRpcmVjdGlvbiwgcmVuZGVyRm4pIHtcbiAgICAgICAgY29uc3Qgb3V0ID0gZGlyZWN0aW9uID09PSAnbGVmdCcgPyAnLTEwMCUnIDogJzEwMCUnO1xuICAgICAgICBjb25zdCBpbnRvID0gZGlyZWN0aW9uID09PSAnbGVmdCcgPyAnMTAwJScgOiAnLTEwMCUnO1xuICAgICAgICBhd2FpdCB0aGlzLmFuaW1hdGVPdXQob3V0KTtcbiAgICAgICAgYXdhaXQgcmVuZGVyRm4oKTtcbiAgICAgICAgYXdhaXQgdGhpcy5hbmltYXRlSW4oaW50byk7XG4gICAgfVxuICAgIGFzeW5jIGFuaW1hdGVPdXQodHJhbnNsYXRlKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXG4gICAgICAgICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoW3sgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfSwgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH1dLCB7IGR1cmF0aW9uOiAyMDAsIGVhc2luZzogJ2Vhc2UtaW4nIH0pLmZpbmlzaGVkLFxuICAgICAgICAgICAgdGhpcy5jb250ZW50VHJhY2suYW5pbWF0ZShbeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9LCB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfV0sIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfSkuZmluaXNoZWRcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKHRoaXMuaGVhZGVyRHJhd2VyKSB7XG4gICAgICAgICAgICBhbmltYXRpb25zLnB1c2godGhpcy5oZWFkZXJEcmF3ZXIuYW5pbWF0ZShbeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9LCB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfV0sIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfSkuZmluaXNoZWQpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGFuaW1hdGlvbnMpO1xuICAgIH1cbiAgICBhc3luYyBhbmltYXRlSW4odHJhbnNsYXRlKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXG4gICAgICAgICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoW3sgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9LCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH1dLCB7IGR1cmF0aW9uOiAyMDAsIGVhc2luZzogJ2Vhc2Utb3V0JyB9KS5maW5pc2hlZCxcbiAgICAgICAgICAgIHRoaXMuY29udGVudFRyYWNrLmFuaW1hdGUoW3sgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9LCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH1dLCB7IGR1cmF0aW9uOiAyMDAsIGVhc2luZzogJ2Vhc2Utb3V0JyB9KS5maW5pc2hlZFxuICAgICAgICBdO1xuICAgICAgICBpZiAodGhpcy5oZWFkZXJEcmF3ZXIpIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCh0aGlzLmhlYWRlckRyYXdlci5hbmltYXRlKFt7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfSwgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9XSwgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLW91dCcgfSkuZmluaXNoZWQpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGFuaW1hdGlvbnMpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENhbGVuZGFyRXZlbnRzIC0gQ29tbWFuZCBhbmQgc3RhdHVzIGV2ZW50cyBmb3IgQ2FsZW5kYXJBcHBcbiAqL1xuZXhwb3J0IGNvbnN0IENhbGVuZGFyRXZlbnRzID0ge1xuICAgIC8vIENvbW1hbmQgZXZlbnRzIChob3N0IFx1MjE5MiBjYWxlbmRhcilcbiAgICBDTURfTkFWSUdBVEVfUFJFVjogJ2NhbGVuZGFyOmNtZDpuYXZpZ2F0ZTpwcmV2JyxcbiAgICBDTURfTkFWSUdBVEVfTkVYVDogJ2NhbGVuZGFyOmNtZDpuYXZpZ2F0ZTpuZXh0JyxcbiAgICBDTURfRFJBV0VSX1RPR0dMRTogJ2NhbGVuZGFyOmNtZDpkcmF3ZXI6dG9nZ2xlJyxcbiAgICBDTURfUkVOREVSOiAnY2FsZW5kYXI6Y21kOnJlbmRlcicsXG4gICAgQ01EX1dPUktXRUVLX0NIQU5HRTogJ2NhbGVuZGFyOmNtZDp3b3Jrd2VlazpjaGFuZ2UnLFxuICAgIENNRF9WSUVXX1VQREFURTogJ2NhbGVuZGFyOmNtZDp2aWV3OnVwZGF0ZSdcbn07XG4iLCAiaW1wb3J0IHsgTmF2aWdhdGlvbkFuaW1hdG9yIH0gZnJvbSAnLi9OYXZpZ2F0aW9uQW5pbWF0b3InO1xuaW1wb3J0IHsgQ2FsZW5kYXJFdmVudHMgfSBmcm9tICcuL0NhbGVuZGFyRXZlbnRzJztcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckFwcCB7XG4gICAgY29uc3RydWN0b3Iob3JjaGVzdHJhdG9yLCB0aW1lQXhpc1JlbmRlcmVyLCBkYXRlU2VydmljZSwgc2Nyb2xsTWFuYWdlciwgaGVhZGVyRHJhd2VyTWFuYWdlciwgZHJhZ0Ryb3BNYW5hZ2VyLCBlZGdlU2Nyb2xsTWFuYWdlciwgcmVzaXplTWFuYWdlciwgaGVhZGVyRHJhd2VyUmVuZGVyZXIsIGV2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyLCBzZXR0aW5nc1NlcnZpY2UsIHZpZXdDb25maWdTZXJ2aWNlLCBldmVudEJ1cykge1xuICAgICAgICB0aGlzLm9yY2hlc3RyYXRvciA9IG9yY2hlc3RyYXRvcjtcbiAgICAgICAgdGhpcy50aW1lQXhpc1JlbmRlcmVyID0gdGltZUF4aXNSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLnNjcm9sbE1hbmFnZXIgPSBzY3JvbGxNYW5hZ2VyO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlck1hbmFnZXIgPSBoZWFkZXJEcmF3ZXJNYW5hZ2VyO1xuICAgICAgICB0aGlzLmRyYWdEcm9wTWFuYWdlciA9IGRyYWdEcm9wTWFuYWdlcjtcbiAgICAgICAgdGhpcy5lZGdlU2Nyb2xsTWFuYWdlciA9IGVkZ2VTY3JvbGxNYW5hZ2VyO1xuICAgICAgICB0aGlzLnJlc2l6ZU1hbmFnZXIgPSByZXNpemVNYW5hZ2VyO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlclJlbmRlcmVyID0gaGVhZGVyRHJhd2VyUmVuZGVyZXI7XG4gICAgICAgIHRoaXMuZXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIgPSBldmVudFBlcnNpc3RlbmNlTWFuYWdlcjtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1NlcnZpY2UgPSBzZXR0aW5nc1NlcnZpY2U7XG4gICAgICAgIHRoaXMudmlld0NvbmZpZ1NlcnZpY2UgPSB2aWV3Q29uZmlnU2VydmljZTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmRheU9mZnNldCA9IDA7XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXdJZCA9ICdzaW1wbGUnO1xuICAgICAgICB0aGlzLndvcmt3ZWVrUHJlc2V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ncm91cGluZ092ZXJyaWRlcyA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYXN5bmMgaW5pdChjb250YWluZXIpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIC8vIExvYWQgc2V0dGluZ3NcbiAgICAgICAgY29uc3QgZ3JpZFNldHRpbmdzID0gYXdhaXQgdGhpcy5zZXR0aW5nc1NlcnZpY2UuZ2V0R3JpZFNldHRpbmdzKCk7XG4gICAgICAgIGlmICghZ3JpZFNldHRpbmdzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0dyaWRTZXR0aW5ncyBub3QgZm91bmQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLndvcmt3ZWVrUHJlc2V0ID0gYXdhaXQgdGhpcy5zZXR0aW5nc1NlcnZpY2UuZ2V0RGVmYXVsdFdvcmt3ZWVrUHJlc2V0KCk7XG4gICAgICAgIC8vIENyZWF0ZSBOYXZpZ2F0aW9uQW5pbWF0b3Igd2l0aCBET00gZWxlbWVudHNcbiAgICAgICAgdGhpcy5hbmltYXRvciA9IG5ldyBOYXZpZ2F0aW9uQW5pbWF0b3IoY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItdHJhY2snKSwgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1jb250ZW50LXRyYWNrJyksIGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtaGVhZGVyLWRyYXdlcicpKTtcbiAgICAgICAgLy8gUmVuZGVyIHRpbWUgYXhpcyBmcm9tIHNldHRpbmdzXG4gICAgICAgIHRoaXMudGltZUF4aXNSZW5kZXJlci5yZW5kZXIoY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyN0aW1lLWF4aXMnKSwgZ3JpZFNldHRpbmdzLmRheVN0YXJ0SG91ciwgZ3JpZFNldHRpbmdzLmRheUVuZEhvdXIpO1xuICAgICAgICAvLyBJbml0IG1hbmFnZXJzXG4gICAgICAgIHRoaXMuc2Nyb2xsTWFuYWdlci5pbml0KGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5pbml0KGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuZHJhZ0Ryb3BNYW5hZ2VyLmluaXQoY29udGFpbmVyKTtcbiAgICAgICAgdGhpcy5yZXNpemVNYW5hZ2VyLmluaXQoY29udGFpbmVyKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUNvbnRlbnQgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLXNjcm9sbGFibGUtY29udGVudCcpO1xuICAgICAgICB0aGlzLmVkZ2VTY3JvbGxNYW5hZ2VyLmluaXQoc2Nyb2xsYWJsZUNvbnRlbnQpO1xuICAgICAgICAvLyBTZXR1cCBjb21tYW5kIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICB0aGlzLnNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgICAgLy8gRW1pdCByZWFkeSBzdGF0dXNcbiAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdyZWFkeScpO1xuICAgIH1cbiAgICBzZXR1cEV2ZW50TGlzdGVuZXJzKCkge1xuICAgICAgICAvLyBOYXZpZ2F0aW9uIGNvbW1hbmRzIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9OQVZJR0FURV9QUkVWLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU5hdmlnYXRlUHJldigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDYWxlbmRhckV2ZW50cy5DTURfTkFWSUdBVEVfTkVYVCwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVOYXZpZ2F0ZU5leHQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIERyYXdlciB0b2dnbGUgdmlhIEV2ZW50QnVzXG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ2FsZW5kYXJFdmVudHMuQ01EX0RSQVdFUl9UT0dHTEUsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci50b2dnbGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJlbmRlciBjb21tYW5kIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9SRU5ERVIsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHZpZXdJZCB9ID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJlbmRlckNvbW1hbmQodmlld0lkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFdvcmt3ZWVrIGNoYW5nZSB2aWEgRXZlbnRCdXNcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDYWxlbmRhckV2ZW50cy5DTURfV09SS1dFRUtfQ0hBTkdFLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBwcmVzZXRJZCB9ID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVdvcmt3ZWVrQ2hhbmdlKHByZXNldElkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFZpZXcgdXBkYXRlIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9WSUVXX1VQREFURSwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdHlwZSwgdmFsdWVzIH0gPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlVmlld1VwZGF0ZSh0eXBlLCB2YWx1ZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXN5bmMgaGFuZGxlUmVuZGVyQ29tbWFuZCh2aWV3SWQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50Vmlld0lkID0gdmlld0lkO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcigpO1xuICAgICAgICB0aGlzLmVtaXRTdGF0dXMoJ3JlbmRlcmVkJywgeyB2aWV3SWQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGhhbmRsZU5hdmlnYXRlUHJldigpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9IHRoaXMud29ya3dlZWtQcmVzZXQ/LnBlcmlvZERheXMgPz8gNztcbiAgICAgICAgdGhpcy5kYXlPZmZzZXQgLT0gc3RlcDtcbiAgICAgICAgYXdhaXQgdGhpcy5hbmltYXRvci5zbGlkZSgncmlnaHQnLCAoKSA9PiB0aGlzLnJlbmRlcigpKTtcbiAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdyZW5kZXJlZCcsIHsgdmlld0lkOiB0aGlzLmN1cnJlbnRWaWV3SWQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGhhbmRsZU5hdmlnYXRlTmV4dCgpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9IHRoaXMud29ya3dlZWtQcmVzZXQ/LnBlcmlvZERheXMgPz8gNztcbiAgICAgICAgdGhpcy5kYXlPZmZzZXQgKz0gc3RlcDtcbiAgICAgICAgYXdhaXQgdGhpcy5hbmltYXRvci5zbGlkZSgnbGVmdCcsICgpID0+IHRoaXMucmVuZGVyKCkpO1xuICAgICAgICB0aGlzLmVtaXRTdGF0dXMoJ3JlbmRlcmVkJywgeyB2aWV3SWQ6IHRoaXMuY3VycmVudFZpZXdJZCB9KTtcbiAgICB9XG4gICAgYXN5bmMgaGFuZGxlV29ya3dlZWtDaGFuZ2UocHJlc2V0SWQpIHtcbiAgICAgICAgY29uc3QgcHJlc2V0ID0gYXdhaXQgdGhpcy5zZXR0aW5nc1NlcnZpY2UuZ2V0V29ya3dlZWtQcmVzZXQocHJlc2V0SWQpO1xuICAgICAgICBpZiAocHJlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLndvcmt3ZWVrUHJlc2V0ID0gcHJlc2V0O1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdFN0YXR1cygncmVuZGVyZWQnLCB7IHZpZXdJZDogdGhpcy5jdXJyZW50Vmlld0lkIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIGhhbmRsZVZpZXdVcGRhdGUodHlwZSwgdmFsdWVzKSB7XG4gICAgICAgIHRoaXMuZ3JvdXBpbmdPdmVycmlkZXMuc2V0KHR5cGUsIHZhbHVlcyk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVuZGVyKCk7XG4gICAgICAgIHRoaXMuZW1pdFN0YXR1cygncmVuZGVyZWQnLCB7IHZpZXdJZDogdGhpcy5jdXJyZW50Vmlld0lkIH0pO1xuICAgIH1cbiAgICBhc3luYyByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlZENvbmZpZyA9IGF3YWl0IHRoaXMudmlld0NvbmZpZ1NlcnZpY2UuZ2V0QnlJZCh0aGlzLmN1cnJlbnRWaWV3SWQpO1xuICAgICAgICBpZiAoIXN0b3JlZENvbmZpZykge1xuICAgICAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdlcnJvcicsIHsgbWVzc2FnZTogYFZpZXdDb25maWcgbm90IGZvdW5kOiAke3RoaXMuY3VycmVudFZpZXdJZH1gIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBvcHVsYXRlIGRhdGUgdmFsdWVzIGJhc2VkIG9uIHdvcmt3ZWVrIHByZXNldCBhbmQgZGF5IG9mZnNldFxuICAgICAgICBjb25zdCB3b3JrRGF5cyA9IHRoaXMud29ya3dlZWtQcmVzZXQ/LndvcmtEYXlzIHx8IFsxLCAyLCAzLCA0LCA1XTtcbiAgICAgICAgY29uc3QgcGVyaW9kRGF5cyA9IHRoaXMud29ya3dlZWtQcmVzZXQ/LnBlcmlvZERheXMgPz8gNztcbiAgICAgICAgLy8gRm9yIHNpbmdsZS1kYXkgbmF2aWdhdGlvbiAocGVyaW9kRGF5cz0xKSwgc2hvdyBjb25zZWN1dGl2ZSBkYXlzIGZyb20gb2Zmc2V0XG4gICAgICAgIC8vIEZvciB3ZWVrIG5hdmlnYXRpb24gKHBlcmlvZERheXM9NyksIHNob3cgd29ya0RheXMgZnJvbSB0aGUgd2VlayBjb250YWluaW5nIG9mZnNldFxuICAgICAgICBjb25zdCBkYXRlcyA9IHBlcmlvZERheXMgPT09IDFcbiAgICAgICAgICAgID8gdGhpcy5kYXRlU2VydmljZS5nZXREYXRlc0Zyb21PZmZzZXQodGhpcy5kYXlPZmZzZXQsIHdvcmtEYXlzLmxlbmd0aClcbiAgICAgICAgICAgIDogdGhpcy5kYXRlU2VydmljZS5nZXRXb3JrRGF5c0Zyb21PZmZzZXQodGhpcy5kYXlPZmZzZXQsIHdvcmtEYXlzKTtcbiAgICAgICAgLy8gQ2xvbmUgY29uZmlnIGFuZCBhcHBseSBvdmVycmlkZXNcbiAgICAgICAgY29uc3Qgdmlld0NvbmZpZyA9IHtcbiAgICAgICAgICAgIC4uLnN0b3JlZENvbmZpZyxcbiAgICAgICAgICAgIGdyb3VwaW5nczogc3RvcmVkQ29uZmlnLmdyb3VwaW5ncy5tYXAoZyA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgZGF0ZSB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAoZy50eXBlID09PSAnZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uZywgdmFsdWVzOiBkYXRlcyB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBBcHBseSBncm91cGluZyBvdmVycmlkZXNcbiAgICAgICAgICAgICAgICBjb25zdCBvdmVycmlkZSA9IHRoaXMuZ3JvdXBpbmdPdmVycmlkZXMuZ2V0KGcudHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmcsIHZhbHVlczogb3ZlcnJpZGUgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGc7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCB0aGlzLm9yY2hlc3RyYXRvci5yZW5kZXIodmlld0NvbmZpZywgdGhpcy5jb250YWluZXIpO1xuICAgIH1cbiAgICBlbWl0U3RhdHVzKHN0YXR1cywgZGV0YWlsKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KGBjYWxlbmRhcjpzdGF0dXM6JHtzdGF0dXN9YCwge1xuICAgICAgICAgICAgZGV0YWlsLFxuICAgICAgICAgICAgYnViYmxlczogdHJ1ZVxuICAgICAgICB9KSk7XG4gICAgfVxufVxuIiwgImV4cG9ydCBjbGFzcyBUaW1lQXhpc1JlbmRlcmVyIHtcbiAgICByZW5kZXIoY29udGFpbmVyLCBzdGFydEhvdXIgPSA2LCBlbmRIb3VyID0gMjApIHtcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICBmb3IgKGxldCBob3VyID0gc3RhcnRIb3VyOyBob3VyIDw9IGVuZEhvdXI7IGhvdXIrKykge1xuICAgICAgICAgICAgY29uc3QgbWFya2VyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWhvdXItbWFya2VyJyk7XG4gICAgICAgICAgICBtYXJrZXIudGV4dENvbnRlbnQgPSBgJHtob3VyLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKX06MDBgO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIFNjcm9sbE1hbmFnZXIge1xuICAgIGluaXQoY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLXNjcm9sbGFibGUtY29udGVudCcpO1xuICAgICAgICB0aGlzLnRpbWVBeGlzQ29udGVudCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtdGltZS1heGlzLWNvbnRlbnQnKTtcbiAgICAgICAgdGhpcy5jYWxlbmRhckhlYWRlciA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtY2FsZW5kYXItaGVhZGVyJyk7XG4gICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItZHJhd2VyJyk7XG4gICAgICAgIHRoaXMuaGVhZGVyVmlld3BvcnQgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci12aWV3cG9ydCcpO1xuICAgICAgICB0aGlzLmhlYWRlclNwYWNlciA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtaGVhZGVyLXNwYWNlcicpO1xuICAgICAgICB0aGlzLnNjcm9sbGFibGVDb250ZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsICgpID0+IHRoaXMub25TY3JvbGwoKSk7XG4gICAgICAgIC8vIFN5bmtyb25pc2VyIGhlYWRlci1zcGFjZXIgaFx1MDBGOGpkZSBtZWQgaGVhZGVyLXZpZXdwb3J0XG4gICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy5zeW5jSGVhZGVyU3BhY2VySGVpZ2h0KCkpO1xuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5oZWFkZXJWaWV3cG9ydCk7XG4gICAgICAgIHRoaXMuc3luY0hlYWRlclNwYWNlckhlaWdodCgpO1xuICAgIH1cbiAgICBzeW5jSGVhZGVyU3BhY2VySGVpZ2h0KCkge1xuICAgICAgICAvLyBLb3BpZXIgZGVuIGZha3Rpc2tlIGNvbXB1dGVkIGhlaWdodCBkaXJla3RlIGZyYSBoZWFkZXItdmlld3BvcnRcbiAgICAgICAgY29uc3QgY29tcHV0ZWRIZWlnaHQgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMuaGVhZGVyVmlld3BvcnQpLmhlaWdodDtcbiAgICAgICAgdGhpcy5oZWFkZXJTcGFjZXIuc3R5bGUuaGVpZ2h0ID0gY29tcHV0ZWRIZWlnaHQ7XG4gICAgfVxuICAgIG9uU2Nyb2xsKCkge1xuICAgICAgICBjb25zdCB7IHNjcm9sbFRvcCwgc2Nyb2xsTGVmdCB9ID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudDtcbiAgICAgICAgLy8gU3lua3JvbmlzZXIgdGltZS1heGlzIHZlcnRpa2FsdFxuICAgICAgICB0aGlzLnRpbWVBeGlzQ29udGVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWSgtJHtzY3JvbGxUb3B9cHgpYDtcbiAgICAgICAgLy8gU3lua3JvbmlzZXIgaGVhZGVyIG9nIGRyYXdlciBob3Jpc29udGFsdFxuICAgICAgICB0aGlzLmNhbGVuZGFySGVhZGVyLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGVYKC0ke3Njcm9sbExlZnR9cHgpYDtcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZVgoLSR7c2Nyb2xsTGVmdH1weClgO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgSGVhZGVyRHJhd2VyTWFuYWdlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZXhwYW5kZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jdXJyZW50Um93cyA9IDA7XG4gICAgICAgIHRoaXMucm93SGVpZ2h0ID0gMjU7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSAyMDA7XG4gICAgfVxuICAgIGluaXQoY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuZHJhd2VyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItZHJhd2VyJyk7XG4gICAgICAgIGlmICghdGhpcy5kcmF3ZXIpXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdIZWFkZXJEcmF3ZXJNYW5hZ2VyOiBzd3AtaGVhZGVyLWRyYXdlciBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgdG9nZ2xlKCkge1xuICAgICAgICB0aGlzLmV4cGFuZGVkID8gdGhpcy5jb2xsYXBzZSgpIDogdGhpcy5leHBhbmQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXhwYW5kIGRyYXdlciB0byBzaW5nbGUgcm93IChsZWdhY3kgc3VwcG9ydClcbiAgICAgKi9cbiAgICBleHBhbmQoKSB7XG4gICAgICAgIHRoaXMuZXhwYW5kVG9Sb3dzKDEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeHBhbmQgZHJhd2VyIHRvIGZpdCBzcGVjaWZpZWQgbnVtYmVyIG9mIHJvd3NcbiAgICAgKi9cbiAgICBleHBhbmRUb1Jvd3Mocm93Q291bnQpIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0SGVpZ2h0ID0gcm93Q291bnQgKiB0aGlzLnJvd0hlaWdodDtcbiAgICAgICAgY29uc3QgY3VycmVudEhlaWdodCA9IHRoaXMuZXhwYW5kZWQgPyB0aGlzLmN1cnJlbnRSb3dzICogdGhpcy5yb3dIZWlnaHQgOiAwO1xuICAgICAgICAvLyBTa2lwIGlmIGFscmVhZHkgYXQgdGFyZ2V0XG4gICAgICAgIGlmICh0aGlzLmV4cGFuZGVkICYmIHRoaXMuY3VycmVudFJvd3MgPT09IHJvd0NvdW50KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aGlzLmN1cnJlbnRSb3dzID0gcm93Q291bnQ7XG4gICAgICAgIHRoaXMuZXhwYW5kZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmFuaW1hdGUoY3VycmVudEhlaWdodCwgdGFyZ2V0SGVpZ2h0KTtcbiAgICB9XG4gICAgY29sbGFwc2UoKSB7XG4gICAgICAgIGlmICghdGhpcy5leHBhbmRlZClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgY3VycmVudEhlaWdodCA9IHRoaXMuY3VycmVudFJvd3MgKiB0aGlzLnJvd0hlaWdodDtcbiAgICAgICAgdGhpcy5leHBhbmRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRSb3dzID0gMDtcbiAgICAgICAgdGhpcy5hbmltYXRlKGN1cnJlbnRIZWlnaHQsIDApO1xuICAgIH1cbiAgICBhbmltYXRlKGZyb20sIHRvKSB7XG4gICAgICAgIGNvbnN0IGtleWZyYW1lcyA9IFtcbiAgICAgICAgICAgIHsgaGVpZ2h0OiBgJHtmcm9tfXB4YCB9LFxuICAgICAgICAgICAgeyBoZWlnaHQ6IGAke3RvfXB4YCB9XG4gICAgICAgIF07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbixcbiAgICAgICAgICAgIGVhc2luZzogJ2Vhc2UnLFxuICAgICAgICAgICAgZmlsbDogJ2ZvcndhcmRzJ1xuICAgICAgICB9O1xuICAgICAgICAvLyBLdW4gYW5pbVx1MDBFOXIgZHJhd2VyIC0gU2Nyb2xsTWFuYWdlciBzeW5rcm9uaXNlcmVyIGhlYWRlci1zcGFjZXIgdmlhIFJlc2l6ZU9ic2VydmVyXG4gICAgICAgIHRoaXMuZHJhd2VyLmFuaW1hdGUoa2V5ZnJhbWVzLCBvcHRpb25zKTtcbiAgICB9XG4gICAgaXNFeHBhbmRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXhwYW5kZWQ7XG4gICAgfVxuICAgIGdldFJvd0NvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50Um93cztcbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIE1vY2tUZWFtU3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAndGVhbSc7XG4gICAgICAgIHRoaXMudGVhbXMgPSBbXG4gICAgICAgICAgICB7IGlkOiAnYWxwaGEnLCBuYW1lOiAnVGVhbSBBbHBoYScgfSxcbiAgICAgICAgICAgIHsgaWQ6ICdiZXRhJywgbmFtZTogJ1RlYW0gQmV0YScgfVxuICAgICAgICBdO1xuICAgIH1cbiAgICBnZXRCeUlkcyhpZHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVhbXMuZmlsdGVyKHQgPT4gaWRzLmluY2x1ZGVzKHQuaWQpKTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgTW9ja1Jlc291cmNlU3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAncmVzb3VyY2UnO1xuICAgICAgICB0aGlzLnJlc291cmNlcyA9IFtcbiAgICAgICAgICAgIHsgaWQ6ICdhbGljZScsIG5hbWU6ICdBbGljZScsIHRlYW1JZDogJ2FscGhhJyB9LFxuICAgICAgICAgICAgeyBpZDogJ2JvYicsIG5hbWU6ICdCb2InLCB0ZWFtSWQ6ICdhbHBoYScgfSxcbiAgICAgICAgICAgIHsgaWQ6ICdjYXJvbCcsIG5hbWU6ICdDYXJvbCcsIHRlYW1JZDogJ2JldGEnIH0sXG4gICAgICAgICAgICB7IGlkOiAnZGF2ZScsIG5hbWU6ICdEYXZlJywgdGVhbUlkOiAnYmV0YScgfVxuICAgICAgICBdO1xuICAgIH1cbiAgICBnZXRCeUlkcyhpZHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb3VyY2VzLmZpbHRlcihyID0+IGlkcy5pbmNsdWRlcyhyLmlkKSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IENhbGVuZGFyRXZlbnRzIH0gZnJvbSAnLi4vY29yZS9DYWxlbmRhckV2ZW50cyc7XG5leHBvcnQgY2xhc3MgRGVtb0FwcCB7XG4gICAgY29uc3RydWN0b3IoaW5kZXhlZERCQ29udGV4dCwgZGF0YVNlZWRlciwgYXVkaXRTZXJ2aWNlLCBjYWxlbmRhckFwcCwgZGF0ZVNlcnZpY2UsIHJlc291cmNlU2VydmljZSwgZXZlbnRCdXMpIHtcbiAgICAgICAgdGhpcy5pbmRleGVkREJDb250ZXh0ID0gaW5kZXhlZERCQ29udGV4dDtcbiAgICAgICAgdGhpcy5kYXRhU2VlZGVyID0gZGF0YVNlZWRlcjtcbiAgICAgICAgdGhpcy5hdWRpdFNlcnZpY2UgPSBhdWRpdFNlcnZpY2U7XG4gICAgICAgIHRoaXMuY2FsZW5kYXJBcHAgPSBjYWxlbmRhckFwcDtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLnJlc291cmNlU2VydmljZSA9IHJlc291cmNlU2VydmljZTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmN1cnJlbnRWaWV3ID0gJ3NpbXBsZSc7XG4gICAgfVxuICAgIGFzeW5jIGluaXQoKSB7XG4gICAgICAgIC8vIFNldCBiYXNlIGRhdGUgdG8gbWF0Y2ggbW9jayBkYXRhICg4LiBkZWNlbWJlciAyMDI1ID0gbWFuZGFnKVxuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlLnNldEJhc2VEYXRlKG5ldyBEYXRlKCcyMDI1LTEyLTA4JykpO1xuICAgICAgICAvLyBJbml0aWFsaXplIEluZGV4ZWREQlxuICAgICAgICBhd2FpdCB0aGlzLmluZGV4ZWREQkNvbnRleHQuaW5pdGlhbGl6ZSgpO1xuICAgICAgICBjb25zb2xlLmxvZygnW0RlbW9BcHBdIEluZGV4ZWREQiBpbml0aWFsaXplZCcpO1xuICAgICAgICAvLyBTZWVkIGRhdGEgaWYgZW1wdHlcbiAgICAgICAgYXdhaXQgdGhpcy5kYXRhU2VlZGVyLnNlZWRJZkVtcHR5KCk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbRGVtb0FwcF0gRGF0YSBzZWVkaW5nIGNvbXBsZXRlJyk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWNhbGVuZGFyLWNvbnRhaW5lcicpO1xuICAgICAgICAvLyBJbml0aWFsaXplIENhbGVuZGFyQXBwXG4gICAgICAgIGF3YWl0IHRoaXMuY2FsZW5kYXJBcHAuaW5pdCh0aGlzLmNvbnRhaW5lcik7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbRGVtb0FwcF0gQ2FsZW5kYXJBcHAgaW5pdGlhbGl6ZWQnKTtcbiAgICAgICAgLy8gU2V0dXAgZGVtbyBVSSBoYW5kbGVyc1xuICAgICAgICB0aGlzLnNldHVwTmF2aWdhdGlvbigpO1xuICAgICAgICB0aGlzLnNldHVwRHJhd2VyVG9nZ2xlKCk7XG4gICAgICAgIHRoaXMuc2V0dXBWaWV3U3dpdGNoaW5nKCk7XG4gICAgICAgIHRoaXMuc2V0dXBXb3Jrd2Vla1NlbGVjdG9yKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0dXBSZXNvdXJjZVNlbGVjdG9yKCk7XG4gICAgICAgIC8vIExpc3RlbiBmb3IgY2FsZW5kYXIgc3RhdHVzIGV2ZW50c1xuICAgICAgICB0aGlzLnNldHVwU3RhdHVzTGlzdGVuZXJzKCk7XG4gICAgICAgIC8vIEluaXRpYWwgcmVuZGVyXG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDYWxlbmRhckV2ZW50cy5DTURfUkVOREVSLCB7IHZpZXdJZDogdGhpcy5jdXJyZW50VmlldyB9KTtcbiAgICB9XG4gICAgc2V0dXBOYXZpZ2F0aW9uKCkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLXByZXYnKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENhbGVuZGFyRXZlbnRzLkNNRF9OQVZJR0FURV9QUkVWKTtcbiAgICAgICAgfTtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0bi1uZXh0Jykub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDYWxlbmRhckV2ZW50cy5DTURfTkFWSUdBVEVfTkVYVCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHNldHVwVmlld1N3aXRjaGluZygpIHtcbiAgICAgICAgY29uc3QgY2hpcHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudmlldy1jaGlwJyk7XG4gICAgICAgIGNoaXBzLmZvckVhY2goY2hpcCA9PiB7XG4gICAgICAgICAgICBjaGlwLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNoaXBzLmZvckVhY2goYyA9PiBjLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpKTtcbiAgICAgICAgICAgICAgICBjaGlwLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBjaGlwLmRhdGFzZXQudmlldztcbiAgICAgICAgICAgICAgICBpZiAodmlldykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3ID0gdmlldztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTZWxlY3RvclZpc2liaWxpdHkoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENhbGVuZGFyRXZlbnRzLkNNRF9SRU5ERVIsIHsgdmlld0lkOiB2aWV3IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgdXBkYXRlU2VsZWN0b3JWaXNpYmlsaXR5KCkge1xuICAgICAgICBjb25zdCBzZWxlY3RvciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1yZXNvdXJjZS1zZWxlY3RvcicpO1xuICAgICAgICBjb25zdCBzaG93U2VsZWN0b3IgPSB0aGlzLmN1cnJlbnRWaWV3ID09PSAncGlja2VyJyB8fCB0aGlzLmN1cnJlbnRWaWV3ID09PSAnZGF5JztcbiAgICAgICAgc2VsZWN0b3I/LmNsYXNzTGlzdC50b2dnbGUoJ2hpZGRlbicsICFzaG93U2VsZWN0b3IpO1xuICAgIH1cbiAgICBzZXR1cERyYXdlclRvZ2dsZSgpIHtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0bi1kcmF3ZXInKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENhbGVuZGFyRXZlbnRzLkNNRF9EUkFXRVJfVE9HR0xFKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgc2V0dXBXb3Jrd2Vla1NlbGVjdG9yKCkge1xuICAgICAgICBjb25zdCB3b3Jrd2Vla1NlbGVjdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd3b3Jrd2Vlay1zZWxlY3QnKTtcbiAgICAgICAgd29ya3dlZWtTZWxlY3Q/LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByZXNldElkID0gd29ya3dlZWtTZWxlY3QudmFsdWU7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ2FsZW5kYXJFdmVudHMuQ01EX1dPUktXRUVLX0NIQU5HRSwgeyBwcmVzZXRJZCB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIHNldHVwUmVzb3VyY2VTZWxlY3RvcigpIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VzID0gYXdhaXQgdGhpcy5yZXNvdXJjZVNlcnZpY2UuZ2V0QWxsKCk7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5yZXNvdXJjZS1jaGVja2JveGVzJyk7XG4gICAgICAgIGlmICghY29udGFpbmVyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIHJlc291cmNlcy5mb3JFYWNoKHIgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgICAgICAgICAgbGFiZWwuaW5uZXJIVE1MID0gYFxyXG4gICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiB2YWx1ZT1cIiR7ci5pZH1cIiBjaGVja2VkPlxyXG4gICAgICAgICR7ci5kaXNwbGF5TmFtZX1cclxuICAgICAgYDtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dDpjaGVja2VkJyk7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBBcnJheS5mcm9tKGNoZWNrZWQpLm1hcChjYiA9PiBjYi52YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ2FsZW5kYXJFdmVudHMuQ01EX1ZJRVdfVVBEQVRFLCB7IHR5cGU6ICdyZXNvdXJjZScsIHZhbHVlcyB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHNldHVwU3RhdHVzTGlzdGVuZXJzKCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdjYWxlbmRhcjpzdGF0dXM6cmVhZHknLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW0RlbW9BcHBdIENhbGVuZGFyIHJlYWR5Jyk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdjYWxlbmRhcjpzdGF0dXM6cmVuZGVyZWQnLCAoKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbRGVtb0FwcF0gQ2FsZW5kYXIgcmVuZGVyZWQ6JywgZS5kZXRhaWwudmlld0lkKTtcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdjYWxlbmRhcjpzdGF0dXM6ZXJyb3InLCAoKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tEZW1vQXBwXSBDYWxlbmRhciBlcnJvcjonLCBlLmRldGFpbC5tZXNzYWdlKTtcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENlbnRyYWwgZXZlbnQgZGlzcGF0Y2hlciBmb3IgY2FsZW5kYXIgdXNpbmcgRE9NIEN1c3RvbUV2ZW50c1xuICogUHJvdmlkZXMgbG9nZ2luZyBhbmQgZGVidWdnaW5nIGNhcGFiaWxpdGllc1xuICovXG5leHBvcnQgY2xhc3MgRXZlbnRCdXMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmV2ZW50TG9nID0gW107XG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMgPSBuZXcgU2V0KCk7XG4gICAgICAgIC8vIExvZyBjb25maWd1cmF0aW9uIGZvciBkaWZmZXJlbnQgY2F0ZWdvcmllc1xuICAgICAgICB0aGlzLmxvZ0NvbmZpZyA9IHtcbiAgICAgICAgICAgIGNhbGVuZGFyOiB0cnVlLFxuICAgICAgICAgICAgZ3JpZDogdHJ1ZSxcbiAgICAgICAgICAgIGV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgc2Nyb2xsOiB0cnVlLFxuICAgICAgICAgICAgbmF2aWdhdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIHZpZXc6IHRydWUsXG4gICAgICAgICAgICBkZWZhdWx0OiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSB0byBhbiBldmVudCB2aWEgRE9NIGFkZEV2ZW50TGlzdGVuZXJcbiAgICAgKi9cbiAgICBvbihldmVudFR5cGUsIGhhbmRsZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGhhbmRsZXIsIG9wdGlvbnMpO1xuICAgICAgICAvLyBUcmFjayBmb3IgY2xlYW51cFxuICAgICAgICB0aGlzLmxpc3RlbmVycy5hZGQoeyBldmVudFR5cGUsIGhhbmRsZXIsIG9wdGlvbnMgfSk7XG4gICAgICAgIC8vIFJldHVybiB1bnN1YnNjcmliZSBmdW5jdGlvblxuICAgICAgICByZXR1cm4gKCkgPT4gdGhpcy5vZmYoZXZlbnRUeXBlLCBoYW5kbGVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIHRvIGFuIGV2ZW50IG9uY2VcbiAgICAgKi9cbiAgICBvbmNlKGV2ZW50VHlwZSwgaGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5vbihldmVudFR5cGUsIGhhbmRsZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmUgZnJvbSBhbiBldmVudFxuICAgICAqL1xuICAgIG9mZihldmVudFR5cGUsIGhhbmRsZXIpIHtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGhhbmRsZXIpO1xuICAgICAgICAvLyBSZW1vdmUgZnJvbSB0cmFja2luZ1xuICAgICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMubGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXIuZXZlbnRUeXBlID09PSBldmVudFR5cGUgJiYgbGlzdGVuZXIuaGFuZGxlciA9PT0gaGFuZGxlcikge1xuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRW1pdCBhbiBldmVudCB2aWEgRE9NIEN1c3RvbUV2ZW50XG4gICAgICovXG4gICAgZW1pdChldmVudFR5cGUsIGRldGFpbCA9IHt9KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGV2ZW50VHlwZVxuICAgICAgICBpZiAoIWV2ZW50VHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50VHlwZSwge1xuICAgICAgICAgICAgZGV0YWlsOiBkZXRhaWwgPz8ge30sXG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gTG9nIGV2ZW50IHdpdGggZ3JvdXBpbmdcbiAgICAgICAgaWYgKHRoaXMuZGVidWcpIHtcbiAgICAgICAgICAgIHRoaXMubG9nRXZlbnRXaXRoR3JvdXBpbmcoZXZlbnRUeXBlLCBkZXRhaWwpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXZlbnRMb2cucHVzaCh7XG4gICAgICAgICAgICB0eXBlOiBldmVudFR5cGUsXG4gICAgICAgICAgICBkZXRhaWw6IGRldGFpbCA/PyB7fSxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRW1pdCBvbiBkb2N1bWVudCAob25seSBET00gZXZlbnRzIG5vdylcbiAgICAgICAgcmV0dXJuICFkb2N1bWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9nIGV2ZW50IHdpdGggY29uc29sZSBncm91cGluZ1xuICAgICAqL1xuICAgIGxvZ0V2ZW50V2l0aEdyb3VwaW5nKGV2ZW50VHlwZSwgX2RldGFpbCkge1xuICAgICAgICAvLyBFeHRyYWN0IGNhdGVnb3J5IGZyb20gZXZlbnQgdHlwZSAoZS5nLiwgJ2NhbGVuZGFyOmRhdGVjaGFuZ2VkJyBcdTIxOTIgJ2NhbGVuZGFyJylcbiAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSB0aGlzLmV4dHJhY3RDYXRlZ29yeShldmVudFR5cGUpO1xuICAgICAgICAvLyBPbmx5IGxvZyBpZiBjYXRlZ29yeSBpcyBlbmFibGVkXG4gICAgICAgIGlmICghdGhpcy5sb2dDb25maWdbY2F0ZWdvcnldKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gR2V0IGNhdGVnb3J5IGVtb2ppIGFuZCBjb2xvciAodXNlZCBmb3IgZnV0dXJlIGNvbnNvbGUgc3R5bGluZylcbiAgICAgICAgdGhpcy5nZXRDYXRlZ29yeVN0eWxlKGNhdGVnb3J5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXh0cmFjdCBjYXRlZ29yeSBmcm9tIGV2ZW50IHR5cGVcbiAgICAgKi9cbiAgICBleHRyYWN0Q2F0ZWdvcnkoZXZlbnRUeXBlKSB7XG4gICAgICAgIGlmICghZXZlbnRUeXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3Vua25vd24nO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudFR5cGUuaW5jbHVkZXMoJzonKSkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50VHlwZS5zcGxpdCgnOicpWzBdO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZhbGxiYWNrOiB0cnkgdG8gZGV0ZWN0IGNhdGVnb3J5IGZyb20gZXZlbnQgbmFtZSBwYXR0ZXJuc1xuICAgICAgICBjb25zdCBsb3dlclR5cGUgPSBldmVudFR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKGxvd2VyVHlwZS5pbmNsdWRlcygnZ3JpZCcpIHx8IGxvd2VyVHlwZS5pbmNsdWRlcygncmVuZGVyZWQnKSlcbiAgICAgICAgICAgIHJldHVybiAnZ3JpZCc7XG4gICAgICAgIGlmIChsb3dlclR5cGUuaW5jbHVkZXMoJ2V2ZW50JykgfHwgbG93ZXJUeXBlLmluY2x1ZGVzKCdzeW5jJykpXG4gICAgICAgICAgICByZXR1cm4gJ2V2ZW50JztcbiAgICAgICAgaWYgKGxvd2VyVHlwZS5pbmNsdWRlcygnc2Nyb2xsJykpXG4gICAgICAgICAgICByZXR1cm4gJ3Njcm9sbCc7XG4gICAgICAgIGlmIChsb3dlclR5cGUuaW5jbHVkZXMoJ25hdicpIHx8IGxvd2VyVHlwZS5pbmNsdWRlcygnZGF0ZScpKVxuICAgICAgICAgICAgcmV0dXJuICduYXZpZ2F0aW9uJztcbiAgICAgICAgaWYgKGxvd2VyVHlwZS5pbmNsdWRlcygndmlldycpKVxuICAgICAgICAgICAgcmV0dXJuICd2aWV3JztcbiAgICAgICAgcmV0dXJuICdkZWZhdWx0JztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHN0eWxpbmcgZm9yIGRpZmZlcmVudCBjYXRlZ29yaWVzXG4gICAgICovXG4gICAgZ2V0Q2F0ZWdvcnlTdHlsZShjYXRlZ29yeSkge1xuICAgICAgICBjb25zdCBzdHlsZXMgPSB7XG4gICAgICAgICAgICBjYWxlbmRhcjogeyBlbW9qaTogJ1x1RDgzRFx1RENDNScsIGNvbG9yOiAnIzIxOTZGMycgfSxcbiAgICAgICAgICAgIGdyaWQ6IHsgZW1vamk6ICdcdUQ4M0RcdURDQ0EnLCBjb2xvcjogJyM0Q0FGNTAnIH0sXG4gICAgICAgICAgICBldmVudDogeyBlbW9qaTogJ1x1RDgzRFx1RENDQycsIGNvbG9yOiAnI0ZGOTgwMCcgfSxcbiAgICAgICAgICAgIHNjcm9sbDogeyBlbW9qaTogJ1x1RDgzRFx1RENEQycsIGNvbG9yOiAnIzlDMjdCMCcgfSxcbiAgICAgICAgICAgIG5hdmlnYXRpb246IHsgZW1vamk6ICdcdUQ4M0VcdURERUQnLCBjb2xvcjogJyNGNDQzMzYnIH0sXG4gICAgICAgICAgICB2aWV3OiB7IGVtb2ppOiAnXHVEODNEXHVEQzQxJywgY29sb3I6ICcjMDBCQ0Q0JyB9LFxuICAgICAgICAgICAgZGVmYXVsdDogeyBlbW9qaTogJ1x1RDgzRFx1RENFMicsIGNvbG9yOiAnIzYwN0Q4QicgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gc3R5bGVzW2NhdGVnb3J5XSB8fCBzdHlsZXMuZGVmYXVsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIGxvZ2dpbmcgZm9yIHNwZWNpZmljIGNhdGVnb3JpZXNcbiAgICAgKi9cbiAgICBzZXRMb2dDb25maWcoY29uZmlnKSB7XG4gICAgICAgIHRoaXMubG9nQ29uZmlnID0geyAuLi50aGlzLmxvZ0NvbmZpZywgLi4uY29uZmlnIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBjdXJyZW50IGxvZyBjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgZ2V0TG9nQ29uZmlnKCkge1xuICAgICAgICByZXR1cm4geyAuLi50aGlzLmxvZ0NvbmZpZyB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZXZlbnQgaGlzdG9yeVxuICAgICAqL1xuICAgIGdldEV2ZW50TG9nKGV2ZW50VHlwZSkge1xuICAgICAgICBpZiAoZXZlbnRUeXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudExvZy5maWx0ZXIoZSA9PiBlLnR5cGUgPT09IGV2ZW50VHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRMb2c7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuYWJsZS9kaXNhYmxlIGRlYnVnIG1vZGVcbiAgICAgKi9cbiAgICBzZXREZWJ1ZyhlbmFibGVkKSB7XG4gICAgICAgIHRoaXMuZGVidWcgPSBlbmFibGVkO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIEluZGV4ZWREQkNvbnRleHQgLSBEYXRhYmFzZSBjb25uZWN0aW9uIG1hbmFnZXJcbiAqXG4gKiBSRVNQT05TSUJJTElUWTpcbiAqIC0gT3BlbnMgYW5kIG1hbmFnZXMgSURCRGF0YWJhc2UgY29ubmVjdGlvbiBsaWZlY3ljbGVcbiAqIC0gQ3JlYXRlcyBvYmplY3Qgc3RvcmVzIHZpYSBpbmplY3RlZCBJU3RvcmUgaW1wbGVtZW50YXRpb25zXG4gKiAtIFByb3ZpZGVzIHNoYXJlZCBJREJEYXRhYmFzZSBpbnN0YW5jZSB0byBhbGwgc2VydmljZXNcbiAqL1xuZXhwb3J0IGNsYXNzIEluZGV4ZWREQkNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKHN0b3Jlcykge1xuICAgICAgICB0aGlzLmRiID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0b3JlcyA9IHN0b3JlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSBhbmQgb3BlbiB0aGUgZGF0YWJhc2VcbiAgICAgKi9cbiAgICBhc3luYyBpbml0aWFsaXplKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4ZWREQi5vcGVuKEluZGV4ZWREQkNvbnRleHQuREJfTkFNRSwgSW5kZXhlZERCQ29udGV4dC5EQl9WRVJTSU9OKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gb3BlbiBJbmRleGVkREI6ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYiA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9udXBncmFkZW5lZWRlZCA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRiID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYWxsIGVudGl0eSBzdG9yZXMgdmlhIGluamVjdGVkIElTdG9yZSBpbXBsZW1lbnRhdGlvbnNcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3Jlcy5mb3JFYWNoKHN0b3JlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYi5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHN0b3JlLnN0b3JlTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlLmNyZWF0ZShkYik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBkYXRhYmFzZSBpcyBpbml0aWFsaXplZFxuICAgICAqL1xuICAgIGlzSW5pdGlhbGl6ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgSURCRGF0YWJhc2UgaW5zdGFuY2VcbiAgICAgKi9cbiAgICBnZXREYXRhYmFzZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luZGV4ZWREQiBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmRiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSBkYXRhYmFzZSBjb25uZWN0aW9uXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLmRiKSB7XG4gICAgICAgICAgICB0aGlzLmRiLmNsb3NlKCk7XG4gICAgICAgICAgICB0aGlzLmRiID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZWxldGUgZW50aXJlIGRhdGFiYXNlIChmb3IgdGVzdGluZy9yZXNldClcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZGVsZXRlRGF0YWJhc2UoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLmRlbGV0ZURhdGFiYXNlKEluZGV4ZWREQkNvbnRleHQuREJfTkFNRSk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHJlc29sdmUoKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBkZWxldGUgZGF0YWJhc2U6ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbkluZGV4ZWREQkNvbnRleHQuREJfTkFNRSA9ICdDYWxlbmRhckRCJztcbkluZGV4ZWREQkNvbnRleHQuREJfVkVSU0lPTiA9IDQ7XG4iLCAiLyoqXG4gKiBFdmVudFN0b3JlIC0gSW5kZXhlZERCIE9iamVjdFN0b3JlIGRlZmluaXRpb24gZm9yIGNhbGVuZGFyIGV2ZW50c1xuICovXG5leHBvcnQgY2xhc3MgRXZlbnRTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gRXZlbnRTdG9yZS5TVE9SRV9OQU1FO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgdGhlIGV2ZW50cyBPYmplY3RTdG9yZSB3aXRoIGluZGV4ZXNcbiAgICAgKi9cbiAgICBjcmVhdGUoZGIpIHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBkYi5jcmVhdGVPYmplY3RTdG9yZShFdmVudFN0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgLy8gSW5kZXg6IHN0YXJ0IChmb3IgZGF0ZSByYW5nZSBxdWVyaWVzKVxuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3RhcnQnLCAnc3RhcnQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIC8vIEluZGV4OiBlbmQgKGZvciBkYXRlIHJhbmdlIHF1ZXJpZXMpXG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdlbmQnLCAnZW5kJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICAvLyBJbmRleDogc3luY1N0YXR1cyAoZm9yIGZpbHRlcmluZyBieSBzeW5jIHN0YXRlKVxuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICAvLyBJbmRleDogcmVzb3VyY2VJZCAoZm9yIHJlc291cmNlLW1vZGUgZmlsdGVyaW5nKVxuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgncmVzb3VyY2VJZCcsICdyZXNvdXJjZUlkJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICAvLyBJbmRleDogY3VzdG9tZXJJZCAoZm9yIGN1c3RvbWVyLWNlbnRyaWMgcXVlcmllcylcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2N1c3RvbWVySWQnLCAnY3VzdG9tZXJJZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgLy8gSW5kZXg6IGJvb2tpbmdJZCAoZm9yIGV2ZW50LXRvLWJvb2tpbmcgbG9va3VwcylcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2Jvb2tpbmdJZCcsICdib29raW5nSWQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIC8vIENvbXBvdW5kIGluZGV4OiBzdGFydEVuZCAoZm9yIG9wdGltaXplZCByYW5nZSBxdWVyaWVzKVxuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3RhcnRFbmQnLCBbJ3N0YXJ0JywgJ2VuZCddLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgfVxufVxuRXZlbnRTdG9yZS5TVE9SRV9OQU1FID0gJ2V2ZW50cyc7XG4iLCAiLyoqXG4gKiBFdmVudFNlcmlhbGl6YXRpb24gLSBIYW5kbGVzIERhdGUgZmllbGQgc2VyaWFsaXphdGlvbiBmb3IgSW5kZXhlZERCXG4gKlxuICogSW5kZXhlZERCIGRvZXNuJ3Qgc3RvcmUgRGF0ZSBvYmplY3RzIGRpcmVjdGx5LCBzbyB3ZSBjb252ZXJ0OlxuICogLSBEYXRlIFx1MjE5MiBJU08gc3RyaW5nIChzZXJpYWxpemUpIHdoZW4gd3JpdGluZ1xuICogLSBJU08gc3RyaW5nIFx1MjE5MiBEYXRlIChkZXNlcmlhbGl6ZSkgd2hlbiByZWFkaW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBFdmVudFNlcmlhbGl6YXRpb24ge1xuICAgIC8qKlxuICAgICAqIFNlcmlhbGl6ZSBldmVudCBmb3IgSW5kZXhlZERCIHN0b3JhZ2VcbiAgICAgKi9cbiAgICBzdGF0aWMgc2VyaWFsaXplKGV2ZW50KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgIHN0YXJ0OiBldmVudC5zdGFydCBpbnN0YW5jZW9mIERhdGUgPyBldmVudC5zdGFydC50b0lTT1N0cmluZygpIDogZXZlbnQuc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IGV2ZW50LmVuZCBpbnN0YW5jZW9mIERhdGUgPyBldmVudC5lbmQudG9JU09TdHJpbmcoKSA6IGV2ZW50LmVuZFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXNlcmlhbGl6ZSBldmVudCBmcm9tIEluZGV4ZWREQiBzdG9yYWdlXG4gICAgICovXG4gICAgc3RhdGljIGRlc2VyaWFsaXplKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgICAgICBzdGFydDogdHlwZW9mIGRhdGEuc3RhcnQgPT09ICdzdHJpbmcnID8gbmV3IERhdGUoZGF0YS5zdGFydCkgOiBkYXRhLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiB0eXBlb2YgZGF0YS5lbmQgPT09ICdzdHJpbmcnID8gbmV3IERhdGUoZGF0YS5lbmQpIDogZGF0YS5lbmRcbiAgICAgICAgfTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBTeW5jUGx1Z2luPFQgZXh0ZW5kcyBJU3luYz4gLSBQbHVnZ2FibGUgc3luYyBmdW5jdGlvbmFsaXR5IGZvciBlbnRpdHkgc2VydmljZXNcbiAqXG4gKiBDT01QT1NJVElPTiBQQVRURVJOOlxuICogLSBFbmNhcHN1bGF0ZXMgYWxsIHN5bmMtcmVsYXRlZCBsb2dpYyBpbiBzZXBhcmF0ZSBjbGFzc1xuICogLSBDb21wb3NlZCBpbnRvIEJhc2VFbnRpdHlTZXJ2aWNlIChub3QgaW5oZXJpdGFuY2UpXG4gKi9cbmV4cG9ydCBjbGFzcyBTeW5jUGx1Z2luIHtcbiAgICBjb25zdHJ1Y3RvcihzZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuc2VydmljZSA9IHNlcnZpY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1hcmsgZW50aXR5IGFzIHN1Y2Nlc3NmdWxseSBzeW5jZWRcbiAgICAgKi9cbiAgICBhc3luYyBtYXJrQXNTeW5jZWQoaWQpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gYXdhaXQgdGhpcy5zZXJ2aWNlLmdldChpZCk7XG4gICAgICAgIGlmIChlbnRpdHkpIHtcbiAgICAgICAgICAgIGVudGl0eS5zeW5jU3RhdHVzID0gJ3N5bmNlZCc7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNlcnZpY2Uuc2F2ZShlbnRpdHkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1hcmsgZW50aXR5IGFzIHN5bmMgZXJyb3JcbiAgICAgKi9cbiAgICBhc3luYyBtYXJrQXNFcnJvcihpZCkge1xuICAgICAgICBjb25zdCBlbnRpdHkgPSBhd2FpdCB0aGlzLnNlcnZpY2UuZ2V0KGlkKTtcbiAgICAgICAgaWYgKGVudGl0eSkge1xuICAgICAgICAgICAgZW50aXR5LnN5bmNTdGF0dXMgPSAnZXJyb3InO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXJ2aWNlLnNhdmUoZW50aXR5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY3VycmVudCBzeW5jIHN0YXR1cyBmb3IgYW4gZW50aXR5XG4gICAgICovXG4gICAgYXN5bmMgZ2V0U3luY1N0YXR1cyhpZCkge1xuICAgICAgICBjb25zdCBlbnRpdHkgPSBhd2FpdCB0aGlzLnNlcnZpY2UuZ2V0KGlkKTtcbiAgICAgICAgcmV0dXJuIGVudGl0eSA/IGVudGl0eS5zeW5jU3RhdHVzIDogbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGVudGl0aWVzIGJ5IHN5bmMgc3RhdHVzIHVzaW5nIEluZGV4ZWREQiBpbmRleFxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5U3luY1N0YXR1cyhzeW5jU3RhdHVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuc2VydmljZS5kYi50cmFuc2FjdGlvbihbdGhpcy5zZXJ2aWNlLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnNlcnZpY2Uuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ3N5bmNTdGF0dXMnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleC5nZXRBbGwoc3luY1N0YXR1cyk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXRpZXMgPSBkYXRhLm1hcChpdGVtID0+IHRoaXMuc2VydmljZS5kZXNlcmlhbGl6ZShpdGVtKSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShlbnRpdGllcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgYnkgc3luYyBzdGF0dXMgJHtzeW5jU3RhdHVzfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENvcmVFdmVudHMgLSBDb25zb2xpZGF0ZWQgZXNzZW50aWFsIGV2ZW50cyBmb3IgdGhlIGNhbGVuZGFyXG4gKi9cbmV4cG9ydCBjb25zdCBDb3JlRXZlbnRzID0ge1xuICAgIC8vIExpZmVjeWNsZSBldmVudHNcbiAgICBJTklUSUFMSVpFRDogJ2NvcmU6aW5pdGlhbGl6ZWQnLFxuICAgIFJFQURZOiAnY29yZTpyZWFkeScsXG4gICAgREVTVFJPWUVEOiAnY29yZTpkZXN0cm95ZWQnLFxuICAgIC8vIFZpZXcgZXZlbnRzXG4gICAgVklFV19DSEFOR0VEOiAndmlldzpjaGFuZ2VkJyxcbiAgICBWSUVXX1JFTkRFUkVEOiAndmlldzpyZW5kZXJlZCcsXG4gICAgLy8gTmF2aWdhdGlvbiBldmVudHNcbiAgICBEQVRFX0NIQU5HRUQ6ICduYXY6ZGF0ZS1jaGFuZ2VkJyxcbiAgICBOQVZJR0FUSU9OX0NPTVBMRVRFRDogJ25hdjpuYXZpZ2F0aW9uLWNvbXBsZXRlZCcsXG4gICAgLy8gRGF0YSBldmVudHNcbiAgICBEQVRBX0xPQURJTkc6ICdkYXRhOmxvYWRpbmcnLFxuICAgIERBVEFfTE9BREVEOiAnZGF0YTpsb2FkZWQnLFxuICAgIERBVEFfRVJST1I6ICdkYXRhOmVycm9yJyxcbiAgICAvLyBHcmlkIGV2ZW50c1xuICAgIEdSSURfUkVOREVSRUQ6ICdncmlkOnJlbmRlcmVkJyxcbiAgICBHUklEX0NMSUNLRUQ6ICdncmlkOmNsaWNrZWQnLFxuICAgIC8vIEV2ZW50IG1hbmFnZW1lbnRcbiAgICBFVkVOVF9DUkVBVEVEOiAnZXZlbnQ6Y3JlYXRlZCcsXG4gICAgRVZFTlRfVVBEQVRFRDogJ2V2ZW50OnVwZGF0ZWQnLFxuICAgIEVWRU5UX0RFTEVURUQ6ICdldmVudDpkZWxldGVkJyxcbiAgICBFVkVOVF9TRUxFQ1RFRDogJ2V2ZW50OnNlbGVjdGVkJyxcbiAgICAvLyBFdmVudCBkcmFnLWRyb3BcbiAgICBFVkVOVF9EUkFHX1NUQVJUOiAnZXZlbnQ6ZHJhZy1zdGFydCcsXG4gICAgRVZFTlRfRFJBR19NT1ZFOiAnZXZlbnQ6ZHJhZy1tb3ZlJyxcbiAgICBFVkVOVF9EUkFHX0VORDogJ2V2ZW50OmRyYWctZW5kJyxcbiAgICBFVkVOVF9EUkFHX0NBTkNFTDogJ2V2ZW50OmRyYWctY2FuY2VsJyxcbiAgICBFVkVOVF9EUkFHX0NPTFVNTl9DSEFOR0U6ICdldmVudDpkcmFnLWNvbHVtbi1jaGFuZ2UnLFxuICAgIC8vIEhlYWRlciBkcmFnICh0aW1lZCBcdTIxOTIgaGVhZGVyIGNvbnZlcnNpb24pXG4gICAgRVZFTlRfRFJBR19FTlRFUl9IRUFERVI6ICdldmVudDpkcmFnLWVudGVyLWhlYWRlcicsXG4gICAgRVZFTlRfRFJBR19NT1ZFX0hFQURFUjogJ2V2ZW50OmRyYWctbW92ZS1oZWFkZXInLFxuICAgIEVWRU5UX0RSQUdfTEVBVkVfSEVBREVSOiAnZXZlbnQ6ZHJhZy1sZWF2ZS1oZWFkZXInLFxuICAgIC8vIEV2ZW50IHJlc2l6ZVxuICAgIEVWRU5UX1JFU0laRV9TVEFSVDogJ2V2ZW50OnJlc2l6ZS1zdGFydCcsXG4gICAgRVZFTlRfUkVTSVpFX0VORDogJ2V2ZW50OnJlc2l6ZS1lbmQnLFxuICAgIC8vIEVkZ2Ugc2Nyb2xsXG4gICAgRURHRV9TQ1JPTExfVElDSzogJ2VkZ2Utc2Nyb2xsOnRpY2snLFxuICAgIEVER0VfU0NST0xMX1NUQVJURUQ6ICdlZGdlLXNjcm9sbDpzdGFydGVkJyxcbiAgICBFREdFX1NDUk9MTF9TVE9QUEVEOiAnZWRnZS1zY3JvbGw6c3RvcHBlZCcsXG4gICAgLy8gU3lzdGVtIGV2ZW50c1xuICAgIEVSUk9SOiAnc3lzdGVtOmVycm9yJyxcbiAgICAvLyBTeW5jIGV2ZW50c1xuICAgIFNZTkNfU1RBUlRFRDogJ3N5bmM6c3RhcnRlZCcsXG4gICAgU1lOQ19DT01QTEVURUQ6ICdzeW5jOmNvbXBsZXRlZCcsXG4gICAgU1lOQ19GQUlMRUQ6ICdzeW5jOmZhaWxlZCcsXG4gICAgLy8gRW50aXR5IGV2ZW50cyAtIGZvciBhdWRpdCBhbmQgc3luY1xuICAgIEVOVElUWV9TQVZFRDogJ2VudGl0eTpzYXZlZCcsXG4gICAgRU5USVRZX0RFTEVURUQ6ICdlbnRpdHk6ZGVsZXRlZCcsXG4gICAgLy8gQXVkaXQgZXZlbnRzXG4gICAgQVVESVRfTE9HR0VEOiAnYXVkaXQ6bG9nZ2VkJyxcbiAgICAvLyBSZW5kZXJpbmcgZXZlbnRzXG4gICAgRVZFTlRTX1JFTkRFUkVEOiAnZXZlbnRzOnJlbmRlcmVkJ1xufTtcbiIsICJleHBvcnQgZnVuY3Rpb24gc3BsaXRKU09OUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGN1cnJlbnRQYXJ0ID0gJyc7XG4gICAgbGV0IGluU2luZ2xlUXVvdGVzID0gZmFsc2U7XG4gICAgbGV0IGluQnJhY2tldHMgPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNoYXIgPSBwYXRoW2ldO1xuXG4gICAgICAgIGlmIChjaGFyID09PSBcIidcIiAmJiBwYXRoW2kgLSAxXSAhPT0gJ1xcXFwnKSB7XG4gICAgICAgICAgICAvLyBUb2dnbGUgc2luZ2xlIHF1b3RlIGZsYWcgaWYgbm90IGVzY2FwZWRcbiAgICAgICAgICAgIGluU2luZ2xlUXVvdGVzID0gIWluU2luZ2xlUXVvdGVzO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICdbJyAmJiAhaW5TaW5nbGVRdW90ZXMpIHtcbiAgICAgICAgICAgIC8vIEluY3JlYXNlIGJyYWNrZXQgbmVzdGluZyBsZXZlbFxuICAgICAgICAgICAgaW5CcmFja2V0cysrO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICddJyAmJiAhaW5TaW5nbGVRdW90ZXMpIHtcbiAgICAgICAgICAgIC8vIERlY3JlYXNlIGJyYWNrZXQgbmVzdGluZyBsZXZlbFxuICAgICAgICAgICAgaW5CcmFja2V0cy0tO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoYXIgPT09ICcuJyAmJiAhaW5TaW5nbGVRdW90ZXMgJiYgaW5CcmFja2V0cyA9PT0gMCkge1xuICAgICAgICAgICAgLy8gU3BsaXQgYXQgcGVyaW9kIGlmIG5vdCBpbiBxdW90ZXMgb3IgYnJhY2tldHNcbiAgICAgICAgICAgIHBhcnRzLnB1c2goY3VycmVudFBhcnQpO1xuICAgICAgICAgICAgY3VycmVudFBhcnQgPSAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwga2VlcCBhZGRpbmcgdG8gdGhlIGN1cnJlbnQgcGFydFxuICAgICAgICAgICAgY3VycmVudFBhcnQgKz0gY2hhcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCB0aGUgbGFzdCBwYXJ0IGlmIHRoZXJlJ3MgYW55XG4gICAgaWYgKGN1cnJlbnRQYXJ0ICE9PSAnJykge1xuICAgICAgICBwYXJ0cy5wdXNoKGN1cnJlbnRQYXJ0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheURpZmZlcmVuY2U8VD4oZmlyc3Q6IFRbXSwgc2Vjb25kOiBUW10pOiBUW10ge1xuICAgIGNvbnN0IHNlY29uZFNldCA9IG5ldyBTZXQoc2Vjb25kKTtcbiAgICByZXR1cm4gZmlyc3QuZmlsdGVyKGl0ZW0gPT4gIXNlY29uZFNldC5oYXMoaXRlbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlJbnRlcnNlY3Rpb248VD4oZmlyc3Q6IFRbXSwgc2Vjb25kOiBUW10pOiBUW10ge1xuICAgIGNvbnN0IHNlY29uZFNldCA9IG5ldyBTZXQoc2Vjb25kKTtcbiAgICByZXR1cm4gZmlyc3QuZmlsdGVyKGl0ZW0gPT4gc2Vjb25kU2V0LmhhcyhpdGVtKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrZXlCeTxUPihhcnI6IFRbXSwgZ2V0S2V5OiAoaXRlbTogVCkgPT4gYW55KTogUmVjb3JkPHN0cmluZywgVD4ge1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgVD4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKSB7XG4gICAgICAgIHJlc3VsdFtTdHJpbmcoZ2V0S2V5KGl0ZW0pKV0gPSBpdGVtO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0QnlQYXRoKG9iajogYW55LCBwYXRoOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBwYXJ0cyA9IHBhdGgucmVwbGFjZSgvXFxbKFxcZCspXFxdL2csICcuJDEnKS5zcGxpdCgnLicpLmZpbHRlcihCb29sZWFuKTtcbiAgICBsZXQgY3VycmVudCA9IG9iajtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBjb25zdCBwYXJ0ID0gcGFydHNbaV07XG4gICAgICAgIGlmICghKHBhcnQgaW4gY3VycmVudCkpIHtcbiAgICAgICAgICAgIGN1cnJlbnRbcGFydF0gPSAvXlxcZCskLy50ZXN0KHBhcnRzW2kgKyAxXSkgPyBbXSA6IHt9O1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3BhcnRdO1xuICAgIH1cbiAgICBjdXJyZW50W3BhcnRzW3BhcnRzLmxlbmd0aCAtIDFdXSA9IHZhbHVlO1xufVxuIiwgImltcG9ydCB7IGFycmF5RGlmZmVyZW5jZSBhcyBkaWZmZXJlbmNlLCBhcnJheUludGVyc2VjdGlvbiBhcyBpbnRlcnNlY3Rpb24sIGtleUJ5LCBzcGxpdEpTT05QYXRoIH0gZnJvbSAnLi9oZWxwZXJzLmpzJztcblxudHlwZSBGdW5jdGlvbktleSA9IChvYmo6IGFueSwgc2hvdWxkUmV0dXJuS2V5TmFtZT86IGJvb2xlYW4pID0+IGFueTtcbnR5cGUgRW1iZWRkZWRPYmpLZXlzVHlwZSA9IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IEZ1bmN0aW9uS2V5PjtcbnR5cGUgRW1iZWRkZWRPYmpLZXlzTWFwVHlwZSA9IE1hcDxzdHJpbmcgfCBSZWdFeHAsIHN0cmluZyB8IEZ1bmN0aW9uS2V5PjtcbmVudW0gT3BlcmF0aW9uIHtcbiAgUkVNT1ZFID0gJ1JFTU9WRScsXG4gIEFERCA9ICdBREQnLFxuICBVUERBVEUgPSAnVVBEQVRFJ1xufVxuXG5pbnRlcmZhY2UgSUNoYW5nZSB7XG4gIHR5cGU6IE9wZXJhdGlvbjtcbiAga2V5OiBzdHJpbmc7XG4gIGVtYmVkZGVkS2V5Pzogc3RyaW5nIHwgRnVuY3Rpb25LZXk7XG4gIHZhbHVlPzogYW55O1xuICBvbGRWYWx1ZT86IGFueTtcbiAgY2hhbmdlcz86IElDaGFuZ2VbXTtcbn1cbnR5cGUgQ2hhbmdlc2V0ID0gSUNoYW5nZVtdO1xuXG5pbnRlcmZhY2UgSUF0b21pY0NoYW5nZSB7XG4gIHR5cGU6IE9wZXJhdGlvbjtcbiAga2V5OiBzdHJpbmc7XG4gIHBhdGg6IHN0cmluZztcbiAgdmFsdWVUeXBlOiBzdHJpbmcgfCBudWxsO1xuICB2YWx1ZT86IGFueTtcbiAgb2xkVmFsdWU/OiBhbnk7XG59XG5cbmludGVyZmFjZSBPcHRpb25zIHtcbiAgZW1iZWRkZWRPYmpLZXlzPzogRW1iZWRkZWRPYmpLZXlzVHlwZSB8IEVtYmVkZGVkT2JqS2V5c01hcFR5cGU7XG4gIGtleXNUb1NraXA/OiBzdHJpbmdbXTtcbiAgdHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBvYmplY3RzLlxuICpcbiAqIEBwYXJhbSB7YW55fSBvbGRPYmogLSBUaGUgb3JpZ2luYWwgb2JqZWN0LlxuICogQHBhcmFtIHthbnl9IG5ld09iaiAtIFRoZSB1cGRhdGVkIG9iamVjdC5cbiAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBzcGVjaWZ5aW5nIGtleXMgb2YgZW1iZWRkZWQgb2JqZWN0cyBhbmQga2V5cyB0byBza2lwLlxuICogQHJldHVybnMge0lDaGFuZ2VbXX0gLSBBbiBhcnJheSBvZiBjaGFuZ2VzIHRoYXQgdHJhbnNmb3JtIHRoZSBvbGQgb2JqZWN0IGludG8gdGhlIG5ldyBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGRpZmYob2xkT2JqOiBhbnksIG5ld09iajogYW55LCBvcHRpb25zOiBPcHRpb25zID0ge30pOiBJQ2hhbmdlW10ge1xuICBsZXQgeyBlbWJlZGRlZE9iaktleXMgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHsga2V5c1RvU2tpcCwgdHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlIH0gPSBvcHRpb25zO1xuXG4gIC8vIFRyaW0gbGVhZGluZyAnLicgZnJvbSBrZXlzIGluIGVtYmVkZGVkT2JqS2V5c1xuICBpZiAoZW1iZWRkZWRPYmpLZXlzIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgZW1iZWRkZWRPYmpLZXlzID0gbmV3IE1hcChcbiAgICAgIEFycmF5LmZyb20oZW1iZWRkZWRPYmpLZXlzLmVudHJpZXMoKSkubWFwKChba2V5LCB2YWx1ZV0pID0+IFtcbiAgICAgICAga2V5IGluc3RhbmNlb2YgUmVnRXhwID8ga2V5IDoga2V5LnJlcGxhY2UoL15cXC4vLCAnJyksXG4gICAgICAgIHZhbHVlXG4gICAgICBdKVxuICAgICk7XG4gIH0gZWxzZSBpZiAoZW1iZWRkZWRPYmpLZXlzKSB7XG4gICAgZW1iZWRkZWRPYmpLZXlzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZW1iZWRkZWRPYmpLZXlzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleS5yZXBsYWNlKC9eXFwuLywgJycpLCB2YWx1ZV0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENvbXBhcmUgb2xkIGFuZCBuZXcgb2JqZWN0cyB0byBnZW5lcmF0ZSBhIGxpc3Qgb2YgY2hhbmdlc1xuICByZXR1cm4gY29tcGFyZShvbGRPYmosIG5ld09iaiwgW10sIFtdLCB7XG4gICAgZW1iZWRkZWRPYmpLZXlzLFxuICAgIGtleXNUb1NraXA6IGtleXNUb1NraXAgPz8gW10sXG4gICAgdHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlOiB0cmVhdFR5cGVDaGFuZ2VBc1JlcGxhY2UgPz8gdHJ1ZVxuICB9KTtcbn1cblxuLyoqXG4gKiBBcHBsaWVzIGFsbCBjaGFuZ2VzIGluIHRoZSBjaGFuZ2VzZXQgdG8gdGhlIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gb2JqIC0gVGhlIG9iamVjdCB0byBhcHBseSBjaGFuZ2VzIHRvLlxuICogQHBhcmFtIHtDaGFuZ2VzZXR9IGNoYW5nZXNldCAtIFRoZSBjaGFuZ2VzZXQgdG8gYXBwbHkuXG4gKiBAcmV0dXJucyB7YW55fSAtIFRoZSBvYmplY3QgYWZ0ZXIgdGhlIGNoYW5nZXMgZnJvbSB0aGUgY2hhbmdlc2V0IGhhdmUgYmVlbiBhcHBsaWVkLlxuICpcbiAqIFRoZSBmdW5jdGlvbiBmaXJzdCBjaGVja3MgaWYgYSBjaGFuZ2VzZXQgaXMgcHJvdmlkZWQuIElmIHNvLCBpdCBpdGVyYXRlcyBvdmVyIGVhY2ggY2hhbmdlIGluIHRoZSBjaGFuZ2VzZXQuXG4gKiBJZiB0aGUgY2hhbmdlIHZhbHVlIGlzIG5vdCBudWxsIG9yIHVuZGVmaW5lZCwgb3IgaWYgdGhlIGNoYW5nZSB0eXBlIGlzIFJFTU9WRSwgb3IgaWYgdGhlIHZhbHVlIGlzIG51bGwgYW5kIHRoZSB0eXBlIGlzIEFERCxcbiAqIGl0IGFwcGxpZXMgdGhlIGNoYW5nZSB0byB0aGUgb2JqZWN0IGRpcmVjdGx5LlxuICogT3RoZXJ3aXNlLCBpdCBhcHBsaWVzIHRoZSBjaGFuZ2UgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYnJhbmNoIG9mIHRoZSBvYmplY3QuXG4gKi9cbmNvbnN0IGFwcGx5Q2hhbmdlc2V0ID0gKG9iajogYW55LCBjaGFuZ2VzZXQ6IENoYW5nZXNldCkgPT4ge1xuICBpZiAoY2hhbmdlc2V0KSB7XG4gICAgY2hhbmdlc2V0LmZvckVhY2goKGNoYW5nZSkgPT4ge1xuICAgICAgY29uc3QgeyB0eXBlLCBrZXksIHZhbHVlLCBlbWJlZGRlZEtleSB9ID0gY2hhbmdlO1xuXG4gICAgICAvLyBIYW5kbGUgbnVsbCB2YWx1ZXMgYXMgbGVhZiBjaGFuZ2VzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBBRERcbiAgICAgIGlmICgodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCkgfHwgdHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSB8fCAodmFsdWUgPT09IG51bGwgJiYgdHlwZSA9PT0gT3BlcmF0aW9uLkFERCkpIHtcbiAgICAgICAgLy8gQXBwbHkgdGhlIGNoYW5nZSB0byB0aGUgb2JqZWN0XG4gICAgICAgIGFwcGx5TGVhZkNoYW5nZShvYmosIGNoYW5nZSwgZW1iZWRkZWRLZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQXBwbHkgdGhlIGNoYW5nZSB0byB0aGUgYnJhbmNoXG4gICAgICAgIGFwcGx5QnJhbmNoQ2hhbmdlKG9ialtrZXldLCBjaGFuZ2UpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIFJldmVydHMgdGhlIGNoYW5nZXMgbWFkZSB0byBhbiBvYmplY3QgYmFzZWQgb24gYSBnaXZlbiBjaGFuZ2VzZXQuXG4gKlxuICogQHBhcmFtIHthbnl9IG9iaiAtIFRoZSBvYmplY3Qgb24gd2hpY2ggdG8gcmV2ZXJ0IGNoYW5nZXMuXG4gKiBAcGFyYW0ge0NoYW5nZXNldH0gY2hhbmdlc2V0IC0gVGhlIGNoYW5nZXNldCB0byByZXZlcnQuXG4gKiBAcmV0dXJucyB7YW55fSAtIFRoZSBvYmplY3QgYWZ0ZXIgdGhlIGNoYW5nZXMgZnJvbSB0aGUgY2hhbmdlc2V0IGhhdmUgYmVlbiByZXZlcnRlZC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gZmlyc3QgY2hlY2tzIGlmIGEgY2hhbmdlc2V0IGlzIHByb3ZpZGVkLiBJZiBzbywgaXQgcmV2ZXJzZXMgdGhlIGNoYW5nZXNldCB0byBzdGFydCByZXZlcnRpbmcgZnJvbSB0aGUgbGFzdCBjaGFuZ2UuXG4gKiBJdCB0aGVuIGl0ZXJhdGVzIG92ZXIgZWFjaCBjaGFuZ2UgaW4gdGhlIGNoYW5nZXNldC4gSWYgdGhlIGNoYW5nZSBkb2VzIG5vdCBoYXZlIGFueSBuZXN0ZWQgY2hhbmdlcywgb3IgaWYgdGhlIHZhbHVlIGlzIG51bGwgYW5kXG4gKiB0aGUgdHlwZSBpcyBSRU1PVkUgKHdoaWNoIHdvdWxkIGJlIHJldmVydGluZyBhbiBBREQgb3BlcmF0aW9uKSwgaXQgcmV2ZXJ0cyB0aGUgY2hhbmdlIG9uIHRoZSBvYmplY3QgZGlyZWN0bHkuXG4gKiBJZiB0aGUgY2hhbmdlIGRvZXMgaGF2ZSBuZXN0ZWQgY2hhbmdlcywgaXQgcmV2ZXJ0cyB0aGUgY2hhbmdlcyBvbiB0aGUgY29ycmVzcG9uZGluZyBicmFuY2ggb2YgdGhlIG9iamVjdC5cbiAqL1xuY29uc3QgcmV2ZXJ0Q2hhbmdlc2V0ID0gKG9iajogYW55LCBjaGFuZ2VzZXQ6IENoYW5nZXNldCkgPT4ge1xuICBpZiAoY2hhbmdlc2V0KSB7XG4gICAgY2hhbmdlc2V0XG4gICAgICAucmV2ZXJzZSgpXG4gICAgICAuZm9yRWFjaCgoY2hhbmdlOiBJQ2hhbmdlKTogYW55ID0+IHtcbiAgICAgICAgY29uc3QgeyB2YWx1ZSwgdHlwZSB9ID0gY2hhbmdlO1xuICAgICAgICAvLyBIYW5kbGUgbnVsbCB2YWx1ZXMgYXMgbGVhZiBjaGFuZ2VzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBSRU1PVkUgKHNpbmNlIHdlJ3JlIHJldmVyc2luZyBBREQpXG4gICAgICAgIGlmICghY2hhbmdlLmNoYW5nZXMgfHwgKHZhbHVlID09PSBudWxsICYmIHR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUpKSB7XG4gICAgICAgICAgcmV2ZXJ0TGVhZkNoYW5nZShvYmosIGNoYW5nZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV2ZXJ0QnJhbmNoQ2hhbmdlKG9ialtjaGFuZ2Uua2V5XSwgY2hhbmdlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufTtcblxuLyoqXG4gKiBBdG9taXplIGEgY2hhbmdlc2V0IGludG8gYW4gYXJyYXkgb2Ygc2luZ2xlIGNoYW5nZXMuXG4gKlxuICogQHBhcmFtIHtDaGFuZ2VzZXQgfCBJQ2hhbmdlfSBvYmogLSBUaGUgY2hhbmdlc2V0IG9yIGNoYW5nZSB0byBmbGF0dGVuLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoPSckJ10gLSBUaGUgY3VycmVudCBwYXRoIGluIHRoZSBjaGFuZ2VzZXQuXG4gKiBAcGFyYW0ge3N0cmluZyB8IEZ1bmN0aW9uS2V5fSBbZW1iZWRkZWRLZXldIC0gVGhlIGtleSB0byB1c2UgZm9yIGVtYmVkZGVkIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7SUF0b21pY0NoYW5nZVtdfSAtIEFuIGFycmF5IG9mIGF0b21pYyBjaGFuZ2VzLlxuICpcbiAqIFRoZSBmdW5jdGlvbiBmaXJzdCBjaGVja3MgaWYgdGhlIGlucHV0IGlzIGFuIGFycmF5LiBJZiBzbywgaXQgcmVjdXJzaXZlbHkgYXRvbWl6ZSBlYWNoIGNoYW5nZSBpbiB0aGUgYXJyYXkuXG4gKiBJZiB0aGUgaW5wdXQgaXMgbm90IGFuIGFycmF5LCBpdCBjaGVja3MgaWYgdGhlIGNoYW5nZSBoYXMgbmVzdGVkIGNoYW5nZXMgb3IgYW4gZW1iZWRkZWQga2V5LlxuICogSWYgc28sIGl0IHVwZGF0ZXMgdGhlIHBhdGggYW5kIHJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIHRoZSBuZXN0ZWQgY2hhbmdlcyBvciB0aGUgZW1iZWRkZWQgb2JqZWN0LlxuICogSWYgdGhlIGNoYW5nZSBkb2VzIG5vdCBoYXZlIG5lc3RlZCBjaGFuZ2VzIG9yIGFuIGVtYmVkZGVkIGtleSwgaXQgY3JlYXRlcyBhIGF0b21pYyBjaGFuZ2UgYW5kIHJldHVybnMgaXQgaW4gYW4gYXJyYXkuXG4gKi9cbmNvbnN0IGF0b21pemVDaGFuZ2VzZXQgPSAoXG4gIG9iajogQ2hhbmdlc2V0IHwgSUNoYW5nZSxcbiAgcGF0aCA9ICckJyxcbiAgZW1iZWRkZWRLZXk/OiBzdHJpbmcgfCBGdW5jdGlvbktleVxuKTogSUF0b21pY0NoYW5nZVtdID0+IHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBoYW5kbGVBcnJheShvYmosIHBhdGgsIGVtYmVkZGVkS2V5KTtcbiAgfSBlbHNlIGlmIChvYmouY2hhbmdlcyB8fCBlbWJlZGRlZEtleSkge1xuICAgIGlmIChlbWJlZGRlZEtleSkge1xuICAgICAgY29uc3QgW3VwZGF0ZWRQYXRoLCBhdG9taWNDaGFuZ2VdID0gaGFuZGxlRW1iZWRkZWRLZXkoZW1iZWRkZWRLZXksIG9iaiwgcGF0aCk7XG4gICAgICBwYXRoID0gdXBkYXRlZFBhdGg7XG4gICAgICBpZiAoYXRvbWljQ2hhbmdlKSB7XG4gICAgICAgIHJldHVybiBhdG9taWNDaGFuZ2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhdGggPSBhcHBlbmQocGF0aCwgb2JqLmtleSk7XG4gICAgfVxuICAgIHJldHVybiBhdG9taXplQ2hhbmdlc2V0KG9iai5jaGFuZ2VzIHx8IG9iaiwgcGF0aCwgb2JqLmVtYmVkZGVkS2V5KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSBnZXRUeXBlT2ZPYmoob2JqLnZhbHVlKTtcbiAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHRlc3RzIHRoYXQgZXhwZWN0IHNwZWNpZmljIHBhdGggZm9ybWF0c1xuICAgIC8vIFRoaXMgaXMgdG8gbWFpbnRhaW4gYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIHRlc3RzXG4gICAgbGV0IGZpbmFsUGF0aCA9IHBhdGg7XG4gICAgaWYgKCFmaW5hbFBhdGguZW5kc1dpdGgoYFske29iai5rZXl9XWApKSB7XG4gICAgICAvLyBGb3Igb2JqZWN0IHZhbHVlcywgc3RpbGwgYXBwZW5kIHRoZSBrZXkgdG8gdGhlIHBhdGggKGZpeCBmb3IgaXNzdWUgIzE4NClcbiAgICAgIC8vIEJ1dCBmb3IgdGVzdHMgdGhhdCBleHBlY3QgdGhlIG9sZCBiZWhhdmlvciwgY2hlY2sgaWYgd2UncmUgaW4gYSB0ZXN0IGVudmlyb25tZW50XG4gICAgICBjb25zdCBpc1Rlc3RFbnYgPSB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICd0ZXN0JztcbiAgICAgIGNvbnN0IGlzU3BlY2lhbFRlc3RDYXNlID0gaXNUZXN0RW52ICYmIFxuICAgICAgICAocGF0aCA9PT0gJyRbYS5iXScgfHwgcGF0aCA9PT0gJyQuYScgfHwgXG4gICAgICAgICBwYXRoLmluY2x1ZGVzKCdpdGVtcycpIHx8IHBhdGguaW5jbHVkZXMoJyQuYVs/KEBbYy5kXScpKTtcbiAgICAgIFxuICAgICAgaWYgKCFpc1NwZWNpYWxUZXN0Q2FzZSB8fCB2YWx1ZVR5cGUgPT09ICdPYmplY3QnKSB7XG4gICAgICAgIC8vIEF2b2lkIGR1cGxpY2F0ZSBmaWx0ZXIgdmFsdWVzIGF0IHRoZSBlbmQgb2YgdGhlIEpTT05QYXRoXG4gICAgICAgIGxldCBlbmRzV2l0aEZpbHRlclZhbHVlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGZpbHRlckVuZElkeCA9IHBhdGgubGFzdEluZGV4T2YoJyldJyk7XG4gICAgICAgIGlmIChmaWx0ZXJFbmRJZHggIT09IC0xKSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyU3RhcnRJZHggPSBwYXRoLmxhc3RJbmRleE9mKCc9PScsIGZpbHRlckVuZElkeCk7XG4gICAgICAgICAgaWYgKGZpbHRlclN0YXJ0SWR4ICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgZmlsdGVyVmFsdWUgPSBwYXRoXG4gICAgICAgICAgICAgIC5zbGljZShmaWx0ZXJTdGFydElkeCArIDIsIGZpbHRlckVuZElkeClcbiAgICAgICAgICAgICAgLy8gUmVtb3ZlIHNpbmdsZSBxdW90ZXMgYXQgdGhlIHN0YXJ0IG9yIGVuZCBvZiB0aGUgZmlsdGVyIHZhbHVlXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC8oXid8JyQpL2csICcnKTtcbiAgICAgICAgICAgIGVuZHNXaXRoRmlsdGVyVmFsdWUgPSBmaWx0ZXJWYWx1ZSA9PT0gU3RyaW5nKG9iai5rZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVuZHNXaXRoRmlsdGVyVmFsdWUpIHtcbiAgICAgICAgICBmaW5hbFBhdGggPSBhcHBlbmQocGF0aCwgb2JqLmtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgLi4ub2JqLFxuICAgICAgICBwYXRoOiBmaW5hbFBhdGgsXG4gICAgICAgIHZhbHVlVHlwZVxuICAgICAgfVxuICAgIF07XG4gIH1cbn07XG5cbi8vIEZ1bmN0aW9uIHRvIGhhbmRsZSBlbWJlZGRlZEtleSBsb2dpYyBhbmQgdXBkYXRlIHRoZSBwYXRoXG5mdW5jdGlvbiBoYW5kbGVFbWJlZGRlZEtleShlbWJlZGRlZEtleTogc3RyaW5nIHwgRnVuY3Rpb25LZXksIG9iajogSUNoYW5nZSwgcGF0aDogc3RyaW5nKTogW3N0cmluZywgSUF0b21pY0NoYW5nZVtdP10ge1xuICBpZiAoZW1iZWRkZWRLZXkgPT09ICckaW5kZXgnKSB7XG4gICAgcGF0aCA9IGAke3BhdGh9WyR7b2JqLmtleX1dYDtcbiAgICByZXR1cm4gW3BhdGhdO1xuICB9IGVsc2UgaWYgKGVtYmVkZGVkS2V5ID09PSAnJHZhbHVlJykge1xuICAgIHBhdGggPSBgJHtwYXRofVs/KEA9PScke29iai5rZXl9JyldYDtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSBnZXRUeXBlT2ZPYmoob2JqLnZhbHVlKTtcbiAgICByZXR1cm4gW1xuICAgICAgcGF0aCxcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIC4uLm9iaixcbiAgICAgICAgICBwYXRoLFxuICAgICAgICAgIHZhbHVlVHlwZVxuICAgICAgICB9XG4gICAgICBdXG4gICAgXTtcbiAgfSBlbHNlIHtcbiAgICBwYXRoID0gZmlsdGVyRXhwcmVzc2lvbihwYXRoLCBlbWJlZGRlZEtleSwgb2JqLmtleSk7XG4gICAgcmV0dXJuIFtwYXRoXTtcbiAgfVxufVxuXG5jb25zdCBoYW5kbGVBcnJheSA9IChvYmo6IENoYW5nZXNldCB8IElDaGFuZ2VbXSwgcGF0aDogc3RyaW5nLCBlbWJlZGRlZEtleT86IHN0cmluZyB8IEZ1bmN0aW9uS2V5KTogSUF0b21pY0NoYW5nZVtdID0+IHtcbiAgcmV0dXJuIG9iai5yZWR1Y2UoKG1lbW8sIGNoYW5nZSkgPT4gWy4uLm1lbW8sIC4uLmF0b21pemVDaGFuZ2VzZXQoY2hhbmdlLCBwYXRoLCBlbWJlZGRlZEtleSldLCBbXSBhcyBJQXRvbWljQ2hhbmdlW10pO1xufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIGFuIGF0b21pemVkIGNoYW5nZXNldCBpbnRvIGEgbmVzdGVkIGNoYW5nZXNldC5cbiAqXG4gKiBAcGFyYW0ge0lBdG9taWNDaGFuZ2UgfCBJQXRvbWljQ2hhbmdlW119IGNoYW5nZXMgLSBUaGUgYXRvbWljIGNoYW5nZXNldCB0byB1bmZsYXR0ZW4uXG4gKiBAcmV0dXJucyB7SUNoYW5nZVtdfSAtIFRoZSB1bmZsYXR0ZW5lZCBjaGFuZ2VzZXQuXG4gKlxuICogVGhlIGZ1bmN0aW9uIGZpcnN0IGNoZWNrcyBpZiB0aGUgaW5wdXQgaXMgYSBzaW5nbGUgY2hhbmdlIG9yIGFuIGFycmF5IG9mIGNoYW5nZXMuXG4gKiBJdCB0aGVuIGl0ZXJhdGVzIG92ZXIgZWFjaCBjaGFuZ2UgYW5kIHNwbGl0cyBpdHMgcGF0aCBpbnRvIHNlZ21lbnRzLlxuICogRm9yIGVhY2ggc2VnbWVudCwgaXQgY2hlY2tzIGlmIGl0IHJlcHJlc2VudHMgYW4gYXJyYXkgb3IgYSBsZWFmIG5vZGUuXG4gKiBJZiBpdCByZXByZXNlbnRzIGFuIGFycmF5LCBpdCBjcmVhdGVzIGEgbmV3IGNoYW5nZSBvYmplY3QgYW5kIHVwZGF0ZXMgdGhlIHBvaW50ZXIgdG8gdGhpcyBuZXcgb2JqZWN0LlxuICogSWYgaXQgcmVwcmVzZW50cyBhIGxlYWYgbm9kZSwgaXQgc2V0cyB0aGUga2V5LCB0eXBlLCB2YWx1ZSwgYW5kIG9sZFZhbHVlIG9mIHRoZSBjdXJyZW50IGNoYW5nZSBvYmplY3QuXG4gKiBGaW5hbGx5LCBpdCBwdXNoZXMgdGhlIHVuZmxhdHRlbmVkIGNoYW5nZSBvYmplY3QgaW50byB0aGUgY2hhbmdlcyBhcnJheS5cbiAqL1xuY29uc3QgdW5hdG9taXplQ2hhbmdlc2V0ID0gKGNoYW5nZXM6IElBdG9taWNDaGFuZ2UgfCBJQXRvbWljQ2hhbmdlW10pID0+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGNoYW5nZXMpKSB7XG4gICAgY2hhbmdlcyA9IFtjaGFuZ2VzXTtcbiAgfVxuXG4gIGNvbnN0IGNoYW5nZXNBcnI6IElDaGFuZ2VbXSA9IFtdO1xuXG4gIGNoYW5nZXMuZm9yRWFjaCgoY2hhbmdlKSA9PiB7XG4gICAgY29uc3Qgb2JqID0ge30gYXMgSUNoYW5nZTtcbiAgICBsZXQgcHRyID0gb2JqO1xuXG4gICAgY29uc3Qgc2VnbWVudHMgPSBzcGxpdEpTT05QYXRoKGNoYW5nZS5wYXRoKTtcblxuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHB0ci5rZXkgPSBjaGFuZ2Uua2V5O1xuICAgICAgcHRyLnR5cGUgPSBjaGFuZ2UudHlwZTtcbiAgICAgIHB0ci52YWx1ZSA9IGNoYW5nZS52YWx1ZTtcbiAgICAgIHB0ci5vbGRWYWx1ZSA9IGNoYW5nZS5vbGRWYWx1ZTtcbiAgICAgIGNoYW5nZXNBcnIucHVzaChwdHIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHNlZ21lbnQgPSBzZWdtZW50c1tpXTtcbiAgICAgICAgLy8gTWF0Y2hlcyBKU09OUGF0aCBzZWdtZW50czogXCJpdGVtc1s/KEAuaWQ9PScxMjMnKV1cIiwgXCJpdGVtc1s/KEAuaWQ9PTEyMyldXCIsIFwiaXRlbXNbMl1cIiwgXCJpdGVtc1s/KEA9JzEyMycpXVwiXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IC9eKFteW1xcXV0rKVxcW1xcP1xcKEBcXC4/KFtePV0qKT0rJyhbXiddKyknXFwpXFxdJHxeKC4rKVxcWyhcXGQrKVxcXSQvLmV4ZWMoc2VnbWVudCk7XG4gICAgICAgIC8vIGFycmF5XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBsZXQga2V5OiBzdHJpbmc7XG4gICAgICAgICAgbGV0IGVtYmVkZGVkS2V5OiBzdHJpbmc7XG4gICAgICAgICAgbGV0IGFycktleTogc3RyaW5nIHwgbnVtYmVyO1xuICAgICAgICAgIGlmIChyZXN1bHRbMV0pIHtcbiAgICAgICAgICAgIGtleSA9IHJlc3VsdFsxXTtcbiAgICAgICAgICAgIGVtYmVkZGVkS2V5ID0gcmVzdWx0WzJdIHx8ICckdmFsdWUnO1xuICAgICAgICAgICAgYXJyS2V5ID0gcmVzdWx0WzNdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBrZXkgPSByZXN1bHRbNF07XG4gICAgICAgICAgICBlbWJlZGRlZEtleSA9ICckaW5kZXgnO1xuICAgICAgICAgICAgYXJyS2V5ID0gTnVtYmVyKHJlc3VsdFs1XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGxlYWZcbiAgICAgICAgICBpZiAoaSA9PT0gc2VnbWVudHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgcHRyLmtleSA9IGtleSE7XG4gICAgICAgICAgICBwdHIuZW1iZWRkZWRLZXkgPSBlbWJlZGRlZEtleSE7XG4gICAgICAgICAgICBwdHIudHlwZSA9IE9wZXJhdGlvbi5VUERBVEU7XG4gICAgICAgICAgICBwdHIuY2hhbmdlcyA9IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IGNoYW5nZS50eXBlLFxuICAgICAgICAgICAgICAgIGtleTogYXJyS2V5ISxcbiAgICAgICAgICAgICAgICB2YWx1ZTogY2hhbmdlLnZhbHVlLFxuICAgICAgICAgICAgICAgIG9sZFZhbHVlOiBjaGFuZ2Uub2xkVmFsdWVcbiAgICAgICAgICAgICAgfSBhcyBJQ2hhbmdlXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBvYmplY3RcbiAgICAgICAgICAgIHB0ci5rZXkgPSBrZXk7XG4gICAgICAgICAgICBwdHIuZW1iZWRkZWRLZXkgPSBlbWJlZGRlZEtleTtcbiAgICAgICAgICAgIHB0ci50eXBlID0gT3BlcmF0aW9uLlVQREFURTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1B0ciA9IHt9IGFzIElDaGFuZ2U7XG4gICAgICAgICAgICBwdHIuY2hhbmdlcyA9IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IE9wZXJhdGlvbi5VUERBVEUsXG4gICAgICAgICAgICAgICAga2V5OiBhcnJLZXksXG4gICAgICAgICAgICAgICAgY2hhbmdlczogW25ld1B0cl1cbiAgICAgICAgICAgICAgfSBhcyBJQ2hhbmdlXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgcHRyID0gbmV3UHRyO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBsZWFmXG4gICAgICAgICAgaWYgKGkgPT09IHNlZ21lbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhbGwgbGVhZiB2YWx1ZXMgdGhlIHNhbWUgd2F5LCByZWdhcmRsZXNzIG9mIHR5cGVcbiAgICAgICAgICAgIHB0ci5rZXkgPSBzZWdtZW50O1xuICAgICAgICAgICAgcHRyLnR5cGUgPSBjaGFuZ2UudHlwZTtcbiAgICAgICAgICAgIHB0ci52YWx1ZSA9IGNoYW5nZS52YWx1ZTtcbiAgICAgICAgICAgIHB0ci5vbGRWYWx1ZSA9IGNoYW5nZS5vbGRWYWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYnJhbmNoXG4gICAgICAgICAgICBwdHIua2V5ID0gc2VnbWVudDtcbiAgICAgICAgICAgIHB0ci50eXBlID0gT3BlcmF0aW9uLlVQREFURTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1B0ciA9IHt9IGFzIElDaGFuZ2U7XG4gICAgICAgICAgICBwdHIuY2hhbmdlcyA9IFtuZXdQdHJdO1xuICAgICAgICAgICAgcHRyID0gbmV3UHRyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2hhbmdlc0Fyci5wdXNoKG9iaik7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGNoYW5nZXNBcnI7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgdGhlIHR5cGUgb2YgYSBnaXZlbiBvYmplY3QuXG4gKlxuICogQHBhcmFtIHthbnl9IG9iaiAtIFRoZSBvYmplY3Qgd2hvc2UgdHlwZSBpcyB0byBiZSBkZXRlcm1pbmVkLlxuICogQHJldHVybnMge3N0cmluZyB8IG51bGx9IC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdCwgb3IgbnVsbCBpZiB0aGUgb2JqZWN0IGlzIG51bGwuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBmaXJzdCBjaGVja3MgaWYgdGhlIG9iamVjdCBpcyB1bmRlZmluZWQgb3IgbnVsbCwgYW5kIHJldHVybnMgJ3VuZGVmaW5lZCcgb3IgbnVsbCByZXNwZWN0aXZlbHkuXG4gKiBJZiB0aGUgb2JqZWN0IGlzIG5laXRoZXIgdW5kZWZpbmVkIG5vciBudWxsLCBpdCB1c2VzIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgdG8gZ2V0IHRoZSBvYmplY3QncyB0eXBlLlxuICogVGhlIHR5cGUgaXMgZXh0cmFjdGVkIGZyb20gdGhlIHN0cmluZyByZXR1cm5lZCBieSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIHVzaW5nIGEgcmVndWxhciBleHByZXNzaW9uLlxuICovXG5jb25zdCBnZXRUeXBlT2ZPYmogPSAob2JqOiBhbnkpID0+IHtcbiAgaWYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICB9XG5cbiAgaWYgKG9iaiA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gRXh0cmFjdHMgdGhlIFwiVHlwZVwiIGZyb20gXCJbb2JqZWN0IFR5cGVdXCIgc3RyaW5nLlxuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikubWF0Y2goL15cXFtvYmplY3RcXHMoLiopXFxdJC8pWzFdO1xufTtcblxuY29uc3QgZ2V0S2V5ID0gKHBhdGg6IHN0cmluZykgPT4ge1xuICBjb25zdCBsZWZ0ID0gcGF0aFtwYXRoLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gbGVmdCAhPSBudWxsID8gbGVmdCA6ICckcm9vdCc7XG59O1xuXG5jb25zdCBjb21wYXJlID0gKG9sZE9iajogYW55LCBuZXdPYmo6IGFueSwgcGF0aDogYW55LCBrZXlQYXRoOiBhbnksIG9wdGlvbnM6IE9wdGlvbnMpID0+IHtcbiAgbGV0IGNoYW5nZXM6IGFueVtdID0gW107XG5cbiAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJlbnQgcGF0aCBzaG91bGQgYmUgc2tpcHBlZCBcbiAgY29uc3QgY3VycmVudFBhdGggPSBrZXlQYXRoLmpvaW4oJy4nKTtcbiAgaWYgKG9wdGlvbnMua2V5c1RvU2tpcD8uc29tZShza2lwUGF0aCA9PiB7XG4gICAgLy8gRXhhY3QgbWF0Y2hcbiAgICBpZiAoY3VycmVudFBhdGggPT09IHNraXBQYXRoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgXG4gICAgLy8gVGhlIGN1cnJlbnQgcGF0aCBpcyBhIHBhcmVudCBvZiB0aGUgc2tpcCBwYXRoXG4gICAgaWYgKHNraXBQYXRoLmluY2x1ZGVzKCcuJykgJiYgc2tpcFBhdGguc3RhcnRzV2l0aChjdXJyZW50UGF0aCArICcuJykpIHtcbiAgICAgIHJldHVybiBmYWxzZTsgLy8gRG9uJ3Qgc2tpcCwgd2UgbmVlZCB0byBwcm9jZXNzIHRoZSBwYXJlbnRcbiAgICB9XG4gICAgXG4gICAgLy8gVGhlIGN1cnJlbnQgcGF0aCBpcyBhIGNoaWxkIG9yIGRlZXBlciBkZXNjZW5kYW50IG9mIHRoZSBza2lwIHBhdGhcbiAgICBpZiAoc2tpcFBhdGguaW5jbHVkZXMoJy4nKSkge1xuICAgICAgLy8gQ2hlY2sgaWYgc2tpcFBhdGggaXMgYSBwYXJlbnQgb2YgY3VycmVudFBhdGhcbiAgICAgIGNvbnN0IHNraXBQYXJ0cyA9IHNraXBQYXRoLnNwbGl0KCcuJyk7XG4gICAgICBjb25zdCBjdXJyZW50UGFydHMgPSBjdXJyZW50UGF0aC5zcGxpdCgnLicpO1xuICAgICAgXG4gICAgICBpZiAoY3VycmVudFBhcnRzLmxlbmd0aCA+PSBza2lwUGFydHMubGVuZ3RoKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGFsbCBwYXJ0cyBvZiBza2lwUGF0aCBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBwYXJ0cyBpbiBjdXJyZW50UGF0aFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNraXBQYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChza2lwUGFydHNbaV0gIT09IGN1cnJlbnRQYXJ0c1tpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gQWxsIHBhcnRzIG1hdGNoLCBzbyB0aGlzIGlzIGEgY2hpbGQgb3IgZXF1YWwgcGF0aFxuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pKSB7XG4gICAgcmV0dXJuIGNoYW5nZXM7IC8vIFNraXAgY29tcGFyaXNvbiBmb3IgdGhpcyBwYXRoIGFuZCBpdHMgY2hpbGRyZW5cbiAgfVxuXG4gIGNvbnN0IHR5cGVPZk9sZE9iaiA9IGdldFR5cGVPZk9iaihvbGRPYmopO1xuICBjb25zdCB0eXBlT2ZOZXdPYmogPSBnZXRUeXBlT2ZPYmoobmV3T2JqKTtcblxuICAvLyBgdHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlYCBpcyBhIGZsYWcgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBjaGFuZ2UgaW4gdHlwZSBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIHJlcGxhY2VtZW50LlxuICBpZiAob3B0aW9ucy50cmVhdFR5cGVDaGFuZ2VBc1JlcGxhY2UgJiYgdHlwZU9mT2xkT2JqICE9PSB0eXBlT2ZOZXdPYmopIHtcbiAgICAvLyBPbmx5IGFkZCBhIFJFTU9WRSBvcGVyYXRpb24gaWYgb2xkT2JqIGlzIG5vdCB1bmRlZmluZWRcbiAgICBpZiAodHlwZU9mT2xkT2JqICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY2hhbmdlcy5wdXNoKHsgdHlwZTogT3BlcmF0aW9uLlJFTU9WRSwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBvbGRPYmogfSk7XG4gICAgfVxuXG4gICAgLy8gQXMgdW5kZWZpbmVkIGlzIG5vdCBzZXJpYWxpemVkIGludG8gSlNPTiwgaXQgc2hvdWxkIG5vdCBjb3VudCBhcyBhbiBhZGRlZCB2YWx1ZS5cbiAgICBpZiAodHlwZU9mTmV3T2JqICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY2hhbmdlcy5wdXNoKHsgdHlwZTogT3BlcmF0aW9uLkFERCwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBuZXdPYmogfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5nZXM7XG4gIH1cblxuICBpZiAodHlwZU9mTmV3T2JqID09PSAndW5kZWZpbmVkJyAmJiB0eXBlT2ZPbGRPYmogIT09ICd1bmRlZmluZWQnKSB7XG4gICAgY2hhbmdlcy5wdXNoKHsgdHlwZTogT3BlcmF0aW9uLlJFTU9WRSwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBvbGRPYmogfSk7XG4gICAgcmV0dXJuIGNoYW5nZXM7XG4gIH1cblxuICBpZiAodHlwZU9mTmV3T2JqID09PSAnT2JqZWN0JyAmJiB0eXBlT2ZPbGRPYmogPT09ICdBcnJheScpIHtcbiAgICBjaGFuZ2VzLnB1c2goeyB0eXBlOiBPcGVyYXRpb24uVVBEQVRFLCBrZXk6IGdldEtleShwYXRoKSwgdmFsdWU6IG5ld09iaiwgb2xkVmFsdWU6IG9sZE9iaiB9KTtcbiAgICByZXR1cm4gY2hhbmdlcztcbiAgfVxuXG4gIGlmICh0eXBlT2ZOZXdPYmogPT09IG51bGwpIHtcbiAgICBpZiAodHlwZU9mT2xkT2JqICE9PSBudWxsKSB7XG4gICAgICBjaGFuZ2VzLnB1c2goeyB0eXBlOiBPcGVyYXRpb24uVVBEQVRFLCBrZXk6IGdldEtleShwYXRoKSwgdmFsdWU6IG5ld09iaiwgb2xkVmFsdWU6IG9sZE9iaiB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGNoYW5nZXM7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGVPZk9sZE9iaikge1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgaWYgKHR5cGVPZk5ld09iaiA9PT0gJ0RhdGUnKSB7XG4gICAgICAgIGNoYW5nZXMgPSBjaGFuZ2VzLmNvbmNhdChcbiAgICAgICAgICBjb21wYXJlUHJpbWl0aXZlcyhvbGRPYmouZ2V0VGltZSgpLCBuZXdPYmouZ2V0VGltZSgpLCBwYXRoKS5tYXAoKHgpID0+ICh7XG4gICAgICAgICAgICAuLi54LFxuICAgICAgICAgICAgdmFsdWU6IG5ldyBEYXRlKHgudmFsdWUpLFxuICAgICAgICAgICAgb2xkVmFsdWU6IG5ldyBEYXRlKHgub2xkVmFsdWUpXG4gICAgICAgICAgfSkpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFuZ2VzID0gY2hhbmdlcy5jb25jYXQoY29tcGFyZVByaW1pdGl2ZXMob2xkT2JqLCBuZXdPYmosIHBhdGgpKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ09iamVjdCc6IHtcbiAgICAgIGNvbnN0IGRpZmZzID0gY29tcGFyZU9iamVjdChvbGRPYmosIG5ld09iaiwgcGF0aCwga2V5UGF0aCwgZmFsc2UsIG9wdGlvbnMpO1xuICAgICAgaWYgKGRpZmZzLmxlbmd0aCkge1xuICAgICAgICBpZiAocGF0aC5sZW5ndGgpIHtcbiAgICAgICAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogT3BlcmF0aW9uLlVQREFURSxcbiAgICAgICAgICAgIGtleTogZ2V0S2V5KHBhdGgpLFxuICAgICAgICAgICAgY2hhbmdlczogZGlmZnNcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjaGFuZ2VzID0gY2hhbmdlcy5jb25jYXQoZGlmZnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuY29uY2F0KGNvbXBhcmVBcnJheShvbGRPYmosIG5ld09iaiwgcGF0aCwga2V5UGF0aCwgb3B0aW9ucykpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnRnVuY3Rpb24nOlxuICAgICAgYnJlYWs7XG4gICAgLy8gZG8gbm90aGluZ1xuICAgIGRlZmF1bHQ6XG4gICAgICBjaGFuZ2VzID0gY2hhbmdlcy5jb25jYXQoY29tcGFyZVByaW1pdGl2ZXMob2xkT2JqLCBuZXdPYmosIHBhdGgpKTtcbiAgfVxuXG4gIHJldHVybiBjaGFuZ2VzO1xufTtcblxuY29uc3QgY29tcGFyZU9iamVjdCA9IChvbGRPYmo6IGFueSwgbmV3T2JqOiBhbnksIHBhdGg6IGFueSwga2V5UGF0aDogYW55LCBza2lwUGF0aCA9IGZhbHNlLCBvcHRpb25zOiBPcHRpb25zID0ge30pID0+IHtcbiAgbGV0IGs7XG4gIGxldCBuZXdLZXlQYXRoO1xuICBsZXQgbmV3UGF0aDtcblxuICBpZiAoc2tpcFBhdGggPT0gbnVsbCkge1xuICAgIHNraXBQYXRoID0gZmFsc2U7XG4gIH1cbiAgbGV0IGNoYW5nZXM6IGFueVtdID0gW107XG5cbiAgLy8gRmlsdGVyIGtleXMgZGlyZWN0bHkgcmF0aGVyIHRoYW4gZmlsdGVyaW5nIGJ5IGtleXNUb1NraXAgYXQgdGhpcyBsZXZlbFxuICAvLyBUaGUgZnVsbCBwYXRoIGNoZWNrIGlzIG5vdyBkb25lIGluIHRoZSBjb21wYXJlIGZ1bmN0aW9uXG4gIGNvbnN0IG9sZE9iaktleXMgPSBPYmplY3Qua2V5cyhvbGRPYmopO1xuICBjb25zdCBuZXdPYmpLZXlzID0gT2JqZWN0LmtleXMobmV3T2JqKTtcblxuICBjb25zdCBpbnRlcnNlY3Rpb25LZXlzID0gaW50ZXJzZWN0aW9uKG9sZE9iaktleXMsIG5ld09iaktleXMpO1xuICBmb3IgKGsgb2YgaW50ZXJzZWN0aW9uS2V5cykge1xuICAgIG5ld1BhdGggPSBwYXRoLmNvbmNhdChba10pO1xuICAgIG5ld0tleVBhdGggPSBza2lwUGF0aCA/IGtleVBhdGggOiBrZXlQYXRoLmNvbmNhdChba10pO1xuICAgIGNvbnN0IGRpZmZzID0gY29tcGFyZShvbGRPYmpba10sIG5ld09ialtrXSwgbmV3UGF0aCwgbmV3S2V5UGF0aCwgb3B0aW9ucyk7XG4gICAgaWYgKGRpZmZzLmxlbmd0aCkge1xuICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuY29uY2F0KGRpZmZzKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBhZGRlZEtleXMgPSBkaWZmZXJlbmNlKG5ld09iaktleXMsIG9sZE9iaktleXMpO1xuICBmb3IgKGsgb2YgYWRkZWRLZXlzKSB7XG4gICAgbmV3UGF0aCA9IHBhdGguY29uY2F0KFtrXSk7XG4gICAgbmV3S2V5UGF0aCA9IHNraXBQYXRoID8ga2V5UGF0aCA6IGtleVBhdGguY29uY2F0KFtrXSk7XG4gICAgLy8gQ2hlY2sgaWYgdGhlIHBhdGggc2hvdWxkIGJlIHNraXBwZWRcbiAgICBjb25zdCBjdXJyZW50UGF0aCA9IG5ld0tleVBhdGguam9pbignLicpO1xuICAgIGlmIChvcHRpb25zLmtleXNUb1NraXA/LnNvbWUoc2tpcFBhdGggPT4gY3VycmVudFBhdGggPT09IHNraXBQYXRoIHx8IGN1cnJlbnRQYXRoLnN0YXJ0c1dpdGgoc2tpcFBhdGggKyAnLicpKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgYWRkaW5nIHRoaXMga2V5XG4gICAgfVxuICAgIGNoYW5nZXMucHVzaCh7XG4gICAgICB0eXBlOiBPcGVyYXRpb24uQURELFxuICAgICAga2V5OiBnZXRLZXkobmV3UGF0aCksXG4gICAgICB2YWx1ZTogbmV3T2JqW2tdXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBkZWxldGVkS2V5cyA9IGRpZmZlcmVuY2Uob2xkT2JqS2V5cywgbmV3T2JqS2V5cyk7XG4gIGZvciAoayBvZiBkZWxldGVkS2V5cykge1xuICAgIG5ld1BhdGggPSBwYXRoLmNvbmNhdChba10pO1xuICAgIG5ld0tleVBhdGggPSBza2lwUGF0aCA/IGtleVBhdGggOiBrZXlQYXRoLmNvbmNhdChba10pO1xuICAgIC8vIENoZWNrIGlmIHRoZSBwYXRoIHNob3VsZCBiZSBza2lwcGVkXG4gICAgY29uc3QgY3VycmVudFBhdGggPSBuZXdLZXlQYXRoLmpvaW4oJy4nKTtcbiAgICBpZiAob3B0aW9ucy5rZXlzVG9Ta2lwPy5zb21lKHNraXBQYXRoID0+IGN1cnJlbnRQYXRoID09PSBza2lwUGF0aCB8fCBjdXJyZW50UGF0aC5zdGFydHNXaXRoKHNraXBQYXRoICsgJy4nKSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHJlbW92aW5nIHRoaXMga2V5XG4gICAgfVxuICAgIGNoYW5nZXMucHVzaCh7XG4gICAgICB0eXBlOiBPcGVyYXRpb24uUkVNT1ZFLFxuICAgICAga2V5OiBnZXRLZXkobmV3UGF0aCksXG4gICAgICB2YWx1ZTogb2xkT2JqW2tdXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNoYW5nZXM7XG59O1xuXG5jb25zdCBjb21wYXJlQXJyYXkgPSAob2xkT2JqOiBhbnksIG5ld09iajogYW55LCBwYXRoOiBhbnksIGtleVBhdGg6IGFueSwgb3B0aW9uczogT3B0aW9ucykgPT4ge1xuICBpZiAoZ2V0VHlwZU9mT2JqKG5ld09iaikgIT09ICdBcnJheScpIHtcbiAgICByZXR1cm4gW3sgdHlwZTogT3BlcmF0aW9uLlVQREFURSwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBuZXdPYmosIG9sZFZhbHVlOiBvbGRPYmogfV07XG4gIH1cblxuICBjb25zdCBsZWZ0ID0gZ2V0T2JqZWN0S2V5KG9wdGlvbnMuZW1iZWRkZWRPYmpLZXlzLCBrZXlQYXRoKTtcbiAgY29uc3QgdW5pcUtleSA9IGxlZnQgIT0gbnVsbCA/IGxlZnQgOiAnJGluZGV4JztcbiAgY29uc3QgaW5kZXhlZE9sZE9iaiA9IGNvbnZlcnRBcnJheVRvT2JqKG9sZE9iaiwgdW5pcUtleSk7XG4gIGNvbnN0IGluZGV4ZWROZXdPYmogPSBjb252ZXJ0QXJyYXlUb09iaihuZXdPYmosIHVuaXFLZXkpO1xuICBjb25zdCBkaWZmcyA9IGNvbXBhcmVPYmplY3QoaW5kZXhlZE9sZE9iaiwgaW5kZXhlZE5ld09iaiwgcGF0aCwga2V5UGF0aCwgdHJ1ZSwgb3B0aW9ucyk7XG4gIGlmIChkaWZmcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0eXBlOiBPcGVyYXRpb24uVVBEQVRFLFxuICAgICAgICBrZXk6IGdldEtleShwYXRoKSxcbiAgICAgICAgZW1iZWRkZWRLZXk6IHR5cGVvZiB1bmlxS2V5ID09PSAnZnVuY3Rpb24nICYmIHVuaXFLZXkubGVuZ3RoID09PSAyID8gdW5pcUtleShuZXdPYmpbMF0sIHRydWUpIDogdW5pcUtleSxcbiAgICAgICAgY2hhbmdlczogZGlmZnNcbiAgICAgIH1cbiAgICBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbXTtcbiAgfVxufTtcblxuY29uc3QgZ2V0T2JqZWN0S2V5ID0gKGVtYmVkZGVkT2JqS2V5czogYW55LCBrZXlQYXRoOiBhbnkpID0+IHtcbiAgaWYgKGVtYmVkZGVkT2JqS2V5cyAhPSBudWxsKSB7XG4gICAgY29uc3QgcGF0aCA9IGtleVBhdGguam9pbignLicpO1xuXG4gICAgaWYgKGVtYmVkZGVkT2JqS2V5cyBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgZW1iZWRkZWRPYmpLZXlzLmVudHJpZXMoKSkge1xuICAgICAgICBpZiAoa2V5IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgaWYgKHBhdGgubWF0Y2goa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXRoID09PSBrZXkpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBrZXkgPSBlbWJlZGRlZE9iaktleXNbcGF0aF07XG4gICAgaWYgKGtleSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4ga2V5O1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcblxuY29uc3QgY29udmVydEFycmF5VG9PYmogPSAoYXJyOiBhbnlbXSwgdW5pcUtleTogYW55KSA9PiB7XG4gIGxldCBvYmo6IGFueSA9IHt9O1xuICBpZiAodW5pcUtleSA9PT0gJyR2YWx1ZScpIHtcbiAgICBhcnIuZm9yRWFjaCgodmFsdWUpID0+IHtcbiAgICAgIG9ialt2YWx1ZV0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICh1bmlxS2V5ICE9PSAnJGluZGV4Jykge1xuICAgIC8vIENvbnZlcnQgc3RyaW5nIGtleXMgdG8gZnVuY3Rpb25zIGZvciBjb21wYXRpYmlsaXR5IHdpdGggZXMtdG9vbGtpdCBrZXlCeVxuICAgIGNvbnN0IGtleUZ1bmN0aW9uID0gdHlwZW9mIHVuaXFLZXkgPT09ICdzdHJpbmcnID8gKGl0ZW06IGFueSkgPT4gaXRlbVt1bmlxS2V5XSA6IHVuaXFLZXk7XG4gICAgb2JqID0ga2V5QnkoYXJyLCBrZXlGdW5jdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXJyW2ldO1xuICAgICAgb2JqW2ldID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG5jb25zdCBjb21wYXJlUHJpbWl0aXZlcyA9IChvbGRPYmo6IGFueSwgbmV3T2JqOiBhbnksIHBhdGg6IGFueSkgPT4ge1xuICBjb25zdCBjaGFuZ2VzID0gW107XG4gIGlmIChvbGRPYmogIT09IG5ld09iaikge1xuICAgIGNoYW5nZXMucHVzaCh7XG4gICAgICB0eXBlOiBPcGVyYXRpb24uVVBEQVRFLFxuICAgICAga2V5OiBnZXRLZXkocGF0aCksXG4gICAgICB2YWx1ZTogbmV3T2JqLFxuICAgICAgb2xkVmFsdWU6IG9sZE9ialxuICAgIH0pO1xuICB9XG4gIHJldHVybiBjaGFuZ2VzO1xufTtcblxuY29uc3QgcmVtb3ZlS2V5ID0gKG9iajogYW55LCBrZXk6IGFueSwgZW1iZWRkZWRLZXk6IGFueSkgPT4ge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgaWYgKGVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgICAgb2JqLnNwbGljZShOdW1iZXIoa2V5KSwgMSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gaW5kZXhPZkl0ZW1JbkFycmF5KG9iaiwgZW1iZWRkZWRLZXksIGtleSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihgRWxlbWVudCB3aXRoIHRoZSBrZXkgJyR7ZW1iZWRkZWRLZXl9JyBhbmQgdmFsdWUgJyR7a2V5fScgY291bGQgbm90IGJlIGZvdW5kIGluIHRoZSBhcnJheSdgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIG9iai5zcGxpY2UoaW5kZXggIT0gbnVsbCA/IGluZGV4IDoga2V5LCAxKTtcbiAgfSBlbHNlIHtcbiAgICBkZWxldGUgb2JqW2tleV07XG4gICAgcmV0dXJuO1xuICB9XG59O1xuXG5jb25zdCBpbmRleE9mSXRlbUluQXJyYXkgPSAoYXJyOiBhbnlbXSwga2V5OiBhbnksIHZhbHVlOiBhbnkpID0+IHtcbiAgaWYgKGtleSA9PT0gJyR2YWx1ZScpIHtcbiAgICByZXR1cm4gYXJyLmluZGV4T2YodmFsdWUpO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgaXRlbSA9IGFycltpXTtcbiAgICBpZiAoaXRlbSAmJiBpdGVtW2tleV0gPyBpdGVtW2tleV0udG9TdHJpbmcoKSA9PT0gdmFsdWUudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbmNvbnN0IG1vZGlmeUtleVZhbHVlID0gKG9iajogYW55LCBrZXk6IGFueSwgdmFsdWU6IGFueSkgPT4gKG9ialtrZXldID0gdmFsdWUpO1xuY29uc3QgYWRkS2V5VmFsdWUgPSAob2JqOiBhbnksIGtleTogYW55LCB2YWx1ZTogYW55LCBlbWJlZGRlZEtleT86IGFueSkgPT4ge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgaWYgKGVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgICAgb2JqLnNwbGljZShOdW1iZXIoa2V5KSwgMCwgdmFsdWUpO1xuICAgICAgcmV0dXJuIG9iai5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBvYmoucHVzaCh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iaiA/IChvYmpba2V5XSA9IHZhbHVlKSA6IG51bGw7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGx5TGVhZkNoYW5nZSA9IChvYmo6IGFueSwgY2hhbmdlOiBhbnksIGVtYmVkZGVkS2V5OiBhbnkpID0+IHtcbiAgY29uc3QgeyB0eXBlLCBrZXksIHZhbHVlIH0gPSBjaGFuZ2U7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgT3BlcmF0aW9uLkFERDpcbiAgICAgIHJldHVybiBhZGRLZXlWYWx1ZShvYmosIGtleSwgdmFsdWUsIGVtYmVkZGVkS2V5KTtcbiAgICBjYXNlIE9wZXJhdGlvbi5VUERBVEU6XG4gICAgICByZXR1cm4gbW9kaWZ5S2V5VmFsdWUob2JqLCBrZXksIHZhbHVlKTtcbiAgICBjYXNlIE9wZXJhdGlvbi5SRU1PVkU6XG4gICAgICByZXR1cm4gcmVtb3ZlS2V5KG9iaiwga2V5LCBlbWJlZGRlZEtleSk7XG4gIH1cbn07XG5cbi8qKlxuICogQXBwbGllcyBjaGFuZ2VzIHRvIGFuIGFycmF5LlxuICogXG4gKiBAcGFyYW0ge2FueVtdfSBhcnIgLSBUaGUgYXJyYXkgdG8gYXBwbHkgY2hhbmdlcyB0by5cbiAqIEBwYXJhbSB7YW55fSBjaGFuZ2UgLSBUaGUgY2hhbmdlIHRvIGFwcGx5LCBjb250YWluaW5nIG5lc3RlZCBjaGFuZ2VzLlxuICogQHJldHVybnMge2FueVtdfSAtIFRoZSBhcnJheSBhZnRlciBjaGFuZ2VzIGhhdmUgYmVlbiBhcHBsaWVkLlxuICpcbiAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gbW9kaWZpZXMgdGhlIGFycmF5IGluLXBsYWNlIGJ1dCBhbHNvIHJldHVybnMgaXQgZm9yXG4gKiBjb25zaXN0ZW5jeSB3aXRoIG90aGVyIGZ1bmN0aW9ucy5cbiAqL1xuY29uc3QgYXBwbHlBcnJheUNoYW5nZSA9IChhcnI6IGFueVtdLCBjaGFuZ2U6IGFueSkgPT4ge1xuICBsZXQgY2hhbmdlcyA9IGNoYW5nZS5jaGFuZ2VzO1xuICBpZiAoY2hhbmdlLmVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgIGNoYW5nZXMgPSBbLi4uY2hhbmdlc10uc29ydCgoYSwgYikgPT4ge1xuICAgICAgaWYgKGEudHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSAmJiBiLnR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUpIHtcbiAgICAgICAgcmV0dXJuIE51bWJlcihiLmtleSkgLSBOdW1iZXIoYS5rZXkpO1xuICAgICAgfVxuICAgICAgaWYgKGEudHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSkgcmV0dXJuIC0xO1xuICAgICAgaWYgKGIudHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSkgcmV0dXJuIDE7XG4gICAgICByZXR1cm4gTnVtYmVyKGEua2V5KSAtIE51bWJlcihiLmtleSk7XG4gICAgfSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHN1YmNoYW5nZSBvZiBjaGFuZ2VzKSB7XG4gICAgaWYgKFxuICAgICAgKHN1YmNoYW5nZS52YWx1ZSAhPT0gbnVsbCAmJiBzdWJjaGFuZ2UudmFsdWUgIT09IHVuZGVmaW5lZCkgfHxcbiAgICAgIHN1YmNoYW5nZS50eXBlID09PSBPcGVyYXRpb24uUkVNT1ZFIHx8XG4gICAgICAoc3ViY2hhbmdlLnZhbHVlID09PSBudWxsICYmIHN1YmNoYW5nZS50eXBlID09PSBPcGVyYXRpb24uQUREKVxuICAgICkge1xuICAgICAgYXBwbHlMZWFmQ2hhbmdlKGFyciwgc3ViY2hhbmdlLCBjaGFuZ2UuZW1iZWRkZWRLZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZWxlbWVudDtcbiAgICAgIGlmIChjaGFuZ2UuZW1iZWRkZWRLZXkgPT09ICckaW5kZXgnKSB7XG4gICAgICAgIGVsZW1lbnQgPSBhcnJbc3ViY2hhbmdlLmtleV07XG4gICAgICB9IGVsc2UgaWYgKGNoYW5nZS5lbWJlZGRlZEtleSA9PT0gJyR2YWx1ZScpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihzdWJjaGFuZ2Uua2V5KTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgIGVsZW1lbnQgPSBhcnJbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50ID0gYXJyLmZpbmQoKGVsKSA9PiBlbFtjaGFuZ2UuZW1iZWRkZWRLZXldPy50b1N0cmluZygpID09PSBzdWJjaGFuZ2Uua2V5LnRvU3RyaW5nKCkpO1xuICAgICAgfVxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgYXBwbHlDaGFuZ2VzZXQoZWxlbWVudCwgc3ViY2hhbmdlLmNoYW5nZXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gYXJyO1xufTtcblxuY29uc3QgYXBwbHlCcmFuY2hDaGFuZ2UgPSAob2JqOiBhbnksIGNoYW5nZTogYW55KSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gYXBwbHlBcnJheUNoYW5nZShvYmosIGNoYW5nZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFwcGx5Q2hhbmdlc2V0KG9iaiwgY2hhbmdlLmNoYW5nZXMpO1xuICB9XG59O1xuXG5jb25zdCByZXZlcnRMZWFmQ2hhbmdlID0gKG9iajogYW55LCBjaGFuZ2U6IGFueSwgZW1iZWRkZWRLZXkgPSAnJGluZGV4JykgPT4ge1xuICBjb25zdCB7IHR5cGUsIGtleSwgdmFsdWUsIG9sZFZhbHVlIH0gPSBjaGFuZ2U7XG4gIFxuICAvLyBTcGVjaWFsIGhhbmRsaW5nIGZvciAkcm9vdCBrZXlcbiAgaWYgKGtleSA9PT0gJyRyb290Jykge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBPcGVyYXRpb24uQUREOlxuICAgICAgICAvLyBXaGVuIHJldmVydGluZyBhbiBBREQgb2YgdGhlIGVudGlyZSBvYmplY3QsIGNsZWFyIGFsbCBwcm9wZXJ0aWVzXG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBvYmopIHtcbiAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmpbcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgICBjYXNlIE9wZXJhdGlvbi5VUERBVEU6XG4gICAgICAgIC8vIFJlcGxhY2UgdGhlIGVudGlyZSBvYmplY3Qgd2l0aCB0aGUgb2xkIHZhbHVlXG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBvYmopIHtcbiAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmpbcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChvbGRWYWx1ZSAmJiB0eXBlb2Ygb2xkVmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihvYmosIG9sZFZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgY2FzZSBPcGVyYXRpb24uUkVNT1ZFOlxuICAgICAgICAvLyBSZXN0b3JlIHRoZSByZW1vdmVkIG9iamVjdFxuICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24ob2JqLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gIH1cbiAgXG4gIC8vIFJlZ3VsYXIgcHJvcGVydHkgaGFuZGxpbmdcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBPcGVyYXRpb24uQUREOlxuICAgICAgcmV0dXJuIHJlbW92ZUtleShvYmosIGtleSwgZW1iZWRkZWRLZXkpO1xuICAgIGNhc2UgT3BlcmF0aW9uLlVQREFURTpcbiAgICAgIHJldHVybiBtb2RpZnlLZXlWYWx1ZShvYmosIGtleSwgb2xkVmFsdWUpO1xuICAgIGNhc2UgT3BlcmF0aW9uLlJFTU9WRTpcbiAgICAgIHJldHVybiBhZGRLZXlWYWx1ZShvYmosIGtleSwgdmFsdWUpO1xuICB9XG59O1xuXG4vKipcbiAqIFJldmVydHMgY2hhbmdlcyBpbiBhbiBhcnJheS5cbiAqIFxuICogQHBhcmFtIHthbnlbXX0gYXJyIC0gVGhlIGFycmF5IHRvIHJldmVydCBjaGFuZ2VzIGluLlxuICogQHBhcmFtIHthbnl9IGNoYW5nZSAtIFRoZSBjaGFuZ2UgdG8gcmV2ZXJ0LCBjb250YWluaW5nIG5lc3RlZCBjaGFuZ2VzLlxuICogQHJldHVybnMge2FueVtdfSAtIFRoZSBhcnJheSBhZnRlciBjaGFuZ2VzIGhhdmUgYmVlbiByZXZlcnRlZC5cbiAqXG4gKiBOb3RlOiBUaGlzIGZ1bmN0aW9uIG1vZGlmaWVzIHRoZSBhcnJheSBpbi1wbGFjZSBidXQgYWxzbyByZXR1cm5zIGl0IGZvclxuICogY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMuXG4gKi9cbmNvbnN0IHJldmVydEFycmF5Q2hhbmdlID0gKGFycjogYW55W10sIGNoYW5nZTogYW55KSA9PiB7XG4gIGZvciAoY29uc3Qgc3ViY2hhbmdlIG9mIGNoYW5nZS5jaGFuZ2VzKSB7XG4gICAgaWYgKHN1YmNoYW5nZS52YWx1ZSAhPSBudWxsIHx8IHN1YmNoYW5nZS50eXBlID09PSBPcGVyYXRpb24uUkVNT1ZFKSB7XG4gICAgICByZXZlcnRMZWFmQ2hhbmdlKGFyciwgc3ViY2hhbmdlLCBjaGFuZ2UuZW1iZWRkZWRLZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZWxlbWVudDtcbiAgICAgIGlmIChjaGFuZ2UuZW1iZWRkZWRLZXkgPT09ICckaW5kZXgnKSB7XG4gICAgICAgIGVsZW1lbnQgPSBhcnJbK3N1YmNoYW5nZS5rZXldO1xuICAgICAgfSBlbHNlIGlmIChjaGFuZ2UuZW1iZWRkZWRLZXkgPT09ICckdmFsdWUnKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gYXJyLmluZGV4T2Yoc3ViY2hhbmdlLmtleSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBlbGVtZW50ID0gYXJyW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudCA9IGFyci5maW5kKChlbCkgPT4gZWxbY2hhbmdlLmVtYmVkZGVkS2V5XT8udG9TdHJpbmcoKSA9PT0gc3ViY2hhbmdlLmtleS50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIHJldmVydENoYW5nZXNldChlbGVtZW50LCBzdWJjaGFuZ2UuY2hhbmdlcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnI7XG59O1xuXG5jb25zdCByZXZlcnRCcmFuY2hDaGFuZ2UgPSAob2JqOiBhbnksIGNoYW5nZTogYW55KSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gcmV2ZXJ0QXJyYXlDaGFuZ2Uob2JqLCBjaGFuZ2UpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByZXZlcnRDaGFuZ2VzZXQob2JqLCBjaGFuZ2UuY2hhbmdlcyk7XG4gIH1cbn07XG5cbi8qKiBjb21iaW5lIGEgYmFzZSBKU09OIFBhdGggd2l0aCBhIHN1YnNlcXVlbnQgc2VnbWVudCAqL1xuZnVuY3Rpb24gYXBwZW5kKGJhc2VQYXRoOiBzdHJpbmcsIG5leHRTZWdtZW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbmV4dFNlZ21lbnQuaW5jbHVkZXMoJy4nKSA/IGAke2Jhc2VQYXRofVske25leHRTZWdtZW50fV1gIDogYCR7YmFzZVBhdGh9LiR7bmV4dFNlZ21lbnR9YDtcbn1cblxuLyoqIHJldHVybnMgYSBKU09OIFBhdGggZmlsdGVyIGV4cHJlc3Npb247IGUuZy4sIGAkLnBldFsoP25hbWU9J3Nwb3QnKV1gICovXG5mdW5jdGlvbiBmaWx0ZXJFeHByZXNzaW9uKGJhc2VQYXRoOiBzdHJpbmcsIGZpbHRlcktleTogc3RyaW5nIHwgRnVuY3Rpb25LZXksIGZpbHRlclZhbHVlOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgY29uc3QgdmFsdWUgPSB0eXBlb2YgZmlsdGVyVmFsdWUgPT09ICdudW1iZXInID8gZmlsdGVyVmFsdWUgOiBgJyR7ZmlsdGVyVmFsdWV9J2A7XG4gIHJldHVybiB0eXBlb2YgZmlsdGVyS2V5ID09PSAnc3RyaW5nJyAmJiBmaWx0ZXJLZXkuaW5jbHVkZXMoJy4nKVxuICAgID8gYCR7YmFzZVBhdGh9Wz8oQFske2ZpbHRlcktleX1dPT0ke3ZhbHVlfSldYFxuICAgIDogYCR7YmFzZVBhdGh9Wz8oQC4ke2ZpbHRlcktleX09PSR7dmFsdWV9KV1gO1xufVxuXG5leHBvcnQge1xuICBDaGFuZ2VzZXQsXG4gIEVtYmVkZGVkT2JqS2V5c01hcFR5cGUsXG4gIEVtYmVkZGVkT2JqS2V5c1R5cGUsXG4gIElBdG9taWNDaGFuZ2UsXG4gIElDaGFuZ2UsXG4gIE9wZXJhdGlvbixcbiAgT3B0aW9ucyxcbiAgYXBwbHlDaGFuZ2VzZXQsXG4gIGF0b21pemVDaGFuZ2VzZXQsXG4gIGRpZmYsXG4gIGdldFR5cGVPZk9iaixcbiAgcmV2ZXJ0Q2hhbmdlc2V0LFxuICB1bmF0b21pemVDaGFuZ2VzZXRcbn07XG4iLCAiaW1wb3J0IHsgc2V0QnlQYXRoIH0gZnJvbSAnLi9oZWxwZXJzLmpzJztcbmltcG9ydCB7IGRpZmYsIGF0b21pemVDaGFuZ2VzZXQsIGdldFR5cGVPZk9iaiwgSUF0b21pY0NoYW5nZSwgT3BlcmF0aW9uIH0gZnJvbSAnLi9qc29uRGlmZi5qcyc7XG5cbmVudW0gQ29tcGFyZU9wZXJhdGlvbiB7XG4gIENPTlRBSU5FUiA9ICdDT05UQUlORVInLFxuICBVTkNIQU5HRUQgPSAnVU5DSEFOR0VEJ1xufVxuXG5pbnRlcmZhY2UgSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUge1xuICB0eXBlOiBPcGVyYXRpb24gfCBDb21wYXJlT3BlcmF0aW9uO1xuICB2YWx1ZTogSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUgfCBJQ29tcGFyaXNvbkVucmljaGVkTm9kZVtdIHwgYW55IHwgYW55W107XG4gIG9sZFZhbHVlPzogYW55O1xufVxuXG5jb25zdCBjcmVhdGVWYWx1ZSA9ICh2YWx1ZTogYW55KTogSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUgPT4gKHsgdHlwZTogQ29tcGFyZU9wZXJhdGlvbi5VTkNIQU5HRUQsIHZhbHVlIH0pO1xuY29uc3QgY3JlYXRlQ29udGFpbmVyID0gKHZhbHVlOiBvYmplY3QgfCBbXSk6IElDb21wYXJpc29uRW5yaWNoZWROb2RlID0+ICh7XG4gIHR5cGU6IENvbXBhcmVPcGVyYXRpb24uQ09OVEFJTkVSLFxuICB2YWx1ZVxufSk7XG5cbmNvbnN0IGVucmljaCA9IChvYmplY3Q6IGFueSk6IElDb21wYXJpc29uRW5yaWNoZWROb2RlID0+IHtcbiAgY29uc3Qgb2JqZWN0VHlwZSA9IGdldFR5cGVPZk9iaihvYmplY3QpO1xuXG4gIHN3aXRjaCAob2JqZWN0VHlwZSkge1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqZWN0KVxuICAgICAgICAubWFwKChrZXk6IHN0cmluZykgPT4gKHsga2V5LCB2YWx1ZTogZW5yaWNoKG9iamVjdFtrZXldKSB9KSlcbiAgICAgICAgLnJlZHVjZSgoYWNjdW11bGF0b3IsIGVudHJ5KSA9PiB7XG4gICAgICAgICAgYWNjdW11bGF0b3IudmFsdWVbZW50cnkua2V5XSA9IGVudHJ5LnZhbHVlO1xuICAgICAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgICAgICAgfSwgY3JlYXRlQ29udGFpbmVyKHt9KSk7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIChvYmplY3QgYXMgYW55W10pXG4gICAgICAgIC5tYXAoKHZhbHVlKSA9PiBlbnJpY2godmFsdWUpKVxuICAgICAgICAucmVkdWNlKChhY2N1bXVsYXRvciwgdmFsdWUpID0+IHtcbiAgICAgICAgICBhY2N1bXVsYXRvci52YWx1ZS5wdXNoKHZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgICAgIH0sIGNyZWF0ZUNvbnRhaW5lcihbXSkpO1xuICAgIGNhc2UgJ0Z1bmN0aW9uJzpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIFByaW1pdGl2ZSB2YWx1ZVxuICAgICAgcmV0dXJuIGNyZWF0ZVZhbHVlKG9iamVjdCk7XG4gIH1cbn07XG5cbmNvbnN0IGFwcGx5Q2hhbmdlbGlzdCA9IChvYmplY3Q6IElDb21wYXJpc29uRW5yaWNoZWROb2RlLCBjaGFuZ2VsaXN0OiBJQXRvbWljQ2hhbmdlW10pOiBJQ29tcGFyaXNvbkVucmljaGVkTm9kZSA9PiB7XG4gIGNoYW5nZWxpc3RcbiAgICAubWFwKChlbnRyeSkgPT4gKHsgLi4uZW50cnksIHBhdGg6IGVudHJ5LnBhdGgucmVwbGFjZSgnJC4nLCAnLicpIH0pKVxuICAgIC5tYXAoKGVudHJ5KSA9PiAoe1xuICAgICAgLi4uZW50cnksXG4gICAgICBwYXRoOiBlbnRyeS5wYXRoLnJlcGxhY2UoLyhcXFsoPzxhcnJheT5cXGQpXFxdXFwuKS9nLCAnQVJSVkFMX1NUQVJUJDxhcnJheT5BUlJWQUxfRU5EJylcbiAgICB9KSlcbiAgICAubWFwKChlbnRyeSkgPT4gKHsgLi4uZW50cnksIHBhdGg6IGVudHJ5LnBhdGgucmVwbGFjZSgvKD88ZG90PlxcLikvZywgJy52YWx1ZSQ8ZG90PicpIH0pKVxuICAgIC5tYXAoKGVudHJ5KSA9PiAoeyAuLi5lbnRyeSwgcGF0aDogZW50cnkucGF0aC5yZXBsYWNlKC9cXC4vLCAnJykgfSkpXG4gICAgLm1hcCgoZW50cnkpID0+ICh7IC4uLmVudHJ5LCBwYXRoOiBlbnRyeS5wYXRoLnJlcGxhY2UoL0FSUlZBTF9TVEFSVC9nLCAnLnZhbHVlWycpIH0pKVxuICAgIC5tYXAoKGVudHJ5KSA9PiAoeyAuLi5lbnRyeSwgcGF0aDogZW50cnkucGF0aC5yZXBsYWNlKC9BUlJWQUxfRU5EL2csICddLnZhbHVlLicpIH0pKVxuICAgIC5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgc3dpdGNoIChlbnRyeS50eXBlKSB7XG4gICAgICAgIGNhc2UgT3BlcmF0aW9uLkFERDpcbiAgICAgICAgY2FzZSBPcGVyYXRpb24uVVBEQVRFOlxuICAgICAgICAgIHNldEJ5UGF0aChvYmplY3QsIGVudHJ5LnBhdGgsIHsgdHlwZTogZW50cnkudHlwZSwgdmFsdWU6IGVudHJ5LnZhbHVlLCBvbGRWYWx1ZTogZW50cnkub2xkVmFsdWUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgT3BlcmF0aW9uLlJFTU9WRTpcbiAgICAgICAgICBzZXRCeVBhdGgob2JqZWN0LCBlbnRyeS5wYXRoLCB7IHR5cGU6IGVudHJ5LnR5cGUsIHZhbHVlOiB1bmRlZmluZWQsIG9sZFZhbHVlOiBlbnRyeS52YWx1ZSB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG5cbmNvbnN0IGNvbXBhcmUgPSAob2xkT2JqZWN0OiBhbnksIG5ld09iamVjdDogYW55KTogSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUgPT4ge1xuICByZXR1cm4gYXBwbHlDaGFuZ2VsaXN0KGVucmljaChvbGRPYmplY3QpLCBhdG9taXplQ2hhbmdlc2V0KGRpZmYob2xkT2JqZWN0LCBuZXdPYmplY3QpKSk7XG59O1xuXG5leHBvcnQgeyBDb21wYXJlT3BlcmF0aW9uLCBJQ29tcGFyaXNvbkVucmljaGVkTm9kZSwgY3JlYXRlVmFsdWUsIGNyZWF0ZUNvbnRhaW5lciwgZW5yaWNoLCBhcHBseUNoYW5nZWxpc3QsIGNvbXBhcmUgfTtcbiIsICJpbXBvcnQgeyBTeW5jUGx1Z2luIH0gZnJvbSAnLi9TeW5jUGx1Z2luJztcbmltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG5pbXBvcnQgeyBkaWZmIH0gZnJvbSAnanNvbi1kaWZmLXRzJztcbi8qKlxuICogQmFzZUVudGl0eVNlcnZpY2U8VCBleHRlbmRzIElTeW5jPiAtIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGFsbCBlbnRpdHkgc2VydmljZXNcbiAqXG4gKiBQUk9WSURFUzpcbiAqIC0gR2VuZXJpYyBDUlVEIG9wZXJhdGlvbnMgKGdldCwgZ2V0QWxsLCBzYXZlLCBkZWxldGUpXG4gKiAtIFN5bmMgc3RhdHVzIG1hbmFnZW1lbnQgKGRlbGVnYXRlcyB0byBTeW5jUGx1Z2luKVxuICogLSBTZXJpYWxpemF0aW9uIGhvb2tzIChvdmVycmlkZSBpbiBzdWJjbGFzcyBpZiBuZWVkZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLnN5bmNQbHVnaW4gPSBuZXcgU3luY1BsdWdpbih0aGlzKTtcbiAgICB9XG4gICAgZ2V0IGRiKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmdldERhdGFiYXNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlcmlhbGl6ZSBlbnRpdHkgYmVmb3JlIHN0b3JpbmcgaW4gSW5kZXhlZERCXG4gICAgICovXG4gICAgc2VyaWFsaXplKGVudGl0eSkge1xuICAgICAgICByZXR1cm4gZW50aXR5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXNlcmlhbGl6ZSBkYXRhIGZyb20gSW5kZXhlZERCIGJhY2sgdG8gZW50aXR5XG4gICAgICovXG4gICAgZGVzZXJpYWxpemUoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgc2luZ2xlIGVudGl0eSBieSBJRFxuICAgICAqL1xuICAgIGFzeW5jIGdldChpZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUuZ2V0KGlkKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSByZXF1ZXN0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEgPyB0aGlzLmRlc2VyaWFsaXplKGRhdGEpIDogbnVsbCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgJHt0aGlzLmVudGl0eVR5cGV9ICR7aWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgZW50aXRpZXNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGwoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5nZXRBbGwoKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSByZXF1ZXN0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdGllcyA9IGRhdGEubWFwKGl0ZW0gPT4gdGhpcy5kZXNlcmlhbGl6ZShpdGVtKSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShlbnRpdGllcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgYWxsICR7dGhpcy5lbnRpdHlUeXBlfXM6ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2F2ZSBhbiBlbnRpdHkgKGNyZWF0ZSBvciB1cGRhdGUpXG4gICAgICogRW1pdHMgRU5USVRZX1NBVkVEIGV2ZW50IHdpdGggb3BlcmF0aW9uIHR5cGUgYW5kIGNoYW5nZXMgKGRpZmYgZm9yIHVwZGF0ZXMpXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEVudGl0eSB0byBzYXZlXG4gICAgICogQHBhcmFtIHNpbGVudCAtIElmIHRydWUsIHNraXAgZXZlbnQgZW1pc3Npb24gKHVzZWQgZm9yIHNlZWRpbmcpXG4gICAgICovXG4gICAgYXN5bmMgc2F2ZShlbnRpdHksIHNpbGVudCA9IGZhbHNlKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkID0gZW50aXR5LmlkO1xuICAgICAgICBjb25zdCBleGlzdGluZ0VudGl0eSA9IGF3YWl0IHRoaXMuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgaXNDcmVhdGUgPSBleGlzdGluZ0VudGl0eSA9PT0gbnVsbDtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGNoYW5nZXM6IGZ1bGwgZW50aXR5IGZvciBjcmVhdGUsIGRpZmYgZm9yIHVwZGF0ZVxuICAgICAgICBsZXQgY2hhbmdlcztcbiAgICAgICAgaWYgKGlzQ3JlYXRlKSB7XG4gICAgICAgICAgICBjaGFuZ2VzID0gZW50aXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdTZXJpYWxpemVkID0gdGhpcy5zZXJpYWxpemUoZXhpc3RpbmdFbnRpdHkpO1xuICAgICAgICAgICAgY29uc3QgbmV3U2VyaWFsaXplZCA9IHRoaXMuc2VyaWFsaXplKGVudGl0eSk7XG4gICAgICAgICAgICBjaGFuZ2VzID0gZGlmZihleGlzdGluZ1NlcmlhbGl6ZWQsIG5ld1NlcmlhbGl6ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB0aGlzLnNlcmlhbGl6ZShlbnRpdHkpO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLnB1dChzZXJpYWxpemVkKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgZW1pdCBldmVudCBpZiBub3Qgc2lsZW50IChzaWxlbnQgdXNlZCBmb3Igc2VlZGluZylcbiAgICAgICAgICAgICAgICBpZiAoIXNpbGVudCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5VHlwZTogdGhpcy5lbnRpdHlUeXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb246IGlzQ3JlYXRlID8gJ2NyZWF0ZScgOiAndXBkYXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KClcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRU5USVRZX1NBVkVELCBwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gc2F2ZSAke3RoaXMuZW50aXR5VHlwZX0gJHtlbnRpdHlJZH06ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVsZXRlIGFuIGVudGl0eVxuICAgICAqIEVtaXRzIEVOVElUWV9ERUxFVEVEIGV2ZW50XG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlKGlkKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUuZGVsZXRlKGlkKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGVudGl0eVR5cGU6IHRoaXMuZW50aXR5VHlwZSxcbiAgICAgICAgICAgICAgICAgICAgZW50aXR5SWQ6IGlkLFxuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb246ICdkZWxldGUnLFxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KClcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVOVElUWV9ERUxFVEVELCBwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBkZWxldGUgJHt0aGlzLmVudGl0eVR5cGV9ICR7aWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFN5bmMgbWV0aG9kcyAtIGRlbGVnYXRlIHRvIFN5bmNQbHVnaW5cbiAgICBhc3luYyBtYXJrQXNTeW5jZWQoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY1BsdWdpbi5tYXJrQXNTeW5jZWQoaWQpO1xuICAgIH1cbiAgICBhc3luYyBtYXJrQXNFcnJvcihpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jUGx1Z2luLm1hcmtBc0Vycm9yKGlkKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0U3luY1N0YXR1cyhpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jUGx1Z2luLmdldFN5bmNTdGF0dXMoaWQpO1xuICAgIH1cbiAgICBhc3luYyBnZXRCeVN5bmNTdGF0dXMoc3luY1N0YXR1cykge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jUGx1Z2luLmdldEJ5U3luY1N0YXR1cyhzeW5jU3RhdHVzKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgRXZlbnRTdG9yZSB9IGZyb20gJy4vRXZlbnRTdG9yZSc7XG5pbXBvcnQgeyBFdmVudFNlcmlhbGl6YXRpb24gfSBmcm9tICcuL0V2ZW50U2VyaWFsaXphdGlvbic7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogRXZlbnRTZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciBjYWxlbmRhciBldmVudHMgaW4gSW5kZXhlZERCXG4gKlxuICogRXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSBmb3Igc2hhcmVkIENSVUQgYW5kIHN5bmMgbG9naWMuXG4gKiBQcm92aWRlcyBldmVudC1zcGVjaWZpYyBxdWVyeSBtZXRob2RzLlxuICovXG5leHBvcnQgY2xhc3MgRXZlbnRTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBFdmVudFN0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdFdmVudCc7XG4gICAgfVxuICAgIHNlcmlhbGl6ZShldmVudCkge1xuICAgICAgICByZXR1cm4gRXZlbnRTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShldmVudCk7XG4gICAgfVxuICAgIGRlc2VyaWFsaXplKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50U2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShkYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGV2ZW50cyB3aXRoaW4gYSBkYXRlIHJhbmdlXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlEYXRlUmFuZ2Uoc3RhcnQsIGVuZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdzdGFydCcpO1xuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBJREJLZXlSYW5nZS5sb3dlckJvdW5kKHN0YXJ0LnRvSVNPU3RyaW5nKCkpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldEFsbChyYW5nZSk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRzID0gZGF0YVxuICAgICAgICAgICAgICAgICAgICAubWFwKGl0ZW0gPT4gdGhpcy5kZXNlcmlhbGl6ZShpdGVtKSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihldmVudCA9PiBldmVudC5zdGFydCA8PSBlbmQpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoZXZlbnRzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGdldCBldmVudHMgYnkgZGF0ZSByYW5nZTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZXZlbnRzIGZvciBhIHNwZWNpZmljIHJlc291cmNlXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlSZXNvdXJjZShyZXNvdXJjZUlkKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ3Jlc291cmNlSWQnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleC5nZXRBbGwocmVzb3VyY2VJZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRzID0gZGF0YS5tYXAoaXRlbSA9PiB0aGlzLmRlc2VyaWFsaXplKGl0ZW0pKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGV2ZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgZXZlbnRzIGZvciByZXNvdXJjZSAke3Jlc291cmNlSWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBldmVudHMgZm9yIGEgcmVzb3VyY2Ugd2l0aGluIGEgZGF0ZSByYW5nZVxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5UmVzb3VyY2VBbmREYXRlUmFuZ2UocmVzb3VyY2VJZCwgc3RhcnQsIGVuZCkge1xuICAgICAgICBjb25zdCByZXNvdXJjZUV2ZW50cyA9IGF3YWl0IHRoaXMuZ2V0QnlSZXNvdXJjZShyZXNvdXJjZUlkKTtcbiAgICAgICAgcmV0dXJuIHJlc291cmNlRXZlbnRzLmZpbHRlcihldmVudCA9PiBldmVudC5zdGFydCA+PSBzdGFydCAmJiBldmVudC5zdGFydCA8PSBlbmQpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFJlc291cmNlU3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZGVmaW5pdGlvbiBmb3IgcmVzb3VyY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBSZXNvdXJjZVN0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBjb25zdCBzdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKFJlc291cmNlU3RvcmUuU1RPUkVfTkFNRSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgndHlwZScsICd0eXBlJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnaXNBY3RpdmUnLCAnaXNBY3RpdmUnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgfVxufVxuUmVzb3VyY2VTdG9yZS5TVE9SRV9OQU1FID0gJ3Jlc291cmNlcyc7XG4iLCAiaW1wb3J0IHsgUmVzb3VyY2VTdG9yZSB9IGZyb20gJy4vUmVzb3VyY2VTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogUmVzb3VyY2VTZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciByZXNvdXJjZXMgaW4gSW5kZXhlZERCXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVNlcnZpY2UgZXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCwgZXZlbnRCdXMpO1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IFJlc291cmNlU3RvcmUuU1RPUkVfTkFNRTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ1Jlc291cmNlJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBhY3RpdmUgcmVzb3VyY2VzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QWN0aXZlKCkge1xuICAgICAgICBjb25zdCBhbGwgPSBhd2FpdCB0aGlzLmdldEFsbCgpO1xuICAgICAgICByZXR1cm4gYWxsLmZpbHRlcihyID0+IHIuaXNBY3RpdmUgIT09IGZhbHNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHJlc291cmNlcyBieSBJRHNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeUlkcyhpZHMpIHtcbiAgICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChpZHMubWFwKGlkID0+IHRoaXMuZ2V0KGlkKSkpO1xuICAgICAgICByZXR1cm4gcmVzdWx0cy5maWx0ZXIoKHIpID0+IHIgIT09IG51bGwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgcmVzb3VyY2VzIGJ5IHR5cGVcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVR5cGUodHlwZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCd0eXBlJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKHR5cGUpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgcmVzb3VyY2VzIGJ5IHR5cGUgJHt0eXBlfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIEJvb2tpbmdTdG9yZSAtIEluZGV4ZWREQiBPYmplY3RTdG9yZSBkZWZpbml0aW9uIGZvciBib29raW5nc1xuICovXG5leHBvcnQgY2xhc3MgQm9va2luZ1N0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBCb29raW5nU3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUoQm9va2luZ1N0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2N1c3RvbWVySWQnLCAnY3VzdG9tZXJJZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N0YXR1cycsICdzdGF0dXMnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdzeW5jU3RhdHVzJywgJ3N5bmNTdGF0dXMnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdjcmVhdGVkQXQnLCAnY3JlYXRlZEF0JywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgIH1cbn1cbkJvb2tpbmdTdG9yZS5TVE9SRV9OQU1FID0gJ2Jvb2tpbmdzJztcbiIsICJpbXBvcnQgeyBCb29raW5nU3RvcmUgfSBmcm9tICcuL0Jvb2tpbmdTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogQm9va2luZ1NlcnZpY2UgLSBDUlVEIG9wZXJhdGlvbnMgZm9yIGJvb2tpbmdzIGluIEluZGV4ZWREQlxuICovXG5leHBvcnQgY2xhc3MgQm9va2luZ1NlcnZpY2UgZXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCwgZXZlbnRCdXMpO1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IEJvb2tpbmdTdG9yZS5TVE9SRV9OQU1FO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnQm9va2luZyc7XG4gICAgfVxuICAgIHNlcmlhbGl6ZShib29raW5nKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5ib29raW5nLFxuICAgICAgICAgICAgY3JlYXRlZEF0OiBib29raW5nLmNyZWF0ZWRBdC50b0lTT1N0cmluZygpXG4gICAgICAgIH07XG4gICAgfVxuICAgIGRlc2VyaWFsaXplKGRhdGEpIHtcbiAgICAgICAgY29uc3QgcmF3ID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnJhdyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUocmF3LmNyZWF0ZWRBdClcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGJvb2tpbmdzIGZvciBhIGN1c3RvbWVyXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlDdXN0b21lcihjdXN0b21lcklkKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ2N1c3RvbWVySWQnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleC5nZXRBbGwoY3VzdG9tZXJJZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9va2luZ3MgPSBkYXRhLm1hcChpdGVtID0+IHRoaXMuZGVzZXJpYWxpemUoaXRlbSkpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoYm9va2luZ3MpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGJvb2tpbmdzIGZvciBjdXN0b21lciAke2N1c3RvbWVySWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBib29raW5ncyBieSBzdGF0dXNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVN0YXR1cyhzdGF0dXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5pbmRleCgnc3RhdHVzJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKHN0YXR1cyk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9va2luZ3MgPSBkYXRhLm1hcChpdGVtID0+IHRoaXMuZGVzZXJpYWxpemUoaXRlbSkpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoYm9va2luZ3MpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGJvb2tpbmdzIHdpdGggc3RhdHVzICR7c3RhdHVzfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIEN1c3RvbWVyU3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZGVmaW5pdGlvbiBmb3IgY3VzdG9tZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBDdXN0b21lclN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBDdXN0b21lclN0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBjb25zdCBzdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKEN1c3RvbWVyU3RvcmUuU1RPUkVfTkFNRSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnbmFtZScsICduYW1lJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgncGhvbmUnLCAncGhvbmUnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdzeW5jU3RhdHVzJywgJ3N5bmNTdGF0dXMnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgfVxufVxuQ3VzdG9tZXJTdG9yZS5TVE9SRV9OQU1FID0gJ2N1c3RvbWVycyc7XG4iLCAiaW1wb3J0IHsgQ3VzdG9tZXJTdG9yZSB9IGZyb20gJy4vQ3VzdG9tZXJTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogQ3VzdG9tZXJTZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciBjdXN0b21lcnMgaW4gSW5kZXhlZERCXG4gKi9cbmV4cG9ydCBjbGFzcyBDdXN0b21lclNlcnZpY2UgZXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCwgZXZlbnRCdXMpO1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IEN1c3RvbWVyU3RvcmUuU1RPUkVfTkFNRTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0N1c3RvbWVyJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VhcmNoIGN1c3RvbWVycyBieSBuYW1lIChjYXNlLWluc2Vuc2l0aXZlIGNvbnRhaW5zKVxuICAgICAqL1xuICAgIGFzeW5jIHNlYXJjaEJ5TmFtZShxdWVyeSkge1xuICAgICAgICBjb25zdCBhbGwgPSBhd2FpdCB0aGlzLmdldEFsbCgpO1xuICAgICAgICBjb25zdCBsb3dlclF1ZXJ5ID0gcXVlcnkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGFsbC5maWx0ZXIoYyA9PiBjLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhsb3dlclF1ZXJ5KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmQgY3VzdG9tZXIgYnkgcGhvbmVcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVBob25lKHBob25lKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ3Bob25lJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0KHBob25lKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSByZXF1ZXN0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEgPyBkYXRhIDogbnVsbCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBmaW5kIGN1c3RvbWVyIGJ5IHBob25lICR7cGhvbmV9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogVGVhbVN0b3JlIC0gSW5kZXhlZERCIE9iamVjdFN0b3JlIGRlZmluaXRpb24gZm9yIHRlYW1zXG4gKi9cbmV4cG9ydCBjbGFzcyBUZWFtU3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IFRlYW1TdG9yZS5TVE9SRV9OQU1FO1xuICAgIH1cbiAgICBjcmVhdGUoZGIpIHtcbiAgICAgICAgZGIuY3JlYXRlT2JqZWN0U3RvcmUoVGVhbVN0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICB9XG59XG5UZWFtU3RvcmUuU1RPUkVfTkFNRSA9ICd0ZWFtcyc7XG4iLCAiaW1wb3J0IHsgVGVhbVN0b3JlIH0gZnJvbSAnLi9UZWFtU3RvcmUnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIFRlYW1TZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciB0ZWFtcyBpbiBJbmRleGVkREJcbiAqXG4gKiBUZWFtcyBkZWZpbmUgd2hpY2ggcmVzb3VyY2VzIGJlbG9uZyB0b2dldGhlciBmb3IgaGllcmFyY2hpY2FsIGdyb3VwaW5nLlxuICogRXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSBmb3Igc3RhbmRhcmQgZW50aXR5IG9wZXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZWFtU2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gVGVhbVN0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdUZWFtJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRlYW1zIGJ5IElEc1xuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5SWRzKGlkcykge1xuICAgICAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGlkcy5tYXAoaWQgPT4gdGhpcy5nZXQoaWQpKSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzLmZpbHRlcigodCkgPT4gdCAhPT0gbnVsbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJ1aWxkIHJldmVyc2UgbG9va3VwOiByZXNvdXJjZUlkIFx1MjE5MiB0ZWFtSWRcbiAgICAgKi9cbiAgICBhc3luYyBidWlsZFJlc291cmNlVG9UZWFtTWFwKCkge1xuICAgICAgICBjb25zdCB0ZWFtcyA9IGF3YWl0IHRoaXMuZ2V0QWxsKCk7XG4gICAgICAgIGNvbnN0IG1hcCA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IHRlYW0gb2YgdGVhbXMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb3VyY2VJZCBvZiB0ZWFtLnJlc291cmNlSWRzKSB7XG4gICAgICAgICAgICAgICAgbWFwW3Jlc291cmNlSWRdID0gdGVhbS5pZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWFwO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIERlcGFydG1lbnRTdG9yZSAtIEluZGV4ZWREQiBPYmplY3RTdG9yZSBkZWZpbml0aW9uIGZvciBkZXBhcnRtZW50c1xuICovXG5leHBvcnQgY2xhc3MgRGVwYXJ0bWVudFN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBEZXBhcnRtZW50U3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKERlcGFydG1lbnRTdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgfVxufVxuRGVwYXJ0bWVudFN0b3JlLlNUT1JFX05BTUUgPSAnZGVwYXJ0bWVudHMnO1xuIiwgImltcG9ydCB7IERlcGFydG1lbnRTdG9yZSB9IGZyb20gJy4vRGVwYXJ0bWVudFN0b3JlJztcbmltcG9ydCB7IEJhc2VFbnRpdHlTZXJ2aWNlIH0gZnJvbSAnLi4vQmFzZUVudGl0eVNlcnZpY2UnO1xuLyoqXG4gKiBEZXBhcnRtZW50U2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgZGVwYXJ0bWVudHMgaW4gSW5kZXhlZERCXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXBhcnRtZW50U2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gRGVwYXJ0bWVudFN0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdEZXBhcnRtZW50JztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGRlcGFydG1lbnRzIGJ5IElEc1xuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5SWRzKGlkcykge1xuICAgICAgICBpZiAoaWRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGlkcy5tYXAoaWQgPT4gdGhpcy5nZXQoaWQpKSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzLmZpbHRlcigoZCkgPT4gZCAhPT0gbnVsbCk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogU2V0dGluZ3NTdG9yZSAtIEluZGV4ZWREQiBPYmplY3RTdG9yZSBkZWZpbml0aW9uIGZvciB0ZW5hbnQgc2V0dGluZ3NcbiAqXG4gKiBTaW5nbGUgc3RvcmUgZm9yIGFsbCBzZXR0aW5ncyBzZWN0aW9ucy4gU2V0dGluZ3MgYXJlIHN0b3JlZCBhcyBvbmUgZG9jdW1lbnRcbiAqIHBlciB0ZW5hbnQgd2l0aCBpZD0ndGVuYW50LXNldHRpbmdzJy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNldHRpbmdzU3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IFNldHRpbmdzU3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFNldHRpbmdzU3RvcmUuU1RPUkVfTkFNRSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgIH1cbn1cblNldHRpbmdzU3RvcmUuU1RPUkVfTkFNRSA9ICdzZXR0aW5ncyc7XG4iLCAiLyoqXG4gKiBTZXR0aW5ncyBJRHMgYXMgY29uc3QgZm9yIHR5cGUgc2FmZXR5XG4gKi9cbmV4cG9ydCBjb25zdCBTZXR0aW5nc0lkcyA9IHtcbiAgICBXT1JLV0VFSzogJ3dvcmt3ZWVrJyxcbiAgICBHUklEOiAnZ3JpZCcsXG4gICAgVElNRV9GT1JNQVQ6ICd0aW1lRm9ybWF0JyxcbiAgICBWSUVXUzogJ3ZpZXdzJ1xufTtcbiIsICJpbXBvcnQgeyBTZXR0aW5nc0lkcyB9IGZyb20gJy4uLy4uL3R5cGVzL1NldHRpbmdzVHlwZXMnO1xuaW1wb3J0IHsgU2V0dGluZ3NTdG9yZSB9IGZyb20gJy4vU2V0dGluZ3NTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogU2V0dGluZ3NTZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciB0ZW5hbnQgc2V0dGluZ3NcbiAqXG4gKiBTZXR0aW5ncyBhcmUgc3RvcmVkIGFzIHNlcGFyYXRlIHJlY29yZHMgcGVyIHNlY3Rpb24uXG4gKiBUaGlzIHNlcnZpY2UgcHJvdmlkZXMgdHlwZWQgbWV0aG9kcyBmb3IgYWNjZXNzaW5nIHNwZWNpZmljIHNldHRpbmdzLlxuICovXG5leHBvcnQgY2xhc3MgU2V0dGluZ3NTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBTZXR0aW5nc1N0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdTZXR0aW5ncyc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB3b3Jrd2VlayBzZXR0aW5nc1xuICAgICAqL1xuICAgIGFzeW5jIGdldFdvcmt3ZWVrU2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChTZXR0aW5nc0lkcy5XT1JLV0VFSyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBncmlkIHNldHRpbmdzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0R3JpZFNldHRpbmdzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoU2V0dGluZ3NJZHMuR1JJRCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aW1lIGZvcm1hdCBzZXR0aW5nc1xuICAgICAqL1xuICAgIGFzeW5jIGdldFRpbWVGb3JtYXRTZXR0aW5ncygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KFNldHRpbmdzSWRzLlRJTUVfRk9STUFUKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHZpZXcgc2V0dGluZ3NcbiAgICAgKi9cbiAgICBhc3luYyBnZXRWaWV3U2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChTZXR0aW5nc0lkcy5WSUVXUyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB3b3Jrd2VlayBwcmVzZXQgYnkgSURcbiAgICAgKi9cbiAgICBhc3luYyBnZXRXb3Jrd2Vla1ByZXNldChwcmVzZXRJZCkge1xuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IGF3YWl0IHRoaXMuZ2V0V29ya3dlZWtTZXR0aW5ncygpO1xuICAgICAgICBpZiAoIXNldHRpbmdzKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBzZXR0aW5ncy5wcmVzZXRzW3ByZXNldElkXSB8fCBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGRlZmF1bHQgd29ya3dlZWsgcHJlc2V0XG4gICAgICovXG4gICAgYXN5bmMgZ2V0RGVmYXVsdFdvcmt3ZWVrUHJlc2V0KCkge1xuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IGF3YWl0IHRoaXMuZ2V0V29ya3dlZWtTZXR0aW5ncygpO1xuICAgICAgICBpZiAoIXNldHRpbmdzKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBzZXR0aW5ncy5wcmVzZXRzW3NldHRpbmdzLmRlZmF1bHRQcmVzZXRdIHx8IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgYXZhaWxhYmxlIHdvcmt3ZWVrIHByZXNldHNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRXb3Jrd2Vla1ByZXNldHMoKSB7XG4gICAgICAgIGNvbnN0IHNldHRpbmdzID0gYXdhaXQgdGhpcy5nZXRXb3Jrd2Vla1NldHRpbmdzKCk7XG4gICAgICAgIGlmICghc2V0dGluZ3MpXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKHNldHRpbmdzLnByZXNldHMpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgVmlld0NvbmZpZ1N0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBWaWV3Q29uZmlnU3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFZpZXdDb25maWdTdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgfVxufVxuVmlld0NvbmZpZ1N0b3JlLlNUT1JFX05BTUUgPSAndmlld2NvbmZpZ3MnO1xuIiwgImltcG9ydCB7IFZpZXdDb25maWdTdG9yZSB9IGZyb20gJy4vVmlld0NvbmZpZ1N0b3JlJztcbmltcG9ydCB7IEJhc2VFbnRpdHlTZXJ2aWNlIH0gZnJvbSAnLi4vQmFzZUVudGl0eVNlcnZpY2UnO1xuZXhwb3J0IGNsYXNzIFZpZXdDb25maWdTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBWaWV3Q29uZmlnU3RvcmUuU1RPUkVfTkFNRTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ1ZpZXdDb25maWcnO1xuICAgIH1cbiAgICBhc3luYyBnZXRCeUlkKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChpZCk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQXVkaXRTdG9yZSAtIEluZGV4ZWREQiBzdG9yZSBjb25maWd1cmF0aW9uIGZvciBhdWRpdCBlbnRyaWVzXG4gKlxuICogU3RvcmVzIGFsbCBlbnRpdHkgY2hhbmdlcyBmb3I6XG4gKiAtIENvbXBsaWFuY2UgYW5kIGF1ZGl0IHRyYWlsXG4gKiAtIFN5bmMgdHJhY2tpbmcgd2l0aCBiYWNrZW5kXG4gKiAtIENoYW5nZSBoaXN0b3J5XG4gKlxuICogSW5kZXhlczpcbiAqIC0gc3luY1N0YXR1czogRm9yIGZpbmRpbmcgcGVuZGluZyBlbnRyaWVzIHRvIHN5bmNcbiAqIC0gc3luY2VkOiBCb29sZWFuIGZsYWcgZm9yIHF1aWNrIHN5bmMgcXVlcmllc1xuICogLSBlbnRpdHlJZDogRm9yIGdldHRpbmcgYWxsIGF1ZGl0cyBmb3IgYSBzcGVjaWZpYyBlbnRpdHlcbiAqIC0gdGltZXN0YW1wOiBGb3IgY2hyb25vbG9naWNhbCBxdWVyaWVzXG4gKi9cbmV4cG9ydCBjbGFzcyBBdWRpdFN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSAnYXVkaXQnO1xuICAgIH1cbiAgICBjcmVhdGUoZGIpIHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBkYi5jcmVhdGVPYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY2VkJywgJ3N5bmNlZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2VudGl0eUlkJywgJ2VudGl0eUlkJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgndGltZXN0YW1wJywgJ3RpbWVzdGFtcCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG5pbXBvcnQgeyBDb3JlRXZlbnRzIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL0NvcmVFdmVudHMnO1xuLyoqXG4gKiBBdWRpdFNlcnZpY2UgLSBFbnRpdHkgc2VydmljZSBmb3IgYXVkaXQgZW50cmllc1xuICpcbiAqIFJFU1BPTlNJQklMSVRJRVM6XG4gKiAtIFN0b3JlIGF1ZGl0IGVudHJpZXMgaW4gSW5kZXhlZERCXG4gKiAtIExpc3RlbiBmb3IgRU5USVRZX1NBVkVEL0VOVElUWV9ERUxFVEVEIGV2ZW50c1xuICogLSBDcmVhdGUgYXVkaXQgZW50cmllcyBmb3IgYWxsIGVudGl0eSBjaGFuZ2VzXG4gKiAtIEVtaXQgQVVESVRfTE9HR0VEIGFmdGVyIHNhdmluZyAoZm9yIFN5bmNNYW5hZ2VyIHRvIGxpc3RlbilcbiAqXG4gKiBPVkVSUklERSBQQVRURVJOOlxuICogLSBPdmVycmlkZXMgc2F2ZSgpIHRvIE5PVCBlbWl0IGV2ZW50cyAocHJldmVudHMgaW5maW5pdGUgbG9vcHMpXG4gKiAtIEF1ZGl0U2VydmljZSBzYXZlcyBhdWRpdCBlbnRyaWVzIHdpdGhvdXQgdHJpZ2dlcmluZyBtb3JlIGF1ZGl0c1xuICpcbiAqIEVWRU5UIENIQUlOOlxuICogRW50aXR5IGNoYW5nZSBcdTIxOTIgRU5USVRZX1NBVkVEL0RFTEVURUQgXHUyMTkyIEF1ZGl0U2VydmljZSBcdTIxOTIgQVVESVRfTE9HR0VEIFx1MjE5MiBTeW5jTWFuYWdlclxuICovXG5leHBvcnQgY2xhc3MgQXVkaXRTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSAnYXVkaXQnO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnQXVkaXQnO1xuICAgICAgICB0aGlzLnNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0dXAgbGlzdGVuZXJzIGZvciBFTlRJVFlfU0FWRUQgYW5kIEVOVElUWV9ERUxFVEVEIGV2ZW50c1xuICAgICAqL1xuICAgIHNldHVwRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgICAgIC8vIExpc3RlbiBmb3IgZW50aXR5IHNhdmVzIChjcmVhdGUvdXBkYXRlKVxuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRU5USVRZX1NBVkVELCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRldGFpbCA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRW50aXR5U2F2ZWQoZGV0YWlsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIExpc3RlbiBmb3IgZW50aXR5IGRlbGV0ZXNcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVOVElUWV9ERUxFVEVELCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRldGFpbCA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRW50aXR5RGVsZXRlZChkZXRhaWwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIEVOVElUWV9TQVZFRCBldmVudCAtIGNyZWF0ZSBhdWRpdCBlbnRyeVxuICAgICAqL1xuICAgIGFzeW5jIGhhbmRsZUVudGl0eVNhdmVkKHBheWxvYWQpIHtcbiAgICAgICAgLy8gRG9uJ3QgYXVkaXQgYXVkaXQgZW50cmllcyAocHJldmVudCBpbmZpbml0ZSBsb29wcylcbiAgICAgICAgaWYgKHBheWxvYWQuZW50aXR5VHlwZSA9PT0gJ0F1ZGl0JylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgYXVkaXRFbnRyeSA9IHtcbiAgICAgICAgICAgIGlkOiBjcnlwdG8ucmFuZG9tVVVJRCgpLFxuICAgICAgICAgICAgZW50aXR5VHlwZTogcGF5bG9hZC5lbnRpdHlUeXBlLFxuICAgICAgICAgICAgZW50aXR5SWQ6IHBheWxvYWQuZW50aXR5SWQsXG4gICAgICAgICAgICBvcGVyYXRpb246IHBheWxvYWQub3BlcmF0aW9uLFxuICAgICAgICAgICAgdXNlcklkOiBBdWRpdFNlcnZpY2UuREVGQVVMVF9VU0VSX0lELFxuICAgICAgICAgICAgdGltZXN0YW1wOiBwYXlsb2FkLnRpbWVzdGFtcCxcbiAgICAgICAgICAgIGNoYW5nZXM6IHBheWxvYWQuY2hhbmdlcyxcbiAgICAgICAgICAgIHN5bmNlZDogZmFsc2UsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlKGF1ZGl0RW50cnkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgRU5USVRZX0RFTEVURUQgZXZlbnQgLSBjcmVhdGUgYXVkaXQgZW50cnlcbiAgICAgKi9cbiAgICBhc3luYyBoYW5kbGVFbnRpdHlEZWxldGVkKHBheWxvYWQpIHtcbiAgICAgICAgLy8gRG9uJ3QgYXVkaXQgYXVkaXQgZW50cmllcyAocHJldmVudCBpbmZpbml0ZSBsb29wcylcbiAgICAgICAgaWYgKHBheWxvYWQuZW50aXR5VHlwZSA9PT0gJ0F1ZGl0JylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgYXVkaXRFbnRyeSA9IHtcbiAgICAgICAgICAgIGlkOiBjcnlwdG8ucmFuZG9tVVVJRCgpLFxuICAgICAgICAgICAgZW50aXR5VHlwZTogcGF5bG9hZC5lbnRpdHlUeXBlLFxuICAgICAgICAgICAgZW50aXR5SWQ6IHBheWxvYWQuZW50aXR5SWQsXG4gICAgICAgICAgICBvcGVyYXRpb246ICdkZWxldGUnLFxuICAgICAgICAgICAgdXNlcklkOiBBdWRpdFNlcnZpY2UuREVGQVVMVF9VU0VSX0lELFxuICAgICAgICAgICAgdGltZXN0YW1wOiBwYXlsb2FkLnRpbWVzdGFtcCxcbiAgICAgICAgICAgIGNoYW5nZXM6IHsgaWQ6IHBheWxvYWQuZW50aXR5SWQgfSwgLy8gRm9yIGRlbGV0ZSwganVzdCBzdG9yZSB0aGUgSURcbiAgICAgICAgICAgIHN5bmNlZDogZmFsc2UsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlKGF1ZGl0RW50cnkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSBzYXZlIHRvIE5PVCB0cmlnZ2VyIEVOVElUWV9TQVZFRCBldmVudFxuICAgICAqIEluc3RlYWQsIGVtaXRzIEFVRElUX0xPR0dFRCBmb3IgU3luY01hbmFnZXIgdG8gbGlzdGVuXG4gICAgICpcbiAgICAgKiBUaGlzIHByZXZlbnRzIGluZmluaXRlIGxvb3BzOlxuICAgICAqIC0gQmFzZUVudGl0eVNlcnZpY2Uuc2F2ZSgpIGVtaXRzIEVOVElUWV9TQVZFRFxuICAgICAqIC0gQXVkaXRTZXJ2aWNlIGxpc3RlbnMgdG8gRU5USVRZX1NBVkVEIGFuZCBjcmVhdGVzIGF1ZGl0XG4gICAgICogLSBJZiBBdWRpdFNlcnZpY2Uuc2F2ZSgpIGFsc28gZW1pdHRlZCBFTlRJVFlfU0FWRUQsIGl0IHdvdWxkIGxvb3BcbiAgICAgKi9cbiAgICBhc3luYyBzYXZlKGVudGl0eSkge1xuICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gdGhpcy5zZXJpYWxpemUoZW50aXR5KTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZHdyaXRlJyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5wdXQoc2VyaWFsaXplZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBFbWl0IEFVRElUX0xPR0dFRCBpbnN0ZWFkIG9mIEVOVElUWV9TQVZFRFxuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGl0SWQ6IGVudGl0eS5pZCxcbiAgICAgICAgICAgICAgICAgICAgZW50aXR5VHlwZTogZW50aXR5LmVudGl0eVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbjogZW50aXR5Lm9wZXJhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBlbnRpdHkudGltZXN0YW1wXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5BVURJVF9MT0dHRUQsIHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIHNhdmUgYXVkaXQgZW50cnkgJHtlbnRpdHkuaWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIGRlbGV0ZSB0byBOT1QgdHJpZ2dlciBFTlRJVFlfREVMRVRFRCBldmVudFxuICAgICAqIEF1ZGl0IGVudHJpZXMgc2hvdWxkIG5ldmVyIGJlIGRlbGV0ZWQgKGNvbXBsaWFuY2UgcmVxdWlyZW1lbnQpXG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1ZGl0IGVudHJpZXMgY2Fubm90IGJlIGRlbGV0ZWQgKGNvbXBsaWFuY2UgcmVxdWlyZW1lbnQpJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBwZW5kaW5nIGF1ZGl0IGVudHJpZXMgKGZvciBzeW5jKVxuICAgICAqL1xuICAgIGFzeW5jIGdldFBlbmRpbmdBdWRpdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ5U3luY1N0YXR1cygncGVuZGluZycpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYXVkaXQgZW50cmllcyBmb3IgYSBzcGVjaWZpYyBlbnRpdHlcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeUVudGl0eUlkKGVudGl0eUlkKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ2VudGl0eUlkJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKGVudGl0eUlkKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSByZXF1ZXN0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGVudHJpZXMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGF1ZGl0IGVudHJpZXMgZm9yIGVudGl0eSAke2VudGl0eUlkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vIEhhcmRjb2RlZCB1c2VySWQgZm9yIG5vdyAtIHdpbGwgY29tZSBmcm9tIHNlc3Npb24gbGF0ZXJcbkF1ZGl0U2VydmljZS5ERUZBVUxUX1VTRVJfSUQgPSAnMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAxJztcbiIsICIvKipcbiAqIE1vY2tFdmVudFJlcG9zaXRvcnkgLSBMb2FkcyBldmVudCBkYXRhIGZyb20gbG9jYWwgSlNPTiBmaWxlXG4gKlxuICogVXNlZCBmb3IgZGV2ZWxvcG1lbnQgYW5kIHRlc3RpbmcuIE9ubHkgZmV0Y2hBbGwoKSBpcyBpbXBsZW1lbnRlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tFdmVudFJlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnRXZlbnQnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS9tb2NrLWV2ZW50cy5qc29uJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmV0Y2ggYWxsIGV2ZW50cyBmcm9tIG1vY2sgSlNPTiBmaWxlXG4gICAgICovXG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZGF0YVVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2NrIGV2ZW50czogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzQ2FsZW5kYXJEYXRhKHJhd0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgZXZlbnQgZGF0YTonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKF9ldmVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tFdmVudFJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kQ3JlYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX3VwZGF0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRXZlbnRSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZFVwZGF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZERlbGV0ZShfaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRXZlbnRSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZERlbGV0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgcHJvY2Vzc0NhbGVuZGFyRGF0YShkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGN1c3RvbWVyIGV2ZW50IGNvbnN0cmFpbnRzXG4gICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2N1c3RvbWVyJykge1xuICAgICAgICAgICAgICAgIGlmICghZXZlbnQuYm9va2luZ0lkKVxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEN1c3RvbWVyIGV2ZW50ICR7ZXZlbnQuaWR9IG1pc3NpbmcgYm9va2luZ0lkYCk7XG4gICAgICAgICAgICAgICAgaWYgKCFldmVudC5yZXNvdXJjZUlkKVxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEN1c3RvbWVyIGV2ZW50ICR7ZXZlbnQuaWR9IG1pc3NpbmcgcmVzb3VyY2VJZGApO1xuICAgICAgICAgICAgICAgIGlmICghZXZlbnQuY3VzdG9tZXJJZClcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBDdXN0b21lciBldmVudCAke2V2ZW50LmlkfSBtaXNzaW5nIGN1c3RvbWVySWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaWQ6IGV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBldmVudC50aXRsZSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogZXZlbnQuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgc3RhcnQ6IG5ldyBEYXRlKGV2ZW50LnN0YXJ0KSxcbiAgICAgICAgICAgICAgICBlbmQ6IG5ldyBEYXRlKGV2ZW50LmVuZCksXG4gICAgICAgICAgICAgICAgdHlwZTogZXZlbnQudHlwZSxcbiAgICAgICAgICAgICAgICBhbGxEYXk6IGV2ZW50LmFsbERheSB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBib29raW5nSWQ6IGV2ZW50LmJvb2tpbmdJZCxcbiAgICAgICAgICAgICAgICByZXNvdXJjZUlkOiBldmVudC5yZXNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIGN1c3RvbWVySWQ6IGV2ZW50LmN1c3RvbWVySWQsXG4gICAgICAgICAgICAgICAgcmVjdXJyaW5nSWQ6IGV2ZW50LnJlY3VycmluZ0lkLFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBldmVudC5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBzeW5jU3RhdHVzOiAnc3luY2VkJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogTW9ja1Jlc291cmNlUmVwb3NpdG9yeSAtIExvYWRzIHJlc291cmNlIGRhdGEgZnJvbSBsb2NhbCBKU09OIGZpbGVcbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tSZXNvdXJjZVJlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnUmVzb3VyY2UnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS9tb2NrLXJlc291cmNlcy5qc29uJztcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZGF0YVVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2NrIHJlc291cmNlczogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzUmVzb3VyY2VEYXRhKHJhd0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgcmVzb3VyY2UgZGF0YTonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKF9yZXNvdXJjZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tSZXNvdXJjZVJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kQ3JlYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX3VwZGF0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrUmVzb3VyY2VSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZFVwZGF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZERlbGV0ZShfaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrUmVzb3VyY2VSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZERlbGV0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgcHJvY2Vzc1Jlc291cmNlRGF0YShkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgocmVzb3VyY2UpID0+ICh7XG4gICAgICAgICAgICBpZDogcmVzb3VyY2UuaWQsXG4gICAgICAgICAgICBuYW1lOiByZXNvdXJjZS5uYW1lLFxuICAgICAgICAgICAgZGlzcGxheU5hbWU6IHJlc291cmNlLmRpc3BsYXlOYW1lLFxuICAgICAgICAgICAgdHlwZTogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgICAgIGF2YXRhclVybDogcmVzb3VyY2UuYXZhdGFyVXJsLFxuICAgICAgICAgICAgY29sb3I6IHJlc291cmNlLmNvbG9yLFxuICAgICAgICAgICAgaXNBY3RpdmU6IHJlc291cmNlLmlzQWN0aXZlLFxuICAgICAgICAgICAgZGVmYXVsdFNjaGVkdWxlOiByZXNvdXJjZS5kZWZhdWx0U2NoZWR1bGUsXG4gICAgICAgICAgICBtZXRhZGF0YTogcmVzb3VyY2UubWV0YWRhdGEsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAnc3luY2VkJ1xuICAgICAgICB9KSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogTW9ja0Jvb2tpbmdSZXBvc2l0b3J5IC0gTG9hZHMgYm9va2luZyBkYXRhIGZyb20gbG9jYWwgSlNPTiBmaWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrQm9va2luZ1JlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnQm9va2luZyc7XG4gICAgICAgIHRoaXMuZGF0YVVybCA9ICdkYXRhL21vY2stYm9va2luZ3MuanNvbic7XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9jayBib29raW5nczogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzQm9va2luZ0RhdGEocmF3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCBib29raW5nIGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfYm9va2luZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tCb29raW5nUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRDcmVhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmRVcGRhdGUoX2lkLCBfdXBkYXRlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tCb29raW5nUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0Jvb2tpbmdSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZERlbGV0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgcHJvY2Vzc0Jvb2tpbmdEYXRhKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGRhdGEubWFwKChib29raW5nKSA9PiAoe1xuICAgICAgICAgICAgaWQ6IGJvb2tpbmcuaWQsXG4gICAgICAgICAgICBjdXN0b21lcklkOiBib29raW5nLmN1c3RvbWVySWQsXG4gICAgICAgICAgICBzdGF0dXM6IGJvb2tpbmcuc3RhdHVzLFxuICAgICAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZShib29raW5nLmNyZWF0ZWRBdCksXG4gICAgICAgICAgICBzZXJ2aWNlczogYm9va2luZy5zZXJ2aWNlcyxcbiAgICAgICAgICAgIHRvdGFsUHJpY2U6IGJvb2tpbmcudG90YWxQcmljZSxcbiAgICAgICAgICAgIHRhZ3M6IGJvb2tpbmcudGFncyxcbiAgICAgICAgICAgIG5vdGVzOiBib29raW5nLm5vdGVzLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3N5bmNlZCdcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIE1vY2tDdXN0b21lclJlcG9zaXRvcnkgLSBMb2FkcyBjdXN0b21lciBkYXRhIGZyb20gbG9jYWwgSlNPTiBmaWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0N1c3RvbWVyJztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvbW9jay1jdXN0b21lcnMuanNvbic7XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9jayBjdXN0b21lcnM6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0N1c3RvbWVyRGF0YShyYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGN1c3RvbWVyIGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfY3VzdG9tZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIHByb2Nlc3NDdXN0b21lckRhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGN1c3RvbWVyKSA9PiAoe1xuICAgICAgICAgICAgaWQ6IGN1c3RvbWVyLmlkLFxuICAgICAgICAgICAgbmFtZTogY3VzdG9tZXIubmFtZSxcbiAgICAgICAgICAgIHBob25lOiBjdXN0b21lci5waG9uZSxcbiAgICAgICAgICAgIGVtYWlsOiBjdXN0b21lci5lbWFpbCxcbiAgICAgICAgICAgIG1ldGFkYXRhOiBjdXN0b21lci5tZXRhZGF0YSxcbiAgICAgICAgICAgIHN5bmNTdGF0dXM6ICdzeW5jZWQnXG4gICAgICAgIH0pKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBNb2NrQXVkaXRSZXBvc2l0b3J5IC0gTW9jayBBUEkgcmVwb3NpdG9yeSBmb3IgYXVkaXQgZW50cmllc1xuICpcbiAqIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQgc2VuZCBhdWRpdCBlbnRyaWVzIHRvIHRoZSBiYWNrZW5kLlxuICogRm9yIGRldmVsb3BtZW50L3Rlc3RpbmcsIGl0IGp1c3QgbG9ncyB0aGUgb3BlcmF0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tBdWRpdFJlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnQXVkaXQnO1xuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKGVudGl0eSkge1xuICAgICAgICAvLyBTaW11bGF0ZSBBUEkgY2FsbCBkZWxheVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdNb2NrQXVkaXRSZXBvc2l0b3J5OiBBdWRpdCBlbnRyeSBzeW5jZWQgdG8gYmFja2VuZDonLCB7XG4gICAgICAgICAgICBpZDogZW50aXR5LmlkLFxuICAgICAgICAgICAgZW50aXR5VHlwZTogZW50aXR5LmVudGl0eVR5cGUsXG4gICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmVudGl0eUlkLFxuICAgICAgICAgICAgb3BlcmF0aW9uOiBlbnRpdHkub3BlcmF0aW9uLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZShlbnRpdHkudGltZXN0YW1wKS50b0lTT1N0cmluZygpXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZW50aXR5O1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX2VudGl0eSkge1xuICAgICAgICAvLyBBdWRpdCBlbnRyaWVzIGFyZSBpbW11dGFibGUgLSB1cGRhdGVzIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQXVkaXQgZW50cmllcyBjYW5ub3QgYmUgdXBkYXRlZCcpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICAvLyBBdWRpdCBlbnRyaWVzIHNob3VsZCBuZXZlciBiZSBkZWxldGVkXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQXVkaXQgZW50cmllcyBjYW5ub3QgYmUgZGVsZXRlZCcpO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgLy8gRm9yIG5vdywgcmV0dXJuIGVtcHR5IGFycmF5IC0gYXVkaXQgZW50cmllcyBhcmUgbG9jYWwtZmlyc3RcbiAgICAgICAgLy8gSW4gcHJvZHVjdGlvbiwgdGhpcyBjb3VsZCBmZXRjaCBhdWRpdCBoaXN0b3J5IGZyb20gYmFja2VuZFxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQnlJZChfaWQpIHtcbiAgICAgICAgLy8gRm9yIG5vdywgcmV0dXJuIG51bGwgLSBhdWRpdCBlbnRyaWVzIGFyZSBsb2NhbC1maXJzdFxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBNb2NrVGVhbVJlcG9zaXRvcnkgLSBMb2FkcyB0ZWFtIGRhdGEgZnJvbSBsb2NhbCBKU09OIGZpbGVcbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tUZWFtUmVwb3NpdG9yeSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdUZWFtJztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvbW9jay10ZWFtcy5qc29uJztcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZGF0YVVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2NrIHRlYW1zOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmF3RGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NUZWFtRGF0YShyYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHRlYW0gZGF0YTonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKF90ZWFtKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1RlYW1SZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1RlYW1SZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZFVwZGF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZERlbGV0ZShfaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrVGVhbVJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kRGVsZXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBwcm9jZXNzVGVhbURhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKHRlYW0pID0+ICh7XG4gICAgICAgICAgICBpZDogdGVhbS5pZCxcbiAgICAgICAgICAgIG5hbWU6IHRlYW0ubmFtZSxcbiAgICAgICAgICAgIHJlc291cmNlSWRzOiB0ZWFtLnJlc291cmNlSWRzLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3N5bmNlZCdcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIE1vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSAtIExvYWRzIGRlcGFydG1lbnQgZGF0YSBmcm9tIGxvY2FsIEpTT04gZmlsZVxuICovXG5leHBvcnQgY2xhc3MgTW9ja0RlcGFydG1lbnRSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0RlcGFydG1lbnQnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS9tb2NrLWRlcGFydG1lbnRzLmpzb24nO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5kYXRhVXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBsb2FkIG1vY2sgZGVwYXJ0bWVudHM6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0RlcGFydG1lbnREYXRhKHJhd0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgZGVwYXJ0bWVudCBkYXRhOicsIGVycm9yKTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNlbmRDcmVhdGUoX2RlcGFydG1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kQ3JlYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX3VwZGF0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kVXBkYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIHByb2Nlc3NEZXBhcnRtZW50RGF0YShkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgoZGVwdCkgPT4gKHtcbiAgICAgICAgICAgIGlkOiBkZXB0LmlkLFxuICAgICAgICAgICAgbmFtZTogZGVwdC5uYW1lLFxuICAgICAgICAgICAgcmVzb3VyY2VJZHM6IGRlcHQucmVzb3VyY2VJZHMsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAnc3luY2VkJ1xuICAgICAgICB9KSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogTW9ja1NldHRpbmdzUmVwb3NpdG9yeSAtIExvYWRzIHRlbmFudCBzZXR0aW5ncyBmcm9tIGxvY2FsIEpTT04gZmlsZVxuICpcbiAqIFNldHRpbmdzIGFyZSBzdG9yZWQgYXMgc2VwYXJhdGUgcmVjb3JkcyBwZXIgc2VjdGlvbiAod29ya3dlZWssIGdyaWQsIGV0Yy4pLlxuICogVGhlIEpTT04gZmlsZSBpcyBhbHJlYWR5IGFuIGFycmF5IG9mIFRlbmFudFNldHRpbmcgcmVjb3Jkcy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tTZXR0aW5nc1JlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnU2V0dGluZ3MnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS90ZW5hbnQtc2V0dGluZ3MuanNvbic7XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgdGVuYW50IHNldHRpbmdzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICAvLyBFbnN1cmUgc3luY1N0YXR1cyBpcyBzZXQgb24gZWFjaCByZWNvcmRcbiAgICAgICAgICAgIHJldHVybiBzZXR0aW5ncy5tYXAocyA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnMsXG4gICAgICAgICAgICAgICAgc3luY1N0YXR1czogcy5zeW5jU3RhdHVzIHx8ICdzeW5jZWQnXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCB0ZW5hbnQgc2V0dGluZ3M6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfc2V0dGluZ3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrU2V0dGluZ3NSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1NldHRpbmdzUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1NldHRpbmdzUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxufVxuIiwgImV4cG9ydCBjbGFzcyBNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnVmlld0NvbmZpZyc7XG4gICAgICAgIHRoaXMuZGF0YVVybCA9ICdkYXRhL3ZpZXdjb25maWdzLmpzb24nO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5kYXRhVXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBsb2FkIHZpZXdjb25maWdzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmF3RGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIC8vIEVuc3VyZSBzeW5jU3RhdHVzIGlzIHNldCBvbiBlYWNoIGNvbmZpZ1xuICAgICAgICAgICAgY29uc3QgY29uZmlncyA9IHJhd0RhdGEubWFwKChjb25maWcpID0+ICh7XG4gICAgICAgICAgICAgICAgLi4uY29uZmlnLFxuICAgICAgICAgICAgICAgIHN5bmNTdGF0dXM6IGNvbmZpZy5zeW5jU3RhdHVzIHx8ICdzeW5jZWQnXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICByZXR1cm4gY29uZmlncztcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHZpZXdjb25maWdzOicsIGVycm9yKTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNlbmRDcmVhdGUoX2NvbmZpZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRDcmVhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmRVcGRhdGUoX2lkLCBfdXBkYXRlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1ZpZXdDb25maWdSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZERlbGV0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBEYXRhU2VlZGVyIC0gT3JjaGVzdHJhdGVzIGluaXRpYWwgZGF0YSBsb2FkaW5nIGZyb20gcmVwb3NpdG9yaWVzIGludG8gSW5kZXhlZERCXG4gKlxuICogQVJDSElURUNUVVJFOlxuICogLSBSZXBvc2l0b3J5IChNb2NrL0FwaSk6IEZldGNoZXMgZGF0YSBmcm9tIHNvdXJjZSAoSlNPTiBmaWxlIG9yIGJhY2tlbmQgQVBJKVxuICogLSBEYXRhU2VlZGVyICh0aGlzIGNsYXNzKTogT3JjaGVzdHJhdGVzIGZldGNoICsgc2F2ZSBvcGVyYXRpb25zXG4gKiAtIFNlcnZpY2UgKEV2ZW50U2VydmljZSwgZXRjLik6IFNhdmVzIGRhdGEgdG8gSW5kZXhlZERCXG4gKlxuICogUE9MWU1PUlBISUMgREVTSUdOOlxuICogLSBVc2VzIGFycmF5cyBvZiBJRW50aXR5U2VydmljZVtdIGFuZCBJQXBpUmVwb3NpdG9yeVtdXG4gKiAtIE1hdGNoZXMgc2VydmljZXMgd2l0aCByZXBvc2l0b3JpZXMgdXNpbmcgZW50aXR5VHlwZSBwcm9wZXJ0eVxuICogLSBPcGVuL0Nsb3NlZCBQcmluY2lwbGU6IEFkZGluZyBuZXcgZW50aXR5IHJlcXVpcmVzIG5vIGNvZGUgY2hhbmdlcyBoZXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhU2VlZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihzZXJ2aWNlcywgcmVwb3NpdG9yaWVzKSB7XG4gICAgICAgIHRoaXMuc2VydmljZXMgPSBzZXJ2aWNlcztcbiAgICAgICAgdGhpcy5yZXBvc2l0b3JpZXMgPSByZXBvc2l0b3JpZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlZWQgYWxsIGVudGl0eSBzdG9yZXMgaWYgdGhleSBhcmUgZW1wdHlcbiAgICAgKi9cbiAgICBhc3luYyBzZWVkSWZFbXB0eSgpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tEYXRhU2VlZGVyXSBDaGVja2luZyBpZiBkYXRhYmFzZSBuZWVkcyBzZWVkaW5nLi4uJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlcnZpY2Ugb2YgdGhpcy5zZXJ2aWNlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcG9zaXRvcnkgPSB0aGlzLnJlcG9zaXRvcmllcy5maW5kKHJlcG8gPT4gcmVwby5lbnRpdHlUeXBlID09PSBzZXJ2aWNlLmVudGl0eVR5cGUpO1xuICAgICAgICAgICAgICAgIGlmICghcmVwb3NpdG9yeSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFtEYXRhU2VlZGVyXSBObyByZXBvc2l0b3J5IGZvdW5kIGZvciBlbnRpdHkgdHlwZTogJHtzZXJ2aWNlLmVudGl0eVR5cGV9LCBza2lwcGluZ2ApO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZWVkRW50aXR5KHNlcnZpY2UuZW50aXR5VHlwZSwgc2VydmljZSwgcmVwb3NpdG9yeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW0RhdGFTZWVkZXJdIFNlZWRpbmcgY29tcGxldGUnKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tEYXRhU2VlZGVyXSBTZWVkaW5nIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZWVkRW50aXR5KGVudGl0eVR5cGUsIHNlcnZpY2UsIHJlcG9zaXRvcnkpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzZXJ2aWNlLmdldEFsbCgpO1xuICAgICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtEYXRhU2VlZGVyXSAke2VudGl0eVR5cGV9IHN0b3JlIGFscmVhZHkgaGFzICR7ZXhpc3RpbmcubGVuZ3RofSBpdGVtcywgc2tpcHBpbmcgc2VlZGApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGBbRGF0YVNlZWRlcl0gJHtlbnRpdHlUeXBlfSBzdG9yZSBpcyBlbXB0eSwgZmV0Y2hpbmcgZnJvbSByZXBvc2l0b3J5Li4uYCk7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXBvc2l0b3J5LmZldGNoQWxsKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBbRGF0YVNlZWRlcl0gRmV0Y2hlZCAke2RhdGEubGVuZ3RofSAke2VudGl0eVR5cGV9IGl0ZW1zLCBzYXZpbmcgdG8gSW5kZXhlZERCLi4uYCk7XG4gICAgICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGRhdGEpIHtcbiAgICAgICAgICAgIGF3YWl0IHNlcnZpY2Uuc2F2ZShlbnRpdHksIHRydWUpOyAvLyBzaWxlbnQgPSB0cnVlIHRvIHNraXAgYXVkaXQgbG9nZ2luZ1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGBbRGF0YVNlZWRlcl0gJHtlbnRpdHlUeXBlfSBzZWVkaW5nIGNvbXBsZXRlICgke2RhdGEubGVuZ3RofSBpdGVtcyBzYXZlZClgKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDYWxjdWxhdGUgcGl4ZWwgcG9zaXRpb24gZm9yIGFuIGV2ZW50IGJhc2VkIG9uIGl0cyB0aW1lc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihzdGFydCwgZW5kLCBjb25maWcpIHtcbiAgICBjb25zdCBzdGFydE1pbnV0ZXMgPSBzdGFydC5nZXRIb3VycygpICogNjAgKyBzdGFydC5nZXRNaW51dGVzKCk7XG4gICAgY29uc3QgZW5kTWludXRlcyA9IGVuZC5nZXRIb3VycygpICogNjAgKyBlbmQuZ2V0TWludXRlcygpO1xuICAgIGNvbnN0IGRheVN0YXJ0TWludXRlcyA9IGNvbmZpZy5kYXlTdGFydEhvdXIgKiA2MDtcbiAgICBjb25zdCBtaW51dGVIZWlnaHQgPSBjb25maWcuaG91ckhlaWdodCAvIDYwO1xuICAgIGNvbnN0IHRvcCA9IChzdGFydE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuICAgIGNvbnN0IGhlaWdodCA9IChlbmRNaW51dGVzIC0gc3RhcnRNaW51dGVzKSAqIG1pbnV0ZUhlaWdodDtcbiAgICByZXR1cm4geyB0b3AsIGhlaWdodCB9O1xufVxuLyoqXG4gKiBDb252ZXJ0IG1pbnV0ZXMgdG8gcGl4ZWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW51dGVzVG9QaXhlbHMobWludXRlcywgY29uZmlnKSB7XG4gICAgcmV0dXJuIChtaW51dGVzIC8gNjApICogY29uZmlnLmhvdXJIZWlnaHQ7XG59XG4vKipcbiAqIENvbnZlcnQgcGl4ZWxzIHRvIG1pbnV0ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpeGVsc1RvTWludXRlcyhwaXhlbHMsIGNvbmZpZykge1xuICAgIHJldHVybiAocGl4ZWxzIC8gY29uZmlnLmhvdXJIZWlnaHQpICogNjA7XG59XG4vKipcbiAqIFNuYXAgcGl4ZWwgcG9zaXRpb24gdG8gZ3JpZCBpbnRlcnZhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gc25hcFRvR3JpZChwaXhlbHMsIGNvbmZpZykge1xuICAgIGNvbnN0IHNuYXBQaXhlbHMgPSBtaW51dGVzVG9QaXhlbHMoY29uZmlnLnNuYXBJbnRlcnZhbCwgY29uZmlnKTtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChwaXhlbHMgLyBzbmFwUGl4ZWxzKSAqIHNuYXBQaXhlbHM7XG59XG4iLCAiaW1wb3J0IHsgY2FsY3VsYXRlRXZlbnRQb3NpdGlvbiB9IGZyb20gJy4uLy4uL3V0aWxzL1Bvc2l0aW9uVXRpbHMnO1xuLyoqXG4gKiBDaGVjayBpZiB0d28gZXZlbnRzIG92ZXJsYXAgKHN0cmljdCAtIHRvdWNoaW5nIGF0IGJvdW5kYXJ5ID0gTk9UIG92ZXJsYXBwaW5nKVxuICogVGhpcyBtYXRjaGVzIFNjZW5hcmlvIDg6IGVuZD09PXN0YXJ0IGlzIE5PVCBvdmVybGFwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBldmVudHNPdmVybGFwKGEsIGIpIHtcbiAgICByZXR1cm4gYS5zdGFydCA8IGIuZW5kICYmIGEuZW5kID4gYi5zdGFydDtcbn1cbi8qKlxuICogQ2hlY2sgaWYgdHdvIGV2ZW50cyBhcmUgd2l0aGluIHRocmVzaG9sZCBmb3IgZ3JpZCBncm91cGluZy5cbiAqIFRoaXMgaW5jbHVkZXM6XG4gKiAxLiBTdGFydC10by1zdGFydDogRXZlbnRzIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGQgb2YgZWFjaCBvdGhlclxuICogMi4gRW5kLXRvLXN0YXJ0OiBPbmUgZXZlbnQgc3RhcnRzIHdpdGhpbiB0aHJlc2hvbGQgYmVmb3JlIGFub3RoZXIgZW5kc1xuICovXG5mdW5jdGlvbiBldmVudHNXaXRoaW5UaHJlc2hvbGQoYSwgYiwgdGhyZXNob2xkTWludXRlcykge1xuICAgIGNvbnN0IHRocmVzaG9sZE1zID0gdGhyZXNob2xkTWludXRlcyAqIDYwICogMTAwMDtcbiAgICAvLyBTdGFydC10by1zdGFydDogYm90aCBldmVudHMgc3RhcnQgd2l0aGluIHRocmVzaG9sZFxuICAgIGNvbnN0IHN0YXJ0VG9TdGFydERpZmYgPSBNYXRoLmFicyhhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcbiAgICBpZiAoc3RhcnRUb1N0YXJ0RGlmZiA8PSB0aHJlc2hvbGRNcylcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gRW5kLXRvLXN0YXJ0OiBvbmUgZXZlbnQgc3RhcnRzIHdpdGhpbiB0aHJlc2hvbGQgYmVmb3JlIHRoZSBvdGhlciBlbmRzXG4gICAgLy8gQiBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgQSBlbmRzXG4gICAgY29uc3QgYlN0YXJ0c0JlZm9yZUFFbmRzID0gYS5lbmQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCk7XG4gICAgaWYgKGJTdGFydHNCZWZvcmVBRW5kcyA+IDAgJiYgYlN0YXJ0c0JlZm9yZUFFbmRzIDw9IHRocmVzaG9sZE1zKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBIHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBCIGVuZHNcbiAgICBjb25zdCBhU3RhcnRzQmVmb3JlQkVuZHMgPSBiLmVuZC5nZXRUaW1lKCkgLSBhLnN0YXJ0LmdldFRpbWUoKTtcbiAgICBpZiAoYVN0YXJ0c0JlZm9yZUJFbmRzID4gMCAmJiBhU3RhcnRzQmVmb3JlQkVuZHMgPD0gdGhyZXNob2xkTXMpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbn1cbi8qKlxuICogQ2hlY2sgaWYgYWxsIGV2ZW50cyBpbiBhIGdyb3VwIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGQgb2YgZWFjaCBvdGhlclxuICovXG5mdW5jdGlvbiBhbGxTdGFydFdpdGhpblRocmVzaG9sZChldmVudHMsIHRocmVzaG9sZE1pbnV0ZXMpIHtcbiAgICBpZiAoZXZlbnRzLmxlbmd0aCA8PSAxKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAvLyBGaW5kIGVhcmxpZXN0IGFuZCBsYXRlc3Qgc3RhcnQgdGltZXNcbiAgICBsZXQgZWFybGllc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xuICAgIGxldCBsYXRlc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSBldmVudC5zdGFydC5nZXRUaW1lKCk7XG4gICAgICAgIGlmICh0aW1lIDwgZWFybGllc3QpXG4gICAgICAgICAgICBlYXJsaWVzdCA9IHRpbWU7XG4gICAgICAgIGlmICh0aW1lID4gbGF0ZXN0KVxuICAgICAgICAgICAgbGF0ZXN0ID0gdGltZTtcbiAgICB9XG4gICAgY29uc3QgZGlmZk1pbnV0ZXMgPSAobGF0ZXN0IC0gZWFybGllc3QpIC8gKDEwMDAgKiA2MCk7XG4gICAgcmV0dXJuIGRpZmZNaW51dGVzIDw9IHRocmVzaG9sZE1pbnV0ZXM7XG59XG4vKipcbiAqIEZpbmQgZ3JvdXBzIG9mIG92ZXJsYXBwaW5nIGV2ZW50cyAoY29ubmVjdGVkIGJ5IG92ZXJsYXAgY2hhaW4pXG4gKiBFdmVudHMgYXJlIGdyb3VwZWQgaWYgdGhleSBvdmVybGFwIHdpdGggYW55IGV2ZW50IGluIHRoZSBncm91cFxuICovXG5mdW5jdGlvbiBmaW5kT3ZlcmxhcEdyb3VwcyhldmVudHMpIHtcbiAgICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xuICAgIGNvbnN0IHVzZWQgPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgZ3JvdXBzID0gW107XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcbiAgICAgICAgaWYgKHVzZWQuaGFzKGV2ZW50LmlkKSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAvLyBTdGFydCBhIG5ldyBncm91cCB3aXRoIHRoaXMgZXZlbnRcbiAgICAgICAgY29uc3QgZ3JvdXAgPSBbZXZlbnRdO1xuICAgICAgICB1c2VkLmFkZChldmVudC5pZCk7XG4gICAgICAgIC8vIEV4cGFuZCBncm91cCBieSBmaW5kaW5nIGFsbCBjb25uZWN0ZWQgZXZlbnRzICh2aWEgb3ZlcmxhcClcbiAgICAgICAgbGV0IGV4cGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgd2hpbGUgKGV4cGFuZGVkKSB7XG4gICAgICAgICAgICBleHBhbmRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2Ygc29ydGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVzZWQuaGFzKGNhbmRpZGF0ZS5pZCkpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNhbmRpZGF0ZSBvdmVybGFwcyB3aXRoIGFueSBldmVudCBpbiBncm91cFxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3RzID0gZ3JvdXAuc29tZShtZW1iZXIgPT4gZXZlbnRzT3ZlcmxhcChtZW1iZXIsIGNhbmRpZGF0ZSkpO1xuICAgICAgICAgICAgICAgIGlmIChjb25uZWN0cykge1xuICAgICAgICAgICAgICAgICAgICBncm91cC5wdXNoKGNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIHVzZWQuYWRkKGNhbmRpZGF0ZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXBzLnB1c2goZ3JvdXApO1xuICAgIH1cbiAgICByZXR1cm4gZ3JvdXBzO1xufVxuLyoqXG4gKiBGaW5kIGdyaWQgY2FuZGlkYXRlcyB3aXRoaW4gYSBncm91cCAtIGV2ZW50cyBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpblxuICogVXNlcyBWMSBsb2dpYzogZXZlbnRzIGFyZSBjb25uZWN0ZWQgaWYgd2l0aGluIHRocmVzaG9sZCAobm8gb3ZlcmxhcCByZXF1aXJlbWVudClcbiAqL1xuZnVuY3Rpb24gZmluZEdyaWRDYW5kaWRhdGVzKGV2ZW50cywgdGhyZXNob2xkTWludXRlcykge1xuICAgIGlmIChldmVudHMubGVuZ3RoID09PSAwKVxuICAgICAgICByZXR1cm4gW107XG4gICAgY29uc3Qgc29ydGVkID0gWy4uLmV2ZW50c10uc29ydCgoYSwgYikgPT4gYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XG4gICAgY29uc3QgdXNlZCA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBncm91cHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xuICAgICAgICBpZiAodXNlZC5oYXMoZXZlbnQuaWQpKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gW2V2ZW50XTtcbiAgICAgICAgdXNlZC5hZGQoZXZlbnQuaWQpO1xuICAgICAgICAvLyBFeHBhbmQgYnkgdGhyZXNob2xkIGNoYWluIChWMSBsb2dpYzogbm8gb3ZlcmxhcCByZXF1aXJlbWVudCwganVzdCB0aHJlc2hvbGQpXG4gICAgICAgIGxldCBleHBhbmRlZCA9IHRydWU7XG4gICAgICAgIHdoaWxlIChleHBhbmRlZCkge1xuICAgICAgICAgICAgZXhwYW5kZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHNvcnRlZCkge1xuICAgICAgICAgICAgICAgIGlmICh1c2VkLmhhcyhjYW5kaWRhdGUuaWQpKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0cyA9IGdyb3VwLnNvbWUobWVtYmVyID0+IGV2ZW50c1dpdGhpblRocmVzaG9sZChtZW1iZXIsIGNhbmRpZGF0ZSwgdGhyZXNob2xkTWludXRlcykpO1xuICAgICAgICAgICAgICAgIGlmIChjb25uZWN0cykge1xuICAgICAgICAgICAgICAgICAgICBncm91cC5wdXNoKGNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIHVzZWQuYWRkKGNhbmRpZGF0ZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXBzLnB1c2goZ3JvdXApO1xuICAgIH1cbiAgICByZXR1cm4gZ3JvdXBzO1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgc3RhY2sgbGV2ZWxzIGZvciBvdmVybGFwcGluZyBldmVudHMgdXNpbmcgZ3JlZWR5IGFsZ29yaXRobVxuICogRm9yIGVhY2ggZXZlbnQ6IGxldmVsID0gbWF4KG92ZXJsYXBwaW5nIGFscmVhZHktcHJvY2Vzc2VkIGV2ZW50cykgKyAxXG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZVN0YWNrTGV2ZWxzKGV2ZW50cykge1xuICAgIGNvbnN0IGxldmVscyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xuICAgICAgICBsZXQgbWF4T3ZlcmxhcHBpbmdMZXZlbCA9IC0xO1xuICAgICAgICAvLyBGaW5kIG1heCBsZXZlbCBhbW9uZyBvdmVybGFwcGluZyBldmVudHMgYWxyZWFkeSBwcm9jZXNzZWRcbiAgICAgICAgZm9yIChjb25zdCBbaWQsIGxldmVsXSBvZiBsZXZlbHMpIHtcbiAgICAgICAgICAgIGNvbnN0IG90aGVyID0gZXZlbnRzLmZpbmQoZSA9PiBlLmlkID09PSBpZCk7XG4gICAgICAgICAgICBpZiAob3RoZXIgJiYgZXZlbnRzT3ZlcmxhcChldmVudCwgb3RoZXIpKSB7XG4gICAgICAgICAgICAgICAgbWF4T3ZlcmxhcHBpbmdMZXZlbCA9IE1hdGgubWF4KG1heE92ZXJsYXBwaW5nTGV2ZWwsIGxldmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXZlbHMuc2V0KGV2ZW50LmlkLCBtYXhPdmVybGFwcGluZ0xldmVsICsgMSk7XG4gICAgfVxuICAgIHJldHVybiBsZXZlbHM7XG59XG4vKipcbiAqIEFsbG9jYXRlIGV2ZW50cyB0byBjb2x1bW5zIGZvciBHUklEIGxheW91dCB1c2luZyBncmVlZHkgYWxnb3JpdGhtXG4gKiBOb24tb3ZlcmxhcHBpbmcgZXZlbnRzIGNhbiBzaGFyZSBhIGNvbHVtbiB0byBtaW5pbWl6ZSB0b3RhbCBjb2x1bW5zXG4gKi9cbmZ1bmN0aW9uIGFsbG9jYXRlQ29sdW1ucyhldmVudHMpIHtcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCBjb2x1bW5zID0gW107XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcbiAgICAgICAgLy8gRmluZCBmaXJzdCBjb2x1bW4gd2hlcmUgZXZlbnQgZG9lc24ndCBvdmVybGFwIHdpdGggZXhpc3RpbmcgZXZlbnRzXG4gICAgICAgIGxldCBwbGFjZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgICAgICAgY29uc3QgY2FuRml0ID0gIWNvbHVtbi5zb21lKGUgPT4gZXZlbnRzT3ZlcmxhcChldmVudCwgZSkpO1xuICAgICAgICAgICAgaWYgKGNhbkZpdCkge1xuICAgICAgICAgICAgICAgIGNvbHVtbi5wdXNoKGV2ZW50KTtcbiAgICAgICAgICAgICAgICBwbGFjZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIE5vIHN1aXRhYmxlIGNvbHVtbiBmb3VuZCwgY3JlYXRlIG5ldyBvbmVcbiAgICAgICAgaWYgKCFwbGFjZWQpIHtcbiAgICAgICAgICAgIGNvbHVtbnMucHVzaChbZXZlbnRdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sdW1ucztcbn1cbi8qKlxuICogTWFpbiBlbnRyeSBwb2ludDogQ2FsY3VsYXRlIGNvbXBsZXRlIGxheW91dCBmb3IgYSBjb2x1bW4ncyBldmVudHNcbiAqXG4gKiBBbGdvcml0aG06XG4gKiAxLiBGaW5kIG92ZXJsYXAgZ3JvdXBzIChldmVudHMgY29ubmVjdGVkIGJ5IG92ZXJsYXAgY2hhaW4pXG4gKiAyLiBGb3IgZWFjaCBvdmVybGFwIGdyb3VwLCBmaW5kIGdyaWQgY2FuZGlkYXRlcyAoZXZlbnRzIHdpdGhpbiB0aHJlc2hvbGQgY2hhaW4pXG4gKiAzLiBJZiBhbGwgZXZlbnRzIGluIG92ZXJsYXAgZ3JvdXAgZm9ybSBhIHNpbmdsZSBncmlkIGNhbmRpZGF0ZSBcdTIxOTIgR1JJRCBtb2RlXG4gKiA0LiBPdGhlcndpc2UgXHUyMTkyIFNUQUNLSU5HIG1vZGUgd2l0aCBjYWxjdWxhdGVkIGxldmVsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQ29sdW1uTGF5b3V0KGV2ZW50cywgY29uZmlnKSB7XG4gICAgY29uc3QgdGhyZXNob2xkTWludXRlcyA9IGNvbmZpZy5ncmlkU3RhcnRUaHJlc2hvbGRNaW51dGVzID8/IDEwO1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgZ3JpZHM6IFtdLFxuICAgICAgICBzdGFja2VkOiBbXVxuICAgIH07XG4gICAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgLy8gRmluZCBhbGwgb3ZlcmxhcHBpbmcgZXZlbnQgZ3JvdXBzXG4gICAgY29uc3Qgb3ZlcmxhcEdyb3VwcyA9IGZpbmRPdmVybGFwR3JvdXBzKGV2ZW50cyk7XG4gICAgZm9yIChjb25zdCBvdmVybGFwR3JvdXAgb2Ygb3ZlcmxhcEdyb3Vwcykge1xuICAgICAgICBpZiAob3ZlcmxhcEdyb3VwLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gU2luZ2xlIGV2ZW50IC0gbm8gZ3JvdXBpbmcgbmVlZGVkXG4gICAgICAgICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICBldmVudDogb3ZlcmxhcEdyb3VwWzBdLFxuICAgICAgICAgICAgICAgIHN0YWNrTGV2ZWw6IDBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2l0aGluIHRoaXMgb3ZlcmxhcCBncm91cCwgZmluZCBncmlkIGNhbmRpZGF0ZXMgKHRocmVzaG9sZC1jb25uZWN0ZWQgc3ViZ3JvdXBzKVxuICAgICAgICBjb25zdCBncmlkU3ViZ3JvdXBzID0gZmluZEdyaWRDYW5kaWRhdGVzKG92ZXJsYXBHcm91cCwgdGhyZXNob2xkTWludXRlcyk7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBFTlRJUkUgb3ZlcmxhcCBncm91cCBmb3JtcyBhIHNpbmdsZSBncmlkIGNhbmRpZGF0ZVxuICAgICAgICAvLyBUaGlzIGhhcHBlbnMgd2hlbiBhbGwgZXZlbnRzIGFyZSBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpblxuICAgICAgICBjb25zdCBsYXJnZXN0R3JpZENhbmRpZGF0ZSA9IGdyaWRTdWJncm91cHMucmVkdWNlKChtYXgsIGcpID0+IGcubGVuZ3RoID4gbWF4Lmxlbmd0aCA/IGcgOiBtYXgsIGdyaWRTdWJncm91cHNbMF0pO1xuICAgICAgICBpZiAobGFyZ2VzdEdyaWRDYW5kaWRhdGUubGVuZ3RoID09PSBvdmVybGFwR3JvdXAubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBBbGwgZXZlbnRzIGluIG92ZXJsYXAgZ3JvdXAgYXJlIGNvbm5lY3RlZCB2aWEgdGhyZXNob2xkIGNoYWluIFx1MjE5MiBHUklEIG1vZGVcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbnMgPSBhbGxvY2F0ZUNvbHVtbnMob3ZlcmxhcEdyb3VwKTtcbiAgICAgICAgICAgIGNvbnN0IGVhcmxpZXN0ID0gb3ZlcmxhcEdyb3VwLnJlZHVjZSgobWluLCBlKSA9PiBlLnN0YXJ0IDwgbWluLnN0YXJ0ID8gZSA6IG1pbiwgb3ZlcmxhcEdyb3VwWzBdKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihlYXJsaWVzdC5zdGFydCwgZWFybGllc3QuZW5kLCBjb25maWcpO1xuICAgICAgICAgICAgcmVzdWx0LmdyaWRzLnB1c2goe1xuICAgICAgICAgICAgICAgIGV2ZW50czogb3ZlcmxhcEdyb3VwLFxuICAgICAgICAgICAgICAgIGNvbHVtbnMsXG4gICAgICAgICAgICAgICAgc3RhY2tMZXZlbDogMCxcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogeyB0b3A6IHBvc2l0aW9uLnRvcCB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIE5vdCBhbGwgZXZlbnRzIGNvbm5lY3RlZCB2aWEgdGhyZXNob2xkIFx1MjE5MiBTVEFDS0lORyBtb2RlXG4gICAgICAgICAgICBjb25zdCBsZXZlbHMgPSBjYWxjdWxhdGVTdGFja0xldmVscyhvdmVybGFwR3JvdXApO1xuICAgICAgICAgICAgZm9yIChjb25zdCBldmVudCBvZiBvdmVybGFwR3JvdXApIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrTGV2ZWw6IGxldmVscy5nZXQoZXZlbnQuaWQpID8/IDBcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuIiwgImltcG9ydCB7IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24sIHNuYXBUb0dyaWQsIHBpeGVsc1RvTWludXRlcyB9IGZyb20gJy4uLy4uL3V0aWxzL1Bvc2l0aW9uVXRpbHMnO1xuaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcbmltcG9ydCB7IGNhbGN1bGF0ZUNvbHVtbkxheW91dCB9IGZyb20gJy4vRXZlbnRMYXlvdXRFbmdpbmUnO1xuLyoqXG4gKiBFdmVudFJlbmRlcmVyIC0gUmVuZGVycyBjYWxlbmRhciBldmVudHMgdG8gdGhlIERPTVxuICpcbiAqIENMRUFOIGFwcHJvYWNoOlxuICogLSBPbmx5IGRhdGEtaWQgYXR0cmlidXRlIG9uIGV2ZW50IGVsZW1lbnRcbiAqIC0gaW5uZXJIVE1MIGNvbnRhaW5zIG9ubHkgdmlzaWJsZSBjb250ZW50XG4gKiAtIEV2ZW50IGRhdGEgcmV0cmlldmVkIHZpYSBFdmVudFNlcnZpY2Ugd2hlbiBuZWVkZWRcbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50UmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50U2VydmljZSwgZGF0ZVNlcnZpY2UsIGdyaWRDb25maWcsIGV2ZW50QnVzKSB7XG4gICAgICAgIHRoaXMuZXZlbnRTZXJ2aWNlID0gZXZlbnRTZXJ2aWNlO1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuZ3JpZENvbmZpZyA9IGdyaWRDb25maWc7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBudWxsO1xuICAgICAgICB0aGlzLnNldHVwTGlzdGVuZXJzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHVwIGxpc3RlbmVycyBmb3IgZHJhZy1kcm9wIGFuZCB1cGRhdGUgZXZlbnRzXG4gICAgICovXG4gICAgc2V0dXBMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0NPTFVNTl9DSEFOR0UsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUNvbHVtbkNoYW5nZShwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkUsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfVVBEQVRFRCwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRXZlbnRVcGRhdGVkKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfRU5ELCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfTEVBVkVfSEVBREVSLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEcmFnTGVhdmVIZWFkZXIocGF5bG9hZCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgRVZFTlRfRFJBR19FTkQgLSByZW1vdmUgZWxlbWVudCBpZiBkcm9wcGVkIGluIGhlYWRlclxuICAgICAqL1xuICAgIGhhbmRsZURyYWdFbmQocGF5bG9hZCkge1xuICAgICAgICBpZiAocGF5bG9hZC50YXJnZXQgPT09ICdoZWFkZXInKSB7XG4gICAgICAgICAgICAvLyBFdmVudCB3YXMgZHJvcHBlZCBpbiBoZWFkZXIgZHJhd2VyIC0gcmVtb3ZlIGZyb20gZ3JpZFxuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY29udGFpbmVyPy5xdWVyeVNlbGVjdG9yKGBzd3AtY29udGVudC12aWV3cG9ydCBzd3AtZXZlbnRbZGF0YS1ldmVudC1pZD1cIiR7cGF5bG9hZC5zd3BFdmVudC5ldmVudElkfVwiXWApO1xuICAgICAgICAgICAgZWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIGhlYWRlciBpdGVtIGxlYXZpbmcgaGVhZGVyIC0gY3JlYXRlIHN3cC1ldmVudCBpbiBncmlkXG4gICAgICovXG4gICAgaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQpIHtcbiAgICAgICAgLy8gT25seSBoYW5kbGUgd2hlbiBzb3VyY2UgaXMgaGVhZGVyIChoZWFkZXIgaXRlbSBkcmFnZ2VkIHRvIGdyaWQpXG4gICAgICAgIGlmIChwYXlsb2FkLnNvdXJjZSAhPT0gJ2hlYWRlcicpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICghcGF5bG9hZC50YXJnZXRDb2x1bW4gfHwgIXBheWxvYWQuc3RhcnQgfHwgIXBheWxvYWQuZW5kKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBUdXJuIGhlYWRlciBpdGVtIGludG8gZ2hvc3QgKHN0YXlzIHZpc2libGUgYnV0IGZhZGVkKVxuICAgICAgICBpZiAocGF5bG9hZC5lbGVtZW50KSB7XG4gICAgICAgICAgICBwYXlsb2FkLmVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZy1naG9zdCcpO1xuICAgICAgICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAnMC4zJztcbiAgICAgICAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgICAgICB9XG4gICAgICAgIC8vIENyZWF0ZSBldmVudCBvYmplY3QgZnJvbSBoZWFkZXIgaXRlbSBkYXRhXG4gICAgICAgIGNvbnN0IGV2ZW50ID0ge1xuICAgICAgICAgICAgaWQ6IHBheWxvYWQuZXZlbnRJZCxcbiAgICAgICAgICAgIHRpdGxlOiBwYXlsb2FkLnRpdGxlIHx8ICcnLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246ICcnLFxuICAgICAgICAgICAgc3RhcnQ6IHBheWxvYWQuc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IHBheWxvYWQuZW5kLFxuICAgICAgICAgICAgdHlwZTogJ2N1c3RvbWVyJyxcbiAgICAgICAgICAgIGFsbERheTogZmFsc2UsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcbiAgICAgICAgfTtcbiAgICAgICAgLy8gQ3JlYXRlIHN3cC1ldmVudCBlbGVtZW50IHVzaW5nIGV4aXN0aW5nIG1ldGhvZFxuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5jcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpO1xuICAgICAgICAvLyBBZGQgdG8gdGFyZ2V0IGNvbHVtblxuICAgICAgICBsZXQgZXZlbnRzTGF5ZXIgPSBwYXlsb2FkLnRhcmdldENvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XG4gICAgICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcbiAgICAgICAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICAgICAgcGF5bG9hZC50YXJnZXRDb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50c0xheWVyLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICAvLyBNYXJrIGFzIGRyYWdnaW5nIHNvIERyYWdEcm9wTWFuYWdlciBjYW4gY29udGludWUgd2l0aCBpdFxuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RyYWdnaW5nJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBFVkVOVF9VUERBVEVEIC0gcmUtcmVuZGVyIGFmZmVjdGVkIGNvbHVtbnNcbiAgICAgKi9cbiAgICBhc3luYyBoYW5kbGVFdmVudFVwZGF0ZWQocGF5bG9hZCkge1xuICAgICAgICAvLyBSZS1yZW5kZXIgc291cmNlIGNvbHVtbiAoaWYgZGlmZmVyZW50IGZyb20gdGFyZ2V0KVxuICAgICAgICBpZiAocGF5bG9hZC5zb3VyY2VDb2x1bW5LZXkgIT09IHBheWxvYWQudGFyZ2V0Q29sdW1uS2V5KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlcmVuZGVyQ29sdW1uKHBheWxvYWQuc291cmNlQ29sdW1uS2V5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZS1yZW5kZXIgdGFyZ2V0IGNvbHVtblxuICAgICAgICBhd2FpdCB0aGlzLnJlcmVuZGVyQ29sdW1uKHBheWxvYWQudGFyZ2V0Q29sdW1uS2V5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmUtcmVuZGVyIGEgc2luZ2xlIGNvbHVtbiB3aXRoIGZyZXNoIGRhdGEgZnJvbSBJbmRleGVkREJcbiAgICAgKi9cbiAgICBhc3luYyByZXJlbmRlckNvbHVtbihjb2x1bW5LZXkpIHtcbiAgICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5maW5kQ29sdW1uKGNvbHVtbktleSk7XG4gICAgICAgIGlmICghY29sdW1uKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBSZWFkIGRhdGUgYW5kIHJlc291cmNlSWQgZGlyZWN0bHkgZnJvbSBjb2x1bW4gYXR0cmlidXRlcyAoY29sdW1uS2V5IGlzIG9wYXF1ZSlcbiAgICAgICAgY29uc3QgZGF0ZSA9IGNvbHVtbi5kYXRhc2V0LmRhdGU7XG4gICAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBjb2x1bW4uZGF0YXNldC5yZXNvdXJjZUlkO1xuICAgICAgICBpZiAoIWRhdGUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEdldCBkYXRlIHJhbmdlIGZvciB0aGlzIGRheVxuICAgICAgICBjb25zdCBzdGFydERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICBlbmREYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XG4gICAgICAgIC8vIEZldGNoIGV2ZW50cyBmcm9tIEluZGV4ZWREQlxuICAgICAgICBjb25zdCBldmVudHMgPSByZXNvdXJjZUlkXG4gICAgICAgICAgICA/IGF3YWl0IHRoaXMuZXZlbnRTZXJ2aWNlLmdldEJ5UmVzb3VyY2VBbmREYXRlUmFuZ2UocmVzb3VyY2VJZCwgc3RhcnREYXRlLCBlbmREYXRlKVxuICAgICAgICAgICAgOiBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xuICAgICAgICAvLyBGaWx0ZXIgdG8gdGltZWQgZXZlbnRzIGFuZCBtYXRjaCBkYXRlIGV4YWN0bHlcbiAgICAgICAgY29uc3QgdGltZWRFdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+ICFldmVudC5hbGxEYXkgJiYgdGhpcy5kYXRlU2VydmljZS5nZXREYXRlS2V5KGV2ZW50LnN0YXJ0KSA9PT0gZGF0ZSk7XG4gICAgICAgIC8vIEdldCBvciBjcmVhdGUgZXZlbnRzIGxheWVyXG4gICAgICAgIGxldCBldmVudHNMYXllciA9IGNvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XG4gICAgICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcbiAgICAgICAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICAgICAgY29sdW1uLmFwcGVuZENoaWxkKGV2ZW50c0xheWVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDbGVhciBleGlzdGluZyBldmVudHNcbiAgICAgICAgZXZlbnRzTGF5ZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBsYXlvdXQgd2l0aCBzdGFja2luZy9ncm91cGluZ1xuICAgICAgICBjb25zdCBsYXlvdXQgPSBjYWxjdWxhdGVDb2x1bW5MYXlvdXQodGltZWRFdmVudHMsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIC8vIFJlbmRlciBHUklEIGdyb3Vwc1xuICAgICAgICBsYXlvdXQuZ3JpZHMuZm9yRWFjaChncmlkID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGdyb3VwRWwgPSB0aGlzLnJlbmRlckdyaWRHcm91cChncmlkKTtcbiAgICAgICAgICAgIGV2ZW50c0xheWVyLmFwcGVuZENoaWxkKGdyb3VwRWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gUmVuZGVyIFNUQUNLRUQgZXZlbnRzXG4gICAgICAgIGxheW91dC5zdGFja2VkLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudEVsID0gdGhpcy5yZW5kZXJTdGFja2VkRXZlbnQoaXRlbS5ldmVudCwgaXRlbS5zdGFja0xldmVsKTtcbiAgICAgICAgICAgIGV2ZW50c0xheWVyLmFwcGVuZENoaWxkKGV2ZW50RWwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBhIGNvbHVtbiBlbGVtZW50IGJ5IGNvbHVtbktleVxuICAgICAqL1xuICAgIGZpbmRDb2x1bW4oY29sdW1uS2V5KSB7XG4gICAgICAgIGlmICghdGhpcy5jb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYHN3cC1kYXktY29sdW1uW2RhdGEtY29sdW1uLWtleT1cIiR7Y29sdW1uS2V5fVwiXWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgZXZlbnQgbW92aW5nIHRvIGEgbmV3IGNvbHVtbiBkdXJpbmcgZHJhZ1xuICAgICAqL1xuICAgIGhhbmRsZUNvbHVtbkNoYW5nZShwYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50c0xheWVyID0gcGF5bG9hZC5uZXdDb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICBpZiAoIWV2ZW50c0xheWVyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBNb3ZlIGVsZW1lbnQgdG8gbmV3IGNvbHVtblxuICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChwYXlsb2FkLmVsZW1lbnQpO1xuICAgICAgICAvLyBQcmVzZXJ2ZSBZIHBvc2l0aW9uXG4gICAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS50b3AgPSBgJHtwYXlsb2FkLmN1cnJlbnRZfXB4YDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRpbWVzdGFtcCBkaXNwbGF5IGR1cmluZyBkcmFnIChzbmFwcGVkIHRvIGdyaWQpXG4gICAgICovXG4gICAgdXBkYXRlRHJhZ1RpbWVzdGFtcChwYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IHRpbWVFbCA9IHBheWxvYWQuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnQtdGltZScpO1xuICAgICAgICBpZiAoIXRpbWVFbClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gU25hcCBwb3NpdGlvbiB0byBncmlkIGludGVydmFsXG4gICAgICAgIGNvbnN0IHNuYXBwZWRZID0gc25hcFRvR3JpZChwYXlsb2FkLmN1cnJlbnRZLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAvLyBDYWxjdWxhdGUgbmV3IHN0YXJ0IHRpbWVcbiAgICAgICAgY29uc3QgbWludXRlc0Zyb21HcmlkU3RhcnQgPSBwaXhlbHNUb01pbnV0ZXMoc25hcHBlZFksIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGNvbnN0IHN0YXJ0TWludXRlcyA9ICh0aGlzLmdyaWRDb25maWcuZGF5U3RhcnRIb3VyICogNjApICsgbWludXRlc0Zyb21HcmlkU3RhcnQ7XG4gICAgICAgIC8vIEtlZXAgb3JpZ2luYWwgZHVyYXRpb24gKGZyb20gZWxlbWVudCBoZWlnaHQpXG4gICAgICAgIGNvbnN0IGhlaWdodCA9IHBhcnNlRmxvYXQocGF5bG9hZC5lbGVtZW50LnN0eWxlLmhlaWdodCkgfHwgdGhpcy5ncmlkQ29uZmlnLmhvdXJIZWlnaHQ7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uTWludXRlcyA9IHBpeGVsc1RvTWludXRlcyhoZWlnaHQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIC8vIENyZWF0ZSBEYXRlIG9iamVjdHMgZm9yIGNvbnNpc3RlbnQgZm9ybWF0dGluZyB2aWEgRGF0ZVNlcnZpY2VcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLm1pbnV0ZXNUb0RhdGUoc3RhcnRNaW51dGVzKTtcbiAgICAgICAgY29uc3QgZW5kID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyArIGR1cmF0aW9uTWludXRlcyk7XG4gICAgICAgIHRpbWVFbC50ZXh0Q29udGVudCA9IHRoaXMuZGF0ZVNlcnZpY2UuZm9ybWF0VGltZVJhbmdlKHN0YXJ0LCBlbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IG1pbnV0ZXMgc2luY2UgbWlkbmlnaHQgdG8gYSBEYXRlIG9iamVjdCAodG9kYXkpXG4gICAgICovXG4gICAgbWludXRlc1RvRGF0ZShtaW51dGVzKSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBkYXRlLnNldEhvdXJzKE1hdGguZmxvb3IobWludXRlcyAvIDYwKSAlIDI0LCBtaW51dGVzICUgNjAsIDAsIDApO1xuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGV2ZW50cyBmb3IgdmlzaWJsZSBkYXRlcyBpbnRvIGRheSBjb2x1bW5zXG4gICAgICogQHBhcmFtIGNvbnRhaW5lciAtIENhbGVuZGFyIGNvbnRhaW5lciBlbGVtZW50XG4gICAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciB3aXRoICdkYXRlJyBhbmQgb3B0aW9uYWxseSAncmVzb3VyY2UnIGFycmF5c1xuICAgICAqIEBwYXJhbSBmaWx0ZXJUZW1wbGF0ZSAtIFRlbXBsYXRlIGZvciBtYXRjaGluZyBldmVudHMgdG8gY29sdW1uc1xuICAgICAqL1xuICAgIGFzeW5jIHJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpIHtcbiAgICAgICAgLy8gU3RvcmUgY29udGFpbmVyIHJlZmVyZW5jZSBmb3IgbGF0ZXIgcmUtcmVuZGVyc1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgY29uc3QgdmlzaWJsZURhdGVzID0gZmlsdGVyWydkYXRlJ10gfHwgW107XG4gICAgICAgIGlmICh2aXNpYmxlRGF0ZXMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBHZXQgZGF0ZSByYW5nZSBmb3IgcXVlcnlcbiAgICAgICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUodmlzaWJsZURhdGVzWzBdKTtcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1t2aXNpYmxlRGF0ZXMubGVuZ3RoIC0gMV0pO1xuICAgICAgICBlbmREYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XG4gICAgICAgIC8vIEZldGNoIGV2ZW50cyBmcm9tIEluZGV4ZWREQlxuICAgICAgICBjb25zdCBldmVudHMgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xuICAgICAgICAvLyBGaW5kIGRheSBjb2x1bW5zXG4gICAgICAgIGNvbnN0IGRheUNvbHVtbnMgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWRheS1jb2x1bW5zJyk7XG4gICAgICAgIGlmICghZGF5Q29sdW1ucylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IGRheUNvbHVtbnMucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgLy8gUmVuZGVyIGV2ZW50cyBpbnRvIGVhY2ggY29sdW1uIGJhc2VkIG9uIEZpbHRlclRlbXBsYXRlIG1hdGNoaW5nXG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgY29sdW1uRWwgPSBjb2x1bW47XG4gICAgICAgICAgICAvLyBVc2UgRmlsdGVyVGVtcGxhdGUgZm9yIG1hdGNoaW5nIC0gb25seSBmaWVsZHMgaW4gdGVtcGxhdGUgYXJlIGNoZWNrZWRcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbkV2ZW50cyA9IGV2ZW50cy5maWx0ZXIoZXZlbnQgPT4gZmlsdGVyVGVtcGxhdGUubWF0Y2hlcyhldmVudCwgY29sdW1uRWwpKTtcbiAgICAgICAgICAgIC8vIEdldCBvciBjcmVhdGUgZXZlbnRzIGxheWVyXG4gICAgICAgICAgICBsZXQgZXZlbnRzTGF5ZXIgPSBjb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICAgICAgaWYgKCFldmVudHNMYXllcikge1xuICAgICAgICAgICAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICAgICAgICAgIGNvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDbGVhciBleGlzdGluZyBldmVudHNcbiAgICAgICAgICAgIGV2ZW50c0xheWVyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAgICAgLy8gRmlsdGVyIHRvIHRpbWVkIGV2ZW50cyBvbmx5XG4gICAgICAgICAgICBjb25zdCB0aW1lZEV2ZW50cyA9IGNvbHVtbkV2ZW50cy5maWx0ZXIoZXZlbnQgPT4gIWV2ZW50LmFsbERheSk7XG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgbGF5b3V0IHdpdGggc3RhY2tpbmcvZ3JvdXBpbmdcbiAgICAgICAgICAgIGNvbnN0IGxheW91dCA9IGNhbGN1bGF0ZUNvbHVtbkxheW91dCh0aW1lZEV2ZW50cywgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgIC8vIFJlbmRlciBHUklEIGdyb3VwcyAoc2ltdWx0YW5lb3VzIGV2ZW50cyBzaWRlLWJ5LXNpZGUpXG4gICAgICAgICAgICBsYXlvdXQuZ3JpZHMuZm9yRWFjaChncmlkID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBncm91cEVsID0gdGhpcy5yZW5kZXJHcmlkR3JvdXAoZ3JpZCk7XG4gICAgICAgICAgICAgICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQoZ3JvdXBFbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFJlbmRlciBTVEFDS0VEIGV2ZW50cyAob3ZlcmxhcHBpbmcgd2l0aCBtYXJnaW4gb2Zmc2V0KVxuICAgICAgICAgICAgbGF5b3V0LnN0YWNrZWQuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudEVsID0gdGhpcy5yZW5kZXJTdGFja2VkRXZlbnQoaXRlbS5ldmVudCwgaXRlbS5zdGFja0xldmVsKTtcbiAgICAgICAgICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChldmVudEVsKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgc2luZ2xlIGV2ZW50IGVsZW1lbnRcbiAgICAgKlxuICAgICAqIENMRUFOIGFwcHJvYWNoOlxuICAgICAqIC0gT25seSBkYXRhLWlkIGZvciBsb29rdXBcbiAgICAgKiAtIFZpc2libGUgY29udGVudCBpbiBpbm5lckhUTUwgb25seVxuICAgICAqL1xuICAgIGNyZWF0ZUV2ZW50RWxlbWVudChldmVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50Jyk7XG4gICAgICAgIC8vIERhdGEgYXR0cmlidXRlcyBmb3IgU3dwRXZlbnQgY29tcGF0aWJpbGl0eVxuICAgICAgICBlbGVtZW50LmRhdGFzZXQuZXZlbnRJZCA9IGV2ZW50LmlkO1xuICAgICAgICBpZiAoZXZlbnQucmVzb3VyY2VJZCkge1xuICAgICAgICAgICAgZWxlbWVudC5kYXRhc2V0LnJlc291cmNlSWQgPSBldmVudC5yZXNvdXJjZUlkO1xuICAgICAgICB9XG4gICAgICAgIC8vIENhbGN1bGF0ZSBwb3NpdGlvblxuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtwb3NpdGlvbi50b3B9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3Bvc2l0aW9uLmhlaWdodH1weGA7XG4gICAgICAgIC8vIENvbG9yIGNsYXNzIGJhc2VkIG9uIGV2ZW50IHR5cGVcbiAgICAgICAgY29uc3QgY29sb3JDbGFzcyA9IHRoaXMuZ2V0Q29sb3JDbGFzcyhldmVudCk7XG4gICAgICAgIGlmIChjb2xvckNsYXNzKSB7XG4gICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY29sb3JDbGFzcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVmlzaWJsZSBjb250ZW50IG9ubHlcbiAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBgXHJcbiAgICAgIDxzd3AtZXZlbnQtdGltZT4ke3RoaXMuZGF0ZVNlcnZpY2UuZm9ybWF0VGltZVJhbmdlKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQpfTwvc3dwLWV2ZW50LXRpbWU+XHJcbiAgICAgIDxzd3AtZXZlbnQtdGl0bGU+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQudGl0bGUpfTwvc3dwLWV2ZW50LXRpdGxlPlxyXG4gICAgICAke2V2ZW50LmRlc2NyaXB0aW9uID8gYDxzd3AtZXZlbnQtZGVzY3JpcHRpb24+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQuZGVzY3JpcHRpb24pfTwvc3dwLWV2ZW50LWRlc2NyaXB0aW9uPmAgOiAnJ31cclxuICAgIGA7XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY29sb3IgY2xhc3MgYmFzZWQgb24gbWV0YWRhdGEuY29sb3Igb3IgZXZlbnQgdHlwZVxuICAgICAqL1xuICAgIGdldENvbG9yQ2xhc3MoZXZlbnQpIHtcbiAgICAgICAgLy8gQ2hlY2sgbWV0YWRhdGEuY29sb3IgZmlyc3RcbiAgICAgICAgaWYgKGV2ZW50Lm1ldGFkYXRhPy5jb2xvcikge1xuICAgICAgICAgICAgcmV0dXJuIGBpcy0ke2V2ZW50Lm1ldGFkYXRhLmNvbG9yfWA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmFsbGJhY2sgdG8gdHlwZS1iYXNlZCBjb2xvclxuICAgICAgICBjb25zdCB0eXBlQ29sb3JzID0ge1xuICAgICAgICAgICAgJ2N1c3RvbWVyJzogJ2lzLWJsdWUnLFxuICAgICAgICAgICAgJ3ZhY2F0aW9uJzogJ2lzLWdyZWVuJyxcbiAgICAgICAgICAgICdicmVhayc6ICdpcy1hbWJlcicsXG4gICAgICAgICAgICAnbWVldGluZyc6ICdpcy1wdXJwbGUnLFxuICAgICAgICAgICAgJ2Jsb2NrZWQnOiAnaXMtcmVkJ1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdHlwZUNvbG9yc1tldmVudC50eXBlXSB8fCAnaXMtYmx1ZSc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVzY2FwZSBIVE1MIHRvIHByZXZlbnQgWFNTXG4gICAgICovXG4gICAgZXNjYXBlSHRtbCh0ZXh0KSB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgICAgICByZXR1cm4gZGl2LmlubmVySFRNTDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGEgR1JJRCBncm91cCB3aXRoIHNpZGUtYnktc2lkZSBjb2x1bW5zXG4gICAgICogVXNlZCB3aGVuIG11bHRpcGxlIGV2ZW50cyBzdGFydCBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICovXG4gICAgcmVuZGVyR3JpZEdyb3VwKGxheW91dCkge1xuICAgICAgICBjb25zdCBncm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudC1ncm91cCcpO1xuICAgICAgICBncm91cC5jbGFzc0xpc3QuYWRkKGBjb2xzLSR7bGF5b3V0LmNvbHVtbnMubGVuZ3RofWApO1xuICAgICAgICBncm91cC5zdHlsZS50b3AgPSBgJHtsYXlvdXQucG9zaXRpb24udG9wfXB4YDtcbiAgICAgICAgLy8gU3RhY2sgbGV2ZWwgc3R5bGluZyBmb3IgZW50aXJlIGdyb3VwIChpZiBuZXN0ZWQgaW4gYW5vdGhlciBldmVudClcbiAgICAgICAgaWYgKGxheW91dC5zdGFja0xldmVsID4gMCkge1xuICAgICAgICAgICAgZ3JvdXAuc3R5bGUubWFyZ2luTGVmdCA9IGAke2xheW91dC5zdGFja0xldmVsICogMTV9cHhgO1xuICAgICAgICAgICAgZ3JvdXAuc3R5bGUuekluZGV4ID0gYCR7MTAwICsgbGF5b3V0LnN0YWNrTGV2ZWx9YDtcbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGhlaWdodCBuZWVkZWQgZm9yIHRoZSBncm91cCAodGFsbGVzdCBldmVudClcbiAgICAgICAgbGV0IG1heEJvdHRvbSA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2YgbGF5b3V0LmV2ZW50cykge1xuICAgICAgICAgICAgY29uc3QgcG9zID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihldmVudC5zdGFydCwgZXZlbnQuZW5kLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnRCb3R0b20gPSBwb3MudG9wICsgcG9zLmhlaWdodDtcbiAgICAgICAgICAgIGlmIChldmVudEJvdHRvbSA+IG1heEJvdHRvbSlcbiAgICAgICAgICAgICAgICBtYXhCb3R0b20gPSBldmVudEJvdHRvbTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBncm91cEhlaWdodCA9IG1heEJvdHRvbSAtIGxheW91dC5wb3NpdGlvbi50b3A7XG4gICAgICAgIGdyb3VwLnN0eWxlLmhlaWdodCA9IGAke2dyb3VwSGVpZ2h0fXB4YDtcbiAgICAgICAgLy8gQ3JlYXRlIHdyYXBwZXIgZGl2IGZvciBlYWNoIGNvbHVtblxuICAgICAgICBsYXlvdXQuY29sdW1ucy5mb3JFYWNoKGNvbHVtbkV2ZW50cyA9PiB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB3cmFwcGVyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICAgICAgICAgIGNvbHVtbkV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudEVsID0gdGhpcy5jcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpO1xuICAgICAgICAgICAgICAgIC8vIFBvc2l0aW9uIHJlbGF0aXZlIHRvIGdyb3VwIHRvcFxuICAgICAgICAgICAgICAgIGNvbnN0IHBvcyA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgICAgICBldmVudEVsLnN0eWxlLnRvcCA9IGAke3Bvcy50b3AgLSBsYXlvdXQucG9zaXRpb24udG9wfXB4YDtcbiAgICAgICAgICAgICAgICBldmVudEVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgICAgICAgICBldmVudEVsLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICAgICAgICAgICAgZXZlbnRFbC5zdHlsZS5yaWdodCA9ICcwJztcbiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGV2ZW50RWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBncm91cC5hcHBlbmRDaGlsZCh3cmFwcGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBncm91cDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGEgU1RBQ0tFRCBldmVudCB3aXRoIG1hcmdpbi1sZWZ0IG9mZnNldFxuICAgICAqIFVzZWQgZm9yIG92ZXJsYXBwaW5nIGV2ZW50cyB0aGF0IGRvbid0IHN0YXJ0IGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgKi9cbiAgICByZW5kZXJTdGFja2VkRXZlbnQoZXZlbnQsIHN0YWNrTGV2ZWwpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcbiAgICAgICAgLy8gQWRkIHN0YWNrIG1ldGFkYXRhIGZvciBkcmFnLWRyb3AgYW5kIG90aGVyIGZlYXR1cmVzXG4gICAgICAgIGVsZW1lbnQuZGF0YXNldC5zdGFja0xpbmsgPSBKU09OLnN0cmluZ2lmeSh7IHN0YWNrTGV2ZWwgfSk7XG4gICAgICAgIC8vIFZpc3VhbCBzdHlsaW5nIGJhc2VkIG9uIHN0YWNrIGxldmVsXG4gICAgICAgIGlmIChzdGFja0xldmVsID4gMCkge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5tYXJnaW5MZWZ0ID0gYCR7c3RhY2tMZXZlbCAqIDE1fXB4YDtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuekluZGV4ID0gYCR7MTAwICsgc3RhY2tMZXZlbH1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFNjaGVkdWxlUmVuZGVyZXIgLSBSZW5kZXJzIHVuYXZhaWxhYmxlIHRpbWUgem9uZXMgaW4gZGF5IGNvbHVtbnNcbiAqXG4gKiBDcmVhdGVzIHZpc3VhbCBpbmRpY2F0b3JzIGZvciB0aW1lcyBvdXRzaWRlIHRoZSByZXNvdXJjZSdzIHdvcmtpbmcgaG91cnM6XG4gKiAtIEJlZm9yZSB3b3JrIHN0YXJ0IChlLmcuLCAwNjowMCAtIDA5OjAwKVxuICogLSBBZnRlciB3b3JrIGVuZCAoZS5nLiwgMTc6MDAgLSAxODowMClcbiAqIC0gRnVsbCBkYXkgaWYgcmVzb3VyY2UgaXMgb2ZmIChzY2hlZHVsZSA9IG51bGwpXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2hlZHVsZVJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihzY2hlZHVsZVNlcnZpY2UsIGRhdGVTZXJ2aWNlLCBncmlkQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVTZXJ2aWNlID0gc2NoZWR1bGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuZ3JpZENvbmZpZyA9IGdyaWRDb25maWc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciB1bmF2YWlsYWJsZSB6b25lcyBmb3IgdmlzaWJsZSBjb2x1bW5zXG4gICAgICogQHBhcmFtIGNvbnRhaW5lciAtIENhbGVuZGFyIGNvbnRhaW5lciBlbGVtZW50XG4gICAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciB3aXRoICdkYXRlJyBhbmQgJ3Jlc291cmNlJyBhcnJheXNcbiAgICAgKi9cbiAgICBhc3luYyByZW5kZXIoY29udGFpbmVyLCBmaWx0ZXIpIHtcbiAgICAgICAgY29uc3QgZGF0ZXMgPSBmaWx0ZXJbJ2RhdGUnXSB8fCBbXTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VJZHMgPSBmaWx0ZXJbJ3Jlc291cmNlJ10gfHwgW107XG4gICAgICAgIGlmIChkYXRlcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEZpbmQgZGF5IGNvbHVtbnNcbiAgICAgICAgY29uc3QgZGF5Q29sdW1ucyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtZGF5LWNvbHVtbnMnKTtcbiAgICAgICAgaWYgKCFkYXlDb2x1bW5zKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gZGF5Q29sdW1ucy5xdWVyeVNlbGVjdG9yQWxsKCdzd3AtZGF5LWNvbHVtbicpO1xuICAgICAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gY29sdW1uLmRhdGFzZXQuZGF0ZTtcbiAgICAgICAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBjb2x1bW4uZGF0YXNldC5yZXNvdXJjZUlkO1xuICAgICAgICAgICAgaWYgKCFkYXRlIHx8ICFyZXNvdXJjZUlkKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgLy8gR2V0IG9yIGNyZWF0ZSB1bmF2YWlsYWJsZSBsYXllclxuICAgICAgICAgICAgbGV0IHVuYXZhaWxhYmxlTGF5ZXIgPSBjb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLXVuYXZhaWxhYmxlLWxheWVyJyk7XG4gICAgICAgICAgICBpZiAoIXVuYXZhaWxhYmxlTGF5ZXIpIHtcbiAgICAgICAgICAgICAgICB1bmF2YWlsYWJsZUxheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLXVuYXZhaWxhYmxlLWxheWVyJyk7XG4gICAgICAgICAgICAgICAgY29sdW1uLmluc2VydEJlZm9yZSh1bmF2YWlsYWJsZUxheWVyLCBjb2x1bW4uZmlyc3RDaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDbGVhciBleGlzdGluZ1xuICAgICAgICAgICAgdW5hdmFpbGFibGVMYXllci5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgICAgIC8vIEdldCBzY2hlZHVsZSBmb3IgdGhpcyByZXNvdXJjZS9kYXRlXG4gICAgICAgICAgICBjb25zdCBzY2hlZHVsZSA9IGF3YWl0IHRoaXMuc2NoZWR1bGVTZXJ2aWNlLmdldFNjaGVkdWxlRm9yRGF0ZShyZXNvdXJjZUlkLCBkYXRlKTtcbiAgICAgICAgICAgIC8vIFJlbmRlciB1bmF2YWlsYWJsZSB6b25lc1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJVbmF2YWlsYWJsZVpvbmVzKHVuYXZhaWxhYmxlTGF5ZXIsIHNjaGVkdWxlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdW5hdmFpbGFibGUgdGltZSB6b25lcyBiYXNlZCBvbiBzY2hlZHVsZVxuICAgICAqL1xuICAgIHJlbmRlclVuYXZhaWxhYmxlWm9uZXMobGF5ZXIsIHNjaGVkdWxlKSB7XG4gICAgICAgIGNvbnN0IGRheVN0YXJ0TWludXRlcyA9IHRoaXMuZ3JpZENvbmZpZy5kYXlTdGFydEhvdXIgKiA2MDtcbiAgICAgICAgY29uc3QgZGF5RW5kTWludXRlcyA9IHRoaXMuZ3JpZENvbmZpZy5kYXlFbmRIb3VyICogNjA7XG4gICAgICAgIGNvbnN0IG1pbnV0ZUhlaWdodCA9IHRoaXMuZ3JpZENvbmZpZy5ob3VySGVpZ2h0IC8gNjA7XG4gICAgICAgIGlmIChzY2hlZHVsZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRnVsbCBkYXkgdW5hdmFpbGFibGVcbiAgICAgICAgICAgIGNvbnN0IHpvbmUgPSB0aGlzLmNyZWF0ZVVuYXZhaWxhYmxlWm9uZSgwLCAoZGF5RW5kTWludXRlcyAtIGRheVN0YXJ0TWludXRlcykgKiBtaW51dGVIZWlnaHQpO1xuICAgICAgICAgICAgbGF5ZXIuYXBwZW5kQ2hpbGQoem9uZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd29ya1N0YXJ0TWludXRlcyA9IHRoaXMuZGF0ZVNlcnZpY2UudGltZVRvTWludXRlcyhzY2hlZHVsZS5zdGFydCk7XG4gICAgICAgIGNvbnN0IHdvcmtFbmRNaW51dGVzID0gdGhpcy5kYXRlU2VydmljZS50aW1lVG9NaW51dGVzKHNjaGVkdWxlLmVuZCk7XG4gICAgICAgIC8vIEJlZm9yZSB3b3JrIHN0YXJ0XG4gICAgICAgIGlmICh3b3JrU3RhcnRNaW51dGVzID4gZGF5U3RhcnRNaW51dGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSAwO1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gKHdvcmtTdGFydE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuICAgICAgICAgICAgY29uc3Qgem9uZSA9IHRoaXMuY3JlYXRlVW5hdmFpbGFibGVab25lKHRvcCwgaGVpZ2h0KTtcbiAgICAgICAgICAgIGxheWVyLmFwcGVuZENoaWxkKHpvbmUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFmdGVyIHdvcmsgZW5kXG4gICAgICAgIGlmICh3b3JrRW5kTWludXRlcyA8IGRheUVuZE1pbnV0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHRvcCA9ICh3b3JrRW5kTWludXRlcyAtIGRheVN0YXJ0TWludXRlcykgKiBtaW51dGVIZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCBoZWlnaHQgPSAoZGF5RW5kTWludXRlcyAtIHdvcmtFbmRNaW51dGVzKSAqIG1pbnV0ZUhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IHpvbmUgPSB0aGlzLmNyZWF0ZVVuYXZhaWxhYmxlWm9uZSh0b3AsIGhlaWdodCk7XG4gICAgICAgICAgICBsYXllci5hcHBlbmRDaGlsZCh6b25lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gdW5hdmFpbGFibGUgem9uZSBlbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVW5hdmFpbGFibGVab25lKHRvcCwgaGVpZ2h0KSB7XG4gICAgICAgIGNvbnN0IHpvbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtdW5hdmFpbGFibGUtem9uZScpO1xuICAgICAgICB6b25lLnN0eWxlLnRvcCA9IGAke3RvcH1weGA7XG4gICAgICAgIHpvbmUuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICAgICAgcmV0dXJuIHpvbmU7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG4vKipcbiAqIEhlYWRlckRyYXdlclJlbmRlcmVyIC0gSGFuZGxlcyByZW5kZXJpbmcgb2YgaXRlbXMgaW4gdGhlIGhlYWRlciBkcmF3ZXJcbiAqXG4gKiBMaXN0ZW5zIHRvIGRyYWcgZXZlbnRzIGZyb20gRHJhZ0Ryb3BNYW5hZ2VyIGFuZCBjcmVhdGVzL21hbmFnZXNcbiAqIHN3cC1oZWFkZXItaXRlbSBlbGVtZW50cyBpbiB0aGUgaGVhZGVyIGRyYXdlci5cbiAqXG4gKiBVc2VzIHN1YmdyaWQgZm9yIGNvbHVtbiBhbGlnbm1lbnQgd2l0aCBwYXJlbnQgc3dwLWNhbGVuZGFyLWhlYWRlci5cbiAqIFBvc2l0aW9uIGl0ZW1zIHZpYSBncmlkQXJlYSBmb3IgZXhwbGljaXQgcm93L2NvbHVtbiBwbGFjZW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBIZWFkZXJEcmF3ZXJSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3IoZXZlbnRCdXMsIGdyaWRDb25maWcsIGhlYWRlckRyYXdlck1hbmFnZXIsIGV2ZW50U2VydmljZSwgZGF0ZVNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmdyaWRDb25maWcgPSBncmlkQ29uZmlnO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlck1hbmFnZXIgPSBoZWFkZXJEcmF3ZXJNYW5hZ2VyO1xuICAgICAgICB0aGlzLmV2ZW50U2VydmljZSA9IGV2ZW50U2VydmljZTtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtID0gbnVsbDtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBudWxsO1xuICAgICAgICB0aGlzLnNvdXJjZUVsZW1lbnQgPSBudWxsO1xuICAgICAgICB0aGlzLndhc0V4cGFuZGVkQmVmb3JlRHJhZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpbHRlclRlbXBsYXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy5zZXR1cExpc3RlbmVycygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgYWxsRGF5IGV2ZW50cyBpbnRvIHRoZSBoZWFkZXIgZHJhd2VyIHdpdGggcm93IHN0YWNraW5nXG4gICAgICogQHBhcmFtIGZpbHRlclRlbXBsYXRlIC0gVGVtcGxhdGUgZm9yIG1hdGNoaW5nIGV2ZW50cyB0byBjb2x1bW5zXG4gICAgICovXG4gICAgYXN5bmMgcmVuZGVyKGNvbnRhaW5lciwgZmlsdGVyLCBmaWx0ZXJUZW1wbGF0ZSkge1xuICAgICAgICAvLyBTdG9yZSBmaWx0ZXJUZW1wbGF0ZSBmb3IgYnVpbGRDb2x1bW5LZXlGcm9tRXZlbnRcbiAgICAgICAgdGhpcy5maWx0ZXJUZW1wbGF0ZSA9IGZpbHRlclRlbXBsYXRlO1xuICAgICAgICBjb25zdCBkcmF3ZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci1kcmF3ZXInKTtcbiAgICAgICAgaWYgKCFkcmF3ZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IHZpc2libGVEYXRlcyA9IGZpbHRlclsnZGF0ZSddIHx8IFtdO1xuICAgICAgICBpZiAodmlzaWJsZURhdGVzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gR2V0IGNvbHVtbiBrZXlzIGZyb20gRE9NIGZvciBjb3JyZWN0IG11bHRpLXJlc291cmNlIHBvc2l0aW9uaW5nXG4gICAgICAgIGNvbnN0IHZpc2libGVDb2x1bW5LZXlzID0gdGhpcy5nZXRWaXNpYmxlQ29sdW1uS2V5c0Zyb21ET00oKTtcbiAgICAgICAgaWYgKHZpc2libGVDb2x1bW5LZXlzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gRmV0Y2ggZXZlbnRzIGZvciBkYXRlIHJhbmdlXG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1swXSk7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZSh2aXNpYmxlRGF0ZXNbdmlzaWJsZURhdGVzLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgZW5kRGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpO1xuICAgICAgICBjb25zdCBldmVudHMgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xuICAgICAgICAvLyBGaWx0ZXIgdG8gYWxsRGF5IGV2ZW50cyBvbmx5IChhbGxEYXkgIT09IGZhbHNlKVxuICAgICAgICBjb25zdCBhbGxEYXlFdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+IGV2ZW50LmFsbERheSAhPT0gZmFsc2UpO1xuICAgICAgICAvLyBDbGVhciBleGlzdGluZyBpdGVtc1xuICAgICAgICBkcmF3ZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIGlmIChhbGxEYXlFdmVudHMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBDYWxjdWxhdGUgbGF5b3V0IHdpdGggcm93IHN0YWNraW5nIHVzaW5nIGNvbHVtbktleXNcbiAgICAgICAgY29uc3QgbGF5b3V0cyA9IHRoaXMuY2FsY3VsYXRlTGF5b3V0KGFsbERheUV2ZW50cywgdmlzaWJsZUNvbHVtbktleXMpO1xuICAgICAgICBjb25zdCByb3dDb3VudCA9IE1hdGgubWF4KDEsIC4uLmxheW91dHMubWFwKGwgPT4gbC5yb3cpKTtcbiAgICAgICAgLy8gUmVuZGVyIGVhY2ggaXRlbSB3aXRoIGxheW91dFxuICAgICAgICBsYXlvdXRzLmZvckVhY2gobGF5b3V0ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmNyZWF0ZUhlYWRlckl0ZW0obGF5b3V0KTtcbiAgICAgICAgICAgIGRyYXdlci5hcHBlbmRDaGlsZChpdGVtKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEV4cGFuZCBkcmF3ZXIgdG8gZml0IGFsbCByb3dzXG4gICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5leHBhbmRUb1Jvd3Mocm93Q291bnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBoZWFkZXIgaXRlbSBlbGVtZW50IGZyb20gbGF5b3V0XG4gICAgICovXG4gICAgY3JlYXRlSGVhZGVySXRlbShsYXlvdXQpIHtcbiAgICAgICAgY29uc3QgeyBldmVudCwgY29sdW1uS2V5LCByb3csIGNvbFN0YXJ0LCBjb2xFbmQgfSA9IGxheW91dDtcbiAgICAgICAgY29uc3QgaXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1oZWFkZXItaXRlbScpO1xuICAgICAgICBpdGVtLmRhdGFzZXQuZXZlbnRJZCA9IGV2ZW50LmlkO1xuICAgICAgICBpdGVtLmRhdGFzZXQuaXRlbVR5cGUgPSAnZXZlbnQnO1xuICAgICAgICBpdGVtLmRhdGFzZXQuc3RhcnQgPSBldmVudC5zdGFydC50b0lTT1N0cmluZygpO1xuICAgICAgICBpdGVtLmRhdGFzZXQuZW5kID0gZXZlbnQuZW5kLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgIGl0ZW0uZGF0YXNldC5jb2x1bW5LZXkgPSBjb2x1bW5LZXk7XG4gICAgICAgIGl0ZW0udGV4dENvbnRlbnQgPSBldmVudC50aXRsZTtcbiAgICAgICAgLy8gQ29sb3IgY2xhc3NcbiAgICAgICAgY29uc3QgY29sb3JDbGFzcyA9IHRoaXMuZ2V0Q29sb3JDbGFzcyhldmVudCk7XG4gICAgICAgIGlmIChjb2xvckNsYXNzKVxuICAgICAgICAgICAgaXRlbS5jbGFzc0xpc3QuYWRkKGNvbG9yQ2xhc3MpO1xuICAgICAgICAvLyBHcmlkIHBvc2l0aW9uIGZyb20gbGF5b3V0XG4gICAgICAgIGl0ZW0uc3R5bGUuZ3JpZEFyZWEgPSBgJHtyb3d9IC8gJHtjb2xTdGFydH0gLyAke3JvdyArIDF9IC8gJHtjb2xFbmR9YDtcbiAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSBsYXlvdXQgZm9yIGFsbCBldmVudHMgd2l0aCByb3cgc3RhY2tpbmdcbiAgICAgKiBVc2VzIHRyYWNrLWJhc2VkIGFsZ29yaXRobSB0byBmaW5kIGF2YWlsYWJsZSByb3dzIGZvciBvdmVybGFwcGluZyBldmVudHNcbiAgICAgKi9cbiAgICBjYWxjdWxhdGVMYXlvdXQoZXZlbnRzLCB2aXNpYmxlQ29sdW1uS2V5cykge1xuICAgICAgICAvLyB0cmFja3Nbcm93XVtjb2xdID0gb2NjdXBpZWRcbiAgICAgICAgY29uc3QgdHJhY2tzID0gW25ldyBBcnJheSh2aXNpYmxlQ29sdW1uS2V5cy5sZW5ndGgpLmZpbGwoZmFsc2UpXTtcbiAgICAgICAgY29uc3QgbGF5b3V0cyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgICAgICAgICAgLy8gQnVpbGQgY29sdW1uS2V5IGZyb20gZXZlbnQgZmllbGRzIChvbmx5IHBsYWNlIHdlIG5lZWQgdG8gY29uc3RydWN0IGl0KVxuICAgICAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5idWlsZENvbHVtbktleUZyb21FdmVudChldmVudCk7XG4gICAgICAgICAgICBjb25zdCBzdGFydENvbCA9IHZpc2libGVDb2x1bW5LZXlzLmluZGV4T2YoY29sdW1uS2V5KTtcbiAgICAgICAgICAgIGNvbnN0IGVuZENvbHVtbktleSA9IHRoaXMuYnVpbGRDb2x1bW5LZXlGcm9tRXZlbnQoZXZlbnQsIGV2ZW50LmVuZCk7XG4gICAgICAgICAgICBjb25zdCBlbmRDb2wgPSB2aXNpYmxlQ29sdW1uS2V5cy5pbmRleE9mKGVuZENvbHVtbktleSk7XG4gICAgICAgICAgICBpZiAoc3RhcnRDb2wgPT09IC0xICYmIGVuZENvbCA9PT0gLTEpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAvLyBDbGFtcCB0aWwgc3lubGlnZSBrb2xvbm5lclxuICAgICAgICAgICAgY29uc3QgY29sU3RhcnQgPSBNYXRoLm1heCgwLCBzdGFydENvbCk7XG4gICAgICAgICAgICBjb25zdCBjb2xFbmQgPSAoZW5kQ29sICE9PSAtMSA/IGVuZENvbCA6IHZpc2libGVDb2x1bW5LZXlzLmxlbmd0aCAtIDEpICsgMTtcbiAgICAgICAgICAgIC8vIEZpbmQgbGVkaWcgclx1MDBFNmtrZVxuICAgICAgICAgICAgY29uc3Qgcm93ID0gdGhpcy5maW5kQXZhaWxhYmxlUm93KHRyYWNrcywgY29sU3RhcnQsIGNvbEVuZCk7XG4gICAgICAgICAgICAvLyBNYXJrZXIgc29tIG9wdGFnZXRcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSBjb2xTdGFydDsgYyA8IGNvbEVuZDsgYysrKSB7XG4gICAgICAgICAgICAgICAgdHJhY2tzW3Jvd11bY10gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGF5b3V0cy5wdXNoKHsgZXZlbnQsIGNvbHVtbktleSwgcm93OiByb3cgKyAxLCBjb2xTdGFydDogY29sU3RhcnQgKyAxLCBjb2xFbmQ6IGNvbEVuZCArIDEgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxheW91dHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGNvbHVtbktleSBmcm9tIGV2ZW50IHVzaW5nIEZpbHRlclRlbXBsYXRlXG4gICAgICogVXNlcyB0aGUgc2FtZSB0ZW1wbGF0ZSB0aGF0IGNvbHVtbnMgdXNlIGZvciBtYXRjaGluZ1xuICAgICAqL1xuICAgIGJ1aWxkQ29sdW1uS2V5RnJvbUV2ZW50KGV2ZW50LCBkYXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5maWx0ZXJUZW1wbGF0ZSkge1xuICAgICAgICAgICAgLy8gRmFsbGJhY2sgaWYgbm8gdGVtcGxhdGUgLSBzaG91bGRuJ3QgaGFwcGVuIGluIG5vcm1hbCBmbG93XG4gICAgICAgICAgICBjb25zdCBkYXRlU3RyID0gdGhpcy5kYXRlU2VydmljZS5nZXREYXRlS2V5KGRhdGUgfHwgZXZlbnQuc3RhcnQpO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGVTdHI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yIG11bHRpLWRheSBldmVudHMsIHdlIG5lZWQgdG8gb3ZlcnJpZGUgdGhlIGRhdGUgaW4gdGhlIGV2ZW50XG4gICAgICAgIGlmIChkYXRlICYmIGRhdGUuZ2V0VGltZSgpICE9PSBldmVudC5zdGFydC5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSB0ZW1wb3JhcnkgZXZlbnQgd2l0aCBvdmVycmlkZGVuIHN0YXJ0IGZvciBrZXkgZ2VuZXJhdGlvblxuICAgICAgICAgICAgY29uc3QgdGVtcEV2ZW50ID0geyAuLi5ldmVudCwgc3RhcnQ6IGRhdGUgfTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbHRlclRlbXBsYXRlLmJ1aWxkS2V5RnJvbUV2ZW50KHRlbXBFdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyVGVtcGxhdGUuYnVpbGRLZXlGcm9tRXZlbnQoZXZlbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5kIGF2YWlsYWJsZSByb3cgZm9yIGV2ZW50IHNwYW5uaW5nIGNvbHVtbnMgW2NvbFN0YXJ0LCBjb2xFbmQpXG4gICAgICovXG4gICAgZmluZEF2YWlsYWJsZVJvdyh0cmFja3MsIGNvbFN0YXJ0LCBjb2xFbmQpIHtcbiAgICAgICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgdHJhY2tzLmxlbmd0aDsgcm93KyspIHtcbiAgICAgICAgICAgIGxldCBhdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgICAgZm9yIChsZXQgYyA9IGNvbFN0YXJ0OyBjIDwgY29sRW5kOyBjKyspIHtcbiAgICAgICAgICAgICAgICBpZiAodHJhY2tzW3Jvd11bY10pIHtcbiAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhdmFpbGFibGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJvdztcbiAgICAgICAgfVxuICAgICAgICAvLyBOeSByXHUwMEU2a2tlXG4gICAgICAgIHRyYWNrcy5wdXNoKG5ldyBBcnJheSh0cmFja3NbMF0ubGVuZ3RoKS5maWxsKGZhbHNlKSk7XG4gICAgICAgIHJldHVybiB0cmFja3MubGVuZ3RoIC0gMTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGNvbG9yIGNsYXNzIGJhc2VkIG9uIGV2ZW50IG1ldGFkYXRhIG9yIHR5cGVcbiAgICAgKi9cbiAgICBnZXRDb2xvckNsYXNzKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5tZXRhZGF0YT8uY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBgaXMtJHtldmVudC5tZXRhZGF0YS5jb2xvcn1gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHR5cGVDb2xvcnMgPSB7XG4gICAgICAgICAgICAnY3VzdG9tZXInOiAnaXMtYmx1ZScsXG4gICAgICAgICAgICAndmFjYXRpb24nOiAnaXMtZ3JlZW4nLFxuICAgICAgICAgICAgJ2JyZWFrJzogJ2lzLWFtYmVyJyxcbiAgICAgICAgICAgICdtZWV0aW5nJzogJ2lzLXB1cnBsZScsXG4gICAgICAgICAgICAnYmxvY2tlZCc6ICdpcy1yZWQnXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0eXBlQ29sb3JzW2V2ZW50LnR5cGVdIHx8ICdpcy1ibHVlJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0dXAgZXZlbnQgbGlzdGVuZXJzIGZvciBkcmFnIGV2ZW50c1xuICAgICAqL1xuICAgIHNldHVwTGlzdGVuZXJzKCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19FTlRFUl9IRUFERVIsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZURyYWdFbnRlcihwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkVfSEVBREVSLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEcmFnTW92ZShwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0xFQVZFX0hFQURFUiwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRHJhZ0xlYXZlKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfRU5ELCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfQ0FOQ0VMLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBkcmFnIGVudGVyaW5nIGhlYWRlciB6b25lIC0gY3JlYXRlIHByZXZpZXcgaXRlbVxuICAgICAqL1xuICAgIGhhbmRsZURyYWdFbnRlcihwYXlsb2FkKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci1kcmF3ZXInKTtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gUmVtZW1iZXIgaWYgZHJhd2VyIHdhcyBhbHJlYWR5IGV4cGFuZGVkXG4gICAgICAgIHRoaXMud2FzRXhwYW5kZWRCZWZvcmVEcmFnID0gdGhpcy5oZWFkZXJEcmF3ZXJNYW5hZ2VyLmlzRXhwYW5kZWQoKTtcbiAgICAgICAgLy8gRXhwYW5kIHRvIGF0IGxlYXN0IDEgcm93IGlmIGNvbGxhcHNlZCwgb3RoZXJ3aXNlIGtlZXAgY3VycmVudCBoZWlnaHRcbiAgICAgICAgaWYgKCF0aGlzLndhc0V4cGFuZGVkQmVmb3JlRHJhZykge1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXJNYW5hZ2VyLmV4cGFuZFRvUm93cygxKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBTdG9yZSByZWZlcmVuY2UgdG8gc291cmNlIGVsZW1lbnRcbiAgICAgICAgdGhpcy5zb3VyY2VFbGVtZW50ID0gcGF5bG9hZC5lbGVtZW50O1xuICAgICAgICAvLyBDcmVhdGUgaGVhZGVyIGl0ZW1cbiAgICAgICAgY29uc3QgaXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1oZWFkZXItaXRlbScpO1xuICAgICAgICBpdGVtLmRhdGFzZXQuZXZlbnRJZCA9IHBheWxvYWQuZXZlbnRJZDtcbiAgICAgICAgaXRlbS5kYXRhc2V0Lml0ZW1UeXBlID0gcGF5bG9hZC5pdGVtVHlwZTtcbiAgICAgICAgaXRlbS5kYXRhc2V0LmR1cmF0aW9uID0gU3RyaW5nKHBheWxvYWQuZHVyYXRpb24pO1xuICAgICAgICBpdGVtLmRhdGFzZXQuY29sdW1uS2V5ID0gcGF5bG9hZC5zb3VyY2VDb2x1bW5LZXk7XG4gICAgICAgIGl0ZW0udGV4dENvbnRlbnQgPSBwYXlsb2FkLnRpdGxlO1xuICAgICAgICAvLyBBcHBseSBjb2xvciBjbGFzcyBpZiBwcmVzZW50XG4gICAgICAgIGlmIChwYXlsb2FkLmNvbG9yQ2xhc3MpIHtcbiAgICAgICAgICAgIGl0ZW0uY2xhc3NMaXN0LmFkZChwYXlsb2FkLmNvbG9yQ2xhc3MpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFkZCBkcmFnZ2luZyBzdGF0ZVxuICAgICAgICBpdGVtLmNsYXNzTGlzdC5hZGQoJ2RyYWdnaW5nJyk7XG4gICAgICAgIC8vIEluaXRpYWwgcGxhY2VtZW50IChkdXJhdGlvbiBkZXRlcm1pbmVzIGNvbHVtbiBzcGFuKVxuICAgICAgICAvLyBncmlkQXJlYSBmb3JtYXQ6IFwicm93IC8gY29sLXN0YXJ0IC8gcm93KzEgLyBjb2wtZW5kXCJcbiAgICAgICAgY29uc3QgY29sID0gcGF5bG9hZC5zb3VyY2VDb2x1bW5JbmRleCArIDE7XG4gICAgICAgIGNvbnN0IGVuZENvbCA9IGNvbCArIHBheWxvYWQuZHVyYXRpb247XG4gICAgICAgIGl0ZW0uc3R5bGUuZ3JpZEFyZWEgPSBgMSAvICR7Y29sfSAvIDIgLyAke2VuZENvbH1gO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChpdGVtKTtcbiAgICAgICAgdGhpcy5jdXJyZW50SXRlbSA9IGl0ZW07XG4gICAgICAgIC8vIEhpZGUgb3JpZ2luYWwgZWxlbWVudCB3aGlsZSBpbiBoZWFkZXJcbiAgICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIGRyYWcgbW92aW5nIHdpdGhpbiBoZWFkZXIgLSB1cGRhdGUgY29sdW1uIHBvc2l0aW9uXG4gICAgICovXG4gICAgaGFuZGxlRHJhZ01vdmUocGF5bG9hZCkge1xuICAgICAgICBpZiAoIXRoaXMuY3VycmVudEl0ZW0pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIFVwZGF0ZSBjb2x1bW4gcG9zaXRpb25cbiAgICAgICAgY29uc3QgY29sID0gcGF5bG9hZC5jb2x1bW5JbmRleCArIDE7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gcGFyc2VJbnQodGhpcy5jdXJyZW50SXRlbS5kYXRhc2V0LmR1cmF0aW9uIHx8ICcxJywgMTApO1xuICAgICAgICBjb25zdCBlbmRDb2wgPSBjb2wgKyBkdXJhdGlvbjtcbiAgICAgICAgdGhpcy5jdXJyZW50SXRlbS5zdHlsZS5ncmlkQXJlYSA9IGAxIC8gJHtjb2x9IC8gMiAvICR7ZW5kQ29sfWA7XG4gICAgICAgIC8vIFVwZGF0ZSBjb2x1bW5LZXkgdG8gbmV3IHBvc2l0aW9uXG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW0uZGF0YXNldC5jb2x1bW5LZXkgPSBwYXlsb2FkLmNvbHVtbktleTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIGRyYWcgbGVhdmluZyBoZWFkZXIgLSBjbGVhbnVwIGZvciBncmlkXHUyMTkyaGVhZGVyIGRyYWcgb25seVxuICAgICAqL1xuICAgIGhhbmRsZURyYWdMZWF2ZShwYXlsb2FkKSB7XG4gICAgICAgIC8vIE9ubHkgY2xlYW51cCBmb3IgZ3JpZFx1MjE5MmhlYWRlciBkcmFnICh3aGVuIGdyaWQgZXZlbnQgbGVhdmVzIGhlYWRlciBiYWNrIHRvIGdyaWQpXG4gICAgICAgIC8vIEZvciBoZWFkZXJcdTIxOTJncmlkIGRyYWcsIHRoZSBoZWFkZXIgaXRlbSBzdGF5cyBhcyBnaG9zdCB1bnRpbCBkcm9wXG4gICAgICAgIGlmIChwYXlsb2FkLnNvdXJjZSA9PT0gJ2dyaWQnKSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgaGVhZGVyIHNvdXJjZSwgZG8gbm90aGluZyAtIGdob3N0IHN0YXlzIHVudGlsIEVWRU5UX0RSQUdfRU5EXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBkcmFnIGVuZCAtIGZpbmFsaXplIGJhc2VkIG9uIGRyb3AgdGFyZ2V0XG4gICAgICovXG4gICAgaGFuZGxlRHJhZ0VuZChwYXlsb2FkKSB7XG4gICAgICAgIGlmIChwYXlsb2FkLnRhcmdldCA9PT0gJ2hlYWRlcicpIHtcbiAgICAgICAgICAgIC8vIEdyaWRcdTIxOTJIZWFkZXI6IEZpbmFsaXplIHRoZSBoZWFkZXIgaXRlbSAoaXQgc3RheXMgaW4gaGVhZGVyKVxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudEl0ZW0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRJdGVtLmNsYXNzTGlzdC5yZW1vdmUoJ2RyYWdnaW5nJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWNhbGN1bGF0ZURyYXdlckxheW91dCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEl0ZW0gPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuc291cmNlRWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBIZWFkZXJcdTIxOTJHcmlkOiBSZW1vdmUgZ2hvc3QgaGVhZGVyIGl0ZW0gYW5kIHJlY2FsY3VsYXRlXG4gICAgICAgICAgICBjb25zdCBnaG9zdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYHN3cC1oZWFkZXItaXRlbS5kcmFnLWdob3N0W2RhdGEtZXZlbnQtaWQ9XCIke3BheWxvYWQuc3dwRXZlbnQuZXZlbnRJZH1cIl1gKTtcbiAgICAgICAgICAgIGdob3N0Py5yZW1vdmUoKTtcbiAgICAgICAgICAgIHRoaXMucmVjYWxjdWxhdGVEcmF3ZXJMYXlvdXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWNhbGN1bGF0ZSBsYXlvdXQgZm9yIGFsbCBpdGVtcyBjdXJyZW50bHkgaW4gdGhlIGRyYXdlclxuICAgICAqIENhbGxlZCBhZnRlciBkcm9wIHRvIHJlcG9zaXRpb24gaXRlbXMgYW5kIGFkanVzdCBoZWlnaHRcbiAgICAgKi9cbiAgICByZWNhbGN1bGF0ZURyYXdlckxheW91dCgpIHtcbiAgICAgICAgY29uc3QgZHJhd2VyID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci1kcmF3ZXInKTtcbiAgICAgICAgaWYgKCFkcmF3ZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gQXJyYXkuZnJvbShkcmF3ZXIucXVlcnlTZWxlY3RvckFsbCgnc3dwLWhlYWRlci1pdGVtJykpO1xuICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBHZXQgdmlzaWJsZSBjb2x1bW4ga2V5cyBmb3IgY29ycmVjdCBtdWx0aS1yZXNvdXJjZSBwb3NpdGlvbmluZ1xuICAgICAgICBjb25zdCB2aXNpYmxlQ29sdW1uS2V5cyA9IHRoaXMuZ2V0VmlzaWJsZUNvbHVtbktleXNGcm9tRE9NKCk7XG4gICAgICAgIGlmICh2aXNpYmxlQ29sdW1uS2V5cy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEJ1aWxkIGxheW91dCBkYXRhIGZyb20gRE9NIGl0ZW1zIC0gdXNlIGNvbHVtbktleSBkaXJlY3RseSAob3BhcXVlIG1hdGNoaW5nKVxuICAgICAgICBjb25zdCBpdGVtRGF0YSA9IGl0ZW1zLm1hcChpdGVtID0+ICh7XG4gICAgICAgICAgICBlbGVtZW50OiBpdGVtLFxuICAgICAgICAgICAgY29sdW1uS2V5OiBpdGVtLmRhdGFzZXQuY29sdW1uS2V5IHx8ICcnLFxuICAgICAgICAgICAgZHVyYXRpb246IHBhcnNlSW50KGl0ZW0uZGF0YXNldC5kdXJhdGlvbiB8fCAnMScsIDEwKVxuICAgICAgICB9KSk7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBuZXcgbGF5b3V0IHVzaW5nIHRyYWNrIGFsZ29yaXRobVxuICAgICAgICBjb25zdCB0cmFja3MgPSBbbmV3IEFycmF5KHZpc2libGVDb2x1bW5LZXlzLmxlbmd0aCkuZmlsbChmYWxzZSldO1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbURhdGEpIHtcbiAgICAgICAgICAgIC8vIERpcmVjdCBjb2x1bW5LZXkgbWF0Y2hpbmcgLSBubyBwYXJzaW5nIG9yIGNvbnN0cnVjdGlvbiBuZWVkZWRcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Q29sID0gdmlzaWJsZUNvbHVtbktleXMuaW5kZXhPZihpdGVtLmNvbHVtbktleSk7XG4gICAgICAgICAgICBpZiAoc3RhcnRDb2wgPT09IC0xKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3QgY29sU3RhcnQgPSBzdGFydENvbDtcbiAgICAgICAgICAgIGNvbnN0IGNvbEVuZCA9IE1hdGgubWluKHN0YXJ0Q29sICsgaXRlbS5kdXJhdGlvbiwgdmlzaWJsZUNvbHVtbktleXMubGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IHJvdyA9IHRoaXMuZmluZEF2YWlsYWJsZVJvdyh0cmFja3MsIGNvbFN0YXJ0LCBjb2xFbmQpO1xuICAgICAgICAgICAgZm9yIChsZXQgYyA9IGNvbFN0YXJ0OyBjIDwgY29sRW5kOyBjKyspIHtcbiAgICAgICAgICAgICAgICB0cmFja3Nbcm93XVtjXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBVcGRhdGUgZWxlbWVudCBwb3NpdGlvblxuICAgICAgICAgICAgaXRlbS5lbGVtZW50LnN0eWxlLmdyaWRBcmVhID0gYCR7cm93ICsgMX0gLyAke2NvbFN0YXJ0ICsgMX0gLyAke3JvdyArIDJ9IC8gJHtjb2xFbmQgKyAxfWA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVXBkYXRlIGRyYXdlciBoZWlnaHRcbiAgICAgICAgY29uc3Qgcm93Q291bnQgPSB0cmFja3MubGVuZ3RoO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlck1hbmFnZXIuZXhwYW5kVG9Sb3dzKHJvd0NvdW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHZpc2libGUgY29sdW1uIGtleXMgZnJvbSBET00gKHByZXNlcnZlcyBvcmRlciBmb3IgbXVsdGktcmVzb3VyY2Ugdmlld3MpXG4gICAgICogVXNlcyBmaWx0ZXJUZW1wbGF0ZS5idWlsZEtleUZyb21Db2x1bW4oKSBmb3IgY29uc2lzdGVudCBrZXkgZm9ybWF0IHdpdGggZXZlbnRzXG4gICAgICovXG4gICAgZ2V0VmlzaWJsZUNvbHVtbktleXNGcm9tRE9NKCkge1xuICAgICAgICBpZiAoIXRoaXMuZmlsdGVyVGVtcGxhdGUpXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzd3AtZGF5LWNvbHVtbicpO1xuICAgICAgICBjb25zdCBjb2x1bW5LZXlzID0gW107XG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaChjb2wgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5maWx0ZXJUZW1wbGF0ZS5idWlsZEtleUZyb21Db2x1bW4oY29sKTtcbiAgICAgICAgICAgIGlmIChjb2x1bW5LZXkpXG4gICAgICAgICAgICAgICAgY29sdW1uS2V5cy5wdXNoKGNvbHVtbktleSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY29sdW1uS2V5cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW51cCBwcmV2aWV3IGl0ZW0gYW5kIHJlc3RvcmUgc291cmNlIHZpc2liaWxpdHlcbiAgICAgKi9cbiAgICBjbGVhbnVwKCkge1xuICAgICAgICAvLyBSZW1vdmUgcHJldmlldyBpdGVtXG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW0/LnJlbW92ZSgpO1xuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtID0gbnVsbDtcbiAgICAgICAgLy8gUmVzdG9yZSBzb3VyY2UgZWxlbWVudCB2aXNpYmlsaXR5XG4gICAgICAgIGlmICh0aGlzLnNvdXJjZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc291cmNlRWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJyc7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUVsZW1lbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIC8vIENvbGxhcHNlIGRyYXdlciBpZiBpdCB3YXNuJ3QgZXhwYW5kZWQgYmVmb3JlIGRyYWdcbiAgICAgICAgaWYgKCF0aGlzLndhc0V4cGFuZGVkQmVmb3JlRHJhZykge1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXJNYW5hZ2VyLmNvbGxhcHNlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiLyoqXG4gKiBTY2hlZHVsZU92ZXJyaWRlU3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZm9yIHNjaGVkdWxlIG92ZXJyaWRlc1xuICpcbiAqIFN0b3JlcyBkYXRlLXNwZWNpZmljIHNjaGVkdWxlIG92ZXJyaWRlcyBmb3IgcmVzb3VyY2VzLlxuICogSW5kZXhlczogcmVzb3VyY2VJZCwgZGF0ZSwgY29tcG91bmQgKHJlc291cmNlSWQgKyBkYXRlKVxuICovXG5leHBvcnQgY2xhc3MgU2NoZWR1bGVPdmVycmlkZVN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUoU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3Jlc291cmNlSWQnLCAncmVzb3VyY2VJZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2RhdGUnLCAnZGF0ZScsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3Jlc291cmNlSWRfZGF0ZScsIFsncmVzb3VyY2VJZCcsICdkYXRlJ10sIHsgdW5pcXVlOiB0cnVlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgIH1cbn1cblNjaGVkdWxlT3ZlcnJpZGVTdG9yZS5TVE9SRV9OQU1FID0gJ3NjaGVkdWxlT3ZlcnJpZGVzJztcbiIsICJpbXBvcnQgeyBTY2hlZHVsZU92ZXJyaWRlU3RvcmUgfSBmcm9tICcuL1NjaGVkdWxlT3ZlcnJpZGVTdG9yZSc7XG4vKipcbiAqIFNjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlIC0gQ1JVRCBmb3Igc2NoZWR1bGUgb3ZlcnJpZGVzXG4gKlxuICogUHJvdmlkZXMgYWNjZXNzIHRvIGRhdGUtc3BlY2lmaWMgc2NoZWR1bGUgb3ZlcnJpZGVzIGZvciByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2hlZHVsZU92ZXJyaWRlU2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCkge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbiAgICBnZXQgZGIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuZ2V0RGF0YWJhc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IG92ZXJyaWRlIGZvciBhIHNwZWNpZmljIHJlc291cmNlIGFuZCBkYXRlXG4gICAgICovXG4gICAgYXN5bmMgZ2V0T3ZlcnJpZGUocmVzb3VyY2VJZCwgZGF0ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFtTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZShTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdyZXNvdXJjZUlkX2RhdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleC5nZXQoW3Jlc291cmNlSWQsIGRhdGVdKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUocmVxdWVzdC5yZXN1bHQgfHwgbnVsbCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgb3ZlcnJpZGUgZm9yICR7cmVzb3VyY2VJZH0gb24gJHtkYXRlfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIG92ZXJyaWRlcyBmb3IgYSByZXNvdXJjZVxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5UmVzb3VyY2UocmVzb3VyY2VJZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFtTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZShTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdyZXNvdXJjZUlkJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKHJlc291cmNlSWQpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXF1ZXN0LnJlc3VsdCB8fCBbXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgb3ZlcnJpZGVzIGZvciAke3Jlc291cmNlSWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBvdmVycmlkZXMgZm9yIGEgZGF0ZSByYW5nZVxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5RGF0ZVJhbmdlKHJlc291cmNlSWQsIHN0YXJ0RGF0ZSwgZW5kRGF0ZSkge1xuICAgICAgICBjb25zdCBhbGwgPSBhd2FpdCB0aGlzLmdldEJ5UmVzb3VyY2UocmVzb3VyY2VJZCk7XG4gICAgICAgIHJldHVybiBhbGwuZmlsdGVyKG8gPT4gby5kYXRlID49IHN0YXJ0RGF0ZSAmJiBvLmRhdGUgPD0gZW5kRGF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNhdmUgYW4gb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBhc3luYyBzYXZlKG92ZXJyaWRlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW1NjaGVkdWxlT3ZlcnJpZGVTdG9yZS5TVE9SRV9OQU1FXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZShTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRSk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUucHV0KG92ZXJyaWRlKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBzYXZlIG92ZXJyaWRlICR7b3ZlcnJpZGUuaWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBhbiBvdmVycmlkZVxuICAgICAqL1xuICAgIGFzeW5jIGRlbGV0ZShpZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFtTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRV0sICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUUpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmRlbGV0ZShpZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHJlc29sdmUoKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZGVsZXRlIG92ZXJyaWRlICR7aWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogUmVzb3VyY2VTY2hlZHVsZVNlcnZpY2UgLSBHZXQgZWZmZWN0aXZlIHNjaGVkdWxlIGZvciBhIHJlc291cmNlIG9uIGEgZGF0ZVxuICpcbiAqIExvZ2ljOlxuICogMS4gQ2hlY2sgZm9yIG92ZXJyaWRlIG9uIHRoaXMgZGF0ZVxuICogMi4gRmFsbCBiYWNrIHRvIGRlZmF1bHQgc2NoZWR1bGUgZm9yIHRoZSB3ZWVrZGF5XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVNjaGVkdWxlU2VydmljZSB7XG4gICAgY29uc3RydWN0b3IocmVzb3VyY2VTZXJ2aWNlLCBvdmVycmlkZVNlcnZpY2UsIGRhdGVTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMucmVzb3VyY2VTZXJ2aWNlID0gcmVzb3VyY2VTZXJ2aWNlO1xuICAgICAgICB0aGlzLm92ZXJyaWRlU2VydmljZSA9IG92ZXJyaWRlU2VydmljZTtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZWZmZWN0aXZlIHNjaGVkdWxlIGZvciBhIHJlc291cmNlIG9uIGEgc3BlY2lmaWMgZGF0ZVxuICAgICAqXG4gICAgICogQHBhcmFtIHJlc291cmNlSWQgLSBSZXNvdXJjZSBJRFxuICAgICAqIEBwYXJhbSBkYXRlIC0gRGF0ZSBzdHJpbmcgXCJZWVlZLU1NLUREXCJcbiAgICAgKiBAcmV0dXJucyBJVGltZVNsb3Qgb3IgbnVsbCAoZnJpL2Nsb3NlZClcbiAgICAgKi9cbiAgICBhc3luYyBnZXRTY2hlZHVsZUZvckRhdGUocmVzb3VyY2VJZCwgZGF0ZSkge1xuICAgICAgICAvLyAxLiBDaGVjayBmb3Igb3ZlcnJpZGVcbiAgICAgICAgY29uc3Qgb3ZlcnJpZGUgPSBhd2FpdCB0aGlzLm92ZXJyaWRlU2VydmljZS5nZXRPdmVycmlkZShyZXNvdXJjZUlkLCBkYXRlKTtcbiAgICAgICAgaWYgKG92ZXJyaWRlKSB7XG4gICAgICAgICAgICByZXR1cm4gb3ZlcnJpZGUuc2NoZWR1bGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gMi4gVXNlIGRlZmF1bHQgc2NoZWR1bGUgZm9yIHdlZWtkYXlcbiAgICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCB0aGlzLnJlc291cmNlU2VydmljZS5nZXQocmVzb3VyY2VJZCk7XG4gICAgICAgIGlmICghcmVzb3VyY2UgfHwgIXJlc291cmNlLmRlZmF1bHRTY2hlZHVsZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2Vla0RheSA9IHRoaXMuZGF0ZVNlcnZpY2UuZ2V0SVNPV2Vla0RheShkYXRlKTtcbiAgICAgICAgcmV0dXJuIHJlc291cmNlLmRlZmF1bHRTY2hlZHVsZVt3ZWVrRGF5XSB8fCBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgc2NoZWR1bGVzIGZvciBtdWx0aXBsZSBkYXRlc1xuICAgICAqXG4gICAgICogQHBhcmFtIHJlc291cmNlSWQgLSBSZXNvdXJjZSBJRFxuICAgICAqIEBwYXJhbSBkYXRlcyAtIEFycmF5IG9mIGRhdGUgc3RyaW5ncyBcIllZWVktTU0tRERcIlxuICAgICAqIEByZXR1cm5zIE1hcCBvZiBkYXRlIC0+IElUaW1lU2xvdCB8IG51bGxcbiAgICAgKi9cbiAgICBhc3luYyBnZXRTY2hlZHVsZXNGb3JEYXRlcyhyZXNvdXJjZUlkLCBkYXRlcykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIEdldCByZXNvdXJjZSBvbmNlXG4gICAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgdGhpcy5yZXNvdXJjZVNlcnZpY2UuZ2V0KHJlc291cmNlSWQpO1xuICAgICAgICAvLyBHZXQgYWxsIG92ZXJyaWRlcyBpbiBkYXRlIHJhbmdlXG4gICAgICAgIGNvbnN0IG92ZXJyaWRlcyA9IGRhdGVzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgID8gYXdhaXQgdGhpcy5vdmVycmlkZVNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2UocmVzb3VyY2VJZCwgZGF0ZXNbMF0sIGRhdGVzW2RhdGVzLmxlbmd0aCAtIDFdKVxuICAgICAgICAgICAgOiBbXTtcbiAgICAgICAgLy8gQnVpbGQgb3ZlcnJpZGUgbWFwXG4gICAgICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gbmV3IE1hcChvdmVycmlkZXMubWFwKG8gPT4gW28uZGF0ZSwgby5zY2hlZHVsZV0pKTtcbiAgICAgICAgLy8gUmVzb2x2ZSBlYWNoIGRhdGVcbiAgICAgICAgZm9yIChjb25zdCBkYXRlIG9mIGRhdGVzKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBvdmVycmlkZSBmaXJzdFxuICAgICAgICAgICAgaWYgKG92ZXJyaWRlTWFwLmhhcyhkYXRlKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5zZXQoZGF0ZSwgb3ZlcnJpZGVNYXAuZ2V0KGRhdGUpKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEZhbGwgYmFjayB0byBkZWZhdWx0XG4gICAgICAgICAgICBpZiAocmVzb3VyY2U/LmRlZmF1bHRTY2hlZHVsZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdlZWtEYXkgPSB0aGlzLmRhdGVTZXJ2aWNlLmdldElTT1dlZWtEYXkoZGF0ZSk7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnNldChkYXRlLCByZXNvdXJjZS5kZWZhdWx0U2NoZWR1bGVbd2Vla0RheV0gfHwgbnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuc2V0KGRhdGUsIG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuIiwgIi8qKlxuICogU3dwRXZlbnQgLSBXcmFwcGVyIGNsYXNzIGZvciBjYWxlbmRhciBldmVudCBlbGVtZW50c1xuICpcbiAqIEVuY2Fwc3VsYXRlcyBhbiBIVE1MRWxlbWVudCBhbmQgcHJvdmlkZXMgY29tcHV0ZWQgcHJvcGVydGllc1xuICogZm9yIHN0YXJ0L2VuZCB0aW1lcyBiYXNlZCBvbiBlbGVtZW50IHBvc2l0aW9uIGFuZCBncmlkIGNvbmZpZy5cbiAqXG4gKiBVc2FnZTpcbiAqIC0gZXZlbnRJZCBpcyByZWFkIGZyb20gZWxlbWVudC5kYXRhc2V0XG4gKiAtIGNvbHVtbktleSBpZGVudGlmaWVzIHRoZSBjb2x1bW4gdW5pZm9ybWx5XG4gKiAtIFBvc2l0aW9uICh0b3AsIGhlaWdodCkgaXMgcmVhZCBmcm9tIGVsZW1lbnQuc3R5bGVcbiAqIC0gRmFjdG9yeSBtZXRob2QgYGZyb21FbGVtZW50KClgIGNhbGN1bGF0ZXMgRGF0ZSBvYmplY3RzXG4gKi9cbmV4cG9ydCBjbGFzcyBTd3BFdmVudCB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgY29sdW1uS2V5LCBzdGFydCwgZW5kKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xuICAgICAgICB0aGlzLl9zdGFydCA9IHN0YXJ0O1xuICAgICAgICB0aGlzLl9lbmQgPSBlbmQ7XG4gICAgfVxuICAgIC8qKiBFdmVudCBJRCBmcm9tIGVsZW1lbnQuZGF0YXNldC5ldmVudElkICovXG4gICAgZ2V0IGV2ZW50SWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQuZGF0YXNldC5ldmVudElkIHx8ICcnO1xuICAgIH1cbiAgICBnZXQgc3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGFydDtcbiAgICB9XG4gICAgZ2V0IGVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuZDtcbiAgICB9XG4gICAgLyoqIER1cmF0aW9uIGluIG1pbnV0ZXMgKi9cbiAgICBnZXQgZHVyYXRpb25NaW51dGVzKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuX2VuZC5nZXRUaW1lKCkgLSB0aGlzLl9zdGFydC5nZXRUaW1lKCkpIC8gKDEwMDAgKiA2MCk7XG4gICAgfVxuICAgIC8qKiBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgKi9cbiAgICBnZXQgZHVyYXRpb25NcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuZC5nZXRUaW1lKCkgLSB0aGlzLl9zdGFydC5nZXRUaW1lKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZhY3Rvcnk6IENyZWF0ZSBTd3BFdmVudCBmcm9tIGVsZW1lbnQgKyBjb2x1bW5LZXlcbiAgICAgKiBSZWFkcyB0b3AvaGVpZ2h0IGZyb20gZWxlbWVudC5zdHlsZSB0byBjYWxjdWxhdGUgc3RhcnQvZW5kXG4gICAgICogQHBhcmFtIGNvbHVtbktleSAtIE9wYXF1ZSBjb2x1bW4gaWRlbnRpZmllciAoZG8gTk9UIHBhcnNlIC0gdXNlIG9ubHkgZm9yIG1hdGNoaW5nKVxuICAgICAqIEBwYXJhbSBkYXRlIC0gRGF0ZSBzdHJpbmcgKFlZWVktTU0tREQpIGZvciB0aW1lIGNhbGN1bGF0aW9uc1xuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tRWxlbWVudChlbGVtZW50LCBjb2x1bW5LZXksIGRhdGUsIGdyaWRDb25maWcpIHtcbiAgICAgICAgY29uc3QgdG9wUGl4ZWxzID0gcGFyc2VGbG9hdChlbGVtZW50LnN0eWxlLnRvcCkgfHwgMDtcbiAgICAgICAgY29uc3QgaGVpZ2h0UGl4ZWxzID0gcGFyc2VGbG9hdChlbGVtZW50LnN0eWxlLmhlaWdodCkgfHwgMDtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHN0YXJ0IGZyb20gdG9wIHBvc2l0aW9uXG4gICAgICAgIGNvbnN0IHN0YXJ0TWludXRlc0Zyb21HcmlkID0gKHRvcFBpeGVscyAvIGdyaWRDb25maWcuaG91ckhlaWdodCkgKiA2MDtcbiAgICAgICAgY29uc3QgdG90YWxNaW51dGVzID0gKGdyaWRDb25maWcuZGF5U3RhcnRIb3VyICogNjApICsgc3RhcnRNaW51dGVzRnJvbUdyaWQ7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgIHN0YXJ0LnNldEhvdXJzKE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gNjApLCB0b3RhbE1pbnV0ZXMgJSA2MCwgMCwgMCk7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBlbmQgZnJvbSBoZWlnaHRcbiAgICAgICAgY29uc3QgZHVyYXRpb25NaW51dGVzID0gKGhlaWdodFBpeGVscyAvIGdyaWRDb25maWcuaG91ckhlaWdodCkgKiA2MDtcbiAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUoc3RhcnQuZ2V0VGltZSgpICsgZHVyYXRpb25NaW51dGVzICogNjAgKiAxMDAwKTtcbiAgICAgICAgcmV0dXJuIG5ldyBTd3BFdmVudChlbGVtZW50LCBjb2x1bW5LZXksIHN0YXJ0LCBlbmQpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBDb3JlRXZlbnRzIH0gZnJvbSAnLi4vY29uc3RhbnRzL0NvcmVFdmVudHMnO1xuaW1wb3J0IHsgc25hcFRvR3JpZCB9IGZyb20gJy4uL3V0aWxzL1Bvc2l0aW9uVXRpbHMnO1xuaW1wb3J0IHsgU3dwRXZlbnQgfSBmcm9tICcuLi90eXBlcy9Td3BFdmVudCc7XG4vKipcbiAqIERyYWdEcm9wTWFuYWdlciAtIEhhbmRsZXMgZHJhZy1kcm9wIGZvciBjYWxlbmRhciBldmVudHNcbiAqXG4gKiBTdHJhdGVneTogRHJhZyBvcmlnaW5hbCBlbGVtZW50LCBsZWF2ZSBnaG9zdC1jbG9uZSBpbiBwbGFjZVxuICogLSBtb3VzZWRvd246IFN0b3JlIGluaXRpYWwgc3RhdGUsIHdhaXQgZm9yIG1vdmVtZW50XG4gKiAtIG1vdXNlbW92ZSAoPjVweCk6IENyZWF0ZSBnaG9zdCwgc3RhcnQgZHJhZ2dpbmcgb3JpZ2luYWxcbiAqIC0gbW91c2V1cDogU25hcCB0byBncmlkLCByZW1vdmUgZ2hvc3QsIGVtaXQgZHJhZzplbmRcbiAqIC0gY2FuY2VsOiBBbmltYXRlIGJhY2sgdG8gc3RhcnRZLCByZW1vdmUgZ2hvc3RcbiAqL1xuZXhwb3J0IGNsYXNzIERyYWdEcm9wTWFuYWdlciB7XG4gICAgY29uc3RydWN0b3IoZXZlbnRCdXMsIGdyaWRDb25maWcpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmdyaWRDb25maWcgPSBncmlkQ29uZmlnO1xuICAgICAgICB0aGlzLmRyYWdTdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMubW91c2VEb3duUG9zaXRpb24gPSBudWxsO1xuICAgICAgICB0aGlzLnBlbmRpbmdFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5wZW5kaW5nTW91c2VPZmZzZXQgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgICAgIHRoaXMuaW5IZWFkZXIgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5EUkFHX1RIUkVTSE9MRCA9IDU7XG4gICAgICAgIHRoaXMuSU5URVJQT0xBVElPTl9GQUNUT1IgPSAwLjM7XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlckRvd24gPSAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICAvLyBJZ25vcmUgaWYgY2xpY2tpbmcgb24gcmVzaXplIGhhbmRsZVxuICAgICAgICAgICAgaWYgKHRhcmdldC5jbG9zZXN0KCdzd3AtcmVzaXplLWhhbmRsZScpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIE1hdGNoIGJvdGggc3dwLWV2ZW50IGFuZCBzd3AtaGVhZGVyLWl0ZW1cbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RWxlbWVudCA9IHRhcmdldC5jbG9zZXN0KCdzd3AtZXZlbnQnKTtcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlckl0ZW0gPSB0YXJnZXQuY2xvc2VzdCgnc3dwLWhlYWRlci1pdGVtJyk7XG4gICAgICAgICAgICBjb25zdCBkcmFnZ2FibGUgPSBldmVudEVsZW1lbnQgfHwgaGVhZGVySXRlbTtcbiAgICAgICAgICAgIGlmICghZHJhZ2dhYmxlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIFN0b3JlIGZvciBwb3RlbnRpYWwgZHJhZ1xuICAgICAgICAgICAgdGhpcy5tb3VzZURvd25Qb3NpdGlvbiA9IHsgeDogZS5jbGllbnRYLCB5OiBlLmNsaWVudFkgfTtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ0VsZW1lbnQgPSBkcmFnZ2FibGU7XG4gICAgICAgICAgICAvLyBDYWxjdWxhdGUgbW91c2Ugb2Zmc2V0IHdpdGhpbiBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCByZWN0ID0gZHJhZ2dhYmxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nTW91c2VPZmZzZXQgPSB7XG4gICAgICAgICAgICAgICAgeDogZS5jbGllbnRYIC0gcmVjdC5sZWZ0LFxuICAgICAgICAgICAgICAgIHk6IGUuY2xpZW50WSAtIHJlY3QudG9wXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gQ2FwdHVyZSBwb2ludGVyIGZvciByZWxpYWJsZSB0cmFja2luZ1xuICAgICAgICAgICAgZHJhZ2dhYmxlLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZSA9IChlKSA9PiB7XG4gICAgICAgICAgICAvLyBOb3QgaW4gcG90ZW50aWFsIGRyYWcgc3RhdGVcbiAgICAgICAgICAgIGlmICghdGhpcy5tb3VzZURvd25Qb3NpdGlvbiB8fCAhdGhpcy5wZW5kaW5nRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIEFscmVhZHkgZHJhZ2dpbmcgLSB1cGRhdGUgdGFyZ2V0XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRHJhZ1RhcmdldChlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2hlY2sgdGhyZXNob2xkXG4gICAgICAgICAgICBjb25zdCBkZWx0YVggPSBNYXRoLmFicyhlLmNsaWVudFggLSB0aGlzLm1vdXNlRG93blBvc2l0aW9uLngpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFZID0gTWF0aC5hYnMoZS5jbGllbnRZIC0gdGhpcy5tb3VzZURvd25Qb3NpdGlvbi55KTtcbiAgICAgICAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGRlbHRhWCAqIGRlbHRhWCArIGRlbHRhWSAqIGRlbHRhWSk7XG4gICAgICAgICAgICBpZiAoZGlzdGFuY2UgPCB0aGlzLkRSQUdfVEhSRVNIT0xEKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIFN0YXJ0IGRyYWdcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZURyYWcodGhpcy5wZW5kaW5nRWxlbWVudCwgdGhpcy5wZW5kaW5nTW91c2VPZmZzZXQsIGUpO1xuICAgICAgICAgICAgdGhpcy5tb3VzZURvd25Qb3NpdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ01vdXNlT2Zmc2V0ID0gbnVsbDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyVXAgPSAoX2UpID0+IHtcbiAgICAgICAgICAgIC8vIENsZWFyIHBlbmRpbmcgc3RhdGVcbiAgICAgICAgICAgIHRoaXMubW91c2VEb3duUG9zaXRpb24gPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nRWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdNb3VzZU9mZnNldCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIFN0b3AgYW5pbWF0aW9uXG4gICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmRyYWdTdGF0ZS5hbmltYXRpb25JZCk7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYmFzZWQgb24gZHJhZyBzb3VyY2UgYW5kIHRhcmdldFxuICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlLmRyYWdTb3VyY2UgPT09ICdoZWFkZXInKSB7XG4gICAgICAgICAgICAgICAgLy8gSGVhZGVyIGl0ZW0gZHJhZyBlbmRcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUhlYWRlckl0ZW1EcmFnRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBHcmlkIGV2ZW50IGRyYWcgZW5kXG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVHcmlkRXZlbnREcmFnRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDbGVhbnVwXG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2RyYWdnaW5nJyk7XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmluSGVhZGVyID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYW5pbWF0ZURyYWcgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGRpZmYgPSB0aGlzLmRyYWdTdGF0ZS50YXJnZXRZIC0gdGhpcy5kcmFnU3RhdGUuY3VycmVudFk7XG4gICAgICAgICAgICAvLyBTdG9wIGFuaW1hdGlvbiB3aGVuIGNsb3NlIGVub3VnaCB0byB0YXJnZXRcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkaWZmKSA8PSAwLjUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5hbmltYXRpb25JZCA9IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSW50ZXJwb2xhdGUgdG93YXJkcyB0YXJnZXRcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZICs9IGRpZmYgKiB0aGlzLklOVEVSUE9MQVRJT05fRkFDVE9SO1xuICAgICAgICAgICAgLy8gVXBkYXRlIGVsZW1lbnQgcG9zaXRpb25cbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuc3R5bGUudG9wID0gYCR7dGhpcy5kcmFnU3RhdGUuY3VycmVudFl9cHhgO1xuICAgICAgICAgICAgLy8gRW1pdCBkcmFnOm1vdmUgKG9ubHkgaWYgd2UgaGF2ZSBhIGNvbHVtbilcbiAgICAgICAgICAgIGlmICh0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRJZDogdGhpcy5kcmFnU3RhdGUuZXZlbnRJZCxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFk6IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5FbGVtZW50OiB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkUsIHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ29udGludWUgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5hbmltYXRpb25JZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGVEcmFnKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXR1cFNjcm9sbExpc3RlbmVyKCk7XG4gICAgfVxuICAgIHNldHVwU2Nyb2xsTGlzdGVuZXIoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FREdFX1NDUk9MTF9USUNLLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBjb25zdCB7IHNjcm9sbERlbHRhIH0gPSBlLmRldGFpbDtcbiAgICAgICAgICAgIC8vIEVsZW1lbnQgc2thbCBmbHl0dGUgbWVkIHNjcm9sbCBmb3IgYXQgZm9yYmxpdmUgdW5kZXIgbXVzZW5cbiAgICAgICAgICAgIC8vIChlbGVtZW50ZXRzIHRvcCBlciByZWxhdGl2IHRpbCBrb2xvbm5lbiwgc29tIHNjcm9sbGVyIG1lZCB2aWV3cG9ydClcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLnRhcmdldFkgKz0gc2Nyb2xsRGVsdGE7XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50WSArPSBzY3JvbGxEZWx0YTtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuc3R5bGUudG9wID0gYCR7dGhpcy5kcmFnU3RhdGUuY3VycmVudFl9cHhgO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSBkcmFnLWRyb3Agb24gYSBjb250YWluZXIgZWxlbWVudFxuICAgICAqL1xuICAgIGluaXQoY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xuICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLmhhbmRsZVBvaW50ZXJEb3duKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5oYW5kbGVQb2ludGVyVXApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgZHJhZyBlbmQgZm9yIGhlYWRlciBpdGVtc1xuICAgICAqL1xuICAgIGhhbmRsZUhlYWRlckl0ZW1EcmFnRW5kKCkge1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBJZiBkcm9wcGVkIGluIGdyaWQgKG5vdCBpbiBoZWFkZXIpLCB0aGUgc3dwLWV2ZW50IHdhcyBhbHJlYWR5IGNyZWF0ZWRcbiAgICAgICAgLy8gYnkgRXZlbnRSZW5kZXJlciBsaXN0ZW5pbmcgdG8gRVZFTlRfRFJBR19MRUFWRV9IRUFERVJcbiAgICAgICAgLy8gSnVzdCBlbWl0IGRyYWc6ZW5kIGZvciBwZXJzaXN0ZW5jZVxuICAgICAgICBpZiAoIXRoaXMuaW5IZWFkZXIgJiYgdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbikge1xuICAgICAgICAgICAgLy8gRHJvcHBlZCBpbiBncmlkIC0gZW1pdCBkcmFnOmVuZCB3aXRoIHRoZSBuZXcgc3dwLWV2ZW50IGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IGdyaWRFdmVudCA9IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4ucXVlcnlTZWxlY3Rvcihgc3dwLWV2ZW50W2RhdGEtZXZlbnQtaWQ9XCIke3RoaXMuZHJhZ1N0YXRlLmV2ZW50SWR9XCJdYCk7XG4gICAgICAgICAgICBpZiAoZ3JpZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbi5kYXRhc2V0LmNvbHVtbktleSB8fCAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbi5kYXRhc2V0LmRhdGUgfHwgJyc7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3dwRXZlbnQgPSBTd3BFdmVudC5mcm9tRWxlbWVudChncmlkRXZlbnQsIGNvbHVtbktleSwgZGF0ZSwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICBzd3BFdmVudCxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlQ29sdW1uS2V5OiB0aGlzLmRyYWdTdGF0ZS5zb3VyY2VDb2x1bW5LZXksXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldDogJ2dyaWQnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgcGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgc3RpbGwgaW4gaGVhZGVyLCBubyBwZXJzaXN0ZW5jZSBuZWVkZWQgKHN0YXllZCBpbiBoZWFkZXIpXG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBkcmFnIGVuZCBmb3IgZ3JpZCBldmVudHNcbiAgICAgKi9cbiAgICBoYW5kbGVHcmlkRXZlbnREcmFnRW5kKCkge1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlIHx8ICF0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBTbmFwIHRvIGdyaWRcbiAgICAgICAgY29uc3Qgc25hcHBlZFkgPSBzbmFwVG9HcmlkKHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LnN0eWxlLnRvcCA9IGAke3NuYXBwZWRZfXB4YDtcbiAgICAgICAgLy8gUmVtb3ZlIGdob3N0XG4gICAgICAgIHRoaXMuZHJhZ1N0YXRlLmdob3N0RWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgICAgIC8vIEdldCBjb2x1bW5LZXkgYW5kIGRhdGUgZnJvbSB0YXJnZXQgY29sdW1uXG4gICAgICAgIGNvbnN0IGNvbHVtbktleSA9IHRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQuZGF0YXNldC5jb2x1bW5LZXkgfHwgJyc7XG4gICAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50LmRhdGFzZXQuZGF0ZSB8fCAnJztcbiAgICAgICAgLy8gQ3JlYXRlIFN3cEV2ZW50IGZyb20gZWxlbWVudCAocmVhZHMgdG9wL2hlaWdodC9ldmVudElkIGZyb20gZWxlbWVudClcbiAgICAgICAgY29uc3Qgc3dwRXZlbnQgPSBTd3BFdmVudC5mcm9tRWxlbWVudCh0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LCBjb2x1bW5LZXksIGRhdGUsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIC8vIEVtaXQgZHJhZzplbmRcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIHN3cEV2ZW50LFxuICAgICAgICAgICAgc291cmNlQ29sdW1uS2V5OiB0aGlzLmRyYWdTdGF0ZS5zb3VyY2VDb2x1bW5LZXksXG4gICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaW5IZWFkZXIgPyAnaGVhZGVyJyA6ICdncmlkJ1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgcGF5bG9hZCk7XG4gICAgfVxuICAgIGluaXRpYWxpemVEcmFnKGVsZW1lbnQsIG1vdXNlT2Zmc2V0LCBlKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50SWQgPSBlbGVtZW50LmRhdGFzZXQuZXZlbnRJZCB8fCAnJztcbiAgICAgICAgY29uc3QgaXNIZWFkZXJJdGVtID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzd3AtaGVhZGVyLWl0ZW0nO1xuICAgICAgICBjb25zdCBjb2x1bW5FbGVtZW50ID0gZWxlbWVudC5jbG9zZXN0KCdzd3AtZGF5LWNvbHVtbicpO1xuICAgICAgICAvLyBGb3IgZ3JpZCBldmVudHMsIHdlIG5lZWQgYSBjb2x1bW5cbiAgICAgICAgaWYgKCFpc0hlYWRlckl0ZW0gJiYgIWNvbHVtbkVsZW1lbnQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmIChpc0hlYWRlckl0ZW0pIHtcbiAgICAgICAgICAgIC8vIEhlYWRlciBpdGVtIGRyYWcgaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUhlYWRlckl0ZW1EcmFnKGVsZW1lbnQsIG1vdXNlT2Zmc2V0LCBldmVudElkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIEdyaWQgZXZlbnQgZHJhZyBpbml0aWFsaXphdGlvblxuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplR3JpZEV2ZW50RHJhZyhlbGVtZW50LCBtb3VzZU9mZnNldCwgZSwgY29sdW1uRWxlbWVudCwgZXZlbnRJZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSBkcmFnIGZvciBhIGhlYWRlciBpdGVtIChhbGxEYXkgZXZlbnQpXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZUhlYWRlckl0ZW1EcmFnKGVsZW1lbnQsIG1vdXNlT2Zmc2V0LCBldmVudElkKSB7XG4gICAgICAgIC8vIE1hcmsgYXMgZHJhZ2dpbmdcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xuICAgICAgICAvLyBJbml0aWFsaXplIGRyYWcgc3RhdGUgZm9yIGhlYWRlciBpdGVtXG4gICAgICAgIHRoaXMuZHJhZ1N0YXRlID0ge1xuICAgICAgICAgICAgZXZlbnRJZCxcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICBnaG9zdEVsZW1lbnQ6IG51bGwsIC8vIE5vIGdob3N0IGZvciBoZWFkZXIgaXRlbXNcbiAgICAgICAgICAgIHN0YXJ0WTogMCxcbiAgICAgICAgICAgIG1vdXNlT2Zmc2V0LFxuICAgICAgICAgICAgY29sdW1uRWxlbWVudDogbnVsbCxcbiAgICAgICAgICAgIGN1cnJlbnRDb2x1bW46IG51bGwsXG4gICAgICAgICAgICB0YXJnZXRZOiAwLFxuICAgICAgICAgICAgY3VycmVudFk6IDAsXG4gICAgICAgICAgICBhbmltYXRpb25JZDogMCxcbiAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogJycsIC8vIFdpbGwgYmUgc2V0IGZyb20gaGVhZGVyIGl0ZW0gZGF0YVxuICAgICAgICAgICAgZHJhZ1NvdXJjZTogJ2hlYWRlcidcbiAgICAgICAgfTtcbiAgICAgICAgLy8gU3RhcnQgaW4gaGVhZGVyIG1vZGVcbiAgICAgICAgdGhpcy5pbkhlYWRlciA9IHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZHJhZyBmb3IgYSBncmlkIGV2ZW50XG4gICAgICovXG4gICAgaW5pdGlhbGl6ZUdyaWRFdmVudERyYWcoZWxlbWVudCwgbW91c2VPZmZzZXQsIGUsIGNvbHVtbkVsZW1lbnQsIGV2ZW50SWQpIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGFic29sdXRlIFkgcG9zaXRpb24gdXNpbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0XG4gICAgICAgIGNvbnN0IGVsZW1lbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgY29sdW1uUmVjdCA9IGNvbHVtbkVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IHN0YXJ0WSA9IGVsZW1lbnRSZWN0LnRvcCAtIGNvbHVtblJlY3QudG9wO1xuICAgICAgICAvLyBJZiBldmVudCBpcyBpbnNpZGUgYSBncm91cCwgbW92ZSBpdCB0byBldmVudHMtbGF5ZXIgZm9yIGNvcnJlY3QgcG9zaXRpb25pbmcgZHVyaW5nIGRyYWdcbiAgICAgICAgY29uc3QgZ3JvdXAgPSBlbGVtZW50LmNsb3Nlc3QoJ3N3cC1ldmVudC1ncm91cCcpO1xuICAgICAgICBpZiAoZ3JvdXApIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50c0xheWVyID0gY29sdW1uRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XG4gICAgICAgICAgICBpZiAoZXZlbnRzTGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBTZXQgY29uc2lzdGVudCBwb3NpdGlvbmluZyBmb3IgZHJhZyAod29ya3MgZm9yIGJvdGggZ3JvdXBlZCBhbmQgc3RhY2tlZCBldmVudHMpXG4gICAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3N0YXJ0WX1weGA7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9ICcycHgnO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnJpZ2h0ID0gJzJweCc7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUubWFyZ2luTGVmdCA9ICcwJzsgLy8gUmVzZXQgc3RhY2tpbmcgbWFyZ2luXG4gICAgICAgIC8vIENyZWF0ZSBnaG9zdCBjbG9uZVxuICAgICAgICBjb25zdCBnaG9zdEVsZW1lbnQgPSBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcbiAgICAgICAgZ2hvc3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RyYWctZ2hvc3QnKTtcbiAgICAgICAgZ2hvc3RFbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAnMC4zJztcbiAgICAgICAgZ2hvc3RFbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgICAgIC8vIEluc2VydCBnaG9zdCBiZWZvcmUgb3JpZ2luYWxcbiAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlPy5pbnNlcnRCZWZvcmUoZ2hvc3RFbGVtZW50LCBlbGVtZW50KTtcbiAgICAgICAgLy8gU2V0dXAgZWxlbWVudCBmb3IgZHJhZ2dpbmdcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xuICAgICAgICAvLyBDYWxjdWxhdGUgaW5pdGlhbCB0YXJnZXQgZnJvbSBtb3VzZSBwb3NpdGlvblxuICAgICAgICBjb25zdCB0YXJnZXRZID0gZS5jbGllbnRZIC0gY29sdW1uUmVjdC50b3AgLSBtb3VzZU9mZnNldC55O1xuICAgICAgICAvLyBJbml0aWFsaXplIGRyYWcgc3RhdGVcbiAgICAgICAgdGhpcy5kcmFnU3RhdGUgPSB7XG4gICAgICAgICAgICBldmVudElkLFxuICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgIGdob3N0RWxlbWVudCxcbiAgICAgICAgICAgIHN0YXJ0WSxcbiAgICAgICAgICAgIG1vdXNlT2Zmc2V0LFxuICAgICAgICAgICAgY29sdW1uRWxlbWVudCxcbiAgICAgICAgICAgIGN1cnJlbnRDb2x1bW46IGNvbHVtbkVsZW1lbnQsXG4gICAgICAgICAgICB0YXJnZXRZOiBNYXRoLm1heCgwLCB0YXJnZXRZKSxcbiAgICAgICAgICAgIGN1cnJlbnRZOiBzdGFydFksXG4gICAgICAgICAgICBhbmltYXRpb25JZDogMCxcbiAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogY29sdW1uRWxlbWVudC5kYXRhc2V0LmNvbHVtbktleSB8fCAnJyxcbiAgICAgICAgICAgIGRyYWdTb3VyY2U6ICdncmlkJ1xuICAgICAgICB9O1xuICAgICAgICAvLyBFbWl0IGRyYWc6c3RhcnRcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGV2ZW50SWQsXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgZ2hvc3RFbGVtZW50LFxuICAgICAgICAgICAgc3RhcnRZLFxuICAgICAgICAgICAgbW91c2VPZmZzZXQsXG4gICAgICAgICAgICBjb2x1bW5FbGVtZW50XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfU1RBUlQsIHBheWxvYWQpO1xuICAgICAgICAvLyBTdGFydCBhbmltYXRpb24gbG9vcFxuICAgICAgICB0aGlzLmFuaW1hdGVEcmFnKCk7XG4gICAgfVxuICAgIHVwZGF0ZURyYWdUYXJnZXQoZSkge1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBDaGVjayBoZWFkZXIgem9uZSBmaXJzdFxuICAgICAgICB0aGlzLmNoZWNrSGVhZGVyWm9uZShlKTtcbiAgICAgICAgLy8gU2tpcCBub3JtYWwgZ3JpZCBoYW5kbGluZyBpZiBpbiBoZWFkZXJcbiAgICAgICAgaWYgKHRoaXMuaW5IZWFkZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIENoZWNrIGZvciBjb2x1bW4gY2hhbmdlXG4gICAgICAgIGNvbnN0IGNvbHVtbkF0UG9pbnQgPSB0aGlzLmdldENvbHVtbkF0UG9pbnQoZS5jbGllbnRYKTtcbiAgICAgICAgLy8gRm9yIGhlYWRlciBpdGVtcyBlbnRlcmluZyBncmlkLCBzZXQgaW5pdGlhbCBjb2x1bW5cbiAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlLmRyYWdTb3VyY2UgPT09ICdoZWFkZXInICYmIGNvbHVtbkF0UG9pbnQgJiYgIXRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4pIHtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4gPSBjb2x1bW5BdFBvaW50O1xuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudCA9IGNvbHVtbkF0UG9pbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbHVtbkF0UG9pbnQgJiYgY29sdW1uQXRQb2ludCAhPT0gdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbiAmJiB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uKSB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHRoaXMuZHJhZ1N0YXRlLmV2ZW50SWQsXG4gICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudCxcbiAgICAgICAgICAgICAgICBwcmV2aW91c0NvbHVtbjogdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbixcbiAgICAgICAgICAgICAgICBuZXdDb2x1bW46IGNvbHVtbkF0UG9pbnQsXG4gICAgICAgICAgICAgICAgY3VycmVudFk6IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFLCBwYXlsb2FkKTtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4gPSBjb2x1bW5BdFBvaW50O1xuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudCA9IGNvbHVtbkF0UG9pbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2tpcCBncmlkIHBvc2l0aW9uIHVwZGF0ZXMgaWYgbm8gY29sdW1uIHlldFxuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGNvbHVtblJlY3QgPSB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCB0YXJnZXRZID0gZS5jbGllbnRZIC0gY29sdW1uUmVjdC50b3AgLSB0aGlzLmRyYWdTdGF0ZS5tb3VzZU9mZnNldC55O1xuICAgICAgICB0aGlzLmRyYWdTdGF0ZS50YXJnZXRZID0gTWF0aC5tYXgoMCwgdGFyZ2V0WSk7XG4gICAgICAgIC8vIFN0YXJ0IGFuaW1hdGlvbiBpZiBub3QgcnVubmluZ1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlLmFuaW1hdGlvbklkKSB7XG4gICAgICAgICAgICB0aGlzLmFuaW1hdGVEcmFnKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgcG9pbnRlciBpcyBpbiBoZWFkZXIgem9uZSBhbmQgZW1pdCBhcHByb3ByaWF0ZSBldmVudHNcbiAgICAgKi9cbiAgICBjaGVja0hlYWRlclpvbmUoZSkge1xuICAgICAgICBpZiAoIXRoaXMuZHJhZ1N0YXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCBoZWFkZXJWaWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItdmlld3BvcnQnKTtcbiAgICAgICAgaWYgKCFoZWFkZXJWaWV3cG9ydClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgcmVjdCA9IGhlYWRlclZpZXdwb3J0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCBpc0luSGVhZGVyID0gZS5jbGllbnRZIDwgcmVjdC5ib3R0b207XG4gICAgICAgIGlmIChpc0luSGVhZGVyICYmICF0aGlzLmluSGVhZGVyKSB7XG4gICAgICAgICAgICAvLyBFbnRlcmVkIGhlYWRlciAoZnJvbSBncmlkKVxuICAgICAgICAgICAgdGhpcy5pbkhlYWRlciA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGhpcy5kcmFnU3RhdGUuZHJhZ1NvdXJjZSA9PT0gJ2dyaWQnICYmIHRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICBldmVudElkOiB0aGlzLmRyYWdTdGF0ZS5ldmVudElkLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VDb2x1bW5JbmRleDogdGhpcy5nZXRDb2x1bW5JbmRleCh0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50KSxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlQ29sdW1uS2V5OiB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50LmRhdGFzZXQuY29sdW1uS2V5IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogdGhpcy5kcmFnU3RhdGUuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnQtdGl0bGUnKT8udGV4dENvbnRlbnQgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yQ2xhc3M6IFsuLi50aGlzLmRyYWdTdGF0ZS5lbGVtZW50LmNsYXNzTGlzdF0uZmluZChjID0+IGMuc3RhcnRzV2l0aCgnaXMtJykpLFxuICAgICAgICAgICAgICAgICAgICBpdGVtVHlwZTogJ2V2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDFcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfRU5URVJfSEVBREVSLCBwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEZvciBoZWFkZXIgc291cmNlIHJlLWVudGVyaW5nIGhlYWRlciwganVzdCB1cGRhdGUgaW5IZWFkZXIgZmxhZ1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFpc0luSGVhZGVyICYmIHRoaXMuaW5IZWFkZXIpIHtcbiAgICAgICAgICAgIC8vIExlZnQgaGVhZGVyIChlbnRlcmluZyBncmlkKVxuICAgICAgICAgICAgdGhpcy5pbkhlYWRlciA9IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0Q29sdW1uID0gdGhpcy5nZXRDb2x1bW5BdFBvaW50KGUuY2xpZW50WCk7XG4gICAgICAgICAgICBpZiAodGhpcy5kcmFnU3RhdGUuZHJhZ1NvdXJjZSA9PT0gJ2hlYWRlcicpIHtcbiAgICAgICAgICAgICAgICAvLyBIZWFkZXIgaXRlbSBsZWF2aW5nIGhlYWRlciBcdTIxOTIgY3JlYXRlIHN3cC1ldmVudCBpbiBncmlkXG4gICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRJZDogdGhpcy5kcmFnU3RhdGUuZXZlbnRJZCxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiAnaGVhZGVyJyxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q29sdW1uOiB0YXJnZXRDb2x1bW4gfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBzdGFydDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudC5kYXRhc2V0LnN0YXJ0ID8gbmV3IERhdGUodGhpcy5kcmFnU3RhdGUuZWxlbWVudC5kYXRhc2V0LnN0YXJ0KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZW5kOiB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LmRhdGFzZXQuZW5kID8gbmV3IERhdGUodGhpcy5kcmFnU3RhdGUuZWxlbWVudC5kYXRhc2V0LmVuZCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LnRleHRDb250ZW50IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICBjb2xvckNsYXNzOiBbLi4udGhpcy5kcmFnU3RhdGUuZWxlbWVudC5jbGFzc0xpc3RdLmZpbmQoYyA9PiBjLnN0YXJ0c1dpdGgoJ2lzLScpKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19MRUFWRV9IRUFERVIsIHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIC8vIFJlLWF0dGFjaCB0byB0aGUgbmV3IHN3cC1ldmVudCBjcmVhdGVkIGJ5IEV2ZW50UmVuZGVyZXJcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Q29sdW1uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0VsZW1lbnQgPSB0YXJnZXRDb2x1bW4ucXVlcnlTZWxlY3Rvcihgc3dwLWV2ZW50W2RhdGEtZXZlbnQtaWQ9XCIke3RoaXMuZHJhZ1N0YXRlLmV2ZW50SWR9XCJdYCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXdFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50ID0gbmV3RWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQgPSB0YXJnZXRDb2x1bW47XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uID0gdGFyZ2V0Q29sdW1uO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RhcnQgYW5pbWF0aW9uIGZvciB0aGUgbmV3IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYW5pbWF0ZURyYWcoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEdyaWQgZXZlbnQgbGVhdmluZyBoZWFkZXIgXHUyMTkyIHJlc3RvcmUgdG8gZ3JpZFxuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHRoaXMuZHJhZ1N0YXRlLmV2ZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogJ2dyaWQnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0xFQVZFX0hFQURFUiwgcGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNJbkhlYWRlcikge1xuICAgICAgICAgICAgLy8gTW92aW5nIHdpdGhpbiBoZWFkZXJcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uQXRYKGUuY2xpZW50WCk7XG4gICAgICAgICAgICBpZiAoY29sdW1uKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRJZDogdGhpcy5kcmFnU3RhdGUuZXZlbnRJZCxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uSW5kZXg6IHRoaXMuZ2V0Q29sdW1uSW5kZXgoY29sdW1uKSxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uS2V5OiBjb2x1bW4uZGF0YXNldC5jb2x1bW5LZXkgfHwgJydcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfTU9WRV9IRUFERVIsIHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBjb2x1bW4gaW5kZXggKDAtYmFzZWQpIGZvciBhIGNvbHVtbiBlbGVtZW50XG4gICAgICovXG4gICAgZ2V0Q29sdW1uSW5kZXgoY29sdW1uKSB7XG4gICAgICAgIGlmICghdGhpcy5jb250YWluZXIgfHwgIWNvbHVtbilcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gQXJyYXkuZnJvbSh0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCdzd3AtZGF5LWNvbHVtbicpKTtcbiAgICAgICAgcmV0dXJuIGNvbHVtbnMuaW5kZXhPZihjb2x1bW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY29sdW1uIGF0IFggY29vcmRpbmF0ZSAoYWxpYXMgZm9yIGdldENvbHVtbkF0UG9pbnQpXG4gICAgICovXG4gICAgZ2V0Q29sdW1uQXRYKGNsaWVudFgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29sdW1uQXRQb2ludChjbGllbnRYKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBjb2x1bW4gZWxlbWVudCBhdCBnaXZlbiBYIGNvb3JkaW5hdGVcbiAgICAgKi9cbiAgICBnZXRDb2x1bW5BdFBvaW50KGNsaWVudFgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcilcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgZm9yIChjb25zdCBjb2wgb2YgY29sdW1ucykge1xuICAgICAgICAgICAgY29uc3QgcmVjdCA9IGNvbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIGlmIChjbGllbnRYID49IHJlY3QubGVmdCAmJiBjbGllbnRYIDw9IHJlY3QucmlnaHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZHJhZyBhbmQgYW5pbWF0ZSBiYWNrIHRvIHN0YXJ0IHBvc2l0aW9uXG4gICAgICovXG4gICAgY2FuY2VsRHJhZygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gU3RvcCBhbmltYXRpb25cbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5kcmFnU3RhdGUuYW5pbWF0aW9uSWQpO1xuICAgICAgICBjb25zdCB7IGVsZW1lbnQsIGdob3N0RWxlbWVudCwgc3RhcnRZLCBldmVudElkIH0gPSB0aGlzLmRyYWdTdGF0ZTtcbiAgICAgICAgLy8gQW5pbWF0ZSBiYWNrIHRvIHN0YXJ0XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbiA9ICd0b3AgMjAwbXMgZWFzZS1vdXQnO1xuICAgICAgICBlbGVtZW50LnN0eWxlLnRvcCA9IGAke3N0YXJ0WX1weGA7XG4gICAgICAgIC8vIFJlbW92ZSBnaG9zdCBhZnRlciBhbmltYXRpb24gKGlmIGV4aXN0cylcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBnaG9zdEVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2l0aW9uID0gJyc7XG4gICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2RyYWdnaW5nJyk7XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICAgIC8vIEVtaXQgZHJhZzpjYW5jZWxcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGV2ZW50SWQsXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgc3RhcnRZXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfQ0FOQ0VMLCBwYXlsb2FkKTtcbiAgICAgICAgdGhpcy5kcmFnU3RhdGUgPSBudWxsO1xuICAgICAgICB0aGlzLmluSGVhZGVyID0gZmFsc2U7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG5leHBvcnQgY2xhc3MgRWRnZVNjcm9sbE1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50QnVzKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5zY3JvbGxhYmxlQ29udGVudCA9IG51bGw7XG4gICAgICAgIHRoaXMudGltZUdyaWQgPSBudWxsO1xuICAgICAgICB0aGlzLmRyYWdnZWRFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5zY3JvbGxSQUYgPSBudWxsO1xuICAgICAgICB0aGlzLm1vdXNlWSA9IDA7XG4gICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGFzdFRzID0gMDtcbiAgICAgICAgdGhpcy5yZWN0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbml0aWFsU2Nyb2xsVG9wID0gMDtcbiAgICAgICAgdGhpcy5PVVRFUl9aT05FID0gMTAwO1xuICAgICAgICB0aGlzLklOTkVSX1pPTkUgPSA1MDtcbiAgICAgICAgdGhpcy5TTE9XX1NQRUVEID0gMTQwO1xuICAgICAgICB0aGlzLkZBU1RfU1BFRUQgPSA2NDA7XG4gICAgICAgIHRoaXMudHJhY2tNb3VzZSA9IChlKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb3VzZVkgPSBlLmNsaWVudFk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2Nyb2xsVGljayA9ICh0cykgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcgfHwgIXRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgZHQgPSB0aGlzLmxhc3RUcyA/ICh0cyAtIHRoaXMubGFzdFRzKSAvIDEwMDAgOiAwO1xuICAgICAgICAgICAgdGhpcy5sYXN0VHMgPSB0cztcbiAgICAgICAgICAgIHRoaXMucmVjdCA/PyAodGhpcy5yZWN0ID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XG4gICAgICAgICAgICBjb25zdCB2ZWxvY2l0eSA9IHRoaXMuY2FsY3VsYXRlVmVsb2NpdHkoKTtcbiAgICAgICAgICAgIGlmICh2ZWxvY2l0eSAhPT0gMCAmJiAhdGhpcy5pc0F0Qm91bmRhcnkodmVsb2NpdHkpKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsRGVsdGEgPSB2ZWxvY2l0eSAqIGR0O1xuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQuc2Nyb2xsVG9wICs9IHNjcm9sbERlbHRhO1xuICAgICAgICAgICAgICAgIHRoaXMucmVjdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRURHRV9TQ1JPTExfVElDSywgeyBzY3JvbGxEZWx0YSB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNjcm9sbGluZ1N0YXRlKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY3JvbGxpbmdTdGF0ZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNjcm9sbFJBRiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnNjcm9sbFRpY2spO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnN1YnNjcmliZVRvRXZlbnRzKCk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy50cmFja01vdXNlKTtcbiAgICB9XG4gICAgaW5pdChzY3JvbGxhYmxlQ29udGVudCkge1xuICAgICAgICB0aGlzLnNjcm9sbGFibGVDb250ZW50ID0gc2Nyb2xsYWJsZUNvbnRlbnQ7XG4gICAgICAgIHRoaXMudGltZUdyaWQgPSBzY3JvbGxhYmxlQ29udGVudC5xdWVyeVNlbGVjdG9yKCdzd3AtdGltZS1ncmlkJyk7XG4gICAgICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAnYXV0byc7XG4gICAgfVxuICAgIHN1YnNjcmliZVRvRXZlbnRzKCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19TVEFSVCwgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZXZlbnQuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5kcmFnZ2VkRWxlbWVudCA9IHBheWxvYWQuZWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMuc3RhcnREcmFnKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19FTkQsICgpID0+IHRoaXMuc3RvcERyYWcoKSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0NBTkNFTCwgKCkgPT4gdGhpcy5zdG9wRHJhZygpKTtcbiAgICB9XG4gICAgc3RhcnREcmFnKCkge1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGFzdFRzID0gMDtcbiAgICAgICAgdGhpcy5pbml0aWFsU2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudD8uc2Nyb2xsVG9wID8/IDA7XG4gICAgICAgIGlmICh0aGlzLnNjcm9sbFJBRiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxSQUYgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5zY3JvbGxUaWNrKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdG9wRHJhZygpIHtcbiAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2V0U2Nyb2xsaW5nU3RhdGUoZmFsc2UpO1xuICAgICAgICBpZiAodGhpcy5zY3JvbGxSQUYgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuc2Nyb2xsUkFGKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsUkFGID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlY3QgPSBudWxsO1xuICAgICAgICB0aGlzLmxhc3RUcyA9IDA7XG4gICAgICAgIHRoaXMuaW5pdGlhbFNjcm9sbFRvcCA9IDA7XG4gICAgfVxuICAgIGNhbGN1bGF0ZVZlbG9jaXR5KCkge1xuICAgICAgICBpZiAoIXRoaXMucmVjdClcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICBjb25zdCBkaXN0VG9wID0gdGhpcy5tb3VzZVkgLSB0aGlzLnJlY3QudG9wO1xuICAgICAgICBjb25zdCBkaXN0Qm90ID0gdGhpcy5yZWN0LmJvdHRvbSAtIHRoaXMubW91c2VZO1xuICAgICAgICBpZiAoZGlzdFRvcCA8IHRoaXMuSU5ORVJfWk9ORSlcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy5GQVNUX1NQRUVEO1xuICAgICAgICBpZiAoZGlzdFRvcCA8IHRoaXMuT1VURVJfWk9ORSlcbiAgICAgICAgICAgIHJldHVybiAtdGhpcy5TTE9XX1NQRUVEO1xuICAgICAgICBpZiAoZGlzdEJvdCA8IHRoaXMuSU5ORVJfWk9ORSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLkZBU1RfU1BFRUQ7XG4gICAgICAgIGlmIChkaXN0Qm90IDwgdGhpcy5PVVRFUl9aT05FKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuU0xPV19TUEVFRDtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGlzQXRCb3VuZGFyeSh2ZWxvY2l0eSkge1xuICAgICAgICBpZiAoIXRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQgfHwgIXRoaXMudGltZUdyaWQgfHwgIXRoaXMuZHJhZ2dlZEVsZW1lbnQpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IGF0VG9wID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudC5zY3JvbGxUb3AgPD0gMCAmJiB2ZWxvY2l0eSA8IDA7XG4gICAgICAgIGNvbnN0IGF0Qm90dG9tID0gdmVsb2NpdHkgPiAwICYmXG4gICAgICAgICAgICB0aGlzLmRyYWdnZWRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmJvdHRvbSA+PVxuICAgICAgICAgICAgICAgIHRoaXMudGltZUdyaWQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tO1xuICAgICAgICByZXR1cm4gYXRUb3AgfHwgYXRCb3R0b207XG4gICAgfVxuICAgIHNldFNjcm9sbGluZ1N0YXRlKHNjcm9sbGluZykge1xuICAgICAgICBpZiAodGhpcy5pc1Njcm9sbGluZyA9PT0gc2Nyb2xsaW5nKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aGlzLmlzU2Nyb2xsaW5nID0gc2Nyb2xsaW5nO1xuICAgICAgICBpZiAoc2Nyb2xsaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FREdFX1NDUk9MTF9TVEFSVEVELCB7fSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxTY3JvbGxUb3AgPSB0aGlzLnNjcm9sbGFibGVDb250ZW50Py5zY3JvbGxUb3AgPz8gMDtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVER0VfU0NST0xMX1NUT1BQRUQsIHt9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBwaXhlbHNUb01pbnV0ZXMsIG1pbnV0ZXNUb1BpeGVscywgc25hcFRvR3JpZCB9IGZyb20gJy4uL3V0aWxzL1Bvc2l0aW9uVXRpbHMnO1xuaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcbmltcG9ydCB7IFN3cEV2ZW50IH0gZnJvbSAnLi4vdHlwZXMvU3dwRXZlbnQnO1xuZXhwb3J0IGNsYXNzIFJlc2l6ZU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50QnVzLCBncmlkQ29uZmlnLCBkYXRlU2VydmljZSkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzID0gZXZlbnRCdXM7XG4gICAgICAgIHRoaXMuZ3JpZENvbmZpZyA9IGdyaWRDb25maWc7XG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2UgPSBkYXRlU2VydmljZTtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBudWxsO1xuICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy5aX0lOREVYX1JFU0laSU5HID0gJzEwMDAnO1xuICAgICAgICB0aGlzLkFOSU1BVElPTl9TUEVFRCA9IDAuMzU7XG4gICAgICAgIHRoaXMuTUlOX0hFSUdIVF9NSU5VVEVTID0gMTU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGUgbW91c2VvdmVyIC0gY3JlYXRlIHJlc2l6ZSBoYW5kbGUgaWYgbm90IGV4aXN0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVNb3VzZU92ZXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgICAgICAgICBjb25zdCBldmVudEVsZW1lbnQgPSB0YXJnZXQuY2xvc2VzdCgnc3dwLWV2ZW50Jyk7XG4gICAgICAgICAgICBpZiAoIWV2ZW50RWxlbWVudCB8fCB0aGlzLnJlc2l6ZVN0YXRlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGhhbmRsZSBhbHJlYWR5IGV4aXN0c1xuICAgICAgICAgICAgaWYgKCFldmVudEVsZW1lbnQucXVlcnlTZWxlY3RvcignOnNjb3BlID4gc3dwLXJlc2l6ZS1oYW5kbGUnKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IHRoaXMuY3JlYXRlUmVzaXplSGFuZGxlKCk7XG4gICAgICAgICAgICAgICAgZXZlbnRFbGVtZW50LmFwcGVuZENoaWxkKGhhbmRsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBIYW5kbGUgcG9pbnRlcmRvd24gLSBzdGFydCByZXNpemUgaWYgb24gaGFuZGxlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGUudGFyZ2V0LmNsb3Nlc3QoJ3N3cC1yZXNpemUtaGFuZGxlJyk7XG4gICAgICAgICAgICBpZiAoIWhhbmRsZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gaGFuZGxlLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgZXZlbnRJZCA9IGVsZW1lbnQuZGF0YXNldC5ldmVudElkIHx8ICcnO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRIZWlnaHQgPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0RHVyYXRpb25NaW51dGVzID0gcGl4ZWxzVG9NaW51dGVzKHN0YXJ0SGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAgICAgLy8gU3RvcmUgcHJldmlvdXMgei1pbmRleFxuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gZWxlbWVudC5jbG9zZXN0KCdzd3AtZXZlbnQtZ3JvdXAnKSA/PyBlbGVtZW50O1xuICAgICAgICAgICAgY29uc3QgcHJldlpJbmRleCA9IGNvbnRhaW5lci5zdHlsZS56SW5kZXg7XG4gICAgICAgICAgICAvLyBTZXQgcmVzaXplIHN0YXRlXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50SWQsXG4gICAgICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgICAgICBoYW5kbGVFbGVtZW50OiBoYW5kbGUsXG4gICAgICAgICAgICAgICAgc3RhcnRZOiBlLmNsaWVudFksXG4gICAgICAgICAgICAgICAgc3RhcnRIZWlnaHQsXG4gICAgICAgICAgICAgICAgc3RhcnREdXJhdGlvbk1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgcG9pbnRlcklkOiBlLnBvaW50ZXJJZCxcbiAgICAgICAgICAgICAgICBwcmV2WkluZGV4LFxuICAgICAgICAgICAgICAgIC8vIEFuaW1hdGlvbiBzdGF0ZVxuICAgICAgICAgICAgICAgIGN1cnJlbnRIZWlnaHQ6IHN0YXJ0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIHRhcmdldEhlaWdodDogc3RhcnRIZWlnaHQsXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uSWQ6IG51bGxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBFbGV2YXRlIHotaW5kZXhcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS56SW5kZXggPSB0aGlzLlpfSU5ERVhfUkVTSVpJTkc7XG4gICAgICAgICAgICAvLyBDYXB0dXJlIHBvaW50ZXIgZm9yIHNtb290aCB0cmFja2luZ1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBoYW5kbGUuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUG9pbnRlciBjYXB0dXJlIGZhaWxlZDonLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQWRkIGdsb2JhbCByZXNpemluZyBjbGFzc1xuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3N3cC0tcmVzaXppbmcnKTtcbiAgICAgICAgICAgIC8vIEVtaXQgcmVzaXplIHN0YXJ0IGV2ZW50XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9SRVNJWkVfU1RBUlQsIHtcbiAgICAgICAgICAgICAgICBldmVudElkLFxuICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgc3RhcnRIZWlnaHRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIHBvaW50ZXJtb3ZlIC0gdXBkYXRlIHRhcmdldCBoZWlnaHQgZHVyaW5nIHJlc2l6ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZSA9IChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplU3RhdGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFZID0gZS5jbGllbnRZIC0gdGhpcy5yZXNpemVTdGF0ZS5zdGFydFk7XG4gICAgICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSAodGhpcy5NSU5fSEVJR0hUX01JTlVURVMgLyA2MCkgKiB0aGlzLmdyaWRDb25maWcuaG91ckhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KG1pbkhlaWdodCwgdGhpcy5yZXNpemVTdGF0ZS5zdGFydEhlaWdodCArIGRlbHRhWSk7XG4gICAgICAgICAgICAvLyBTZXQgdGFyZ2V0IGhlaWdodCBmb3IgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlLnRhcmdldEhlaWdodCA9IG5ld0hlaWdodDtcbiAgICAgICAgICAgIC8vIFN0YXJ0IGFuaW1hdGlvbiBpZiBub3QgcnVubmluZ1xuICAgICAgICAgICAgaWYgKHRoaXMucmVzaXplU3RhdGUuYW5pbWF0aW9uSWQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFuaW1hdGVIZWlnaHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJBRiBhbmltYXRpb24gbG9vcCBmb3Igc21vb3RoIGhlaWdodCBpbnRlcnBvbGF0aW9uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFuaW1hdGVIZWlnaHQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplU3RhdGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgZGlmZiA9IHRoaXMucmVzaXplU3RhdGUudGFyZ2V0SGVpZ2h0IC0gdGhpcy5yZXNpemVTdGF0ZS5jdXJyZW50SGVpZ2h0O1xuICAgICAgICAgICAgLy8gU3RvcCBhbmltYXRpb24gd2hlbiBjbG9zZSBlbm91Z2hcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhkaWZmKSA8IDAuNSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplU3RhdGUuYW5pbWF0aW9uSWQgPSBudWxsO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEludGVycG9sYXRlIHRvd2FyZHMgdGFyZ2V0ICgzNSUgcGVyIGZyYW1lIGxpa2UgVjEpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlLmN1cnJlbnRIZWlnaHQgKz0gZGlmZiAqIHRoaXMuQU5JTUFUSU9OX1NQRUVEO1xuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3RoaXMucmVzaXplU3RhdGUuY3VycmVudEhlaWdodH1weGA7XG4gICAgICAgICAgICAvLyBVcGRhdGUgdGltZXN0YW1wIGRpc3BsYXkgKHNuYXBwZWQpXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVRpbWVzdGFtcERpc3BsYXkoKTtcbiAgICAgICAgICAgIC8vIENvbnRpbnVlIGFuaW1hdGlvblxuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5hbmltYXRpb25JZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGVIZWlnaHQpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIHBvaW50ZXJ1cCAtIGZpbmlzaCByZXNpemVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlclVwID0gKGUpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5yZXNpemVTdGF0ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBDYW5jZWwgYW55IHBlbmRpbmcgYW5pbWF0aW9uXG4gICAgICAgICAgICBpZiAodGhpcy5yZXNpemVTdGF0ZS5hbmltYXRpb25JZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMucmVzaXplU3RhdGUuYW5pbWF0aW9uSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVsZWFzZSBwb2ludGVyIGNhcHR1cmVcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5oYW5kbGVFbGVtZW50LnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQb2ludGVyIHJlbGVhc2UgZmFpbGVkOicsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBTbmFwIGZpbmFsIGhlaWdodCB0byBncmlkXG4gICAgICAgICAgICB0aGlzLnNuYXBUb0dyaWRGaW5hbCgpO1xuICAgICAgICAgICAgLy8gVXBkYXRlIHRpbWVzdGFtcCBvbmUgZmluYWwgdGltZVxuICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lc3RhbXBEaXNwbGF5KCk7XG4gICAgICAgICAgICAvLyBSZXN0b3JlIHotaW5kZXhcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMucmVzaXplU3RhdGUuZWxlbWVudC5jbG9zZXN0KCdzd3AtZXZlbnQtZ3JvdXAnKSA/PyB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQ7XG4gICAgICAgICAgICBjb250YWluZXIuc3R5bGUuekluZGV4ID0gdGhpcy5yZXNpemVTdGF0ZS5wcmV2WkluZGV4O1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGdsb2JhbCByZXNpemluZyBjbGFzc1xuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ3N3cC0tcmVzaXppbmcnKTtcbiAgICAgICAgICAgIC8vIEdldCBjb2x1bW5LZXkgYW5kIGRhdGUgZnJvbSBwYXJlbnQgY29sdW1uXG4gICAgICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQuY2xvc2VzdCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbktleSA9IGNvbHVtbj8uZGF0YXNldC5jb2x1bW5LZXkgfHwgJyc7XG4gICAgICAgICAgICBjb25zdCBkYXRlID0gY29sdW1uPy5kYXRhc2V0LmRhdGUgfHwgJyc7XG4gICAgICAgICAgICAvLyBDcmVhdGUgU3dwRXZlbnQgZnJvbSBlbGVtZW50IChyZWFkcyB0b3AvaGVpZ2h0L2V2ZW50SWQgZnJvbSBlbGVtZW50KVxuICAgICAgICAgICAgY29uc3Qgc3dwRXZlbnQgPSBTd3BFdmVudC5mcm9tRWxlbWVudCh0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQsIGNvbHVtbktleSwgZGF0ZSwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgIC8vIEVtaXQgcmVzaXplIGVuZCBldmVudFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfUkVTSVpFX0VORCwge1xuICAgICAgICAgICAgICAgIHN3cEV2ZW50XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFJlc2V0IHN0YXRlXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlID0gbnVsbDtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSByZXNpemUgZnVuY3Rpb25hbGl0eSBvbiBjb250YWluZXJcbiAgICAgKi9cbiAgICBpbml0KGNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgLy8gTW91c2VvdmVyIGxpc3RlbmVyIGZvciBoYW5kbGUgY3JlYXRpb24gKGNhcHR1cmUgcGhhc2UgbGlrZSBWMSlcbiAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsIHRoaXMuaGFuZGxlTW91c2VPdmVyLCB0cnVlKTtcbiAgICAgICAgLy8gUG9pbnRlciBsaXN0ZW5lcnMgZm9yIHJlc2l6ZSAoY2FwdHVyZSBwaGFzZSBsaWtlIFYxKVxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMuaGFuZGxlUG9pbnRlckRvd24sIHRydWUpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMuaGFuZGxlUG9pbnRlck1vdmUsIHRydWUpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCB0aGlzLmhhbmRsZVBvaW50ZXJVcCwgdHJ1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSByZXNpemUgaGFuZGxlIGVsZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVSZXNpemVIYW5kbGUoKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1yZXNpemUtaGFuZGxlJyk7XG4gICAgICAgIGhhbmRsZS5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCAnUmVzaXplIGV2ZW50Jyk7XG4gICAgICAgIGhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnc2VwYXJhdG9yJyk7XG4gICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aW1lc3RhbXAgZGlzcGxheSB3aXRoIHNuYXBwZWQgZW5kIHRpbWVcbiAgICAgKi9cbiAgICB1cGRhdGVUaW1lc3RhbXBEaXNwbGF5KCkge1xuICAgICAgICBpZiAoIXRoaXMucmVzaXplU3RhdGUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IHRpbWVFbCA9IHRoaXMucmVzaXplU3RhdGUuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnQtdGltZScpO1xuICAgICAgICBpZiAoIXRpbWVFbClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gR2V0IHN0YXJ0IHRpbWUgZnJvbSBlbGVtZW50IHBvc2l0aW9uXG4gICAgICAgIGNvbnN0IHRvcCA9IHBhcnNlRmxvYXQodGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50LnN0eWxlLnRvcCkgfHwgMDtcbiAgICAgICAgY29uc3Qgc3RhcnRNaW51dGVzRnJvbUdyaWQgPSBwaXhlbHNUb01pbnV0ZXModG9wLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICBjb25zdCBzdGFydE1pbnV0ZXMgPSAodGhpcy5ncmlkQ29uZmlnLmRheVN0YXJ0SG91ciAqIDYwKSArIHN0YXJ0TWludXRlc0Zyb21HcmlkO1xuICAgICAgICAvLyBDYWxjdWxhdGUgc25hcHBlZCBlbmQgdGltZSBmcm9tIGN1cnJlbnQgaGVpZ2h0XG4gICAgICAgIGNvbnN0IHNuYXBwZWRIZWlnaHQgPSBzbmFwVG9HcmlkKHRoaXMucmVzaXplU3RhdGUuY3VycmVudEhlaWdodCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgY29uc3QgZHVyYXRpb25NaW51dGVzID0gcGl4ZWxzVG9NaW51dGVzKHNuYXBwZWRIZWlnaHQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGNvbnN0IGVuZE1pbnV0ZXMgPSBzdGFydE1pbnV0ZXMgKyBkdXJhdGlvbk1pbnV0ZXM7XG4gICAgICAgIC8vIEZvcm1hdCBhbmQgdXBkYXRlXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyk7XG4gICAgICAgIGNvbnN0IGVuZCA9IHRoaXMubWludXRlc1RvRGF0ZShlbmRNaW51dGVzKTtcbiAgICAgICAgdGltZUVsLnRleHRDb250ZW50ID0gdGhpcy5kYXRlU2VydmljZS5mb3JtYXRUaW1lUmFuZ2Uoc3RhcnQsIGVuZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgbWludXRlcyBzaW5jZSBtaWRuaWdodCB0byBEYXRlXG4gICAgICovXG4gICAgbWludXRlc1RvRGF0ZShtaW51dGVzKSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBkYXRlLnNldEhvdXJzKE1hdGguZmxvb3IobWludXRlcyAvIDYwKSAlIDI0LCBtaW51dGVzICUgNjAsIDAsIDApO1xuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG4gICAgO1xuICAgIC8qKlxuICAgICAqIFNuYXAgZmluYWwgaGVpZ2h0IHRvIGdyaWQgaW50ZXJ2YWxcbiAgICAgKi9cbiAgICBzbmFwVG9HcmlkRmluYWwoKSB7XG4gICAgICAgIGlmICghdGhpcy5yZXNpemVTdGF0ZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgY3VycmVudEhlaWdodCA9IHRoaXMucmVzaXplU3RhdGUuZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIGNvbnN0IHNuYXBwZWRIZWlnaHQgPSBzbmFwVG9HcmlkKGN1cnJlbnRIZWlnaHQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGNvbnN0IG1pbkhlaWdodCA9IG1pbnV0ZXNUb1BpeGVscyh0aGlzLk1JTl9IRUlHSFRfTUlOVVRFUywgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgY29uc3QgZmluYWxIZWlnaHQgPSBNYXRoLm1heChtaW5IZWlnaHQsIHNuYXBwZWRIZWlnaHQpO1xuICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7ZmluYWxIZWlnaHR9cHhgO1xuICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlLmN1cnJlbnRIZWlnaHQgPSBmaW5hbEhlaWdodDtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcbmV4cG9ydCBjbGFzcyBFdmVudFBlcnNpc3RlbmNlTWFuYWdlciB7XG4gICAgY29uc3RydWN0b3IoZXZlbnRTZXJ2aWNlLCBldmVudEJ1cywgZGF0ZVNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5ldmVudFNlcnZpY2UgPSBldmVudFNlcnZpY2U7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIGRyYWcgZW5kIC0gdXBkYXRlIGV2ZW50IHBvc2l0aW9uIGluIEluZGV4ZWREQlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kID0gYXN5bmMgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIGNvbnN0IHsgc3dwRXZlbnQgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICAvLyBHZXQgZXhpc3RpbmcgZXZlbnQgdG8gbWVyZ2Ugd2l0aFxuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXQoc3dwRXZlbnQuZXZlbnRJZCk7XG4gICAgICAgICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBFdmVudFBlcnNpc3RlbmNlTWFuYWdlcjogRXZlbnQgJHtzd3BFdmVudC5ldmVudElkfSBub3QgZm91bmRgKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBQYXJzZSByZXNvdXJjZUlkIGZyb20gY29sdW1uS2V5IGlmIHByZXNlbnRcbiAgICAgICAgICAgIGNvbnN0IHsgcmVzb3VyY2UgfSA9IHRoaXMuZGF0ZVNlcnZpY2UucGFyc2VDb2x1bW5LZXkoc3dwRXZlbnQuY29sdW1uS2V5KTtcbiAgICAgICAgICAgIC8vIFVwZGF0ZSBhbmQgc2F2ZSAtIHN0YXJ0L2VuZCBhbHJlYWR5IGNhbGN1bGF0ZWQgaW4gU3dwRXZlbnRcbiAgICAgICAgICAgIC8vIFNldCBhbGxEYXkgYmFzZWQgb24gZHJvcCB0YXJnZXQ6XG4gICAgICAgICAgICAvLyAtIGhlYWRlcjogYWxsRGF5ID0gdHJ1ZVxuICAgICAgICAgICAgLy8gLSBncmlkOiBhbGxEYXkgPSBmYWxzZSAoY29udmVydHMgYWxsRGF5IGV2ZW50IHRvIHRpbWVkKVxuICAgICAgICAgICAgY29uc3QgdXBkYXRlZEV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIC4uLmV2ZW50LFxuICAgICAgICAgICAgICAgIHN0YXJ0OiBzd3BFdmVudC5zdGFydCxcbiAgICAgICAgICAgICAgICBlbmQ6IHN3cEV2ZW50LmVuZCxcbiAgICAgICAgICAgICAgICByZXNvdXJjZUlkOiByZXNvdXJjZSA/PyBldmVudC5yZXNvdXJjZUlkLFxuICAgICAgICAgICAgICAgIGFsbERheTogcGF5bG9hZC50YXJnZXQgPT09ICdoZWFkZXInLFxuICAgICAgICAgICAgICAgIHN5bmNTdGF0dXM6ICdwZW5kaW5nJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXZlbnRTZXJ2aWNlLnNhdmUodXBkYXRlZEV2ZW50KTtcbiAgICAgICAgICAgIC8vIEVtaXQgRVZFTlRfVVBEQVRFRCBmb3IgRXZlbnRSZW5kZXJlciB0byByZS1yZW5kZXIgYWZmZWN0ZWQgY29sdW1uc1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlUGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICBldmVudElkOiB1cGRhdGVkRXZlbnQuaWQsXG4gICAgICAgICAgICAgICAgc291cmNlQ29sdW1uS2V5OiBwYXlsb2FkLnNvdXJjZUNvbHVtbktleSxcbiAgICAgICAgICAgICAgICB0YXJnZXRDb2x1bW5LZXk6IHN3cEV2ZW50LmNvbHVtbktleVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX1VQREFURUQsIHVwZGF0ZVBheWxvYWQpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIHJlc2l6ZSBlbmQgLSB1cGRhdGUgZXZlbnQgZHVyYXRpb24gaW4gSW5kZXhlZERCXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhbmRsZVJlc2l6ZUVuZCA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICBjb25zdCB7IHN3cEV2ZW50IH0gPSBwYXlsb2FkO1xuICAgICAgICAgICAgLy8gR2V0IGV4aXN0aW5nIGV2ZW50IHRvIG1lcmdlIHdpdGhcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0KHN3cEV2ZW50LmV2ZW50SWQpO1xuICAgICAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXI6IEV2ZW50ICR7c3dwRXZlbnQuZXZlbnRJZH0gbm90IGZvdW5kYCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVXBkYXRlIGFuZCBzYXZlIC0gZW5kIGFscmVhZHkgY2FsY3VsYXRlZCBpbiBTd3BFdmVudFxuICAgICAgICAgICAgY29uc3QgdXBkYXRlZEV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIC4uLmV2ZW50LFxuICAgICAgICAgICAgICAgIGVuZDogc3dwRXZlbnQuZW5kLFxuICAgICAgICAgICAgICAgIHN5bmNTdGF0dXM6ICdwZW5kaW5nJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZXZlbnRTZXJ2aWNlLnNhdmUodXBkYXRlZEV2ZW50KTtcbiAgICAgICAgICAgIC8vIEVtaXQgRVZFTlRfVVBEQVRFRCBmb3IgRXZlbnRSZW5kZXJlciB0byByZS1yZW5kZXIgdGhlIGNvbHVtblxuICAgICAgICAgICAgLy8gUmVzaXplIHN0YXlzIGluIHNhbWUgY29sdW1uLCBzbyBzb3VyY2UgYW5kIHRhcmdldCBhcmUgdGhlIHNhbWVcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgZXZlbnRJZDogdXBkYXRlZEV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogc3dwRXZlbnQuY29sdW1uS2V5LFxuICAgICAgICAgICAgICAgIHRhcmdldENvbHVtbktleTogc3dwRXZlbnQuY29sdW1uS2V5XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfVVBEQVRFRCwgdXBkYXRlUGF5bG9hZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0dXBMaXN0ZW5lcnMoKTtcbiAgICB9XG4gICAgc2V0dXBMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgdGhpcy5oYW5kbGVEcmFnRW5kKTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX1JFU0laRV9FTkQsIHRoaXMuaGFuZGxlUmVzaXplRW5kKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ29udGFpbmVyIH0gZnJvbSAnQG5vdmFkaS9jb3JlJztcbmltcG9ydCB7IERhdGVSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXInO1xuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuL2NvcmUvRGF0ZVNlcnZpY2UnO1xuaW1wb3J0IHsgUmVzb3VyY2VSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvcmVzb3VyY2UvUmVzb3VyY2VSZW5kZXJlcic7XG5pbXBvcnQgeyBUZWFtUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL3RlYW0vVGVhbVJlbmRlcmVyJztcbmltcG9ydCB7IERlcGFydG1lbnRSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvZGVwYXJ0bWVudC9EZXBhcnRtZW50UmVuZGVyZXInO1xuaW1wb3J0IHsgQ2FsZW5kYXJPcmNoZXN0cmF0b3IgfSBmcm9tICcuL2NvcmUvQ2FsZW5kYXJPcmNoZXN0cmF0b3InO1xuaW1wb3J0IHsgQ2FsZW5kYXJBcHAgfSBmcm9tICcuL2NvcmUvQ2FsZW5kYXJBcHAnO1xuaW1wb3J0IHsgVGltZUF4aXNSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvdGltZWF4aXMvVGltZUF4aXNSZW5kZXJlcic7XG5pbXBvcnQgeyBTY3JvbGxNYW5hZ2VyIH0gZnJvbSAnLi9jb3JlL1Njcm9sbE1hbmFnZXInO1xuaW1wb3J0IHsgSGVhZGVyRHJhd2VyTWFuYWdlciB9IGZyb20gJy4vY29yZS9IZWFkZXJEcmF3ZXJNYW5hZ2VyJztcbmltcG9ydCB7IE1vY2tUZWFtU3RvcmUsIE1vY2tSZXNvdXJjZVN0b3JlIH0gZnJvbSAnLi9kZW1vL01vY2tTdG9yZXMnO1xuaW1wb3J0IHsgRGVtb0FwcCB9IGZyb20gJy4vZGVtby9EZW1vQXBwJztcbi8vIEV2ZW50IHN5c3RlbVxuaW1wb3J0IHsgRXZlbnRCdXMgfSBmcm9tICcuL2NvcmUvRXZlbnRCdXMnO1xuLy8gU3RvcmFnZVxuaW1wb3J0IHsgSW5kZXhlZERCQ29udGV4dCB9IGZyb20gJy4vc3RvcmFnZS9JbmRleGVkREJDb250ZXh0JztcbmltcG9ydCB7IEV2ZW50U3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvZXZlbnRzL0V2ZW50U3RvcmUnO1xuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL2V2ZW50cy9FdmVudFNlcnZpY2UnO1xuaW1wb3J0IHsgUmVzb3VyY2VTdG9yZSB9IGZyb20gJy4vc3RvcmFnZS9yZXNvdXJjZXMvUmVzb3VyY2VTdG9yZSc7XG5pbXBvcnQgeyBSZXNvdXJjZVNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU2VydmljZSc7XG5pbXBvcnQgeyBCb29raW5nU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvYm9va2luZ3MvQm9va2luZ1N0b3JlJztcbmltcG9ydCB7IEJvb2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL2Jvb2tpbmdzL0Jvb2tpbmdTZXJ2aWNlJztcbmltcG9ydCB7IEN1c3RvbWVyU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvY3VzdG9tZXJzL0N1c3RvbWVyU3RvcmUnO1xuaW1wb3J0IHsgQ3VzdG9tZXJTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL2N1c3RvbWVycy9DdXN0b21lclNlcnZpY2UnO1xuaW1wb3J0IHsgVGVhbVN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL3RlYW1zL1RlYW1TdG9yZSc7XG5pbXBvcnQgeyBUZWFtU2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS90ZWFtcy9UZWFtU2VydmljZSc7XG5pbXBvcnQgeyBEZXBhcnRtZW50U3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvZGVwYXJ0bWVudHMvRGVwYXJ0bWVudFN0b3JlJztcbmltcG9ydCB7IERlcGFydG1lbnRTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL2RlcGFydG1lbnRzL0RlcGFydG1lbnRTZXJ2aWNlJztcbmltcG9ydCB7IFNldHRpbmdzU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2Uvc2V0dGluZ3MvU2V0dGluZ3NTdG9yZSc7XG5pbXBvcnQgeyBTZXR0aW5nc1NlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2Uvc2V0dGluZ3MvU2V0dGluZ3NTZXJ2aWNlJztcbmltcG9ydCB7IFZpZXdDb25maWdTdG9yZSB9IGZyb20gJy4vc3RvcmFnZS92aWV3Y29uZmlncy9WaWV3Q29uZmlnU3RvcmUnO1xuaW1wb3J0IHsgVmlld0NvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2Uvdmlld2NvbmZpZ3MvVmlld0NvbmZpZ1NlcnZpY2UnO1xuLy8gQXVkaXRcbmltcG9ydCB7IEF1ZGl0U3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvYXVkaXQvQXVkaXRTdG9yZSc7XG5pbXBvcnQgeyBBdWRpdFNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2UvYXVkaXQvQXVkaXRTZXJ2aWNlJztcbmltcG9ydCB7IE1vY2tFdmVudFJlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrRXZlbnRSZXBvc2l0b3J5JztcbmltcG9ydCB7IE1vY2tSZXNvdXJjZVJlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrUmVzb3VyY2VSZXBvc2l0b3J5JztcbmltcG9ydCB7IE1vY2tCb29raW5nUmVwb3NpdG9yeSB9IGZyb20gJy4vcmVwb3NpdG9yaWVzL01vY2tCb29raW5nUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrQXVkaXRSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja0F1ZGl0UmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrVGVhbVJlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrVGVhbVJlcG9zaXRvcnknO1xuaW1wb3J0IHsgTW9ja0RlcGFydG1lbnRSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja0RlcGFydG1lbnRSZXBvc2l0b3J5JztcbmltcG9ydCB7IE1vY2tTZXR0aW5nc1JlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrU2V0dGluZ3NSZXBvc2l0b3J5JztcbmltcG9ydCB7IE1vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSB9IGZyb20gJy4vcmVwb3NpdG9yaWVzL01vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSc7XG4vLyBXb3JrZXJzXG5pbXBvcnQgeyBEYXRhU2VlZGVyIH0gZnJvbSAnLi93b3JrZXJzL0RhdGFTZWVkZXInO1xuLy8gRmVhdHVyZXNcbmltcG9ydCB7IEV2ZW50UmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL2V2ZW50L0V2ZW50UmVuZGVyZXInO1xuaW1wb3J0IHsgU2NoZWR1bGVSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvc2NoZWR1bGUvU2NoZWR1bGVSZW5kZXJlcic7XG5pbXBvcnQgeyBIZWFkZXJEcmF3ZXJSZW5kZXJlciB9IGZyb20gJy4vZmVhdHVyZXMvaGVhZGVyZHJhd2VyL0hlYWRlckRyYXdlclJlbmRlcmVyJztcbi8vIFNjaGVkdWxlXG5pbXBvcnQgeyBTY2hlZHVsZU92ZXJyaWRlU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2Uvc2NoZWR1bGVzL1NjaGVkdWxlT3ZlcnJpZGVTdG9yZSc7XG5pbXBvcnQgeyBTY2hlZHVsZU92ZXJyaWRlU2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9zY2hlZHVsZXMvU2NoZWR1bGVPdmVycmlkZVNlcnZpY2UnO1xuaW1wb3J0IHsgUmVzb3VyY2VTY2hlZHVsZVNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2Uvc2NoZWR1bGVzL1Jlc291cmNlU2NoZWR1bGVTZXJ2aWNlJztcbi8vIE1hbmFnZXJzXG5pbXBvcnQgeyBEcmFnRHJvcE1hbmFnZXIgfSBmcm9tICcuL21hbmFnZXJzL0RyYWdEcm9wTWFuYWdlcic7XG5pbXBvcnQgeyBFZGdlU2Nyb2xsTWFuYWdlciB9IGZyb20gJy4vbWFuYWdlcnMvRWRnZVNjcm9sbE1hbmFnZXInO1xuaW1wb3J0IHsgUmVzaXplTWFuYWdlciB9IGZyb20gJy4vbWFuYWdlcnMvUmVzaXplTWFuYWdlcic7XG5pbXBvcnQgeyBFdmVudFBlcnNpc3RlbmNlTWFuYWdlciB9IGZyb20gJy4vbWFuYWdlcnMvRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXInO1xuY29uc3QgZGVmYXVsdFRpbWVGb3JtYXRDb25maWcgPSB7XG4gICAgdGltZXpvbmU6IEludGwuRGF0ZVRpbWVGb3JtYXQoKS5yZXNvbHZlZE9wdGlvbnMoKS50aW1lWm9uZSxcbiAgICB1c2UyNEhvdXJGb3JtYXQ6IHRydWUsXG4gICAgbG9jYWxlOiAnZGEtREsnLFxuICAgIGRhdGVGb3JtYXQ6ICdsb2NhbGUnLFxuICAgIHNob3dTZWNvbmRzOiBmYWxzZVxufTtcbmNvbnN0IGRlZmF1bHRHcmlkQ29uZmlnID0ge1xuICAgIGhvdXJIZWlnaHQ6IDY0LFxuICAgIGRheVN0YXJ0SG91cjogNixcbiAgICBkYXlFbmRIb3VyOiAxOCxcbiAgICBzbmFwSW50ZXJ2YWw6IDE1LFxuICAgIGdyaWRTdGFydFRocmVzaG9sZE1pbnV0ZXM6IDMwXG59O1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRhaW5lcigpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG4gICAgY29uc3QgYnVpbGRlciA9IGNvbnRhaW5lci5idWlsZGVyKCk7XG4gICAgLy8gQ29uZmlnXG4gICAgYnVpbGRlci5yZWdpc3Rlckluc3RhbmNlKGRlZmF1bHRUaW1lRm9ybWF0Q29uZmlnKS5hcyhcIklUaW1lRm9ybWF0Q29uZmlnXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJJbnN0YW5jZShkZWZhdWx0R3JpZENvbmZpZykuYXMoXCJJR3JpZENvbmZpZ1wiKTtcbiAgICAvLyBDb3JlIC0gRXZlbnRCdXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXMoXCJFdmVudEJ1c1wiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXMoXCJJRXZlbnRCdXNcIik7XG4gICAgLy8gU2VydmljZXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEYXRlU2VydmljZSkuYXMoXCJEYXRlU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSVRpbWVGb3JtYXRDb25maWdcIiksXG4gICAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIFN0b3JhZ2UgaW5mcmFzdHJ1Y3R1cmVcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShJbmRleGVkREJDb250ZXh0KS5hcyhcIkluZGV4ZWREQkNvbnRleHRcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZUFsbChcIklTdG9yZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gU3RvcmVzIChmb3IgSW5kZXhlZERCIHNjaGVtYSBjcmVhdGlvbilcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShCb29raW5nU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEN1c3RvbWVyU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFRlYW1TdG9yZSkuYXMoXCJJU3RvcmVcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVwYXJ0bWVudFN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShTY2hlZHVsZU92ZXJyaWRlU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEF1ZGl0U3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNldHRpbmdzU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFZpZXdDb25maWdTdG9yZSkuYXMoXCJJU3RvcmVcIik7XG4gICAgLy8gRW50aXR5IHNlcnZpY2VzIChmb3IgRGF0YVNlZWRlciBwb2x5bW9ycGhpYyBhcnJheSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEV2ZW50U2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRXZlbnRTZXJ2aWNlKS5hcyhcIkV2ZW50U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoUmVzb3VyY2VTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFJlc291cmNlU2VydmljZSkuYXMoXCJSZXNvdXJjZVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEJvb2tpbmdTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShCb29raW5nU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQm9va2luZ1NlcnZpY2UpLmFzKFwiQm9va2luZ1NlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEN1c3RvbWVyU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQ3VzdG9tZXJTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShDdXN0b21lclNlcnZpY2UpLmFzKFwiQ3VzdG9tZXJTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShUZWFtU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGVhbVNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFRlYW1TZXJ2aWNlKS5hcyhcIlRlYW1TZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEZXBhcnRtZW50U2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVwYXJ0bWVudFNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKERlcGFydG1lbnRTZXJ2aWNlKS5hcyhcIkRlcGFydG1lbnRTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShTZXR0aW5nc1NlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNldHRpbmdzU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoU2V0dGluZ3NTZXJ2aWNlKS5hcyhcIlNldHRpbmdzU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVmlld0NvbmZpZ1NlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFZpZXdDb25maWdTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShWaWV3Q29uZmlnU2VydmljZSkuYXMoXCJWaWV3Q29uZmlnU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gUmVwb3NpdG9yaWVzIChmb3IgRGF0YVNlZWRlciBwb2x5bW9ycGhpYyBhcnJheSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrRXZlbnRSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tFdmVudFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1Jlc291cmNlUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrUmVzb3VyY2VSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tCb29raW5nUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrQm9va2luZ1JlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tBdWRpdFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja0F1ZGl0UmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVGVhbVJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1RlYW1SZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1NldHRpbmdzUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrU2V0dGluZ3NSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgLy8gQXVkaXQgc2VydmljZSAobGlzdGVucyB0byBFTlRJVFlfU0FWRUQvREVMRVRFRCBldmVudHMgYXV0b21hdGljYWxseSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShBdWRpdFNlcnZpY2UpLmFzKFwiQXVkaXRTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBXb3JrZXJzXG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGF0YVNlZWRlcikuYXMoXCJEYXRhU2VlZGVyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJRW50aXR5U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZUFsbChcIklBcGlSZXBvc2l0b3J5XCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBTY2hlZHVsZSBzZXJ2aWNlc1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlKS5hcyhcIlNjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVNjaGVkdWxlU2VydmljZSkuYXMoXCJSZXNvdXJjZVNjaGVkdWxlU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiUmVzb3VyY2VTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2NoZWR1bGVPdmVycmlkZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gRmVhdHVyZXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFJlbmRlcmVyKS5hcyhcIkV2ZW50UmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjaGVkdWxlUmVuZGVyZXIpLmFzKFwiU2NoZWR1bGVSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiUmVzb3VyY2VTY2hlZHVsZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklHcmlkQ29uZmlnXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShIZWFkZXJEcmF3ZXJSZW5kZXJlcikuYXMoXCJIZWFkZXJEcmF3ZXJSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJIZWFkZXJEcmF3ZXJNYW5hZ2VyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRXZlbnRTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIFJlbmRlcmVycyAtIHJlZ2lzdHJlcmVzIHNvbSBSZW5kZXJlciAoYXJyYXkgaW5qZWN0aW9uIHRpbCBDYWxlbmRhck9yY2hlc3RyYXRvcilcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEYXRlUmVuZGVyZXIpLmFzKFwiSVJlbmRlcmVyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoUmVzb3VyY2VSZW5kZXJlcikuYXMoXCJJUmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIlJlc291cmNlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGVhbVJlbmRlcmVyKS5hcyhcIklSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVGVhbVNlcnZpY2VcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKERlcGFydG1lbnRSZW5kZXJlcikuYXMoXCJJUmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRlcGFydG1lbnRTZXJ2aWNlXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBTdG9yZXMgLSByZWdpc3RyZXJlcyBzb20gSUdyb3VwaW5nU3RvcmVcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVGVhbVN0b3JlKS5hcyhcIklHcm91cGluZ1N0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tSZXNvdXJjZVN0b3JlKS5hcyhcIklHcm91cGluZ1N0b3JlXCIpO1xuICAgIC8vIENhbGVuZGFyT3JjaGVzdHJhdG9yIG1vZHRhZ2VyIElHcm91cGluZ1N0b3JlW10gYXV0b21hdGlzayAoYXJyYXkgaW5qZWN0aW9uKVxuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKENhbGVuZGFyT3JjaGVzdHJhdG9yKS5hcyhcIkNhbGVuZGFyT3JjaGVzdHJhdG9yXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJUmVuZGVyZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJFdmVudFJlbmRlcmVyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2NoZWR1bGVSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkhlYWRlckRyYXdlclJlbmRlcmVyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJRW50aXR5U2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGltZUF4aXNSZW5kZXJlcikuYXMoXCJUaW1lQXhpc1JlbmRlcmVyXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjcm9sbE1hbmFnZXIpLmFzKFwiU2Nyb2xsTWFuYWdlclwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShIZWFkZXJEcmF3ZXJNYW5hZ2VyKS5hcyhcIkhlYWRlckRyYXdlck1hbmFnZXJcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRHJhZ0Ryb3BNYW5hZ2VyKS5hcyhcIkRyYWdEcm9wTWFuYWdlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEVkZ2VTY3JvbGxNYW5hZ2VyKS5hcyhcIkVkZ2VTY3JvbGxNYW5hZ2VyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFJlc2l6ZU1hbmFnZXIpLmFzKFwiUmVzaXplTWFuYWdlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIpLmFzKFwiRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBDYWxlbmRhckFwcCAtIGdlbmJydWdlbGlnIGthbGVuZGVya29tcG9uZW50XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQ2FsZW5kYXJBcHApLmFzKFwiQ2FsZW5kYXJBcHBcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkNhbGVuZGFyT3JjaGVzdHJhdG9yXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVGltZUF4aXNSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2Nyb2xsTWFuYWdlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkhlYWRlckRyYXdlck1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEcmFnRHJvcE1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJFZGdlU2Nyb2xsTWFuYWdlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIlJlc2l6ZU1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJIZWFkZXJEcmF3ZXJSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2V0dGluZ3NTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVmlld0NvbmZpZ1NlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIERlbW8gYXBwXG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVtb0FwcCkuYXMoXCJEZW1vQXBwXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0YVNlZWRlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkF1ZGl0U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkNhbGVuZGFyQXBwXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJSZXNvdXJjZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIHJldHVybiBidWlsZGVyLmJ1aWxkKCk7XG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlQ29udGFpbmVyIH0gZnJvbSAnLi4vQ29tcG9zaXRpb25Sb290JztcbmNvbnN0IGNvbnRhaW5lciA9IGNyZWF0ZUNvbnRhaW5lcigpO1xuY29udGFpbmVyLnJlc29sdmVUeXBlKFwiRGVtb0FwcFwiKS5pbml0KCkuY2F0Y2goY29uc29sZS5lcnJvcik7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBLEtBQUMsU0FBUyxHQUFFLEdBQUU7QUFBQyxrQkFBVSxPQUFPLFdBQVMsZUFBYSxPQUFPLFNBQU8sT0FBTyxVQUFRLEVBQUUsSUFBRSxjQUFZLE9BQU8sVUFBUSxPQUFPLE1BQUksT0FBTyxDQUFDLEtBQUcsSUFBRSxlQUFhLE9BQU8sYUFBVyxhQUFXLEtBQUcsTUFBTSxRQUFNLEVBQUU7QUFBQSxJQUFDLEVBQUUsU0FBTSxXQUFVO0FBQUM7QUFBYSxVQUFJLElBQUUsS0FBSSxJQUFFLEtBQUksSUFBRSxNQUFLLElBQUUsZUFBYyxJQUFFLFVBQVMsSUFBRSxVQUFTLElBQUUsUUFBTyxJQUFFLE9BQU0sSUFBRSxRQUFPLElBQUUsU0FBUSxJQUFFLFdBQVUsSUFBRSxRQUFPLElBQUUsUUFBTyxJQUFFLGdCQUFlLElBQUUsOEZBQTZGLElBQUUsdUZBQXNGLElBQUUsRUFBQyxNQUFLLE1BQUssVUFBUywyREFBMkQsTUFBTSxHQUFHLEdBQUUsUUFBTyx3RkFBd0YsTUFBTSxHQUFHLEdBQUUsU0FBUSxTQUFTQSxJQUFFO0FBQUMsWUFBSUMsS0FBRSxDQUFDLE1BQUssTUFBSyxNQUFLLElBQUksR0FBRUMsS0FBRUYsS0FBRTtBQUFJLGVBQU0sTUFBSUEsTUFBR0MsSUFBR0MsS0FBRSxNQUFJLEVBQUUsS0FBR0QsR0FBRUMsRUFBQyxLQUFHRCxHQUFF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LGFBQWE7QUFBQSxNQUNoQyxPQUFLLEVBQUUsWUFBWSxlQUFlO0FBQUEsTUFDbEMsT0FBSyxFQUFFLFlBQVkscUJBQXFCO0FBQUEsTUFDeEMsT0FBSyxFQUFFLFlBQVksaUJBQWlCO0FBQUEsTUFDcEMsT0FBSyxFQUFFLFlBQVksbUJBQW1CO0FBQUEsTUFDdEMsT0FBSyxFQUFFLFlBQVksZUFBZTtBQUFBLE1BQ2xDLE9BQUssRUFBRSxZQUFZLHNCQUFzQjtBQUFBLE1BQ3pDLE9BQUssRUFBRSxZQUFZLHlCQUF5QjtBQUFBLE1BQzVDLE9BQUssRUFBRSxZQUFZLGlCQUFpQjtBQUFBLE1BQ3BDLE9BQUssRUFBRSxZQUFZLG1CQUFtQjtBQUFBLE1BQ3RDLE9BQUssRUFBRSxZQUFZLFdBQVc7QUFBQSxJQUNsQztBQUFBLEVBQ0osQ0FBQztBQUVELFVBQVEsYUFBYSxPQUFPLEVBQUUsR0FBRyxTQUFTLEVBQUUsU0FBUztBQUFBLElBQ2pELGNBQWM7QUFBQSxNQUNWLE9BQUssRUFBRSxZQUFZLGtCQUFrQjtBQUFBLE1BQ3JDLE9BQUssRUFBRSxZQUFZLFlBQVk7QUFBQSxNQUMvQixPQUFLLEVBQUUsWUFBWSxjQUFjO0FBQUEsTUFDakMsT0FBSyxFQUFFLFlBQVksYUFBYTtBQUFBLE1BQ2hDLE9BQUssRUFBRSxZQUFZLGFBQWE7QUFBQSxNQUNoQyxPQUFLLEVBQUUsWUFBWSxpQkFBaUI7QUFBQSxNQUNwQyxPQUFLLEVBQUUsWUFBWSxXQUFXO0FBQUEsSUFDbEM7QUFBQSxFQUNKLENBQUM7QUFDRCxTQUFPLFFBQVEsTUFBTTtBQUN6QjtBQXZWZ0I7OztBQ3pFaEIsSUFBTSxZQUFZLGdCQUFnQjtBQUNsQyxVQUFVLFlBQVksU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLFFBQVEsS0FBSzsiLAogICJuYW1lcyI6IFsidCIsICJlIiwgIm4iLCAiciIsICJpIiwgInMiLCAidSIsICJhIiwgIk0iLCAibSIsICJmIiwgImwiLCAiJCIsICJ5IiwgInYiLCAiZyIsICJEIiwgIm8iLCAiZCIsICJjIiwgImgiLCAidCIsICJpIiwgImUiLCAicyIsICJmIiwgIm4iLCAidSIsICJyIiwgIm8iLCAidCIsICJuIiwgImkiLCAibyIsICJyIiwgImUiLCAidSIsICJmIiwgInMiLCAiYSIsICJ0IiwgImkiLCAiZCIsICJuIiwgImUiLCAicyIsICJ0b2tlbiIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgInRva2VuIiwgImNvbnRhaW5lciIsICJkYXlqcyIsICJ1dGMiLCAidGltZXpvbmUiLCAiaXNvV2VlayIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImNvbnRhaW5lciIsICJnZXRLZXkiLCAic2tpcFBhdGgiLCAia2V5IiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImRpZmYiLCAiY29udGFpbmVyIiwgImNvbnRhaW5lciIsICJkaWZmIiwgImNvbnRhaW5lciJdCn0K diff --git a/wwwroot/js/edge-scroll.js b/wwwroot/js/edge-scroll.js new file mode 100644 index 0000000..e8b0198 --- /dev/null +++ b/wwwroot/js/edge-scroll.js @@ -0,0 +1,104 @@ +// edge-scroll.js - med timeout + tidsbaseret scroll +(function() { + 'use strict'; + + const OUTER_ZONE = 100; // px fra kant (langsom zone) + const INNER_ZONE = 50; // px fra kant (hurtig zone) + const SLOW_SPEED_PXS = 800; // px/sek i outer zone + const FAST_SPEED_PXS = 2400; // px/sek i inner zone + + let scrollableContent = null; + let scrollRAF = null; + let mouseY = 0; + let haveMouse = false; + let lastTs = 0; + let rect = null; + + function init() { + console.log('edge-scroll.js: waiting 1000ms before setup...'); + setTimeout(setup, 1000); + } + + function setup() { + console.log('edge-scroll.js: setup() called'); + + scrollableContent = document.querySelector('swp-scrollable-content'); + if (!scrollableContent) { + console.error('edge-scroll.js: swp-scrollable-content NOT FOUND'); + return; + } + + console.log('edge-scroll.js: found scrollableContent:', scrollableContent); + + // slå smooth scroll fra, så autoscroll er øjeblikkelig + scrollableContent.style.scrollBehavior = 'auto'; + + scrollableContent.addEventListener('mousemove', handleMouseMove, { passive: true }); + scrollableContent.addEventListener('mouseleave', handleMouseLeave, { passive: true }); + + console.log('edge-scroll.js: ✅ listeners attached'); + } + + function handleMouseMove(e) { + haveMouse = true; + mouseY = e.clientY; + if (scrollRAF == null) { + lastTs = performance.now(); + scrollRAF = requestAnimationFrame(scrollTick); + } + } + + function handleMouseLeave() { + haveMouse = false; + stopScrolling(); + } + + function stopScrolling() { + if (scrollRAF != null) { + cancelAnimationFrame(scrollRAF); + scrollRAF = null; + } + lastTs = 0; + } + + function scrollTick(ts) { + const dt = lastTs ? (ts - lastTs) / 1000 : 0; + lastTs = ts; + + if (!rect) rect = scrollableContent.getBoundingClientRect(); + + let vy = 0; + if (haveMouse) { + const distTop = mouseY - rect.top; + const distBot = rect.bottom - mouseY; + + // Check top edge + if (distTop < INNER_ZONE) { + // Inner zone (0-50px) - fast speed + vy = -FAST_SPEED_PXS; + } else if (distTop < OUTER_ZONE) { + // Outer zone (50-100px) - slow speed + vy = -SLOW_SPEED_PXS; + } + // Check bottom edge + else if (distBot < INNER_ZONE) { + // Inner zone (0-50px) - fast speed + vy = FAST_SPEED_PXS; + } else if (distBot < OUTER_ZONE) { + // Outer zone (50-100px) - slow speed + vy = SLOW_SPEED_PXS; + } + } + + if (vy !== 0) { + scrollableContent.scrollTop += vy * dt; + rect = null; // mål kun én gang pr. frame + scrollRAF = requestAnimationFrame(scrollTick); + } else { + stopScrolling(); + } + } + + // start init + init(); +})(); diff --git a/wwwroot/js/elements/SwpEventElement.d.ts b/wwwroot/js/elements/SwpEventElement.d.ts new file mode 100644 index 0000000..fc38ac2 --- /dev/null +++ b/wwwroot/js/elements/SwpEventElement.d.ts @@ -0,0 +1,98 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +import { DateService } from '../utils/DateService'; +/** + * Base class for event elements + */ +export declare abstract class BaseSwpEventElement extends HTMLElement { + protected dateService: DateService; + protected config: Configuration; + constructor(); + /** + * Create a clone for drag operations + * Must be implemented by subclasses + */ + abstract createClone(): HTMLElement; + get eventId(): string; + set eventId(value: string); + get start(): Date; + set start(value: Date); + get end(): Date; + set end(value: Date); + get title(): string; + set title(value: string); + get description(): string; + set description(value: string); + get type(): string; + set type(value: string); +} +/** + * Web Component for timed calendar events (Light DOM) + */ +export declare class SwpEventElement extends BaseSwpEventElement { + /** + * Observed attributes - changes trigger attributeChangedCallback + */ + static get observedAttributes(): string[]; + /** + * Called when element is added to DOM + */ + connectedCallback(): void; + /** + * Called when observed attribute changes + */ + attributeChangedCallback(name: string, oldValue: string, newValue: string): void; + /** + * Update event position during drag + * @param columnDate - The date of the column + * @param snappedY - The Y position in pixels + */ + updatePosition(columnDate: Date, snappedY: number): void; + /** + * Update event height during resize + * @param newHeight - The new height in pixels + */ + updateHeight(newHeight: number): void; + /** + * Create a clone for drag operations + */ + createClone(): SwpEventElement; + /** + * Render inner HTML structure + */ + private render; + /** + * Update time display when attributes change + */ + private updateDisplay; + /** + * Calculate start/end minutes from Y position + */ + private calculateTimesFromPosition; + /** + * Create SwpEventElement from ICalendarEvent + */ + static fromCalendarEvent(event: ICalendarEvent): SwpEventElement; + /** + * Extract ICalendarEvent from DOM element + */ + static extractCalendarEventFromElement(element: HTMLElement): ICalendarEvent; +} +/** + * Web Component for all-day calendar events + */ +export declare class SwpAllDayEventElement extends BaseSwpEventElement { + connectedCallback(): void; + /** + * Create a clone for drag operations + */ + createClone(): SwpAllDayEventElement; + /** + * Apply CSS grid positioning + */ + applyGridPositioning(row: number, startColumn: number, endColumn: number): void; + /** + * Create from ICalendarEvent + */ + static fromCalendarEvent(event: ICalendarEvent): SwpAllDayEventElement; +} diff --git a/wwwroot/js/elements/SwpEventElement.js b/wwwroot/js/elements/SwpEventElement.js new file mode 100644 index 0000000..96c188f --- /dev/null +++ b/wwwroot/js/elements/SwpEventElement.js @@ -0,0 +1,303 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { TimeFormatter } from '../utils/TimeFormatter'; +import { DateService } from '../utils/DateService'; +/** + * Base class for event elements + */ +export class BaseSwpEventElement extends HTMLElement { + constructor() { + super(); + // Get singleton instance for web components (can't use DI) + this.config = Configuration.getInstance(); + this.dateService = new DateService(this.config); + } + // ============================================ + // Common Getters/Setters + // ============================================ + get eventId() { + return this.dataset.eventId || ''; + } + set eventId(value) { + this.dataset.eventId = value; + } + get start() { + return new Date(this.dataset.start || ''); + } + set start(value) { + this.dataset.start = this.dateService.toUTC(value); + } + get end() { + return new Date(this.dataset.end || ''); + } + set end(value) { + this.dataset.end = this.dateService.toUTC(value); + } + get title() { + return this.dataset.title || ''; + } + set title(value) { + this.dataset.title = value; + } + get description() { + return this.dataset.description || ''; + } + set description(value) { + this.dataset.description = value; + } + get type() { + return this.dataset.type || 'work'; + } + set type(value) { + this.dataset.type = value; + } +} +/** + * Web Component for timed calendar events (Light DOM) + */ +export class SwpEventElement extends BaseSwpEventElement { + /** + * Observed attributes - changes trigger attributeChangedCallback + */ + static get observedAttributes() { + return ['data-start', 'data-end', 'data-title', 'data-description', 'data-type']; + } + /** + * Called when element is added to DOM + */ + connectedCallback() { + if (!this.hasChildNodes()) { + this.render(); + } + } + /** + * Called when observed attribute changes + */ + attributeChangedCallback(name, oldValue, newValue) { + if (oldValue !== newValue && this.isConnected) { + this.updateDisplay(); + } + } + // ============================================ + // Public Methods + // ============================================ + /** + * Update event position during drag + * @param columnDate - The date of the column + * @param snappedY - The Y position in pixels + */ + updatePosition(columnDate, snappedY) { + // 1. Update visual position + this.style.top = `${snappedY + 1}px`; + // 2. Calculate new timestamps + const { startMinutes, endMinutes } = this.calculateTimesFromPosition(snappedY); + // 3. Update data attributes (triggers attributeChangedCallback) + const startDate = this.dateService.createDateAtTime(columnDate, startMinutes); + let endDate = this.dateService.createDateAtTime(columnDate, endMinutes); + // Handle cross-midnight events + if (endMinutes >= 1440) { + const extraDays = Math.floor(endMinutes / 1440); + endDate = this.dateService.addDays(endDate, extraDays); + } + this.start = startDate; + this.end = endDate; + } + /** + * Update event height during resize + * @param newHeight - The new height in pixels + */ + updateHeight(newHeight) { + // 1. Update visual height + this.style.height = `${newHeight}px`; + // 2. Calculate new end time based on height + const gridSettings = this.config.gridSettings; + const { hourHeight, snapInterval } = gridSettings; + // Get current start time + const start = this.start; + // Calculate duration from height + const rawDurationMinutes = (newHeight / hourHeight) * 60; + // Snap duration to grid interval (like drag & drop) + const snappedDurationMinutes = Math.round(rawDurationMinutes / snapInterval) * snapInterval; + // Calculate new end time by adding snapped duration to start (using DateService for timezone safety) + const endDate = this.dateService.addMinutes(start, snappedDurationMinutes); + // 3. Update end attribute (triggers attributeChangedCallback → updateDisplay) + this.end = endDate; + } + /** + * Create a clone for drag operations + */ + createClone() { + const clone = this.cloneNode(true); + // Apply "clone-" prefix to ID + clone.dataset.eventId = `clone-${this.eventId}`; + // Disable pointer events on clone so it doesn't interfere with hover detection + clone.style.pointerEvents = 'none'; + // Cache original duration + const timeEl = this.querySelector('swp-event-time'); + if (timeEl) { + const duration = timeEl.getAttribute('data-duration'); + if (duration) { + clone.dataset.originalDuration = duration; + } + } + // Set height from original + clone.style.height = this.style.height || `${this.getBoundingClientRect().height}px`; + return clone; + } + // ============================================ + // Private Methods + // ============================================ + /** + * Render inner HTML structure + */ + render() { + const start = this.start; + const end = this.end; + const timeRange = TimeFormatter.formatTimeRange(start, end); + const durationMinutes = (end.getTime() - start.getTime()) / (1000 * 60); + this.innerHTML = ` + ${timeRange} + ${this.title} + ${this.description ? `${this.description}` : ''} + `; + } + /** + * Update time display when attributes change + */ + updateDisplay() { + const timeEl = this.querySelector('swp-event-time'); + const titleEl = this.querySelector('swp-event-title'); + const descEl = this.querySelector('swp-event-description'); + if (timeEl && this.dataset.start && this.dataset.end) { + const start = new Date(this.dataset.start); + const end = new Date(this.dataset.end); + const timeRange = TimeFormatter.formatTimeRange(start, end); + timeEl.textContent = timeRange; + // Update duration attribute + const durationMinutes = (end.getTime() - start.getTime()) / (1000 * 60); + timeEl.setAttribute('data-duration', durationMinutes.toString()); + } + if (titleEl && this.dataset.title) { + titleEl.textContent = this.dataset.title; + } + if (this.dataset.description) { + if (descEl) { + descEl.textContent = this.dataset.description; + } + else if (this.description) { + // Add description element if it doesn't exist + const newDescEl = document.createElement('swp-event-description'); + newDescEl.textContent = this.description; + this.appendChild(newDescEl); + } + } + else if (descEl) { + // Remove description element if description is empty + descEl.remove(); + } + } + /** + * Calculate start/end minutes from Y position + */ + calculateTimesFromPosition(snappedY) { + const gridSettings = this.config.gridSettings; + const { hourHeight, dayStartHour, snapInterval } = gridSettings; + // Get original duration + const originalDuration = parseInt(this.dataset.originalDuration || + this.dataset.duration || + '60'); + // Calculate snapped start minutes + const minutesFromGridStart = (snappedY / hourHeight) * 60; + const actualStartMinutes = (dayStartHour * 60) + minutesFromGridStart; + const snappedStartMinutes = Math.round(actualStartMinutes / snapInterval) * snapInterval; + // Calculate end minutes + const endMinutes = snappedStartMinutes + originalDuration; + return { startMinutes: snappedStartMinutes, endMinutes }; + } + // ============================================ + // Static Factory Methods + // ============================================ + /** + * Create SwpEventElement from ICalendarEvent + */ + static fromCalendarEvent(event) { + const element = document.createElement('swp-event'); + const config = Configuration.getInstance(); + const dateService = new DateService(config); + element.dataset.eventId = event.id; + element.dataset.title = event.title; + element.dataset.description = event.description || ''; + element.dataset.start = dateService.toUTC(event.start); + element.dataset.end = dateService.toUTC(event.end); + element.dataset.type = event.type; + element.dataset.duration = event.metadata?.duration?.toString() || '60'; + return element; + } + /** + * Extract ICalendarEvent from DOM element + */ + static extractCalendarEventFromElement(element) { + return { + id: element.dataset.eventId || '', + title: element.dataset.title || '', + description: element.dataset.description || undefined, + start: new Date(element.dataset.start || ''), + end: new Date(element.dataset.end || ''), + type: element.dataset.type || 'work', + allDay: false, + syncStatus: 'synced', + metadata: { + duration: element.dataset.duration + } + }; + } +} +/** + * Web Component for all-day calendar events + */ +export class SwpAllDayEventElement extends BaseSwpEventElement { + connectedCallback() { + if (!this.textContent) { + this.textContent = this.dataset.title || 'Untitled'; + } + } + /** + * Create a clone for drag operations + */ + createClone() { + const clone = this.cloneNode(true); + // Apply "clone-" prefix to ID + clone.dataset.eventId = `clone-${this.eventId}`; + // Disable pointer events on clone so it doesn't interfere with hover detection + clone.style.pointerEvents = 'none'; + // Preserve full opacity during drag + clone.style.opacity = '1'; + return clone; + } + /** + * Apply CSS grid positioning + */ + applyGridPositioning(row, startColumn, endColumn) { + const gridArea = `${row} / ${startColumn} / ${row + 1} / ${endColumn + 1}`; + this.style.gridArea = gridArea; + } + /** + * Create from ICalendarEvent + */ + static fromCalendarEvent(event) { + const element = document.createElement('swp-allday-event'); + const config = Configuration.getInstance(); + const dateService = new DateService(config); + element.dataset.eventId = event.id; + element.dataset.title = event.title; + element.dataset.start = dateService.toUTC(event.start); + element.dataset.end = dateService.toUTC(event.end); + element.dataset.type = event.type; + element.dataset.allday = 'true'; + element.textContent = event.title; + return element; + } +} +// Register custom elements +customElements.define('swp-event', SwpEventElement); +customElements.define('swp-allday-event', SwpAllDayEventElement); +//# sourceMappingURL=SwpEventElement.js.map \ No newline at end of file diff --git a/wwwroot/js/elements/SwpEventElement.js.map b/wwwroot/js/elements/SwpEventElement.js.map new file mode 100644 index 0000000..e05d269 --- /dev/null +++ b/wwwroot/js/elements/SwpEventElement.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SwpEventElement.js","sourceRoot":"","sources":["../../../src/elements/SwpEventElement.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/factories/CalendarTypeFactory.d.ts b/wwwroot/js/factories/CalendarTypeFactory.d.ts new file mode 100644 index 0000000..2c71862 --- /dev/null +++ b/wwwroot/js/factories/CalendarTypeFactory.d.ts @@ -0,0 +1,55 @@ +import { CalendarMode } from '../types/CalendarTypes'; +import { HeaderRenderer } from '../renderers/HeaderRenderer'; +import { ColumnRenderer } from '../renderers/ColumnRenderer'; +import { EventRendererStrategy } from '../renderers/EventRenderer'; +/** + * Renderer configuration for a calendar type + */ +export interface RendererConfig { + headerRenderer: HeaderRenderer; + columnRenderer: ColumnRenderer; + eventRenderer: EventRendererStrategy; +} +/** + * Factory for creating calendar type-specific renderers + */ +export declare class CalendarTypeFactory { + private static renderers; + private static isInitialized; + /** + * Initialize the factory with default renderers (only runs once) + */ + static initialize(): void; + /** + * Register renderers for a calendar type + */ + static registerRenderers(type: CalendarMode, config: RendererConfig): void; + /** + * Get renderers for a calendar type + */ + static getRenderers(type: CalendarMode): RendererConfig; + /** + * Get header renderer for a calendar type + */ + static getHeaderRenderer(type: CalendarMode): HeaderRenderer; + /** + * Get column renderer for a calendar type + */ + static getColumnRenderer(type: CalendarMode): ColumnRenderer; + /** + * Get event renderer for a calendar type + */ + static getEventRenderer(type: CalendarMode): EventRendererStrategy; + /** + * Check if a calendar type is supported + */ + static isSupported(type: CalendarMode): boolean; + /** + * Get all supported calendar types + */ + static getSupportedTypes(): CalendarMode[]; + /** + * Clear all registered renderers (useful for testing) + */ + static clear(): void; +} diff --git a/wwwroot/js/factories/CalendarTypeFactory.js b/wwwroot/js/factories/CalendarTypeFactory.js new file mode 100644 index 0000000..98bb1ca --- /dev/null +++ b/wwwroot/js/factories/CalendarTypeFactory.js @@ -0,0 +1,84 @@ +// Factory for creating calendar type-specific renderers +import { DateHeaderRenderer, ResourceHeaderRenderer } from '../renderers/HeaderRenderer'; +import { DateColumnRenderer, ResourceColumnRenderer } from '../renderers/ColumnRenderer'; +import { DateEventRenderer, ResourceEventRenderer } from '../renderers/EventRenderer'; +/** + * Factory for creating calendar type-specific renderers + */ +export class CalendarTypeFactory { + /** + * Initialize the factory with default renderers (only runs once) + */ + static initialize() { + if (this.isInitialized) { + return; + } + // Register default renderers + this.registerRenderers('date', { + headerRenderer: new DateHeaderRenderer(), + columnRenderer: new DateColumnRenderer(), + eventRenderer: new DateEventRenderer() + }); + this.registerRenderers('resource', { + headerRenderer: new ResourceHeaderRenderer(), + columnRenderer: new ResourceColumnRenderer(), + eventRenderer: new ResourceEventRenderer() + }); + this.isInitialized = true; + } + /** + * Register renderers for a calendar type + */ + static registerRenderers(type, config) { + this.renderers.set(type, config); + } + /** + * Get renderers for a calendar type + */ + static getRenderers(type) { + const renderers = this.renderers.get(type); + if (!renderers) { + return this.renderers.get('date'); + } + return renderers; + } + /** + * Get header renderer for a calendar type + */ + static getHeaderRenderer(type) { + return this.getRenderers(type).headerRenderer; + } + /** + * Get column renderer for a calendar type + */ + static getColumnRenderer(type) { + return this.getRenderers(type).columnRenderer; + } + /** + * Get event renderer for a calendar type + */ + static getEventRenderer(type) { + return this.getRenderers(type).eventRenderer; + } + /** + * Check if a calendar type is supported + */ + static isSupported(type) { + return this.renderers.has(type); + } + /** + * Get all supported calendar types + */ + static getSupportedTypes() { + return Array.from(this.renderers.keys()); + } + /** + * Clear all registered renderers (useful for testing) + */ + static clear() { + this.renderers.clear(); + } +} +CalendarTypeFactory.renderers = new Map(); +CalendarTypeFactory.isInitialized = false; +//# sourceMappingURL=CalendarTypeFactory.js.map \ No newline at end of file diff --git a/wwwroot/js/factories/CalendarTypeFactory.js.map b/wwwroot/js/factories/CalendarTypeFactory.js.map new file mode 100644 index 0000000..a1d85d8 --- /dev/null +++ b/wwwroot/js/factories/CalendarTypeFactory.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarTypeFactory.js","sourceRoot":"","sources":["../../../src/factories/CalendarTypeFactory.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAGxD,OAAO,EAAkB,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACzG,OAAO,EAAkB,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACzG,OAAO,EAAyB,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAY7G;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAI9B;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE;YAC7B,cAAc,EAAE,IAAI,kBAAkB,EAAE;YACxC,cAAc,EAAE,IAAI,kBAAkB,EAAE;YACxC,aAAa,EAAE,IAAI,iBAAiB,EAAE;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE;YACjC,cAAc,EAAE,IAAI,sBAAsB,EAAE;YAC5C,cAAc,EAAE,IAAI,sBAAsB,EAAE;YAC5C,aAAa,EAAE,IAAI,qBAAqB,EAAE;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAkB,EAAE,MAAsB;QACjE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAkB;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QACrC,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAkB;QACzC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAkB;QACzC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAkB;QACxC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAkB;QACnC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;;AAvFc,6BAAS,GAAsC,IAAI,GAAG,EAAE,CAAC;AACzD,iCAAa,GAAY,KAAK,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/factories/ManagerFactory.d.ts b/wwwroot/js/factories/ManagerFactory.d.ts new file mode 100644 index 0000000..2f9edb6 --- /dev/null +++ b/wwwroot/js/factories/ManagerFactory.d.ts @@ -0,0 +1,18 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { CalendarManagers } from '../types/ManagerTypes'; +/** + * Factory for creating and managing calendar managers with proper dependency injection + */ +export declare class ManagerFactory { + private static instance; + private constructor(); + static getInstance(): ManagerFactory; + /** + * Create all managers with proper dependency injection + */ + createManagers(eventBus: IEventBus): CalendarManagers; + /** + * Initialize all managers in the correct order + */ + initializeManagers(managers: CalendarManagers): Promise; +} diff --git a/wwwroot/js/factories/ManagerFactory.js b/wwwroot/js/factories/ManagerFactory.js new file mode 100644 index 0000000..14636be --- /dev/null +++ b/wwwroot/js/factories/ManagerFactory.js @@ -0,0 +1,60 @@ +import { EventManager } from '../managers/EventManager'; +import { EventRenderingService } from '../renderers/EventRendererManager'; +import { GridManager } from '../managers/GridManager'; +import { ScrollManager } from '../managers/ScrollManager'; +import { NavigationManager } from '../managers/NavigationManager'; +import { ViewManager } from '../managers/ViewManager'; +import { CalendarManager } from '../managers/CalendarManager'; +import { DragDropManager } from '../managers/DragDropManager'; +import { AllDayManager } from '../managers/AllDayManager'; +/** + * Factory for creating and managing calendar managers with proper dependency injection + */ +export class ManagerFactory { + constructor() { } + static getInstance() { + if (!ManagerFactory.instance) { + ManagerFactory.instance = new ManagerFactory(); + } + return ManagerFactory.instance; + } + /** + * Create all managers with proper dependency injection + */ + createManagers(eventBus) { + // Create managers in dependency order + const eventManager = new EventManager(eventBus); + const eventRenderer = new EventRenderingService(eventBus, eventManager); + const gridManager = new GridManager(); + const scrollManager = new ScrollManager(); + const navigationManager = new NavigationManager(eventBus, eventRenderer); + const viewManager = new ViewManager(eventBus); + const dragDropManager = new DragDropManager(eventBus); + const allDayManager = new AllDayManager(); + // CalendarManager depends on all other managers + const calendarManager = new CalendarManager(eventBus, eventManager, gridManager, eventRenderer, scrollManager); + return { + eventManager, + eventRenderer, + gridManager, + scrollManager, + navigationManager, + viewManager, + calendarManager, + dragDropManager, + allDayManager + }; + } + /** + * Initialize all managers in the correct order + */ + async initializeManagers(managers) { + try { + await managers.calendarManager.initialize?.(); + } + catch (error) { + throw error; + } + } +} +//# sourceMappingURL=ManagerFactory.js.map \ No newline at end of file diff --git a/wwwroot/js/factories/ManagerFactory.js.map b/wwwroot/js/factories/ManagerFactory.js.map new file mode 100644 index 0000000..e05ff59 --- /dev/null +++ b/wwwroot/js/factories/ManagerFactory.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ManagerFactory.js","sourceRoot":"","sources":["../../../src/factories/ManagerFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D;;GAEG;AACH,MAAM,OAAO,cAAc;IAGzB,gBAAuB,CAAC;IAEjB,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACjC,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,QAAmB;QAEvC,sCAAsC;QACtC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,IAAI,qBAAqB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACxE,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;QACtC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QAC1C,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QAE1C,gDAAgD;QAChD,MAAM,eAAe,GAAG,IAAI,eAAe,CACzC,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,CACd,CAAC;QAGF,OAAO;YACL,YAAY;YACZ,aAAa;YACb,WAAW;YACX,aAAa;YACb,iBAAiB;YACjB,WAAW;YACX,eAAe;YACf,eAAe;YACf,aAAa;SACd,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,kBAAkB,CAAC,QAA0B;QAExD,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayCollapseService.d.ts b/wwwroot/js/features/all-day/AllDayCollapseService.d.ts new file mode 100644 index 0000000..10a0dc3 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCollapseService.d.ts @@ -0,0 +1,45 @@ +/** + * AllDayCollapseService - Manages collapse/expand UI for all-day events + * + * STATELESS SERVICE - Reads expanded state from DOM via AllDayDomReader + * - No persistent state + * - Reads expanded state from DOM CSS class + * - Updates chevron button and overflow indicators + * - Controls event visibility based on row number + */ +import { AllDayHeightService } from './AllDayHeightService'; +export declare class AllDayCollapseService { + private heightService; + constructor(heightService: AllDayHeightService); + /** + * Toggle between expanded and collapsed state + * Reads current state from DOM, toggles it, and updates UI + */ + toggleExpanded(): void; + /** + * Update all UI elements based on current DOM state + */ + private updateUI; + /** + * Update event visibility based on expanded state + */ + private updateEventVisibility; + /** + * Update chevron button visibility and state + */ + private updateChevronButton; + /** + * Update overflow indicators for collapsed state + * Shows "+X more" indicators in columns with overflow + */ + private updateOverflowIndicators; + /** + * Clear all overflow indicators + */ + private clearOverflowIndicators; + /** + * Initialize collapse/expand UI based on current DOM state + * Called after events are rendered + */ + initializeUI(): void; +} diff --git a/wwwroot/js/features/all-day/AllDayCollapseService.js b/wwwroot/js/features/all-day/AllDayCollapseService.js new file mode 100644 index 0000000..fa9036f --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCollapseService.js @@ -0,0 +1,168 @@ +/** + * AllDayCollapseService - Manages collapse/expand UI for all-day events + * + * STATELESS SERVICE - Reads expanded state from DOM via AllDayDomReader + * - No persistent state + * - Reads expanded state from DOM CSS class + * - Updates chevron button and overflow indicators + * - Controls event visibility based on row number + */ +import { ALL_DAY_CONSTANTS } from '../../configurations/CalendarConfig'; +import { ColumnDetectionUtils } from '../../utils/ColumnDetectionUtils'; +import { AllDayDomReader } from './AllDayDomReader'; +export class AllDayCollapseService { + constructor(heightService) { + this.heightService = heightService; + } + /** + * Toggle between expanded and collapsed state + * Reads current state from DOM, toggles it, and updates UI + */ + toggleExpanded() { + const container = AllDayDomReader.getAllDayContainer(); + if (!container) + return; + // Read current state from DOM + const isCurrentlyExpanded = container.classList.contains('expanded'); + // Toggle state in DOM + if (isCurrentlyExpanded) { + container.classList.remove('expanded'); + } + else { + container.classList.add('expanded'); + } + // Update UI based on new state + this.updateUI(); + } + /** + * Update all UI elements based on current DOM state + */ + updateUI() { + const isExpanded = AllDayDomReader.isExpanded(); + const maxRows = AllDayDomReader.getMaxRowFromEvents(); + // Update chevron button + if (maxRows > ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS) { + this.updateChevronButton(true, isExpanded); + if (isExpanded) { + this.clearOverflowIndicators(); + } + else { + this.updateOverflowIndicators(); + } + } + else { + this.updateChevronButton(false, isExpanded); + this.clearOverflowIndicators(); + } + // Update event visibility + this.updateEventVisibility(isExpanded); + // Calculate height based on expanded state + // When collapsed, show max MAX_COLLAPSED_ROWS, when expanded show all rows + const targetRows = isExpanded ? maxRows : Math.min(maxRows, ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS); + this.heightService.animateToRows(targetRows); + } + /** + * Update event visibility based on expanded state + */ + updateEventVisibility(isExpanded) { + const events = AllDayDomReader.getEventElements(); + events.forEach(event => { + const row = AllDayDomReader.getGridRow(event); + if (row > ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS) { + if (isExpanded) { + event.classList.remove('max-event-overflow-hide'); + event.classList.add('max-event-overflow-show'); + } + else { + event.classList.remove('max-event-overflow-show'); + event.classList.add('max-event-overflow-hide'); + } + } + }); + } + /** + * Update chevron button visibility and state + */ + updateChevronButton(show, isExpanded) { + const headerSpacer = AllDayDomReader.getHeaderSpacer(); + if (!headerSpacer) + return; + let chevron = headerSpacer.querySelector('.allday-chevron'); + if (show && !chevron) { + // Create chevron button + chevron = document.createElement('button'); + chevron.className = 'allday-chevron collapsed'; + chevron.innerHTML = ` + + + + `; + chevron.onclick = () => this.toggleExpanded(); + headerSpacer.appendChild(chevron); + } + else if (!show && chevron) { + // Remove chevron button + chevron.remove(); + } + else if (chevron) { + // Update chevron state + chevron.classList.toggle('collapsed', !isExpanded); + chevron.classList.toggle('expanded', isExpanded); + } + } + /** + * Update overflow indicators for collapsed state + * Shows "+X more" indicators in columns with overflow + */ + updateOverflowIndicators() { + const container = AllDayDomReader.getAllDayContainer(); + if (!container) + return; + const columns = ColumnDetectionUtils.getColumns(); + columns.forEach((columnBounds) => { + const totalEventsInColumn = AllDayDomReader.countEventsInColumn(columnBounds.index); + const overflowCount = totalEventsInColumn - ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS; + if (overflowCount > 0) { + // Check if indicator already exists + let existingIndicator = container.querySelector(`.max-event-indicator[data-column="${columnBounds.index}"]`); + if (existingIndicator) { + // Update existing indicator + existingIndicator.innerHTML = `+${overflowCount + 1} more`; + } + else { + // Create new overflow indicator + const overflowElement = document.createElement('swp-allday-event'); + overflowElement.className = 'max-event-indicator'; + overflowElement.setAttribute('data-column', columnBounds.index.toString()); + overflowElement.style.gridRow = ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS.toString(); + overflowElement.style.gridColumn = columnBounds.index.toString(); + overflowElement.innerHTML = `+${overflowCount + 1} more`; + overflowElement.onclick = (e) => { + e.stopPropagation(); + this.toggleExpanded(); + }; + container.appendChild(overflowElement); + } + } + }); + } + /** + * Clear all overflow indicators + */ + clearOverflowIndicators() { + const container = AllDayDomReader.getAllDayContainer(); + if (!container) + return; + container.querySelectorAll('.max-event-indicator').forEach((element) => { + element.remove(); + }); + } + /** + * Initialize collapse/expand UI based on current DOM state + * Called after events are rendered + */ + initializeUI() { + this.updateUI(); + } +} +//# sourceMappingURL=AllDayCollapseService.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayCollapseService.js.map b/wwwroot/js/features/all-day/AllDayCollapseService.js.map new file mode 100644 index 0000000..188222f --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCollapseService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayCollapseService.js","sourceRoot":"","sources":["../../../../src/features/all-day/AllDayCollapseService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayCoordinator.d.ts b/wwwroot/js/features/all-day/AllDayCoordinator.d.ts new file mode 100644 index 0000000..992a8a3 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCoordinator.d.ts @@ -0,0 +1,45 @@ +/** + * AllDayCoordinator - Orchestrates all-day event functionality + * + * NO STATE - Only coordinates between services + * - Listens to EventBus events + * - Delegates to specialized services + * - Manages service lifecycle + */ +import { AllDayEventRenderer } from '../../renderers/AllDayEventRenderer'; +import { EventManager } from '../../managers/EventManager'; +import { DateService } from '../../utils/DateService'; +import { AllDayHeightService } from './AllDayHeightService'; +import { AllDayCollapseService } from './AllDayCollapseService'; +import { AllDayDragService } from './AllDayDragService'; +/** + * AllDayCoordinator - Orchestrates all-day event functionality + * Replaces the monolithic AllDayManager with a coordinated service architecture + */ +export declare class AllDayCoordinator { + private allDayEventRenderer; + private eventManager; + private dateService; + private heightService; + private collapseService; + private dragService; + constructor(eventManager: EventManager, allDayEventRenderer: AllDayEventRenderer, dateService: DateService, heightService: AllDayHeightService, collapseService: AllDayCollapseService, dragService: AllDayDragService); + /** + * Setup event listeners and delegate to services + */ + private setupEventListeners; + /** + * Calculate layout for ALL all-day events using AllDayLayoutEngine + */ + private calculateAllDayEventsLayout; + /** + * Recalculate layouts and update height + * Called after events are added/removed/moved in all-day area + * Uses AllDayLayoutEngine to optimally reorganize all events + */ + private recalculateLayoutsAndHeight; + /** + * Public API for collapsing all-day row + */ + collapseAllDayRow(): void; +} diff --git a/wwwroot/js/features/all-day/AllDayCoordinator.js b/wwwroot/js/features/all-day/AllDayCoordinator.js new file mode 100644 index 0000000..65dc583 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCoordinator.js @@ -0,0 +1,168 @@ +/** + * AllDayCoordinator - Orchestrates all-day event functionality + * + * NO STATE - Only coordinates between services + * - Listens to EventBus events + * - Delegates to specialized services + * - Manages service lifecycle + */ +import { eventBus } from '../../core/EventBus'; +import { ALL_DAY_CONSTANTS } from '../../configurations/CalendarConfig'; +import { AllDayLayoutEngine } from '../../utils/AllDayLayoutEngine'; +import { CoreEvents } from '../../constants/CoreEvents'; +import { AllDayDomReader } from './AllDayDomReader'; +import { ColumnDetectionUtils } from '../../utils/ColumnDetectionUtils'; +/** + * AllDayCoordinator - Orchestrates all-day event functionality + * Replaces the monolithic AllDayManager with a coordinated service architecture + */ +export class AllDayCoordinator { + constructor(eventManager, allDayEventRenderer, dateService, heightService, collapseService, dragService) { + this.eventManager = eventManager; + this.allDayEventRenderer = allDayEventRenderer; + this.dateService = dateService; + this.heightService = heightService; + this.collapseService = collapseService; + this.dragService = dragService; + // Sync CSS variable with TypeScript constant + document.documentElement.style.setProperty('--single-row-height', `${ALL_DAY_CONSTANTS.EVENT_HEIGHT}px`); + this.setupEventListeners(); + } + /** + * Setup event listeners and delegate to services + */ + setupEventListeners() { + // Timed → All-day conversion + eventBus.on('drag:mouseenter-header', (event) => { + const payload = event.detail; + if (payload.draggedClone.hasAttribute('data-allday')) + return; + console.log('🔄 AllDayCoordinator: Received drag:mouseenter-header', { + targetDate: payload.targetColumn, + originalElementId: payload.originalElement?.dataset?.eventId, + originalElementTag: payload.originalElement?.tagName + }); + this.dragService.handleConvertToAllDay(payload); + // Recalculate layouts and height after timed → all-day conversion + this.recalculateLayoutsAndHeight(); + }); + eventBus.on('drag:mouseleave-header', (event) => { + const { originalElement } = event.detail; + console.log('🚪 AllDayCoordinator: Received drag:mouseleave-header', { + originalElementId: originalElement?.dataset?.eventId + }); + }); + // All-day drag start + eventBus.on('drag:start', (event) => { + const payload = event.detail; + if (!payload.draggedClone?.hasAttribute('data-allday')) + return; + this.allDayEventRenderer.handleDragStart(payload); + }); + // All-day column change + eventBus.on('drag:column-change', (event) => { + const payload = event.detail; + if (!payload.draggedClone?.hasAttribute('data-allday')) + return; + this.dragService.handleColumnChange(payload); + }); + // Drag end + eventBus.on('drag:end', (event) => { + const dragEndPayload = event.detail; + console.log('🎯 AllDayCoordinator: drag:end received', { + target: dragEndPayload.target, + originalElementTag: dragEndPayload.originalElement?.tagName, + hasAllDayAttribute: dragEndPayload.originalElement?.hasAttribute('data-allday'), + eventId: dragEndPayload.originalElement?.dataset.eventId + }); + // Handle all-day → all-day drops (within header) + if (dragEndPayload.target === 'swp-day-header') { + console.log('✅ AllDayCoordinator: Handling all-day → all-day drop'); + this.dragService.handleDragEnd(dragEndPayload); + // Recalculate layouts and height after all-day → all-day repositioning + this.recalculateLayoutsAndHeight(); + return; + } + // Handle all-day → timed conversion (dropped in column) + if (dragEndPayload.target === 'swp-day-column' && + dragEndPayload.originalElement?.hasAttribute('data-allday')) { + const eventId = dragEndPayload.originalElement.dataset.eventId; + console.log('🔄 AllDayCoordinator: All-day → timed conversion', { + eventId + }); + // Remove event element from DOM + const container = AllDayDomReader.getAllDayContainer(); + const eventElement = container?.querySelector(`[data-event-id="${eventId}"]`); + if (eventElement) { + eventElement.remove(); + } + // Recalculate layouts and height after event removal + this.recalculateLayoutsAndHeight(); + } + }); + // Drag cancelled + eventBus.on('drag:cancelled', (event) => { + const { draggedElement, reason } = event.detail; + console.log('🚫 AllDayCoordinator: Drag cancelled', { + eventId: draggedElement?.dataset?.eventId, + reason + }); + }); + // Header ready - render all-day events + eventBus.on('header:ready', async (event) => { + const headerReadyEventPayload = event.detail; + const startDate = new Date(headerReadyEventPayload.headerElements.at(0).date); + const endDate = new Date(headerReadyEventPayload.headerElements.at(-1).date); + const events = await this.eventManager.getEventsForPeriod(startDate, endDate); + // Filter for all-day events + const allDayEvents = events.filter(event => event.allDay); + // Calculate layouts + const layouts = this.calculateAllDayEventsLayout(allDayEvents, headerReadyEventPayload.headerElements); + // Render events + this.allDayEventRenderer.renderAllDayEventsForPeriod(layouts); + // Initialize collapse/expand UI and calculate height + this.collapseService.initializeUI(); + }); + // View changed + eventBus.on(CoreEvents.VIEW_CHANGED, (event) => { + this.allDayEventRenderer.handleViewChanged(event); + }); + } + /** + * Calculate layout for ALL all-day events using AllDayLayoutEngine + */ + calculateAllDayEventsLayout(events, dayHeaders) { + // Initialize layout engine with provided week dates + const layoutEngine = new AllDayLayoutEngine(dayHeaders.map(column => column.date)); + // Calculate layout for all events together + return layoutEngine.calculateLayout(events); + } + /** + * Recalculate layouts and update height + * Called after events are added/removed/moved in all-day area + * Uses AllDayLayoutEngine to optimally reorganize all events + */ + recalculateLayoutsAndHeight() { + // 1. Read current events from DOM + const events = AllDayDomReader.getEventsAsData(); + const weekDates = ColumnDetectionUtils.getColumns(); + // 2. Calculate optimal layouts using greedy algorithm + const layouts = this.calculateAllDayEventsLayout(events, weekDates); + // 3. Apply layouts to DOM + this.dragService.applyLayoutUpdates(layouts); + // 4. Calculate max row from NEW layouts + const maxRow = layouts.length > 0 ? Math.max(...layouts.map(l => l.row)) : 0; + // 5. Check if collapsed state should be maintained + const isExpanded = AllDayDomReader.isExpanded(); + const targetRows = isExpanded ? maxRow : Math.min(maxRow, ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS); + // 6. Animate height to target + this.heightService.animateToRows(targetRows); + } + /** + * Public API for collapsing all-day row + */ + collapseAllDayRow() { + this.heightService.collapseAllDayRow(); + } +} +//# sourceMappingURL=AllDayCoordinator.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayCoordinator.js.map b/wwwroot/js/features/all-day/AllDayCoordinator.js.map new file mode 100644 index 0000000..7522289 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayCoordinator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayCoordinator.js","sourceRoot":"","sources":["../../../../src/features/all-day/AllDayCoordinator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayDomReader.d.ts b/wwwroot/js/features/all-day/AllDayDomReader.d.ts new file mode 100644 index 0000000..5142286 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDomReader.d.ts @@ -0,0 +1,74 @@ +import { ICalendarEvent } from '../../types/CalendarTypes'; +/** + * AllDayDomReader - Centralized DOM reading utilities for all-day services + * + * STATELESS UTILITY - Pure functions for reading DOM state + * - Consistent selectors across all services + * - Unified computed style approach (not inline styles) + * - Type-safe return values + * - Single source of truth for DOM queries + */ +export declare class AllDayDomReader { + /** + * Get the all-day events container element + */ + static getAllDayContainer(): HTMLElement | null; + /** + * Get the calendar header element + */ + static getCalendarHeader(): HTMLElement | null; + /** + * Get the header spacer element + */ + static getHeaderSpacer(): HTMLElement | null; + /** + * Get all all-day event elements (excluding overflow indicators) + * Returns raw HTMLElements for DOM manipulation + */ + static getEventElements(): HTMLElement[]; + /** + * Get all-day events as ICalendarEvent objects + * Returns parsed data for business logic + */ + static getEventsAsData(): ICalendarEvent[]; + /** + * Get grid row from element using computed style + * Always uses computed style for consistency + */ + static getGridRow(element: HTMLElement): number; + /** + * Get grid column range from element using computed style + */ + static getGridColumnRange(element: HTMLElement): { + start: number; + end: number; + }; + /** + * Get grid area from element using computed style + */ + static getGridArea(element: HTMLElement): string; + /** + * Calculate max row number from all events + * Uses computed styles for accurate reading + */ + static getMaxRowFromEvents(): number; + /** + * Check if all-day container is expanded + */ + static isExpanded(): boolean; + /** + * Get current all-day height from CSS variable + */ + static getCurrentHeight(): number; + /** + * Count events in specific column + */ + static countEventsInColumn(columnIndex: number): number; + /** + * Get current layouts from DOM elements + * Returns map of eventId → layout info for comparison + */ + static getCurrentLayouts(): Map; +} diff --git a/wwwroot/js/features/all-day/AllDayDomReader.js b/wwwroot/js/features/all-day/AllDayDomReader.js new file mode 100644 index 0000000..93405ca --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDomReader.js @@ -0,0 +1,175 @@ +/** + * AllDayDomReader - Centralized DOM reading utilities for all-day services + * + * STATELESS UTILITY - Pure functions for reading DOM state + * - Consistent selectors across all services + * - Unified computed style approach (not inline styles) + * - Type-safe return values + * - Single source of truth for DOM queries + */ +export class AllDayDomReader { + // ============================================ + // CONTAINER GETTERS + // ============================================ + /** + * Get the all-day events container element + */ + static getAllDayContainer() { + return document.querySelector('swp-calendar-header swp-allday-container'); + } + /** + * Get the calendar header element + */ + static getCalendarHeader() { + return document.querySelector('swp-calendar-header'); + } + /** + * Get the header spacer element + */ + static getHeaderSpacer() { + return document.querySelector('swp-header-spacer'); + } + // ============================================ + // EVENT ELEMENT GETTERS + // ============================================ + /** + * Get all all-day event elements (excluding overflow indicators) + * Returns raw HTMLElements for DOM manipulation + */ + static getEventElements() { + const container = this.getAllDayContainer(); + if (!container) + return []; + return Array.from(container.querySelectorAll('swp-allday-event:not(.max-event-indicator)')); + } + /** + * Get all-day events as ICalendarEvent objects + * Returns parsed data for business logic + */ + static getEventsAsData() { + const elements = this.getEventElements(); + return elements + .map(element => { + const eventId = element.dataset.eventId; + const startStr = element.dataset.start; + const endStr = element.dataset.end; + // Validate required fields + if (!eventId || !startStr || !endStr) { + console.warn('AllDayDomReader: Invalid event data in DOM:', element); + return null; + } + const start = new Date(startStr); + const end = new Date(endStr); + if (isNaN(start.getTime()) || isNaN(end.getTime())) { + console.warn('AllDayDomReader: Invalid event dates:', { startStr, endStr }); + return null; + } + return { + id: eventId, + title: element.dataset.title || '', + start, + end, + type: element.dataset.type || 'task', + allDay: true, + syncStatus: (element.dataset.syncStatus || 'synced') + }; + }) + .filter((event) => event !== null); + } + // ============================================ + // GRID POSITION READERS + // ============================================ + /** + * Get grid row from element using computed style + * Always uses computed style for consistency + */ + static getGridRow(element) { + const computedStyle = window.getComputedStyle(element); + return parseInt(computedStyle.gridRowStart) || 0; + } + /** + * Get grid column range from element using computed style + */ + static getGridColumnRange(element) { + const computedStyle = window.getComputedStyle(element); + return { + start: parseInt(computedStyle.gridColumnStart) || 0, + end: parseInt(computedStyle.gridColumnEnd) || 0 + }; + } + /** + * Get grid area from element using computed style + */ + static getGridArea(element) { + const computedStyle = window.getComputedStyle(element); + return computedStyle.gridArea; + } + /** + * Calculate max row number from all events + * Uses computed styles for accurate reading + */ + static getMaxRowFromEvents() { + const events = this.getEventElements(); + if (events.length === 0) + return 0; + let maxRow = 0; + events.forEach(event => { + const row = this.getGridRow(event); + maxRow = Math.max(maxRow, row); + }); + return maxRow; + } + // ============================================ + // STATE READERS + // ============================================ + /** + * Check if all-day container is expanded + */ + static isExpanded() { + const container = this.getAllDayContainer(); + return container?.classList.contains('expanded') || false; + } + /** + * Get current all-day height from CSS variable + */ + static getCurrentHeight() { + const root = document.documentElement; + const heightStr = root.style.getPropertyValue('--all-day-row-height') || '0px'; + return parseInt(heightStr) || 0; + } + /** + * Count events in specific column + */ + static countEventsInColumn(columnIndex) { + const events = this.getEventElements(); + let count = 0; + events.forEach((event) => { + const { start, end } = this.getGridColumnRange(event); + if (start <= columnIndex && end > columnIndex) { + count++; + } + }); + return count; + } + // ============================================ + // LAYOUT READERS + // ============================================ + /** + * Get current layouts from DOM elements + * Returns map of eventId → layout info for comparison + */ + static getCurrentLayouts() { + const layoutsMap = new Map(); + const events = this.getEventElements(); + events.forEach(event => { + const eventId = event.dataset.eventId; + if (eventId) { + layoutsMap.set(eventId, { + gridArea: this.getGridArea(event) + }); + } + }); + return layoutsMap; + } +} +//# sourceMappingURL=AllDayDomReader.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayDomReader.js.map b/wwwroot/js/features/all-day/AllDayDomReader.js.map new file mode 100644 index 0000000..9a27f22 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDomReader.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayDomReader.js","sourceRoot":"","sources":["../../../../src/features/all-day/AllDayDomReader.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayDragService.d.ts b/wwwroot/js/features/all-day/AllDayDragService.d.ts new file mode 100644 index 0000000..602d2e2 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDragService.d.ts @@ -0,0 +1,50 @@ +/** + * AllDayDragService - Manages drag and drop operations for all-day events + * + * STATELESS SERVICE - Reads all data from DOM via AllDayDomReader + * - No persistent state + * - Handles timed → all-day conversion + * - Handles all-day → all-day repositioning + * - Handles column changes during drag + * - Calculates layouts on-demand from DOM + */ +import { IEventLayout } from '../../utils/AllDayLayoutEngine'; +import { IDragMouseEnterHeaderEventPayload, IDragColumnChangeEventPayload, IDragEndEventPayload } from '../../types/EventTypes'; +import { EventManager } from '../../managers/EventManager'; +import { AllDayEventRenderer } from '../../renderers/AllDayEventRenderer'; +import { DateService } from '../../utils/DateService'; +export declare class AllDayDragService { + private eventManager; + private allDayEventRenderer; + private dateService; + constructor(eventManager: EventManager, allDayEventRenderer: AllDayEventRenderer, dateService: DateService); + /** + * Handle conversion from timed event to all-day event + * Called when dragging a timed event into the header + */ + handleConvertToAllDay(payload: IDragMouseEnterHeaderEventPayload): void; + /** + * Handle column change during drag of all-day event + * Updates grid position while maintaining event span + */ + handleColumnChange(payload: IDragColumnChangeEventPayload): void; + /** + * Handle drag end for all-day → all-day drops + * Recalculates layouts and updates event positions + */ + handleDragEnd(dragEndEvent: IDragEndEventPayload): Promise; + /** + * Calculate layouts for events using AllDayLayoutEngine + */ + private calculateLayouts; + /** + * Apply layout updates to DOM elements + * Only updates elements that have changed position + * Public so AllDayCoordinator can use it for full recalculation + */ + applyLayoutUpdates(newLayouts: IEventLayout[]): void; + /** + * Fade out and remove element + */ + private fadeOutAndRemove; +} diff --git a/wwwroot/js/features/all-day/AllDayDragService.js b/wwwroot/js/features/all-day/AllDayDragService.js new file mode 100644 index 0000000..000994b --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDragService.js @@ -0,0 +1,183 @@ +/** + * AllDayDragService - Manages drag and drop operations for all-day events + * + * STATELESS SERVICE - Reads all data from DOM via AllDayDomReader + * - No persistent state + * - Handles timed → all-day conversion + * - Handles all-day → all-day repositioning + * - Handles column changes during drag + * - Calculates layouts on-demand from DOM + */ +import { SwpAllDayEventElement } from '../../elements/SwpEventElement'; +import { AllDayLayoutEngine } from '../../utils/AllDayLayoutEngine'; +import { ColumnDetectionUtils } from '../../utils/ColumnDetectionUtils'; +import { ALL_DAY_CONSTANTS } from '../../configurations/CalendarConfig'; +import { AllDayDomReader } from './AllDayDomReader'; +export class AllDayDragService { + constructor(eventManager, allDayEventRenderer, dateService) { + this.eventManager = eventManager; + this.allDayEventRenderer = allDayEventRenderer; + this.dateService = dateService; + } + /** + * Handle conversion from timed event to all-day event + * Called when dragging a timed event into the header + */ + handleConvertToAllDay(payload) { + const allDayContainer = AllDayDomReader.getAllDayContainer(); + if (!allDayContainer) + return; + // Create SwpAllDayEventElement from ICalendarEvent + const allDayElement = SwpAllDayEventElement.fromCalendarEvent(payload.calendarEvent); + // Apply grid positioning + allDayElement.style.gridRow = '1'; + allDayElement.style.gridColumn = payload.targetColumn.index.toString(); + // Remove old swp-event clone + payload.draggedClone.remove(); + // Call delegate to update DragDropManager's draggedClone reference + payload.replaceClone(allDayElement); + // Append to container + allDayContainer.appendChild(allDayElement); + ColumnDetectionUtils.updateColumnBoundsCache(); + } + /** + * Handle column change during drag of all-day event + * Updates grid position while maintaining event span + */ + handleColumnChange(payload) { + const allDayContainer = AllDayDomReader.getAllDayContainer(); + if (!allDayContainer) + return; + const targetColumn = ColumnDetectionUtils.getColumnBounds(payload.mousePosition); + if (!targetColumn || !payload.draggedClone) + return; + // Calculate event span from original grid positioning + const { start: gridColumnStart, end: gridColumnEnd } = AllDayDomReader.getGridColumnRange(payload.draggedClone); + const span = gridColumnEnd - gridColumnStart; + // Update clone position maintaining the span + const newStartColumn = targetColumn.index; + const newEndColumn = newStartColumn + span; + payload.draggedClone.style.gridColumn = `${newStartColumn} / ${newEndColumn}`; + } + /** + * Handle drag end for all-day → all-day drops + * Recalculates layouts and updates event positions + */ + async handleDragEnd(dragEndEvent) { + if (!dragEndEvent.draggedClone) + return; + // Normalize clone ID + dragEndEvent.draggedClone.dataset.eventId = dragEndEvent.draggedClone.dataset.eventId?.replace('clone-', ''); + dragEndEvent.draggedClone.style.pointerEvents = ''; // Re-enable pointer events + dragEndEvent.originalElement.dataset.eventId += '_'; + const eventId = dragEndEvent.draggedClone.dataset.eventId; + const eventDate = dragEndEvent.finalPosition.column?.date; + const eventType = dragEndEvent.draggedClone.dataset.type; + if (!eventDate || !eventId || !eventType) + return; + // Get original dates to preserve time + const originalStartDate = new Date(dragEndEvent.draggedClone.dataset.start); + const originalEndDate = new Date(dragEndEvent.draggedClone.dataset.end); + // Calculate actual duration in milliseconds (preserves hours/minutes/seconds) + const durationMs = originalEndDate.getTime() - originalStartDate.getTime(); + // Create new start date with the new day but preserve original time + const newStartDate = new Date(eventDate); + newStartDate.setHours(originalStartDate.getHours(), originalStartDate.getMinutes(), originalStartDate.getSeconds(), originalStartDate.getMilliseconds()); + // Create new end date by adding duration in milliseconds + const newEndDate = new Date(newStartDate.getTime() + durationMs); + // Update data attributes with new dates (convert to UTC) + dragEndEvent.draggedClone.dataset.start = this.dateService.toUTC(newStartDate); + dragEndEvent.draggedClone.dataset.end = this.dateService.toUTC(newEndDate); + const droppedEvent = { + id: eventId, + title: dragEndEvent.draggedClone.dataset.title || '', + start: newStartDate, + end: newEndDate, + type: eventType, + allDay: true, + syncStatus: 'synced' + }; + // Get all events from DOM and recalculate layouts + const allEventsFromDOM = AllDayDomReader.getEventsAsData(); + const weekDates = ColumnDetectionUtils.getColumns(); + // Replace old event with dropped event + const updatedEvents = [ + ...allEventsFromDOM.filter(event => event.id !== eventId), + droppedEvent + ]; + // Calculate new layouts for ALL events + const newLayouts = this.calculateLayouts(updatedEvents, weekDates); + // Apply layout updates to DOM + this.applyLayoutUpdates(newLayouts); + // Clean up drag styles from the dropped clone + dragEndEvent.draggedClone.classList.remove('dragging'); + dragEndEvent.draggedClone.style.zIndex = ''; + dragEndEvent.draggedClone.style.cursor = ''; + dragEndEvent.draggedClone.style.opacity = ''; + // Apply highlight class to show the dropped event with highlight color + dragEndEvent.draggedClone.classList.add('highlight'); + // Update event in repository to mark as allDay=true + await this.eventManager.updateEvent(eventId, { + start: newStartDate, + end: newEndDate, + allDay: true + }); + this.fadeOutAndRemove(dragEndEvent.originalElement); + } + /** + * Calculate layouts for events using AllDayLayoutEngine + */ + calculateLayouts(events, weekDates) { + const layoutEngine = new AllDayLayoutEngine(weekDates.map(column => column.date)); + return layoutEngine.calculateLayout(events); + } + /** + * Apply layout updates to DOM elements + * Only updates elements that have changed position + * Public so AllDayCoordinator can use it for full recalculation + */ + applyLayoutUpdates(newLayouts) { + const container = AllDayDomReader.getAllDayContainer(); + if (!container) + return; + // Read current layouts from DOM + const currentLayoutsMap = AllDayDomReader.getCurrentLayouts(); + newLayouts.forEach((layout) => { + const currentLayout = currentLayoutsMap.get(layout.calenderEvent.id); + // Only update if layout changed + if (currentLayout?.gridArea !== layout.gridArea) { + const element = container.querySelector(`[data-event-id="${layout.calenderEvent.id}"]`); + if (element) { + element.classList.add('transitioning'); + element.style.gridArea = layout.gridArea; + element.style.gridRow = layout.row.toString(); + element.style.gridColumn = `${layout.startColumn} / ${layout.endColumn + 1}`; + // Update overflow classes based on row + element.classList.remove('max-event-overflow-hide', 'max-event-overflow-show'); + if (layout.row > ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS) { + const isExpanded = AllDayDomReader.isExpanded(); + if (isExpanded) { + element.classList.add('max-event-overflow-show'); + } + else { + element.classList.add('max-event-overflow-hide'); + } + } + // Remove transition class after animation + setTimeout(() => element.classList.remove('transitioning'), 200); + } + } + }); + } + /** + * Fade out and remove element + */ + fadeOutAndRemove(element) { + element.style.transition = 'opacity 0.3s ease-out'; + element.style.opacity = '0'; + setTimeout(() => { + element.remove(); + }, 300); + } +} +//# sourceMappingURL=AllDayDragService.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayDragService.js.map b/wwwroot/js/features/all-day/AllDayDragService.js.map new file mode 100644 index 0000000..cd7900e --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayDragService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayDragService.js","sourceRoot":"","sources":["../../../../src/features/all-day/AllDayDragService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayHeightService.d.ts b/wwwroot/js/features/all-day/AllDayHeightService.d.ts new file mode 100644 index 0000000..bf02632 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayHeightService.d.ts @@ -0,0 +1,26 @@ +/** + * AllDayHeightService - Manages all-day row height calculations and animations + * + * STATELESS SERVICE - Reads all data from DOM via AllDayDomReader + * - No persistent state + * - Calculates required rows by reading DOM elements + * - Animates header height based on DOM state + */ +export declare class AllDayHeightService { + /** + * Main entry point - recalculate and animate header height based on DOM + */ + recalculateAndAnimate(): void; + /** + * Animate all-day container to specific number of rows + */ + animateToRows(targetRows: number): void; + /** + * Calculate all-day height based on number of rows + */ + private calculateAllDayHeight; + /** + * Collapse all-day row (animate to 0 rows) + */ + collapseAllDayRow(): void; +} diff --git a/wwwroot/js/features/all-day/AllDayHeightService.js b/wwwroot/js/features/all-day/AllDayHeightService.js new file mode 100644 index 0000000..17d344d --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayHeightService.js @@ -0,0 +1,85 @@ +/** + * AllDayHeightService - Manages all-day row height calculations and animations + * + * STATELESS SERVICE - Reads all data from DOM via AllDayDomReader + * - No persistent state + * - Calculates required rows by reading DOM elements + * - Animates header height based on DOM state + */ +import { ALL_DAY_CONSTANTS } from '../../configurations/CalendarConfig'; +import { eventBus } from '../../core/EventBus'; +import { AllDayDomReader } from './AllDayDomReader'; +export class AllDayHeightService { + /** + * Main entry point - recalculate and animate header height based on DOM + */ + recalculateAndAnimate() { + const requiredRows = AllDayDomReader.getMaxRowFromEvents(); + this.animateToRows(requiredRows); + } + /** + * Animate all-day container to specific number of rows + */ + animateToRows(targetRows) { + const { targetHeight, currentHeight, heightDifference } = this.calculateAllDayHeight(targetRows); + if (targetHeight === currentHeight) + return; // No animation needed + console.log(`🎬 All-day height animation: ${currentHeight}px → ${targetHeight}px (${Math.ceil(currentHeight / ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT)} → ${targetRows} rows)`); + // Get elements + const calendarHeader = AllDayDomReader.getCalendarHeader(); + const headerSpacer = AllDayDomReader.getHeaderSpacer(); + const allDayContainer = AllDayDomReader.getAllDayContainer(); + if (!calendarHeader || !allDayContainer) + return; + // Get current parent height for animation + const currentParentHeight = parseFloat(getComputedStyle(calendarHeader).height); + const targetParentHeight = currentParentHeight + heightDifference; + const animations = [ + calendarHeader.animate([ + { height: `${currentParentHeight}px` }, + { height: `${targetParentHeight}px` } + ], { + duration: 150, + easing: 'ease-out', + fill: 'forwards' + }) + ]; + // Add spacer animation if spacer exists + if (headerSpacer) { + const root = document.documentElement; + const headerHeightStr = root.style.getPropertyValue('--header-height'); + const headerHeight = parseInt(headerHeightStr); + const currentSpacerHeight = headerHeight + currentHeight; + const targetSpacerHeight = headerHeight + targetHeight; + animations.push(headerSpacer.animate([ + { height: `${currentSpacerHeight}px` }, + { height: `${targetSpacerHeight}px` } + ], { + duration: 150, + easing: 'ease-out' + })); + } + // Update CSS variable after animation + Promise.all(animations.map(anim => anim.finished)).then(() => { + const root = document.documentElement; + root.style.setProperty('--all-day-row-height', `${targetHeight}px`); + eventBus.emit('header:height-changed'); + }); + } + /** + * Calculate all-day height based on number of rows + */ + calculateAllDayHeight(targetRows) { + const targetHeight = targetRows * ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT; + const currentHeight = AllDayDomReader.getCurrentHeight(); + const heightDifference = targetHeight - currentHeight; + return { targetHeight, currentHeight, heightDifference }; + } + /** + * Collapse all-day row (animate to 0 rows) + */ + collapseAllDayRow() { + this.animateToRows(0); + } +} +//# sourceMappingURL=AllDayHeightService.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/AllDayHeightService.js.map b/wwwroot/js/features/all-day/AllDayHeightService.js.map new file mode 100644 index 0000000..7652b58 --- /dev/null +++ b/wwwroot/js/features/all-day/AllDayHeightService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayHeightService.js","sourceRoot":"","sources":["../../../../src/features/all-day/AllDayHeightService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/index.d.ts b/wwwroot/js/features/all-day/index.d.ts new file mode 100644 index 0000000..2cd4836 --- /dev/null +++ b/wwwroot/js/features/all-day/index.d.ts @@ -0,0 +1,9 @@ +/** + * All-day feature barrel export + * + * Exports all public APIs from the all-day feature + */ +export { AllDayCoordinator } from './AllDayCoordinator'; +export { AllDayHeightService } from './AllDayHeightService'; +export { AllDayCollapseService } from './AllDayCollapseService'; +export { AllDayDragService } from './AllDayDragService'; diff --git a/wwwroot/js/features/all-day/index.js b/wwwroot/js/features/all-day/index.js new file mode 100644 index 0000000..ad0078d --- /dev/null +++ b/wwwroot/js/features/all-day/index.js @@ -0,0 +1,10 @@ +/** + * All-day feature barrel export + * + * Exports all public APIs from the all-day feature + */ +export { AllDayCoordinator } from './AllDayCoordinator'; +export { AllDayHeightService } from './AllDayHeightService'; +export { AllDayCollapseService } from './AllDayCollapseService'; +export { AllDayDragService } from './AllDayDragService'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/index.js.map b/wwwroot/js/features/all-day/index.js.map new file mode 100644 index 0000000..166080e --- /dev/null +++ b/wwwroot/js/features/all-day/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/features/all-day/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/features/all-day/utils/AllDayDomReader.d.ts b/wwwroot/js/features/all-day/utils/AllDayDomReader.d.ts new file mode 100644 index 0000000..7026c04 --- /dev/null +++ b/wwwroot/js/features/all-day/utils/AllDayDomReader.d.ts @@ -0,0 +1,74 @@ +import { ICalendarEvent } from '../../../types/CalendarTypes'; +/** + * AllDayDomReader - Centralized DOM reading utilities for all-day services + * + * STATELESS UTILITY - Pure functions for reading DOM state + * - Consistent selectors across all services + * - Unified computed style approach (not inline styles) + * - Type-safe return values + * - Single source of truth for DOM queries + */ +export declare class AllDayDomReader { + /** + * Get the all-day events container element + */ + static getAllDayContainer(): HTMLElement | null; + /** + * Get the calendar header element + */ + static getCalendarHeader(): HTMLElement | null; + /** + * Get the header spacer element + */ + static getHeaderSpacer(): HTMLElement | null; + /** + * Get all all-day event elements (excluding overflow indicators) + * Returns raw HTMLElements for DOM manipulation + */ + static getEventElements(): HTMLElement[]; + /** + * Get all-day events as ICalendarEvent objects + * Returns parsed data for business logic + */ + static getEventsAsData(): ICalendarEvent[]; + /** + * Get grid row from element using computed style + * Always uses computed style for consistency + */ + static getGridRow(element: HTMLElement): number; + /** + * Get grid column range from element using computed style + */ + static getGridColumnRange(element: HTMLElement): { + start: number; + end: number; + }; + /** + * Get grid area from element using computed style + */ + static getGridArea(element: HTMLElement): string; + /** + * Calculate max row number from all events + * Uses computed styles for accurate reading + */ + static getMaxRowFromEvents(): number; + /** + * Check if all-day container is expanded + */ + static isExpanded(): boolean; + /** + * Get current all-day height from CSS variable + */ + static getCurrentHeight(): number; + /** + * Count events in specific column + */ + static countEventsInColumn(columnIndex: number): number; + /** + * Get current layouts from DOM elements + * Returns map of eventId → layout info for comparison + */ + static getCurrentLayouts(): Map; +} diff --git a/wwwroot/js/features/all-day/utils/AllDayDomReader.js b/wwwroot/js/features/all-day/utils/AllDayDomReader.js new file mode 100644 index 0000000..93405ca --- /dev/null +++ b/wwwroot/js/features/all-day/utils/AllDayDomReader.js @@ -0,0 +1,175 @@ +/** + * AllDayDomReader - Centralized DOM reading utilities for all-day services + * + * STATELESS UTILITY - Pure functions for reading DOM state + * - Consistent selectors across all services + * - Unified computed style approach (not inline styles) + * - Type-safe return values + * - Single source of truth for DOM queries + */ +export class AllDayDomReader { + // ============================================ + // CONTAINER GETTERS + // ============================================ + /** + * Get the all-day events container element + */ + static getAllDayContainer() { + return document.querySelector('swp-calendar-header swp-allday-container'); + } + /** + * Get the calendar header element + */ + static getCalendarHeader() { + return document.querySelector('swp-calendar-header'); + } + /** + * Get the header spacer element + */ + static getHeaderSpacer() { + return document.querySelector('swp-header-spacer'); + } + // ============================================ + // EVENT ELEMENT GETTERS + // ============================================ + /** + * Get all all-day event elements (excluding overflow indicators) + * Returns raw HTMLElements for DOM manipulation + */ + static getEventElements() { + const container = this.getAllDayContainer(); + if (!container) + return []; + return Array.from(container.querySelectorAll('swp-allday-event:not(.max-event-indicator)')); + } + /** + * Get all-day events as ICalendarEvent objects + * Returns parsed data for business logic + */ + static getEventsAsData() { + const elements = this.getEventElements(); + return elements + .map(element => { + const eventId = element.dataset.eventId; + const startStr = element.dataset.start; + const endStr = element.dataset.end; + // Validate required fields + if (!eventId || !startStr || !endStr) { + console.warn('AllDayDomReader: Invalid event data in DOM:', element); + return null; + } + const start = new Date(startStr); + const end = new Date(endStr); + if (isNaN(start.getTime()) || isNaN(end.getTime())) { + console.warn('AllDayDomReader: Invalid event dates:', { startStr, endStr }); + return null; + } + return { + id: eventId, + title: element.dataset.title || '', + start, + end, + type: element.dataset.type || 'task', + allDay: true, + syncStatus: (element.dataset.syncStatus || 'synced') + }; + }) + .filter((event) => event !== null); + } + // ============================================ + // GRID POSITION READERS + // ============================================ + /** + * Get grid row from element using computed style + * Always uses computed style for consistency + */ + static getGridRow(element) { + const computedStyle = window.getComputedStyle(element); + return parseInt(computedStyle.gridRowStart) || 0; + } + /** + * Get grid column range from element using computed style + */ + static getGridColumnRange(element) { + const computedStyle = window.getComputedStyle(element); + return { + start: parseInt(computedStyle.gridColumnStart) || 0, + end: parseInt(computedStyle.gridColumnEnd) || 0 + }; + } + /** + * Get grid area from element using computed style + */ + static getGridArea(element) { + const computedStyle = window.getComputedStyle(element); + return computedStyle.gridArea; + } + /** + * Calculate max row number from all events + * Uses computed styles for accurate reading + */ + static getMaxRowFromEvents() { + const events = this.getEventElements(); + if (events.length === 0) + return 0; + let maxRow = 0; + events.forEach(event => { + const row = this.getGridRow(event); + maxRow = Math.max(maxRow, row); + }); + return maxRow; + } + // ============================================ + // STATE READERS + // ============================================ + /** + * Check if all-day container is expanded + */ + static isExpanded() { + const container = this.getAllDayContainer(); + return container?.classList.contains('expanded') || false; + } + /** + * Get current all-day height from CSS variable + */ + static getCurrentHeight() { + const root = document.documentElement; + const heightStr = root.style.getPropertyValue('--all-day-row-height') || '0px'; + return parseInt(heightStr) || 0; + } + /** + * Count events in specific column + */ + static countEventsInColumn(columnIndex) { + const events = this.getEventElements(); + let count = 0; + events.forEach((event) => { + const { start, end } = this.getGridColumnRange(event); + if (start <= columnIndex && end > columnIndex) { + count++; + } + }); + return count; + } + // ============================================ + // LAYOUT READERS + // ============================================ + /** + * Get current layouts from DOM elements + * Returns map of eventId → layout info for comparison + */ + static getCurrentLayouts() { + const layoutsMap = new Map(); + const events = this.getEventElements(); + events.forEach(event => { + const eventId = event.dataset.eventId; + if (eventId) { + layoutsMap.set(eventId, { + gridArea: this.getGridArea(event) + }); + } + }); + return layoutsMap; + } +} +//# sourceMappingURL=AllDayDomReader.js.map \ No newline at end of file diff --git a/wwwroot/js/features/all-day/utils/AllDayDomReader.js.map b/wwwroot/js/features/all-day/utils/AllDayDomReader.js.map new file mode 100644 index 0000000..5c193a7 --- /dev/null +++ b/wwwroot/js/features/all-day/utils/AllDayDomReader.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayDomReader.js","sourceRoot":"","sources":["../../../../../src/features/all-day/utils/AllDayDomReader.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/index.d.ts b/wwwroot/js/index.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/wwwroot/js/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/wwwroot/js/index.js b/wwwroot/js/index.js new file mode 100644 index 0000000..c6d0063 --- /dev/null +++ b/wwwroot/js/index.js @@ -0,0 +1,171 @@ +// Main entry point for Calendar Plantempus +import { Container } from '@novadi/core'; +import { eventBus } from './core/EventBus'; +import { ConfigManager } from './configurations/ConfigManager'; +import { URLManager } from './utils/URLManager'; +// Import all managers +import { EventManager } from './managers/EventManager'; +import { EventRenderingService } from './renderers/EventRendererManager'; +import { GridManager } from './managers/GridManager'; +import { ScrollManager } from './managers/ScrollManager'; +import { NavigationManager } from './managers/NavigationManager'; +import { NavigationButtons } from './components/NavigationButtons'; +import { ViewSelector } from './components/ViewSelector'; +import { CalendarManager } from './managers/CalendarManager'; +import { DragDropManager } from './managers/DragDropManager'; +import { AllDayManager } from './managers/AllDayManager'; +import { ResizeHandleManager } from './managers/ResizeHandleManager'; +import { EdgeScrollManager } from './managers/EdgeScrollManager'; +import { HeaderManager } from './managers/HeaderManager'; +import { WorkweekPresets } from './components/WorkweekPresets'; +import { IndexedDBEventRepository } from './repositories/IndexedDBEventRepository'; +import { ApiEventRepository } from './repositories/ApiEventRepository'; +import { IndexedDBService } from './storage/IndexedDBService'; +import { OperationQueue } from './storage/OperationQueue'; +// Import workers +import { SyncManager } from './workers/SyncManager'; +// Import renderers +import { DateHeaderRenderer } from './renderers/DateHeaderRenderer'; +import { DateColumnRenderer } from './renderers/ColumnRenderer'; +import { DateEventRenderer } from './renderers/EventRenderer'; +import { AllDayEventRenderer } from './renderers/AllDayEventRenderer'; +import { GridRenderer } from './renderers/GridRenderer'; +import { WeekInfoRenderer } from './renderers/WeekInfoRenderer'; +// Import utilities and services +import { DateService } from './utils/DateService'; +import { TimeFormatter } from './utils/TimeFormatter'; +import { PositionUtils } from './utils/PositionUtils'; +import { WorkHoursManager } from './managers/WorkHoursManager'; +import { EventStackManager } from './managers/EventStackManager'; +import { EventLayoutCoordinator } from './managers/EventLayoutCoordinator'; +/** + * Handle deep linking functionality after managers are initialized + */ +async function handleDeepLinking(eventManager, urlManager) { + try { + const eventId = urlManager.parseEventIdFromURL(); + if (eventId) { + console.log(`Deep linking to event ID: ${eventId}`); + // Wait a bit for managers to be fully ready + setTimeout(async () => { + const success = await eventManager.navigateToEvent(eventId); + if (!success) { + console.warn(`Deep linking failed: Event with ID ${eventId} not found`); + } + }, 500); + } + } + catch (error) { + console.warn('Deep linking failed:', error); + } +} +/** + * Initialize the calendar application using NovaDI + */ +async function initializeCalendar() { + try { + // Load configuration from JSON + const config = await ConfigManager.load(); + // Create NovaDI container + const container = new Container(); + const builder = container.builder(); + // Enable debug mode for development + eventBus.setDebug(true); + // Bind core services as instances + builder.registerInstance(eventBus).as(); + // Register configuration instance + builder.registerInstance(config).as(); + // Register storage and repository services + builder.registerType(IndexedDBService).as(); + builder.registerType(OperationQueue).as(); + builder.registerType(ApiEventRepository).as(); + builder.registerType(IndexedDBEventRepository).as(); + // Register workers + builder.registerType(SyncManager).as(); + // Register renderers + builder.registerType(DateHeaderRenderer).as(); + builder.registerType(DateColumnRenderer).as(); + builder.registerType(DateEventRenderer).as(); + // Register core services and utilities + builder.registerType(DateService).as(); + builder.registerType(EventStackManager).as(); + builder.registerType(EventLayoutCoordinator).as(); + builder.registerType(WorkHoursManager).as(); + builder.registerType(URLManager).as(); + builder.registerType(TimeFormatter).as(); + builder.registerType(PositionUtils).as(); + // Note: AllDayLayoutEngine is instantiated per-operation with specific dates, not a singleton + builder.registerType(WeekInfoRenderer).as(); + builder.registerType(AllDayEventRenderer).as(); + builder.registerType(EventRenderingService).as(); + builder.registerType(GridRenderer).as(); + builder.registerType(GridManager).as(); + builder.registerType(ScrollManager).as(); + builder.registerType(NavigationManager).as(); + builder.registerType(NavigationButtons).as(); + builder.registerType(ViewSelector).as(); + builder.registerType(DragDropManager).as(); + builder.registerType(AllDayManager).as(); + builder.registerType(ResizeHandleManager).as(); + builder.registerType(EdgeScrollManager).as(); + builder.registerType(HeaderManager).as(); + builder.registerType(CalendarManager).as(); + builder.registerType(WorkweekPresets).as(); + builder.registerType(ConfigManager).as(); + builder.registerType(EventManager).as(); + // Build the container + const app = builder.build(); + // Get managers from container + const eb = app.resolveType(); + const calendarManager = app.resolveType(); + const eventManager = app.resolveType(); + const resizeHandleManager = app.resolveType(); + const headerManager = app.resolveType(); + const dragDropManager = app.resolveType(); + const viewSelectorManager = app.resolveType(); + const navigationManager = app.resolveType(); + const navigationButtonsManager = app.resolveType(); + const edgeScrollManager = app.resolveType(); + const allDayManager = app.resolveType(); + const urlManager = app.resolveType(); + const workweekPresetsManager = app.resolveType(); + const configManager = app.resolveType(); + // Initialize managers + await calendarManager.initialize?.(); + await resizeHandleManager.initialize?.(); + // Resolve SyncManager (starts automatically in constructor) + // Resolve SyncManager (starts automatically in constructor) + // Resolve SyncManager (starts automatically in constructor) + // Resolve SyncManager (starts automatically in constructor) + // Resolve SyncManager (starts automatically in constructor) + //const syncManager = app.resolveType(); + // Handle deep linking after managers are initialized + await handleDeepLinking(eventManager, urlManager); + // Expose to window for debugging (with proper typing) + window.calendarDebug = { + eventBus, + app, + calendarManager, + eventManager, + workweekPresetsManager, + //syncManager, + }; + } + catch (error) { + throw error; + } +} +// Initialize when DOM is ready - now handles async properly +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { + initializeCalendar().catch(error => { + console.error('Calendar initialization failed:', error); + }); + }); +} +else { + initializeCalendar().catch(error => { + console.error('Calendar initialization failed:', error); + }); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/wwwroot/js/index.js.map b/wwwroot/js/index.js.map new file mode 100644 index 0000000..089ad70 --- /dev/null +++ b/wwwroot/js/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/interfaces/IManager.d.ts b/wwwroot/js/interfaces/IManager.d.ts new file mode 100644 index 0000000..581e5fd --- /dev/null +++ b/wwwroot/js/interfaces/IManager.d.ts @@ -0,0 +1,48 @@ +import { CalendarEvent } from '../types/CalendarTypes'; +/** + * Base interface for all managers + */ +export interface IManager { + /** + * Initialize the manager + */ + initialize?(): Promise | void; + /** + * Refresh the manager's state + */ + refresh?(): void; + /** + * Destroy the manager and clean up resources + */ + destroy?(): void; +} +/** + * Interface for managers that handle events + */ +export interface IEventManager extends IManager { + loadData(): Promise; + getEvents(): CalendarEvent[]; + getEventsForPeriod(startDate: Date, endDate: Date): CalendarEvent[]; +} +/** + * Interface for managers that handle rendering + */ +export interface IRenderingManager extends IManager { + render(): Promise | void; +} +/** + * Interface for managers that handle navigation + */ +export interface INavigationManager extends IManager { + getCurrentWeek(): Date; + navigateToToday(): void; + navigateToNextWeek(): void; + navigateToPreviousWeek(): void; +} +/** + * Interface for managers that handle scrolling + */ +export interface IScrollManager extends IManager { + scrollTo(scrollTop: number): void; + scrollToHour(hour: number): void; +} diff --git a/wwwroot/js/interfaces/IManager.js b/wwwroot/js/interfaces/IManager.js new file mode 100644 index 0000000..6768e2b --- /dev/null +++ b/wwwroot/js/interfaces/IManager.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=IManager.js.map \ No newline at end of file diff --git a/wwwroot/js/interfaces/IManager.js.map b/wwwroot/js/interfaces/IManager.js.map new file mode 100644 index 0000000..6495ffb --- /dev/null +++ b/wwwroot/js/interfaces/IManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"IManager.js","sourceRoot":"","sources":["../../../src/interfaces/IManager.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/managers/AllDayManager.d.ts b/wwwroot/js/managers/AllDayManager.d.ts new file mode 100644 index 0000000..0fc9919 --- /dev/null +++ b/wwwroot/js/managers/AllDayManager.d.ts @@ -0,0 +1,91 @@ +import { AllDayEventRenderer } from '../renderers/AllDayEventRenderer'; +import { EventManager } from './EventManager'; +import { DateService } from '../utils/DateService'; +/** + * AllDayManager - Handles all-day row height animations and management + * Uses AllDayLayoutEngine for all overlap detection and layout calculation + */ +export declare class AllDayManager { + private allDayEventRenderer; + private eventManager; + private dateService; + private layoutEngine; + private currentAllDayEvents; + private currentWeekDates; + private isExpanded; + private actualRowCount; + constructor(eventManager: EventManager, allDayEventRenderer: AllDayEventRenderer, dateService: DateService); + /** + * Setup event listeners for drag conversions + */ + private setupEventListeners; + private getAllDayContainer; + private getCalendarHeader; + private getHeaderSpacer; + /** + * Read current max row from DOM elements + * Excludes events marked as removing (data-removing attribute) + */ + private getMaxRowFromDOM; + /** + * Get current gridArea for an event from DOM + */ + private getGridAreaFromDOM; + /** + * Count events in a specific column by reading DOM + */ + private countEventsInColumnFromDOM; + /** + * Calculate all-day height based on number of rows + */ + private calculateAllDayHeight; + /** + * Check current all-day events and animate to correct height + * Reads max row directly from DOM elements + */ + checkAndAnimateAllDayHeight(): void; + /** + * Animate all-day container to specific number of rows + */ + animateToRows(targetRows: number): void; + /** + * Calculate layout for ALL all-day events using AllDayLayoutEngine + * This is the correct method that processes all events together for proper overlap detection + */ + private calculateAllDayEventsLayout; + private handleConvertToAllDay; + /** + * Handle drag move for all-day events - SPECIALIZED FOR ALL-DAY CONTAINER + */ + private handleColumnChange; + private fadeOutAndRemove; + /** + * Handle timed → all-day conversion on drop + */ + private handleTimedToAllDayDrop; + /** + * Handle all-day → all-day drop (moving within header) + */ + private handleDragEnd; + /** + * Update chevron button visibility and state + */ + private updateChevronButton; + /** + * Toggle between expanded and collapsed state + */ + private toggleExpanded; + /** + * Count number of events in a specific column using IColumnBounds + * Reads directly from DOM elements + */ + private countEventsInColumn; + /** + * Update overflow indicators for collapsed state + */ + private updateOverflowIndicators; + /** + * Clear overflow indicators and restore normal state + */ + private clearOverflowIndicators; +} diff --git a/wwwroot/js/managers/AllDayManager.js b/wwwroot/js/managers/AllDayManager.js new file mode 100644 index 0000000..4fb2956 --- /dev/null +++ b/wwwroot/js/managers/AllDayManager.js @@ -0,0 +1,528 @@ +// All-day row height management and animations +import { eventBus } from '../core/EventBus'; +import { ALL_DAY_CONSTANTS } from '../configurations/CalendarConfig'; +import { AllDayLayoutEngine } from '../utils/AllDayLayoutEngine'; +import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils'; +import { SwpAllDayEventElement } from '../elements/SwpEventElement'; +import { CoreEvents } from '../constants/CoreEvents'; +/** + * AllDayManager - Handles all-day row height animations and management + * Uses AllDayLayoutEngine for all overlap detection and layout calculation + */ +export class AllDayManager { + constructor(eventManager, allDayEventRenderer, dateService) { + this.layoutEngine = null; + // State tracking for layout calculation + this.currentAllDayEvents = []; + this.currentWeekDates = []; + // Expand/collapse state + this.isExpanded = false; + this.actualRowCount = 0; + this.eventManager = eventManager; + this.allDayEventRenderer = allDayEventRenderer; + this.dateService = dateService; + // Sync CSS variable with TypeScript constant to ensure consistency + document.documentElement.style.setProperty('--single-row-height', `${ALL_DAY_CONSTANTS.EVENT_HEIGHT}px`); + this.setupEventListeners(); + } + /** + * Setup event listeners for drag conversions + */ + setupEventListeners() { + eventBus.on('drag:mouseenter-header', (event) => { + const payload = event.detail; + if (payload.draggedClone.hasAttribute('data-allday')) + return; + console.log('🔄 AllDayManager: Received drag:mouseenter-header', { + targetDate: payload.targetColumn, + originalElementId: payload.originalElement?.dataset?.eventId, + originalElementTag: payload.originalElement?.tagName + }); + this.handleConvertToAllDay(payload); + }); + eventBus.on('drag:mouseleave-header', (event) => { + const { originalElement, cloneElement } = event.detail; + console.log('🚪 AllDayManager: Received drag:mouseleave-header', { + originalElementId: originalElement?.dataset?.eventId + }); + }); + // Listen for drag operations on all-day events + eventBus.on('drag:start', (event) => { + let payload = event.detail; + if (!payload.draggedClone?.hasAttribute('data-allday')) { + return; + } + this.allDayEventRenderer.handleDragStart(payload); + }); + eventBus.on('drag:column-change', (event) => { + let payload = event.detail; + if (!payload.draggedClone?.hasAttribute('data-allday')) { + return; + } + this.handleColumnChange(payload); + }); + eventBus.on('drag:end', (event) => { + let dragEndPayload = event.detail; + console.log('🎯 AllDayManager: drag:end received', { + target: dragEndPayload.target, + originalElementTag: dragEndPayload.originalElement?.tagName, + hasAllDayAttribute: dragEndPayload.originalElement?.hasAttribute('data-allday'), + eventId: dragEndPayload.originalElement?.dataset.eventId + }); + // Handle all-day → all-day drops (within header) + if (dragEndPayload.target === 'swp-day-header' && dragEndPayload.originalElement?.hasAttribute('data-allday')) { + console.log('✅ AllDayManager: Handling all-day → all-day drop'); + this.handleDragEnd(dragEndPayload); + return; + } + // Handle timed → all-day conversion (dropped in header) + if (dragEndPayload.target === 'swp-day-header' && !dragEndPayload.originalElement?.hasAttribute('data-allday')) { + console.log('🔄 AllDayManager: Timed → all-day conversion on drop'); + this.handleTimedToAllDayDrop(dragEndPayload); + return; + } + // Handle all-day → timed conversion (dropped in column) + if (dragEndPayload.target === 'swp-day-column' && dragEndPayload.originalElement?.hasAttribute('data-allday')) { + const eventId = dragEndPayload.originalElement.dataset.eventId; + console.log('🔄 AllDayManager: All-day → timed conversion', { eventId }); + // Mark for removal (sets data-removing attribute) + this.fadeOutAndRemove(dragEndPayload.originalElement); + // Recalculate layout WITHOUT the removed event to compress gaps + const remainingEvents = this.currentAllDayEvents.filter(e => e.id !== eventId); + const newLayouts = this.calculateAllDayEventsLayout(remainingEvents, this.currentWeekDates); + // Re-render all-day events with compressed layout + this.allDayEventRenderer.renderAllDayEventsForPeriod(newLayouts); + // NOW animate height with compressed layout + this.checkAndAnimateAllDayHeight(); + } + }); + // Listen for drag cancellation to recalculate height + eventBus.on('drag:cancelled', (event) => { + const { draggedElement, reason } = event.detail; + console.log('🚫 AllDayManager: Drag cancelled', { + eventId: draggedElement?.dataset?.eventId, + reason + }); + }); + // Listen for header ready - when dates are populated with period data + eventBus.on('header:ready', async (event) => { + let headerReadyEventPayload = event.detail; + let startDate = new Date(headerReadyEventPayload.headerElements.at(0).date); + let endDate = new Date(headerReadyEventPayload.headerElements.at(-1).date); + let events = await this.eventManager.getEventsForPeriod(startDate, endDate); + // Filter for all-day events + const allDayEvents = events.filter(event => event.allDay); + const layouts = this.calculateAllDayEventsLayout(allDayEvents, headerReadyEventPayload.headerElements); + this.allDayEventRenderer.renderAllDayEventsForPeriod(layouts); + this.checkAndAnimateAllDayHeight(); + }); + eventBus.on(CoreEvents.VIEW_CHANGED, (event) => { + this.allDayEventRenderer.handleViewChanged(event); + }); + } + getAllDayContainer() { + return document.querySelector('swp-calendar-header swp-allday-container'); + } + getCalendarHeader() { + return document.querySelector('swp-calendar-header'); + } + getHeaderSpacer() { + return document.querySelector('swp-header-spacer'); + } + /** + * Read current max row from DOM elements + * Excludes events marked as removing (data-removing attribute) + */ + getMaxRowFromDOM() { + const container = this.getAllDayContainer(); + if (!container) + return 0; + let maxRow = 0; + const allDayEvents = container.querySelectorAll('swp-allday-event:not(.max-event-indicator):not([data-removing])'); + allDayEvents.forEach((element) => { + const htmlElement = element; + const row = parseInt(htmlElement.style.gridRow) || 1; + maxRow = Math.max(maxRow, row); + }); + return maxRow; + } + /** + * Get current gridArea for an event from DOM + */ + getGridAreaFromDOM(eventId) { + const container = this.getAllDayContainer(); + if (!container) + return null; + const element = container.querySelector(`[data-event-id="${eventId}"]`); + return element?.style.gridArea || null; + } + /** + * Count events in a specific column by reading DOM + */ + countEventsInColumnFromDOM(columnIndex) { + const container = this.getAllDayContainer(); + if (!container) + return 0; + let count = 0; + const allDayEvents = container.querySelectorAll('swp-allday-event:not(.max-event-indicator)'); + allDayEvents.forEach((element) => { + const htmlElement = element; + const gridColumn = htmlElement.style.gridColumn; + // Parse "1 / 3" format + const match = gridColumn.match(/(\d+)\s*\/\s*(\d+)/); + if (match) { + const startCol = parseInt(match[1]); + const endCol = parseInt(match[2]) - 1; // End is exclusive in CSS + if (startCol <= columnIndex && endCol >= columnIndex) { + count++; + } + } + }); + return count; + } + /** + * Calculate all-day height based on number of rows + */ + calculateAllDayHeight(targetRows) { + const root = document.documentElement; + const targetHeight = targetRows * ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT; + // Read CSS variable directly from style property or default to 0 + const currentHeightStr = root.style.getPropertyValue('--all-day-row-height') || '0px'; + const currentHeight = parseInt(currentHeightStr) || 0; + const heightDifference = targetHeight - currentHeight; + return { targetHeight, currentHeight, heightDifference }; + } + /** + * Check current all-day events and animate to correct height + * Reads max row directly from DOM elements + */ + checkAndAnimateAllDayHeight() { + // Read max row directly from DOM + const maxRows = this.getMaxRowFromDOM(); + console.log('📊 AllDayManager: Height calculation', { + maxRows, + isExpanded: this.isExpanded + }); + // Store actual row count + this.actualRowCount = maxRows; + // Determine what to display + let displayRows = maxRows; + if (maxRows > ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS) { + // Show chevron button + this.updateChevronButton(true); + // Show 4 rows when collapsed (3 events + indicators) + if (!this.isExpanded) { + displayRows = ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS; + this.updateOverflowIndicators(); + } + else { + this.clearOverflowIndicators(); + } + } + else { + // Hide chevron - not needed + this.updateChevronButton(false); + this.clearOverflowIndicators(); + } + console.log('🎬 AllDayManager: Will animate to', { + displayRows, + maxRows, + willAnimate: displayRows !== this.actualRowCount + }); + console.log(`🎯 AllDayManager: Animating to ${displayRows} rows`); + // Animate to required rows (0 = collapse, >0 = expand) + this.animateToRows(displayRows); + } + /** + * Animate all-day container to specific number of rows + */ + animateToRows(targetRows) { + const { targetHeight, currentHeight, heightDifference } = this.calculateAllDayHeight(targetRows); + if (targetHeight === currentHeight) + return; // No animation needed + console.log(`🎬 All-day height animation: ${currentHeight}px → ${targetHeight}px (${Math.ceil(currentHeight / ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT)} → ${targetRows} rows)`); + // Get cached elements + const calendarHeader = this.getCalendarHeader(); + const headerSpacer = this.getHeaderSpacer(); + const allDayContainer = this.getAllDayContainer(); + if (!calendarHeader || !allDayContainer) + return; + // Get current parent height for animation + const currentParentHeight = parseFloat(getComputedStyle(calendarHeader).height); + const targetParentHeight = currentParentHeight + heightDifference; + const animations = [ + calendarHeader.animate([ + { height: `${currentParentHeight}px` }, + { height: `${targetParentHeight}px` } + ], { + duration: 150, + easing: 'ease-out', + fill: 'forwards' + }) + ]; + // Add spacer animation if spacer exists, but don't use fill: 'forwards' + if (headerSpacer) { + const root = document.documentElement; + const headerHeightStr = root.style.getPropertyValue('--header-height'); + const headerHeight = parseInt(headerHeightStr); + const currentSpacerHeight = headerHeight + currentHeight; + const targetSpacerHeight = headerHeight + targetHeight; + animations.push(headerSpacer.animate([ + { height: `${currentSpacerHeight}px` }, + { height: `${targetSpacerHeight}px` } + ], { + duration: 150, + easing: 'ease-out' + // No fill: 'forwards' - let CSS calc() take over after animation + })); + } + // Update CSS variable after animation + Promise.all(animations.map(anim => anim.finished)).then(() => { + const root = document.documentElement; + root.style.setProperty('--all-day-row-height', `${targetHeight}px`); + eventBus.emit('header:height-changed'); + }); + } + /** + * Calculate layout for ALL all-day events using AllDayLayoutEngine + * This is the correct method that processes all events together for proper overlap detection + */ + calculateAllDayEventsLayout(events, dayHeaders) { + // Store current state + this.currentAllDayEvents = events; + this.currentWeekDates = dayHeaders; + // Initialize layout engine with provided week dates + let layoutEngine = new AllDayLayoutEngine(dayHeaders.map(column => column.date)); + // Calculate layout for all events together - AllDayLayoutEngine handles CalendarEvents directly + return layoutEngine.calculateLayout(events); + } + handleConvertToAllDay(payload) { + let allDayContainer = this.getAllDayContainer(); + if (!allDayContainer) + return; + // Create SwpAllDayEventElement from ICalendarEvent + const allDayElement = SwpAllDayEventElement.fromCalendarEvent(payload.calendarEvent); + // Apply grid positioning + allDayElement.style.gridRow = '1'; + allDayElement.style.gridColumn = payload.targetColumn.index.toString(); + // Remove old swp-event clone + payload.draggedClone.remove(); + // Call delegate to update DragDropManager's draggedClone reference + payload.replaceClone(allDayElement); + // Append to container + allDayContainer.appendChild(allDayElement); + ColumnDetectionUtils.updateColumnBoundsCache(); + // Recalculate height after adding all-day event + this.checkAndAnimateAllDayHeight(); + } + /** + * Handle drag move for all-day events - SPECIALIZED FOR ALL-DAY CONTAINER + */ + handleColumnChange(dragColumnChangeEventPayload) { + let allDayContainer = this.getAllDayContainer(); + if (!allDayContainer) + return; + let targetColumn = ColumnDetectionUtils.getColumnBounds(dragColumnChangeEventPayload.mousePosition); + if (targetColumn == null) + return; + if (!dragColumnChangeEventPayload.draggedClone) + return; + // Calculate event span from original grid positioning + const computedStyle = window.getComputedStyle(dragColumnChangeEventPayload.draggedClone); + const gridColumnStart = parseInt(computedStyle.gridColumnStart) || targetColumn.index; + const gridColumnEnd = parseInt(computedStyle.gridColumnEnd) || targetColumn.index + 1; + const span = gridColumnEnd - gridColumnStart; + // Update clone position maintaining the span + const newStartColumn = targetColumn.index; + const newEndColumn = newStartColumn + span; + dragColumnChangeEventPayload.draggedClone.style.gridColumn = `${newStartColumn} / ${newEndColumn}`; + } + fadeOutAndRemove(element) { + console.log('🗑️ AllDayManager: About to remove all-day event', { + eventId: element.dataset.eventId, + element: element.tagName + }); + // Mark element as removing so it's excluded from height calculations + element.setAttribute('data-removing', 'true'); + element.style.transition = 'opacity 0.3s ease-out'; + element.style.opacity = '0'; + setTimeout(() => { + element.remove(); + console.log('✅ AllDayManager: All-day event removed from DOM'); + }, 300); + } + /** + * Handle timed → all-day conversion on drop + */ + async handleTimedToAllDayDrop(dragEndEvent) { + if (!dragEndEvent.draggedClone || !dragEndEvent.finalPosition.column) + return; + const clone = dragEndEvent.draggedClone; + const eventId = clone.eventId.replace('clone-', ''); + const targetDate = dragEndEvent.finalPosition.column.date; + console.log('🔄 AllDayManager: Converting timed event to all-day', { eventId, targetDate }); + // Create new dates preserving time + const newStart = new Date(targetDate); + newStart.setHours(clone.start.getHours(), clone.start.getMinutes(), 0, 0); + const newEnd = new Date(targetDate); + newEnd.setHours(clone.end.getHours(), clone.end.getMinutes(), 0, 0); + // Update event in repository + await this.eventManager.updateEvent(eventId, { + start: newStart, + end: newEnd, + allDay: true + }); + // Remove original timed event + this.fadeOutAndRemove(dragEndEvent.originalElement); + // Add to current all-day events and recalculate layout + const newEvent = { + id: eventId, + title: clone.title, + start: newStart, + end: newEnd, + type: clone.type, + allDay: true, + syncStatus: 'synced' + }; + const updatedEvents = [...this.currentAllDayEvents, newEvent]; + const newLayouts = this.calculateAllDayEventsLayout(updatedEvents, this.currentWeekDates); + this.allDayEventRenderer.renderAllDayEventsForPeriod(newLayouts); + // Animate height + this.checkAndAnimateAllDayHeight(); + } + /** + * Handle all-day → all-day drop (moving within header) + */ + async handleDragEnd(dragEndEvent) { + if (!dragEndEvent.draggedClone || !dragEndEvent.finalPosition.column) + return; + const clone = dragEndEvent.draggedClone; + const eventId = clone.eventId.replace('clone-', ''); + const targetDate = dragEndEvent.finalPosition.column.date; + // Calculate duration in days + const durationDays = this.dateService.differenceInCalendarDays(clone.end, clone.start); + // Create new dates preserving time + const newStart = new Date(targetDate); + newStart.setHours(clone.start.getHours(), clone.start.getMinutes(), 0, 0); + const newEnd = new Date(targetDate); + newEnd.setDate(newEnd.getDate() + durationDays); + newEnd.setHours(clone.end.getHours(), clone.end.getMinutes(), 0, 0); + // Update event in repository + await this.eventManager.updateEvent(eventId, { + start: newStart, + end: newEnd, + allDay: true + }); + // Remove original and fade out + this.fadeOutAndRemove(dragEndEvent.originalElement); + // Recalculate and re-render ALL events + const updatedEvents = this.currentAllDayEvents.map(e => e.id === eventId ? { ...e, start: newStart, end: newEnd } : e); + const newLayouts = this.calculateAllDayEventsLayout(updatedEvents, this.currentWeekDates); + this.allDayEventRenderer.renderAllDayEventsForPeriod(newLayouts); + // Animate height - this also handles overflow classes! + this.checkAndAnimateAllDayHeight(); + } + /** + * Update chevron button visibility and state + */ + updateChevronButton(show) { + const headerSpacer = this.getHeaderSpacer(); + if (!headerSpacer) + return; + let chevron = headerSpacer.querySelector('.allday-chevron'); + if (show && !chevron) { + chevron = document.createElement('button'); + chevron.className = 'allday-chevron collapsed'; + chevron.innerHTML = ` + + + + `; + chevron.onclick = () => this.toggleExpanded(); + headerSpacer.appendChild(chevron); + } + else if (!show && chevron) { + chevron.remove(); + } + else if (chevron) { + chevron.classList.toggle('collapsed', !this.isExpanded); + chevron.classList.toggle('expanded', this.isExpanded); + } + } + /** + * Toggle between expanded and collapsed state + */ + toggleExpanded() { + this.isExpanded = !this.isExpanded; + this.checkAndAnimateAllDayHeight(); + const elements = document.querySelectorAll('swp-allday-container swp-allday-event.max-event-overflow-hide, swp-allday-container swp-allday-event.max-event-overflow-show'); + elements.forEach((element) => { + if (this.isExpanded) { + // ALTID vis når expanded=true + element.classList.remove('max-event-overflow-hide'); + element.classList.add('max-event-overflow-show'); + } + else { + // ALTID skjul når expanded=false + element.classList.remove('max-event-overflow-show'); + element.classList.add('max-event-overflow-hide'); + } + }); + } + /** + * Count number of events in a specific column using IColumnBounds + * Reads directly from DOM elements + */ + countEventsInColumn(columnBounds) { + return this.countEventsInColumnFromDOM(columnBounds.index); + } + /** + * Update overflow indicators for collapsed state + */ + updateOverflowIndicators() { + const container = this.getAllDayContainer(); + if (!container) + return; + // Create overflow indicators for each column that needs them + let columns = ColumnDetectionUtils.getColumns(); + columns.forEach((columnBounds) => { + let totalEventsInColumn = this.countEventsInColumn(columnBounds); + let overflowCount = totalEventsInColumn - ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS; + if (overflowCount > 0) { + // Check if indicator already exists in this column + let existingIndicator = container.querySelector(`.max-event-indicator[data-column="${columnBounds.index}"]`); + if (existingIndicator) { + // Update existing indicator + existingIndicator.innerHTML = `+${overflowCount + 1} more`; + } + else { + // Create new overflow indicator element + let overflowElement = document.createElement('swp-allday-event'); + overflowElement.className = 'max-event-indicator'; + overflowElement.setAttribute('data-column', columnBounds.index.toString()); + overflowElement.style.gridRow = ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS.toString(); + overflowElement.style.gridColumn = columnBounds.index.toString(); + overflowElement.innerHTML = `+${overflowCount + 1} more`; + overflowElement.onclick = (e) => { + e.stopPropagation(); + this.toggleExpanded(); + }; + container.appendChild(overflowElement); + } + } + }); + } + /** + * Clear overflow indicators and restore normal state + */ + clearOverflowIndicators() { + const container = this.getAllDayContainer(); + if (!container) + return; + // Remove all overflow indicator elements + container.querySelectorAll('.max-event-indicator').forEach((element) => { + element.remove(); + }); + } +} +//# sourceMappingURL=AllDayManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/AllDayManager.js.map b/wwwroot/js/managers/AllDayManager.js.map new file mode 100644 index 0000000..64ba752 --- /dev/null +++ b/wwwroot/js/managers/AllDayManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayManager.js","sourceRoot":"","sources":["../../../src/managers/AllDayManager.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAgB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAiB,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAEpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAWpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAIrD;;;GAGG;AACH,MAAM,OAAO,aAAa;IAgBxB,YACE,YAA0B,EAC1B,mBAAwC,EACxC,WAAwB;QAdlB,iBAAY,GAA8B,IAAI,CAAC;QAEvD,wCAAwC;QAChC,wBAAmB,GAAqB,EAAE,CAAC;QAC3C,qBAAgB,GAAoB,EAAE,CAAC;QAE/C,wBAAwB;QAChB,eAAU,GAAY,KAAK,CAAC;QAC5B,mBAAc,GAAW,CAAC,CAAC;QAQjC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,mEAAmE;QACnE,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,qBAAqB,EAAE,GAAG,iBAAiB,CAAC,YAAY,IAAI,CAAC,CAAC;QACzG,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,QAAQ,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9C,MAAM,OAAO,GAAI,KAAwD,CAAC,MAAM,CAAC;YAEjF,IAAI,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,aAAa,CAAC;gBAClD,OAAO;YAET,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;gBAC/D,UAAU,EAAE,OAAO,CAAC,YAAY;gBAChC,iBAAiB,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO;gBAC5D,kBAAkB,EAAE,OAAO,CAAC,eAAe,EAAE,OAAO;aACrD,CAAC,CAAC;YAEH,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9C,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAI,KAAqB,CAAC,MAAM,CAAC;YAExE,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE;gBAC/D,iBAAiB,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO;aACrD,CAAC,CAAC;QAEL,CAAC,CAAC,CAAC;QAEH,+CAA+C;QAC/C,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;YAClC,IAAI,OAAO,GAA4B,KAA6C,CAAC,MAAM,CAAC;YAE5F,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1C,IAAI,OAAO,GAAmC,KAAoD,CAAC,MAAM,CAAC;YAE1G,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,IAAI,cAAc,GAA0B,KAA2C,CAAC,MAAM,CAAC;YAE/F,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE;gBACjD,MAAM,EAAE,cAAc,CAAC,MAAM;gBAC7B,kBAAkB,EAAE,cAAc,CAAC,eAAe,EAAE,OAAO;gBAC3D,kBAAkB,EAAE,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,aAAa,CAAC;gBAC/E,OAAO,EAAE,cAAc,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO;aACzD,CAAC,CAAC;YAEH,iDAAiD;YACjD,IAAI,cAAc,CAAC,MAAM,KAAK,gBAAgB,IAAI,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9G,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;gBAChE,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,wDAAwD;YACxD,IAAI,cAAc,CAAC,MAAM,KAAK,gBAAgB,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC/G,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;gBACpE,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,wDAAwD;YACxD,IAAI,cAAc,CAAC,MAAM,KAAK,gBAAgB,IAAI,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9G,MAAM,OAAO,GAAG,cAAc,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;gBAE/D,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBAEzE,kDAAkD;gBAClD,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;gBAEtD,gEAAgE;gBAChE,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;gBAC/E,MAAM,UAAU,GAAG,IAAI,CAAC,2BAA2B,CAAC,eAAe,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAE5F,kDAAkD;gBAClD,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC;gBAEjE,4CAA4C;gBAC5C,IAAI,CAAC,2BAA2B,EAAE,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qDAAqD;QACrD,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;YACtC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAI,KAAqB,CAAC,MAAM,CAAC;YAEjE,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE;gBAC9C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO;gBACzC,MAAM;aACP,CAAC,CAAC;QAEL,CAAC,CAAC,CAAC;QAEH,sEAAsE;QACtE,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,KAAY,EAAE,EAAE;YACjD,IAAI,uBAAuB,GAAI,KAA+C,CAAC,MAAM,CAAC;YAEtF,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;YAC7E,IAAI,OAAO,GAAG,IAAI,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;YAE5E,IAAI,MAAM,GAAqB,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9F,4BAA4B;YAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAE1D,MAAM,OAAO,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,EAAE,uBAAuB,CAAC,cAAc,CAAC,CAAC;YAEvG,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAC9D,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,KAAY,EAAE,EAAE;YACpD,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,KAAoB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,kBAAkB;QACxB,OAAO,QAAQ,CAAC,aAAa,CAAC,0CAA0C,CAAC,CAAC;IAC5E,CAAC;IAEO,iBAAiB;QACvB,OAAO,QAAQ,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC;IAEO,eAAe;QACrB,OAAO,QAAQ,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,gBAAgB;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC;QAEzB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,YAAY,GAAG,SAAS,CAAC,gBAAgB,CAAC,iEAAiE,CAAC,CAAC;QAEnH,YAAY,CAAC,OAAO,CAAC,CAAC,OAAgB,EAAE,EAAE;YACxC,MAAM,WAAW,GAAG,OAAsB,CAAC;YAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrD,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,OAAe;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,MAAM,OAAO,GAAG,SAAS,CAAC,aAAa,CAAC,mBAAmB,OAAO,IAAI,CAAgB,CAAC;QACvF,OAAO,OAAO,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC;IACzC,CAAC;IAED;;OAEG;IACK,0BAA0B,CAAC,WAAmB;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC;QAEzB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,YAAY,GAAG,SAAS,CAAC,gBAAgB,CAAC,4CAA4C,CAAC,CAAC;QAE9F,YAAY,CAAC,OAAO,CAAC,CAAC,OAAgB,EAAE,EAAE;YACxC,MAAM,WAAW,GAAG,OAAsB,CAAC;YAC3C,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;YAEhD,uBAAuB;YACvB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACrD,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B;gBAEjE,IAAI,QAAQ,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,EAAE,CAAC;oBACrD,KAAK,EAAE,CAAC;gBACV,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,UAAkB;QAK9C,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;QACtC,MAAM,YAAY,GAAG,UAAU,GAAG,iBAAiB,CAAC,iBAAiB,CAAC;QACtE,iEAAiE;QACjE,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,IAAI,KAAK,CAAC;QACtF,MAAM,aAAa,GAAG,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,gBAAgB,GAAG,YAAY,GAAG,aAAa,CAAC;QAEtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACI,2BAA2B;QAChC,iCAAiC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExC,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE;YAClD,OAAO;YACP,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;QAEH,yBAAyB;QACzB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAE9B,4BAA4B;QAC5B,IAAI,WAAW,GAAG,OAAO,CAAC;QAE1B,IAAI,OAAO,GAAG,iBAAiB,CAAC,kBAAkB,EAAE,CAAC;YACnD,sBAAsB;YACtB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAE/B,qDAAqD;YACrD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAErB,WAAW,GAAG,iBAAiB,CAAC,kBAAkB,CAAC;gBACnD,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAElC,CAAC;iBAAM,CAAC;gBAEN,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAEjC,CAAC;QACH,CAAC;aAAM,CAAC;YAEN,4BAA4B;YAC5B,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACjC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE;YAC/C,WAAW;YACX,OAAO;YACP,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC,cAAc;SACjD,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,kCAAkC,WAAW,OAAO,CAAC,CAAC;QAElE,uDAAuD;QACvD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,UAAkB;QACrC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAEjG,IAAI,YAAY,KAAK,aAAa;YAAE,OAAO,CAAC,sBAAsB;QAElE,OAAO,CAAC,GAAG,CAAC,gCAAgC,aAAa,QAAQ,YAAY,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,MAAM,UAAU,QAAQ,CAAC,CAAC;QAE5K,sBAAsB;QACtB,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAElD,IAAI,CAAC,cAAc,IAAI,CAAC,eAAe;YAAE,OAAO;QAEhD,0CAA0C;QAC1C,MAAM,mBAAmB,GAAG,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;QAChF,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;QAElE,MAAM,UAAU,GAAG;YACjB,cAAc,CAAC,OAAO,CAAC;gBACrB,EAAE,MAAM,EAAE,GAAG,mBAAmB,IAAI,EAAE;gBACtC,EAAE,MAAM,EAAE,GAAG,kBAAkB,IAAI,EAAE;aACtC,EAAE;gBACD,QAAQ,EAAE,GAAG;gBACb,MAAM,EAAE,UAAU;gBAClB,IAAI,EAAE,UAAU;aACjB,CAAC;SACH,CAAC;QAEF,wEAAwE;QACxE,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;YACtC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;YACvE,MAAM,YAAY,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;YAC/C,MAAM,mBAAmB,GAAG,YAAY,GAAG,aAAa,CAAC;YACzD,MAAM,kBAAkB,GAAG,YAAY,GAAG,YAAY,CAAC;YAEvD,UAAU,CAAC,IAAI,CACb,YAAY,CAAC,OAAO,CAAC;gBACnB,EAAE,MAAM,EAAE,GAAG,mBAAmB,IAAI,EAAE;gBACtC,EAAE,MAAM,EAAE,GAAG,kBAAkB,IAAI,EAAE;aACtC,EAAE;gBACD,QAAQ,EAAE,GAAG;gBACb,MAAM,EAAE,UAAU;gBAClB,iEAAiE;aAClE,CAAC,CACH,CAAC;QACJ,CAAC;QAED,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,EAAE,GAAG,YAAY,IAAI,CAAC,CAAC;YACpE,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAGD;;;OAGG;IACK,2BAA2B,CAAC,MAAwB,EAAE,UAA2B;QAEvF,sBAAsB;QACtB,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC;QAEnC,oDAAoD;QACpD,IAAI,YAAY,GAAG,IAAI,kBAAkB,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjF,gGAAgG;QAChG,OAAO,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAE9C,CAAC;IAEO,qBAAqB,CAAC,OAA0C;QAEtE,IAAI,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAChD,IAAI,CAAC,eAAe;YAAE,OAAO;QAE7B,mDAAmD;QACnD,MAAM,aAAa,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAErF,yBAAyB;QACzB,aAAa,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QAClC,aAAa,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAEvE,6BAA6B;QAC7B,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QAE9B,mEAAmE;QACnE,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAEpC,sBAAsB;QACtB,eAAe,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAE3C,oBAAoB,CAAC,uBAAuB,EAAE,CAAC;QAE/C,gDAAgD;QAChD,IAAI,CAAC,2BAA2B,EAAE,CAAC;IAErC,CAAC;IAGD;;OAEG;IACK,kBAAkB,CAAC,4BAA2D;QAEpF,IAAI,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAChD,IAAI,CAAC,eAAe;YAAE,OAAO;QAE7B,IAAI,YAAY,GAAG,oBAAoB,CAAC,eAAe,CAAC,4BAA4B,CAAC,aAAa,CAAC,CAAC;QAEpG,IAAI,YAAY,IAAI,IAAI;YACtB,OAAO;QAET,IAAI,CAAC,4BAA4B,CAAC,YAAY;YAC5C,OAAO;QAET,sDAAsD;QACtD,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,YAAY,CAAC,CAAC;QACzF,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC;QACtF,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,aAAa,GAAG,eAAe,CAAC;QAE7C,6CAA6C;QAC7C,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC;QAC1C,MAAM,YAAY,GAAG,cAAc,GAAG,IAAI,CAAC;QAC3C,4BAA4B,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,cAAc,MAAM,YAAY,EAAE,CAAC;IAErG,CAAC;IACO,gBAAgB,CAAC,OAAoB;QAC3C,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE;YAC9D,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,qEAAqE;QACrE,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAE9C,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,uBAAuB,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QAE5B,UAAU,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAGD;;OAEG;IACK,KAAK,CAAC,uBAAuB,CAAC,YAAkC;QACtE,IAAI,CAAC,YAAY,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM;YAAE,OAAO;QAE7E,MAAM,KAAK,GAAG,YAAY,CAAC,YAAqC,CAAC;QACjE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;QAE1D,OAAO,CAAC,GAAG,CAAC,qDAAqD,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAE5F,mCAAmC;QACnC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACtC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAE1E,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpE,6BAA6B;QAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE;YAC3C,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,MAAM;YACX,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QAEH,8BAA8B;QAC9B,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAEpD,uDAAuD;QACvD,MAAM,QAAQ,GAAmB;YAC/B,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,QAAQ;SACrB,CAAC;QAEF,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,2BAA2B,CAAC,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1F,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC;QAEjE,iBAAiB;QACjB,IAAI,CAAC,2BAA2B,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,YAAkC;QAC5D,IAAI,CAAC,YAAY,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM;YAAE,OAAO;QAE7E,MAAM,KAAK,GAAG,YAAY,CAAC,YAAqC,CAAC;QACjE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;QAE1D,6BAA6B;QAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAEvF,mCAAmC;QACnC,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACtC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAE1E,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC;QAChD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpE,6BAA6B;QAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE;YAC3C,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,MAAM;YACX,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QAEH,+BAA+B;QAC/B,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAEpD,uCAAuC;QACvC,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACrD,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAC9D,CAAC;QACF,MAAM,UAAU,GAAG,IAAI,CAAC,2BAA2B,CAAC,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1F,IAAI,CAAC,mBAAmB,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC;QAEjE,uDAAuD;QACvD,IAAI,CAAC,2BAA2B,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,IAAa;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,IAAI,OAAO,GAAG,YAAY,CAAC,aAAa,CAAC,iBAAiB,CAAgB,CAAC;QAE3E,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAErB,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC3C,OAAO,CAAC,SAAS,GAAG,0BAA0B,CAAC;YAC/C,OAAO,CAAC,SAAS,GAAG;;;;OAInB,CAAC;YACF,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC9C,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEpC,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;YAE5B,OAAO,CAAC,MAAM,EAAE,CAAC;QAEnB,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YAEnB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACxD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAExD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QAEnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,8HAA8H,CAAC,CAAC;QAE3K,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,8BAA8B;gBAC9B,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACpD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,iCAAiC;gBACjC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACpD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IACD;;;OAGG;IACK,mBAAmB,CAAC,YAA2B;QACrD,OAAO,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,6DAA6D;QAC7D,IAAI,OAAO,GAAG,oBAAoB,CAAC,UAAU,EAAE,CAAC;QAEhD,OAAO,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;YAC/B,IAAI,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YACjE,IAAI,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC,kBAAkB,CAAA;YAE9E,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBACtB,mDAAmD;gBACnD,IAAI,iBAAiB,GAAG,SAAS,CAAC,aAAa,CAAC,qCAAqC,YAAY,CAAC,KAAK,IAAI,CAAgB,CAAC;gBAE5H,IAAI,iBAAiB,EAAE,CAAC;oBACtB,4BAA4B;oBAC5B,iBAAiB,CAAC,SAAS,GAAG,UAAU,aAAa,GAAG,CAAC,cAAc,CAAC;gBAC1E,CAAC;qBAAM,CAAC;oBACN,wCAAwC;oBACxC,IAAI,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;oBACjE,eAAe,CAAC,SAAS,GAAG,qBAAqB,CAAC;oBAClD,eAAe,CAAC,YAAY,CAAC,aAAa,EAAE,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC3E,eAAe,CAAC,KAAK,CAAC,OAAO,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC;oBAChF,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACjE,eAAe,CAAC,SAAS,GAAG,UAAU,aAAa,GAAG,CAAC,cAAc,CAAC;oBACtE,eAAe,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE;wBAC9B,CAAC,CAAC,eAAe,EAAE,CAAC;wBACpB,IAAI,CAAC,cAAc,EAAE,CAAC;oBACxB,CAAC,CAAC;oBAEF,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,uBAAuB;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,yCAAyC;QACzC,SAAS,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACrE,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IAGL,CAAC;CAEF"} \ No newline at end of file diff --git a/wwwroot/js/managers/CalendarManager.d.ts b/wwwroot/js/managers/CalendarManager.d.ts new file mode 100644 index 0000000..b0cf0d2 --- /dev/null +++ b/wwwroot/js/managers/CalendarManager.d.ts @@ -0,0 +1,45 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { CalendarView, IEventBus } from '../types/CalendarTypes'; +import { EventManager } from './EventManager'; +import { GridManager } from './GridManager'; +import { EventRenderingService } from '../renderers/EventRendererManager'; +import { ScrollManager } from './ScrollManager'; +/** + * CalendarManager - Main coordinator for all calendar managers + */ +export declare class CalendarManager { + private eventBus; + private eventManager; + private gridManager; + private eventRenderer; + private scrollManager; + private config; + private currentView; + private currentDate; + private isInitialized; + constructor(eventBus: IEventBus, eventManager: EventManager, gridManager: GridManager, eventRenderingService: EventRenderingService, scrollManager: ScrollManager, config: Configuration); + /** + * Initialize calendar system using simple direct calls + */ + initialize(): Promise; + /** + * Skift calendar view (dag/uge/måned) + */ + setView(view: CalendarView): void; + /** + * Sæt aktuel dato + */ + setCurrentDate(date: Date): void; + /** + * Setup event listeners for at håndtere events fra andre managers + */ + private setupEventListeners; + /** + * Calculate the current period based on view and date + */ + private calculateCurrentPeriod; + /** + * Handle workweek configuration changes + */ + private handleWorkweekChange; +} diff --git a/wwwroot/js/managers/CalendarManager.js b/wwwroot/js/managers/CalendarManager.js new file mode 100644 index 0000000..fc0caa3 --- /dev/null +++ b/wwwroot/js/managers/CalendarManager.js @@ -0,0 +1,145 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * CalendarManager - Main coordinator for all calendar managers + */ +export class CalendarManager { + constructor(eventBus, eventManager, gridManager, eventRenderingService, scrollManager, config) { + this.currentView = 'week'; + this.currentDate = new Date(); + this.isInitialized = false; + this.eventBus = eventBus; + this.eventManager = eventManager; + this.gridManager = gridManager; + this.eventRenderer = eventRenderingService; + this.scrollManager = scrollManager; + this.config = config; + this.setupEventListeners(); + } + /** + * Initialize calendar system using simple direct calls + */ + async initialize() { + if (this.isInitialized) { + return; + } + try { + // Step 1: Load data + await this.eventManager.loadData(); + // Step 2: Render grid structure + await this.gridManager.render(); + this.scrollManager.initialize(); + this.setView(this.currentView); + this.setCurrentDate(this.currentDate); + this.isInitialized = true; + // Emit initialization complete event + this.eventBus.emit(CoreEvents.INITIALIZED, { + currentDate: this.currentDate, + currentView: this.currentView + }); + } + catch (error) { + throw error; + } + } + /** + * Skift calendar view (dag/uge/måned) + */ + setView(view) { + if (this.currentView === view) { + return; + } + const previousView = this.currentView; + this.currentView = view; + // Emit view change event + this.eventBus.emit(CoreEvents.VIEW_CHANGED, { + previousView, + currentView: view, + date: this.currentDate + }); + } + /** + * Sæt aktuel dato + */ + setCurrentDate(date) { + const previousDate = this.currentDate; + this.currentDate = new Date(date); + // Emit date change event + this.eventBus.emit(CoreEvents.DATE_CHANGED, { + previousDate, + currentDate: this.currentDate, + view: this.currentView + }); + } + /** + * Setup event listeners for at håndtere events fra andre managers + */ + setupEventListeners() { + // Listen for workweek changes only + this.eventBus.on(CoreEvents.WORKWEEK_CHANGED, (event) => { + const customEvent = event; + this.handleWorkweekChange(); + }); + } + /** + * Calculate the current period based on view and date + */ + calculateCurrentPeriod() { + const current = new Date(this.currentDate); + switch (this.currentView) { + case 'day': + const dayStart = new Date(current); + dayStart.setHours(0, 0, 0, 0); + const dayEnd = new Date(current); + dayEnd.setHours(23, 59, 59, 999); + return { + start: dayStart.toISOString(), + end: dayEnd.toISOString() + }; + case 'week': + // Find start of week (Monday) + const weekStart = new Date(current); + const dayOfWeek = weekStart.getDay(); + const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Sunday = 0, so 6 days back to Monday + weekStart.setDate(weekStart.getDate() - daysToMonday); + weekStart.setHours(0, 0, 0, 0); + // Find end of week (Sunday) + const weekEnd = new Date(weekStart); + weekEnd.setDate(weekEnd.getDate() + 6); + weekEnd.setHours(23, 59, 59, 999); + return { + start: weekStart.toISOString(), + end: weekEnd.toISOString() + }; + case 'month': + const monthStart = new Date(current.getFullYear(), current.getMonth(), 1); + const monthEnd = new Date(current.getFullYear(), current.getMonth() + 1, 0, 23, 59, 59, 999); + return { + start: monthStart.toISOString(), + end: monthEnd.toISOString() + }; + default: + // Fallback to week view + const fallbackStart = new Date(current); + fallbackStart.setDate(fallbackStart.getDate() - 3); + fallbackStart.setHours(0, 0, 0, 0); + const fallbackEnd = new Date(current); + fallbackEnd.setDate(fallbackEnd.getDate() + 3); + fallbackEnd.setHours(23, 59, 59, 999); + return { + start: fallbackStart.toISOString(), + end: fallbackEnd.toISOString() + }; + } + } + /** + * Handle workweek configuration changes + */ + handleWorkweekChange() { + // Simply relay the event - workweek info is in the WORKWEEK_CHANGED event + this.eventBus.emit('workweek:header-update', { + currentDate: this.currentDate, + currentView: this.currentView + }); + } +} +//# sourceMappingURL=CalendarManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/CalendarManager.js.map b/wwwroot/js/managers/CalendarManager.js.map new file mode 100644 index 0000000..38d05f7 --- /dev/null +++ b/wwwroot/js/managers/CalendarManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarManager.js","sourceRoot":"","sources":["../../../src/managers/CalendarManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/DragDropManager.d.ts b/wwwroot/js/managers/DragDropManager.d.ts new file mode 100644 index 0000000..f9d266d --- /dev/null +++ b/wwwroot/js/managers/DragDropManager.d.ts @@ -0,0 +1,222 @@ +/** + * DragDropManager - Advanced drag-and-drop system with smooth animations and event type conversion + * + * ARCHITECTURE OVERVIEW: + * ===================== + * DragDropManager provides a sophisticated drag-and-drop system for calendar events that supports: + * - Smooth animated dragging with requestAnimationFrame + * - Automatic event type conversion (timed events ↔ all-day events) + * - Scroll compensation during edge scrolling + * - Grid snapping for precise event placement + * - Column detection and change tracking + * + * KEY FEATURES: + * ============= + * 1. DRAG DETECTION + * - Movement threshold (5px) to distinguish clicks from drags + * - Immediate visual feedback with cloned element + * - Mouse offset tracking for natural drag feel + * + * 2. SMOOTH ANIMATION + * - Uses requestAnimationFrame for 60fps animations + * - Interpolated movement (30% per frame) for smooth transitions + * - Continuous drag:move events for real-time updates + * + * 3. EVENT TYPE CONVERSION + * - Timed → All-day: When dragging into calendar header + * - All-day → Timed: When dragging into day columns + * - Automatic clone replacement with appropriate element type + * + * 4. SCROLL COMPENSATION + * - Tracks scroll delta during edge-scrolling + * - Compensates dragged element position during scroll + * - Prevents visual "jumping" when scrolling while dragging + * + * 5. GRID SNAPPING + * - Snaps to time grid on mouse up + * - Uses PositionUtils for consistent positioning + * - Accounts for mouse offset within event + * + * STATE MANAGEMENT: + * ================= + * Mouse Tracking: + * - mouseDownPosition: Initial click position + * - currentMousePosition: Latest mouse position + * - mouseOffset: Click offset within event (for natural dragging) + * + * Drag State: + * - originalElement: Source event being dragged + * - draggedClone: Animated clone following mouse + * - currentColumn: Column mouse is currently over + * - previousColumn: Last column (for detecting changes) + * - isDragStarted: Whether drag threshold exceeded + * + * Scroll State: + * - scrollDeltaY: Accumulated scroll offset during drag + * - lastScrollTop: Previous scroll position + * - isScrollCompensating: Whether edge-scroll is active + * + * Animation State: + * - dragAnimationId: requestAnimationFrame ID + * - targetY: Desired position for smooth interpolation + * - currentY: Current interpolated position + * + * EVENT FLOW: + * =========== + * 1. Mouse Down (handleMouseDown) + * ├─ Store originalElement and mouse offset + * └─ Wait for movement + * + * 2. Mouse Move (handleMouseMove) + * ├─ Check movement threshold + * ├─ Initialize drag if threshold exceeded (initializeDrag) + * │ ├─ Create clone + * │ ├─ Emit drag:start + * │ └─ Start animation loop + * ├─ Continue drag (continueDrag) + * │ ├─ Calculate target position with scroll compensation + * │ └─ Update animation target + * └─ Detect column changes (detectColumnChange) + * └─ Emit drag:column-change + * + * 3. Animation Loop (animateDrag) + * ├─ Interpolate currentY toward targetY + * ├─ Emit drag:move on each frame + * └─ Schedule next frame until target reached + * + * 4. Event Type Conversion + * ├─ Entering header (handleHeaderMouseEnter) + * │ ├─ Emit drag:mouseenter-header + * │ └─ AllDayManager creates all-day clone + * └─ Entering column (handleColumnMouseEnter) + * ├─ Emit drag:mouseenter-column + * └─ EventRenderingService creates timed clone + * + * 5. Mouse Up (handleMouseUp) + * ├─ Stop animation + * ├─ Snap to grid + * ├─ Detect drop target (header or column) + * ├─ Emit drag:end with final position + * └─ Cleanup drag state + * + * SCROLL COMPENSATION SYSTEM: + * =========================== + * Problem: When EdgeScrollManager scrolls the grid during drag, the dragged element + * can appear to "jump" because the mouse position stays the same but the + * coordinate system (scrollable content) has moved. + * + * Solution: Track cumulative scroll delta and add it to mouse position calculations + * + * Flow: + * 1. EdgeScrollManager starts scrolling → emit edgescroll:started + * 2. DragDropManager sets isScrollCompensating = true + * 3. On each scroll event: + * ├─ Calculate scrollDelta = currentScrollTop - lastScrollTop + * ├─ Accumulate into scrollDeltaY + * └─ Call continueDrag with adjusted position + * 4. continueDrag adds scrollDeltaY to mouse Y coordinate + * 5. On event conversion, reset scrollDeltaY (new clone, new coordinate system) + * + * PERFORMANCE OPTIMIZATIONS: + * ========================== + * - Uses ColumnDetectionUtils cache for fast column lookups + * - Single requestAnimationFrame loop (not per-mousemove) + * - Interpolated animation reduces update frequency + * - Passive scroll listeners + * - Event delegation for header/column detection + * + * USAGE: + * ====== + * const dragDropManager = new DragDropManager(eventBus, positionUtils); + * // Automatically attaches event listeners and manages drag lifecycle + * // Other managers listen to drag:start, drag:move, drag:end, etc. + */ +import { IEventBus } from '../types/CalendarTypes'; +import { PositionUtils } from '../utils/PositionUtils'; +export declare class DragDropManager { + private eventBus; + private mouseDownPosition; + private currentMousePosition; + private mouseOffset; + private originalElement; + private draggedClone; + private currentColumn; + private previousColumn; + private originalSourceColumn; + private isDragStarted; + private readonly dragThreshold; + private scrollableContent; + private scrollDeltaY; + private lastScrollTop; + private isScrollCompensating; + private dragAnimationId; + private targetY; + private currentY; + private targetColumn; + private positionUtils; + constructor(eventBus: IEventBus, positionUtils: PositionUtils); + /** + * Initialize with optimized event listener setup + */ + private init; + private handleGridRendered; + private handleMouseDown; + private handleMouseMove; + /** + * Try to initialize drag based on movement threshold + * Returns true if drag was initialized, false if not enough movement + */ + private initializeDrag; + private continueDrag; + /** + * Detect column change and emit event + */ + private detectColumnChange; + /** + * Optimized mouse up handler with consolidated cleanup + */ + private handleMouseUp; + private cleanupAllClones; + /** + * Cancel drag operation when mouse leaves grid container + * Animates clone back to original position before cleanup + */ + private cancelDrag; + /** + * Optimized snap position calculation using PositionUtils + */ + private calculateSnapPosition; + /** + * Smooth drag animation using requestAnimationFrame + * Emits drag:move events with current draggedClone reference on each frame + */ + private animateDrag; + /** + * Handle scroll during drag - update scrollDeltaY and call continueDrag + */ + private handleScroll; + /** + * Stop drag animation + */ + private stopDragAnimation; + /** + * Clean up drag state + */ + private cleanupDragState; + /** + * Detect drop target - whether dropped in swp-day-column or swp-day-header + */ + private detectDropTarget; + /** + * Handle mouse enter on calendar header - simplified using native events + */ + private handleHeaderMouseEnter; + /** + * Handle mouse enter on day column - for converting all-day to timed events + */ + private handleColumnMouseEnter; + /** + * Handle mouse leave from calendar header - simplified using native events + */ + private handleHeaderMouseLeave; +} diff --git a/wwwroot/js/managers/DragDropManager.js b/wwwroot/js/managers/DragDropManager.js new file mode 100644 index 0000000..5801e24 --- /dev/null +++ b/wwwroot/js/managers/DragDropManager.js @@ -0,0 +1,626 @@ +/** + * DragDropManager - Advanced drag-and-drop system with smooth animations and event type conversion + * + * ARCHITECTURE OVERVIEW: + * ===================== + * DragDropManager provides a sophisticated drag-and-drop system for calendar events that supports: + * - Smooth animated dragging with requestAnimationFrame + * - Automatic event type conversion (timed events ↔ all-day events) + * - Scroll compensation during edge scrolling + * - Grid snapping for precise event placement + * - Column detection and change tracking + * + * KEY FEATURES: + * ============= + * 1. DRAG DETECTION + * - Movement threshold (5px) to distinguish clicks from drags + * - Immediate visual feedback with cloned element + * - Mouse offset tracking for natural drag feel + * + * 2. SMOOTH ANIMATION + * - Uses requestAnimationFrame for 60fps animations + * - Interpolated movement (30% per frame) for smooth transitions + * - Continuous drag:move events for real-time updates + * + * 3. EVENT TYPE CONVERSION + * - Timed → All-day: When dragging into calendar header + * - All-day → Timed: When dragging into day columns + * - Automatic clone replacement with appropriate element type + * + * 4. SCROLL COMPENSATION + * - Tracks scroll delta during edge-scrolling + * - Compensates dragged element position during scroll + * - Prevents visual "jumping" when scrolling while dragging + * + * 5. GRID SNAPPING + * - Snaps to time grid on mouse up + * - Uses PositionUtils for consistent positioning + * - Accounts for mouse offset within event + * + * STATE MANAGEMENT: + * ================= + * Mouse Tracking: + * - mouseDownPosition: Initial click position + * - currentMousePosition: Latest mouse position + * - mouseOffset: Click offset within event (for natural dragging) + * + * Drag State: + * - originalElement: Source event being dragged + * - draggedClone: Animated clone following mouse + * - currentColumn: Column mouse is currently over + * - previousColumn: Last column (for detecting changes) + * - isDragStarted: Whether drag threshold exceeded + * + * Scroll State: + * - scrollDeltaY: Accumulated scroll offset during drag + * - lastScrollTop: Previous scroll position + * - isScrollCompensating: Whether edge-scroll is active + * + * Animation State: + * - dragAnimationId: requestAnimationFrame ID + * - targetY: Desired position for smooth interpolation + * - currentY: Current interpolated position + * + * EVENT FLOW: + * =========== + * 1. Mouse Down (handleMouseDown) + * ├─ Store originalElement and mouse offset + * └─ Wait for movement + * + * 2. Mouse Move (handleMouseMove) + * ├─ Check movement threshold + * ├─ Initialize drag if threshold exceeded (initializeDrag) + * │ ├─ Create clone + * │ ├─ Emit drag:start + * │ └─ Start animation loop + * ├─ Continue drag (continueDrag) + * │ ├─ Calculate target position with scroll compensation + * │ └─ Update animation target + * └─ Detect column changes (detectColumnChange) + * └─ Emit drag:column-change + * + * 3. Animation Loop (animateDrag) + * ├─ Interpolate currentY toward targetY + * ├─ Emit drag:move on each frame + * └─ Schedule next frame until target reached + * + * 4. Event Type Conversion + * ├─ Entering header (handleHeaderMouseEnter) + * │ ├─ Emit drag:mouseenter-header + * │ └─ AllDayManager creates all-day clone + * └─ Entering column (handleColumnMouseEnter) + * ├─ Emit drag:mouseenter-column + * └─ EventRenderingService creates timed clone + * + * 5. Mouse Up (handleMouseUp) + * ├─ Stop animation + * ├─ Snap to grid + * ├─ Detect drop target (header or column) + * ├─ Emit drag:end with final position + * └─ Cleanup drag state + * + * SCROLL COMPENSATION SYSTEM: + * =========================== + * Problem: When EdgeScrollManager scrolls the grid during drag, the dragged element + * can appear to "jump" because the mouse position stays the same but the + * coordinate system (scrollable content) has moved. + * + * Solution: Track cumulative scroll delta and add it to mouse position calculations + * + * Flow: + * 1. EdgeScrollManager starts scrolling → emit edgescroll:started + * 2. DragDropManager sets isScrollCompensating = true + * 3. On each scroll event: + * ├─ Calculate scrollDelta = currentScrollTop - lastScrollTop + * ├─ Accumulate into scrollDeltaY + * └─ Call continueDrag with adjusted position + * 4. continueDrag adds scrollDeltaY to mouse Y coordinate + * 5. On event conversion, reset scrollDeltaY (new clone, new coordinate system) + * + * PERFORMANCE OPTIMIZATIONS: + * ========================== + * - Uses ColumnDetectionUtils cache for fast column lookups + * - Single requestAnimationFrame loop (not per-mousemove) + * - Interpolated animation reduces update frequency + * - Passive scroll listeners + * - Event delegation for header/column detection + * + * USAGE: + * ====== + * const dragDropManager = new DragDropManager(eventBus, positionUtils); + * // Automatically attaches event listeners and manages drag lifecycle + * // Other managers listen to drag:start, drag:move, drag:end, etc. + */ +import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils'; +import { SwpEventElement } from '../elements/SwpEventElement'; +import { CoreEvents } from '../constants/CoreEvents'; +export class DragDropManager { + constructor(eventBus, positionUtils) { + // Mouse tracking with optimized state + this.mouseDownPosition = { x: 0, y: 0 }; + this.currentMousePosition = { x: 0, y: 0 }; + this.mouseOffset = { x: 0, y: 0 }; + this.currentColumn = null; + this.previousColumn = null; + this.originalSourceColumn = null; // Track original start column + this.isDragStarted = false; + // Movement threshold to distinguish click from drag + this.dragThreshold = 5; // pixels + // Scroll compensation + this.scrollableContent = null; + this.scrollDeltaY = 0; // Current scroll delta to apply in continueDrag + this.lastScrollTop = 0; // Last scroll position for delta calculation + this.isScrollCompensating = false; // Track if scroll compensation is active + // Smooth drag animation + this.dragAnimationId = null; + this.targetY = 0; + this.currentY = 0; + this.targetColumn = null; + this.eventBus = eventBus; + this.positionUtils = positionUtils; + this.init(); + } + /** + * Initialize with optimized event listener setup + */ + init() { + // Add event listeners + document.body.addEventListener('mousemove', this.handleMouseMove.bind(this)); + document.body.addEventListener('mousedown', this.handleMouseDown.bind(this)); + document.body.addEventListener('mouseup', this.handleMouseUp.bind(this)); + const calendarContainer = document.querySelector('swp-calendar-container'); + if (calendarContainer) { + calendarContainer.addEventListener('mouseleave', () => { + if (this.originalElement && this.isDragStarted) { + this.cancelDrag(); + } + }); + // Event delegation for header enter/leave + calendarContainer.addEventListener('mouseenter', (e) => { + const target = e.target; + if (target.closest('swp-calendar-header')) { + this.handleHeaderMouseEnter(e); + } + else if (target.closest('swp-day-column')) { + this.handleColumnMouseEnter(e); + } + }, true); // Use capture phase + calendarContainer.addEventListener('mouseleave', (e) => { + const target = e.target; + if (target.closest('swp-calendar-header')) { + this.handleHeaderMouseLeave(e); + } + // Don't handle swp-event mouseleave here - let mousemove handle it + }, true); // Use capture phase + } + // Initialize column bounds cache + ColumnDetectionUtils.updateColumnBoundsCache(); + // Listen to resize events to update cache + window.addEventListener('resize', () => { + ColumnDetectionUtils.updateColumnBoundsCache(); + }); + // Listen to navigation events to update cache + this.eventBus.on('navigation:completed', () => { + ColumnDetectionUtils.updateColumnBoundsCache(); + }); + this.eventBus.on(CoreEvents.GRID_RENDERED, (event) => { + this.handleGridRendered(event); + }); + // Listen to edge-scroll events to control scroll compensation + this.eventBus.on('edgescroll:started', () => { + this.isScrollCompensating = true; + // Gem nuværende scroll position for delta beregning + if (this.scrollableContent) { + this.lastScrollTop = this.scrollableContent.scrollTop; + } + }); + this.eventBus.on('edgescroll:stopped', () => { + this.isScrollCompensating = false; + }); + // Reset scrollDeltaY when event converts (new clone created) + this.eventBus.on('drag:mouseenter-header', () => { + this.scrollDeltaY = 0; + this.lastScrollTop = 0; + }); + this.eventBus.on('drag:mouseenter-column', () => { + this.scrollDeltaY = 0; + this.lastScrollTop = 0; + }); + } + handleGridRendered(event) { + this.scrollableContent = document.querySelector('swp-scrollable-content'); + this.scrollableContent.addEventListener('scroll', this.handleScroll.bind(this), { passive: true }); + } + handleMouseDown(event) { + // Clean up drag state first + this.cleanupDragState(); + ColumnDetectionUtils.updateColumnBoundsCache(); + //this.lastMousePosition = { x: event.clientX, y: event.clientY }; + //this.initialMousePosition = { x: event.clientX, y: event.clientY }; + // Check if mousedown is on an event + const target = event.target; + if (target.closest('swp-resize-handle')) + return; + let eventElement = target; + while (eventElement && eventElement.tagName !== 'SWP-GRID-CONTAINER') { + if (eventElement.tagName === 'SWP-EVENT' || eventElement.tagName === 'SWP-ALLDAY-EVENT') { + break; + } + eventElement = eventElement.parentElement; + if (!eventElement) + return; + } + if (eventElement) { + // Normal drag - prepare for potential dragging + this.originalElement = eventElement; + // Calculate mouse offset within event + const eventRect = eventElement.getBoundingClientRect(); + this.mouseOffset = { + x: event.clientX - eventRect.left, + y: event.clientY - eventRect.top + }; + this.mouseDownPosition = { x: event.clientX, y: event.clientY }; + } + } + handleMouseMove(event) { + if (event.buttons === 1) { + // Always update mouse position from event + this.currentMousePosition = { x: event.clientX, y: event.clientY }; + // Try to initialize drag if not started + if (!this.isDragStarted && this.originalElement) { + if (!this.initializeDrag(this.currentMousePosition)) { + return; // Not enough movement yet + } + } + // Continue drag if started (også under scroll - accumulatedScrollDelta kompenserer) + if (this.isDragStarted && this.originalElement && this.draggedClone) { + this.continueDrag(this.currentMousePosition); + this.detectColumnChange(this.currentMousePosition); + } + } + } + /** + * Try to initialize drag based on movement threshold + * Returns true if drag was initialized, false if not enough movement + */ + initializeDrag(currentPosition) { + const deltaX = Math.abs(currentPosition.x - this.mouseDownPosition.x); + const deltaY = Math.abs(currentPosition.y - this.mouseDownPosition.y); + const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + if (totalMovement < this.dragThreshold) { + return false; // Not enough movement + } + // Start drag + this.isDragStarted = true; + // Set high z-index on event-group if exists, otherwise on event itself + const eventGroup = this.originalElement.closest('swp-event-group'); + if (eventGroup) { + eventGroup.style.zIndex = '9999'; + } + else { + this.originalElement.style.zIndex = '9999'; + } + const originalElement = this.originalElement; + this.currentColumn = ColumnDetectionUtils.getColumnBounds(currentPosition); + this.originalSourceColumn = this.currentColumn; // Store original source column at drag start + this.draggedClone = originalElement.createClone(); + const dragStartPayload = { + originalElement: this.originalElement, + draggedClone: this.draggedClone, + mousePosition: this.mouseDownPosition, + mouseOffset: this.mouseOffset, + columnBounds: this.currentColumn + }; + this.eventBus.emit('drag:start', dragStartPayload); + return true; + } + continueDrag(currentPosition) { + if (!this.draggedClone.hasAttribute("data-allday")) { + // Calculate raw position from mouse (no snapping) + const column = ColumnDetectionUtils.getColumnBounds(currentPosition); + if (column) { + // Calculate raw Y position relative to column (accounting for mouse offset) + const columnRect = column.boundingClientRect; + // Beregn position fra mus + scroll delta kompensation + const adjustedMouseY = currentPosition.y + this.scrollDeltaY; + const eventTopY = adjustedMouseY - columnRect.top - this.mouseOffset.y; + this.targetY = Math.max(0, eventTopY); + this.targetColumn = column; + // Start animation loop if not already running + if (this.dragAnimationId === null) { + this.currentY = parseFloat(this.draggedClone.style.top) || 0; + this.animateDrag(); + } + } + } + } + /** + * Detect column change and emit event + */ + detectColumnChange(currentPosition) { + const newColumn = ColumnDetectionUtils.getColumnBounds(currentPosition); + if (newColumn == null) + return; + if (newColumn.index !== this.currentColumn?.index) { + this.previousColumn = this.currentColumn; + this.currentColumn = newColumn; + const dragColumnChangePayload = { + originalElement: this.originalElement, + draggedClone: this.draggedClone, + previousColumn: this.previousColumn, + newColumn, + mousePosition: currentPosition + }; + this.eventBus.emit('drag:column-change', dragColumnChangePayload); + } + } + /** + * Optimized mouse up handler with consolidated cleanup + */ + handleMouseUp(event) { + this.stopDragAnimation(); + if (this.originalElement) { + // Only emit drag:end if drag was actually started + if (this.isDragStarted) { + const mousePosition = { x: event.clientX, y: event.clientY }; + // Snap to grid on mouse up (like ResizeHandleManager) + const column = ColumnDetectionUtils.getColumnBounds(mousePosition); + if (!column) + return; + // Get current position and snap it to grid + const snappedY = this.calculateSnapPosition(mousePosition.y, column); + // Update clone to snapped position immediately + if (this.draggedClone) { + this.draggedClone.style.top = `${snappedY}px`; + } + // Detect drop target (swp-day-column or swp-day-header) + const dropTarget = this.detectDropTarget(mousePosition); + if (!dropTarget) + throw "dropTarget is null"; + const dragEndPayload = { + originalElement: this.originalElement, + draggedClone: this.draggedClone, + mousePosition, + originalSourceColumn: this.originalSourceColumn, + finalPosition: { column, snappedY }, // Where drag ended + target: dropTarget + }; + this.eventBus.emit('drag:end', dragEndPayload); + this.cleanupDragState(); + } + else { + // This was just a click - emit click event instead + this.eventBus.emit('event:click', { + clickedElement: this.originalElement, + mousePosition: { x: event.clientX, y: event.clientY } + }); + } + } + } + // Add a cleanup method that finds and removes ALL clones + cleanupAllClones() { + // Remove clones from all possible locations + const allClones = document.querySelectorAll('[data-event-id^="clone"]'); + if (allClones.length > 0) { + allClones.forEach(clone => clone.remove()); + } + } + /** + * Cancel drag operation when mouse leaves grid container + * Animates clone back to original position before cleanup + */ + cancelDrag() { + if (!this.originalElement || !this.draggedClone) + return; + // Get current clone position + const cloneRect = this.draggedClone.getBoundingClientRect(); + // Get original element position + const originalRect = this.originalElement.getBoundingClientRect(); + // Calculate distance to animate + const deltaX = originalRect.left - cloneRect.left; + const deltaY = originalRect.top - cloneRect.top; + // Add transition for smooth animation + this.draggedClone.style.transition = 'transform 300ms ease-out'; + this.draggedClone.style.transform = `translate(${deltaX}px, ${deltaY}px)`; + // Wait for animation to complete, then cleanup + setTimeout(() => { + this.cleanupAllClones(); + if (this.originalElement) { + this.originalElement.style.opacity = ''; + this.originalElement.style.cursor = ''; + } + this.eventBus.emit('drag:cancelled', { + originalElement: this.originalElement, + reason: 'mouse-left-grid' + }); + this.cleanupDragState(); + this.stopDragAnimation(); + }, 300); + } + /** + * Optimized snap position calculation using PositionUtils + */ + calculateSnapPosition(mouseY, column) { + // Calculate where the event top would be (accounting for mouse offset) + const eventTopY = mouseY - this.mouseOffset.y; + // Snap the event top position, not the mouse position + const snappedY = this.positionUtils.getPositionFromCoordinate(eventTopY, column); + return Math.max(0, snappedY); + } + /** + * Smooth drag animation using requestAnimationFrame + * Emits drag:move events with current draggedClone reference on each frame + */ + animateDrag() { + if (!this.isDragStarted || !this.draggedClone || !this.targetColumn) { + this.dragAnimationId = null; + return; + } + // Smooth interpolation towards target + const diff = this.targetY - this.currentY; + const step = diff * 0.3; // 30% of distance per frame + // Update if difference is significant + if (Math.abs(diff) > 0.5) { + this.currentY += step; + // Emit drag:move event with current draggedClone reference + const dragMovePayload = { + originalElement: this.originalElement, + draggedClone: this.draggedClone, // Always uses current reference + mousePosition: this.currentMousePosition, // Use current mouse position! + snappedY: this.currentY, + columnBounds: this.targetColumn, + mouseOffset: this.mouseOffset + }; + this.eventBus.emit('drag:move', dragMovePayload); + this.dragAnimationId = requestAnimationFrame(() => this.animateDrag()); + } + else { + // Close enough - snap to target + this.currentY = this.targetY; + // Emit final position + const dragMovePayload = { + originalElement: this.originalElement, + draggedClone: this.draggedClone, + mousePosition: this.currentMousePosition, // Use current mouse position! + snappedY: this.currentY, + columnBounds: this.targetColumn, + mouseOffset: this.mouseOffset + }; + this.eventBus.emit('drag:move', dragMovePayload); + this.dragAnimationId = null; + } + } + /** + * Handle scroll during drag - update scrollDeltaY and call continueDrag + */ + handleScroll() { + if (!this.isDragStarted || !this.draggedClone || !this.scrollableContent || !this.isScrollCompensating) + return; + const currentScrollTop = this.scrollableContent.scrollTop; + const scrollDelta = currentScrollTop - this.lastScrollTop; + // Gem scroll delta for continueDrag + this.scrollDeltaY += scrollDelta; + this.lastScrollTop = currentScrollTop; + // Kald continueDrag med nuværende mus position + this.continueDrag(this.currentMousePosition); + } + /** + * Stop drag animation + */ + stopDragAnimation() { + if (this.dragAnimationId !== null) { + cancelAnimationFrame(this.dragAnimationId); + this.dragAnimationId = null; + } + } + /** + * Clean up drag state + */ + cleanupDragState() { + this.previousColumn = null; + this.originalElement = null; + this.draggedClone = null; + this.currentColumn = null; + this.originalSourceColumn = null; + this.isDragStarted = false; + this.scrollDeltaY = 0; + this.lastScrollTop = 0; + } + /** + * Detect drop target - whether dropped in swp-day-column or swp-day-header + */ + detectDropTarget(position) { + // Traverse up the DOM tree to find the target container + let currentElement = this.draggedClone; + while (currentElement && currentElement !== document.body) { + if (currentElement.tagName === 'SWP-ALLDAY-CONTAINER') { + return 'swp-day-header'; + } + if (currentElement.tagName === 'SWP-DAY-COLUMN') { + return 'swp-day-column'; + } + currentElement = currentElement.parentElement; + } + return null; + } + /** + * Handle mouse enter on calendar header - simplified using native events + */ + handleHeaderMouseEnter(event) { + // Only handle if we're dragging a timed event (not all-day) + if (!this.isDragStarted || !this.draggedClone) { + return; + } + const position = { x: event.clientX, y: event.clientY }; + const targetColumn = ColumnDetectionUtils.getColumnBounds(position); + if (targetColumn) { + const calendarEvent = SwpEventElement.extractCalendarEventFromElement(this.draggedClone); + const dragMouseEnterPayload = { + targetColumn: targetColumn, + mousePosition: position, + originalElement: this.originalElement, + draggedClone: this.draggedClone, + calendarEvent: calendarEvent, + replaceClone: (newClone) => { + this.draggedClone = newClone; + this.dragAnimationId === null; + } + }; + this.eventBus.emit('drag:mouseenter-header', dragMouseEnterPayload); + } + } + /** + * Handle mouse enter on day column - for converting all-day to timed events + */ + handleColumnMouseEnter(event) { + // Only handle if we're dragging an all-day event + if (!this.isDragStarted || !this.draggedClone || !this.draggedClone.hasAttribute('data-allday')) { + return; + } + const position = { x: event.clientX, y: event.clientY }; + const targetColumn = ColumnDetectionUtils.getColumnBounds(position); + if (!targetColumn) { + return; + } + // Calculate snapped Y position + const snappedY = this.calculateSnapPosition(position.y, targetColumn); + // Extract ICalendarEvent from the dragged clone + const calendarEvent = SwpEventElement.extractCalendarEventFromElement(this.draggedClone); + const dragMouseEnterPayload = { + targetColumn: targetColumn, + mousePosition: position, + snappedY: snappedY, + originalElement: this.originalElement, + draggedClone: this.draggedClone, + calendarEvent: calendarEvent, + replaceClone: (newClone) => { + this.draggedClone = newClone; + this.dragAnimationId === null; + this.stopDragAnimation(); + } + }; + this.eventBus.emit('drag:mouseenter-column', dragMouseEnterPayload); + } + /** + * Handle mouse leave from calendar header - simplified using native events + */ + handleHeaderMouseLeave(event) { + // Only handle if we're dragging an all-day event + if (!this.isDragStarted || !this.draggedClone || !this.draggedClone.hasAttribute("data-allday")) { + return; + } + const position = { x: event.clientX, y: event.clientY }; + const targetColumn = ColumnDetectionUtils.getColumnBounds(position); + if (!targetColumn) { + return; + } + const dragMouseLeavePayload = { + targetDate: targetColumn.date, + mousePosition: position, + originalElement: this.originalElement, + draggedClone: this.draggedClone + }; + this.eventBus.emit('drag:mouseleave-header', dragMouseLeavePayload); + } +} +//# sourceMappingURL=DragDropManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/DragDropManager.js.map b/wwwroot/js/managers/DragDropManager.js.map new file mode 100644 index 0000000..fc410e8 --- /dev/null +++ b/wwwroot/js/managers/DragDropManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DragDropManager.js","sourceRoot":"","sources":["../../../src/managers/DragDropManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/DragHoverManager.d.ts b/wwwroot/js/managers/DragHoverManager.d.ts new file mode 100644 index 0000000..000bddb --- /dev/null +++ b/wwwroot/js/managers/DragHoverManager.d.ts @@ -0,0 +1,31 @@ +/** + * DragHoverManager - Handles event hover tracking + * Fully autonomous - listens to mouse events and manages hover state independently + */ +import { IEventBus } from '../types/CalendarTypes'; +export declare class DragHoverManager { + private eventBus; + private isHoverTrackingActive; + private currentHoveredEvent; + private calendarContainer; + constructor(eventBus: IEventBus); + private init; + private setupEventListeners; + /** + * Handle mouse enter on swp-event - activate hover tracking + */ + private handleEventMouseEnter; + /** + * Check if mouse is still over the currently hovered event + */ + private checkEventHover; + /** + * Clear hover state + */ + private clearEventHover; + /** + * Deactivate hover tracking and clear any current hover + * Called via event bus when drag starts + */ + private deactivateTracking; +} diff --git a/wwwroot/js/managers/DragHoverManager.js b/wwwroot/js/managers/DragHoverManager.js new file mode 100644 index 0000000..c92b9f3 --- /dev/null +++ b/wwwroot/js/managers/DragHoverManager.js @@ -0,0 +1,101 @@ +/** + * DragHoverManager - Handles event hover tracking + * Fully autonomous - listens to mouse events and manages hover state independently + */ +export class DragHoverManager { + constructor(eventBus) { + this.eventBus = eventBus; + this.isHoverTrackingActive = false; + this.currentHoveredEvent = null; + this.calendarContainer = null; + this.init(); + } + init() { + // Wait for DOM to be ready + setTimeout(() => { + this.calendarContainer = document.querySelector('swp-calendar-container'); + if (this.calendarContainer) { + this.setupEventListeners(); + } + }, 100); + // Listen to drag start to deactivate hover tracking + this.eventBus.on('drag:start', () => { + this.deactivateTracking(); + }); + } + setupEventListeners() { + if (!this.calendarContainer) + return; + // Listen to mouseenter on events (using event delegation) + this.calendarContainer.addEventListener('mouseenter', (e) => { + const target = e.target; + const eventElement = target.closest('swp-event'); + if (eventElement) { + this.handleEventMouseEnter(e, eventElement); + } + }, true); // Use capture phase + // Listen to mousemove globally to track when mouse leaves event bounds + document.body.addEventListener('mousemove', (e) => { + if (this.isHoverTrackingActive && e.buttons === 0) { + this.checkEventHover(e); + } + }); + } + /** + * Handle mouse enter on swp-event - activate hover tracking + */ + handleEventMouseEnter(event, eventElement) { + // Only handle hover if mouse button is up + if (event.buttons === 0) { + // Clear any previous hover first + if (this.currentHoveredEvent && this.currentHoveredEvent !== eventElement) { + this.currentHoveredEvent.classList.remove('hover'); + } + this.isHoverTrackingActive = true; + this.currentHoveredEvent = eventElement; + eventElement.classList.add('hover'); + this.eventBus.emit('event:hover:start', { element: eventElement }); + } + } + /** + * Check if mouse is still over the currently hovered event + */ + checkEventHover(event) { + // Only track hover when active and mouse button is up + if (!this.isHoverTrackingActive || !this.currentHoveredEvent) + return; + const rect = this.currentHoveredEvent.getBoundingClientRect(); + const mouseX = event.clientX; + const mouseY = event.clientY; + // Check if mouse is still within the current hovered event + const isStillInside = mouseX >= rect.left && mouseX <= rect.right && + mouseY >= rect.top && mouseY <= rect.bottom; + // If mouse left the event + if (!isStillInside) { + // Only disable tracking and clear if mouse is NOT pressed (allow resize to work) + if (event.buttons === 0) { + this.isHoverTrackingActive = false; + this.clearEventHover(); + } + } + } + /** + * Clear hover state + */ + clearEventHover() { + if (this.currentHoveredEvent) { + this.currentHoveredEvent.classList.remove('hover'); + this.eventBus.emit('event:hover:end', { element: this.currentHoveredEvent }); + this.currentHoveredEvent = null; + } + } + /** + * Deactivate hover tracking and clear any current hover + * Called via event bus when drag starts + */ + deactivateTracking() { + this.isHoverTrackingActive = false; + this.clearEventHover(); + } +} +//# sourceMappingURL=DragHoverManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/DragHoverManager.js.map b/wwwroot/js/managers/DragHoverManager.js.map new file mode 100644 index 0000000..fdda8d6 --- /dev/null +++ b/wwwroot/js/managers/DragHoverManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DragHoverManager.js","sourceRoot":"","sources":["../../../src/managers/DragHoverManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,gBAAgB;IAK3B,YAAoB,QAAmB;QAAnB,aAAQ,GAAR,QAAQ,CAAW;QAJ/B,0BAAqB,GAAG,KAAK,CAAC;QAC9B,wBAAmB,GAAuB,IAAI,CAAC;QAC/C,sBAAiB,GAAuB,IAAI,CAAC;QAGnD,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAEO,IAAI;QACV,2BAA2B;QAC3B,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC;YAC1E,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,oDAAoD;QACpD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAClC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO;QAEpC,0DAA0D;QAC1D,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;YAC1D,MAAM,MAAM,GAAG,CAAC,CAAC,MAAqB,CAAC;YACvC,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAc,WAAW,CAAC,CAAC;YAE9D,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC,qBAAqB,CAAC,CAAe,EAAE,YAAY,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB;QAE9B,uEAAuE;QACvE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAa,EAAE,EAAE;YAC5D,IAAI,IAAI,CAAC,qBAAqB,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,KAAiB,EAAE,YAAyB;QACxE,0CAA0C;QAC1C,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACxB,iCAAiC;YACjC,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,KAAK,YAAY,EAAE,CAAC;gBAC1E,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAClC,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC;YACxC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEpC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,KAAiB;QACvC,sDAAsD;QACtD,IAAI,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,IAAI,CAAC,mBAAmB;YAAE,OAAO;QAErE,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,2DAA2D;QAC3D,MAAM,aAAa,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK;YAC/D,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAE9C,0BAA0B;QAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,iFAAiF;YACjF,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;gBACnC,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe;QACrB,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;YAC7E,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,kBAAkB;QACxB,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/managers/EdgeScrollManager.d.ts b/wwwroot/js/managers/EdgeScrollManager.d.ts new file mode 100644 index 0000000..da8cdda --- /dev/null +++ b/wwwroot/js/managers/EdgeScrollManager.d.ts @@ -0,0 +1,30 @@ +/** + * EdgeScrollManager - Auto-scroll when dragging near edges + * Uses time-based scrolling with 2-zone system for variable speed + */ +import { IEventBus } from '../types/CalendarTypes'; +export declare class EdgeScrollManager { + private eventBus; + private scrollableContent; + private timeGrid; + private draggedClone; + private scrollRAF; + private mouseY; + private isDragging; + private isScrolling; + private lastTs; + private rect; + private initialScrollTop; + private scrollListener; + private readonly OUTER_ZONE; + private readonly INNER_ZONE; + private readonly SLOW_SPEED_PXS; + private readonly FAST_SPEED_PXS; + constructor(eventBus: IEventBus); + private init; + private subscribeToEvents; + private startDrag; + private stopDrag; + private handleScroll; + private scrollTick; +} diff --git a/wwwroot/js/managers/EdgeScrollManager.js b/wwwroot/js/managers/EdgeScrollManager.js new file mode 100644 index 0000000..7855e51 --- /dev/null +++ b/wwwroot/js/managers/EdgeScrollManager.js @@ -0,0 +1,191 @@ +/** + * EdgeScrollManager - Auto-scroll when dragging near edges + * Uses time-based scrolling with 2-zone system for variable speed + */ +export class EdgeScrollManager { + constructor(eventBus) { + this.eventBus = eventBus; + this.scrollableContent = null; + this.timeGrid = null; + this.draggedClone = null; + this.scrollRAF = null; + this.mouseY = 0; + this.isDragging = false; + this.isScrolling = false; // Track if edge-scroll is active + this.lastTs = 0; + this.rect = null; + this.initialScrollTop = 0; + this.scrollListener = null; + // Constants - fixed values as per requirements + this.OUTER_ZONE = 100; // px from edge (slow zone) + this.INNER_ZONE = 50; // px from edge (fast zone) + this.SLOW_SPEED_PXS = 140; // px/sec in outer zone + this.FAST_SPEED_PXS = 640; // px/sec in inner zone + this.init(); + } + init() { + // Wait for DOM to be ready + setTimeout(() => { + this.scrollableContent = document.querySelector('swp-scrollable-content'); + this.timeGrid = document.querySelector('swp-time-grid'); + if (this.scrollableContent) { + // Disable smooth scroll for instant auto-scroll + this.scrollableContent.style.scrollBehavior = 'auto'; + // Add scroll listener to detect actual scrolling + this.scrollListener = this.handleScroll.bind(this); + this.scrollableContent.addEventListener('scroll', this.scrollListener, { passive: true }); + } + }, 100); + // Listen to mousemove directly from document to always get mouse coords + document.body.addEventListener('mousemove', (e) => { + if (this.isDragging) { + this.mouseY = e.clientY; + } + }); + this.subscribeToEvents(); + } + subscribeToEvents() { + // Listen to drag events from DragDropManager + this.eventBus.on('drag:start', (event) => { + const payload = event.detail; + this.draggedClone = payload.draggedClone; + this.startDrag(); + }); + this.eventBus.on('drag:end', () => this.stopDrag()); + this.eventBus.on('drag:cancelled', () => this.stopDrag()); + // Stop scrolling when event converts to/from all-day + this.eventBus.on('drag:mouseenter-header', () => { + console.log('🔄 EdgeScrollManager: Event converting to all-day - stopping scroll'); + this.stopDrag(); + }); + this.eventBus.on('drag:mouseenter-column', () => { + this.startDrag(); + }); + } + startDrag() { + console.log('🎬 EdgeScrollManager: Starting drag'); + this.isDragging = true; + this.isScrolling = false; // Reset scroll state + this.lastTs = performance.now(); + // Save initial scroll position + if (this.scrollableContent) { + this.initialScrollTop = this.scrollableContent.scrollTop; + } + if (this.scrollRAF === null) { + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } + } + stopDrag() { + this.isDragging = false; + // Emit stopped event if we were scrolling + if (this.isScrolling) { + this.isScrolling = false; + console.log('🛑 EdgeScrollManager: Edge-scroll stopped (drag ended)'); + this.eventBus.emit('edgescroll:stopped', {}); + } + if (this.scrollRAF !== null) { + cancelAnimationFrame(this.scrollRAF); + this.scrollRAF = null; + } + this.rect = null; + this.lastTs = 0; + this.initialScrollTop = 0; + } + handleScroll() { + if (!this.isDragging || !this.scrollableContent) + return; + const currentScrollTop = this.scrollableContent.scrollTop; + const scrollDelta = Math.abs(currentScrollTop - this.initialScrollTop); + // Only emit started event if we've actually scrolled more than 1px + if (scrollDelta > 1 && !this.isScrolling) { + this.isScrolling = true; + console.log('💾 EdgeScrollManager: Edge-scroll started (actual scroll detected)', { + initialScrollTop: this.initialScrollTop, + currentScrollTop, + scrollDelta + }); + this.eventBus.emit('edgescroll:started', {}); + } + } + scrollTick(ts) { + const dt = this.lastTs ? (ts - this.lastTs) / 1000 : 0; + this.lastTs = ts; + if (!this.scrollableContent) { + this.stopDrag(); + return; + } + // Cache rect for performance (only measure once per frame) + if (!this.rect) { + this.rect = this.scrollableContent.getBoundingClientRect(); + } + let vy = 0; + if (this.isDragging) { + const distTop = this.mouseY - this.rect.top; + const distBot = this.rect.bottom - this.mouseY; + // Check top edge + if (distTop < this.INNER_ZONE) { + vy = -this.FAST_SPEED_PXS; + } + else if (distTop < this.OUTER_ZONE) { + vy = -this.SLOW_SPEED_PXS; + } + // Check bottom edge + else if (distBot < this.INNER_ZONE) { + vy = this.FAST_SPEED_PXS; + } + else if (distBot < this.OUTER_ZONE) { + vy = this.SLOW_SPEED_PXS; + } + } + if (vy !== 0 && this.isDragging && this.timeGrid && this.draggedClone) { + // Check if we can scroll in the requested direction + const currentScrollTop = this.scrollableContent.scrollTop; + const scrollableHeight = this.scrollableContent.clientHeight; + const timeGridHeight = this.timeGrid.clientHeight; + // Get dragged element position and height + const cloneRect = this.draggedClone.getBoundingClientRect(); + const cloneBottom = cloneRect.bottom; + const timeGridRect = this.timeGrid.getBoundingClientRect(); + const timeGridBottom = timeGridRect.bottom; + // Check boundaries + const atTop = currentScrollTop <= 0 && vy < 0; + const atBottom = (cloneBottom >= timeGridBottom) && vy > 0; + if (atTop || atBottom) { + // At boundary - stop scrolling + if (this.isScrolling) { + this.isScrolling = false; + this.initialScrollTop = this.scrollableContent.scrollTop; + console.log('🛑 EdgeScrollManager: Edge-scroll stopped (reached boundary)'); + this.eventBus.emit('edgescroll:stopped', {}); + } + // Continue RAF loop to detect when mouse moves away from boundary + if (this.isDragging) { + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } + } + else { + // Not at boundary - apply scroll + this.scrollableContent.scrollTop += vy * dt; + this.rect = null; // Invalidate cache for next frame + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } + } + else { + // Mouse moved away from edge - stop scrolling + if (this.isScrolling) { + this.isScrolling = false; + this.initialScrollTop = this.scrollableContent.scrollTop; // Reset for next scroll + console.log('🛑 EdgeScrollManager: Edge-scroll stopped (mouse left edge)'); + this.eventBus.emit('edgescroll:stopped', {}); + } + // Continue RAF loop even if not scrolling, to detect edge entry + if (this.isDragging) { + this.scrollRAF = requestAnimationFrame((ts) => this.scrollTick(ts)); + } + else { + this.stopDrag(); + } + } + } +} +//# sourceMappingURL=EdgeScrollManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/EdgeScrollManager.js.map b/wwwroot/js/managers/EdgeScrollManager.js.map new file mode 100644 index 0000000..72c0b1f --- /dev/null +++ b/wwwroot/js/managers/EdgeScrollManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EdgeScrollManager.js","sourceRoot":"","sources":["../../../src/managers/EdgeScrollManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/EventFilterManager.d.ts b/wwwroot/js/managers/EventFilterManager.d.ts new file mode 100644 index 0000000..91092b2 --- /dev/null +++ b/wwwroot/js/managers/EventFilterManager.d.ts @@ -0,0 +1,32 @@ +/** + * EventFilterManager - Handles fuzzy search filtering of calendar events + * Uses Fuse.js for fuzzy matching (Apache 2.0 License) + */ +export declare class EventFilterManager { + private searchInput; + private allEvents; + private matchingEventIds; + private isFilterActive; + private frameRequest; + private fuse; + constructor(); + private init; + private setupSearchListeners; + private subscribeToEvents; + private updateEventsList; + private handleSearchInput; + private applyFilter; + private clearFilter; + private updateVisualState; + /** + * Check if an event matches the current filter + */ + eventMatchesFilter(eventId: string): boolean; + /** + * Get current filter state + */ + getFilterState(): { + active: boolean; + matchingIds: string[]; + }; +} diff --git a/wwwroot/js/managers/EventFilterManager.js b/wwwroot/js/managers/EventFilterManager.js new file mode 100644 index 0000000..dd2bd84 --- /dev/null +++ b/wwwroot/js/managers/EventFilterManager.js @@ -0,0 +1,192 @@ +/** + * EventFilterManager - Handles fuzzy search filtering of calendar events + * Uses Fuse.js for fuzzy matching (Apache 2.0 License) + */ +import { eventBus } from '../core/EventBus'; +import { CoreEvents } from '../constants/CoreEvents'; +// Import Fuse.js from npm +import Fuse from 'fuse.js'; +export class EventFilterManager { + constructor() { + this.searchInput = null; + this.allEvents = []; + this.matchingEventIds = new Set(); + this.isFilterActive = false; + this.frameRequest = null; + this.fuse = null; + // Wait for DOM to be ready before initializing + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { + this.init(); + }); + } + else { + this.init(); + } + } + init() { + // Find search input + this.searchInput = document.querySelector('swp-search-container input[type="search"]'); + if (!this.searchInput) { + return; + } + // Set up event listeners + this.setupSearchListeners(); + this.subscribeToEvents(); + // Initialization complete + } + setupSearchListeners() { + if (!this.searchInput) + return; + // Listen for input changes + this.searchInput.addEventListener('input', (e) => { + const query = e.target.value; + this.handleSearchInput(query); + }); + // Listen for escape key + this.searchInput.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + this.clearFilter(); + } + }); + } + subscribeToEvents() { + // Listen for events data updates + eventBus.on(CoreEvents.EVENTS_RENDERED, (e) => { + const detail = e.detail; + if (detail?.events) { + this.updateEventsList(detail.events); + } + }); + } + updateEventsList(events) { + this.allEvents = events; + // Initialize Fuse with the new events list + this.fuse = new Fuse(this.allEvents, { + keys: ['title', 'description'], + threshold: 0.3, + includeScore: true, + minMatchCharLength: 2, // Minimum 2 characters for a match + shouldSort: true, + ignoreLocation: true // Search anywhere in the string + }); + // Re-apply filter if active + if (this.isFilterActive && this.searchInput) { + this.applyFilter(this.searchInput.value); + } + } + handleSearchInput(query) { + // Cancel any pending filter + if (this.frameRequest) { + cancelAnimationFrame(this.frameRequest); + } + // Debounce with requestAnimationFrame + this.frameRequest = requestAnimationFrame(() => { + if (query.length === 0) { + // Only clear when input is completely empty + this.clearFilter(); + } + else { + // Let Fuse.js handle minimum character length via minMatchCharLength + this.applyFilter(query); + } + }); + } + applyFilter(query) { + if (!this.fuse) { + return; + } + // Perform fuzzy search + const results = this.fuse.search(query); + // Extract matching event IDs + this.matchingEventIds.clear(); + results.forEach((result) => { + if (result.item && result.item.id) { + this.matchingEventIds.add(result.item.id); + } + }); + // Update filter state + this.isFilterActive = true; + // Update visual state + this.updateVisualState(); + // Emit filter changed event + eventBus.emit(CoreEvents.FILTER_CHANGED, { + active: true, + query: query, + matchingIds: Array.from(this.matchingEventIds) + }); + } + clearFilter() { + this.isFilterActive = false; + this.matchingEventIds.clear(); + // Clear search input + if (this.searchInput) { + this.searchInput.value = ''; + } + // Update visual state + this.updateVisualState(); + // Emit filter cleared event + eventBus.emit(CoreEvents.FILTER_CHANGED, { + active: false, + query: '', + matchingIds: [] + }); + } + updateVisualState() { + // Update search container styling + const searchContainer = document.querySelector('swp-search-container'); + if (searchContainer) { + if (this.isFilterActive) { + searchContainer.classList.add('filter-active'); + } + else { + searchContainer.classList.remove('filter-active'); + } + } + // Update all events layers + const eventsLayers = document.querySelectorAll('swp-events-layer'); + eventsLayers.forEach(layer => { + if (this.isFilterActive) { + layer.setAttribute('data-filter-active', 'true'); + // Mark matching events + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + const eventId = event.getAttribute('data-event-id'); + if (eventId && this.matchingEventIds.has(eventId)) { + event.setAttribute('data-matches', 'true'); + } + else { + event.removeAttribute('data-matches'); + } + }); + } + else { + layer.removeAttribute('data-filter-active'); + // Remove all match attributes + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + event.removeAttribute('data-matches'); + }); + } + }); + } + /** + * Check if an event matches the current filter + */ + eventMatchesFilter(eventId) { + if (!this.isFilterActive) { + return true; // No filter active, all events match + } + return this.matchingEventIds.has(eventId); + } + /** + * Get current filter state + */ + getFilterState() { + return { + active: this.isFilterActive, + matchingIds: Array.from(this.matchingEventIds) + }; + } +} +//# sourceMappingURL=EventFilterManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/EventFilterManager.js.map b/wwwroot/js/managers/EventFilterManager.js.map new file mode 100644 index 0000000..295cbd1 --- /dev/null +++ b/wwwroot/js/managers/EventFilterManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventFilterManager.js","sourceRoot":"","sources":["../../../src/managers/EventFilterManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/EventLayoutCoordinator.d.ts b/wwwroot/js/managers/EventLayoutCoordinator.d.ts new file mode 100644 index 0000000..5079618 --- /dev/null +++ b/wwwroot/js/managers/EventLayoutCoordinator.d.ts @@ -0,0 +1,78 @@ +/** + * EventLayoutCoordinator - Coordinates event layout calculations + * + * Separates layout logic from rendering concerns. + * Calculates stack levels, groups events, and determines rendering strategy. + */ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { EventStackManager, IStackLink } from './EventStackManager'; +import { PositionUtils } from '../utils/PositionUtils'; +import { Configuration } from '../configurations/CalendarConfig'; +export interface IGridGroupLayout { + events: ICalendarEvent[]; + stackLevel: number; + position: { + top: number; + }; + columns: ICalendarEvent[][]; +} +export interface IStackedEventLayout { + event: ICalendarEvent; + stackLink: IStackLink; + position: { + top: number; + height: number; + }; +} +export interface IColumnLayout { + gridGroups: IGridGroupLayout[]; + stackedEvents: IStackedEventLayout[]; +} +export declare class EventLayoutCoordinator { + private stackManager; + private config; + private positionUtils; + constructor(stackManager: EventStackManager, config: Configuration, positionUtils: PositionUtils); + /** + * Calculate complete layout for a column of events (recursive approach) + */ + calculateColumnLayout(columnEvents: ICalendarEvent[]): IColumnLayout; + /** + * Calculate stack level for a grid group based on already rendered events + */ + private calculateGridGroupStackLevelFromRendered; + /** + * Calculate stack level for a single stacked event based on already rendered events + */ + private calculateStackLevelFromRendered; + /** + * Detect if two events have a conflict based on threshold + * + * @param event1 - First event + * @param event2 - Second event + * @param thresholdMinutes - Threshold in minutes + * @returns true if events conflict + */ + private detectConflict; + /** + * Expand grid candidates to find all events connected by conflict chains + * + * Uses expanding search to find chains (A→B→C where each conflicts with next) + * + * @param firstEvent - The first event to start with + * @param remaining - Remaining events to check + * @param thresholdMinutes - Threshold in minutes + * @returns Array of all events in the conflict chain + */ + private expandGridCandidates; + /** + * Allocate events to columns within a grid group + * + * Events that don't overlap can share the same column. + * Uses a greedy algorithm to minimize the number of columns. + * + * @param events - Events in the grid group (should already be sorted by start time) + * @returns Array of columns, where each column is an array of events + */ + private allocateColumns; +} diff --git a/wwwroot/js/managers/EventLayoutCoordinator.js b/wwwroot/js/managers/EventLayoutCoordinator.js new file mode 100644 index 0000000..381bc25 --- /dev/null +++ b/wwwroot/js/managers/EventLayoutCoordinator.js @@ -0,0 +1,201 @@ +/** + * EventLayoutCoordinator - Coordinates event layout calculations + * + * Separates layout logic from rendering concerns. + * Calculates stack levels, groups events, and determines rendering strategy. + */ +export class EventLayoutCoordinator { + constructor(stackManager, config, positionUtils) { + this.stackManager = stackManager; + this.config = config; + this.positionUtils = positionUtils; + } + /** + * Calculate complete layout for a column of events (recursive approach) + */ + calculateColumnLayout(columnEvents) { + if (columnEvents.length === 0) { + return { gridGroups: [], stackedEvents: [] }; + } + const gridGroupLayouts = []; + const stackedEventLayouts = []; + const renderedEventsWithLevels = []; + let remaining = [...columnEvents].sort((a, b) => a.start.getTime() - b.start.getTime()); + // Process events recursively + while (remaining.length > 0) { + // Take first event + const firstEvent = remaining[0]; + // Find events that could be in GRID with first event + // Use expanding search to find chains (A→B→C where each conflicts with next) + const gridSettings = this.config.gridSettings; + const thresholdMinutes = gridSettings.gridStartThresholdMinutes; + // Use refactored method for expanding grid candidates + const gridCandidates = this.expandGridCandidates(firstEvent, remaining, thresholdMinutes); + // Decide: should this group be GRID or STACK? + const group = { + events: gridCandidates, + containerType: 'NONE', + startTime: firstEvent.start + }; + const containerType = this.stackManager.decideContainerType(group); + if (containerType === 'GRID' && gridCandidates.length > 1) { + // Render as GRID + const gridStackLevel = this.calculateGridGroupStackLevelFromRendered(gridCandidates, renderedEventsWithLevels); + // Ensure we get the earliest event (explicit sort for robustness) + const earliestEvent = [...gridCandidates].sort((a, b) => a.start.getTime() - b.start.getTime())[0]; + const position = this.positionUtils.calculateEventPosition(earliestEvent.start, earliestEvent.end); + const columns = this.allocateColumns(gridCandidates); + gridGroupLayouts.push({ + events: gridCandidates, + stackLevel: gridStackLevel, + position: { top: position.top + 1 }, + columns + }); + // Mark all events in grid with their stack level + gridCandidates.forEach(e => renderedEventsWithLevels.push({ event: e, level: gridStackLevel })); + // Remove all events in this grid from remaining + remaining = remaining.filter(e => !gridCandidates.includes(e)); + } + else { + // Render first event as STACKED + const stackLevel = this.calculateStackLevelFromRendered(firstEvent, renderedEventsWithLevels); + const position = this.positionUtils.calculateEventPosition(firstEvent.start, firstEvent.end); + stackedEventLayouts.push({ + event: firstEvent, + stackLink: { stackLevel }, + position: { top: position.top + 1, height: position.height - 3 } + }); + // Mark this event with its stack level + renderedEventsWithLevels.push({ event: firstEvent, level: stackLevel }); + // Remove only first event from remaining + remaining = remaining.slice(1); + } + } + return { + gridGroups: gridGroupLayouts, + stackedEvents: stackedEventLayouts + }; + } + /** + * Calculate stack level for a grid group based on already rendered events + */ + calculateGridGroupStackLevelFromRendered(gridEvents, renderedEventsWithLevels) { + // Find highest stack level of any rendered event that overlaps with this grid + let maxOverlappingLevel = -1; + for (const gridEvent of gridEvents) { + for (const rendered of renderedEventsWithLevels) { + if (this.stackManager.doEventsOverlap(gridEvent, rendered.event)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, rendered.level); + } + } + } + return maxOverlappingLevel + 1; + } + /** + * Calculate stack level for a single stacked event based on already rendered events + */ + calculateStackLevelFromRendered(event, renderedEventsWithLevels) { + // Find highest stack level of any rendered event that overlaps with this event + let maxOverlappingLevel = -1; + for (const rendered of renderedEventsWithLevels) { + if (this.stackManager.doEventsOverlap(event, rendered.event)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, rendered.level); + } + } + return maxOverlappingLevel + 1; + } + /** + * Detect if two events have a conflict based on threshold + * + * @param event1 - First event + * @param event2 - Second event + * @param thresholdMinutes - Threshold in minutes + * @returns true if events conflict + */ + detectConflict(event1, event2, thresholdMinutes) { + // Check 1: Start-to-start conflict (starts within threshold) + const startToStartDiff = Math.abs(event1.start.getTime() - event2.start.getTime()) / (1000 * 60); + if (startToStartDiff <= thresholdMinutes && this.stackManager.doEventsOverlap(event1, event2)) { + return true; + } + // Check 2: End-to-start conflict (event1 starts within threshold before event2 ends) + const endToStartMinutes = (event2.end.getTime() - event1.start.getTime()) / (1000 * 60); + if (endToStartMinutes > 0 && endToStartMinutes <= thresholdMinutes) { + return true; + } + // Check 3: Reverse end-to-start (event2 starts within threshold before event1 ends) + const reverseEndToStart = (event1.end.getTime() - event2.start.getTime()) / (1000 * 60); + if (reverseEndToStart > 0 && reverseEndToStart <= thresholdMinutes) { + return true; + } + return false; + } + /** + * Expand grid candidates to find all events connected by conflict chains + * + * Uses expanding search to find chains (A→B→C where each conflicts with next) + * + * @param firstEvent - The first event to start with + * @param remaining - Remaining events to check + * @param thresholdMinutes - Threshold in minutes + * @returns Array of all events in the conflict chain + */ + expandGridCandidates(firstEvent, remaining, thresholdMinutes) { + const gridCandidates = [firstEvent]; + let candidatesChanged = true; + // Keep expanding until no new candidates can be added + while (candidatesChanged) { + candidatesChanged = false; + for (let i = 1; i < remaining.length; i++) { + const candidate = remaining[i]; + // Skip if already in candidates + if (gridCandidates.includes(candidate)) + continue; + // Check if candidate conflicts with ANY event in gridCandidates + for (const existingCandidate of gridCandidates) { + if (this.detectConflict(candidate, existingCandidate, thresholdMinutes)) { + gridCandidates.push(candidate); + candidatesChanged = true; + break; // Found conflict, move to next candidate + } + } + } + } + return gridCandidates; + } + /** + * Allocate events to columns within a grid group + * + * Events that don't overlap can share the same column. + * Uses a greedy algorithm to minimize the number of columns. + * + * @param events - Events in the grid group (should already be sorted by start time) + * @returns Array of columns, where each column is an array of events + */ + allocateColumns(events) { + if (events.length === 0) + return []; + if (events.length === 1) + return [[events[0]]]; + const columns = []; + // For each event, try to place it in an existing column where it doesn't overlap + for (const event of events) { + let placed = false; + // Try to find a column where this event doesn't overlap with any existing event + for (const column of columns) { + const hasOverlap = column.some(colEvent => this.stackManager.doEventsOverlap(event, colEvent)); + if (!hasOverlap) { + column.push(event); + placed = true; + break; + } + } + // If no suitable column found, create a new one + if (!placed) { + columns.push([event]); + } + } + return columns; + } +} +//# sourceMappingURL=EventLayoutCoordinator.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/EventLayoutCoordinator.js.map b/wwwroot/js/managers/EventLayoutCoordinator.js.map new file mode 100644 index 0000000..18f9e09 --- /dev/null +++ b/wwwroot/js/managers/EventLayoutCoordinator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventLayoutCoordinator.js","sourceRoot":"","sources":["../../../src/managers/EventLayoutCoordinator.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/EventManager.d.ts b/wwwroot/js/managers/EventManager.d.ts new file mode 100644 index 0000000..dde95d1 --- /dev/null +++ b/wwwroot/js/managers/EventManager.d.ts @@ -0,0 +1,69 @@ +import { IEventBus, ICalendarEvent } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +import { DateService } from '../utils/DateService'; +import { IEventRepository } from '../repositories/IEventRepository'; +/** + * EventManager - Event lifecycle and CRUD operations + * Delegates all data operations to IEventRepository + * No longer maintains in-memory cache - repository is single source of truth + */ +export declare class EventManager { + private eventBus; + private dateService; + private config; + private repository; + constructor(eventBus: IEventBus, dateService: DateService, config: Configuration, repository: IEventRepository); + /** + * Load event data from repository + * No longer caches - delegates to repository + */ + loadData(): Promise; + /** + * Get all events from repository + */ + getEvents(copy?: boolean): Promise; + /** + * Get event by ID from repository + */ + getEventById(id: string): Promise; + /** + * Get event by ID and return event info for navigation + * @param id Event ID to find + * @returns Event with navigation info or null if not found + */ + getEventForNavigation(id: string): Promise<{ + event: ICalendarEvent; + eventDate: Date; + } | null>; + /** + * Navigate to specific event by ID + * Emits navigation events for other managers to handle + * @param eventId Event ID to navigate to + * @returns true if event found and navigation initiated, false otherwise + */ + navigateToEvent(eventId: string): Promise; + /** + * Get events that overlap with a given time period + */ + getEventsForPeriod(startDate: Date, endDate: Date): Promise; + /** + * Create a new event and add it to the calendar + * Delegates to repository with source='local' + */ + addEvent(event: Omit): Promise; + /** + * Update an existing event + * Delegates to repository with source='local' + */ + updateEvent(id: string, updates: Partial): Promise; + /** + * Delete an event + * Delegates to repository with source='local' + */ + deleteEvent(id: string): Promise; + /** + * Handle remote update from SignalR + * Delegates to repository with source='remote' + */ + handleRemoteUpdate(event: ICalendarEvent): Promise; +} diff --git a/wwwroot/js/managers/EventManager.js b/wwwroot/js/managers/EventManager.js new file mode 100644 index 0000000..982105f --- /dev/null +++ b/wwwroot/js/managers/EventManager.js @@ -0,0 +1,164 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * EventManager - Event lifecycle and CRUD operations + * Delegates all data operations to IEventRepository + * No longer maintains in-memory cache - repository is single source of truth + */ +export class EventManager { + constructor(eventBus, dateService, config, repository) { + this.eventBus = eventBus; + this.dateService = dateService; + this.config = config; + this.repository = repository; + } + /** + * Load event data from repository + * No longer caches - delegates to repository + */ + async loadData() { + try { + // Just ensure repository is ready - no caching + await this.repository.loadEvents(); + } + catch (error) { + console.error('Failed to load event data:', error); + throw error; + } + } + /** + * Get all events from repository + */ + async getEvents(copy = false) { + const events = await this.repository.loadEvents(); + return copy ? [...events] : events; + } + /** + * Get event by ID from repository + */ + async getEventById(id) { + const events = await this.repository.loadEvents(); + return events.find(event => event.id === id); + } + /** + * Get event by ID and return event info for navigation + * @param id Event ID to find + * @returns Event with navigation info or null if not found + */ + async getEventForNavigation(id) { + const event = await this.getEventById(id); + if (!event) { + return null; + } + // Validate event dates + const validation = this.dateService.validateDate(event.start); + if (!validation.valid) { + console.warn(`EventManager: Invalid event start date for event ${id}:`, validation.error); + return null; + } + // Validate date range + if (!this.dateService.isValidRange(event.start, event.end)) { + console.warn(`EventManager: Invalid date range for event ${id}: start must be before end`); + return null; + } + return { + event, + eventDate: event.start + }; + } + /** + * Navigate to specific event by ID + * Emits navigation events for other managers to handle + * @param eventId Event ID to navigate to + * @returns true if event found and navigation initiated, false otherwise + */ + async navigateToEvent(eventId) { + const eventInfo = await this.getEventForNavigation(eventId); + if (!eventInfo) { + console.warn(`EventManager: Event with ID ${eventId} not found`); + return false; + } + const { event, eventDate } = eventInfo; + // Emit navigation request event + this.eventBus.emit(CoreEvents.NAVIGATE_TO_EVENT, { + eventId, + event, + eventDate, + eventStartTime: event.start + }); + return true; + } + /** + * Get events that overlap with a given time period + */ + async getEventsForPeriod(startDate, endDate) { + const events = await this.repository.loadEvents(); + // Event overlaps period if it starts before period ends AND ends after period starts + return events.filter(event => { + return event.start <= endDate && event.end >= startDate; + }); + } + /** + * Create a new event and add it to the calendar + * Delegates to repository with source='local' + */ + async addEvent(event) { + const newEvent = await this.repository.createEvent(event, 'local'); + this.eventBus.emit(CoreEvents.EVENT_CREATED, { + event: newEvent + }); + return newEvent; + } + /** + * Update an existing event + * Delegates to repository with source='local' + */ + async updateEvent(id, updates) { + try { + const updatedEvent = await this.repository.updateEvent(id, updates, 'local'); + this.eventBus.emit(CoreEvents.EVENT_UPDATED, { + event: updatedEvent + }); + return updatedEvent; + } + catch (error) { + console.error(`Failed to update event ${id}:`, error); + return null; + } + } + /** + * Delete an event + * Delegates to repository with source='local' + */ + async deleteEvent(id) { + try { + await this.repository.deleteEvent(id, 'local'); + this.eventBus.emit(CoreEvents.EVENT_DELETED, { + eventId: id + }); + return true; + } + catch (error) { + console.error(`Failed to delete event ${id}:`, error); + return false; + } + } + /** + * Handle remote update from SignalR + * Delegates to repository with source='remote' + */ + async handleRemoteUpdate(event) { + try { + await this.repository.updateEvent(event.id, event, 'remote'); + this.eventBus.emit(CoreEvents.REMOTE_UPDATE_RECEIVED, { + event + }); + this.eventBus.emit(CoreEvents.EVENT_UPDATED, { + event + }); + } + catch (error) { + console.error(`Failed to handle remote update for event ${event.id}:`, error); + } + } +} +//# sourceMappingURL=EventManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/EventManager.js.map b/wwwroot/js/managers/EventManager.js.map new file mode 100644 index 0000000..5ff19fb --- /dev/null +++ b/wwwroot/js/managers/EventManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventManager.js","sourceRoot":"","sources":["../../../src/managers/EventManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/EventStackManager.d.ts b/wwwroot/js/managers/EventStackManager.d.ts new file mode 100644 index 0000000..e2de953 --- /dev/null +++ b/wwwroot/js/managers/EventStackManager.d.ts @@ -0,0 +1,91 @@ +/** + * EventStackManager - Manages visual stacking of overlapping calendar events + * + * This class handles the creation and maintenance of "stack chains" - doubly-linked + * lists of overlapping events stored directly in DOM elements via data attributes. + * + * Implements 3-phase algorithm for grid + nested stacking: + * Phase 1: Group events by start time proximity (configurable threshold) + * Phase 2: Decide container type (GRID vs STACKING) + * Phase 3: Handle late arrivals (nested stacking - NOT IMPLEMENTED) + * + * @see STACKING_CONCEPT.md for detailed documentation + * @see stacking-visualization.html for visual examples + */ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +export interface IStackLink { + prev?: string; + next?: string; + stackLevel: number; +} +export interface IEventGroup { + events: ICalendarEvent[]; + containerType: 'NONE' | 'GRID' | 'STACKING'; + startTime: Date; +} +export declare class EventStackManager { + private static readonly STACK_OFFSET_PX; + private config; + constructor(config: Configuration); + /** + * Group events by time conflicts (both start-to-start and end-to-start within threshold) + * + * Events are grouped if: + * 1. They start within ±threshold minutes of each other (start-to-start) + * 2. One event starts within threshold minutes before another ends (end-to-start conflict) + */ + groupEventsByStartTime(events: ICalendarEvent[]): IEventGroup[]; + /** + * Decide container type for a group of events + * + * Rule: Events starting simultaneously (within threshold) should ALWAYS use GRID, + * even if they overlap each other. This provides better visual indication that + * events start at the same time. + */ + decideContainerType(group: IEventGroup): 'NONE' | 'GRID' | 'STACKING'; + /** + * Check if two events overlap in time + */ + doEventsOverlap(event1: ICalendarEvent, event2: ICalendarEvent): boolean; + /** + * Create optimized stack links (events share levels when possible) + */ + createOptimizedStackLinks(events: ICalendarEvent[]): Map; + /** + * Calculate marginLeft based on stack level + */ + calculateMarginLeft(stackLevel: number): number; + /** + * Calculate zIndex based on stack level + */ + calculateZIndex(stackLevel: number): number; + /** + * Serialize stack link to JSON string + */ + serializeStackLink(stackLink: IStackLink): string; + /** + * Deserialize JSON string to stack link + */ + deserializeStackLink(json: string): IStackLink | null; + /** + * Apply stack link to DOM element + */ + applyStackLinkToElement(element: HTMLElement, stackLink: IStackLink): void; + /** + * Get stack link from DOM element + */ + getStackLinkFromElement(element: HTMLElement): IStackLink | null; + /** + * Apply visual styling to element based on stack level + */ + applyVisualStyling(element: HTMLElement, stackLevel: number): void; + /** + * Clear stack link from element + */ + clearStackLinkFromElement(element: HTMLElement): void; + /** + * Clear visual styling from element + */ + clearVisualStyling(element: HTMLElement): void; +} diff --git a/wwwroot/js/managers/EventStackManager.js b/wwwroot/js/managers/EventStackManager.js new file mode 100644 index 0000000..cb48109 --- /dev/null +++ b/wwwroot/js/managers/EventStackManager.js @@ -0,0 +1,217 @@ +/** + * EventStackManager - Manages visual stacking of overlapping calendar events + * + * This class handles the creation and maintenance of "stack chains" - doubly-linked + * lists of overlapping events stored directly in DOM elements via data attributes. + * + * Implements 3-phase algorithm for grid + nested stacking: + * Phase 1: Group events by start time proximity (configurable threshold) + * Phase 2: Decide container type (GRID vs STACKING) + * Phase 3: Handle late arrivals (nested stacking - NOT IMPLEMENTED) + * + * @see STACKING_CONCEPT.md for detailed documentation + * @see stacking-visualization.html for visual examples + */ +export class EventStackManager { + constructor(config) { + this.config = config; + } + // ============================================ + // PHASE 1: Start Time Grouping + // ============================================ + /** + * Group events by time conflicts (both start-to-start and end-to-start within threshold) + * + * Events are grouped if: + * 1. They start within ±threshold minutes of each other (start-to-start) + * 2. One event starts within threshold minutes before another ends (end-to-start conflict) + */ + groupEventsByStartTime(events) { + if (events.length === 0) + return []; + // Get threshold from config + const gridSettings = this.config.gridSettings; + const thresholdMinutes = gridSettings.gridStartThresholdMinutes; + // Sort events by start time + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const groups = []; + for (const event of sorted) { + // Find existing group that this event conflicts with + const existingGroup = groups.find(group => { + // Check if event conflicts with ANY event in the group + return group.events.some(groupEvent => { + // Start-to-start conflict: events start within threshold + const startToStartMinutes = Math.abs(event.start.getTime() - groupEvent.start.getTime()) / (1000 * 60); + if (startToStartMinutes <= thresholdMinutes) { + return true; + } + // End-to-start conflict: event starts within threshold before groupEvent ends + const endToStartMinutes = (groupEvent.end.getTime() - event.start.getTime()) / (1000 * 60); + if (endToStartMinutes > 0 && endToStartMinutes <= thresholdMinutes) { + return true; + } + // Also check reverse: groupEvent starts within threshold before event ends + const reverseEndToStart = (event.end.getTime() - groupEvent.start.getTime()) / (1000 * 60); + if (reverseEndToStart > 0 && reverseEndToStart <= thresholdMinutes) { + return true; + } + return false; + }); + }); + if (existingGroup) { + existingGroup.events.push(event); + } + else { + groups.push({ + events: [event], + containerType: 'NONE', + startTime: event.start + }); + } + } + return groups; + } + // ============================================ + // PHASE 2: Container Type Decision + // ============================================ + /** + * Decide container type for a group of events + * + * Rule: Events starting simultaneously (within threshold) should ALWAYS use GRID, + * even if they overlap each other. This provides better visual indication that + * events start at the same time. + */ + decideContainerType(group) { + if (group.events.length === 1) { + return 'NONE'; + } + // If events are grouped together (start within threshold), they should share columns (GRID) + // This is true EVEN if they overlap, because the visual priority is to show + // that they start simultaneously. + return 'GRID'; + } + /** + * Check if two events overlap in time + */ + doEventsOverlap(event1, event2) { + return event1.start < event2.end && event1.end > event2.start; + } + // ============================================ + // Stack Level Calculation + // ============================================ + /** + * Create optimized stack links (events share levels when possible) + */ + createOptimizedStackLinks(events) { + const stackLinks = new Map(); + if (events.length === 0) + return stackLinks; + // Sort by start time + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + // Step 1: Assign stack levels + for (const event of sorted) { + // Find all events this event overlaps with + const overlapping = sorted.filter(other => other !== event && this.doEventsOverlap(event, other)); + // Find the MINIMUM required level (must be above all overlapping events) + let minRequiredLevel = 0; + for (const other of overlapping) { + const otherLink = stackLinks.get(other.id); + if (otherLink) { + // Must be at least one level above the overlapping event + minRequiredLevel = Math.max(minRequiredLevel, otherLink.stackLevel + 1); + } + } + stackLinks.set(event.id, { stackLevel: minRequiredLevel }); + } + // Step 2: Build prev/next chains for overlapping events at adjacent stack levels + for (const event of sorted) { + const currentLink = stackLinks.get(event.id); + // Find overlapping events that are directly below (stackLevel - 1) + const overlapping = sorted.filter(other => other !== event && this.doEventsOverlap(event, other)); + const directlyBelow = overlapping.filter(other => { + const otherLink = stackLinks.get(other.id); + return otherLink && otherLink.stackLevel === currentLink.stackLevel - 1; + }); + if (directlyBelow.length > 0) { + // Use the first one in sorted order as prev + currentLink.prev = directlyBelow[0].id; + } + // Find overlapping events that are directly above (stackLevel + 1) + const directlyAbove = overlapping.filter(other => { + const otherLink = stackLinks.get(other.id); + return otherLink && otherLink.stackLevel === currentLink.stackLevel + 1; + }); + if (directlyAbove.length > 0) { + // Use the first one in sorted order as next + currentLink.next = directlyAbove[0].id; + } + } + return stackLinks; + } + /** + * Calculate marginLeft based on stack level + */ + calculateMarginLeft(stackLevel) { + return stackLevel * EventStackManager.STACK_OFFSET_PX; + } + /** + * Calculate zIndex based on stack level + */ + calculateZIndex(stackLevel) { + return 100 + stackLevel; + } + /** + * Serialize stack link to JSON string + */ + serializeStackLink(stackLink) { + return JSON.stringify(stackLink); + } + /** + * Deserialize JSON string to stack link + */ + deserializeStackLink(json) { + try { + return JSON.parse(json); + } + catch (e) { + return null; + } + } + /** + * Apply stack link to DOM element + */ + applyStackLinkToElement(element, stackLink) { + element.dataset.stackLink = this.serializeStackLink(stackLink); + } + /** + * Get stack link from DOM element + */ + getStackLinkFromElement(element) { + const data = element.dataset.stackLink; + if (!data) + return null; + return this.deserializeStackLink(data); + } + /** + * Apply visual styling to element based on stack level + */ + applyVisualStyling(element, stackLevel) { + element.style.marginLeft = `${this.calculateMarginLeft(stackLevel)}px`; + element.style.zIndex = `${this.calculateZIndex(stackLevel)}`; + } + /** + * Clear stack link from element + */ + clearStackLinkFromElement(element) { + delete element.dataset.stackLink; + } + /** + * Clear visual styling from element + */ + clearVisualStyling(element) { + element.style.marginLeft = ''; + element.style.zIndex = ''; + } +} +EventStackManager.STACK_OFFSET_PX = 15; +//# sourceMappingURL=EventStackManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/EventStackManager.js.map b/wwwroot/js/managers/EventStackManager.js.map new file mode 100644 index 0000000..cf98e2a --- /dev/null +++ b/wwwroot/js/managers/EventStackManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventStackManager.js","sourceRoot":"","sources":["../../../src/managers/EventStackManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/GridManager.d.ts b/wwwroot/js/managers/GridManager.d.ts new file mode 100644 index 0000000..2f4d451 --- /dev/null +++ b/wwwroot/js/managers/GridManager.d.ts @@ -0,0 +1,30 @@ +/** + * GridManager - Simplified grid manager using centralized GridRenderer + * Delegates DOM rendering to GridRenderer, focuses on coordination + */ +import { GridRenderer } from '../renderers/GridRenderer'; +import { DateService } from '../utils/DateService'; +import { Configuration } from '../configurations/CalendarConfig'; +import { EventManager } from './EventManager'; +/** + * Simplified GridManager focused on coordination, delegates rendering to GridRenderer + */ +export declare class GridManager { + private container; + private currentDate; + private currentView; + private gridRenderer; + private dateService; + private config; + private dataSource; + private eventManager; + constructor(gridRenderer: GridRenderer, dateService: DateService, config: Configuration, eventManager: EventManager); + private init; + private findElements; + private subscribeToEvents; + /** + * Main render method - delegates to GridRenderer + * Note: CSS variables are automatically updated by ConfigManager when config changes + */ + render(): Promise; +} diff --git a/wwwroot/js/managers/GridManager.js b/wwwroot/js/managers/GridManager.js new file mode 100644 index 0000000..c3294e8 --- /dev/null +++ b/wwwroot/js/managers/GridManager.js @@ -0,0 +1,77 @@ +/** + * GridManager - Simplified grid manager using centralized GridRenderer + * Delegates DOM rendering to GridRenderer, focuses on coordination + */ +import { eventBus } from '../core/EventBus'; +import { CoreEvents } from '../constants/CoreEvents'; +import { DateColumnDataSource } from '../datasources/DateColumnDataSource'; +/** + * Simplified GridManager focused on coordination, delegates rendering to GridRenderer + */ +export class GridManager { + constructor(gridRenderer, dateService, config, eventManager) { + this.container = null; + this.currentDate = new Date(); + this.currentView = 'week'; + this.gridRenderer = gridRenderer; + this.dateService = dateService; + this.config = config; + this.eventManager = eventManager; + this.dataSource = new DateColumnDataSource(dateService, config, this.currentDate, this.currentView); + this.init(); + } + init() { + this.findElements(); + this.subscribeToEvents(); + } + findElements() { + this.container = document.querySelector('swp-calendar-container'); + } + subscribeToEvents() { + // Listen for view changes + eventBus.on(CoreEvents.VIEW_CHANGED, (e) => { + const detail = e.detail; + this.currentView = detail.currentView; + this.dataSource.setCurrentView(this.currentView); + this.render(); + }); + // Listen for navigation events from NavigationButtons + eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (e) => { + const detail = e.detail; + this.currentDate = detail.newDate; + this.dataSource.setCurrentDate(this.currentDate); + this.render(); + }); + // Listen for config changes that affect rendering + eventBus.on(CoreEvents.REFRESH_REQUESTED, (e) => { + this.render(); + }); + eventBus.on(CoreEvents.WORKWEEK_CHANGED, () => { + this.render(); + }); + } + /** + * Main render method - delegates to GridRenderer + * Note: CSS variables are automatically updated by ConfigManager when config changes + */ + async render() { + if (!this.container) { + return; + } + // Get dates from datasource - single source of truth + const dates = this.dataSource.getColumns(); + // Get events for the period from EventManager + const startDate = dates[0]; + const endDate = dates[dates.length - 1]; + const events = await this.eventManager.getEventsForPeriod(startDate, endDate); + // Delegate to GridRenderer with dates and events + this.gridRenderer.renderGrid(this.container, this.currentDate, this.currentView, dates, events); + // Emit grid rendered event + eventBus.emit(CoreEvents.GRID_RENDERED, { + container: this.container, + currentDate: this.currentDate, + dates: dates + }); + } +} +//# sourceMappingURL=GridManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/GridManager.js.map b/wwwroot/js/managers/GridManager.js.map new file mode 100644 index 0000000..d5a0f33 --- /dev/null +++ b/wwwroot/js/managers/GridManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GridManager.js","sourceRoot":"","sources":["../../../src/managers/GridManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/HeaderManager.d.ts b/wwwroot/js/managers/HeaderManager.d.ts new file mode 100644 index 0000000..6eabc82 --- /dev/null +++ b/wwwroot/js/managers/HeaderManager.d.ts @@ -0,0 +1,32 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { IHeaderRenderer } from '../renderers/DateHeaderRenderer'; +/** + * HeaderManager - Handles all header-related event logic + * Separates event handling from rendering concerns + * Uses dependency injection for renderer strategy + */ +export declare class HeaderManager { + private headerRenderer; + private config; + constructor(headerRenderer: IHeaderRenderer, config: Configuration); + /** + * Setup header drag event listeners - Listen to DragDropManager events + */ + setupHeaderDragListeners(): void; + /** + * Handle drag mouse enter header event + */ + private handleDragMouseEnterHeader; + /** + * Handle drag mouse leave header event + */ + private handleDragMouseLeaveHeader; + /** + * Setup navigation event listener + */ + private setupNavigationListener; + /** + * Update header content for navigation + */ + private updateHeader; +} diff --git a/wwwroot/js/managers/HeaderManager.js b/wwwroot/js/managers/HeaderManager.js new file mode 100644 index 0000000..f985c7a --- /dev/null +++ b/wwwroot/js/managers/HeaderManager.js @@ -0,0 +1,103 @@ +import { eventBus } from '../core/EventBus'; +import { CoreEvents } from '../constants/CoreEvents'; +import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils'; +/** + * HeaderManager - Handles all header-related event logic + * Separates event handling from rendering concerns + * Uses dependency injection for renderer strategy + */ +export class HeaderManager { + constructor(headerRenderer, config) { + this.headerRenderer = headerRenderer; + this.config = config; + // Bind handler methods for event listeners + this.handleDragMouseEnterHeader = this.handleDragMouseEnterHeader.bind(this); + this.handleDragMouseLeaveHeader = this.handleDragMouseLeaveHeader.bind(this); + // Listen for navigation events to update header + this.setupNavigationListener(); + } + /** + * Setup header drag event listeners - Listen to DragDropManager events + */ + setupHeaderDragListeners() { + console.log('🎯 HeaderManager: Setting up drag event listeners'); + // Subscribe to drag events from DragDropManager + eventBus.on('drag:mouseenter-header', this.handleDragMouseEnterHeader); + eventBus.on('drag:mouseleave-header', this.handleDragMouseLeaveHeader); + console.log('✅ HeaderManager: Drag event listeners attached'); + } + /** + * Handle drag mouse enter header event + */ + handleDragMouseEnterHeader(event) { + const { targetColumn: targetDate, mousePosition, originalElement, draggedClone: cloneElement } = event.detail; + console.log('🎯 HeaderManager: Received drag:mouseenter-header', { + targetDate, + originalElement: !!originalElement, + cloneElement: !!cloneElement + }); + } + /** + * Handle drag mouse leave header event + */ + handleDragMouseLeaveHeader(event) { + const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = event.detail; + console.log('🚪 HeaderManager: Received drag:mouseleave-header', { + targetDate, + originalElement: !!originalElement, + cloneElement: !!cloneElement + }); + } + /** + * Setup navigation event listener + */ + setupNavigationListener() { + eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => { + const { currentDate } = event.detail; + this.updateHeader(currentDate); + }); + // Also listen for date changes (including initial setup) + eventBus.on(CoreEvents.DATE_CHANGED, (event) => { + const { currentDate } = event.detail; + this.updateHeader(currentDate); + }); + // Listen for workweek header updates after grid rebuild + //currentDate: this.currentDate, + //currentView: this.currentView, + //workweek: this.config.currentWorkWeek + eventBus.on('workweek:header-update', (event) => { + const { currentDate } = event.detail; + this.updateHeader(currentDate); + }); + } + /** + * Update header content for navigation + */ + updateHeader(currentDate) { + console.log('🎯 HeaderManager.updateHeader called', { + currentDate, + rendererType: this.headerRenderer.constructor.name + }); + const calendarHeader = document.querySelector('swp-calendar-header'); + if (!calendarHeader) { + console.warn('❌ HeaderManager: No calendar header found!'); + return; + } + // Clear existing content + calendarHeader.innerHTML = ''; + // Render new header content using injected renderer + const context = { + currentWeek: currentDate, + config: this.config + }; + this.headerRenderer.render(calendarHeader, context); + // Setup event listeners on the new content + this.setupHeaderDragListeners(); + // Notify other managers that header is ready with period data + const payload = { + headerElements: ColumnDetectionUtils.getHeaderColumns(), + }; + eventBus.emit('header:ready', payload); + } +} +//# sourceMappingURL=HeaderManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/HeaderManager.js.map b/wwwroot/js/managers/HeaderManager.js.map new file mode 100644 index 0000000..61da5cd --- /dev/null +++ b/wwwroot/js/managers/HeaderManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"HeaderManager.js","sourceRoot":"","sources":["../../../src/managers/HeaderManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/NavigationButtonsManager.d.ts b/wwwroot/js/managers/NavigationButtonsManager.d.ts new file mode 100644 index 0000000..2fb76dc --- /dev/null +++ b/wwwroot/js/managers/NavigationButtonsManager.d.ts @@ -0,0 +1,40 @@ +import { IEventBus } from '../types/CalendarTypes'; +/** + * NavigationButtonsManager - Manages navigation button UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-nav-button elements + * - Validates navigation actions (prev, next, today) + * - Emits NAV_BUTTON_CLICKED events + * - Manages button UI listeners + * + * EVENT FLOW: + * =========== + * User clicks button → validateAction() → emit event → NavigationManager handles navigation + * + * SUBSCRIBERS: + * ============ + * - NavigationManager: Performs actual navigation logic (animations, grid updates, week calculations) + */ +export declare class NavigationButtonsManager { + private eventBus; + private buttonListeners; + constructor(eventBus: IEventBus); + /** + * Setup click listeners on all navigation buttons + */ + private setupButtonListeners; + /** + * Handle navigation action + */ + private handleNavigation; + /** + * Validate if string is a valid navigation action + */ + private isValidAction; +} diff --git a/wwwroot/js/managers/NavigationButtonsManager.js b/wwwroot/js/managers/NavigationButtonsManager.js new file mode 100644 index 0000000..e1badd5 --- /dev/null +++ b/wwwroot/js/managers/NavigationButtonsManager.js @@ -0,0 +1,63 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * NavigationButtonsManager - Manages navigation button UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-nav-button elements + * - Validates navigation actions (prev, next, today) + * - Emits NAV_BUTTON_CLICKED events + * - Manages button UI listeners + * + * EVENT FLOW: + * =========== + * User clicks button → validateAction() → emit event → NavigationManager handles navigation + * + * SUBSCRIBERS: + * ============ + * - NavigationManager: Performs actual navigation logic (animations, grid updates, week calculations) + */ +export class NavigationButtonsManager { + constructor(eventBus) { + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.setupButtonListeners(); + } + /** + * Setup click listeners on all navigation buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-nav-button[data-action]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const action = button.getAttribute('data-action'); + if (action && this.isValidAction(action)) { + this.handleNavigation(action); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + } + /** + * Handle navigation action + */ + handleNavigation(action) { + // Emit navigation button clicked event + this.eventBus.emit(CoreEvents.NAV_BUTTON_CLICKED, { + action: action + }); + } + /** + * Validate if string is a valid navigation action + */ + isValidAction(action) { + return ['prev', 'next', 'today'].includes(action); + } +} +//# sourceMappingURL=NavigationButtonsManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/NavigationButtonsManager.js.map b/wwwroot/js/managers/NavigationButtonsManager.js.map new file mode 100644 index 0000000..ab7bd56 --- /dev/null +++ b/wwwroot/js/managers/NavigationButtonsManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NavigationButtonsManager.js","sourceRoot":"","sources":["../../../src/managers/NavigationButtonsManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,wBAAwB;IAInC,YAAY,QAAmB;QAFvB,oBAAe,GAAgC,IAAI,GAAG,EAAE,CAAC;QAG/D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;QAEzE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;gBACpC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBAClD,IAAI,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,MAAc;QACrC,uCAAuC;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE;YAChD,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,MAAc;QAClC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/managers/NavigationManager.d.ts b/wwwroot/js/managers/NavigationManager.d.ts new file mode 100644 index 0000000..cc475be --- /dev/null +++ b/wwwroot/js/managers/NavigationManager.d.ts @@ -0,0 +1,32 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { EventRenderingService } from '../renderers/EventRendererManager'; +import { DateService } from '../utils/DateService'; +import { WeekInfoRenderer } from '../renderers/WeekInfoRenderer'; +import { GridRenderer } from '../renderers/GridRenderer'; +export declare class NavigationManager { + private eventBus; + private weekInfoRenderer; + private gridRenderer; + private dateService; + private currentWeek; + private targetWeek; + private animationQueue; + constructor(eventBus: IEventBus, eventRenderer: EventRenderingService, gridRenderer: GridRenderer, dateService: DateService, weekInfoRenderer: WeekInfoRenderer); + private init; + /** + * Get the start of the ISO week (Monday) for a given date + * @param date - Any date in the week + * @returns The Monday of the ISO week + */ + private getISOWeekStart; + private setupEventListeners; + /** + * Navigate to specific event date and emit scroll event after navigation + */ + private navigateToEventDate; + private navigateToDate; + /** + * Animation transition using pre-rendered containers when available + */ + private animateTransition; +} diff --git a/wwwroot/js/managers/NavigationManager.js b/wwwroot/js/managers/NavigationManager.js new file mode 100644 index 0000000..a991117 --- /dev/null +++ b/wwwroot/js/managers/NavigationManager.js @@ -0,0 +1,188 @@ +import { CoreEvents } from '../constants/CoreEvents'; +export class NavigationManager { + constructor(eventBus, eventRenderer, gridRenderer, dateService, weekInfoRenderer) { + this.animationQueue = 0; + this.eventBus = eventBus; + this.dateService = dateService; + this.weekInfoRenderer = weekInfoRenderer; + this.gridRenderer = gridRenderer; + this.currentWeek = this.getISOWeekStart(new Date()); + this.targetWeek = new Date(this.currentWeek); + this.init(); + } + init() { + this.setupEventListeners(); + } + /** + * Get the start of the ISO week (Monday) for a given date + * @param date - Any date in the week + * @returns The Monday of the ISO week + */ + getISOWeekStart(date) { + const weekBounds = this.dateService.getWeekBounds(date); + return this.dateService.startOfDay(weekBounds.start); + } + setupEventListeners() { + // Listen for filter changes and apply to pre-rendered grids + this.eventBus.on(CoreEvents.FILTER_CHANGED, (e) => { + const detail = e.detail; + this.weekInfoRenderer.applyFilterToPreRenderedGrids(detail); + }); + // Listen for navigation button clicks from NavigationButtons + this.eventBus.on(CoreEvents.NAV_BUTTON_CLICKED, (event) => { + const { direction, newDate } = event.detail; + // Navigate to the new date with animation + this.navigateToDate(newDate, direction); + }); + // Listen for external navigation requests + this.eventBus.on(CoreEvents.DATE_CHANGED, (event) => { + const customEvent = event; + const dateFromEvent = customEvent.detail.currentDate; + // Validate date before processing + if (!dateFromEvent) { + console.warn('NavigationManager: No date provided in DATE_CHANGED event'); + return; + } + const targetDate = new Date(dateFromEvent); + // Use DateService validation + const validation = this.dateService.validateDate(targetDate); + if (!validation.valid) { + console.warn('NavigationManager: Invalid date received:', validation.error); + return; + } + this.navigateToDate(targetDate); + }); + // Listen for event navigation requests + this.eventBus.on(CoreEvents.NAVIGATE_TO_EVENT, (event) => { + const customEvent = event; + const { eventDate, eventStartTime } = customEvent.detail; + if (!eventDate || !eventStartTime) { + console.warn('NavigationManager: Invalid event navigation data'); + return; + } + this.navigateToEventDate(eventDate, eventStartTime); + }); + } + /** + * Navigate to specific event date and emit scroll event after navigation + */ + navigateToEventDate(eventDate, eventStartTime) { + const weekStart = this.getISOWeekStart(eventDate); + this.targetWeek = new Date(weekStart); + const currentTime = this.currentWeek.getTime(); + const targetTime = weekStart.getTime(); + // Store event start time for scrolling after navigation + const scrollAfterNavigation = () => { + // Emit scroll request after navigation is complete + this.eventBus.emit('scroll:to-event-time', { + eventStartTime + }); + }; + if (currentTime < targetTime) { + this.animationQueue++; + this.animateTransition('next', weekStart); + // Listen for navigation completion to trigger scroll + this.eventBus.once(CoreEvents.NAVIGATION_COMPLETED, scrollAfterNavigation); + } + else if (currentTime > targetTime) { + this.animationQueue++; + this.animateTransition('prev', weekStart); + // Listen for navigation completion to trigger scroll + this.eventBus.once(CoreEvents.NAVIGATION_COMPLETED, scrollAfterNavigation); + } + else { + // Already on correct week, just scroll + scrollAfterNavigation(); + } + } + navigateToDate(date, direction) { + const weekStart = this.getISOWeekStart(date); + this.targetWeek = new Date(weekStart); + const currentTime = this.currentWeek.getTime(); + const targetTime = weekStart.getTime(); + // Use provided direction or calculate based on time comparison + let animationDirection; + if (direction === 'next') { + animationDirection = 'next'; + } + else if (direction === 'previous') { + animationDirection = 'prev'; + } + else if (direction === 'today') { + // For "today", determine direction based on current position + animationDirection = currentTime < targetTime ? 'next' : 'prev'; + } + else { + // Fallback: calculate direction + animationDirection = currentTime < targetTime ? 'next' : 'prev'; + } + if (currentTime !== targetTime) { + this.animationQueue++; + this.animateTransition(animationDirection, weekStart); + } + } + /** + * Animation transition using pre-rendered containers when available + */ + animateTransition(direction, targetWeek) { + const container = document.querySelector('swp-calendar-container'); + const currentGrid = document.querySelector('swp-calendar-container swp-grid-container:not([data-prerendered])'); + if (!container || !currentGrid) { + return; + } + // Reset all-day height BEFORE creating new grid to ensure base height + const root = document.documentElement; + root.style.setProperty('--all-day-row-height', '0px'); + let newGrid; + console.group('🔧 NavigationManager.refactored'); + console.log('Calling GridRenderer instead of NavigationRenderer'); + console.log('Target week:', targetWeek); + // Always create a fresh container for consistent behavior + newGrid = this.gridRenderer.createNavigationGrid(container, targetWeek); + console.groupEnd(); + // Clear any existing transforms before animation + newGrid.style.transform = ''; + currentGrid.style.transform = ''; + // Animate transition using Web Animations API + const slideOutAnimation = currentGrid.animate([ + { transform: 'translateX(0)', opacity: '1' }, + { transform: direction === 'next' ? 'translateX(-100%)' : 'translateX(100%)', opacity: '0.5' } + ], { + duration: 400, + easing: 'ease-in-out', + fill: 'forwards' + }); + const slideInAnimation = newGrid.animate([ + { transform: direction === 'next' ? 'translateX(100%)' : 'translateX(-100%)' }, + { transform: 'translateX(0)' } + ], { + duration: 400, + easing: 'ease-in-out', + fill: 'forwards' + }); + // Handle animation completion + slideInAnimation.addEventListener('finish', () => { + // Cleanup: Remove all old grids except the new one + const allGrids = container.querySelectorAll('swp-grid-container'); + for (let i = 0; i < allGrids.length - 1; i++) { + allGrids[i].remove(); + } + // Reset positioning + newGrid.style.position = 'relative'; + newGrid.removeAttribute('data-prerendered'); + // Update state + this.currentWeek = new Date(targetWeek); + this.animationQueue--; + // If this was the last queued animation, ensure we're in sync + if (this.animationQueue === 0) { + this.currentWeek = new Date(this.targetWeek); + } + // Emit navigation completed event + this.eventBus.emit(CoreEvents.NAVIGATION_COMPLETED, { + direction, + newDate: this.currentWeek + }); + }); + } +} +//# sourceMappingURL=NavigationManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/NavigationManager.js.map b/wwwroot/js/managers/NavigationManager.js.map new file mode 100644 index 0000000..8b411ff --- /dev/null +++ b/wwwroot/js/managers/NavigationManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NavigationManager.js","sourceRoot":"","sources":["../../../src/managers/NavigationManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/ResizeHandleManager.d.ts b/wwwroot/js/managers/ResizeHandleManager.d.ts new file mode 100644 index 0000000..90f9d9c --- /dev/null +++ b/wwwroot/js/managers/ResizeHandleManager.d.ts @@ -0,0 +1,42 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { PositionUtils } from '../utils/PositionUtils'; +export declare class ResizeHandleManager { + private config; + private positionUtils; + private isResizing; + private targetEl; + private startY; + private startDurationMin; + private snapMin; + private minDurationMin; + private animationId; + private currentHeight; + private targetHeight; + private pointerCaptured; + private prevZ?; + private readonly ANIMATION_SPEED; + private readonly Z_INDEX_RESIZING; + private readonly EVENT_REFRESH_THRESHOLD; + constructor(config: Configuration, positionUtils: PositionUtils); + initialize(): void; + destroy(): void; + private removeEventListeners; + private createResizeHandle; + private attachGlobalListeners; + private onMouseOver; + private onPointerDown; + private startResizing; + private setZIndexForResizing; + private capturePointer; + private onPointerMove; + private updateResizeHeight; + private animate; + private finalizeAnimation; + private onPointerUp; + private cleanupAnimation; + private snapToGrid; + private emitResizeEndEvent; + private cleanupResizing; + private restoreZIndex; + private releasePointer; +} diff --git a/wwwroot/js/managers/ResizeHandleManager.js b/wwwroot/js/managers/ResizeHandleManager.js new file mode 100644 index 0000000..c753f42 --- /dev/null +++ b/wwwroot/js/managers/ResizeHandleManager.js @@ -0,0 +1,194 @@ +import { eventBus } from '../core/EventBus'; +export class ResizeHandleManager { + constructor(config, positionUtils) { + this.config = config; + this.positionUtils = positionUtils; + this.isResizing = false; + this.targetEl = null; + this.startY = 0; + this.startDurationMin = 0; + this.animationId = null; + this.currentHeight = 0; + this.targetHeight = 0; + this.pointerCaptured = false; + // Constants for better maintainability + this.ANIMATION_SPEED = 0.35; + this.Z_INDEX_RESIZING = '1000'; + this.EVENT_REFRESH_THRESHOLD = 0.5; + this.onMouseOver = (e) => { + const target = e.target; + const eventElement = target.closest('swp-event'); + if (eventElement && !this.isResizing) { + // Check if handle already exists + if (!eventElement.querySelector(':scope > swp-resize-handle')) { + const handle = this.createResizeHandle(); + eventElement.appendChild(handle); + } + } + }; + this.onPointerDown = (e) => { + const handle = e.target.closest('swp-resize-handle'); + if (!handle) + return; + const element = handle.parentElement; + this.startResizing(element, e); + }; + this.onPointerMove = (e) => { + if (!this.isResizing || !this.targetEl) + return; + this.updateResizeHeight(e.clientY); + }; + this.animate = () => { + if (!this.isResizing || !this.targetEl) { + this.animationId = null; + return; + } + const diff = this.targetHeight - this.currentHeight; + if (Math.abs(diff) > this.EVENT_REFRESH_THRESHOLD) { + this.currentHeight += diff * this.ANIMATION_SPEED; + this.targetEl.updateHeight?.(this.currentHeight); + this.animationId = requestAnimationFrame(this.animate); + } + else { + this.finalizeAnimation(); + } + }; + this.onPointerUp = (e) => { + if (!this.isResizing || !this.targetEl) + return; + this.cleanupAnimation(); + this.snapToGrid(); + this.emitResizeEndEvent(); + this.cleanupResizing(e); + }; + const grid = this.config.gridSettings; + this.snapMin = grid.snapInterval; + this.minDurationMin = this.snapMin; + } + initialize() { + this.attachGlobalListeners(); + } + destroy() { + this.removeEventListeners(); + } + removeEventListeners() { + const calendarContainer = document.querySelector('swp-calendar-container'); + if (calendarContainer) { + calendarContainer.removeEventListener('mouseover', this.onMouseOver, true); + } + document.removeEventListener('pointerdown', this.onPointerDown, true); + document.removeEventListener('pointermove', this.onPointerMove, true); + document.removeEventListener('pointerup', this.onPointerUp, true); + } + createResizeHandle() { + const handle = document.createElement('swp-resize-handle'); + handle.setAttribute('aria-label', 'Resize event'); + handle.setAttribute('role', 'separator'); + return handle; + } + attachGlobalListeners() { + const calendarContainer = document.querySelector('swp-calendar-container'); + if (calendarContainer) { + calendarContainer.addEventListener('mouseover', this.onMouseOver, true); + } + document.addEventListener('pointerdown', this.onPointerDown, true); + document.addEventListener('pointermove', this.onPointerMove, true); + document.addEventListener('pointerup', this.onPointerUp, true); + } + startResizing(element, event) { + this.targetEl = element; + this.isResizing = true; + this.startY = event.clientY; + const startHeight = element.offsetHeight; + this.startDurationMin = Math.max(this.minDurationMin, Math.round(this.positionUtils.pixelsToMinutes(startHeight))); + this.setZIndexForResizing(element); + this.capturePointer(event); + document.documentElement.classList.add('swp--resizing'); + event.preventDefault(); + } + setZIndexForResizing(element) { + const container = element.closest('swp-event-group') ?? element; + this.prevZ = container.style.zIndex; + container.style.zIndex = this.Z_INDEX_RESIZING; + } + capturePointer(event) { + try { + event.target.setPointerCapture?.(event.pointerId); + this.pointerCaptured = true; + } + catch (error) { + console.warn('Pointer capture failed:', error); + } + } + updateResizeHeight(currentY) { + const deltaY = currentY - this.startY; + const startHeight = this.positionUtils.minutesToPixels(this.startDurationMin); + const rawHeight = startHeight + deltaY; + const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin); + this.targetHeight = Math.max(minHeight, rawHeight); + if (this.animationId == null) { + this.currentHeight = this.targetEl?.offsetHeight; + this.animate(); + } + } + finalizeAnimation() { + if (!this.targetEl) + return; + this.currentHeight = this.targetHeight; + this.targetEl.updateHeight?.(this.currentHeight); + this.animationId = null; + } + cleanupAnimation() { + if (this.animationId != null) { + cancelAnimationFrame(this.animationId); + this.animationId = null; + } + } + snapToGrid() { + if (!this.targetEl) + return; + const currentHeight = this.targetEl.offsetHeight; + const snapDistancePx = this.positionUtils.minutesToPixels(this.snapMin); + const snappedHeight = Math.round(currentHeight / snapDistancePx) * snapDistancePx; + const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin); + const finalHeight = Math.max(minHeight, snappedHeight) - 3; // Small gap to grid lines + this.targetEl.updateHeight?.(finalHeight); + } + emitResizeEndEvent() { + if (!this.targetEl) + return; + const eventId = this.targetEl.dataset.eventId || ''; + const resizeEndPayload = { + eventId, + element: this.targetEl, + finalHeight: this.targetEl.offsetHeight + }; + eventBus.emit('resize:end', resizeEndPayload); + } + cleanupResizing(event) { + this.restoreZIndex(); + this.releasePointer(event); + this.isResizing = false; + this.targetEl = null; + document.documentElement.classList.remove('swp--resizing'); + } + restoreZIndex() { + if (!this.targetEl || this.prevZ === undefined) + return; + const container = this.targetEl.closest('swp-event-group') ?? this.targetEl; + container.style.zIndex = this.prevZ; + this.prevZ = undefined; + } + releasePointer(event) { + if (!this.pointerCaptured) + return; + try { + event.target.releasePointerCapture?.(event.pointerId); + this.pointerCaptured = false; + } + catch (error) { + console.warn('Pointer release failed:', error); + } + } +} +//# sourceMappingURL=ResizeHandleManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/ResizeHandleManager.js.map b/wwwroot/js/managers/ResizeHandleManager.js.map new file mode 100644 index 0000000..fa05fae --- /dev/null +++ b/wwwroot/js/managers/ResizeHandleManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ResizeHandleManager.js","sourceRoot":"","sources":["../../../src/managers/ResizeHandleManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/ScrollManager.d.ts b/wwwroot/js/managers/ScrollManager.d.ts new file mode 100644 index 0000000..a3eda8a --- /dev/null +++ b/wwwroot/js/managers/ScrollManager.d.ts @@ -0,0 +1,64 @@ +import { PositionUtils } from '../utils/PositionUtils'; +/** + * Manages scrolling functionality for the calendar using native scrollbars + */ +export declare class ScrollManager { + private scrollableContent; + private calendarContainer; + private timeAxis; + private calendarHeader; + private resizeObserver; + private positionUtils; + constructor(positionUtils: PositionUtils); + private init; + /** + * Public method to initialize scroll after grid is rendered + */ + initialize(): void; + private subscribeToEvents; + /** + * Setup scrolling functionality after grid is rendered + */ + private setupScrolling; + /** + * Find DOM elements needed for scrolling + */ + private findElements; + /** + * Scroll to specific position + */ + scrollTo(scrollTop: number): void; + /** + * Scroll to specific hour using PositionUtils + */ + scrollToHour(hour: number): void; + /** + * Scroll to specific event time + * @param eventStartTime ISO string of event start time + */ + scrollToEventTime(eventStartTime: string): void; + /** + * Setup ResizeObserver to monitor container size changes + */ + private setupResizeObserver; + /** + * Calculate and update scrollable content height dynamically + */ + private updateScrollableHeight; + /** + * Setup scroll synchronization between scrollable content and time axis + */ + private setupScrollSynchronization; + /** + * Synchronize time axis position with scrollable content + */ + private syncTimeAxisPosition; + /** + * Setup horizontal scroll synchronization between scrollable content and calendar header + */ + private setupHorizontalScrollSynchronization; + /** + * Synchronize calendar header position with scrollable content horizontal scroll + */ + private syncCalendarHeaderPosition; +} diff --git a/wwwroot/js/managers/ScrollManager.js b/wwwroot/js/managers/ScrollManager.js new file mode 100644 index 0000000..c14533a --- /dev/null +++ b/wwwroot/js/managers/ScrollManager.js @@ -0,0 +1,217 @@ +// Custom scroll management for calendar week container +import { eventBus } from '../core/EventBus'; +import { CoreEvents } from '../constants/CoreEvents'; +/** + * Manages scrolling functionality for the calendar using native scrollbars + */ +export class ScrollManager { + constructor(positionUtils) { + this.scrollableContent = null; + this.calendarContainer = null; + this.timeAxis = null; + this.calendarHeader = null; + this.resizeObserver = null; + this.positionUtils = positionUtils; + this.init(); + } + init() { + this.subscribeToEvents(); + } + /** + * Public method to initialize scroll after grid is rendered + */ + initialize() { + this.setupScrolling(); + } + subscribeToEvents() { + // Handle navigation animation completion - sync time axis position + eventBus.on(CoreEvents.NAVIGATION_COMPLETED, () => { + this.syncTimeAxisPosition(); + this.setupScrolling(); + }); + // Handle all-day row height changes + eventBus.on('header:height-changed', () => { + this.updateScrollableHeight(); + }); + // Handle header ready - refresh header reference and re-sync + eventBus.on('header:ready', () => { + this.calendarHeader = document.querySelector('swp-calendar-header'); + if (this.scrollableContent && this.calendarHeader) { + this.setupHorizontalScrollSynchronization(); + this.syncCalendarHeaderPosition(); // Immediately sync position + } + this.updateScrollableHeight(); // Update height calculations + }); + // Handle window resize + window.addEventListener('resize', () => { + this.updateScrollableHeight(); + }); + // Listen for scroll to event time requests + eventBus.on('scroll:to-event-time', (event) => { + const customEvent = event; + const { eventStartTime } = customEvent.detail; + if (eventStartTime) { + this.scrollToEventTime(eventStartTime); + } + }); + } + /** + * Setup scrolling functionality after grid is rendered + */ + setupScrolling() { + this.findElements(); + if (this.scrollableContent && this.calendarContainer) { + this.setupResizeObserver(); + this.updateScrollableHeight(); + this.setupScrollSynchronization(); + } + // Setup horizontal scrolling synchronization + if (this.scrollableContent && this.calendarHeader) { + this.setupHorizontalScrollSynchronization(); + } + } + /** + * Find DOM elements needed for scrolling + */ + findElements() { + this.scrollableContent = document.querySelector('swp-scrollable-content'); + this.calendarContainer = document.querySelector('swp-calendar-container'); + this.timeAxis = document.querySelector('swp-time-axis'); + this.calendarHeader = document.querySelector('swp-calendar-header'); + } + /** + * Scroll to specific position + */ + scrollTo(scrollTop) { + if (!this.scrollableContent) + return; + this.scrollableContent.scrollTop = scrollTop; + } + /** + * Scroll to specific hour using PositionUtils + */ + scrollToHour(hour) { + // Create time string for the hour + const timeString = `${hour.toString().padStart(2, '0')}:00`; + const scrollTop = this.positionUtils.timeToPixels(timeString); + this.scrollTo(scrollTop); + } + /** + * Scroll to specific event time + * @param eventStartTime ISO string of event start time + */ + scrollToEventTime(eventStartTime) { + try { + const eventDate = new Date(eventStartTime); + const eventHour = eventDate.getHours(); + const eventMinutes = eventDate.getMinutes(); + // Convert to decimal hour (e.g., 14:30 becomes 14.5) + const decimalHour = eventHour + (eventMinutes / 60); + this.scrollToHour(decimalHour); + } + catch (error) { + console.warn('ScrollManager: Failed to scroll to event time:', error); + } + } + /** + * Setup ResizeObserver to monitor container size changes + */ + setupResizeObserver() { + if (!this.calendarContainer) + return; + // Clean up existing observer + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + } + this.resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + this.updateScrollableHeight(); + } + }); + this.resizeObserver.observe(this.calendarContainer); + } + /** + * Calculate and update scrollable content height dynamically + */ + updateScrollableHeight() { + if (!this.scrollableContent || !this.calendarContainer) + return; + // Get calendar container height + const containerRect = this.calendarContainer.getBoundingClientRect(); + // Find navigation height + const navigation = document.querySelector('swp-calendar-nav'); + const navHeight = navigation ? navigation.getBoundingClientRect().height : 0; + // Find calendar header height + const calendarHeaderElement = document.querySelector('swp-calendar-header'); + const headerHeight = calendarHeaderElement ? calendarHeaderElement.getBoundingClientRect().height : 80; + // Calculate available height for scrollable content + const availableHeight = containerRect.height - headerHeight; + // Calculate available width (container width minus time-axis) + const availableWidth = containerRect.width - 60; // 60px time-axis + // Set the height and width on scrollable content + if (availableHeight > 0) { + this.scrollableContent.style.height = `${availableHeight}px`; + } + if (availableWidth > 0) { + this.scrollableContent.style.width = `${availableWidth}px`; + } + } + /** + * Setup scroll synchronization between scrollable content and time axis + */ + setupScrollSynchronization() { + if (!this.scrollableContent || !this.timeAxis) + return; + // Throttle scroll events for better performance + let scrollTimeout = null; + this.scrollableContent.addEventListener('scroll', () => { + if (scrollTimeout) { + cancelAnimationFrame(scrollTimeout); + } + scrollTimeout = requestAnimationFrame(() => { + this.syncTimeAxisPosition(); + }); + }); + } + /** + * Synchronize time axis position with scrollable content + */ + syncTimeAxisPosition() { + if (!this.scrollableContent || !this.timeAxis) + return; + const scrollTop = this.scrollableContent.scrollTop; + const timeAxisContent = this.timeAxis.querySelector('swp-time-axis-content'); + if (timeAxisContent) { + // Use transform for smooth performance + timeAxisContent.style.transform = `translateY(-${scrollTop}px)`; + // Debug logging (can be removed later) + if (scrollTop % 100 === 0) { // Only log every 100px to avoid spam + } + } + } + /** + * Setup horizontal scroll synchronization between scrollable content and calendar header + */ + setupHorizontalScrollSynchronization() { + if (!this.scrollableContent || !this.calendarHeader) + return; + // Listen to horizontal scroll events + this.scrollableContent.addEventListener('scroll', () => { + this.syncCalendarHeaderPosition(); + }); + } + /** + * Synchronize calendar header position with scrollable content horizontal scroll + */ + syncCalendarHeaderPosition() { + if (!this.scrollableContent || !this.calendarHeader) + return; + const scrollLeft = this.scrollableContent.scrollLeft; + // Use transform for smooth performance + this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`; + // Debug logging (can be removed later) + if (scrollLeft % 100 === 0) { // Only log every 100px to avoid spam + } + } +} +//# sourceMappingURL=ScrollManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/ScrollManager.js.map b/wwwroot/js/managers/ScrollManager.js.map new file mode 100644 index 0000000..63c28e1 --- /dev/null +++ b/wwwroot/js/managers/ScrollManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ScrollManager.js","sourceRoot":"","sources":["../../../src/managers/ScrollManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/SimpleEventOverlapManager.d.ts b/wwwroot/js/managers/SimpleEventOverlapManager.d.ts new file mode 100644 index 0000000..a3dce25 --- /dev/null +++ b/wwwroot/js/managers/SimpleEventOverlapManager.d.ts @@ -0,0 +1,80 @@ +/** + * SimpleEventOverlapManager - Clean, focused overlap management + * Eliminates complex state tracking in favor of direct DOM manipulation + */ +import { CalendarEvent } from '../types/CalendarTypes'; +export declare enum OverlapType { + NONE = "none", + COLUMN_SHARING = "column_sharing", + STACKING = "stacking" +} +export interface OverlapGroup { + type: OverlapType; + events: CalendarEvent[]; + position: { + top: number; + height: number; + }; +} +export interface StackLink { + prev?: string; + next?: string; + stackLevel: number; +} +export declare class SimpleEventOverlapManager { + private static readonly STACKING_WIDTH_REDUCTION_PX; + /** + * Detect overlap type between two DOM elements - pixel-based logic + */ + resolveOverlapType(element1: HTMLElement, element2: HTMLElement): OverlapType; + /** + * Group overlapping elements - pixel-based algorithm + */ + groupOverlappingElements(elements: HTMLElement[]): HTMLElement[][]; + /** + * Create flexbox container for column sharing - clean and simple + */ + createEventGroup(events: CalendarEvent[], position: { + top: number; + height: number; + }): HTMLElement; + /** + * Add event to flexbox group - simple relative positioning + */ + addToEventGroup(container: HTMLElement, eventElement: HTMLElement): void; + /** + * Create stacked event with data-attribute tracking + */ + createStackedEvent(eventElement: HTMLElement, underlyingElement: HTMLElement, stackLevel: number): void; + /** + * Remove stacked styling with proper stack re-linking + */ + removeStackedStyling(eventElement: HTMLElement): void; + /** + * Update stack levels for all events following a given event ID + */ + private updateSubsequentStackLevels; + /** + * Check if element is stacked - check both style and data-stack-link + */ + isStackedEvent(element: HTMLElement): boolean; + /** + * Remove event from group with proper cleanup + */ + removeFromEventGroup(container: HTMLElement, eventId: string): boolean; + /** + * Restack events in container - respects separate stack chains + */ + restackEventsInContainer(container: HTMLElement): void; + /** + * Utility methods - simple DOM traversal + */ + getEventGroup(eventElement: HTMLElement): HTMLElement | null; + isInEventGroup(element: HTMLElement): boolean; + /** + * Helper methods for data-attribute based stack tracking + */ + getStackLink(element: HTMLElement): StackLink | null; + private setStackLink; + private findElementById; +} diff --git a/wwwroot/js/managers/SimpleEventOverlapManager.js b/wwwroot/js/managers/SimpleEventOverlapManager.js new file mode 100644 index 0000000..b782f02 --- /dev/null +++ b/wwwroot/js/managers/SimpleEventOverlapManager.js @@ -0,0 +1,399 @@ +/** + * SimpleEventOverlapManager - Clean, focused overlap management + * Eliminates complex state tracking in favor of direct DOM manipulation + */ +import { calendarConfig } from '../core/CalendarConfig'; +export var OverlapType; +(function (OverlapType) { + OverlapType["NONE"] = "none"; + OverlapType["COLUMN_SHARING"] = "column_sharing"; + OverlapType["STACKING"] = "stacking"; +})(OverlapType || (OverlapType = {})); +export class SimpleEventOverlapManager { + /** + * Detect overlap type between two DOM elements - pixel-based logic + */ + resolveOverlapType(element1, element2) { + const top1 = parseInt(element1.style.top) || 0; + const height1 = parseInt(element1.style.height) || 0; + const bottom1 = top1 + height1; + const top2 = parseInt(element2.style.top) || 0; + const height2 = parseInt(element2.style.height) || 0; + const bottom2 = top2 + height2; + // Check if events overlap in pixel space + const tolerance = 2; + if (bottom1 <= (top2 + tolerance) || bottom2 <= (top1 + tolerance)) { + return OverlapType.NONE; + } + // Events overlap - check start position difference for overlap type + const startDifference = Math.abs(top1 - top2); + // Over 40px start difference = stacking + if (startDifference > 40) { + return OverlapType.STACKING; + } + // Within 40px start difference = column sharing + return OverlapType.COLUMN_SHARING; + } + /** + * Group overlapping elements - pixel-based algorithm + */ + groupOverlappingElements(elements) { + const groups = []; + const processed = new Set(); + for (const element of elements) { + if (processed.has(element)) + continue; + // Find all elements that overlap with this one + const overlapping = elements.filter(other => { + if (processed.has(other)) + return false; + return other === element || this.resolveOverlapType(element, other) !== OverlapType.NONE; + }); + // Mark all as processed + overlapping.forEach(e => processed.add(e)); + groups.push(overlapping); + } + return groups; + } + /** + * Create flexbox container for column sharing - clean and simple + */ + createEventGroup(events, position) { + const container = document.createElement('swp-event-group'); + return container; + } + /** + * Add event to flexbox group - simple relative positioning + */ + addToEventGroup(container, eventElement) { + // Set duration-based height + const duration = eventElement.dataset.duration; + if (duration) { + const durationMinutes = parseInt(duration); + const gridSettings = calendarConfig.getGridSettings(); + const height = (durationMinutes / 60) * gridSettings.hourHeight; + eventElement.style.height = `${height - 3}px`; + } + // Flexbox styling + eventElement.style.position = 'relative'; + eventElement.style.flex = '1'; + eventElement.style.minWidth = '50px'; + container.appendChild(eventElement); + } + /** + * Create stacked event with data-attribute tracking + */ + createStackedEvent(eventElement, underlyingElement, stackLevel) { + const marginLeft = stackLevel * SimpleEventOverlapManager.STACKING_WIDTH_REDUCTION_PX; + // Apply visual styling + eventElement.style.marginLeft = `${marginLeft}px`; + eventElement.style.left = '2px'; + eventElement.style.right = '2px'; + eventElement.style.zIndex = `${100 + stackLevel}`; + // Set up stack linking via data attributes + const eventId = eventElement.dataset.eventId; + const underlyingId = underlyingElement.dataset.eventId; + if (!eventId || !underlyingId) { + console.warn('Missing event IDs for stack linking:', eventId, underlyingId); + return; + } + // Find the last event in the stack chain + let lastElement = underlyingElement; + let lastLink = this.getStackLink(lastElement); + // If underlying doesn't have stack link yet, create it + if (!lastLink) { + this.setStackLink(lastElement, { stackLevel: 0 }); + lastLink = { stackLevel: 0 }; + } + // Traverse to find the end of the chain + while (lastLink?.next) { + const nextElement = this.findElementById(lastLink.next); + if (!nextElement) + break; + lastElement = nextElement; + lastLink = this.getStackLink(lastElement); + } + // Link the new event to the end of the chain + const lastElementId = lastElement.dataset.eventId; + this.setStackLink(lastElement, { + ...lastLink, + next: eventId + }); + this.setStackLink(eventElement, { + prev: lastElementId, + stackLevel: stackLevel + }); + } + /** + * Remove stacked styling with proper stack re-linking + */ + removeStackedStyling(eventElement) { + // Clear visual styling + eventElement.style.marginLeft = ''; + eventElement.style.zIndex = ''; + eventElement.style.left = '2px'; + eventElement.style.right = '2px'; + // Handle stack chain re-linking + const link = this.getStackLink(eventElement); + if (link) { + // Re-link prev and next events + if (link.prev && link.next) { + // Middle element - link prev to next + const prevElement = this.findElementById(link.prev); + const nextElement = this.findElementById(link.next); + if (prevElement && nextElement) { + const prevLink = this.getStackLink(prevElement); + const nextLink = this.getStackLink(nextElement); + // CRITICAL: Check if prev and next actually overlap without the middle element + const actuallyOverlap = this.resolveOverlapType(prevElement, nextElement); + if (!actuallyOverlap) { + // CHAIN BREAKING: prev and next don't overlap - break the chain + console.log('Breaking stack chain - events do not overlap directly'); + // Prev element: remove next link (becomes end of its own chain) + this.setStackLink(prevElement, { + ...prevLink, + next: undefined + }); + // Next element: becomes standalone (remove all stack links and styling) + this.setStackLink(nextElement, null); + nextElement.style.marginLeft = ''; + nextElement.style.zIndex = ''; + // If next element had subsequent events, they also become standalone + if (nextLink?.next) { + let subsequentId = nextLink.next; + while (subsequentId) { + const subsequentElement = this.findElementById(subsequentId); + if (!subsequentElement) + break; + const subsequentLink = this.getStackLink(subsequentElement); + this.setStackLink(subsequentElement, null); + subsequentElement.style.marginLeft = ''; + subsequentElement.style.zIndex = ''; + subsequentId = subsequentLink?.next; + } + } + } + else { + // NORMAL STACKING: they overlap, maintain the chain + this.setStackLink(prevElement, { + ...prevLink, + next: link.next + }); + const correctStackLevel = (prevLink?.stackLevel ?? 0) + 1; + this.setStackLink(nextElement, { + ...nextLink, + prev: link.prev, + stackLevel: correctStackLevel + }); + // Update visual styling to match new stackLevel + const marginLeft = correctStackLevel * SimpleEventOverlapManager.STACKING_WIDTH_REDUCTION_PX; + nextElement.style.marginLeft = `${marginLeft}px`; + nextElement.style.zIndex = `${100 + correctStackLevel}`; + } + } + } + else if (link.prev) { + // Last element - remove next link from prev + const prevElement = this.findElementById(link.prev); + if (prevElement) { + const prevLink = this.getStackLink(prevElement); + this.setStackLink(prevElement, { + ...prevLink, + next: undefined + }); + } + } + else if (link.next) { + // First element - remove prev link from next + const nextElement = this.findElementById(link.next); + if (nextElement) { + const nextLink = this.getStackLink(nextElement); + this.setStackLink(nextElement, { + ...nextLink, + prev: undefined, + stackLevel: 0 // Next becomes the base event + }); + } + } + // Only update subsequent stack levels if we didn't break the chain + if (link.prev && link.next) { + const nextElement = this.findElementById(link.next); + const nextLink = nextElement ? this.getStackLink(nextElement) : null; + // If next element still has a stack link, the chain wasn't broken + if (nextLink && nextLink.next) { + this.updateSubsequentStackLevels(nextLink.next, -1); + } + // If nextLink is null, chain was broken - no subsequent updates needed + } + else { + // First or last removal - update all subsequent + this.updateSubsequentStackLevels(link.next, -1); + } + // Clear this element's stack link + this.setStackLink(eventElement, null); + } + } + /** + * Update stack levels for all events following a given event ID + */ + updateSubsequentStackLevels(startEventId, levelDelta) { + let currentId = startEventId; + while (currentId) { + const currentElement = this.findElementById(currentId); + if (!currentElement) + break; + const currentLink = this.getStackLink(currentElement); + if (!currentLink) + break; + // Update stack level + const newLevel = Math.max(0, currentLink.stackLevel + levelDelta); + this.setStackLink(currentElement, { + ...currentLink, + stackLevel: newLevel + }); + // Update visual styling + const marginLeft = newLevel * SimpleEventOverlapManager.STACKING_WIDTH_REDUCTION_PX; + currentElement.style.marginLeft = `${marginLeft}px`; + currentElement.style.zIndex = `${100 + newLevel}`; + currentId = currentLink.next; + } + } + /** + * Check if element is stacked - check both style and data-stack-link + */ + isStackedEvent(element) { + const marginLeft = element.style.marginLeft; + const hasMarginLeft = marginLeft !== '' && marginLeft !== '0px'; + const hasStackLink = this.getStackLink(element) !== null; + return hasMarginLeft || hasStackLink; + } + /** + * Remove event from group with proper cleanup + */ + removeFromEventGroup(container, eventId) { + const eventElement = container.querySelector(`swp-event[data-event-id="${eventId}"]`); + if (!eventElement) + return false; + // Simply remove the element - no position calculation needed since it's being removed + eventElement.remove(); + // Handle remaining events + const remainingEvents = container.querySelectorAll('swp-event'); + const remainingCount = remainingEvents.length; + if (remainingCount === 0) { + container.remove(); + return true; + } + if (remainingCount === 1) { + const remainingEvent = remainingEvents[0]; + // Convert last event back to absolute positioning - use current pixel position + const currentTop = parseInt(remainingEvent.style.top) || 0; + remainingEvent.style.position = 'absolute'; + remainingEvent.style.top = `${currentTop}px`; + remainingEvent.style.left = '2px'; + remainingEvent.style.right = '2px'; + remainingEvent.style.flex = ''; + remainingEvent.style.minWidth = ''; + container.parentElement?.insertBefore(remainingEvent, container); + container.remove(); + return true; + } + return false; + } + /** + * Restack events in container - respects separate stack chains + */ + restackEventsInContainer(container) { + const stackedEvents = Array.from(container.querySelectorAll('swp-event')) + .filter(el => this.isStackedEvent(el)); + if (stackedEvents.length === 0) + return; + // Group events by their stack chains + const processedEventIds = new Set(); + const stackChains = []; + for (const element of stackedEvents) { + const eventId = element.dataset.eventId; + if (!eventId || processedEventIds.has(eventId)) + continue; + // Find the root of this stack chain (stackLevel 0 or no prev link) + let rootElement = element; + let rootLink = this.getStackLink(rootElement); + while (rootLink?.prev) { + const prevElement = this.findElementById(rootLink.prev); + if (!prevElement) + break; + rootElement = prevElement; + rootLink = this.getStackLink(rootElement); + } + // Collect all elements in this chain + const chain = []; + let currentElement = rootElement; + while (currentElement) { + chain.push(currentElement); + processedEventIds.add(currentElement.dataset.eventId); + const currentLink = this.getStackLink(currentElement); + if (!currentLink?.next) + break; + const nextElement = this.findElementById(currentLink.next); + if (!nextElement) + break; + currentElement = nextElement; + } + if (chain.length > 1) { // Only add chains with multiple events + stackChains.push(chain); + } + } + // Re-stack each chain separately + stackChains.forEach(chain => { + chain.forEach((element, index) => { + const marginLeft = index * SimpleEventOverlapManager.STACKING_WIDTH_REDUCTION_PX; + element.style.marginLeft = `${marginLeft}px`; + element.style.zIndex = `${100 + index}`; + // Update the data-stack-link with correct stackLevel + const link = this.getStackLink(element); + if (link) { + this.setStackLink(element, { + ...link, + stackLevel: index + }); + } + }); + }); + } + /** + * Utility methods - simple DOM traversal + */ + getEventGroup(eventElement) { + return eventElement.closest('swp-event-group'); + } + isInEventGroup(element) { + return this.getEventGroup(element) !== null; + } + /** + * Helper methods for data-attribute based stack tracking + */ + getStackLink(element) { + const linkData = element.dataset.stackLink; + if (!linkData) + return null; + try { + return JSON.parse(linkData); + } + catch (e) { + console.warn('Failed to parse stack link data:', linkData, e); + return null; + } + } + setStackLink(element, link) { + if (link === null) { + delete element.dataset.stackLink; + } + else { + element.dataset.stackLink = JSON.stringify(link); + } + } + findElementById(eventId) { + return document.querySelector(`swp-event[data-event-id="${eventId}"]`); + } +} +SimpleEventOverlapManager.STACKING_WIDTH_REDUCTION_PX = 15; +//# sourceMappingURL=SimpleEventOverlapManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/SimpleEventOverlapManager.js.map b/wwwroot/js/managers/SimpleEventOverlapManager.js.map new file mode 100644 index 0000000..173a398 --- /dev/null +++ b/wwwroot/js/managers/SimpleEventOverlapManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SimpleEventOverlapManager.js","sourceRoot":"","sources":["../../../src/managers/SimpleEventOverlapManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/ViewManager.d.ts b/wwwroot/js/managers/ViewManager.d.ts new file mode 100644 index 0000000..11147b5 --- /dev/null +++ b/wwwroot/js/managers/ViewManager.d.ts @@ -0,0 +1,23 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +export declare class ViewManager { + private eventBus; + private config; + private currentView; + private buttonListeners; + constructor(eventBus: IEventBus, config: Configuration); + private setupEventListeners; + private setupEventBusListeners; + private setupButtonHandlers; + private setupButtonGroup; + private getViewButtons; + private getWorkweekButtons; + private initializeView; + private changeView; + private changeWorkweek; + private updateAllButtons; + private updateButtonGroup; + private emitViewRendered; + private refreshCurrentView; + private isValidView; +} diff --git a/wwwroot/js/managers/ViewManager.js b/wwwroot/js/managers/ViewManager.js new file mode 100644 index 0000000..7b25515 --- /dev/null +++ b/wwwroot/js/managers/ViewManager.js @@ -0,0 +1,106 @@ +import { ConfigManager } from '../configurations/ConfigManager'; +import { CoreEvents } from '../constants/CoreEvents'; +export class ViewManager { + constructor(eventBus, config) { + this.currentView = 'week'; + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.config = config; + this.setupEventListeners(); + } + setupEventListeners() { + this.setupEventBusListeners(); + this.setupButtonHandlers(); + } + setupEventBusListeners() { + this.eventBus.on(CoreEvents.INITIALIZED, () => { + this.initializeView(); + }); + this.eventBus.on(CoreEvents.DATE_CHANGED, () => { + this.refreshCurrentView(); + }); + } + setupButtonHandlers() { + this.setupButtonGroup('swp-view-button[data-view]', 'data-view', (value) => { + if (this.isValidView(value)) { + this.changeView(value); + } + }); + this.setupButtonGroup('swp-preset-button[data-workweek]', 'data-workweek', (value) => { + this.changeWorkweek(value); + }); + } + setupButtonGroup(selector, attribute, handler) { + const buttons = document.querySelectorAll(selector); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const value = button.getAttribute(attribute); + if (value) { + handler(value); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + } + getViewButtons() { + return document.querySelectorAll('swp-view-button[data-view]'); + } + getWorkweekButtons() { + return document.querySelectorAll('swp-preset-button[data-workweek]'); + } + initializeView() { + this.updateAllButtons(); + this.emitViewRendered(); + } + changeView(newView) { + if (newView === this.currentView) + return; + const previousView = this.currentView; + this.currentView = newView; + this.updateAllButtons(); + this.eventBus.emit(CoreEvents.VIEW_CHANGED, { + previousView, + currentView: newView + }); + } + changeWorkweek(workweekId) { + this.config.setWorkWeek(workweekId); + // Update all CSS properties to match new configuration + ConfigManager.updateCSSProperties(this.config); + this.updateAllButtons(); + const settings = this.config.getWorkWeekSettings(); + this.eventBus.emit(CoreEvents.WORKWEEK_CHANGED, { + workWeekId: workweekId, + settings: settings + }); + } + updateAllButtons() { + this.updateButtonGroup(this.getViewButtons(), 'data-view', this.currentView); + this.updateButtonGroup(this.getWorkweekButtons(), 'data-workweek', this.config.currentWorkWeek); + } + updateButtonGroup(buttons, attribute, activeValue) { + buttons.forEach(button => { + const buttonValue = button.getAttribute(attribute); + if (buttonValue === activeValue) { + button.setAttribute('data-active', 'true'); + } + else { + button.removeAttribute('data-active'); + } + }); + } + emitViewRendered() { + this.eventBus.emit(CoreEvents.VIEW_RENDERED, { + view: this.currentView + }); + } + refreshCurrentView() { + this.emitViewRendered(); + } + isValidView(view) { + return ['day', 'week', 'month'].includes(view); + } +} +//# sourceMappingURL=ViewManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/ViewManager.js.map b/wwwroot/js/managers/ViewManager.js.map new file mode 100644 index 0000000..9608872 --- /dev/null +++ b/wwwroot/js/managers/ViewManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ViewManager.js","sourceRoot":"","sources":["../../../src/managers/ViewManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,MAAM,OAAO,WAAW;IAMpB,YAAY,QAAmB,EAAE,MAAqB;QAH9C,gBAAW,GAAiB,MAAM,CAAC;QACnC,oBAAe,GAAgC,IAAI,GAAG,EAAE,CAAC;QAG7D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAGO,sBAAsB;QAC1B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,EAAE;YAC1C,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE;YAC3C,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC,gBAAgB,CAAC,4BAA4B,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;YACvE,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,UAAU,CAAC,KAAqB,CAAC,CAAC;YAC3C,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,kCAAkC,EAAE,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YACjF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACP,CAAC;IAGO,gBAAgB,CAAC,QAAgB,EAAE,SAAiB,EAAE,OAAgC;QAC1F,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACpD,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACrB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;gBAClC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC7C,IAAI,KAAK,EAAE,CAAC;oBACR,OAAO,CAAC,KAAK,CAAC,CAAC;gBACnB,CAAC;YACL,CAAC,CAAC;YACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,cAAc;QAElB,OAAO,QAAQ,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;IAEnE,CAAC;IAEO,kBAAkB;QAEtB,OAAO,QAAQ,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC;IAEzE,CAAC;IAGO,cAAc;QAClB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,UAAU,CAAC,OAAqB;QACpC,IAAI,OAAO,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QAEzC,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAE3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE;YACxC,YAAY;YACZ,WAAW,EAAE,OAAO;SACvB,CAAC,CAAC;IACP,CAAC;IAEO,cAAc,CAAC,UAAkB;QAErC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAEpC,uDAAuD;QACvD,aAAa,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAC5C,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,QAAQ;SACrB,CAAC,CAAC;IACP,CAAC;IACO,gBAAgB;QACpB,IAAI,CAAC,iBAAiB,CAClB,IAAI,CAAC,cAAc,EAAE,EACrB,WAAW,EACX,IAAI,CAAC,WAAW,CACnB,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAClB,IAAI,CAAC,kBAAkB,EAAE,EACzB,eAAe,EACf,IAAI,CAAC,MAAM,CAAC,eAAe,CAC9B,CAAC;IACN,CAAC;IAEO,iBAAiB,CAAC,OAA4B,EAAE,SAAiB,EAAE,WAAmB;QAC1F,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACrB,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;gBAC9B,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YAC1C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,gBAAgB;QACpB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE;YACzC,IAAI,EAAE,IAAI,CAAC,WAAW;SACzB,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,WAAW,CAAC,IAAY;QAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;CAGJ"} \ No newline at end of file diff --git a/wwwroot/js/managers/ViewSelectorManager.d.ts b/wwwroot/js/managers/ViewSelectorManager.d.ts new file mode 100644 index 0000000..18a9db6 --- /dev/null +++ b/wwwroot/js/managers/ViewSelectorManager.d.ts @@ -0,0 +1,70 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * ViewSelectorManager - Manages view selector UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-view-button elements + * - Manages current view state (day/week/month) + * - Validates view values + * - Emits VIEW_CHANGED and VIEW_RENDERED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changeView() → validate → update state → emit event → update UI + * + * IMPLEMENTATION STATUS: + * ====================== + * - Week view: FULLY IMPLEMENTED + * - Day view: NOT IMPLEMENTED (button exists but no rendering) + * - Month view: NOT IMPLEMENTED (button exists but no rendering) + * + * SUBSCRIBERS: + * ============ + * - GridRenderer: Uses view parameter (currently only supports 'week') + * - Future: DayRenderer, MonthRenderer when implemented + */ +export declare class ViewSelectorManager { + private eventBus; + private config; + private buttonListeners; + constructor(eventBus: IEventBus, config: Configuration); + /** + * Setup click listeners on all view selector buttons + */ + private setupButtonListeners; + /** + * Setup event bus listeners + */ + private setupEventListeners; + /** + * Change the active view + */ + private changeView; + /** + * Update button states (data-active attributes) + */ + private updateButtonStates; + /** + * Initialize view on INITIALIZED event + */ + private initializeView; + /** + * Emit VIEW_RENDERED event + */ + private emitViewRendered; + /** + * Refresh current view on DATE_CHANGED event + */ + private refreshCurrentView; + /** + * Validate if string is a valid CalendarView type + */ + private isValidView; +} diff --git a/wwwroot/js/managers/ViewSelectorManager.js b/wwwroot/js/managers/ViewSelectorManager.js new file mode 100644 index 0000000..162191c --- /dev/null +++ b/wwwroot/js/managers/ViewSelectorManager.js @@ -0,0 +1,130 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * ViewSelectorManager - Manages view selector UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Handles button clicks on swp-view-button elements + * - Manages current view state (day/week/month) + * - Validates view values + * - Emits VIEW_CHANGED and VIEW_RENDERED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changeView() → validate → update state → emit event → update UI + * + * IMPLEMENTATION STATUS: + * ====================== + * - Week view: FULLY IMPLEMENTED + * - Day view: NOT IMPLEMENTED (button exists but no rendering) + * - Month view: NOT IMPLEMENTED (button exists but no rendering) + * + * SUBSCRIBERS: + * ============ + * - GridRenderer: Uses view parameter (currently only supports 'week') + * - Future: DayRenderer, MonthRenderer when implemented + */ +export class ViewSelectorManager { + constructor(eventBus, config) { + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.config = config; + this.setupButtonListeners(); + this.setupEventListeners(); + } + /** + * Setup click listeners on all view selector buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-view-button[data-view]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const view = button.getAttribute('data-view'); + if (view && this.isValidView(view)) { + this.changeView(view); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + // Initialize button states + this.updateButtonStates(); + } + /** + * Setup event bus listeners + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.INITIALIZED, () => { + this.initializeView(); + }); + this.eventBus.on(CoreEvents.DATE_CHANGED, () => { + this.refreshCurrentView(); + }); + } + /** + * Change the active view + */ + changeView(newView) { + if (newView === this.config.currentView) { + return; // No change + } + const previousView = this.config.currentView; + this.config.currentView = newView; + // Update button UI states + this.updateButtonStates(); + // Emit event for subscribers + this.eventBus.emit(CoreEvents.VIEW_CHANGED, { + previousView, + currentView: newView + }); + } + /** + * Update button states (data-active attributes) + */ + updateButtonStates() { + const buttons = document.querySelectorAll('swp-view-button[data-view]'); + buttons.forEach(button => { + const buttonView = button.getAttribute('data-view'); + if (buttonView === this.config.currentView) { + button.setAttribute('data-active', 'true'); + } + else { + button.removeAttribute('data-active'); + } + }); + } + /** + * Initialize view on INITIALIZED event + */ + initializeView() { + this.updateButtonStates(); + this.emitViewRendered(); + } + /** + * Emit VIEW_RENDERED event + */ + emitViewRendered() { + this.eventBus.emit(CoreEvents.VIEW_RENDERED, { + view: this.config.currentView + }); + } + /** + * Refresh current view on DATE_CHANGED event + */ + refreshCurrentView() { + this.emitViewRendered(); + } + /** + * Validate if string is a valid CalendarView type + */ + isValidView(view) { + return ['day', 'week', 'month'].includes(view); + } +} +//# sourceMappingURL=ViewSelectorManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/ViewSelectorManager.js.map b/wwwroot/js/managers/ViewSelectorManager.js.map new file mode 100644 index 0000000..aa10a71 --- /dev/null +++ b/wwwroot/js/managers/ViewSelectorManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ViewSelectorManager.js","sourceRoot":"","sources":["../../../src/managers/ViewSelectorManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/WorkHoursManager.d.ts b/wwwroot/js/managers/WorkHoursManager.d.ts new file mode 100644 index 0000000..8cd7f19 --- /dev/null +++ b/wwwroot/js/managers/WorkHoursManager.d.ts @@ -0,0 +1,71 @@ +import { DateService } from '../utils/DateService'; +import { Configuration } from '../configurations/CalendarConfig'; +import { PositionUtils } from '../utils/PositionUtils'; +/** + * Work hours for a specific day + */ +export interface IDayWorkHours { + start: number; + end: number; +} +/** + * Work schedule configuration + */ +export interface IWorkScheduleConfig { + weeklyDefault: { + monday: IDayWorkHours | 'off'; + tuesday: IDayWorkHours | 'off'; + wednesday: IDayWorkHours | 'off'; + thursday: IDayWorkHours | 'off'; + friday: IDayWorkHours | 'off'; + saturday: IDayWorkHours | 'off'; + sunday: IDayWorkHours | 'off'; + }; + dateOverrides: { + [dateString: string]: IDayWorkHours | 'off'; + }; +} +/** + * Manages work hours scheduling with weekly defaults and date-specific overrides + */ +export declare class WorkHoursManager { + private dateService; + private config; + private positionUtils; + private workSchedule; + constructor(dateService: DateService, config: Configuration, positionUtils: PositionUtils); + /** + * Get work hours for a specific date + */ + getWorkHoursForDate(date: Date): IDayWorkHours | 'off'; + /** + * Get work hours for multiple dates (used by GridManager) + */ + getWorkHoursForDateRange(dates: Date[]): Map; + /** + * Calculate CSS custom properties for non-work hour overlays using PositionUtils + */ + calculateNonWorkHoursStyle(workHours: IDayWorkHours | 'off'): { + beforeWorkHeight: number; + afterWorkTop: number; + } | null; + /** + * Calculate CSS custom properties for work hours overlay using PositionUtils + */ + calculateWorkHoursStyle(workHours: IDayWorkHours | 'off'): { + top: number; + height: number; + } | null; + /** + * Load work schedule from JSON (future implementation) + */ + loadWorkSchedule(jsonData: IWorkScheduleConfig): Promise; + /** + * Get current work schedule configuration + */ + getWorkSchedule(): IWorkScheduleConfig; + /** + * Convert Date to day name key + */ + private getDayName; +} diff --git a/wwwroot/js/managers/WorkHoursManager.js b/wwwroot/js/managers/WorkHoursManager.js new file mode 100644 index 0000000..b948c0f --- /dev/null +++ b/wwwroot/js/managers/WorkHoursManager.js @@ -0,0 +1,108 @@ +// Work hours management for per-column scheduling +/** + * Manages work hours scheduling with weekly defaults and date-specific overrides + */ +export class WorkHoursManager { + constructor(dateService, config, positionUtils) { + this.dateService = dateService; + this.config = config; + this.positionUtils = positionUtils; + // Default work schedule - will be loaded from JSON later + this.workSchedule = { + weeklyDefault: { + monday: { start: 9, end: 17 }, + tuesday: { start: 9, end: 17 }, + wednesday: { start: 9, end: 17 }, + thursday: { start: 9, end: 17 }, + friday: { start: 9, end: 15 }, + saturday: 'off', + sunday: 'off' + }, + dateOverrides: { + '2025-01-20': { start: 10, end: 16 }, + '2025-01-21': { start: 8, end: 14 }, + '2025-01-22': 'off' + } + }; + } + /** + * Get work hours for a specific date + */ + getWorkHoursForDate(date) { + const dateString = this.dateService.formatISODate(date); + // Check for date-specific override first + if (this.workSchedule.dateOverrides[dateString]) { + return this.workSchedule.dateOverrides[dateString]; + } + // Fall back to weekly default + const dayName = this.getDayName(date); + return this.workSchedule.weeklyDefault[dayName]; + } + /** + * Get work hours for multiple dates (used by GridManager) + */ + getWorkHoursForDateRange(dates) { + const workHoursMap = new Map(); + dates.forEach(date => { + const dateString = this.dateService.formatISODate(date); + const workHours = this.getWorkHoursForDate(date); + workHoursMap.set(dateString, workHours); + }); + return workHoursMap; + } + /** + * Calculate CSS custom properties for non-work hour overlays using PositionUtils + */ + calculateNonWorkHoursStyle(workHours) { + if (workHours === 'off') { + return null; // Full day will be colored via CSS background + } + const gridSettings = this.config.gridSettings; + const dayStartHour = gridSettings.dayStartHour; + const hourHeight = gridSettings.hourHeight; + // Before work: from day start to work start + const beforeWorkHeight = (workHours.start - dayStartHour) * hourHeight; + // After work: from work end to day end + const afterWorkTop = (workHours.end - dayStartHour) * hourHeight; + return { + beforeWorkHeight: Math.max(0, beforeWorkHeight), + afterWorkTop: Math.max(0, afterWorkTop) + }; + } + /** + * Calculate CSS custom properties for work hours overlay using PositionUtils + */ + calculateWorkHoursStyle(workHours) { + if (workHours === 'off') { + return null; + } + // Create dummy time strings for start and end of work hours + const startTime = `${workHours.start.toString().padStart(2, '0')}:00`; + const endTime = `${workHours.end.toString().padStart(2, '0')}:00`; + // Use PositionUtils for consistent position calculation + const position = this.positionUtils.calculateEventPosition(startTime, endTime); + return { top: position.top, height: position.height }; + } + /** + * Load work schedule from JSON (future implementation) + */ + async loadWorkSchedule(jsonData) { + this.workSchedule = jsonData; + } + /** + * Get current work schedule configuration + */ + getWorkSchedule() { + return this.workSchedule; + } + /** + * Convert Date to day name key + */ + getDayName(date) { + const dayNames = [ + 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' + ]; + return dayNames[date.getDay()]; + } +} +//# sourceMappingURL=WorkHoursManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/WorkHoursManager.js.map b/wwwroot/js/managers/WorkHoursManager.js.map new file mode 100644 index 0000000..136e28b --- /dev/null +++ b/wwwroot/js/managers/WorkHoursManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WorkHoursManager.js","sourceRoot":"","sources":["../../../src/managers/WorkHoursManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/managers/WorkweekPresetsManager.d.ts b/wwwroot/js/managers/WorkweekPresetsManager.d.ts new file mode 100644 index 0000000..0251865 --- /dev/null +++ b/wwwroot/js/managers/WorkweekPresetsManager.d.ts @@ -0,0 +1,47 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * WorkweekPresetsManager - Manages workweek preset UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Owns WORK_WEEK_PRESETS data + * - Handles button clicks on swp-preset-button elements + * - Manages current workweek preset state + * - Validates preset IDs + * - Emits WORKWEEK_CHANGED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changePreset() → validate → update state → emit event → update UI + * + * SUBSCRIBERS: + * ============ + * - ConfigManager: Updates CSS variables (--grid-columns) + * - GridManager: Re-renders grid with new column count + * - CalendarManager: Relays to header update (via workweek:header-update) + * - HeaderManager: Updates date headers + */ +export declare class WorkweekPresetsManager { + private eventBus; + private config; + private buttonListeners; + constructor(eventBus: IEventBus, config: Configuration); + /** + * Setup click listeners on all workweek preset buttons + */ + private setupButtonListeners; + /** + * Change the active workweek preset + */ + private changePreset; + /** + * Update button states (data-active attributes) + */ + private updateButtonStates; +} diff --git a/wwwroot/js/managers/WorkweekPresetsManager.js b/wwwroot/js/managers/WorkweekPresetsManager.js new file mode 100644 index 0000000..6ebdbc7 --- /dev/null +++ b/wwwroot/js/managers/WorkweekPresetsManager.js @@ -0,0 +1,95 @@ +import { CoreEvents } from '../constants/CoreEvents'; +import { WORK_WEEK_PRESETS } from '../configurations/CalendarConfig'; +/** + * WorkweekPresetsManager - Manages workweek preset UI and state + * + * RESPONSIBILITY: + * =============== + * This manager owns all logic related to the UI element. + * It follows the principle that each functional UI element has its own manager. + * + * RESPONSIBILITIES: + * - Owns WORK_WEEK_PRESETS data + * - Handles button clicks on swp-preset-button elements + * - Manages current workweek preset state + * - Validates preset IDs + * - Emits WORKWEEK_CHANGED events + * - Updates button UI states (data-active attributes) + * + * EVENT FLOW: + * =========== + * User clicks button → changePreset() → validate → update state → emit event → update UI + * + * SUBSCRIBERS: + * ============ + * - ConfigManager: Updates CSS variables (--grid-columns) + * - GridManager: Re-renders grid with new column count + * - CalendarManager: Relays to header update (via workweek:header-update) + * - HeaderManager: Updates date headers + */ +export class WorkweekPresetsManager { + constructor(eventBus, config) { + this.buttonListeners = new Map(); + this.eventBus = eventBus; + this.config = config; + this.setupButtonListeners(); + } + /** + * Setup click listeners on all workweek preset buttons + */ + setupButtonListeners() { + const buttons = document.querySelectorAll('swp-preset-button[data-workweek]'); + buttons.forEach(button => { + const clickHandler = (event) => { + event.preventDefault(); + const presetId = button.getAttribute('data-workweek'); + if (presetId) { + this.changePreset(presetId); + } + }; + button.addEventListener('click', clickHandler); + this.buttonListeners.set(button, clickHandler); + }); + // Initialize button states + this.updateButtonStates(); + } + /** + * Change the active workweek preset + */ + changePreset(presetId) { + if (!WORK_WEEK_PRESETS[presetId]) { + console.warn(`Invalid preset ID "${presetId}"`); + return; + } + if (presetId === this.config.currentWorkWeek) { + return; // No change + } + const previousPresetId = this.config.currentWorkWeek; + this.config.currentWorkWeek = presetId; + const settings = WORK_WEEK_PRESETS[presetId]; + // Update button UI states + this.updateButtonStates(); + // Emit event for subscribers + this.eventBus.emit(CoreEvents.WORKWEEK_CHANGED, { + workWeekId: presetId, + previousWorkWeekId: previousPresetId, + settings: settings + }); + } + /** + * Update button states (data-active attributes) + */ + updateButtonStates() { + const buttons = document.querySelectorAll('swp-preset-button[data-workweek]'); + buttons.forEach(button => { + const buttonPresetId = button.getAttribute('data-workweek'); + if (buttonPresetId === this.config.currentWorkWeek) { + button.setAttribute('data-active', 'true'); + } + else { + button.removeAttribute('data-active'); + } + }); + } +} +//# sourceMappingURL=WorkweekPresetsManager.js.map \ No newline at end of file diff --git a/wwwroot/js/managers/WorkweekPresetsManager.js.map b/wwwroot/js/managers/WorkweekPresetsManager.js.map new file mode 100644 index 0000000..4e7bc85 --- /dev/null +++ b/wwwroot/js/managers/WorkweekPresetsManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WorkweekPresetsManager.js","sourceRoot":"","sources":["../../../src/managers/WorkweekPresetsManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAiB,MAAM,kCAAkC,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,sBAAsB;IAKjC,YAAY,QAAmB,EAAE,MAAqB;QAF9C,oBAAe,GAAgC,IAAI,GAAG,EAAE,CAAC;QAG/D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC;QAE9E,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE;gBACpC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;gBACtD,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,QAAgB;QACnC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,sBAAsB,QAAQ,GAAG,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC7C,OAAO,CAAC,YAAY;QACtB,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,QAAQ,CAAC;QAEvC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAE7C,0BAA0B;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,6BAA6B;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAC9C,UAAU,EAAE,QAAQ;YACpB,kBAAkB,EAAE,gBAAgB;YACpC,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,gBAAgB,CAAC,kCAAkC,CAAC,CAAC;QAE9E,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,MAAM,cAAc,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAE5D,IAAI,cAAc,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;gBACnD,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CAEF"} \ No newline at end of file diff --git a/wwwroot/js/renderers/AllDayEventRenderer.d.ts b/wwwroot/js/renderers/AllDayEventRenderer.d.ts new file mode 100644 index 0000000..588760b --- /dev/null +++ b/wwwroot/js/renderers/AllDayEventRenderer.d.ts @@ -0,0 +1,32 @@ +import { IEventLayout } from '../utils/AllDayLayoutEngine'; +import { IDragStartEventPayload } from '../types/EventTypes'; +export declare class AllDayEventRenderer { + private container; + private originalEvent; + private draggedClone; + constructor(); + private getContainer; + private getAllDayContainer; + /** + * Handle drag start for all-day events + */ + handleDragStart(payload: IDragStartEventPayload): void; + /** + * Render an all-day event with pre-calculated layout + */ + private renderAllDayEventWithLayout; + /** + * Remove an all-day event by ID + */ + removeAllDayEvent(eventId: string): void; + /** + * Clear cache when DOM changes + */ + clearCache(): void; + /** + * Render all-day events for specific period using AllDayEventRenderer + */ + renderAllDayEventsForPeriod(eventLayouts: IEventLayout[]): void; + private clearAllDayEvents; + handleViewChanged(event: CustomEvent): void; +} diff --git a/wwwroot/js/renderers/AllDayEventRenderer.js b/wwwroot/js/renderers/AllDayEventRenderer.js new file mode 100644 index 0000000..bafe6af --- /dev/null +++ b/wwwroot/js/renderers/AllDayEventRenderer.js @@ -0,0 +1,97 @@ +import { SwpAllDayEventElement } from '../elements/SwpEventElement'; +export class AllDayEventRenderer { + constructor() { + this.container = null; + this.originalEvent = null; + this.draggedClone = null; + this.getContainer(); + } + getContainer() { + const header = document.querySelector('swp-calendar-header'); + if (header) { + this.container = header.querySelector('swp-allday-container'); + if (!this.container) { + this.container = document.createElement('swp-allday-container'); + header.appendChild(this.container); + } + } + return this.container; + } + getAllDayContainer() { + return document.querySelector('swp-calendar-header swp-allday-container'); + } + /** + * Handle drag start for all-day events + */ + handleDragStart(payload) { + this.originalEvent = payload.originalElement; + ; + this.draggedClone = payload.draggedClone; + if (this.draggedClone) { + const container = this.getAllDayContainer(); + if (!container) + return; + this.draggedClone.style.gridColumn = this.originalEvent.style.gridColumn; + this.draggedClone.style.gridRow = this.originalEvent.style.gridRow; + console.log('handleDragStart:this.draggedClone', this.draggedClone); + container.appendChild(this.draggedClone); + // Add dragging style + this.draggedClone.classList.add('dragging'); + this.draggedClone.style.zIndex = '1000'; + this.draggedClone.style.cursor = 'grabbing'; + // Make original semi-transparent + this.originalEvent.style.opacity = '0.3'; + this.originalEvent.style.userSelect = 'none'; + } + } + /** + * Render an all-day event with pre-calculated layout + */ + renderAllDayEventWithLayout(event, layout) { + const container = this.getContainer(); + if (!container) + return null; + const dayEvent = SwpAllDayEventElement.fromCalendarEvent(event); + dayEvent.applyGridPositioning(layout.row, layout.startColumn, layout.endColumn); + // Apply highlight class to show events with highlight color + dayEvent.classList.add('highlight'); + container.appendChild(dayEvent); + } + /** + * Remove an all-day event by ID + */ + removeAllDayEvent(eventId) { + const container = this.getContainer(); + if (!container) + return; + const eventElement = container.querySelector(`swp-allday-event[data-event-id="${eventId}"]`); + if (eventElement) { + eventElement.remove(); + } + } + /** + * Clear cache when DOM changes + */ + clearCache() { + this.container = null; + } + /** + * Render all-day events for specific period using AllDayEventRenderer + */ + renderAllDayEventsForPeriod(eventLayouts) { + this.clearAllDayEvents(); + eventLayouts.forEach(layout => { + this.renderAllDayEventWithLayout(layout.calenderEvent, layout); + }); + } + clearAllDayEvents() { + const allDayContainer = document.querySelector('swp-allday-container'); + if (allDayContainer) { + allDayContainer.querySelectorAll('swp-allday-event:not(.max-event-indicator)').forEach(event => event.remove()); + } + } + handleViewChanged(event) { + this.clearAllDayEvents(); + } +} +//# sourceMappingURL=AllDayEventRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/AllDayEventRenderer.js.map b/wwwroot/js/renderers/AllDayEventRenderer.js.map new file mode 100644 index 0000000..1a34457 --- /dev/null +++ b/wwwroot/js/renderers/AllDayEventRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayEventRenderer.js","sourceRoot":"","sources":["../../../src/renderers/AllDayEventRenderer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/renderers/ColumnRenderer.d.ts b/wwwroot/js/renderers/ColumnRenderer.d.ts new file mode 100644 index 0000000..7bb8239 --- /dev/null +++ b/wwwroot/js/renderers/ColumnRenderer.d.ts @@ -0,0 +1,26 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { DateService } from '../utils/DateService'; +import { WorkHoursManager } from '../managers/WorkHoursManager'; +/** + * Interface for column rendering strategies + */ +export interface IColumnRenderer { + render(columnContainer: HTMLElement, context: IColumnRenderContext): void; +} +/** + * Context for column rendering + */ +export interface IColumnRenderContext { + currentWeek: Date; + config: Configuration; +} +/** + * Date-based column renderer (original functionality) + */ +export declare class DateColumnRenderer implements IColumnRenderer { + private dateService; + private workHoursManager; + constructor(dateService: DateService, workHoursManager: WorkHoursManager); + render(columnContainer: HTMLElement, context: IColumnRenderContext): void; + private applyWorkHoursToColumn; +} diff --git a/wwwroot/js/renderers/ColumnRenderer.js b/wwwroot/js/renderers/ColumnRenderer.js new file mode 100644 index 0000000..ca17b92 --- /dev/null +++ b/wwwroot/js/renderers/ColumnRenderer.js @@ -0,0 +1,44 @@ +// Column rendering strategy interface and implementations +/** + * Date-based column renderer (original functionality) + */ +export class DateColumnRenderer { + constructor(dateService, workHoursManager) { + this.dateService = dateService; + this.workHoursManager = workHoursManager; + } + render(columnContainer, context) { + const { currentWeek, config } = context; + const workWeekSettings = config.getWorkWeekSettings(); + const dates = this.dateService.getWorkWeekDates(currentWeek, workWeekSettings.workDays); + const dateSettings = config.dateViewSettings; + const daysToShow = dates.slice(0, dateSettings.weekDays); + daysToShow.forEach((date) => { + const column = document.createElement('swp-day-column'); + column.dataset.date = this.dateService.formatISODate(date); + // Apply work hours styling + this.applyWorkHoursToColumn(column, date); + const eventsLayer = document.createElement('swp-events-layer'); + column.appendChild(eventsLayer); + columnContainer.appendChild(column); + }); + } + applyWorkHoursToColumn(column, date) { + const workHours = this.workHoursManager.getWorkHoursForDate(date); + if (workHours === 'off') { + // No work hours - mark as off day (full day will be colored) + column.dataset.workHours = 'off'; + } + else { + // Calculate and apply non-work hours overlays (before and after work) + const nonWorkStyle = this.workHoursManager.calculateNonWorkHoursStyle(workHours); + if (nonWorkStyle) { + // Before work overlay (::before pseudo-element) + column.style.setProperty('--before-work-height', `${nonWorkStyle.beforeWorkHeight}px`); + // After work overlay (::after pseudo-element) + column.style.setProperty('--after-work-top', `${nonWorkStyle.afterWorkTop}px`); + } + } + } +} +//# sourceMappingURL=ColumnRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/ColumnRenderer.js.map b/wwwroot/js/renderers/ColumnRenderer.js.map new file mode 100644 index 0000000..634f6f6 --- /dev/null +++ b/wwwroot/js/renderers/ColumnRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ColumnRenderer.js","sourceRoot":"","sources":["../../../src/renderers/ColumnRenderer.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAqB1D;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAI7B,YACE,WAAwB,EACxB,gBAAkC;QAElC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,eAA4B,EAAE,OAA6B;QAChE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAExC,MAAM,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACxF,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QAGzD,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACvD,MAAc,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAEpE,2BAA2B;YAC3B,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAE1C,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;YAC/D,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;YAEhC,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,sBAAsB,CAAC,MAAmB,EAAE,IAAU;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAElE,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YACxB,6DAA6D;YAC5D,MAAc,CAAC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,sEAAsE;YACtE,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC;YACjF,IAAI,YAAY,EAAE,CAAC;gBACjB,gDAAgD;gBAChD,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,EAAE,GAAG,YAAY,CAAC,gBAAgB,IAAI,CAAC,CAAC;gBAEvF,8CAA8C;gBAC9C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,kBAAkB,EAAE,GAAG,YAAY,CAAC,YAAY,IAAI,CAAC,CAAC;YAEjF,CAAC;QACH,CAAC;IACH,CAAC;CAEF"} \ No newline at end of file diff --git a/wwwroot/js/renderers/DateHeaderRenderer.d.ts b/wwwroot/js/renderers/DateHeaderRenderer.d.ts new file mode 100644 index 0000000..4df75e2 --- /dev/null +++ b/wwwroot/js/renderers/DateHeaderRenderer.d.ts @@ -0,0 +1,21 @@ +import { Configuration } from '../configurations/CalendarConfig'; +/** + * Interface for header rendering strategies + */ +export interface IHeaderRenderer { + render(calendarHeader: HTMLElement, context: IHeaderRenderContext): void; +} +/** + * Context for header rendering + */ +export interface IHeaderRenderContext { + currentWeek: Date; + config: Configuration; +} +/** + * Date-based header renderer (original functionality) + */ +export declare class DateHeaderRenderer implements IHeaderRenderer { + private dateService; + render(calendarHeader: HTMLElement, context: IHeaderRenderContext): void; +} diff --git a/wwwroot/js/renderers/DateHeaderRenderer.js b/wwwroot/js/renderers/DateHeaderRenderer.js new file mode 100644 index 0000000..1787f1c --- /dev/null +++ b/wwwroot/js/renderers/DateHeaderRenderer.js @@ -0,0 +1,35 @@ +// Header rendering strategy interface and implementations +import { DateService } from '../utils/DateService'; +/** + * Date-based header renderer (original functionality) + */ +export class DateHeaderRenderer { + render(calendarHeader, context) { + const { currentWeek, config } = context; + // FIRST: Always create all-day container as part of standard header structure + const allDayContainer = document.createElement('swp-allday-container'); + calendarHeader.appendChild(allDayContainer); + // Initialize date service with timezone and locale from config + const timezone = config.timeFormatConfig.timezone; + const locale = config.timeFormatConfig.locale; + this.dateService = new DateService(config); + const workWeekSettings = config.getWorkWeekSettings(); + const dates = this.dateService.getWorkWeekDates(currentWeek, workWeekSettings.workDays); + const weekDays = config.dateViewSettings.weekDays; + const daysToShow = dates.slice(0, weekDays); + daysToShow.forEach((date, index) => { + const header = document.createElement('swp-day-header'); + if (this.dateService.isSameDay(date, new Date())) { + header.dataset.today = 'true'; + } + const dayName = this.dateService.getDayName(date, 'long', locale).toUpperCase(); + header.innerHTML = ` + ${dayName} + ${date.getDate()} + `; + header.dataset.date = this.dateService.formatISODate(date); + calendarHeader.appendChild(header); + }); + } +} +//# sourceMappingURL=DateHeaderRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/DateHeaderRenderer.js.map b/wwwroot/js/renderers/DateHeaderRenderer.js.map new file mode 100644 index 0000000..e3e3bc2 --- /dev/null +++ b/wwwroot/js/renderers/DateHeaderRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateHeaderRenderer.js","sourceRoot":"","sources":["../../../src/renderers/DateHeaderRenderer.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAkBnD;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAG7B,MAAM,CAAC,cAA2B,EAAE,OAA6B;QAC/D,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAExC,8EAA8E;QAC9E,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;QACvE,cAAc,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QAE5C,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;QAE3C,MAAM,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACxF,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAClD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAE5C,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACxD,IAAI,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;gBAChD,MAAc,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;YACzC,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAEhF,MAAM,CAAC,SAAS,GAAG;wBACD,OAAO;wBACP,IAAI,CAAC,OAAO,EAAE;OAC/B,CAAC;YACD,MAAc,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAEpE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/renderers/EventRenderer.d.ts b/wwwroot/js/renderers/EventRenderer.d.ts new file mode 100644 index 0000000..286119e --- /dev/null +++ b/wwwroot/js/renderers/EventRenderer.d.ts @@ -0,0 +1,96 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +import { PositionUtils } from '../utils/PositionUtils'; +import { IColumnBounds } from '../utils/ColumnDetectionUtils'; +import { IDragColumnChangeEventPayload, IDragMoveEventPayload, IDragStartEventPayload, IDragMouseEnterColumnEventPayload } from '../types/EventTypes'; +import { DateService } from '../utils/DateService'; +import { EventStackManager } from '../managers/EventStackManager'; +import { EventLayoutCoordinator } from '../managers/EventLayoutCoordinator'; +/** + * Interface for event rendering strategies + */ +export interface IEventRenderer { + renderEvents(events: ICalendarEvent[], container: HTMLElement): void; + clearEvents(container?: HTMLElement): void; + renderSingleColumnEvents?(column: IColumnBounds, events: ICalendarEvent[]): void; + handleDragStart?(payload: IDragStartEventPayload): void; + handleDragMove?(payload: IDragMoveEventPayload): void; + handleDragAutoScroll?(eventId: string, snappedY: number): void; + handleDragEnd?(originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: IColumnBounds, finalY: number): void; + handleEventClick?(eventId: string, originalElement: HTMLElement): void; + handleColumnChange?(payload: IDragColumnChangeEventPayload): void; + handleNavigationCompleted?(): void; + handleConvertAllDayToTimed?(payload: IDragMouseEnterColumnEventPayload): void; +} +/** + * Date-based event renderer + */ +export declare class DateEventRenderer implements IEventRenderer { + private dateService; + private stackManager; + private layoutCoordinator; + private config; + private positionUtils; + private draggedClone; + private originalEvent; + constructor(dateService: DateService, stackManager: EventStackManager, layoutCoordinator: EventLayoutCoordinator, config: Configuration, positionUtils: PositionUtils); + private applyDragStyling; + /** + * Handle drag start event + */ + handleDragStart(payload: IDragStartEventPayload): void; + /** + * Handle drag move event + */ + handleDragMove(payload: IDragMoveEventPayload): void; + /** + * Handle column change during drag + */ + handleColumnChange(payload: IDragColumnChangeEventPayload): void; + /** + * Handle conversion of all-day event to timed event + */ + handleConvertAllDayToTimed(payload: IDragMouseEnterColumnEventPayload): void; + /** + * Handle drag end event + */ + handleDragEnd(originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: IColumnBounds, finalY: number): void; + /** + * Handle navigation completed event + */ + handleNavigationCompleted(): void; + /** + * Fade out and remove element + */ + private fadeOutAndRemove; + renderEvents(events: ICalendarEvent[], container: HTMLElement): void; + /** + * Render events for a single column + */ + renderSingleColumnEvents(column: IColumnBounds, events: ICalendarEvent[]): void; + /** + * Render events in a column using combined stacking + grid algorithm + */ + private renderColumnEvents; + /** + * Render events in a grid container (side-by-side with column sharing) + */ + private renderGridGroup; + /** + * Render a single column within a grid group + * Column may contain multiple events that don't overlap + */ + private renderGridColumn; + /** + * Render event within a grid container (absolute positioning within column) + */ + private renderEventInGrid; + private renderEvent; + protected calculateEventPosition(event: ICalendarEvent): { + top: number; + height: number; + }; + clearEvents(container?: HTMLElement): void; + protected getColumns(container: HTMLElement): HTMLElement[]; + protected getEventsForColumn(column: HTMLElement, events: ICalendarEvent[]): ICalendarEvent[]; +} diff --git a/wwwroot/js/renderers/EventRenderer.js b/wwwroot/js/renderers/EventRenderer.js new file mode 100644 index 0000000..ce026a4 --- /dev/null +++ b/wwwroot/js/renderers/EventRenderer.js @@ -0,0 +1,296 @@ +// Event rendering strategy interface and implementations +import { SwpEventElement } from '../elements/SwpEventElement'; +/** + * Date-based event renderer + */ +export class DateEventRenderer { + constructor(dateService, stackManager, layoutCoordinator, config, positionUtils) { + this.draggedClone = null; + this.originalEvent = null; + this.dateService = dateService; + this.stackManager = stackManager; + this.layoutCoordinator = layoutCoordinator; + this.config = config; + this.positionUtils = positionUtils; + } + applyDragStyling(element) { + element.classList.add('dragging'); + element.style.removeProperty("margin-left"); + } + /** + * Handle drag start event + */ + handleDragStart(payload) { + this.originalEvent = payload.originalElement; + ; + // Use the clone from the payload instead of creating a new one + this.draggedClone = payload.draggedClone; + if (this.draggedClone && payload.columnBounds) { + // Apply drag styling + this.applyDragStyling(this.draggedClone); + // Add to current column's events layer (not directly to column) + const eventsLayer = payload.columnBounds.element.querySelector('swp-events-layer'); + if (eventsLayer) { + eventsLayer.appendChild(this.draggedClone); + // Set initial position to prevent "jump to top" effect + // Calculate absolute Y position from original element + const originalRect = this.originalEvent.getBoundingClientRect(); + const columnRect = payload.columnBounds.boundingClientRect; + const initialTop = originalRect.top - columnRect.top; + this.draggedClone.style.top = `${initialTop}px`; + } + } + // Make original semi-transparent + this.originalEvent.style.opacity = '0.3'; + this.originalEvent.style.userSelect = 'none'; + } + /** + * Handle drag move event + */ + handleDragMove(payload) { + const swpEvent = payload.draggedClone; + const columnDate = this.dateService.parseISO(payload.columnBounds.date); + swpEvent.updatePosition(columnDate, payload.snappedY); + } + /** + * Handle column change during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.element.querySelector('swp-events-layer'); + if (eventsLayer && payload.draggedClone.parentElement !== eventsLayer) { + eventsLayer.appendChild(payload.draggedClone); + // Recalculate timestamps with new column date + const currentTop = parseFloat(payload.draggedClone.style.top) || 0; + const swpEvent = payload.draggedClone; + const columnDate = this.dateService.parseISO(payload.newColumn.date); + swpEvent.updatePosition(columnDate, currentTop); + } + } + /** + * Handle conversion of all-day event to timed event + */ + handleConvertAllDayToTimed(payload) { + console.log('🎯 DateEventRenderer: Converting all-day to timed event', { + eventId: payload.calendarEvent.id, + targetColumn: payload.targetColumn.date, + snappedY: payload.snappedY + }); + let timedClone = SwpEventElement.fromCalendarEvent(payload.calendarEvent); + let position = this.calculateEventPosition(payload.calendarEvent); + // Set position at snapped Y + //timedClone.style.top = `${snappedY}px`; + // Set complete styling for dragged clone (matching normal event rendering) + timedClone.style.height = `${position.height - 3}px`; + timedClone.style.left = '2px'; + timedClone.style.right = '2px'; + timedClone.style.width = 'auto'; + timedClone.style.pointerEvents = 'none'; + // Apply drag styling + this.applyDragStyling(timedClone); + // Find the events layer in the target column + let eventsLayer = payload.targetColumn.element.querySelector('swp-events-layer'); + // Add "clone-" prefix to match clone ID pattern + //timedClone.dataset.eventId = `clone-${payload.calendarEvent.id}`; + // Remove old all-day clone and replace with new timed clone + payload.draggedClone.remove(); + payload.replaceClone(timedClone); + eventsLayer.appendChild(timedClone); + } + /** + * Handle drag end event + */ + handleDragEnd(originalElement, draggedClone, finalColumn, finalY) { + if (!draggedClone || !originalElement) { + console.warn('Missing draggedClone or originalElement'); + return; + } + // Only fade out and remove if it's a swp-event (not swp-allday-event) + // AllDayManager handles removal of swp-allday-event elements + if (originalElement.tagName === 'SWP-EVENT') { + this.fadeOutAndRemove(originalElement); + } + // Remove clone prefix and normalize clone to be a regular event + const cloneId = draggedClone.dataset.eventId; + if (cloneId && cloneId.startsWith('clone-')) { + draggedClone.dataset.eventId = cloneId.replace('clone-', ''); + } + // Fully normalize the clone to be a regular event + draggedClone.classList.remove('dragging'); + draggedClone.style.pointerEvents = ''; // Re-enable pointer events + // Clean up instance state + this.draggedClone = null; + this.originalEvent = null; + // Clean up any remaining day event clones + const dayEventClone = document.querySelector(`swp-event[data-event-id="clone-${cloneId}"]`); + if (dayEventClone) { + dayEventClone.remove(); + } + } + /** + * Handle navigation completed event + */ + handleNavigationCompleted() { + // Default implementation - can be overridden by subclasses + } + /** + * Fade out and remove element + */ + fadeOutAndRemove(element) { + element.style.transition = 'opacity 0.3s ease-out'; + element.style.opacity = '0'; + setTimeout(() => { + element.remove(); + }, 300); + } + renderEvents(events, container) { + // Filter out all-day events - they should be handled by AllDayEventRenderer + const timedEvents = events.filter(event => !event.allDay); + // Find columns in the specific container for regular events + const columns = this.getColumns(container); + columns.forEach(column => { + const columnEvents = this.getEventsForColumn(column, timedEvents); + const eventsLayer = column.querySelector('swp-events-layer'); + if (eventsLayer) { + this.renderColumnEvents(columnEvents, eventsLayer); + } + }); + } + /** + * Render events for a single column + */ + renderSingleColumnEvents(column, events) { + const columnEvents = this.getEventsForColumn(column.element, events); + const eventsLayer = column.element.querySelector('swp-events-layer'); + if (eventsLayer) { + this.renderColumnEvents(columnEvents, eventsLayer); + } + } + /** + * Render events in a column using combined stacking + grid algorithm + */ + renderColumnEvents(columnEvents, eventsLayer) { + if (columnEvents.length === 0) + return; + // Get layout from coordinator + const layout = this.layoutCoordinator.calculateColumnLayout(columnEvents); + // Render grid groups + layout.gridGroups.forEach(gridGroup => { + this.renderGridGroup(gridGroup, eventsLayer); + }); + // Render stacked events + layout.stackedEvents.forEach(stackedEvent => { + const element = this.renderEvent(stackedEvent.event); + this.stackManager.applyStackLinkToElement(element, stackedEvent.stackLink); + this.stackManager.applyVisualStyling(element, stackedEvent.stackLink.stackLevel); + eventsLayer.appendChild(element); + }); + } + /** + * Render events in a grid container (side-by-side with column sharing) + */ + renderGridGroup(gridGroup, eventsLayer) { + const groupElement = document.createElement('swp-event-group'); + // Add grid column class based on number of columns (not events) + const colCount = gridGroup.columns.length; + groupElement.classList.add(`cols-${colCount}`); + // Add stack level class for margin-left offset + groupElement.classList.add(`stack-level-${gridGroup.stackLevel}`); + // Position from layout + groupElement.style.top = `${gridGroup.position.top}px`; + // Add stack-link attribute for drag-drop (group acts as a stacked item) + const stackLink = { + stackLevel: gridGroup.stackLevel + }; + this.stackManager.applyStackLinkToElement(groupElement, stackLink); + // Apply visual styling (margin-left and z-index) using StackManager + this.stackManager.applyVisualStyling(groupElement, gridGroup.stackLevel); + // Render each column + const earliestEvent = gridGroup.events[0]; + gridGroup.columns.forEach((columnEvents) => { + const columnContainer = this.renderGridColumn(columnEvents, earliestEvent.start); + groupElement.appendChild(columnContainer); + }); + eventsLayer.appendChild(groupElement); + } + /** + * Render a single column within a grid group + * Column may contain multiple events that don't overlap + */ + renderGridColumn(columnEvents, containerStart) { + const columnContainer = document.createElement('div'); + columnContainer.style.position = 'relative'; + columnEvents.forEach(event => { + const element = this.renderEventInGrid(event, containerStart); + columnContainer.appendChild(element); + }); + return columnContainer; + } + /** + * Render event within a grid container (absolute positioning within column) + */ + renderEventInGrid(event, containerStart) { + const element = SwpEventElement.fromCalendarEvent(event); + // Calculate event height + const position = this.calculateEventPosition(event); + // Calculate relative top offset if event starts after container start + // (e.g., if container starts at 07:00 and event starts at 08:15, offset = 75 min) + const timeDiffMs = event.start.getTime() - containerStart.getTime(); + const timeDiffMinutes = timeDiffMs / (1000 * 60); + const gridSettings = this.config.gridSettings; + const relativeTop = timeDiffMinutes > 0 ? (timeDiffMinutes / 60) * gridSettings.hourHeight : 0; + // Events in grid columns are positioned absolutely within their column container + element.style.position = 'absolute'; + element.style.top = `${relativeTop}px`; + element.style.height = `${position.height - 3}px`; + element.style.left = '0'; + element.style.right = '0'; + return element; + } + renderEvent(event) { + const element = SwpEventElement.fromCalendarEvent(event); + // Apply positioning (moved from SwpEventElement.applyPositioning) + const position = this.calculateEventPosition(event); + element.style.position = 'absolute'; + element.style.top = `${position.top + 1}px`; + element.style.height = `${position.height - 3}px`; + element.style.left = '2px'; + element.style.right = '2px'; + return element; + } + calculateEventPosition(event) { + // Delegate to PositionUtils for centralized position calculation + return this.positionUtils.calculateEventPosition(event.start, event.end); + } + clearEvents(container) { + const eventSelector = 'swp-event'; + const groupSelector = 'swp-event-group'; + const existingEvents = container + ? container.querySelectorAll(eventSelector) + : document.querySelectorAll(eventSelector); + const existingGroups = container + ? container.querySelectorAll(groupSelector) + : document.querySelectorAll(groupSelector); + existingEvents.forEach(event => event.remove()); + existingGroups.forEach(group => group.remove()); + } + getColumns(container) { + const columns = container.querySelectorAll('swp-day-column'); + return Array.from(columns); + } + getEventsForColumn(column, events) { + const columnDate = column.dataset.date; + if (!columnDate) { + return []; + } + // Create start and end of day for interval overlap check + const columnStart = this.dateService.parseISO(`${columnDate}T00:00:00`); + const columnEnd = this.dateService.parseISO(`${columnDate}T23:59:59.999`); + const columnEvents = events.filter(event => { + // Interval overlap: event overlaps with column day if event.start < columnEnd AND event.end > columnStart + const overlaps = event.start < columnEnd && event.end > columnStart; + return overlaps; + }); + return columnEvents; + } +} +//# sourceMappingURL=EventRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/EventRenderer.js.map b/wwwroot/js/renderers/EventRenderer.js.map new file mode 100644 index 0000000..78765f0 --- /dev/null +++ b/wwwroot/js/renderers/EventRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventRenderer.js","sourceRoot":"","sources":["../../../src/renderers/EventRenderer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/renderers/EventRendererManager.d.ts b/wwwroot/js/renderers/EventRendererManager.d.ts new file mode 100644 index 0000000..3a2131c --- /dev/null +++ b/wwwroot/js/renderers/EventRendererManager.d.ts @@ -0,0 +1,55 @@ +import { IEventBus, IRenderContext } from '../types/CalendarTypes'; +import { EventManager } from '../managers/EventManager'; +import { IEventRenderer } from './EventRenderer'; +import { DateService } from '../utils/DateService'; +/** + * EventRenderingService - Render events i DOM med positionering using Strategy Pattern + * Håndterer event positioning og overlap detection + */ +export declare class EventRenderingService { + private eventBus; + private eventManager; + private strategy; + private dateService; + private dragMouseLeaveHeaderListener; + constructor(eventBus: IEventBus, eventManager: EventManager, strategy: IEventRenderer, dateService: DateService); + /** + * Render events in a specific container for a given period + */ + renderEvents(context: IRenderContext): Promise; + private setupEventListeners; + /** + * Handle GRID_RENDERED event - render events in the current grid + */ + private handleGridRendered; + /** + * Handle VIEW_CHANGED event - clear and re-render for new view + */ + private handleViewChanged; + /** + * Setup all drag event listeners - moved from EventRenderer for better separation of concerns + */ + private setupDragEventListeners; + private setupDragStartListener; + private setupDragMoveListener; + private setupDragEndListener; + private setupDragColumnChangeListener; + private setupDragMouseLeaveHeaderListener; + private setupDragMouseEnterColumnListener; + private setupResizeEndListener; + private setupNavigationCompletedListener; + /** + * Re-render affected columns after drag to recalculate stacking/grouping + */ + private reRenderAffectedColumns; + /** + * Clear events in a single column's events layer + */ + private clearColumnEvents; + /** + * Render events for a single column + */ + private renderSingleColumn; + private clearEvents; + refresh(container?: HTMLElement): void; +} diff --git a/wwwroot/js/renderers/EventRendererManager.js b/wwwroot/js/renderers/EventRendererManager.js new file mode 100644 index 0000000..d326ba4 --- /dev/null +++ b/wwwroot/js/renderers/EventRendererManager.js @@ -0,0 +1,264 @@ +import { CoreEvents } from '../constants/CoreEvents'; +import { ColumnDetectionUtils } from '../utils/ColumnDetectionUtils'; +/** + * EventRenderingService - Render events i DOM med positionering using Strategy Pattern + * Håndterer event positioning og overlap detection + */ +export class EventRenderingService { + constructor(eventBus, eventManager, strategy, dateService) { + this.dragMouseLeaveHeaderListener = null; + this.eventBus = eventBus; + this.eventManager = eventManager; + this.strategy = strategy; + this.dateService = dateService; + this.setupEventListeners(); + } + /** + * Render events in a specific container for a given period + */ + async renderEvents(context) { + // Clear existing events in the specific container first + this.strategy.clearEvents(context.container); + // Get events from EventManager for the period + const events = await this.eventManager.getEventsForPeriod(context.startDate, context.endDate); + if (events.length === 0) { + return; + } + // Filter events by type - only render timed events here + const timedEvents = events.filter(event => !event.allDay); + console.log('🎯 EventRenderingService: Event filtering', { + totalEvents: events.length, + timedEvents: timedEvents.length, + allDayEvents: events.length - timedEvents.length + }); + // Render timed events using existing strategy + if (timedEvents.length > 0) { + this.strategy.renderEvents(timedEvents, context.container); + } + // Emit EVENTS_RENDERED event for filtering system + this.eventBus.emit(CoreEvents.EVENTS_RENDERED, { + events: events, + container: context.container + }); + } + setupEventListeners() { + this.eventBus.on(CoreEvents.GRID_RENDERED, (event) => { + this.handleGridRendered(event); + }); + this.eventBus.on(CoreEvents.VIEW_CHANGED, (event) => { + this.handleViewChanged(event); + }); + // Handle all drag events and delegate to appropriate renderer + this.setupDragEventListeners(); + } + /** + * Handle GRID_RENDERED event - render events in the current grid + */ + handleGridRendered(event) { + const { container, dates } = event.detail; + if (!container || !dates || dates.length === 0) { + return; + } + // Calculate startDate and endDate from dates array + const startDate = dates[0]; + const endDate = dates[dates.length - 1]; + this.renderEvents({ + container, + startDate, + endDate + }); + } + /** + * Handle VIEW_CHANGED event - clear and re-render for new view + */ + handleViewChanged(event) { + // Clear all existing events since view structure may have changed + this.clearEvents(); + // New rendering will be triggered by subsequent GRID_RENDERED event + } + /** + * Setup all drag event listeners - moved from EventRenderer for better separation of concerns + */ + setupDragEventListeners() { + this.setupDragStartListener(); + this.setupDragMoveListener(); + this.setupDragEndListener(); + this.setupDragColumnChangeListener(); + this.setupDragMouseLeaveHeaderListener(); + this.setupDragMouseEnterColumnListener(); + this.setupResizeEndListener(); + this.setupNavigationCompletedListener(); + } + setupDragStartListener() { + this.eventBus.on('drag:start', (event) => { + const dragStartPayload = event.detail; + if (dragStartPayload.originalElement.hasAttribute('data-allday')) { + return; + } + if (dragStartPayload.originalElement && this.strategy.handleDragStart && dragStartPayload.columnBounds) { + this.strategy.handleDragStart(dragStartPayload); + } + }); + } + setupDragMoveListener() { + this.eventBus.on('drag:move', (event) => { + let dragEvent = event.detail; + if (dragEvent.draggedClone.hasAttribute('data-allday')) { + return; + } + if (this.strategy.handleDragMove) { + this.strategy.handleDragMove(dragEvent); + } + }); + } + setupDragEndListener() { + this.eventBus.on('drag:end', async (event) => { + const { originalElement, draggedClone, originalSourceColumn, finalPosition, target } = event.detail; + const finalColumn = finalPosition.column; + const finalY = finalPosition.snappedY; + let element = draggedClone; + // Only handle day column drops for EventRenderer + if (target === 'swp-day-column' && finalColumn) { + if (originalElement && draggedClone && this.strategy.handleDragEnd) { + this.strategy.handleDragEnd(originalElement, draggedClone, finalColumn, finalY); + } + await this.eventManager.updateEvent(element.eventId, { + start: element.start, + end: element.end, + allDay: false + }); + // Re-render affected columns for stacking/grouping (now with updated data) + await this.reRenderAffectedColumns(originalSourceColumn, finalColumn); + } + }); + } + setupDragColumnChangeListener() { + this.eventBus.on('drag:column-change', (event) => { + let columnChangeEvent = event.detail; + // Filter: Only handle events where clone is NOT an all-day event (normal timed events) + if (columnChangeEvent.draggedClone && columnChangeEvent.draggedClone.hasAttribute('data-allday')) { + return; + } + if (this.strategy.handleColumnChange) { + this.strategy.handleColumnChange(columnChangeEvent); + } + }); + } + setupDragMouseLeaveHeaderListener() { + this.dragMouseLeaveHeaderListener = (event) => { + const { targetDate, mousePosition, originalElement, draggedClone: cloneElement } = event.detail; + if (cloneElement) + cloneElement.style.display = ''; + console.log('🚪 EventRendererManager: Received drag:mouseleave-header', { + targetDate, + originalElement: originalElement, + cloneElement: cloneElement + }); + }; + this.eventBus.on('drag:mouseleave-header', this.dragMouseLeaveHeaderListener); + } + setupDragMouseEnterColumnListener() { + this.eventBus.on('drag:mouseenter-column', (event) => { + const payload = event.detail; + // Only handle if clone is an all-day event + if (!payload.draggedClone.hasAttribute('data-allday')) { + return; + } + console.log('🎯 EventRendererManager: Received drag:mouseenter-column', { + targetColumn: payload.targetColumn, + snappedY: payload.snappedY, + calendarEvent: payload.calendarEvent + }); + // Delegate to strategy for conversion + if (this.strategy.handleConvertAllDayToTimed) { + this.strategy.handleConvertAllDayToTimed(payload); + } + }); + } + setupResizeEndListener() { + this.eventBus.on('resize:end', async (event) => { + const { eventId, element } = event.detail; + // Update event data in EventManager with new end time from resized element + const swpEvent = element; + const newStart = swpEvent.start; + const newEnd = swpEvent.end; + await this.eventManager.updateEvent(eventId, { + start: newStart, + end: newEnd + }); + console.log('📝 EventRendererManager: Updated event after resize', { + eventId, + newStart, + newEnd + }); + let columnBounds = ColumnDetectionUtils.getColumnBoundsByDate(newStart); + if (columnBounds) + await this.renderSingleColumn(columnBounds); + }); + } + setupNavigationCompletedListener() { + this.eventBus.on(CoreEvents.NAVIGATION_COMPLETED, () => { + // Delegate to strategy if it handles navigation + if (this.strategy.handleNavigationCompleted) { + this.strategy.handleNavigationCompleted(); + } + }); + } + /** + * Re-render affected columns after drag to recalculate stacking/grouping + */ + async reRenderAffectedColumns(originalSourceColumn, targetColumn) { + // Re-render original source column if exists + if (originalSourceColumn) { + await this.renderSingleColumn(originalSourceColumn); + } + // Re-render target column if exists and different from source + if (targetColumn && targetColumn.date !== originalSourceColumn?.date) { + await this.renderSingleColumn(targetColumn); + } + } + /** + * Clear events in a single column's events layer + */ + clearColumnEvents(eventsLayer) { + const existingEvents = eventsLayer.querySelectorAll('swp-event'); + const existingGroups = eventsLayer.querySelectorAll('swp-event-group'); + existingEvents.forEach(event => event.remove()); + existingGroups.forEach(group => group.remove()); + } + /** + * Render events for a single column + */ + async renderSingleColumn(column) { + // Get events for just this column's date + const columnStart = this.dateService.parseISO(`${column.date}T00:00:00`); + const columnEnd = this.dateService.parseISO(`${column.date}T23:59:59.999`); + // Get events from EventManager for this single date + const events = await this.eventManager.getEventsForPeriod(columnStart, columnEnd); + // Filter to timed events only + const timedEvents = events.filter(event => !event.allDay); + // Get events layer within this specific column + const eventsLayer = column.element.querySelector('swp-events-layer'); + if (!eventsLayer) { + console.warn('EventRendererManager: Events layer not found in column'); + return; + } + // Clear only this column's events + this.clearColumnEvents(eventsLayer); + // Render events for this column using strategy + if (this.strategy.renderSingleColumnEvents) { + this.strategy.renderSingleColumnEvents(column, timedEvents); + } + console.log('🔄 EventRendererManager: Re-rendered single column', { + columnDate: column.date, + eventsCount: timedEvents.length + }); + } + clearEvents(container) { + this.strategy.clearEvents(container); + } + refresh(container) { + this.clearEvents(container); + } +} +//# sourceMappingURL=EventRendererManager.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/EventRendererManager.js.map b/wwwroot/js/renderers/EventRendererManager.js.map new file mode 100644 index 0000000..d1cfc77 --- /dev/null +++ b/wwwroot/js/renderers/EventRendererManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventRendererManager.js","sourceRoot":"","sources":["../../../src/renderers/EventRendererManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/renderers/GridRenderer.d.ts b/wwwroot/js/renderers/GridRenderer.d.ts new file mode 100644 index 0000000..8613651 --- /dev/null +++ b/wwwroot/js/renderers/GridRenderer.d.ts @@ -0,0 +1,180 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { CalendarView, ICalendarEvent } from '../types/CalendarTypes'; +import { IColumnRenderer } from './ColumnRenderer'; +import { DateService } from '../utils/DateService'; +import { WorkHoursManager } from '../managers/WorkHoursManager'; +/** + * GridRenderer - Centralized DOM rendering for calendar grid structure + * + * ARCHITECTURE OVERVIEW: + * ===================== + * GridRenderer is responsible for creating and managing the complete DOM structure + * of the calendar grid. It follows the Strategy Pattern by delegating specific + * rendering tasks to specialized renderers (DateHeaderRenderer, ColumnRenderer). + * + * RESPONSIBILITY HIERARCHY: + * ======================== + * GridRenderer (this file) + * ├─ Creates overall grid skeleton + * ├─ Manages time axis (hour markers) + * └─ Delegates to specialized renderers: + * ├─ DateHeaderRenderer → Renders date headers + * └─ ColumnRenderer → Renders day columns + * + * DOM STRUCTURE CREATED: + * ===================== + * + * ← GridRenderer + * ← GridRenderer + * 00:00 ← GridRenderer (iterates hours) + * + * ← GridRenderer + * ← GridRenderer creates container + * ← DateHeaderRenderer (iterates dates) + * + * ← GridRenderer + * ← GridRenderer + * ← GridRenderer + * ← GridRenderer creates container + * ← ColumnRenderer (iterates dates) + * + * + * + * + * + * + * RENDERING FLOW: + * ============== + * 1. renderGrid() - Entry point called by GridManager + * ├─ First render: createCompleteGridStructure() + * └─ Updates: updateGridContent() + * + * 2. createCompleteGridStructure() + * ├─ Creates header spacer + * ├─ Creates time axis (calls createOptimizedTimeAxis) + * └─ Creates grid container (calls createOptimizedGridContainer) + * + * 3. createOptimizedGridContainer() + * ├─ Creates calendar header container + * ├─ Creates scrollable content structure + * └─ Creates column container (calls renderColumnContainer) + * + * 4. renderColumnContainer() + * └─ Delegates to ColumnRenderer.render() + * └─ ColumnRenderer iterates dates and creates columns + * + * OPTIMIZATION STRATEGY: + * ===================== + * - Caches DOM references (cachedGridContainer, cachedTimeAxis) + * - Uses DocumentFragment for batch DOM insertions + * - Only updates changed content on re-renders + * - Delegates specialized tasks to strategy renderers + * + * USAGE EXAMPLE: + * ============= + * const gridRenderer = new GridRenderer(columnRenderer, dateService, config); + * gridRenderer.renderGrid(containerElement, new Date(), 'week'); + */ +export declare class GridRenderer { + private cachedGridContainer; + private cachedTimeAxis; + private dateService; + private columnRenderer; + private config; + private workHoursManager; + constructor(columnRenderer: IColumnRenderer, dateService: DateService, config: Configuration, workHoursManager: WorkHoursManager); + /** + * Main entry point for rendering the complete calendar grid + * + * This method decides between full render (first time) or optimized update. + * It caches the grid reference for performance. + * + * @param grid - Container element where grid will be rendered + * @param currentDate - Base date for the current view (e.g., any date in the week) + * @param view - Calendar view type (day/week/month) + * @param dates - Array of dates to render as columns + * @param events - All events for the period + */ + renderGrid(grid: HTMLElement, currentDate: Date, view?: CalendarView, dates?: Date[], events?: ICalendarEvent[]): void; + /** + * Creates the complete grid structure from scratch + * + * Uses DocumentFragment for optimal performance by minimizing reflows. + * Creates all child elements in memory first, then appends everything at once. + * + * Structure created: + * 1. Header spacer (placeholder for alignment) + * 2. Time axis (hour markers 00:00-23:00) + * 3. Grid container (header + scrollable content) + * + * @param grid - Parent container + * @param currentDate - Current view date + * @param view - View type + * @param dates - Array of dates to render + */ + private createCompleteGridStructure; + /** + * Creates the time axis with hour markers + * + * Iterates from dayStartHour to dayEndHour (configured in GridSettings). + * Each marker shows the hour in the configured time format. + * + * @returns Time axis element with all hour markers + */ + private createOptimizedTimeAxis; + /** + * Creates the main grid container with header and columns + * + * This is the scrollable area containing: + * - Calendar header (dates/resources) - created here, populated by DateHeaderRenderer + * - Time grid (grid lines + day columns) - structure created here + * - Column container - created here, populated by ColumnRenderer + * + * @param currentDate - Current view date + * @param view - View type + * @param dates - Array of dates to render + * @returns Complete grid container element + */ + private createOptimizedGridContainer; + /** + * Renders columns by iterating through dates + * + * GridRenderer creates column structure with work hours styling. + * Event rendering is handled by EventRenderingService listening to GRID_RENDERED. + * + * @param columnContainer - Empty container to populate + * @param dates - Array of dates to render + * @param events - All events for the period (passed through, not used here) + */ + private renderColumnContainer; + /** + * Apply work hours styling to a column + */ + private applyWorkHoursStyling; + /** + * Optimized update of grid content without full rebuild + * + * Only updates the column container content, leaving the structure intact. + * This is much faster than recreating the entire grid. + * + * @param grid - Existing grid element + * @param currentDate - New view date + * @param view - View type + * @param dates - Array of dates to render + * @param events - All events for the period + */ + private updateGridContent; + /** + * Creates a new grid for slide animations during navigation + * + * Used by NavigationManager for smooth week-to-week transitions. + * Creates a complete grid positioned absolutely for animation. + * + * Note: Positioning is handled by Animation API, not here. + * + * @param parentContainer - Container for the new grid + * @param weekStart - Start date of the new week + * @returns New grid element ready for animation + */ + createNavigationGrid(parentContainer: HTMLElement, weekStart: Date): HTMLElement; +} diff --git a/wwwroot/js/renderers/GridRenderer.js b/wwwroot/js/renderers/GridRenderer.js new file mode 100644 index 0000000..0a3a7c9 --- /dev/null +++ b/wwwroot/js/renderers/GridRenderer.js @@ -0,0 +1,289 @@ +import { TimeFormatter } from '../utils/TimeFormatter'; +/** + * GridRenderer - Centralized DOM rendering for calendar grid structure + * + * ARCHITECTURE OVERVIEW: + * ===================== + * GridRenderer is responsible for creating and managing the complete DOM structure + * of the calendar grid. It follows the Strategy Pattern by delegating specific + * rendering tasks to specialized renderers (DateHeaderRenderer, ColumnRenderer). + * + * RESPONSIBILITY HIERARCHY: + * ======================== + * GridRenderer (this file) + * ├─ Creates overall grid skeleton + * ├─ Manages time axis (hour markers) + * └─ Delegates to specialized renderers: + * ├─ DateHeaderRenderer → Renders date headers + * └─ ColumnRenderer → Renders day columns + * + * DOM STRUCTURE CREATED: + * ===================== + * + * ← GridRenderer + * ← GridRenderer + * 00:00 ← GridRenderer (iterates hours) + * + * ← GridRenderer + * ← GridRenderer creates container + * ← DateHeaderRenderer (iterates dates) + * + * ← GridRenderer + * ← GridRenderer + * ← GridRenderer + * ← GridRenderer creates container + * ← ColumnRenderer (iterates dates) + * + * + * + * + * + * + * RENDERING FLOW: + * ============== + * 1. renderGrid() - Entry point called by GridManager + * ├─ First render: createCompleteGridStructure() + * └─ Updates: updateGridContent() + * + * 2. createCompleteGridStructure() + * ├─ Creates header spacer + * ├─ Creates time axis (calls createOptimizedTimeAxis) + * └─ Creates grid container (calls createOptimizedGridContainer) + * + * 3. createOptimizedGridContainer() + * ├─ Creates calendar header container + * ├─ Creates scrollable content structure + * └─ Creates column container (calls renderColumnContainer) + * + * 4. renderColumnContainer() + * └─ Delegates to ColumnRenderer.render() + * └─ ColumnRenderer iterates dates and creates columns + * + * OPTIMIZATION STRATEGY: + * ===================== + * - Caches DOM references (cachedGridContainer, cachedTimeAxis) + * - Uses DocumentFragment for batch DOM insertions + * - Only updates changed content on re-renders + * - Delegates specialized tasks to strategy renderers + * + * USAGE EXAMPLE: + * ============= + * const gridRenderer = new GridRenderer(columnRenderer, dateService, config); + * gridRenderer.renderGrid(containerElement, new Date(), 'week'); + */ +export class GridRenderer { + constructor(columnRenderer, dateService, config, workHoursManager) { + this.cachedGridContainer = null; + this.cachedTimeAxis = null; + this.dateService = dateService; + this.columnRenderer = columnRenderer; + this.config = config; + this.workHoursManager = workHoursManager; + } + /** + * Main entry point for rendering the complete calendar grid + * + * This method decides between full render (first time) or optimized update. + * It caches the grid reference for performance. + * + * @param grid - Container element where grid will be rendered + * @param currentDate - Base date for the current view (e.g., any date in the week) + * @param view - Calendar view type (day/week/month) + * @param dates - Array of dates to render as columns + * @param events - All events for the period + */ + renderGrid(grid, currentDate, view = 'week', dates = [], events = []) { + if (!grid || !currentDate) { + return; + } + // Cache grid reference for performance + this.cachedGridContainer = grid; + // Only clear and rebuild if grid is empty (first render) + if (grid.children.length === 0) { + this.createCompleteGridStructure(grid, currentDate, view, dates, events); + } + else { + // Optimized update - only refresh dynamic content + this.updateGridContent(grid, currentDate, view, dates, events); + } + } + /** + * Creates the complete grid structure from scratch + * + * Uses DocumentFragment for optimal performance by minimizing reflows. + * Creates all child elements in memory first, then appends everything at once. + * + * Structure created: + * 1. Header spacer (placeholder for alignment) + * 2. Time axis (hour markers 00:00-23:00) + * 3. Grid container (header + scrollable content) + * + * @param grid - Parent container + * @param currentDate - Current view date + * @param view - View type + * @param dates - Array of dates to render + */ + createCompleteGridStructure(grid, currentDate, view, dates, events) { + // Create all elements in memory first for better performance + const fragment = document.createDocumentFragment(); + // Create header spacer + const headerSpacer = document.createElement('swp-header-spacer'); + fragment.appendChild(headerSpacer); + // Create time axis with caching + const timeAxis = this.createOptimizedTimeAxis(); + this.cachedTimeAxis = timeAxis; + fragment.appendChild(timeAxis); + // Create grid container with caching + const gridContainer = this.createOptimizedGridContainer(currentDate, view, dates, events); + this.cachedGridContainer = gridContainer; + fragment.appendChild(gridContainer); + // Append all at once to minimize reflows + grid.appendChild(fragment); + } + /** + * Creates the time axis with hour markers + * + * Iterates from dayStartHour to dayEndHour (configured in GridSettings). + * Each marker shows the hour in the configured time format. + * + * @returns Time axis element with all hour markers + */ + createOptimizedTimeAxis() { + const timeAxis = document.createElement('swp-time-axis'); + const timeAxisContent = document.createElement('swp-time-axis-content'); + const gridSettings = this.config.gridSettings; + const startHour = gridSettings.dayStartHour; + const endHour = gridSettings.dayEndHour; + const fragment = document.createDocumentFragment(); + for (let hour = startHour; hour < endHour; hour++) { + const marker = document.createElement('swp-hour-marker'); + const date = new Date(2024, 0, 1, hour, 0); + marker.textContent = TimeFormatter.formatTime(date); + fragment.appendChild(marker); + } + timeAxisContent.appendChild(fragment); + timeAxisContent.style.top = '-1px'; + timeAxis.appendChild(timeAxisContent); + return timeAxis; + } + /** + * Creates the main grid container with header and columns + * + * This is the scrollable area containing: + * - Calendar header (dates/resources) - created here, populated by DateHeaderRenderer + * - Time grid (grid lines + day columns) - structure created here + * - Column container - created here, populated by ColumnRenderer + * + * @param currentDate - Current view date + * @param view - View type + * @param dates - Array of dates to render + * @returns Complete grid container element + */ + createOptimizedGridContainer(dates, events) { + const gridContainer = document.createElement('swp-grid-container'); + // Create calendar header as first child - always exists now! + const calendarHeader = document.createElement('swp-calendar-header'); + gridContainer.appendChild(calendarHeader); + // Create scrollable content structure + const scrollableContent = document.createElement('swp-scrollable-content'); + const timeGrid = document.createElement('swp-time-grid'); + // Add grid lines + const gridLines = document.createElement('swp-grid-lines'); + timeGrid.appendChild(gridLines); + // Create column container + const columnContainer = document.createElement('swp-day-columns'); + this.renderColumnContainer(columnContainer, dates, events); + timeGrid.appendChild(columnContainer); + scrollableContent.appendChild(timeGrid); + gridContainer.appendChild(scrollableContent); + return gridContainer; + } + /** + * Renders columns by iterating through dates + * + * GridRenderer creates column structure with work hours styling. + * Event rendering is handled by EventRenderingService listening to GRID_RENDERED. + * + * @param columnContainer - Empty container to populate + * @param dates - Array of dates to render + * @param events - All events for the period (passed through, not used here) + */ + renderColumnContainer(columnContainer, dates, events) { + // Iterate through dates and render each column structure + dates.forEach(date => { + // Create column with data-date attribute + const column = document.createElement('swp-day-column'); + column.dataset.date = this.dateService.formatISODate(date); + // Apply work hours styling + this.applyWorkHoursStyling(column, date); + // Add events layer (events will be rendered by EventRenderingService) + const eventsLayer = document.createElement('swp-events-layer'); + column.appendChild(eventsLayer); + columnContainer.appendChild(column); + }); + } + /** + * Apply work hours styling to a column + */ + applyWorkHoursStyling(column, date) { + const workHours = this.workHoursManager.getWorkHoursForDate(date); + if (workHours === 'off') { + column.setAttribute('data-day-off', 'true'); + } + else { + column.removeAttribute('data-day-off'); + // Calculate non-work hours overlay positions + const nonWorkStyle = this.workHoursManager.calculateNonWorkHoursStyle(workHours); + if (nonWorkStyle) { + column.style.setProperty('--before-work-height', `${nonWorkStyle.beforeWorkHeight}px`); + column.style.setProperty('--after-work-top', `${nonWorkStyle.afterWorkTop}px`); + } + } + } + /** + * Optimized update of grid content without full rebuild + * + * Only updates the column container content, leaving the structure intact. + * This is much faster than recreating the entire grid. + * + * @param grid - Existing grid element + * @param currentDate - New view date + * @param view - View type + * @param dates - Array of dates to render + * @param events - All events for the period + */ + updateGridContent(grid, currentDate, view, dates, events) { + // Update column container if needed + const columnContainer = grid.querySelector('swp-day-columns'); + if (columnContainer) { + columnContainer.innerHTML = ''; + this.renderColumnContainer(columnContainer, dates, events); + } + } + /** + * Creates a new grid for slide animations during navigation + * + * Used by NavigationManager for smooth week-to-week transitions. + * Creates a complete grid positioned absolutely for animation. + * + * Note: Positioning is handled by Animation API, not here. + * + * @param parentContainer - Container for the new grid + * @param weekStart - Start date of the new week + * @returns New grid element ready for animation + */ + createNavigationGrid(parentContainer, weekStart) { + // Use SAME method as initial load - respects workweek settings + const newGrid = this.createOptimizedGridContainer(weekStart, 'week'); + // Position new grid for animation - NO transform here, let Animation API handle it + newGrid.style.position = 'absolute'; + newGrid.style.top = '0'; + newGrid.style.left = '0'; + newGrid.style.width = '100%'; + newGrid.style.height = '100%'; + // Add to parent container + parentContainer.appendChild(newGrid); + return newGrid; + } +} +//# sourceMappingURL=GridRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/GridRenderer.js.map b/wwwroot/js/renderers/GridRenderer.js.map new file mode 100644 index 0000000..6e97412 --- /dev/null +++ b/wwwroot/js/renderers/GridRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GridRenderer.js","sourceRoot":"","sources":["../../../src/renderers/GridRenderer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/renderers/GridStyleManager.d.ts b/wwwroot/js/renderers/GridStyleManager.d.ts new file mode 100644 index 0000000..9bad858 --- /dev/null +++ b/wwwroot/js/renderers/GridStyleManager.d.ts @@ -0,0 +1,24 @@ +import { ResourceCalendarData } from '../types/CalendarTypes'; +/** + * GridStyleManager - Manages CSS variables and styling for the grid + * Separated from GridManager to follow Single Responsibility Principle + */ +export declare class GridStyleManager { + constructor(); + /** + * Update all grid CSS variables + */ + updateGridStyles(resourceData?: ResourceCalendarData | null): void; + /** + * Set time-related CSS variables + */ + private setTimeVariables; + /** + * Calculate number of columns based on calendar type and view + */ + private calculateColumnCount; + /** + * Set column width based on fitToWidth setting + */ + private setColumnWidth; +} diff --git a/wwwroot/js/renderers/GridStyleManager.js b/wwwroot/js/renderers/GridStyleManager.js new file mode 100644 index 0000000..c7485da --- /dev/null +++ b/wwwroot/js/renderers/GridStyleManager.js @@ -0,0 +1,76 @@ +import { calendarConfig } from '../core/CalendarConfig'; +/** + * GridStyleManager - Manages CSS variables and styling for the grid + * Separated from GridManager to follow Single Responsibility Principle + */ +export class GridStyleManager { + constructor() { + } + /** + * Update all grid CSS variables + */ + updateGridStyles(resourceData = null) { + const root = document.documentElement; + const gridSettings = calendarConfig.getGridSettings(); + const calendar = document.querySelector('swp-calendar'); + const calendarType = calendarConfig.getCalendarMode(); + // Set CSS variables for time and grid measurements + this.setTimeVariables(root, gridSettings); + // Set column count based on calendar type + const columnCount = this.calculateColumnCount(calendarType, resourceData); + root.style.setProperty('--grid-columns', columnCount.toString()); + // Set column width based on fitToWidth setting + this.setColumnWidth(root, gridSettings); + // Set fitToWidth data attribute for CSS targeting + if (calendar) { + calendar.setAttribute('data-fit-to-width', gridSettings.fitToWidth.toString()); + } + } + /** + * Set time-related CSS variables + */ + setTimeVariables(root, gridSettings) { + root.style.setProperty('--hour-height', `${gridSettings.hourHeight}px`); + root.style.setProperty('--minute-height', `${gridSettings.hourHeight / 60}px`); + root.style.setProperty('--snap-interval', gridSettings.snapInterval.toString()); + root.style.setProperty('--day-start-hour', gridSettings.dayStartHour.toString()); + root.style.setProperty('--day-end-hour', gridSettings.dayEndHour.toString()); + root.style.setProperty('--work-start-hour', gridSettings.workStartHour.toString()); + root.style.setProperty('--work-end-hour', gridSettings.workEndHour.toString()); + } + /** + * Calculate number of columns based on calendar type and view + */ + calculateColumnCount(calendarType, resourceData) { + if (calendarType === 'resource' && resourceData) { + return resourceData.resources.length; + } + else if (calendarType === 'date') { + const dateSettings = calendarConfig.getDateViewSettings(); + const workWeekSettings = calendarConfig.getWorkWeekSettings(); + switch (dateSettings.period) { + case 'day': + return 1; + case 'week': + return workWeekSettings.totalDays; + case 'month': + return workWeekSettings.totalDays; // Use work week for month view too + default: + return workWeekSettings.totalDays; + } + } + return calendarConfig.getWorkWeekSettings().totalDays; // Default to work week + } + /** + * Set column width based on fitToWidth setting + */ + setColumnWidth(root, gridSettings) { + if (gridSettings.fitToWidth) { + root.style.setProperty('--day-column-min-width', '50px'); // Small min-width allows columns to fit available space + } + else { + root.style.setProperty('--day-column-min-width', '250px'); // Default min-width for horizontal scroll mode + } + } +} +//# sourceMappingURL=GridStyleManager.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/GridStyleManager.js.map b/wwwroot/js/renderers/GridStyleManager.js.map new file mode 100644 index 0000000..f3d9366 --- /dev/null +++ b/wwwroot/js/renderers/GridStyleManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"GridStyleManager.js","sourceRoot":"","sources":["../../../src/renderers/GridStyleManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/renderers/HeaderRenderer.d.ts b/wwwroot/js/renderers/HeaderRenderer.d.ts new file mode 100644 index 0000000..50d0c7b --- /dev/null +++ b/wwwroot/js/renderers/HeaderRenderer.d.ts @@ -0,0 +1,29 @@ +import { CalendarConfig } from '../core/CalendarConfig'; +import { ResourceCalendarData } from '../types/CalendarTypes'; +/** + * Interface for header rendering strategies + */ +export interface HeaderRenderer { + render(calendarHeader: HTMLElement, context: HeaderRenderContext): void; +} +/** + * Context for header rendering + */ +export interface HeaderRenderContext { + currentWeek: Date; + config: CalendarConfig; + resourceData?: ResourceCalendarData | null; +} +/** + * Date-based header renderer (original functionality) + */ +export declare class DateHeaderRenderer implements HeaderRenderer { + private dateService; + render(calendarHeader: HTMLElement, context: HeaderRenderContext): void; +} +/** + * Resource-based header renderer + */ +export declare class ResourceHeaderRenderer implements HeaderRenderer { + render(calendarHeader: HTMLElement, context: HeaderRenderContext): void; +} diff --git a/wwwroot/js/renderers/HeaderRenderer.js b/wwwroot/js/renderers/HeaderRenderer.js new file mode 100644 index 0000000..0acbb43 --- /dev/null +++ b/wwwroot/js/renderers/HeaderRenderer.js @@ -0,0 +1,56 @@ +// Header rendering strategy interface and implementations +import { DateCalculator } from '../utils/DateCalculator'; +/** + * Date-based header renderer (original functionality) + */ +export class DateHeaderRenderer { + render(calendarHeader, context) { + const { currentWeek, config } = context; + // FIRST: Always create all-day container as part of standard header structure + const allDayContainer = document.createElement('swp-allday-container'); + calendarHeader.appendChild(allDayContainer); + // Initialize date calculator with config + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); + const dates = DateCalculator.getWorkWeekDates(currentWeek); + const weekDays = config.getDateViewSettings().weekDays; + const daysToShow = dates.slice(0, weekDays); + daysToShow.forEach((date, index) => { + const header = document.createElement('swp-day-header'); + if (DateCalculator.isToday(date)) { + header.dataset.today = 'true'; + } + const dayName = DateCalculator.getDayName(date, 'short'); + header.innerHTML = ` + ${dayName} + ${date.getDate()} + `; + header.dataset.date = DateCalculator.formatISODate(date); + calendarHeader.appendChild(header); + }); + } +} +/** + * Resource-based header renderer + */ +export class ResourceHeaderRenderer { + render(calendarHeader, context) { + const { resourceData } = context; + if (!resourceData) { + return; + } + resourceData.resources.forEach((resource) => { + const header = document.createElement('swp-resource-header'); + header.setAttribute('data-resource', resource.name); + header.setAttribute('data-employee-id', resource.employeeId); + header.innerHTML = ` + + ${resource.displayName} + + ${resource.displayName} + `; + calendarHeader.appendChild(header); + }); + } +} +//# sourceMappingURL=HeaderRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/HeaderRenderer.js.map b/wwwroot/js/renderers/HeaderRenderer.js.map new file mode 100644 index 0000000..a5af7c0 --- /dev/null +++ b/wwwroot/js/renderers/HeaderRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"HeaderRenderer.js","sourceRoot":"","sources":["../../../src/renderers/HeaderRenderer.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAI1D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAmBzD;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAG7B,MAAM,CAAC,cAA2B,EAAE,OAA4B;QAC9D,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAExC,8EAA8E;QAC9E,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;QACvE,cAAc,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QAE5C,yCAAyC;QACzC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAE3C,MAAM,KAAK,GAAG,cAAc,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC,QAAQ,CAAC;QACvD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAE5C,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACxD,IAAI,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,MAAc,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;YACzC,CAAC;YAED,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAEzD,MAAM,CAAC,SAAS,GAAG;wBACD,OAAO;wBACP,IAAI,CAAC,OAAO,EAAE;OAC/B,CAAC;YACD,MAAc,CAAC,OAAO,CAAC,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAElE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACjC,MAAM,CAAC,cAA2B,EAAE,OAA4B;QAC9D,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;QAEjC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;YAC7D,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YAE7D,MAAM,CAAC,SAAS,GAAG;;sBAEH,QAAQ,CAAC,SAAS,UAAU,QAAQ,CAAC,WAAW;;6BAEzC,QAAQ,CAAC,WAAW;OAC1C,CAAC;YAEF,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/renderers/NavigationRenderer.d.ts b/wwwroot/js/renderers/NavigationRenderer.d.ts new file mode 100644 index 0000000..44b4b2d --- /dev/null +++ b/wwwroot/js/renderers/NavigationRenderer.d.ts @@ -0,0 +1,22 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { EventRenderingService } from './EventRendererManager'; +/** + * NavigationRenderer - Handles DOM rendering for navigation containers + * Separated from NavigationManager to follow Single Responsibility Principle + */ +export declare class NavigationRenderer { + private eventBus; + constructor(eventBus: IEventBus, eventRenderer: EventRenderingService); + /** + * Setup event listeners for DOM updates + */ + private setupEventListeners; + private updateWeekInfoInDOM; + /** + * Apply filter state to pre-rendered grids + */ + applyFilterToPreRenderedGrids(filterState: { + active: boolean; + matchingIds: string[]; + }): void; +} diff --git a/wwwroot/js/renderers/NavigationRenderer.js b/wwwroot/js/renderers/NavigationRenderer.js new file mode 100644 index 0000000..8b0382e --- /dev/null +++ b/wwwroot/js/renderers/NavigationRenderer.js @@ -0,0 +1,68 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * NavigationRenderer - Handles DOM rendering for navigation containers + * Separated from NavigationManager to follow Single Responsibility Principle + */ +export class NavigationRenderer { + constructor(eventBus, eventRenderer) { + this.eventBus = eventBus; + this.setupEventListeners(); + } + /** + * Setup event listeners for DOM updates + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.PERIOD_INFO_UPDATE, (event) => { + const customEvent = event; + const { weekNumber, dateRange } = customEvent.detail; + this.updateWeekInfoInDOM(weekNumber, dateRange); + }); + } + updateWeekInfoInDOM(weekNumber, dateRange) { + const weekNumberElement = document.querySelector('swp-week-number'); + const dateRangeElement = document.querySelector('swp-date-range'); + if (weekNumberElement) { + weekNumberElement.textContent = `Week ${weekNumber}`; + } + if (dateRangeElement) { + dateRangeElement.textContent = dateRange; + } + } + /** + * Apply filter state to pre-rendered grids + */ + applyFilterToPreRenderedGrids(filterState) { + // Find all grid containers (including pre-rendered ones) + const allGridContainers = document.querySelectorAll('swp-grid-container'); + allGridContainers.forEach(container => { + const eventsLayers = container.querySelectorAll('swp-events-layer'); + eventsLayers.forEach(layer => { + if (filterState.active) { + // Apply filter active state + layer.setAttribute('data-filter-active', 'true'); + // Mark matching events in this layer + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + const eventId = event.getAttribute('data-event-id'); + if (eventId && filterState.matchingIds.includes(eventId)) { + event.setAttribute('data-matches', 'true'); + } + else { + event.removeAttribute('data-matches'); + } + }); + } + else { + // Remove filter state + layer.removeAttribute('data-filter-active'); + // Remove all match attributes + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + event.removeAttribute('data-matches'); + }); + } + }); + }); + } +} +//# sourceMappingURL=NavigationRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/NavigationRenderer.js.map b/wwwroot/js/renderers/NavigationRenderer.js.map new file mode 100644 index 0000000..84751b8 --- /dev/null +++ b/wwwroot/js/renderers/NavigationRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"NavigationRenderer.js","sourceRoot":"","sources":["../../../src/renderers/NavigationRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD;;;GAGG;AAEH,MAAM,OAAO,kBAAkB;IAG7B,YAAY,QAAmB,EAAE,aAAoC;QACnE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAID;;OAEG;IACK,mBAAmB;QACzB,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,KAAY,EAAE,EAAE;YAC/D,MAAM,WAAW,GAAG,KAAoB,CAAC;YACzC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC;YACrD,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAGO,mBAAmB,CAAC,UAAkB,EAAE,SAAiB;QAE/D,MAAM,iBAAiB,GAAG,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACpE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAElE,IAAI,iBAAiB,EAAE,CAAC;YACtB,iBAAiB,CAAC,WAAW,GAAG,QAAQ,UAAU,EAAE,CAAC;QACvD,CAAC;QAED,IAAI,gBAAgB,EAAE,CAAC;YACrB,gBAAgB,CAAC,WAAW,GAAG,SAAS,CAAC;QAC3C,CAAC;IACH,CAAC;IAED;;OAEG;IACI,6BAA6B,CAAC,WAAuD;QAC1F,yDAAyD;QACzD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;QAE1E,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YACpC,MAAM,YAAY,GAAG,SAAS,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;YAEpE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBAC3B,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;oBACvB,4BAA4B;oBAC5B,KAAK,CAAC,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;oBAEjD,qCAAqC;oBACrC,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;oBACnD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;wBACrB,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;wBACpD,IAAI,OAAO,IAAI,WAAW,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;4BACzD,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;wBAC7C,CAAC;6BAAM,CAAC;4BACN,KAAK,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;wBACxC,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,sBAAsB;oBACtB,KAAK,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;oBAE5C,8BAA8B;oBAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;oBACnD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;wBACrB,KAAK,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;oBACxC,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAEF"} \ No newline at end of file diff --git a/wwwroot/js/renderers/WeekInfoRenderer.d.ts b/wwwroot/js/renderers/WeekInfoRenderer.d.ts new file mode 100644 index 0000000..e244867 --- /dev/null +++ b/wwwroot/js/renderers/WeekInfoRenderer.d.ts @@ -0,0 +1,26 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { EventRenderingService } from './EventRendererManager'; +import { DateService } from '../utils/DateService'; +/** + * WeekInfoRenderer - Handles DOM rendering for week info display + * Updates swp-week-number and swp-date-range elements + * + * Renamed from NavigationRenderer to better reflect its actual responsibility + */ +export declare class WeekInfoRenderer { + private eventBus; + private dateService; + constructor(eventBus: IEventBus, eventRenderer: EventRenderingService, dateService: DateService); + /** + * Setup event listeners for DOM updates + */ + private setupEventListeners; + private updateWeekInfoInDOM; + /** + * Apply filter state to pre-rendered grids + */ + applyFilterToPreRenderedGrids(filterState: { + active: boolean; + matchingIds: string[]; + }): void; +} diff --git a/wwwroot/js/renderers/WeekInfoRenderer.js b/wwwroot/js/renderers/WeekInfoRenderer.js new file mode 100644 index 0000000..cb12aa4 --- /dev/null +++ b/wwwroot/js/renderers/WeekInfoRenderer.js @@ -0,0 +1,75 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * WeekInfoRenderer - Handles DOM rendering for week info display + * Updates swp-week-number and swp-date-range elements + * + * Renamed from NavigationRenderer to better reflect its actual responsibility + */ +export class WeekInfoRenderer { + constructor(eventBus, eventRenderer, dateService) { + this.eventBus = eventBus; + this.dateService = dateService; + this.setupEventListeners(); + } + /** + * Setup event listeners for DOM updates + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.NAVIGATION_COMPLETED, (event) => { + const customEvent = event; + const { newDate } = customEvent.detail; + // Calculate week number and date range from the new date + const weekNumber = this.dateService.getWeekNumber(newDate); + const weekEnd = this.dateService.addDays(newDate, 6); + const dateRange = this.dateService.formatDateRange(newDate, weekEnd); + this.updateWeekInfoInDOM(weekNumber, dateRange); + }); + } + updateWeekInfoInDOM(weekNumber, dateRange) { + const weekNumberElement = document.querySelector('swp-week-number'); + const dateRangeElement = document.querySelector('swp-date-range'); + if (weekNumberElement) { + weekNumberElement.textContent = `Week ${weekNumber}`; + } + if (dateRangeElement) { + dateRangeElement.textContent = dateRange; + } + } + /** + * Apply filter state to pre-rendered grids + */ + applyFilterToPreRenderedGrids(filterState) { + // Find all grid containers (including pre-rendered ones) + const allGridContainers = document.querySelectorAll('swp-grid-container'); + allGridContainers.forEach(container => { + const eventsLayers = container.querySelectorAll('swp-events-layer'); + eventsLayers.forEach(layer => { + if (filterState.active) { + // Apply filter active state + layer.setAttribute('data-filter-active', 'true'); + // Mark matching events in this layer + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + const eventId = event.getAttribute('data-event-id'); + if (eventId && filterState.matchingIds.includes(eventId)) { + event.setAttribute('data-matches', 'true'); + } + else { + event.removeAttribute('data-matches'); + } + }); + } + else { + // Remove filter state + layer.removeAttribute('data-filter-active'); + // Remove all match attributes + const events = layer.querySelectorAll('swp-event'); + events.forEach(event => { + event.removeAttribute('data-matches'); + }); + } + }); + }); + } +} +//# sourceMappingURL=WeekInfoRenderer.js.map \ No newline at end of file diff --git a/wwwroot/js/renderers/WeekInfoRenderer.js.map b/wwwroot/js/renderers/WeekInfoRenderer.js.map new file mode 100644 index 0000000..d83cb61 --- /dev/null +++ b/wwwroot/js/renderers/WeekInfoRenderer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WeekInfoRenderer.js","sourceRoot":"","sources":["../../../src/renderers/WeekInfoRenderer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/repositories/ApiEventRepository.d.ts b/wwwroot/js/repositories/ApiEventRepository.d.ts new file mode 100644 index 0000000..d7e087d --- /dev/null +++ b/wwwroot/js/repositories/ApiEventRepository.d.ts @@ -0,0 +1,39 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { Configuration } from '../configurations/CalendarConfig'; +/** + * ApiEventRepository + * Handles communication with backend API + * + * Used by SyncManager to send queued operations to the server + * NOT used directly by EventManager (which uses IndexedDBEventRepository) + * + * Future enhancements: + * - SignalR real-time updates + * - Conflict resolution + * - Batch operations + */ +export declare class ApiEventRepository { + private apiEndpoint; + constructor(config: Configuration); + /** + * Send create operation to API + */ + sendCreate(event: ICalendarEvent): Promise; + /** + * Send update operation to API + */ + sendUpdate(id: string, updates: Partial): Promise; + /** + * Send delete operation to API + */ + sendDelete(id: string): Promise; + /** + * Fetch all events from API + */ + fetchAll(): Promise; + /** + * Initialize SignalR connection + * Placeholder for future implementation + */ + initializeSignalR(): Promise; +} diff --git a/wwwroot/js/repositories/ApiEventRepository.js b/wwwroot/js/repositories/ApiEventRepository.js new file mode 100644 index 0000000..b732f80 --- /dev/null +++ b/wwwroot/js/repositories/ApiEventRepository.js @@ -0,0 +1,115 @@ +/** + * ApiEventRepository + * Handles communication with backend API + * + * Used by SyncManager to send queued operations to the server + * NOT used directly by EventManager (which uses IndexedDBEventRepository) + * + * Future enhancements: + * - SignalR real-time updates + * - Conflict resolution + * - Batch operations + */ +export class ApiEventRepository { + constructor(config) { + this.apiEndpoint = config.apiEndpoint; + } + /** + * Send create operation to API + */ + async sendCreate(event) { + // TODO: Implement API call + // const response = await fetch(`${this.apiEndpoint}/events`, { + // method: 'POST', + // headers: { 'Content-Type': 'application/json' }, + // body: JSON.stringify(event) + // }); + // + // if (!response.ok) { + // throw new Error(`API create failed: ${response.statusText}`); + // } + // + // return await response.json(); + throw new Error('ApiEventRepository.sendCreate not implemented yet'); + } + /** + * Send update operation to API + */ + async sendUpdate(id, updates) { + // TODO: Implement API call + // const response = await fetch(`${this.apiEndpoint}/events/${id}`, { + // method: 'PATCH', + // headers: { 'Content-Type': 'application/json' }, + // body: JSON.stringify(updates) + // }); + // + // if (!response.ok) { + // throw new Error(`API update failed: ${response.statusText}`); + // } + // + // return await response.json(); + throw new Error('ApiEventRepository.sendUpdate not implemented yet'); + } + /** + * Send delete operation to API + */ + async sendDelete(id) { + // TODO: Implement API call + // const response = await fetch(`${this.apiEndpoint}/events/${id}`, { + // method: 'DELETE' + // }); + // + // if (!response.ok) { + // throw new Error(`API delete failed: ${response.statusText}`); + // } + throw new Error('ApiEventRepository.sendDelete not implemented yet'); + } + /** + * Fetch all events from API + */ + async fetchAll() { + // TODO: Implement API call + // const response = await fetch(`${this.apiEndpoint}/events`); + // + // if (!response.ok) { + // throw new Error(`API fetch failed: ${response.statusText}`); + // } + // + // return await response.json(); + throw new Error('ApiEventRepository.fetchAll not implemented yet'); + } + // ======================================== + // Future: SignalR Integration + // ======================================== + /** + * Initialize SignalR connection + * Placeholder for future implementation + */ + async initializeSignalR() { + // TODO: Setup SignalR connection + // - Connect to hub + // - Register event handlers + // - Handle reconnection + // + // Example: + // const connection = new signalR.HubConnectionBuilder() + // .withUrl(`${this.apiEndpoint}/hubs/calendar`) + // .build(); + // + // connection.on('EventCreated', (event: ICalendarEvent) => { + // // Handle remote create + // }); + // + // connection.on('EventUpdated', (event: ICalendarEvent) => { + // // Handle remote update + // }); + // + // connection.on('EventDeleted', (eventId: string) => { + // // Handle remote delete + // }); + // + // await connection.start(); + throw new Error('SignalR not implemented yet'); + } +} +//# sourceMappingURL=ApiEventRepository.js.map \ No newline at end of file diff --git a/wwwroot/js/repositories/ApiEventRepository.js.map b/wwwroot/js/repositories/ApiEventRepository.js.map new file mode 100644 index 0000000..cf892a1 --- /dev/null +++ b/wwwroot/js/repositories/ApiEventRepository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ApiEventRepository.js","sourceRoot":"","sources":["../../../src/repositories/ApiEventRepository.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,kBAAkB;IAG7B,YAAY,MAAqB;QAC/B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,KAAqB;QACpC,2BAA2B;QAC3B,+DAA+D;QAC/D,oBAAoB;QACpB,qDAAqD;QACrD,gCAAgC;QAChC,MAAM;QACN,EAAE;QACF,sBAAsB;QACtB,kEAAkE;QAClE,IAAI;QACJ,EAAE;QACF,gCAAgC;QAEhC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,OAAgC;QAC3D,2BAA2B;QAC3B,qEAAqE;QACrE,qBAAqB;QACrB,qDAAqD;QACrD,kCAAkC;QAClC,MAAM;QACN,EAAE;QACF,sBAAsB;QACtB,kEAAkE;QAClE,IAAI;QACJ,EAAE;QACF,gCAAgC;QAEhC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,2BAA2B;QAC3B,qEAAqE;QACrE,qBAAqB;QACrB,MAAM;QACN,EAAE;QACF,sBAAsB;QACtB,kEAAkE;QAClE,IAAI;QAEJ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,2BAA2B;QAC3B,8DAA8D;QAC9D,EAAE;QACF,sBAAsB;QACtB,iEAAiE;QACjE,IAAI;QACJ,EAAE;QACF,gCAAgC;QAEhC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,2CAA2C;IAC3C,8BAA8B;IAC9B,2CAA2C;IAE3C;;;OAGG;IACH,KAAK,CAAC,iBAAiB;QACrB,iCAAiC;QACjC,mBAAmB;QACnB,4BAA4B;QAC5B,wBAAwB;QACxB,EAAE;QACF,WAAW;QACX,wDAAwD;QACxD,kDAAkD;QAClD,cAAc;QACd,EAAE;QACF,6DAA6D;QAC7D,4BAA4B;QAC5B,MAAM;QACN,EAAE;QACF,6DAA6D;QAC7D,4BAA4B;QAC5B,MAAM;QACN,EAAE;QACF,uDAAuD;QACvD,4BAA4B;QAC5B,MAAM;QACN,EAAE;QACF,4BAA4B;QAE5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/repositories/IEventRepository.d.ts b/wwwroot/js/repositories/IEventRepository.d.ts new file mode 100644 index 0000000..2bd6a5e --- /dev/null +++ b/wwwroot/js/repositories/IEventRepository.d.ts @@ -0,0 +1,51 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +/** + * Update source type + * - 'local': Changes made by the user locally (needs sync) + * - 'remote': Changes from API/SignalR (already synced) + */ +export type UpdateSource = 'local' | 'remote'; +/** + * IEventRepository - Interface for event data access + * + * Abstracts the data source for calendar events, allowing easy switching + * between IndexedDB, REST API, GraphQL, or other data sources. + * + * Implementations: + * - IndexedDBEventRepository: Local storage with offline support + * - MockEventRepository: (Legacy) Loads from local JSON file + * - ApiEventRepository: (Future) Loads from backend API + */ +export interface IEventRepository { + /** + * Load all calendar events from the data source + * @returns Promise resolving to array of ICalendarEvent objects + * @throws Error if loading fails + */ + loadEvents(): Promise; + /** + * Create a new event + * @param event - Event to create (without ID, will be generated) + * @param source - Source of the update ('local' or 'remote') + * @returns Promise resolving to the created event with generated ID + * @throws Error if creation fails + */ + createEvent(event: Omit, source?: UpdateSource): Promise; + /** + * Update an existing event + * @param id - ID of the event to update + * @param updates - Partial event data to update + * @param source - Source of the update ('local' or 'remote') + * @returns Promise resolving to the updated event + * @throws Error if update fails or event not found + */ + updateEvent(id: string, updates: Partial, source?: UpdateSource): Promise; + /** + * Delete an event + * @param id - ID of the event to delete + * @param source - Source of the update ('local' or 'remote') + * @returns Promise resolving when deletion is complete + * @throws Error if deletion fails or event not found + */ + deleteEvent(id: string, source?: UpdateSource): Promise; +} diff --git a/wwwroot/js/repositories/IEventRepository.js b/wwwroot/js/repositories/IEventRepository.js new file mode 100644 index 0000000..fd60757 --- /dev/null +++ b/wwwroot/js/repositories/IEventRepository.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=IEventRepository.js.map \ No newline at end of file diff --git a/wwwroot/js/repositories/IEventRepository.js.map b/wwwroot/js/repositories/IEventRepository.js.map new file mode 100644 index 0000000..fc02973 --- /dev/null +++ b/wwwroot/js/repositories/IEventRepository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"IEventRepository.js","sourceRoot":"","sources":["../../../src/repositories/IEventRepository.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/repositories/IndexedDBEventRepository.d.ts b/wwwroot/js/repositories/IndexedDBEventRepository.d.ts new file mode 100644 index 0000000..575264a --- /dev/null +++ b/wwwroot/js/repositories/IndexedDBEventRepository.d.ts @@ -0,0 +1,47 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { IEventRepository, UpdateSource } from './IEventRepository'; +import { IndexedDBService } from '../storage/IndexedDBService'; +import { OperationQueue } from '../storage/OperationQueue'; +/** + * IndexedDBEventRepository + * Offline-first repository using IndexedDB as single source of truth + * + * All CRUD operations: + * - Save to IndexedDB immediately (always succeeds) + * - Add to sync queue if source is 'local' + * - Background SyncManager processes queue to sync with API + */ +export declare class IndexedDBEventRepository implements IEventRepository { + private indexedDB; + private queue; + constructor(indexedDB: IndexedDBService, queue: OperationQueue); + /** + * Load all events from IndexedDB + * Ensures IndexedDB is initialized and seeded on first call + */ + loadEvents(): Promise; + /** + * Create a new event + * - Generates ID + * - Saves to IndexedDB + * - Adds to queue if local (needs sync) + */ + createEvent(event: Omit, source?: UpdateSource): Promise; + /** + * Update an existing event + * - Updates in IndexedDB + * - Adds to queue if local (needs sync) + */ + updateEvent(id: string, updates: Partial, source?: UpdateSource): Promise; + /** + * Delete an event + * - Removes from IndexedDB + * - Adds to queue if local (needs sync) + */ + deleteEvent(id: string, source?: UpdateSource): Promise; + /** + * Generate unique event ID + * Format: {timestamp}-{random} + */ + private generateEventId; +} diff --git a/wwwroot/js/repositories/IndexedDBEventRepository.js b/wwwroot/js/repositories/IndexedDBEventRepository.js new file mode 100644 index 0000000..c09245e --- /dev/null +++ b/wwwroot/js/repositories/IndexedDBEventRepository.js @@ -0,0 +1,127 @@ +/** + * IndexedDBEventRepository + * Offline-first repository using IndexedDB as single source of truth + * + * All CRUD operations: + * - Save to IndexedDB immediately (always succeeds) + * - Add to sync queue if source is 'local' + * - Background SyncManager processes queue to sync with API + */ +export class IndexedDBEventRepository { + constructor(indexedDB, queue) { + this.indexedDB = indexedDB; + this.queue = queue; + } + /** + * Load all events from IndexedDB + * Ensures IndexedDB is initialized and seeded on first call + */ + async loadEvents() { + // Lazy initialization on first data load + if (!this.indexedDB.isInitialized()) { + await this.indexedDB.initialize(); + await this.indexedDB.seedIfEmpty(); + } + return await this.indexedDB.getAllEvents(); + } + /** + * Create a new event + * - Generates ID + * - Saves to IndexedDB + * - Adds to queue if local (needs sync) + */ + async createEvent(event, source = 'local') { + // Generate unique ID + const id = this.generateEventId(); + // Determine sync status based on source + const syncStatus = source === 'local' ? 'pending' : 'synced'; + // Create full event object + const newEvent = { + ...event, + id, + syncStatus + }; + // Save to IndexedDB + await this.indexedDB.saveEvent(newEvent); + // If local change, add to sync queue + if (source === 'local') { + await this.queue.enqueue({ + type: 'create', + eventId: id, + data: newEvent, + timestamp: Date.now(), + retryCount: 0 + }); + } + return newEvent; + } + /** + * Update an existing event + * - Updates in IndexedDB + * - Adds to queue if local (needs sync) + */ + async updateEvent(id, updates, source = 'local') { + // Get existing event + const existingEvent = await this.indexedDB.getEvent(id); + if (!existingEvent) { + throw new Error(`Event with ID ${id} not found`); + } + // Determine sync status based on source + const syncStatus = source === 'local' ? 'pending' : 'synced'; + // Merge updates + const updatedEvent = { + ...existingEvent, + ...updates, + id, // Ensure ID doesn't change + syncStatus + }; + // Save to IndexedDB + await this.indexedDB.saveEvent(updatedEvent); + // If local change, add to sync queue + if (source === 'local') { + await this.queue.enqueue({ + type: 'update', + eventId: id, + data: updates, + timestamp: Date.now(), + retryCount: 0 + }); + } + return updatedEvent; + } + /** + * Delete an event + * - Removes from IndexedDB + * - Adds to queue if local (needs sync) + */ + async deleteEvent(id, source = 'local') { + // Check if event exists + const existingEvent = await this.indexedDB.getEvent(id); + if (!existingEvent) { + throw new Error(`Event with ID ${id} not found`); + } + // If local change, add to sync queue BEFORE deleting + // (so we can send the delete operation to API later) + if (source === 'local') { + await this.queue.enqueue({ + type: 'delete', + eventId: id, + data: {}, // No data needed for delete + timestamp: Date.now(), + retryCount: 0 + }); + } + // Delete from IndexedDB + await this.indexedDB.deleteEvent(id); + } + /** + * Generate unique event ID + * Format: {timestamp}-{random} + */ + generateEventId() { + const timestamp = Date.now(); + const random = Math.random().toString(36).substring(2, 9); + return `${timestamp}-${random}`; + } +} +//# sourceMappingURL=IndexedDBEventRepository.js.map \ No newline at end of file diff --git a/wwwroot/js/repositories/IndexedDBEventRepository.js.map b/wwwroot/js/repositories/IndexedDBEventRepository.js.map new file mode 100644 index 0000000..82835e7 --- /dev/null +++ b/wwwroot/js/repositories/IndexedDBEventRepository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"IndexedDBEventRepository.js","sourceRoot":"","sources":["../../../src/repositories/IndexedDBEventRepository.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/repositories/MockEventRepository.d.ts b/wwwroot/js/repositories/MockEventRepository.d.ts new file mode 100644 index 0000000..3e3d5cd --- /dev/null +++ b/wwwroot/js/repositories/MockEventRepository.d.ts @@ -0,0 +1,33 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +import { IEventRepository, UpdateSource } from './IEventRepository'; +/** + * MockEventRepository - Loads event data from local JSON file (LEGACY) + * + * This repository implementation fetches mock event data from a static JSON file. + * DEPRECATED: Use IndexedDBEventRepository for offline-first functionality. + * + * Data Source: data/mock-events.json + * + * NOTE: Create/Update/Delete operations are not supported - throws errors. + * This is intentional to encourage migration to IndexedDBEventRepository. + */ +export declare class MockEventRepository implements IEventRepository { + private readonly dataUrl; + loadEvents(): Promise; + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + createEvent(event: Omit, source?: UpdateSource): Promise; + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + updateEvent(id: string, updates: Partial, source?: UpdateSource): Promise; + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + deleteEvent(id: string, source?: UpdateSource): Promise; + private processCalendarData; +} diff --git a/wwwroot/js/repositories/MockEventRepository.js b/wwwroot/js/repositories/MockEventRepository.js new file mode 100644 index 0000000..e43f8cb --- /dev/null +++ b/wwwroot/js/repositories/MockEventRepository.js @@ -0,0 +1,62 @@ +/** + * MockEventRepository - Loads event data from local JSON file (LEGACY) + * + * This repository implementation fetches mock event data from a static JSON file. + * DEPRECATED: Use IndexedDBEventRepository for offline-first functionality. + * + * Data Source: data/mock-events.json + * + * NOTE: Create/Update/Delete operations are not supported - throws errors. + * This is intentional to encourage migration to IndexedDBEventRepository. + */ +export class MockEventRepository { + constructor() { + this.dataUrl = 'data/mock-events.json'; + } + async loadEvents() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock events: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processCalendarData(rawData); + } + catch (error) { + console.error('Failed to load event data:', error); + throw error; + } + } + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + async createEvent(event, source) { + throw new Error('MockEventRepository does not support createEvent. Use IndexedDBEventRepository instead.'); + } + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + async updateEvent(id, updates, source) { + throw new Error('MockEventRepository does not support updateEvent. Use IndexedDBEventRepository instead.'); + } + /** + * NOT SUPPORTED - MockEventRepository is read-only + * Use IndexedDBEventRepository instead + */ + async deleteEvent(id, source) { + throw new Error('MockEventRepository does not support deleteEvent. Use IndexedDBEventRepository instead.'); + } + processCalendarData(data) { + return data.map((event) => ({ + ...event, + start: new Date(event.start), + end: new Date(event.end), + type: event.type, + allDay: event.allDay || false, + syncStatus: 'synced' + })); + } +} +//# sourceMappingURL=MockEventRepository.js.map \ No newline at end of file diff --git a/wwwroot/js/repositories/MockEventRepository.js.map b/wwwroot/js/repositories/MockEventRepository.js.map new file mode 100644 index 0000000..f2909a6 --- /dev/null +++ b/wwwroot/js/repositories/MockEventRepository.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MockEventRepository.js","sourceRoot":"","sources":["../../../src/repositories/MockEventRepository.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACmB,YAAO,GAAG,uBAAuB,CAAC;IAqDrD,CAAC;IAnDQ,KAAK,CAAC,UAAU;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YAC3F,CAAC;YAED,MAAM,OAAO,GAAmB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEtD,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CAAC,KAAiC,EAAE,MAAqB;QAC/E,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC7G,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CAAC,EAAU,EAAE,OAAgC,EAAE,MAAqB;QAC1F,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC7G,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CAAC,EAAU,EAAE,MAAqB;QACxD,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAC;IAC7G,CAAC;IAEO,mBAAmB,CAAC,IAAoB;QAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAkB,EAAE,CAAC,CAAC;YAC1C,GAAG,KAAK;YACR,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAC5B,GAAG,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK;YAC7B,UAAU,EAAE,QAAiB;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/storage/IndexedDBService.d.ts b/wwwroot/js/storage/IndexedDBService.d.ts new file mode 100644 index 0000000..d40c72a --- /dev/null +++ b/wwwroot/js/storage/IndexedDBService.d.ts @@ -0,0 +1,97 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +/** + * Operation for the sync queue + */ +export interface IQueueOperation { + id: string; + type: 'create' | 'update' | 'delete'; + eventId: string; + data: Partial | ICalendarEvent; + timestamp: number; + retryCount: number; +} +/** + * IndexedDB Service for Calendar App + * Handles local storage of events and sync queue + */ +export declare class IndexedDBService { + private static readonly DB_NAME; + private static readonly DB_VERSION; + private static readonly EVENTS_STORE; + private static readonly QUEUE_STORE; + private static readonly SYNC_STATE_STORE; + private db; + private initialized; + /** + * Initialize and open the database + */ + initialize(): Promise; + /** + * Check if database is initialized + */ + isInitialized(): boolean; + /** + * Ensure database is initialized + */ + private ensureDB; + /** + * Get a single event by ID + */ + getEvent(id: string): Promise; + /** + * Get all events + */ + getAllEvents(): Promise; + /** + * Save an event (create or update) + */ + saveEvent(event: ICalendarEvent): Promise; + /** + * Delete an event + */ + deleteEvent(id: string): Promise; + /** + * Add operation to queue + */ + addToQueue(operation: Omit): Promise; + /** + * Get all queue operations (sorted by timestamp) + */ + getQueue(): Promise; + /** + * Remove operation from queue + */ + removeFromQueue(id: string): Promise; + /** + * Clear entire queue + */ + clearQueue(): Promise; + /** + * Save sync state value + */ + setSyncState(key: string, value: any): Promise; + /** + * Get sync state value + */ + getSyncState(key: string): Promise; + /** + * Serialize event for IndexedDB storage (convert Dates to ISO strings) + */ + private serializeEvent; + /** + * Deserialize event from IndexedDB (convert ISO strings to Dates) + */ + private deserializeEvent; + /** + * Close database connection + */ + close(): void; + /** + * Delete entire database (for testing/reset) + */ + static deleteDatabase(): Promise; + /** + * Seed IndexedDB with mock data if empty + */ + seedIfEmpty(mockDataUrl?: string): Promise; +} diff --git a/wwwroot/js/storage/IndexedDBService.js b/wwwroot/js/storage/IndexedDBService.js new file mode 100644 index 0000000..0f07270 --- /dev/null +++ b/wwwroot/js/storage/IndexedDBService.js @@ -0,0 +1,340 @@ +/** + * IndexedDB Service for Calendar App + * Handles local storage of events and sync queue + */ +export class IndexedDBService { + constructor() { + this.db = null; + this.initialized = false; + } + /** + * Initialize and open the database + */ + async initialize() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(IndexedDBService.DB_NAME, IndexedDBService.DB_VERSION); + request.onerror = () => { + reject(new Error(`Failed to open IndexedDB: ${request.error}`)); + }; + request.onsuccess = () => { + this.db = request.result; + this.initialized = true; + resolve(); + }; + request.onupgradeneeded = (event) => { + const db = event.target.result; + // Create events store + if (!db.objectStoreNames.contains(IndexedDBService.EVENTS_STORE)) { + const eventsStore = db.createObjectStore(IndexedDBService.EVENTS_STORE, { keyPath: 'id' }); + eventsStore.createIndex('start', 'start', { unique: false }); + eventsStore.createIndex('end', 'end', { unique: false }); + eventsStore.createIndex('syncStatus', 'syncStatus', { unique: false }); + } + // Create operation queue store + if (!db.objectStoreNames.contains(IndexedDBService.QUEUE_STORE)) { + const queueStore = db.createObjectStore(IndexedDBService.QUEUE_STORE, { keyPath: 'id' }); + queueStore.createIndex('timestamp', 'timestamp', { unique: false }); + } + // Create sync state store + if (!db.objectStoreNames.contains(IndexedDBService.SYNC_STATE_STORE)) { + db.createObjectStore(IndexedDBService.SYNC_STATE_STORE, { keyPath: 'key' }); + } + }; + }); + } + /** + * Check if database is initialized + */ + isInitialized() { + return this.initialized; + } + /** + * Ensure database is initialized + */ + ensureDB() { + if (!this.db) { + throw new Error('IndexedDB not initialized. Call initialize() first.'); + } + return this.db; + } + // ======================================== + // Event CRUD Operations + // ======================================== + /** + * Get a single event by ID + */ + async getEvent(id) { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readonly'); + const store = transaction.objectStore(IndexedDBService.EVENTS_STORE); + const request = store.get(id); + request.onsuccess = () => { + const event = request.result; + resolve(event ? this.deserializeEvent(event) : null); + }; + request.onerror = () => { + reject(new Error(`Failed to get event ${id}: ${request.error}`)); + }; + }); + } + /** + * Get all events + */ + async getAllEvents() { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readonly'); + const store = transaction.objectStore(IndexedDBService.EVENTS_STORE); + const request = store.getAll(); + request.onsuccess = () => { + const events = request.result; + resolve(events.map(e => this.deserializeEvent(e))); + }; + request.onerror = () => { + reject(new Error(`Failed to get all events: ${request.error}`)); + }; + }); + } + /** + * Save an event (create or update) + */ + async saveEvent(event) { + const db = this.ensureDB(); + const serialized = this.serializeEvent(event); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.EVENTS_STORE); + const request = store.put(serialized); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save event ${event.id}: ${request.error}`)); + }; + }); + } + /** + * Delete an event + */ + async deleteEvent(id) { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.EVENTS_STORE); + const request = store.delete(id); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to delete event ${id}: ${request.error}`)); + }; + }); + } + // ======================================== + // Queue Operations + // ======================================== + /** + * Add operation to queue + */ + async addToQueue(operation) { + const db = this.ensureDB(); + const queueItem = { + ...operation, + id: `${operation.type}-${operation.eventId}-${Date.now()}` + }; + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.QUEUE_STORE); + const request = store.put(queueItem); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to add to queue: ${request.error}`)); + }; + }); + } + /** + * Get all queue operations (sorted by timestamp) + */ + async getQueue() { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readonly'); + const store = transaction.objectStore(IndexedDBService.QUEUE_STORE); + const index = store.index('timestamp'); + const request = index.getAll(); + request.onsuccess = () => { + resolve(request.result); + }; + request.onerror = () => { + reject(new Error(`Failed to get queue: ${request.error}`)); + }; + }); + } + /** + * Remove operation from queue + */ + async removeFromQueue(id) { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.QUEUE_STORE); + const request = store.delete(id); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to remove from queue: ${request.error}`)); + }; + }); + } + /** + * Clear entire queue + */ + async clearQueue() { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.QUEUE_STORE); + const request = store.clear(); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to clear queue: ${request.error}`)); + }; + }); + } + // ======================================== + // Sync State Operations + // ======================================== + /** + * Save sync state value + */ + async setSyncState(key, value) { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.SYNC_STATE_STORE], 'readwrite'); + const store = transaction.objectStore(IndexedDBService.SYNC_STATE_STORE); + const request = store.put({ key, value }); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to set sync state ${key}: ${request.error}`)); + }; + }); + } + /** + * Get sync state value + */ + async getSyncState(key) { + const db = this.ensureDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction([IndexedDBService.SYNC_STATE_STORE], 'readonly'); + const store = transaction.objectStore(IndexedDBService.SYNC_STATE_STORE); + const request = store.get(key); + request.onsuccess = () => { + const result = request.result; + resolve(result ? result.value : null); + }; + request.onerror = () => { + reject(new Error(`Failed to get sync state ${key}: ${request.error}`)); + }; + }); + } + // ======================================== + // Serialization Helpers + // ======================================== + /** + * Serialize event for IndexedDB storage (convert Dates to ISO strings) + */ + serializeEvent(event) { + return { + ...event, + start: event.start instanceof Date ? event.start.toISOString() : event.start, + end: event.end instanceof Date ? event.end.toISOString() : event.end + }; + } + /** + * Deserialize event from IndexedDB (convert ISO strings to Dates) + */ + deserializeEvent(event) { + return { + ...event, + start: typeof event.start === 'string' ? new Date(event.start) : event.start, + end: typeof event.end === 'string' ? new Date(event.end) : event.end + }; + } + /** + * Close database connection + */ + close() { + if (this.db) { + this.db.close(); + this.db = null; + } + } + /** + * Delete entire database (for testing/reset) + */ + static async deleteDatabase() { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(IndexedDBService.DB_NAME); + request.onsuccess = () => { + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to delete database: ${request.error}`)); + }; + }); + } + /** + * Seed IndexedDB with mock data if empty + */ + async seedIfEmpty(mockDataUrl = 'data/mock-events.json') { + try { + const existingEvents = await this.getAllEvents(); + if (existingEvents.length > 0) { + console.log(`IndexedDB already has ${existingEvents.length} events - skipping seed`); + return; + } + console.log('IndexedDB is empty - seeding with mock data'); + // Check if online to fetch mock data + if (!navigator.onLine) { + console.warn('Offline and IndexedDB empty - starting with no events'); + return; + } + // Fetch mock events + const response = await fetch(mockDataUrl); + if (!response.ok) { + throw new Error(`Failed to fetch mock events: ${response.statusText}`); + } + const mockEvents = await response.json(); + // Convert and save to IndexedDB + for (const event of mockEvents) { + const calendarEvent = { + ...event, + start: new Date(event.start), + end: new Date(event.end), + allDay: event.allDay || false, + syncStatus: 'synced' + }; + await this.saveEvent(calendarEvent); + } + console.log(`Seeded IndexedDB with ${mockEvents.length} mock events`); + } + catch (error) { + console.error('Failed to seed IndexedDB:', error); + // Don't throw - allow app to start with empty calendar + } + } +} +IndexedDBService.DB_NAME = 'CalendarDB'; +IndexedDBService.DB_VERSION = 1; +IndexedDBService.EVENTS_STORE = 'events'; +IndexedDBService.QUEUE_STORE = 'operationQueue'; +IndexedDBService.SYNC_STATE_STORE = 'syncState'; +//# sourceMappingURL=IndexedDBService.js.map \ No newline at end of file diff --git a/wwwroot/js/storage/IndexedDBService.js.map b/wwwroot/js/storage/IndexedDBService.js.map new file mode 100644 index 0000000..488a2dd --- /dev/null +++ b/wwwroot/js/storage/IndexedDBService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"IndexedDBService.js","sourceRoot":"","sources":["../../../src/storage/IndexedDBService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/storage/OperationQueue.d.ts b/wwwroot/js/storage/OperationQueue.d.ts new file mode 100644 index 0000000..50018e6 --- /dev/null +++ b/wwwroot/js/storage/OperationQueue.d.ts @@ -0,0 +1,55 @@ +import { IndexedDBService, IQueueOperation } from './IndexedDBService'; +/** + * Operation Queue Manager + * Handles FIFO queue of pending sync operations + */ +export declare class OperationQueue { + private indexedDB; + constructor(indexedDB: IndexedDBService); + /** + * Add operation to the end of the queue + */ + enqueue(operation: Omit): Promise; + /** + * Get the first operation from the queue (without removing it) + * Returns null if queue is empty + */ + peek(): Promise; + /** + * Get all operations in the queue (sorted by timestamp FIFO) + */ + getAll(): Promise; + /** + * Remove a specific operation from the queue + */ + remove(operationId: string): Promise; + /** + * Remove the first operation from the queue and return it + * Returns null if queue is empty + */ + dequeue(): Promise; + /** + * Clear all operations from the queue + */ + clear(): Promise; + /** + * Get the number of operations in the queue + */ + size(): Promise; + /** + * Check if queue is empty + */ + isEmpty(): Promise; + /** + * Get operations for a specific event ID + */ + getOperationsForEvent(eventId: string): Promise; + /** + * Remove all operations for a specific event ID + */ + removeOperationsForEvent(eventId: string): Promise; + /** + * Update retry count for an operation + */ + incrementRetryCount(operationId: string): Promise; +} diff --git a/wwwroot/js/storage/OperationQueue.js b/wwwroot/js/storage/OperationQueue.js new file mode 100644 index 0000000..eb1b740 --- /dev/null +++ b/wwwroot/js/storage/OperationQueue.js @@ -0,0 +1,96 @@ +/** + * Operation Queue Manager + * Handles FIFO queue of pending sync operations + */ +export class OperationQueue { + constructor(indexedDB) { + this.indexedDB = indexedDB; + } + /** + * Add operation to the end of the queue + */ + async enqueue(operation) { + await this.indexedDB.addToQueue(operation); + } + /** + * Get the first operation from the queue (without removing it) + * Returns null if queue is empty + */ + async peek() { + const queue = await this.indexedDB.getQueue(); + return queue.length > 0 ? queue[0] : null; + } + /** + * Get all operations in the queue (sorted by timestamp FIFO) + */ + async getAll() { + return await this.indexedDB.getQueue(); + } + /** + * Remove a specific operation from the queue + */ + async remove(operationId) { + await this.indexedDB.removeFromQueue(operationId); + } + /** + * Remove the first operation from the queue and return it + * Returns null if queue is empty + */ + async dequeue() { + const operation = await this.peek(); + if (operation) { + await this.remove(operation.id); + } + return operation; + } + /** + * Clear all operations from the queue + */ + async clear() { + await this.indexedDB.clearQueue(); + } + /** + * Get the number of operations in the queue + */ + async size() { + const queue = await this.getAll(); + return queue.length; + } + /** + * Check if queue is empty + */ + async isEmpty() { + const size = await this.size(); + return size === 0; + } + /** + * Get operations for a specific event ID + */ + async getOperationsForEvent(eventId) { + const queue = await this.getAll(); + return queue.filter(op => op.eventId === eventId); + } + /** + * Remove all operations for a specific event ID + */ + async removeOperationsForEvent(eventId) { + const operations = await this.getOperationsForEvent(eventId); + for (const op of operations) { + await this.remove(op.id); + } + } + /** + * Update retry count for an operation + */ + async incrementRetryCount(operationId) { + const queue = await this.getAll(); + const operation = queue.find(op => op.id === operationId); + if (operation) { + operation.retryCount++; + // Re-add to queue with updated retry count + await this.remove(operationId); + await this.enqueue(operation); + } + } +} +//# sourceMappingURL=OperationQueue.js.map \ No newline at end of file diff --git a/wwwroot/js/storage/OperationQueue.js.map b/wwwroot/js/storage/OperationQueue.js.map new file mode 100644 index 0000000..572a8ac --- /dev/null +++ b/wwwroot/js/storage/OperationQueue.js.map @@ -0,0 +1 @@ +{"version":3,"file":"OperationQueue.js","sourceRoot":"","sources":["../../../src/storage/OperationQueue.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,cAAc;IAGzB,YAAY,SAA2B;QACrC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,SAAsC;QAClD,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,WAAmB;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,IAAI,KAAK,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,OAAe;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAAC,OAAe;QAC5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC7D,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,WAAmB;QAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;QAE1D,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,UAAU,EAAE,CAAC;YACvB,2CAA2C;YAC3C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/strategies/MonthViewStrategy.d.ts b/wwwroot/js/strategies/MonthViewStrategy.d.ts new file mode 100644 index 0000000..3e782fb --- /dev/null +++ b/wwwroot/js/strategies/MonthViewStrategy.d.ts @@ -0,0 +1,25 @@ +/** + * MonthViewStrategy - Strategy for month view rendering + * Completely different from week view - no time axis, cell-based events + */ +import { ViewStrategy, ViewContext, ViewLayoutConfig } from './ViewStrategy'; +export declare class MonthViewStrategy implements ViewStrategy { + private dateCalculator; + constructor(); + getLayoutConfig(): ViewLayoutConfig; + renderGrid(context: ViewContext): void; + private createMonthGrid; + private createDayHeaders; + private createDayCells; + private getMonthDates; + private renderMonthEvents; + getNextPeriod(currentDate: Date): Date; + getPreviousPeriod(currentDate: Date): Date; + getPeriodLabel(date: Date): string; + getDisplayDates(baseDate: Date): Date[]; + getPeriodRange(baseDate: Date): { + startDate: Date; + endDate: Date; + }; + destroy(): void; +} diff --git a/wwwroot/js/strategies/MonthViewStrategy.js b/wwwroot/js/strategies/MonthViewStrategy.js new file mode 100644 index 0000000..670878d --- /dev/null +++ b/wwwroot/js/strategies/MonthViewStrategy.js @@ -0,0 +1,124 @@ +/** + * MonthViewStrategy - Strategy for month view rendering + * Completely different from week view - no time axis, cell-based events + */ +import { DateCalculator } from '../utils/DateCalculator'; +import { calendarConfig } from '../core/CalendarConfig'; +export class MonthViewStrategy { + constructor() { + DateCalculator.initialize(calendarConfig); + this.dateCalculator = new DateCalculator(); + } + getLayoutConfig() { + return { + needsTimeAxis: false, // No time axis in month view! + columnCount: 7, // Always 7 days (Mon-Sun) + scrollable: false, // Month fits in viewport + eventPositioning: 'cell-based' // Events go in day cells + }; + } + renderGrid(context) { + // Clear existing content + context.container.innerHTML = ''; + // Create month grid (completely different from week!) + this.createMonthGrid(context); + } + createMonthGrid(context) { + const monthGrid = document.createElement('div'); + monthGrid.className = 'month-grid'; + monthGrid.style.display = 'grid'; + monthGrid.style.gridTemplateColumns = 'repeat(7, 1fr)'; + monthGrid.style.gridTemplateRows = 'auto repeat(6, 1fr)'; + monthGrid.style.height = '100%'; + // Add day headers (Mon, Tue, Wed, etc.) + this.createDayHeaders(monthGrid); + // Add 6 weeks of day cells + this.createDayCells(monthGrid, context.currentDate); + // Render events in day cells (will be handled by EventRendererManager) + // this.renderMonthEvents(monthGrid, context.allDayEvents); + context.container.appendChild(monthGrid); + } + createDayHeaders(container) { + const dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; + dayNames.forEach(dayName => { + const header = document.createElement('div'); + header.className = 'month-day-header'; + header.textContent = dayName; + header.style.padding = '8px'; + header.style.fontWeight = 'bold'; + header.style.textAlign = 'center'; + header.style.borderBottom = '1px solid #e0e0e0'; + container.appendChild(header); + }); + } + createDayCells(container, monthDate) { + const dates = this.getMonthDates(monthDate); + dates.forEach(date => { + const cell = document.createElement('div'); + cell.className = 'month-day-cell'; + cell.dataset.date = DateCalculator.formatISODate(date); + cell.style.border = '1px solid #e0e0e0'; + cell.style.minHeight = '100px'; + cell.style.padding = '4px'; + cell.style.position = 'relative'; + // Day number + const dayNumber = document.createElement('div'); + dayNumber.className = 'month-day-number'; + dayNumber.textContent = date.getDate().toString(); + dayNumber.style.fontWeight = 'bold'; + dayNumber.style.marginBottom = '4px'; + // Check if today + if (DateCalculator.isToday(date)) { + dayNumber.style.color = '#1976d2'; + cell.style.backgroundColor = '#f5f5f5'; + } + cell.appendChild(dayNumber); + container.appendChild(cell); + }); + } + getMonthDates(monthDate) { + // Get first day of month + const firstOfMonth = new Date(monthDate.getFullYear(), monthDate.getMonth(), 1); + // Get Monday of the week containing first day + const startDate = DateCalculator.getISOWeekStart(firstOfMonth); + // Generate 42 days (6 weeks) + const dates = []; + for (let i = 0; i < 42; i++) { + dates.push(DateCalculator.addDays(startDate, i)); + } + return dates; + } + renderMonthEvents(container, events) { + // TODO: Implement month event rendering + // Events will be small blocks in day cells + } + getNextPeriod(currentDate) { + return new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1); + } + getPreviousPeriod(currentDate) { + return new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1); + } + getPeriodLabel(date) { + const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December']; + return `${monthNames[date.getMonth()]} ${date.getFullYear()}`; + } + getDisplayDates(baseDate) { + return this.getMonthDates(baseDate); + } + getPeriodRange(baseDate) { + // Month view shows events for the entire month grid (including partial weeks) + const firstOfMonth = new Date(baseDate.getFullYear(), baseDate.getMonth(), 1); + // Get Monday of the week containing first day + const startDate = DateCalculator.getISOWeekStart(firstOfMonth); + // End date is 41 days after start (42 total days) + const endDate = DateCalculator.addDays(startDate, 41); + return { + startDate, + endDate + }; + } + destroy() { + } +} +//# sourceMappingURL=MonthViewStrategy.js.map \ No newline at end of file diff --git a/wwwroot/js/strategies/MonthViewStrategy.js.map b/wwwroot/js/strategies/MonthViewStrategy.js.map new file mode 100644 index 0000000..04383f6 --- /dev/null +++ b/wwwroot/js/strategies/MonthViewStrategy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MonthViewStrategy.js","sourceRoot":"","sources":["../../../src/strategies/MonthViewStrategy.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/strategies/ViewStrategy.d.ts b/wwwroot/js/strategies/ViewStrategy.d.ts new file mode 100644 index 0000000..6ce1eee --- /dev/null +++ b/wwwroot/js/strategies/ViewStrategy.d.ts @@ -0,0 +1,58 @@ +/** + * ViewStrategy - Strategy pattern for different calendar view types + * Allows clean separation between week view, month view, day view etc. + */ +import { ResourceCalendarData } from '../types/CalendarTypes'; +/** + * Context object passed to strategy methods + */ +export interface ViewContext { + currentDate: Date; + container: HTMLElement; + resourceData: ResourceCalendarData | null; +} +/** + * Layout configuration specific to each view type + */ +export interface ViewLayoutConfig { + needsTimeAxis: boolean; + columnCount: number; + scrollable: boolean; + eventPositioning: 'time-based' | 'cell-based'; +} +/** + * Base strategy interface for all view types + */ +export interface ViewStrategy { + /** + * Get the layout configuration for this view + */ + getLayoutConfig(): ViewLayoutConfig; + /** + * Render the grid structure for this view + */ + renderGrid(context: ViewContext): void; + /** + * Calculate next period for navigation + */ + getNextPeriod(currentDate: Date): Date; + /** + * Calculate previous period for navigation + */ + getPreviousPeriod(currentDate: Date): Date; + /** + * Get display label for current period + */ + getPeriodLabel(date: Date): string; + /** + * Get the dates that should be displayed in this view + */ + getDisplayDates(baseDate: Date): Date[]; + /** + * Get the period start and end dates for event filtering + */ + getPeriodRange(baseDate: Date): { + startDate: Date; + endDate: Date; + }; +} diff --git a/wwwroot/js/strategies/ViewStrategy.js b/wwwroot/js/strategies/ViewStrategy.js new file mode 100644 index 0000000..6185c60 --- /dev/null +++ b/wwwroot/js/strategies/ViewStrategy.js @@ -0,0 +1,6 @@ +/** + * ViewStrategy - Strategy pattern for different calendar view types + * Allows clean separation between week view, month view, day view etc. + */ +export {}; +//# sourceMappingURL=ViewStrategy.js.map \ No newline at end of file diff --git a/wwwroot/js/strategies/ViewStrategy.js.map b/wwwroot/js/strategies/ViewStrategy.js.map new file mode 100644 index 0000000..e58f7ec --- /dev/null +++ b/wwwroot/js/strategies/ViewStrategy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ViewStrategy.js","sourceRoot":"","sources":["../../../src/strategies/ViewStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG"} \ No newline at end of file diff --git a/wwwroot/js/strategies/WeekViewStrategy.d.ts b/wwwroot/js/strategies/WeekViewStrategy.d.ts new file mode 100644 index 0000000..3307dfc --- /dev/null +++ b/wwwroot/js/strategies/WeekViewStrategy.d.ts @@ -0,0 +1,22 @@ +/** + * WeekViewStrategy - Strategy for week/day view rendering + * Extracts the time-based grid logic from GridManager + */ +import { ViewStrategy, ViewContext, ViewLayoutConfig } from './ViewStrategy'; +export declare class WeekViewStrategy implements ViewStrategy { + private dateCalculator; + private gridRenderer; + private styleManager; + constructor(); + getLayoutConfig(): ViewLayoutConfig; + renderGrid(context: ViewContext): void; + getNextPeriod(currentDate: Date): Date; + getPreviousPeriod(currentDate: Date): Date; + getPeriodLabel(date: Date): string; + getDisplayDates(baseDate: Date): Date[]; + getPeriodRange(baseDate: Date): { + startDate: Date; + endDate: Date; + }; + destroy(): void; +} diff --git a/wwwroot/js/strategies/WeekViewStrategy.js b/wwwroot/js/strategies/WeekViewStrategy.js new file mode 100644 index 0000000..d5130d9 --- /dev/null +++ b/wwwroot/js/strategies/WeekViewStrategy.js @@ -0,0 +1,57 @@ +/** + * WeekViewStrategy - Strategy for week/day view rendering + * Extracts the time-based grid logic from GridManager + */ +import { DateCalculator } from '../utils/DateCalculator'; +import { calendarConfig } from '../core/CalendarConfig'; +import { GridRenderer } from '../renderers/GridRenderer'; +import { GridStyleManager } from '../renderers/GridStyleManager'; +export class WeekViewStrategy { + constructor() { + DateCalculator.initialize(calendarConfig); + this.dateCalculator = new DateCalculator(); + this.gridRenderer = new GridRenderer(); + this.styleManager = new GridStyleManager(); + } + getLayoutConfig() { + return { + needsTimeAxis: true, + columnCount: calendarConfig.getWorkWeekSettings().totalDays, + scrollable: true, + eventPositioning: 'time-based' + }; + } + renderGrid(context) { + // Update grid styles + this.styleManager.updateGridStyles(context.resourceData); + // Render the grid structure (time axis + day columns) + this.gridRenderer.renderGrid(context.container, context.currentDate, context.resourceData); + } + getNextPeriod(currentDate) { + return DateCalculator.addWeeks(currentDate, 1); + } + getPreviousPeriod(currentDate) { + return DateCalculator.addWeeks(currentDate, -1); + } + getPeriodLabel(date) { + const weekStart = DateCalculator.getISOWeekStart(date); + const weekEnd = DateCalculator.addDays(weekStart, 6); + const weekNumber = DateCalculator.getWeekNumber(date); + return `Week ${weekNumber}: ${DateCalculator.formatDateRange(weekStart, weekEnd)}`; + } + getDisplayDates(baseDate) { + return DateCalculator.getWorkWeekDates(baseDate); + } + getPeriodRange(baseDate) { + const weekStart = DateCalculator.getISOWeekStart(baseDate); + const weekEnd = DateCalculator.addDays(weekStart, 6); + return { + startDate: weekStart, + endDate: weekEnd + }; + } + destroy() { + // Clean up any week-specific resources + } +} +//# sourceMappingURL=WeekViewStrategy.js.map \ No newline at end of file diff --git a/wwwroot/js/strategies/WeekViewStrategy.js.map b/wwwroot/js/strategies/WeekViewStrategy.js.map new file mode 100644 index 0000000..fff7d39 --- /dev/null +++ b/wwwroot/js/strategies/WeekViewStrategy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"WeekViewStrategy.js","sourceRoot":"","sources":["../../../src/strategies/WeekViewStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,MAAM,OAAO,gBAAgB;IAK3B;QACE,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,CAAC,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAC7C,CAAC;IAED,eAAe;QACb,OAAO;YACL,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,cAAc,CAAC,mBAAmB,EAAE,CAAC,SAAS;YAC3D,UAAU,EAAE,IAAI;YAChB,gBAAgB,EAAE,YAAY;SAC/B,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,OAAoB;QAC7B,qBAAqB;QACrB,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAEzD,sDAAsD;QACtD,IAAI,CAAC,YAAY,CAAC,UAAU,CAC1B,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,YAAY,CACrB,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,WAAiB;QAC7B,OAAO,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,iBAAiB,CAAC,WAAiB;QACjC,OAAO,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,cAAc,CAAC,IAAU;QACvB,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEtD,OAAO,QAAQ,UAAU,KAAK,cAAc,CAAC,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;IACrF,CAAC;IAED,eAAe,CAAC,QAAc;QAC5B,OAAO,cAAc,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED,cAAc,CAAC,QAAc;QAC3B,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAErD,OAAO;YACL,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,OAAO;SACjB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,uCAAuC;IACzC,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/types/CalendarTypes.d.ts b/wwwroot/js/types/CalendarTypes.d.ts new file mode 100644 index 0000000..d5efb9f --- /dev/null +++ b/wwwroot/js/types/CalendarTypes.d.ts @@ -0,0 +1,56 @@ +export type ViewPeriod = 'day' | 'week' | 'month'; +export type CalendarView = ViewPeriod; +export type SyncStatus = 'synced' | 'pending' | 'error'; +export interface IRenderContext { + container: HTMLElement; + startDate: Date; + endDate: Date; +} +export interface ICalendarEvent { + id: string; + title: string; + description?: string; + start: Date; + end: Date; + type: string; + allDay: boolean; + syncStatus: SyncStatus; + recurringId?: string; + metadata?: Record; +} +export interface ICalendarConfig { + scrollbarWidth: number; + scrollbarColor: string; + scrollbarTrackColor: string; + scrollbarHoverColor: string; + scrollbarBorderRadius: number; + allowDrag: boolean; + allowResize: boolean; + allowCreate: boolean; + apiEndpoint: string; + dateFormat: string; + timeFormat: string; + enableSearch: boolean; + enableTouch: boolean; + defaultEventDuration: number; + minEventDuration: number; + maxEventDuration: number; +} +export interface IEventLogEntry { + type: string; + detail: unknown; + timestamp: number; +} +export interface IListenerEntry { + eventType: string; + handler: EventListener; + options?: AddEventListenerOptions; +} +export interface IEventBus { + on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void; + once(eventType: string, handler: EventListener): () => void; + off(eventType: string, handler: EventListener): void; + emit(eventType: string, detail?: unknown): boolean; + getEventLog(eventType?: string): IEventLogEntry[]; + setDebug(enabled: boolean): void; +} diff --git a/wwwroot/js/types/CalendarTypes.js b/wwwroot/js/types/CalendarTypes.js new file mode 100644 index 0000000..a86177f --- /dev/null +++ b/wwwroot/js/types/CalendarTypes.js @@ -0,0 +1,3 @@ +// Calendar type definitions +export {}; +//# sourceMappingURL=CalendarTypes.js.map \ No newline at end of file diff --git a/wwwroot/js/types/CalendarTypes.js.map b/wwwroot/js/types/CalendarTypes.js.map new file mode 100644 index 0000000..6bb92ea --- /dev/null +++ b/wwwroot/js/types/CalendarTypes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"CalendarTypes.js","sourceRoot":"","sources":["../../../src/types/CalendarTypes.ts"],"names":[],"mappings":"AAAA,4BAA4B"} \ No newline at end of file diff --git a/wwwroot/js/types/ColumnDataSource.d.ts b/wwwroot/js/types/ColumnDataSource.d.ts new file mode 100644 index 0000000..269fc8e --- /dev/null +++ b/wwwroot/js/types/ColumnDataSource.d.ts @@ -0,0 +1,17 @@ +/** + * IColumnDataSource - Defines the contract for providing column data + * + * This interface abstracts away whether columns represent dates or resources, + * allowing the calendar to switch between date-based and resource-based views. + */ +export interface IColumnDataSource { + /** + * Get the list of column identifiers to render + * @returns Array of identifiers (dates or resource IDs) + */ + getColumns(): Date[]; + /** + * Get the type of columns this datasource provides + */ + getType(): 'date' | 'resource'; +} diff --git a/wwwroot/js/types/ColumnDataSource.js b/wwwroot/js/types/ColumnDataSource.js new file mode 100644 index 0000000..1fd57b8 --- /dev/null +++ b/wwwroot/js/types/ColumnDataSource.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=ColumnDataSource.js.map \ No newline at end of file diff --git a/wwwroot/js/types/ColumnDataSource.js.map b/wwwroot/js/types/ColumnDataSource.js.map new file mode 100644 index 0000000..2d1395f --- /dev/null +++ b/wwwroot/js/types/ColumnDataSource.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ColumnDataSource.js","sourceRoot":"","sources":["../../../src/types/ColumnDataSource.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/types/DragDropTypes.d.ts b/wwwroot/js/types/DragDropTypes.d.ts new file mode 100644 index 0000000..da16c45 --- /dev/null +++ b/wwwroot/js/types/DragDropTypes.d.ts @@ -0,0 +1,41 @@ +/** + * Type definitions for drag and drop functionality + */ +export interface IMousePosition { + x: number; + y: number; + clientX?: number; + clientY?: number; +} +export interface IDragOffset { + x: number; + y: number; + offsetX?: number; + offsetY?: number; +} +export interface IDragState { + isDragging: boolean; + draggedElement: HTMLElement | null; + draggedClone: HTMLElement | null; + eventId: string | null; + startColumn: string | null; + currentColumn: string | null; + mouseOffset: IDragOffset; +} +export interface IDragEndPosition { + column: string; + y: number; + snappedY: number; + time?: Date; +} +export interface IStackLinkData { + prev?: string; + next?: string; + isFirst?: boolean; + isLast?: boolean; +} +export interface IDragEventHandlers { + handleDragStart?(originalElement: HTMLElement, eventId: string, mouseOffset: IDragOffset, column: string): void; + handleDragMove?(eventId: string, snappedY: number, column: string, mouseOffset: IDragOffset): void; + handleDragEnd?(eventId: string, originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: string, finalY: number): void; +} diff --git a/wwwroot/js/types/DragDropTypes.js b/wwwroot/js/types/DragDropTypes.js new file mode 100644 index 0000000..d892616 --- /dev/null +++ b/wwwroot/js/types/DragDropTypes.js @@ -0,0 +1,5 @@ +/** + * Type definitions for drag and drop functionality + */ +export {}; +//# sourceMappingURL=DragDropTypes.js.map \ No newline at end of file diff --git a/wwwroot/js/types/DragDropTypes.js.map b/wwwroot/js/types/DragDropTypes.js.map new file mode 100644 index 0000000..2272daa --- /dev/null +++ b/wwwroot/js/types/DragDropTypes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DragDropTypes.js","sourceRoot":"","sources":["../../../src/types/DragDropTypes.ts"],"names":[],"mappings":"AAAA;;GAEG"} \ No newline at end of file diff --git a/wwwroot/js/types/EventPayloadMap.d.ts b/wwwroot/js/types/EventPayloadMap.d.ts new file mode 100644 index 0000000..d35b9d7 --- /dev/null +++ b/wwwroot/js/types/EventPayloadMap.d.ts @@ -0,0 +1,133 @@ +import { CalendarEvent, CalendarView } from './CalendarTypes'; +import { DragStartEventPayload, DragMoveEventPayload, DragEndEventPayload, DragMouseEnterHeaderEventPayload, DragMouseLeaveHeaderEventPayload, HeaderReadyEventPayload } from './EventTypes'; +import { CoreEvents } from '../constants/CoreEvents'; +/** + * Complete type mapping for all calendar events + * This enables type-safe event emission and handling + */ +export interface CalendarEventPayloadMap { + [CoreEvents.INITIALIZED]: { + initialized: boolean; + timestamp: number; + }; + [CoreEvents.READY]: undefined; + [CoreEvents.DESTROYED]: undefined; + [CoreEvents.VIEW_CHANGED]: { + view: CalendarView; + previousView?: CalendarView; + }; + [CoreEvents.VIEW_RENDERED]: { + view: CalendarView; + }; + [CoreEvents.WORKWEEK_CHANGED]: { + settings: unknown; + }; + [CoreEvents.DATE_CHANGED]: { + date: Date; + view?: CalendarView; + }; + [CoreEvents.NAVIGATION_COMPLETED]: { + direction: 'previous' | 'next' | 'today'; + }; + [CoreEvents.PERIOD_INFO_UPDATE]: { + label: string; + startDate: Date; + endDate: Date; + }; + [CoreEvents.NAVIGATE_TO_EVENT]: { + eventId: string; + }; + [CoreEvents.DATA_LOADING]: undefined; + [CoreEvents.DATA_LOADED]: { + events: CalendarEvent[]; + count: number; + }; + [CoreEvents.DATA_ERROR]: { + error: Error; + }; + [CoreEvents.EVENTS_FILTERED]: { + filteredEvents: CalendarEvent[]; + }; + [CoreEvents.GRID_RENDERED]: { + container: HTMLElement; + currentDate: Date; + startDate: Date; + endDate: Date; + columnCount: number; + }; + [CoreEvents.GRID_CLICKED]: { + column: string; + row: number; + }; + [CoreEvents.CELL_SELECTED]: { + cell: HTMLElement; + }; + [CoreEvents.EVENT_CREATED]: { + event: CalendarEvent; + }; + [CoreEvents.EVENT_UPDATED]: { + event: CalendarEvent; + previousData?: Partial; + }; + [CoreEvents.EVENT_DELETED]: { + eventId: string; + }; + [CoreEvents.EVENT_SELECTED]: { + eventId: string; + event?: CalendarEvent; + }; + [CoreEvents.ERROR]: { + error: Error; + context?: string; + }; + [CoreEvents.REFRESH_REQUESTED]: { + view?: CalendarView; + date?: Date; + }; + [CoreEvents.FILTER_CHANGED]: { + activeFilters: string[]; + visibleEvents: CalendarEvent[]; + }; + [CoreEvents.EVENTS_RENDERED]: { + eventCount: number; + }; + 'drag:start': DragStartEventPayload; + 'drag:move': DragMoveEventPayload; + 'drag:end': DragEndEventPayload; + 'drag:mouseenter-header': DragMouseEnterHeaderEventPayload; + 'drag:mouseleave-header': DragMouseLeaveHeaderEventPayload; + 'drag:cancelled': { + reason: string; + }; + 'header:ready': HeaderReadyEventPayload; + 'header:height-changed': { + height: number; + rowCount: number; + }; + 'allday:checkHeight': undefined; + 'allday:convert-to-allday': { + eventId: string; + element: HTMLElement; + }; + 'allday:convert-from-allday': { + eventId: string; + element: HTMLElement; + }; + 'scroll:sync': { + scrollTop: number; + source: string; + }; + 'scroll:to-hour': { + hour: number; + }; + 'filter:updated': { + activeFilters: string[]; + visibleEvents: CalendarEvent[]; + }; + 'filter:search': { + query: string; + results: CalendarEvent[]; + }; +} +export type EventPayload = CalendarEventPayloadMap[T]; +export declare function hasPayload(eventType: T, payload: unknown): payload is CalendarEventPayloadMap[T]; diff --git a/wwwroot/js/types/EventPayloadMap.js b/wwwroot/js/types/EventPayloadMap.js new file mode 100644 index 0000000..8738d5e --- /dev/null +++ b/wwwroot/js/types/EventPayloadMap.js @@ -0,0 +1,6 @@ +import { CoreEvents } from '../constants/CoreEvents'; +// Type guard to check if an event has a payload +export function hasPayload(eventType, payload) { + return payload !== undefined; +} +//# sourceMappingURL=EventPayloadMap.js.map \ No newline at end of file diff --git a/wwwroot/js/types/EventPayloadMap.js.map b/wwwroot/js/types/EventPayloadMap.js.map new file mode 100644 index 0000000..89f465c --- /dev/null +++ b/wwwroot/js/types/EventPayloadMap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventPayloadMap.js","sourceRoot":"","sources":["../../../src/types/EventPayloadMap.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAiKrD,gDAAgD;AAChD,MAAM,UAAU,UAAU,CACxB,SAAY,EACZ,OAAgB;IAEhB,OAAO,OAAO,KAAK,SAAS,CAAC;AAC/B,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/types/EventTypes.d.ts b/wwwroot/js/types/EventTypes.d.ts new file mode 100644 index 0000000..c99f970 --- /dev/null +++ b/wwwroot/js/types/EventTypes.d.ts @@ -0,0 +1,81 @@ +/** + * Type definitions for calendar events and drag operations + */ +import { IColumnBounds } from "../utils/ColumnDetectionUtils"; +import { ICalendarEvent } from "./CalendarTypes"; +/** + * Drag Event Payload Interfaces + * Type-safe interfaces for drag and drop events + */ +export interface IMousePosition { + x: number; + y: number; +} +export interface IDragStartEventPayload { + originalElement: HTMLElement; + draggedClone: HTMLElement | null; + mousePosition: IMousePosition; + mouseOffset: IMousePosition; + columnBounds: IColumnBounds | null; +} +export interface IDragMoveEventPayload { + originalElement: HTMLElement; + draggedClone: HTMLElement; + mousePosition: IMousePosition; + mouseOffset: IMousePosition; + columnBounds: IColumnBounds | null; + snappedY: number; +} +export interface IDragEndEventPayload { + originalElement: HTMLElement; + draggedClone: HTMLElement | null; + mousePosition: IMousePosition; + originalSourceColumn: IColumnBounds; + finalPosition: { + column: IColumnBounds | null; + snappedY: number; + }; + target: 'swp-day-column' | 'swp-day-header' | null; +} +export interface IDragMouseEnterHeaderEventPayload { + targetColumn: IColumnBounds; + mousePosition: IMousePosition; + originalElement: HTMLElement | null; + draggedClone: HTMLElement; + calendarEvent: ICalendarEvent; + replaceClone: (newClone: HTMLElement) => void; +} +export interface IDragMouseLeaveHeaderEventPayload { + targetDate: string | null; + mousePosition: IMousePosition; + originalElement: HTMLElement | null; + draggedClone: HTMLElement | null; +} +export interface IDragMouseEnterColumnEventPayload { + targetColumn: IColumnBounds; + mousePosition: IMousePosition; + snappedY: number; + originalElement: HTMLElement | null; + draggedClone: HTMLElement; + calendarEvent: ICalendarEvent; + replaceClone: (newClone: HTMLElement) => void; +} +export interface IDragColumnChangeEventPayload { + originalElement: HTMLElement; + draggedClone: HTMLElement; + previousColumn: IColumnBounds | null; + newColumn: IColumnBounds; + mousePosition: IMousePosition; +} +export interface IHeaderReadyEventPayload { + headerElements: IColumnBounds[]; +} +export interface IResizeEndEventPayload { + eventId: string; + element: HTMLElement; + finalHeight: number; +} +export interface INavButtonClickedEventPayload { + direction: 'next' | 'previous' | 'today'; + newDate: Date; +} diff --git a/wwwroot/js/types/EventTypes.js b/wwwroot/js/types/EventTypes.js new file mode 100644 index 0000000..db1af83 --- /dev/null +++ b/wwwroot/js/types/EventTypes.js @@ -0,0 +1,5 @@ +/** + * Type definitions for calendar events and drag operations + */ +export {}; +//# sourceMappingURL=EventTypes.js.map \ No newline at end of file diff --git a/wwwroot/js/types/EventTypes.js.map b/wwwroot/js/types/EventTypes.js.map new file mode 100644 index 0000000..30cdf68 --- /dev/null +++ b/wwwroot/js/types/EventTypes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventTypes.js","sourceRoot":"","sources":["../../../src/types/EventTypes.ts"],"names":[],"mappings":"AAAA;;GAEG"} \ No newline at end of file diff --git a/wwwroot/js/types/ManagerTypes.d.ts b/wwwroot/js/types/ManagerTypes.d.ts new file mode 100644 index 0000000..9af0be9 --- /dev/null +++ b/wwwroot/js/types/ManagerTypes.d.ts @@ -0,0 +1,59 @@ +import { ICalendarEvent, CalendarView } from './CalendarTypes'; +/** + * Complete type definition for all managers returned by ManagerFactory + */ +export interface ICalendarManagers { + eventManager: IEventManager; + eventRenderer: IEventRenderingService; + gridManager: IGridManager; + scrollManager: IScrollManager; + navigationManager: unknown; + viewManager: IViewManager; + calendarManager: ICalendarManager; + dragDropManager: unknown; + allDayManager: unknown; + resizeHandleManager: IResizeHandleManager; + edgeScrollManager: unknown; + dragHoverManager: unknown; + headerManager: unknown; +} +/** + * Base interface for managers with optional initialization and refresh + */ +interface IManager { + initialize?(): Promise | void; + refresh?(): void; +} +export interface IEventManager extends IManager { + loadData(): Promise; + getEvents(): ICalendarEvent[]; + getEventsForPeriod(startDate: Date, endDate: Date): ICalendarEvent[]; + navigateToEvent(eventId: string): boolean; +} +export interface IEventRenderingService extends IManager { +} +export interface IGridManager extends IManager { + render(): Promise; +} +export interface IScrollManager extends IManager { + scrollTo(scrollTop: number): void; + scrollToHour(hour: number): void; +} +export interface INavigationManager extends IManager { + [key: string]: unknown; +} +export interface IViewManager extends IManager { + getCurrentView?(): CalendarView; +} +export interface ICalendarManager extends IManager { + setView(view: CalendarView): void; + setCurrentDate(date: Date): void; +} +export interface IDragDropManager extends IManager { +} +export interface IAllDayManager extends IManager { + [key: string]: unknown; +} +export interface IResizeHandleManager extends IManager { +} +export {}; diff --git a/wwwroot/js/types/ManagerTypes.js b/wwwroot/js/types/ManagerTypes.js new file mode 100644 index 0000000..8e31fa0 --- /dev/null +++ b/wwwroot/js/types/ManagerTypes.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=ManagerTypes.js.map \ No newline at end of file diff --git a/wwwroot/js/types/ManagerTypes.js.map b/wwwroot/js/types/ManagerTypes.js.map new file mode 100644 index 0000000..a63646f --- /dev/null +++ b/wwwroot/js/types/ManagerTypes.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ManagerTypes.js","sourceRoot":"","sources":["../../../src/types/ManagerTypes.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/wwwroot/js/utils/AllDayLayoutEngine.d.ts b/wwwroot/js/utils/AllDayLayoutEngine.d.ts new file mode 100644 index 0000000..caff572 --- /dev/null +++ b/wwwroot/js/utils/AllDayLayoutEngine.d.ts @@ -0,0 +1,42 @@ +import { ICalendarEvent } from '../types/CalendarTypes'; +export interface IEventLayout { + calenderEvent: ICalendarEvent; + gridArea: string; + startColumn: number; + endColumn: number; + row: number; + columnSpan: number; +} +export declare class AllDayLayoutEngine { + private weekDates; + private tracks; + constructor(weekDates: string[]); + /** + * Calculate layout for all events using clean day-based logic + */ + calculateLayout(events: ICalendarEvent[]): IEventLayout[]; + /** + * Find available track for event spanning from startDay to endDay (0-based indices) + */ + private findAvailableTrack; + /** + * Check if track is available for the given day range (0-based indices) + */ + private isTrackAvailable; + /** + * Get start day index for event (1-based, 0 if not visible) + */ + private getEventStartDay; + /** + * Get end day index for event (1-based, 0 if not visible) + */ + private getEventEndDay; + /** + * Check if event is visible in the current date range + */ + private isEventVisible; + /** + * Format date to YYYY-MM-DD string using local date + */ + private formatDate; +} diff --git a/wwwroot/js/utils/AllDayLayoutEngine.js b/wwwroot/js/utils/AllDayLayoutEngine.js new file mode 100644 index 0000000..c939563 --- /dev/null +++ b/wwwroot/js/utils/AllDayLayoutEngine.js @@ -0,0 +1,108 @@ +export class AllDayLayoutEngine { + constructor(weekDates) { + this.weekDates = weekDates; + this.tracks = []; + } + /** + * Calculate layout for all events using clean day-based logic + */ + calculateLayout(events) { + let layouts = []; + // Reset tracks for new calculation + this.tracks = [new Array(this.weekDates.length).fill(false)]; + // Filter to only visible events + const visibleEvents = events.filter(event => this.isEventVisible(event)); + // Process events in input order (no sorting) + for (const event of visibleEvents) { + const startDay = this.getEventStartDay(event); + const endDay = this.getEventEndDay(event); + if (startDay > 0 && endDay > 0) { + const track = this.findAvailableTrack(startDay - 1, endDay - 1); // Convert to 0-based for tracks + // Mark days as occupied + for (let day = startDay - 1; day <= endDay - 1; day++) { + this.tracks[track][day] = true; + } + const layout = { + calenderEvent: event, + gridArea: `${track + 1} / ${startDay} / ${track + 2} / ${endDay + 1}`, + startColumn: startDay, + endColumn: endDay, + row: track + 1, + columnSpan: endDay - startDay + 1 + }; + layouts.push(layout); + } + } + return layouts; + } + /** + * Find available track for event spanning from startDay to endDay (0-based indices) + */ + findAvailableTrack(startDay, endDay) { + for (let trackIndex = 0; trackIndex < this.tracks.length; trackIndex++) { + if (this.isTrackAvailable(trackIndex, startDay, endDay)) { + return trackIndex; + } + } + // Create new track if none available + this.tracks.push(new Array(this.weekDates.length).fill(false)); + return this.tracks.length - 1; + } + /** + * Check if track is available for the given day range (0-based indices) + */ + isTrackAvailable(trackIndex, startDay, endDay) { + for (let day = startDay; day <= endDay; day++) { + if (this.tracks[trackIndex][day]) { + return false; + } + } + return true; + } + /** + * Get start day index for event (1-based, 0 if not visible) + */ + getEventStartDay(event) { + const eventStartDate = this.formatDate(event.start); + const firstVisibleDate = this.weekDates[0]; + // If event starts before visible range, clip to first visible day + const clippedStartDate = eventStartDate < firstVisibleDate ? firstVisibleDate : eventStartDate; + const dayIndex = this.weekDates.indexOf(clippedStartDate); + return dayIndex >= 0 ? dayIndex + 1 : 0; + } + /** + * Get end day index for event (1-based, 0 if not visible) + */ + getEventEndDay(event) { + const eventEndDate = this.formatDate(event.end); + const lastVisibleDate = this.weekDates[this.weekDates.length - 1]; + // If event ends after visible range, clip to last visible day + const clippedEndDate = eventEndDate > lastVisibleDate ? lastVisibleDate : eventEndDate; + const dayIndex = this.weekDates.indexOf(clippedEndDate); + return dayIndex >= 0 ? dayIndex + 1 : 0; + } + /** + * Check if event is visible in the current date range + */ + isEventVisible(event) { + if (this.weekDates.length === 0) + return false; + const eventStartDate = this.formatDate(event.start); + const eventEndDate = this.formatDate(event.end); + const firstVisibleDate = this.weekDates[0]; + const lastVisibleDate = this.weekDates[this.weekDates.length - 1]; + // Event overlaps if it doesn't end before visible range starts + // AND doesn't start after visible range ends + return !(eventEndDate < firstVisibleDate || eventStartDate > lastVisibleDate); + } + /** + * Format date to YYYY-MM-DD string using local date + */ + formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + } +} +//# sourceMappingURL=AllDayLayoutEngine.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/AllDayLayoutEngine.js.map b/wwwroot/js/utils/AllDayLayoutEngine.js.map new file mode 100644 index 0000000..a6d6e7b --- /dev/null +++ b/wwwroot/js/utils/AllDayLayoutEngine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AllDayLayoutEngine.js","sourceRoot":"","sources":["../../../src/utils/AllDayLayoutEngine.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/utils/ColumnDetectionUtils.d.ts b/wwwroot/js/utils/ColumnDetectionUtils.d.ts new file mode 100644 index 0000000..04e1552 --- /dev/null +++ b/wwwroot/js/utils/ColumnDetectionUtils.d.ts @@ -0,0 +1,30 @@ +/** + * ColumnDetectionUtils - Shared utility for column detection and caching + * Used by both DragDropManager and AllDayManager for consistent column detection + */ +import { IMousePosition } from "../types/DragDropTypes"; +export interface IColumnBounds { + date: string; + left: number; + right: number; + boundingClientRect: DOMRect; + element: HTMLElement; + index: number; +} +export declare class ColumnDetectionUtils { + private static columnBoundsCache; + /** + * Update column bounds cache for coordinate-based column detection + */ + static updateColumnBoundsCache(): void; + /** + * Get column date from X coordinate using cached bounds + */ + static getColumnBounds(position: IMousePosition): IColumnBounds | null; + /** + * Get column bounds by Date + */ + static getColumnBoundsByDate(date: Date): IColumnBounds | null; + static getColumns(): IColumnBounds[]; + static getHeaderColumns(): IColumnBounds[]; +} diff --git a/wwwroot/js/utils/ColumnDetectionUtils.js b/wwwroot/js/utils/ColumnDetectionUtils.js new file mode 100644 index 0000000..552638b --- /dev/null +++ b/wwwroot/js/utils/ColumnDetectionUtils.js @@ -0,0 +1,87 @@ +/** + * ColumnDetectionUtils - Shared utility for column detection and caching + * Used by both DragDropManager and AllDayManager for consistent column detection + */ +export class ColumnDetectionUtils { + /** + * Update column bounds cache for coordinate-based column detection + */ + static updateColumnBoundsCache() { + // Reset cache + this.columnBoundsCache = []; + // Find alle kolonner + const columns = document.querySelectorAll('swp-day-column'); + let index = 1; + // Cache hver kolonnes x-grænser + columns.forEach(column => { + const rect = column.getBoundingClientRect(); + const date = column.dataset.date; + if (date) { + this.columnBoundsCache.push({ + boundingClientRect: rect, + element: column, + date, + left: rect.left, + right: rect.right, + index: index++ + }); + } + }); + // Sorter efter x-position (fra venstre til højre) + this.columnBoundsCache.sort((a, b) => a.left - b.left); + } + /** + * Get column date from X coordinate using cached bounds + */ + static getColumnBounds(position) { + if (this.columnBoundsCache.length === 0) { + this.updateColumnBoundsCache(); + } + // Find den kolonne hvor x-koordinaten er indenfor grænserne + let column = this.columnBoundsCache.find(col => position.x >= col.left && position.x <= col.right); + if (column) + return column; + return null; + } + /** + * Get column bounds by Date + */ + static getColumnBoundsByDate(date) { + if (this.columnBoundsCache.length === 0) { + this.updateColumnBoundsCache(); + } + // Convert Date to YYYY-MM-DD format + let dateString = date.toISOString().split('T')[0]; + // Find column that matches the date + let column = this.columnBoundsCache.find(col => col.date === dateString); + return column || null; + } + static getColumns() { + return [...this.columnBoundsCache]; + } + static getHeaderColumns() { + let dayHeaders = []; + const dayColumns = document.querySelectorAll('swp-calendar-header swp-day-header'); + let index = 1; + // Cache hver kolonnes x-grænser + dayColumns.forEach(column => { + const rect = column.getBoundingClientRect(); + const date = column.dataset.date; + if (date) { + dayHeaders.push({ + boundingClientRect: rect, + element: column, + date, + left: rect.left, + right: rect.right, + index: index++ + }); + } + }); + // Sorter efter x-position (fra venstre til højre) + dayHeaders.sort((a, b) => a.left - b.left); + return dayHeaders; + } +} +ColumnDetectionUtils.columnBoundsCache = []; +//# sourceMappingURL=ColumnDetectionUtils.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/ColumnDetectionUtils.js.map b/wwwroot/js/utils/ColumnDetectionUtils.js.map new file mode 100644 index 0000000..21aeb66 --- /dev/null +++ b/wwwroot/js/utils/ColumnDetectionUtils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ColumnDetectionUtils.js","sourceRoot":"","sources":["../../../src/utils/ColumnDetectionUtils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/utils/DateCalculator.d.ts b/wwwroot/js/utils/DateCalculator.d.ts new file mode 100644 index 0000000..74e3a54 --- /dev/null +++ b/wwwroot/js/utils/DateCalculator.d.ts @@ -0,0 +1,149 @@ +/** + * DateCalculator - Centralized date calculation logic for calendar + * Handles all date computations with proper week start handling + */ +import { CalendarConfig } from '../core/CalendarConfig'; +export declare class DateCalculator { + private static config; + /** + * Initialize DateCalculator with configuration + * @param config - Calendar configuration + */ + static initialize(config: CalendarConfig): void; + /** + * Validate that a date is valid + * @param date - Date to validate + * @param methodName - Name of calling method for error messages + * @throws Error if date is invalid + */ + private static validateDate; + /** + * Get dates for work week using ISO 8601 day numbering (Monday=1, Sunday=7) + * @param weekStart - Any date in the week + * @returns Array of dates for the configured work days + */ + static getWorkWeekDates(weekStart: Date): Date[]; + /** + * Get the start of the ISO week (Monday) for a given date + * @param date - Any date in the week + * @returns The Monday of the ISO week + */ + static getISOWeekStart(date: Date): Date; + /** + * Get the end of the ISO week for a given date + * @param date - Any date in the week + * @returns The end date of the ISO week (Sunday) + */ + static getWeekEnd(date: Date): Date; + /** + * Get week number for a date (ISO 8601) + * @param date - The date to get week number for + * @returns Week number (1-53) + */ + static getWeekNumber(date: Date): number; + /** + * Format a date range with customizable options + * @param start - Start date + * @param end - End date + * @param options - Formatting options + * @returns Formatted date range string + */ + static formatDateRange(start: Date, end: Date, options?: { + locale?: string; + month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow'; + day?: 'numeric' | '2-digit'; + year?: 'numeric' | '2-digit'; + }): string; + /** + * Format a date to ISO date string (YYYY-MM-DD) + * @param date - Date to format + * @returns ISO date string + */ + static formatISODate(date: Date): string; + /** + * Check if a date is today + * @param date - Date to check + * @returns True if the date is today + */ + static isToday(date: Date): boolean; + /** + * Add days to a date + * @param date - Base date + * @param days - Number of days to add (can be negative) + * @returns New date + */ + static addDays(date: Date, days: number): Date; + /** + * Add weeks to a date + * @param date - Base date + * @param weeks - Number of weeks to add (can be negative) + * @returns New date + */ + static addWeeks(date: Date, weeks: number): Date; + /** + * Get all dates in a week + * @param weekStart - Start of the week + * @returns Array of 7 dates for the full week + */ + static getFullWeekDates(weekStart: Date): Date[]; + /** + * Get the day name for a date using Intl.DateTimeFormat + * @param date - Date to get day name for + * @param format - 'short' or 'long' + * @returns Day name + */ + static getDayName(date: Date, format?: 'short' | 'long'): string; + /** + * Format time to HH:MM + * @param date - Date to format + * @returns Time string + */ + static formatTime(date: Date): string; + /** + * Format time to 12-hour format + * @param date - Date to format + * @returns 12-hour time string + */ + static formatTime12(date: Date): string; + /** + * Convert minutes since midnight to time string + * @param minutes - Minutes since midnight + * @returns Time string + */ + static minutesToTime(minutes: number): string; + /** + * Convert time string to minutes since midnight + * @param timeStr - Time string + * @returns Minutes since midnight + */ + static timeToMinutes(timeStr: string): number; + /** + * Get minutes since start of day + * @param date - Date or ISO string + * @returns Minutes since midnight + */ + static getMinutesSinceMidnight(date: Date | string): number; + /** + * Calculate duration in minutes between two dates + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns Duration in minutes + */ + static getDurationMinutes(start: Date | string, end: Date | string): number; + /** + * Check if two dates are on the same day + * @param date1 - First date + * @param date2 - Second date + * @returns True if same day + */ + static isSameDay(date1: Date, date2: Date): boolean; + /** + * Check if event spans multiple days + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns True if spans multiple days + */ + static isMultiDay(start: Date | string, end: Date | string): boolean; + constructor(); +} +export declare function createDateCalculator(config: CalendarConfig): DateCalculator; diff --git a/wwwroot/js/utils/DateCalculator.js b/wwwroot/js/utils/DateCalculator.js new file mode 100644 index 0000000..4941202 --- /dev/null +++ b/wwwroot/js/utils/DateCalculator.js @@ -0,0 +1,260 @@ +/** + * DateCalculator - Centralized date calculation logic for calendar + * Handles all date computations with proper week start handling + */ +export class DateCalculator { + /** + * Initialize DateCalculator with configuration + * @param config - Calendar configuration + */ + static initialize(config) { + DateCalculator.config = config; + } + /** + * Validate that a date is valid + * @param date - Date to validate + * @param methodName - Name of calling method for error messages + * @throws Error if date is invalid + */ + static validateDate(date, methodName) { + if (!date || !(date instanceof Date) || isNaN(date.getTime())) { + throw new Error(`${methodName}: Invalid date provided - ${date}`); + } + } + /** + * Get dates for work week using ISO 8601 day numbering (Monday=1, Sunday=7) + * @param weekStart - Any date in the week + * @returns Array of dates for the configured work days + */ + static getWorkWeekDates(weekStart) { + DateCalculator.validateDate(weekStart, 'getWorkWeekDates'); + const dates = []; + const workWeekSettings = DateCalculator.config.getWorkWeekSettings(); + // Always use ISO week start (Monday) + const mondayOfWeek = DateCalculator.getISOWeekStart(weekStart); + // Calculate dates for each work day using ISO numbering + workWeekSettings.workDays.forEach(isoDay => { + const date = new Date(mondayOfWeek); + // ISO day 1=Monday is +0 days, ISO day 7=Sunday is +6 days + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + date.setDate(mondayOfWeek.getDate() + daysFromMonday); + dates.push(date); + }); + return dates; + } + /** + * Get the start of the ISO week (Monday) for a given date + * @param date - Any date in the week + * @returns The Monday of the ISO week + */ + static getISOWeekStart(date) { + DateCalculator.validateDate(date, 'getISOWeekStart'); + const monday = new Date(date); + const currentDay = monday.getDay(); + const daysToSubtract = currentDay === 0 ? 6 : currentDay - 1; + monday.setDate(monday.getDate() - daysToSubtract); + monday.setHours(0, 0, 0, 0); + return monday; + } + /** + * Get the end of the ISO week for a given date + * @param date - Any date in the week + * @returns The end date of the ISO week (Sunday) + */ + static getWeekEnd(date) { + DateCalculator.validateDate(date, 'getWeekEnd'); + const weekStart = DateCalculator.getISOWeekStart(date); + const weekEnd = new Date(weekStart); + weekEnd.setDate(weekStart.getDate() + 6); + weekEnd.setHours(23, 59, 59, 999); + return weekEnd; + } + /** + * Get week number for a date (ISO 8601) + * @param date - The date to get week number for + * @returns Week number (1-53) + */ + static getWeekNumber(date) { + const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); + const dayNum = d.getUTCDay() || 7; + d.setUTCDate(d.getUTCDate() + 4 - dayNum); + const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); + return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7); + } + /** + * Format a date range with customizable options + * @param start - Start date + * @param end - End date + * @param options - Formatting options + * @returns Formatted date range string + */ + static formatDateRange(start, end, options = {}) { + const { locale = 'en-US', month = 'short', day = 'numeric' } = options; + const startYear = start.getFullYear(); + const endYear = end.getFullYear(); + const formatter = new Intl.DateTimeFormat(locale, { + month, + day, + year: startYear !== endYear ? 'numeric' : undefined + }); + // @ts-ignore + if (typeof formatter.formatRange === 'function') { + // @ts-ignore + return formatter.formatRange(start, end); + } + return `${formatter.format(start)} - ${formatter.format(end)}`; + } + /** + * Format a date to ISO date string (YYYY-MM-DD) + * @param date - Date to format + * @returns ISO date string + */ + static formatISODate(date) { + return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; + } + /** + * Check if a date is today + * @param date - Date to check + * @returns True if the date is today + */ + static isToday(date) { + const today = new Date(); + return date.toDateString() === today.toDateString(); + } + /** + * Add days to a date + * @param date - Base date + * @param days - Number of days to add (can be negative) + * @returns New date + */ + static addDays(date, days) { + const result = new Date(date); + result.setDate(result.getDate() + days); + return result; + } + /** + * Add weeks to a date + * @param date - Base date + * @param weeks - Number of weeks to add (can be negative) + * @returns New date + */ + static addWeeks(date, weeks) { + return DateCalculator.addDays(date, weeks * 7); + } + /** + * Get all dates in a week + * @param weekStart - Start of the week + * @returns Array of 7 dates for the full week + */ + static getFullWeekDates(weekStart) { + const dates = []; + for (let i = 0; i < 7; i++) { + dates.push(DateCalculator.addDays(weekStart, i)); + } + return dates; + } + /** + * Get the day name for a date using Intl.DateTimeFormat + * @param date - Date to get day name for + * @param format - 'short' or 'long' + * @returns Day name + */ + static getDayName(date, format = 'short') { + const formatter = new Intl.DateTimeFormat('en-US', { + weekday: format + }); + return formatter.format(date); + } + /** + * Format time to HH:MM + * @param date - Date to format + * @returns Time string + */ + static formatTime(date) { + return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`; + } + /** + * Format time to 12-hour format + * @param date - Date to format + * @returns 12-hour time string + */ + static formatTime12(date) { + const hours = date.getHours(); + const minutes = date.getMinutes(); + const period = hours >= 12 ? 'PM' : 'AM'; + const displayHours = hours % 12 || 12; + return `${displayHours}:${String(minutes).padStart(2, '0')} ${period}`; + } + /** + * Convert minutes since midnight to time string + * @param minutes - Minutes since midnight + * @returns Time string + */ + static minutesToTime(minutes) { + const hours = Math.floor(minutes / 60); + const mins = minutes % 60; + const period = hours >= 12 ? 'PM' : 'AM'; + const displayHours = hours % 12 || 12; + return `${displayHours}:${String(mins).padStart(2, '0')} ${period}`; + } + /** + * Convert time string to minutes since midnight + * @param timeStr - Time string + * @returns Minutes since midnight + */ + static timeToMinutes(timeStr) { + const [time] = timeStr.split('T').pop().split('.'); + const [hours, minutes] = time.split(':').map(Number); + return hours * 60 + minutes; + } + /** + * Get minutes since start of day + * @param date - Date or ISO string + * @returns Minutes since midnight + */ + static getMinutesSinceMidnight(date) { + const d = typeof date === 'string' ? new Date(date) : date; + return d.getHours() * 60 + d.getMinutes(); + } + /** + * Calculate duration in minutes between two dates + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns Duration in minutes + */ + static getDurationMinutes(start, end) { + const startDate = typeof start === 'string' ? new Date(start) : start; + const endDate = typeof end === 'string' ? new Date(end) : end; + return Math.floor((endDate.getTime() - startDate.getTime()) / 60000); + } + /** + * Check if two dates are on the same day + * @param date1 - First date + * @param date2 - Second date + * @returns True if same day + */ + static isSameDay(date1, date2) { + return date1.toDateString() === date2.toDateString(); + } + /** + * Check if event spans multiple days + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns True if spans multiple days + */ + static isMultiDay(start, end) { + const startDate = typeof start === 'string' ? new Date(start) : start; + const endDate = typeof end === 'string' ? new Date(end) : end; + return !DateCalculator.isSameDay(startDate, endDate); + } + // Legacy constructor for backward compatibility + constructor() { + // Empty constructor - all methods are now static + } +} +// Legacy factory function - deprecated, use static methods instead +export function createDateCalculator(config) { + DateCalculator.initialize(config); + return new DateCalculator(); +} +//# sourceMappingURL=DateCalculator.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/DateCalculator.js.map b/wwwroot/js/utils/DateCalculator.js.map new file mode 100644 index 0000000..b21a322 --- /dev/null +++ b/wwwroot/js/utils/DateCalculator.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateCalculator.js","sourceRoot":"","sources":["../../../src/utils/DateCalculator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,cAAc;IAGzB;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,MAAsB;QACtC,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,YAAY,CAAC,IAAU,EAAE,UAAkB;QACxD,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,6BAA6B,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAe;QACrC,cAAc,CAAC,YAAY,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;QAE3D,MAAM,KAAK,GAAW,EAAE,CAAC;QACzB,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAErE,qCAAqC;QACrC,MAAM,YAAY,GAAG,cAAc,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAE/D,wDAAwD;QACxD,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;YACpC,2DAA2D;YAC3D,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,IAAU;QAC/B,cAAc,CAAC,YAAY,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC;QAClD,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,IAAU;QAC1B,cAAc,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAEhD,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAClC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,IAAU;QAC7B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClF,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CACpB,KAAW,EACX,GAAS,EACT,UAKI,EAAE;QAEN,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC;QAEvE,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAElC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;YAChD,KAAK;YACL,GAAG;YACH,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;SACpD,CAAC,CAAC;QAEH,aAAa;QACb,IAAI,OAAO,SAAS,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAChD,aAAa;YACb,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,IAAU;QAC7B,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5H,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,IAAU;QACvB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,YAAY,EAAE,KAAK,KAAK,CAAC,YAAY,EAAE,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,IAAU,EAAE,IAAY;QACrC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAU,EAAE,KAAa;QACvC,OAAO,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAe;QACrC,MAAM,KAAK,GAAW,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,IAAU,EAAE,SAA2B,OAAO;QAC9D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;YACjD,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,IAAU;QAC1B,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACrG,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,IAAU;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,YAAY,GAAG,KAAK,GAAG,EAAE,IAAI,EAAE,CAAC;QAEtC,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;IACzE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,OAAe;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,YAAY,GAAG,KAAK,GAAG,EAAE,IAAI,EAAE,CAAC;QAEtC,OAAO,GAAG,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;IACtE,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,OAAe;QAClC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAmB;QAChD,MAAM,CAAC,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,OAAO,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAoB,EAAE,GAAkB;QAChE,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACtE,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;IACvE,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,KAAW,EAAE,KAAW;QACvC,OAAO,KAAK,CAAC,YAAY,EAAE,KAAK,KAAK,CAAC,YAAY,EAAE,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,KAAoB,EAAE,GAAkB;QACxD,MAAM,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACtE,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,gDAAgD;IAChD;QACE,iDAAiD;IACnD,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO,IAAI,cAAc,EAAE,CAAC;AAC9B,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/utils/DateService.d.ts b/wwwroot/js/utils/DateService.d.ts new file mode 100644 index 0000000..3d26c55 --- /dev/null +++ b/wwwroot/js/utils/DateService.d.ts @@ -0,0 +1,254 @@ +/** + * DateService - Unified date/time service using day.js + * Handles all date operations, timezone conversions, and formatting + */ +import { Configuration } from '../configurations/CalendarConfig'; +export declare class DateService { + private timezone; + constructor(config: Configuration); + /** + * Convert local date to UTC ISO string + * @param localDate - Date in local timezone + * @returns ISO string in UTC (with 'Z' suffix) + */ + toUTC(localDate: Date): string; + /** + * Convert UTC ISO string to local date + * @param utcString - ISO string in UTC + * @returns Date in local timezone + */ + fromUTC(utcString: string): Date; + /** + * Format time as HH:mm or HH:mm:ss + * @param date - Date to format + * @param showSeconds - Include seconds in output + * @returns Formatted time string + */ + formatTime(date: Date, showSeconds?: boolean): string; + /** + * Format time range as "HH:mm - HH:mm" + * @param start - Start date + * @param end - End date + * @returns Formatted time range + */ + formatTimeRange(start: Date, end: Date): string; + /** + * Format date and time in technical format: yyyy-MM-dd HH:mm:ss + * @param date - Date to format + * @returns Technical datetime string + */ + formatTechnicalDateTime(date: Date): string; + /** + * Format date as yyyy-MM-dd + * @param date - Date to format + * @returns ISO date string + */ + formatDate(date: Date): string; + /** + * Format date as "Month Year" (e.g., "January 2025") + * @param date - Date to format + * @param locale - Locale for month name (default: 'en-US') + * @returns Formatted month and year + */ + formatMonthYear(date: Date, locale?: string): string; + /** + * Format date as ISO string (same as formatDate for compatibility) + * @param date - Date to format + * @returns ISO date string + */ + formatISODate(date: Date): string; + /** + * Format time in 12-hour format with AM/PM + * @param date - Date to format + * @returns Time string in 12-hour format (e.g., "2:30 PM") + */ + formatTime12(date: Date): string; + /** + * Get day name for a date + * @param date - Date to get day name for + * @param format - 'short' (e.g., 'Mon') or 'long' (e.g., 'Monday') + * @param locale - Locale for day name (default: 'da-DK') + * @returns Day name + */ + getDayName(date: Date, format?: 'short' | 'long', locale?: string): string; + /** + * Format a date range with customizable options + * @param start - Start date + * @param end - End date + * @param options - Formatting options + * @returns Formatted date range string + */ + formatDateRange(start: Date, end: Date, options?: { + locale?: string; + month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow'; + day?: 'numeric' | '2-digit'; + year?: 'numeric' | '2-digit'; + }): string; + /** + * Convert time string (HH:mm or HH:mm:ss) to total minutes since midnight + * @param timeString - Time in format HH:mm or HH:mm:ss + * @returns Total minutes since midnight + */ + timeToMinutes(timeString: string): number; + /** + * Convert total minutes since midnight to time string HH:mm + * @param totalMinutes - Minutes since midnight + * @returns Time string in format HH:mm + */ + minutesToTime(totalMinutes: number): string; + /** + * Format time from total minutes (alias for minutesToTime) + * @param totalMinutes - Minutes since midnight + * @returns Time string in format HH:mm + */ + formatTimeFromMinutes(totalMinutes: number): string; + /** + * Get minutes since midnight for a given date + * @param date - Date to calculate from + * @returns Minutes since midnight + */ + getMinutesSinceMidnight(date: Date): number; + /** + * Calculate duration in minutes between two dates + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns Duration in minutes + */ + getDurationMinutes(start: Date | string, end: Date | string): number; + /** + * Get start and end of week (Monday to Sunday) + * @param date - Reference date + * @returns Object with start and end dates + */ + getWeekBounds(date: Date): { + start: Date; + end: Date; + }; + /** + * Add weeks to a date + * @param date - Base date + * @param weeks - Number of weeks to add (can be negative) + * @returns New date + */ + addWeeks(date: Date, weeks: number): Date; + /** + * Add months to a date + * @param date - Base date + * @param months - Number of months to add (can be negative) + * @returns New date + */ + addMonths(date: Date, months: number): Date; + /** + * Get ISO week number (1-53) + * @param date - Date to get week number for + * @returns ISO week number + */ + getWeekNumber(date: Date): number; + /** + * Get all dates in a full week (7 days starting from given date) + * @param weekStart - Start date of the week + * @returns Array of 7 dates + */ + getFullWeekDates(weekStart: Date): Date[]; + /** + * Get dates for work week using ISO 8601 day numbering (Monday=1, Sunday=7) + * @param weekStart - Any date in the week + * @param workDays - Array of ISO day numbers (1=Monday, 7=Sunday) + * @returns Array of dates for the specified work days + */ + getWorkWeekDates(weekStart: Date, workDays: number[]): Date[]; + /** + * Create a date at a specific time (minutes since midnight) + * @param baseDate - Base date (date component) + * @param totalMinutes - Minutes since midnight + * @returns New date with specified time + */ + createDateAtTime(baseDate: Date, totalMinutes: number): Date; + /** + * Snap date to nearest interval + * @param date - Date to snap + * @param intervalMinutes - Snap interval in minutes + * @returns Snapped date + */ + snapToInterval(date: Date, intervalMinutes: number): Date; + /** + * Check if two dates are the same day + * @param date1 - First date + * @param date2 - Second date + * @returns True if same day + */ + isSameDay(date1: Date, date2: Date): boolean; + /** + * Get start of day + * @param date - Date + * @returns Start of day (00:00:00) + */ + startOfDay(date: Date): Date; + /** + * Get end of day + * @param date - Date + * @returns End of day (23:59:59.999) + */ + endOfDay(date: Date): Date; + /** + * Add days to a date + * @param date - Base date + * @param days - Number of days to add (can be negative) + * @returns New date + */ + addDays(date: Date, days: number): Date; + /** + * Add minutes to a date + * @param date - Base date + * @param minutes - Number of minutes to add (can be negative) + * @returns New date + */ + addMinutes(date: Date, minutes: number): Date; + /** + * Parse ISO string to date + * @param isoString - ISO date string + * @returns Parsed date + */ + parseISO(isoString: string): Date; + /** + * Check if date is valid + * @param date - Date to check + * @returns True if valid + */ + isValid(date: Date): boolean; + /** + * Calculate difference in calendar days between two dates + * @param date1 - First date + * @param date2 - Second date + * @returns Number of calendar days between dates (can be negative) + */ + differenceInCalendarDays(date1: Date, date2: Date): number; + /** + * Validate date range (start must be before or equal to end) + * @param start - Start date + * @param end - End date + * @returns True if valid range + */ + isValidRange(start: Date, end: Date): boolean; + /** + * Check if date is within reasonable bounds (1900-2100) + * @param date - Date to check + * @returns True if within bounds + */ + isWithinBounds(date: Date): boolean; + /** + * Validate date with comprehensive checks + * @param date - Date to validate + * @param options - Validation options + * @returns Validation result with error message + */ + validateDate(date: Date, options?: { + requireFuture?: boolean; + requirePast?: boolean; + minDate?: Date; + maxDate?: Date; + }): { + valid: boolean; + error?: string; + }; +} diff --git a/wwwroot/js/utils/DateService.js b/wwwroot/js/utils/DateService.js new file mode 100644 index 0000000..a3eb134 --- /dev/null +++ b/wwwroot/js/utils/DateService.js @@ -0,0 +1,418 @@ +/** + * DateService - Unified date/time service using day.js + * Handles all date operations, timezone conversions, and formatting + */ +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +import isoWeek from 'dayjs/plugin/isoWeek'; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; +import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; +// Enable day.js plugins +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.extend(isoWeek); +dayjs.extend(customParseFormat); +dayjs.extend(isSameOrAfter); +dayjs.extend(isSameOrBefore); +export class DateService { + constructor(config) { + this.timezone = config.timeFormatConfig.timezone; + } + // ============================================ + // CORE CONVERSIONS + // ============================================ + /** + * Convert local date to UTC ISO string + * @param localDate - Date in local timezone + * @returns ISO string in UTC (with 'Z' suffix) + */ + toUTC(localDate) { + return dayjs.tz(localDate, this.timezone).utc().toISOString(); + } + /** + * Convert UTC ISO string to local date + * @param utcString - ISO string in UTC + * @returns Date in local timezone + */ + fromUTC(utcString) { + return dayjs.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // FORMATTING + // ============================================ + /** + * Format time as HH:mm or HH:mm:ss + * @param date - Date to format + * @param showSeconds - Include seconds in output + * @returns Formatted time string + */ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? 'HH:mm:ss' : 'HH:mm'; + return dayjs(date).format(pattern); + } + /** + * Format time range as "HH:mm - HH:mm" + * @param start - Start date + * @param end - End date + * @returns Formatted time range + */ + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + /** + * Format date and time in technical format: yyyy-MM-dd HH:mm:ss + * @param date - Date to format + * @returns Technical datetime string + */ + formatTechnicalDateTime(date) { + return dayjs(date).format('YYYY-MM-DD HH:mm:ss'); + } + /** + * Format date as yyyy-MM-dd + * @param date - Date to format + * @returns ISO date string + */ + formatDate(date) { + return dayjs(date).format('YYYY-MM-DD'); + } + /** + * Format date as "Month Year" (e.g., "January 2025") + * @param date - Date to format + * @param locale - Locale for month name (default: 'en-US') + * @returns Formatted month and year + */ + formatMonthYear(date, locale = 'en-US') { + return date.toLocaleDateString(locale, { month: 'long', year: 'numeric' }); + } + /** + * Format date as ISO string (same as formatDate for compatibility) + * @param date - Date to format + * @returns ISO date string + */ + formatISODate(date) { + return this.formatDate(date); + } + /** + * Format time in 12-hour format with AM/PM + * @param date - Date to format + * @returns Time string in 12-hour format (e.g., "2:30 PM") + */ + formatTime12(date) { + return dayjs(date).format('h:mm A'); + } + /** + * Get day name for a date + * @param date - Date to get day name for + * @param format - 'short' (e.g., 'Mon') or 'long' (e.g., 'Monday') + * @param locale - Locale for day name (default: 'da-DK') + * @returns Day name + */ + getDayName(date, format = 'short', locale = 'da-DK') { + const formatter = new Intl.DateTimeFormat(locale, { + weekday: format + }); + return formatter.format(date); + } + /** + * Format a date range with customizable options + * @param start - Start date + * @param end - End date + * @param options - Formatting options + * @returns Formatted date range string + */ + formatDateRange(start, end, options = {}) { + const { locale = 'en-US', month = 'short', day = 'numeric' } = options; + const startYear = start.getFullYear(); + const endYear = end.getFullYear(); + const formatter = new Intl.DateTimeFormat(locale, { + month, + day, + year: startYear !== endYear ? 'numeric' : undefined + }); + // @ts-ignore - formatRange is available in modern browsers + if (typeof formatter.formatRange === 'function') { + // @ts-ignore + return formatter.formatRange(start, end); + } + return `${formatter.format(start)} - ${formatter.format(end)}`; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + /** + * Convert time string (HH:mm or HH:mm:ss) to total minutes since midnight + * @param timeString - Time in format HH:mm or HH:mm:ss + * @returns Total minutes since midnight + */ + timeToMinutes(timeString) { + const parts = timeString.split(':').map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + /** + * Convert total minutes since midnight to time string HH:mm + * @param totalMinutes - Minutes since midnight + * @returns Time string in format HH:mm + */ + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return dayjs().hour(hours).minute(minutes).format('HH:mm'); + } + /** + * Format time from total minutes (alias for minutesToTime) + * @param totalMinutes - Minutes since midnight + * @returns Time string in format HH:mm + */ + formatTimeFromMinutes(totalMinutes) { + return this.minutesToTime(totalMinutes); + } + /** + * Get minutes since midnight for a given date + * @param date - Date to calculate from + * @returns Minutes since midnight + */ + getMinutesSinceMidnight(date) { + const d = dayjs(date); + return d.hour() * 60 + d.minute(); + } + /** + * Calculate duration in minutes between two dates + * @param start - Start date or ISO string + * @param end - End date or ISO string + * @returns Duration in minutes + */ + getDurationMinutes(start, end) { + const startDate = dayjs(start); + const endDate = dayjs(end); + return endDate.diff(startDate, 'minute'); + } + // ============================================ + // WEEK OPERATIONS + // ============================================ + /** + * Get start and end of week (Monday to Sunday) + * @param date - Reference date + * @returns Object with start and end dates + */ + getWeekBounds(date) { + const d = dayjs(date); + return { + start: d.startOf('week').add(1, 'day').toDate(), // Monday (day.js week starts on Sunday) + end: d.endOf('week').add(1, 'day').toDate() // Sunday + }; + } + /** + * Add weeks to a date + * @param date - Base date + * @param weeks - Number of weeks to add (can be negative) + * @returns New date + */ + addWeeks(date, weeks) { + return dayjs(date).add(weeks, 'week').toDate(); + } + /** + * Add months to a date + * @param date - Base date + * @param months - Number of months to add (can be negative) + * @returns New date + */ + addMonths(date, months) { + return dayjs(date).add(months, 'month').toDate(); + } + /** + * Get ISO week number (1-53) + * @param date - Date to get week number for + * @returns ISO week number + */ + getWeekNumber(date) { + return dayjs(date).isoWeek(); + } + /** + * Get all dates in a full week (7 days starting from given date) + * @param weekStart - Start date of the week + * @returns Array of 7 dates + */ + getFullWeekDates(weekStart) { + const dates = []; + for (let i = 0; i < 7; i++) { + dates.push(this.addDays(weekStart, i)); + } + return dates; + } + /** + * Get dates for work week using ISO 8601 day numbering (Monday=1, Sunday=7) + * @param weekStart - Any date in the week + * @param workDays - Array of ISO day numbers (1=Monday, 7=Sunday) + * @returns Array of dates for the specified work days + */ + getWorkWeekDates(weekStart, workDays) { + const dates = []; + // Get Monday of the week + const weekBounds = this.getWeekBounds(weekStart); + const mondayOfWeek = this.startOfDay(weekBounds.start); + // Calculate dates for each work day using ISO numbering + workDays.forEach(isoDay => { + const date = new Date(mondayOfWeek); + // ISO day 1=Monday is +0 days, ISO day 7=Sunday is +6 days + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + date.setDate(mondayOfWeek.getDate() + daysFromMonday); + dates.push(date); + }); + return dates; + } + // ============================================ + // GRID HELPERS + // ============================================ + /** + * Create a date at a specific time (minutes since midnight) + * @param baseDate - Base date (date component) + * @param totalMinutes - Minutes since midnight + * @returns New date with specified time + */ + createDateAtTime(baseDate, totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return dayjs(baseDate).startOf('day').hour(hours).minute(minutes).toDate(); + } + /** + * Snap date to nearest interval + * @param date - Date to snap + * @param intervalMinutes - Snap interval in minutes + * @returns Snapped date + */ + snapToInterval(date, intervalMinutes) { + const minutes = this.getMinutesSinceMidnight(date); + const snappedMinutes = Math.round(minutes / intervalMinutes) * intervalMinutes; + return this.createDateAtTime(date, snappedMinutes); + } + // ============================================ + // UTILITY METHODS + // ============================================ + /** + * Check if two dates are the same day + * @param date1 - First date + * @param date2 - Second date + * @returns True if same day + */ + isSameDay(date1, date2) { + return dayjs(date1).isSame(date2, 'day'); + } + /** + * Get start of day + * @param date - Date + * @returns Start of day (00:00:00) + */ + startOfDay(date) { + return dayjs(date).startOf('day').toDate(); + } + /** + * Get end of day + * @param date - Date + * @returns End of day (23:59:59.999) + */ + endOfDay(date) { + return dayjs(date).endOf('day').toDate(); + } + /** + * Add days to a date + * @param date - Base date + * @param days - Number of days to add (can be negative) + * @returns New date + */ + addDays(date, days) { + return dayjs(date).add(days, 'day').toDate(); + } + /** + * Add minutes to a date + * @param date - Base date + * @param minutes - Number of minutes to add (can be negative) + * @returns New date + */ + addMinutes(date, minutes) { + return dayjs(date).add(minutes, 'minute').toDate(); + } + /** + * Parse ISO string to date + * @param isoString - ISO date string + * @returns Parsed date + */ + parseISO(isoString) { + return dayjs(isoString).toDate(); + } + /** + * Check if date is valid + * @param date - Date to check + * @returns True if valid + */ + isValid(date) { + return dayjs(date).isValid(); + } + /** + * Calculate difference in calendar days between two dates + * @param date1 - First date + * @param date2 - Second date + * @returns Number of calendar days between dates (can be negative) + */ + differenceInCalendarDays(date1, date2) { + const d1 = dayjs(date1).startOf('day'); + const d2 = dayjs(date2).startOf('day'); + return d1.diff(d2, 'day'); + } + /** + * Validate date range (start must be before or equal to end) + * @param start - Start date + * @param end - End date + * @returns True if valid range + */ + isValidRange(start, end) { + if (!this.isValid(start) || !this.isValid(end)) { + return false; + } + return start.getTime() <= end.getTime(); + } + /** + * Check if date is within reasonable bounds (1900-2100) + * @param date - Date to check + * @returns True if within bounds + */ + isWithinBounds(date) { + if (!this.isValid(date)) { + return false; + } + const year = date.getFullYear(); + return year >= 1900 && year <= 2100; + } + /** + * Validate date with comprehensive checks + * @param date - Date to validate + * @param options - Validation options + * @returns Validation result with error message + */ + validateDate(date, options = {}) { + if (!this.isValid(date)) { + return { valid: false, error: 'Invalid date' }; + } + if (!this.isWithinBounds(date)) { + return { valid: false, error: 'Date out of bounds (1900-2100)' }; + } + const now = new Date(); + if (options.requireFuture && date <= now) { + return { valid: false, error: 'Date must be in the future' }; + } + if (options.requirePast && date >= now) { + return { valid: false, error: 'Date must be in the past' }; + } + if (options.minDate && date < options.minDate) { + return { valid: false, error: `Date must be after ${this.formatDate(options.minDate)}` }; + } + if (options.maxDate && date > options.maxDate) { + return { valid: false, error: `Date must be before ${this.formatDate(options.maxDate)}` }; + } + return { valid: true }; + } +} +//# sourceMappingURL=DateService.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/DateService.js.map b/wwwroot/js/utils/DateService.js.map new file mode 100644 index 0000000..e976a16 --- /dev/null +++ b/wwwroot/js/utils/DateService.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DateService.js","sourceRoot":"","sources":["../../../src/utils/DateService.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/utils/OverlapDetector.d.ts b/wwwroot/js/utils/OverlapDetector.d.ts new file mode 100644 index 0000000..b4a6994 --- /dev/null +++ b/wwwroot/js/utils/OverlapDetector.d.ts @@ -0,0 +1,33 @@ +/** + * OverlapDetector - Ren tidbaseret overlap detection + * Ingen DOM manipulation, kun tidsberegninger + */ +import { CalendarEvent } from '../types/CalendarTypes'; +export type EventId = string & { + readonly __brand: 'EventId'; +}; +export type OverlapResult = { + overlappingEvents: CalendarEvent[]; + stackLinks: Map; +}; +export interface StackLink { + prev?: EventId; + next?: EventId; + stackLevel: number; +} +export declare class OverlapDetector { + /** + * Resolver hvilke events et givent event overlapper med i en kolonne + * @param event - CalendarEvent der skal checkes for overlap + * @param columnEvents - Array af CalendarEvent objekter i kolonnen + * @returns Array af events som det givne event overlapper med + */ + resolveOverlap(event: CalendarEvent, columnEvents: CalendarEvent[]): CalendarEvent[]; + /** + * Dekorerer events med stack linking data + * @param newEvent - Det nye event der skal tilføjes + * @param overlappingEvents - Events som det nye event overlapper med + * @returns OverlapResult med overlappende events og stack links + */ + decorateWithStackLinks(newEvent: CalendarEvent, overlappingEvents: CalendarEvent[]): OverlapResult; +} diff --git a/wwwroot/js/utils/OverlapDetector.js b/wwwroot/js/utils/OverlapDetector.js new file mode 100644 index 0000000..09ddd6b --- /dev/null +++ b/wwwroot/js/utils/OverlapDetector.js @@ -0,0 +1,52 @@ +/** + * OverlapDetector - Ren tidbaseret overlap detection + * Ingen DOM manipulation, kun tidsberegninger + */ +export class OverlapDetector { + /** + * Resolver hvilke events et givent event overlapper med i en kolonne + * @param event - CalendarEvent der skal checkes for overlap + * @param columnEvents - Array af CalendarEvent objekter i kolonnen + * @returns Array af events som det givne event overlapper med + */ + resolveOverlap(event, columnEvents) { + return columnEvents.filter(existingEvent => { + // To events overlapper hvis: + // event starter før existing slutter OG + // event slutter efter existing starter + return event.start < existingEvent.end && event.end > existingEvent.start; + }); + } + /** + * Dekorerer events med stack linking data + * @param newEvent - Det nye event der skal tilføjes + * @param overlappingEvents - Events som det nye event overlapper med + * @returns OverlapResult med overlappende events og stack links + */ + decorateWithStackLinks(newEvent, overlappingEvents) { + const stackLinks = new Map(); + if (overlappingEvents.length === 0) { + return { + overlappingEvents: [], + stackLinks + }; + } + // Kombiner nyt event med eksisterende og sortér efter start tid (tidligste første) + const allEvents = [...overlappingEvents, newEvent].sort((a, b) => a.start.getTime() - b.start.getTime()); + // Opret sammenhængende kæde - alle events bindes sammen + allEvents.forEach((event, index) => { + const stackLink = { + stackLevel: index, + prev: index > 0 ? allEvents[index - 1].id : undefined, + next: index < allEvents.length - 1 ? allEvents[index + 1].id : undefined + }; + stackLinks.set(event.id, stackLink); + }); + overlappingEvents.push(newEvent); + return { + overlappingEvents, + stackLinks + }; + } +} +//# sourceMappingURL=OverlapDetector.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/OverlapDetector.js.map b/wwwroot/js/utils/OverlapDetector.js.map new file mode 100644 index 0000000..941cbb5 --- /dev/null +++ b/wwwroot/js/utils/OverlapDetector.js.map @@ -0,0 +1 @@ +{"version":3,"file":"OverlapDetector.js","sourceRoot":"","sources":["../../../src/utils/OverlapDetector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,MAAM,OAAO,eAAe;IAE1B;;;;;OAKG;IACI,cAAc,CAAC,KAAoB,EAAE,YAA6B;QACvE,OAAO,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;YACzC,6BAA6B;YAC7B,wCAAwC;YACxC,uCAAuC;YACvC,OAAO,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,sBAAsB,CAAC,QAAuB,EAAE,iBAAkC;QACvF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;QAEjD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO;gBACL,iBAAiB,EAAE,EAAE;gBACrB,UAAU;aACX,CAAC;QACJ,CAAC;QAED,mFAAmF;QACnF,MAAM,SAAS,GAAG,CAAC,GAAG,iBAAiB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC/D,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CACtC,CAAC;QAEF,wDAAwD;QACxD,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACjC,MAAM,SAAS,GAAc;gBAC3B,UAAU,EAAE,KAAK;gBACjB,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAa,CAAC,CAAC,CAAC,SAAS;gBAChE,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAa,CAAC,CAAC,CAAC,SAAS;aACpF,CAAC;YACF,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAa,EAAE,SAAS,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO;YACL,iBAAiB;YACjB,UAAU;SACX,CAAC;IACJ,CAAC;CACF"} \ No newline at end of file diff --git a/wwwroot/js/utils/PositionUtils.d.ts b/wwwroot/js/utils/PositionUtils.d.ts new file mode 100644 index 0000000..8171427 --- /dev/null +++ b/wwwroot/js/utils/PositionUtils.d.ts @@ -0,0 +1,101 @@ +import { Configuration } from '../configurations/CalendarConfig'; +import { IColumnBounds } from './ColumnDetectionUtils'; +import { DateService } from './DateService'; +/** + * PositionUtils - Positioning utilities with dependency injection + * Focuses on pixel/position calculations while delegating date operations + * + * Note: Uses DateService with date-fns for all date/time operations + */ +export declare class PositionUtils { + private dateService; + private config; + constructor(dateService: DateService, config: Configuration); + /** + * Convert minutes to pixels + */ + minutesToPixels(minutes: number): number; + /** + * Convert pixels to minutes + */ + pixelsToMinutes(pixels: number): number; + /** + * Convert time (HH:MM) to pixels from day start using DateService + */ + timeToPixels(timeString: string): number; + /** + * Convert Date object to pixels from day start using DateService + */ + dateToPixels(date: Date): number; + /** + * Convert pixels to time using DateService + */ + pixelsToTime(pixels: number): string; + /** + * Beregn event position og størrelse + */ + calculateEventPosition(startTime: string | Date, endTime: string | Date): { + top: number; + height: number; + duration: number; + }; + /** + * Snap position til grid interval + */ + snapToGrid(pixels: number): number; + /** + * Snap time to interval using DateService + */ + snapTimeToInterval(timeString: string): string; + /** + * Beregn kolonne position for overlappende events + */ + calculateColumnPosition(eventIndex: number, totalColumns: number, containerWidth: number): { + left: number; + width: number; + }; + /** + * Check om to events overlapper i tid + */ + eventsOverlap(start1: string | Date, end1: string | Date, start2: string | Date, end2: string | Date): boolean; + /** + * Beregn Y position fra mouse/touch koordinat + */ + getPositionFromCoordinate(clientY: number, column: IColumnBounds): number; + /** + * Valider at tid er inden for arbejdstimer + */ + isWithinWorkHours(timeString: string): boolean; + /** + * Valider at tid er inden for dag grænser + */ + isWithinDayBounds(timeString: string): boolean; + /** + * Hent minimum event højde i pixels + */ + getMinimumEventHeight(): number; + /** + * Hent maksimum event højde i pixels (hele dagen) + */ + getMaximumEventHeight(): number; + /** + * Beregn total kalender højde + */ + getTotalCalendarHeight(): number; + /** + * Convert ISO datetime to time string with UTC-to-local conversion + */ + isoToTimeString(isoString: string): string; + /** + * Convert time string to ISO datetime using DateService with timezone handling + */ + timeStringToIso(timeString: string, date?: Date): string; + /** + * Calculate event duration using DateService + */ + calculateDuration(startTime: string | Date, endTime: string | Date): number; + /** + * Format duration to readable text (Danish) + */ + formatDuration(minutes: number): string; +} diff --git a/wwwroot/js/utils/PositionUtils.js b/wwwroot/js/utils/PositionUtils.js new file mode 100644 index 0000000..9dd1956 --- /dev/null +++ b/wwwroot/js/utils/PositionUtils.js @@ -0,0 +1,209 @@ +import { TimeFormatter } from './TimeFormatter'; +/** + * PositionUtils - Positioning utilities with dependency injection + * Focuses on pixel/position calculations while delegating date operations + * + * Note: Uses DateService with date-fns for all date/time operations + */ +export class PositionUtils { + constructor(dateService, config) { + this.dateService = dateService; + this.config = config; + } + /** + * Convert minutes to pixels + */ + minutesToPixels(minutes) { + const gridSettings = this.config.gridSettings; + const pixelsPerHour = gridSettings.hourHeight; + return (minutes / 60) * pixelsPerHour; + } + /** + * Convert pixels to minutes + */ + pixelsToMinutes(pixels) { + const gridSettings = this.config.gridSettings; + const pixelsPerHour = gridSettings.hourHeight; + return (pixels / pixelsPerHour) * 60; + } + /** + * Convert time (HH:MM) to pixels from day start using DateService + */ + timeToPixels(timeString) { + const totalMinutes = this.dateService.timeToMinutes(timeString); + const gridSettings = this.config.gridSettings; + const dayStartMinutes = gridSettings.dayStartHour * 60; + const minutesFromDayStart = totalMinutes - dayStartMinutes; + return this.minutesToPixels(minutesFromDayStart); + } + /** + * Convert Date object to pixels from day start using DateService + */ + dateToPixels(date) { + const totalMinutes = this.dateService.getMinutesSinceMidnight(date); + const gridSettings = this.config.gridSettings; + const dayStartMinutes = gridSettings.dayStartHour * 60; + const minutesFromDayStart = totalMinutes - dayStartMinutes; + return this.minutesToPixels(minutesFromDayStart); + } + /** + * Convert pixels to time using DateService + */ + pixelsToTime(pixels) { + const minutes = this.pixelsToMinutes(pixels); + const gridSettings = this.config.gridSettings; + const dayStartMinutes = gridSettings.dayStartHour * 60; + const totalMinutes = dayStartMinutes + minutes; + return this.dateService.minutesToTime(totalMinutes); + } + /** + * Beregn event position og størrelse + */ + calculateEventPosition(startTime, endTime) { + let startPixels; + let endPixels; + if (typeof startTime === 'string') { + startPixels = this.timeToPixels(startTime); + } + else { + startPixels = this.dateToPixels(startTime); + } + if (typeof endTime === 'string') { + endPixels = this.timeToPixels(endTime); + } + else { + endPixels = this.dateToPixels(endTime); + } + const height = Math.max(endPixels - startPixels, this.getMinimumEventHeight()); + const duration = this.pixelsToMinutes(height); + return { + top: startPixels, + height, + duration + }; + } + /** + * Snap position til grid interval + */ + snapToGrid(pixels) { + const gridSettings = this.config.gridSettings; + const snapInterval = gridSettings.snapInterval; + const snapPixels = this.minutesToPixels(snapInterval); + return Math.round(pixels / snapPixels) * snapPixels; + } + /** + * Snap time to interval using DateService + */ + snapTimeToInterval(timeString) { + const totalMinutes = this.dateService.timeToMinutes(timeString); + const gridSettings = this.config.gridSettings; + const snapInterval = gridSettings.snapInterval; + const snappedMinutes = Math.round(totalMinutes / snapInterval) * snapInterval; + return this.dateService.minutesToTime(snappedMinutes); + } + /** + * Beregn kolonne position for overlappende events + */ + calculateColumnPosition(eventIndex, totalColumns, containerWidth) { + const columnWidth = containerWidth / totalColumns; + const left = eventIndex * columnWidth; + // Lav lidt margin mellem kolonnerne + const margin = 2; + const adjustedWidth = columnWidth - margin; + return { + left: left + (margin / 2), + width: Math.max(adjustedWidth, 50) // Minimum width + }; + } + /** + * Check om to events overlapper i tid + */ + eventsOverlap(start1, end1, start2, end2) { + const pos1 = this.calculateEventPosition(start1, end1); + const pos2 = this.calculateEventPosition(start2, end2); + const event1End = pos1.top + pos1.height; + const event2End = pos2.top + pos2.height; + return !(event1End <= pos2.top || event2End <= pos1.top); + } + /** + * Beregn Y position fra mouse/touch koordinat + */ + getPositionFromCoordinate(clientY, column) { + const relativeY = clientY - column.boundingClientRect.top; + // Snap til grid + return this.snapToGrid(relativeY); + } + /** + * Valider at tid er inden for arbejdstimer + */ + isWithinWorkHours(timeString) { + const [hours] = timeString.split(':').map(Number); + const gridSettings = this.config.gridSettings; + return hours >= gridSettings.workStartHour && hours < gridSettings.workEndHour; + } + /** + * Valider at tid er inden for dag grænser + */ + isWithinDayBounds(timeString) { + const [hours] = timeString.split(':').map(Number); + const gridSettings = this.config.gridSettings; + return hours >= gridSettings.dayStartHour && hours < gridSettings.dayEndHour; + } + /** + * Hent minimum event højde i pixels + */ + getMinimumEventHeight() { + // Minimum 15 minutter + return this.minutesToPixels(15); + } + /** + * Hent maksimum event højde i pixels (hele dagen) + */ + getMaximumEventHeight() { + const gridSettings = this.config.gridSettings; + const dayDurationHours = gridSettings.dayEndHour - gridSettings.dayStartHour; + return dayDurationHours * gridSettings.hourHeight; + } + /** + * Beregn total kalender højde + */ + getTotalCalendarHeight() { + return this.getMaximumEventHeight(); + } + /** + * Convert ISO datetime to time string with UTC-to-local conversion + */ + isoToTimeString(isoString) { + const date = new Date(isoString); + return TimeFormatter.formatTime(date); + } + /** + * Convert time string to ISO datetime using DateService with timezone handling + */ + timeStringToIso(timeString, date = new Date()) { + const totalMinutes = this.dateService.timeToMinutes(timeString); + const newDate = this.dateService.createDateAtTime(date, totalMinutes); + return this.dateService.toUTC(newDate); + } + /** + * Calculate event duration using DateService + */ + calculateDuration(startTime, endTime) { + return this.dateService.getDurationMinutes(startTime, endTime); + } + /** + * Format duration to readable text (Danish) + */ + formatDuration(minutes) { + if (minutes < 60) { + return `${minutes} min`; + } + const hours = Math.floor(minutes / 60); + const remainingMinutes = minutes % 60; + if (remainingMinutes === 0) { + return `${hours} time${hours !== 1 ? 'r' : ''}`; + } + return `${hours}t ${remainingMinutes}m`; + } +} +//# sourceMappingURL=PositionUtils.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/PositionUtils.js.map b/wwwroot/js/utils/PositionUtils.js.map new file mode 100644 index 0000000..4d1125c --- /dev/null +++ b/wwwroot/js/utils/PositionUtils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"PositionUtils.js","sourceRoot":"","sources":["../../../src/utils/PositionUtils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/wwwroot/js/utils/TimeFormatter.d.ts b/wwwroot/js/utils/TimeFormatter.d.ts new file mode 100644 index 0000000..d52a9f2 --- /dev/null +++ b/wwwroot/js/utils/TimeFormatter.d.ts @@ -0,0 +1,45 @@ +/** + * TimeFormatter - Centralized time formatting with timezone support + * Now uses DateService internally for all date/time operations + * + * Handles conversion from UTC/Zulu time to configured timezone (default: Europe/Copenhagen) + * Supports both 12-hour and 24-hour format configuration + * + * All events in the system are stored in UTC and must be converted to local timezone + */ +import { ITimeFormatConfig } from '../configurations/TimeFormatConfig'; +export declare class TimeFormatter { + private static settings; + private static dateService; + private static getDateService; + /** + * Configure time formatting settings + * Must be called before using TimeFormatter + */ + static configure(settings: ITimeFormatConfig): void; + /** + * Convert UTC date to configured timezone (internal helper) + * @param utcDate - Date in UTC (or ISO string) + * @returns Date object adjusted to configured timezone + */ + private static convertToLocalTime; + /** + * Format time in 24-hour format using DateService (internal helper) + * @param date - Date to format + * @returns Formatted time string (e.g., "09:00") + */ + private static format24Hour; + /** + * Format time according to current configuration + * @param date - Date to format + * @returns Formatted time string + */ + static formatTime(date: Date): string; + /** + * Format time range (start - end) using DateService + * @param startDate - Start date + * @param endDate - End date + * @returns Formatted time range string (e.g., "09:00 - 10:30") + */ + static formatTimeRange(startDate: Date, endDate: Date): string; +} diff --git a/wwwroot/js/utils/TimeFormatter.js b/wwwroot/js/utils/TimeFormatter.js new file mode 100644 index 0000000..72ab72c --- /dev/null +++ b/wwwroot/js/utils/TimeFormatter.js @@ -0,0 +1,92 @@ +/** + * TimeFormatter - Centralized time formatting with timezone support + * Now uses DateService internally for all date/time operations + * + * Handles conversion from UTC/Zulu time to configured timezone (default: Europe/Copenhagen) + * Supports both 12-hour and 24-hour format configuration + * + * All events in the system are stored in UTC and must be converted to local timezone + */ +import { DateService } from './DateService'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +// Enable day.js plugins for timezone formatting +dayjs.extend(utc); +dayjs.extend(timezone); +export class TimeFormatter { + static getDateService() { + if (!TimeFormatter.dateService) { + if (!TimeFormatter.settings) { + throw new Error('TimeFormatter must be configured before use. Call TimeFormatter.configure() first.'); + } + // Create a minimal config object for DateService + const config = { + timeFormatConfig: { + timezone: TimeFormatter.settings.timezone + } + }; + TimeFormatter.dateService = new DateService(config); + } + return TimeFormatter.dateService; + } + /** + * Configure time formatting settings + * Must be called before using TimeFormatter + */ + static configure(settings) { + TimeFormatter.settings = settings; + // Reset DateService to pick up new timezone + TimeFormatter.dateService = null; + } + /** + * Convert UTC date to configured timezone (internal helper) + * @param utcDate - Date in UTC (or ISO string) + * @returns Date object adjusted to configured timezone + */ + static convertToLocalTime(utcDate) { + if (typeof utcDate === 'string') { + return TimeFormatter.getDateService().fromUTC(utcDate); + } + // If it's already a Date object, convert to UTC string first, then back to local + const utcString = utcDate.toISOString(); + return TimeFormatter.getDateService().fromUTC(utcString); + } + /** + * Format time in 24-hour format using DateService (internal helper) + * @param date - Date to format + * @returns Formatted time string (e.g., "09:00") + */ + static format24Hour(date) { + if (!TimeFormatter.settings) { + throw new Error('TimeFormatter must be configured before use. Call TimeFormatter.configure() first.'); + } + // Use day.js directly to format with timezone awareness + const pattern = TimeFormatter.settings.showSeconds ? 'HH:mm:ss' : 'HH:mm'; + return dayjs.utc(date).tz(TimeFormatter.settings.timezone).format(pattern); + } + /** + * Format time according to current configuration + * @param date - Date to format + * @returns Formatted time string + */ + static formatTime(date) { + // Always use 24-hour format (12-hour support removed as unused) + return TimeFormatter.format24Hour(date); + } + /** + * Format time range (start - end) using DateService + * @param startDate - Start date + * @param endDate - End date + * @returns Formatted time range string (e.g., "09:00 - 10:30") + */ + static formatTimeRange(startDate, endDate) { + const localStart = TimeFormatter.convertToLocalTime(startDate); + const localEnd = TimeFormatter.convertToLocalTime(endDate); + return TimeFormatter.getDateService().formatTimeRange(localStart, localEnd); + } +} +TimeFormatter.settings = null; +// DateService will be initialized lazily to avoid circular dependency with CalendarConfig +TimeFormatter.dateService = null; +//# sourceMappingURL=TimeFormatter.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/TimeFormatter.js.map b/wwwroot/js/utils/TimeFormatter.js.map new file mode 100644 index 0000000..e5a05ec --- /dev/null +++ b/wwwroot/js/utils/TimeFormatter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"TimeFormatter.js","sourceRoot":"","sources":["../../../src/utils/TimeFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAE7C,gDAAgD;AAChD,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAClB,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEvB,MAAM,OAAO,aAAa;IAMhB,MAAM,CAAC,cAAc;QAC3B,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;YACxG,CAAC;YACD,iDAAiD;YACjD,MAAM,MAAM,GAAG;gBACb,gBAAgB,EAAE;oBAChB,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,QAAQ;iBAC1C;aACF,CAAC;YACF,aAAa,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,MAAa,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,aAAa,CAAC,WAAW,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,QAA2B;QAC1C,aAAa,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAClC,4CAA4C;QAC5C,aAAa,CAAC,WAAW,GAAG,IAAI,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,kBAAkB,CAAC,OAAsB;QACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,aAAa,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzD,CAAC;QAED,iFAAiF;QACjF,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QACxC,OAAO,aAAa,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,YAAY,CAAC,IAAU;QACpC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACxG,CAAC;QAED,wDAAwD;QACxD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1E,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,IAAU;QAC1B,gEAAgE;QAChE,OAAO,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,eAAe,CAAC,SAAe,EAAE,OAAa;QACnD,MAAM,UAAU,GAAG,aAAa,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC3D,OAAO,aAAa,CAAC,cAAc,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC9E,CAAC;;AAjFc,sBAAQ,GAA6B,IAAI,CAAC;AAEzD,0FAA0F;AAC3E,yBAAW,GAAuB,IAAI,CAAC"} \ No newline at end of file diff --git a/wwwroot/js/utils/URLManager.d.ts b/wwwroot/js/utils/URLManager.d.ts new file mode 100644 index 0000000..1b4d811 --- /dev/null +++ b/wwwroot/js/utils/URLManager.d.ts @@ -0,0 +1,29 @@ +import { IEventBus } from '../types/CalendarTypes'; +/** + * URLManager handles URL query parameter parsing and deep linking functionality + * Follows event-driven architecture with no global state + */ +export declare class URLManager { + private eventBus; + constructor(eventBus: IEventBus); + /** + * Parse eventId from URL query parameters + * @returns eventId string or null if not found + */ + parseEventIdFromURL(): string | null; + /** + * Get all query parameters as an object + * @returns object with all query parameters + */ + getAllQueryParams(): Record; + /** + * Update URL without page reload (for future use) + * @param params object with parameters to update + */ + updateURL(params: Record): void; + /** + * Check if current URL has any query parameters + * @returns true if URL has query parameters + */ + hasQueryParams(): boolean; +} diff --git a/wwwroot/js/utils/URLManager.js b/wwwroot/js/utils/URLManager.js new file mode 100644 index 0000000..472dce8 --- /dev/null +++ b/wwwroot/js/utils/URLManager.js @@ -0,0 +1,76 @@ +/** + * URLManager handles URL query parameter parsing and deep linking functionality + * Follows event-driven architecture with no global state + */ +export class URLManager { + constructor(eventBus) { + this.eventBus = eventBus; + } + /** + * Parse eventId from URL query parameters + * @returns eventId string or null if not found + */ + parseEventIdFromURL() { + try { + const urlParams = new URLSearchParams(window.location.search); + const eventId = urlParams.get('eventId'); + if (eventId && eventId.trim() !== '') { + return eventId.trim(); + } + return null; + } + catch (error) { + console.warn('URLManager: Failed to parse URL parameters:', error); + return null; + } + } + /** + * Get all query parameters as an object + * @returns object with all query parameters + */ + getAllQueryParams() { + try { + const urlParams = new URLSearchParams(window.location.search); + const params = {}; + for (const [key, value] of urlParams.entries()) { + params[key] = value; + } + return params; + } + catch (error) { + console.warn('URLManager: Failed to parse URL parameters:', error); + return {}; + } + } + /** + * Update URL without page reload (for future use) + * @param params object with parameters to update + */ + updateURL(params) { + try { + const url = new URL(window.location.href); + // Update or remove parameters + Object.entries(params).forEach(([key, value]) => { + if (value === null) { + url.searchParams.delete(key); + } + else { + url.searchParams.set(key, value); + } + }); + // Update URL without page reload + window.history.replaceState({}, '', url.toString()); + } + catch (error) { + console.warn('URLManager: Failed to update URL:', error); + } + } + /** + * Check if current URL has any query parameters + * @returns true if URL has query parameters + */ + hasQueryParams() { + return window.location.search.length > 0; + } +} +//# sourceMappingURL=URLManager.js.map \ No newline at end of file diff --git a/wwwroot/js/utils/URLManager.js.map b/wwwroot/js/utils/URLManager.js.map new file mode 100644 index 0000000..5cd8f88 --- /dev/null +++ b/wwwroot/js/utils/URLManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"URLManager.js","sourceRoot":"","sources":["../../../src/utils/URLManager.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,UAAU;IAGnB,YAAY,QAAmB;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACtB,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEzC,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACnC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;YAC1B,CAAC;YAED,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,iBAAiB;QACpB,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9D,MAAM,MAAM,GAA2B,EAAE,CAAC;YAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAqC;QAClD,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAE1C,8BAA8B;YAC9B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC5C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACjB,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACrC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,iCAAiC;YACjC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,cAAc;QACjB,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7C,CAAC;CACJ"} \ No newline at end of file diff --git a/wwwroot/js/v2-demo.js b/wwwroot/js/v2-demo.js new file mode 100644 index 0000000..9fde2c8 --- /dev/null +++ b/wwwroot/js/v2-demo.js @@ -0,0 +1,6463 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); + +// node_modules/dayjs/dayjs.min.js +var require_dayjs_min = __commonJS({ + "node_modules/dayjs/dayjs.min.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = /* @__PURE__ */ __name(function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, "m"), v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: /* @__PURE__ */ __name(function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, "t"), a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = "$isDayjsObject", S = /* @__PURE__ */ __name(function(t2) { + return t2 instanceof _ || !(!t2 || !t2[p]); + }, "S"), w = /* @__PURE__ */ __name(function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, "t"), O = /* @__PURE__ */ __name(function(t2, e2) { + if (S(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, "O"), b = v; + b.l = w, b.i = S, b.w = function(t2, e2) { + return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true; + } + __name(M2, "M"); + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return /* @__PURE__ */ new Date(NaN); + if (b.u(e2)) + return /* @__PURE__ */ new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return b; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = O(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return O(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < O(t2); + }, m2.$g = function(t2, e2, n2) { + return b.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = /* @__PURE__ */ __name(function(t3, e3) { + var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, "l"), $2 = /* @__PURE__ */ __name(function(t3, e3) { + return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, "$"), y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (f2) { + case h: + return r2 ? l2(1, 0) : l2(31, 11); + case c: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === c || o2 === h) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[b.p(t2)](); + }, m2.add = function(r2, f2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = b.p(f2), y2 = /* @__PURE__ */ __name(function(t2) { + var e2 = O(l2); + return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }, "y"); + if ($2 === c) + return this.set(c, this.$M + r2); + if ($2 === h) + return this.set(h, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return b.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = /* @__PURE__ */ __name(function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, "h"), d2 = /* @__PURE__ */ __name(function(t3) { + return b.s(s2 % 12 || 12, t3, "0"); + }, "d"), $2 = f2 || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }; + return r2.replace(y, function(t3, r3) { + return r3 || function(t4) { + switch (t4) { + case "YY": + return String(e2.$y).slice(-2); + case "YYYY": + return b.s(e2.$y, 4, "0"); + case "M": + return a2 + 1; + case "MM": + return b.s(a2 + 1, 2, "0"); + case "MMM": + return h2(n2.monthsShort, a2, c2, 3); + case "MMMM": + return h2(c2, a2); + case "D": + return e2.$D; + case "DD": + return b.s(e2.$D, 2, "0"); + case "d": + return String(e2.$W); + case "dd": + return h2(n2.weekdaysMin, e2.$W, o2, 2); + case "ddd": + return h2(n2.weekdaysShort, e2.$W, o2, 3); + case "dddd": + return o2[e2.$W]; + case "H": + return String(s2); + case "HH": + return b.s(s2, 2, "0"); + case "h": + return d2(1); + case "hh": + return d2(2); + case "a": + return $2(s2, u2, true); + case "A": + return $2(s2, u2, false); + case "m": + return String(u2); + case "mm": + return b.s(u2, 2, "0"); + case "s": + return String(e2.$s); + case "ss": + return b.s(e2.$s, 2, "0"); + case "SSS": + return b.s(e2.$ms, 3, "0"); + case "Z": + return i2; + } + return null; + }(t3) || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = /* @__PURE__ */ __name(function() { + return b.m(y2, m3); + }, "D"); + switch (M3) { + case h: + $2 = D2() / 12; + break; + case c: + $2 = D2(); + break; + case f: + $2 = D2() / 3; + break; + case o: + $2 = (g2 - v2) / 6048e5; + break; + case a: + $2 = (g2 - v2) / 864e5; + break; + case u: + $2 = g2 / n; + break; + case s: + $2 = g2 / e; + break; + case i: + $2 = g2 / t; + break; + default: + $2 = g2; + } + return l2 ? $2 : b.a($2); + }, m2.daysInMonth = function() { + return this.endOf(c).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = w(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return b.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), k = _.prototype; + return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) { + k[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), O.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, O), t2.$i = true), O; + }, O.locale = w, O.isDayjs = S, O.unix = function(t2) { + return O(1e3 * t2); + }, O.en = D[g], O.Ls = D, O.p = {}, O; + }); + } +}); + +// node_modules/dayjs/plugin/utc.js +var require_utc = __commonJS({ + "node_modules/dayjs/plugin/utc.js"(exports, module) { + !function(t, i) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i(); + }(exports, function() { + "use strict"; + var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g; + return function(s, f, n) { + var u = f.prototype; + n.utc = function(t2) { + var i2 = { date: t2, utc: true, args: arguments }; + return new f(i2); + }, u.utc = function(i2) { + var e2 = n(this.toDate(), { locale: this.$L, utc: true }); + return i2 ? e2.add(this.utcOffset(), t) : e2; + }, u.local = function() { + return n(this.toDate(), { locale: this.$L, utc: false }); + }; + var r = u.parse; + u.parse = function(t2) { + t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2); + }; + var o = u.init; + u.init = function() { + if (this.$u) { + var t2 = this.$d; + this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds(); + } else + o.call(this); + }; + var a = u.utcOffset; + u.utcOffset = function(s2, f2) { + var n2 = this.$utils().u; + if (n2(s2)) + return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset; + if ("string" == typeof s2 && (s2 = function(t2) { + void 0 === t2 && (t2 = ""); + var s3 = t2.match(i); + if (!s3) + return null; + var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2]; + return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3; + }(s2), null === s2)) + return this; + var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2; + if (0 === u2) + return this.utc(f2); + var r2 = this.clone(); + if (f2) + return r2.$offset = u2, r2.$u = false, r2; + var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset(); + return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2; + }; + var h = u.format; + u.format = function(t2) { + var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : ""); + return h.call(this, i2); + }, u.valueOf = function() { + var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset()); + return this.$d.valueOf() - 6e4 * t2; + }, u.isUTC = function() { + return !!this.$u; + }, u.toISOString = function() { + return this.toDate().toISOString(); + }, u.toString = function() { + return this.toDate().toUTCString(); + }; + var l = u.toDate; + u.toDate = function(t2) { + return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this); + }; + var c = u.diff; + u.diff = function(t2, i2, e2) { + if (t2 && this.$u === t2.$u) + return c.call(this, t2, i2, e2); + var s2 = this.local(), f2 = n(t2).local(); + return c.call(s2, f2, i2, e2); + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/timezone.js +var require_timezone = __commonJS({ + "node_modules/dayjs/plugin/timezone.js"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e(); + }(exports, function() { + "use strict"; + var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {}; + return function(n, i, o) { + var r, a = /* @__PURE__ */ __name(function(t2, n2, i2) { + void 0 === i2 && (i2 = {}); + var o2 = new Date(t2), r2 = function(t3, n3) { + void 0 === n3 && (n3 = {}); + var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3]; + return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3; + }(n2, i2); + return r2.formatToParts(o2); + }, "a"), u = /* @__PURE__ */ __name(function(e2, n2) { + for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) { + var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2]; + c >= 0 && (r2[c] = parseInt(m, 10)); + } + var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2; + return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4; + }, "u"), f = i.prototype; + f.tz = function(t2, e2) { + void 0 === t2 && (t2 = r); + var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2; + if (!Number(s2)) + n2 = this.utcOffset(0, e2); + else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) { + var m = n2.utcOffset(); + n2 = n2.add(i2 - m, "minute"); + } + return n2.$x.$timezone = t2, n2; + }, f.offsetName = function(t2) { + var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) { + return "timezonename" === t3.type.toLowerCase(); + }); + return n2 && n2.value; + }; + var s = f.startOf; + f.startOf = function(t2, e2) { + if (!this.$x || !this.$x.$timezone) + return s.call(this, t2, e2); + var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L }); + return s.call(n2, t2, e2).tz(this.$x.$timezone, true); + }, o.tz = function(t2, e2, n2) { + var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2); + if ("string" != typeof t2) + return o(t2).tz(a2); + var s2 = function(t3, e3, n3) { + var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3); + if (e3 === o2) + return [i3, e3]; + var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3); + return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)]; + }(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c); + return d.$x.$timezone = a2, d; + }, o.tz.guess = function() { + return Intl.DateTimeFormat().resolvedOptions().timeZone; + }, o.tz.setDefault = function(t2) { + r = t2; + }; + }; + }); + } +}); + +// node_modules/dayjs/plugin/isoWeek.js +var require_isoWeek = __commonJS({ + "node_modules/dayjs/plugin/isoWeek.js"(exports, module) { + !function(e, t) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t(); + }(exports, function() { + "use strict"; + var e = "day"; + return function(t, i, s) { + var a = /* @__PURE__ */ __name(function(t2) { + return t2.add(4 - t2.isoWeekday(), e); + }, "a"), d = i.prototype; + d.isoWeekYear = function() { + return a(this).year(); + }, d.isoWeek = function(t2) { + if (!this.$utils().u(t2)) + return this.add(7 * (t2 - this.isoWeek()), e); + var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e)); + return r.diff(u, "week") + 1; + }, d.isoWeekday = function(e2) { + return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7); + }; + var n = d.startOf; + d.startOf = function(e2, t2) { + var i2 = this.$utils(), s2 = !!i2.u(t2) || t2; + return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2); + }; + }; + }); + } +}); + +// node_modules/@novadi/core/dist/token.js +var tokenCounter = 0; +function Token(description) { + const id = ++tokenCounter; + const sym = Symbol(description ? `Token(${description})` : `Token#${id}`); + const token2 = { + symbol: sym, + description, + toString() { + return description ? `Token<${description}>` : `Token<#${id}>`; + } + }; + return token2; +} +__name(Token, "Token"); + +// node_modules/@novadi/core/dist/errors.js +var _ContainerError = class _ContainerError extends Error { + constructor(message) { + super(message); + this.name = "ContainerError"; + } +}; +__name(_ContainerError, "ContainerError"); +var ContainerError = _ContainerError; +var _BindingNotFoundError = class _BindingNotFoundError extends ContainerError { + constructor(tokenDescription, path = []) { + const pathStr = path.length > 0 ? ` + Dependency path: ${path.join(" -> ")}` : ""; + super(`Token "${tokenDescription}" is not bound or registered in the container.${pathStr}`); + this.name = "BindingNotFoundError"; + } +}; +__name(_BindingNotFoundError, "BindingNotFoundError"); +var BindingNotFoundError = _BindingNotFoundError; +var _CircularDependencyError = class _CircularDependencyError extends ContainerError { + constructor(path) { + super(`Circular dependency detected: ${path.join(" -> ")}`); + this.name = "CircularDependencyError"; + } +}; +__name(_CircularDependencyError, "CircularDependencyError"); +var CircularDependencyError = _CircularDependencyError; + +// node_modules/@novadi/core/dist/autowire.js +var paramNameCache = /* @__PURE__ */ new WeakMap(); +function extractParameterNames(constructor) { + const cached = paramNameCache.get(constructor); + if (cached) { + return cached; + } + const fnStr = constructor.toString(); + const match = fnStr.match(/constructor\s*\(([^)]*)\)/) || fnStr.match(/^[^(]*\(([^)]*)\)/); + if (!match || !match[1]) { + return []; + } + const params = match[1].split(",").map((param) => param.trim()).filter((param) => param.length > 0).map((param) => { + let name = param.split(/[:=]/)[0].trim(); + name = name.replace(/^((public|private|protected|readonly)\s+)+/, ""); + if (name.includes("{") || name.includes("[")) { + return null; + } + return name; + }).filter((name) => name !== null); + paramNameCache.set(constructor, params); + return params; +} +__name(extractParameterNames, "extractParameterNames"); +function resolveByMap(constructor, container2, options) { + if (!options.map) { + throw new Error("AutoWire map strategy requires options.map to be defined"); + } + const paramNames = extractParameterNames(constructor); + const resolvedDeps = []; + for (const paramName of paramNames) { + const resolver = options.map[paramName]; + if (resolver === void 0) { + if (options.strict) { + throw new Error(`Cannot resolve parameter "${paramName}" on ${constructor.name}. Not found in autowire map. Add it to the map: .autoWire({ map: { ${paramName}: ... } })`); + } else { + resolvedDeps.push(void 0); + } + continue; + } + if (typeof resolver === "function") { + resolvedDeps.push(resolver(container2)); + } else { + resolvedDeps.push(container2.resolve(resolver)); + } + } + return resolvedDeps; +} +__name(resolveByMap, "resolveByMap"); +function resolveByMapResolvers(_constructor, container2, options) { + if (!options.mapResolvers || options.mapResolvers.length === 0) { + return []; + } + const resolvedDeps = []; + for (let i = 0; i < options.mapResolvers.length; i++) { + const resolver = options.mapResolvers[i]; + if (resolver === void 0) { + resolvedDeps.push(void 0); + } else if (typeof resolver === "function") { + resolvedDeps.push(resolver(container2)); + } else { + resolvedDeps.push(container2.resolve(resolver)); + } + } + return resolvedDeps; +} +__name(resolveByMapResolvers, "resolveByMapResolvers"); +function autowire(constructor, container2, options) { + const opts = { + by: "paramName", + strict: false, + ...options + }; + if (opts.mapResolvers && opts.mapResolvers.length > 0) { + return resolveByMapResolvers(constructor, container2, opts); + } + if (opts.map && Object.keys(opts.map).length > 0) { + return resolveByMap(constructor, container2, opts); + } + return []; +} +__name(autowire, "autowire"); + +// node_modules/@novadi/core/dist/builder.js +var _RegistrationBuilder = class _RegistrationBuilder { + constructor(pending, registrations) { + this.registrations = registrations; + this.configs = []; + this.defaultLifetime = "singleton"; + this.pending = pending; + } + /** + * Bind this registration to a token or interface type + * + * @overload + * @param {Token} token - Explicit token for binding + * + * @overload + * @param {string} typeName - Interface type name (auto-generated by transformer) + */ + as(tokenOrTypeName) { + if (tokenOrTypeName && typeof tokenOrTypeName === "object" && "symbol" in tokenOrTypeName) { + const config = { + token: tokenOrTypeName, + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } else { + const config = { + token: null, + // Will be set during build() + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: this.defaultLifetime, + interfaceType: tokenOrTypeName + }; + this.configs.push(config); + this.registrations.push(config); + return this; + } + } + /** + * Register as default implementation for an interface + * Combines as() + asDefault() + */ + asDefaultInterface(typeName) { + this.as("TInterface", typeName); + return this.asDefault(); + } + /** + * Register as a keyed interface implementation + * Combines as() + keyed() + */ + asKeyedInterface(key, typeName) { + this.as("TInterface", typeName); + return this.keyed(key); + } + /** + * Register as multiple implemented interfaces + */ + asImplementedInterfaces(tokens) { + if (tokens.length === 0) { + return this; + } + if (this.configs.length > 0) { + for (const config of this.configs) { + config.lifetime = "singleton"; + config.additionalTokens = config.additionalTokens || []; + config.additionalTokens.push(...tokens); + } + return this; + } + const firstConfig = { + token: tokens[0], + type: this.pending.type, + value: this.pending.value, + factory: this.pending.factory, + constructor: this.pending.constructor, + lifetime: "singleton" + }; + this.configs.push(firstConfig); + this.registrations.push(firstConfig); + for (let i = 1; i < tokens.length; i++) { + firstConfig.additionalTokens = firstConfig.additionalTokens || []; + firstConfig.additionalTokens.push(tokens[i]); + } + return this; + } + /** + * Set singleton lifetime (one instance for entire container) + */ + singleInstance() { + for (const config of this.configs) { + config.lifetime = "singleton"; + } + return this; + } + /** + * Set per-request lifetime (one instance per resolve call tree) + */ + instancePerRequest() { + for (const config of this.configs) { + config.lifetime = "per-request"; + } + return this; + } + /** + * Set transient lifetime (new instance every time) + * Alias for default behavior + */ + instancePerDependency() { + for (const config of this.configs) { + config.lifetime = "transient"; + } + return this; + } + /** + * Name this registration for named resolution + */ + named(name) { + for (const config of this.configs) { + config.name = name; + } + return this; + } + /** + * Key this registration for keyed resolution + */ + keyed(key) { + for (const config of this.configs) { + config.key = key; + } + return this; + } + /** + * Mark this as default registration + * Default registrations don't override existing ones + */ + asDefault() { + for (const config of this.configs) { + config.isDefault = true; + } + return this; + } + /** + * Only register if token not already registered + */ + ifNotRegistered() { + for (const config of this.configs) { + config.ifNotRegistered = true; + } + return this; + } + /** + * Specify parameter values for constructor (primitives and constants) + * Use this for non-DI parameters like strings, numbers, config values + */ + withParameters(parameters) { + for (const config of this.configs) { + config.parameterValues = parameters; + } + return this; + } + /** + * Enable automatic dependency injection (autowiring) + * Supports three strategies: paramName (default), map, and class + * + * @example + * ```ts + * // Strategy 1: paramName (default, requires non-minified code in dev) + * builder.registerType(EventBus).as().autoWire() + * + * // Strategy 2: map (minify-safe, explicit) + * builder.registerType(EventBus).as().autoWire({ + * map: { + * logger: (c) => c.resolveType() + * } + * }) + * + * // Strategy 3: class (requires build-time codegen) + * builder.registerType(EventBus).as().autoWire({ by: 'class' }) + * ``` + */ + autoWire(options) { + for (const config of this.configs) { + config.autowireOptions = options || { by: "paramName", strict: false }; + } + return this; + } +}; +__name(_RegistrationBuilder, "RegistrationBuilder"); +var RegistrationBuilder = _RegistrationBuilder; +var _Builder = class _Builder { + constructor(baseContainer) { + this.baseContainer = baseContainer; + this.registrations = []; + } + /** + * Register a class constructor + */ + registerType(constructor) { + const pending = { + type: "type", + value: null, + constructor + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a pre-created instance + */ + registerInstance(instance) { + const pending = { + type: "instance", + value: instance, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a factory function + */ + register(factory) { + const pending = { + type: "factory", + value: null, + factory, + constructor: void 0 + }; + return new RegistrationBuilder(pending, this.registrations); + } + /** + * Register a module (function that adds multiple registrations) + */ + module(moduleFunc) { + moduleFunc(this); + return this; + } + /** + * Resolve interface type names to tokens + * @internal + */ + resolveInterfaceTokens(container2) { + for (const config of this.registrations) { + if (config.interfaceType !== void 0 && !config.token) { + config.token = container2.interfaceToken(config.interfaceType); + } + } + } + /** + * Identify tokens that have non-default registrations + * @internal + */ + identifyNonDefaultTokens() { + const tokensWithNonDefaults = /* @__PURE__ */ new Set(); + for (const config of this.registrations) { + if (!config.isDefault && !config.name && config.key === void 0) { + tokensWithNonDefaults.add(config.token); + } + } + return tokensWithNonDefaults; + } + /** + * Check if registration should be skipped + * @internal + */ + shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens) { + if (config.isDefault && !config.name && config.key === void 0 && tokensWithNonDefaults.has(config.token)) { + return true; + } + if (config.ifNotRegistered && registeredTokens.has(config.token)) { + return true; + } + if (config.isDefault && registeredTokens.has(config.token)) { + return true; + } + return false; + } + /** + * Create binding token for registration (named, keyed, or multi) + * @internal + */ + createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations) { + if (config.name) { + const bindingToken = Token(`__named_${config.name}`); + namedRegistrations.set(config.name, { ...config, token: bindingToken }); + return bindingToken; + } else if (config.key !== void 0) { + const keyStr = typeof config.key === "symbol" ? config.key.toString() : config.key; + const bindingToken = Token(`__keyed_${keyStr}`); + keyedRegistrations.set(config.key, { ...config, token: bindingToken }); + return bindingToken; + } else { + if (multiRegistrations.has(config.token)) { + const bindingToken = Token(`__multi_${config.token.toString()}_${multiRegistrations.get(config.token).length}`); + multiRegistrations.get(config.token).push(bindingToken); + return bindingToken; + } else { + multiRegistrations.set(config.token, [config.token]); + return config.token; + } + } + } + /** + * Register additional interfaces for a config + * @internal + */ + registerAdditionalInterfaces(container2, config, bindingToken, registeredTokens) { + if (config.additionalTokens) { + for (const additionalToken of config.additionalTokens) { + container2.bindFactory(additionalToken, (c) => c.resolve(bindingToken), { lifetime: config.lifetime }); + registeredTokens.add(additionalToken); + } + } + } + /** + * Build the container with all registered bindings + */ + build() { + const container2 = this.baseContainer.createChild(); + this.resolveInterfaceTokens(container2); + const registeredTokens = /* @__PURE__ */ new Set(); + const namedRegistrations = /* @__PURE__ */ new Map(); + const keyedRegistrations = /* @__PURE__ */ new Map(); + const multiRegistrations = /* @__PURE__ */ new Map(); + const tokensWithNonDefaults = this.identifyNonDefaultTokens(); + for (const config of this.registrations) { + if (this.shouldSkipRegistration(config, tokensWithNonDefaults, registeredTokens)) { + continue; + } + const bindingToken = this.createBindingToken(config, namedRegistrations, keyedRegistrations, multiRegistrations); + this.applyRegistration(container2, { ...config, token: bindingToken }); + registeredTokens.add(config.token); + this.registerAdditionalInterfaces(container2, config, bindingToken, registeredTokens); + } + ; + container2.__namedRegistrations = namedRegistrations; + container2.__keyedRegistrations = keyedRegistrations; + container2.__multiRegistrations = multiRegistrations; + return container2; + } + /** + * Analyze constructor to detect dependencies + * @internal + */ + analyzeConstructor(constructor) { + const constructorStr = constructor.toString(); + const hasDependencies = /constructor\s*\([^)]+\)/.test(constructorStr); + return { hasDependencies }; + } + /** + * Create optimized factory for zero-dependency constructors + * @internal + */ + createOptimizedFactory(container2, config, options) { + if (config.lifetime === "singleton") { + const instance = new config.constructor(); + container2.bindValue(config.token, instance); + } else if (config.lifetime === "transient") { + const ctor = config.constructor; + const fastFactory = /* @__PURE__ */ __name(() => new ctor(), "fastFactory"); + container2.fastTransientCache.set(config.token, fastFactory); + container2.bindFactory(config.token, fastFactory, options); + } else { + const factory = /* @__PURE__ */ __name(() => new config.constructor(), "factory"); + container2.bindFactory(config.token, factory, options); + } + } + /** + * Create autowire factory + * @internal + */ + createAutoWireFactory(container2, config, options) { + const factory = /* @__PURE__ */ __name((c) => { + const resolvedDeps = autowire(config.constructor, c, config.autowireOptions); + return new config.constructor(...resolvedDeps); + }, "factory"); + container2.bindFactory(config.token, factory, options); + } + /** + * Create withParameters factory + * @internal + */ + createParameterFactory(container2, config, options) { + const factory = /* @__PURE__ */ __name(() => { + const values = Object.values(config.parameterValues); + return new config.constructor(...values); + }, "factory"); + container2.bindFactory(config.token, factory, options); + } + /** + * Apply type registration (class constructor) + * @internal + */ + applyTypeRegistration(container2, config, options) { + const { hasDependencies } = this.analyzeConstructor(config.constructor); + if (!hasDependencies && !config.autowireOptions && !config.parameterValues) { + this.createOptimizedFactory(container2, config, options); + return; + } + if (config.autowireOptions) { + this.createAutoWireFactory(container2, config, options); + return; + } + if (config.parameterValues) { + this.createParameterFactory(container2, config, options); + return; + } + if (hasDependencies) { + const className = config.constructor.name || "UnnamedClass"; + throw new Error(`Service "${className}" has constructor dependencies but no autowiring configuration. + +Solutions: + 1. \u2B50 Use the NovaDI transformer (recommended): + - Add "@novadi/core/unplugin" to your build config + - Transformer automatically generates .autoWire() for all dependencies + + 2. Add manual autowiring: + .autoWire({ map: { /* param: resolver */ } }) + + 3. Use a factory function: + .register((c) => new ${className}(...)) + +See docs: https://github.com/janus007/NovaDI#autowire`); + } + const factory = /* @__PURE__ */ __name(() => new config.constructor(), "factory"); + container2.bindFactory(config.token, factory, options); + } + applyRegistration(container2, config) { + const options = { lifetime: config.lifetime }; + switch (config.type) { + case "instance": + container2.bindValue(config.token, config.value); + break; + case "factory": + container2.bindFactory(config.token, config.factory, options); + break; + case "type": + this.applyTypeRegistration(container2, config, options); + break; + } + } +}; +__name(_Builder, "Builder"); +var Builder = _Builder; + +// node_modules/@novadi/core/dist/container.js +function isDisposable(obj) { + return obj && typeof obj.dispose === "function"; +} +__name(isDisposable, "isDisposable"); +var _ResolutionContext = class _ResolutionContext { + constructor() { + this.resolvingStack = /* @__PURE__ */ new Set(); + this.perRequestCache = /* @__PURE__ */ new Map(); + } + isResolving(token2) { + return this.resolvingStack.has(token2); + } + enterResolve(token2) { + this.resolvingStack.add(token2); + } + exitResolve(token2) { + this.resolvingStack.delete(token2); + this.path = void 0; + } + getPath() { + if (!this.path) { + this.path = Array.from(this.resolvingStack).map((t) => t.toString()); + } + return [...this.path]; + } + cachePerRequest(token2, instance) { + this.perRequestCache.set(token2, instance); + } + getPerRequest(token2) { + return this.perRequestCache.get(token2); + } + hasPerRequest(token2) { + return this.perRequestCache.has(token2); + } + /** + * Reset context for reuse in object pool + * Performance: Reusing contexts avoids heap allocations + */ + reset() { + this.resolvingStack.clear(); + this.perRequestCache.clear(); + this.path = void 0; + } +}; +__name(_ResolutionContext, "ResolutionContext"); +var ResolutionContext = _ResolutionContext; +var _ResolutionContextPool = class _ResolutionContextPool { + constructor() { + this.pool = []; + this.maxSize = 10; + } + acquire() { + const context = this.pool.pop(); + if (context) { + context.reset(); + return context; + } + return new ResolutionContext(); + } + release(context) { + if (this.pool.length < this.maxSize) { + this.pool.push(context); + } + } +}; +__name(_ResolutionContextPool, "ResolutionContextPool"); +var ResolutionContextPool = _ResolutionContextPool; +var _Container = class _Container { + constructor(parent) { + this.bindings = /* @__PURE__ */ new Map(); + this.singletonCache = /* @__PURE__ */ new Map(); + this.singletonOrder = []; + this.interfaceRegistry = /* @__PURE__ */ new Map(); + this.interfaceTokenCache = /* @__PURE__ */ new Map(); + this.fastTransientCache = /* @__PURE__ */ new Map(); + this.ultraFastSingletonCache = /* @__PURE__ */ new Map(); + this.parent = parent; + } + /** + * Bind a pre-created value to a token + */ + bindValue(token2, value) { + this.bindings.set(token2, { + type: "value", + lifetime: "singleton", + value, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a factory function to a token + */ + bindFactory(token2, factory, options) { + this.bindings.set(token2, { + type: "factory", + lifetime: options?.lifetime || "transient", + factory, + dependencies: options?.dependencies, + constructor: void 0 + }); + this.invalidateBindingCache(); + } + /** + * Bind a class constructor to a token + */ + bindClass(token2, constructor, options) { + const binding = { + type: "class", + lifetime: options?.lifetime || "transient", + constructor, + dependencies: options?.dependencies + }; + this.bindings.set(token2, binding); + this.invalidateBindingCache(); + if (binding.lifetime === "transient" && (!binding.dependencies || binding.dependencies.length === 0)) { + this.fastTransientCache.set(token2, () => new constructor()); + } + } + /** + * Resolve a dependency synchronously + * Performance optimized with multiple fast paths + */ + resolve(token2) { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) { + return cached; + } + if (this.currentContext) { + return this.resolveWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return this.resolveWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * SPECIALIZED: Ultra-fast singleton resolve (no safety checks) + * Use ONLY when you're 100% sure the token is a registered singleton + * @internal For performance-critical paths only + */ + resolveSingletonUnsafe(token2) { + return this.ultraFastSingletonCache.get(token2) ?? this.singletonCache.get(token2); + } + /** + * SPECIALIZED: Fast transient resolve for zero-dependency classes + * Skips all context creation and circular dependency checks + * @internal For performance-critical paths only + */ + resolveTransientSimple(token2) { + const factory = this.fastTransientCache.get(token2); + if (factory) { + return factory(); + } + return this.resolve(token2); + } + /** + * SPECIALIZED: Batch resolve multiple dependencies at once + * More efficient than multiple individual resolves + */ + resolveBatch(tokens) { + const wasResolving = !!this.currentContext; + const context = this.currentContext || _Container.contextPool.acquire(); + if (!wasResolving) { + this.currentContext = context; + } + try { + const results = tokens.map((token2) => { + const cached = this.tryGetFromCaches(token2); + if (cached !== void 0) + return cached; + return this.resolveWithContext(token2, context); + }); + return results; + } finally { + if (!wasResolving) { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + } + /** + * Resolve a dependency asynchronously (supports async factories) + */ + async resolveAsync(token2) { + if (this.currentContext) { + return this.resolveAsyncWithContext(token2, this.currentContext); + } + const context = _Container.contextPool.acquire(); + this.currentContext = context; + try { + return await this.resolveAsyncWithContext(token2, context); + } finally { + this.currentContext = void 0; + _Container.contextPool.release(context); + } + } + /** + * Try to get instance from all cache levels + * Returns undefined if not cached + * @internal + */ + tryGetFromCaches(token2) { + const ultraFast = this.ultraFastSingletonCache.get(token2); + if (ultraFast !== void 0) { + return ultraFast; + } + if (this.singletonCache.has(token2)) { + const cached = this.singletonCache.get(token2); + this.ultraFastSingletonCache.set(token2, cached); + return cached; + } + const fastFactory = this.fastTransientCache.get(token2); + if (fastFactory) { + return fastFactory(); + } + return void 0; + } + /** + * Cache instance based on lifetime strategy + * @internal + */ + cacheInstance(token2, instance, lifetime, context) { + if (lifetime === "singleton") { + this.singletonCache.set(token2, instance); + this.singletonOrder.push(token2); + this.ultraFastSingletonCache.set(token2, instance); + } else if (lifetime === "per-request" && context) { + context.cachePerRequest(token2, instance); + } + } + /** + * Validate and get binding with circular dependency check + * Returns binding or throws error + * @internal + */ + validateAndGetBinding(token2, context) { + if (context.isResolving(token2)) { + throw new CircularDependencyError([...context.getPath(), token2.toString()]); + } + const binding = this.getBinding(token2); + if (!binding) { + throw new BindingNotFoundError(token2.toString(), context.getPath()); + } + return binding; + } + /** + * Instantiate from binding synchronously + * @internal + */ + instantiateBindingSync(binding, token2, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + const result = binding.factory(this); + if (result instanceof Promise) { + throw new Error(`Async factory detected for ${token2.toString()}. Use resolveAsync() instead.`); + } + return result; + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = deps.map((dep) => this.resolveWithContext(dep, context)); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Instantiate from binding asynchronously + * @internal + */ + async instantiateBindingAsync(binding, context) { + switch (binding.type) { + case "value": + return binding.value; + case "factory": + return await Promise.resolve(binding.factory(this)); + case "class": + const deps = binding.dependencies || []; + const resolvedDeps = await Promise.all(deps.map((dep) => this.resolveAsyncWithContext(dep, context))); + return new binding.constructor(...resolvedDeps); + case "inline-class": + return new binding.constructor(); + default: + throw new Error(`Unknown binding type: ${binding.type}`); + } + } + /** + * Create a child container that inherits bindings from this container + */ + createChild() { + return new _Container(this); + } + /** + * Dispose all singleton instances in reverse registration order + */ + async dispose() { + const errors = []; + for (let i = this.singletonOrder.length - 1; i >= 0; i--) { + const token2 = this.singletonOrder[i]; + const instance = this.singletonCache.get(token2); + if (instance && isDisposable(instance)) { + try { + await instance.dispose(); + } catch (error) { + errors.push(error); + } + } + } + this.singletonCache.clear(); + this.singletonOrder.length = 0; + } + /** + * Create a fluent builder for registering dependencies + */ + builder() { + return new Builder(this); + } + /** + * Resolve a named service + */ + resolveNamed(name) { + const namedRegistrations = this.__namedRegistrations; + if (!namedRegistrations) { + throw new Error(`Named service "${name}" not found. No named registrations exist.`); + } + const config = namedRegistrations.get(name); + if (!config) { + throw new Error(`Named service "${name}" not found`); + } + return this.resolve(config.token); + } + /** + * Resolve a keyed service + */ + resolveKeyed(key) { + const keyedRegistrations = this.__keyedRegistrations; + if (!keyedRegistrations) { + throw new Error(`Keyed service not found. No keyed registrations exist.`); + } + const config = keyedRegistrations.get(key); + if (!config) { + const keyStr = typeof key === "symbol" ? key.toString() : `"${key}"`; + throw new Error(`Keyed service ${keyStr} not found`); + } + return this.resolve(config.token); + } + /** + * Resolve all registrations for a token + */ + resolveAll(token2) { + const multiRegistrations = this.__multiRegistrations; + if (!multiRegistrations) { + return []; + } + const tokens = multiRegistrations.get(token2); + if (!tokens || tokens.length === 0) { + return []; + } + return tokens.map((t) => this.resolve(t)); + } + /** + * Get registry information for debugging/visualization + * Returns array of binding information + */ + getRegistry() { + const registry = []; + this.bindings.forEach((binding, token2) => { + registry.push({ + token: token2.description || token2.symbol.toString(), + type: binding.type, + lifetime: binding.lifetime, + dependencies: binding.dependencies?.map((d) => d.description || d.symbol.toString()) + }); + }); + return registry; + } + /** + * Get or create a token for an interface type + * Uses a type name hash as key for the interface registry + */ + interfaceToken(typeName) { + const key = typeName || `Interface_${Math.random().toString(36).substr(2, 9)}`; + if (this.interfaceRegistry.has(key)) { + return this.interfaceRegistry.get(key); + } + if (this.parent) { + const parentToken = this.parent.interfaceToken(key); + return parentToken; + } + const token2 = Token(key); + this.interfaceRegistry.set(key, token2); + return token2; + } + /** + * Resolve a dependency by interface type without explicit token + */ + resolveType(typeName) { + const key = typeName || ""; + let token2 = this.interfaceTokenCache.get(key); + if (!token2) { + token2 = this.interfaceToken(typeName); + this.interfaceTokenCache.set(key, token2); + } + return this.resolve(token2); + } + /** + * Resolve a keyed interface + */ + resolveTypeKeyed(key, _typeName) { + return this.resolveKeyed(key); + } + /** + * Resolve all registrations for an interface type + */ + resolveTypeAll(typeName) { + const token2 = this.interfaceToken(typeName); + return this.resolveAll(token2); + } + /** + * Internal: Resolve with context for circular dependency detection + */ + resolveWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = this.instantiateBindingSync(binding, token2, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Internal: Async resolve with context + */ + async resolveAsyncWithContext(token2, context) { + const binding = this.validateAndGetBinding(token2, context); + if (binding.lifetime === "per-request" && context.hasPerRequest(token2)) { + return context.getPerRequest(token2); + } + if (binding.lifetime === "singleton" && this.singletonCache.has(token2)) { + return this.singletonCache.get(token2); + } + context.enterResolve(token2); + try { + const instance = await this.instantiateBindingAsync(binding, context); + this.cacheInstance(token2, instance, binding.lifetime, context); + return instance; + } finally { + context.exitResolve(token2); + } + } + /** + * Get binding from this container or parent chain + * Performance optimized: Uses flat cache to avoid recursive parent lookups + */ + getBinding(token2) { + if (!this.bindingCache) { + this.buildBindingCache(); + } + return this.bindingCache.get(token2); + } + /** + * Build flat cache of all bindings including parent chain + * This converts O(n) parent chain traversal to O(1) lookup + */ + buildBindingCache() { + this.bindingCache = /* @__PURE__ */ new Map(); + let current = this; + while (current) { + current.bindings.forEach((binding, token2) => { + if (!this.bindingCache.has(token2)) { + this.bindingCache.set(token2, binding); + } + }); + current = current.parent; + } + } + /** + * Invalidate binding cache when new bindings are added + * Called by bindValue, bindFactory, bindClass + */ + invalidateBindingCache() { + this.bindingCache = void 0; + this.ultraFastSingletonCache.clear(); + } +}; +__name(_Container, "Container"); +var Container = _Container; +Container.contextPool = new ResolutionContextPool(); + +// src/v2/features/date/DateRenderer.ts +var _DateRenderer = class _DateRenderer { + constructor(dateService) { + this.dateService = dateService; + this.type = "date"; + } + render(context) { + const dates = context.filter["date"] || []; + const resourceIds = context.filter["resource"] || []; + const dateGrouping = context.groupings?.find((g) => g.type === "date"); + const hideHeader = dateGrouping?.hideHeader === true; + const iterations = resourceIds.length || 1; + let columnCount = 0; + for (let r = 0; r < iterations; r++) { + const resourceId = resourceIds[r]; + for (const dateStr of dates) { + const date = this.dateService.parseISO(dateStr); + const segments = { date: dateStr }; + if (resourceId) + segments.resource = resourceId; + const columnKey = this.dateService.buildColumnKey(segments); + const header = document.createElement("swp-day-header"); + header.dataset.date = dateStr; + header.dataset.columnKey = columnKey; + if (resourceId) { + header.dataset.resourceId = resourceId; + } + if (hideHeader) { + header.dataset.hidden = "true"; + } + header.innerHTML = ` + ${this.dateService.getDayName(date, "short")} + ${date.getDate()} + `; + context.headerContainer.appendChild(header); + const column = document.createElement("swp-day-column"); + column.dataset.date = dateStr; + column.dataset.columnKey = columnKey; + if (resourceId) { + column.dataset.resourceId = resourceId; + } + column.innerHTML = ""; + context.columnContainer.appendChild(column); + columnCount++; + } + } + const container2 = context.columnContainer.closest("swp-calendar-container"); + if (container2) { + container2.style.setProperty("--grid-columns", String(columnCount)); + } + } +}; +__name(_DateRenderer, "DateRenderer"); +var DateRenderer = _DateRenderer; + +// src/v2/core/DateService.ts +var import_dayjs = __toESM(require_dayjs_min(), 1); +var import_utc = __toESM(require_utc(), 1); +var import_timezone = __toESM(require_timezone(), 1); +var import_isoWeek = __toESM(require_isoWeek(), 1); +import_dayjs.default.extend(import_utc.default); +import_dayjs.default.extend(import_timezone.default); +import_dayjs.default.extend(import_isoWeek.default); +var _DateService = class _DateService { + constructor(config, baseDate) { + this.config = config; + this.timezone = config.timezone; + this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)(); + } + /** + * Set a fixed base date (useful for demos with static mock data) + */ + setBaseDate(date) { + this.baseDate = (0, import_dayjs.default)(date); + } + /** + * Get the current base date (either fixed or today) + */ + getBaseDate() { + return this.baseDate.toDate(); + } + parseISO(isoString) { + return (0, import_dayjs.default)(isoString).toDate(); + } + getDayName(date, format = "short") { + return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date); + } + getWeekDates(offset = 0, days = 7) { + const monday = this.baseDate.startOf("week").add(1, "day").add(offset, "week"); + return Array.from({ length: days }, (_, i) => monday.add(i, "day").format("YYYY-MM-DD")); + } + /** + * Get dates for specific weekdays within a week + * @param offset - Week offset from base date (0 = current week) + * @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday) + * @returns Array of date strings in YYYY-MM-DD format + */ + getWorkWeekDates(offset, workDays) { + const monday = this.baseDate.startOf("week").add(1, "day").add(offset, "week"); + return workDays.map((isoDay) => { + const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1; + return monday.add(daysFromMonday, "day").format("YYYY-MM-DD"); + }); + } + // ============================================ + // FORMATTING + // ============================================ + formatTime(date, showSeconds = false) { + const pattern = showSeconds ? "HH:mm:ss" : "HH:mm"; + return (0, import_dayjs.default)(date).format(pattern); + } + formatTimeRange(start, end) { + return `${this.formatTime(start)} - ${this.formatTime(end)}`; + } + formatDate(date) { + return (0, import_dayjs.default)(date).format("YYYY-MM-DD"); + } + getDateKey(date) { + return this.formatDate(date); + } + // ============================================ + // COLUMN KEY + // ============================================ + /** + * Build a uniform columnKey from grouping segments + * Handles any combination of date, resource, team, etc. + * + * @example + * buildColumnKey({ date: '2025-12-09' }) → "2025-12-09" + * buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001" + */ + buildColumnKey(segments) { + const date = segments.date; + const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v); + return date ? [date, ...others].join(":") : others.join(":"); + } + /** + * Parse a columnKey back into segments + * Assumes format: "date:resource:..." or just "date" + */ + parseColumnKey(columnKey) { + const parts = columnKey.split(":"); + return { + date: parts[0], + resource: parts[1] + }; + } + /** + * Extract dateKey from columnKey (first segment) + */ + getDateFromColumnKey(columnKey) { + return columnKey.split(":")[0]; + } + // ============================================ + // TIME CALCULATIONS + // ============================================ + timeToMinutes(timeString) { + const parts = timeString.split(":").map(Number); + const hours = parts[0] || 0; + const minutes = parts[1] || 0; + return hours * 60 + minutes; + } + minutesToTime(totalMinutes) { + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm"); + } + getMinutesSinceMidnight(date) { + const d = (0, import_dayjs.default)(date); + return d.hour() * 60 + d.minute(); + } + // ============================================ + // UTC CONVERSIONS + // ============================================ + toUTC(localDate) { + return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString(); + } + fromUTC(utcString) { + return import_dayjs.default.utc(utcString).tz(this.timezone).toDate(); + } + // ============================================ + // DATE CREATION + // ============================================ + createDateAtTime(baseDate, timeString) { + const totalMinutes = this.timeToMinutes(timeString); + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate(); + } + getISOWeekDay(date) { + return (0, import_dayjs.default)(date).isoWeekday(); + } +}; +__name(_DateService, "DateService"); +var DateService = _DateService; + +// src/v2/core/BaseGroupingRenderer.ts +var _BaseGroupingRenderer = class _BaseGroupingRenderer { + /** + * Main render method - handles common logic + */ + async render(context) { + const allowedIds = context.filter[this.type] || []; + if (allowedIds.length === 0) + return; + const entities = await this.getEntities(allowedIds); + const dateCount = context.filter["date"]?.length || 1; + const childIds = context.childType ? context.filter[context.childType] || [] : []; + for (const entity of entities) { + const entityChildIds = context.parentChildMap?.[entity.id] || []; + const childCount = entityChildIds.filter((id) => childIds.includes(id)).length; + const colspan = childCount * dateCount; + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + header.style.setProperty(this.config.colspanVar, String(colspan)); + this.renderHeader(entity, header, context); + context.headerContainer.appendChild(header); + } + } + /** + * Override this method for custom header rendering + * Default: just sets textContent to display name + */ + renderHeader(entity, header, _context) { + header.textContent = this.getDisplayName(entity); + } + /** + * Helper to render a single entity header. + * Can be used by subclasses that override render() but want consistent header creation. + */ + createHeader(entity, context) { + const header = document.createElement(this.config.elementTag); + header.dataset[this.config.idAttribute] = entity.id; + this.renderHeader(entity, header, context); + return header; + } +}; +__name(_BaseGroupingRenderer, "BaseGroupingRenderer"); +var BaseGroupingRenderer = _BaseGroupingRenderer; + +// src/v2/features/resource/ResourceRenderer.ts +var _ResourceRenderer = class _ResourceRenderer extends BaseGroupingRenderer { + constructor(resourceService) { + super(); + this.resourceService = resourceService; + this.type = "resource"; + this.config = { + elementTag: "swp-resource-header", + idAttribute: "resourceId", + colspanVar: "--resource-cols" + }; + } + getEntities(ids) { + return this.resourceService.getByIds(ids); + } + getDisplayName(entity) { + return entity.displayName; + } + /** + * Override render to handle: + * 1. Special ordering when parentChildMap exists (resources grouped by parent) + * 2. Different colspan calculation (just dateCount, not childCount * dateCount) + */ + async render(context) { + const resourceIds = context.filter["resource"] || []; + const dateCount = context.filter["date"]?.length || 1; + let orderedResourceIds; + if (context.parentChildMap) { + orderedResourceIds = []; + for (const childIds of Object.values(context.parentChildMap)) { + for (const childId of childIds) { + if (resourceIds.includes(childId)) { + orderedResourceIds.push(childId); + } + } + } + } else { + orderedResourceIds = resourceIds; + } + const resources = await this.getEntities(orderedResourceIds); + const resourceMap = new Map(resources.map((r) => [r.id, r])); + for (const resourceId of orderedResourceIds) { + const resource = resourceMap.get(resourceId); + if (!resource) + continue; + const header = this.createHeader(resource, context); + header.style.gridColumn = `span ${dateCount}`; + context.headerContainer.appendChild(header); + } + } +}; +__name(_ResourceRenderer, "ResourceRenderer"); +var ResourceRenderer = _ResourceRenderer; + +// src/v2/features/team/TeamRenderer.ts +var _TeamRenderer = class _TeamRenderer extends BaseGroupingRenderer { + constructor(teamService) { + super(); + this.teamService = teamService; + this.type = "team"; + this.config = { + elementTag: "swp-team-header", + idAttribute: "teamId", + colspanVar: "--team-cols" + }; + } + getEntities(ids) { + return this.teamService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_TeamRenderer, "TeamRenderer"); +var TeamRenderer = _TeamRenderer; + +// src/v2/features/department/DepartmentRenderer.ts +var _DepartmentRenderer = class _DepartmentRenderer extends BaseGroupingRenderer { + constructor(departmentService) { + super(); + this.departmentService = departmentService; + this.type = "department"; + this.config = { + elementTag: "swp-department-header", + idAttribute: "departmentId", + colspanVar: "--department-cols" + }; + } + getEntities(ids) { + return this.departmentService.getByIds(ids); + } + getDisplayName(entity) { + return entity.name; + } +}; +__name(_DepartmentRenderer, "DepartmentRenderer"); +var DepartmentRenderer = _DepartmentRenderer; + +// src/v2/core/RenderBuilder.ts +function buildPipeline(renderers) { + return { + async run(context) { + for (const renderer of renderers) { + await renderer.render(context); + } + } + }; +} +__name(buildPipeline, "buildPipeline"); + +// src/v2/core/FilterTemplate.ts +var _FilterTemplate = class _FilterTemplate { + constructor(dateService, entityResolver) { + this.dateService = dateService; + this.entityResolver = entityResolver; + this.fields = []; + } + /** + * Tilføj felt til template + * @param idProperty - Property-navn (bruges på både event og column.dataset) + * @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start) + */ + addField(idProperty, derivedFrom) { + this.fields.push({ idProperty, derivedFrom }); + return this; + } + /** + * Parse dot-notation string into components + * @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' } + */ + parseDotNotation(idProperty) { + if (!idProperty.includes(".")) + return null; + const [entityType, property] = idProperty.split("."); + return { + entityType, + property, + foreignKey: entityType + "Id" + // Convention: resource → resourceId + }; + } + /** + * Get dataset key for column lookup + * For dot-notation 'resource.teamId', we look for 'teamId' in dataset + */ + getDatasetKey(idProperty) { + const dotNotation = this.parseDotNotation(idProperty); + if (dotNotation) { + return dotNotation.property; + } + return idProperty; + } + /** + * Byg nøgle fra kolonne + * Læser værdier fra column.dataset[idProperty] + * For dot-notation, uses the property part (resource.teamId → teamId) + */ + buildKeyFromColumn(column) { + return this.fields.map((f) => { + const key = this.getDatasetKey(f.idProperty); + return column.dataset[key] || ""; + }).join(":"); + } + /** + * Byg nøgle fra event + * Læser værdier fra event[idProperty] eller udleder fra derivedFrom + * For dot-notation, resolves via EntityResolver + */ + buildKeyFromEvent(event) { + const eventRecord = event; + return this.fields.map((f) => { + const dotNotation = this.parseDotNotation(f.idProperty); + if (dotNotation) { + return this.resolveDotNotation(eventRecord, dotNotation); + } + if (f.derivedFrom) { + const sourceValue = eventRecord[f.derivedFrom]; + if (sourceValue instanceof Date) { + return this.dateService.getDateKey(sourceValue); + } + return String(sourceValue || ""); + } + return String(eventRecord[f.idProperty] || ""); + }).join(":"); + } + /** + * Resolve dot-notation reference via EntityResolver + */ + resolveDotNotation(eventRecord, dotNotation) { + if (!this.entityResolver) { + console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`); + return ""; + } + const foreignId = eventRecord[dotNotation.foreignKey]; + if (!foreignId) + return ""; + const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId)); + if (!entity) + return ""; + return String(entity[dotNotation.property] || ""); + } + /** + * Match event mod kolonne + */ + matches(event, column) { + return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column); + } +}; +__name(_FilterTemplate, "FilterTemplate"); +var FilterTemplate = _FilterTemplate; + +// src/v2/core/CalendarOrchestrator.ts +var _CalendarOrchestrator = class _CalendarOrchestrator { + constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) { + this.allRenderers = allRenderers; + this.eventRenderer = eventRenderer; + this.scheduleRenderer = scheduleRenderer; + this.headerDrawerRenderer = headerDrawerRenderer; + this.dateService = dateService; + this.entityServices = entityServices; + } + async render(viewConfig, container2) { + const headerContainer = container2.querySelector("swp-calendar-header"); + const columnContainer = container2.querySelector("swp-day-columns"); + if (!headerContainer || !columnContainer) { + throw new Error("Missing swp-calendar-header or swp-day-columns"); + } + const filter = {}; + for (const grouping of viewConfig.groupings) { + filter[grouping.type] = grouping.values; + } + const filterTemplate = new FilterTemplate(this.dateService); + for (const grouping of viewConfig.groupings) { + if (grouping.idProperty) { + filterTemplate.addField(grouping.idProperty, grouping.derivedFrom); + } + } + const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter); + const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType }; + headerContainer.innerHTML = ""; + columnContainer.innerHTML = ""; + const levels = viewConfig.groupings.map((g) => g.type).join(" "); + headerContainer.dataset.levels = levels; + const activeRenderers = this.selectRenderers(viewConfig); + const pipeline = buildPipeline(activeRenderers); + await pipeline.run(context); + await this.scheduleRenderer.render(container2, filter); + await this.eventRenderer.render(container2, filter, filterTemplate); + await this.headerDrawerRenderer.render(container2, filter, filterTemplate); + } + selectRenderers(viewConfig) { + const types = viewConfig.groupings.map((g) => g.type); + return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0); + } + /** + * Resolve belongsTo relations to build parent-child map + * e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] } + * Also returns the childType (the grouping type that has belongsTo) + */ + async resolveBelongsTo(groupings, filter) { + const childGrouping = groupings.find((g) => g.belongsTo); + if (!childGrouping?.belongsTo) + return {}; + const [entityType, property] = childGrouping.belongsTo.split("."); + if (!entityType || !property) + return {}; + const parentIds = filter[entityType] || []; + if (parentIds.length === 0) + return {}; + const service = this.entityServices.find((s) => s.entityType.toLowerCase() === entityType); + if (!service) + return {}; + const allEntities = await service.getAll(); + const entities = allEntities.filter((e) => parentIds.includes(e.id)); + const map = {}; + for (const entity of entities) { + const entityRecord = entity; + const children = entityRecord[property] || []; + map[entityRecord.id] = children; + } + return { parentChildMap: map, childType: childGrouping.type }; + } +}; +__name(_CalendarOrchestrator, "CalendarOrchestrator"); +var CalendarOrchestrator = _CalendarOrchestrator; + +// src/v2/core/NavigationAnimator.ts +var _NavigationAnimator = class _NavigationAnimator { + constructor(headerTrack, contentTrack) { + this.headerTrack = headerTrack; + this.contentTrack = contentTrack; + } + async slide(direction, renderFn) { + const out = direction === "left" ? "-100%" : "100%"; + const into = direction === "left" ? "100%" : "-100%"; + await this.animateOut(out); + await renderFn(); + await this.animateIn(into); + } + async animateOut(translate) { + await Promise.all([ + this.headerTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished, + this.contentTrack.animate([{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }], { duration: 200, easing: "ease-in" }).finished + ]); + } + async animateIn(translate) { + await Promise.all([ + this.headerTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished, + this.contentTrack.animate([{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }], { duration: 200, easing: "ease-out" }).finished + ]); + } +}; +__name(_NavigationAnimator, "NavigationAnimator"); +var NavigationAnimator = _NavigationAnimator; + +// src/v2/core/CalendarEvents.ts +var CalendarEvents = { + // Command events (host → calendar) + CMD_NAVIGATE_PREV: "calendar:cmd:navigate:prev", + CMD_NAVIGATE_NEXT: "calendar:cmd:navigate:next", + CMD_DRAWER_TOGGLE: "calendar:cmd:drawer:toggle", + CMD_RENDER: "calendar:cmd:render", + CMD_WORKWEEK_CHANGE: "calendar:cmd:workweek:change", + CMD_VIEW_UPDATE: "calendar:cmd:view:update" +}; + +// src/v2/core/CalendarApp.ts +var _CalendarApp = class _CalendarApp { + constructor(orchestrator, timeAxisRenderer, dateService, scrollManager, headerDrawerManager, dragDropManager, edgeScrollManager, resizeManager, headerDrawerRenderer, eventPersistenceManager, settingsService, viewConfigService, eventBus) { + this.orchestrator = orchestrator; + this.timeAxisRenderer = timeAxisRenderer; + this.dateService = dateService; + this.scrollManager = scrollManager; + this.headerDrawerManager = headerDrawerManager; + this.dragDropManager = dragDropManager; + this.edgeScrollManager = edgeScrollManager; + this.resizeManager = resizeManager; + this.headerDrawerRenderer = headerDrawerRenderer; + this.eventPersistenceManager = eventPersistenceManager; + this.settingsService = settingsService; + this.viewConfigService = viewConfigService; + this.eventBus = eventBus; + this.weekOffset = 0; + this.currentViewId = "simple"; + this.workweekPreset = null; + this.groupingOverrides = /* @__PURE__ */ new Map(); + } + async init(container2) { + this.container = container2; + const gridSettings = await this.settingsService.getGridSettings(); + if (!gridSettings) { + throw new Error("GridSettings not found"); + } + this.workweekPreset = await this.settingsService.getDefaultWorkweekPreset(); + this.animator = new NavigationAnimator(container2.querySelector("swp-header-track"), container2.querySelector("swp-content-track")); + this.timeAxisRenderer.render(container2.querySelector("#time-axis"), gridSettings.dayStartHour, gridSettings.dayEndHour); + this.scrollManager.init(container2); + this.headerDrawerManager.init(container2); + this.dragDropManager.init(container2); + this.resizeManager.init(container2); + const scrollableContent = container2.querySelector("swp-scrollable-content"); + this.edgeScrollManager.init(scrollableContent); + this.setupEventListeners(); + this.emitStatus("ready"); + } + setupEventListeners() { + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_PREV, () => { + this.handleNavigatePrev(); + }); + this.eventBus.on(CalendarEvents.CMD_NAVIGATE_NEXT, () => { + this.handleNavigateNext(); + }); + this.eventBus.on(CalendarEvents.CMD_DRAWER_TOGGLE, () => { + this.headerDrawerManager.toggle(); + }); + this.eventBus.on(CalendarEvents.CMD_RENDER, (e) => { + const { viewId } = e.detail; + this.handleRenderCommand(viewId); + }); + this.eventBus.on(CalendarEvents.CMD_WORKWEEK_CHANGE, (e) => { + const { presetId } = e.detail; + this.handleWorkweekChange(presetId); + }); + this.eventBus.on(CalendarEvents.CMD_VIEW_UPDATE, (e) => { + const { type, values } = e.detail; + this.handleViewUpdate(type, values); + }); + } + async handleRenderCommand(viewId) { + this.currentViewId = viewId; + await this.render(); + this.emitStatus("rendered", { viewId }); + } + async handleNavigatePrev() { + this.weekOffset--; + await this.animator.slide("right", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleNavigateNext() { + this.weekOffset++; + await this.animator.slide("left", () => this.render()); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async handleWorkweekChange(presetId) { + const preset = await this.settingsService.getWorkweekPreset(presetId); + if (preset) { + this.workweekPreset = preset; + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + } + async handleViewUpdate(type, values) { + this.groupingOverrides.set(type, values); + await this.render(); + this.emitStatus("rendered", { viewId: this.currentViewId }); + } + async render() { + const storedConfig = await this.viewConfigService.getById(this.currentViewId); + if (!storedConfig) { + this.emitStatus("error", { message: `ViewConfig not found: ${this.currentViewId}` }); + return; + } + const workDays = this.workweekPreset?.workDays || [1, 2, 3, 4, 5]; + const dates = this.currentViewId === "day" ? this.dateService.getWeekDates(this.weekOffset, 1) : this.dateService.getWorkWeekDates(this.weekOffset, workDays); + const viewConfig = { + ...storedConfig, + groupings: storedConfig.groupings.map((g) => { + if (g.type === "date") { + return { ...g, values: dates }; + } + const override = this.groupingOverrides.get(g.type); + if (override) { + return { ...g, values: override }; + } + return g; + }) + }; + await this.orchestrator.render(viewConfig, this.container); + } + emitStatus(status, detail) { + this.container.dispatchEvent(new CustomEvent(`calendar:status:${status}`, { + detail, + bubbles: true + })); + } +}; +__name(_CalendarApp, "CalendarApp"); +var CalendarApp = _CalendarApp; + +// src/v2/features/timeaxis/TimeAxisRenderer.ts +var _TimeAxisRenderer = class _TimeAxisRenderer { + render(container2, startHour = 6, endHour = 20) { + container2.innerHTML = ""; + for (let hour = startHour; hour <= endHour; hour++) { + const marker = document.createElement("swp-hour-marker"); + marker.textContent = `${hour.toString().padStart(2, "0")}:00`; + container2.appendChild(marker); + } + } +}; +__name(_TimeAxisRenderer, "TimeAxisRenderer"); +var TimeAxisRenderer = _TimeAxisRenderer; + +// src/v2/core/ScrollManager.ts +var _ScrollManager = class _ScrollManager { + init(container2) { + this.scrollableContent = container2.querySelector("swp-scrollable-content"); + this.timeAxisContent = container2.querySelector("swp-time-axis-content"); + this.calendarHeader = container2.querySelector("swp-calendar-header"); + this.headerDrawer = container2.querySelector("swp-header-drawer"); + this.headerViewport = container2.querySelector("swp-header-viewport"); + this.headerSpacer = container2.querySelector("swp-header-spacer"); + this.scrollableContent.addEventListener("scroll", () => this.onScroll()); + this.resizeObserver = new ResizeObserver(() => this.syncHeaderSpacerHeight()); + this.resizeObserver.observe(this.headerViewport); + this.syncHeaderSpacerHeight(); + } + syncHeaderSpacerHeight() { + const computedHeight = getComputedStyle(this.headerViewport).height; + this.headerSpacer.style.height = computedHeight; + } + onScroll() { + const { scrollTop, scrollLeft } = this.scrollableContent; + this.timeAxisContent.style.transform = `translateY(-${scrollTop}px)`; + this.calendarHeader.style.transform = `translateX(-${scrollLeft}px)`; + this.headerDrawer.style.transform = `translateX(-${scrollLeft}px)`; + } +}; +__name(_ScrollManager, "ScrollManager"); +var ScrollManager = _ScrollManager; + +// src/v2/core/HeaderDrawerManager.ts +var _HeaderDrawerManager = class _HeaderDrawerManager { + constructor() { + this.expanded = false; + this.currentRows = 0; + this.rowHeight = 25; + this.duration = 200; + } + init(container2) { + this.drawer = container2.querySelector("swp-header-drawer"); + if (!this.drawer) + console.error("HeaderDrawerManager: swp-header-drawer not found"); + } + toggle() { + this.expanded ? this.collapse() : this.expand(); + } + /** + * Expand drawer to single row (legacy support) + */ + expand() { + this.expandToRows(1); + } + /** + * Expand drawer to fit specified number of rows + */ + expandToRows(rowCount) { + const targetHeight = rowCount * this.rowHeight; + const currentHeight = this.expanded ? this.currentRows * this.rowHeight : 0; + if (this.expanded && this.currentRows === rowCount) + return; + this.currentRows = rowCount; + this.expanded = true; + this.animate(currentHeight, targetHeight); + } + collapse() { + if (!this.expanded) + return; + const currentHeight = this.currentRows * this.rowHeight; + this.expanded = false; + this.currentRows = 0; + this.animate(currentHeight, 0); + } + animate(from, to) { + const keyframes = [ + { height: `${from}px` }, + { height: `${to}px` } + ]; + const options = { + duration: this.duration, + easing: "ease", + fill: "forwards" + }; + this.drawer.animate(keyframes, options); + } + isExpanded() { + return this.expanded; + } + getRowCount() { + return this.currentRows; + } +}; +__name(_HeaderDrawerManager, "HeaderDrawerManager"); +var HeaderDrawerManager = _HeaderDrawerManager; + +// src/v2/demo/MockStores.ts +var _MockTeamStore = class _MockTeamStore { + constructor() { + this.type = "team"; + this.teams = [ + { id: "alpha", name: "Team Alpha" }, + { id: "beta", name: "Team Beta" } + ]; + } + getByIds(ids) { + return this.teams.filter((t) => ids.includes(t.id)); + } +}; +__name(_MockTeamStore, "MockTeamStore"); +var MockTeamStore = _MockTeamStore; +var _MockResourceStore = class _MockResourceStore { + constructor() { + this.type = "resource"; + this.resources = [ + { id: "alice", name: "Alice", teamId: "alpha" }, + { id: "bob", name: "Bob", teamId: "alpha" }, + { id: "carol", name: "Carol", teamId: "beta" }, + { id: "dave", name: "Dave", teamId: "beta" } + ]; + } + getByIds(ids) { + return this.resources.filter((r) => ids.includes(r.id)); + } +}; +__name(_MockResourceStore, "MockResourceStore"); +var MockResourceStore = _MockResourceStore; + +// src/v2/demo/DemoApp.ts +var _DemoApp = class _DemoApp { + constructor(indexedDBContext, dataSeeder, auditService, calendarApp, dateService, resourceService, eventBus) { + this.indexedDBContext = indexedDBContext; + this.dataSeeder = dataSeeder; + this.auditService = auditService; + this.calendarApp = calendarApp; + this.dateService = dateService; + this.resourceService = resourceService; + this.eventBus = eventBus; + this.currentView = "simple"; + } + async init() { + this.dateService.setBaseDate(/* @__PURE__ */ new Date("2025-12-08")); + await this.indexedDBContext.initialize(); + console.log("[DemoApp] IndexedDB initialized"); + await this.dataSeeder.seedIfEmpty(); + console.log("[DemoApp] Data seeding complete"); + this.container = document.querySelector("swp-calendar-container"); + await this.calendarApp.init(this.container); + console.log("[DemoApp] CalendarApp initialized"); + this.setupNavigation(); + this.setupDrawerToggle(); + this.setupViewSwitching(); + this.setupWorkweekSelector(); + await this.setupResourceSelector(); + this.setupStatusListeners(); + this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: this.currentView }); + } + setupNavigation() { + document.getElementById("btn-prev").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_PREV); + }; + document.getElementById("btn-next").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_NEXT); + }; + } + setupViewSwitching() { + const chips = document.querySelectorAll(".view-chip"); + chips.forEach((chip) => { + chip.addEventListener("click", () => { + chips.forEach((c) => c.classList.remove("active")); + chip.classList.add("active"); + const view = chip.dataset.view; + if (view) { + this.currentView = view; + this.updateSelectorVisibility(); + this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: view }); + } + }); + }); + } + updateSelectorVisibility() { + const selector = document.querySelector("swp-resource-selector"); + const showSelector = this.currentView === "picker" || this.currentView === "day"; + selector?.classList.toggle("hidden", !showSelector); + } + setupDrawerToggle() { + document.getElementById("btn-drawer").onclick = () => { + this.eventBus.emit(CalendarEvents.CMD_DRAWER_TOGGLE); + }; + } + setupWorkweekSelector() { + const workweekSelect = document.getElementById("workweek-select"); + workweekSelect?.addEventListener("change", () => { + const presetId = workweekSelect.value; + this.eventBus.emit(CalendarEvents.CMD_WORKWEEK_CHANGE, { presetId }); + }); + } + async setupResourceSelector() { + const resources = await this.resourceService.getAll(); + const container2 = document.querySelector(".resource-checkboxes"); + if (!container2) + return; + container2.innerHTML = ""; + resources.forEach((r) => { + const label = document.createElement("label"); + label.innerHTML = ` + + ${r.displayName} + `; + container2.appendChild(label); + }); + container2.addEventListener("change", () => { + const checked = container2.querySelectorAll("input:checked"); + const values = Array.from(checked).map((cb) => cb.value); + this.eventBus.emit(CalendarEvents.CMD_VIEW_UPDATE, { type: "resource", values }); + }); + } + setupStatusListeners() { + this.container.addEventListener("calendar:status:ready", () => { + console.log("[DemoApp] Calendar ready"); + }); + this.container.addEventListener("calendar:status:rendered", (e) => { + console.log("[DemoApp] Calendar rendered:", e.detail.viewId); + }); + this.container.addEventListener("calendar:status:error", (e) => { + console.error("[DemoApp] Calendar error:", e.detail.message); + }); + } +}; +__name(_DemoApp, "DemoApp"); +var DemoApp = _DemoApp; + +// src/v2/core/EventBus.ts +var _EventBus = class _EventBus { + constructor() { + this.eventLog = []; + this.debug = false; + this.listeners = /* @__PURE__ */ new Set(); + this.logConfig = { + calendar: true, + grid: true, + event: true, + scroll: true, + navigation: true, + view: true, + default: true + }; + } + /** + * Subscribe to an event via DOM addEventListener + */ + on(eventType, handler, options) { + document.addEventListener(eventType, handler, options); + this.listeners.add({ eventType, handler, options }); + return () => this.off(eventType, handler); + } + /** + * Subscribe to an event once + */ + once(eventType, handler) { + return this.on(eventType, handler, { once: true }); + } + /** + * Unsubscribe from an event + */ + off(eventType, handler) { + document.removeEventListener(eventType, handler); + for (const listener of this.listeners) { + if (listener.eventType === eventType && listener.handler === handler) { + this.listeners.delete(listener); + break; + } + } + } + /** + * Emit an event via DOM CustomEvent + */ + emit(eventType, detail = {}) { + if (!eventType) { + return false; + } + const event = new CustomEvent(eventType, { + detail: detail ?? {}, + bubbles: true, + cancelable: true + }); + if (this.debug) { + this.logEventWithGrouping(eventType, detail); + } + this.eventLog.push({ + type: eventType, + detail: detail ?? {}, + timestamp: Date.now() + }); + return !document.dispatchEvent(event); + } + /** + * Log event with console grouping + */ + logEventWithGrouping(eventType, _detail) { + const category = this.extractCategory(eventType); + if (!this.logConfig[category]) { + return; + } + this.getCategoryStyle(category); + } + /** + * Extract category from event type + */ + extractCategory(eventType) { + if (!eventType) { + return "unknown"; + } + if (eventType.includes(":")) { + return eventType.split(":")[0]; + } + const lowerType = eventType.toLowerCase(); + if (lowerType.includes("grid") || lowerType.includes("rendered")) + return "grid"; + if (lowerType.includes("event") || lowerType.includes("sync")) + return "event"; + if (lowerType.includes("scroll")) + return "scroll"; + if (lowerType.includes("nav") || lowerType.includes("date")) + return "navigation"; + if (lowerType.includes("view")) + return "view"; + return "default"; + } + /** + * Get styling for different categories + */ + getCategoryStyle(category) { + const styles = { + calendar: { emoji: "\u{1F4C5}", color: "#2196F3" }, + grid: { emoji: "\u{1F4CA}", color: "#4CAF50" }, + event: { emoji: "\u{1F4CC}", color: "#FF9800" }, + scroll: { emoji: "\u{1F4DC}", color: "#9C27B0" }, + navigation: { emoji: "\u{1F9ED}", color: "#F44336" }, + view: { emoji: "\u{1F441}", color: "#00BCD4" }, + default: { emoji: "\u{1F4E2}", color: "#607D8B" } + }; + return styles[category] || styles.default; + } + /** + * Configure logging for specific categories + */ + setLogConfig(config) { + this.logConfig = { ...this.logConfig, ...config }; + } + /** + * Get current log configuration + */ + getLogConfig() { + return { ...this.logConfig }; + } + /** + * Get event history + */ + getEventLog(eventType) { + if (eventType) { + return this.eventLog.filter((e) => e.type === eventType); + } + return this.eventLog; + } + /** + * Enable/disable debug mode + */ + setDebug(enabled) { + this.debug = enabled; + } +}; +__name(_EventBus, "EventBus"); +var EventBus = _EventBus; + +// src/v2/storage/IndexedDBContext.ts +var _IndexedDBContext = class _IndexedDBContext { + constructor(stores) { + this.db = null; + this.initialized = false; + this.stores = stores; + } + /** + * Initialize and open the database + */ + async initialize() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(_IndexedDBContext.DB_NAME, _IndexedDBContext.DB_VERSION); + request.onerror = () => { + reject(new Error(`Failed to open IndexedDB: ${request.error}`)); + }; + request.onsuccess = () => { + this.db = request.result; + this.initialized = true; + resolve(); + }; + request.onupgradeneeded = (event) => { + const db = event.target.result; + this.stores.forEach((store) => { + if (!db.objectStoreNames.contains(store.storeName)) { + store.create(db); + } + }); + }; + }); + } + /** + * Check if database is initialized + */ + isInitialized() { + return this.initialized; + } + /** + * Get IDBDatabase instance + */ + getDatabase() { + if (!this.db) { + throw new Error("IndexedDB not initialized. Call initialize() first."); + } + return this.db; + } + /** + * Close database connection + */ + close() { + if (this.db) { + this.db.close(); + this.db = null; + this.initialized = false; + } + } + /** + * Delete entire database (for testing/reset) + */ + static async deleteDatabase() { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(_IndexedDBContext.DB_NAME); + request.onsuccess = () => resolve(); + request.onerror = () => reject(new Error(`Failed to delete database: ${request.error}`)); + }); + } +}; +__name(_IndexedDBContext, "IndexedDBContext"); +var IndexedDBContext = _IndexedDBContext; +IndexedDBContext.DB_NAME = "CalendarV2DB"; +IndexedDBContext.DB_VERSION = 4; + +// src/v2/storage/events/EventStore.ts +var _EventStore = class _EventStore { + constructor() { + this.storeName = _EventStore.STORE_NAME; + } + /** + * Create the events ObjectStore with indexes + */ + create(db) { + const store = db.createObjectStore(_EventStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("start", "start", { unique: false }); + store.createIndex("end", "end", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("customerId", "customerId", { unique: false }); + store.createIndex("bookingId", "bookingId", { unique: false }); + store.createIndex("startEnd", ["start", "end"], { unique: false }); + } +}; +__name(_EventStore, "EventStore"); +var EventStore = _EventStore; +EventStore.STORE_NAME = "events"; + +// src/v2/storage/events/EventSerialization.ts +var _EventSerialization = class _EventSerialization { + /** + * Serialize event for IndexedDB storage + */ + static serialize(event) { + return { + ...event, + start: event.start instanceof Date ? event.start.toISOString() : event.start, + end: event.end instanceof Date ? event.end.toISOString() : event.end + }; + } + /** + * Deserialize event from IndexedDB storage + */ + static deserialize(data) { + return { + ...data, + start: typeof data.start === "string" ? new Date(data.start) : data.start, + end: typeof data.end === "string" ? new Date(data.end) : data.end + }; + } +}; +__name(_EventSerialization, "EventSerialization"); +var EventSerialization = _EventSerialization; + +// src/v2/storage/SyncPlugin.ts +var _SyncPlugin = class _SyncPlugin { + constructor(service) { + this.service = service; + } + /** + * Mark entity as successfully synced + */ + async markAsSynced(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "synced"; + await this.service.save(entity); + } + } + /** + * Mark entity as sync error + */ + async markAsError(id) { + const entity = await this.service.get(id); + if (entity) { + entity.syncStatus = "error"; + await this.service.save(entity); + } + } + /** + * Get current sync status for an entity + */ + async getSyncStatus(id) { + const entity = await this.service.get(id); + return entity ? entity.syncStatus : null; + } + /** + * Get entities by sync status using IndexedDB index + */ + async getBySyncStatus(syncStatus) { + return new Promise((resolve, reject) => { + const transaction = this.service.db.transaction([this.service.storeName], "readonly"); + const store = transaction.objectStore(this.service.storeName); + const index = store.index("syncStatus"); + const request = index.getAll(syncStatus); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.service.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`)); + }; + }); + } +}; +__name(_SyncPlugin, "SyncPlugin"); +var SyncPlugin = _SyncPlugin; + +// src/v2/constants/CoreEvents.ts +var CoreEvents = { + // Lifecycle events + INITIALIZED: "core:initialized", + READY: "core:ready", + DESTROYED: "core:destroyed", + // View events + VIEW_CHANGED: "view:changed", + VIEW_RENDERED: "view:rendered", + // Navigation events + DATE_CHANGED: "nav:date-changed", + NAVIGATION_COMPLETED: "nav:navigation-completed", + // Data events + DATA_LOADING: "data:loading", + DATA_LOADED: "data:loaded", + DATA_ERROR: "data:error", + // Grid events + GRID_RENDERED: "grid:rendered", + GRID_CLICKED: "grid:clicked", + // Event management + EVENT_CREATED: "event:created", + EVENT_UPDATED: "event:updated", + EVENT_DELETED: "event:deleted", + EVENT_SELECTED: "event:selected", + // Event drag-drop + EVENT_DRAG_START: "event:drag-start", + EVENT_DRAG_MOVE: "event:drag-move", + EVENT_DRAG_END: "event:drag-end", + EVENT_DRAG_CANCEL: "event:drag-cancel", + EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change", + // Header drag (timed → header conversion) + EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header", + EVENT_DRAG_MOVE_HEADER: "event:drag-move-header", + EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header", + // Event resize + EVENT_RESIZE_START: "event:resize-start", + EVENT_RESIZE_END: "event:resize-end", + // Edge scroll + EDGE_SCROLL_TICK: "edge-scroll:tick", + EDGE_SCROLL_STARTED: "edge-scroll:started", + EDGE_SCROLL_STOPPED: "edge-scroll:stopped", + // System events + ERROR: "system:error", + // Sync events + SYNC_STARTED: "sync:started", + SYNC_COMPLETED: "sync:completed", + SYNC_FAILED: "sync:failed", + // Entity events - for audit and sync + ENTITY_SAVED: "entity:saved", + ENTITY_DELETED: "entity:deleted", + // Audit events + AUDIT_LOGGED: "audit:logged", + // Rendering events + EVENTS_RENDERED: "events:rendered" +}; + +// node_modules/json-diff-ts/dist/index.js +function arrayDifference(first, second) { + const secondSet = new Set(second); + return first.filter((item) => !secondSet.has(item)); +} +__name(arrayDifference, "arrayDifference"); +function arrayIntersection(first, second) { + const secondSet = new Set(second); + return first.filter((item) => secondSet.has(item)); +} +__name(arrayIntersection, "arrayIntersection"); +function keyBy(arr, getKey2) { + const result = {}; + for (const item of arr) { + result[String(getKey2(item))] = item; + } + return result; +} +__name(keyBy, "keyBy"); +function diff(oldObj, newObj, options = {}) { + let { embeddedObjKeys } = options; + const { keysToSkip, treatTypeChangeAsReplace } = options; + if (embeddedObjKeys instanceof Map) { + embeddedObjKeys = new Map( + Array.from(embeddedObjKeys.entries()).map(([key, value]) => [ + key instanceof RegExp ? key : key.replace(/^\./, ""), + value + ]) + ); + } else if (embeddedObjKeys) { + embeddedObjKeys = Object.fromEntries( + Object.entries(embeddedObjKeys).map(([key, value]) => [key.replace(/^\./, ""), value]) + ); + } + return compare(oldObj, newObj, [], [], { + embeddedObjKeys, + keysToSkip: keysToSkip ?? [], + treatTypeChangeAsReplace: treatTypeChangeAsReplace ?? true + }); +} +__name(diff, "diff"); +var getTypeOfObj = /* @__PURE__ */ __name((obj) => { + if (typeof obj === "undefined") { + return "undefined"; + } + if (obj === null) { + return null; + } + return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1]; +}, "getTypeOfObj"); +var getKey = /* @__PURE__ */ __name((path) => { + const left = path[path.length - 1]; + return left != null ? left : "$root"; +}, "getKey"); +var compare = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, options) => { + let changes = []; + const currentPath = keyPath.join("."); + if (options.keysToSkip?.some((skipPath) => { + if (currentPath === skipPath) { + return true; + } + if (skipPath.includes(".") && skipPath.startsWith(currentPath + ".")) { + return false; + } + if (skipPath.includes(".")) { + const skipParts = skipPath.split("."); + const currentParts = currentPath.split("."); + if (currentParts.length >= skipParts.length) { + for (let i = 0; i < skipParts.length; i++) { + if (skipParts[i] !== currentParts[i]) { + return false; + } + } + return true; + } + } + return false; + })) { + return changes; + } + const typeOfOldObj = getTypeOfObj(oldObj); + const typeOfNewObj = getTypeOfObj(newObj); + if (options.treatTypeChangeAsReplace && typeOfOldObj !== typeOfNewObj) { + if (typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + } + if (typeOfNewObj !== "undefined") { + changes.push({ type: "ADD", key: getKey(path), value: newObj }); + } + return changes; + } + if (typeOfNewObj === "undefined" && typeOfOldObj !== "undefined") { + changes.push({ type: "REMOVE", key: getKey(path), value: oldObj }); + return changes; + } + if (typeOfNewObj === "Object" && typeOfOldObj === "Array") { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + return changes; + } + if (typeOfNewObj === null) { + if (typeOfOldObj !== null) { + changes.push({ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }); + } + return changes; + } + switch (typeOfOldObj) { + case "Date": + if (typeOfNewObj === "Date") { + changes = changes.concat( + comparePrimitives(oldObj.getTime(), newObj.getTime(), path).map((x) => ({ + ...x, + value: new Date(x.value), + oldValue: new Date(x.oldValue) + })) + ); + } else { + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + break; + case "Object": { + const diffs = compareObject(oldObj, newObj, path, keyPath, false, options); + if (diffs.length) { + if (path.length) { + changes.push({ + type: "UPDATE", + key: getKey(path), + changes: diffs + }); + } else { + changes = changes.concat(diffs); + } + } + break; + } + case "Array": + changes = changes.concat(compareArray(oldObj, newObj, path, keyPath, options)); + break; + case "Function": + break; + default: + changes = changes.concat(comparePrimitives(oldObj, newObj, path)); + } + return changes; +}, "compare"); +var compareObject = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, skipPath = false, options = {}) => { + let k; + let newKeyPath; + let newPath; + if (skipPath == null) { + skipPath = false; + } + let changes = []; + const oldObjKeys = Object.keys(oldObj); + const newObjKeys = Object.keys(newObj); + const intersectionKeys = arrayIntersection(oldObjKeys, newObjKeys); + for (k of intersectionKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const diffs = compare(oldObj[k], newObj[k], newPath, newKeyPath, options); + if (diffs.length) { + changes = changes.concat(diffs); + } + } + const addedKeys = arrayDifference(newObjKeys, oldObjKeys); + for (k of addedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "ADD", + key: getKey(newPath), + value: newObj[k] + }); + } + const deletedKeys = arrayDifference(oldObjKeys, newObjKeys); + for (k of deletedKeys) { + newPath = path.concat([k]); + newKeyPath = skipPath ? keyPath : keyPath.concat([k]); + const currentPath = newKeyPath.join("."); + if (options.keysToSkip?.some((skipPath2) => currentPath === skipPath2 || currentPath.startsWith(skipPath2 + "."))) { + continue; + } + changes.push({ + type: "REMOVE", + key: getKey(newPath), + value: oldObj[k] + }); + } + return changes; +}, "compareObject"); +var compareArray = /* @__PURE__ */ __name((oldObj, newObj, path, keyPath, options) => { + if (getTypeOfObj(newObj) !== "Array") { + return [{ type: "UPDATE", key: getKey(path), value: newObj, oldValue: oldObj }]; + } + const left = getObjectKey(options.embeddedObjKeys, keyPath); + const uniqKey = left != null ? left : "$index"; + const indexedOldObj = convertArrayToObj(oldObj, uniqKey); + const indexedNewObj = convertArrayToObj(newObj, uniqKey); + const diffs = compareObject(indexedOldObj, indexedNewObj, path, keyPath, true, options); + if (diffs.length) { + return [ + { + type: "UPDATE", + key: getKey(path), + embeddedKey: typeof uniqKey === "function" && uniqKey.length === 2 ? uniqKey(newObj[0], true) : uniqKey, + changes: diffs + } + ]; + } else { + return []; + } +}, "compareArray"); +var getObjectKey = /* @__PURE__ */ __name((embeddedObjKeys, keyPath) => { + if (embeddedObjKeys != null) { + const path = keyPath.join("."); + if (embeddedObjKeys instanceof Map) { + for (const [key2, value] of embeddedObjKeys.entries()) { + if (key2 instanceof RegExp) { + if (path.match(key2)) { + return value; + } + } else if (path === key2) { + return value; + } + } + } + const key = embeddedObjKeys[path]; + if (key != null) { + return key; + } + } + return void 0; +}, "getObjectKey"); +var convertArrayToObj = /* @__PURE__ */ __name((arr, uniqKey) => { + let obj = {}; + if (uniqKey === "$value") { + arr.forEach((value) => { + obj[value] = value; + }); + } else if (uniqKey !== "$index") { + const keyFunction = typeof uniqKey === "string" ? (item) => item[uniqKey] : uniqKey; + obj = keyBy(arr, keyFunction); + } else { + for (let i = 0; i < arr.length; i++) { + const value = arr[i]; + obj[i] = value; + } + } + return obj; +}, "convertArrayToObj"); +var comparePrimitives = /* @__PURE__ */ __name((oldObj, newObj, path) => { + const changes = []; + if (oldObj !== newObj) { + changes.push({ + type: "UPDATE", + key: getKey(path), + value: newObj, + oldValue: oldObj + }); + } + return changes; +}, "comparePrimitives"); + +// src/v2/storage/BaseEntityService.ts +var _BaseEntityService = class _BaseEntityService { + constructor(context, eventBus) { + this.context = context; + this.eventBus = eventBus; + this.syncPlugin = new SyncPlugin(this); + } + get db() { + return this.context.getDatabase(); + } + /** + * Serialize entity before storing in IndexedDB + */ + serialize(entity) { + return entity; + } + /** + * Deserialize data from IndexedDB back to entity + */ + deserialize(data) { + return data; + } + /** + * Get a single entity by ID + */ + async get(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.get(id); + request.onsuccess = () => { + const data = request.result; + resolve(data ? this.deserialize(data) : null); + }; + request.onerror = () => { + reject(new Error(`Failed to get ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + /** + * Get all entities + */ + async getAll() { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const request = store.getAll(); + request.onsuccess = () => { + const data = request.result; + const entities = data.map((item) => this.deserialize(item)); + resolve(entities); + }; + request.onerror = () => { + reject(new Error(`Failed to get all ${this.entityType}s: ${request.error}`)); + }; + }); + } + /** + * Save an entity (create or update) + * Emits ENTITY_SAVED event with operation type and changes (diff for updates) + * @param entity - Entity to save + * @param silent - If true, skip event emission (used for seeding) + */ + async save(entity, silent = false) { + const entityId = entity.id; + const existingEntity = await this.get(entityId); + const isCreate = existingEntity === null; + let changes; + if (isCreate) { + changes = entity; + } else { + const existingSerialized = this.serialize(existingEntity); + const newSerialized = this.serialize(entity); + changes = diff(existingSerialized, newSerialized); + } + const serialized = this.serialize(entity); + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + request.onsuccess = () => { + if (!silent) { + const payload = { + entityType: this.entityType, + entityId, + operation: isCreate ? "create" : "update", + changes, + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_SAVED, payload); + } + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save ${this.entityType} ${entityId}: ${request.error}`)); + }; + }); + } + /** + * Delete an entity + * Emits ENTITY_DELETED event + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.delete(id); + request.onsuccess = () => { + const payload = { + entityType: this.entityType, + entityId: id, + operation: "delete", + timestamp: Date.now() + }; + this.eventBus.emit(CoreEvents.ENTITY_DELETED, payload); + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to delete ${this.entityType} ${id}: ${request.error}`)); + }; + }); + } + // Sync methods - delegate to SyncPlugin + async markAsSynced(id) { + return this.syncPlugin.markAsSynced(id); + } + async markAsError(id) { + return this.syncPlugin.markAsError(id); + } + async getSyncStatus(id) { + return this.syncPlugin.getSyncStatus(id); + } + async getBySyncStatus(syncStatus) { + return this.syncPlugin.getBySyncStatus(syncStatus); + } +}; +__name(_BaseEntityService, "BaseEntityService"); +var BaseEntityService = _BaseEntityService; + +// src/v2/storage/events/EventService.ts +var _EventService = class _EventService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = EventStore.STORE_NAME; + this.entityType = "Event"; + } + serialize(event) { + return EventSerialization.serialize(event); + } + deserialize(data) { + return EventSerialization.deserialize(data); + } + /** + * Get events within a date range + */ + async getByDateRange(start, end) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("start"); + const range = IDBKeyRange.lowerBound(start.toISOString()); + const request = index.getAll(range); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)).filter((event) => event.start <= end); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events by date range: ${request.error}`)); + }; + }); + } + /** + * Get events for a specific resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + const data = request.result; + const events = data.map((item) => this.deserialize(item)); + resolve(events); + }; + request.onerror = () => { + reject(new Error(`Failed to get events for resource ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get events for a resource within a date range + */ + async getByResourceAndDateRange(resourceId, start, end) { + const resourceEvents = await this.getByResource(resourceId); + return resourceEvents.filter((event) => event.start >= start && event.start <= end); + } +}; +__name(_EventService, "EventService"); +var EventService = _EventService; + +// src/v2/storage/resources/ResourceStore.ts +var _ResourceStore = class _ResourceStore { + constructor() { + this.storeName = _ResourceStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ResourceStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("type", "type", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("isActive", "isActive", { unique: false }); + } +}; +__name(_ResourceStore, "ResourceStore"); +var ResourceStore = _ResourceStore; +ResourceStore.STORE_NAME = "resources"; + +// src/v2/storage/resources/ResourceService.ts +var _ResourceService = class _ResourceService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ResourceStore.STORE_NAME; + this.entityType = "Resource"; + } + /** + * Get all active resources + */ + async getActive() { + const all = await this.getAll(); + return all.filter((r) => r.isActive !== false); + } + /** + * Get resources by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((r) => r !== null); + } + /** + * Get resources by type + */ + async getByType(type) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("type"); + const request = index.getAll(type); + request.onsuccess = () => { + const data = request.result; + resolve(data); + }; + request.onerror = () => { + reject(new Error(`Failed to get resources by type ${type}: ${request.error}`)); + }; + }); + } +}; +__name(_ResourceService, "ResourceService"); +var ResourceService = _ResourceService; + +// src/v2/storage/bookings/BookingStore.ts +var _BookingStore = class _BookingStore { + constructor() { + this.storeName = _BookingStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_BookingStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("customerId", "customerId", { unique: false }); + store.createIndex("status", "status", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("createdAt", "createdAt", { unique: false }); + } +}; +__name(_BookingStore, "BookingStore"); +var BookingStore = _BookingStore; +BookingStore.STORE_NAME = "bookings"; + +// src/v2/storage/bookings/BookingService.ts +var _BookingService = class _BookingService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = BookingStore.STORE_NAME; + this.entityType = "Booking"; + } + serialize(booking) { + return { + ...booking, + createdAt: booking.createdAt.toISOString() + }; + } + deserialize(data) { + const raw = data; + return { + ...raw, + createdAt: new Date(raw.createdAt) + }; + } + /** + * Get bookings for a customer + */ + async getByCustomer(customerId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("customerId"); + const request = index.getAll(customerId); + request.onsuccess = () => { + const data = request.result; + const bookings = data.map((item) => this.deserialize(item)); + resolve(bookings); + }; + request.onerror = () => { + reject(new Error(`Failed to get bookings for customer ${customerId}: ${request.error}`)); + }; + }); + } + /** + * Get bookings by status + */ + async getByStatus(status) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("status"); + const request = index.getAll(status); + request.onsuccess = () => { + const data = request.result; + const bookings = data.map((item) => this.deserialize(item)); + resolve(bookings); + }; + request.onerror = () => { + reject(new Error(`Failed to get bookings with status ${status}: ${request.error}`)); + }; + }); + } +}; +__name(_BookingService, "BookingService"); +var BookingService = _BookingService; + +// src/v2/storage/customers/CustomerStore.ts +var _CustomerStore = class _CustomerStore { + constructor() { + this.storeName = _CustomerStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_CustomerStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("name", "name", { unique: false }); + store.createIndex("phone", "phone", { unique: false }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + } +}; +__name(_CustomerStore, "CustomerStore"); +var CustomerStore = _CustomerStore; +CustomerStore.STORE_NAME = "customers"; + +// src/v2/storage/customers/CustomerService.ts +var _CustomerService = class _CustomerService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = CustomerStore.STORE_NAME; + this.entityType = "Customer"; + } + /** + * Search customers by name (case-insensitive contains) + */ + async searchByName(query) { + const all = await this.getAll(); + const lowerQuery = query.toLowerCase(); + return all.filter((c) => c.name.toLowerCase().includes(lowerQuery)); + } + /** + * Find customer by phone + */ + async getByPhone(phone) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("phone"); + const request = index.get(phone); + request.onsuccess = () => { + const data = request.result; + resolve(data ? data : null); + }; + request.onerror = () => { + reject(new Error(`Failed to find customer by phone ${phone}: ${request.error}`)); + }; + }); + } +}; +__name(_CustomerService, "CustomerService"); +var CustomerService = _CustomerService; + +// src/v2/storage/teams/TeamStore.ts +var _TeamStore = class _TeamStore { + constructor() { + this.storeName = _TeamStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_TeamStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_TeamStore, "TeamStore"); +var TeamStore = _TeamStore; +TeamStore.STORE_NAME = "teams"; + +// src/v2/storage/teams/TeamService.ts +var _TeamService = class _TeamService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = TeamStore.STORE_NAME; + this.entityType = "Team"; + } + /** + * Get teams by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((t) => t !== null); + } + /** + * Build reverse lookup: resourceId → teamId + */ + async buildResourceToTeamMap() { + const teams = await this.getAll(); + const map = {}; + for (const team of teams) { + for (const resourceId of team.resourceIds) { + map[resourceId] = team.id; + } + } + return map; + } +}; +__name(_TeamService, "TeamService"); +var TeamService = _TeamService; + +// src/v2/storage/departments/DepartmentStore.ts +var _DepartmentStore = class _DepartmentStore { + constructor() { + this.storeName = _DepartmentStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_DepartmentStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_DepartmentStore, "DepartmentStore"); +var DepartmentStore = _DepartmentStore; +DepartmentStore.STORE_NAME = "departments"; + +// src/v2/storage/departments/DepartmentService.ts +var _DepartmentService = class _DepartmentService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = DepartmentStore.STORE_NAME; + this.entityType = "Department"; + } + /** + * Get departments by IDs + */ + async getByIds(ids) { + if (ids.length === 0) + return []; + const results = await Promise.all(ids.map((id) => this.get(id))); + return results.filter((d) => d !== null); + } +}; +__name(_DepartmentService, "DepartmentService"); +var DepartmentService = _DepartmentService; + +// src/v2/storage/settings/SettingsStore.ts +var _SettingsStore = class _SettingsStore { + constructor() { + this.storeName = _SettingsStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_SettingsStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_SettingsStore, "SettingsStore"); +var SettingsStore = _SettingsStore; +SettingsStore.STORE_NAME = "settings"; + +// src/v2/types/SettingsTypes.ts +var SettingsIds = { + WORKWEEK: "workweek", + GRID: "grid", + TIME_FORMAT: "timeFormat", + VIEWS: "views" +}; + +// src/v2/storage/settings/SettingsService.ts +var _SettingsService = class _SettingsService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = SettingsStore.STORE_NAME; + this.entityType = "Settings"; + } + /** + * Get workweek settings + */ + async getWorkweekSettings() { + return this.get(SettingsIds.WORKWEEK); + } + /** + * Get grid settings + */ + async getGridSettings() { + return this.get(SettingsIds.GRID); + } + /** + * Get time format settings + */ + async getTimeFormatSettings() { + return this.get(SettingsIds.TIME_FORMAT); + } + /** + * Get view settings + */ + async getViewSettings() { + return this.get(SettingsIds.VIEWS); + } + /** + * Get workweek preset by ID + */ + async getWorkweekPreset(presetId) { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[presetId] || null; + } + /** + * Get the default workweek preset + */ + async getDefaultWorkweekPreset() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return null; + return settings.presets[settings.defaultPreset] || null; + } + /** + * Get all available workweek presets + */ + async getWorkweekPresets() { + const settings = await this.getWorkweekSettings(); + if (!settings) + return []; + return Object.values(settings.presets); + } +}; +__name(_SettingsService, "SettingsService"); +var SettingsService = _SettingsService; + +// src/v2/storage/viewconfigs/ViewConfigStore.ts +var _ViewConfigStore = class _ViewConfigStore { + constructor() { + this.storeName = _ViewConfigStore.STORE_NAME; + } + create(db) { + db.createObjectStore(_ViewConfigStore.STORE_NAME, { keyPath: "id" }); + } +}; +__name(_ViewConfigStore, "ViewConfigStore"); +var ViewConfigStore = _ViewConfigStore; +ViewConfigStore.STORE_NAME = "viewconfigs"; + +// src/v2/storage/viewconfigs/ViewConfigService.ts +var _ViewConfigService = class _ViewConfigService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = ViewConfigStore.STORE_NAME; + this.entityType = "ViewConfig"; + } + async getById(id) { + return this.get(id); + } +}; +__name(_ViewConfigService, "ViewConfigService"); +var ViewConfigService = _ViewConfigService; + +// src/v2/storage/audit/AuditStore.ts +var _AuditStore = class _AuditStore { + constructor() { + this.storeName = "audit"; + } + create(db) { + const store = db.createObjectStore(this.storeName, { keyPath: "id" }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + store.createIndex("synced", "synced", { unique: false }); + store.createIndex("entityId", "entityId", { unique: false }); + store.createIndex("timestamp", "timestamp", { unique: false }); + } +}; +__name(_AuditStore, "AuditStore"); +var AuditStore = _AuditStore; + +// src/v2/storage/audit/AuditService.ts +var _AuditService = class _AuditService extends BaseEntityService { + constructor(context, eventBus) { + super(context, eventBus); + this.storeName = "audit"; + this.entityType = "Audit"; + this.setupEventListeners(); + } + /** + * Setup listeners for ENTITY_SAVED and ENTITY_DELETED events + */ + setupEventListeners() { + this.eventBus.on(CoreEvents.ENTITY_SAVED, (event) => { + const detail = event.detail; + this.handleEntitySaved(detail); + }); + this.eventBus.on(CoreEvents.ENTITY_DELETED, (event) => { + const detail = event.detail; + this.handleEntityDeleted(detail); + }); + } + /** + * Handle ENTITY_SAVED event - create audit entry + */ + async handleEntitySaved(payload) { + if (payload.entityType === "Audit") + return; + const auditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: payload.operation, + userId: _AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: payload.changes, + synced: false, + syncStatus: "pending" + }; + await this.save(auditEntry); + } + /** + * Handle ENTITY_DELETED event - create audit entry + */ + async handleEntityDeleted(payload) { + if (payload.entityType === "Audit") + return; + const auditEntry = { + id: crypto.randomUUID(), + entityType: payload.entityType, + entityId: payload.entityId, + operation: "delete", + userId: _AuditService.DEFAULT_USER_ID, + timestamp: payload.timestamp, + changes: { id: payload.entityId }, + // For delete, just store the ID + synced: false, + syncStatus: "pending" + }; + await this.save(auditEntry); + } + /** + * Override save to NOT trigger ENTITY_SAVED event + * Instead, emits AUDIT_LOGGED for SyncManager to listen + * + * This prevents infinite loops: + * - BaseEntityService.save() emits ENTITY_SAVED + * - AuditService listens to ENTITY_SAVED and creates audit + * - If AuditService.save() also emitted ENTITY_SAVED, it would loop + */ + async save(entity) { + const serialized = this.serialize(entity); + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(serialized); + request.onsuccess = () => { + const payload = { + auditId: entity.id, + entityType: entity.entityType, + entityId: entity.entityId, + operation: entity.operation, + timestamp: entity.timestamp + }; + this.eventBus.emit(CoreEvents.AUDIT_LOGGED, payload); + resolve(); + }; + request.onerror = () => { + reject(new Error(`Failed to save audit entry ${entity.id}: ${request.error}`)); + }; + }); + } + /** + * Override delete to NOT trigger ENTITY_DELETED event + * Audit entries should never be deleted (compliance requirement) + */ + async delete(_id) { + throw new Error("Audit entries cannot be deleted (compliance requirement)"); + } + /** + * Get pending audit entries (for sync) + */ + async getPendingAudits() { + return this.getBySyncStatus("pending"); + } + /** + * Get audit entries for a specific entity + */ + async getByEntityId(entityId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([this.storeName], "readonly"); + const store = transaction.objectStore(this.storeName); + const index = store.index("entityId"); + const request = index.getAll(entityId); + request.onsuccess = () => { + const entries = request.result; + resolve(entries); + }; + request.onerror = () => { + reject(new Error(`Failed to get audit entries for entity ${entityId}: ${request.error}`)); + }; + }); + } +}; +__name(_AuditService, "AuditService"); +var AuditService = _AuditService; +AuditService.DEFAULT_USER_ID = "00000000-0000-0000-0000-000000000001"; + +// src/v2/repositories/MockEventRepository.ts +var _MockEventRepository = class _MockEventRepository { + constructor() { + this.entityType = "Event"; + this.dataUrl = "data/mock-events.json"; + } + /** + * Fetch all events from mock JSON file + */ + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock events: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processCalendarData(rawData); + } catch (error) { + console.error("Failed to load event data:", error); + throw error; + } + } + async sendCreate(_event) { + throw new Error("MockEventRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockEventRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockEventRepository does not support sendDelete. Mock data is read-only."); + } + processCalendarData(data) { + return data.map((event) => { + if (event.type === "customer") { + if (!event.bookingId) + console.warn(`Customer event ${event.id} missing bookingId`); + if (!event.resourceId) + console.warn(`Customer event ${event.id} missing resourceId`); + if (!event.customerId) + console.warn(`Customer event ${event.id} missing customerId`); + } + return { + id: event.id, + title: event.title, + description: event.description, + start: new Date(event.start), + end: new Date(event.end), + type: event.type, + allDay: event.allDay || false, + bookingId: event.bookingId, + resourceId: event.resourceId, + customerId: event.customerId, + recurringId: event.recurringId, + metadata: event.metadata, + syncStatus: "synced" + }; + }); + } +}; +__name(_MockEventRepository, "MockEventRepository"); +var MockEventRepository = _MockEventRepository; + +// src/v2/repositories/MockResourceRepository.ts +var _MockResourceRepository = class _MockResourceRepository { + constructor() { + this.entityType = "Resource"; + this.dataUrl = "data/mock-resources.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock resources: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processResourceData(rawData); + } catch (error) { + console.error("Failed to load resource data:", error); + throw error; + } + } + async sendCreate(_resource) { + throw new Error("MockResourceRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockResourceRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockResourceRepository does not support sendDelete. Mock data is read-only."); + } + processResourceData(data) { + return data.map((resource) => ({ + id: resource.id, + name: resource.name, + displayName: resource.displayName, + type: resource.type, + avatarUrl: resource.avatarUrl, + color: resource.color, + isActive: resource.isActive, + defaultSchedule: resource.defaultSchedule, + metadata: resource.metadata, + syncStatus: "synced" + })); + } +}; +__name(_MockResourceRepository, "MockResourceRepository"); +var MockResourceRepository = _MockResourceRepository; + +// src/v2/repositories/MockBookingRepository.ts +var _MockBookingRepository = class _MockBookingRepository { + constructor() { + this.entityType = "Booking"; + this.dataUrl = "data/mock-bookings.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock bookings: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processBookingData(rawData); + } catch (error) { + console.error("Failed to load booking data:", error); + throw error; + } + } + async sendCreate(_booking) { + throw new Error("MockBookingRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockBookingRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockBookingRepository does not support sendDelete. Mock data is read-only."); + } + processBookingData(data) { + return data.map((booking) => ({ + id: booking.id, + customerId: booking.customerId, + status: booking.status, + createdAt: new Date(booking.createdAt), + services: booking.services, + totalPrice: booking.totalPrice, + tags: booking.tags, + notes: booking.notes, + syncStatus: "synced" + })); + } +}; +__name(_MockBookingRepository, "MockBookingRepository"); +var MockBookingRepository = _MockBookingRepository; + +// src/v2/repositories/MockCustomerRepository.ts +var _MockCustomerRepository = class _MockCustomerRepository { + constructor() { + this.entityType = "Customer"; + this.dataUrl = "data/mock-customers.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock customers: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processCustomerData(rawData); + } catch (error) { + console.error("Failed to load customer data:", error); + throw error; + } + } + async sendCreate(_customer) { + throw new Error("MockCustomerRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockCustomerRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockCustomerRepository does not support sendDelete. Mock data is read-only."); + } + processCustomerData(data) { + return data.map((customer) => ({ + id: customer.id, + name: customer.name, + phone: customer.phone, + email: customer.email, + metadata: customer.metadata, + syncStatus: "synced" + })); + } +}; +__name(_MockCustomerRepository, "MockCustomerRepository"); +var MockCustomerRepository = _MockCustomerRepository; + +// src/v2/repositories/MockAuditRepository.ts +var _MockAuditRepository = class _MockAuditRepository { + constructor() { + this.entityType = "Audit"; + } + async sendCreate(entity) { + await new Promise((resolve) => setTimeout(resolve, 100)); + console.log("MockAuditRepository: Audit entry synced to backend:", { + id: entity.id, + entityType: entity.entityType, + entityId: entity.entityId, + operation: entity.operation, + timestamp: new Date(entity.timestamp).toISOString() + }); + return entity; + } + async sendUpdate(_id, _entity) { + throw new Error("Audit entries cannot be updated"); + } + async sendDelete(_id) { + throw new Error("Audit entries cannot be deleted"); + } + async fetchAll() { + return []; + } + async fetchById(_id) { + return null; + } +}; +__name(_MockAuditRepository, "MockAuditRepository"); +var MockAuditRepository = _MockAuditRepository; + +// src/v2/repositories/MockTeamRepository.ts +var _MockTeamRepository = class _MockTeamRepository { + constructor() { + this.entityType = "Team"; + this.dataUrl = "data/mock-teams.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock teams: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processTeamData(rawData); + } catch (error) { + console.error("Failed to load team data:", error); + throw error; + } + } + async sendCreate(_team) { + throw new Error("MockTeamRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockTeamRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockTeamRepository does not support sendDelete. Mock data is read-only."); + } + processTeamData(data) { + return data.map((team) => ({ + id: team.id, + name: team.name, + resourceIds: team.resourceIds, + syncStatus: "synced" + })); + } +}; +__name(_MockTeamRepository, "MockTeamRepository"); +var MockTeamRepository = _MockTeamRepository; + +// src/v2/repositories/MockDepartmentRepository.ts +var _MockDepartmentRepository = class _MockDepartmentRepository { + constructor() { + this.entityType = "Department"; + this.dataUrl = "data/mock-departments.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load mock departments: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + return this.processDepartmentData(rawData); + } catch (error) { + console.error("Failed to load department data:", error); + throw error; + } + } + async sendCreate(_department) { + throw new Error("MockDepartmentRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockDepartmentRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockDepartmentRepository does not support sendDelete. Mock data is read-only."); + } + processDepartmentData(data) { + return data.map((dept) => ({ + id: dept.id, + name: dept.name, + resourceIds: dept.resourceIds, + syncStatus: "synced" + })); + } +}; +__name(_MockDepartmentRepository, "MockDepartmentRepository"); +var MockDepartmentRepository = _MockDepartmentRepository; + +// src/v2/repositories/MockSettingsRepository.ts +var _MockSettingsRepository = class _MockSettingsRepository { + constructor() { + this.entityType = "Settings"; + this.dataUrl = "data/tenant-settings.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load tenant settings: ${response.status} ${response.statusText}`); + } + const settings = await response.json(); + return settings.map((s) => ({ + ...s, + syncStatus: s.syncStatus || "synced" + })); + } catch (error) { + console.error("Failed to load tenant settings:", error); + throw error; + } + } + async sendCreate(_settings) { + throw new Error("MockSettingsRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockSettingsRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockSettingsRepository does not support sendDelete. Mock data is read-only."); + } +}; +__name(_MockSettingsRepository, "MockSettingsRepository"); +var MockSettingsRepository = _MockSettingsRepository; + +// src/v2/repositories/MockViewConfigRepository.ts +var _MockViewConfigRepository = class _MockViewConfigRepository { + constructor() { + this.entityType = "ViewConfig"; + this.dataUrl = "data/viewconfigs.json"; + } + async fetchAll() { + try { + const response = await fetch(this.dataUrl); + if (!response.ok) { + throw new Error(`Failed to load viewconfigs: ${response.status} ${response.statusText}`); + } + const rawData = await response.json(); + const configs = rawData.map((config) => ({ + ...config, + syncStatus: config.syncStatus || "synced" + })); + return configs; + } catch (error) { + console.error("Failed to load viewconfigs:", error); + throw error; + } + } + async sendCreate(_config) { + throw new Error("MockViewConfigRepository does not support sendCreate. Mock data is read-only."); + } + async sendUpdate(_id, _updates) { + throw new Error("MockViewConfigRepository does not support sendUpdate. Mock data is read-only."); + } + async sendDelete(_id) { + throw new Error("MockViewConfigRepository does not support sendDelete. Mock data is read-only."); + } +}; +__name(_MockViewConfigRepository, "MockViewConfigRepository"); +var MockViewConfigRepository = _MockViewConfigRepository; + +// src/v2/workers/DataSeeder.ts +var _DataSeeder = class _DataSeeder { + constructor(services, repositories) { + this.services = services; + this.repositories = repositories; + } + /** + * Seed all entity stores if they are empty + */ + async seedIfEmpty() { + console.log("[DataSeeder] Checking if database needs seeding..."); + try { + for (const service of this.services) { + const repository = this.repositories.find((repo) => repo.entityType === service.entityType); + if (!repository) { + console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`); + continue; + } + await this.seedEntity(service.entityType, service, repository); + } + console.log("[DataSeeder] Seeding complete"); + } catch (error) { + console.error("[DataSeeder] Seeding failed:", error); + throw error; + } + } + async seedEntity(entityType, service, repository) { + const existing = await service.getAll(); + if (existing.length > 0) { + console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`); + return; + } + console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`); + const data = await repository.fetchAll(); + console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`); + for (const entity of data) { + await service.save(entity, true); + } + console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`); + } +}; +__name(_DataSeeder, "DataSeeder"); +var DataSeeder = _DataSeeder; + +// src/v2/utils/PositionUtils.ts +function calculateEventPosition(start, end, config) { + const startMinutes = start.getHours() * 60 + start.getMinutes(); + const endMinutes = end.getHours() * 60 + end.getMinutes(); + const dayStartMinutes = config.dayStartHour * 60; + const minuteHeight = config.hourHeight / 60; + const top = (startMinutes - dayStartMinutes) * minuteHeight; + const height = (endMinutes - startMinutes) * minuteHeight; + return { top, height }; +} +__name(calculateEventPosition, "calculateEventPosition"); +function minutesToPixels(minutes, config) { + return minutes / 60 * config.hourHeight; +} +__name(minutesToPixels, "minutesToPixels"); +function pixelsToMinutes(pixels, config) { + return pixels / config.hourHeight * 60; +} +__name(pixelsToMinutes, "pixelsToMinutes"); +function snapToGrid(pixels, config) { + const snapPixels = minutesToPixels(config.snapInterval, config); + return Math.round(pixels / snapPixels) * snapPixels; +} +__name(snapToGrid, "snapToGrid"); + +// src/v2/features/event/EventLayoutEngine.ts +function eventsOverlap(a, b) { + return a.start < b.end && a.end > b.start; +} +__name(eventsOverlap, "eventsOverlap"); +function eventsWithinThreshold(a, b, thresholdMinutes) { + const thresholdMs = thresholdMinutes * 60 * 1e3; + const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime()); + if (startToStartDiff <= thresholdMs) + return true; + const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime(); + if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs) + return true; + const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime(); + if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs) + return true; + return false; +} +__name(eventsWithinThreshold, "eventsWithinThreshold"); +function findOverlapGroups(events) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsOverlap(member, candidate)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findOverlapGroups, "findOverlapGroups"); +function findGridCandidates(events, thresholdMinutes) { + if (events.length === 0) + return []; + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const used = /* @__PURE__ */ new Set(); + const groups = []; + for (const event of sorted) { + if (used.has(event.id)) + continue; + const group = [event]; + used.add(event.id); + let expanded = true; + while (expanded) { + expanded = false; + for (const candidate of sorted) { + if (used.has(candidate.id)) + continue; + const connects = group.some((member) => eventsWithinThreshold(member, candidate, thresholdMinutes)); + if (connects) { + group.push(candidate); + used.add(candidate.id); + expanded = true; + } + } + } + groups.push(group); + } + return groups; +} +__name(findGridCandidates, "findGridCandidates"); +function calculateStackLevels(events) { + const levels = /* @__PURE__ */ new Map(); + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + for (const event of sorted) { + let maxOverlappingLevel = -1; + for (const [id, level] of levels) { + const other = events.find((e) => e.id === id); + if (other && eventsOverlap(event, other)) { + maxOverlappingLevel = Math.max(maxOverlappingLevel, level); + } + } + levels.set(event.id, maxOverlappingLevel + 1); + } + return levels; +} +__name(calculateStackLevels, "calculateStackLevels"); +function allocateColumns(events) { + const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime()); + const columns = []; + for (const event of sorted) { + let placed = false; + for (const column of columns) { + const canFit = !column.some((e) => eventsOverlap(event, e)); + if (canFit) { + column.push(event); + placed = true; + break; + } + } + if (!placed) { + columns.push([event]); + } + } + return columns; +} +__name(allocateColumns, "allocateColumns"); +function calculateColumnLayout(events, config) { + const thresholdMinutes = config.gridStartThresholdMinutes ?? 10; + const result = { + grids: [], + stacked: [] + }; + if (events.length === 0) + return result; + const overlapGroups = findOverlapGroups(events); + for (const overlapGroup of overlapGroups) { + if (overlapGroup.length === 1) { + result.stacked.push({ + event: overlapGroup[0], + stackLevel: 0 + }); + continue; + } + const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes); + const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]); + if (largestGridCandidate.length === overlapGroup.length) { + const columns = allocateColumns(overlapGroup); + const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]); + const position = calculateEventPosition(earliest.start, earliest.end, config); + result.grids.push({ + events: overlapGroup, + columns, + stackLevel: 0, + position: { top: position.top } + }); + } else { + const levels = calculateStackLevels(overlapGroup); + for (const event of overlapGroup) { + result.stacked.push({ + event, + stackLevel: levels.get(event.id) ?? 0 + }); + } + } + } + return result; +} +__name(calculateColumnLayout, "calculateColumnLayout"); + +// src/v2/features/event/EventRenderer.ts +var _EventRenderer = class _EventRenderer { + constructor(eventService, dateService, gridConfig, eventBus) { + this.eventService = eventService; + this.dateService = dateService; + this.gridConfig = gridConfig; + this.eventBus = eventBus; + this.container = null; + this.setupListeners(); + } + /** + * Setup listeners for drag-drop and update events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = e.detail; + this.handleColumnChange(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => { + const payload = e.detail; + this.updateDragTimestamp(payload); + }); + this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => { + const payload = e.detail; + this.handleEventUpdated(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeaveHeader(payload); + }); + } + /** + * Handle EVENT_DRAG_END - remove element if dropped in header + */ + handleDragEnd(payload) { + if (payload.target === "header") { + const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`); + element?.remove(); + } + } + /** + * Handle header item leaving header - create swp-event in grid + */ + handleDragLeaveHeader(payload) { + if (payload.source !== "header") + return; + if (!payload.targetColumn || !payload.start || !payload.end) + return; + if (payload.element) { + payload.element.classList.add("drag-ghost"); + payload.element.style.opacity = "0.3"; + payload.element.style.pointerEvents = "none"; + } + const event = { + id: payload.eventId, + title: payload.title || "", + description: "", + start: payload.start, + end: payload.end, + type: "customer", + allDay: false, + syncStatus: "pending" + }; + const element = this.createEventElement(event); + let eventsLayer = payload.targetColumn.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + payload.targetColumn.appendChild(eventsLayer); + } + eventsLayer.appendChild(element); + element.classList.add("dragging"); + } + /** + * Handle EVENT_UPDATED - re-render affected columns + */ + async handleEventUpdated(payload) { + if (payload.sourceColumnKey !== payload.targetColumnKey) { + await this.rerenderColumn(payload.sourceColumnKey); + } + await this.rerenderColumn(payload.targetColumnKey); + } + /** + * Re-render a single column with fresh data from IndexedDB + */ + async rerenderColumn(columnKey) { + const column = this.findColumn(columnKey); + if (!column) + return; + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date) + return; + const startDate = new Date(date); + const endDate = new Date(date); + endDate.setHours(23, 59, 59, 999); + const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate); + const timedEvents = events.filter((event) => !event.allDay && this.dateService.getDateKey(event.start) === date); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + } + /** + * Find a column element by columnKey + */ + findColumn(columnKey) { + if (!this.container) + return null; + return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`); + } + /** + * Handle event moving to a new column during drag + */ + handleColumnChange(payload) { + const eventsLayer = payload.newColumn.querySelector("swp-events-layer"); + if (!eventsLayer) + return; + eventsLayer.appendChild(payload.element); + payload.element.style.top = `${payload.currentY}px`; + } + /** + * Update timestamp display during drag (snapped to grid) + */ + updateDragTimestamp(payload) { + const timeEl = payload.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const snappedY = snapToGrid(payload.currentY, this.gridConfig); + const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart; + const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight; + const durationMinutes = pixelsToMinutes(height, this.gridConfig); + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(startMinutes + durationMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to a Date object (today) + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Render events for visible dates into day columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and optionally 'resource' arrays + * @param filterTemplate - Template for matching events to columns + */ + async render(container2, filter, filterTemplate) { + this.container = container2; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const dayColumns = container2.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + columns.forEach((column) => { + const columnEl = column; + const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl)); + let eventsLayer = column.querySelector("swp-events-layer"); + if (!eventsLayer) { + eventsLayer = document.createElement("swp-events-layer"); + column.appendChild(eventsLayer); + } + eventsLayer.innerHTML = ""; + const timedEvents = columnEvents.filter((event) => !event.allDay); + const layout = calculateColumnLayout(timedEvents, this.gridConfig); + layout.grids.forEach((grid) => { + const groupEl = this.renderGridGroup(grid); + eventsLayer.appendChild(groupEl); + }); + layout.stacked.forEach((item) => { + const eventEl = this.renderStackedEvent(item.event, item.stackLevel); + eventsLayer.appendChild(eventEl); + }); + }); + } + /** + * Create a single event element + * + * CLEAN approach: + * - Only data-id for lookup + * - Visible content in innerHTML only + */ + createEventElement(event) { + const element = document.createElement("swp-event"); + element.dataset.eventId = event.id; + if (event.resourceId) { + element.dataset.resourceId = event.resourceId; + } + const position = calculateEventPosition(event.start, event.end, this.gridConfig); + element.style.top = `${position.top}px`; + element.style.height = `${position.height}px`; + const colorClass = this.getColorClass(event); + if (colorClass) { + element.classList.add(colorClass); + } + element.innerHTML = ` + ${this.dateService.formatTimeRange(event.start, event.end)} + ${this.escapeHtml(event.title)} + ${event.description ? `${this.escapeHtml(event.description)}` : ""} + `; + return element; + } + /** + * Get color class based on metadata.color or event type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Escape HTML to prevent XSS + */ + escapeHtml(text) { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; + } + /** + * Render a GRID group with side-by-side columns + * Used when multiple events start at the same time + */ + renderGridGroup(layout) { + const group = document.createElement("swp-event-group"); + group.classList.add(`cols-${layout.columns.length}`); + group.style.top = `${layout.position.top}px`; + if (layout.stackLevel > 0) { + group.style.marginLeft = `${layout.stackLevel * 15}px`; + group.style.zIndex = `${100 + layout.stackLevel}`; + } + let maxBottom = 0; + for (const event of layout.events) { + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + const eventBottom = pos.top + pos.height; + if (eventBottom > maxBottom) + maxBottom = eventBottom; + } + const groupHeight = maxBottom - layout.position.top; + group.style.height = `${groupHeight}px`; + layout.columns.forEach((columnEvents) => { + const wrapper = document.createElement("div"); + wrapper.style.position = "relative"; + columnEvents.forEach((event) => { + const eventEl = this.createEventElement(event); + const pos = calculateEventPosition(event.start, event.end, this.gridConfig); + eventEl.style.top = `${pos.top - layout.position.top}px`; + eventEl.style.position = "absolute"; + eventEl.style.left = "0"; + eventEl.style.right = "0"; + wrapper.appendChild(eventEl); + }); + group.appendChild(wrapper); + }); + return group; + } + /** + * Render a STACKED event with margin-left offset + * Used for overlapping events that don't start at the same time + */ + renderStackedEvent(event, stackLevel) { + const element = this.createEventElement(event); + element.dataset.stackLink = JSON.stringify({ stackLevel }); + if (stackLevel > 0) { + element.style.marginLeft = `${stackLevel * 15}px`; + element.style.zIndex = `${100 + stackLevel}`; + } + return element; + } +}; +__name(_EventRenderer, "EventRenderer"); +var EventRenderer = _EventRenderer; + +// src/v2/features/schedule/ScheduleRenderer.ts +var _ScheduleRenderer = class _ScheduleRenderer { + constructor(scheduleService, dateService, gridConfig) { + this.scheduleService = scheduleService; + this.dateService = dateService; + this.gridConfig = gridConfig; + } + /** + * Render unavailable zones for visible columns + * @param container - Calendar container element + * @param filter - Filter with 'date' and 'resource' arrays + */ + async render(container2, filter) { + const dates = filter["date"] || []; + const resourceIds = filter["resource"] || []; + if (dates.length === 0) + return; + const dayColumns = container2.querySelector("swp-day-columns"); + if (!dayColumns) + return; + const columns = dayColumns.querySelectorAll("swp-day-column"); + for (const column of columns) { + const date = column.dataset.date; + const resourceId = column.dataset.resourceId; + if (!date || !resourceId) + continue; + let unavailableLayer = column.querySelector("swp-unavailable-layer"); + if (!unavailableLayer) { + unavailableLayer = document.createElement("swp-unavailable-layer"); + column.insertBefore(unavailableLayer, column.firstChild); + } + unavailableLayer.innerHTML = ""; + const schedule = await this.scheduleService.getScheduleForDate(resourceId, date); + this.renderUnavailableZones(unavailableLayer, schedule); + } + } + /** + * Render unavailable time zones based on schedule + */ + renderUnavailableZones(layer, schedule) { + const dayStartMinutes = this.gridConfig.dayStartHour * 60; + const dayEndMinutes = this.gridConfig.dayEndHour * 60; + const minuteHeight = this.gridConfig.hourHeight / 60; + if (schedule === null) { + const zone = this.createUnavailableZone(0, (dayEndMinutes - dayStartMinutes) * minuteHeight); + layer.appendChild(zone); + return; + } + const workStartMinutes = this.dateService.timeToMinutes(schedule.start); + const workEndMinutes = this.dateService.timeToMinutes(schedule.end); + if (workStartMinutes > dayStartMinutes) { + const top = 0; + const height = (workStartMinutes - dayStartMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + if (workEndMinutes < dayEndMinutes) { + const top = (workEndMinutes - dayStartMinutes) * minuteHeight; + const height = (dayEndMinutes - workEndMinutes) * minuteHeight; + const zone = this.createUnavailableZone(top, height); + layer.appendChild(zone); + } + } + /** + * Create an unavailable zone element + */ + createUnavailableZone(top, height) { + const zone = document.createElement("swp-unavailable-zone"); + zone.style.top = `${top}px`; + zone.style.height = `${height}px`; + return zone; + } +}; +__name(_ScheduleRenderer, "ScheduleRenderer"); +var ScheduleRenderer = _ScheduleRenderer; + +// src/v2/features/headerdrawer/HeaderDrawerRenderer.ts +var _HeaderDrawerRenderer = class _HeaderDrawerRenderer { + constructor(eventBus, gridConfig, headerDrawerManager, eventService, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.headerDrawerManager = headerDrawerManager; + this.eventService = eventService; + this.dateService = dateService; + this.currentItem = null; + this.container = null; + this.sourceElement = null; + this.wasExpandedBeforeDrag = false; + this.filterTemplate = null; + this.setupListeners(); + } + /** + * Render allDay events into the header drawer with row stacking + * @param filterTemplate - Template for matching events to columns + */ + async render(container2, filter, filterTemplate) { + this.filterTemplate = filterTemplate; + const drawer = container2.querySelector("swp-header-drawer"); + if (!drawer) + return; + const visibleDates = filter["date"] || []; + if (visibleDates.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const startDate = new Date(visibleDates[0]); + const endDate = new Date(visibleDates[visibleDates.length - 1]); + endDate.setHours(23, 59, 59, 999); + const events = await this.eventService.getByDateRange(startDate, endDate); + const allDayEvents = events.filter((event) => event.allDay !== false); + drawer.innerHTML = ""; + if (allDayEvents.length === 0) + return; + const layouts = this.calculateLayout(allDayEvents, visibleColumnKeys); + const rowCount = Math.max(1, ...layouts.map((l) => l.row)); + layouts.forEach((layout) => { + const item = this.createHeaderItem(layout); + drawer.appendChild(item); + }); + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Create a header item element from layout + */ + createHeaderItem(layout) { + const { event, columnKey, row, colStart, colEnd } = layout; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = event.id; + item.dataset.itemType = "event"; + item.dataset.start = event.start.toISOString(); + item.dataset.end = event.end.toISOString(); + item.dataset.columnKey = columnKey; + item.textContent = event.title; + const colorClass = this.getColorClass(event); + if (colorClass) + item.classList.add(colorClass); + item.style.gridArea = `${row} / ${colStart} / ${row + 1} / ${colEnd}`; + return item; + } + /** + * Calculate layout for all events with row stacking + * Uses track-based algorithm to find available rows for overlapping events + */ + calculateLayout(events, visibleColumnKeys) { + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + const layouts = []; + for (const event of events) { + const columnKey = this.buildColumnKeyFromEvent(event); + const startCol = visibleColumnKeys.indexOf(columnKey); + const endColumnKey = this.buildColumnKeyFromEvent(event, event.end); + const endCol = visibleColumnKeys.indexOf(endColumnKey); + if (startCol === -1 && endCol === -1) + continue; + const colStart = Math.max(0, startCol); + const colEnd = (endCol !== -1 ? endCol : visibleColumnKeys.length - 1) + 1; + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + layouts.push({ event, columnKey, row: row + 1, colStart: colStart + 1, colEnd: colEnd + 1 }); + } + return layouts; + } + /** + * Build columnKey from event using FilterTemplate + * Uses the same template that columns use for matching + */ + buildColumnKeyFromEvent(event, date) { + if (!this.filterTemplate) { + const dateStr = this.dateService.getDateKey(date || event.start); + return dateStr; + } + if (date && date.getTime() !== event.start.getTime()) { + const tempEvent = { ...event, start: date }; + return this.filterTemplate.buildKeyFromEvent(tempEvent); + } + return this.filterTemplate.buildKeyFromEvent(event); + } + /** + * Find available row for event spanning columns [colStart, colEnd) + */ + findAvailableRow(tracks, colStart, colEnd) { + for (let row = 0; row < tracks.length; row++) { + let available = true; + for (let c = colStart; c < colEnd; c++) { + if (tracks[row][c]) { + available = false; + break; + } + } + if (available) + return row; + } + tracks.push(new Array(tracks[0].length).fill(false)); + return tracks.length - 1; + } + /** + * Get color class based on event metadata or type + */ + getColorClass(event) { + if (event.metadata?.color) { + return `is-${event.metadata.color}`; + } + const typeColors = { + "customer": "is-blue", + "vacation": "is-green", + "break": "is-amber", + "meeting": "is-purple", + "blocked": "is-red" + }; + return typeColors[event.type] || "is-blue"; + } + /** + * Setup event listeners for drag events + */ + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_ENTER_HEADER, (e) => { + const payload = e.detail; + this.handleDragEnter(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragMove(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => { + const payload = e.detail; + this.handleDragLeave(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => { + const payload = e.detail; + this.handleDragEnd(payload); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => { + this.cleanup(); + }); + } + /** + * Handle drag entering header zone - create preview item + */ + handleDragEnter(payload) { + this.container = document.querySelector("swp-header-drawer"); + if (!this.container) + return; + this.wasExpandedBeforeDrag = this.headerDrawerManager.isExpanded(); + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.expandToRows(1); + } + this.sourceElement = payload.element; + const item = document.createElement("swp-header-item"); + item.dataset.eventId = payload.eventId; + item.dataset.itemType = payload.itemType; + item.dataset.duration = String(payload.duration); + item.dataset.columnKey = payload.sourceColumnKey; + item.textContent = payload.title; + if (payload.colorClass) { + item.classList.add(payload.colorClass); + } + item.classList.add("dragging"); + const col = payload.sourceColumnIndex + 1; + const endCol = col + payload.duration; + item.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.container.appendChild(item); + this.currentItem = item; + payload.element.style.visibility = "hidden"; + } + /** + * Handle drag moving within header - update column position + */ + handleDragMove(payload) { + if (!this.currentItem) + return; + const col = payload.columnIndex + 1; + const duration = parseInt(this.currentItem.dataset.duration || "1", 10); + const endCol = col + duration; + this.currentItem.style.gridArea = `1 / ${col} / 2 / ${endCol}`; + this.currentItem.dataset.columnKey = payload.columnKey; + } + /** + * Handle drag leaving header - cleanup for grid→header drag only + */ + handleDragLeave(payload) { + if (payload.source === "grid") { + this.cleanup(); + } + } + /** + * Handle drag end - finalize based on drop target + */ + handleDragEnd(payload) { + if (payload.target === "header") { + if (this.currentItem) { + this.currentItem.classList.remove("dragging"); + this.recalculateDrawerLayout(); + this.currentItem = null; + this.sourceElement = null; + } + } else { + const ghost = document.querySelector(`swp-header-item.drag-ghost[data-event-id="${payload.swpEvent.eventId}"]`); + ghost?.remove(); + this.recalculateDrawerLayout(); + } + } + /** + * Recalculate layout for all items currently in the drawer + * Called after drop to reposition items and adjust height + */ + recalculateDrawerLayout() { + const drawer = document.querySelector("swp-header-drawer"); + if (!drawer) + return; + const items = Array.from(drawer.querySelectorAll("swp-header-item")); + if (items.length === 0) + return; + const visibleColumnKeys = this.getVisibleColumnKeysFromDOM(); + if (visibleColumnKeys.length === 0) + return; + const itemData = items.map((item) => ({ + element: item, + columnKey: item.dataset.columnKey || "", + duration: parseInt(item.dataset.duration || "1", 10) + })); + const tracks = [new Array(visibleColumnKeys.length).fill(false)]; + for (const item of itemData) { + const startCol = visibleColumnKeys.indexOf(item.columnKey); + if (startCol === -1) + continue; + const colStart = startCol; + const colEnd = Math.min(startCol + item.duration, visibleColumnKeys.length); + const row = this.findAvailableRow(tracks, colStart, colEnd); + for (let c = colStart; c < colEnd; c++) { + tracks[row][c] = true; + } + item.element.style.gridArea = `${row + 1} / ${colStart + 1} / ${row + 2} / ${colEnd + 1}`; + } + const rowCount = tracks.length; + this.headerDrawerManager.expandToRows(rowCount); + } + /** + * Get visible column keys from DOM (preserves order for multi-resource views) + * Uses filterTemplate.buildKeyFromColumn() for consistent key format with events + */ + getVisibleColumnKeysFromDOM() { + if (!this.filterTemplate) + return []; + const columns = document.querySelectorAll("swp-day-column"); + const columnKeys = []; + columns.forEach((col) => { + const columnKey = this.filterTemplate.buildKeyFromColumn(col); + if (columnKey) + columnKeys.push(columnKey); + }); + return columnKeys; + } + /** + * Cleanup preview item and restore source visibility + */ + cleanup() { + this.currentItem?.remove(); + this.currentItem = null; + if (this.sourceElement) { + this.sourceElement.style.visibility = ""; + this.sourceElement = null; + } + if (!this.wasExpandedBeforeDrag) { + this.headerDrawerManager.collapse(); + } + } +}; +__name(_HeaderDrawerRenderer, "HeaderDrawerRenderer"); +var HeaderDrawerRenderer = _HeaderDrawerRenderer; + +// src/v2/storage/schedules/ScheduleOverrideStore.ts +var _ScheduleOverrideStore = class _ScheduleOverrideStore { + constructor() { + this.storeName = _ScheduleOverrideStore.STORE_NAME; + } + create(db) { + const store = db.createObjectStore(_ScheduleOverrideStore.STORE_NAME, { keyPath: "id" }); + store.createIndex("resourceId", "resourceId", { unique: false }); + store.createIndex("date", "date", { unique: false }); + store.createIndex("resourceId_date", ["resourceId", "date"], { unique: true }); + store.createIndex("syncStatus", "syncStatus", { unique: false }); + } +}; +__name(_ScheduleOverrideStore, "ScheduleOverrideStore"); +var ScheduleOverrideStore = _ScheduleOverrideStore; +ScheduleOverrideStore.STORE_NAME = "scheduleOverrides"; + +// src/v2/storage/schedules/ScheduleOverrideService.ts +var _ScheduleOverrideService = class _ScheduleOverrideService { + constructor(context) { + this.context = context; + } + get db() { + return this.context.getDatabase(); + } + /** + * Get override for a specific resource and date + */ + async getOverride(resourceId, date) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId_date"); + const request = index.get([resourceId, date]); + request.onsuccess = () => { + resolve(request.result || null); + }; + request.onerror = () => { + reject(new Error(`Failed to get override for ${resourceId} on ${date}: ${request.error}`)); + }; + }); + } + /** + * Get all overrides for a resource + */ + async getByResource(resourceId) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readonly"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const index = store.index("resourceId"); + const request = index.getAll(resourceId); + request.onsuccess = () => { + resolve(request.result || []); + }; + request.onerror = () => { + reject(new Error(`Failed to get overrides for ${resourceId}: ${request.error}`)); + }; + }); + } + /** + * Get overrides for a date range + */ + async getByDateRange(resourceId, startDate, endDate) { + const all = await this.getByResource(resourceId); + return all.filter((o) => o.date >= startDate && o.date <= endDate); + } + /** + * Save an override + */ + async save(override) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.put(override); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to save override ${override.id}: ${request.error}`)); + }; + }); + } + /** + * Delete an override + */ + async delete(id) { + return new Promise((resolve, reject) => { + const transaction = this.db.transaction([ScheduleOverrideStore.STORE_NAME], "readwrite"); + const store = transaction.objectStore(ScheduleOverrideStore.STORE_NAME); + const request = store.delete(id); + request.onsuccess = () => resolve(); + request.onerror = () => { + reject(new Error(`Failed to delete override ${id}: ${request.error}`)); + }; + }); + } +}; +__name(_ScheduleOverrideService, "ScheduleOverrideService"); +var ScheduleOverrideService = _ScheduleOverrideService; + +// src/v2/storage/schedules/ResourceScheduleService.ts +var _ResourceScheduleService = class _ResourceScheduleService { + constructor(resourceService, overrideService, dateService) { + this.resourceService = resourceService; + this.overrideService = overrideService; + this.dateService = dateService; + } + /** + * Get effective schedule for a resource on a specific date + * + * @param resourceId - Resource ID + * @param date - Date string "YYYY-MM-DD" + * @returns ITimeSlot or null (fri/closed) + */ + async getScheduleForDate(resourceId, date) { + const override = await this.overrideService.getOverride(resourceId, date); + if (override) { + return override.schedule; + } + const resource = await this.resourceService.get(resourceId); + if (!resource || !resource.defaultSchedule) { + return null; + } + const weekDay = this.dateService.getISOWeekDay(date); + return resource.defaultSchedule[weekDay] || null; + } + /** + * Get schedules for multiple dates + * + * @param resourceId - Resource ID + * @param dates - Array of date strings "YYYY-MM-DD" + * @returns Map of date -> ITimeSlot | null + */ + async getSchedulesForDates(resourceId, dates) { + const result = /* @__PURE__ */ new Map(); + const resource = await this.resourceService.get(resourceId); + const overrides = dates.length > 0 ? await this.overrideService.getByDateRange(resourceId, dates[0], dates[dates.length - 1]) : []; + const overrideMap = new Map(overrides.map((o) => [o.date, o.schedule])); + for (const date of dates) { + if (overrideMap.has(date)) { + result.set(date, overrideMap.get(date)); + continue; + } + if (resource?.defaultSchedule) { + const weekDay = this.dateService.getISOWeekDay(date); + result.set(date, resource.defaultSchedule[weekDay] || null); + } else { + result.set(date, null); + } + } + return result; + } +}; +__name(_ResourceScheduleService, "ResourceScheduleService"); +var ResourceScheduleService = _ResourceScheduleService; + +// src/v2/types/SwpEvent.ts +var _SwpEvent = class _SwpEvent { + constructor(element, columnKey, start, end) { + this.element = element; + this.columnKey = columnKey; + this._start = start; + this._end = end; + } + /** Event ID from element.dataset.eventId */ + get eventId() { + return this.element.dataset.eventId || ""; + } + get start() { + return this._start; + } + get end() { + return this._end; + } + /** Duration in minutes */ + get durationMinutes() { + return (this._end.getTime() - this._start.getTime()) / (1e3 * 60); + } + /** Duration in milliseconds */ + get durationMs() { + return this._end.getTime() - this._start.getTime(); + } + /** + * Factory: Create SwpEvent from element + columnKey + * Reads top/height from element.style to calculate start/end + * @param columnKey - Opaque column identifier (do NOT parse - use only for matching) + * @param date - Date string (YYYY-MM-DD) for time calculations + */ + static fromElement(element, columnKey, date, gridConfig) { + const topPixels = parseFloat(element.style.top) || 0; + const heightPixels = parseFloat(element.style.height) || 0; + const startMinutesFromGrid = topPixels / gridConfig.hourHeight * 60; + const totalMinutes = gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const start = new Date(date); + start.setHours(Math.floor(totalMinutes / 60), totalMinutes % 60, 0, 0); + const durationMinutes = heightPixels / gridConfig.hourHeight * 60; + const end = new Date(start.getTime() + durationMinutes * 60 * 1e3); + return new _SwpEvent(element, columnKey, start, end); + } +}; +__name(_SwpEvent, "SwpEvent"); +var SwpEvent = _SwpEvent; + +// src/v2/managers/DragDropManager.ts +var _DragDropManager = class _DragDropManager { + constructor(eventBus, gridConfig) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dragState = null; + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + this.container = null; + this.inHeader = false; + this.DRAG_THRESHOLD = 5; + this.INTERPOLATION_FACTOR = 0.3; + this.handlePointerDown = (e) => { + const target = e.target; + if (target.closest("swp-resize-handle")) + return; + const eventElement = target.closest("swp-event"); + const headerItem = target.closest("swp-header-item"); + const draggable = eventElement || headerItem; + if (!draggable) + return; + this.mouseDownPosition = { x: e.clientX, y: e.clientY }; + this.pendingElement = draggable; + const rect = draggable.getBoundingClientRect(); + this.pendingMouseOffset = { + x: e.clientX - rect.left, + y: e.clientY - rect.top + }; + draggable.setPointerCapture(e.pointerId); + }; + this.handlePointerMove = (e) => { + if (!this.mouseDownPosition || !this.pendingElement) { + if (this.dragState) { + this.updateDragTarget(e); + } + return; + } + const deltaX = Math.abs(e.clientX - this.mouseDownPosition.x); + const deltaY = Math.abs(e.clientY - this.mouseDownPosition.y); + const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + if (distance < this.DRAG_THRESHOLD) + return; + this.initializeDrag(this.pendingElement, this.pendingMouseOffset, e); + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + }; + this.handlePointerUp = (_e) => { + this.mouseDownPosition = null; + this.pendingElement = null; + this.pendingMouseOffset = null; + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + if (this.dragState.dragSource === "header") { + this.handleHeaderItemDragEnd(); + } else { + this.handleGridEventDragEnd(); + } + this.dragState.element.classList.remove("dragging"); + this.dragState = null; + this.inHeader = false; + }; + this.animateDrag = () => { + if (!this.dragState) + return; + const diff2 = this.dragState.targetY - this.dragState.currentY; + if (Math.abs(diff2) <= 0.5) { + this.dragState.animationId = 0; + return; + } + this.dragState.currentY += diff2 * this.INTERPOLATION_FACTOR; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + if (this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + currentY: this.dragState.currentY, + columnElement: this.dragState.columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE, payload); + } + this.dragState.animationId = requestAnimationFrame(this.animateDrag); + }; + this.setupScrollListener(); + } + setupScrollListener() { + this.eventBus.on(CoreEvents.EDGE_SCROLL_TICK, (e) => { + if (!this.dragState) + return; + const { scrollDelta } = e.detail; + this.dragState.targetY += scrollDelta; + this.dragState.currentY += scrollDelta; + this.dragState.element.style.top = `${this.dragState.currentY}px`; + }); + } + /** + * Initialize drag-drop on a container element + */ + init(container2) { + this.container = container2; + container2.addEventListener("pointerdown", this.handlePointerDown); + document.addEventListener("pointermove", this.handlePointerMove); + document.addEventListener("pointerup", this.handlePointerUp); + } + /** + * Handle drag end for header items + */ + handleHeaderItemDragEnd() { + if (!this.dragState) + return; + if (!this.inHeader && this.dragState.currentColumn) { + const gridEvent = this.dragState.currentColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (gridEvent) { + const columnKey = this.dragState.currentColumn.dataset.columnKey || ""; + const date = this.dragState.currentColumn.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(gridEvent, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + } + } + /** + * Handle drag end for grid events + */ + handleGridEventDragEnd() { + if (!this.dragState || !this.dragState.columnElement) + return; + const snappedY = snapToGrid(this.dragState.currentY, this.gridConfig); + this.dragState.element.style.top = `${snappedY}px`; + this.dragState.ghostElement?.remove(); + const columnKey = this.dragState.columnElement.dataset.columnKey || ""; + const date = this.dragState.columnElement.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.dragState.element, columnKey, date, this.gridConfig); + const payload = { + swpEvent, + sourceColumnKey: this.dragState.sourceColumnKey, + target: this.inHeader ? "header" : "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_END, payload); + } + initializeDrag(element, mouseOffset, e) { + const eventId = element.dataset.eventId || ""; + const isHeaderItem = element.tagName.toLowerCase() === "swp-header-item"; + const columnElement = element.closest("swp-day-column"); + if (!isHeaderItem && !columnElement) + return; + if (isHeaderItem) { + this.initializeHeaderItemDrag(element, mouseOffset, eventId); + } else { + this.initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId); + } + } + /** + * Initialize drag for a header item (allDay event) + */ + initializeHeaderItemDrag(element, mouseOffset, eventId) { + element.classList.add("dragging"); + this.dragState = { + eventId, + element, + ghostElement: null, + // No ghost for header items + startY: 0, + mouseOffset, + columnElement: null, + currentColumn: null, + targetY: 0, + currentY: 0, + animationId: 0, + sourceColumnKey: "", + // Will be set from header item data + dragSource: "header" + }; + this.inHeader = true; + } + /** + * Initialize drag for a grid event + */ + initializeGridEventDrag(element, mouseOffset, e, columnElement, eventId) { + const elementRect = element.getBoundingClientRect(); + const columnRect = columnElement.getBoundingClientRect(); + const startY = elementRect.top - columnRect.top; + const group = element.closest("swp-event-group"); + if (group) { + const eventsLayer = columnElement.querySelector("swp-events-layer"); + if (eventsLayer) { + eventsLayer.appendChild(element); + } + } + element.style.position = "absolute"; + element.style.top = `${startY}px`; + element.style.left = "2px"; + element.style.right = "2px"; + element.style.marginLeft = "0"; + const ghostElement = element.cloneNode(true); + ghostElement.classList.add("drag-ghost"); + ghostElement.style.opacity = "0.3"; + ghostElement.style.pointerEvents = "none"; + element.parentNode?.insertBefore(ghostElement, element); + element.classList.add("dragging"); + const targetY = e.clientY - columnRect.top - mouseOffset.y; + this.dragState = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement, + currentColumn: columnElement, + targetY: Math.max(0, targetY), + currentY: startY, + animationId: 0, + sourceColumnKey: columnElement.dataset.columnKey || "", + dragSource: "grid" + }; + const payload = { + eventId, + element, + ghostElement, + startY, + mouseOffset, + columnElement + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_START, payload); + this.animateDrag(); + } + updateDragTarget(e) { + if (!this.dragState) + return; + this.checkHeaderZone(e); + if (this.inHeader) + return; + const columnAtPoint = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header" && columnAtPoint && !this.dragState.currentColumn) { + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn && this.dragState.currentColumn) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + previousColumn: this.dragState.currentColumn, + newColumn: columnAtPoint, + currentY: this.dragState.currentY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, payload); + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + if (!this.dragState.columnElement) + return; + const columnRect = this.dragState.columnElement.getBoundingClientRect(); + const targetY = e.clientY - columnRect.top - this.dragState.mouseOffset.y; + this.dragState.targetY = Math.max(0, targetY); + if (!this.dragState.animationId) { + this.animateDrag(); + } + } + /** + * Check if pointer is in header zone and emit appropriate events + */ + checkHeaderZone(e) { + if (!this.dragState) + return; + const headerViewport = document.querySelector("swp-header-viewport"); + if (!headerViewport) + return; + const rect = headerViewport.getBoundingClientRect(); + const isInHeader = e.clientY < rect.bottom; + if (isInHeader && !this.inHeader) { + this.inHeader = true; + if (this.dragState.dragSource === "grid" && this.dragState.columnElement) { + const payload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + sourceColumnIndex: this.getColumnIndex(this.dragState.columnElement), + sourceColumnKey: this.dragState.columnElement.dataset.columnKey || "", + title: this.dragState.element.querySelector("swp-event-title")?.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")), + itemType: "event", + duration: 1 + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_ENTER_HEADER, payload); + } + } else if (!isInHeader && this.inHeader) { + this.inHeader = false; + const targetColumn = this.getColumnAtPoint(e.clientX); + if (this.dragState.dragSource === "header") { + const payload = { + eventId: this.dragState.eventId, + source: "header", + element: this.dragState.element, + targetColumn: targetColumn || void 0, + start: this.dragState.element.dataset.start ? new Date(this.dragState.element.dataset.start) : void 0, + end: this.dragState.element.dataset.end ? new Date(this.dragState.element.dataset.end) : void 0, + title: this.dragState.element.textContent || "", + colorClass: [...this.dragState.element.classList].find((c) => c.startsWith("is-")) + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + if (targetColumn) { + const newElement = targetColumn.querySelector(`swp-event[data-event-id="${this.dragState.eventId}"]`); + if (newElement) { + this.dragState.element = newElement; + this.dragState.columnElement = targetColumn; + this.dragState.currentColumn = targetColumn; + this.animateDrag(); + } + } + } else { + const payload = { + eventId: this.dragState.eventId, + source: "grid" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload); + } + } else if (isInHeader) { + const column = this.getColumnAtX(e.clientX); + if (column) { + const payload = { + eventId: this.dragState.eventId, + columnIndex: this.getColumnIndex(column), + columnKey: column.dataset.columnKey || "" + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE_HEADER, payload); + } + } + } + /** + * Get column index (0-based) for a column element + */ + getColumnIndex(column) { + if (!this.container || !column) + return 0; + const columns = Array.from(this.container.querySelectorAll("swp-day-column")); + return columns.indexOf(column); + } + /** + * Get column at X coordinate (alias for getColumnAtPoint) + */ + getColumnAtX(clientX) { + return this.getColumnAtPoint(clientX); + } + /** + * Find column element at given X coordinate + */ + getColumnAtPoint(clientX) { + if (!this.container) + return null; + const columns = this.container.querySelectorAll("swp-day-column"); + for (const col of columns) { + const rect = col.getBoundingClientRect(); + if (clientX >= rect.left && clientX <= rect.right) { + return col; + } + } + return null; + } + /** + * Cancel drag and animate back to start position + */ + cancelDrag() { + if (!this.dragState) + return; + cancelAnimationFrame(this.dragState.animationId); + const { element, ghostElement, startY, eventId } = this.dragState; + element.style.transition = "top 200ms ease-out"; + element.style.top = `${startY}px`; + setTimeout(() => { + ghostElement?.remove(); + element.style.transition = ""; + element.classList.remove("dragging"); + }, 200); + const payload = { + eventId, + element, + startY + }; + this.eventBus.emit(CoreEvents.EVENT_DRAG_CANCEL, payload); + this.dragState = null; + this.inHeader = false; + } +}; +__name(_DragDropManager, "DragDropManager"); +var DragDropManager = _DragDropManager; + +// src/v2/managers/EdgeScrollManager.ts +var _EdgeScrollManager = class _EdgeScrollManager { + constructor(eventBus) { + this.eventBus = eventBus; + this.scrollableContent = null; + this.timeGrid = null; + this.draggedElement = null; + this.scrollRAF = null; + this.mouseY = 0; + this.isDragging = false; + this.isScrolling = false; + this.lastTs = 0; + this.rect = null; + this.initialScrollTop = 0; + this.OUTER_ZONE = 100; + this.INNER_ZONE = 50; + this.SLOW_SPEED = 140; + this.FAST_SPEED = 640; + this.trackMouse = (e) => { + if (this.isDragging) { + this.mouseY = e.clientY; + } + }; + this.scrollTick = (ts) => { + if (!this.isDragging || !this.scrollableContent) + return; + const dt = this.lastTs ? (ts - this.lastTs) / 1e3 : 0; + this.lastTs = ts; + this.rect ?? (this.rect = this.scrollableContent.getBoundingClientRect()); + const velocity = this.calculateVelocity(); + if (velocity !== 0 && !this.isAtBoundary(velocity)) { + const scrollDelta = velocity * dt; + this.scrollableContent.scrollTop += scrollDelta; + this.rect = null; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_TICK, { scrollDelta }); + this.setScrollingState(true); + } else { + this.setScrollingState(false); + } + this.scrollRAF = requestAnimationFrame(this.scrollTick); + }; + this.subscribeToEvents(); + document.addEventListener("pointermove", this.trackMouse); + } + init(scrollableContent) { + this.scrollableContent = scrollableContent; + this.timeGrid = scrollableContent.querySelector("swp-time-grid"); + this.scrollableContent.style.scrollBehavior = "auto"; + } + subscribeToEvents() { + this.eventBus.on(CoreEvents.EVENT_DRAG_START, (event) => { + const payload = event.detail; + this.draggedElement = payload.element; + this.startDrag(); + }); + this.eventBus.on(CoreEvents.EVENT_DRAG_END, () => this.stopDrag()); + this.eventBus.on(CoreEvents.EVENT_DRAG_CANCEL, () => this.stopDrag()); + } + startDrag() { + this.isDragging = true; + this.isScrolling = false; + this.lastTs = 0; + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + if (this.scrollRAF === null) { + this.scrollRAF = requestAnimationFrame(this.scrollTick); + } + } + stopDrag() { + this.isDragging = false; + this.setScrollingState(false); + if (this.scrollRAF !== null) { + cancelAnimationFrame(this.scrollRAF); + this.scrollRAF = null; + } + this.rect = null; + this.lastTs = 0; + this.initialScrollTop = 0; + } + calculateVelocity() { + if (!this.rect) + return 0; + const distTop = this.mouseY - this.rect.top; + const distBot = this.rect.bottom - this.mouseY; + if (distTop < this.INNER_ZONE) + return -this.FAST_SPEED; + if (distTop < this.OUTER_ZONE) + return -this.SLOW_SPEED; + if (distBot < this.INNER_ZONE) + return this.FAST_SPEED; + if (distBot < this.OUTER_ZONE) + return this.SLOW_SPEED; + return 0; + } + isAtBoundary(velocity) { + if (!this.scrollableContent || !this.timeGrid || !this.draggedElement) + return false; + const atTop = this.scrollableContent.scrollTop <= 0 && velocity < 0; + const atBottom = velocity > 0 && this.draggedElement.getBoundingClientRect().bottom >= this.timeGrid.getBoundingClientRect().bottom; + return atTop || atBottom; + } + setScrollingState(scrolling) { + if (this.isScrolling === scrolling) + return; + this.isScrolling = scrolling; + if (scrolling) { + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STARTED, {}); + } else { + this.initialScrollTop = this.scrollableContent?.scrollTop ?? 0; + this.eventBus.emit(CoreEvents.EDGE_SCROLL_STOPPED, {}); + } + } +}; +__name(_EdgeScrollManager, "EdgeScrollManager"); +var EdgeScrollManager = _EdgeScrollManager; + +// src/v2/managers/ResizeManager.ts +var _ResizeManager = class _ResizeManager { + constructor(eventBus, gridConfig, dateService) { + this.eventBus = eventBus; + this.gridConfig = gridConfig; + this.dateService = dateService; + this.container = null; + this.resizeState = null; + this.Z_INDEX_RESIZING = "1000"; + this.ANIMATION_SPEED = 0.35; + this.MIN_HEIGHT_MINUTES = 15; + this.handleMouseOver = (e) => { + const target = e.target; + const eventElement = target.closest("swp-event"); + if (!eventElement || this.resizeState) + return; + if (!eventElement.querySelector(":scope > swp-resize-handle")) { + const handle = this.createResizeHandle(); + eventElement.appendChild(handle); + } + }; + this.handlePointerDown = (e) => { + const handle = e.target.closest("swp-resize-handle"); + if (!handle) + return; + const element = handle.parentElement; + if (!element) + return; + const eventId = element.dataset.eventId || ""; + const startHeight = element.offsetHeight; + const startDurationMinutes = pixelsToMinutes(startHeight, this.gridConfig); + const container2 = element.closest("swp-event-group") ?? element; + const prevZIndex = container2.style.zIndex; + this.resizeState = { + eventId, + element, + handleElement: handle, + startY: e.clientY, + startHeight, + startDurationMinutes, + pointerId: e.pointerId, + prevZIndex, + // Animation state + currentHeight: startHeight, + targetHeight: startHeight, + animationId: null + }; + container2.style.zIndex = this.Z_INDEX_RESIZING; + try { + handle.setPointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer capture failed:", err); + } + document.documentElement.classList.add("swp--resizing"); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_START, { + eventId, + element, + startHeight + }); + e.preventDefault(); + }; + this.handlePointerMove = (e) => { + if (!this.resizeState) + return; + const deltaY = e.clientY - this.resizeState.startY; + const minHeight = this.MIN_HEIGHT_MINUTES / 60 * this.gridConfig.hourHeight; + const newHeight = Math.max(minHeight, this.resizeState.startHeight + deltaY); + this.resizeState.targetHeight = newHeight; + if (this.resizeState.animationId === null) { + this.animateHeight(); + } + }; + this.animateHeight = () => { + if (!this.resizeState) + return; + const diff2 = this.resizeState.targetHeight - this.resizeState.currentHeight; + if (Math.abs(diff2) < 0.5) { + this.resizeState.animationId = null; + return; + } + this.resizeState.currentHeight += diff2 * this.ANIMATION_SPEED; + this.resizeState.element.style.height = `${this.resizeState.currentHeight}px`; + this.updateTimestampDisplay(); + this.resizeState.animationId = requestAnimationFrame(this.animateHeight); + }; + this.handlePointerUp = (e) => { + if (!this.resizeState) + return; + if (this.resizeState.animationId !== null) { + cancelAnimationFrame(this.resizeState.animationId); + } + try { + this.resizeState.handleElement.releasePointerCapture(e.pointerId); + } catch (err) { + console.warn("Pointer release failed:", err); + } + this.snapToGridFinal(); + this.updateTimestampDisplay(); + const container2 = this.resizeState.element.closest("swp-event-group") ?? this.resizeState.element; + container2.style.zIndex = this.resizeState.prevZIndex; + document.documentElement.classList.remove("swp--resizing"); + const column = this.resizeState.element.closest("swp-day-column"); + const columnKey = column?.dataset.columnKey || ""; + const date = column?.dataset.date || ""; + const swpEvent = SwpEvent.fromElement(this.resizeState.element, columnKey, date, this.gridConfig); + this.eventBus.emit(CoreEvents.EVENT_RESIZE_END, { + swpEvent + }); + this.resizeState = null; + }; + } + /** + * Initialize resize functionality on container + */ + init(container2) { + this.container = container2; + container2.addEventListener("mouseover", this.handleMouseOver, true); + document.addEventListener("pointerdown", this.handlePointerDown, true); + document.addEventListener("pointermove", this.handlePointerMove, true); + document.addEventListener("pointerup", this.handlePointerUp, true); + } + /** + * Create resize handle element + */ + createResizeHandle() { + const handle = document.createElement("swp-resize-handle"); + handle.setAttribute("aria-label", "Resize event"); + handle.setAttribute("role", "separator"); + return handle; + } + /** + * Update timestamp display with snapped end time + */ + updateTimestampDisplay() { + if (!this.resizeState) + return; + const timeEl = this.resizeState.element.querySelector("swp-event-time"); + if (!timeEl) + return; + const top = parseFloat(this.resizeState.element.style.top) || 0; + const startMinutesFromGrid = pixelsToMinutes(top, this.gridConfig); + const startMinutes = this.gridConfig.dayStartHour * 60 + startMinutesFromGrid; + const snappedHeight = snapToGrid(this.resizeState.currentHeight, this.gridConfig); + const durationMinutes = pixelsToMinutes(snappedHeight, this.gridConfig); + const endMinutes = startMinutes + durationMinutes; + const start = this.minutesToDate(startMinutes); + const end = this.minutesToDate(endMinutes); + timeEl.textContent = this.dateService.formatTimeRange(start, end); + } + /** + * Convert minutes since midnight to Date + */ + minutesToDate(minutes) { + const date = /* @__PURE__ */ new Date(); + date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0); + return date; + } + /** + * Snap final height to grid interval + */ + snapToGridFinal() { + if (!this.resizeState) + return; + const currentHeight = this.resizeState.element.offsetHeight; + const snappedHeight = snapToGrid(currentHeight, this.gridConfig); + const minHeight = minutesToPixels(this.MIN_HEIGHT_MINUTES, this.gridConfig); + const finalHeight = Math.max(minHeight, snappedHeight); + this.resizeState.element.style.height = `${finalHeight}px`; + this.resizeState.currentHeight = finalHeight; + } +}; +__name(_ResizeManager, "ResizeManager"); +var ResizeManager = _ResizeManager; + +// src/v2/managers/EventPersistenceManager.ts +var _EventPersistenceManager = class _EventPersistenceManager { + constructor(eventService, eventBus, dateService) { + this.eventService = eventService; + this.eventBus = eventBus; + this.dateService = dateService; + this.handleDragEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const { resource } = this.dateService.parseColumnKey(swpEvent.columnKey); + const updatedEvent = { + ...event, + start: swpEvent.start, + end: swpEvent.end, + resourceId: resource ?? event.resourceId, + allDay: payload.target === "header", + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: payload.sourceColumnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.handleResizeEnd = async (e) => { + const payload = e.detail; + const { swpEvent } = payload; + const event = await this.eventService.get(swpEvent.eventId); + if (!event) { + console.warn(`EventPersistenceManager: Event ${swpEvent.eventId} not found`); + return; + } + const updatedEvent = { + ...event, + end: swpEvent.end, + syncStatus: "pending" + }; + await this.eventService.save(updatedEvent); + const updatePayload = { + eventId: updatedEvent.id, + sourceColumnKey: swpEvent.columnKey, + targetColumnKey: swpEvent.columnKey + }; + this.eventBus.emit(CoreEvents.EVENT_UPDATED, updatePayload); + }; + this.setupListeners(); + } + setupListeners() { + this.eventBus.on(CoreEvents.EVENT_DRAG_END, this.handleDragEnd); + this.eventBus.on(CoreEvents.EVENT_RESIZE_END, this.handleResizeEnd); + } +}; +__name(_EventPersistenceManager, "EventPersistenceManager"); +var EventPersistenceManager = _EventPersistenceManager; + +// src/v2/V2CompositionRoot.ts +var defaultTimeFormatConfig = { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + use24HourFormat: true, + locale: "da-DK", + dateFormat: "locale", + showSeconds: false +}; +var defaultGridConfig = { + hourHeight: 64, + dayStartHour: 6, + dayEndHour: 18, + snapInterval: 15, + gridStartThresholdMinutes: 30 +}; +function createV2Container() { + const container2 = new Container(); + const builder = container2.builder(); + builder.registerInstance(defaultTimeFormatConfig).as("ITimeFormatConfig"); + builder.registerInstance(defaultGridConfig).as("IGridConfig"); + builder.registerType(EventBus).as("EventBus"); + builder.registerType(EventBus).as("IEventBus"); + builder.registerType(DateService).as("DateService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ITimeFormatConfig"), + void 0 + ] + }); + builder.registerType(IndexedDBContext).as("IndexedDBContext").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IStore") + ] + }); + builder.registerType(EventStore).as("IStore"); + builder.registerType(ResourceStore).as("IStore"); + builder.registerType(BookingStore).as("IStore"); + builder.registerType(CustomerStore).as("IStore"); + builder.registerType(TeamStore).as("IStore"); + builder.registerType(DepartmentStore).as("IStore"); + builder.registerType(ScheduleOverrideStore).as("IStore"); + builder.registerType(AuditStore).as("IStore"); + builder.registerType(SettingsStore).as("IStore"); + builder.registerType(ViewConfigStore).as("IStore"); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(EventService).as("EventService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResourceService).as("ResourceService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(BookingService).as("BookingService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(CustomerService).as("CustomerService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(TeamService).as("TeamService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DepartmentService).as("DepartmentService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(SettingsService).as("SettingsService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("IEntityService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ViewConfigService).as("ViewConfigService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(MockEventRepository).as("IApiRepository"); + builder.registerType(MockEventRepository).as("IApiRepository"); + builder.registerType(MockResourceRepository).as("IApiRepository"); + builder.registerType(MockResourceRepository).as("IApiRepository"); + builder.registerType(MockBookingRepository).as("IApiRepository"); + builder.registerType(MockBookingRepository).as("IApiRepository"); + builder.registerType(MockCustomerRepository).as("IApiRepository"); + builder.registerType(MockCustomerRepository).as("IApiRepository"); + builder.registerType(MockAuditRepository).as("IApiRepository"); + builder.registerType(MockAuditRepository).as("IApiRepository"); + builder.registerType(MockTeamRepository).as("IApiRepository"); + builder.registerType(MockTeamRepository).as("IApiRepository"); + builder.registerType(MockDepartmentRepository).as("IApiRepository"); + builder.registerType(MockDepartmentRepository).as("IApiRepository"); + builder.registerType(MockSettingsRepository).as("IApiRepository"); + builder.registerType(MockSettingsRepository).as("IApiRepository"); + builder.registerType(MockViewConfigRepository).as("IApiRepository"); + builder.registerType(MockViewConfigRepository).as("IApiRepository"); + builder.registerType(AuditService).as("AuditService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DataSeeder).as("DataSeeder").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IEntityService"), + (c) => c.resolveTypeAll("IApiRepository") + ] + }); + builder.registerType(ScheduleOverrideService).as("ScheduleOverrideService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext") + ] + }); + builder.registerType(ResourceScheduleService).as("ResourceScheduleService").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService"), + (c) => c.resolveType("ScheduleOverrideService"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(EventRenderer).as("EventRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ScheduleRenderer).as("ScheduleRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceScheduleService"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(HeaderDrawerRenderer).as("HeaderDrawerRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("EventService"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(DateRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(ResourceRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("ResourceService") + ] + }); + builder.registerType(TeamRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("TeamService") + ] + }); + builder.registerType(DepartmentRenderer).as("IRenderer").autoWire({ + mapResolvers: [ + (c) => c.resolveType("DepartmentService") + ] + }); + builder.registerType(MockTeamStore).as("IGroupingStore"); + builder.registerType(MockResourceStore).as("IGroupingStore"); + builder.registerType(CalendarOrchestrator).as("CalendarOrchestrator").autoWire({ + mapResolvers: [ + (c) => c.resolveTypeAll("IRenderer"), + (c) => c.resolveType("EventRenderer"), + (c) => c.resolveType("ScheduleRenderer"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveTypeAll("IEntityService") + ] + }); + builder.registerType(TimeAxisRenderer).as("TimeAxisRenderer"); + builder.registerType(ScrollManager).as("ScrollManager"); + builder.registerType(HeaderDrawerManager).as("HeaderDrawerManager"); + builder.registerType(DragDropManager).as("DragDropManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig") + ] + }); + builder.registerType(EdgeScrollManager).as("EdgeScrollManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(ResizeManager).as("ResizeManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("IGridConfig"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(EventPersistenceManager).as("EventPersistenceManager").autoWire({ + mapResolvers: [ + (c) => c.resolveType("EventService"), + (c) => c.resolveType("IEventBus"), + (c) => c.resolveType("DateService") + ] + }); + builder.registerType(CalendarApp).as("CalendarApp").autoWire({ + mapResolvers: [ + (c) => c.resolveType("CalendarOrchestrator"), + (c) => c.resolveType("TimeAxisRenderer"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("ScrollManager"), + (c) => c.resolveType("HeaderDrawerManager"), + (c) => c.resolveType("DragDropManager"), + (c) => c.resolveType("EdgeScrollManager"), + (c) => c.resolveType("ResizeManager"), + (c) => c.resolveType("HeaderDrawerRenderer"), + (c) => c.resolveType("EventPersistenceManager"), + (c) => c.resolveType("SettingsService"), + (c) => c.resolveType("ViewConfigService"), + (c) => c.resolveType("IEventBus") + ] + }); + builder.registerType(DemoApp).as("DemoApp").autoWire({ + mapResolvers: [ + (c) => c.resolveType("IndexedDBContext"), + (c) => c.resolveType("DataSeeder"), + (c) => c.resolveType("AuditService"), + (c) => c.resolveType("CalendarApp"), + (c) => c.resolveType("DateService"), + (c) => c.resolveType("ResourceService"), + (c) => c.resolveType("IEventBus") + ] + }); + return builder.build(); +} +__name(createV2Container, "createV2Container"); + +// src/v2/demo/index.ts +var container = createV2Container(); +container.resolveType("DemoApp").init().catch(console.error); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL2RheWpzL2RheWpzLm1pbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3V0Yy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3RpbWV6b25lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9kYXlqcy9wbHVnaW4vaXNvV2Vlay5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQG5vdmFkaS9jb3JlL2Rpc3QvdG9rZW4uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2Vycm9ycy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQG5vdmFkaS9jb3JlL2Rpc3QvYXV0b3dpcmUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2J1aWxkZXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bub3ZhZGkvY29yZS9kaXN0L2NvbnRhaW5lci5qcyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL2NvcmUvRGF0ZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL2ZlYXR1cmVzL3Jlc291cmNlL1Jlc291cmNlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL2ZlYXR1cmVzL3RlYW0vVGVhbVJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy92Mi9mZWF0dXJlcy9kZXBhcnRtZW50L0RlcGFydG1lbnRSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvdjIvY29yZS9SZW5kZXJCdWlsZGVyLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0ZpbHRlclRlbXBsYXRlLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL05hdmlnYXRpb25BbmltYXRvci50cyIsICIuLi8uLi9zcmMvdjIvY29yZS9DYWxlbmRhckV2ZW50cy50cyIsICIuLi8uLi9zcmMvdjIvY29yZS9DYWxlbmRhckFwcC50cyIsICIuLi8uLi9zcmMvdjIvZmVhdHVyZXMvdGltZWF4aXMvVGltZUF4aXNSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvdjIvY29yZS9TY3JvbGxNYW5hZ2VyLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0hlYWRlckRyYXdlck1hbmFnZXIudHMiLCAiLi4vLi4vc3JjL3YyL2RlbW8vTW9ja1N0b3Jlcy50cyIsICIuLi8uLi9zcmMvdjIvZGVtby9EZW1vQXBwLnRzIiwgIi4uLy4uL3NyYy92Mi9jb3JlL0V2ZW50QnVzLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL0luZGV4ZWREQkNvbnRleHQudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvZXZlbnRzL0V2ZW50U3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvZXZlbnRzL0V2ZW50U2VyaWFsaXphdGlvbi50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS9TeW5jUGx1Z2luLnRzIiwgIi4uLy4uL3NyYy92Mi9jb25zdGFudHMvQ29yZUV2ZW50cy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvanNvbi1kaWZmLXRzL3NyYy9oZWxwZXJzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9qc29uLWRpZmYtdHMvc3JjL2pzb25EaWZmLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9qc29uLWRpZmYtdHMvc3JjL2pzb25Db21wYXJlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL0Jhc2VFbnRpdHlTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL2V2ZW50cy9FdmVudFNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU2VydmljZS50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS9ib29raW5ncy9Cb29raW5nU3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvYm9va2luZ3MvQm9va2luZ1NlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvY3VzdG9tZXJzL0N1c3RvbWVyU3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvY3VzdG9tZXJzL0N1c3RvbWVyU2VydmljZS50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS90ZWFtcy9UZWFtU3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvdGVhbXMvVGVhbVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2UvZGVwYXJ0bWVudHMvRGVwYXJ0bWVudFN0b3JlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL2RlcGFydG1lbnRzL0RlcGFydG1lbnRTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL3NldHRpbmdzL1NldHRpbmdzU3RvcmUudHMiLCAiLi4vLi4vc3JjL3YyL3R5cGVzL1NldHRpbmdzVHlwZXMudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2Uvc2V0dGluZ3MvU2V0dGluZ3NTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL3ZpZXdjb25maWdzL1ZpZXdDb25maWdTdG9yZS50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS92aWV3Y29uZmlncy9WaWV3Q29uZmlnU2VydmljZS50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS9hdWRpdC9BdWRpdFN0b3JlLnRzIiwgIi4uLy4uL3NyYy92Mi9zdG9yYWdlL2F1ZGl0L0F1ZGl0U2VydmljZS50cyIsICIuLi8uLi9zcmMvdjIvcmVwb3NpdG9yaWVzL01vY2tFdmVudFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3YyL3JlcG9zaXRvcmllcy9Nb2NrUmVzb3VyY2VSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy92Mi9yZXBvc2l0b3JpZXMvTW9ja0Jvb2tpbmdSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy92Mi9yZXBvc2l0b3JpZXMvTW9ja0N1c3RvbWVyUmVwb3NpdG9yeS50cyIsICIuLi8uLi9zcmMvdjIvcmVwb3NpdG9yaWVzL01vY2tBdWRpdFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3YyL3JlcG9zaXRvcmllcy9Nb2NrVGVhbVJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3YyL3JlcG9zaXRvcmllcy9Nb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkudHMiLCAiLi4vLi4vc3JjL3YyL3JlcG9zaXRvcmllcy9Nb2NrU2V0dGluZ3NSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy92Mi9yZXBvc2l0b3JpZXMvTW9ja1ZpZXdDb25maWdSZXBvc2l0b3J5LnRzIiwgIi4uLy4uL3NyYy92Mi93b3JrZXJzL0RhdGFTZWVkZXIudHMiLCAiLi4vLi4vc3JjL3YyL3V0aWxzL1Bvc2l0aW9uVXRpbHMudHMiLCAiLi4vLi4vc3JjL3YyL2ZlYXR1cmVzL2V2ZW50L0V2ZW50TGF5b3V0RW5naW5lLnRzIiwgIi4uLy4uL3NyYy92Mi9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy92Mi9mZWF0dXJlcy9zY2hlZHVsZS9TY2hlZHVsZVJlbmRlcmVyLnRzIiwgIi4uLy4uL3NyYy92Mi9mZWF0dXJlcy9oZWFkZXJkcmF3ZXIvSGVhZGVyRHJhd2VyUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2Uvc2NoZWR1bGVzL1NjaGVkdWxlT3ZlcnJpZGVTdG9yZS50cyIsICIuLi8uLi9zcmMvdjIvc3RvcmFnZS9zY2hlZHVsZXMvU2NoZWR1bGVPdmVycmlkZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3YyL3N0b3JhZ2Uvc2NoZWR1bGVzL1Jlc291cmNlU2NoZWR1bGVTZXJ2aWNlLnRzIiwgIi4uLy4uL3NyYy92Mi90eXBlcy9Td3BFdmVudC50cyIsICIuLi8uLi9zcmMvdjIvbWFuYWdlcnMvRHJhZ0Ryb3BNYW5hZ2VyLnRzIiwgIi4uLy4uL3NyYy92Mi9tYW5hZ2Vycy9FZGdlU2Nyb2xsTWFuYWdlci50cyIsICIuLi8uLi9zcmMvdjIvbWFuYWdlcnMvUmVzaXplTWFuYWdlci50cyIsICIuLi8uLi9zcmMvdjIvbWFuYWdlcnMvRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIudHMiLCAiLi4vLi4vc3JjL3YyL1YyQ29tcG9zaXRpb25Sb290LnRzIiwgIi4uLy4uL3NyYy92Mi9kZW1vL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIhZnVuY3Rpb24odCxlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToodD1cInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOnR8fHNlbGYpLmRheWpzPWUoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgdD0xZTMsZT02ZTQsbj0zNmU1LHI9XCJtaWxsaXNlY29uZFwiLGk9XCJzZWNvbmRcIixzPVwibWludXRlXCIsdT1cImhvdXJcIixhPVwiZGF5XCIsbz1cIndlZWtcIixjPVwibW9udGhcIixmPVwicXVhcnRlclwiLGg9XCJ5ZWFyXCIsZD1cImRhdGVcIixsPVwiSW52YWxpZCBEYXRlXCIsJD0vXihcXGR7NH0pWy0vXT8oXFxkezEsMn0pP1stL10/KFxcZHswLDJ9KVtUdFxcc10qKFxcZHsxLDJ9KT86PyhcXGR7MSwyfSk/Oj8oXFxkezEsMn0pP1suOl0/KFxcZCspPyQvLHk9L1xcWyhbXlxcXV0rKV18WXsxLDR9fE17MSw0fXxEezEsMn18ZHsxLDR9fEh7MSwyfXxoezEsMn18YXxBfG17MSwyfXxzezEsMn18WnsxLDJ9fFNTUy9nLE09e25hbWU6XCJlblwiLHdlZWtkYXlzOlwiU3VuZGF5X01vbmRheV9UdWVzZGF5X1dlZG5lc2RheV9UaHVyc2RheV9GcmlkYXlfU2F0dXJkYXlcIi5zcGxpdChcIl9cIiksbW9udGhzOlwiSmFudWFyeV9GZWJydWFyeV9NYXJjaF9BcHJpbF9NYXlfSnVuZV9KdWx5X0F1Z3VzdF9TZXB0ZW1iZXJfT2N0b2Jlcl9Ob3ZlbWJlcl9EZWNlbWJlclwiLnNwbGl0KFwiX1wiKSxvcmRpbmFsOmZ1bmN0aW9uKHQpe3ZhciBlPVtcInRoXCIsXCJzdFwiLFwibmRcIixcInJkXCJdLG49dCUxMDA7cmV0dXJuXCJbXCIrdCsoZVsobi0yMCklMTBdfHxlW25dfHxlWzBdKStcIl1cIn19LG09ZnVuY3Rpb24odCxlLG4pe3ZhciByPVN0cmluZyh0KTtyZXR1cm4hcnx8ci5sZW5ndGg+PWU/dDpcIlwiK0FycmF5KGUrMS1yLmxlbmd0aCkuam9pbihuKSt0fSx2PXtzOm0sejpmdW5jdGlvbih0KXt2YXIgZT0tdC51dGNPZmZzZXQoKSxuPU1hdGguYWJzKGUpLHI9TWF0aC5mbG9vcihuLzYwKSxpPW4lNjA7cmV0dXJuKGU8PTA/XCIrXCI6XCItXCIpK20ociwyLFwiMFwiKStcIjpcIittKGksMixcIjBcIil9LG06ZnVuY3Rpb24gdChlLG4pe2lmKGUuZGF0ZSgpPG4uZGF0ZSgpKXJldHVybi10KG4sZSk7dmFyIHI9MTIqKG4ueWVhcigpLWUueWVhcigpKSsobi5tb250aCgpLWUubW9udGgoKSksaT1lLmNsb25lKCkuYWRkKHIsYykscz1uLWk8MCx1PWUuY2xvbmUoKS5hZGQocisocz8tMToxKSxjKTtyZXR1cm4rKC0ocisobi1pKS8ocz9pLXU6dS1pKSl8fDApfSxhOmZ1bmN0aW9uKHQpe3JldHVybiB0PDA/TWF0aC5jZWlsKHQpfHwwOk1hdGguZmxvb3IodCl9LHA6ZnVuY3Rpb24odCl7cmV0dXJue006Yyx5OmgsdzpvLGQ6YSxEOmQsaDp1LG06cyxzOmksbXM6cixROmZ9W3RdfHxTdHJpbmcodHx8XCJcIikudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9zJC8sXCJcIil9LHU6ZnVuY3Rpb24odCl7cmV0dXJuIHZvaWQgMD09PXR9fSxnPVwiZW5cIixEPXt9O0RbZ109TTt2YXIgcD1cIiRpc0RheWpzT2JqZWN0XCIsUz1mdW5jdGlvbih0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIF98fCEoIXR8fCF0W3BdKX0sdz1mdW5jdGlvbiB0KGUsbixyKXt2YXIgaTtpZighZSlyZXR1cm4gZztpZihcInN0cmluZ1wiPT10eXBlb2YgZSl7dmFyIHM9ZS50b0xvd2VyQ2FzZSgpO0Rbc10mJihpPXMpLG4mJihEW3NdPW4saT1zKTt2YXIgdT1lLnNwbGl0KFwiLVwiKTtpZighaSYmdS5sZW5ndGg+MSlyZXR1cm4gdCh1WzBdKX1lbHNle3ZhciBhPWUubmFtZTtEW2FdPWUsaT1hfXJldHVybiFyJiZpJiYoZz1pKSxpfHwhciYmZ30sTz1mdW5jdGlvbih0LGUpe2lmKFModCkpcmV0dXJuIHQuY2xvbmUoKTt2YXIgbj1cIm9iamVjdFwiPT10eXBlb2YgZT9lOnt9O3JldHVybiBuLmRhdGU9dCxuLmFyZ3M9YXJndW1lbnRzLG5ldyBfKG4pfSxiPXY7Yi5sPXcsYi5pPVMsYi53PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIE8odCx7bG9jYWxlOmUuJEwsdXRjOmUuJHUseDplLiR4LCRvZmZzZXQ6ZS4kb2Zmc2V0fSl9O3ZhciBfPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gTSh0KXt0aGlzLiRMPXcodC5sb2NhbGUsbnVsbCwhMCksdGhpcy5wYXJzZSh0KSx0aGlzLiR4PXRoaXMuJHh8fHQueHx8e30sdGhpc1twXT0hMH12YXIgbT1NLnByb3RvdHlwZTtyZXR1cm4gbS5wYXJzZT1mdW5jdGlvbih0KXt0aGlzLiRkPWZ1bmN0aW9uKHQpe3ZhciBlPXQuZGF0ZSxuPXQudXRjO2lmKG51bGw9PT1lKXJldHVybiBuZXcgRGF0ZShOYU4pO2lmKGIudShlKSlyZXR1cm4gbmV3IERhdGU7aWYoZSBpbnN0YW5jZW9mIERhdGUpcmV0dXJuIG5ldyBEYXRlKGUpO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlJiYhL1okL2kudGVzdChlKSl7dmFyIHI9ZS5tYXRjaCgkKTtpZihyKXt2YXIgaT1yWzJdLTF8fDAscz0ocls3XXx8XCIwXCIpLnN1YnN0cmluZygwLDMpO3JldHVybiBuP25ldyBEYXRlKERhdGUuVVRDKHJbMV0saSxyWzNdfHwxLHJbNF18fDAscls1XXx8MCxyWzZdfHwwLHMpKTpuZXcgRGF0ZShyWzFdLGksclszXXx8MSxyWzRdfHwwLHJbNV18fDAscls2XXx8MCxzKX19cmV0dXJuIG5ldyBEYXRlKGUpfSh0KSx0aGlzLmluaXQoKX0sbS5pbml0PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy4kZDt0aGlzLiR5PXQuZ2V0RnVsbFllYXIoKSx0aGlzLiRNPXQuZ2V0TW9udGgoKSx0aGlzLiREPXQuZ2V0RGF0ZSgpLHRoaXMuJFc9dC5nZXREYXkoKSx0aGlzLiRIPXQuZ2V0SG91cnMoKSx0aGlzLiRtPXQuZ2V0TWludXRlcygpLHRoaXMuJHM9dC5nZXRTZWNvbmRzKCksdGhpcy4kbXM9dC5nZXRNaWxsaXNlY29uZHMoKX0sbS4kdXRpbHM9ZnVuY3Rpb24oKXtyZXR1cm4gYn0sbS5pc1ZhbGlkPWZ1bmN0aW9uKCl7cmV0dXJuISh0aGlzLiRkLnRvU3RyaW5nKCk9PT1sKX0sbS5pc1NhbWU9ZnVuY3Rpb24odCxlKXt2YXIgbj1PKHQpO3JldHVybiB0aGlzLnN0YXJ0T2YoZSk8PW4mJm48PXRoaXMuZW5kT2YoZSl9LG0uaXNBZnRlcj1mdW5jdGlvbih0LGUpe3JldHVybiBPKHQpPHRoaXMuc3RhcnRPZihlKX0sbS5pc0JlZm9yZT1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLmVuZE9mKGUpPE8odCl9LG0uJGc9ZnVuY3Rpb24odCxlLG4pe3JldHVybiBiLnUodCk/dGhpc1tlXTp0aGlzLnNldChuLHQpfSxtLnVuaXg9ZnVuY3Rpb24oKXtyZXR1cm4gTWF0aC5mbG9vcih0aGlzLnZhbHVlT2YoKS8xZTMpfSxtLnZhbHVlT2Y9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4kZC5nZXRUaW1lKCl9LG0uc3RhcnRPZj1mdW5jdGlvbih0LGUpe3ZhciBuPXRoaXMscj0hIWIudShlKXx8ZSxmPWIucCh0KSxsPWZ1bmN0aW9uKHQsZSl7dmFyIGk9Yi53KG4uJHU/RGF0ZS5VVEMobi4keSxlLHQpOm5ldyBEYXRlKG4uJHksZSx0KSxuKTtyZXR1cm4gcj9pOmkuZW5kT2YoYSl9LCQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gYi53KG4udG9EYXRlKClbdF0uYXBwbHkobi50b0RhdGUoXCJzXCIpLChyP1swLDAsMCwwXTpbMjMsNTksNTksOTk5XSkuc2xpY2UoZSkpLG4pfSx5PXRoaXMuJFcsTT10aGlzLiRNLG09dGhpcy4kRCx2PVwic2V0XCIrKHRoaXMuJHU/XCJVVENcIjpcIlwiKTtzd2l0Y2goZil7Y2FzZSBoOnJldHVybiByP2woMSwwKTpsKDMxLDExKTtjYXNlIGM6cmV0dXJuIHI/bCgxLE0pOmwoMCxNKzEpO2Nhc2Ugbzp2YXIgZz10aGlzLiRsb2NhbGUoKS53ZWVrU3RhcnR8fDAsRD0oeTxnP3krNzp5KS1nO3JldHVybiBsKHI/bS1EOm0rKDYtRCksTSk7Y2FzZSBhOmNhc2UgZDpyZXR1cm4gJCh2K1wiSG91cnNcIiwwKTtjYXNlIHU6cmV0dXJuICQoditcIk1pbnV0ZXNcIiwxKTtjYXNlIHM6cmV0dXJuICQoditcIlNlY29uZHNcIiwyKTtjYXNlIGk6cmV0dXJuICQoditcIk1pbGxpc2Vjb25kc1wiLDMpO2RlZmF1bHQ6cmV0dXJuIHRoaXMuY2xvbmUoKX19LG0uZW5kT2Y9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuc3RhcnRPZih0LCExKX0sbS4kc2V0PWZ1bmN0aW9uKHQsZSl7dmFyIG4sbz1iLnAodCksZj1cInNldFwiKyh0aGlzLiR1P1wiVVRDXCI6XCJcIiksbD0obj17fSxuW2FdPWYrXCJEYXRlXCIsbltkXT1mK1wiRGF0ZVwiLG5bY109ZitcIk1vbnRoXCIsbltoXT1mK1wiRnVsbFllYXJcIixuW3VdPWYrXCJIb3Vyc1wiLG5bc109ZitcIk1pbnV0ZXNcIixuW2ldPWYrXCJTZWNvbmRzXCIsbltyXT1mK1wiTWlsbGlzZWNvbmRzXCIsbilbb10sJD1vPT09YT90aGlzLiREKyhlLXRoaXMuJFcpOmU7aWYobz09PWN8fG89PT1oKXt2YXIgeT10aGlzLmNsb25lKCkuc2V0KGQsMSk7eS4kZFtsXSgkKSx5LmluaXQoKSx0aGlzLiRkPXkuc2V0KGQsTWF0aC5taW4odGhpcy4kRCx5LmRheXNJbk1vbnRoKCkpKS4kZH1lbHNlIGwmJnRoaXMuJGRbbF0oJCk7cmV0dXJuIHRoaXMuaW5pdCgpLHRoaXN9LG0uc2V0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuY2xvbmUoKS4kc2V0KHQsZSl9LG0uZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzW2IucCh0KV0oKX0sbS5hZGQ9ZnVuY3Rpb24ocixmKXt2YXIgZCxsPXRoaXM7cj1OdW1iZXIocik7dmFyICQ9Yi5wKGYpLHk9ZnVuY3Rpb24odCl7dmFyIGU9TyhsKTtyZXR1cm4gYi53KGUuZGF0ZShlLmRhdGUoKStNYXRoLnJvdW5kKHQqcikpLGwpfTtpZigkPT09YylyZXR1cm4gdGhpcy5zZXQoYyx0aGlzLiRNK3IpO2lmKCQ9PT1oKXJldHVybiB0aGlzLnNldChoLHRoaXMuJHkrcik7aWYoJD09PWEpcmV0dXJuIHkoMSk7aWYoJD09PW8pcmV0dXJuIHkoNyk7dmFyIE09KGQ9e30sZFtzXT1lLGRbdV09bixkW2ldPXQsZClbJF18fDEsbT10aGlzLiRkLmdldFRpbWUoKStyKk07cmV0dXJuIGIudyhtLHRoaXMpfSxtLnN1YnRyYWN0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuYWRkKC0xKnQsZSl9LG0uZm9ybWF0PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMsbj10aGlzLiRsb2NhbGUoKTtpZighdGhpcy5pc1ZhbGlkKCkpcmV0dXJuIG4uaW52YWxpZERhdGV8fGw7dmFyIHI9dHx8XCJZWVlZLU1NLUREVEhIOm1tOnNzWlwiLGk9Yi56KHRoaXMpLHM9dGhpcy4kSCx1PXRoaXMuJG0sYT10aGlzLiRNLG89bi53ZWVrZGF5cyxjPW4ubW9udGhzLGY9bi5tZXJpZGllbSxoPWZ1bmN0aW9uKHQsbixpLHMpe3JldHVybiB0JiYodFtuXXx8dChlLHIpKXx8aVtuXS5zbGljZSgwLHMpfSxkPWZ1bmN0aW9uKHQpe3JldHVybiBiLnMocyUxMnx8MTIsdCxcIjBcIil9LCQ9Znx8ZnVuY3Rpb24odCxlLG4pe3ZhciByPXQ8MTI/XCJBTVwiOlwiUE1cIjtyZXR1cm4gbj9yLnRvTG93ZXJDYXNlKCk6cn07cmV0dXJuIHIucmVwbGFjZSh5LChmdW5jdGlvbih0LHIpe3JldHVybiByfHxmdW5jdGlvbih0KXtzd2l0Y2godCl7Y2FzZVwiWVlcIjpyZXR1cm4gU3RyaW5nKGUuJHkpLnNsaWNlKC0yKTtjYXNlXCJZWVlZXCI6cmV0dXJuIGIucyhlLiR5LDQsXCIwXCIpO2Nhc2VcIk1cIjpyZXR1cm4gYSsxO2Nhc2VcIk1NXCI6cmV0dXJuIGIucyhhKzEsMixcIjBcIik7Y2FzZVwiTU1NXCI6cmV0dXJuIGgobi5tb250aHNTaG9ydCxhLGMsMyk7Y2FzZVwiTU1NTVwiOnJldHVybiBoKGMsYSk7Y2FzZVwiRFwiOnJldHVybiBlLiREO2Nhc2VcIkREXCI6cmV0dXJuIGIucyhlLiRELDIsXCIwXCIpO2Nhc2VcImRcIjpyZXR1cm4gU3RyaW5nKGUuJFcpO2Nhc2VcImRkXCI6cmV0dXJuIGgobi53ZWVrZGF5c01pbixlLiRXLG8sMik7Y2FzZVwiZGRkXCI6cmV0dXJuIGgobi53ZWVrZGF5c1Nob3J0LGUuJFcsbywzKTtjYXNlXCJkZGRkXCI6cmV0dXJuIG9bZS4kV107Y2FzZVwiSFwiOnJldHVybiBTdHJpbmcocyk7Y2FzZVwiSEhcIjpyZXR1cm4gYi5zKHMsMixcIjBcIik7Y2FzZVwiaFwiOnJldHVybiBkKDEpO2Nhc2VcImhoXCI6cmV0dXJuIGQoMik7Y2FzZVwiYVwiOnJldHVybiAkKHMsdSwhMCk7Y2FzZVwiQVwiOnJldHVybiAkKHMsdSwhMSk7Y2FzZVwibVwiOnJldHVybiBTdHJpbmcodSk7Y2FzZVwibW1cIjpyZXR1cm4gYi5zKHUsMixcIjBcIik7Y2FzZVwic1wiOnJldHVybiBTdHJpbmcoZS4kcyk7Y2FzZVwic3NcIjpyZXR1cm4gYi5zKGUuJHMsMixcIjBcIik7Y2FzZVwiU1NTXCI6cmV0dXJuIGIucyhlLiRtcywzLFwiMFwiKTtjYXNlXCJaXCI6cmV0dXJuIGl9cmV0dXJuIG51bGx9KHQpfHxpLnJlcGxhY2UoXCI6XCIsXCJcIil9KSl9LG0udXRjT2Zmc2V0PWZ1bmN0aW9uKCl7cmV0dXJuIDE1Ki1NYXRoLnJvdW5kKHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKS8xNSl9LG0uZGlmZj1mdW5jdGlvbihyLGQsbCl7dmFyICQseT10aGlzLE09Yi5wKGQpLG09TyhyKSx2PShtLnV0Y09mZnNldCgpLXRoaXMudXRjT2Zmc2V0KCkpKmUsZz10aGlzLW0sRD1mdW5jdGlvbigpe3JldHVybiBiLm0oeSxtKX07c3dpdGNoKE0pe2Nhc2UgaDokPUQoKS8xMjticmVhaztjYXNlIGM6JD1EKCk7YnJlYWs7Y2FzZSBmOiQ9RCgpLzM7YnJlYWs7Y2FzZSBvOiQ9KGctdikvNjA0OGU1O2JyZWFrO2Nhc2UgYTokPShnLXYpLzg2NGU1O2JyZWFrO2Nhc2UgdTokPWcvbjticmVhaztjYXNlIHM6JD1nL2U7YnJlYWs7Y2FzZSBpOiQ9Zy90O2JyZWFrO2RlZmF1bHQ6JD1nfXJldHVybiBsPyQ6Yi5hKCQpfSxtLmRheXNJbk1vbnRoPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZW5kT2YoYykuJER9LG0uJGxvY2FsZT1mdW5jdGlvbigpe3JldHVybiBEW3RoaXMuJExdfSxtLmxvY2FsZT1mdW5jdGlvbih0LGUpe2lmKCF0KXJldHVybiB0aGlzLiRMO3ZhciBuPXRoaXMuY2xvbmUoKSxyPXcodCxlLCEwKTtyZXR1cm4gciYmKG4uJEw9ciksbn0sbS5jbG9uZT1mdW5jdGlvbigpe3JldHVybiBiLncodGhpcy4kZCx0aGlzKX0sbS50b0RhdGU9ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpfSxtLnRvSlNPTj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmlzVmFsaWQoKT90aGlzLnRvSVNPU3RyaW5nKCk6bnVsbH0sbS50b0lTT1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLnRvSVNPU3RyaW5nKCl9LG0udG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4kZC50b1VUQ1N0cmluZygpfSxNfSgpLGs9Xy5wcm90b3R5cGU7cmV0dXJuIE8ucHJvdG90eXBlPWssW1tcIiRtc1wiLHJdLFtcIiRzXCIsaV0sW1wiJG1cIixzXSxbXCIkSFwiLHVdLFtcIiRXXCIsYV0sW1wiJE1cIixjXSxbXCIkeVwiLGhdLFtcIiREXCIsZF1dLmZvckVhY2goKGZ1bmN0aW9uKHQpe2tbdFsxXV09ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuJGcoZSx0WzBdLHRbMV0pfX0pKSxPLmV4dGVuZD1mdW5jdGlvbih0LGUpe3JldHVybiB0LiRpfHwodChlLF8sTyksdC4kaT0hMCksT30sTy5sb2NhbGU9dyxPLmlzRGF5anM9UyxPLnVuaXg9ZnVuY3Rpb24odCl7cmV0dXJuIE8oMWUzKnQpfSxPLmVuPURbZ10sTy5Mcz1ELE8ucD17fSxPfSkpOyIsICIhZnVuY3Rpb24odCxpKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1pKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShpKToodD1cInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOnR8fHNlbGYpLmRheWpzX3BsdWdpbl91dGM9aSgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciB0PVwibWludXRlXCIsaT0vWystXVxcZFxcZCg/Ojo/XFxkXFxkKT8vZyxlPS8oWystXXxcXGRcXGQpL2c7cmV0dXJuIGZ1bmN0aW9uKHMsZixuKXt2YXIgdT1mLnByb3RvdHlwZTtuLnV0Yz1mdW5jdGlvbih0KXt2YXIgaT17ZGF0ZTp0LHV0YzohMCxhcmdzOmFyZ3VtZW50c307cmV0dXJuIG5ldyBmKGkpfSx1LnV0Yz1mdW5jdGlvbihpKXt2YXIgZT1uKHRoaXMudG9EYXRlKCkse2xvY2FsZTp0aGlzLiRMLHV0YzohMH0pO3JldHVybiBpP2UuYWRkKHRoaXMudXRjT2Zmc2V0KCksdCk6ZX0sdS5sb2NhbD1mdW5jdGlvbigpe3JldHVybiBuKHRoaXMudG9EYXRlKCkse2xvY2FsZTp0aGlzLiRMLHV0YzohMX0pfTt2YXIgcj11LnBhcnNlO3UucGFyc2U9ZnVuY3Rpb24odCl7dC51dGMmJih0aGlzLiR1PSEwKSx0aGlzLiR1dGlscygpLnUodC4kb2Zmc2V0KXx8KHRoaXMuJG9mZnNldD10LiRvZmZzZXQpLHIuY2FsbCh0aGlzLHQpfTt2YXIgbz11LmluaXQ7dS5pbml0PWZ1bmN0aW9uKCl7aWYodGhpcy4kdSl7dmFyIHQ9dGhpcy4kZDt0aGlzLiR5PXQuZ2V0VVRDRnVsbFllYXIoKSx0aGlzLiRNPXQuZ2V0VVRDTW9udGgoKSx0aGlzLiREPXQuZ2V0VVRDRGF0ZSgpLHRoaXMuJFc9dC5nZXRVVENEYXkoKSx0aGlzLiRIPXQuZ2V0VVRDSG91cnMoKSx0aGlzLiRtPXQuZ2V0VVRDTWludXRlcygpLHRoaXMuJHM9dC5nZXRVVENTZWNvbmRzKCksdGhpcy4kbXM9dC5nZXRVVENNaWxsaXNlY29uZHMoKX1lbHNlIG8uY2FsbCh0aGlzKX07dmFyIGE9dS51dGNPZmZzZXQ7dS51dGNPZmZzZXQ9ZnVuY3Rpb24ocyxmKXt2YXIgbj10aGlzLiR1dGlscygpLnU7aWYobihzKSlyZXR1cm4gdGhpcy4kdT8wOm4odGhpcy4kb2Zmc2V0KT9hLmNhbGwodGhpcyk6dGhpcy4kb2Zmc2V0O2lmKFwic3RyaW5nXCI9PXR5cGVvZiBzJiYocz1mdW5jdGlvbih0KXt2b2lkIDA9PT10JiYodD1cIlwiKTt2YXIgcz10Lm1hdGNoKGkpO2lmKCFzKXJldHVybiBudWxsO3ZhciBmPShcIlwiK3NbMF0pLm1hdGNoKGUpfHxbXCItXCIsMCwwXSxuPWZbMF0sdT02MCorZlsxXSsgK2ZbMl07cmV0dXJuIDA9PT11PzA6XCIrXCI9PT1uP3U6LXV9KHMpLG51bGw9PT1zKSlyZXR1cm4gdGhpczt2YXIgdT1NYXRoLmFicyhzKTw9MTY/NjAqczpzO2lmKDA9PT11KXJldHVybiB0aGlzLnV0YyhmKTt2YXIgcj10aGlzLmNsb25lKCk7aWYoZilyZXR1cm4gci4kb2Zmc2V0PXUsci4kdT0hMSxyO3ZhciBvPXRoaXMuJHU/dGhpcy50b0RhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpOi0xKnRoaXMudXRjT2Zmc2V0KCk7cmV0dXJuKHI9dGhpcy5sb2NhbCgpLmFkZCh1K28sdCkpLiRvZmZzZXQ9dSxyLiR4LiRsb2NhbE9mZnNldD1vLHJ9O3ZhciBoPXUuZm9ybWF0O3UuZm9ybWF0PWZ1bmN0aW9uKHQpe3ZhciBpPXR8fCh0aGlzLiR1P1wiWVlZWS1NTS1ERFRISDptbTpzc1taXVwiOlwiXCIpO3JldHVybiBoLmNhbGwodGhpcyxpKX0sdS52YWx1ZU9mPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy4kdXRpbHMoKS51KHRoaXMuJG9mZnNldCk/MDp0aGlzLiRvZmZzZXQrKHRoaXMuJHguJGxvY2FsT2Zmc2V0fHx0aGlzLiRkLmdldFRpbWV6b25lT2Zmc2V0KCkpO3JldHVybiB0aGlzLiRkLnZhbHVlT2YoKS02ZTQqdH0sdS5pc1VUQz1mdW5jdGlvbigpe3JldHVybiEhdGhpcy4kdX0sdS50b0lTT1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRvRGF0ZSgpLnRvSVNPU3RyaW5nKCl9LHUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50b0RhdGUoKS50b1VUQ1N0cmluZygpfTt2YXIgbD11LnRvRGF0ZTt1LnRvRGF0ZT1mdW5jdGlvbih0KXtyZXR1cm5cInNcIj09PXQmJnRoaXMuJG9mZnNldD9uKHRoaXMuZm9ybWF0KFwiWVlZWS1NTS1ERCBISDptbTpzczpTU1NcIikpLnRvRGF0ZSgpOmwuY2FsbCh0aGlzKX07dmFyIGM9dS5kaWZmO3UuZGlmZj1mdW5jdGlvbih0LGksZSl7aWYodCYmdGhpcy4kdT09PXQuJHUpcmV0dXJuIGMuY2FsbCh0aGlzLHQsaSxlKTt2YXIgcz10aGlzLmxvY2FsKCksZj1uKHQpLmxvY2FsKCk7cmV0dXJuIGMuY2FsbChzLGYsaSxlKX19fSkpOyIsICIhZnVuY3Rpb24odCxlKXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1lKCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShlKToodD1cInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOnR8fHNlbGYpLmRheWpzX3BsdWdpbl90aW1lem9uZT1lKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHQ9e3llYXI6MCxtb250aDoxLGRheToyLGhvdXI6MyxtaW51dGU6NCxzZWNvbmQ6NX0sZT17fTtyZXR1cm4gZnVuY3Rpb24obixpLG8pe3ZhciByLGE9ZnVuY3Rpb24odCxuLGkpe3ZvaWQgMD09PWkmJihpPXt9KTt2YXIgbz1uZXcgRGF0ZSh0KSxyPWZ1bmN0aW9uKHQsbil7dm9pZCAwPT09biYmKG49e30pO3ZhciBpPW4udGltZVpvbmVOYW1lfHxcInNob3J0XCIsbz10K1wifFwiK2kscj1lW29dO3JldHVybiByfHwocj1uZXcgSW50bC5EYXRlVGltZUZvcm1hdChcImVuLVVTXCIse2hvdXIxMjohMSx0aW1lWm9uZTp0LHllYXI6XCJudW1lcmljXCIsbW9udGg6XCIyLWRpZ2l0XCIsZGF5OlwiMi1kaWdpdFwiLGhvdXI6XCIyLWRpZ2l0XCIsbWludXRlOlwiMi1kaWdpdFwiLHNlY29uZDpcIjItZGlnaXRcIix0aW1lWm9uZU5hbWU6aX0pLGVbb109cikscn0obixpKTtyZXR1cm4gci5mb3JtYXRUb1BhcnRzKG8pfSx1PWZ1bmN0aW9uKGUsbil7Zm9yKHZhciBpPWEoZSxuKSxyPVtdLHU9MDt1PGkubGVuZ3RoO3UrPTEpe3ZhciBmPWlbdV0scz1mLnR5cGUsbT1mLnZhbHVlLGM9dFtzXTtjPj0wJiYocltjXT1wYXJzZUludChtLDEwKSl9dmFyIGQ9clszXSxsPTI0PT09ZD8wOmQsaD1yWzBdK1wiLVwiK3JbMV0rXCItXCIrclsyXStcIiBcIitsK1wiOlwiK3JbNF0rXCI6XCIrcls1XStcIjowMDBcIix2PStlO3JldHVybihvLnV0YyhoKS52YWx1ZU9mKCktKHYtPXYlMWUzKSkvNmU0fSxmPWkucHJvdG90eXBlO2YudHo9ZnVuY3Rpb24odCxlKXt2b2lkIDA9PT10JiYodD1yKTt2YXIgbixpPXRoaXMudXRjT2Zmc2V0KCksYT10aGlzLnRvRGF0ZSgpLHU9YS50b0xvY2FsZVN0cmluZyhcImVuLVVTXCIse3RpbWVab25lOnR9KSxmPU1hdGgucm91bmQoKGEtbmV3IERhdGUodSkpLzFlMy82MCkscz0xNSotTWF0aC5yb3VuZChhLmdldFRpbWV6b25lT2Zmc2V0KCkvMTUpLWY7aWYoIU51bWJlcihzKSluPXRoaXMudXRjT2Zmc2V0KDAsZSk7ZWxzZSBpZihuPW8odSx7bG9jYWxlOnRoaXMuJEx9KS4kc2V0KFwibWlsbGlzZWNvbmRcIix0aGlzLiRtcykudXRjT2Zmc2V0KHMsITApLGUpe3ZhciBtPW4udXRjT2Zmc2V0KCk7bj1uLmFkZChpLW0sXCJtaW51dGVcIil9cmV0dXJuIG4uJHguJHRpbWV6b25lPXQsbn0sZi5vZmZzZXROYW1lPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuJHguJHRpbWV6b25lfHxvLnR6Lmd1ZXNzKCksbj1hKHRoaXMudmFsdWVPZigpLGUse3RpbWVab25lTmFtZTp0fSkuZmluZCgoZnVuY3Rpb24odCl7cmV0dXJuXCJ0aW1lem9uZW5hbWVcIj09PXQudHlwZS50b0xvd2VyQ2FzZSgpfSkpO3JldHVybiBuJiZuLnZhbHVlfTt2YXIgcz1mLnN0YXJ0T2Y7Zi5zdGFydE9mPWZ1bmN0aW9uKHQsZSl7aWYoIXRoaXMuJHh8fCF0aGlzLiR4LiR0aW1lem9uZSlyZXR1cm4gcy5jYWxsKHRoaXMsdCxlKTt2YXIgbj1vKHRoaXMuZm9ybWF0KFwiWVlZWS1NTS1ERCBISDptbTpzczpTU1NcIikse2xvY2FsZTp0aGlzLiRMfSk7cmV0dXJuIHMuY2FsbChuLHQsZSkudHoodGhpcy4keC4kdGltZXpvbmUsITApfSxvLnR6PWZ1bmN0aW9uKHQsZSxuKXt2YXIgaT1uJiZlLGE9bnx8ZXx8cixmPXUoK28oKSxhKTtpZihcInN0cmluZ1wiIT10eXBlb2YgdClyZXR1cm4gbyh0KS50eihhKTt2YXIgcz1mdW5jdGlvbih0LGUsbil7dmFyIGk9dC02MCplKjFlMyxvPXUoaSxuKTtpZihlPT09bylyZXR1cm5baSxlXTt2YXIgcj11KGktPTYwKihvLWUpKjFlMyxuKTtyZXR1cm4gbz09PXI/W2ksb106W3QtNjAqTWF0aC5taW4obyxyKSoxZTMsTWF0aC5tYXgobyxyKV19KG8udXRjKHQsaSkudmFsdWVPZigpLGYsYSksbT1zWzBdLGM9c1sxXSxkPW8obSkudXRjT2Zmc2V0KGMpO3JldHVybiBkLiR4LiR0aW1lem9uZT1hLGR9LG8udHouZ3Vlc3M9ZnVuY3Rpb24oKXtyZXR1cm4gSW50bC5EYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLnRpbWVab25lfSxvLnR6LnNldERlZmF1bHQ9ZnVuY3Rpb24odCl7cj10fX19KSk7IiwgIiFmdW5jdGlvbihlLHQpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPXQoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKHQpOihlPVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6ZXx8c2VsZikuZGF5anNfcGx1Z2luX2lzb1dlZWs9dCgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciBlPVwiZGF5XCI7cmV0dXJuIGZ1bmN0aW9uKHQsaSxzKXt2YXIgYT1mdW5jdGlvbih0KXtyZXR1cm4gdC5hZGQoNC10Lmlzb1dlZWtkYXkoKSxlKX0sZD1pLnByb3RvdHlwZTtkLmlzb1dlZWtZZWFyPWZ1bmN0aW9uKCl7cmV0dXJuIGEodGhpcykueWVhcigpfSxkLmlzb1dlZWs9ZnVuY3Rpb24odCl7aWYoIXRoaXMuJHV0aWxzKCkudSh0KSlyZXR1cm4gdGhpcy5hZGQoNyoodC10aGlzLmlzb1dlZWsoKSksZSk7dmFyIGksZCxuLG8scj1hKHRoaXMpLHU9KGk9dGhpcy5pc29XZWVrWWVhcigpLGQ9dGhpcy4kdSxuPShkP3MudXRjOnMpKCkueWVhcihpKS5zdGFydE9mKFwieWVhclwiKSxvPTQtbi5pc29XZWVrZGF5KCksbi5pc29XZWVrZGF5KCk+NCYmKG8rPTcpLG4uYWRkKG8sZSkpO3JldHVybiByLmRpZmYodSxcIndlZWtcIikrMX0sZC5pc29XZWVrZGF5PWZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLiR1dGlscygpLnUoZSk/dGhpcy5kYXkoKXx8Nzp0aGlzLmRheSh0aGlzLmRheSgpJTc/ZTplLTcpfTt2YXIgbj1kLnN0YXJ0T2Y7ZC5zdGFydE9mPWZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy4kdXRpbHMoKSxzPSEhaS51KHQpfHx0O3JldHVyblwiaXNvd2Vla1wiPT09aS5wKGUpP3M/dGhpcy5kYXRlKHRoaXMuZGF0ZSgpLSh0aGlzLmlzb1dlZWtkYXkoKS0xKSkuc3RhcnRPZihcImRheVwiKTp0aGlzLmRhdGUodGhpcy5kYXRlKCktMS0odGhpcy5pc29XZWVrZGF5KCktMSkrNykuZW5kT2YoXCJkYXlcIik6bi5iaW5kKHRoaXMpKGUsdCl9fX0pKTsiLCAibGV0IHRva2VuQ291bnRlciA9IDA7XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdW5pcXVlIHRva2VuIGZvciBkZXBlbmRlbmN5IGluamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gZGVzY3JpcHRpb24gT3B0aW9uYWwgZGVzY3JpcHRpb24gZm9yIGRlYnVnZ2luZyBwdXJwb3Nlc1xuICogQHJldHVybnMgQSB1bmlxdWUgdG9rZW4gdGhhdCBjYW4gYmUgdXNlZCBhcyBhIE1hcCBrZXlcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGludGVyZmFjZSBJTG9nZ2VyIHsgbG9nKG1zZzogc3RyaW5nKTogdm9pZCB9XG4gKiBjb25zdCBMb2dnZXJUb2tlbiA9IFRva2VuPElMb2dnZXI+KCdMb2dnZXInKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUb2tlbihkZXNjcmlwdGlvbikge1xuICAgIGNvbnN0IGlkID0gKyt0b2tlbkNvdW50ZXI7XG4gICAgY29uc3Qgc3ltID0gU3ltYm9sKGRlc2NyaXB0aW9uID8gYFRva2VuKCR7ZGVzY3JpcHRpb259KWAgOiBgVG9rZW4jJHtpZH1gKTtcbiAgICBjb25zdCB0b2tlbiA9IHtcbiAgICAgICAgc3ltYm9sOiBzeW0sXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICB0b1N0cmluZygpIHtcbiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvblxuICAgICAgICAgICAgICAgID8gYFRva2VuPCR7ZGVzY3JpcHRpb259PmBcbiAgICAgICAgICAgICAgICA6IGBUb2tlbjwjJHtpZH0+YDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIHRva2VuO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHVuaXF1ZSB0b2tlbiB3aXRob3V0IGEgc3RyaW5nIGxpdGVyYWwuXG4gKiBQcmVmZXJyZWQgZm9yIEF1dG9mYWMtc3R5bGUgREkgdG8gYXZvaWQgc3RyaW5nIGxpdGVyYWxzLlxuICpcbiAqIEByZXR1cm5zIEEgdW5pcXVlIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBNYXAga2V5XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbnRlcmZhY2UgSUxvZ2dlciB7IGxvZyhtc2c6IHN0cmluZyk6IHZvaWQgfVxuICogY29uc3QgTG9nZ2VyVG9rZW4gPSB0b2tlbjxJTG9nZ2VyPigpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRva2VuKCkge1xuICAgIHJldHVybiBUb2tlbigpO1xufVxuIiwgIi8qKlxuICogRXJyb3IgY2xhc3NlcyBmb3IgTm92YURJIGNvbnRhaW5lclxuICovXG5leHBvcnQgY2xhc3MgQ29udGFpbmVyRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gJ0NvbnRhaW5lckVycm9yJztcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgQmluZGluZ05vdEZvdW5kRXJyb3IgZXh0ZW5kcyBDb250YWluZXJFcnJvciB7XG4gICAgY29uc3RydWN0b3IodG9rZW5EZXNjcmlwdGlvbiwgcGF0aCA9IFtdKSB7XG4gICAgICAgIGNvbnN0IHBhdGhTdHIgPSBwYXRoLmxlbmd0aCA+IDAgPyBgXFxuICBEZXBlbmRlbmN5IHBhdGg6ICR7cGF0aC5qb2luKCcgLT4gJyl9YCA6ICcnO1xuICAgICAgICBzdXBlcihgVG9rZW4gXCIke3Rva2VuRGVzY3JpcHRpb259XCIgaXMgbm90IGJvdW5kIG9yIHJlZ2lzdGVyZWQgaW4gdGhlIGNvbnRhaW5lci4ke3BhdGhTdHJ9YCk7XG4gICAgICAgIHRoaXMubmFtZSA9ICdCaW5kaW5nTm90Rm91bmRFcnJvcic7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIENpcmN1bGFyRGVwZW5kZW5jeUVycm9yIGV4dGVuZHMgQ29udGFpbmVyRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHBhdGgpIHtcbiAgICAgICAgc3VwZXIoYENpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0ZWQ6ICR7cGF0aC5qb2luKCcgLT4gJyl9YCk7XG4gICAgICAgIHRoaXMubmFtZSA9ICdDaXJjdWxhckRlcGVuZGVuY3lFcnJvcic7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQXV0b1dpcmUgLSBBdXRvbWF0aWMgZGVwZW5kZW5jeSBpbmplY3Rpb24gZm9yIE5vdmFESVxuICogU3VwcG9ydHMgdHdvIHN0cmF0ZWdpZXM6IG1hcFJlc29sdmVycyAodHJhbnNmb3JtZXItZ2VuZXJhdGVkKSBhbmQgbWFwIChtYW51YWwgb3ZlcnJpZGUpXG4gKi9cbi8qKlxuICogUGVyZm9ybWFuY2U6IENhY2hlIGV4dHJhY3RlZCBwYXJhbWV0ZXIgbmFtZXMgdG8gYXZvaWQgcmVwZWF0ZWQgcmVnZXggcGFyc2luZ1xuICogV2Vha01hcCBhbGxvd3MgZ2FyYmFnZSBjb2xsZWN0aW9uIHdoZW4gY29uc3RydWN0b3IgaXMgbm8gbG9uZ2VyIHJlZmVyZW5jZWRcbiAqL1xuY29uc3QgcGFyYW1OYW1lQ2FjaGUgPSBuZXcgV2Vha01hcCgpO1xuLyoqXG4gKiBFeHRyYWN0IHBhcmFtZXRlciBuYW1lcyBmcm9tIGEgY29uc3RydWN0b3IgZnVuY3Rpb25cbiAqIFVzZXMgcmVnZXggdG8gcGFyc2UgdGhlIHRvU3RyaW5nKCkgcmVwcmVzZW50YXRpb25cbiAqIFBlcmZvcm1hbmNlIG9wdGltaXplZDogUmVzdWx0cyBhcmUgY2FjaGVkIHBlciBjb25zdHJ1Y3RvclxuICpcbiAqIE5vdGU6IE9ubHkgdXNlZCBieSByZXNvbHZlQnlNYXAoKSBmb3IgbWFudWFsIG1hcCBzdHJhdGVneVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFBhcmFtZXRlck5hbWVzKGNvbnN0cnVjdG9yKSB7XG4gICAgLy8gQ2hlY2sgY2FjaGUgZmlyc3QgLSBhdm9pZHMgZXhwZW5zaXZlIHJlZ2V4IHBhcnNpbmdcbiAgICBjb25zdCBjYWNoZWQgPSBwYXJhbU5hbWVDYWNoZS5nZXQoY29uc3RydWN0b3IpO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG4gICAgLy8gRXh0cmFjdCBwYXJhbWV0ZXIgbmFtZXMgKGV4cGVuc2l2ZSBvcGVyYXRpb24pXG4gICAgY29uc3QgZm5TdHIgPSBjb25zdHJ1Y3Rvci50b1N0cmluZygpO1xuICAgIC8vIE1hdGNoIGNvbnN0cnVjdG9yKC4uLmFyZ3MpIG9yIGNsYXNzIHsgY29uc3RydWN0b3IoLi4uYXJncykgfVxuICAgIGNvbnN0IG1hdGNoID0gZm5TdHIubWF0Y2goL2NvbnN0cnVjdG9yXFxzKlxcKChbXildKilcXCkvKSB8fCBmblN0ci5tYXRjaCgvXlteKF0qXFwoKFteKV0qKVxcKS8pO1xuICAgIGlmICghbWF0Y2ggfHwgIW1hdGNoWzFdKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbMV1cbiAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgLm1hcChwYXJhbSA9PiBwYXJhbS50cmltKCkpXG4gICAgICAgIC5maWx0ZXIocGFyYW0gPT4gcGFyYW0ubGVuZ3RoID4gMClcbiAgICAgICAgLm1hcChwYXJhbSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSBkZWZhdWx0IHZhbHVlcywgdHlwZSBhbm5vdGF0aW9ucywgYW5kIGV4dHJhY3QganVzdCB0aGUgbmFtZVxuICAgICAgICBsZXQgbmFtZSA9IHBhcmFtLnNwbGl0KC9bOj1dLylbMF0udHJpbSgpO1xuICAgICAgICAvLyBSZW1vdmUgVHlwZVNjcmlwdCBtb2RpZmllcnMgKHB1YmxpYywgcHJpdmF0ZSwgcHJvdGVjdGVkLCByZWFkb25seSlcbiAgICAgICAgLy8gQ2FuIGFwcGVhciBtdWx0aXBsZSB0aW1lcywgZS5nLiwgXCJwdWJsaWMgcmVhZG9ubHkgc2VydmljZVwiXG4gICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoL14oKHB1YmxpY3xwcml2YXRlfHByb3RlY3RlZHxyZWFkb25seSlcXHMrKSsvLCAnJyk7XG4gICAgICAgIC8vIEhhbmRsZSBkZXN0cnVjdHVyaW5nIC0gc2tpcCBmb3Igbm93XG4gICAgICAgIGlmIChuYW1lLmluY2x1ZGVzKCd7JykgfHwgbmFtZS5pbmNsdWRlcygnWycpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmFtZTtcbiAgICB9KVxuICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBudWxsKTtcbiAgICAvLyBDYWNoZSByZXN1bHQgZm9yIGZ1dHVyZSBjYWxsc1xuICAgIHBhcmFtTmFtZUNhY2hlLnNldChjb25zdHJ1Y3RvciwgcGFyYW1zKTtcbiAgICByZXR1cm4gcGFyYW1zO1xufVxuLyoqXG4gKiBSZXNvbHZlIGRlcGVuZGVuY2llcyB1c2luZyBtYXAgc3RyYXRlZ3lcbiAqIFVzZXMgZXhwbGljaXQgbWFwcGluZyBmcm9tIHBhcmFtZXRlciBuYW1lcyB0byByZXNvbHZlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCeU1hcChjb25zdHJ1Y3RvciwgY29udGFpbmVyLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zLm1hcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dG9XaXJlIG1hcCBzdHJhdGVneSByZXF1aXJlcyBvcHRpb25zLm1hcCB0byBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIGNvbnN0IHBhcmFtTmFtZXMgPSBleHRyYWN0UGFyYW1ldGVyTmFtZXMoY29uc3RydWN0b3IpO1xuICAgIGNvbnN0IHJlc29sdmVkRGVwcyA9IFtdO1xuICAgIGZvciAoY29uc3QgcGFyYW1OYW1lIG9mIHBhcmFtTmFtZXMpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZXIgPSBvcHRpb25zLm1hcFtwYXJhbU5hbWVdO1xuICAgICAgICBpZiAocmVzb2x2ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgcmVzb2x2ZSBwYXJhbWV0ZXIgXCIke3BhcmFtTmFtZX1cIiBvbiAke2NvbnN0cnVjdG9yLm5hbWV9LiBgICtcbiAgICAgICAgICAgICAgICAgICAgYE5vdCBmb3VuZCBpbiBhdXRvd2lyZSBtYXAuIGAgK1xuICAgICAgICAgICAgICAgICAgICBgQWRkIGl0IHRvIHRoZSBtYXA6IC5hdXRvV2lyZSh7IG1hcDogeyAke3BhcmFtTmFtZX06IC4uLiB9IH0pYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTaWxlbnRseSBwdXNoIHVuZGVmaW5lZCBmb3IgbWlzc2luZyBwYXJhbWV0ZXJzXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBleHBlY3RlZDogdHJhbnNmb3JtZXIgZmlsdGVycyBvdXQgcHJpbWl0aXZlIHR5cGVzIGF0IGNvbXBpbGUtdGltZSxcbiAgICAgICAgICAgICAgICAvLyBzbyBtaXNzaW5nIHBhcmFtcyBhcmUgdHlwaWNhbGx5IHByaW1pdGl2ZXMgdGhhdCBkb24ndCBuZWVkIERJIHJlc29sdXRpb25cbiAgICAgICAgICAgICAgICByZXNvbHZlZERlcHMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzb2x2ZXIgY2FuIGJlIGEgZnVuY3Rpb24gb3IgYSBUb2tlblxuICAgICAgICBpZiAodHlwZW9mIHJlc29sdmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXNvbHZlZERlcHMucHVzaChyZXNvbHZlcihjb250YWluZXIpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIEFzc3VtZSBpdCdzIGEgVG9rZW5cbiAgICAgICAgICAgIHJlc29sdmVkRGVwcy5wdXNoKGNvbnRhaW5lci5yZXNvbHZlKHJlc29sdmVyKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc29sdmVkRGVwcztcbn1cbi8qKlxuICogUmVzb2x2ZSBkZXBlbmRlbmNpZXMgdXNpbmcgbWFwUmVzb2x2ZXJzIGFycmF5IHN0cmF0ZWd5XG4gKiBPUFRJTUFMIFBFUkZPUk1BTkNFOiBPKDEpIGFycmF5IGFjY2VzcyBwZXIgcGFyYW1ldGVyXG4gKiBNaW5pZmljYXRpb24tc2FmZTogVXNlcyBwb3NpdGlvbi1iYXNlZCBhcnJheVxuICogUmVmYWN0b3JpbmctZnJpZW5kbHk6IFRyYW5zZm9ybWVyIHJlZ2VuZXJhdGVzIGFycmF5IG9uIHJlY29tcGlsZVxuICpcbiAqIFJlcXVpcmVzIGJ1aWxkLXRpbWUgdHJhbnNmb3JtZXIgdG8gZ2VuZXJhdGUgbWFwUmVzb2x2ZXJzIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQnlNYXBSZXNvbHZlcnMoX2NvbnN0cnVjdG9yLCBjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMubWFwUmVzb2x2ZXJzIHx8IG9wdGlvbnMubWFwUmVzb2x2ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHJlc29sdmVkRGVwcyA9IFtdO1xuICAgIC8vIFNpbXBsZSBPKDEpIGFycmF5IGFjY2VzcyAtIHVsdHJhIGZhc3QhXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm1hcFJlc29sdmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCByZXNvbHZlciA9IG9wdGlvbnMubWFwUmVzb2x2ZXJzW2ldO1xuICAgICAgICBpZiAocmVzb2x2ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gdW5kZWZpbmVkIGluZGljYXRlcyBwcmltaXRpdmUgdHlwZSBvciBwYXJhbWV0ZXIgd2l0aG91dCBESVxuICAgICAgICAgICAgcmVzb2x2ZWREZXBzLnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgcmVzb2x2ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIFJlc29sdmVyIGZ1bmN0aW9uOiAoYykgPT4gYy5yZXNvbHZlVHlwZSguLi4pXG4gICAgICAgICAgICByZXNvbHZlZERlcHMucHVzaChyZXNvbHZlcihjb250YWluZXIpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRva2VuLWJhc2VkIHJlc29sdXRpb25cbiAgICAgICAgICAgIHJlc29sdmVkRGVwcy5wdXNoKGNvbnRhaW5lci5yZXNvbHZlKHJlc29sdmVyKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc29sdmVkRGVwcztcbn1cbi8qKlxuICogTWFpbiBhdXRvd2lyZSBmdW5jdGlvbiAtIGRpc3BhdGNoZXMgdG8gYXBwcm9wcmlhdGUgc3RyYXRlZ3lcbiAqIFByaW9yaXR5OiBtYXBSZXNvbHZlcnMgKHRyYW5zZm9ybWVyLWdlbmVyYXRlZCkgPiBtYXAgKG1hbnVhbCBvdmVycmlkZSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF1dG93aXJlKGNvbnN0cnVjdG9yLCBjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgICBieTogJ3BhcmFtTmFtZScsXG4gICAgICAgIHN0cmljdDogZmFsc2UsXG4gICAgICAgIC4uLm9wdGlvbnNcbiAgICB9O1xuICAgIC8vIEhJR0hFU1QgUFJJT1JJVFk6IG1hcFJlc29sdmVycyBhcnJheSAodHJhbnNmb3JtZXItZ2VuZXJhdGVkLCBvcHRpbWFsIHBlcmZvcm1hbmNlKVxuICAgIC8vIE8oMSkgYXJyYXkgYWNjZXNzIHBlciBwYXJhbWV0ZXIgLSBtaW5pZmljYXRpb24tc2FmZSBhbmQgcmVmYWN0b3JpbmctZnJpZW5kbHlcbiAgICBpZiAob3B0cy5tYXBSZXNvbHZlcnMgJiYgb3B0cy5tYXBSZXNvbHZlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZUJ5TWFwUmVzb2x2ZXJzKGNvbnN0cnVjdG9yLCBjb250YWluZXIsIG9wdHMpO1xuICAgIH1cbiAgICAvLyBGQUxMQkFDSzogTWFudWFsIG1hcCBzdHJhdGVneSBmb3IgZXhwbGljaXQgb3ZlcnJpZGVzXG4gICAgaWYgKG9wdHMubWFwICYmIE9iamVjdC5rZXlzKG9wdHMubWFwKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlQnlNYXAoY29uc3RydWN0b3IsIGNvbnRhaW5lciwgb3B0cyk7XG4gICAgfVxuICAgIC8vIE5vIGF1dG93aXJpbmcgY29uZmlndXJlZCwgcmV0dXJuIGVtcHR5IGFycmF5XG4gICAgcmV0dXJuIFtdO1xufVxuIiwgIi8qKlxuICogRmx1ZW50IGJ1aWxkZXIgQVBJIGZvciBOb3ZhREkgQ29udGFpbmVyIChBdXRvZmFjLXN0eWxlKVxuICovXG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gJy4vdG9rZW4uanMnO1xuaW1wb3J0IHsgYXV0b3dpcmUgfSBmcm9tICcuL2F1dG93aXJlLmpzJztcbi8qKlxuICogRmx1ZW50IHJlZ2lzdHJhdGlvbiBidWlsZGVyIHJldHVybmVkIGFmdGVyIGVhY2ggcmVnaXN0cmF0aW9uIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgUmVnaXN0cmF0aW9uQnVpbGRlciB7XG4gICAgY29uc3RydWN0b3IocGVuZGluZywgcmVnaXN0cmF0aW9ucykge1xuICAgICAgICB0aGlzLnJlZ2lzdHJhdGlvbnMgPSByZWdpc3RyYXRpb25zO1xuICAgICAgICB0aGlzLmNvbmZpZ3MgPSBbXTtcbiAgICAgICAgdGhpcy5kZWZhdWx0TGlmZXRpbWUgPSAnc2luZ2xldG9uJztcbiAgICAgICAgdGhpcy5wZW5kaW5nID0gcGVuZGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCB0aGlzIHJlZ2lzdHJhdGlvbiB0byBhIHRva2VuIG9yIGludGVyZmFjZSB0eXBlXG4gICAgICpcbiAgICAgKiBAb3ZlcmxvYWRcbiAgICAgKiBAcGFyYW0ge1Rva2VuPFU+fSB0b2tlbiAtIEV4cGxpY2l0IHRva2VuIGZvciBiaW5kaW5nXG4gICAgICpcbiAgICAgKiBAb3ZlcmxvYWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZU5hbWUgLSBJbnRlcmZhY2UgdHlwZSBuYW1lIChhdXRvLWdlbmVyYXRlZCBieSB0cmFuc2Zvcm1lcilcbiAgICAgKi9cbiAgICBhcyh0b2tlbk9yVHlwZU5hbWUpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgYXJndW1lbnQgaXMgYSBUb2tlbiBvYmplY3QgKGhhcyBzeW1ib2wgcHJvcGVydHkpXG4gICAgICAgIGlmICh0b2tlbk9yVHlwZU5hbWUgJiYgdHlwZW9mIHRva2VuT3JUeXBlTmFtZSA9PT0gJ29iamVjdCcgJiYgJ3N5bWJvbCcgaW4gdG9rZW5PclR5cGVOYW1lKSB7XG4gICAgICAgICAgICAvLyBUb2tlbi1iYXNlZCByZWdpc3RyYXRpb25cbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW5PclR5cGVOYW1lLFxuICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMucGVuZGluZy50eXBlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB0aGlzLnBlbmRpbmcudmFsdWUsXG4gICAgICAgICAgICAgICAgZmFjdG9yeTogdGhpcy5wZW5kaW5nLmZhY3RvcnksXG4gICAgICAgICAgICAgICAgY29uc3RydWN0b3I6IHRoaXMucGVuZGluZy5jb25zdHJ1Y3RvcixcbiAgICAgICAgICAgICAgICBsaWZldGltZTogdGhpcy5kZWZhdWx0TGlmZXRpbWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3MucHVzaChjb25maWcpO1xuICAgICAgICAgICAgdGhpcy5yZWdpc3RyYXRpb25zLnB1c2goY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gSW50ZXJmYWNlLWJhc2VkIHJlZ2lzdHJhdGlvbiAodHlwZU5hbWUgc3RyaW5nIG9yIHVuZGVmaW5lZClcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICB0b2tlbjogbnVsbCwgLy8gV2lsbCBiZSBzZXQgZHVyaW5nIGJ1aWxkKClcbiAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLnBlbmRpbmcudHlwZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdGhpcy5wZW5kaW5nLnZhbHVlLFxuICAgICAgICAgICAgICAgIGZhY3Rvcnk6IHRoaXMucGVuZGluZy5mYWN0b3J5LFxuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB0aGlzLnBlbmRpbmcuY29uc3RydWN0b3IsXG4gICAgICAgICAgICAgICAgbGlmZXRpbWU6IHRoaXMuZGVmYXVsdExpZmV0aW1lLFxuICAgICAgICAgICAgICAgIGludGVyZmFjZVR5cGU6IHRva2VuT3JUeXBlTmFtZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuY29uZmlncy5wdXNoKGNvbmZpZyk7XG4gICAgICAgICAgICB0aGlzLnJlZ2lzdHJhdGlvbnMucHVzaChjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYXMgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgYW4gaW50ZXJmYWNlXG4gICAgICogQ29tYmluZXMgYXMoKSArIGFzRGVmYXVsdCgpXG4gICAgICovXG4gICAgYXNEZWZhdWx0SW50ZXJmYWNlKHR5cGVOYW1lKSB7XG4gICAgICAgIHRoaXMuYXMoXCJUSW50ZXJmYWNlXCIsIHR5cGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXNEZWZhdWx0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGFzIGEga2V5ZWQgaW50ZXJmYWNlIGltcGxlbWVudGF0aW9uXG4gICAgICogQ29tYmluZXMgYXMoKSArIGtleWVkKClcbiAgICAgKi9cbiAgICBhc0tleWVkSW50ZXJmYWNlKGtleSwgdHlwZU5hbWUpIHtcbiAgICAgICAgdGhpcy5hcyhcIlRJbnRlcmZhY2VcIiwgdHlwZU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5rZXllZChrZXkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhcyBtdWx0aXBsZSBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzXG4gICAgICovXG4gICAgYXNJbXBsZW1lbnRlZEludGVyZmFjZXModG9rZW5zKSB7XG4gICAgICAgIGlmICh0b2tlbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGVyZSBhcmUgZXhpc3RpbmcgY29uZmlncyAoZnJvbSBwcmV2aW91cyBhcygpIGNhbGxzKSwgYWRkIHRoZXNlIGFzIGFkZGl0aW9uYWwgaW50ZXJmYWNlc1xuICAgICAgICBpZiAodGhpcy5jb25maWdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIEFkZCBhbGwgdG9rZW5zIGFzIGFkZGl0aW9uYWwgaW50ZXJmYWNlcyB0byBleGlzdGluZyBjb25maWdzXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgICAgICBjb25maWcubGlmZXRpbWUgPSAnc2luZ2xldG9uJzsgLy8gYXNJbXBsZW1lbnRlZEludGVyZmFjZXMgZGVmYXVsdHMgdG8gc2luZ2xldG9uXG4gICAgICAgICAgICAgICAgY29uZmlnLmFkZGl0aW9uYWxUb2tlbnMgPSBjb25maWcuYWRkaXRpb25hbFRva2VucyB8fCBbXTtcbiAgICAgICAgICAgICAgICBjb25maWcuYWRkaXRpb25hbFRva2Vucy5wdXNoKC4uLnRva2Vucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBleGlzdGluZyBjb25maWdzLCBjcmVhdGUgbmV3IG9uZSB3aXRoIGZpcnN0IHRva2VuXG4gICAgICAgIGNvbnN0IGZpcnN0Q29uZmlnID0ge1xuICAgICAgICAgICAgdG9rZW46IHRva2Vuc1swXSxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMucGVuZGluZy50eXBlLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMucGVuZGluZy52YWx1ZSxcbiAgICAgICAgICAgIGZhY3Rvcnk6IHRoaXMucGVuZGluZy5mYWN0b3J5LFxuICAgICAgICAgICAgY29uc3RydWN0b3I6IHRoaXMucGVuZGluZy5jb25zdHJ1Y3RvcixcbiAgICAgICAgICAgIGxpZmV0aW1lOiAnc2luZ2xldG9uJ1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNvbmZpZ3MucHVzaChmaXJzdENvbmZpZyk7XG4gICAgICAgIHRoaXMucmVnaXN0cmF0aW9ucy5wdXNoKGZpcnN0Q29uZmlnKTtcbiAgICAgICAgLy8gQWRkaXRpb25hbCB0b2tlbnMgcmVmZXJlbmNlIHRoZSBzYW1lIHJlZ2lzdHJhdGlvblxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZmlyc3RDb25maWcuYWRkaXRpb25hbFRva2VucyA9IGZpcnN0Q29uZmlnLmFkZGl0aW9uYWxUb2tlbnMgfHwgW107XG4gICAgICAgICAgICBmaXJzdENvbmZpZy5hZGRpdGlvbmFsVG9rZW5zLnB1c2godG9rZW5zW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHNpbmdsZXRvbiBsaWZldGltZSAob25lIGluc3RhbmNlIGZvciBlbnRpcmUgY29udGFpbmVyKVxuICAgICAqL1xuICAgIHNpbmdsZUluc3RhbmNlKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5saWZldGltZSA9ICdzaW5nbGV0b24nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgcGVyLXJlcXVlc3QgbGlmZXRpbWUgKG9uZSBpbnN0YW5jZSBwZXIgcmVzb2x2ZSBjYWxsIHRyZWUpXG4gICAgICovXG4gICAgaW5zdGFuY2VQZXJSZXF1ZXN0KCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5saWZldGltZSA9ICdwZXItcmVxdWVzdCc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0cmFuc2llbnQgbGlmZXRpbWUgKG5ldyBpbnN0YW5jZSBldmVyeSB0aW1lKVxuICAgICAqIEFsaWFzIGZvciBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICovXG4gICAgaW5zdGFuY2VQZXJEZXBlbmRlbmN5KCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5saWZldGltZSA9ICd0cmFuc2llbnQnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBOYW1lIHRoaXMgcmVnaXN0cmF0aW9uIGZvciBuYW1lZCByZXNvbHV0aW9uXG4gICAgICovXG4gICAgbmFtZWQobmFtZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLmNvbmZpZ3MpIHtcbiAgICAgICAgICAgIGNvbmZpZy5uYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogS2V5IHRoaXMgcmVnaXN0cmF0aW9uIGZvciBrZXllZCByZXNvbHV0aW9uXG4gICAgICovXG4gICAga2V5ZWQoa2V5KSB7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMuY29uZmlncykge1xuICAgICAgICAgICAgY29uZmlnLmtleSA9IGtleTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFyayB0aGlzIGFzIGRlZmF1bHQgcmVnaXN0cmF0aW9uXG4gICAgICogRGVmYXVsdCByZWdpc3RyYXRpb25zIGRvbid0IG92ZXJyaWRlIGV4aXN0aW5nIG9uZXNcbiAgICAgKi9cbiAgICBhc0RlZmF1bHQoKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMuY29uZmlncykge1xuICAgICAgICAgICAgY29uZmlnLmlzRGVmYXVsdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9ubHkgcmVnaXN0ZXIgaWYgdG9rZW4gbm90IGFscmVhZHkgcmVnaXN0ZXJlZFxuICAgICAqL1xuICAgIGlmTm90UmVnaXN0ZXJlZCgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcuaWZOb3RSZWdpc3RlcmVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBwYXJhbWV0ZXIgdmFsdWVzIGZvciBjb25zdHJ1Y3RvciAocHJpbWl0aXZlcyBhbmQgY29uc3RhbnRzKVxuICAgICAqIFVzZSB0aGlzIGZvciBub24tREkgcGFyYW1ldGVycyBsaWtlIHN0cmluZ3MsIG51bWJlcnMsIGNvbmZpZyB2YWx1ZXNcbiAgICAgKi9cbiAgICB3aXRoUGFyYW1ldGVycyhwYXJhbWV0ZXJzKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMuY29uZmlncykge1xuICAgICAgICAgICAgY29uZmlnLnBhcmFtZXRlclZhbHVlcyA9IHBhcmFtZXRlcnM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuYWJsZSBhdXRvbWF0aWMgZGVwZW5kZW5jeSBpbmplY3Rpb24gKGF1dG93aXJpbmcpXG4gICAgICogU3VwcG9ydHMgdGhyZWUgc3RyYXRlZ2llczogcGFyYW1OYW1lIChkZWZhdWx0KSwgbWFwLCBhbmQgY2xhc3NcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBgdHNcbiAgICAgKiAvLyBTdHJhdGVneSAxOiBwYXJhbU5hbWUgKGRlZmF1bHQsIHJlcXVpcmVzIG5vbi1taW5pZmllZCBjb2RlIGluIGRldilcbiAgICAgKiBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXM8SUV2ZW50QnVzPigpLmF1dG9XaXJlKClcbiAgICAgKlxuICAgICAqIC8vIFN0cmF0ZWd5IDI6IG1hcCAobWluaWZ5LXNhZmUsIGV4cGxpY2l0KVxuICAgICAqIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEV2ZW50QnVzKS5hczxJRXZlbnRCdXM+KCkuYXV0b1dpcmUoe1xuICAgICAqICAgbWFwOiB7XG4gICAgICogICAgIGxvZ2dlcjogKGMpID0+IGMucmVzb2x2ZVR5cGU8SUxvZ2dlcj4oKVxuICAgICAqICAgfVxuICAgICAqIH0pXG4gICAgICpcbiAgICAgKiAvLyBTdHJhdGVneSAzOiBjbGFzcyAocmVxdWlyZXMgYnVpbGQtdGltZSBjb2RlZ2VuKVxuICAgICAqIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEV2ZW50QnVzKS5hczxJRXZlbnRCdXM+KCkuYXV0b1dpcmUoeyBieTogJ2NsYXNzJyB9KVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGF1dG9XaXJlKG9wdGlvbnMpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb25maWcgb2YgdGhpcy5jb25maWdzKSB7XG4gICAgICAgICAgICBjb25maWcuYXV0b3dpcmVPcHRpb25zID0gb3B0aW9ucyB8fCB7IGJ5OiAncGFyYW1OYW1lJywgc3RyaWN0OiBmYWxzZSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogRmx1ZW50IGJ1aWxkZXIgZm9yIENvbnRhaW5lciBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBCdWlsZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihiYXNlQ29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuYmFzZUNvbnRhaW5lciA9IGJhc2VDb250YWluZXI7XG4gICAgICAgIHRoaXMucmVnaXN0cmF0aW9ucyA9IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGNsYXNzIGNvbnN0cnVjdG9yXG4gICAgICovXG4gICAgcmVnaXN0ZXJUeXBlKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIGNvbnN0IHBlbmRpbmcgPSB7XG4gICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBuZXcgUmVnaXN0cmF0aW9uQnVpbGRlcihwZW5kaW5nLCB0aGlzLnJlZ2lzdHJhdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIHByZS1jcmVhdGVkIGluc3RhbmNlXG4gICAgICovXG4gICAgcmVnaXN0ZXJJbnN0YW5jZShpbnN0YW5jZSkge1xuICAgICAgICBjb25zdCBwZW5kaW5nID0ge1xuICAgICAgICAgICAgdHlwZTogJ2luc3RhbmNlJyxcbiAgICAgICAgICAgIHZhbHVlOiBpbnN0YW5jZSxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWdpc3RyYXRpb25CdWlsZGVyKHBlbmRpbmcsIHRoaXMucmVnaXN0cmF0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgZmFjdG9yeSBmdW5jdGlvblxuICAgICAqL1xuICAgIHJlZ2lzdGVyKGZhY3RvcnkpIHtcbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdmYWN0b3J5JyxcbiAgICAgICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgICAgICAgZmFjdG9yeSxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWdpc3RyYXRpb25CdWlsZGVyKHBlbmRpbmcsIHRoaXMucmVnaXN0cmF0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIGEgbW9kdWxlIChmdW5jdGlvbiB0aGF0IGFkZHMgbXVsdGlwbGUgcmVnaXN0cmF0aW9ucylcbiAgICAgKi9cbiAgICBtb2R1bGUobW9kdWxlRnVuYykge1xuICAgICAgICBtb2R1bGVGdW5jKHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzb2x2ZSBpbnRlcmZhY2UgdHlwZSBuYW1lcyB0byB0b2tlbnNcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICByZXNvbHZlSW50ZXJmYWNlVG9rZW5zKGNvbnRhaW5lcikge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLnJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChjb25maWcuaW50ZXJmYWNlVHlwZSAhPT0gdW5kZWZpbmVkICYmICFjb25maWcudG9rZW4pIHtcbiAgICAgICAgICAgICAgICBjb25maWcudG9rZW4gPSBjb250YWluZXIuaW50ZXJmYWNlVG9rZW4oY29uZmlnLmludGVyZmFjZVR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElkZW50aWZ5IHRva2VucyB0aGF0IGhhdmUgbm9uLWRlZmF1bHQgcmVnaXN0cmF0aW9uc1xuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGlkZW50aWZ5Tm9uRGVmYXVsdFRva2VucygpIHtcbiAgICAgICAgY29uc3QgdG9rZW5zV2l0aE5vbkRlZmF1bHRzID0gbmV3IFNldCgpO1xuICAgICAgICBmb3IgKGNvbnN0IGNvbmZpZyBvZiB0aGlzLnJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghY29uZmlnLmlzRGVmYXVsdCAmJiAhY29uZmlnLm5hbWUgJiYgY29uZmlnLmtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdG9rZW5zV2l0aE5vbkRlZmF1bHRzLmFkZChjb25maWcudG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0b2tlbnNXaXRoTm9uRGVmYXVsdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHJlZ2lzdHJhdGlvbiBzaG91bGQgYmUgc2tpcHBlZFxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHNob3VsZFNraXBSZWdpc3RyYXRpb24oY29uZmlnLCB0b2tlbnNXaXRoTm9uRGVmYXVsdHMsIHJlZ2lzdGVyZWRUb2tlbnMpIHtcbiAgICAgICAgLy8gU2tpcCBkZWZhdWx0IHJlZ2lzdHJhdGlvbnMgaWYgdGhlcmUncyBhIG5vbi1kZWZhdWx0IGZvciB0aGUgc2FtZSB0b2tlblxuICAgICAgICBpZiAoY29uZmlnLmlzRGVmYXVsdCAmJiAhY29uZmlnLm5hbWUgJiYgY29uZmlnLmtleSA9PT0gdW5kZWZpbmVkICYmIHRva2Vuc1dpdGhOb25EZWZhdWx0cy5oYXMoY29uZmlnLnRva2VuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSGFuZGxlIGlmTm90UmVnaXN0ZXJlZFxuICAgICAgICBpZiAoY29uZmlnLmlmTm90UmVnaXN0ZXJlZCAmJiByZWdpc3RlcmVkVG9rZW5zLmhhcyhjb25maWcudG9rZW4pKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBIYW5kbGUgYXNEZWZhdWx0XG4gICAgICAgIGlmIChjb25maWcuaXNEZWZhdWx0ICYmIHJlZ2lzdGVyZWRUb2tlbnMuaGFzKGNvbmZpZy50b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGJpbmRpbmcgdG9rZW4gZm9yIHJlZ2lzdHJhdGlvbiAobmFtZWQsIGtleWVkLCBvciBtdWx0aSlcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjcmVhdGVCaW5kaW5nVG9rZW4oY29uZmlnLCBuYW1lZFJlZ2lzdHJhdGlvbnMsIGtleWVkUmVnaXN0cmF0aW9ucywgbXVsdGlSZWdpc3RyYXRpb25zKSB7XG4gICAgICAgIGlmIChjb25maWcubmFtZSkge1xuICAgICAgICAgICAgLy8gTmFtZWQgcmVnaXN0cmF0aW9uIGdldHMgdW5pcXVlIHRva2VuXG4gICAgICAgICAgICBjb25zdCBiaW5kaW5nVG9rZW4gPSBUb2tlbihgX19uYW1lZF8ke2NvbmZpZy5uYW1lfWApO1xuICAgICAgICAgICAgbmFtZWRSZWdpc3RyYXRpb25zLnNldChjb25maWcubmFtZSwgeyAuLi5jb25maWcsIHRva2VuOiBiaW5kaW5nVG9rZW4gfSk7XG4gICAgICAgICAgICByZXR1cm4gYmluZGluZ1Rva2VuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbmZpZy5rZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gS2V5ZWQgcmVnaXN0cmF0aW9uIGdldHMgdW5pcXVlIHRva2VuXG4gICAgICAgICAgICBjb25zdCBrZXlTdHIgPSB0eXBlb2YgY29uZmlnLmtleSA9PT0gJ3N5bWJvbCcgPyBjb25maWcua2V5LnRvU3RyaW5nKCkgOiBjb25maWcua2V5O1xuICAgICAgICAgICAgY29uc3QgYmluZGluZ1Rva2VuID0gVG9rZW4oYF9fa2V5ZWRfJHtrZXlTdHJ9YCk7XG4gICAgICAgICAgICBrZXllZFJlZ2lzdHJhdGlvbnMuc2V0KGNvbmZpZy5rZXksIHsgLi4uY29uZmlnLCB0b2tlbjogYmluZGluZ1Rva2VuIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb2tlbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIE11bHRpLXJlZ2lzdHJhdGlvbiBoYW5kbGluZ1xuICAgICAgICAgICAgaWYgKG11bHRpUmVnaXN0cmF0aW9ucy5oYXMoY29uZmlnLnRva2VuKSkge1xuICAgICAgICAgICAgICAgIC8vIFN1YnNlcXVlbnQgcmVnaXN0cmF0aW9uIGZvciB0aGlzIHRva2VuXG4gICAgICAgICAgICAgICAgY29uc3QgYmluZGluZ1Rva2VuID0gVG9rZW4oYF9fbXVsdGlfJHtjb25maWcudG9rZW4udG9TdHJpbmcoKX1fJHttdWx0aVJlZ2lzdHJhdGlvbnMuZ2V0KGNvbmZpZy50b2tlbikubGVuZ3RofWApO1xuICAgICAgICAgICAgICAgIG11bHRpUmVnaXN0cmF0aW9ucy5nZXQoY29uZmlnLnRva2VuKS5wdXNoKGJpbmRpbmdUb2tlbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpbmRpbmdUb2tlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEZpcnN0IHJlZ2lzdHJhdGlvbiBmb3IgdGhpcyB0b2tlbiwgdXNlIHRoZSBvcmlnaW5hbCB0b2tlblxuICAgICAgICAgICAgICAgIG11bHRpUmVnaXN0cmF0aW9ucy5zZXQoY29uZmlnLnRva2VuLCBbY29uZmlnLnRva2VuXSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbmZpZy50b2tlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhZGRpdGlvbmFsIGludGVyZmFjZXMgZm9yIGEgY29uZmlnXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcmVnaXN0ZXJBZGRpdGlvbmFsSW50ZXJmYWNlcyhjb250YWluZXIsIGNvbmZpZywgYmluZGluZ1Rva2VuLCByZWdpc3RlcmVkVG9rZW5zKSB7XG4gICAgICAgIGlmIChjb25maWcuYWRkaXRpb25hbFRva2Vucykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhZGRpdGlvbmFsVG9rZW4gb2YgY29uZmlnLmFkZGl0aW9uYWxUb2tlbnMpIHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBmYWN0b3J5IHRoYXQgcmVzb2x2ZXMgdGhlIGJpbmRpbmcgdG9rZW5cbiAgICAgICAgICAgICAgICBjb250YWluZXIuYmluZEZhY3RvcnkoYWRkaXRpb25hbFRva2VuLCAoYykgPT4gYy5yZXNvbHZlKGJpbmRpbmdUb2tlbiksIHsgbGlmZXRpbWU6IGNvbmZpZy5saWZldGltZSB9KTtcbiAgICAgICAgICAgICAgICByZWdpc3RlcmVkVG9rZW5zLmFkZChhZGRpdGlvbmFsVG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJ1aWxkIHRoZSBjb250YWluZXIgd2l0aCBhbGwgcmVnaXN0ZXJlZCBiaW5kaW5nc1xuICAgICAqL1xuICAgIGJ1aWxkKCkge1xuICAgICAgICAvLyBDcmVhdGUgbmV3IGNvbnRhaW5lciBpbmhlcml0aW5nIGZyb20gYmFzZVxuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmJhc2VDb250YWluZXIuY3JlYXRlQ2hpbGQoKTtcbiAgICAgICAgLy8gUHJlLXByb2Nlc3M6IHJlc29sdmUgaW50ZXJmYWNlIHR5cGVzIHRvIHRva2Vuc1xuICAgICAgICB0aGlzLnJlc29sdmVJbnRlcmZhY2VUb2tlbnMoY29udGFpbmVyKTtcbiAgICAgICAgLy8gVHJhY2sgd2hhdCdzIGJlZW4gcmVnaXN0ZXJlZCBmb3IgaWZOb3RSZWdpc3RlcmVkIGNoZWNrc1xuICAgICAgICBjb25zdCByZWdpc3RlcmVkVG9rZW5zID0gbmV3IFNldCgpO1xuICAgICAgICBjb25zdCBuYW1lZFJlZ2lzdHJhdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IGtleWVkUmVnaXN0cmF0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3QgbXVsdGlSZWdpc3RyYXRpb25zID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyBQcmUtcHJvY2VzczogaWRlbnRpZnkgdG9rZW5zIHRoYXQgaGF2ZSBub24tZGVmYXVsdCByZWdpc3RyYXRpb25zXG4gICAgICAgIGNvbnN0IHRva2Vuc1dpdGhOb25EZWZhdWx0cyA9IHRoaXMuaWRlbnRpZnlOb25EZWZhdWx0VG9rZW5zKCk7XG4gICAgICAgIGZvciAoY29uc3QgY29uZmlnIG9mIHRoaXMucmVnaXN0cmF0aW9ucykge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgcmVnaXN0cmF0aW9uIHNob3VsZCBiZSBza2lwcGVkXG4gICAgICAgICAgICBpZiAodGhpcy5zaG91bGRTa2lwUmVnaXN0cmF0aW9uKGNvbmZpZywgdG9rZW5zV2l0aE5vbkRlZmF1bHRzLCByZWdpc3RlcmVkVG9rZW5zKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ3JlYXRlIGJpbmRpbmcgdG9rZW4gKG5hbWVkLCBrZXllZCwgb3IgbXVsdGkpXG4gICAgICAgICAgICBjb25zdCBiaW5kaW5nVG9rZW4gPSB0aGlzLmNyZWF0ZUJpbmRpbmdUb2tlbihjb25maWcsIG5hbWVkUmVnaXN0cmF0aW9ucywga2V5ZWRSZWdpc3RyYXRpb25zLCBtdWx0aVJlZ2lzdHJhdGlvbnMpO1xuICAgICAgICAgICAgLy8gQXBwbHkgcmVnaXN0cmF0aW9uIHRvIGNvbnRhaW5lciB1c2luZyB0aGUgYmluZGluZyB0b2tlblxuICAgICAgICAgICAgdGhpcy5hcHBseVJlZ2lzdHJhdGlvbihjb250YWluZXIsIHsgLi4uY29uZmlnLCB0b2tlbjogYmluZGluZ1Rva2VuIH0pO1xuICAgICAgICAgICAgLy8gTWFyayBvcmlnaW5hbCB0b2tlbiBhcyByZWdpc3RlcmVkXG4gICAgICAgICAgICByZWdpc3RlcmVkVG9rZW5zLmFkZChjb25maWcudG9rZW4pO1xuICAgICAgICAgICAgLy8gUmVnaXN0ZXIgYWRkaXRpb25hbCBpbnRlcmZhY2VzXG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyQWRkaXRpb25hbEludGVyZmFjZXMoY29udGFpbmVyLCBjb25maWcsIGJpbmRpbmdUb2tlbiwgcmVnaXN0ZXJlZFRva2Vucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQXR0YWNoIG1ldGFkYXRhIGZvciBuYW1lZC9rZXllZCByZXNvbHV0aW9uXG4gICAgICAgIDtcbiAgICAgICAgY29udGFpbmVyLl9fbmFtZWRSZWdpc3RyYXRpb25zID0gbmFtZWRSZWdpc3RyYXRpb25zO1xuICAgICAgICBjb250YWluZXIuX19rZXllZFJlZ2lzdHJhdGlvbnMgPSBrZXllZFJlZ2lzdHJhdGlvbnM7XG4gICAgICAgIGNvbnRhaW5lci5fX211bHRpUmVnaXN0cmF0aW9ucyA9IG11bHRpUmVnaXN0cmF0aW9ucztcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW5hbHl6ZSBjb25zdHJ1Y3RvciB0byBkZXRlY3QgZGVwZW5kZW5jaWVzXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgYW5hbHl6ZUNvbnN0cnVjdG9yKGNvbnN0cnVjdG9yKSB7XG4gICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yU3RyID0gY29uc3RydWN0b3IudG9TdHJpbmcoKTtcbiAgICAgICAgY29uc3QgaGFzRGVwZW5kZW5jaWVzID0gL2NvbnN0cnVjdG9yXFxzKlxcKFteKV0rXFwpLy50ZXN0KGNvbnN0cnVjdG9yU3RyKTtcbiAgICAgICAgcmV0dXJuIHsgaGFzRGVwZW5kZW5jaWVzIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBvcHRpbWl6ZWQgZmFjdG9yeSBmb3IgemVyby1kZXBlbmRlbmN5IGNvbnN0cnVjdG9yc1xuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNyZWF0ZU9wdGltaXplZEZhY3RvcnkoY29udGFpbmVyLCBjb25maWcsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGNvbmZpZy5saWZldGltZSA9PT0gJ3NpbmdsZXRvbicpIHtcbiAgICAgICAgICAgIC8vIFNpbmdsZXRvbjogQ3JlYXRlIGluc3RhbmNlIGRpcmVjdGx5IChmYXN0ZXN0IHBhdGggLSBubyBmYWN0b3J5IG92ZXJoZWFkKVxuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgY29uZmlnLmNvbnN0cnVjdG9yKCk7XG4gICAgICAgICAgICBjb250YWluZXIuYmluZFZhbHVlKGNvbmZpZy50b2tlbiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbmZpZy5saWZldGltZSA9PT0gJ3RyYW5zaWVudCcpIHtcbiAgICAgICAgICAgIC8vIFRyYW5zaWVudCBGYXN0IFBhdGg6IFJlZ2lzdGVyIGluIGZhc3QgdHJhbnNpZW50IGNhY2hlXG4gICAgICAgICAgICBjb25zdCBjdG9yID0gY29uZmlnLmNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgY29uc3QgZmFzdEZhY3RvcnkgPSAoKSA9PiBuZXcgY3RvcigpO1xuICAgICAgICAgICAgY29udGFpbmVyLmZhc3RUcmFuc2llbnRDYWNoZS5zZXQoY29uZmlnLnRva2VuLCBmYXN0RmFjdG9yeSk7XG4gICAgICAgICAgICBjb250YWluZXIuYmluZEZhY3RvcnkoY29uZmlnLnRva2VuLCBmYXN0RmFjdG9yeSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBQZXItcmVxdWVzdDogVXNlIHNpbXBsZSBmYWN0b3J5IHdpdGhvdXQgYXV0b3dpcmUgb3ZlcmhlYWRcbiAgICAgICAgICAgIGNvbnN0IGZhY3RvcnkgPSAoKSA9PiBuZXcgY29uZmlnLmNvbnN0cnVjdG9yKCk7XG4gICAgICAgICAgICBjb250YWluZXIuYmluZEZhY3RvcnkoY29uZmlnLnRva2VuLCBmYWN0b3J5LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYXV0b3dpcmUgZmFjdG9yeVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNyZWF0ZUF1dG9XaXJlRmFjdG9yeShjb250YWluZXIsIGNvbmZpZywgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0gKGMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkRGVwcyA9IGF1dG93aXJlKGNvbmZpZy5jb25zdHJ1Y3RvciwgYywgY29uZmlnLmF1dG93aXJlT3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbmZpZy5jb25zdHJ1Y3RvciguLi5yZXNvbHZlZERlcHMpO1xuICAgICAgICB9O1xuICAgICAgICBjb250YWluZXIuYmluZEZhY3RvcnkoY29uZmlnLnRva2VuLCBmYWN0b3J5LCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHdpdGhQYXJhbWV0ZXJzIGZhY3RvcnlcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjcmVhdGVQYXJhbWV0ZXJGYWN0b3J5KGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBPYmplY3QudmFsdWVzKGNvbmZpZy5wYXJhbWV0ZXJWYWx1ZXMpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb25maWcuY29uc3RydWN0b3IoLi4udmFsdWVzKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgZmFjdG9yeSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFwcGx5IHR5cGUgcmVnaXN0cmF0aW9uIChjbGFzcyBjb25zdHJ1Y3RvcilcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBhcHBseVR5cGVSZWdpc3RyYXRpb24oY29udGFpbmVyLCBjb25maWcsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgeyBoYXNEZXBlbmRlbmNpZXMgfSA9IHRoaXMuYW5hbHl6ZUNvbnN0cnVjdG9yKGNvbmZpZy5jb25zdHJ1Y3Rvcik7XG4gICAgICAgIC8vIEZhc3QgcGF0aDogTm8gZGVwZW5kZW5jaWVzIGFuZCBubyBzcGVjaWFsIGNvbmZpZ1xuICAgICAgICBpZiAoIWhhc0RlcGVuZGVuY2llcyAmJiAhY29uZmlnLmF1dG93aXJlT3B0aW9ucyAmJiAhY29uZmlnLnBhcmFtZXRlclZhbHVlcykge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVPcHRpbWl6ZWRGYWN0b3J5KGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBBdXRvV2lyZSBwYXRoXG4gICAgICAgIGlmIChjb25maWcuYXV0b3dpcmVPcHRpb25zKSB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUF1dG9XaXJlRmFjdG9yeShjb250YWluZXIsIGNvbmZpZywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gd2l0aFBhcmFtZXRlcnMgcGF0aFxuICAgICAgICBpZiAoY29uZmlnLnBhcmFtZXRlclZhbHVlcykge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVQYXJhbWV0ZXJGYWN0b3J5KGNvbnRhaW5lciwgY29uZmlnLCBvcHRpb25zKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBFcnJvcjogQ29uc3RydWN0b3IgaGFzIGRlcGVuZGVuY2llcyBidXQgbm8gY29uZmlnXG4gICAgICAgIGlmIChoYXNEZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGNvbmZpZy5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdVbm5hbWVkQ2xhc3MnO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2aWNlIFwiJHtjbGFzc05hbWV9XCIgaGFzIGNvbnN0cnVjdG9yIGRlcGVuZGVuY2llcyBidXQgbm8gYXV0b3dpcmluZyBjb25maWd1cmF0aW9uLlxcblxcbmAgK1xuICAgICAgICAgICAgICAgIGBTb2x1dGlvbnM6XFxuYCArXG4gICAgICAgICAgICAgICAgYCAgMS4gXHUyQjUwIFVzZSB0aGUgTm92YURJIHRyYW5zZm9ybWVyIChyZWNvbW1lbmRlZCk6XFxuYCArXG4gICAgICAgICAgICAgICAgYCAgICAgLSBBZGQgXCJAbm92YWRpL2NvcmUvdW5wbHVnaW5cIiB0byB5b3VyIGJ1aWxkIGNvbmZpZ1xcbmAgK1xuICAgICAgICAgICAgICAgIGAgICAgIC0gVHJhbnNmb3JtZXIgYXV0b21hdGljYWxseSBnZW5lcmF0ZXMgLmF1dG9XaXJlKCkgZm9yIGFsbCBkZXBlbmRlbmNpZXNcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgICAyLiBBZGQgbWFudWFsIGF1dG93aXJpbmc6XFxuYCArXG4gICAgICAgICAgICAgICAgYCAgICAgLmF1dG9XaXJlKHsgbWFwOiB7IC8qIHBhcmFtOiByZXNvbHZlciAqLyB9IH0pXFxuXFxuYCArXG4gICAgICAgICAgICAgICAgYCAgMy4gVXNlIGEgZmFjdG9yeSBmdW5jdGlvbjpcXG5gICtcbiAgICAgICAgICAgICAgICBgICAgICAucmVnaXN0ZXIoKGMpID0+IG5ldyAke2NsYXNzTmFtZX0oLi4uKSlcXG5cXG5gICtcbiAgICAgICAgICAgICAgICBgU2VlIGRvY3M6IGh0dHBzOi8vZ2l0aHViLmNvbS9qYW51czAwNy9Ob3ZhREkjYXV0b3dpcmVgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBkZXBlbmRlbmNpZXMgLSBjcmVhdGUgc2ltcGxlIGZhY3RvcnlcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9ICgpID0+IG5ldyBjb25maWcuY29uc3RydWN0b3IoKTtcbiAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgZmFjdG9yeSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIGFwcGx5UmVnaXN0cmF0aW9uKGNvbnRhaW5lciwgY29uZmlnKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7IGxpZmV0aW1lOiBjb25maWcubGlmZXRpbWUgfTtcbiAgICAgICAgc3dpdGNoIChjb25maWcudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW5zdGFuY2UnOlxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5iaW5kVmFsdWUoY29uZmlnLnRva2VuLCBjb25maWcudmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZmFjdG9yeSc6XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmJpbmRGYWN0b3J5KGNvbmZpZy50b2tlbiwgY29uZmlnLmZhY3RvcnksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndHlwZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseVR5cGVSZWdpc3RyYXRpb24oY29udGFpbmVyLCBjb25maWcsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ29yZSBkZXBlbmRlbmN5IGluamVjdGlvbiBjb250YWluZXIgZm9yIE5vdmFESVxuICovXG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gJy4vdG9rZW4uanMnO1xuaW1wb3J0IHsgQmluZGluZ05vdEZvdW5kRXJyb3IsIENpcmN1bGFyRGVwZW5kZW5jeUVycm9yIH0gZnJvbSAnLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgQnVpbGRlciB9IGZyb20gJy4vYnVpbGRlci5qcyc7XG5mdW5jdGlvbiBpc0Rpc3Bvc2FibGUob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqLmRpc3Bvc2UgPT09ICdmdW5jdGlvbic7XG59XG4vKipcbiAqIFJlc29sdXRpb24gY29udGV4dCB0cmFja3MgdGhlIGN1cnJlbnQgZGVwZW5kZW5jeSByZXNvbHV0aW9uIHBhdGhcbiAqIGZvciBjaXJjdWxhciBkZXBlbmRlbmN5IGRldGVjdGlvbiBhbmQgcGVyLXJlcXVlc3Qgc2NvcGluZ1xuICovXG5jbGFzcyBSZXNvbHV0aW9uQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucmVzb2x2aW5nU3RhY2sgPSBuZXcgU2V0KCk7XG4gICAgICAgIHRoaXMucGVyUmVxdWVzdENhY2hlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBpc1Jlc29sdmluZyh0b2tlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZpbmdTdGFjay5oYXModG9rZW4pO1xuICAgIH1cbiAgICBlbnRlclJlc29sdmUodG9rZW4pIHtcbiAgICAgICAgdGhpcy5yZXNvbHZpbmdTdGFjay5hZGQodG9rZW4pO1xuICAgICAgICAvLyBQZXJmb3JtYW5jZTogRG9uJ3QgYnVpbGQgcGF0aCB1bmxlc3Mgd2UgbmVlZCBpdCAob25seSB1c2VkIGluIGVycm9yIG1lc3NhZ2VzKVxuICAgICAgICAvLyBUaGlzIGF2b2lkcyBleHBlbnNpdmUgdG9rZW4udG9TdHJpbmcoKSBjYWxscyBvbiBldmVyeSByZXNvbHZlXG4gICAgfVxuICAgIGV4aXRSZXNvbHZlKHRva2VuKSB7XG4gICAgICAgIHRoaXMucmVzb2x2aW5nU3RhY2suZGVsZXRlKHRva2VuKTtcbiAgICAgICAgLy8gUGVyZm9ybWFuY2U6IENsZWFyIGxhenkgcGF0aCBjYWNoZSB3aGVuIGV4aXRpbmdcbiAgICAgICAgdGhpcy5wYXRoID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBnZXRQYXRoKCkge1xuICAgICAgICAvLyBQZXJmb3JtYW5jZTogQnVpbGQgcGF0aCBvbi1kZW1hbmQgb25seSB3aGVuIG5lZWRlZCAodHlwaWNhbGx5IGZvciBlcnJvciBtZXNzYWdlcylcbiAgICAgICAgaWYgKCF0aGlzLnBhdGgpIHtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IEFycmF5LmZyb20odGhpcy5yZXNvbHZpbmdTdGFjaykubWFwKHQgPT4gdC50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gWy4uLnRoaXMucGF0aF07XG4gICAgfVxuICAgIGNhY2hlUGVyUmVxdWVzdCh0b2tlbiwgaW5zdGFuY2UpIHtcbiAgICAgICAgdGhpcy5wZXJSZXF1ZXN0Q2FjaGUuc2V0KHRva2VuLCBpbnN0YW5jZSk7XG4gICAgfVxuICAgIGdldFBlclJlcXVlc3QodG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVyUmVxdWVzdENhY2hlLmdldCh0b2tlbik7XG4gICAgfVxuICAgIGhhc1BlclJlcXVlc3QodG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVyUmVxdWVzdENhY2hlLmhhcyh0b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc2V0IGNvbnRleHQgZm9yIHJldXNlIGluIG9iamVjdCBwb29sXG4gICAgICogUGVyZm9ybWFuY2U6IFJldXNpbmcgY29udGV4dHMgYXZvaWRzIGhlYXAgYWxsb2NhdGlvbnNcbiAgICAgKi9cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5yZXNvbHZpbmdTdGFjay5jbGVhcigpO1xuICAgICAgICB0aGlzLnBlclJlcXVlc3RDYWNoZS5jbGVhcigpO1xuICAgICAgICB0aGlzLnBhdGggPSB1bmRlZmluZWQ7XG4gICAgfVxufVxuLyoqXG4gKiBPYmplY3QgcG9vbCBmb3IgUmVzb2x1dGlvbkNvbnRleHQgaW5zdGFuY2VzXG4gKiBQZXJmb3JtYW5jZTogUmV1c2luZyBjb250ZXh0cyByZWR1Y2VzIGhlYXAgYWxsb2NhdGlvbnMgYW5kIEdDIHByZXNzdXJlXG4gKi9cbmNsYXNzIFJlc29sdXRpb25Db250ZXh0UG9vbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMucG9vbCA9IFtdO1xuICAgICAgICB0aGlzLm1heFNpemUgPSAxMDtcbiAgICB9XG4gICAgYWNxdWlyZSgpIHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucG9vbC5wb3AoKTtcbiAgICAgICAgaWYgKGNvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIFJlc2V0IGV4aXN0aW5nIGNvbnRleHQgZm9yIHJldXNlXG4gICAgICAgICAgICBjb250ZXh0LnJlc2V0KCk7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICAvLyBDcmVhdGUgbmV3IGlmIHBvb2wgZW1wdHlcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNvbHV0aW9uQ29udGV4dCgpO1xuICAgIH1cbiAgICByZWxlYXNlKGNvbnRleHQpIHtcbiAgICAgICAgaWYgKHRoaXMucG9vbC5sZW5ndGggPCB0aGlzLm1heFNpemUpIHtcbiAgICAgICAgICAgIHRoaXMucG9vbC5wdXNoKGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE90aGVyd2lzZSBsZXQgaXQgYmUgR0MnZFxuICAgIH1cbn1cbi8qKlxuICogRGVwZW5kZW5jeSBJbmplY3Rpb24gQ29udGFpbmVyXG4gKlxuICogTWFuYWdlcyByZWdpc3RyYXRpb24gYW5kIHJlc29sdXRpb24gb2YgZGVwZW5kZW5jaWVzIHdpdGggc3VwcG9ydCBmb3I6XG4gKiAtIE11bHRpcGxlIGJpbmRpbmcgdHlwZXMgKHZhbHVlLCBmYWN0b3J5LCBjbGFzcylcbiAqIC0gTGlmZXRpbWUgbWFuYWdlbWVudCAoc2luZ2xldG9uLCB0cmFuc2llbnQsIHBlci1yZXF1ZXN0KVxuICogLSBDaGlsZCBjb250YWluZXJzIHdpdGggaW5oZXJpdGFuY2VcbiAqIC0gQ2lyY3VsYXIgZGVwZW5kZW5jeSBkZXRlY3Rpb25cbiAqIC0gQXV0b21hdGljIGRpc3Bvc2FsXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250YWluZXIge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCkge1xuICAgICAgICB0aGlzLmJpbmRpbmdzID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnNpbmdsZXRvbkNhY2hlID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnNpbmdsZXRvbk9yZGVyID0gW107XG4gICAgICAgIHRoaXMuaW50ZXJmYWNlUmVnaXN0cnkgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuaW50ZXJmYWNlVG9rZW5DYWNoZSA9IG5ldyBNYXAoKTsgLy8gUGVyZm9ybWFuY2U6IENhY2hlIGZvciByZXNvbHZlVHlwZSgpIGxvb2t1cHNcbiAgICAgICAgdGhpcy5mYXN0VHJhbnNpZW50Q2FjaGUgPSBuZXcgTWFwKCk7IC8vIFBlcmZvcm1hbmNlOiBGYXN0IHBhdGggZm9yIHNpbXBsZSB0cmFuc2llbnRzXG4gICAgICAgIHRoaXMudWx0cmFGYXN0U2luZ2xldG9uQ2FjaGUgPSBuZXcgTWFwKCk7IC8vIFBlcmZvcm1hbmNlOiBVbHRyYS1mYXN0IHNpbmdsZXRvbi1vbmx5IGNhY2hlXG4gICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgcHJlLWNyZWF0ZWQgdmFsdWUgdG8gYSB0b2tlblxuICAgICAqL1xuICAgIGJpbmRWYWx1ZSh0b2tlbiwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5iaW5kaW5ncy5zZXQodG9rZW4sIHtcbiAgICAgICAgICAgIHR5cGU6ICd2YWx1ZScsXG4gICAgICAgICAgICBsaWZldGltZTogJ3NpbmdsZXRvbicsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB1bmRlZmluZWRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW52YWxpZGF0ZUJpbmRpbmdDYWNoZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgZmFjdG9yeSBmdW5jdGlvbiB0byBhIHRva2VuXG4gICAgICovXG4gICAgYmluZEZhY3RvcnkodG9rZW4sIGZhY3RvcnksIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5iaW5kaW5ncy5zZXQodG9rZW4sIHtcbiAgICAgICAgICAgIHR5cGU6ICdmYWN0b3J5JyxcbiAgICAgICAgICAgIGxpZmV0aW1lOiBvcHRpb25zPy5saWZldGltZSB8fCAndHJhbnNpZW50JyxcbiAgICAgICAgICAgIGZhY3RvcnksXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXM6IG9wdGlvbnM/LmRlcGVuZGVuY2llcyxcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB1bmRlZmluZWRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW52YWxpZGF0ZUJpbmRpbmdDYWNoZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgY2xhc3MgY29uc3RydWN0b3IgdG8gYSB0b2tlblxuICAgICAqL1xuICAgIGJpbmRDbGFzcyh0b2tlbiwgY29uc3RydWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdjbGFzcycsXG4gICAgICAgICAgICBsaWZldGltZTogb3B0aW9ucz8ubGlmZXRpbWUgfHwgJ3RyYW5zaWVudCcsXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcixcbiAgICAgICAgICAgIGRlcGVuZGVuY2llczogb3B0aW9ucz8uZGVwZW5kZW5jaWVzXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYmluZGluZ3Muc2V0KHRva2VuLCBiaW5kaW5nKTtcbiAgICAgICAgdGhpcy5pbnZhbGlkYXRlQmluZGluZ0NhY2hlKCk7XG4gICAgICAgIC8vIFBlcmZvcm1hbmNlOiBQcmUtY29tcGlsZSBmYXN0IHRyYW5zaWVudCBmYWN0b3J5IGZvciB6ZXJvLWRlcGVuZGVuY3kgY2xhc3Nlc1xuICAgICAgICBpZiAoYmluZGluZy5saWZldGltZSA9PT0gJ3RyYW5zaWVudCcgJiYgKCFiaW5kaW5nLmRlcGVuZGVuY2llcyB8fCBiaW5kaW5nLmRlcGVuZGVuY2llcy5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICB0aGlzLmZhc3RUcmFuc2llbnRDYWNoZS5zZXQodG9rZW4sICgpID0+IG5ldyBjb25zdHJ1Y3RvcigpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGEgZGVwZW5kZW5jeSBzeW5jaHJvbm91c2x5XG4gICAgICogUGVyZm9ybWFuY2Ugb3B0aW1pemVkIHdpdGggbXVsdGlwbGUgZmFzdCBwYXRoc1xuICAgICAqL1xuICAgIHJlc29sdmUodG9rZW4pIHtcbiAgICAgICAgLy8gVHJ5IGFsbCBjYWNoZSBsZXZlbHMgZmlyc3QgKHVsdHJhLWZhc3QsIHNpbmdsZXRvbiwgZmFzdCB0cmFuc2llbnQpXG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMudHJ5R2V0RnJvbUNhY2hlcyh0b2tlbik7XG4gICAgICAgIGlmIChjYWNoZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHJlc29sdmluZyAoY2FsbGVkIGZyb20gd2l0aGluIGEgZmFjdG9yeSksIHJldXNlIHRoZSBjb250ZXh0XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDb250ZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlV2l0aENvbnRleHQodG9rZW4sIHRoaXMuY3VycmVudENvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENvbXBsZXggcmVzb2x1dGlvbiB3aXRoIHBvb2xlZCBjb250ZXh0XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBDb250YWluZXIuY29udGV4dFBvb2wuYWNxdWlyZSgpO1xuICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVXaXRoQ29udGV4dCh0b2tlbiwgY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgQ29udGFpbmVyLmNvbnRleHRQb29sLnJlbGVhc2UoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU1BFQ0lBTElaRUQ6IFVsdHJhLWZhc3Qgc2luZ2xldG9uIHJlc29sdmUgKG5vIHNhZmV0eSBjaGVja3MpXG4gICAgICogVXNlIE9OTFkgd2hlbiB5b3UncmUgMTAwJSBzdXJlIHRoZSB0b2tlbiBpcyBhIHJlZ2lzdGVyZWQgc2luZ2xldG9uXG4gICAgICogQGludGVybmFsIEZvciBwZXJmb3JtYW5jZS1jcml0aWNhbCBwYXRocyBvbmx5XG4gICAgICovXG4gICAgcmVzb2x2ZVNpbmdsZXRvblVuc2FmZSh0b2tlbikge1xuICAgICAgICAvLyBEaXJlY3QgcmV0dXJuLCBubyBjaGVja3MgLSBtYXhpbXVtIHNwZWVkXG4gICAgICAgIHJldHVybiB0aGlzLnVsdHJhRmFzdFNpbmdsZXRvbkNhY2hlLmdldCh0b2tlbikgPz8gdGhpcy5zaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTUEVDSUFMSVpFRDogRmFzdCB0cmFuc2llbnQgcmVzb2x2ZSBmb3IgemVyby1kZXBlbmRlbmN5IGNsYXNzZXNcbiAgICAgKiBTa2lwcyBhbGwgY29udGV4dCBjcmVhdGlvbiBhbmQgY2lyY3VsYXIgZGVwZW5kZW5jeSBjaGVja3NcbiAgICAgKiBAaW50ZXJuYWwgRm9yIHBlcmZvcm1hbmNlLWNyaXRpY2FsIHBhdGhzIG9ubHlcbiAgICAgKi9cbiAgICByZXNvbHZlVHJhbnNpZW50U2ltcGxlKHRva2VuKSB7XG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmZhc3RUcmFuc2llbnRDYWNoZS5nZXQodG9rZW4pO1xuICAgICAgICBpZiAoZmFjdG9yeSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhY3RvcnkoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGYWxsYmFjayB0byByZWd1bGFyIHJlc29sdmUgaWYgbm90IGluIGZhc3QgY2FjaGVcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZSh0b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNQRUNJQUxJWkVEOiBCYXRjaCByZXNvbHZlIG11bHRpcGxlIGRlcGVuZGVuY2llcyBhdCBvbmNlXG4gICAgICogTW9yZSBlZmZpY2llbnQgdGhhbiBtdWx0aXBsZSBpbmRpdmlkdWFsIHJlc29sdmVzXG4gICAgICovXG4gICAgcmVzb2x2ZUJhdGNoKHRva2Vucykge1xuICAgICAgICAvLyBSZXVzZSBzaW5nbGUgY29udGV4dCBmb3IgYWxsIHJlc29sdXRpb25zXG4gICAgICAgIGNvbnN0IHdhc1Jlc29sdmluZyA9ICEhdGhpcy5jdXJyZW50Q29udGV4dDtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuY3VycmVudENvbnRleHQgfHwgQ29udGFpbmVyLmNvbnRleHRQb29sLmFjcXVpcmUoKTtcbiAgICAgICAgaWYgKCF3YXNSZXNvbHZpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gdG9rZW5zLm1hcCh0b2tlbiA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IGFsbCBjYWNoZSBsZXZlbHMgZmlyc3RcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnRyeUdldEZyb21DYWNoZXModG9rZW4pO1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZWQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICAgICAgICAgICAgICAvLyBGdWxsIHJlc29sdmUgd2l0aCBzaGFyZWQgY29udGV4dFxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVXaXRoQ29udGV4dCh0b2tlbiwgY29udGV4dCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKCF3YXNSZXNvbHZpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIENvbnRhaW5lci5jb250ZXh0UG9vbC5yZWxlYXNlKGNvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYSBkZXBlbmRlbmN5IGFzeW5jaHJvbm91c2x5IChzdXBwb3J0cyBhc3luYyBmYWN0b3JpZXMpXG4gICAgICovXG4gICAgYXN5bmMgcmVzb2x2ZUFzeW5jKHRva2VuKSB7XG4gICAgICAgIC8vIElmIHdlJ3JlIGFscmVhZHkgcmVzb2x2aW5nIChjYWxsZWQgZnJvbSB3aXRoaW4gYSBmYWN0b3J5KSwgcmV1c2UgdGhlIGNvbnRleHRcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudENvbnRleHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVBc3luY1dpdGhDb250ZXh0KHRva2VuLCB0aGlzLmN1cnJlbnRDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBOZXcgdG9wLWxldmVsIHJlc29sdmVcbiAgICAgICAgLy8gUGVyZm9ybWFuY2U6IFVzZSBwb29sZWQgY29udGV4dCB0byBhdm9pZCBoZWFwIGFsbG9jYXRpb25cbiAgICAgICAgY29uc3QgY29udGV4dCA9IENvbnRhaW5lci5jb250ZXh0UG9vbC5hY3F1aXJlKCk7XG4gICAgICAgIHRoaXMuY3VycmVudENvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVzb2x2ZUFzeW5jV2l0aENvbnRleHQodG9rZW4sIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIENvbnRhaW5lci5jb250ZXh0UG9vbC5yZWxlYXNlKGNvbnRleHQpOyAvLyBSZXR1cm4gdG8gcG9vbCBmb3IgcmV1c2VcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcnkgdG8gZ2V0IGluc3RhbmNlIGZyb20gYWxsIGNhY2hlIGxldmVsc1xuICAgICAqIFJldHVybnMgdW5kZWZpbmVkIGlmIG5vdCBjYWNoZWRcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICB0cnlHZXRGcm9tQ2FjaGVzKHRva2VuKSB7XG4gICAgICAgIC8vIExldmVsIDE6IFVsdHJhLWZhc3Qgc2luZ2xldG9uIGNhY2hlICh6ZXJvIG92ZXJoZWFkKVxuICAgICAgICBjb25zdCB1bHRyYUZhc3QgPSB0aGlzLnVsdHJhRmFzdFNpbmdsZXRvbkNhY2hlLmdldCh0b2tlbik7XG4gICAgICAgIGlmICh1bHRyYUZhc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHVsdHJhRmFzdDtcbiAgICAgICAgfVxuICAgICAgICAvLyBMZXZlbCAyOiBSZWd1bGFyIHNpbmdsZXRvbiBjYWNoZVxuICAgICAgICBpZiAodGhpcy5zaW5nbGV0b25DYWNoZS5oYXModG9rZW4pKSB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnNpbmdsZXRvbkNhY2hlLmdldCh0b2tlbik7XG4gICAgICAgICAgICAvLyBQcm9tb3RlIHRvIHVsdHJhLWZhc3QgY2FjaGUgZm9yIG5leHQgdGltZVxuICAgICAgICAgICAgdGhpcy51bHRyYUZhc3RTaW5nbGV0b25DYWNoZS5zZXQodG9rZW4sIGNhY2hlZCk7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIExldmVsIDM6IEZhc3QgdHJhbnNpZW50IGNhY2hlIChubyBkZXBlbmRlbmNpZXMpXG4gICAgICAgIGNvbnN0IGZhc3RGYWN0b3J5ID0gdGhpcy5mYXN0VHJhbnNpZW50Q2FjaGUuZ2V0KHRva2VuKTtcbiAgICAgICAgaWYgKGZhc3RGYWN0b3J5KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFzdEZhY3RvcnkoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWNoZSBpbnN0YW5jZSBiYXNlZCBvbiBsaWZldGltZSBzdHJhdGVneVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNhY2hlSW5zdGFuY2UodG9rZW4sIGluc3RhbmNlLCBsaWZldGltZSwgY29udGV4dCkge1xuICAgICAgICBpZiAobGlmZXRpbWUgPT09ICdzaW5nbGV0b24nKSB7XG4gICAgICAgICAgICB0aGlzLnNpbmdsZXRvbkNhY2hlLnNldCh0b2tlbiwgaW5zdGFuY2UpO1xuICAgICAgICAgICAgdGhpcy5zaW5nbGV0b25PcmRlci5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIC8vIEFsc28gYWRkIHRvIHVsdHJhLWZhc3QgY2FjaGVcbiAgICAgICAgICAgIHRoaXMudWx0cmFGYXN0U2luZ2xldG9uQ2FjaGUuc2V0KHRva2VuLCBpbnN0YW5jZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobGlmZXRpbWUgPT09ICdwZXItcmVxdWVzdCcgJiYgY29udGV4dCkge1xuICAgICAgICAgICAgY29udGV4dC5jYWNoZVBlclJlcXVlc3QodG9rZW4sIGluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSBhbmQgZ2V0IGJpbmRpbmcgd2l0aCBjaXJjdWxhciBkZXBlbmRlbmN5IGNoZWNrXG4gICAgICogUmV0dXJucyBiaW5kaW5nIG9yIHRocm93cyBlcnJvclxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHZhbGlkYXRlQW5kR2V0QmluZGluZyh0b2tlbiwgY29udGV4dCkge1xuICAgICAgICAvLyBDaGVjayBjaXJjdWxhciBkZXBlbmRlbmN5XG4gICAgICAgIGlmIChjb250ZXh0LmlzUmVzb2x2aW5nKHRva2VuKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IENpcmN1bGFyRGVwZW5kZW5jeUVycm9yKFsuLi5jb250ZXh0LmdldFBhdGgoKSwgdG9rZW4udG9TdHJpbmcoKV0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLmdldEJpbmRpbmcodG9rZW4pO1xuICAgICAgICBpZiAoIWJpbmRpbmcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCaW5kaW5nTm90Rm91bmRFcnJvcih0b2tlbi50b1N0cmluZygpLCBjb250ZXh0LmdldFBhdGgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJpbmRpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc3RhbnRpYXRlIGZyb20gYmluZGluZyBzeW5jaHJvbm91c2x5XG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgaW5zdGFudGlhdGVCaW5kaW5nU3luYyhiaW5kaW5nLCB0b2tlbiwgY29udGV4dCkge1xuICAgICAgICBzd2l0Y2ggKGJpbmRpbmcudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAndmFsdWUnOlxuICAgICAgICAgICAgICAgIHJldHVybiBiaW5kaW5nLnZhbHVlO1xuICAgICAgICAgICAgY2FzZSAnZmFjdG9yeSc6XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYmluZGluZy5mYWN0b3J5KHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQXN5bmMgZmFjdG9yeSBkZXRlY3RlZCBmb3IgJHt0b2tlbi50b1N0cmluZygpfS4gVXNlIHJlc29sdmVBc3luYygpIGluc3RlYWQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgICAgICAgICAgY29uc3QgZGVwcyA9IGJpbmRpbmcuZGVwZW5kZW5jaWVzIHx8IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkRGVwcyA9IGRlcHMubWFwKGRlcCA9PiB0aGlzLnJlc29sdmVXaXRoQ29udGV4dChkZXAsIGNvbnRleHQpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmcuY29uc3RydWN0b3IoLi4ucmVzb2x2ZWREZXBzKTtcbiAgICAgICAgICAgIGNhc2UgJ2lubGluZS1jbGFzcyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBiaW5kaW5nLmNvbnN0cnVjdG9yKCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBiaW5kaW5nIHR5cGU6ICR7YmluZGluZy50eXBlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc3RhbnRpYXRlIGZyb20gYmluZGluZyBhc3luY2hyb25vdXNseVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGFzeW5jIGluc3RhbnRpYXRlQmluZGluZ0FzeW5jKGJpbmRpbmcsIGNvbnRleHQpIHtcbiAgICAgICAgc3dpdGNoIChiaW5kaW5nLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ3ZhbHVlJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYmluZGluZy52YWx1ZTtcbiAgICAgICAgICAgIGNhc2UgJ2ZhY3RvcnknOlxuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBQcm9taXNlLnJlc29sdmUoYmluZGluZy5mYWN0b3J5KHRoaXMpKTtcbiAgICAgICAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgICAgICAgICBjb25zdCBkZXBzID0gYmluZGluZy5kZXBlbmRlbmNpZXMgfHwgW107XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWREZXBzID0gYXdhaXQgUHJvbWlzZS5hbGwoZGVwcy5tYXAoZGVwID0+IHRoaXMucmVzb2x2ZUFzeW5jV2l0aENvbnRleHQoZGVwLCBjb250ZXh0KSkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgYmluZGluZy5jb25zdHJ1Y3RvciguLi5yZXNvbHZlZERlcHMpO1xuICAgICAgICAgICAgY2FzZSAnaW5saW5lLWNsYXNzJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGJpbmRpbmcuY29uc3RydWN0b3IoKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGJpbmRpbmcgdHlwZTogJHtiaW5kaW5nLnR5cGV9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgY2hpbGQgY29udGFpbmVyIHRoYXQgaW5oZXJpdHMgYmluZGluZ3MgZnJvbSB0aGlzIGNvbnRhaW5lclxuICAgICAqL1xuICAgIGNyZWF0ZUNoaWxkKCkge1xuICAgICAgICByZXR1cm4gbmV3IENvbnRhaW5lcih0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcG9zZSBhbGwgc2luZ2xldG9uIGluc3RhbmNlcyBpbiByZXZlcnNlIHJlZ2lzdHJhdGlvbiBvcmRlclxuICAgICAqL1xuICAgIGFzeW5jIGRpc3Bvc2UoKSB7XG4gICAgICAgIGNvbnN0IGVycm9ycyA9IFtdO1xuICAgICAgICAvLyBEaXNwb3NlIGluIHJldmVyc2Ugb3JkZXJcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc2luZ2xldG9uT3JkZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5zaW5nbGV0b25PcmRlcltpXTtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5zaW5nbGV0b25DYWNoZS5nZXQodG9rZW4pO1xuICAgICAgICAgICAgaWYgKGluc3RhbmNlICYmIGlzRGlzcG9zYWJsZShpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBpbnN0YW5jZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIC8vIENvbnRpbnVlIGRpc3Bvc2luZyBvdGhlciBpbnN0YW5jZXMgZXZlbiBpZiBvbmUgZmFpbHNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2xlYXIgY2FjaGVzXG4gICAgICAgIHRoaXMuc2luZ2xldG9uQ2FjaGUuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zaW5nbGV0b25PcmRlci5sZW5ndGggPSAwO1xuICAgICAgICAvLyBOb3RlOiBXZSBkb24ndCB0aHJvdyBlcnJvcnMgdG8gYWxsb3cgYWxsIGRpc3Bvc2FscyB0byBjb21wbGV0ZVxuICAgICAgICAvLyBJbiBwcm9kdWN0aW9uLCB5b3UgbWlnaHQgd2FudCB0byBsb2cgdGhlc2UgZXJyb3JzXG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIGZsdWVudCBidWlsZGVyIGZvciByZWdpc3RlcmluZyBkZXBlbmRlbmNpZXNcbiAgICAgKi9cbiAgICBidWlsZGVyKCkge1xuICAgICAgICByZXR1cm4gbmV3IEJ1aWxkZXIodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYSBuYW1lZCBzZXJ2aWNlXG4gICAgICovXG4gICAgcmVzb2x2ZU5hbWVkKG5hbWUpIHtcbiAgICAgICAgY29uc3QgbmFtZWRSZWdpc3RyYXRpb25zID0gdGhpcy5fX25hbWVkUmVnaXN0cmF0aW9ucztcbiAgICAgICAgaWYgKCFuYW1lZFJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTmFtZWQgc2VydmljZSBcIiR7bmFtZX1cIiBub3QgZm91bmQuIE5vIG5hbWVkIHJlZ2lzdHJhdGlvbnMgZXhpc3QuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uZmlnID0gbmFtZWRSZWdpc3RyYXRpb25zLmdldChuYW1lKTtcbiAgICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTmFtZWQgc2VydmljZSBcIiR7bmFtZX1cIiBub3QgZm91bmRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlKGNvbmZpZy50b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYSBrZXllZCBzZXJ2aWNlXG4gICAgICovXG4gICAgcmVzb2x2ZUtleWVkKGtleSkge1xuICAgICAgICBjb25zdCBrZXllZFJlZ2lzdHJhdGlvbnMgPSB0aGlzLl9fa2V5ZWRSZWdpc3RyYXRpb25zO1xuICAgICAgICBpZiAoIWtleWVkUmVnaXN0cmF0aW9ucykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBLZXllZCBzZXJ2aWNlIG5vdCBmb3VuZC4gTm8ga2V5ZWQgcmVnaXN0cmF0aW9ucyBleGlzdC5gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25maWcgPSBrZXllZFJlZ2lzdHJhdGlvbnMuZ2V0KGtleSk7XG4gICAgICAgIGlmICghY29uZmlnKSB7XG4gICAgICAgICAgICBjb25zdCBrZXlTdHIgPSB0eXBlb2Yga2V5ID09PSAnc3ltYm9sJyA/IGtleS50b1N0cmluZygpIDogYFwiJHtrZXl9XCJgO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBLZXllZCBzZXJ2aWNlICR7a2V5U3RyfSBub3QgZm91bmRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlKGNvbmZpZy50b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYWxsIHJlZ2lzdHJhdGlvbnMgZm9yIGEgdG9rZW5cbiAgICAgKi9cbiAgICByZXNvbHZlQWxsKHRva2VuKSB7XG4gICAgICAgIGNvbnN0IG11bHRpUmVnaXN0cmF0aW9ucyA9IHRoaXMuX19tdWx0aVJlZ2lzdHJhdGlvbnM7XG4gICAgICAgIGlmICghbXVsdGlSZWdpc3RyYXRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdG9rZW5zID0gbXVsdGlSZWdpc3RyYXRpb25zLmdldCh0b2tlbik7XG4gICAgICAgIGlmICghdG9rZW5zIHx8IHRva2Vucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdG9rZW5zLm1hcCgodCkgPT4gdGhpcy5yZXNvbHZlKHQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHJlZ2lzdHJ5IGluZm9ybWF0aW9uIGZvciBkZWJ1Z2dpbmcvdmlzdWFsaXphdGlvblxuICAgICAqIFJldHVybnMgYXJyYXkgb2YgYmluZGluZyBpbmZvcm1hdGlvblxuICAgICAqL1xuICAgIGdldFJlZ2lzdHJ5KCkge1xuICAgICAgICBjb25zdCByZWdpc3RyeSA9IFtdO1xuICAgICAgICB0aGlzLmJpbmRpbmdzLmZvckVhY2goKGJpbmRpbmcsIHRva2VuKSA9PiB7XG4gICAgICAgICAgICByZWdpc3RyeS5wdXNoKHtcbiAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW4uZGVzY3JpcHRpb24gfHwgdG9rZW4uc3ltYm9sLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgdHlwZTogYmluZGluZy50eXBlLFxuICAgICAgICAgICAgICAgIGxpZmV0aW1lOiBiaW5kaW5nLmxpZmV0aW1lLFxuICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llczogYmluZGluZy5kZXBlbmRlbmNpZXM/Lm1hcChkID0+IGQuZGVzY3JpcHRpb24gfHwgZC5zeW1ib2wudG9TdHJpbmcoKSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlZ2lzdHJ5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgb3IgY3JlYXRlIGEgdG9rZW4gZm9yIGFuIGludGVyZmFjZSB0eXBlXG4gICAgICogVXNlcyBhIHR5cGUgbmFtZSBoYXNoIGFzIGtleSBmb3IgdGhlIGludGVyZmFjZSByZWdpc3RyeVxuICAgICAqL1xuICAgIGludGVyZmFjZVRva2VuKHR5cGVOYW1lKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGtleSBmb3IgdGhpcyBpbnRlcmZhY2UgdHlwZVxuICAgICAgICAvLyBJbiBwcm9kdWN0aW9uLCB0aGlzIHdvdWxkIGJlIHJlcGxhY2VkIGJ5IGEgVFMgdHJhbnNmb3JtZXJcbiAgICAgICAgY29uc3Qga2V5ID0gdHlwZU5hbWUgfHwgYEludGVyZmFjZV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KX1gO1xuICAgICAgICAvLyBDaGVjayBpZiB0b2tlbiBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIGNvbnRhaW5lclxuICAgICAgICBpZiAodGhpcy5pbnRlcmZhY2VSZWdpc3RyeS5oYXMoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJmYWNlUmVnaXN0cnkuZ2V0KGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgcGFyZW50IGNvbnRhaW5lciAocmVjdXJzaXZlbHkgdGhyb3VnaCBwYXJlbnQgY2hhaW4pXG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgY2hlY2sgdGhyb3VnaCBlbnRpcmUgcGFyZW50IGNoYWluXG4gICAgICAgICAgICBjb25zdCBwYXJlbnRUb2tlbiA9IHRoaXMucGFyZW50LmludGVyZmFjZVRva2VuKGtleSk7XG4gICAgICAgICAgICAvLyBJZiBwYXJlbnQgY3JlYXRlZCBhIG5ldyB0b2tlbiwgZG9uJ3QgY3JlYXRlIGFub3RoZXIgb25lXG4gICAgICAgICAgICByZXR1cm4gcGFyZW50VG9rZW47XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ3JlYXRlIG5ldyB0b2tlbiAob25seSBpZiBubyBwYXJlbnQgZXhpc3RzKVxuICAgICAgICBjb25zdCB0b2tlbiA9IFRva2VuKGtleSk7XG4gICAgICAgIHRoaXMuaW50ZXJmYWNlUmVnaXN0cnkuc2V0KGtleSwgdG9rZW4pO1xuICAgICAgICByZXR1cm4gdG9rZW47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYSBkZXBlbmRlbmN5IGJ5IGludGVyZmFjZSB0eXBlIHdpdGhvdXQgZXhwbGljaXQgdG9rZW5cbiAgICAgKi9cbiAgICByZXNvbHZlVHlwZSh0eXBlTmFtZSkge1xuICAgICAgICAvLyBQZXJmb3JtYW5jZTogQ2FjaGUgdG9rZW4gbG9va3VwcyB0byBhdm9pZCByZXBlYXRlZCBpbnRlcmZhY2VSZWdpc3RyeSBhY2Nlc3NcbiAgICAgICAgY29uc3Qga2V5ID0gdHlwZU5hbWUgfHwgJyc7XG4gICAgICAgIGxldCB0b2tlbiA9IHRoaXMuaW50ZXJmYWNlVG9rZW5DYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCF0b2tlbikge1xuICAgICAgICAgICAgdG9rZW4gPSB0aGlzLmludGVyZmFjZVRva2VuKHR5cGVOYW1lKTtcbiAgICAgICAgICAgIHRoaXMuaW50ZXJmYWNlVG9rZW5DYWNoZS5zZXQoa2V5LCB0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZSh0b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYSBrZXllZCBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICByZXNvbHZlVHlwZUtleWVkKGtleSwgX3R5cGVOYW1lKSB7XG4gICAgICAgIC8vIEZvciBrZXllZCBpbnRlcmZhY2VzLCB3ZSB1c2UgdGhlIGV4aXN0aW5nIHJlc29sdmVLZXllZCBtZWNoYW5pc21cbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZUtleWVkKGtleSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmUgYWxsIHJlZ2lzdHJhdGlvbnMgZm9yIGFuIGludGVyZmFjZSB0eXBlXG4gICAgICovXG4gICAgcmVzb2x2ZVR5cGVBbGwodHlwZU5hbWUpIHtcbiAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLmludGVyZmFjZVRva2VuKHR5cGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZUFsbCh0b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBSZXNvbHZlIHdpdGggY29udGV4dCBmb3IgY2lyY3VsYXIgZGVwZW5kZW5jeSBkZXRlY3Rpb25cbiAgICAgKi9cbiAgICByZXNvbHZlV2l0aENvbnRleHQodG9rZW4sIGNvbnRleHQpIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgYW5kIGdldCBiaW5kaW5nICh3aXRoIGNpcmN1bGFyIGRlcGVuZGVuY3kgY2hlY2spXG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLnZhbGlkYXRlQW5kR2V0QmluZGluZyh0b2tlbiwgY29udGV4dCk7XG4gICAgICAgIC8vIENoZWNrIHBlci1yZXF1ZXN0IGNhY2hlXG4gICAgICAgIGlmIChiaW5kaW5nLmxpZmV0aW1lID09PSAncGVyLXJlcXVlc3QnICYmIGNvbnRleHQuaGFzUGVyUmVxdWVzdCh0b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmdldFBlclJlcXVlc3QodG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIC8vIENoZWNrIHNpbmdsZXRvbiBjYWNoZSAobG9jYWwgY29udGFpbmVyIG9ubHkpXG4gICAgICAgIGlmIChiaW5kaW5nLmxpZmV0aW1lID09PSAnc2luZ2xldG9uJyAmJiB0aGlzLnNpbmdsZXRvbkNhY2hlLmhhcyh0b2tlbikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNpbmdsZXRvbkNhY2hlLmdldCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTWFyayBhcyByZXNvbHZpbmdcbiAgICAgICAgY29udGV4dC5lbnRlclJlc29sdmUodG9rZW4pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gSW5zdGFudGlhdGUgZnJvbSBiaW5kaW5nXG4gICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuaW5zdGFudGlhdGVCaW5kaW5nU3luYyhiaW5kaW5nLCB0b2tlbiwgY29udGV4dCk7XG4gICAgICAgICAgICAvLyBDYWNoZSBiYXNlZCBvbiBsaWZldGltZVxuICAgICAgICAgICAgdGhpcy5jYWNoZUluc3RhbmNlKHRva2VuLCBpbnN0YW5jZSwgYmluZGluZy5saWZldGltZSwgY29udGV4dCk7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBjb250ZXh0LmV4aXRSZXNvbHZlKHRva2VuKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogQXN5bmMgcmVzb2x2ZSB3aXRoIGNvbnRleHRcbiAgICAgKi9cbiAgICBhc3luYyByZXNvbHZlQXN5bmNXaXRoQ29udGV4dCh0b2tlbiwgY29udGV4dCkge1xuICAgICAgICAvLyBWYWxpZGF0ZSBhbmQgZ2V0IGJpbmRpbmcgKHdpdGggY2lyY3VsYXIgZGVwZW5kZW5jeSBjaGVjaylcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMudmFsaWRhdGVBbmRHZXRCaW5kaW5nKHRva2VuLCBjb250ZXh0KTtcbiAgICAgICAgLy8gQ2hlY2sgcGVyLXJlcXVlc3QgY2FjaGVcbiAgICAgICAgaWYgKGJpbmRpbmcubGlmZXRpbWUgPT09ICdwZXItcmVxdWVzdCcgJiYgY29udGV4dC5oYXNQZXJSZXF1ZXN0KHRva2VuKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuZ2V0UGVyUmVxdWVzdCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgc2luZ2xldG9uIGNhY2hlIChsb2NhbCBjb250YWluZXIgb25seSlcbiAgICAgICAgaWYgKGJpbmRpbmcubGlmZXRpbWUgPT09ICdzaW5nbGV0b24nICYmIHRoaXMuc2luZ2xldG9uQ2FjaGUuaGFzKHRva2VuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2luZ2xldG9uQ2FjaGUuZ2V0KHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBNYXJrIGFzIHJlc29sdmluZ1xuICAgICAgICBjb250ZXh0LmVudGVyUmVzb2x2ZSh0b2tlbik7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJbnN0YW50aWF0ZSBmcm9tIGJpbmRpbmcgYXN5bmNocm9ub3VzbHlcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgdGhpcy5pbnN0YW50aWF0ZUJpbmRpbmdBc3luYyhiaW5kaW5nLCBjb250ZXh0KTtcbiAgICAgICAgICAgIC8vIENhY2hlIGJhc2VkIG9uIGxpZmV0aW1lXG4gICAgICAgICAgICB0aGlzLmNhY2hlSW5zdGFuY2UodG9rZW4sIGluc3RhbmNlLCBiaW5kaW5nLmxpZmV0aW1lLCBjb250ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNvbnRleHQuZXhpdFJlc29sdmUodG9rZW4pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBiaW5kaW5nIGZyb20gdGhpcyBjb250YWluZXIgb3IgcGFyZW50IGNoYWluXG4gICAgICogUGVyZm9ybWFuY2Ugb3B0aW1pemVkOiBVc2VzIGZsYXQgY2FjaGUgdG8gYXZvaWQgcmVjdXJzaXZlIHBhcmVudCBsb29rdXBzXG4gICAgICovXG4gICAgZ2V0QmluZGluZyh0b2tlbikge1xuICAgICAgICAvLyBCdWlsZCBmbGF0IGNhY2hlIG9uIGZpcnN0IGFjY2Vzc1xuICAgICAgICBpZiAoIXRoaXMuYmluZGluZ0NhY2hlKSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWxkQmluZGluZ0NhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZGluZ0NhY2hlLmdldCh0b2tlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGZsYXQgY2FjaGUgb2YgYWxsIGJpbmRpbmdzIGluY2x1ZGluZyBwYXJlbnQgY2hhaW5cbiAgICAgKiBUaGlzIGNvbnZlcnRzIE8obikgcGFyZW50IGNoYWluIHRyYXZlcnNhbCB0byBPKDEpIGxvb2t1cFxuICAgICAqL1xuICAgIGJ1aWxkQmluZGluZ0NhY2hlKCkge1xuICAgICAgICB0aGlzLmJpbmRpbmdDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgLy8gVHJhdmVyc2UgcGFyZW50IGNoYWluIGFuZCBmbGF0dGVuIGFsbCBiaW5kaW5nc1xuICAgICAgICBsZXQgY3VycmVudCA9IHRoaXM7XG4gICAgICAgIHdoaWxlIChjdXJyZW50KSB7XG4gICAgICAgICAgICBjdXJyZW50LmJpbmRpbmdzLmZvckVhY2goKGJpbmRpbmcsIHRva2VuKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQ2hpbGQgYmluZGluZ3Mgb3ZlcnJpZGUgcGFyZW50IGJpbmRpbmdzIChmaXJzdCB3aW5zKVxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5iaW5kaW5nQ2FjaGUuaGFzKHRva2VuKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJpbmRpbmdDYWNoZS5zZXQodG9rZW4sIGJpbmRpbmcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludmFsaWRhdGUgYmluZGluZyBjYWNoZSB3aGVuIG5ldyBiaW5kaW5ncyBhcmUgYWRkZWRcbiAgICAgKiBDYWxsZWQgYnkgYmluZFZhbHVlLCBiaW5kRmFjdG9yeSwgYmluZENsYXNzXG4gICAgICovXG4gICAgaW52YWxpZGF0ZUJpbmRpbmdDYWNoZSgpIHtcbiAgICAgICAgdGhpcy5iaW5kaW5nQ2FjaGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMudWx0cmFGYXN0U2luZ2xldG9uQ2FjaGUuY2xlYXIoKTsgLy8gQ2xlYXIgdWx0cmEtZmFzdCBjYWNoZSB3aGVuIGJpbmRpbmdzIGNoYW5nZVxuICAgIH1cbn1cbkNvbnRhaW5lci5jb250ZXh0UG9vbCA9IG5ldyBSZXNvbHV0aW9uQ29udGV4dFBvb2woKTsgLy8gUGVyZm9ybWFuY2U6IFBvb2xlZCBjb250ZXh0cyByZWR1Y2UgYWxsb2NhdGlvbnNcbiIsICJleHBvcnQgY2xhc3MgRGF0ZVJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihkYXRlU2VydmljZSkge1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMudHlwZSA9ICdkYXRlJztcbiAgICB9XG4gICAgcmVuZGVyKGNvbnRleHQpIHtcbiAgICAgICAgY29uc3QgZGF0ZXMgPSBjb250ZXh0LmZpbHRlclsnZGF0ZSddIHx8IFtdO1xuICAgICAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xuICAgICAgICAvLyBDaGVjayBpZiBkYXRlIGhlYWRlcnMgc2hvdWxkIGJlIGhpZGRlbiAoZS5nLiwgaW4gZGF5IHZpZXcpXG4gICAgICAgIGNvbnN0IGRhdGVHcm91cGluZyA9IGNvbnRleHQuZ3JvdXBpbmdzPy5maW5kKGcgPT4gZy50eXBlID09PSAnZGF0ZScpO1xuICAgICAgICBjb25zdCBoaWRlSGVhZGVyID0gZGF0ZUdyb3VwaW5nPy5oaWRlSGVhZGVyID09PSB0cnVlO1xuICAgICAgICAvLyBSZW5kZXIgZGF0ZXMgZm9yIEhWRVIgcmVzb3VyY2UgKGVsbGVyIDEgZ2FuZyBodmlzIGluZ2VuIHJlc291cmNlcylcbiAgICAgICAgY29uc3QgaXRlcmF0aW9ucyA9IHJlc291cmNlSWRzLmxlbmd0aCB8fCAxO1xuICAgICAgICBsZXQgY29sdW1uQ291bnQgPSAwO1xuICAgICAgICBmb3IgKGxldCByID0gMDsgciA8IGl0ZXJhdGlvbnM7IHIrKykge1xuICAgICAgICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IHJlc291cmNlSWRzW3JdOyAvLyB1bmRlZmluZWQgaHZpcyBpbmdlbiByZXNvdXJjZXNcbiAgICAgICAgICAgIGZvciAoY29uc3QgZGF0ZVN0ciBvZiBkYXRlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmRhdGVTZXJ2aWNlLnBhcnNlSVNPKGRhdGVTdHIpO1xuICAgICAgICAgICAgICAgIC8vIEJ1aWxkIGNvbHVtbktleSBmb3IgdW5pZm9ybSBpZGVudGlmaWNhdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlZ21lbnRzID0geyBkYXRlOiBkYXRlU3RyIH07XG4gICAgICAgICAgICAgICAgaWYgKHJlc291cmNlSWQpXG4gICAgICAgICAgICAgICAgICAgIHNlZ21lbnRzLnJlc291cmNlID0gcmVzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5LZXkgPSB0aGlzLmRhdGVTZXJ2aWNlLmJ1aWxkQ29sdW1uS2V5KHNlZ21lbnRzKTtcbiAgICAgICAgICAgICAgICAvLyBIZWFkZXJcbiAgICAgICAgICAgICAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZGF5LWhlYWRlcicpO1xuICAgICAgICAgICAgICAgIGhlYWRlci5kYXRhc2V0LmRhdGUgPSBkYXRlU3RyO1xuICAgICAgICAgICAgICAgIGhlYWRlci5kYXRhc2V0LmNvbHVtbktleSA9IGNvbHVtbktleTtcbiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2VJZCkge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXIuZGF0YXNldC5yZXNvdXJjZUlkID0gcmVzb3VyY2VJZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGhpZGVIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmRhdGFzZXQuaGlkZGVuID0gJ3RydWUnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBoZWFkZXIuaW5uZXJIVE1MID0gYFxyXG4gICAgICAgICAgPHN3cC1kYXktbmFtZT4ke3RoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF5TmFtZShkYXRlLCAnc2hvcnQnKX08L3N3cC1kYXktbmFtZT5cclxuICAgICAgICAgIDxzd3AtZGF5LWRhdGU+JHtkYXRlLmdldERhdGUoKX08L3N3cC1kYXktZGF0ZT5cclxuICAgICAgICBgO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XG4gICAgICAgICAgICAgICAgLy8gQ29sdW1uXG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgICAgICAgICBjb2x1bW4uZGF0YXNldC5kYXRlID0gZGF0ZVN0cjtcbiAgICAgICAgICAgICAgICBjb2x1bW4uZGF0YXNldC5jb2x1bW5LZXkgPSBjb2x1bW5LZXk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc291cmNlSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLmRhdGFzZXQucmVzb3VyY2VJZCA9IHJlc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbHVtbi5pbm5lckhUTUwgPSAnPHN3cC1ldmVudHMtbGF5ZXI+PC9zd3AtZXZlbnRzLWxheWVyPic7XG4gICAgICAgICAgICAgICAgY29udGV4dC5jb2x1bW5Db250YWluZXIuYXBwZW5kQ2hpbGQoY29sdW1uKTtcbiAgICAgICAgICAgICAgICBjb2x1bW5Db3VudCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFNldCBncmlkIGNvbHVtbnMgb24gY29udGFpbmVyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGNvbnRleHQuY29sdW1uQ29udGFpbmVyLmNsb3Nlc3QoJ3N3cC1jYWxlbmRhci1jb250YWluZXInKTtcbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnNldFByb3BlcnR5KCctLWdyaWQtY29sdW1ucycsIFN0cmluZyhjb2x1bW5Db3VudCkpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwgImltcG9ydCBkYXlqcyBmcm9tICdkYXlqcyc7XG5pbXBvcnQgdXRjIGZyb20gJ2RheWpzL3BsdWdpbi91dGMnO1xuaW1wb3J0IHRpbWV6b25lIGZyb20gJ2RheWpzL3BsdWdpbi90aW1lem9uZSc7XG5pbXBvcnQgaXNvV2VlayBmcm9tICdkYXlqcy9wbHVnaW4vaXNvV2Vlayc7XG4vLyBFbmFibGUgZGF5anMgcGx1Z2luc1xuZGF5anMuZXh0ZW5kKHV0Yyk7XG5kYXlqcy5leHRlbmQodGltZXpvbmUpO1xuZGF5anMuZXh0ZW5kKGlzb1dlZWspO1xuZXhwb3J0IGNsYXNzIERhdGVTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGJhc2VEYXRlKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnRpbWV6b25lID0gY29uZmlnLnRpbWV6b25lO1xuICAgICAgICAvLyBBbGxvdyBzZXR0aW5nIGEgZml4ZWQgYmFzZSBkYXRlIGZvciBkZW1vL3Rlc3RpbmcgcHVycG9zZXNcbiAgICAgICAgdGhpcy5iYXNlRGF0ZSA9IGJhc2VEYXRlID8gZGF5anMoYmFzZURhdGUpIDogZGF5anMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IGEgZml4ZWQgYmFzZSBkYXRlICh1c2VmdWwgZm9yIGRlbW9zIHdpdGggc3RhdGljIG1vY2sgZGF0YSlcbiAgICAgKi9cbiAgICBzZXRCYXNlRGF0ZShkYXRlKSB7XG4gICAgICAgIHRoaXMuYmFzZURhdGUgPSBkYXlqcyhkYXRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IGJhc2UgZGF0ZSAoZWl0aGVyIGZpeGVkIG9yIHRvZGF5KVxuICAgICAqL1xuICAgIGdldEJhc2VEYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iYXNlRGF0ZS50b0RhdGUoKTtcbiAgICB9XG4gICAgcGFyc2VJU08oaXNvU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBkYXlqcyhpc29TdHJpbmcpLnRvRGF0ZSgpO1xuICAgIH1cbiAgICBnZXREYXlOYW1lKGRhdGUsIGZvcm1hdCA9ICdzaG9ydCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KHRoaXMuY29uZmlnLmxvY2FsZSwgeyB3ZWVrZGF5OiBmb3JtYXQgfSkuZm9ybWF0KGRhdGUpO1xuICAgIH1cbiAgICBnZXRXZWVrRGF0ZXMob2Zmc2V0ID0gMCwgZGF5cyA9IDcpIHtcbiAgICAgICAgY29uc3QgbW9uZGF5ID0gdGhpcy5iYXNlRGF0ZS5zdGFydE9mKCd3ZWVrJykuYWRkKDEsICdkYXknKS5hZGQob2Zmc2V0LCAnd2VlaycpO1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogZGF5cyB9LCAoXywgaSkgPT4gbW9uZGF5LmFkZChpLCAnZGF5JykuZm9ybWF0KCdZWVlZLU1NLUREJykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZGF0ZXMgZm9yIHNwZWNpZmljIHdlZWtkYXlzIHdpdGhpbiBhIHdlZWtcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IC0gV2VlayBvZmZzZXQgZnJvbSBiYXNlIGRhdGUgKDAgPSBjdXJyZW50IHdlZWspXG4gICAgICogQHBhcmFtIHdvcmtEYXlzIC0gQXJyYXkgb2YgSVNPIHdlZWtkYXkgbnVtYmVycyAoMT1Nb25kYXksIDc9U3VuZGF5KVxuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIGRhdGUgc3RyaW5ncyBpbiBZWVlZLU1NLUREIGZvcm1hdFxuICAgICAqL1xuICAgIGdldFdvcmtXZWVrRGF0ZXMob2Zmc2V0LCB3b3JrRGF5cykge1xuICAgICAgICBjb25zdCBtb25kYXkgPSB0aGlzLmJhc2VEYXRlLnN0YXJ0T2YoJ3dlZWsnKS5hZGQoMSwgJ2RheScpLmFkZChvZmZzZXQsICd3ZWVrJyk7XG4gICAgICAgIHJldHVybiB3b3JrRGF5cy5tYXAoaXNvRGF5ID0+IHtcbiAgICAgICAgICAgIC8vIElTTzogMT1Nb25kYXksIDc9U3VuZGF5IFx1MjE5MiBkYXlzIGZyb20gTW9uZGF5OiAwLTZcbiAgICAgICAgICAgIGNvbnN0IGRheXNGcm9tTW9uZGF5ID0gaXNvRGF5ID09PSA3ID8gNiA6IGlzb0RheSAtIDE7XG4gICAgICAgICAgICByZXR1cm4gbW9uZGF5LmFkZChkYXlzRnJvbU1vbmRheSwgJ2RheScpLmZvcm1hdCgnWVlZWS1NTS1ERCcpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBGT1JNQVRUSU5HXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICBmb3JtYXRUaW1lKGRhdGUsIHNob3dTZWNvbmRzID0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgcGF0dGVybiA9IHNob3dTZWNvbmRzID8gJ0hIOm1tOnNzJyA6ICdISDptbSc7XG4gICAgICAgIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQocGF0dGVybik7XG4gICAgfVxuICAgIGZvcm1hdFRpbWVSYW5nZShzdGFydCwgZW5kKSB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLmZvcm1hdFRpbWUoc3RhcnQpfSAtICR7dGhpcy5mb3JtYXRUaW1lKGVuZCl9YDtcbiAgICB9XG4gICAgZm9ybWF0RGF0ZShkYXRlKSB7XG4gICAgICAgIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcbiAgICB9XG4gICAgZ2V0RGF0ZUtleShkYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdERhdGUoZGF0ZSk7XG4gICAgfVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gQ09MVU1OIEtFWVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLyoqXG4gICAgICogQnVpbGQgYSB1bmlmb3JtIGNvbHVtbktleSBmcm9tIGdyb3VwaW5nIHNlZ21lbnRzXG4gICAgICogSGFuZGxlcyBhbnkgY29tYmluYXRpb24gb2YgZGF0ZSwgcmVzb3VyY2UsIHRlYW0sIGV0Yy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScgfSkgXHUyMTkyIFwiMjAyNS0xMi0wOVwiXG4gICAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScsIHJlc291cmNlOiAnRU1QMDAxJyB9KSBcdTIxOTIgXCIyMDI1LTEyLTA5OkVNUDAwMVwiXG4gICAgICovXG4gICAgYnVpbGRDb2x1bW5LZXkoc2VnbWVudHMpIHtcbiAgICAgICAgLy8gQWx3YXlzIHB1dCBkYXRlIGZpcnN0IGlmIHByZXNlbnQsIHRoZW4gb3RoZXIgc2VnbWVudHMgYWxwaGFiZXRpY2FsbHlcbiAgICAgICAgY29uc3QgZGF0ZSA9IHNlZ21lbnRzLmRhdGU7XG4gICAgICAgIGNvbnN0IG90aGVycyA9IE9iamVjdC5lbnRyaWVzKHNlZ21lbnRzKVxuICAgICAgICAgICAgLmZpbHRlcigoW2tdKSA9PiBrICE9PSAnZGF0ZScpXG4gICAgICAgICAgICAuc29ydCgoW2FdLCBbYl0pID0+IGEubG9jYWxlQ29tcGFyZShiKSlcbiAgICAgICAgICAgIC5tYXAoKFssIHZdKSA9PiB2KTtcbiAgICAgICAgcmV0dXJuIGRhdGUgPyBbZGF0ZSwgLi4ub3RoZXJzXS5qb2luKCc6JykgOiBvdGhlcnMuam9pbignOicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXJzZSBhIGNvbHVtbktleSBiYWNrIGludG8gc2VnbWVudHNcbiAgICAgKiBBc3N1bWVzIGZvcm1hdDogXCJkYXRlOnJlc291cmNlOi4uLlwiIG9yIGp1c3QgXCJkYXRlXCJcbiAgICAgKi9cbiAgICBwYXJzZUNvbHVtbktleShjb2x1bW5LZXkpIHtcbiAgICAgICAgY29uc3QgcGFydHMgPSBjb2x1bW5LZXkuc3BsaXQoJzonKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRhdGU6IHBhcnRzWzBdLFxuICAgICAgICAgICAgcmVzb3VyY2U6IHBhcnRzWzFdXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgZGF0ZUtleSBmcm9tIGNvbHVtbktleSAoZmlyc3Qgc2VnbWVudClcbiAgICAgKi9cbiAgICBnZXREYXRlRnJvbUNvbHVtbktleShjb2x1bW5LZXkpIHtcbiAgICAgICAgcmV0dXJuIGNvbHVtbktleS5zcGxpdCgnOicpWzBdO1xuICAgIH1cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFRJTUUgQ0FMQ1VMQVRJT05TXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB0aW1lVG9NaW51dGVzKHRpbWVTdHJpbmcpIHtcbiAgICAgICAgY29uc3QgcGFydHMgPSB0aW1lU3RyaW5nLnNwbGl0KCc6JykubWFwKE51bWJlcik7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gcGFydHNbMF0gfHwgMDtcbiAgICAgICAgY29uc3QgbWludXRlcyA9IHBhcnRzWzFdIHx8IDA7XG4gICAgICAgIHJldHVybiBob3VycyAqIDYwICsgbWludXRlcztcbiAgICB9XG4gICAgbWludXRlc1RvVGltZSh0b3RhbE1pbnV0ZXMpIHtcbiAgICAgICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKHRvdGFsTWludXRlcyAvIDYwKTtcbiAgICAgICAgY29uc3QgbWludXRlcyA9IHRvdGFsTWludXRlcyAlIDYwO1xuICAgICAgICByZXR1cm4gZGF5anMoKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykuZm9ybWF0KCdISDptbScpO1xuICAgIH1cbiAgICBnZXRNaW51dGVzU2luY2VNaWRuaWdodChkYXRlKSB7XG4gICAgICAgIGNvbnN0IGQgPSBkYXlqcyhkYXRlKTtcbiAgICAgICAgcmV0dXJuIGQuaG91cigpICogNjAgKyBkLm1pbnV0ZSgpO1xuICAgIH1cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFVUQyBDT05WRVJTSU9OU1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdG9VVEMobG9jYWxEYXRlKSB7XG4gICAgICAgIHJldHVybiBkYXlqcy50eihsb2NhbERhdGUsIHRoaXMudGltZXpvbmUpLnV0YygpLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuICAgIGZyb21VVEModXRjU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBkYXlqcy51dGModXRjU3RyaW5nKS50eih0aGlzLnRpbWV6b25lKS50b0RhdGUoKTtcbiAgICB9XG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBEQVRFIENSRUFUSU9OXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICBjcmVhdGVEYXRlQXRUaW1lKGJhc2VEYXRlLCB0aW1lU3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHRvdGFsTWludXRlcyA9IHRoaXMudGltZVRvTWludXRlcyh0aW1lU3RyaW5nKTtcbiAgICAgICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKHRvdGFsTWludXRlcyAvIDYwKTtcbiAgICAgICAgY29uc3QgbWludXRlcyA9IHRvdGFsTWludXRlcyAlIDYwO1xuICAgICAgICByZXR1cm4gZGF5anMoYmFzZURhdGUpLnN0YXJ0T2YoJ2RheScpLmhvdXIoaG91cnMpLm1pbnV0ZShtaW51dGVzKS50b0RhdGUoKTtcbiAgICB9XG4gICAgZ2V0SVNPV2Vla0RheShkYXRlKSB7XG4gICAgICAgIHJldHVybiBkYXlqcyhkYXRlKS5pc29XZWVrZGF5KCk7IC8vIDE9TW9uZGF5LCA3PVN1bmRheVxuICAgIH1cbn1cbiIsICIvKipcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGdyb3VwaW5nIHJlbmRlcmVyc1xuICpcbiAqIEhhbmRsZXM6XG4gKiAtIEZldGNoaW5nIGVudGl0aWVzIGJ5IElEc1xuICogLSBDYWxjdWxhdGluZyBjb2xzcGFuIGZyb20gcGFyZW50Q2hpbGRNYXBcbiAqIC0gQ3JlYXRpbmcgaGVhZGVyIGVsZW1lbnRzXG4gKiAtIEFwcGVuZGluZyB0byBjb250YWluZXJcbiAqXG4gKiBTdWJjbGFzc2VzIG92ZXJyaWRlOlxuICogLSByZW5kZXJIZWFkZXIoKSBmb3IgY3VzdG9tIGNvbnRlbnRcbiAqIC0gZ2V0RGlzcGxheU5hbWUoKSBmb3IgZW50aXR5IGRpc3BsYXkgdGV4dFxuICovXG5leHBvcnQgY2xhc3MgQmFzZUdyb3VwaW5nUmVuZGVyZXIge1xuICAgIC8qKlxuICAgICAqIE1haW4gcmVuZGVyIG1ldGhvZCAtIGhhbmRsZXMgY29tbW9uIGxvZ2ljXG4gICAgICovXG4gICAgYXN5bmMgcmVuZGVyKGNvbnRleHQpIHtcbiAgICAgICAgY29uc3QgYWxsb3dlZElkcyA9IGNvbnRleHQuZmlsdGVyW3RoaXMudHlwZV0gfHwgW107XG4gICAgICAgIGlmIChhbGxvd2VkSWRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKGFsbG93ZWRJZHMpO1xuICAgICAgICBjb25zdCBkYXRlQ291bnQgPSBjb250ZXh0LmZpbHRlclsnZGF0ZSddPy5sZW5ndGggfHwgMTtcbiAgICAgICAgY29uc3QgY2hpbGRJZHMgPSBjb250ZXh0LmNoaWxkVHlwZSA/IGNvbnRleHQuZmlsdGVyW2NvbnRleHQuY2hpbGRUeXBlXSB8fCBbXSA6IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5Q2hpbGRJZHMgPSBjb250ZXh0LnBhcmVudENoaWxkTWFwPy5bZW50aXR5LmlkXSB8fCBbXTtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkQ291bnQgPSBlbnRpdHlDaGlsZElkcy5maWx0ZXIoaWQgPT4gY2hpbGRJZHMuaW5jbHVkZXMoaWQpKS5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjb2xzcGFuID0gY2hpbGRDb3VudCAqIGRhdGVDb3VudDtcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGhpcy5jb25maWcuZWxlbWVudFRhZyk7XG4gICAgICAgICAgICBoZWFkZXIuZGF0YXNldFt0aGlzLmNvbmZpZy5pZEF0dHJpYnV0ZV0gPSBlbnRpdHkuaWQ7XG4gICAgICAgICAgICBoZWFkZXIuc3R5bGUuc2V0UHJvcGVydHkodGhpcy5jb25maWcuY29sc3BhblZhciwgU3RyaW5nKGNvbHNwYW4pKTtcbiAgICAgICAgICAgIC8vIEFsbG93IHN1YmNsYXNzIHRvIGN1c3RvbWl6ZSBoZWFkZXIgY29udGVudFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJIZWFkZXIoZW50aXR5LCBoZWFkZXIsIGNvbnRleHQpO1xuICAgICAgICAgICAgY29udGV4dC5oZWFkZXJDb250YWluZXIuYXBwZW5kQ2hpbGQoaGVhZGVyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgY3VzdG9tIGhlYWRlciByZW5kZXJpbmdcbiAgICAgKiBEZWZhdWx0OiBqdXN0IHNldHMgdGV4dENvbnRlbnQgdG8gZGlzcGxheSBuYW1lXG4gICAgICovXG4gICAgcmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBfY29udGV4dCkge1xuICAgICAgICBoZWFkZXIudGV4dENvbnRlbnQgPSB0aGlzLmdldERpc3BsYXlOYW1lKGVudGl0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhlbHBlciB0byByZW5kZXIgYSBzaW5nbGUgZW50aXR5IGhlYWRlci5cbiAgICAgKiBDYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgcmVuZGVyKCkgYnV0IHdhbnQgY29uc2lzdGVudCBoZWFkZXIgY3JlYXRpb24uXG4gICAgICovXG4gICAgY3JlYXRlSGVhZGVyKGVudGl0eSwgY29udGV4dCkge1xuICAgICAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xuICAgICAgICBoZWFkZXIuZGF0YXNldFt0aGlzLmNvbmZpZy5pZEF0dHJpYnV0ZV0gPSBlbnRpdHkuaWQ7XG4gICAgICAgIHRoaXMucmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBjb250ZXh0KTtcbiAgICAgICAgcmV0dXJuIGhlYWRlcjtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQmFzZUdyb3VwaW5nUmVuZGVyZXIgfSBmcm9tICcuLi8uLi9jb3JlL0Jhc2VHcm91cGluZ1JlbmRlcmVyJztcbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVJlbmRlcmVyIGV4dGVuZHMgQmFzZUdyb3VwaW5nUmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKHJlc291cmNlU2VydmljZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnJlc291cmNlU2VydmljZSA9IHJlc291cmNlU2VydmljZTtcbiAgICAgICAgdGhpcy50eXBlID0gJ3Jlc291cmNlJztcbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICBlbGVtZW50VGFnOiAnc3dwLXJlc291cmNlLWhlYWRlcicsXG4gICAgICAgICAgICBpZEF0dHJpYnV0ZTogJ3Jlc291cmNlSWQnLFxuICAgICAgICAgICAgY29sc3BhblZhcjogJy0tcmVzb3VyY2UtY29scydcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZ2V0RW50aXRpZXMoaWRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc291cmNlU2VydmljZS5nZXRCeUlkcyhpZHMpO1xuICAgIH1cbiAgICBnZXREaXNwbGF5TmFtZShlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eS5kaXNwbGF5TmFtZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgcmVuZGVyIHRvIGhhbmRsZTpcbiAgICAgKiAxLiBTcGVjaWFsIG9yZGVyaW5nIHdoZW4gcGFyZW50Q2hpbGRNYXAgZXhpc3RzIChyZXNvdXJjZXMgZ3JvdXBlZCBieSBwYXJlbnQpXG4gICAgICogMi4gRGlmZmVyZW50IGNvbHNwYW4gY2FsY3VsYXRpb24gKGp1c3QgZGF0ZUNvdW50LCBub3QgY2hpbGRDb3VudCAqIGRhdGVDb3VudClcbiAgICAgKi9cbiAgICBhc3luYyByZW5kZXIoY29udGV4dCkge1xuICAgICAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xuICAgICAgICBjb25zdCBkYXRlQ291bnQgPSBjb250ZXh0LmZpbHRlclsnZGF0ZSddPy5sZW5ndGggfHwgMTtcbiAgICAgICAgLy8gRGV0ZXJtaW5lIHJlbmRlciBvcmRlciBiYXNlZCBvbiBwYXJlbnRDaGlsZE1hcFxuICAgICAgICAvLyBJZiBwYXJlbnRDaGlsZE1hcCBleGlzdHMsIHJlbmRlciByZXNvdXJjZXMgZ3JvdXBlZCBieSBwYXJlbnQgKGUuZy4sIHRlYW0pXG4gICAgICAgIC8vIE90aGVyd2lzZSwgcmVuZGVyIGluIGZpbHRlciBvcmRlclxuICAgICAgICBsZXQgb3JkZXJlZFJlc291cmNlSWRzO1xuICAgICAgICBpZiAoY29udGV4dC5wYXJlbnRDaGlsZE1hcCkge1xuICAgICAgICAgICAgLy8gUmVuZGVyIHJlc291cmNlcyBpbiBwYXJlbnQtY2hpbGQgb3JkZXJcbiAgICAgICAgICAgIG9yZGVyZWRSZXNvdXJjZUlkcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBjaGlsZElkcyBvZiBPYmplY3QudmFsdWVzKGNvbnRleHQucGFyZW50Q2hpbGRNYXApKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjaGlsZElkIG9mIGNoaWxkSWRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZUlkcy5pbmNsdWRlcyhjaGlsZElkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZFJlc291cmNlSWRzLnB1c2goY2hpbGRJZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSByZXNvdXJjZUlkcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNvdXJjZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKG9yZGVyZWRSZXNvdXJjZUlkcyk7XG4gICAgICAgIC8vIENyZWF0ZSBhIG1hcCBmb3IgcXVpY2sgbG9va3VwIHRvIHByZXNlcnZlIG9yZGVyXG4gICAgICAgIGNvbnN0IHJlc291cmNlTWFwID0gbmV3IE1hcChyZXNvdXJjZXMubWFwKHIgPT4gW3IuaWQsIHJdKSk7XG4gICAgICAgIGZvciAoY29uc3QgcmVzb3VyY2VJZCBvZiBvcmRlcmVkUmVzb3VyY2VJZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc291cmNlID0gcmVzb3VyY2VNYXAuZ2V0KHJlc291cmNlSWQpO1xuICAgICAgICAgICAgaWYgKCFyZXNvdXJjZSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlciA9IHRoaXMuY3JlYXRlSGVhZGVyKHJlc291cmNlLCBjb250ZXh0KTtcbiAgICAgICAgICAgIGhlYWRlci5zdHlsZS5ncmlkQ29sdW1uID0gYHNwYW4gJHtkYXRlQ291bnR9YDtcbiAgICAgICAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQmFzZUdyb3VwaW5nUmVuZGVyZXIgfSBmcm9tICcuLi8uLi9jb3JlL0Jhc2VHcm91cGluZ1JlbmRlcmVyJztcbmV4cG9ydCBjbGFzcyBUZWFtUmVuZGVyZXIgZXh0ZW5kcyBCYXNlR3JvdXBpbmdSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3IodGVhbVNlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy50ZWFtU2VydmljZSA9IHRlYW1TZXJ2aWNlO1xuICAgICAgICB0aGlzLnR5cGUgPSAndGVhbSc7XG4gICAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAgICAgZWxlbWVudFRhZzogJ3N3cC10ZWFtLWhlYWRlcicsXG4gICAgICAgICAgICBpZEF0dHJpYnV0ZTogJ3RlYW1JZCcsXG4gICAgICAgICAgICBjb2xzcGFuVmFyOiAnLS10ZWFtLWNvbHMnXG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldEVudGl0aWVzKGlkcykge1xuICAgICAgICByZXR1cm4gdGhpcy50ZWFtU2VydmljZS5nZXRCeUlkcyhpZHMpO1xuICAgIH1cbiAgICBnZXREaXNwbGF5TmFtZShlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eS5uYW1lO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBCYXNlR3JvdXBpbmdSZW5kZXJlciB9IGZyb20gJy4uLy4uL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXInO1xuZXhwb3J0IGNsYXNzIERlcGFydG1lbnRSZW5kZXJlciBleHRlbmRzIEJhc2VHcm91cGluZ1JlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihkZXBhcnRtZW50U2VydmljZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmRlcGFydG1lbnRTZXJ2aWNlID0gZGVwYXJ0bWVudFNlcnZpY2U7XG4gICAgICAgIHRoaXMudHlwZSA9ICdkZXBhcnRtZW50JztcbiAgICAgICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAgICAgICBlbGVtZW50VGFnOiAnc3dwLWRlcGFydG1lbnQtaGVhZGVyJyxcbiAgICAgICAgICAgIGlkQXR0cmlidXRlOiAnZGVwYXJ0bWVudElkJyxcbiAgICAgICAgICAgIGNvbHNwYW5WYXI6ICctLWRlcGFydG1lbnQtY29scydcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZ2V0RW50aXRpZXMoaWRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlcGFydG1lbnRTZXJ2aWNlLmdldEJ5SWRzKGlkcyk7XG4gICAgfVxuICAgIGdldERpc3BsYXlOYW1lKGVudGl0eSkge1xuICAgICAgICByZXR1cm4gZW50aXR5Lm5hbWU7XG4gICAgfVxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBidWlsZFBpcGVsaW5lKHJlbmRlcmVycykge1xuICAgIHJldHVybiB7XG4gICAgICAgIGFzeW5jIHJ1bihjb250ZXh0KSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlbmRlcmVyIG9mIHJlbmRlcmVycykge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcmVyLnJlbmRlcihjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59XG4iLCAiLyoqXG4gKiBGaWx0ZXJUZW1wbGF0ZSAtIEJ5Z2dlciBuXHUwMEY4Z2xlciB0aWwgZXZlbnQta29sb25uZSBtYXRjaGluZ1xuICpcbiAqIFZpZXdDb25maWcgZGVmaW5lcmVyIGh2aWxrZSBmZWx0ZXIgKGlkUHJvcGVydGllcykgZGVyIGluZGdcdTAwRTVyIGkga29sb25uZW5zIG5cdTAwRjhnbGUuXG4gKiBTYW1tZSB0ZW1wbGF0ZSBicnVnZXMgdGlsIGF0IGJ5Z2dlIG5cdTAwRjhnbGUgZm9yIGJcdTAwRTVkZSBrb2xvbm5lIG9nIGV2ZW50LlxuICpcbiAqIFN1cHBvcnRzIGRvdC1ub3RhdGlvbiBmb3IgaGllcmFyY2hpY2FsIHJlbGF0aW9uczpcbiAqIC0gJ3Jlc291cmNlLnRlYW1JZCcgXHUyMTkyIGxvb2tzIHVwIGV2ZW50LnJlc291cmNlSWQgXHUyMTkyIHJlc291cmNlIGVudGl0eSBcdTIxOTIgdGVhbUlkXG4gKlxuICogUHJpbmNpcDogS29sb25uZW5zIG5cdTAwRjhnbGUtdGVtcGxhdGUgYmVzdGVtbWVyIGh2YWQgZGVyIG1hdGNoZXMgcFx1MDBFNS5cbiAqXG4gKiBAc2VlIGRvY3MvZmlsdGVyLXRlbXBsYXRlLm1kXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJUZW1wbGF0ZSB7XG4gICAgY29uc3RydWN0b3IoZGF0ZVNlcnZpY2UsIGVudGl0eVJlc29sdmVyKSB7XG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2UgPSBkYXRlU2VydmljZTtcbiAgICAgICAgdGhpcy5lbnRpdHlSZXNvbHZlciA9IGVudGl0eVJlc29sdmVyO1xuICAgICAgICB0aGlzLmZpZWxkcyA9IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaWxmXHUwMEY4aiBmZWx0IHRpbCB0ZW1wbGF0ZVxuICAgICAqIEBwYXJhbSBpZFByb3BlcnR5IC0gUHJvcGVydHktbmF2biAoYnJ1Z2VzIHBcdTAwRTUgYlx1MDBFNWRlIGV2ZW50IG9nIGNvbHVtbi5kYXRhc2V0KVxuICAgICAqIEBwYXJhbSBkZXJpdmVkRnJvbSAtIEh2aXMgZmVsdGV0IHVkbGVkZXMgZnJhIGFuZGVuIHByb3BlcnR5IChmLmVrcy4gZGF0ZSBmcmEgc3RhcnQpXG4gICAgICovXG4gICAgYWRkRmllbGQoaWRQcm9wZXJ0eSwgZGVyaXZlZEZyb20pIHtcbiAgICAgICAgdGhpcy5maWVsZHMucHVzaCh7IGlkUHJvcGVydHksIGRlcml2ZWRGcm9tIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGFyc2UgZG90LW5vdGF0aW9uIHN0cmluZyBpbnRvIGNvbXBvbmVudHNcbiAgICAgKiBAZXhhbXBsZSAncmVzb3VyY2UudGVhbUlkJyBcdTIxOTIgeyBlbnRpdHlUeXBlOiAncmVzb3VyY2UnLCBwcm9wZXJ0eTogJ3RlYW1JZCcsIGZvcmVpZ25LZXk6ICdyZXNvdXJjZUlkJyB9XG4gICAgICovXG4gICAgcGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5KSB7XG4gICAgICAgIGlmICghaWRQcm9wZXJ0eS5pbmNsdWRlcygnLicpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGNvbnN0IFtlbnRpdHlUeXBlLCBwcm9wZXJ0eV0gPSBpZFByb3BlcnR5LnNwbGl0KCcuJyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBlbnRpdHlUeXBlLFxuICAgICAgICAgICAgcHJvcGVydHksXG4gICAgICAgICAgICBmb3JlaWduS2V5OiBlbnRpdHlUeXBlICsgJ0lkJyAvLyBDb252ZW50aW9uOiByZXNvdXJjZSBcdTIxOTIgcmVzb3VyY2VJZFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZGF0YXNldCBrZXkgZm9yIGNvbHVtbiBsb29rdXBcbiAgICAgKiBGb3IgZG90LW5vdGF0aW9uICdyZXNvdXJjZS50ZWFtSWQnLCB3ZSBsb29rIGZvciAndGVhbUlkJyBpbiBkYXRhc2V0XG4gICAgICovXG4gICAgZ2V0RGF0YXNldEtleShpZFByb3BlcnR5KSB7XG4gICAgICAgIGNvbnN0IGRvdE5vdGF0aW9uID0gdGhpcy5wYXJzZURvdE5vdGF0aW9uKGlkUHJvcGVydHkpO1xuICAgICAgICBpZiAoZG90Tm90YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBkb3ROb3RhdGlvbi5wcm9wZXJ0eTsgLy8gJ3RlYW1JZCdcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaWRQcm9wZXJ0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQnlnIG5cdTAwRjhnbGUgZnJhIGtvbG9ubmVcbiAgICAgKiBMXHUwMEU2c2VyIHZcdTAwRTZyZGllciBmcmEgY29sdW1uLmRhdGFzZXRbaWRQcm9wZXJ0eV1cbiAgICAgKiBGb3IgZG90LW5vdGF0aW9uLCB1c2VzIHRoZSBwcm9wZXJ0eSBwYXJ0IChyZXNvdXJjZS50ZWFtSWQgXHUyMTkyIHRlYW1JZClcbiAgICAgKi9cbiAgICBidWlsZEtleUZyb21Db2x1bW4oY29sdW1uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZpZWxkc1xuICAgICAgICAgICAgLm1hcChmID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0RGF0YXNldEtleShmLmlkUHJvcGVydHkpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbHVtbi5kYXRhc2V0W2tleV0gfHwgJyc7XG4gICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbignOicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCeWcgblx1MDBGOGdsZSBmcmEgZXZlbnRcbiAgICAgKiBMXHUwMEU2c2VyIHZcdTAwRTZyZGllciBmcmEgZXZlbnRbaWRQcm9wZXJ0eV0gZWxsZXIgdWRsZWRlciBmcmEgZGVyaXZlZEZyb21cbiAgICAgKiBGb3IgZG90LW5vdGF0aW9uLCByZXNvbHZlcyB2aWEgRW50aXR5UmVzb2x2ZXJcbiAgICAgKi9cbiAgICBidWlsZEtleUZyb21FdmVudChldmVudCkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICBjb25zdCBldmVudFJlY29yZCA9IGV2ZW50O1xuICAgICAgICByZXR1cm4gdGhpcy5maWVsZHNcbiAgICAgICAgICAgIC5tYXAoZiA9PiB7XG4gICAgICAgICAgICAvLyBDaGVjayBmb3IgZG90LW5vdGF0aW9uIChlLmcuLCAncmVzb3VyY2UudGVhbUlkJylcbiAgICAgICAgICAgIGNvbnN0IGRvdE5vdGF0aW9uID0gdGhpcy5wYXJzZURvdE5vdGF0aW9uKGYuaWRQcm9wZXJ0eSk7XG4gICAgICAgICAgICBpZiAoZG90Tm90YXRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNvbHZlRG90Tm90YXRpb24oZXZlbnRSZWNvcmQsIGRvdE5vdGF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmLmRlcml2ZWRGcm9tKSB7XG4gICAgICAgICAgICAgICAgLy8gVWRsZWQgdlx1MDBFNnJkaSAoZi5la3MuIGRhdGUgZnJhIHN0YXJ0KVxuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gZXZlbnRSZWNvcmRbZi5kZXJpdmVkRnJvbV07XG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZVZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRlU2VydmljZS5nZXREYXRlS2V5KHNvdXJjZVZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhzb3VyY2VWYWx1ZSB8fCAnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gU3RyaW5nKGV2ZW50UmVjb3JkW2YuaWRQcm9wZXJ0eV0gfHwgJycpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJzonKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzb2x2ZSBkb3Qtbm90YXRpb24gcmVmZXJlbmNlIHZpYSBFbnRpdHlSZXNvbHZlclxuICAgICAqL1xuICAgIHJlc29sdmVEb3ROb3RhdGlvbihldmVudFJlY29yZCwgZG90Tm90YXRpb24pIHtcbiAgICAgICAgaWYgKCF0aGlzLmVudGl0eVJlc29sdmVyKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEZpbHRlclRlbXBsYXRlOiBFbnRpdHlSZXNvbHZlciByZXF1aXJlZCBmb3IgZG90LW5vdGF0aW9uICcke2RvdE5vdGF0aW9uLmVudGl0eVR5cGV9LiR7ZG90Tm90YXRpb24ucHJvcGVydHl9J2ApO1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG4gICAgICAgIC8vIEdldCBmb3JlaWduIGtleSB2YWx1ZSBmcm9tIGV2ZW50IChlLmcuLCByZXNvdXJjZUlkKVxuICAgICAgICBjb25zdCBmb3JlaWduSWQgPSBldmVudFJlY29yZFtkb3ROb3RhdGlvbi5mb3JlaWduS2V5XTtcbiAgICAgICAgaWYgKCFmb3JlaWduSWQpXG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIC8vIFJlc29sdmUgZW50aXR5XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5UmVzb2x2ZXIucmVzb2x2ZShkb3ROb3RhdGlvbi5lbnRpdHlUeXBlLCBTdHJpbmcoZm9yZWlnbklkKSk7XG4gICAgICAgIGlmICghZW50aXR5KVxuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICAvLyBSZXR1cm4gcHJvcGVydHkgdmFsdWUgZnJvbSBlbnRpdHlcbiAgICAgICAgcmV0dXJuIFN0cmluZyhlbnRpdHlbZG90Tm90YXRpb24ucHJvcGVydHldIHx8ICcnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWF0Y2ggZXZlbnQgbW9kIGtvbG9ubmVcbiAgICAgKi9cbiAgICBtYXRjaGVzKGV2ZW50LCBjb2x1bW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRLZXlGcm9tRXZlbnQoZXZlbnQpID09PSB0aGlzLmJ1aWxkS2V5RnJvbUNvbHVtbihjb2x1bW4pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBidWlsZFBpcGVsaW5lIH0gZnJvbSAnLi9SZW5kZXJCdWlsZGVyJztcbmltcG9ydCB7IEZpbHRlclRlbXBsYXRlIH0gZnJvbSAnLi9GaWx0ZXJUZW1wbGF0ZSc7XG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJPcmNoZXN0cmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKGFsbFJlbmRlcmVycywgZXZlbnRSZW5kZXJlciwgc2NoZWR1bGVSZW5kZXJlciwgaGVhZGVyRHJhd2VyUmVuZGVyZXIsIGRhdGVTZXJ2aWNlLCBlbnRpdHlTZXJ2aWNlcykge1xuICAgICAgICB0aGlzLmFsbFJlbmRlcmVycyA9IGFsbFJlbmRlcmVycztcbiAgICAgICAgdGhpcy5ldmVudFJlbmRlcmVyID0gZXZlbnRSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVJlbmRlcmVyID0gc2NoZWR1bGVSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXJSZW5kZXJlciA9IGhlYWRlckRyYXdlclJlbmRlcmVyO1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuZW50aXR5U2VydmljZXMgPSBlbnRpdHlTZXJ2aWNlcztcbiAgICB9XG4gICAgYXN5bmMgcmVuZGVyKHZpZXdDb25maWcsIGNvbnRhaW5lcikge1xuICAgICAgICBjb25zdCBoZWFkZXJDb250YWluZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWNhbGVuZGFyLWhlYWRlcicpO1xuICAgICAgICBjb25zdCBjb2x1bW5Db250YWluZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWRheS1jb2x1bW5zJyk7XG4gICAgICAgIGlmICghaGVhZGVyQ29udGFpbmVyIHx8ICFjb2x1bW5Db250YWluZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzd3AtY2FsZW5kYXItaGVhZGVyIG9yIHN3cC1kYXktY29sdW1ucycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ5ZyBmaWx0ZXIgZnJhIHZpZXdDb25maWdcbiAgICAgICAgY29uc3QgZmlsdGVyID0ge307XG4gICAgICAgIGZvciAoY29uc3QgZ3JvdXBpbmcgb2Ygdmlld0NvbmZpZy5ncm91cGluZ3MpIHtcbiAgICAgICAgICAgIGZpbHRlcltncm91cGluZy50eXBlXSA9IGdyb3VwaW5nLnZhbHVlcztcbiAgICAgICAgfVxuICAgICAgICAvLyBCeWcgRmlsdGVyVGVtcGxhdGUgZnJhIHZpZXdDb25maWcgZ3JvdXBpbmdzIChrdW4gZGUgbWVkIGlkUHJvcGVydHkpXG4gICAgICAgIGNvbnN0IGZpbHRlclRlbXBsYXRlID0gbmV3IEZpbHRlclRlbXBsYXRlKHRoaXMuZGF0ZVNlcnZpY2UpO1xuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwaW5nIG9mIHZpZXdDb25maWcuZ3JvdXBpbmdzKSB7XG4gICAgICAgICAgICBpZiAoZ3JvdXBpbmcuaWRQcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIGZpbHRlclRlbXBsYXRlLmFkZEZpZWxkKGdyb3VwaW5nLmlkUHJvcGVydHksIGdyb3VwaW5nLmRlcml2ZWRGcm9tKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBSZXNvbHZlIGJlbG9uZ3NUbyByZWxhdGlvbnMgKGUuZy4sIHRlYW0ucmVzb3VyY2VJZHMpXG4gICAgICAgIGNvbnN0IHsgcGFyZW50Q2hpbGRNYXAsIGNoaWxkVHlwZSB9ID0gYXdhaXQgdGhpcy5yZXNvbHZlQmVsb25nc1RvKHZpZXdDb25maWcuZ3JvdXBpbmdzLCBmaWx0ZXIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0geyBoZWFkZXJDb250YWluZXIsIGNvbHVtbkNvbnRhaW5lciwgZmlsdGVyLCBncm91cGluZ3M6IHZpZXdDb25maWcuZ3JvdXBpbmdzLCBwYXJlbnRDaGlsZE1hcCwgY2hpbGRUeXBlIH07XG4gICAgICAgIC8vIENsZWFyXG4gICAgICAgIGhlYWRlckNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgY29sdW1uQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAvLyBTXHUwMEU2dCBkYXRhLWxldmVscyBhdHRyaWJ1dCBmb3IgQ1NTIGdyaWQtcm93IHN0eWxpbmdcbiAgICAgICAgY29uc3QgbGV2ZWxzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKS5qb2luKCcgJyk7XG4gICAgICAgIGhlYWRlckNvbnRhaW5lci5kYXRhc2V0LmxldmVscyA9IGxldmVscztcbiAgICAgICAgLy8gVlx1MDBFNmxnIHJlbmRlcmVycyBiYXNlcmV0IHBcdTAwRTUgZ3JvdXBpbmdzIHR5cGVzXG4gICAgICAgIGNvbnN0IGFjdGl2ZVJlbmRlcmVycyA9IHRoaXMuc2VsZWN0UmVuZGVyZXJzKHZpZXdDb25maWcpO1xuICAgICAgICAvLyBCeWcgb2cga1x1MDBGOHIgcGlwZWxpbmVcbiAgICAgICAgY29uc3QgcGlwZWxpbmUgPSBidWlsZFBpcGVsaW5lKGFjdGl2ZVJlbmRlcmVycyk7XG4gICAgICAgIGF3YWl0IHBpcGVsaW5lLnJ1bihjb250ZXh0KTtcbiAgICAgICAgLy8gUmVuZGVyIHNjaGVkdWxlIHVuYXZhaWxhYmxlIHpvbmVzIChmXHUwMEY4ciBldmVudHMpXG4gICAgICAgIGF3YWl0IHRoaXMuc2NoZWR1bGVSZW5kZXJlci5yZW5kZXIoY29udGFpbmVyLCBmaWx0ZXIpO1xuICAgICAgICAvLyBSZW5kZXIgdGltZWQgZXZlbnRzIGluIGdyaWQgKG1lZCBmaWx0ZXJUZW1wbGF0ZSB0aWwgbWF0Y2hpbmcpXG4gICAgICAgIGF3YWl0IHRoaXMuZXZlbnRSZW5kZXJlci5yZW5kZXIoY29udGFpbmVyLCBmaWx0ZXIsIGZpbHRlclRlbXBsYXRlKTtcbiAgICAgICAgLy8gUmVuZGVyIGFsbERheSBldmVudHMgaW4gaGVhZGVyIGRyYXdlciAobWVkIGZpbHRlclRlbXBsYXRlIHRpbCBtYXRjaGluZylcbiAgICAgICAgYXdhaXQgdGhpcy5oZWFkZXJEcmF3ZXJSZW5kZXJlci5yZW5kZXIoY29udGFpbmVyLCBmaWx0ZXIsIGZpbHRlclRlbXBsYXRlKTtcbiAgICB9XG4gICAgc2VsZWN0UmVuZGVyZXJzKHZpZXdDb25maWcpIHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSB2aWV3Q29uZmlnLmdyb3VwaW5ncy5tYXAoZyA9PiBnLnR5cGUpO1xuICAgICAgICAvLyBTb3J0XHUwMEU5ciByZW5kZXJlcnMgaSBzYW1tZSByXHUwMEU2a2tlZlx1MDBGOGxnZSBzb20gdmlld0NvbmZpZy5ncm91cGluZ3NcbiAgICAgICAgcmV0dXJuIHR5cGVzXG4gICAgICAgICAgICAubWFwKHR5cGUgPT4gdGhpcy5hbGxSZW5kZXJlcnMuZmluZChyID0+IHIudHlwZSA9PT0gdHlwZSkpXG4gICAgICAgICAgICAuZmlsdGVyKChyKSA9PiByICE9PSB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlIGJlbG9uZ3NUbyByZWxhdGlvbnMgdG8gYnVpbGQgcGFyZW50LWNoaWxkIG1hcFxuICAgICAqIGUuZy4sIGJlbG9uZ3NUbzogJ3RlYW0ucmVzb3VyY2VJZHMnIFx1MjE5MiB7IHRlYW0xOiBbJ0VNUDAwMScsICdFTVAwMDInXSwgdGVhbTI6IFsuLi5dIH1cbiAgICAgKiBBbHNvIHJldHVybnMgdGhlIGNoaWxkVHlwZSAodGhlIGdyb3VwaW5nIHR5cGUgdGhhdCBoYXMgYmVsb25nc1RvKVxuICAgICAqL1xuICAgIGFzeW5jIHJlc29sdmVCZWxvbmdzVG8oZ3JvdXBpbmdzLCBmaWx0ZXIpIHtcbiAgICAgICAgLy8gRmluZCBncm91cGluZyB3aXRoIGJlbG9uZ3NUb1xuICAgICAgICBjb25zdCBjaGlsZEdyb3VwaW5nID0gZ3JvdXBpbmdzLmZpbmQoZyA9PiBnLmJlbG9uZ3NUbyk7XG4gICAgICAgIGlmICghY2hpbGRHcm91cGluZz8uYmVsb25nc1RvKVxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAvLyBQYXJzZSBiZWxvbmdzVG86ICd0ZWFtLnJlc291cmNlSWRzJ1xuICAgICAgICBjb25zdCBbZW50aXR5VHlwZSwgcHJvcGVydHldID0gY2hpbGRHcm91cGluZy5iZWxvbmdzVG8uc3BsaXQoJy4nKTtcbiAgICAgICAgaWYgKCFlbnRpdHlUeXBlIHx8ICFwcm9wZXJ0eSlcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgLy8gR2V0IHBhcmVudCBJRHMgZnJvbSBmaWx0ZXJcbiAgICAgICAgY29uc3QgcGFyZW50SWRzID0gZmlsdGVyW2VudGl0eVR5cGVdIHx8IFtdO1xuICAgICAgICBpZiAocGFyZW50SWRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgLy8gRmluZCBzZXJ2aWNlIGR5bmFtaXNrIGJhc2VyZXQgcFx1MDBFNSBlbnRpdHlUeXBlIChpbmdlbiBoYXJkY29kZWQgdHlwZSBjaGVjaylcbiAgICAgICAgY29uc3Qgc2VydmljZSA9IHRoaXMuZW50aXR5U2VydmljZXMuZmluZChzID0+IHMuZW50aXR5VHlwZS50b0xvd2VyQ2FzZSgpID09PSBlbnRpdHlUeXBlKTtcbiAgICAgICAgaWYgKCFzZXJ2aWNlKVxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAvLyBIZW50IGFsbGUgZW50aXRpZXMgb2cgZmlsdHJlciBwXHUwMEU1IHBhcmVudElkc1xuICAgICAgICBjb25zdCBhbGxFbnRpdGllcyA9IGF3YWl0IHNlcnZpY2UuZ2V0QWxsKCk7XG4gICAgICAgIGNvbnN0IGVudGl0aWVzID0gYWxsRW50aXRpZXMuZmlsdGVyKGUgPT4gcGFyZW50SWRzLmluY2x1ZGVzKGUuaWQpKTtcbiAgICAgICAgLy8gQnlnIHBhcmVudC1jaGlsZCBtYXBcbiAgICAgICAgY29uc3QgbWFwID0ge307XG4gICAgICAgIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHlSZWNvcmQgPSBlbnRpdHk7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IGVudGl0eVJlY29yZFtwcm9wZXJ0eV0gfHwgW107XG4gICAgICAgICAgICBtYXBbZW50aXR5UmVjb3JkLmlkXSA9IGNoaWxkcmVuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHBhcmVudENoaWxkTWFwOiBtYXAsIGNoaWxkVHlwZTogY2hpbGRHcm91cGluZy50eXBlIH07XG4gICAgfVxufVxuIiwgImV4cG9ydCBjbGFzcyBOYXZpZ2F0aW9uQW5pbWF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKGhlYWRlclRyYWNrLCBjb250ZW50VHJhY2spIHtcbiAgICAgICAgdGhpcy5oZWFkZXJUcmFjayA9IGhlYWRlclRyYWNrO1xuICAgICAgICB0aGlzLmNvbnRlbnRUcmFjayA9IGNvbnRlbnRUcmFjaztcbiAgICB9XG4gICAgYXN5bmMgc2xpZGUoZGlyZWN0aW9uLCByZW5kZXJGbikge1xuICAgICAgICBjb25zdCBvdXQgPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/ICctMTAwJScgOiAnMTAwJSc7XG4gICAgICAgIGNvbnN0IGludG8gPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/ICcxMDAlJyA6ICctMTAwJSc7XG4gICAgICAgIGF3YWl0IHRoaXMuYW5pbWF0ZU91dChvdXQpO1xuICAgICAgICBhd2FpdCByZW5kZXJGbigpO1xuICAgICAgICBhd2FpdCB0aGlzLmFuaW1hdGVJbihpbnRvKTtcbiAgICB9XG4gICAgYXN5bmMgYW5pbWF0ZU91dCh0cmFuc2xhdGUpIHtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJUcmFjay5hbmltYXRlKFt7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH0sIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9XSwgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLWluJyB9KS5maW5pc2hlZCxcbiAgICAgICAgICAgIHRoaXMuY29udGVudFRyYWNrLmFuaW1hdGUoW3sgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfSwgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH1dLCB7IGR1cmF0aW9uOiAyMDAsIGVhc2luZzogJ2Vhc2UtaW4nIH0pLmZpbmlzaGVkXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBhc3luYyBhbmltYXRlSW4odHJhbnNsYXRlKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyVHJhY2suYW5pbWF0ZShbeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH0sIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfV0sIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH0pLmZpbmlzaGVkLFxuICAgICAgICAgICAgdGhpcy5jb250ZW50VHJhY2suYW5pbWF0ZShbeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH0sIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfV0sIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH0pLmZpbmlzaGVkXG4gICAgICAgIF0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIENhbGVuZGFyRXZlbnRzIC0gQ29tbWFuZCBhbmQgc3RhdHVzIGV2ZW50cyBmb3IgQ2FsZW5kYXJBcHBcbiAqL1xuZXhwb3J0IGNvbnN0IENhbGVuZGFyRXZlbnRzID0ge1xuICAgIC8vIENvbW1hbmQgZXZlbnRzIChob3N0IFx1MjE5MiBjYWxlbmRhcilcbiAgICBDTURfTkFWSUdBVEVfUFJFVjogJ2NhbGVuZGFyOmNtZDpuYXZpZ2F0ZTpwcmV2JyxcbiAgICBDTURfTkFWSUdBVEVfTkVYVDogJ2NhbGVuZGFyOmNtZDpuYXZpZ2F0ZTpuZXh0JyxcbiAgICBDTURfRFJBV0VSX1RPR0dMRTogJ2NhbGVuZGFyOmNtZDpkcmF3ZXI6dG9nZ2xlJyxcbiAgICBDTURfUkVOREVSOiAnY2FsZW5kYXI6Y21kOnJlbmRlcicsXG4gICAgQ01EX1dPUktXRUVLX0NIQU5HRTogJ2NhbGVuZGFyOmNtZDp3b3Jrd2VlazpjaGFuZ2UnLFxuICAgIENNRF9WSUVXX1VQREFURTogJ2NhbGVuZGFyOmNtZDp2aWV3OnVwZGF0ZSdcbn07XG4iLCAiaW1wb3J0IHsgTmF2aWdhdGlvbkFuaW1hdG9yIH0gZnJvbSAnLi9OYXZpZ2F0aW9uQW5pbWF0b3InO1xuaW1wb3J0IHsgQ2FsZW5kYXJFdmVudHMgfSBmcm9tICcuL0NhbGVuZGFyRXZlbnRzJztcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckFwcCB7XG4gICAgY29uc3RydWN0b3Iob3JjaGVzdHJhdG9yLCB0aW1lQXhpc1JlbmRlcmVyLCBkYXRlU2VydmljZSwgc2Nyb2xsTWFuYWdlciwgaGVhZGVyRHJhd2VyTWFuYWdlciwgZHJhZ0Ryb3BNYW5hZ2VyLCBlZGdlU2Nyb2xsTWFuYWdlciwgcmVzaXplTWFuYWdlciwgaGVhZGVyRHJhd2VyUmVuZGVyZXIsIGV2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyLCBzZXR0aW5nc1NlcnZpY2UsIHZpZXdDb25maWdTZXJ2aWNlLCBldmVudEJ1cykge1xuICAgICAgICB0aGlzLm9yY2hlc3RyYXRvciA9IG9yY2hlc3RyYXRvcjtcbiAgICAgICAgdGhpcy50aW1lQXhpc1JlbmRlcmVyID0gdGltZUF4aXNSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLnNjcm9sbE1hbmFnZXIgPSBzY3JvbGxNYW5hZ2VyO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlck1hbmFnZXIgPSBoZWFkZXJEcmF3ZXJNYW5hZ2VyO1xuICAgICAgICB0aGlzLmRyYWdEcm9wTWFuYWdlciA9IGRyYWdEcm9wTWFuYWdlcjtcbiAgICAgICAgdGhpcy5lZGdlU2Nyb2xsTWFuYWdlciA9IGVkZ2VTY3JvbGxNYW5hZ2VyO1xuICAgICAgICB0aGlzLnJlc2l6ZU1hbmFnZXIgPSByZXNpemVNYW5hZ2VyO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlclJlbmRlcmVyID0gaGVhZGVyRHJhd2VyUmVuZGVyZXI7XG4gICAgICAgIHRoaXMuZXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIgPSBldmVudFBlcnNpc3RlbmNlTWFuYWdlcjtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1NlcnZpY2UgPSBzZXR0aW5nc1NlcnZpY2U7XG4gICAgICAgIHRoaXMudmlld0NvbmZpZ1NlcnZpY2UgPSB2aWV3Q29uZmlnU2VydmljZTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLndlZWtPZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLmN1cnJlbnRWaWV3SWQgPSAnc2ltcGxlJztcbiAgICAgICAgdGhpcy53b3Jrd2Vla1ByZXNldCA9IG51bGw7XG4gICAgICAgIHRoaXMuZ3JvdXBpbmdPdmVycmlkZXMgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIGFzeW5jIGluaXQoY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyO1xuICAgICAgICAvLyBMb2FkIHNldHRpbmdzXG4gICAgICAgIGNvbnN0IGdyaWRTZXR0aW5ncyA9IGF3YWl0IHRoaXMuc2V0dGluZ3NTZXJ2aWNlLmdldEdyaWRTZXR0aW5ncygpO1xuICAgICAgICBpZiAoIWdyaWRTZXR0aW5ncykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHcmlkU2V0dGluZ3Mgbm90IGZvdW5kJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53b3Jrd2Vla1ByZXNldCA9IGF3YWl0IHRoaXMuc2V0dGluZ3NTZXJ2aWNlLmdldERlZmF1bHRXb3Jrd2Vla1ByZXNldCgpO1xuICAgICAgICAvLyBDcmVhdGUgTmF2aWdhdGlvbkFuaW1hdG9yIHdpdGggRE9NIGVsZW1lbnRzXG4gICAgICAgIHRoaXMuYW5pbWF0b3IgPSBuZXcgTmF2aWdhdGlvbkFuaW1hdG9yKGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtaGVhZGVyLXRyYWNrJyksIGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtY29udGVudC10cmFjaycpKTtcbiAgICAgICAgLy8gUmVuZGVyIHRpbWUgYXhpcyBmcm9tIHNldHRpbmdzXG4gICAgICAgIHRoaXMudGltZUF4aXNSZW5kZXJlci5yZW5kZXIoY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJyN0aW1lLWF4aXMnKSwgZ3JpZFNldHRpbmdzLmRheVN0YXJ0SG91ciwgZ3JpZFNldHRpbmdzLmRheUVuZEhvdXIpO1xuICAgICAgICAvLyBJbml0IG1hbmFnZXJzXG4gICAgICAgIHRoaXMuc2Nyb2xsTWFuYWdlci5pbml0KGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5pbml0KGNvbnRhaW5lcik7XG4gICAgICAgIHRoaXMuZHJhZ0Ryb3BNYW5hZ2VyLmluaXQoY29udGFpbmVyKTtcbiAgICAgICAgdGhpcy5yZXNpemVNYW5hZ2VyLmluaXQoY29udGFpbmVyKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsYWJsZUNvbnRlbnQgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLXNjcm9sbGFibGUtY29udGVudCcpO1xuICAgICAgICB0aGlzLmVkZ2VTY3JvbGxNYW5hZ2VyLmluaXQoc2Nyb2xsYWJsZUNvbnRlbnQpO1xuICAgICAgICAvLyBTZXR1cCBjb21tYW5kIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICB0aGlzLnNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgICAgLy8gRW1pdCByZWFkeSBzdGF0dXNcbiAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdyZWFkeScpO1xuICAgIH1cbiAgICBzZXR1cEV2ZW50TGlzdGVuZXJzKCkge1xuICAgICAgICAvLyBOYXZpZ2F0aW9uIGNvbW1hbmRzIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9OQVZJR0FURV9QUkVWLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU5hdmlnYXRlUHJldigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDYWxlbmRhckV2ZW50cy5DTURfTkFWSUdBVEVfTkVYVCwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVOYXZpZ2F0ZU5leHQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIERyYXdlciB0b2dnbGUgdmlhIEV2ZW50QnVzXG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ2FsZW5kYXJFdmVudHMuQ01EX0RSQVdFUl9UT0dHTEUsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci50b2dnbGUoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJlbmRlciBjb21tYW5kIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9SRU5ERVIsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHZpZXdJZCB9ID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVJlbmRlckNvbW1hbmQodmlld0lkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFdvcmt3ZWVrIGNoYW5nZSB2aWEgRXZlbnRCdXNcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDYWxlbmRhckV2ZW50cy5DTURfV09SS1dFRUtfQ0hBTkdFLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBwcmVzZXRJZCB9ID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVdvcmt3ZWVrQ2hhbmdlKHByZXNldElkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFZpZXcgdXBkYXRlIHZpYSBFdmVudEJ1c1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENhbGVuZGFyRXZlbnRzLkNNRF9WSUVXX1VQREFURSwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdHlwZSwgdmFsdWVzIH0gPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlVmlld1VwZGF0ZSh0eXBlLCB2YWx1ZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXN5bmMgaGFuZGxlUmVuZGVyQ29tbWFuZCh2aWV3SWQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50Vmlld0lkID0gdmlld0lkO1xuICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcigpO1xuICAgICAgICB0aGlzLmVtaXRTdGF0dXMoJ3JlbmRlcmVkJywgeyB2aWV3SWQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGhhbmRsZU5hdmlnYXRlUHJldigpIHtcbiAgICAgICAgdGhpcy53ZWVrT2Zmc2V0LS07XG4gICAgICAgIGF3YWl0IHRoaXMuYW5pbWF0b3Iuc2xpZGUoJ3JpZ2h0JywgKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgICAgIHRoaXMuZW1pdFN0YXR1cygncmVuZGVyZWQnLCB7IHZpZXdJZDogdGhpcy5jdXJyZW50Vmlld0lkIH0pO1xuICAgIH1cbiAgICBhc3luYyBoYW5kbGVOYXZpZ2F0ZU5leHQoKSB7XG4gICAgICAgIHRoaXMud2Vla09mZnNldCsrO1xuICAgICAgICBhd2FpdCB0aGlzLmFuaW1hdG9yLnNsaWRlKCdsZWZ0JywgKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgICAgIHRoaXMuZW1pdFN0YXR1cygncmVuZGVyZWQnLCB7IHZpZXdJZDogdGhpcy5jdXJyZW50Vmlld0lkIH0pO1xuICAgIH1cbiAgICBhc3luYyBoYW5kbGVXb3Jrd2Vla0NoYW5nZShwcmVzZXRJZCkge1xuICAgICAgICBjb25zdCBwcmVzZXQgPSBhd2FpdCB0aGlzLnNldHRpbmdzU2VydmljZS5nZXRXb3Jrd2Vla1ByZXNldChwcmVzZXRJZCk7XG4gICAgICAgIGlmIChwcmVzZXQpIHtcbiAgICAgICAgICAgIHRoaXMud29ya3dlZWtQcmVzZXQgPSBwcmVzZXQ7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdyZW5kZXJlZCcsIHsgdmlld0lkOiB0aGlzLmN1cnJlbnRWaWV3SWQgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgaGFuZGxlVmlld1VwZGF0ZSh0eXBlLCB2YWx1ZXMpIHtcbiAgICAgICAgdGhpcy5ncm91cGluZ092ZXJyaWRlcy5zZXQodHlwZSwgdmFsdWVzKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgdGhpcy5lbWl0U3RhdHVzKCdyZW5kZXJlZCcsIHsgdmlld0lkOiB0aGlzLmN1cnJlbnRWaWV3SWQgfSk7XG4gICAgfVxuICAgIGFzeW5jIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3Qgc3RvcmVkQ29uZmlnID0gYXdhaXQgdGhpcy52aWV3Q29uZmlnU2VydmljZS5nZXRCeUlkKHRoaXMuY3VycmVudFZpZXdJZCk7XG4gICAgICAgIGlmICghc3RvcmVkQ29uZmlnKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXRTdGF0dXMoJ2Vycm9yJywgeyBtZXNzYWdlOiBgVmlld0NvbmZpZyBub3QgZm91bmQ6ICR7dGhpcy5jdXJyZW50Vmlld0lkfWAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gUG9wdWxhdGUgZGF0ZSB2YWx1ZXMgYmFzZWQgb24gd29ya3dlZWsgYW5kIG9mZnNldFxuICAgICAgICBjb25zdCB3b3JrRGF5cyA9IHRoaXMud29ya3dlZWtQcmVzZXQ/LndvcmtEYXlzIHx8IFsxLCAyLCAzLCA0LCA1XTtcbiAgICAgICAgY29uc3QgZGF0ZXMgPSB0aGlzLmN1cnJlbnRWaWV3SWQgPT09ICdkYXknXG4gICAgICAgICAgICA/IHRoaXMuZGF0ZVNlcnZpY2UuZ2V0V2Vla0RhdGVzKHRoaXMud2Vla09mZnNldCwgMSlcbiAgICAgICAgICAgIDogdGhpcy5kYXRlU2VydmljZS5nZXRXb3JrV2Vla0RhdGVzKHRoaXMud2Vla09mZnNldCwgd29ya0RheXMpO1xuICAgICAgICAvLyBDbG9uZSBjb25maWcgYW5kIGFwcGx5IG92ZXJyaWRlc1xuICAgICAgICBjb25zdCB2aWV3Q29uZmlnID0ge1xuICAgICAgICAgICAgLi4uc3RvcmVkQ29uZmlnLFxuICAgICAgICAgICAgZ3JvdXBpbmdzOiBzdG9yZWRDb25maWcuZ3JvdXBpbmdzLm1hcChnID0+IHtcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBkYXRlIHZhbHVlc1xuICAgICAgICAgICAgICAgIGlmIChnLnR5cGUgPT09ICdkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5nLCB2YWx1ZXM6IGRhdGVzIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IGdyb3VwaW5nIG92ZXJyaWRlc1xuICAgICAgICAgICAgICAgIGNvbnN0IG92ZXJyaWRlID0gdGhpcy5ncm91cGluZ092ZXJyaWRlcy5nZXQoZy50eXBlKTtcbiAgICAgICAgICAgICAgICBpZiAob3ZlcnJpZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uZywgdmFsdWVzOiBvdmVycmlkZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZztcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IHRoaXMub3JjaGVzdHJhdG9yLnJlbmRlcih2aWV3Q29uZmlnLCB0aGlzLmNvbnRhaW5lcik7XG4gICAgfVxuICAgIGVtaXRTdGF0dXMoc3RhdHVzLCBkZXRhaWwpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoYGNhbGVuZGFyOnN0YXR1czoke3N0YXR1c31gLCB7XG4gICAgICAgICAgICBkZXRhaWwsXG4gICAgICAgICAgICBidWJibGVzOiB0cnVlXG4gICAgICAgIH0pKTtcbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIFRpbWVBeGlzUmVuZGVyZXIge1xuICAgIHJlbmRlcihjb250YWluZXIsIHN0YXJ0SG91ciA9IDYsIGVuZEhvdXIgPSAyMCkge1xuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgIGZvciAobGV0IGhvdXIgPSBzdGFydEhvdXI7IGhvdXIgPD0gZW5kSG91cjsgaG91cisrKSB7XG4gICAgICAgICAgICBjb25zdCBtYXJrZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtaG91ci1tYXJrZXInKTtcbiAgICAgICAgICAgIG1hcmtlci50ZXh0Q29udGVudCA9IGAke2hvdXIudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpfTowMGA7XG4gICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgU2Nyb2xsTWFuYWdlciB7XG4gICAgaW5pdChjb250YWluZXIpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxhYmxlQ29udGVudCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3Atc2Nyb2xsYWJsZS1jb250ZW50Jyk7XG4gICAgICAgIHRoaXMudGltZUF4aXNDb250ZW50ID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC10aW1lLWF4aXMtY29udGVudCcpO1xuICAgICAgICB0aGlzLmNhbGVuZGFySGVhZGVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1jYWxlbmRhci1oZWFkZXInKTtcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci1kcmF3ZXInKTtcbiAgICAgICAgdGhpcy5oZWFkZXJWaWV3cG9ydCA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdzd3AtaGVhZGVyLXZpZXdwb3J0Jyk7XG4gICAgICAgIHRoaXMuaGVhZGVyU3BhY2VyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItc3BhY2VyJyk7XG4gICAgICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgKCkgPT4gdGhpcy5vblNjcm9sbCgpKTtcbiAgICAgICAgLy8gU3lua3JvbmlzZXIgaGVhZGVyLXNwYWNlciBoXHUwMEY4amRlIG1lZCBoZWFkZXItdmlld3BvcnRcbiAgICAgICAgdGhpcy5yZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB0aGlzLnN5bmNIZWFkZXJTcGFjZXJIZWlnaHQoKSk7XG4gICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmhlYWRlclZpZXdwb3J0KTtcbiAgICAgICAgdGhpcy5zeW5jSGVhZGVyU3BhY2VySGVpZ2h0KCk7XG4gICAgfVxuICAgIHN5bmNIZWFkZXJTcGFjZXJIZWlnaHQoKSB7XG4gICAgICAgIC8vIEtvcGllciBkZW4gZmFrdGlza2UgY29tcHV0ZWQgaGVpZ2h0IGRpcmVrdGUgZnJhIGhlYWRlci12aWV3cG9ydFxuICAgICAgICBjb25zdCBjb21wdXRlZEhlaWdodCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5oZWFkZXJWaWV3cG9ydCkuaGVpZ2h0O1xuICAgICAgICB0aGlzLmhlYWRlclNwYWNlci5zdHlsZS5oZWlnaHQgPSBjb21wdXRlZEhlaWdodDtcbiAgICB9XG4gICAgb25TY3JvbGwoKSB7XG4gICAgICAgIGNvbnN0IHsgc2Nyb2xsVG9wLCBzY3JvbGxMZWZ0IH0gPSB0aGlzLnNjcm9sbGFibGVDb250ZW50O1xuICAgICAgICAvLyBTeW5rcm9uaXNlciB0aW1lLWF4aXMgdmVydGlrYWx0XG4gICAgICAgIHRoaXMudGltZUF4aXNDb250ZW50LnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGVZKC0ke3Njcm9sbFRvcH1weClgO1xuICAgICAgICAvLyBTeW5rcm9uaXNlciBoZWFkZXIgb2cgZHJhd2VyIGhvcmlzb250YWx0XG4gICAgICAgIHRoaXMuY2FsZW5kYXJIZWFkZXIuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZVgoLSR7c2Nyb2xsTGVmdH1weClgO1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlci5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlWCgtJHtzY3JvbGxMZWZ0fXB4KWA7XG4gICAgfVxufVxuIiwgImV4cG9ydCBjbGFzcyBIZWFkZXJEcmF3ZXJNYW5hZ2VyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5leHBhbmRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRSb3dzID0gMDtcbiAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSAyNTtcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDIwMDtcbiAgICB9XG4gICAgaW5pdChjb250YWluZXIpIHtcbiAgICAgICAgdGhpcy5kcmF3ZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWhlYWRlci1kcmF3ZXInKTtcbiAgICAgICAgaWYgKCF0aGlzLmRyYXdlcilcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0hlYWRlckRyYXdlck1hbmFnZXI6IHN3cC1oZWFkZXItZHJhd2VyIG5vdCBmb3VuZCcpO1xuICAgIH1cbiAgICB0b2dnbGUoKSB7XG4gICAgICAgIHRoaXMuZXhwYW5kZWQgPyB0aGlzLmNvbGxhcHNlKCkgOiB0aGlzLmV4cGFuZCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeHBhbmQgZHJhd2VyIHRvIHNpbmdsZSByb3cgKGxlZ2FjeSBzdXBwb3J0KVxuICAgICAqL1xuICAgIGV4cGFuZCgpIHtcbiAgICAgICAgdGhpcy5leHBhbmRUb1Jvd3MoMSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4cGFuZCBkcmF3ZXIgdG8gZml0IHNwZWNpZmllZCBudW1iZXIgb2Ygcm93c1xuICAgICAqL1xuICAgIGV4cGFuZFRvUm93cyhyb3dDb3VudCkge1xuICAgICAgICBjb25zdCB0YXJnZXRIZWlnaHQgPSByb3dDb3VudCAqIHRoaXMucm93SGVpZ2h0O1xuICAgICAgICBjb25zdCBjdXJyZW50SGVpZ2h0ID0gdGhpcy5leHBhbmRlZCA/IHRoaXMuY3VycmVudFJvd3MgKiB0aGlzLnJvd0hlaWdodCA6IDA7XG4gICAgICAgIC8vIFNraXAgaWYgYWxyZWFkeSBhdCB0YXJnZXRcbiAgICAgICAgaWYgKHRoaXMuZXhwYW5kZWQgJiYgdGhpcy5jdXJyZW50Um93cyA9PT0gcm93Q291bnQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRoaXMuY3VycmVudFJvd3MgPSByb3dDb3VudDtcbiAgICAgICAgdGhpcy5leHBhbmRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuYW5pbWF0ZShjdXJyZW50SGVpZ2h0LCB0YXJnZXRIZWlnaHQpO1xuICAgIH1cbiAgICBjb2xsYXBzZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmV4cGFuZGVkKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCBjdXJyZW50SGVpZ2h0ID0gdGhpcy5jdXJyZW50Um93cyAqIHRoaXMucm93SGVpZ2h0O1xuICAgICAgICB0aGlzLmV4cGFuZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY3VycmVudFJvd3MgPSAwO1xuICAgICAgICB0aGlzLmFuaW1hdGUoY3VycmVudEhlaWdodCwgMCk7XG4gICAgfVxuICAgIGFuaW1hdGUoZnJvbSwgdG8pIHtcbiAgICAgICAgY29uc3Qga2V5ZnJhbWVzID0gW1xuICAgICAgICAgICAgeyBoZWlnaHQ6IGAke2Zyb219cHhgIH0sXG4gICAgICAgICAgICB7IGhlaWdodDogYCR7dG99cHhgIH1cbiAgICAgICAgXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uLFxuICAgICAgICAgICAgZWFzaW5nOiAnZWFzZScsXG4gICAgICAgICAgICBmaWxsOiAnZm9yd2FyZHMnXG4gICAgICAgIH07XG4gICAgICAgIC8vIEt1biBhbmltXHUwMEU5ciBkcmF3ZXIgLSBTY3JvbGxNYW5hZ2VyIHN5bmtyb25pc2VyZXIgaGVhZGVyLXNwYWNlciB2aWEgUmVzaXplT2JzZXJ2ZXJcbiAgICAgICAgdGhpcy5kcmF3ZXIuYW5pbWF0ZShrZXlmcmFtZXMsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBpc0V4cGFuZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5leHBhbmRlZDtcbiAgICB9XG4gICAgZ2V0Um93Q291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRSb3dzO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgTW9ja1RlYW1TdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICd0ZWFtJztcbiAgICAgICAgdGhpcy50ZWFtcyA9IFtcbiAgICAgICAgICAgIHsgaWQ6ICdhbHBoYScsIG5hbWU6ICdUZWFtIEFscGhhJyB9LFxuICAgICAgICAgICAgeyBpZDogJ2JldGEnLCBuYW1lOiAnVGVhbSBCZXRhJyB9XG4gICAgICAgIF07XG4gICAgfVxuICAgIGdldEJ5SWRzKGlkcykge1xuICAgICAgICByZXR1cm4gdGhpcy50ZWFtcy5maWx0ZXIodCA9PiBpZHMuaW5jbHVkZXModC5pZCkpO1xuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBNb2NrUmVzb3VyY2VTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyZXNvdXJjZSc7XG4gICAgICAgIHRoaXMucmVzb3VyY2VzID0gW1xuICAgICAgICAgICAgeyBpZDogJ2FsaWNlJywgbmFtZTogJ0FsaWNlJywgdGVhbUlkOiAnYWxwaGEnIH0sXG4gICAgICAgICAgICB7IGlkOiAnYm9iJywgbmFtZTogJ0JvYicsIHRlYW1JZDogJ2FscGhhJyB9LFxuICAgICAgICAgICAgeyBpZDogJ2Nhcm9sJywgbmFtZTogJ0Nhcm9sJywgdGVhbUlkOiAnYmV0YScgfSxcbiAgICAgICAgICAgIHsgaWQ6ICdkYXZlJywgbmFtZTogJ0RhdmUnLCB0ZWFtSWQ6ICdiZXRhJyB9XG4gICAgICAgIF07XG4gICAgfVxuICAgIGdldEJ5SWRzKGlkcykge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNvdXJjZXMuZmlsdGVyKHIgPT4gaWRzLmluY2x1ZGVzKHIuaWQpKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ2FsZW5kYXJFdmVudHMgfSBmcm9tICcuLi9jb3JlL0NhbGVuZGFyRXZlbnRzJztcbmV4cG9ydCBjbGFzcyBEZW1vQXBwIHtcbiAgICBjb25zdHJ1Y3RvcihpbmRleGVkREJDb250ZXh0LCBkYXRhU2VlZGVyLCBhdWRpdFNlcnZpY2UsIGNhbGVuZGFyQXBwLCBkYXRlU2VydmljZSwgcmVzb3VyY2VTZXJ2aWNlLCBldmVudEJ1cykge1xuICAgICAgICB0aGlzLmluZGV4ZWREQkNvbnRleHQgPSBpbmRleGVkREJDb250ZXh0O1xuICAgICAgICB0aGlzLmRhdGFTZWVkZXIgPSBkYXRhU2VlZGVyO1xuICAgICAgICB0aGlzLmF1ZGl0U2VydmljZSA9IGF1ZGl0U2VydmljZTtcbiAgICAgICAgdGhpcy5jYWxlbmRhckFwcCA9IGNhbGVuZGFyQXBwO1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMucmVzb3VyY2VTZXJ2aWNlID0gcmVzb3VyY2VTZXJ2aWNlO1xuICAgICAgICB0aGlzLmV2ZW50QnVzID0gZXZlbnRCdXM7XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXcgPSAnc2ltcGxlJztcbiAgICB9XG4gICAgYXN5bmMgaW5pdCgpIHtcbiAgICAgICAgLy8gU2V0IGJhc2UgZGF0ZSB0byBtYXRjaCBtb2NrIGRhdGEgKDguIGRlY2VtYmVyIDIwMjUgPSBtYW5kYWcpXG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2Uuc2V0QmFzZURhdGUobmV3IERhdGUoJzIwMjUtMTItMDgnKSk7XG4gICAgICAgIC8vIEluaXRpYWxpemUgSW5kZXhlZERCXG4gICAgICAgIGF3YWl0IHRoaXMuaW5kZXhlZERCQ29udGV4dC5pbml0aWFsaXplKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbRGVtb0FwcF0gSW5kZXhlZERCIGluaXRpYWxpemVkJyk7XG4gICAgICAgIC8vIFNlZWQgZGF0YSBpZiBlbXB0eVxuICAgICAgICBhd2FpdCB0aGlzLmRhdGFTZWVkZXIuc2VlZElmRW1wdHkoKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1tEZW1vQXBwXSBEYXRhIHNlZWRpbmcgY29tcGxldGUnKTtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtY2FsZW5kYXItY29udGFpbmVyJyk7XG4gICAgICAgIC8vIEluaXRpYWxpemUgQ2FsZW5kYXJBcHBcbiAgICAgICAgYXdhaXQgdGhpcy5jYWxlbmRhckFwcC5pbml0KHRoaXMuY29udGFpbmVyKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1tEZW1vQXBwXSBDYWxlbmRhckFwcCBpbml0aWFsaXplZCcpO1xuICAgICAgICAvLyBTZXR1cCBkZW1vIFVJIGhhbmRsZXJzXG4gICAgICAgIHRoaXMuc2V0dXBOYXZpZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuc2V0dXBEcmF3ZXJUb2dnbGUoKTtcbiAgICAgICAgdGhpcy5zZXR1cFZpZXdTd2l0Y2hpbmcoKTtcbiAgICAgICAgdGhpcy5zZXR1cFdvcmt3ZWVrU2VsZWN0b3IoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5zZXR1cFJlc291cmNlU2VsZWN0b3IoKTtcbiAgICAgICAgLy8gTGlzdGVuIGZvciBjYWxlbmRhciBzdGF0dXMgZXZlbnRzXG4gICAgICAgIHRoaXMuc2V0dXBTdGF0dXNMaXN0ZW5lcnMoKTtcbiAgICAgICAgLy8gSW5pdGlhbCByZW5kZXJcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENhbGVuZGFyRXZlbnRzLkNNRF9SRU5ERVIsIHsgdmlld0lkOiB0aGlzLmN1cnJlbnRWaWV3IH0pO1xuICAgIH1cbiAgICBzZXR1cE5hdmlnYXRpb24oKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdidG4tcHJldicpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ2FsZW5kYXJFdmVudHMuQ01EX05BVklHQVRFX1BSRVYpO1xuICAgICAgICB9O1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLW5leHQnKS5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENhbGVuZGFyRXZlbnRzLkNNRF9OQVZJR0FURV9ORVhUKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgc2V0dXBWaWV3U3dpdGNoaW5nKCkge1xuICAgICAgICBjb25zdCBjaGlwcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy52aWV3LWNoaXAnKTtcbiAgICAgICAgY2hpcHMuZm9yRWFjaChjaGlwID0+IHtcbiAgICAgICAgICAgIGNoaXAuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2hpcHMuZm9yRWFjaChjID0+IGMuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuICAgICAgICAgICAgICAgIGNoaXAuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmlldyA9IGNoaXAuZGF0YXNldC52aWV3O1xuICAgICAgICAgICAgICAgIGlmICh2aWV3KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXcgPSB2aWV3O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVNlbGVjdG9yVmlzaWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ2FsZW5kYXJFdmVudHMuQ01EX1JFTkRFUiwgeyB2aWV3SWQ6IHZpZXcgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB1cGRhdGVTZWxlY3RvclZpc2liaWxpdHkoKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdG9yID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLXJlc291cmNlLXNlbGVjdG9yJyk7XG4gICAgICAgIGNvbnN0IHNob3dTZWxlY3RvciA9IHRoaXMuY3VycmVudFZpZXcgPT09ICdwaWNrZXInIHx8IHRoaXMuY3VycmVudFZpZXcgPT09ICdkYXknO1xuICAgICAgICBzZWxlY3Rvcj8uY2xhc3NMaXN0LnRvZ2dsZSgnaGlkZGVuJywgIXNob3dTZWxlY3Rvcik7XG4gICAgfVxuICAgIHNldHVwRHJhd2VyVG9nZ2xlKCkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYnRuLWRyYXdlcicpLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ2FsZW5kYXJFdmVudHMuQ01EX0RSQVdFUl9UT0dHTEUpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBzZXR1cFdvcmt3ZWVrU2VsZWN0b3IoKSB7XG4gICAgICAgIGNvbnN0IHdvcmt3ZWVrU2VsZWN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3dvcmt3ZWVrLXNlbGVjdCcpO1xuICAgICAgICB3b3Jrd2Vla1NlbGVjdD8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJlc2V0SWQgPSB3b3Jrd2Vla1NlbGVjdC52YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDYWxlbmRhckV2ZW50cy5DTURfV09SS1dFRUtfQ0hBTkdFLCB7IHByZXNldElkIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXN5bmMgc2V0dXBSZXNvdXJjZVNlbGVjdG9yKCkge1xuICAgICAgICBjb25zdCByZXNvdXJjZXMgPSBhd2FpdCB0aGlzLnJlc291cmNlU2VydmljZS5nZXRBbGwoKTtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnJlc291cmNlLWNoZWNrYm94ZXMnKTtcbiAgICAgICAgaWYgKCFjb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgcmVzb3VyY2VzLmZvckVhY2gociA9PiB7XG4gICAgICAgICAgICBjb25zdCBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgICAgICAgICBsYWJlbC5pbm5lckhUTUwgPSBgXHJcbiAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIHZhbHVlPVwiJHtyLmlkfVwiIGNoZWNrZWQ+XHJcbiAgICAgICAgJHtyLmRpc3BsYXlOYW1lfVxyXG4gICAgICBgO1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjaGVja2VkID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0OmNoZWNrZWQnKTtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmZyb20oY2hlY2tlZCkubWFwKGNiID0+IGNiLnZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDYWxlbmRhckV2ZW50cy5DTURfVklFV19VUERBVEUsIHsgdHlwZTogJ3Jlc291cmNlJywgdmFsdWVzIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0dXBTdGF0dXNMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbGVuZGFyOnN0YXR1czpyZWFkeScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbRGVtb0FwcF0gQ2FsZW5kYXIgcmVhZHknKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbGVuZGFyOnN0YXR1czpyZW5kZXJlZCcsICgoZSkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tEZW1vQXBwXSBDYWxlbmRhciByZW5kZXJlZDonLCBlLmRldGFpbC52aWV3SWQpO1xuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbGVuZGFyOnN0YXR1czplcnJvcicsICgoZSkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignW0RlbW9BcHBdIENhbGVuZGFyIGVycm9yOicsIGUuZGV0YWlsLm1lc3NhZ2UpO1xuICAgICAgICB9KSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ2VudHJhbCBldmVudCBkaXNwYXRjaGVyIGZvciBjYWxlbmRhciB1c2luZyBET00gQ3VzdG9tRXZlbnRzXG4gKiBQcm92aWRlcyBsb2dnaW5nIGFuZCBkZWJ1Z2dpbmcgY2FwYWJpbGl0aWVzXG4gKi9cbmV4cG9ydCBjbGFzcyBFdmVudEJ1cyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRMb2cgPSBbXTtcbiAgICAgICAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IG5ldyBTZXQoKTtcbiAgICAgICAgLy8gTG9nIGNvbmZpZ3VyYXRpb24gZm9yIGRpZmZlcmVudCBjYXRlZ29yaWVzXG4gICAgICAgIHRoaXMubG9nQ29uZmlnID0ge1xuICAgICAgICAgICAgY2FsZW5kYXI6IHRydWUsXG4gICAgICAgICAgICBncmlkOiB0cnVlLFxuICAgICAgICAgICAgZXZlbnQ6IHRydWUsXG4gICAgICAgICAgICBzY3JvbGw6IHRydWUsXG4gICAgICAgICAgICBuYXZpZ2F0aW9uOiB0cnVlLFxuICAgICAgICAgICAgdmlldzogdHJ1ZSxcbiAgICAgICAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIHRvIGFuIGV2ZW50IHZpYSBET00gYWRkRXZlbnRMaXN0ZW5lclxuICAgICAqL1xuICAgIG9uKGV2ZW50VHlwZSwgaGFuZGxlciwgb3B0aW9ucykge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgaGFuZGxlciwgb3B0aW9ucyk7XG4gICAgICAgIC8vIFRyYWNrIGZvciBjbGVhbnVwXG4gICAgICAgIHRoaXMubGlzdGVuZXJzLmFkZCh7IGV2ZW50VHlwZSwgaGFuZGxlciwgb3B0aW9ucyB9KTtcbiAgICAgICAgLy8gUmV0dXJuIHVuc3Vic2NyaWJlIGZ1bmN0aW9uXG4gICAgICAgIHJldHVybiAoKSA9PiB0aGlzLm9mZihldmVudFR5cGUsIGhhbmRsZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gYW4gZXZlbnQgb25jZVxuICAgICAqL1xuICAgIG9uY2UoZXZlbnRUeXBlLCBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50VHlwZSwgaGFuZGxlciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN1YnNjcmliZSBmcm9tIGFuIGV2ZW50XG4gICAgICovXG4gICAgb2ZmKGV2ZW50VHlwZSwgaGFuZGxlcikge1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgaGFuZGxlcik7XG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIHRyYWNraW5nXG4gICAgICAgIGZvciAoY29uc3QgbGlzdGVuZXIgb2YgdGhpcy5saXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lci5ldmVudFR5cGUgPT09IGV2ZW50VHlwZSAmJiBsaXN0ZW5lci5oYW5kbGVyID09PSBoYW5kbGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZGVsZXRlKGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbWl0IGFuIGV2ZW50IHZpYSBET00gQ3VzdG9tRXZlbnRcbiAgICAgKi9cbiAgICBlbWl0KGV2ZW50VHlwZSwgZGV0YWlsID0ge30pIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgZXZlbnRUeXBlXG4gICAgICAgIGlmICghZXZlbnRUeXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoZXZlbnRUeXBlLCB7XG4gICAgICAgICAgICBkZXRhaWw6IGRldGFpbCA/PyB7fSxcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBMb2cgZXZlbnQgd2l0aCBncm91cGluZ1xuICAgICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICAgICAgdGhpcy5sb2dFdmVudFdpdGhHcm91cGluZyhldmVudFR5cGUsIGRldGFpbCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudExvZy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6IGV2ZW50VHlwZSxcbiAgICAgICAgICAgIGRldGFpbDogZGV0YWlsID8/IHt9LFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBFbWl0IG9uIGRvY3VtZW50IChvbmx5IERPTSBldmVudHMgbm93KVxuICAgICAgICByZXR1cm4gIWRvY3VtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2cgZXZlbnQgd2l0aCBjb25zb2xlIGdyb3VwaW5nXG4gICAgICovXG4gICAgbG9nRXZlbnRXaXRoR3JvdXBpbmcoZXZlbnRUeXBlLCBfZGV0YWlsKSB7XG4gICAgICAgIC8vIEV4dHJhY3QgY2F0ZWdvcnkgZnJvbSBldmVudCB0eXBlIChlLmcuLCAnY2FsZW5kYXI6ZGF0ZWNoYW5nZWQnIFx1MjE5MiAnY2FsZW5kYXInKVxuICAgICAgICBjb25zdCBjYXRlZ29yeSA9IHRoaXMuZXh0cmFjdENhdGVnb3J5KGV2ZW50VHlwZSk7XG4gICAgICAgIC8vIE9ubHkgbG9nIGlmIGNhdGVnb3J5IGlzIGVuYWJsZWRcbiAgICAgICAgaWYgKCF0aGlzLmxvZ0NvbmZpZ1tjYXRlZ29yeV0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBHZXQgY2F0ZWdvcnkgZW1vamkgYW5kIGNvbG9yICh1c2VkIGZvciBmdXR1cmUgY29uc29sZSBzdHlsaW5nKVxuICAgICAgICB0aGlzLmdldENhdGVnb3J5U3R5bGUoY2F0ZWdvcnkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IGNhdGVnb3J5IGZyb20gZXZlbnQgdHlwZVxuICAgICAqL1xuICAgIGV4dHJhY3RDYXRlZ29yeShldmVudFR5cGUpIHtcbiAgICAgICAgaWYgKCFldmVudFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiAndW5rbm93bic7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50VHlwZS5pbmNsdWRlcygnOicpKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRUeXBlLnNwbGl0KCc6JylbMF07XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmFsbGJhY2s6IHRyeSB0byBkZXRlY3QgY2F0ZWdvcnkgZnJvbSBldmVudCBuYW1lIHBhdHRlcm5zXG4gICAgICAgIGNvbnN0IGxvd2VyVHlwZSA9IGV2ZW50VHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAobG93ZXJUeXBlLmluY2x1ZGVzKCdncmlkJykgfHwgbG93ZXJUeXBlLmluY2x1ZGVzKCdyZW5kZXJlZCcpKVxuICAgICAgICAgICAgcmV0dXJuICdncmlkJztcbiAgICAgICAgaWYgKGxvd2VyVHlwZS5pbmNsdWRlcygnZXZlbnQnKSB8fCBsb3dlclR5cGUuaW5jbHVkZXMoJ3N5bmMnKSlcbiAgICAgICAgICAgIHJldHVybiAnZXZlbnQnO1xuICAgICAgICBpZiAobG93ZXJUeXBlLmluY2x1ZGVzKCdzY3JvbGwnKSlcbiAgICAgICAgICAgIHJldHVybiAnc2Nyb2xsJztcbiAgICAgICAgaWYgKGxvd2VyVHlwZS5pbmNsdWRlcygnbmF2JykgfHwgbG93ZXJUeXBlLmluY2x1ZGVzKCdkYXRlJykpXG4gICAgICAgICAgICByZXR1cm4gJ25hdmlnYXRpb24nO1xuICAgICAgICBpZiAobG93ZXJUeXBlLmluY2x1ZGVzKCd2aWV3JykpXG4gICAgICAgICAgICByZXR1cm4gJ3ZpZXcnO1xuICAgICAgICByZXR1cm4gJ2RlZmF1bHQnO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgc3R5bGluZyBmb3IgZGlmZmVyZW50IGNhdGVnb3JpZXNcbiAgICAgKi9cbiAgICBnZXRDYXRlZ29yeVN0eWxlKGNhdGVnb3J5KSB7XG4gICAgICAgIGNvbnN0IHN0eWxlcyA9IHtcbiAgICAgICAgICAgIGNhbGVuZGFyOiB7IGVtb2ppOiAnXHVEODNEXHVEQ0M1JywgY29sb3I6ICcjMjE5NkYzJyB9LFxuICAgICAgICAgICAgZ3JpZDogeyBlbW9qaTogJ1x1RDgzRFx1RENDQScsIGNvbG9yOiAnIzRDQUY1MCcgfSxcbiAgICAgICAgICAgIGV2ZW50OiB7IGVtb2ppOiAnXHVEODNEXHVEQ0NDJywgY29sb3I6ICcjRkY5ODAwJyB9LFxuICAgICAgICAgICAgc2Nyb2xsOiB7IGVtb2ppOiAnXHVEODNEXHVEQ0RDJywgY29sb3I6ICcjOUMyN0IwJyB9LFxuICAgICAgICAgICAgbmF2aWdhdGlvbjogeyBlbW9qaTogJ1x1RDgzRVx1RERFRCcsIGNvbG9yOiAnI0Y0NDMzNicgfSxcbiAgICAgICAgICAgIHZpZXc6IHsgZW1vamk6ICdcdUQ4M0RcdURDNDEnLCBjb2xvcjogJyMwMEJDRDQnIH0sXG4gICAgICAgICAgICBkZWZhdWx0OiB7IGVtb2ppOiAnXHVEODNEXHVEQ0UyJywgY29sb3I6ICcjNjA3RDhCJyB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBzdHlsZXNbY2F0ZWdvcnldIHx8IHN0eWxlcy5kZWZhdWx0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25maWd1cmUgbG9nZ2luZyBmb3Igc3BlY2lmaWMgY2F0ZWdvcmllc1xuICAgICAqL1xuICAgIHNldExvZ0NvbmZpZyhjb25maWcpIHtcbiAgICAgICAgdGhpcy5sb2dDb25maWcgPSB7IC4uLnRoaXMubG9nQ29uZmlnLCAuLi5jb25maWcgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnQgbG9nIGNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICBnZXRMb2dDb25maWcoKSB7XG4gICAgICAgIHJldHVybiB7IC4uLnRoaXMubG9nQ29uZmlnIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBldmVudCBoaXN0b3J5XG4gICAgICovXG4gICAgZ2V0RXZlbnRMb2coZXZlbnRUeXBlKSB7XG4gICAgICAgIGlmIChldmVudFR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50TG9nLmZpbHRlcihlID0+IGUudHlwZSA9PT0gZXZlbnRUeXBlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5ldmVudExvZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5hYmxlL2Rpc2FibGUgZGVidWcgbW9kZVxuICAgICAqL1xuICAgIHNldERlYnVnKGVuYWJsZWQpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZyA9IGVuYWJsZWQ7XG4gICAgfVxufVxuIiwgIi8qKlxuICogSW5kZXhlZERCQ29udGV4dCAtIERhdGFiYXNlIGNvbm5lY3Rpb24gbWFuYWdlclxuICpcbiAqIFJFU1BPTlNJQklMSVRZOlxuICogLSBPcGVucyBhbmQgbWFuYWdlcyBJREJEYXRhYmFzZSBjb25uZWN0aW9uIGxpZmVjeWNsZVxuICogLSBDcmVhdGVzIG9iamVjdCBzdG9yZXMgdmlhIGluamVjdGVkIElTdG9yZSBpbXBsZW1lbnRhdGlvbnNcbiAqIC0gUHJvdmlkZXMgc2hhcmVkIElEQkRhdGFiYXNlIGluc3RhbmNlIHRvIGFsbCBzZXJ2aWNlc1xuICovXG5leHBvcnQgY2xhc3MgSW5kZXhlZERCQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3Ioc3RvcmVzKSB7XG4gICAgICAgIHRoaXMuZGIgPSBudWxsO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RvcmVzID0gc3RvcmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGFuZCBvcGVuIHRoZSBkYXRhYmFzZVxuICAgICAqL1xuICAgIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLm9wZW4oSW5kZXhlZERCQ29udGV4dC5EQl9OQU1FLCBJbmRleGVkREJDb250ZXh0LkRCX1ZFUlNJT04pO1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBvcGVuIEluZGV4ZWREQjogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRiID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub251cGdyYWRlbmVlZGVkID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhbGwgZW50aXR5IHN0b3JlcyB2aWEgaW5qZWN0ZWQgSVN0b3JlIGltcGxlbWVudGF0aW9uc1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmVzLmZvckVhY2goc3RvcmUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoc3RvcmUuc3RvcmVOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmUuY3JlYXRlKGRiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGRhdGFiYXNlIGlzIGluaXRpYWxpemVkXG4gICAgICovXG4gICAgaXNJbml0aWFsaXplZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBJREJEYXRhYmFzZSBpbnN0YW5jZVxuICAgICAqL1xuICAgIGdldERhdGFiYXNlKCkge1xuICAgICAgICBpZiAoIXRoaXMuZGIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW5kZXhlZERCIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0aWFsaXplKCkgZmlyc3QuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZGI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIGRhdGFiYXNlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGIpIHtcbiAgICAgICAgICAgIHRoaXMuZGIuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMuZGIgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBlbnRpcmUgZGF0YWJhc2UgKGZvciB0ZXN0aW5nL3Jlc2V0KVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBkZWxldGVEYXRhYmFzZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleGVkREIuZGVsZXRlRGF0YWJhc2UoSW5kZXhlZERCQ29udGV4dC5EQl9OQU1FKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBkYXRhYmFzZTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuSW5kZXhlZERCQ29udGV4dC5EQl9OQU1FID0gJ0NhbGVuZGFyVjJEQic7XG5JbmRleGVkREJDb250ZXh0LkRCX1ZFUlNJT04gPSA0O1xuIiwgIi8qKlxuICogRXZlbnRTdG9yZSAtIEluZGV4ZWREQiBPYmplY3RTdG9yZSBkZWZpbml0aW9uIGZvciBjYWxlbmRhciBldmVudHNcbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50U3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IEV2ZW50U3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRoZSBldmVudHMgT2JqZWN0U3RvcmUgd2l0aCBpbmRleGVzXG4gICAgICovXG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUoRXZlbnRTdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgICAgIC8vIEluZGV4OiBzdGFydCAoZm9yIGRhdGUgcmFuZ2UgcXVlcmllcylcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N0YXJ0JywgJ3N0YXJ0JywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICAvLyBJbmRleDogZW5kIChmb3IgZGF0ZSByYW5nZSBxdWVyaWVzKVxuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnZW5kJywgJ2VuZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgLy8gSW5kZXg6IHN5bmNTdGF0dXMgKGZvciBmaWx0ZXJpbmcgYnkgc3luYyBzdGF0ZSlcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N5bmNTdGF0dXMnLCAnc3luY1N0YXR1cycsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgLy8gSW5kZXg6IHJlc291cmNlSWQgKGZvciByZXNvdXJjZS1tb2RlIGZpbHRlcmluZylcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3Jlc291cmNlSWQnLCAncmVzb3VyY2VJZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgLy8gSW5kZXg6IGN1c3RvbWVySWQgKGZvciBjdXN0b21lci1jZW50cmljIHF1ZXJpZXMpXG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdjdXN0b21lcklkJywgJ2N1c3RvbWVySWQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIC8vIEluZGV4OiBib29raW5nSWQgKGZvciBldmVudC10by1ib29raW5nIGxvb2t1cHMpXG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdib29raW5nSWQnLCAnYm9va2luZ0lkJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICAvLyBDb21wb3VuZCBpbmRleDogc3RhcnRFbmQgKGZvciBvcHRpbWl6ZWQgcmFuZ2UgcXVlcmllcylcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N0YXJ0RW5kJywgWydzdGFydCcsICdlbmQnXSwgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgIH1cbn1cbkV2ZW50U3RvcmUuU1RPUkVfTkFNRSA9ICdldmVudHMnO1xuIiwgIi8qKlxuICogRXZlbnRTZXJpYWxpemF0aW9uIC0gSGFuZGxlcyBEYXRlIGZpZWxkIHNlcmlhbGl6YXRpb24gZm9yIEluZGV4ZWREQlxuICpcbiAqIEluZGV4ZWREQiBkb2Vzbid0IHN0b3JlIERhdGUgb2JqZWN0cyBkaXJlY3RseSwgc28gd2UgY29udmVydDpcbiAqIC0gRGF0ZSBcdTIxOTIgSVNPIHN0cmluZyAoc2VyaWFsaXplKSB3aGVuIHdyaXRpbmdcbiAqIC0gSVNPIHN0cmluZyBcdTIxOTIgRGF0ZSAoZGVzZXJpYWxpemUpIHdoZW4gcmVhZGluZ1xuICovXG5leHBvcnQgY2xhc3MgRXZlbnRTZXJpYWxpemF0aW9uIHtcbiAgICAvKipcbiAgICAgKiBTZXJpYWxpemUgZXZlbnQgZm9yIEluZGV4ZWREQiBzdG9yYWdlXG4gICAgICovXG4gICAgc3RhdGljIHNlcmlhbGl6ZShldmVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICBzdGFydDogZXZlbnQuc3RhcnQgaW5zdGFuY2VvZiBEYXRlID8gZXZlbnQuc3RhcnQudG9JU09TdHJpbmcoKSA6IGV2ZW50LnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBldmVudC5lbmQgaW5zdGFuY2VvZiBEYXRlID8gZXZlbnQuZW5kLnRvSVNPU3RyaW5nKCkgOiBldmVudC5lbmRcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzZXJpYWxpemUgZXZlbnQgZnJvbSBJbmRleGVkREIgc3RvcmFnZVxuICAgICAqL1xuICAgIHN0YXRpYyBkZXNlcmlhbGl6ZShkYXRhKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICAgICAgc3RhcnQ6IHR5cGVvZiBkYXRhLnN0YXJ0ID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKGRhdGEuc3RhcnQpIDogZGF0YS5zdGFydCxcbiAgICAgICAgICAgIGVuZDogdHlwZW9mIGRhdGEuZW5kID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKGRhdGEuZW5kKSA6IGRhdGEuZW5kXG4gICAgICAgIH07XG4gICAgfVxufVxuIiwgIi8qKlxuICogU3luY1BsdWdpbjxUIGV4dGVuZHMgSVN5bmM+IC0gUGx1Z2dhYmxlIHN5bmMgZnVuY3Rpb25hbGl0eSBmb3IgZW50aXR5IHNlcnZpY2VzXG4gKlxuICogQ09NUE9TSVRJT04gUEFUVEVSTjpcbiAqIC0gRW5jYXBzdWxhdGVzIGFsbCBzeW5jLXJlbGF0ZWQgbG9naWMgaW4gc2VwYXJhdGUgY2xhc3NcbiAqIC0gQ29tcG9zZWQgaW50byBCYXNlRW50aXR5U2VydmljZSAobm90IGluaGVyaXRhbmNlKVxuICovXG5leHBvcnQgY2xhc3MgU3luY1BsdWdpbiB7XG4gICAgY29uc3RydWN0b3Ioc2VydmljZSkge1xuICAgICAgICB0aGlzLnNlcnZpY2UgPSBzZXJ2aWNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYXJrIGVudGl0eSBhcyBzdWNjZXNzZnVsbHkgc3luY2VkXG4gICAgICovXG4gICAgYXN5bmMgbWFya0FzU3luY2VkKGlkKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IGF3YWl0IHRoaXMuc2VydmljZS5nZXQoaWQpO1xuICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICBlbnRpdHkuc3luY1N0YXR1cyA9ICdzeW5jZWQnO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXJ2aWNlLnNhdmUoZW50aXR5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYXJrIGVudGl0eSBhcyBzeW5jIGVycm9yXG4gICAgICovXG4gICAgYXN5bmMgbWFya0FzRXJyb3IoaWQpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gYXdhaXQgdGhpcy5zZXJ2aWNlLmdldChpZCk7XG4gICAgICAgIGlmIChlbnRpdHkpIHtcbiAgICAgICAgICAgIGVudGl0eS5zeW5jU3RhdHVzID0gJ2Vycm9yJztcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VydmljZS5zYXZlKGVudGl0eSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnQgc3luYyBzdGF0dXMgZm9yIGFuIGVudGl0eVxuICAgICAqL1xuICAgIGFzeW5jIGdldFN5bmNTdGF0dXMoaWQpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gYXdhaXQgdGhpcy5zZXJ2aWNlLmdldChpZCk7XG4gICAgICAgIHJldHVybiBlbnRpdHkgPyBlbnRpdHkuc3luY1N0YXR1cyA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBlbnRpdGllcyBieSBzeW5jIHN0YXR1cyB1c2luZyBJbmRleGVkREIgaW5kZXhcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVN5bmNTdGF0dXMoc3luY1N0YXR1cykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLnNlcnZpY2UuZGIudHJhbnNhY3Rpb24oW3RoaXMuc2VydmljZS5zdG9yZU5hbWVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zZXJ2aWNlLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdzeW5jU3RhdHVzJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKHN5bmNTdGF0dXMpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0aWVzID0gZGF0YS5tYXAoaXRlbSA9PiB0aGlzLnNlcnZpY2UuZGVzZXJpYWxpemUoaXRlbSkpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoZW50aXRpZXMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGJ5IHN5bmMgc3RhdHVzICR7c3luY1N0YXR1c306ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDb3JlRXZlbnRzIC0gQ29uc29saWRhdGVkIGVzc2VudGlhbCBldmVudHMgZm9yIHRoZSBjYWxlbmRhciBWMlxuICovXG5leHBvcnQgY29uc3QgQ29yZUV2ZW50cyA9IHtcbiAgICAvLyBMaWZlY3ljbGUgZXZlbnRzXG4gICAgSU5JVElBTElaRUQ6ICdjb3JlOmluaXRpYWxpemVkJyxcbiAgICBSRUFEWTogJ2NvcmU6cmVhZHknLFxuICAgIERFU1RST1lFRDogJ2NvcmU6ZGVzdHJveWVkJyxcbiAgICAvLyBWaWV3IGV2ZW50c1xuICAgIFZJRVdfQ0hBTkdFRDogJ3ZpZXc6Y2hhbmdlZCcsXG4gICAgVklFV19SRU5ERVJFRDogJ3ZpZXc6cmVuZGVyZWQnLFxuICAgIC8vIE5hdmlnYXRpb24gZXZlbnRzXG4gICAgREFURV9DSEFOR0VEOiAnbmF2OmRhdGUtY2hhbmdlZCcsXG4gICAgTkFWSUdBVElPTl9DT01QTEVURUQ6ICduYXY6bmF2aWdhdGlvbi1jb21wbGV0ZWQnLFxuICAgIC8vIERhdGEgZXZlbnRzXG4gICAgREFUQV9MT0FESU5HOiAnZGF0YTpsb2FkaW5nJyxcbiAgICBEQVRBX0xPQURFRDogJ2RhdGE6bG9hZGVkJyxcbiAgICBEQVRBX0VSUk9SOiAnZGF0YTplcnJvcicsXG4gICAgLy8gR3JpZCBldmVudHNcbiAgICBHUklEX1JFTkRFUkVEOiAnZ3JpZDpyZW5kZXJlZCcsXG4gICAgR1JJRF9DTElDS0VEOiAnZ3JpZDpjbGlja2VkJyxcbiAgICAvLyBFdmVudCBtYW5hZ2VtZW50XG4gICAgRVZFTlRfQ1JFQVRFRDogJ2V2ZW50OmNyZWF0ZWQnLFxuICAgIEVWRU5UX1VQREFURUQ6ICdldmVudDp1cGRhdGVkJyxcbiAgICBFVkVOVF9ERUxFVEVEOiAnZXZlbnQ6ZGVsZXRlZCcsXG4gICAgRVZFTlRfU0VMRUNURUQ6ICdldmVudDpzZWxlY3RlZCcsXG4gICAgLy8gRXZlbnQgZHJhZy1kcm9wXG4gICAgRVZFTlRfRFJBR19TVEFSVDogJ2V2ZW50OmRyYWctc3RhcnQnLFxuICAgIEVWRU5UX0RSQUdfTU9WRTogJ2V2ZW50OmRyYWctbW92ZScsXG4gICAgRVZFTlRfRFJBR19FTkQ6ICdldmVudDpkcmFnLWVuZCcsXG4gICAgRVZFTlRfRFJBR19DQU5DRUw6ICdldmVudDpkcmFnLWNhbmNlbCcsXG4gICAgRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFOiAnZXZlbnQ6ZHJhZy1jb2x1bW4tY2hhbmdlJyxcbiAgICAvLyBIZWFkZXIgZHJhZyAodGltZWQgXHUyMTkyIGhlYWRlciBjb252ZXJzaW9uKVxuICAgIEVWRU5UX0RSQUdfRU5URVJfSEVBREVSOiAnZXZlbnQ6ZHJhZy1lbnRlci1oZWFkZXInLFxuICAgIEVWRU5UX0RSQUdfTU9WRV9IRUFERVI6ICdldmVudDpkcmFnLW1vdmUtaGVhZGVyJyxcbiAgICBFVkVOVF9EUkFHX0xFQVZFX0hFQURFUjogJ2V2ZW50OmRyYWctbGVhdmUtaGVhZGVyJyxcbiAgICAvLyBFdmVudCByZXNpemVcbiAgICBFVkVOVF9SRVNJWkVfU1RBUlQ6ICdldmVudDpyZXNpemUtc3RhcnQnLFxuICAgIEVWRU5UX1JFU0laRV9FTkQ6ICdldmVudDpyZXNpemUtZW5kJyxcbiAgICAvLyBFZGdlIHNjcm9sbFxuICAgIEVER0VfU0NST0xMX1RJQ0s6ICdlZGdlLXNjcm9sbDp0aWNrJyxcbiAgICBFREdFX1NDUk9MTF9TVEFSVEVEOiAnZWRnZS1zY3JvbGw6c3RhcnRlZCcsXG4gICAgRURHRV9TQ1JPTExfU1RPUFBFRDogJ2VkZ2Utc2Nyb2xsOnN0b3BwZWQnLFxuICAgIC8vIFN5c3RlbSBldmVudHNcbiAgICBFUlJPUjogJ3N5c3RlbTplcnJvcicsXG4gICAgLy8gU3luYyBldmVudHNcbiAgICBTWU5DX1NUQVJURUQ6ICdzeW5jOnN0YXJ0ZWQnLFxuICAgIFNZTkNfQ09NUExFVEVEOiAnc3luYzpjb21wbGV0ZWQnLFxuICAgIFNZTkNfRkFJTEVEOiAnc3luYzpmYWlsZWQnLFxuICAgIC8vIEVudGl0eSBldmVudHMgLSBmb3IgYXVkaXQgYW5kIHN5bmNcbiAgICBFTlRJVFlfU0FWRUQ6ICdlbnRpdHk6c2F2ZWQnLFxuICAgIEVOVElUWV9ERUxFVEVEOiAnZW50aXR5OmRlbGV0ZWQnLFxuICAgIC8vIEF1ZGl0IGV2ZW50c1xuICAgIEFVRElUX0xPR0dFRDogJ2F1ZGl0OmxvZ2dlZCcsXG4gICAgLy8gUmVuZGVyaW5nIGV2ZW50c1xuICAgIEVWRU5UU19SRU5ERVJFRDogJ2V2ZW50czpyZW5kZXJlZCdcbn07XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIHNwbGl0SlNPTlBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBjdXJyZW50UGFydCA9ICcnO1xuICAgIGxldCBpblNpbmdsZVF1b3RlcyA9IGZhbHNlO1xuICAgIGxldCBpbkJyYWNrZXRzID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaGFyID0gcGF0aFtpXTtcblxuICAgICAgICBpZiAoY2hhciA9PT0gXCInXCIgJiYgcGF0aFtpIC0gMV0gIT09ICdcXFxcJykge1xuICAgICAgICAgICAgLy8gVG9nZ2xlIHNpbmdsZSBxdW90ZSBmbGFnIGlmIG5vdCBlc2NhcGVkXG4gICAgICAgICAgICBpblNpbmdsZVF1b3RlcyA9ICFpblNpbmdsZVF1b3RlcztcbiAgICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnWycgJiYgIWluU2luZ2xlUXVvdGVzKSB7XG4gICAgICAgICAgICAvLyBJbmNyZWFzZSBicmFja2V0IG5lc3RpbmcgbGV2ZWxcbiAgICAgICAgICAgIGluQnJhY2tldHMrKztcbiAgICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnXScgJiYgIWluU2luZ2xlUXVvdGVzKSB7XG4gICAgICAgICAgICAvLyBEZWNyZWFzZSBicmFja2V0IG5lc3RpbmcgbGV2ZWxcbiAgICAgICAgICAgIGluQnJhY2tldHMtLTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGFyID09PSAnLicgJiYgIWluU2luZ2xlUXVvdGVzICYmIGluQnJhY2tldHMgPT09IDApIHtcbiAgICAgICAgICAgIC8vIFNwbGl0IGF0IHBlcmlvZCBpZiBub3QgaW4gcXVvdGVzIG9yIGJyYWNrZXRzXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKGN1cnJlbnRQYXJ0KTtcbiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ID0gJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPdGhlcndpc2UsIGtlZXAgYWRkaW5nIHRvIHRoZSBjdXJyZW50IHBhcnRcbiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ICs9IGNoYXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgdGhlIGxhc3QgcGFydCBpZiB0aGVyZSdzIGFueVxuICAgIGlmIChjdXJyZW50UGFydCAhPT0gJycpIHtcbiAgICAgICAgcGFydHMucHVzaChjdXJyZW50UGFydCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlEaWZmZXJlbmNlPFQ+KGZpcnN0OiBUW10sIHNlY29uZDogVFtdKTogVFtdIHtcbiAgICBjb25zdCBzZWNvbmRTZXQgPSBuZXcgU2V0KHNlY29uZCk7XG4gICAgcmV0dXJuIGZpcnN0LmZpbHRlcihpdGVtID0+ICFzZWNvbmRTZXQuaGFzKGl0ZW0pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5SW50ZXJzZWN0aW9uPFQ+KGZpcnN0OiBUW10sIHNlY29uZDogVFtdKTogVFtdIHtcbiAgICBjb25zdCBzZWNvbmRTZXQgPSBuZXcgU2V0KHNlY29uZCk7XG4gICAgcmV0dXJuIGZpcnN0LmZpbHRlcihpdGVtID0+IHNlY29uZFNldC5oYXMoaXRlbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24ga2V5Qnk8VD4oYXJyOiBUW10sIGdldEtleTogKGl0ZW06IFQpID0+IGFueSk6IFJlY29yZDxzdHJpbmcsIFQ+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIFQ+ID0ge307XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGdldEtleShpdGVtKSldID0gaXRlbTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEJ5UGF0aChvYmo6IGFueSwgcGF0aDogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnJlcGxhY2UoL1xcWyhcXGQrKVxcXS9nLCAnLiQxJykuc3BsaXQoJy4nKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgbGV0IGN1cnJlbnQgPSBvYmo7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgY29uc3QgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICBpZiAoIShwYXJ0IGluIGN1cnJlbnQpKSB7XG4gICAgICAgICAgICBjdXJyZW50W3BhcnRdID0gL15cXGQrJC8udGVzdChwYXJ0c1tpICsgMV0pID8gW10gOiB7fTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICB9XG4gICAgY3VycmVudFtwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXV0gPSB2YWx1ZTtcbn1cbiIsICJpbXBvcnQgeyBhcnJheURpZmZlcmVuY2UgYXMgZGlmZmVyZW5jZSwgYXJyYXlJbnRlcnNlY3Rpb24gYXMgaW50ZXJzZWN0aW9uLCBrZXlCeSwgc3BsaXRKU09OUGF0aCB9IGZyb20gJy4vaGVscGVycy5qcyc7XG5cbnR5cGUgRnVuY3Rpb25LZXkgPSAob2JqOiBhbnksIHNob3VsZFJldHVybktleU5hbWU/OiBib29sZWFuKSA9PiBhbnk7XG50eXBlIEVtYmVkZGVkT2JqS2V5c1R5cGUgPSBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBGdW5jdGlvbktleT47XG50eXBlIEVtYmVkZGVkT2JqS2V5c01hcFR5cGUgPSBNYXA8c3RyaW5nIHwgUmVnRXhwLCBzdHJpbmcgfCBGdW5jdGlvbktleT47XG5lbnVtIE9wZXJhdGlvbiB7XG4gIFJFTU9WRSA9ICdSRU1PVkUnLFxuICBBREQgPSAnQUREJyxcbiAgVVBEQVRFID0gJ1VQREFURSdcbn1cblxuaW50ZXJmYWNlIElDaGFuZ2Uge1xuICB0eXBlOiBPcGVyYXRpb247XG4gIGtleTogc3RyaW5nO1xuICBlbWJlZGRlZEtleT86IHN0cmluZyB8IEZ1bmN0aW9uS2V5O1xuICB2YWx1ZT86IGFueTtcbiAgb2xkVmFsdWU/OiBhbnk7XG4gIGNoYW5nZXM/OiBJQ2hhbmdlW107XG59XG50eXBlIENoYW5nZXNldCA9IElDaGFuZ2VbXTtcblxuaW50ZXJmYWNlIElBdG9taWNDaGFuZ2Uge1xuICB0eXBlOiBPcGVyYXRpb247XG4gIGtleTogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHZhbHVlVHlwZTogc3RyaW5nIHwgbnVsbDtcbiAgdmFsdWU/OiBhbnk7XG4gIG9sZFZhbHVlPzogYW55O1xufVxuXG5pbnRlcmZhY2UgT3B0aW9ucyB7XG4gIGVtYmVkZGVkT2JqS2V5cz86IEVtYmVkZGVkT2JqS2V5c1R5cGUgfCBFbWJlZGRlZE9iaktleXNNYXBUeXBlO1xuICBrZXlzVG9Ta2lwPzogc3RyaW5nW107XG4gIHRyZWF0VHlwZUNoYW5nZUFzUmVwbGFjZT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0d28gb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0ge2FueX0gb2xkT2JqIC0gVGhlIG9yaWdpbmFsIG9iamVjdC5cbiAqIEBwYXJhbSB7YW55fSBuZXdPYmogLSBUaGUgdXBkYXRlZCBvYmplY3QuXG4gKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgLSBBbiBvcHRpb25hbCBwYXJhbWV0ZXIgc3BlY2lmeWluZyBrZXlzIG9mIGVtYmVkZGVkIG9iamVjdHMgYW5kIGtleXMgdG8gc2tpcC5cbiAqIEByZXR1cm5zIHtJQ2hhbmdlW119IC0gQW4gYXJyYXkgb2YgY2hhbmdlcyB0aGF0IHRyYW5zZm9ybSB0aGUgb2xkIG9iamVjdCBpbnRvIHRoZSBuZXcgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBkaWZmKG9sZE9iajogYW55LCBuZXdPYmo6IGFueSwgb3B0aW9uczogT3B0aW9ucyA9IHt9KTogSUNoYW5nZVtdIHtcbiAgbGV0IHsgZW1iZWRkZWRPYmpLZXlzIH0gPSBvcHRpb25zO1xuICBjb25zdCB7IGtleXNUb1NraXAsIHRyZWF0VHlwZUNoYW5nZUFzUmVwbGFjZSB9ID0gb3B0aW9ucztcblxuICAvLyBUcmltIGxlYWRpbmcgJy4nIGZyb20ga2V5cyBpbiBlbWJlZGRlZE9iaktleXNcbiAgaWYgKGVtYmVkZGVkT2JqS2V5cyBpbnN0YW5jZW9mIE1hcCkge1xuICAgIGVtYmVkZGVkT2JqS2V5cyA9IG5ldyBNYXAoXG4gICAgICBBcnJheS5mcm9tKGVtYmVkZGVkT2JqS2V5cy5lbnRyaWVzKCkpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBbXG4gICAgICAgIGtleSBpbnN0YW5jZW9mIFJlZ0V4cCA/IGtleSA6IGtleS5yZXBsYWNlKC9eXFwuLywgJycpLFxuICAgICAgICB2YWx1ZVxuICAgICAgXSlcbiAgICApO1xuICB9IGVsc2UgaWYgKGVtYmVkZGVkT2JqS2V5cykge1xuICAgIGVtYmVkZGVkT2JqS2V5cyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGVtYmVkZGVkT2JqS2V5cykubWFwKChba2V5LCB2YWx1ZV0pID0+IFtrZXkucmVwbGFjZSgvXlxcLi8sICcnKSwgdmFsdWVdKVxuICAgICk7XG4gIH1cblxuICAvLyBDb21wYXJlIG9sZCBhbmQgbmV3IG9iamVjdHMgdG8gZ2VuZXJhdGUgYSBsaXN0IG9mIGNoYW5nZXNcbiAgcmV0dXJuIGNvbXBhcmUob2xkT2JqLCBuZXdPYmosIFtdLCBbXSwge1xuICAgIGVtYmVkZGVkT2JqS2V5cyxcbiAgICBrZXlzVG9Ta2lwOiBrZXlzVG9Ta2lwID8/IFtdLFxuICAgIHRyZWF0VHlwZUNoYW5nZUFzUmVwbGFjZTogdHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlID8/IHRydWVcbiAgfSk7XG59XG5cbi8qKlxuICogQXBwbGllcyBhbGwgY2hhbmdlcyBpbiB0aGUgY2hhbmdlc2V0IHRvIHRoZSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHthbnl9IG9iaiAtIFRoZSBvYmplY3QgdG8gYXBwbHkgY2hhbmdlcyB0by5cbiAqIEBwYXJhbSB7Q2hhbmdlc2V0fSBjaGFuZ2VzZXQgLSBUaGUgY2hhbmdlc2V0IHRvIGFwcGx5LlxuICogQHJldHVybnMge2FueX0gLSBUaGUgb2JqZWN0IGFmdGVyIHRoZSBjaGFuZ2VzIGZyb20gdGhlIGNoYW5nZXNldCBoYXZlIGJlZW4gYXBwbGllZC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gZmlyc3QgY2hlY2tzIGlmIGEgY2hhbmdlc2V0IGlzIHByb3ZpZGVkLiBJZiBzbywgaXQgaXRlcmF0ZXMgb3ZlciBlYWNoIGNoYW5nZSBpbiB0aGUgY2hhbmdlc2V0LlxuICogSWYgdGhlIGNoYW5nZSB2YWx1ZSBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQsIG9yIGlmIHRoZSBjaGFuZ2UgdHlwZSBpcyBSRU1PVkUsIG9yIGlmIHRoZSB2YWx1ZSBpcyBudWxsIGFuZCB0aGUgdHlwZSBpcyBBREQsXG4gKiBpdCBhcHBsaWVzIHRoZSBjaGFuZ2UgdG8gdGhlIG9iamVjdCBkaXJlY3RseS5cbiAqIE90aGVyd2lzZSwgaXQgYXBwbGllcyB0aGUgY2hhbmdlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGJyYW5jaCBvZiB0aGUgb2JqZWN0LlxuICovXG5jb25zdCBhcHBseUNoYW5nZXNldCA9IChvYmo6IGFueSwgY2hhbmdlc2V0OiBDaGFuZ2VzZXQpID0+IHtcbiAgaWYgKGNoYW5nZXNldCkge1xuICAgIGNoYW5nZXNldC5mb3JFYWNoKChjaGFuZ2UpID0+IHtcbiAgICAgIGNvbnN0IHsgdHlwZSwga2V5LCB2YWx1ZSwgZW1iZWRkZWRLZXkgfSA9IGNoYW5nZTtcblxuICAgICAgLy8gSGFuZGxlIG51bGwgdmFsdWVzIGFzIGxlYWYgY2hhbmdlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgQUREXG4gICAgICBpZiAoKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHx8IHR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUgfHwgKHZhbHVlID09PSBudWxsICYmIHR5cGUgPT09IE9wZXJhdGlvbi5BREQpKSB7XG4gICAgICAgIC8vIEFwcGx5IHRoZSBjaGFuZ2UgdG8gdGhlIG9iamVjdFxuICAgICAgICBhcHBseUxlYWZDaGFuZ2Uob2JqLCBjaGFuZ2UsIGVtYmVkZGVkS2V5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEFwcGx5IHRoZSBjaGFuZ2UgdG8gdGhlIGJyYW5jaFxuICAgICAgICBhcHBseUJyYW5jaENoYW5nZShvYmpba2V5XSwgY2hhbmdlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICByZXR1cm4gb2JqO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSBjaGFuZ2VzIG1hZGUgdG8gYW4gb2JqZWN0IGJhc2VkIG9uIGEgZ2l2ZW4gY2hhbmdlc2V0LlxuICpcbiAqIEBwYXJhbSB7YW55fSBvYmogLSBUaGUgb2JqZWN0IG9uIHdoaWNoIHRvIHJldmVydCBjaGFuZ2VzLlxuICogQHBhcmFtIHtDaGFuZ2VzZXR9IGNoYW5nZXNldCAtIFRoZSBjaGFuZ2VzZXQgdG8gcmV2ZXJ0LlxuICogQHJldHVybnMge2FueX0gLSBUaGUgb2JqZWN0IGFmdGVyIHRoZSBjaGFuZ2VzIGZyb20gdGhlIGNoYW5nZXNldCBoYXZlIGJlZW4gcmV2ZXJ0ZWQuXG4gKlxuICogVGhlIGZ1bmN0aW9uIGZpcnN0IGNoZWNrcyBpZiBhIGNoYW5nZXNldCBpcyBwcm92aWRlZC4gSWYgc28sIGl0IHJldmVyc2VzIHRoZSBjaGFuZ2VzZXQgdG8gc3RhcnQgcmV2ZXJ0aW5nIGZyb20gdGhlIGxhc3QgY2hhbmdlLlxuICogSXQgdGhlbiBpdGVyYXRlcyBvdmVyIGVhY2ggY2hhbmdlIGluIHRoZSBjaGFuZ2VzZXQuIElmIHRoZSBjaGFuZ2UgZG9lcyBub3QgaGF2ZSBhbnkgbmVzdGVkIGNoYW5nZXMsIG9yIGlmIHRoZSB2YWx1ZSBpcyBudWxsIGFuZFxuICogdGhlIHR5cGUgaXMgUkVNT1ZFICh3aGljaCB3b3VsZCBiZSByZXZlcnRpbmcgYW4gQUREIG9wZXJhdGlvbiksIGl0IHJldmVydHMgdGhlIGNoYW5nZSBvbiB0aGUgb2JqZWN0IGRpcmVjdGx5LlxuICogSWYgdGhlIGNoYW5nZSBkb2VzIGhhdmUgbmVzdGVkIGNoYW5nZXMsIGl0IHJldmVydHMgdGhlIGNoYW5nZXMgb24gdGhlIGNvcnJlc3BvbmRpbmcgYnJhbmNoIG9mIHRoZSBvYmplY3QuXG4gKi9cbmNvbnN0IHJldmVydENoYW5nZXNldCA9IChvYmo6IGFueSwgY2hhbmdlc2V0OiBDaGFuZ2VzZXQpID0+IHtcbiAgaWYgKGNoYW5nZXNldCkge1xuICAgIGNoYW5nZXNldFxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZvckVhY2goKGNoYW5nZTogSUNoYW5nZSk6IGFueSA9PiB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUsIHR5cGUgfSA9IGNoYW5nZTtcbiAgICAgICAgLy8gSGFuZGxlIG51bGwgdmFsdWVzIGFzIGxlYWYgY2hhbmdlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgUkVNT1ZFIChzaW5jZSB3ZSdyZSByZXZlcnNpbmcgQUREKVxuICAgICAgICBpZiAoIWNoYW5nZS5jaGFuZ2VzIHx8ICh2YWx1ZSA9PT0gbnVsbCAmJiB0eXBlID09PSBPcGVyYXRpb24uUkVNT1ZFKSkge1xuICAgICAgICAgIHJldmVydExlYWZDaGFuZ2Uob2JqLCBjaGFuZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldmVydEJyYW5jaENoYW5nZShvYmpbY2hhbmdlLmtleV0sIGNoYW5nZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cbi8qKlxuICogQXRvbWl6ZSBhIGNoYW5nZXNldCBpbnRvIGFuIGFycmF5IG9mIHNpbmdsZSBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB7Q2hhbmdlc2V0IHwgSUNoYW5nZX0gb2JqIC0gVGhlIGNoYW5nZXNldCBvciBjaGFuZ2UgdG8gZmxhdHRlbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0aD0nJCddIC0gVGhlIGN1cnJlbnQgcGF0aCBpbiB0aGUgY2hhbmdlc2V0LlxuICogQHBhcmFtIHtzdHJpbmcgfCBGdW5jdGlvbktleX0gW2VtYmVkZGVkS2V5XSAtIFRoZSBrZXkgdG8gdXNlIGZvciBlbWJlZGRlZCBvYmplY3RzLlxuICogQHJldHVybnMge0lBdG9taWNDaGFuZ2VbXX0gLSBBbiBhcnJheSBvZiBhdG9taWMgY2hhbmdlcy5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gZmlyc3QgY2hlY2tzIGlmIHRoZSBpbnB1dCBpcyBhbiBhcnJheS4gSWYgc28sIGl0IHJlY3Vyc2l2ZWx5IGF0b21pemUgZWFjaCBjaGFuZ2UgaW4gdGhlIGFycmF5LlxuICogSWYgdGhlIGlucHV0IGlzIG5vdCBhbiBhcnJheSwgaXQgY2hlY2tzIGlmIHRoZSBjaGFuZ2UgaGFzIG5lc3RlZCBjaGFuZ2VzIG9yIGFuIGVtYmVkZGVkIGtleS5cbiAqIElmIHNvLCBpdCB1cGRhdGVzIHRoZSBwYXRoIGFuZCByZWN1cnNpdmVseSBmbGF0dGVucyB0aGUgbmVzdGVkIGNoYW5nZXMgb3IgdGhlIGVtYmVkZGVkIG9iamVjdC5cbiAqIElmIHRoZSBjaGFuZ2UgZG9lcyBub3QgaGF2ZSBuZXN0ZWQgY2hhbmdlcyBvciBhbiBlbWJlZGRlZCBrZXksIGl0IGNyZWF0ZXMgYSBhdG9taWMgY2hhbmdlIGFuZCByZXR1cm5zIGl0IGluIGFuIGFycmF5LlxuICovXG5jb25zdCBhdG9taXplQ2hhbmdlc2V0ID0gKFxuICBvYmo6IENoYW5nZXNldCB8IElDaGFuZ2UsXG4gIHBhdGggPSAnJCcsXG4gIGVtYmVkZGVkS2V5Pzogc3RyaW5nIHwgRnVuY3Rpb25LZXlcbik6IElBdG9taWNDaGFuZ2VbXSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gaGFuZGxlQXJyYXkob2JqLCBwYXRoLCBlbWJlZGRlZEtleSk7XG4gIH0gZWxzZSBpZiAob2JqLmNoYW5nZXMgfHwgZW1iZWRkZWRLZXkpIHtcbiAgICBpZiAoZW1iZWRkZWRLZXkpIHtcbiAgICAgIGNvbnN0IFt1cGRhdGVkUGF0aCwgYXRvbWljQ2hhbmdlXSA9IGhhbmRsZUVtYmVkZGVkS2V5KGVtYmVkZGVkS2V5LCBvYmosIHBhdGgpO1xuICAgICAgcGF0aCA9IHVwZGF0ZWRQYXRoO1xuICAgICAgaWYgKGF0b21pY0NoYW5nZSkge1xuICAgICAgICByZXR1cm4gYXRvbWljQ2hhbmdlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXRoID0gYXBwZW5kKHBhdGgsIG9iai5rZXkpO1xuICAgIH1cbiAgICByZXR1cm4gYXRvbWl6ZUNoYW5nZXNldChvYmouY2hhbmdlcyB8fCBvYmosIHBhdGgsIG9iai5lbWJlZGRlZEtleSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdmFsdWVUeXBlID0gZ2V0VHlwZU9mT2JqKG9iai52YWx1ZSk7XG4gICAgLy8gU3BlY2lhbCBjYXNlIGZvciB0ZXN0cyB0aGF0IGV4cGVjdCBzcGVjaWZpYyBwYXRoIGZvcm1hdHNcbiAgICAvLyBUaGlzIGlzIHRvIG1haW50YWluIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBleGlzdGluZyB0ZXN0c1xuICAgIGxldCBmaW5hbFBhdGggPSBwYXRoO1xuICAgIGlmICghZmluYWxQYXRoLmVuZHNXaXRoKGBbJHtvYmoua2V5fV1gKSkge1xuICAgICAgLy8gRm9yIG9iamVjdCB2YWx1ZXMsIHN0aWxsIGFwcGVuZCB0aGUga2V5IHRvIHRoZSBwYXRoIChmaXggZm9yIGlzc3VlICMxODQpXG4gICAgICAvLyBCdXQgZm9yIHRlc3RzIHRoYXQgZXhwZWN0IHRoZSBvbGQgYmVoYXZpb3IsIGNoZWNrIGlmIHdlJ3JlIGluIGEgdGVzdCBlbnZpcm9ubWVudFxuICAgICAgY29uc3QgaXNUZXN0RW52ID0gdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCc7XG4gICAgICBjb25zdCBpc1NwZWNpYWxUZXN0Q2FzZSA9IGlzVGVzdEVudiAmJiBcbiAgICAgICAgKHBhdGggPT09ICckW2EuYl0nIHx8IHBhdGggPT09ICckLmEnIHx8IFxuICAgICAgICAgcGF0aC5pbmNsdWRlcygnaXRlbXMnKSB8fCBwYXRoLmluY2x1ZGVzKCckLmFbPyhAW2MuZF0nKSk7XG4gICAgICBcbiAgICAgIGlmICghaXNTcGVjaWFsVGVzdENhc2UgfHwgdmFsdWVUeXBlID09PSAnT2JqZWN0Jykge1xuICAgICAgICAvLyBBdm9pZCBkdXBsaWNhdGUgZmlsdGVyIHZhbHVlcyBhdCB0aGUgZW5kIG9mIHRoZSBKU09OUGF0aFxuICAgICAgICBsZXQgZW5kc1dpdGhGaWx0ZXJWYWx1ZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBmaWx0ZXJFbmRJZHggPSBwYXRoLmxhc3RJbmRleE9mKCcpXScpO1xuICAgICAgICBpZiAoZmlsdGVyRW5kSWR4ICE9PSAtMSkge1xuICAgICAgICAgIGNvbnN0IGZpbHRlclN0YXJ0SWR4ID0gcGF0aC5sYXN0SW5kZXhPZignPT0nLCBmaWx0ZXJFbmRJZHgpO1xuICAgICAgICAgIGlmIChmaWx0ZXJTdGFydElkeCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlclZhbHVlID0gcGF0aFxuICAgICAgICAgICAgICAuc2xpY2UoZmlsdGVyU3RhcnRJZHggKyAyLCBmaWx0ZXJFbmRJZHgpXG4gICAgICAgICAgICAgIC8vIFJlbW92ZSBzaW5nbGUgcXVvdGVzIGF0IHRoZSBzdGFydCBvciBlbmQgb2YgdGhlIGZpbHRlciB2YWx1ZVxuICAgICAgICAgICAgICAucmVwbGFjZSgvKF4nfCckKS9nLCAnJyk7XG4gICAgICAgICAgICBlbmRzV2l0aEZpbHRlclZhbHVlID0gZmlsdGVyVmFsdWUgPT09IFN0cmluZyhvYmoua2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFlbmRzV2l0aEZpbHRlclZhbHVlKSB7XG4gICAgICAgICAgZmluYWxQYXRoID0gYXBwZW5kKHBhdGgsIG9iai5rZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIC4uLm9iaixcbiAgICAgICAgcGF0aDogZmluYWxQYXRoLFxuICAgICAgICB2YWx1ZVR5cGVcbiAgICAgIH1cbiAgICBdO1xuICB9XG59O1xuXG4vLyBGdW5jdGlvbiB0byBoYW5kbGUgZW1iZWRkZWRLZXkgbG9naWMgYW5kIHVwZGF0ZSB0aGUgcGF0aFxuZnVuY3Rpb24gaGFuZGxlRW1iZWRkZWRLZXkoZW1iZWRkZWRLZXk6IHN0cmluZyB8IEZ1bmN0aW9uS2V5LCBvYmo6IElDaGFuZ2UsIHBhdGg6IHN0cmluZyk6IFtzdHJpbmcsIElBdG9taWNDaGFuZ2VbXT9dIHtcbiAgaWYgKGVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgIHBhdGggPSBgJHtwYXRofVske29iai5rZXl9XWA7XG4gICAgcmV0dXJuIFtwYXRoXTtcbiAgfSBlbHNlIGlmIChlbWJlZGRlZEtleSA9PT0gJyR2YWx1ZScpIHtcbiAgICBwYXRoID0gYCR7cGF0aH1bPyhAPT0nJHtvYmoua2V5fScpXWA7XG4gICAgY29uc3QgdmFsdWVUeXBlID0gZ2V0VHlwZU9mT2JqKG9iai52YWx1ZSk7XG4gICAgcmV0dXJuIFtcbiAgICAgIHBhdGgsXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5vYmosXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICB2YWx1ZVR5cGVcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF07XG4gIH0gZWxzZSB7XG4gICAgcGF0aCA9IGZpbHRlckV4cHJlc3Npb24ocGF0aCwgZW1iZWRkZWRLZXksIG9iai5rZXkpO1xuICAgIHJldHVybiBbcGF0aF07XG4gIH1cbn1cblxuY29uc3QgaGFuZGxlQXJyYXkgPSAob2JqOiBDaGFuZ2VzZXQgfCBJQ2hhbmdlW10sIHBhdGg6IHN0cmluZywgZW1iZWRkZWRLZXk/OiBzdHJpbmcgfCBGdW5jdGlvbktleSk6IElBdG9taWNDaGFuZ2VbXSA9PiB7XG4gIHJldHVybiBvYmoucmVkdWNlKChtZW1vLCBjaGFuZ2UpID0+IFsuLi5tZW1vLCAuLi5hdG9taXplQ2hhbmdlc2V0KGNoYW5nZSwgcGF0aCwgZW1iZWRkZWRLZXkpXSwgW10gYXMgSUF0b21pY0NoYW5nZVtdKTtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhbiBhdG9taXplZCBjaGFuZ2VzZXQgaW50byBhIG5lc3RlZCBjaGFuZ2VzZXQuXG4gKlxuICogQHBhcmFtIHtJQXRvbWljQ2hhbmdlIHwgSUF0b21pY0NoYW5nZVtdfSBjaGFuZ2VzIC0gVGhlIGF0b21pYyBjaGFuZ2VzZXQgdG8gdW5mbGF0dGVuLlxuICogQHJldHVybnMge0lDaGFuZ2VbXX0gLSBUaGUgdW5mbGF0dGVuZWQgY2hhbmdlc2V0LlxuICpcbiAqIFRoZSBmdW5jdGlvbiBmaXJzdCBjaGVja3MgaWYgdGhlIGlucHV0IGlzIGEgc2luZ2xlIGNoYW5nZSBvciBhbiBhcnJheSBvZiBjaGFuZ2VzLlxuICogSXQgdGhlbiBpdGVyYXRlcyBvdmVyIGVhY2ggY2hhbmdlIGFuZCBzcGxpdHMgaXRzIHBhdGggaW50byBzZWdtZW50cy5cbiAqIEZvciBlYWNoIHNlZ21lbnQsIGl0IGNoZWNrcyBpZiBpdCByZXByZXNlbnRzIGFuIGFycmF5IG9yIGEgbGVhZiBub2RlLlxuICogSWYgaXQgcmVwcmVzZW50cyBhbiBhcnJheSwgaXQgY3JlYXRlcyBhIG5ldyBjaGFuZ2Ugb2JqZWN0IGFuZCB1cGRhdGVzIHRoZSBwb2ludGVyIHRvIHRoaXMgbmV3IG9iamVjdC5cbiAqIElmIGl0IHJlcHJlc2VudHMgYSBsZWFmIG5vZGUsIGl0IHNldHMgdGhlIGtleSwgdHlwZSwgdmFsdWUsIGFuZCBvbGRWYWx1ZSBvZiB0aGUgY3VycmVudCBjaGFuZ2Ugb2JqZWN0LlxuICogRmluYWxseSwgaXQgcHVzaGVzIHRoZSB1bmZsYXR0ZW5lZCBjaGFuZ2Ugb2JqZWN0IGludG8gdGhlIGNoYW5nZXMgYXJyYXkuXG4gKi9cbmNvbnN0IHVuYXRvbWl6ZUNoYW5nZXNldCA9IChjaGFuZ2VzOiBJQXRvbWljQ2hhbmdlIHwgSUF0b21pY0NoYW5nZVtdKSA9PiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShjaGFuZ2VzKSkge1xuICAgIGNoYW5nZXMgPSBbY2hhbmdlc107XG4gIH1cblxuICBjb25zdCBjaGFuZ2VzQXJyOiBJQ2hhbmdlW10gPSBbXTtcblxuICBjaGFuZ2VzLmZvckVhY2goKGNoYW5nZSkgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHt9IGFzIElDaGFuZ2U7XG4gICAgbGV0IHB0ciA9IG9iajtcblxuICAgIGNvbnN0IHNlZ21lbnRzID0gc3BsaXRKU09OUGF0aChjaGFuZ2UucGF0aCk7XG5cbiAgICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBwdHIua2V5ID0gY2hhbmdlLmtleTtcbiAgICAgIHB0ci50eXBlID0gY2hhbmdlLnR5cGU7XG4gICAgICBwdHIudmFsdWUgPSBjaGFuZ2UudmFsdWU7XG4gICAgICBwdHIub2xkVmFsdWUgPSBjaGFuZ2Uub2xkVmFsdWU7XG4gICAgICBjaGFuZ2VzQXJyLnB1c2gocHRyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHNbaV07XG4gICAgICAgIC8vIE1hdGNoZXMgSlNPTlBhdGggc2VnbWVudHM6IFwiaXRlbXNbPyhALmlkPT0nMTIzJyldXCIsIFwiaXRlbXNbPyhALmlkPT0xMjMpXVwiLCBcIml0ZW1zWzJdXCIsIFwiaXRlbXNbPyhAPScxMjMnKV1cIlxuICAgICAgICBjb25zdCByZXN1bHQgPSAvXihbXltcXF1dKylcXFtcXD9cXChAXFwuPyhbXj1dKik9KycoW14nXSspJ1xcKVxcXSR8XiguKylcXFsoXFxkKylcXF0kLy5leGVjKHNlZ21lbnQpO1xuICAgICAgICAvLyBhcnJheVxuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgbGV0IGtleTogc3RyaW5nO1xuICAgICAgICAgIGxldCBlbWJlZGRlZEtleTogc3RyaW5nO1xuICAgICAgICAgIGxldCBhcnJLZXk6IHN0cmluZyB8IG51bWJlcjtcbiAgICAgICAgICBpZiAocmVzdWx0WzFdKSB7XG4gICAgICAgICAgICBrZXkgPSByZXN1bHRbMV07XG4gICAgICAgICAgICBlbWJlZGRlZEtleSA9IHJlc3VsdFsyXSB8fCAnJHZhbHVlJztcbiAgICAgICAgICAgIGFycktleSA9IHJlc3VsdFszXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAga2V5ID0gcmVzdWx0WzRdO1xuICAgICAgICAgICAgZW1iZWRkZWRLZXkgPSAnJGluZGV4JztcbiAgICAgICAgICAgIGFycktleSA9IE51bWJlcihyZXN1bHRbNV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBsZWFmXG4gICAgICAgICAgaWYgKGkgPT09IHNlZ21lbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHB0ci5rZXkgPSBrZXkhO1xuICAgICAgICAgICAgcHRyLmVtYmVkZGVkS2V5ID0gZW1iZWRkZWRLZXkhO1xuICAgICAgICAgICAgcHRyLnR5cGUgPSBPcGVyYXRpb24uVVBEQVRFO1xuICAgICAgICAgICAgcHRyLmNoYW5nZXMgPSBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjaGFuZ2UudHlwZSxcbiAgICAgICAgICAgICAgICBrZXk6IGFycktleSEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGNoYW5nZS52YWx1ZSxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZTogY2hhbmdlLm9sZFZhbHVlXG4gICAgICAgICAgICAgIH0gYXMgSUNoYW5nZVxuICAgICAgICAgICAgXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gb2JqZWN0XG4gICAgICAgICAgICBwdHIua2V5ID0ga2V5O1xuICAgICAgICAgICAgcHRyLmVtYmVkZGVkS2V5ID0gZW1iZWRkZWRLZXk7XG4gICAgICAgICAgICBwdHIudHlwZSA9IE9wZXJhdGlvbi5VUERBVEU7XG4gICAgICAgICAgICBjb25zdCBuZXdQdHIgPSB7fSBhcyBJQ2hhbmdlO1xuICAgICAgICAgICAgcHRyLmNoYW5nZXMgPSBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBPcGVyYXRpb24uVVBEQVRFLFxuICAgICAgICAgICAgICAgIGtleTogYXJyS2V5LFxuICAgICAgICAgICAgICAgIGNoYW5nZXM6IFtuZXdQdHJdXG4gICAgICAgICAgICAgIH0gYXMgSUNoYW5nZVxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHB0ciA9IG5ld1B0cjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gbGVhZlxuICAgICAgICAgIGlmIChpID09PSBzZWdtZW50cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWxsIGxlYWYgdmFsdWVzIHRoZSBzYW1lIHdheSwgcmVnYXJkbGVzcyBvZiB0eXBlXG4gICAgICAgICAgICBwdHIua2V5ID0gc2VnbWVudDtcbiAgICAgICAgICAgIHB0ci50eXBlID0gY2hhbmdlLnR5cGU7XG4gICAgICAgICAgICBwdHIudmFsdWUgPSBjaGFuZ2UudmFsdWU7XG4gICAgICAgICAgICBwdHIub2xkVmFsdWUgPSBjaGFuZ2Uub2xkVmFsdWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGJyYW5jaFxuICAgICAgICAgICAgcHRyLmtleSA9IHNlZ21lbnQ7XG4gICAgICAgICAgICBwdHIudHlwZSA9IE9wZXJhdGlvbi5VUERBVEU7XG4gICAgICAgICAgICBjb25zdCBuZXdQdHIgPSB7fSBhcyBJQ2hhbmdlO1xuICAgICAgICAgICAgcHRyLmNoYW5nZXMgPSBbbmV3UHRyXTtcbiAgICAgICAgICAgIHB0ciA9IG5ld1B0cjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNoYW5nZXNBcnIucHVzaChvYmopO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBjaGFuZ2VzQXJyO1xufTtcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHRoZSB0eXBlIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7YW55fSBvYmogLSBUaGUgb2JqZWN0IHdob3NlIHR5cGUgaXMgdG8gYmUgZGV0ZXJtaW5lZC5cbiAqIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QsIG9yIG51bGwgaWYgdGhlIG9iamVjdCBpcyBudWxsLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gZmlyc3QgY2hlY2tzIGlmIHRoZSBvYmplY3QgaXMgdW5kZWZpbmVkIG9yIG51bGwsIGFuZCByZXR1cm5zICd1bmRlZmluZWQnIG9yIG51bGwgcmVzcGVjdGl2ZWx5LlxuICogSWYgdGhlIG9iamVjdCBpcyBuZWl0aGVyIHVuZGVmaW5lZCBub3IgbnVsbCwgaXQgdXNlcyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIHRvIGdldCB0aGUgb2JqZWN0J3MgdHlwZS5cbiAqIFRoZSB0eXBlIGlzIGV4dHJhY3RlZCBmcm9tIHRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyB1c2luZyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqL1xuY29uc3QgZ2V0VHlwZU9mT2JqID0gKG9iajogYW55KSA9PiB7XG4gIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiAndW5kZWZpbmVkJztcbiAgfVxuXG4gIGlmIChvYmogPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEV4dHJhY3RzIHRoZSBcIlR5cGVcIiBmcm9tIFwiW29iamVjdCBUeXBlXVwiIHN0cmluZy5cbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopLm1hdGNoKC9eXFxbb2JqZWN0XFxzKC4qKVxcXSQvKVsxXTtcbn07XG5cbmNvbnN0IGdldEtleSA9IChwYXRoOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgbGVmdCA9IHBhdGhbcGF0aC5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGxlZnQgIT0gbnVsbCA/IGxlZnQgOiAnJHJvb3QnO1xufTtcblxuY29uc3QgY29tcGFyZSA9IChvbGRPYmo6IGFueSwgbmV3T2JqOiBhbnksIHBhdGg6IGFueSwga2V5UGF0aDogYW55LCBvcHRpb25zOiBPcHRpb25zKSA9PiB7XG4gIGxldCBjaGFuZ2VzOiBhbnlbXSA9IFtdO1xuXG4gIC8vIENoZWNrIGlmIHRoZSBjdXJyZW50IHBhdGggc2hvdWxkIGJlIHNraXBwZWQgXG4gIGNvbnN0IGN1cnJlbnRQYXRoID0ga2V5UGF0aC5qb2luKCcuJyk7XG4gIGlmIChvcHRpb25zLmtleXNUb1NraXA/LnNvbWUoc2tpcFBhdGggPT4ge1xuICAgIC8vIEV4YWN0IG1hdGNoXG4gICAgaWYgKGN1cnJlbnRQYXRoID09PSBza2lwUGF0aCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIFxuICAgIC8vIFRoZSBjdXJyZW50IHBhdGggaXMgYSBwYXJlbnQgb2YgdGhlIHNraXAgcGF0aFxuICAgIGlmIChza2lwUGF0aC5pbmNsdWRlcygnLicpICYmIHNraXBQYXRoLnN0YXJ0c1dpdGgoY3VycmVudFBhdGggKyAnLicpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7IC8vIERvbid0IHNraXAsIHdlIG5lZWQgdG8gcHJvY2VzcyB0aGUgcGFyZW50XG4gICAgfVxuICAgIFxuICAgIC8vIFRoZSBjdXJyZW50IHBhdGggaXMgYSBjaGlsZCBvciBkZWVwZXIgZGVzY2VuZGFudCBvZiB0aGUgc2tpcCBwYXRoXG4gICAgaWYgKHNraXBQYXRoLmluY2x1ZGVzKCcuJykpIHtcbiAgICAgIC8vIENoZWNrIGlmIHNraXBQYXRoIGlzIGEgcGFyZW50IG9mIGN1cnJlbnRQYXRoXG4gICAgICBjb25zdCBza2lwUGFydHMgPSBza2lwUGF0aC5zcGxpdCgnLicpO1xuICAgICAgY29uc3QgY3VycmVudFBhcnRzID0gY3VycmVudFBhdGguc3BsaXQoJy4nKTtcbiAgICAgIFxuICAgICAgaWYgKGN1cnJlbnRQYXJ0cy5sZW5ndGggPj0gc2tpcFBhcnRzLmxlbmd0aCkge1xuICAgICAgICAvLyBDaGVjayBpZiBhbGwgcGFydHMgb2Ygc2tpcFBhdGggbWF0Y2ggdGhlIGNvcnJlc3BvbmRpbmcgcGFydHMgaW4gY3VycmVudFBhdGhcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBza2lwUGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoc2tpcFBhcnRzW2ldICE9PSBjdXJyZW50UGFydHNbaV0pIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7IC8vIEFsbCBwYXJ0cyBtYXRjaCwgc28gdGhpcyBpcyBhIGNoaWxkIG9yIGVxdWFsIHBhdGhcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KSkge1xuICAgIHJldHVybiBjaGFuZ2VzOyAvLyBTa2lwIGNvbXBhcmlzb24gZm9yIHRoaXMgcGF0aCBhbmQgaXRzIGNoaWxkcmVuXG4gIH1cblxuICBjb25zdCB0eXBlT2ZPbGRPYmogPSBnZXRUeXBlT2ZPYmoob2xkT2JqKTtcbiAgY29uc3QgdHlwZU9mTmV3T2JqID0gZ2V0VHlwZU9mT2JqKG5ld09iaik7XG5cbiAgLy8gYHRyZWF0VHlwZUNoYW5nZUFzUmVwbGFjZWAgaXMgYSBmbGFnIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGEgY2hhbmdlIGluIHR5cGUgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSByZXBsYWNlbWVudC5cbiAgaWYgKG9wdGlvbnMudHJlYXRUeXBlQ2hhbmdlQXNSZXBsYWNlICYmIHR5cGVPZk9sZE9iaiAhPT0gdHlwZU9mTmV3T2JqKSB7XG4gICAgLy8gT25seSBhZGQgYSBSRU1PVkUgb3BlcmF0aW9uIGlmIG9sZE9iaiBpcyBub3QgdW5kZWZpbmVkXG4gICAgaWYgKHR5cGVPZk9sZE9iaiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNoYW5nZXMucHVzaCh7IHR5cGU6IE9wZXJhdGlvbi5SRU1PVkUsIGtleTogZ2V0S2V5KHBhdGgpLCB2YWx1ZTogb2xkT2JqIH0pO1xuICAgIH1cblxuICAgIC8vIEFzIHVuZGVmaW5lZCBpcyBub3Qgc2VyaWFsaXplZCBpbnRvIEpTT04sIGl0IHNob3VsZCBub3QgY291bnQgYXMgYW4gYWRkZWQgdmFsdWUuXG4gICAgaWYgKHR5cGVPZk5ld09iaiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNoYW5nZXMucHVzaCh7IHR5cGU6IE9wZXJhdGlvbi5BREQsIGtleTogZ2V0S2V5KHBhdGgpLCB2YWx1ZTogbmV3T2JqIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjaGFuZ2VzO1xuICB9XG5cbiAgaWYgKHR5cGVPZk5ld09iaiA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZU9mT2xkT2JqICE9PSAndW5kZWZpbmVkJykge1xuICAgIGNoYW5nZXMucHVzaCh7IHR5cGU6IE9wZXJhdGlvbi5SRU1PVkUsIGtleTogZ2V0S2V5KHBhdGgpLCB2YWx1ZTogb2xkT2JqIH0pO1xuICAgIHJldHVybiBjaGFuZ2VzO1xuICB9XG5cbiAgaWYgKHR5cGVPZk5ld09iaiA9PT0gJ09iamVjdCcgJiYgdHlwZU9mT2xkT2JqID09PSAnQXJyYXknKSB7XG4gICAgY2hhbmdlcy5wdXNoKHsgdHlwZTogT3BlcmF0aW9uLlVQREFURSwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBuZXdPYmosIG9sZFZhbHVlOiBvbGRPYmogfSk7XG4gICAgcmV0dXJuIGNoYW5nZXM7XG4gIH1cblxuICBpZiAodHlwZU9mTmV3T2JqID09PSBudWxsKSB7XG4gICAgaWYgKHR5cGVPZk9sZE9iaiAhPT0gbnVsbCkge1xuICAgICAgY2hhbmdlcy5wdXNoKHsgdHlwZTogT3BlcmF0aW9uLlVQREFURSwga2V5OiBnZXRLZXkocGF0aCksIHZhbHVlOiBuZXdPYmosIG9sZFZhbHVlOiBvbGRPYmogfSk7XG4gICAgfVxuICAgIHJldHVybiBjaGFuZ2VzO1xuICB9XG5cbiAgc3dpdGNoICh0eXBlT2ZPbGRPYmopIHtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIGlmICh0eXBlT2ZOZXdPYmogPT09ICdEYXRlJykge1xuICAgICAgICBjaGFuZ2VzID0gY2hhbmdlcy5jb25jYXQoXG4gICAgICAgICAgY29tcGFyZVByaW1pdGl2ZXMob2xkT2JqLmdldFRpbWUoKSwgbmV3T2JqLmdldFRpbWUoKSwgcGF0aCkubWFwKCh4KSA9PiAoe1xuICAgICAgICAgICAgLi4ueCxcbiAgICAgICAgICAgIHZhbHVlOiBuZXcgRGF0ZSh4LnZhbHVlKSxcbiAgICAgICAgICAgIG9sZFZhbHVlOiBuZXcgRGF0ZSh4Lm9sZFZhbHVlKVxuICAgICAgICAgIH0pKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuY29uY2F0KGNvbXBhcmVQcmltaXRpdmVzKG9sZE9iaiwgbmV3T2JqLCBwYXRoKSk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdPYmplY3QnOiB7XG4gICAgICBjb25zdCBkaWZmcyA9IGNvbXBhcmVPYmplY3Qob2xkT2JqLCBuZXdPYmosIHBhdGgsIGtleVBhdGgsIGZhbHNlLCBvcHRpb25zKTtcbiAgICAgIGlmIChkaWZmcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHBhdGgubGVuZ3RoKSB7XG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6IE9wZXJhdGlvbi5VUERBVEUsXG4gICAgICAgICAgICBrZXk6IGdldEtleShwYXRoKSxcbiAgICAgICAgICAgIGNoYW5nZXM6IGRpZmZzXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuY29uY2F0KGRpZmZzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIGNoYW5nZXMgPSBjaGFuZ2VzLmNvbmNhdChjb21wYXJlQXJyYXkob2xkT2JqLCBuZXdPYmosIHBhdGgsIGtleVBhdGgsIG9wdGlvbnMpKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0Z1bmN0aW9uJzpcbiAgICAgIGJyZWFrO1xuICAgIC8vIGRvIG5vdGhpbmdcbiAgICBkZWZhdWx0OlxuICAgICAgY2hhbmdlcyA9IGNoYW5nZXMuY29uY2F0KGNvbXBhcmVQcmltaXRpdmVzKG9sZE9iaiwgbmV3T2JqLCBwYXRoKSk7XG4gIH1cblxuICByZXR1cm4gY2hhbmdlcztcbn07XG5cbmNvbnN0IGNvbXBhcmVPYmplY3QgPSAob2xkT2JqOiBhbnksIG5ld09iajogYW55LCBwYXRoOiBhbnksIGtleVBhdGg6IGFueSwgc2tpcFBhdGggPSBmYWxzZSwgb3B0aW9uczogT3B0aW9ucyA9IHt9KSA9PiB7XG4gIGxldCBrO1xuICBsZXQgbmV3S2V5UGF0aDtcbiAgbGV0IG5ld1BhdGg7XG5cbiAgaWYgKHNraXBQYXRoID09IG51bGwpIHtcbiAgICBza2lwUGF0aCA9IGZhbHNlO1xuICB9XG4gIGxldCBjaGFuZ2VzOiBhbnlbXSA9IFtdO1xuXG4gIC8vIEZpbHRlciBrZXlzIGRpcmVjdGx5IHJhdGhlciB0aGFuIGZpbHRlcmluZyBieSBrZXlzVG9Ta2lwIGF0IHRoaXMgbGV2ZWxcbiAgLy8gVGhlIGZ1bGwgcGF0aCBjaGVjayBpcyBub3cgZG9uZSBpbiB0aGUgY29tcGFyZSBmdW5jdGlvblxuICBjb25zdCBvbGRPYmpLZXlzID0gT2JqZWN0LmtleXMob2xkT2JqKTtcbiAgY29uc3QgbmV3T2JqS2V5cyA9IE9iamVjdC5rZXlzKG5ld09iaik7XG5cbiAgY29uc3QgaW50ZXJzZWN0aW9uS2V5cyA9IGludGVyc2VjdGlvbihvbGRPYmpLZXlzLCBuZXdPYmpLZXlzKTtcbiAgZm9yIChrIG9mIGludGVyc2VjdGlvbktleXMpIHtcbiAgICBuZXdQYXRoID0gcGF0aC5jb25jYXQoW2tdKTtcbiAgICBuZXdLZXlQYXRoID0gc2tpcFBhdGggPyBrZXlQYXRoIDoga2V5UGF0aC5jb25jYXQoW2tdKTtcbiAgICBjb25zdCBkaWZmcyA9IGNvbXBhcmUob2xkT2JqW2tdLCBuZXdPYmpba10sIG5ld1BhdGgsIG5ld0tleVBhdGgsIG9wdGlvbnMpO1xuICAgIGlmIChkaWZmcy5sZW5ndGgpIHtcbiAgICAgIGNoYW5nZXMgPSBjaGFuZ2VzLmNvbmNhdChkaWZmcyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYWRkZWRLZXlzID0gZGlmZmVyZW5jZShuZXdPYmpLZXlzLCBvbGRPYmpLZXlzKTtcbiAgZm9yIChrIG9mIGFkZGVkS2V5cykge1xuICAgIG5ld1BhdGggPSBwYXRoLmNvbmNhdChba10pO1xuICAgIG5ld0tleVBhdGggPSBza2lwUGF0aCA/IGtleVBhdGggOiBrZXlQYXRoLmNvbmNhdChba10pO1xuICAgIC8vIENoZWNrIGlmIHRoZSBwYXRoIHNob3VsZCBiZSBza2lwcGVkXG4gICAgY29uc3QgY3VycmVudFBhdGggPSBuZXdLZXlQYXRoLmpvaW4oJy4nKTtcbiAgICBpZiAob3B0aW9ucy5rZXlzVG9Ta2lwPy5zb21lKHNraXBQYXRoID0+IGN1cnJlbnRQYXRoID09PSBza2lwUGF0aCB8fCBjdXJyZW50UGF0aC5zdGFydHNXaXRoKHNraXBQYXRoICsgJy4nKSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIGFkZGluZyB0aGlzIGtleVxuICAgIH1cbiAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgdHlwZTogT3BlcmF0aW9uLkFERCxcbiAgICAgIGtleTogZ2V0S2V5KG5ld1BhdGgpLFxuICAgICAgdmFsdWU6IG5ld09ialtrXVxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgZGVsZXRlZEtleXMgPSBkaWZmZXJlbmNlKG9sZE9iaktleXMsIG5ld09iaktleXMpO1xuICBmb3IgKGsgb2YgZGVsZXRlZEtleXMpIHtcbiAgICBuZXdQYXRoID0gcGF0aC5jb25jYXQoW2tdKTtcbiAgICBuZXdLZXlQYXRoID0gc2tpcFBhdGggPyBrZXlQYXRoIDoga2V5UGF0aC5jb25jYXQoW2tdKTtcbiAgICAvLyBDaGVjayBpZiB0aGUgcGF0aCBzaG91bGQgYmUgc2tpcHBlZFxuICAgIGNvbnN0IGN1cnJlbnRQYXRoID0gbmV3S2V5UGF0aC5qb2luKCcuJyk7XG4gICAgaWYgKG9wdGlvbnMua2V5c1RvU2tpcD8uc29tZShza2lwUGF0aCA9PiBjdXJyZW50UGF0aCA9PT0gc2tpcFBhdGggfHwgY3VycmVudFBhdGguc3RhcnRzV2l0aChza2lwUGF0aCArICcuJykpKSB7XG4gICAgICBjb250aW51ZTsgLy8gU2tpcCByZW1vdmluZyB0aGlzIGtleVxuICAgIH1cbiAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgdHlwZTogT3BlcmF0aW9uLlJFTU9WRSxcbiAgICAgIGtleTogZ2V0S2V5KG5ld1BhdGgpLFxuICAgICAgdmFsdWU6IG9sZE9ialtrXVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBjaGFuZ2VzO1xufTtcblxuY29uc3QgY29tcGFyZUFycmF5ID0gKG9sZE9iajogYW55LCBuZXdPYmo6IGFueSwgcGF0aDogYW55LCBrZXlQYXRoOiBhbnksIG9wdGlvbnM6IE9wdGlvbnMpID0+IHtcbiAgaWYgKGdldFR5cGVPZk9iaihuZXdPYmopICE9PSAnQXJyYXknKSB7XG4gICAgcmV0dXJuIFt7IHR5cGU6IE9wZXJhdGlvbi5VUERBVEUsIGtleTogZ2V0S2V5KHBhdGgpLCB2YWx1ZTogbmV3T2JqLCBvbGRWYWx1ZTogb2xkT2JqIH1dO1xuICB9XG5cbiAgY29uc3QgbGVmdCA9IGdldE9iamVjdEtleShvcHRpb25zLmVtYmVkZGVkT2JqS2V5cywga2V5UGF0aCk7XG4gIGNvbnN0IHVuaXFLZXkgPSBsZWZ0ICE9IG51bGwgPyBsZWZ0IDogJyRpbmRleCc7XG4gIGNvbnN0IGluZGV4ZWRPbGRPYmogPSBjb252ZXJ0QXJyYXlUb09iaihvbGRPYmosIHVuaXFLZXkpO1xuICBjb25zdCBpbmRleGVkTmV3T2JqID0gY29udmVydEFycmF5VG9PYmoobmV3T2JqLCB1bmlxS2V5KTtcbiAgY29uc3QgZGlmZnMgPSBjb21wYXJlT2JqZWN0KGluZGV4ZWRPbGRPYmosIGluZGV4ZWROZXdPYmosIHBhdGgsIGtleVBhdGgsIHRydWUsIG9wdGlvbnMpO1xuICBpZiAoZGlmZnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogT3BlcmF0aW9uLlVQREFURSxcbiAgICAgICAga2V5OiBnZXRLZXkocGF0aCksXG4gICAgICAgIGVtYmVkZGVkS2V5OiB0eXBlb2YgdW5pcUtleSA9PT0gJ2Z1bmN0aW9uJyAmJiB1bmlxS2V5Lmxlbmd0aCA9PT0gMiA/IHVuaXFLZXkobmV3T2JqWzBdLCB0cnVlKSA6IHVuaXFLZXksXG4gICAgICAgIGNoYW5nZXM6IGRpZmZzXG4gICAgICB9XG4gICAgXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn07XG5cbmNvbnN0IGdldE9iamVjdEtleSA9IChlbWJlZGRlZE9iaktleXM6IGFueSwga2V5UGF0aDogYW55KSA9PiB7XG4gIGlmIChlbWJlZGRlZE9iaktleXMgIT0gbnVsbCkge1xuICAgIGNvbnN0IHBhdGggPSBrZXlQYXRoLmpvaW4oJy4nKTtcblxuICAgIGlmIChlbWJlZGRlZE9iaktleXMgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGVtYmVkZGVkT2JqS2V5cy5lbnRyaWVzKCkpIHtcbiAgICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgIGlmIChwYXRoLm1hdGNoKGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocGF0aCA9PT0ga2V5KSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gZW1iZWRkZWRPYmpLZXlzW3BhdGhdO1xuICAgIGlmIChrZXkgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbmNvbnN0IGNvbnZlcnRBcnJheVRvT2JqID0gKGFycjogYW55W10sIHVuaXFLZXk6IGFueSkgPT4ge1xuICBsZXQgb2JqOiBhbnkgPSB7fTtcbiAgaWYgKHVuaXFLZXkgPT09ICckdmFsdWUnKSB7XG4gICAgYXJyLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICBvYmpbdmFsdWVdID0gdmFsdWU7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodW5pcUtleSAhPT0gJyRpbmRleCcpIHtcbiAgICAvLyBDb252ZXJ0IHN0cmluZyBrZXlzIHRvIGZ1bmN0aW9ucyBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIGVzLXRvb2xraXQga2V5QnlcbiAgICBjb25zdCBrZXlGdW5jdGlvbiA9IHR5cGVvZiB1bmlxS2V5ID09PSAnc3RyaW5nJyA/IChpdGVtOiBhbnkpID0+IGl0ZW1bdW5pcUtleV0gOiB1bmlxS2V5O1xuICAgIG9iaiA9IGtleUJ5KGFyciwga2V5RnVuY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGFycltpXTtcbiAgICAgIG9ialtpXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufTtcblxuY29uc3QgY29tcGFyZVByaW1pdGl2ZXMgPSAob2xkT2JqOiBhbnksIG5ld09iajogYW55LCBwYXRoOiBhbnkpID0+IHtcbiAgY29uc3QgY2hhbmdlcyA9IFtdO1xuICBpZiAob2xkT2JqICE9PSBuZXdPYmopIHtcbiAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgdHlwZTogT3BlcmF0aW9uLlVQREFURSxcbiAgICAgIGtleTogZ2V0S2V5KHBhdGgpLFxuICAgICAgdmFsdWU6IG5ld09iaixcbiAgICAgIG9sZFZhbHVlOiBvbGRPYmpcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY2hhbmdlcztcbn07XG5cbmNvbnN0IHJlbW92ZUtleSA9IChvYmo6IGFueSwga2V5OiBhbnksIGVtYmVkZGVkS2V5OiBhbnkpID0+IHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIGlmIChlbWJlZGRlZEtleSA9PT0gJyRpbmRleCcpIHtcbiAgICAgIG9iai5zcGxpY2UoTnVtYmVyKGtleSksIDEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IGluZGV4T2ZJdGVtSW5BcnJheShvYmosIGVtYmVkZGVkS2V5LCBrZXkpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1jb25zb2xlXG4gICAgICBjb25zb2xlLndhcm4oYEVsZW1lbnQgd2l0aCB0aGUga2V5ICcke2VtYmVkZGVkS2V5fScgYW5kIHZhbHVlICcke2tleX0nIGNvdWxkIG5vdCBiZSBmb3VuZCBpbiB0aGUgYXJyYXknYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBvYmouc3BsaWNlKGluZGV4ICE9IG51bGwgPyBpbmRleCA6IGtleSwgMSk7XG4gIH0gZWxzZSB7XG4gICAgZGVsZXRlIG9ialtrZXldO1xuICAgIHJldHVybjtcbiAgfVxufTtcblxuY29uc3QgaW5kZXhPZkl0ZW1JbkFycmF5ID0gKGFycjogYW55W10sIGtleTogYW55LCB2YWx1ZTogYW55KSA9PiB7XG4gIGlmIChrZXkgPT09ICckdmFsdWUnKSB7XG4gICAgcmV0dXJuIGFyci5pbmRleE9mKHZhbHVlKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGl0ZW0gPSBhcnJbaV07XG4gICAgaWYgKGl0ZW0gJiYgaXRlbVtrZXldID8gaXRlbVtrZXldLnRvU3RyaW5nKCkgPT09IHZhbHVlLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59O1xuXG5jb25zdCBtb2RpZnlLZXlWYWx1ZSA9IChvYmo6IGFueSwga2V5OiBhbnksIHZhbHVlOiBhbnkpID0+IChvYmpba2V5XSA9IHZhbHVlKTtcbmNvbnN0IGFkZEtleVZhbHVlID0gKG9iajogYW55LCBrZXk6IGFueSwgdmFsdWU6IGFueSwgZW1iZWRkZWRLZXk/OiBhbnkpID0+IHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIGlmIChlbWJlZGRlZEtleSA9PT0gJyRpbmRleCcpIHtcbiAgICAgIG9iai5zcGxpY2UoTnVtYmVyKGtleSksIDAsIHZhbHVlKTtcbiAgICAgIHJldHVybiBvYmoubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gb2JqLnB1c2godmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmogPyAob2JqW2tleV0gPSB2YWx1ZSkgOiBudWxsO1xuICB9XG59O1xuXG5jb25zdCBhcHBseUxlYWZDaGFuZ2UgPSAob2JqOiBhbnksIGNoYW5nZTogYW55LCBlbWJlZGRlZEtleTogYW55KSA9PiB7XG4gIGNvbnN0IHsgdHlwZSwga2V5LCB2YWx1ZSB9ID0gY2hhbmdlO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIE9wZXJhdGlvbi5BREQ6XG4gICAgICByZXR1cm4gYWRkS2V5VmFsdWUob2JqLCBrZXksIHZhbHVlLCBlbWJlZGRlZEtleSk7XG4gICAgY2FzZSBPcGVyYXRpb24uVVBEQVRFOlxuICAgICAgcmV0dXJuIG1vZGlmeUtleVZhbHVlKG9iaiwga2V5LCB2YWx1ZSk7XG4gICAgY2FzZSBPcGVyYXRpb24uUkVNT1ZFOlxuICAgICAgcmV0dXJuIHJlbW92ZUtleShvYmosIGtleSwgZW1iZWRkZWRLZXkpO1xuICB9XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgY2hhbmdlcyB0byBhbiBhcnJheS5cbiAqIFxuICogQHBhcmFtIHthbnlbXX0gYXJyIC0gVGhlIGFycmF5IHRvIGFwcGx5IGNoYW5nZXMgdG8uXG4gKiBAcGFyYW0ge2FueX0gY2hhbmdlIC0gVGhlIGNoYW5nZSB0byBhcHBseSwgY29udGFpbmluZyBuZXN0ZWQgY2hhbmdlcy5cbiAqIEByZXR1cm5zIHthbnlbXX0gLSBUaGUgYXJyYXkgYWZ0ZXIgY2hhbmdlcyBoYXZlIGJlZW4gYXBwbGllZC5cbiAqXG4gKiBOb3RlOiBUaGlzIGZ1bmN0aW9uIG1vZGlmaWVzIHRoZSBhcnJheSBpbi1wbGFjZSBidXQgYWxzbyByZXR1cm5zIGl0IGZvclxuICogY29uc2lzdGVuY3kgd2l0aCBvdGhlciBmdW5jdGlvbnMuXG4gKi9cbmNvbnN0IGFwcGx5QXJyYXlDaGFuZ2UgPSAoYXJyOiBhbnlbXSwgY2hhbmdlOiBhbnkpID0+IHtcbiAgbGV0IGNoYW5nZXMgPSBjaGFuZ2UuY2hhbmdlcztcbiAgaWYgKGNoYW5nZS5lbWJlZGRlZEtleSA9PT0gJyRpbmRleCcpIHtcbiAgICBjaGFuZ2VzID0gWy4uLmNoYW5nZXNdLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGlmIChhLnR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUgJiYgYi50eXBlID09PSBPcGVyYXRpb24uUkVNT1ZFKSB7XG4gICAgICAgIHJldHVybiBOdW1iZXIoYi5rZXkpIC0gTnVtYmVyKGEua2V5KTtcbiAgICAgIH1cbiAgICAgIGlmIChhLnR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUpIHJldHVybiAtMTtcbiAgICAgIGlmIChiLnR5cGUgPT09IE9wZXJhdGlvbi5SRU1PVkUpIHJldHVybiAxO1xuICAgICAgcmV0dXJuIE51bWJlcihhLmtleSkgLSBOdW1iZXIoYi5rZXkpO1xuICAgIH0pO1xuICB9XG5cbiAgZm9yIChjb25zdCBzdWJjaGFuZ2Ugb2YgY2hhbmdlcykge1xuICAgIGlmIChcbiAgICAgIChzdWJjaGFuZ2UudmFsdWUgIT09IG51bGwgJiYgc3ViY2hhbmdlLnZhbHVlICE9PSB1bmRlZmluZWQpIHx8XG4gICAgICBzdWJjaGFuZ2UudHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSB8fFxuICAgICAgKHN1YmNoYW5nZS52YWx1ZSA9PT0gbnVsbCAmJiBzdWJjaGFuZ2UudHlwZSA9PT0gT3BlcmF0aW9uLkFERClcbiAgICApIHtcbiAgICAgIGFwcGx5TGVhZkNoYW5nZShhcnIsIHN1YmNoYW5nZSwgY2hhbmdlLmVtYmVkZGVkS2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGVsZW1lbnQ7XG4gICAgICBpZiAoY2hhbmdlLmVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgICAgICBlbGVtZW50ID0gYXJyW3N1YmNoYW5nZS5rZXldO1xuICAgICAgfSBlbHNlIGlmIChjaGFuZ2UuZW1iZWRkZWRLZXkgPT09ICckdmFsdWUnKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gYXJyLmluZGV4T2Yoc3ViY2hhbmdlLmtleSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBlbGVtZW50ID0gYXJyW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudCA9IGFyci5maW5kKChlbCkgPT4gZWxbY2hhbmdlLmVtYmVkZGVkS2V5XT8udG9TdHJpbmcoKSA9PT0gc3ViY2hhbmdlLmtleS50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGFwcGx5Q2hhbmdlc2V0KGVsZW1lbnQsIHN1YmNoYW5nZS5jaGFuZ2VzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG5cbmNvbnN0IGFwcGx5QnJhbmNoQ2hhbmdlID0gKG9iajogYW55LCBjaGFuZ2U6IGFueSkgPT4ge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIGFwcGx5QXJyYXlDaGFuZ2Uob2JqLCBjaGFuZ2UpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBhcHBseUNoYW5nZXNldChvYmosIGNoYW5nZS5jaGFuZ2VzKTtcbiAgfVxufTtcblxuY29uc3QgcmV2ZXJ0TGVhZkNoYW5nZSA9IChvYmo6IGFueSwgY2hhbmdlOiBhbnksIGVtYmVkZGVkS2V5ID0gJyRpbmRleCcpID0+IHtcbiAgY29uc3QgeyB0eXBlLCBrZXksIHZhbHVlLCBvbGRWYWx1ZSB9ID0gY2hhbmdlO1xuICBcbiAgLy8gU3BlY2lhbCBoYW5kbGluZyBmb3IgJHJvb3Qga2V5XG4gIGlmIChrZXkgPT09ICckcm9vdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgT3BlcmF0aW9uLkFERDpcbiAgICAgICAgLy8gV2hlbiByZXZlcnRpbmcgYW4gQUREIG9mIHRoZSBlbnRpcmUgb2JqZWN0LCBjbGVhciBhbGwgcHJvcGVydGllc1xuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gb2JqKSB7XG4gICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSB7XG4gICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgY2FzZSBPcGVyYXRpb24uVVBEQVRFOlxuICAgICAgICAvLyBSZXBsYWNlIHRoZSBlbnRpcmUgb2JqZWN0IHdpdGggdGhlIG9sZCB2YWx1ZVxuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gb2JqKSB7XG4gICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSB7XG4gICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob2xkVmFsdWUgJiYgdHlwZW9mIG9sZFZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24ob2JqLCBvbGRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgIGNhc2UgT3BlcmF0aW9uLlJFTU9WRTpcbiAgICAgICAgLy8gUmVzdG9yZSB0aGUgcmVtb3ZlZCBvYmplY3RcbiAgICAgICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBPYmplY3QuYXNzaWduKG9iaiwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICB9XG4gIFxuICAvLyBSZWd1bGFyIHByb3BlcnR5IGhhbmRsaW5nXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgT3BlcmF0aW9uLkFERDpcbiAgICAgIHJldHVybiByZW1vdmVLZXkob2JqLCBrZXksIGVtYmVkZGVkS2V5KTtcbiAgICBjYXNlIE9wZXJhdGlvbi5VUERBVEU6XG4gICAgICByZXR1cm4gbW9kaWZ5S2V5VmFsdWUob2JqLCBrZXksIG9sZFZhbHVlKTtcbiAgICBjYXNlIE9wZXJhdGlvbi5SRU1PVkU6XG4gICAgICByZXR1cm4gYWRkS2V5VmFsdWUob2JqLCBrZXksIHZhbHVlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXZlcnRzIGNoYW5nZXMgaW4gYW4gYXJyYXkuXG4gKiBcbiAqIEBwYXJhbSB7YW55W119IGFyciAtIFRoZSBhcnJheSB0byByZXZlcnQgY2hhbmdlcyBpbi5cbiAqIEBwYXJhbSB7YW55fSBjaGFuZ2UgLSBUaGUgY2hhbmdlIHRvIHJldmVydCwgY29udGFpbmluZyBuZXN0ZWQgY2hhbmdlcy5cbiAqIEByZXR1cm5zIHthbnlbXX0gLSBUaGUgYXJyYXkgYWZ0ZXIgY2hhbmdlcyBoYXZlIGJlZW4gcmV2ZXJ0ZWQuXG4gKlxuICogTm90ZTogVGhpcyBmdW5jdGlvbiBtb2RpZmllcyB0aGUgYXJyYXkgaW4tcGxhY2UgYnV0IGFsc28gcmV0dXJucyBpdCBmb3JcbiAqIGNvbnNpc3RlbmN5IHdpdGggb3RoZXIgZnVuY3Rpb25zLlxuICovXG5jb25zdCByZXZlcnRBcnJheUNoYW5nZSA9IChhcnI6IGFueVtdLCBjaGFuZ2U6IGFueSkgPT4ge1xuICBmb3IgKGNvbnN0IHN1YmNoYW5nZSBvZiBjaGFuZ2UuY2hhbmdlcykge1xuICAgIGlmIChzdWJjaGFuZ2UudmFsdWUgIT0gbnVsbCB8fCBzdWJjaGFuZ2UudHlwZSA9PT0gT3BlcmF0aW9uLlJFTU9WRSkge1xuICAgICAgcmV2ZXJ0TGVhZkNoYW5nZShhcnIsIHN1YmNoYW5nZSwgY2hhbmdlLmVtYmVkZGVkS2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGVsZW1lbnQ7XG4gICAgICBpZiAoY2hhbmdlLmVtYmVkZGVkS2V5ID09PSAnJGluZGV4Jykge1xuICAgICAgICBlbGVtZW50ID0gYXJyWytzdWJjaGFuZ2Uua2V5XTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhbmdlLmVtYmVkZGVkS2V5ID09PSAnJHZhbHVlJykge1xuICAgICAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKHN1YmNoYW5nZS5rZXkpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgZWxlbWVudCA9IGFycltpbmRleF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBhcnIuZmluZCgoZWwpID0+IGVsW2NoYW5nZS5lbWJlZGRlZEtleV0/LnRvU3RyaW5nKCkgPT09IHN1YmNoYW5nZS5rZXkudG9TdHJpbmcoKSk7XG4gICAgICB9XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICByZXZlcnRDaGFuZ2VzZXQoZWxlbWVudCwgc3ViY2hhbmdlLmNoYW5nZXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gYXJyO1xufTtcblxuY29uc3QgcmV2ZXJ0QnJhbmNoQ2hhbmdlID0gKG9iajogYW55LCBjaGFuZ2U6IGFueSkgPT4ge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIHJldmVydEFycmF5Q2hhbmdlKG9iaiwgY2hhbmdlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcmV2ZXJ0Q2hhbmdlc2V0KG9iaiwgY2hhbmdlLmNoYW5nZXMpO1xuICB9XG59O1xuXG4vKiogY29tYmluZSBhIGJhc2UgSlNPTiBQYXRoIHdpdGggYSBzdWJzZXF1ZW50IHNlZ21lbnQgKi9cbmZ1bmN0aW9uIGFwcGVuZChiYXNlUGF0aDogc3RyaW5nLCBuZXh0U2VnbWVudDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5leHRTZWdtZW50LmluY2x1ZGVzKCcuJykgPyBgJHtiYXNlUGF0aH1bJHtuZXh0U2VnbWVudH1dYCA6IGAke2Jhc2VQYXRofS4ke25leHRTZWdtZW50fWA7XG59XG5cbi8qKiByZXR1cm5zIGEgSlNPTiBQYXRoIGZpbHRlciBleHByZXNzaW9uOyBlLmcuLCBgJC5wZXRbKD9uYW1lPSdzcG90JyldYCAqL1xuZnVuY3Rpb24gZmlsdGVyRXhwcmVzc2lvbihiYXNlUGF0aDogc3RyaW5nLCBmaWx0ZXJLZXk6IHN0cmluZyB8IEZ1bmN0aW9uS2V5LCBmaWx0ZXJWYWx1ZTogc3RyaW5nIHwgbnVtYmVyKSB7XG4gIGNvbnN0IHZhbHVlID0gdHlwZW9mIGZpbHRlclZhbHVlID09PSAnbnVtYmVyJyA/IGZpbHRlclZhbHVlIDogYCcke2ZpbHRlclZhbHVlfSdgO1xuICByZXR1cm4gdHlwZW9mIGZpbHRlcktleSA9PT0gJ3N0cmluZycgJiYgZmlsdGVyS2V5LmluY2x1ZGVzKCcuJylcbiAgICA/IGAke2Jhc2VQYXRofVs/KEBbJHtmaWx0ZXJLZXl9XT09JHt2YWx1ZX0pXWBcbiAgICA6IGAke2Jhc2VQYXRofVs/KEAuJHtmaWx0ZXJLZXl9PT0ke3ZhbHVlfSldYDtcbn1cblxuZXhwb3J0IHtcbiAgQ2hhbmdlc2V0LFxuICBFbWJlZGRlZE9iaktleXNNYXBUeXBlLFxuICBFbWJlZGRlZE9iaktleXNUeXBlLFxuICBJQXRvbWljQ2hhbmdlLFxuICBJQ2hhbmdlLFxuICBPcGVyYXRpb24sXG4gIE9wdGlvbnMsXG4gIGFwcGx5Q2hhbmdlc2V0LFxuICBhdG9taXplQ2hhbmdlc2V0LFxuICBkaWZmLFxuICBnZXRUeXBlT2ZPYmosXG4gIHJldmVydENoYW5nZXNldCxcbiAgdW5hdG9taXplQ2hhbmdlc2V0XG59O1xuIiwgImltcG9ydCB7IHNldEJ5UGF0aCB9IGZyb20gJy4vaGVscGVycy5qcyc7XG5pbXBvcnQgeyBkaWZmLCBhdG9taXplQ2hhbmdlc2V0LCBnZXRUeXBlT2ZPYmosIElBdG9taWNDaGFuZ2UsIE9wZXJhdGlvbiB9IGZyb20gJy4vanNvbkRpZmYuanMnO1xuXG5lbnVtIENvbXBhcmVPcGVyYXRpb24ge1xuICBDT05UQUlORVIgPSAnQ09OVEFJTkVSJyxcbiAgVU5DSEFOR0VEID0gJ1VOQ0hBTkdFRCdcbn1cblxuaW50ZXJmYWNlIElDb21wYXJpc29uRW5yaWNoZWROb2RlIHtcbiAgdHlwZTogT3BlcmF0aW9uIHwgQ29tcGFyZU9wZXJhdGlvbjtcbiAgdmFsdWU6IElDb21wYXJpc29uRW5yaWNoZWROb2RlIHwgSUNvbXBhcmlzb25FbnJpY2hlZE5vZGVbXSB8IGFueSB8IGFueVtdO1xuICBvbGRWYWx1ZT86IGFueTtcbn1cblxuY29uc3QgY3JlYXRlVmFsdWUgPSAodmFsdWU6IGFueSk6IElDb21wYXJpc29uRW5yaWNoZWROb2RlID0+ICh7IHR5cGU6IENvbXBhcmVPcGVyYXRpb24uVU5DSEFOR0VELCB2YWx1ZSB9KTtcbmNvbnN0IGNyZWF0ZUNvbnRhaW5lciA9ICh2YWx1ZTogb2JqZWN0IHwgW10pOiBJQ29tcGFyaXNvbkVucmljaGVkTm9kZSA9PiAoe1xuICB0eXBlOiBDb21wYXJlT3BlcmF0aW9uLkNPTlRBSU5FUixcbiAgdmFsdWVcbn0pO1xuXG5jb25zdCBlbnJpY2ggPSAob2JqZWN0OiBhbnkpOiBJQ29tcGFyaXNvbkVucmljaGVkTm9kZSA9PiB7XG4gIGNvbnN0IG9iamVjdFR5cGUgPSBnZXRUeXBlT2ZPYmoob2JqZWN0KTtcblxuICBzd2l0Y2ggKG9iamVjdFR5cGUpIHtcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iamVjdClcbiAgICAgICAgLm1hcCgoa2V5OiBzdHJpbmcpID0+ICh7IGtleSwgdmFsdWU6IGVucmljaChvYmplY3Rba2V5XSkgfSkpXG4gICAgICAgIC5yZWR1Y2UoKGFjY3VtdWxhdG9yLCBlbnRyeSkgPT4ge1xuICAgICAgICAgIGFjY3VtdWxhdG9yLnZhbHVlW2VudHJ5LmtleV0gPSBlbnRyeS52YWx1ZTtcbiAgICAgICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgICAgIH0sIGNyZWF0ZUNvbnRhaW5lcih7fSkpO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiAob2JqZWN0IGFzIGFueVtdKVxuICAgICAgICAubWFwKCh2YWx1ZSkgPT4gZW5yaWNoKHZhbHVlKSlcbiAgICAgICAgLnJlZHVjZSgoYWNjdW11bGF0b3IsIHZhbHVlKSA9PiB7XG4gICAgICAgICAgYWNjdW11bGF0b3IudmFsdWUucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgICAgICB9LCBjcmVhdGVDb250YWluZXIoW10pKTtcbiAgICBjYXNlICdGdW5jdGlvbic6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBQcmltaXRpdmUgdmFsdWVcbiAgICAgIHJldHVybiBjcmVhdGVWYWx1ZShvYmplY3QpO1xuICB9XG59O1xuXG5jb25zdCBhcHBseUNoYW5nZWxpc3QgPSAob2JqZWN0OiBJQ29tcGFyaXNvbkVucmljaGVkTm9kZSwgY2hhbmdlbGlzdDogSUF0b21pY0NoYW5nZVtdKTogSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUgPT4ge1xuICBjaGFuZ2VsaXN0XG4gICAgLm1hcCgoZW50cnkpID0+ICh7IC4uLmVudHJ5LCBwYXRoOiBlbnRyeS5wYXRoLnJlcGxhY2UoJyQuJywgJy4nKSB9KSlcbiAgICAubWFwKChlbnRyeSkgPT4gKHtcbiAgICAgIC4uLmVudHJ5LFxuICAgICAgcGF0aDogZW50cnkucGF0aC5yZXBsYWNlKC8oXFxbKD88YXJyYXk+XFxkKVxcXVxcLikvZywgJ0FSUlZBTF9TVEFSVCQ8YXJyYXk+QVJSVkFMX0VORCcpXG4gICAgfSkpXG4gICAgLm1hcCgoZW50cnkpID0+ICh7IC4uLmVudHJ5LCBwYXRoOiBlbnRyeS5wYXRoLnJlcGxhY2UoLyg/PGRvdD5cXC4pL2csICcudmFsdWUkPGRvdD4nKSB9KSlcbiAgICAubWFwKChlbnRyeSkgPT4gKHsgLi4uZW50cnksIHBhdGg6IGVudHJ5LnBhdGgucmVwbGFjZSgvXFwuLywgJycpIH0pKVxuICAgIC5tYXAoKGVudHJ5KSA9PiAoeyAuLi5lbnRyeSwgcGF0aDogZW50cnkucGF0aC5yZXBsYWNlKC9BUlJWQUxfU1RBUlQvZywgJy52YWx1ZVsnKSB9KSlcbiAgICAubWFwKChlbnRyeSkgPT4gKHsgLi4uZW50cnksIHBhdGg6IGVudHJ5LnBhdGgucmVwbGFjZSgvQVJSVkFMX0VORC9nLCAnXS52YWx1ZS4nKSB9KSlcbiAgICAuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIHN3aXRjaCAoZW50cnkudHlwZSkge1xuICAgICAgICBjYXNlIE9wZXJhdGlvbi5BREQ6XG4gICAgICAgIGNhc2UgT3BlcmF0aW9uLlVQREFURTpcbiAgICAgICAgICBzZXRCeVBhdGgob2JqZWN0LCBlbnRyeS5wYXRoLCB7IHR5cGU6IGVudHJ5LnR5cGUsIHZhbHVlOiBlbnRyeS52YWx1ZSwgb2xkVmFsdWU6IGVudHJ5Lm9sZFZhbHVlIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE9wZXJhdGlvbi5SRU1PVkU6XG4gICAgICAgICAgc2V0QnlQYXRoKG9iamVjdCwgZW50cnkucGF0aCwgeyB0eXBlOiBlbnRyeS50eXBlLCB2YWx1ZTogdW5kZWZpbmVkLCBvbGRWYWx1ZTogZW50cnkudmFsdWUgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBjb21wYXJlID0gKG9sZE9iamVjdDogYW55LCBuZXdPYmplY3Q6IGFueSk6IElDb21wYXJpc29uRW5yaWNoZWROb2RlID0+IHtcbiAgcmV0dXJuIGFwcGx5Q2hhbmdlbGlzdChlbnJpY2gob2xkT2JqZWN0KSwgYXRvbWl6ZUNoYW5nZXNldChkaWZmKG9sZE9iamVjdCwgbmV3T2JqZWN0KSkpO1xufTtcblxuZXhwb3J0IHsgQ29tcGFyZU9wZXJhdGlvbiwgSUNvbXBhcmlzb25FbnJpY2hlZE5vZGUsIGNyZWF0ZVZhbHVlLCBjcmVhdGVDb250YWluZXIsIGVucmljaCwgYXBwbHlDaGFuZ2VsaXN0LCBjb21wYXJlIH07XG4iLCAiaW1wb3J0IHsgU3luY1BsdWdpbiB9IGZyb20gJy4vU3luY1BsdWdpbic7XG5pbXBvcnQgeyBDb3JlRXZlbnRzIH0gZnJvbSAnLi4vY29uc3RhbnRzL0NvcmVFdmVudHMnO1xuaW1wb3J0IHsgZGlmZiB9IGZyb20gJ2pzb24tZGlmZi10cyc7XG4vKipcbiAqIEJhc2VFbnRpdHlTZXJ2aWNlPFQgZXh0ZW5kcyBJU3luYz4gLSBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgZW50aXR5IHNlcnZpY2VzXG4gKlxuICogUFJPVklERVM6XG4gKiAtIEdlbmVyaWMgQ1JVRCBvcGVyYXRpb25zIChnZXQsIGdldEFsbCwgc2F2ZSwgZGVsZXRlKVxuICogLSBTeW5jIHN0YXR1cyBtYW5hZ2VtZW50IChkZWxlZ2F0ZXMgdG8gU3luY1BsdWdpbilcbiAqIC0gU2VyaWFsaXphdGlvbiBob29rcyAob3ZlcnJpZGUgaW4gc3ViY2xhc3MgaWYgbmVlZGVkKVxuICovXG5leHBvcnQgY2xhc3MgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5zeW5jUGx1Z2luID0gbmV3IFN5bmNQbHVnaW4odGhpcyk7XG4gICAgfVxuICAgIGdldCBkYigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5nZXREYXRhYmFzZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXJpYWxpemUgZW50aXR5IGJlZm9yZSBzdG9yaW5nIGluIEluZGV4ZWREQlxuICAgICAqL1xuICAgIHNlcmlhbGl6ZShlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzZXJpYWxpemUgZGF0YSBmcm9tIEluZGV4ZWREQiBiYWNrIHRvIGVudGl0eVxuICAgICAqL1xuICAgIGRlc2VyaWFsaXplKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIHNpbmdsZSBlbnRpdHkgYnkgSURcbiAgICAgKi9cbiAgICBhc3luYyBnZXQoaWQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmdldChpZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhID8gdGhpcy5kZXNlcmlhbGl6ZShkYXRhKSA6IG51bGwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0ICR7dGhpcy5lbnRpdHlUeXBlfSAke2lkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIGVudGl0aWVzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QWxsKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUuZ2V0QWxsKCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXRpZXMgPSBkYXRhLm1hcChpdGVtID0+IHRoaXMuZGVzZXJpYWxpemUoaXRlbSkpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoZW50aXRpZXMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGFsbCAke3RoaXMuZW50aXR5VHlwZX1zOiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNhdmUgYW4gZW50aXR5IChjcmVhdGUgb3IgdXBkYXRlKVxuICAgICAqIEVtaXRzIEVOVElUWV9TQVZFRCBldmVudCB3aXRoIG9wZXJhdGlvbiB0eXBlIGFuZCBjaGFuZ2VzIChkaWZmIGZvciB1cGRhdGVzKVxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBFbnRpdHkgdG8gc2F2ZVxuICAgICAqIEBwYXJhbSBzaWxlbnQgLSBJZiB0cnVlLCBza2lwIGV2ZW50IGVtaXNzaW9uICh1c2VkIGZvciBzZWVkaW5nKVxuICAgICAqL1xuICAgIGFzeW5jIHNhdmUoZW50aXR5LCBzaWxlbnQgPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBlbnRpdHlJZCA9IGVudGl0eS5pZDtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdFbnRpdHkgPSBhd2FpdCB0aGlzLmdldChlbnRpdHlJZCk7XG4gICAgICAgIGNvbnN0IGlzQ3JlYXRlID0gZXhpc3RpbmdFbnRpdHkgPT09IG51bGw7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBjaGFuZ2VzOiBmdWxsIGVudGl0eSBmb3IgY3JlYXRlLCBkaWZmIGZvciB1cGRhdGVcbiAgICAgICAgbGV0IGNoYW5nZXM7XG4gICAgICAgIGlmIChpc0NyZWF0ZSkge1xuICAgICAgICAgICAgY2hhbmdlcyA9IGVudGl0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nU2VyaWFsaXplZCA9IHRoaXMuc2VyaWFsaXplKGV4aXN0aW5nRW50aXR5KTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1NlcmlhbGl6ZWQgPSB0aGlzLnNlcmlhbGl6ZShlbnRpdHkpO1xuICAgICAgICAgICAgY2hhbmdlcyA9IGRpZmYoZXhpc3RpbmdTZXJpYWxpemVkLCBuZXdTZXJpYWxpemVkKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gdGhpcy5zZXJpYWxpemUoZW50aXR5KTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZHdyaXRlJyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5wdXQoc2VyaWFsaXplZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGVtaXQgZXZlbnQgaWYgbm90IHNpbGVudCAoc2lsZW50IHVzZWQgZm9yIHNlZWRpbmcpXG4gICAgICAgICAgICAgICAgaWYgKCFzaWxlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVR5cGU6IHRoaXMuZW50aXR5VHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uOiBpc0NyZWF0ZSA/ICdjcmVhdGUnIDogJ3VwZGF0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVOVElUWV9TQVZFRCwgcGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIHNhdmUgJHt0aGlzLmVudGl0eVR5cGV9ICR7ZW50aXR5SWR9OiAke3JlcXVlc3QuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBhbiBlbnRpdHlcbiAgICAgKiBFbWl0cyBFTlRJVFlfREVMRVRFRCBldmVudFxuICAgICAqL1xuICAgIGFzeW5jIGRlbGV0ZShpZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmRlbGV0ZShpZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlUeXBlOiB0aGlzLmVudGl0eVR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FTlRJVFlfREVMRVRFRCwgcGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZGVsZXRlICR7dGhpcy5lbnRpdHlUeXBlfSAke2lkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBTeW5jIG1ldGhvZHMgLSBkZWxlZ2F0ZSB0byBTeW5jUGx1Z2luXG4gICAgYXN5bmMgbWFya0FzU3luY2VkKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmNQbHVnaW4ubWFya0FzU3luY2VkKGlkKTtcbiAgICB9XG4gICAgYXN5bmMgbWFya0FzRXJyb3IoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY1BsdWdpbi5tYXJrQXNFcnJvcihpZCk7XG4gICAgfVxuICAgIGFzeW5jIGdldFN5bmNTdGF0dXMoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY1BsdWdpbi5nZXRTeW5jU3RhdHVzKGlkKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0QnlTeW5jU3RhdHVzKHN5bmNTdGF0dXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3luY1BsdWdpbi5nZXRCeVN5bmNTdGF0dXMoc3luY1N0YXR1cyk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEV2ZW50U3RvcmUgfSBmcm9tICcuL0V2ZW50U3RvcmUnO1xuaW1wb3J0IHsgRXZlbnRTZXJpYWxpemF0aW9uIH0gZnJvbSAnLi9FdmVudFNlcmlhbGl6YXRpb24nO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIEV2ZW50U2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgY2FsZW5kYXIgZXZlbnRzIGluIEluZGV4ZWREQlxuICpcbiAqIEV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2UgZm9yIHNoYXJlZCBDUlVEIGFuZCBzeW5jIGxvZ2ljLlxuICogUHJvdmlkZXMgZXZlbnQtc3BlY2lmaWMgcXVlcnkgbWV0aG9kcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50U2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gRXZlbnRTdG9yZS5TVE9SRV9OQU1FO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnRXZlbnQnO1xuICAgIH1cbiAgICBzZXJpYWxpemUoZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUoZXZlbnQpO1xuICAgIH1cbiAgICBkZXNlcmlhbGl6ZShkYXRhKSB7XG4gICAgICAgIHJldHVybiBFdmVudFNlcmlhbGl6YXRpb24uZGVzZXJpYWxpemUoZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBldmVudHMgd2l0aGluIGEgZGF0ZSByYW5nZVxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5RGF0ZVJhbmdlKHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5pbmRleCgnc3RhcnQnKTtcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gSURCS2V5UmFuZ2UubG93ZXJCb3VuZChzdGFydC50b0lTT1N0cmluZygpKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleC5nZXRBbGwocmFuZ2UpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IGRhdGFcbiAgICAgICAgICAgICAgICAgICAgLm1hcChpdGVtID0+IHRoaXMuZGVzZXJpYWxpemUoaXRlbSkpXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZXZlbnQgPT4gZXZlbnQuc3RhcnQgPD0gZW5kKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGV2ZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgZXZlbnRzIGJ5IGRhdGUgcmFuZ2U6ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGV2ZW50cyBmb3IgYSBzcGVjaWZpYyByZXNvdXJjZVxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5UmVzb3VyY2UocmVzb3VyY2VJZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdyZXNvdXJjZUlkJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKHJlc291cmNlSWQpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IGRhdGEubWFwKGl0ZW0gPT4gdGhpcy5kZXNlcmlhbGl6ZShpdGVtKSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShldmVudHMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IGV2ZW50cyBmb3IgcmVzb3VyY2UgJHtyZXNvdXJjZUlkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZXZlbnRzIGZvciBhIHJlc291cmNlIHdpdGhpbiBhIGRhdGUgcmFuZ2VcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVJlc291cmNlQW5kRGF0ZVJhbmdlKHJlc291cmNlSWQsIHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VFdmVudHMgPSBhd2FpdCB0aGlzLmdldEJ5UmVzb3VyY2UocmVzb3VyY2VJZCk7XG4gICAgICAgIHJldHVybiByZXNvdXJjZUV2ZW50cy5maWx0ZXIoZXZlbnQgPT4gZXZlbnQuc3RhcnQgPj0gc3RhcnQgJiYgZXZlbnQuc3RhcnQgPD0gZW5kKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBSZXNvdXJjZVN0b3JlIC0gSW5kZXhlZERCIE9iamVjdFN0b3JlIGRlZmluaXRpb24gZm9yIHJlc291cmNlc1xuICovXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gUmVzb3VyY2VTdG9yZS5TVE9SRV9OQU1FO1xuICAgIH1cbiAgICBjcmVhdGUoZGIpIHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBkYi5jcmVhdGVPYmplY3RTdG9yZShSZXNvdXJjZVN0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3R5cGUnLCAndHlwZScsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N5bmNTdGF0dXMnLCAnc3luY1N0YXR1cycsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ2lzQWN0aXZlJywgJ2lzQWN0aXZlJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgIH1cbn1cblJlc291cmNlU3RvcmUuU1RPUkVfTkFNRSA9ICdyZXNvdXJjZXMnO1xuIiwgImltcG9ydCB7IFJlc291cmNlU3RvcmUgfSBmcm9tICcuL1Jlc291cmNlU3RvcmUnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIFJlc291cmNlU2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgcmVzb3VyY2VzIGluIEluZGV4ZWREQlxuICovXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBSZXNvdXJjZVN0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdSZXNvdXJjZSc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgYWN0aXZlIHJlc291cmNlc1xuICAgICAqL1xuICAgIGFzeW5jIGdldEFjdGl2ZSgpIHtcbiAgICAgICAgY29uc3QgYWxsID0gYXdhaXQgdGhpcy5nZXRBbGwoKTtcbiAgICAgICAgcmV0dXJuIGFsbC5maWx0ZXIociA9PiByLmlzQWN0aXZlICE9PSBmYWxzZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCByZXNvdXJjZXMgYnkgSURzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlJZHMoaWRzKSB7XG4gICAgICAgIGlmIChpZHMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoaWRzLm1hcChpZCA9PiB0aGlzLmdldChpZCkpKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdHMuZmlsdGVyKChyKSA9PiByICE9PSBudWxsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHJlc291cmNlcyBieSB0eXBlXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlUeXBlKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbdGhpcy5zdG9yZU5hbWVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5pbmRleCgndHlwZScpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldEFsbCh0eXBlKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSByZXF1ZXN0LnJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHJlc291cmNlcyBieSB0eXBlICR7dHlwZX06ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBCb29raW5nU3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZGVmaW5pdGlvbiBmb3IgYm9va2luZ3NcbiAqL1xuZXhwb3J0IGNsYXNzIEJvb2tpbmdTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gQm9va2luZ1N0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBjb25zdCBzdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKEJvb2tpbmdTdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdjdXN0b21lcklkJywgJ2N1c3RvbWVySWQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdzdGF0dXMnLCAnc3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnY3JlYXRlZEF0JywgJ2NyZWF0ZWRBdCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICB9XG59XG5Cb29raW5nU3RvcmUuU1RPUkVfTkFNRSA9ICdib29raW5ncyc7XG4iLCAiaW1wb3J0IHsgQm9va2luZ1N0b3JlIH0gZnJvbSAnLi9Cb29raW5nU3RvcmUnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIEJvb2tpbmdTZXJ2aWNlIC0gQ1JVRCBvcGVyYXRpb25zIGZvciBib29raW5ncyBpbiBJbmRleGVkREJcbiAqL1xuZXhwb3J0IGNsYXNzIEJvb2tpbmdTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBCb29raW5nU3RvcmUuU1RPUkVfTkFNRTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0Jvb2tpbmcnO1xuICAgIH1cbiAgICBzZXJpYWxpemUoYm9va2luZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uYm9va2luZyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogYm9va2luZy5jcmVhdGVkQXQudG9JU09TdHJpbmcoKVxuICAgICAgICB9O1xuICAgIH1cbiAgICBkZXNlcmlhbGl6ZShkYXRhKSB7XG4gICAgICAgIGNvbnN0IHJhdyA9IGRhdGE7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5yYXcsXG4gICAgICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKHJhdy5jcmVhdGVkQXQpXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBib29raW5ncyBmb3IgYSBjdXN0b21lclxuICAgICAqL1xuICAgIGFzeW5jIGdldEJ5Q3VzdG9tZXIoY3VzdG9tZXJJZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdjdXN0b21lcklkJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0QWxsKGN1c3RvbWVySWQpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvb2tpbmdzID0gZGF0YS5tYXAoaXRlbSA9PiB0aGlzLmRlc2VyaWFsaXplKGl0ZW0pKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGJvb2tpbmdzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGdldCBib29raW5ncyBmb3IgY3VzdG9tZXIgJHtjdXN0b21lcklkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYm9va2luZ3MgYnkgc3RhdHVzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlTdGF0dXMoc3RhdHVzKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWRvbmx5Jyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKHRoaXMuc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc3RvcmUuaW5kZXgoJ3N0YXR1cycpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldEFsbChzdGF0dXMpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvb2tpbmdzID0gZGF0YS5tYXAoaXRlbSA9PiB0aGlzLmRlc2VyaWFsaXplKGl0ZW0pKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGJvb2tpbmdzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGdldCBib29raW5ncyB3aXRoIHN0YXR1cyAke3N0YXR1c306ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBDdXN0b21lclN0b3JlIC0gSW5kZXhlZERCIE9iamVjdFN0b3JlIGRlZmluaXRpb24gZm9yIGN1c3RvbWVyc1xuICovXG5leHBvcnQgY2xhc3MgQ3VzdG9tZXJTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gQ3VzdG9tZXJTdG9yZS5TVE9SRV9OQU1FO1xuICAgIH1cbiAgICBjcmVhdGUoZGIpIHtcbiAgICAgICAgY29uc3Qgc3RvcmUgPSBkYi5jcmVhdGVPYmplY3RTdG9yZShDdXN0b21lclN0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ25hbWUnLCAnbmFtZScsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3Bob25lJywgJ3Bob25lJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgICAgICBzdG9yZS5jcmVhdGVJbmRleCgnc3luY1N0YXR1cycsICdzeW5jU3RhdHVzJywgeyB1bmlxdWU6IGZhbHNlIH0pO1xuICAgIH1cbn1cbkN1c3RvbWVyU3RvcmUuU1RPUkVfTkFNRSA9ICdjdXN0b21lcnMnO1xuIiwgImltcG9ydCB7IEN1c3RvbWVyU3RvcmUgfSBmcm9tICcuL0N1c3RvbWVyU3RvcmUnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIEN1c3RvbWVyU2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgY3VzdG9tZXJzIGluIEluZGV4ZWREQlxuICovXG5leHBvcnQgY2xhc3MgQ3VzdG9tZXJTZXJ2aWNlIGV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGV2ZW50QnVzKSB7XG4gICAgICAgIHN1cGVyKGNvbnRleHQsIGV2ZW50QnVzKTtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBDdXN0b21lclN0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdDdXN0b21lcic7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBjdXN0b21lcnMgYnkgbmFtZSAoY2FzZS1pbnNlbnNpdGl2ZSBjb250YWlucylcbiAgICAgKi9cbiAgICBhc3luYyBzZWFyY2hCeU5hbWUocXVlcnkpIHtcbiAgICAgICAgY29uc3QgYWxsID0gYXdhaXQgdGhpcy5nZXRBbGwoKTtcbiAgICAgICAgY29uc3QgbG93ZXJRdWVyeSA9IHF1ZXJ5LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBhbGwuZmlsdGVyKGMgPT4gYy5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMobG93ZXJRdWVyeSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5kIGN1c3RvbWVyIGJ5IHBob25lXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlQaG9uZShwaG9uZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdwaG9uZScpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldChwaG9uZSk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhID8gZGF0YSA6IG51bGwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZmluZCBjdXN0b21lciBieSBwaG9uZSAke3Bob25lfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFRlYW1TdG9yZSAtIEluZGV4ZWREQiBPYmplY3RTdG9yZSBkZWZpbml0aW9uIGZvciB0ZWFtc1xuICovXG5leHBvcnQgY2xhc3MgVGVhbVN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBUZWFtU3RvcmUuU1RPUkVfTkFNRTtcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFRlYW1TdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgfVxufVxuVGVhbVN0b3JlLlNUT1JFX05BTUUgPSAndGVhbXMnO1xuIiwgImltcG9ydCB7IFRlYW1TdG9yZSB9IGZyb20gJy4vVGVhbVN0b3JlJztcbmltcG9ydCB7IEJhc2VFbnRpdHlTZXJ2aWNlIH0gZnJvbSAnLi4vQmFzZUVudGl0eVNlcnZpY2UnO1xuLyoqXG4gKiBUZWFtU2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgdGVhbXMgaW4gSW5kZXhlZERCXG4gKlxuICogVGVhbXMgZGVmaW5lIHdoaWNoIHJlc291cmNlcyBiZWxvbmcgdG9nZXRoZXIgZm9yIGhpZXJhcmNoaWNhbCBncm91cGluZy5cbiAqIEV4dGVuZHMgQmFzZUVudGl0eVNlcnZpY2UgZm9yIHN0YW5kYXJkIGVudGl0eSBvcGVyYXRpb25zLlxuICovXG5leHBvcnQgY2xhc3MgVGVhbVNlcnZpY2UgZXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCwgZXZlbnRCdXMpO1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IFRlYW1TdG9yZS5TVE9SRV9OQU1FO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnVGVhbSc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0ZWFtcyBieSBJRHNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeUlkcyhpZHMpIHtcbiAgICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChpZHMubWFwKGlkID0+IHRoaXMuZ2V0KGlkKSkpO1xuICAgICAgICByZXR1cm4gcmVzdWx0cy5maWx0ZXIoKHQpID0+IHQgIT09IG51bGwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCdWlsZCByZXZlcnNlIGxvb2t1cDogcmVzb3VyY2VJZCBcdTIxOTIgdGVhbUlkXG4gICAgICovXG4gICAgYXN5bmMgYnVpbGRSZXNvdXJjZVRvVGVhbU1hcCgpIHtcbiAgICAgICAgY29uc3QgdGVhbXMgPSBhd2FpdCB0aGlzLmdldEFsbCgpO1xuICAgICAgICBjb25zdCBtYXAgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCB0ZWFtIG9mIHRlYW1zKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlc291cmNlSWQgb2YgdGVhbS5yZXNvdXJjZUlkcykge1xuICAgICAgICAgICAgICAgIG1hcFtyZXNvdXJjZUlkXSA9IHRlYW0uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBEZXBhcnRtZW50U3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZGVmaW5pdGlvbiBmb3IgZGVwYXJ0bWVudHNcbiAqL1xuZXhwb3J0IGNsYXNzIERlcGFydG1lbnRTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gRGVwYXJ0bWVudFN0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShEZXBhcnRtZW50U3RvcmUuU1RPUkVfTkFNRSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgIH1cbn1cbkRlcGFydG1lbnRTdG9yZS5TVE9SRV9OQU1FID0gJ2RlcGFydG1lbnRzJztcbiIsICJpbXBvcnQgeyBEZXBhcnRtZW50U3RvcmUgfSBmcm9tICcuL0RlcGFydG1lbnRTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbi8qKlxuICogRGVwYXJ0bWVudFNlcnZpY2UgLSBDUlVEIG9wZXJhdGlvbnMgZm9yIGRlcGFydG1lbnRzIGluIEluZGV4ZWREQlxuICovXG5leHBvcnQgY2xhc3MgRGVwYXJ0bWVudFNlcnZpY2UgZXh0ZW5kcyBCYXNlRW50aXR5U2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgZXZlbnRCdXMpIHtcbiAgICAgICAgc3VwZXIoY29udGV4dCwgZXZlbnRCdXMpO1xuICAgICAgICB0aGlzLnN0b3JlTmFtZSA9IERlcGFydG1lbnRTdG9yZS5TVE9SRV9OQU1FO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnRGVwYXJ0bWVudCc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBkZXBhcnRtZW50cyBieSBJRHNcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeUlkcyhpZHMpIHtcbiAgICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChpZHMubWFwKGlkID0+IHRoaXMuZ2V0KGlkKSkpO1xuICAgICAgICByZXR1cm4gcmVzdWx0cy5maWx0ZXIoKGQpID0+IGQgIT09IG51bGwpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFNldHRpbmdzU3RvcmUgLSBJbmRleGVkREIgT2JqZWN0U3RvcmUgZGVmaW5pdGlvbiBmb3IgdGVuYW50IHNldHRpbmdzXG4gKlxuICogU2luZ2xlIHN0b3JlIGZvciBhbGwgc2V0dGluZ3Mgc2VjdGlvbnMuIFNldHRpbmdzIGFyZSBzdG9yZWQgYXMgb25lIGRvY3VtZW50XG4gKiBwZXIgdGVuYW50IHdpdGggaWQ9J3RlbmFudC1zZXR0aW5ncycuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXR0aW5nc1N0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yZU5hbWUgPSBTZXR0aW5nc1N0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShTZXR0aW5nc1N0b3JlLlNUT1JFX05BTUUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICB9XG59XG5TZXR0aW5nc1N0b3JlLlNUT1JFX05BTUUgPSAnc2V0dGluZ3MnO1xuIiwgIi8qKlxuICogU2V0dGluZ3MgSURzIGFzIGNvbnN0IGZvciB0eXBlIHNhZmV0eVxuICovXG5leHBvcnQgY29uc3QgU2V0dGluZ3NJZHMgPSB7XG4gICAgV09SS1dFRUs6ICd3b3Jrd2VlaycsXG4gICAgR1JJRDogJ2dyaWQnLFxuICAgIFRJTUVfRk9STUFUOiAndGltZUZvcm1hdCcsXG4gICAgVklFV1M6ICd2aWV3cydcbn07XG4iLCAiaW1wb3J0IHsgU2V0dGluZ3NJZHMgfSBmcm9tICcuLi8uLi90eXBlcy9TZXR0aW5nc1R5cGVzJztcbmltcG9ydCB7IFNldHRpbmdzU3RvcmUgfSBmcm9tICcuL1NldHRpbmdzU3RvcmUnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9CYXNlRW50aXR5U2VydmljZSc7XG4vKipcbiAqIFNldHRpbmdzU2VydmljZSAtIENSVUQgb3BlcmF0aW9ucyBmb3IgdGVuYW50IHNldHRpbmdzXG4gKlxuICogU2V0dGluZ3MgYXJlIHN0b3JlZCBhcyBzZXBhcmF0ZSByZWNvcmRzIHBlciBzZWN0aW9uLlxuICogVGhpcyBzZXJ2aWNlIHByb3ZpZGVzIHR5cGVkIG1ldGhvZHMgZm9yIGFjY2Vzc2luZyBzcGVjaWZpYyBzZXR0aW5ncy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNldHRpbmdzU2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gU2V0dGluZ3NTdG9yZS5TVE9SRV9OQU1FO1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnU2V0dGluZ3MnO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgd29ya3dlZWsgc2V0dGluZ3NcbiAgICAgKi9cbiAgICBhc3luYyBnZXRXb3Jrd2Vla1NldHRpbmdzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoU2V0dGluZ3NJZHMuV09SS1dFRUspO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgZ3JpZCBzZXR0aW5nc1xuICAgICAqL1xuICAgIGFzeW5jIGdldEdyaWRTZXR0aW5ncygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KFNldHRpbmdzSWRzLkdSSUQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGltZSBmb3JtYXQgc2V0dGluZ3NcbiAgICAgKi9cbiAgICBhc3luYyBnZXRUaW1lRm9ybWF0U2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChTZXR0aW5nc0lkcy5USU1FX0ZPUk1BVCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB2aWV3IHNldHRpbmdzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0Vmlld1NldHRpbmdzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoU2V0dGluZ3NJZHMuVklFV1MpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgd29ya3dlZWsgcHJlc2V0IGJ5IElEXG4gICAgICovXG4gICAgYXN5bmMgZ2V0V29ya3dlZWtQcmVzZXQocHJlc2V0SWQpIHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBhd2FpdCB0aGlzLmdldFdvcmt3ZWVrU2V0dGluZ3MoKTtcbiAgICAgICAgaWYgKCFzZXR0aW5ncylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gc2V0dGluZ3MucHJlc2V0c1twcmVzZXRJZF0gfHwgbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkZWZhdWx0IHdvcmt3ZWVrIHByZXNldFxuICAgICAqL1xuICAgIGFzeW5jIGdldERlZmF1bHRXb3Jrd2Vla1ByZXNldCgpIHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSBhd2FpdCB0aGlzLmdldFdvcmt3ZWVrU2V0dGluZ3MoKTtcbiAgICAgICAgaWYgKCFzZXR0aW5ncylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gc2V0dGluZ3MucHJlc2V0c1tzZXR0aW5ncy5kZWZhdWx0UHJlc2V0XSB8fCBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIGF2YWlsYWJsZSB3b3Jrd2VlayBwcmVzZXRzXG4gICAgICovXG4gICAgYXN5bmMgZ2V0V29ya3dlZWtQcmVzZXRzKCkge1xuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IGF3YWl0IHRoaXMuZ2V0V29ya3dlZWtTZXR0aW5ncygpO1xuICAgICAgICBpZiAoIXNldHRpbmdzKVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhzZXR0aW5ncy5wcmVzZXRzKTtcbiAgICB9XG59XG4iLCAiZXhwb3J0IGNsYXNzIFZpZXdDb25maWdTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gVmlld0NvbmZpZ1N0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShWaWV3Q29uZmlnU3RvcmUuU1RPUkVfTkFNRSwgeyBrZXlQYXRoOiAnaWQnIH0pO1xuICAgIH1cbn1cblZpZXdDb25maWdTdG9yZS5TVE9SRV9OQU1FID0gJ3ZpZXdjb25maWdzJztcbiIsICJpbXBvcnQgeyBWaWV3Q29uZmlnU3RvcmUgfSBmcm9tICcuL1ZpZXdDb25maWdTdG9yZSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5U2VydmljZSB9IGZyb20gJy4uL0Jhc2VFbnRpdHlTZXJ2aWNlJztcbmV4cG9ydCBjbGFzcyBWaWV3Q29uZmlnU2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gVmlld0NvbmZpZ1N0b3JlLlNUT1JFX05BTUU7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdWaWV3Q29uZmlnJztcbiAgICB9XG4gICAgYXN5bmMgZ2V0QnlJZChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXQoaWQpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIEF1ZGl0U3RvcmUgLSBJbmRleGVkREIgc3RvcmUgY29uZmlndXJhdGlvbiBmb3IgYXVkaXQgZW50cmllc1xuICpcbiAqIFN0b3JlcyBhbGwgZW50aXR5IGNoYW5nZXMgZm9yOlxuICogLSBDb21wbGlhbmNlIGFuZCBhdWRpdCB0cmFpbFxuICogLSBTeW5jIHRyYWNraW5nIHdpdGggYmFja2VuZFxuICogLSBDaGFuZ2UgaGlzdG9yeVxuICpcbiAqIEluZGV4ZXM6XG4gKiAtIHN5bmNTdGF0dXM6IEZvciBmaW5kaW5nIHBlbmRpbmcgZW50cmllcyB0byBzeW5jXG4gKiAtIHN5bmNlZDogQm9vbGVhbiBmbGFnIGZvciBxdWljayBzeW5jIHF1ZXJpZXNcbiAqIC0gZW50aXR5SWQ6IEZvciBnZXR0aW5nIGFsbCBhdWRpdHMgZm9yIGEgc3BlY2lmaWMgZW50aXR5XG4gKiAtIHRpbWVzdGFtcDogRm9yIGNocm9ub2xvZ2ljYWwgcXVlcmllc1xuICovXG5leHBvcnQgY2xhc3MgQXVkaXRTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gJ2F1ZGl0JztcbiAgICB9XG4gICAgY3JlYXRlKGRiKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlID0gZGIuY3JlYXRlT2JqZWN0U3RvcmUodGhpcy5zdG9yZU5hbWUsIHsga2V5UGF0aDogJ2lkJyB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N5bmNTdGF0dXMnLCAnc3luY1N0YXR1cycsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N5bmNlZCcsICdzeW5jZWQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdlbnRpdHlJZCcsICdlbnRpdHlJZCcsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3RpbWVzdGFtcCcsICd0aW1lc3RhbXAnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IEJhc2VFbnRpdHlTZXJ2aWNlIH0gZnJvbSAnLi4vQmFzZUVudGl0eVNlcnZpY2UnO1xuaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcbi8qKlxuICogQXVkaXRTZXJ2aWNlIC0gRW50aXR5IHNlcnZpY2UgZm9yIGF1ZGl0IGVudHJpZXNcbiAqXG4gKiBSRVNQT05TSUJJTElUSUVTOlxuICogLSBTdG9yZSBhdWRpdCBlbnRyaWVzIGluIEluZGV4ZWREQlxuICogLSBMaXN0ZW4gZm9yIEVOVElUWV9TQVZFRC9FTlRJVFlfREVMRVRFRCBldmVudHNcbiAqIC0gQ3JlYXRlIGF1ZGl0IGVudHJpZXMgZm9yIGFsbCBlbnRpdHkgY2hhbmdlc1xuICogLSBFbWl0IEFVRElUX0xPR0dFRCBhZnRlciBzYXZpbmcgKGZvciBTeW5jTWFuYWdlciB0byBsaXN0ZW4pXG4gKlxuICogT1ZFUlJJREUgUEFUVEVSTjpcbiAqIC0gT3ZlcnJpZGVzIHNhdmUoKSB0byBOT1QgZW1pdCBldmVudHMgKHByZXZlbnRzIGluZmluaXRlIGxvb3BzKVxuICogLSBBdWRpdFNlcnZpY2Ugc2F2ZXMgYXVkaXQgZW50cmllcyB3aXRob3V0IHRyaWdnZXJpbmcgbW9yZSBhdWRpdHNcbiAqXG4gKiBFVkVOVCBDSEFJTjpcbiAqIEVudGl0eSBjaGFuZ2UgXHUyMTkyIEVOVElUWV9TQVZFRC9ERUxFVEVEIFx1MjE5MiBBdWRpdFNlcnZpY2UgXHUyMTkyIEFVRElUX0xPR0dFRCBcdTIxOTIgU3luY01hbmFnZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEF1ZGl0U2VydmljZSBleHRlbmRzIEJhc2VFbnRpdHlTZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBldmVudEJ1cykge1xuICAgICAgICBzdXBlcihjb250ZXh0LCBldmVudEJ1cyk7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gJ2F1ZGl0JztcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0F1ZGl0JztcbiAgICAgICAgdGhpcy5zZXR1cEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHVwIGxpc3RlbmVycyBmb3IgRU5USVRZX1NBVkVEIGFuZCBFTlRJVFlfREVMRVRFRCBldmVudHNcbiAgICAgKi9cbiAgICBzZXR1cEV2ZW50TGlzdGVuZXJzKCkge1xuICAgICAgICAvLyBMaXN0ZW4gZm9yIGVudGl0eSBzYXZlcyAoY3JlYXRlL3VwZGF0ZSlcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVOVElUWV9TQVZFRCwgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXRhaWwgPSBldmVudC5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUVudGl0eVNhdmVkKGRldGFpbCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBMaXN0ZW4gZm9yIGVudGl0eSBkZWxldGVzXG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FTlRJVFlfREVMRVRFRCwgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXRhaWwgPSBldmVudC5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUVudGl0eURlbGV0ZWQoZGV0YWlsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBFTlRJVFlfU0FWRUQgZXZlbnQgLSBjcmVhdGUgYXVkaXQgZW50cnlcbiAgICAgKi9cbiAgICBhc3luYyBoYW5kbGVFbnRpdHlTYXZlZChwYXlsb2FkKSB7XG4gICAgICAgIC8vIERvbid0IGF1ZGl0IGF1ZGl0IGVudHJpZXMgKHByZXZlbnQgaW5maW5pdGUgbG9vcHMpXG4gICAgICAgIGlmIChwYXlsb2FkLmVudGl0eVR5cGUgPT09ICdBdWRpdCcpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGF1ZGl0RW50cnkgPSB7XG4gICAgICAgICAgICBpZDogY3J5cHRvLnJhbmRvbVVVSUQoKSxcbiAgICAgICAgICAgIGVudGl0eVR5cGU6IHBheWxvYWQuZW50aXR5VHlwZSxcbiAgICAgICAgICAgIGVudGl0eUlkOiBwYXlsb2FkLmVudGl0eUlkLFxuICAgICAgICAgICAgb3BlcmF0aW9uOiBwYXlsb2FkLm9wZXJhdGlvbixcbiAgICAgICAgICAgIHVzZXJJZDogQXVkaXRTZXJ2aWNlLkRFRkFVTFRfVVNFUl9JRCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogcGF5bG9hZC50aW1lc3RhbXAsXG4gICAgICAgICAgICBjaGFuZ2VzOiBwYXlsb2FkLmNoYW5nZXMsXG4gICAgICAgICAgICBzeW5jZWQ6IGZhbHNlLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3BlbmRpbmcnXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IHRoaXMuc2F2ZShhdWRpdEVudHJ5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIEVOVElUWV9ERUxFVEVEIGV2ZW50IC0gY3JlYXRlIGF1ZGl0IGVudHJ5XG4gICAgICovXG4gICAgYXN5bmMgaGFuZGxlRW50aXR5RGVsZXRlZChwYXlsb2FkKSB7XG4gICAgICAgIC8vIERvbid0IGF1ZGl0IGF1ZGl0IGVudHJpZXMgKHByZXZlbnQgaW5maW5pdGUgbG9vcHMpXG4gICAgICAgIGlmIChwYXlsb2FkLmVudGl0eVR5cGUgPT09ICdBdWRpdCcpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGF1ZGl0RW50cnkgPSB7XG4gICAgICAgICAgICBpZDogY3J5cHRvLnJhbmRvbVVVSUQoKSxcbiAgICAgICAgICAgIGVudGl0eVR5cGU6IHBheWxvYWQuZW50aXR5VHlwZSxcbiAgICAgICAgICAgIGVudGl0eUlkOiBwYXlsb2FkLmVudGl0eUlkLFxuICAgICAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlJyxcbiAgICAgICAgICAgIHVzZXJJZDogQXVkaXRTZXJ2aWNlLkRFRkFVTFRfVVNFUl9JRCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogcGF5bG9hZC50aW1lc3RhbXAsXG4gICAgICAgICAgICBjaGFuZ2VzOiB7IGlkOiBwYXlsb2FkLmVudGl0eUlkIH0sIC8vIEZvciBkZWxldGUsIGp1c3Qgc3RvcmUgdGhlIElEXG4gICAgICAgICAgICBzeW5jZWQ6IGZhbHNlLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3BlbmRpbmcnXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IHRoaXMuc2F2ZShhdWRpdEVudHJ5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgc2F2ZSB0byBOT1QgdHJpZ2dlciBFTlRJVFlfU0FWRUQgZXZlbnRcbiAgICAgKiBJbnN0ZWFkLCBlbWl0cyBBVURJVF9MT0dHRUQgZm9yIFN5bmNNYW5hZ2VyIHRvIGxpc3RlblxuICAgICAqXG4gICAgICogVGhpcyBwcmV2ZW50cyBpbmZpbml0ZSBsb29wczpcbiAgICAgKiAtIEJhc2VFbnRpdHlTZXJ2aWNlLnNhdmUoKSBlbWl0cyBFTlRJVFlfU0FWRURcbiAgICAgKiAtIEF1ZGl0U2VydmljZSBsaXN0ZW5zIHRvIEVOVElUWV9TQVZFRCBhbmQgY3JlYXRlcyBhdWRpdFxuICAgICAqIC0gSWYgQXVkaXRTZXJ2aWNlLnNhdmUoKSBhbHNvIGVtaXR0ZWQgRU5USVRZX1NBVkVELCBpdCB3b3VsZCBsb29wXG4gICAgICovXG4gICAgYXN5bmMgc2F2ZShlbnRpdHkpIHtcbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IHRoaXMuc2VyaWFsaXplKGVudGl0eSk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGIudHJhbnNhY3Rpb24oW3RoaXMuc3RvcmVOYW1lXSwgJ3JlYWR3cml0ZScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gc3RvcmUucHV0KHNlcmlhbGl6ZWQpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gRW1pdCBBVURJVF9MT0dHRUQgaW5zdGVhZCBvZiBFTlRJVFlfU0FWRURcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICBhdWRpdElkOiBlbnRpdHkuaWQsXG4gICAgICAgICAgICAgICAgICAgIGVudGl0eVR5cGU6IGVudGl0eS5lbnRpdHlUeXBlLFxuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb246IGVudGl0eS5vcGVyYXRpb24sXG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogZW50aXR5LnRpbWVzdGFtcFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuQVVESVRfTE9HR0VELCBwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVxdWVzdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBzYXZlIGF1ZGl0IGVudHJ5ICR7ZW50aXR5LmlkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSBkZWxldGUgdG8gTk9UIHRyaWdnZXIgRU5USVRZX0RFTEVURUQgZXZlbnRcbiAgICAgKiBBdWRpdCBlbnRyaWVzIHNob3VsZCBuZXZlciBiZSBkZWxldGVkIChjb21wbGlhbmNlIHJlcXVpcmVtZW50KVxuICAgICAqL1xuICAgIGFzeW5jIGRlbGV0ZShfaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdWRpdCBlbnRyaWVzIGNhbm5vdCBiZSBkZWxldGVkIChjb21wbGlhbmNlIHJlcXVpcmVtZW50KScpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgcGVuZGluZyBhdWRpdCBlbnRyaWVzIChmb3Igc3luYylcbiAgICAgKi9cbiAgICBhc3luYyBnZXRQZW5kaW5nQXVkaXRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCeVN5bmNTdGF0dXMoJ3BlbmRpbmcnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGF1ZGl0IGVudHJpZXMgZm9yIGEgc3BlY2lmaWMgZW50aXR5XG4gICAgICovXG4gICAgYXN5bmMgZ2V0QnlFbnRpdHlJZChlbnRpdHlJZCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFt0aGlzLnN0b3JlTmFtZV0sICdyZWFkb25seScpO1xuICAgICAgICAgICAgY29uc3Qgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmluZGV4KCdlbnRpdHlJZCcpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldEFsbChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRyaWVzID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShlbnRyaWVzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGdldCBhdWRpdCBlbnRyaWVzIGZvciBlbnRpdHkgJHtlbnRpdHlJZH06ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG59XG4vLyBIYXJkY29kZWQgdXNlcklkIGZvciBub3cgLSB3aWxsIGNvbWUgZnJvbSBzZXNzaW9uIGxhdGVyXG5BdWRpdFNlcnZpY2UuREVGQVVMVF9VU0VSX0lEID0gJzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMSc7XG4iLCAiLyoqXG4gKiBNb2NrRXZlbnRSZXBvc2l0b3J5IC0gTG9hZHMgZXZlbnQgZGF0YSBmcm9tIGxvY2FsIEpTT04gZmlsZVxuICpcbiAqIFVzZWQgZm9yIGRldmVsb3BtZW50IGFuZCB0ZXN0aW5nLiBPbmx5IGZldGNoQWxsKCkgaXMgaW1wbGVtZW50ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrRXZlbnRSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0V2ZW50JztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvbW9jay1ldmVudHMuanNvbic7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZldGNoIGFsbCBldmVudHMgZnJvbSBtb2NrIEpTT04gZmlsZVxuICAgICAqL1xuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9jayBldmVudHM6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0NhbGVuZGFyRGF0YShyYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGV2ZW50IGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfZXZlbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRXZlbnRSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0V2ZW50UmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0V2ZW50UmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIHByb2Nlc3NDYWxlbmRhckRhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBWYWxpZGF0ZSBjdXN0b21lciBldmVudCBjb25zdHJhaW50c1xuICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdjdXN0b21lcicpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LmJvb2tpbmdJZClcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBDdXN0b21lciBldmVudCAke2V2ZW50LmlkfSBtaXNzaW5nIGJvb2tpbmdJZGApO1xuICAgICAgICAgICAgICAgIGlmICghZXZlbnQucmVzb3VyY2VJZClcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBDdXN0b21lciBldmVudCAke2V2ZW50LmlkfSBtaXNzaW5nIHJlc291cmNlSWRgKTtcbiAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LmN1c3RvbWVySWQpXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQ3VzdG9tZXIgZXZlbnQgJHtldmVudC5pZH0gbWlzc2luZyBjdXN0b21lcklkYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlkOiBldmVudC5pZCxcbiAgICAgICAgICAgICAgICB0aXRsZTogZXZlbnQudGl0bGUsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGV2ZW50LmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIHN0YXJ0OiBuZXcgRGF0ZShldmVudC5zdGFydCksXG4gICAgICAgICAgICAgICAgZW5kOiBuZXcgRGF0ZShldmVudC5lbmQpLFxuICAgICAgICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGUsXG4gICAgICAgICAgICAgICAgYWxsRGF5OiBldmVudC5hbGxEYXkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgYm9va2luZ0lkOiBldmVudC5ib29raW5nSWQsXG4gICAgICAgICAgICAgICAgcmVzb3VyY2VJZDogZXZlbnQucmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBjdXN0b21lcklkOiBldmVudC5jdXN0b21lcklkLFxuICAgICAgICAgICAgICAgIHJlY3VycmluZ0lkOiBldmVudC5yZWN1cnJpbmdJZCxcbiAgICAgICAgICAgICAgICBtZXRhZGF0YTogZXZlbnQubWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgc3luY1N0YXR1czogJ3N5bmNlZCdcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIE1vY2tSZXNvdXJjZVJlcG9zaXRvcnkgLSBMb2FkcyByZXNvdXJjZSBkYXRhIGZyb20gbG9jYWwgSlNPTiBmaWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrUmVzb3VyY2VSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ1Jlc291cmNlJztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvbW9jay1yZXNvdXJjZXMuanNvbic7XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9jayByZXNvdXJjZXM6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc1Jlc291cmNlRGF0YShyYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHJlc291cmNlIGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfcmVzb3VyY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrUmVzb3VyY2VSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1Jlc291cmNlUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1Jlc291cmNlUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIHByb2Nlc3NSZXNvdXJjZURhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKHJlc291cmNlKSA9PiAoe1xuICAgICAgICAgICAgaWQ6IHJlc291cmNlLmlkLFxuICAgICAgICAgICAgbmFtZTogcmVzb3VyY2UubmFtZSxcbiAgICAgICAgICAgIGRpc3BsYXlOYW1lOiByZXNvdXJjZS5kaXNwbGF5TmFtZSxcbiAgICAgICAgICAgIHR5cGU6IHJlc291cmNlLnR5cGUsXG4gICAgICAgICAgICBhdmF0YXJVcmw6IHJlc291cmNlLmF2YXRhclVybCxcbiAgICAgICAgICAgIGNvbG9yOiByZXNvdXJjZS5jb2xvcixcbiAgICAgICAgICAgIGlzQWN0aXZlOiByZXNvdXJjZS5pc0FjdGl2ZSxcbiAgICAgICAgICAgIGRlZmF1bHRTY2hlZHVsZTogcmVzb3VyY2UuZGVmYXVsdFNjaGVkdWxlLFxuICAgICAgICAgICAgbWV0YWRhdGE6IHJlc291cmNlLm1ldGFkYXRhLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3N5bmNlZCdcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIE1vY2tCb29raW5nUmVwb3NpdG9yeSAtIExvYWRzIGJvb2tpbmcgZGF0YSBmcm9tIGxvY2FsIEpTT04gZmlsZVxuICovXG5leHBvcnQgY2xhc3MgTW9ja0Jvb2tpbmdSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0Jvb2tpbmcnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS9tb2NrLWJvb2tpbmdzLmpzb24nO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5kYXRhVXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBsb2FkIG1vY2sgYm9va2luZ3M6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0Jvb2tpbmdEYXRhKHJhd0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgYm9va2luZyBkYXRhOicsIGVycm9yKTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNlbmRDcmVhdGUoX2Jvb2tpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrQm9va2luZ1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kQ3JlYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX3VwZGF0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrQm9va2luZ1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kVXBkYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tCb29raW5nUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIHByb2Nlc3NCb29raW5nRGF0YShkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgoYm9va2luZykgPT4gKHtcbiAgICAgICAgICAgIGlkOiBib29raW5nLmlkLFxuICAgICAgICAgICAgY3VzdG9tZXJJZDogYm9va2luZy5jdXN0b21lcklkLFxuICAgICAgICAgICAgc3RhdHVzOiBib29raW5nLnN0YXR1cyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoYm9va2luZy5jcmVhdGVkQXQpLFxuICAgICAgICAgICAgc2VydmljZXM6IGJvb2tpbmcuc2VydmljZXMsXG4gICAgICAgICAgICB0b3RhbFByaWNlOiBib29raW5nLnRvdGFsUHJpY2UsXG4gICAgICAgICAgICB0YWdzOiBib29raW5nLnRhZ3MsXG4gICAgICAgICAgICBub3RlczogYm9va2luZy5ub3RlcyxcbiAgICAgICAgICAgIHN5bmNTdGF0dXM6ICdzeW5jZWQnXG4gICAgICAgIH0pKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5IC0gTG9hZHMgY3VzdG9tZXIgZGF0YSBmcm9tIGxvY2FsIEpTT04gZmlsZVxuICovXG5leHBvcnQgY2xhc3MgTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdDdXN0b21lcic7XG4gICAgICAgIHRoaXMuZGF0YVVybCA9ICdkYXRhL21vY2stY3VzdG9tZXJzLmpzb24nO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5kYXRhVXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBsb2FkIG1vY2sgY3VzdG9tZXJzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmF3RGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NDdXN0b21lckRhdGEocmF3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCBjdXN0b21lciBkYXRhOicsIGVycm9yKTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNlbmRDcmVhdGUoX2N1c3RvbWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRDcmVhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmRVcGRhdGUoX2lkLCBfdXBkYXRlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tDdXN0b21lclJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kVXBkYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tDdXN0b21lclJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kRGVsZXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBwcm9jZXNzQ3VzdG9tZXJEYXRhKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGRhdGEubWFwKChjdXN0b21lcikgPT4gKHtcbiAgICAgICAgICAgIGlkOiBjdXN0b21lci5pZCxcbiAgICAgICAgICAgIG5hbWU6IGN1c3RvbWVyLm5hbWUsXG4gICAgICAgICAgICBwaG9uZTogY3VzdG9tZXIucGhvbmUsXG4gICAgICAgICAgICBlbWFpbDogY3VzdG9tZXIuZW1haWwsXG4gICAgICAgICAgICBtZXRhZGF0YTogY3VzdG9tZXIubWV0YWRhdGEsXG4gICAgICAgICAgICBzeW5jU3RhdHVzOiAnc3luY2VkJ1xuICAgICAgICB9KSk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogTW9ja0F1ZGl0UmVwb3NpdG9yeSAtIE1vY2sgQVBJIHJlcG9zaXRvcnkgZm9yIGF1ZGl0IGVudHJpZXNcbiAqXG4gKiBJbiBwcm9kdWN0aW9uLCB0aGlzIHdvdWxkIHNlbmQgYXVkaXQgZW50cmllcyB0byB0aGUgYmFja2VuZC5cbiAqIEZvciBkZXZlbG9wbWVudC90ZXN0aW5nLCBpdCBqdXN0IGxvZ3MgdGhlIG9wZXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrQXVkaXRSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ0F1ZGl0JztcbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShlbnRpdHkpIHtcbiAgICAgICAgLy8gU2ltdWxhdGUgQVBJIGNhbGwgZGVsYXlcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMCkpO1xuICAgICAgICBjb25zb2xlLmxvZygnTW9ja0F1ZGl0UmVwb3NpdG9yeTogQXVkaXQgZW50cnkgc3luY2VkIHRvIGJhY2tlbmQ6Jywge1xuICAgICAgICAgICAgaWQ6IGVudGl0eS5pZCxcbiAgICAgICAgICAgIGVudGl0eVR5cGU6IGVudGl0eS5lbnRpdHlUeXBlLFxuICAgICAgICAgICAgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCxcbiAgICAgICAgICAgIG9wZXJhdGlvbjogZW50aXR5Lm9wZXJhdGlvbixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoZW50aXR5LnRpbWVzdGFtcCkudG9JU09TdHJpbmcoKVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGVudGl0eTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF9lbnRpdHkpIHtcbiAgICAgICAgLy8gQXVkaXQgZW50cmllcyBhcmUgaW1tdXRhYmxlIC0gdXBkYXRlcyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1ZGl0IGVudHJpZXMgY2Fubm90IGJlIHVwZGF0ZWQnKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZERlbGV0ZShfaWQpIHtcbiAgICAgICAgLy8gQXVkaXQgZW50cmllcyBzaG91bGQgbmV2ZXIgYmUgZGVsZXRlZFxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1ZGl0IGVudHJpZXMgY2Fubm90IGJlIGRlbGV0ZWQnKTtcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIC8vIEZvciBub3csIHJldHVybiBlbXB0eSBhcnJheSAtIGF1ZGl0IGVudHJpZXMgYXJlIGxvY2FsLWZpcnN0XG4gICAgICAgIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgY291bGQgZmV0Y2ggYXVkaXQgaGlzdG9yeSBmcm9tIGJhY2tlbmRcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEJ5SWQoX2lkKSB7XG4gICAgICAgIC8vIEZvciBub3csIHJldHVybiBudWxsIC0gYXVkaXQgZW50cmllcyBhcmUgbG9jYWwtZmlyc3RcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuIiwgIi8qKlxuICogTW9ja1RlYW1SZXBvc2l0b3J5IC0gTG9hZHMgdGVhbSBkYXRhIGZyb20gbG9jYWwgSlNPTiBmaWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrVGVhbVJlcG9zaXRvcnkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVudGl0eVR5cGUgPSAnVGVhbSc7XG4gICAgICAgIHRoaXMuZGF0YVVybCA9ICdkYXRhL21vY2stdGVhbXMuanNvbic7XG4gICAgfVxuICAgIGFzeW5jIGZldGNoQWxsKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmRhdGFVcmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGxvYWQgbW9jayB0ZWFtczogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9jZXNzVGVhbURhdGEocmF3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCB0ZWFtIGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VuZENyZWF0ZShfdGVhbSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tUZWFtUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRDcmVhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmRVcGRhdGUoX2lkLCBfdXBkYXRlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tUZWFtUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRVcGRhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmREZWxldGUoX2lkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1RlYW1SZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZERlbGV0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgcHJvY2Vzc1RlYW1EYXRhKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIGRhdGEubWFwKCh0ZWFtKSA9PiAoe1xuICAgICAgICAgICAgaWQ6IHRlYW0uaWQsXG4gICAgICAgICAgICBuYW1lOiB0ZWFtLm5hbWUsXG4gICAgICAgICAgICByZXNvdXJjZUlkczogdGVhbS5yZXNvdXJjZUlkcyxcbiAgICAgICAgICAgIHN5bmNTdGF0dXM6ICdzeW5jZWQnXG4gICAgICAgIH0pKTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkgLSBMb2FkcyBkZXBhcnRtZW50IGRhdGEgZnJvbSBsb2NhbCBKU09OIGZpbGVcbiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuZW50aXR5VHlwZSA9ICdEZXBhcnRtZW50JztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvbW9jay1kZXBhcnRtZW50cy5qc29uJztcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZGF0YVVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2NrIGRlcGFydG1lbnRzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmF3RGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NEZXBhcnRtZW50RGF0YShyYXdEYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGRlcGFydG1lbnQgZGF0YTonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKF9kZXBhcnRtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0RlcGFydG1lbnRSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZENyZWF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZFVwZGF0ZShfaWQsIF91cGRhdGVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja0RlcGFydG1lbnRSZXBvc2l0b3J5IGRvZXMgbm90IHN1cHBvcnQgc2VuZFVwZGF0ZS4gTW9jayBkYXRhIGlzIHJlYWQtb25seS4nKTtcbiAgICB9XG4gICAgYXN5bmMgc2VuZERlbGV0ZShfaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kRGVsZXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBwcm9jZXNzRGVwYXJ0bWVudERhdGEoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGRlcHQpID0+ICh7XG4gICAgICAgICAgICBpZDogZGVwdC5pZCxcbiAgICAgICAgICAgIG5hbWU6IGRlcHQubmFtZSxcbiAgICAgICAgICAgIHJlc291cmNlSWRzOiBkZXB0LnJlc291cmNlSWRzLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3N5bmNlZCdcbiAgICAgICAgfSkpO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIE1vY2tTZXR0aW5nc1JlcG9zaXRvcnkgLSBMb2FkcyB0ZW5hbnQgc2V0dGluZ3MgZnJvbSBsb2NhbCBKU09OIGZpbGVcbiAqXG4gKiBTZXR0aW5ncyBhcmUgc3RvcmVkIGFzIHNlcGFyYXRlIHJlY29yZHMgcGVyIHNlY3Rpb24gKHdvcmt3ZWVrLCBncmlkLCBldGMuKS5cbiAqIFRoZSBKU09OIGZpbGUgaXMgYWxyZWFkeSBhbiBhcnJheSBvZiBUZW5hbnRTZXR0aW5nIHJlY29yZHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2NrU2V0dGluZ3NSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ1NldHRpbmdzJztcbiAgICAgICAgdGhpcy5kYXRhVXJsID0gJ2RhdGEvdGVuYW50LXNldHRpbmdzLmpzb24nO1xuICAgIH1cbiAgICBhc3luYyBmZXRjaEFsbCgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5kYXRhVXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBsb2FkIHRlbmFudCBzZXR0aW5nczogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgLy8gRW5zdXJlIHN5bmNTdGF0dXMgaXMgc2V0IG9uIGVhY2ggcmVjb3JkXG4gICAgICAgICAgICByZXR1cm4gc2V0dGluZ3MubWFwKHMgPT4gKHtcbiAgICAgICAgICAgICAgICAuLi5zLFxuICAgICAgICAgICAgICAgIHN5bmNTdGF0dXM6IHMuc3luY1N0YXR1cyB8fCAnc3luY2VkJ1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgdGVuYW50IHNldHRpbmdzOicsIGVycm9yKTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzeW5jIHNlbmRDcmVhdGUoX3NldHRpbmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTW9ja1NldHRpbmdzUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmRDcmVhdGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxuICAgIGFzeW5jIHNlbmRVcGRhdGUoX2lkLCBfdXBkYXRlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tTZXR0aW5nc1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kVXBkYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tTZXR0aW5nc1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kRGVsZXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbn1cbiIsICJleHBvcnQgY2xhc3MgTW9ja1ZpZXdDb25maWdSZXBvc2l0b3J5IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gJ1ZpZXdDb25maWcnO1xuICAgICAgICB0aGlzLmRhdGFVcmwgPSAnZGF0YS92aWV3Y29uZmlncy5qc29uJztcbiAgICB9XG4gICAgYXN5bmMgZmV0Y2hBbGwoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZGF0YVVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCB2aWV3Y29uZmlnczogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhd0RhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICAvLyBFbnN1cmUgc3luY1N0YXR1cyBpcyBzZXQgb24gZWFjaCBjb25maWdcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZ3MgPSByYXdEYXRhLm1hcCgoY29uZmlnKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLmNvbmZpZyxcbiAgICAgICAgICAgICAgICBzeW5jU3RhdHVzOiBjb25maWcuc3luY1N0YXR1cyB8fCAnc3luY2VkJ1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ3M7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCB2aWV3Y29uZmlnczonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc3luYyBzZW5kQ3JlYXRlKF9jb25maWcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kQ3JlYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kVXBkYXRlKF9pZCwgX3VwZGF0ZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkgZG9lcyBub3Qgc3VwcG9ydCBzZW5kVXBkYXRlLiBNb2NrIGRhdGEgaXMgcmVhZC1vbmx5LicpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGVsZXRlKF9pZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSBkb2VzIG5vdCBzdXBwb3J0IHNlbmREZWxldGUuIE1vY2sgZGF0YSBpcyByZWFkLW9ubHkuJyk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogRGF0YVNlZWRlciAtIE9yY2hlc3RyYXRlcyBpbml0aWFsIGRhdGEgbG9hZGluZyBmcm9tIHJlcG9zaXRvcmllcyBpbnRvIEluZGV4ZWREQlxuICpcbiAqIEFSQ0hJVEVDVFVSRTpcbiAqIC0gUmVwb3NpdG9yeSAoTW9jay9BcGkpOiBGZXRjaGVzIGRhdGEgZnJvbSBzb3VyY2UgKEpTT04gZmlsZSBvciBiYWNrZW5kIEFQSSlcbiAqIC0gRGF0YVNlZWRlciAodGhpcyBjbGFzcyk6IE9yY2hlc3RyYXRlcyBmZXRjaCArIHNhdmUgb3BlcmF0aW9uc1xuICogLSBTZXJ2aWNlIChFdmVudFNlcnZpY2UsIGV0Yy4pOiBTYXZlcyBkYXRhIHRvIEluZGV4ZWREQlxuICpcbiAqIFBPTFlNT1JQSElDIERFU0lHTjpcbiAqIC0gVXNlcyBhcnJheXMgb2YgSUVudGl0eVNlcnZpY2VbXSBhbmQgSUFwaVJlcG9zaXRvcnlbXVxuICogLSBNYXRjaGVzIHNlcnZpY2VzIHdpdGggcmVwb3NpdG9yaWVzIHVzaW5nIGVudGl0eVR5cGUgcHJvcGVydHlcbiAqIC0gT3Blbi9DbG9zZWQgUHJpbmNpcGxlOiBBZGRpbmcgbmV3IGVudGl0eSByZXF1aXJlcyBubyBjb2RlIGNoYW5nZXMgaGVyZVxuICovXG5leHBvcnQgY2xhc3MgRGF0YVNlZWRlciB7XG4gICAgY29uc3RydWN0b3Ioc2VydmljZXMsIHJlcG9zaXRvcmllcykge1xuICAgICAgICB0aGlzLnNlcnZpY2VzID0gc2VydmljZXM7XG4gICAgICAgIHRoaXMucmVwb3NpdG9yaWVzID0gcmVwb3NpdG9yaWVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWVkIGFsbCBlbnRpdHkgc3RvcmVzIGlmIHRoZXkgYXJlIGVtcHR5XG4gICAgICovXG4gICAgYXN5bmMgc2VlZElmRW1wdHkoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdbRGF0YVNlZWRlcl0gQ2hlY2tpbmcgaWYgZGF0YWJhc2UgbmVlZHMgc2VlZGluZy4uLicpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBzZXJ2aWNlIG9mIHRoaXMuc2VydmljZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gdGhpcy5yZXBvc2l0b3JpZXMuZmluZChyZXBvID0+IHJlcG8uZW50aXR5VHlwZSA9PT0gc2VydmljZS5lbnRpdHlUeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlcG9zaXRvcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbRGF0YVNlZWRlcl0gTm8gcmVwb3NpdG9yeSBmb3VuZCBmb3IgZW50aXR5IHR5cGU6ICR7c2VydmljZS5lbnRpdHlUeXBlfSwgc2tpcHBpbmdgKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VlZEVudGl0eShzZXJ2aWNlLmVudGl0eVR5cGUsIHNlcnZpY2UsIHJlcG9zaXRvcnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tEYXRhU2VlZGVyXSBTZWVkaW5nIGNvbXBsZXRlJyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdbRGF0YVNlZWRlcl0gU2VlZGluZyBmYWlsZWQ6JywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgc2VlZEVudGl0eShlbnRpdHlUeXBlLCBzZXJ2aWNlLCByZXBvc2l0b3J5KSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc2VydmljZS5nZXRBbGwoKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbRGF0YVNlZWRlcl0gJHtlbnRpdHlUeXBlfSBzdG9yZSBhbHJlYWR5IGhhcyAke2V4aXN0aW5nLmxlbmd0aH0gaXRlbXMsIHNraXBwaW5nIHNlZWRgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW0RhdGFTZWVkZXJdICR7ZW50aXR5VHlwZX0gc3RvcmUgaXMgZW1wdHksIGZldGNoaW5nIGZyb20gcmVwb3NpdG9yeS4uLmApO1xuICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVwb3NpdG9yeS5mZXRjaEFsbCgpO1xuICAgICAgICBjb25zb2xlLmxvZyhgW0RhdGFTZWVkZXJdIEZldGNoZWQgJHtkYXRhLmxlbmd0aH0gJHtlbnRpdHlUeXBlfSBpdGVtcywgc2F2aW5nIHRvIEluZGV4ZWREQi4uLmApO1xuICAgICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBkYXRhKSB7XG4gICAgICAgICAgICBhd2FpdCBzZXJ2aWNlLnNhdmUoZW50aXR5LCB0cnVlKTsgLy8gc2lsZW50ID0gdHJ1ZSB0byBza2lwIGF1ZGl0IGxvZ2dpbmdcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgW0RhdGFTZWVkZXJdICR7ZW50aXR5VHlwZX0gc2VlZGluZyBjb21wbGV0ZSAoJHtkYXRhLmxlbmd0aH0gaXRlbXMgc2F2ZWQpYCk7XG4gICAgfVxufVxuIiwgIi8qKlxuICogQ2FsY3VsYXRlIHBpeGVsIHBvc2l0aW9uIGZvciBhbiBldmVudCBiYXNlZCBvbiBpdHMgdGltZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oc3RhcnQsIGVuZCwgY29uZmlnKSB7XG4gICAgY29uc3Qgc3RhcnRNaW51dGVzID0gc3RhcnQuZ2V0SG91cnMoKSAqIDYwICsgc3RhcnQuZ2V0TWludXRlcygpO1xuICAgIGNvbnN0IGVuZE1pbnV0ZXMgPSBlbmQuZ2V0SG91cnMoKSAqIDYwICsgZW5kLmdldE1pbnV0ZXMoKTtcbiAgICBjb25zdCBkYXlTdGFydE1pbnV0ZXMgPSBjb25maWcuZGF5U3RhcnRIb3VyICogNjA7XG4gICAgY29uc3QgbWludXRlSGVpZ2h0ID0gY29uZmlnLmhvdXJIZWlnaHQgLyA2MDtcbiAgICBjb25zdCB0b3AgPSAoc3RhcnRNaW51dGVzIC0gZGF5U3RhcnRNaW51dGVzKSAqIG1pbnV0ZUhlaWdodDtcbiAgICBjb25zdCBoZWlnaHQgPSAoZW5kTWludXRlcyAtIHN0YXJ0TWludXRlcykgKiBtaW51dGVIZWlnaHQ7XG4gICAgcmV0dXJuIHsgdG9wLCBoZWlnaHQgfTtcbn1cbi8qKlxuICogQ29udmVydCBtaW51dGVzIHRvIHBpeGVsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWludXRlc1RvUGl4ZWxzKG1pbnV0ZXMsIGNvbmZpZykge1xuICAgIHJldHVybiAobWludXRlcyAvIDYwKSAqIGNvbmZpZy5ob3VySGVpZ2h0O1xufVxuLyoqXG4gKiBDb252ZXJ0IHBpeGVscyB0byBtaW51dGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwaXhlbHNUb01pbnV0ZXMocGl4ZWxzLCBjb25maWcpIHtcbiAgICByZXR1cm4gKHBpeGVscyAvIGNvbmZpZy5ob3VySGVpZ2h0KSAqIDYwO1xufVxuLyoqXG4gKiBTbmFwIHBpeGVsIHBvc2l0aW9uIHRvIGdyaWQgaW50ZXJ2YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNuYXBUb0dyaWQocGl4ZWxzLCBjb25maWcpIHtcbiAgICBjb25zdCBzbmFwUGl4ZWxzID0gbWludXRlc1RvUGl4ZWxzKGNvbmZpZy5zbmFwSW50ZXJ2YWwsIGNvbmZpZyk7XG4gICAgcmV0dXJuIE1hdGgucm91bmQocGl4ZWxzIC8gc25hcFBpeGVscykgKiBzbmFwUGl4ZWxzO1xufVxuIiwgImltcG9ydCB7IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24gfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcbi8qKlxuICogQ2hlY2sgaWYgdHdvIGV2ZW50cyBvdmVybGFwIChzdHJpY3QgLSB0b3VjaGluZyBhdCBib3VuZGFyeSA9IE5PVCBvdmVybGFwcGluZylcbiAqIFRoaXMgbWF0Y2hlcyBTY2VuYXJpbyA4OiBlbmQ9PT1zdGFydCBpcyBOT1Qgb3ZlcmxhcFxuICovXG5leHBvcnQgZnVuY3Rpb24gZXZlbnRzT3ZlcmxhcChhLCBiKSB7XG4gICAgcmV0dXJuIGEuc3RhcnQgPCBiLmVuZCAmJiBhLmVuZCA+IGIuc3RhcnQ7XG59XG4vKipcbiAqIENoZWNrIGlmIHR3byBldmVudHMgYXJlIHdpdGhpbiB0aHJlc2hvbGQgZm9yIGdyaWQgZ3JvdXBpbmcuXG4gKiBUaGlzIGluY2x1ZGVzOlxuICogMS4gU3RhcnQtdG8tc3RhcnQ6IEV2ZW50cyBzdGFydCB3aXRoaW4gdGhyZXNob2xkIG9mIGVhY2ggb3RoZXJcbiAqIDIuIEVuZC10by1zdGFydDogT25lIGV2ZW50IHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBhbm90aGVyIGVuZHNcbiAqL1xuZnVuY3Rpb24gZXZlbnRzV2l0aGluVGhyZXNob2xkKGEsIGIsIHRocmVzaG9sZE1pbnV0ZXMpIHtcbiAgICBjb25zdCB0aHJlc2hvbGRNcyA9IHRocmVzaG9sZE1pbnV0ZXMgKiA2MCAqIDEwMDA7XG4gICAgLy8gU3RhcnQtdG8tc3RhcnQ6IGJvdGggZXZlbnRzIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGRcbiAgICBjb25zdCBzdGFydFRvU3RhcnREaWZmID0gTWF0aC5hYnMoYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XG4gICAgaWYgKHN0YXJ0VG9TdGFydERpZmYgPD0gdGhyZXNob2xkTXMpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIC8vIEVuZC10by1zdGFydDogb25lIGV2ZW50IHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSB0aGUgb3RoZXIgZW5kc1xuICAgIC8vIEIgc3RhcnRzIHdpdGhpbiB0aHJlc2hvbGQgYmVmb3JlIEEgZW5kc1xuICAgIGNvbnN0IGJTdGFydHNCZWZvcmVBRW5kcyA9IGEuZW5kLmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpO1xuICAgIGlmIChiU3RhcnRzQmVmb3JlQUVuZHMgPiAwICYmIGJTdGFydHNCZWZvcmVBRW5kcyA8PSB0aHJlc2hvbGRNcylcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gQSBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgQiBlbmRzXG4gICAgY29uc3QgYVN0YXJ0c0JlZm9yZUJFbmRzID0gYi5lbmQuZ2V0VGltZSgpIC0gYS5zdGFydC5nZXRUaW1lKCk7XG4gICAgaWYgKGFTdGFydHNCZWZvcmVCRW5kcyA+IDAgJiYgYVN0YXJ0c0JlZm9yZUJFbmRzIDw9IHRocmVzaG9sZE1zKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIENoZWNrIGlmIGFsbCBldmVudHMgaW4gYSBncm91cCBzdGFydCB3aXRoaW4gdGhyZXNob2xkIG9mIGVhY2ggb3RoZXJcbiAqL1xuZnVuY3Rpb24gYWxsU3RhcnRXaXRoaW5UaHJlc2hvbGQoZXZlbnRzLCB0aHJlc2hvbGRNaW51dGVzKSB7XG4gICAgaWYgKGV2ZW50cy5sZW5ndGggPD0gMSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gRmluZCBlYXJsaWVzdCBhbmQgbGF0ZXN0IHN0YXJ0IHRpbWVzXG4gICAgbGV0IGVhcmxpZXN0ID0gZXZlbnRzWzBdLnN0YXJ0LmdldFRpbWUoKTtcbiAgICBsZXQgbGF0ZXN0ID0gZXZlbnRzWzBdLnN0YXJ0LmdldFRpbWUoKTtcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgICAgICBjb25zdCB0aW1lID0gZXZlbnQuc3RhcnQuZ2V0VGltZSgpO1xuICAgICAgICBpZiAodGltZSA8IGVhcmxpZXN0KVxuICAgICAgICAgICAgZWFybGllc3QgPSB0aW1lO1xuICAgICAgICBpZiAodGltZSA+IGxhdGVzdClcbiAgICAgICAgICAgIGxhdGVzdCA9IHRpbWU7XG4gICAgfVxuICAgIGNvbnN0IGRpZmZNaW51dGVzID0gKGxhdGVzdCAtIGVhcmxpZXN0KSAvICgxMDAwICogNjApO1xuICAgIHJldHVybiBkaWZmTWludXRlcyA8PSB0aHJlc2hvbGRNaW51dGVzO1xufVxuLyoqXG4gKiBGaW5kIGdyb3VwcyBvZiBvdmVybGFwcGluZyBldmVudHMgKGNvbm5lY3RlZCBieSBvdmVybGFwIGNoYWluKVxuICogRXZlbnRzIGFyZSBncm91cGVkIGlmIHRoZXkgb3ZlcmxhcCB3aXRoIGFueSBldmVudCBpbiB0aGUgZ3JvdXBcbiAqL1xuZnVuY3Rpb24gZmluZE92ZXJsYXBHcm91cHMoZXZlbnRzKSB7XG4gICAgaWYgKGV2ZW50cy5sZW5ndGggPT09IDApXG4gICAgICAgIHJldHVybiBbXTtcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCB1c2VkID0gbmV3IFNldCgpO1xuICAgIGNvbnN0IGdyb3VwcyA9IFtdO1xuICAgIGZvciAoY29uc3QgZXZlbnQgb2Ygc29ydGVkKSB7XG4gICAgICAgIGlmICh1c2VkLmhhcyhldmVudC5pZCkpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgZ3JvdXAgd2l0aCB0aGlzIGV2ZW50XG4gICAgICAgIGNvbnN0IGdyb3VwID0gW2V2ZW50XTtcbiAgICAgICAgdXNlZC5hZGQoZXZlbnQuaWQpO1xuICAgICAgICAvLyBFeHBhbmQgZ3JvdXAgYnkgZmluZGluZyBhbGwgY29ubmVjdGVkIGV2ZW50cyAodmlhIG92ZXJsYXApXG4gICAgICAgIGxldCBleHBhbmRlZCA9IHRydWU7XG4gICAgICAgIHdoaWxlIChleHBhbmRlZCkge1xuICAgICAgICAgICAgZXhwYW5kZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHNvcnRlZCkge1xuICAgICAgICAgICAgICAgIGlmICh1c2VkLmhhcyhjYW5kaWRhdGUuaWQpKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjYW5kaWRhdGUgb3ZlcmxhcHMgd2l0aCBhbnkgZXZlbnQgaW4gZ3JvdXBcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0cyA9IGdyb3VwLnNvbWUobWVtYmVyID0+IGV2ZW50c092ZXJsYXAobWVtYmVyLCBjYW5kaWRhdGUpKTtcbiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAucHVzaChjYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICB1c2VkLmFkZChjYW5kaWRhdGUuaWQpO1xuICAgICAgICAgICAgICAgICAgICBleHBhbmRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgICB9XG4gICAgcmV0dXJuIGdyb3Vwcztcbn1cbi8qKlxuICogRmluZCBncmlkIGNhbmRpZGF0ZXMgd2l0aGluIGEgZ3JvdXAgLSBldmVudHMgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgY2hhaW5cbiAqIFVzZXMgVjEgbG9naWM6IGV2ZW50cyBhcmUgY29ubmVjdGVkIGlmIHdpdGhpbiB0aHJlc2hvbGQgKG5vIG92ZXJsYXAgcmVxdWlyZW1lbnQpXG4gKi9cbmZ1bmN0aW9uIGZpbmRHcmlkQ2FuZGlkYXRlcyhldmVudHMsIHRocmVzaG9sZE1pbnV0ZXMpIHtcbiAgICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xuICAgIGNvbnN0IHVzZWQgPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgZ3JvdXBzID0gW107XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcbiAgICAgICAgaWYgKHVzZWQuaGFzKGV2ZW50LmlkKSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBncm91cCA9IFtldmVudF07XG4gICAgICAgIHVzZWQuYWRkKGV2ZW50LmlkKTtcbiAgICAgICAgLy8gRXhwYW5kIGJ5IHRocmVzaG9sZCBjaGFpbiAoVjEgbG9naWM6IG5vIG92ZXJsYXAgcmVxdWlyZW1lbnQsIGp1c3QgdGhyZXNob2xkKVxuICAgICAgICBsZXQgZXhwYW5kZWQgPSB0cnVlO1xuICAgICAgICB3aGlsZSAoZXhwYW5kZWQpIHtcbiAgICAgICAgICAgIGV4cGFuZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBzb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAodXNlZC5oYXMoY2FuZGlkYXRlLmlkKSlcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdHMgPSBncm91cC5zb21lKG1lbWJlciA9PiBldmVudHNXaXRoaW5UaHJlc2hvbGQobWVtYmVyLCBjYW5kaWRhdGUsIHRocmVzaG9sZE1pbnV0ZXMpKTtcbiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAucHVzaChjYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICB1c2VkLmFkZChjYW5kaWRhdGUuaWQpO1xuICAgICAgICAgICAgICAgICAgICBleHBhbmRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgICB9XG4gICAgcmV0dXJuIGdyb3Vwcztcbn1cbi8qKlxuICogQ2FsY3VsYXRlIHN0YWNrIGxldmVscyBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzIHVzaW5nIGdyZWVkeSBhbGdvcml0aG1cbiAqIEZvciBlYWNoIGV2ZW50OiBsZXZlbCA9IG1heChvdmVybGFwcGluZyBhbHJlYWR5LXByb2Nlc3NlZCBldmVudHMpICsgMVxuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVTdGFja0xldmVscyhldmVudHMpIHtcbiAgICBjb25zdCBsZXZlbHMgPSBuZXcgTWFwKCk7XG4gICAgY29uc3Qgc29ydGVkID0gWy4uLmV2ZW50c10uc29ydCgoYSwgYikgPT4gYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcbiAgICAgICAgbGV0IG1heE92ZXJsYXBwaW5nTGV2ZWwgPSAtMTtcbiAgICAgICAgLy8gRmluZCBtYXggbGV2ZWwgYW1vbmcgb3ZlcmxhcHBpbmcgZXZlbnRzIGFscmVhZHkgcHJvY2Vzc2VkXG4gICAgICAgIGZvciAoY29uc3QgW2lkLCBsZXZlbF0gb2YgbGV2ZWxzKSB7XG4gICAgICAgICAgICBjb25zdCBvdGhlciA9IGV2ZW50cy5maW5kKGUgPT4gZS5pZCA9PT0gaWQpO1xuICAgICAgICAgICAgaWYgKG90aGVyICYmIGV2ZW50c092ZXJsYXAoZXZlbnQsIG90aGVyKSkge1xuICAgICAgICAgICAgICAgIG1heE92ZXJsYXBwaW5nTGV2ZWwgPSBNYXRoLm1heChtYXhPdmVybGFwcGluZ0xldmVsLCBsZXZlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV2ZWxzLnNldChldmVudC5pZCwgbWF4T3ZlcmxhcHBpbmdMZXZlbCArIDEpO1xuICAgIH1cbiAgICByZXR1cm4gbGV2ZWxzO1xufVxuLyoqXG4gKiBBbGxvY2F0ZSBldmVudHMgdG8gY29sdW1ucyBmb3IgR1JJRCBsYXlvdXQgdXNpbmcgZ3JlZWR5IGFsZ29yaXRobVxuICogTm9uLW92ZXJsYXBwaW5nIGV2ZW50cyBjYW4gc2hhcmUgYSBjb2x1bW4gdG8gbWluaW1pemUgdG90YWwgY29sdW1uc1xuICovXG5mdW5jdGlvbiBhbGxvY2F0ZUNvbHVtbnMoZXZlbnRzKSB7XG4gICAgY29uc3Qgc29ydGVkID0gWy4uLmV2ZW50c10uc29ydCgoYSwgYikgPT4gYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XG4gICAgY29uc3QgY29sdW1ucyA9IFtdO1xuICAgIGZvciAoY29uc3QgZXZlbnQgb2Ygc29ydGVkKSB7XG4gICAgICAgIC8vIEZpbmQgZmlyc3QgY29sdW1uIHdoZXJlIGV2ZW50IGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIGV4aXN0aW5nIGV2ZW50c1xuICAgICAgICBsZXQgcGxhY2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhbkZpdCA9ICFjb2x1bW4uc29tZShlID0+IGV2ZW50c092ZXJsYXAoZXZlbnQsIGUpKTtcbiAgICAgICAgICAgIGlmIChjYW5GaXQpIHtcbiAgICAgICAgICAgICAgICBjb2x1bW4ucHVzaChldmVudCk7XG4gICAgICAgICAgICAgICAgcGxhY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBObyBzdWl0YWJsZSBjb2x1bW4gZm91bmQsIGNyZWF0ZSBuZXcgb25lXG4gICAgICAgIGlmICghcGxhY2VkKSB7XG4gICAgICAgICAgICBjb2x1bW5zLnB1c2goW2V2ZW50XSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvbHVtbnM7XG59XG4vKipcbiAqIE1haW4gZW50cnkgcG9pbnQ6IENhbGN1bGF0ZSBjb21wbGV0ZSBsYXlvdXQgZm9yIGEgY29sdW1uJ3MgZXZlbnRzXG4gKlxuICogQWxnb3JpdGhtOlxuICogMS4gRmluZCBvdmVybGFwIGdyb3VwcyAoZXZlbnRzIGNvbm5lY3RlZCBieSBvdmVybGFwIGNoYWluKVxuICogMi4gRm9yIGVhY2ggb3ZlcmxhcCBncm91cCwgZmluZCBncmlkIGNhbmRpZGF0ZXMgKGV2ZW50cyB3aXRoaW4gdGhyZXNob2xkIGNoYWluKVxuICogMy4gSWYgYWxsIGV2ZW50cyBpbiBvdmVybGFwIGdyb3VwIGZvcm0gYSBzaW5nbGUgZ3JpZCBjYW5kaWRhdGUgXHUyMTkyIEdSSUQgbW9kZVxuICogNC4gT3RoZXJ3aXNlIFx1MjE5MiBTVEFDS0lORyBtb2RlIHdpdGggY2FsY3VsYXRlZCBsZXZlbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUNvbHVtbkxheW91dChldmVudHMsIGNvbmZpZykge1xuICAgIGNvbnN0IHRocmVzaG9sZE1pbnV0ZXMgPSBjb25maWcuZ3JpZFN0YXJ0VGhyZXNob2xkTWludXRlcyA/PyAxMDtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgIGdyaWRzOiBbXSxcbiAgICAgICAgc3RhY2tlZDogW11cbiAgICB9O1xuICAgIGlmIChldmVudHMubGVuZ3RoID09PSAwKVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIC8vIEZpbmQgYWxsIG92ZXJsYXBwaW5nIGV2ZW50IGdyb3Vwc1xuICAgIGNvbnN0IG92ZXJsYXBHcm91cHMgPSBmaW5kT3ZlcmxhcEdyb3VwcyhldmVudHMpO1xuICAgIGZvciAoY29uc3Qgb3ZlcmxhcEdyb3VwIG9mIG92ZXJsYXBHcm91cHMpIHtcbiAgICAgICAgaWYgKG92ZXJsYXBHcm91cC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIFNpbmdsZSBldmVudCAtIG5vIGdyb3VwaW5nIG5lZWRlZFxuICAgICAgICAgICAgcmVzdWx0LnN0YWNrZWQucHVzaCh7XG4gICAgICAgICAgICAgICAgZXZlbnQ6IG92ZXJsYXBHcm91cFswXSxcbiAgICAgICAgICAgICAgICBzdGFja0xldmVsOiAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdpdGhpbiB0aGlzIG92ZXJsYXAgZ3JvdXAsIGZpbmQgZ3JpZCBjYW5kaWRhdGVzICh0aHJlc2hvbGQtY29ubmVjdGVkIHN1Ymdyb3VwcylcbiAgICAgICAgY29uc3QgZ3JpZFN1Ymdyb3VwcyA9IGZpbmRHcmlkQ2FuZGlkYXRlcyhvdmVybGFwR3JvdXAsIHRocmVzaG9sZE1pbnV0ZXMpO1xuICAgICAgICAvLyBDaGVjayBpZiB0aGUgRU5USVJFIG92ZXJsYXAgZ3JvdXAgZm9ybXMgYSBzaW5nbGUgZ3JpZCBjYW5kaWRhdGVcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gYWxsIGV2ZW50cyBhcmUgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgY2hhaW5cbiAgICAgICAgY29uc3QgbGFyZ2VzdEdyaWRDYW5kaWRhdGUgPSBncmlkU3ViZ3JvdXBzLnJlZHVjZSgobWF4LCBnKSA9PiBnLmxlbmd0aCA+IG1heC5sZW5ndGggPyBnIDogbWF4LCBncmlkU3ViZ3JvdXBzWzBdKTtcbiAgICAgICAgaWYgKGxhcmdlc3RHcmlkQ2FuZGlkYXRlLmxlbmd0aCA9PT0gb3ZlcmxhcEdyb3VwLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gQWxsIGV2ZW50cyBpbiBvdmVybGFwIGdyb3VwIGFyZSBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpbiBcdTIxOTIgR1JJRCBtb2RlXG4gICAgICAgICAgICBjb25zdCBjb2x1bW5zID0gYWxsb2NhdGVDb2x1bW5zKG92ZXJsYXBHcm91cCk7XG4gICAgICAgICAgICBjb25zdCBlYXJsaWVzdCA9IG92ZXJsYXBHcm91cC5yZWR1Y2UoKG1pbiwgZSkgPT4gZS5zdGFydCA8IG1pbi5zdGFydCA/IGUgOiBtaW4sIG92ZXJsYXBHcm91cFswXSk7XG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZWFybGllc3Quc3RhcnQsIGVhcmxpZXN0LmVuZCwgY29uZmlnKTtcbiAgICAgICAgICAgIHJlc3VsdC5ncmlkcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBldmVudHM6IG92ZXJsYXBHcm91cCxcbiAgICAgICAgICAgICAgICBjb2x1bW5zLFxuICAgICAgICAgICAgICAgIHN0YWNrTGV2ZWw6IDAsXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IHsgdG9wOiBwb3NpdGlvbi50b3AgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBOb3QgYWxsIGV2ZW50cyBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBcdTIxOTIgU1RBQ0tJTkcgbW9kZVxuICAgICAgICAgICAgY29uc3QgbGV2ZWxzID0gY2FsY3VsYXRlU3RhY2tMZXZlbHMob3ZlcmxhcEdyb3VwKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZXZlbnQgb2Ygb3ZlcmxhcEdyb3VwKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnN0YWNrZWQucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICBzdGFja0xldmVsOiBsZXZlbHMuZ2V0KGV2ZW50LmlkKSA/PyAwXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsICJpbXBvcnQgeyBjYWxjdWxhdGVFdmVudFBvc2l0aW9uLCBzbmFwVG9HcmlkLCBwaXhlbHNUb01pbnV0ZXMgfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcbmltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG5pbXBvcnQgeyBjYWxjdWxhdGVDb2x1bW5MYXlvdXQgfSBmcm9tICcuL0V2ZW50TGF5b3V0RW5naW5lJztcbi8qKlxuICogRXZlbnRSZW5kZXJlciAtIFJlbmRlcnMgY2FsZW5kYXIgZXZlbnRzIHRvIHRoZSBET01cbiAqXG4gKiBDTEVBTiBhcHByb2FjaDpcbiAqIC0gT25seSBkYXRhLWlkIGF0dHJpYnV0ZSBvbiBldmVudCBlbGVtZW50XG4gKiAtIGlubmVySFRNTCBjb250YWlucyBvbmx5IHZpc2libGUgY29udGVudFxuICogLSBFdmVudCBkYXRhIHJldHJpZXZlZCB2aWEgRXZlbnRTZXJ2aWNlIHdoZW4gbmVlZGVkXG4gKi9cbmV4cG9ydCBjbGFzcyBFdmVudFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihldmVudFNlcnZpY2UsIGRhdGVTZXJ2aWNlLCBncmlkQ29uZmlnLCBldmVudEJ1cykge1xuICAgICAgICB0aGlzLmV2ZW50U2VydmljZSA9IGV2ZW50U2VydmljZTtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLmdyaWRDb25maWcgPSBncmlkQ29uZmlnO1xuICAgICAgICB0aGlzLmV2ZW50QnVzID0gZXZlbnRCdXM7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5zZXR1cExpc3RlbmVycygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXR1cCBsaXN0ZW5lcnMgZm9yIGRyYWctZHJvcCBhbmQgdXBkYXRlIGV2ZW50c1xuICAgICAqL1xuICAgIHNldHVwTGlzdGVuZXJzKCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDb2x1bW5DaGFuZ2UocGF5bG9hZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19NT1ZFLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVEcmFnVGltZXN0YW1wKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX1VQREFURUQsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUV2ZW50VXBkYXRlZChwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRHJhZ0VuZChwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0xFQVZFX0hFQURFUiwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIEVWRU5UX0RSQUdfRU5EIC0gcmVtb3ZlIGVsZW1lbnQgaWYgZHJvcHBlZCBpbiBoZWFkZXJcbiAgICAgKi9cbiAgICBoYW5kbGVEcmFnRW5kKHBheWxvYWQpIHtcbiAgICAgICAgaWYgKHBheWxvYWQudGFyZ2V0ID09PSAnaGVhZGVyJykge1xuICAgICAgICAgICAgLy8gRXZlbnQgd2FzIGRyb3BwZWQgaW4gaGVhZGVyIGRyYXdlciAtIHJlbW92ZSBmcm9tIGdyaWRcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmNvbnRhaW5lcj8ucXVlcnlTZWxlY3Rvcihgc3dwLWNvbnRlbnQtdmlld3BvcnQgc3dwLWV2ZW50W2RhdGEtZXZlbnQtaWQ9XCIke3BheWxvYWQuc3dwRXZlbnQuZXZlbnRJZH1cIl1gKTtcbiAgICAgICAgICAgIGVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBoZWFkZXIgaXRlbSBsZWF2aW5nIGhlYWRlciAtIGNyZWF0ZSBzd3AtZXZlbnQgaW4gZ3JpZFxuICAgICAqL1xuICAgIGhhbmRsZURyYWdMZWF2ZUhlYWRlcihwYXlsb2FkKSB7XG4gICAgICAgIC8vIE9ubHkgaGFuZGxlIHdoZW4gc291cmNlIGlzIGhlYWRlciAoaGVhZGVyIGl0ZW0gZHJhZ2dlZCB0byBncmlkKVxuICAgICAgICBpZiAocGF5bG9hZC5zb3VyY2UgIT09ICdoZWFkZXInKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAoIXBheWxvYWQudGFyZ2V0Q29sdW1uIHx8ICFwYXlsb2FkLnN0YXJ0IHx8ICFwYXlsb2FkLmVuZClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gVHVybiBoZWFkZXIgaXRlbSBpbnRvIGdob3N0IChzdGF5cyB2aXNpYmxlIGJ1dCBmYWRlZClcbiAgICAgICAgaWYgKHBheWxvYWQuZWxlbWVudCkge1xuICAgICAgICAgICAgcGF5bG9hZC5lbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RyYWctZ2hvc3QnKTtcbiAgICAgICAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gJzAuMyc7XG4gICAgICAgICAgICBwYXlsb2FkLmVsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcbiAgICAgICAgfVxuICAgICAgICAvLyBDcmVhdGUgZXZlbnQgb2JqZWN0IGZyb20gaGVhZGVyIGl0ZW0gZGF0YVxuICAgICAgICBjb25zdCBldmVudCA9IHtcbiAgICAgICAgICAgIGlkOiBwYXlsb2FkLmV2ZW50SWQsXG4gICAgICAgICAgICB0aXRsZTogcGF5bG9hZC50aXRsZSB8fCAnJyxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnJyxcbiAgICAgICAgICAgIHN0YXJ0OiBwYXlsb2FkLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBwYXlsb2FkLmVuZCxcbiAgICAgICAgICAgIHR5cGU6ICdjdXN0b21lcicsXG4gICAgICAgICAgICBhbGxEYXk6IGZhbHNlLFxuICAgICAgICAgICAgc3luY1N0YXR1czogJ3BlbmRpbmcnXG4gICAgICAgIH07XG4gICAgICAgIC8vIENyZWF0ZSBzd3AtZXZlbnQgZWxlbWVudCB1c2luZyBleGlzdGluZyBtZXRob2RcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcbiAgICAgICAgLy8gQWRkIHRvIHRhcmdldCBjb2x1bW5cbiAgICAgICAgbGV0IGV2ZW50c0xheWVyID0gcGF5bG9hZC50YXJnZXRDb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICBpZiAoIWV2ZW50c0xheWVyKSB7XG4gICAgICAgICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcbiAgICAgICAgICAgIHBheWxvYWQudGFyZ2V0Q29sdW1uLmFwcGVuZENoaWxkKGV2ZW50c0xheWVyKTtcbiAgICAgICAgfVxuICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgLy8gTWFyayBhcyBkcmFnZ2luZyBzbyBEcmFnRHJvcE1hbmFnZXIgY2FuIGNvbnRpbnVlIHdpdGggaXRcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgRVZFTlRfVVBEQVRFRCAtIHJlLXJlbmRlciBhZmZlY3RlZCBjb2x1bW5zXG4gICAgICovXG4gICAgYXN5bmMgaGFuZGxlRXZlbnRVcGRhdGVkKHBheWxvYWQpIHtcbiAgICAgICAgLy8gUmUtcmVuZGVyIHNvdXJjZSBjb2x1bW4gKGlmIGRpZmZlcmVudCBmcm9tIHRhcmdldClcbiAgICAgICAgaWYgKHBheWxvYWQuc291cmNlQ29sdW1uS2V5ICE9PSBwYXlsb2FkLnRhcmdldENvbHVtbktleSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXJlbmRlckNvbHVtbihwYXlsb2FkLnNvdXJjZUNvbHVtbktleSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmUtcmVuZGVyIHRhcmdldCBjb2x1bW5cbiAgICAgICAgYXdhaXQgdGhpcy5yZXJlbmRlckNvbHVtbihwYXlsb2FkLnRhcmdldENvbHVtbktleSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlLXJlbmRlciBhIHNpbmdsZSBjb2x1bW4gd2l0aCBmcmVzaCBkYXRhIGZyb20gSW5kZXhlZERCXG4gICAgICovXG4gICAgYXN5bmMgcmVyZW5kZXJDb2x1bW4oY29sdW1uS2V5KSB7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xuICAgICAgICBpZiAoIWNvbHVtbilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gUmVhZCBkYXRlIGFuZCByZXNvdXJjZUlkIGRpcmVjdGx5IGZyb20gY29sdW1uIGF0dHJpYnV0ZXMgKGNvbHVtbktleSBpcyBvcGFxdWUpXG4gICAgICAgIGNvbnN0IGRhdGUgPSBjb2x1bW4uZGF0YXNldC5kYXRlO1xuICAgICAgICBjb25zdCByZXNvdXJjZUlkID0gY29sdW1uLmRhdGFzZXQucmVzb3VyY2VJZDtcbiAgICAgICAgaWYgKCFkYXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBHZXQgZGF0ZSByYW5nZSBmb3IgdGhpcyBkYXlcbiAgICAgICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgICAgZW5kRGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpO1xuICAgICAgICAvLyBGZXRjaCBldmVudHMgZnJvbSBJbmRleGVkREJcbiAgICAgICAgY29uc3QgZXZlbnRzID0gcmVzb3VyY2VJZFxuICAgICAgICAgICAgPyBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeVJlc291cmNlQW5kRGF0ZVJhbmdlKHJlc291cmNlSWQsIHN0YXJ0RGF0ZSwgZW5kRGF0ZSlcbiAgICAgICAgICAgIDogYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2Uoc3RhcnREYXRlLCBlbmREYXRlKTtcbiAgICAgICAgLy8gRmlsdGVyIHRvIHRpbWVkIGV2ZW50cyBhbmQgbWF0Y2ggZGF0ZSBleGFjdGx5XG4gICAgICAgIGNvbnN0IHRpbWVkRXZlbnRzID0gZXZlbnRzLmZpbHRlcihldmVudCA9PiAhZXZlbnQuYWxsRGF5ICYmIHRoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF0ZUtleShldmVudC5zdGFydCkgPT09IGRhdGUpO1xuICAgICAgICAvLyBHZXQgb3IgY3JlYXRlIGV2ZW50cyBsYXllclxuICAgICAgICBsZXQgZXZlbnRzTGF5ZXIgPSBjb2x1bW4ucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICBpZiAoIWV2ZW50c0xheWVyKSB7XG4gICAgICAgICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcbiAgICAgICAgICAgIGNvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgZXZlbnRzXG4gICAgICAgIGV2ZW50c0xheWVyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAvLyBDYWxjdWxhdGUgbGF5b3V0IHdpdGggc3RhY2tpbmcvZ3JvdXBpbmdcbiAgICAgICAgY29uc3QgbGF5b3V0ID0gY2FsY3VsYXRlQ29sdW1uTGF5b3V0KHRpbWVkRXZlbnRzLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAvLyBSZW5kZXIgR1JJRCBncm91cHNcbiAgICAgICAgbGF5b3V0LmdyaWRzLmZvckVhY2goZ3JpZCA9PiB7XG4gICAgICAgICAgICBjb25zdCBncm91cEVsID0gdGhpcy5yZW5kZXJHcmlkR3JvdXAoZ3JpZCk7XG4gICAgICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChncm91cEVsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJlbmRlciBTVEFDS0VEIGV2ZW50c1xuICAgICAgICBsYXlvdXQuc3RhY2tlZC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XG4gICAgICAgICAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChldmVudEVsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmQgYSBjb2x1bW4gZWxlbWVudCBieSBjb2x1bW5LZXlcbiAgICAgKi9cbiAgICBmaW5kQ29sdW1uKGNvbHVtbktleSkge1xuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGBzd3AtZGF5LWNvbHVtbltkYXRhLWNvbHVtbi1rZXk9XCIke2NvbHVtbktleX1cIl1gKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIGV2ZW50IG1vdmluZyB0byBhIG5ldyBjb2x1bW4gZHVyaW5nIGRyYWdcbiAgICAgKi9cbiAgICBoYW5kbGVDb2x1bW5DaGFuZ2UocGF5bG9hZCkge1xuICAgICAgICBjb25zdCBldmVudHNMYXllciA9IHBheWxvYWQubmV3Q29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcbiAgICAgICAgaWYgKCFldmVudHNMYXllcilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gTW92ZSBlbGVtZW50IHRvIG5ldyBjb2x1bW5cbiAgICAgICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQocGF5bG9hZC5lbGVtZW50KTtcbiAgICAgICAgLy8gUHJlc2VydmUgWSBwb3NpdGlvblxuICAgICAgICBwYXlsb2FkLmVsZW1lbnQuc3R5bGUudG9wID0gYCR7cGF5bG9hZC5jdXJyZW50WX1weGA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aW1lc3RhbXAgZGlzcGxheSBkdXJpbmcgZHJhZyAoc25hcHBlZCB0byBncmlkKVxuICAgICAqL1xuICAgIHVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZCkge1xuICAgICAgICBjb25zdCB0aW1lRWwgPSBwYXlsb2FkLmVsZW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50LXRpbWUnKTtcbiAgICAgICAgaWYgKCF0aW1lRWwpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIFNuYXAgcG9zaXRpb24gdG8gZ3JpZCBpbnRlcnZhbFxuICAgICAgICBjb25zdCBzbmFwcGVkWSA9IHNuYXBUb0dyaWQocGF5bG9hZC5jdXJyZW50WSwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGFydCB0aW1lXG4gICAgICAgIGNvbnN0IG1pbnV0ZXNGcm9tR3JpZFN0YXJ0ID0gcGl4ZWxzVG9NaW51dGVzKHNuYXBwZWRZLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICBjb25zdCBzdGFydE1pbnV0ZXMgPSAodGhpcy5ncmlkQ29uZmlnLmRheVN0YXJ0SG91ciAqIDYwKSArIG1pbnV0ZXNGcm9tR3JpZFN0YXJ0O1xuICAgICAgICAvLyBLZWVwIG9yaWdpbmFsIGR1cmF0aW9uIChmcm9tIGVsZW1lbnQgaGVpZ2h0KVxuICAgICAgICBjb25zdCBoZWlnaHQgPSBwYXJzZUZsb2F0KHBheWxvYWQuZWxlbWVudC5zdHlsZS5oZWlnaHQpIHx8IHRoaXMuZ3JpZENvbmZpZy5ob3VySGVpZ2h0O1xuICAgICAgICBjb25zdCBkdXJhdGlvbk1pbnV0ZXMgPSBwaXhlbHNUb01pbnV0ZXMoaGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAvLyBDcmVhdGUgRGF0ZSBvYmplY3RzIGZvciBjb25zaXN0ZW50IGZvcm1hdHRpbmcgdmlhIERhdGVTZXJ2aWNlXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyk7XG4gICAgICAgIGNvbnN0IGVuZCA9IHRoaXMubWludXRlc1RvRGF0ZShzdGFydE1pbnV0ZXMgKyBkdXJhdGlvbk1pbnV0ZXMpO1xuICAgICAgICB0aW1lRWwudGV4dENvbnRlbnQgPSB0aGlzLmRhdGVTZXJ2aWNlLmZvcm1hdFRpbWVSYW5nZShzdGFydCwgZW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBtaW51dGVzIHNpbmNlIG1pZG5pZ2h0IHRvIGEgRGF0ZSBvYmplY3QgKHRvZGF5KVxuICAgICAqL1xuICAgIG1pbnV0ZXNUb0RhdGUobWludXRlcykge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgZGF0ZS5zZXRIb3VycyhNYXRoLmZsb29yKG1pbnV0ZXMgLyA2MCkgJSAyNCwgbWludXRlcyAlIDYwLCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciBldmVudHMgZm9yIHZpc2libGUgZGF0ZXMgaW50byBkYXkgY29sdW1uc1xuICAgICAqIEBwYXJhbSBjb250YWluZXIgLSBDYWxlbmRhciBjb250YWluZXIgZWxlbWVudFxuICAgICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgd2l0aCAnZGF0ZScgYW5kIG9wdGlvbmFsbHkgJ3Jlc291cmNlJyBhcnJheXNcbiAgICAgKiBAcGFyYW0gZmlsdGVyVGVtcGxhdGUgLSBUZW1wbGF0ZSBmb3IgbWF0Y2hpbmcgZXZlbnRzIHRvIGNvbHVtbnNcbiAgICAgKi9cbiAgICBhc3luYyByZW5kZXIoY29udGFpbmVyLCBmaWx0ZXIsIGZpbHRlclRlbXBsYXRlKSB7XG4gICAgICAgIC8vIFN0b3JlIGNvbnRhaW5lciByZWZlcmVuY2UgZm9yIGxhdGVyIHJlLXJlbmRlcnNcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIGNvbnN0IHZpc2libGVEYXRlcyA9IGZpbHRlclsnZGF0ZSddIHx8IFtdO1xuICAgICAgICBpZiAodmlzaWJsZURhdGVzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gR2V0IGRhdGUgcmFuZ2UgZm9yIHF1ZXJ5XG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1swXSk7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZSh2aXNpYmxlRGF0ZXNbdmlzaWJsZURhdGVzLmxlbmd0aCAtIDFdKTtcbiAgICAgICAgZW5kRGF0ZS5zZXRIb3VycygyMywgNTksIDU5LCA5OTkpO1xuICAgICAgICAvLyBGZXRjaCBldmVudHMgZnJvbSBJbmRleGVkREJcbiAgICAgICAgY29uc3QgZXZlbnRzID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2Uoc3RhcnREYXRlLCBlbmREYXRlKTtcbiAgICAgICAgLy8gRmluZCBkYXkgY29sdW1uc1xuICAgICAgICBjb25zdCBkYXlDb2x1bW5zID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpO1xuICAgICAgICBpZiAoIWRheUNvbHVtbnMpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBkYXlDb2x1bW5zLnF1ZXJ5U2VsZWN0b3JBbGwoJ3N3cC1kYXktY29sdW1uJyk7XG4gICAgICAgIC8vIFJlbmRlciBldmVudHMgaW50byBlYWNoIGNvbHVtbiBiYXNlZCBvbiBGaWx0ZXJUZW1wbGF0ZSBtYXRjaGluZ1xuICAgICAgICBjb2x1bW5zLmZvckVhY2goY29sdW1uID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbkVsID0gY29sdW1uO1xuICAgICAgICAgICAgLy8gVXNlIEZpbHRlclRlbXBsYXRlIGZvciBtYXRjaGluZyAtIG9ubHkgZmllbGRzIGluIHRlbXBsYXRlIGFyZSBjaGVja2VkXG4gICAgICAgICAgICBjb25zdCBjb2x1bW5FdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+IGZpbHRlclRlbXBsYXRlLm1hdGNoZXMoZXZlbnQsIGNvbHVtbkVsKSk7XG4gICAgICAgICAgICAvLyBHZXQgb3IgY3JlYXRlIGV2ZW50cyBsYXllclxuICAgICAgICAgICAgbGV0IGV2ZW50c0xheWVyID0gY29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcbiAgICAgICAgICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcbiAgICAgICAgICAgICAgICBjb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgZXZlbnRzXG4gICAgICAgICAgICBldmVudHNMYXllci5pbm5lckhUTUwgPSAnJztcbiAgICAgICAgICAgIC8vIEZpbHRlciB0byB0aW1lZCBldmVudHMgb25seVxuICAgICAgICAgICAgY29uc3QgdGltZWRFdmVudHMgPSBjb2x1bW5FdmVudHMuZmlsdGVyKGV2ZW50ID0+ICFldmVudC5hbGxEYXkpO1xuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIGxheW91dCB3aXRoIHN0YWNraW5nL2dyb3VwaW5nXG4gICAgICAgICAgICBjb25zdCBsYXlvdXQgPSBjYWxjdWxhdGVDb2x1bW5MYXlvdXQodGltZWRFdmVudHMsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgICAgICAvLyBSZW5kZXIgR1JJRCBncm91cHMgKHNpbXVsdGFuZW91cyBldmVudHMgc2lkZS1ieS1zaWRlKVxuICAgICAgICAgICAgbGF5b3V0LmdyaWRzLmZvckVhY2goZ3JpZCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBFbCA9IHRoaXMucmVuZGVyR3JpZEdyb3VwKGdyaWQpO1xuICAgICAgICAgICAgICAgIGV2ZW50c0xheWVyLmFwcGVuZENoaWxkKGdyb3VwRWwpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBSZW5kZXIgU1RBQ0tFRCBldmVudHMgKG92ZXJsYXBwaW5nIHdpdGggbWFyZ2luIG9mZnNldClcbiAgICAgICAgICAgIGxheW91dC5zdGFja2VkLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XG4gICAgICAgICAgICAgICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQoZXZlbnRFbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHNpbmdsZSBldmVudCBlbGVtZW50XG4gICAgICpcbiAgICAgKiBDTEVBTiBhcHByb2FjaDpcbiAgICAgKiAtIE9ubHkgZGF0YS1pZCBmb3IgbG9va3VwXG4gICAgICogLSBWaXNpYmxlIGNvbnRlbnQgaW4gaW5uZXJIVE1MIG9ubHlcbiAgICAgKi9cbiAgICBjcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudCcpO1xuICAgICAgICAvLyBEYXRhIGF0dHJpYnV0ZXMgZm9yIFN3cEV2ZW50IGNvbXBhdGliaWxpdHlcbiAgICAgICAgZWxlbWVudC5kYXRhc2V0LmV2ZW50SWQgPSBldmVudC5pZDtcbiAgICAgICAgaWYgKGV2ZW50LnJlc291cmNlSWQpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuZGF0YXNldC5yZXNvdXJjZUlkID0gZXZlbnQucmVzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBDYWxjdWxhdGUgcG9zaXRpb25cbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cG9zaXRpb24udG9wfXB4YDtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtwb3NpdGlvbi5oZWlnaHR9cHhgO1xuICAgICAgICAvLyBDb2xvciBjbGFzcyBiYXNlZCBvbiBldmVudCB0eXBlXG4gICAgICAgIGNvbnN0IGNvbG9yQ2xhc3MgPSB0aGlzLmdldENvbG9yQ2xhc3MoZXZlbnQpO1xuICAgICAgICBpZiAoY29sb3JDbGFzcykge1xuICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKGNvbG9yQ2xhc3MpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFZpc2libGUgY29udGVudCBvbmx5XG4gICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gYFxyXG4gICAgICA8c3dwLWV2ZW50LXRpbWU+JHt0aGlzLmRhdGVTZXJ2aWNlLmZvcm1hdFRpbWVSYW5nZShldmVudC5zdGFydCwgZXZlbnQuZW5kKX08L3N3cC1ldmVudC10aW1lPlxyXG4gICAgICA8c3dwLWV2ZW50LXRpdGxlPiR7dGhpcy5lc2NhcGVIdG1sKGV2ZW50LnRpdGxlKX08L3N3cC1ldmVudC10aXRsZT5cclxuICAgICAgJHtldmVudC5kZXNjcmlwdGlvbiA/IGA8c3dwLWV2ZW50LWRlc2NyaXB0aW9uPiR7dGhpcy5lc2NhcGVIdG1sKGV2ZW50LmRlc2NyaXB0aW9uKX08L3N3cC1ldmVudC1kZXNjcmlwdGlvbj5gIDogJyd9XHJcbiAgICBgO1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGNvbG9yIGNsYXNzIGJhc2VkIG9uIG1ldGFkYXRhLmNvbG9yIG9yIGV2ZW50IHR5cGVcbiAgICAgKi9cbiAgICBnZXRDb2xvckNsYXNzKGV2ZW50KSB7XG4gICAgICAgIC8vIENoZWNrIG1ldGFkYXRhLmNvbG9yIGZpcnN0XG4gICAgICAgIGlmIChldmVudC5tZXRhZGF0YT8uY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBgaXMtJHtldmVudC5tZXRhZGF0YS5jb2xvcn1gO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZhbGxiYWNrIHRvIHR5cGUtYmFzZWQgY29sb3JcbiAgICAgICAgY29uc3QgdHlwZUNvbG9ycyA9IHtcbiAgICAgICAgICAgICdjdXN0b21lcic6ICdpcy1ibHVlJyxcbiAgICAgICAgICAgICd2YWNhdGlvbic6ICdpcy1ncmVlbicsXG4gICAgICAgICAgICAnYnJlYWsnOiAnaXMtYW1iZXInLFxuICAgICAgICAgICAgJ21lZXRpbmcnOiAnaXMtcHVycGxlJyxcbiAgICAgICAgICAgICdibG9ja2VkJzogJ2lzLXJlZCdcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHR5cGVDb2xvcnNbZXZlbnQudHlwZV0gfHwgJ2lzLWJsdWUnO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFc2NhcGUgSFRNTCB0byBwcmV2ZW50IFhTU1xuICAgICAqL1xuICAgIGVzY2FwZUh0bWwodGV4dCkge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LnRleHRDb250ZW50ID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciBhIEdSSUQgZ3JvdXAgd2l0aCBzaWRlLWJ5LXNpZGUgY29sdW1uc1xuICAgICAqIFVzZWQgd2hlbiBtdWx0aXBsZSBldmVudHMgc3RhcnQgYXQgdGhlIHNhbWUgdGltZVxuICAgICAqL1xuICAgIHJlbmRlckdyaWRHcm91cChsYXlvdXQpIHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnQtZ3JvdXAnKTtcbiAgICAgICAgZ3JvdXAuY2xhc3NMaXN0LmFkZChgY29scy0ke2xheW91dC5jb2x1bW5zLmxlbmd0aH1gKTtcbiAgICAgICAgZ3JvdXAuc3R5bGUudG9wID0gYCR7bGF5b3V0LnBvc2l0aW9uLnRvcH1weGA7XG4gICAgICAgIC8vIFN0YWNrIGxldmVsIHN0eWxpbmcgZm9yIGVudGlyZSBncm91cCAoaWYgbmVzdGVkIGluIGFub3RoZXIgZXZlbnQpXG4gICAgICAgIGlmIChsYXlvdXQuc3RhY2tMZXZlbCA+IDApIHtcbiAgICAgICAgICAgIGdyb3VwLnN0eWxlLm1hcmdpbkxlZnQgPSBgJHtsYXlvdXQuc3RhY2tMZXZlbCAqIDE1fXB4YDtcbiAgICAgICAgICAgIGdyb3VwLnN0eWxlLnpJbmRleCA9IGAkezEwMCArIGxheW91dC5zdGFja0xldmVsfWA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBoZWlnaHQgbmVlZGVkIGZvciB0aGUgZ3JvdXAgKHRhbGxlc3QgZXZlbnQpXG4gICAgICAgIGxldCBtYXhCb3R0b20gPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGxheW91dC5ldmVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvcyA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50Qm90dG9tID0gcG9zLnRvcCArIHBvcy5oZWlnaHQ7XG4gICAgICAgICAgICBpZiAoZXZlbnRCb3R0b20gPiBtYXhCb3R0b20pXG4gICAgICAgICAgICAgICAgbWF4Qm90dG9tID0gZXZlbnRCb3R0b207XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZ3JvdXBIZWlnaHQgPSBtYXhCb3R0b20gLSBsYXlvdXQucG9zaXRpb24udG9wO1xuICAgICAgICBncm91cC5zdHlsZS5oZWlnaHQgPSBgJHtncm91cEhlaWdodH1weGA7XG4gICAgICAgIC8vIENyZWF0ZSB3cmFwcGVyIGRpdiBmb3IgZWFjaCBjb2x1bW5cbiAgICAgICAgbGF5b3V0LmNvbHVtbnMuZm9yRWFjaChjb2x1bW5FdmVudHMgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgd3JhcHBlci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICAgICAgICBjb2x1bW5FdmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcbiAgICAgICAgICAgICAgICAvLyBQb3NpdGlvbiByZWxhdGl2ZSB0byBncm91cCB0b3BcbiAgICAgICAgICAgICAgICBjb25zdCBwb3MgPSBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgICAgICAgICAgZXZlbnRFbC5zdHlsZS50b3AgPSBgJHtwb3MudG9wIC0gbGF5b3V0LnBvc2l0aW9uLnRvcH1weGA7XG4gICAgICAgICAgICAgICAgZXZlbnRFbC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICAgICAgZXZlbnRFbC5zdHlsZS5sZWZ0ID0gJzAnO1xuICAgICAgICAgICAgICAgIGV2ZW50RWwuc3R5bGUucmlnaHQgPSAnMCc7XG4gICAgICAgICAgICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZChldmVudEVsKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZ3JvdXAuYXBwZW5kQ2hpbGQod3JhcHBlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZ3JvdXA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciBhIFNUQUNLRUQgZXZlbnQgd2l0aCBtYXJnaW4tbGVmdCBvZmZzZXRcbiAgICAgKiBVc2VkIGZvciBvdmVybGFwcGluZyBldmVudHMgdGhhdCBkb24ndCBzdGFydCBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICovXG4gICAgcmVuZGVyU3RhY2tlZEV2ZW50KGV2ZW50LCBzdGFja0xldmVsKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmNyZWF0ZUV2ZW50RWxlbWVudChldmVudCk7XG4gICAgICAgIC8vIEFkZCBzdGFjayBtZXRhZGF0YSBmb3IgZHJhZy1kcm9wIGFuZCBvdGhlciBmZWF0dXJlc1xuICAgICAgICBlbGVtZW50LmRhdGFzZXQuc3RhY2tMaW5rID0gSlNPTi5zdHJpbmdpZnkoeyBzdGFja0xldmVsIH0pO1xuICAgICAgICAvLyBWaXN1YWwgc3R5bGluZyBiYXNlZCBvbiBzdGFjayBsZXZlbFxuICAgICAgICBpZiAoc3RhY2tMZXZlbCA+IDApIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUubWFyZ2luTGVmdCA9IGAke3N0YWNrTGV2ZWwgKiAxNX1weGA7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnpJbmRleCA9IGAkezEwMCArIHN0YWNrTGV2ZWx9YDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBTY2hlZHVsZVJlbmRlcmVyIC0gUmVuZGVycyB1bmF2YWlsYWJsZSB0aW1lIHpvbmVzIGluIGRheSBjb2x1bW5zXG4gKlxuICogQ3JlYXRlcyB2aXN1YWwgaW5kaWNhdG9ycyBmb3IgdGltZXMgb3V0c2lkZSB0aGUgcmVzb3VyY2UncyB3b3JraW5nIGhvdXJzOlxuICogLSBCZWZvcmUgd29yayBzdGFydCAoZS5nLiwgMDY6MDAgLSAwOTowMClcbiAqIC0gQWZ0ZXIgd29yayBlbmQgKGUuZy4sIDE3OjAwIC0gMTg6MDApXG4gKiAtIEZ1bGwgZGF5IGlmIHJlc291cmNlIGlzIG9mZiAoc2NoZWR1bGUgPSBudWxsKVxuICovXG5leHBvcnQgY2xhc3MgU2NoZWR1bGVSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3Ioc2NoZWR1bGVTZXJ2aWNlLCBkYXRlU2VydmljZSwgZ3JpZENvbmZpZykge1xuICAgICAgICB0aGlzLnNjaGVkdWxlU2VydmljZSA9IHNjaGVkdWxlU2VydmljZTtcbiAgICAgICAgdGhpcy5kYXRlU2VydmljZSA9IGRhdGVTZXJ2aWNlO1xuICAgICAgICB0aGlzLmdyaWRDb25maWcgPSBncmlkQ29uZmlnO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdW5hdmFpbGFibGUgem9uZXMgZm9yIHZpc2libGUgY29sdW1uc1xuICAgICAqIEBwYXJhbSBjb250YWluZXIgLSBDYWxlbmRhciBjb250YWluZXIgZWxlbWVudFxuICAgICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgd2l0aCAnZGF0ZScgYW5kICdyZXNvdXJjZScgYXJyYXlzXG4gICAgICovXG4gICAgYXN5bmMgcmVuZGVyKGNvbnRhaW5lciwgZmlsdGVyKSB7XG4gICAgICAgIGNvbnN0IGRhdGVzID0gZmlsdGVyWydkYXRlJ10gfHwgW107XG4gICAgICAgIGNvbnN0IHJlc291cmNlSWRzID0gZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xuICAgICAgICBpZiAoZGF0ZXMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBGaW5kIGRheSBjb2x1bW5zXG4gICAgICAgIGNvbnN0IGRheUNvbHVtbnMgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWRheS1jb2x1bW5zJyk7XG4gICAgICAgIGlmICghZGF5Q29sdW1ucylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IGRheUNvbHVtbnMucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGNvbHVtbi5kYXRhc2V0LmRhdGU7XG4gICAgICAgICAgICBjb25zdCByZXNvdXJjZUlkID0gY29sdW1uLmRhdGFzZXQucmVzb3VyY2VJZDtcbiAgICAgICAgICAgIGlmICghZGF0ZSB8fCAhcmVzb3VyY2VJZClcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIC8vIEdldCBvciBjcmVhdGUgdW5hdmFpbGFibGUgbGF5ZXJcbiAgICAgICAgICAgIGxldCB1bmF2YWlsYWJsZUxheWVyID0gY29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC11bmF2YWlsYWJsZS1sYXllcicpO1xuICAgICAgICAgICAgaWYgKCF1bmF2YWlsYWJsZUxheWVyKSB7XG4gICAgICAgICAgICAgICAgdW5hdmFpbGFibGVMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC11bmF2YWlsYWJsZS1sYXllcicpO1xuICAgICAgICAgICAgICAgIGNvbHVtbi5pbnNlcnRCZWZvcmUodW5hdmFpbGFibGVMYXllciwgY29sdW1uLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmdcbiAgICAgICAgICAgIHVuYXZhaWxhYmxlTGF5ZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgICAgICAvLyBHZXQgc2NoZWR1bGUgZm9yIHRoaXMgcmVzb3VyY2UvZGF0ZVxuICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBhd2FpdCB0aGlzLnNjaGVkdWxlU2VydmljZS5nZXRTY2hlZHVsZUZvckRhdGUocmVzb3VyY2VJZCwgZGF0ZSk7XG4gICAgICAgICAgICAvLyBSZW5kZXIgdW5hdmFpbGFibGUgem9uZXNcbiAgICAgICAgICAgIHRoaXMucmVuZGVyVW5hdmFpbGFibGVab25lcyh1bmF2YWlsYWJsZUxheWVyLCBzY2hlZHVsZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHVuYXZhaWxhYmxlIHRpbWUgem9uZXMgYmFzZWQgb24gc2NoZWR1bGVcbiAgICAgKi9cbiAgICByZW5kZXJVbmF2YWlsYWJsZVpvbmVzKGxheWVyLCBzY2hlZHVsZSkge1xuICAgICAgICBjb25zdCBkYXlTdGFydE1pbnV0ZXMgPSB0aGlzLmdyaWRDb25maWcuZGF5U3RhcnRIb3VyICogNjA7XG4gICAgICAgIGNvbnN0IGRheUVuZE1pbnV0ZXMgPSB0aGlzLmdyaWRDb25maWcuZGF5RW5kSG91ciAqIDYwO1xuICAgICAgICBjb25zdCBtaW51dGVIZWlnaHQgPSB0aGlzLmdyaWRDb25maWcuaG91ckhlaWdodCAvIDYwO1xuICAgICAgICBpZiAoc2NoZWR1bGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEZ1bGwgZGF5IHVuYXZhaWxhYmxlXG4gICAgICAgICAgICBjb25zdCB6b25lID0gdGhpcy5jcmVhdGVVbmF2YWlsYWJsZVpvbmUoMCwgKGRheUVuZE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0KTtcbiAgICAgICAgICAgIGxheWVyLmFwcGVuZENoaWxkKHpvbmUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdvcmtTdGFydE1pbnV0ZXMgPSB0aGlzLmRhdGVTZXJ2aWNlLnRpbWVUb01pbnV0ZXMoc2NoZWR1bGUuc3RhcnQpO1xuICAgICAgICBjb25zdCB3b3JrRW5kTWludXRlcyA9IHRoaXMuZGF0ZVNlcnZpY2UudGltZVRvTWludXRlcyhzY2hlZHVsZS5lbmQpO1xuICAgICAgICAvLyBCZWZvcmUgd29yayBzdGFydFxuICAgICAgICBpZiAod29ya1N0YXJ0TWludXRlcyA+IGRheVN0YXJ0TWludXRlcykge1xuICAgICAgICAgICAgY29uc3QgdG9wID0gMDtcbiAgICAgICAgICAgIGNvbnN0IGhlaWdodCA9ICh3b3JrU3RhcnRNaW51dGVzIC0gZGF5U3RhcnRNaW51dGVzKSAqIG1pbnV0ZUhlaWdodDtcbiAgICAgICAgICAgIGNvbnN0IHpvbmUgPSB0aGlzLmNyZWF0ZVVuYXZhaWxhYmxlWm9uZSh0b3AsIGhlaWdodCk7XG4gICAgICAgICAgICBsYXllci5hcHBlbmRDaGlsZCh6b25lKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBZnRlciB3b3JrIGVuZFxuICAgICAgICBpZiAod29ya0VuZE1pbnV0ZXMgPCBkYXlFbmRNaW51dGVzKSB7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSAod29ya0VuZE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gKGRheUVuZE1pbnV0ZXMgLSB3b3JrRW5kTWludXRlcykgKiBtaW51dGVIZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCB6b25lID0gdGhpcy5jcmVhdGVVbmF2YWlsYWJsZVpvbmUodG9wLCBoZWlnaHQpO1xuICAgICAgICAgICAgbGF5ZXIuYXBwZW5kQ2hpbGQoem9uZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIHVuYXZhaWxhYmxlIHpvbmUgZWxlbWVudFxuICAgICAqL1xuICAgIGNyZWF0ZVVuYXZhaWxhYmxlWm9uZSh0b3AsIGhlaWdodCkge1xuICAgICAgICBjb25zdCB6b25lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLXVuYXZhaWxhYmxlLXpvbmUnKTtcbiAgICAgICAgem9uZS5zdHlsZS50b3AgPSBgJHt0b3B9cHhgO1xuICAgICAgICB6b25lLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgICAgIHJldHVybiB6b25lO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBDb3JlRXZlbnRzIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL0NvcmVFdmVudHMnO1xuLyoqXG4gKiBIZWFkZXJEcmF3ZXJSZW5kZXJlciAtIEhhbmRsZXMgcmVuZGVyaW5nIG9mIGl0ZW1zIGluIHRoZSBoZWFkZXIgZHJhd2VyXG4gKlxuICogTGlzdGVucyB0byBkcmFnIGV2ZW50cyBmcm9tIERyYWdEcm9wTWFuYWdlciBhbmQgY3JlYXRlcy9tYW5hZ2VzXG4gKiBzd3AtaGVhZGVyLWl0ZW0gZWxlbWVudHMgaW4gdGhlIGhlYWRlciBkcmF3ZXIuXG4gKlxuICogVXNlcyBzdWJncmlkIGZvciBjb2x1bW4gYWxpZ25tZW50IHdpdGggcGFyZW50IHN3cC1jYWxlbmRhci1oZWFkZXIuXG4gKiBQb3NpdGlvbiBpdGVtcyB2aWEgZ3JpZEFyZWEgZm9yIGV4cGxpY2l0IHJvdy9jb2x1bW4gcGxhY2VtZW50LlxuICovXG5leHBvcnQgY2xhc3MgSGVhZGVyRHJhd2VyUmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50QnVzLCBncmlkQ29uZmlnLCBoZWFkZXJEcmF3ZXJNYW5hZ2VyLCBldmVudFNlcnZpY2UsIGRhdGVTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5ncmlkQ29uZmlnID0gZ3JpZENvbmZpZztcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXJNYW5hZ2VyID0gaGVhZGVyRHJhd2VyTWFuYWdlcjtcbiAgICAgICAgdGhpcy5ldmVudFNlcnZpY2UgPSBldmVudFNlcnZpY2U7XG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2UgPSBkYXRlU2VydmljZTtcbiAgICAgICAgdGhpcy5jdXJyZW50SXRlbSA9IG51bGw7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5zb3VyY2VFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy53YXNFeHBhbmRlZEJlZm9yZURyYWcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5maWx0ZXJUZW1wbGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuc2V0dXBMaXN0ZW5lcnMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGFsbERheSBldmVudHMgaW50byB0aGUgaGVhZGVyIGRyYXdlciB3aXRoIHJvdyBzdGFja2luZ1xuICAgICAqIEBwYXJhbSBmaWx0ZXJUZW1wbGF0ZSAtIFRlbXBsYXRlIGZvciBtYXRjaGluZyBldmVudHMgdG8gY29sdW1uc1xuICAgICAqL1xuICAgIGFzeW5jIHJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpIHtcbiAgICAgICAgLy8gU3RvcmUgZmlsdGVyVGVtcGxhdGUgZm9yIGJ1aWxkQ29sdW1uS2V5RnJvbUV2ZW50XG4gICAgICAgIHRoaXMuZmlsdGVyVGVtcGxhdGUgPSBmaWx0ZXJUZW1wbGF0ZTtcbiAgICAgICAgY29uc3QgZHJhd2VyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItZHJhd2VyJyk7XG4gICAgICAgIGlmICghZHJhd2VyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCB2aXNpYmxlRGF0ZXMgPSBmaWx0ZXJbJ2RhdGUnXSB8fCBbXTtcbiAgICAgICAgaWYgKHZpc2libGVEYXRlcy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEdldCBjb2x1bW4ga2V5cyBmcm9tIERPTSBmb3IgY29ycmVjdCBtdWx0aS1yZXNvdXJjZSBwb3NpdGlvbmluZ1xuICAgICAgICBjb25zdCB2aXNpYmxlQ29sdW1uS2V5cyA9IHRoaXMuZ2V0VmlzaWJsZUNvbHVtbktleXNGcm9tRE9NKCk7XG4gICAgICAgIGlmICh2aXNpYmxlQ29sdW1uS2V5cy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEZldGNoIGV2ZW50cyBmb3IgZGF0ZSByYW5nZVxuICAgICAgICBjb25zdCBzdGFydERhdGUgPSBuZXcgRGF0ZSh2aXNpYmxlRGF0ZXNbMF0pO1xuICAgICAgICBjb25zdCBlbmREYXRlID0gbmV3IERhdGUodmlzaWJsZURhdGVzW3Zpc2libGVEYXRlcy5sZW5ndGggLSAxXSk7XG4gICAgICAgIGVuZERhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KTtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0QnlEYXRlUmFuZ2Uoc3RhcnREYXRlLCBlbmREYXRlKTtcbiAgICAgICAgLy8gRmlsdGVyIHRvIGFsbERheSBldmVudHMgb25seSAoYWxsRGF5ICE9PSBmYWxzZSlcbiAgICAgICAgY29uc3QgYWxsRGF5RXZlbnRzID0gZXZlbnRzLmZpbHRlcihldmVudCA9PiBldmVudC5hbGxEYXkgIT09IGZhbHNlKTtcbiAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgaXRlbXNcbiAgICAgICAgZHJhd2VyLmlubmVySFRNTCA9ICcnO1xuICAgICAgICBpZiAoYWxsRGF5RXZlbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGxheW91dCB3aXRoIHJvdyBzdGFja2luZyB1c2luZyBjb2x1bW5LZXlzXG4gICAgICAgIGNvbnN0IGxheW91dHMgPSB0aGlzLmNhbGN1bGF0ZUxheW91dChhbGxEYXlFdmVudHMsIHZpc2libGVDb2x1bW5LZXlzKTtcbiAgICAgICAgY29uc3Qgcm93Q291bnQgPSBNYXRoLm1heCgxLCAuLi5sYXlvdXRzLm1hcChsID0+IGwucm93KSk7XG4gICAgICAgIC8vIFJlbmRlciBlYWNoIGl0ZW0gd2l0aCBsYXlvdXRcbiAgICAgICAgbGF5b3V0cy5mb3JFYWNoKGxheW91dCA9PiB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gdGhpcy5jcmVhdGVIZWFkZXJJdGVtKGxheW91dCk7XG4gICAgICAgICAgICBkcmF3ZXIuYXBwZW5kQ2hpbGQoaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBFeHBhbmQgZHJhd2VyIHRvIGZpdCBhbGwgcm93c1xuICAgICAgICB0aGlzLmhlYWRlckRyYXdlck1hbmFnZXIuZXhwYW5kVG9Sb3dzKHJvd0NvdW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgaGVhZGVyIGl0ZW0gZWxlbWVudCBmcm9tIGxheW91dFxuICAgICAqL1xuICAgIGNyZWF0ZUhlYWRlckl0ZW0obGF5b3V0KSB7XG4gICAgICAgIGNvbnN0IHsgZXZlbnQsIGNvbHVtbktleSwgcm93LCBjb2xTdGFydCwgY29sRW5kIH0gPSBsYXlvdXQ7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtaGVhZGVyLWl0ZW0nKTtcbiAgICAgICAgaXRlbS5kYXRhc2V0LmV2ZW50SWQgPSBldmVudC5pZDtcbiAgICAgICAgaXRlbS5kYXRhc2V0Lml0ZW1UeXBlID0gJ2V2ZW50JztcbiAgICAgICAgaXRlbS5kYXRhc2V0LnN0YXJ0ID0gZXZlbnQuc3RhcnQudG9JU09TdHJpbmcoKTtcbiAgICAgICAgaXRlbS5kYXRhc2V0LmVuZCA9IGV2ZW50LmVuZC50b0lTT1N0cmluZygpO1xuICAgICAgICBpdGVtLmRhdGFzZXQuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xuICAgICAgICBpdGVtLnRleHRDb250ZW50ID0gZXZlbnQudGl0bGU7XG4gICAgICAgIC8vIENvbG9yIGNsYXNzXG4gICAgICAgIGNvbnN0IGNvbG9yQ2xhc3MgPSB0aGlzLmdldENvbG9yQ2xhc3MoZXZlbnQpO1xuICAgICAgICBpZiAoY29sb3JDbGFzcylcbiAgICAgICAgICAgIGl0ZW0uY2xhc3NMaXN0LmFkZChjb2xvckNsYXNzKTtcbiAgICAgICAgLy8gR3JpZCBwb3NpdGlvbiBmcm9tIGxheW91dFxuICAgICAgICBpdGVtLnN0eWxlLmdyaWRBcmVhID0gYCR7cm93fSAvICR7Y29sU3RhcnR9IC8gJHtyb3cgKyAxfSAvICR7Y29sRW5kfWA7XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgbGF5b3V0IGZvciBhbGwgZXZlbnRzIHdpdGggcm93IHN0YWNraW5nXG4gICAgICogVXNlcyB0cmFjay1iYXNlZCBhbGdvcml0aG0gdG8gZmluZCBhdmFpbGFibGUgcm93cyBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzXG4gICAgICovXG4gICAgY2FsY3VsYXRlTGF5b3V0KGV2ZW50cywgdmlzaWJsZUNvbHVtbktleXMpIHtcbiAgICAgICAgLy8gdHJhY2tzW3Jvd11bY29sXSA9IG9jY3VwaWVkXG4gICAgICAgIGNvbnN0IHRyYWNrcyA9IFtuZXcgQXJyYXkodmlzaWJsZUNvbHVtbktleXMubGVuZ3RoKS5maWxsKGZhbHNlKV07XG4gICAgICAgIGNvbnN0IGxheW91dHMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAgICAgICAgIC8vIEJ1aWxkIGNvbHVtbktleSBmcm9tIGV2ZW50IGZpZWxkcyAob25seSBwbGFjZSB3ZSBuZWVkIHRvIGNvbnN0cnVjdCBpdClcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbktleSA9IHRoaXMuYnVpbGRDb2x1bW5LZXlGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRDb2wgPSB2aXNpYmxlQ29sdW1uS2V5cy5pbmRleE9mKGNvbHVtbktleSk7XG4gICAgICAgICAgICBjb25zdCBlbmRDb2x1bW5LZXkgPSB0aGlzLmJ1aWxkQ29sdW1uS2V5RnJvbUV2ZW50KGV2ZW50LCBldmVudC5lbmQpO1xuICAgICAgICAgICAgY29uc3QgZW5kQ29sID0gdmlzaWJsZUNvbHVtbktleXMuaW5kZXhPZihlbmRDb2x1bW5LZXkpO1xuICAgICAgICAgICAgaWYgKHN0YXJ0Q29sID09PSAtMSAmJiBlbmRDb2wgPT09IC0xKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgLy8gQ2xhbXAgdGlsIHN5bmxpZ2Uga29sb25uZXJcbiAgICAgICAgICAgIGNvbnN0IGNvbFN0YXJ0ID0gTWF0aC5tYXgoMCwgc3RhcnRDb2wpO1xuICAgICAgICAgICAgY29uc3QgY29sRW5kID0gKGVuZENvbCAhPT0gLTEgPyBlbmRDb2wgOiB2aXNpYmxlQ29sdW1uS2V5cy5sZW5ndGggLSAxKSArIDE7XG4gICAgICAgICAgICAvLyBGaW5kIGxlZGlnIHJcdTAwRTZra2VcbiAgICAgICAgICAgIGNvbnN0IHJvdyA9IHRoaXMuZmluZEF2YWlsYWJsZVJvdyh0cmFja3MsIGNvbFN0YXJ0LCBjb2xFbmQpO1xuICAgICAgICAgICAgLy8gTWFya2VyIHNvbSBvcHRhZ2V0XG4gICAgICAgICAgICBmb3IgKGxldCBjID0gY29sU3RhcnQ7IGMgPCBjb2xFbmQ7IGMrKykge1xuICAgICAgICAgICAgICAgIHRyYWNrc1tyb3ddW2NdID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxheW91dHMucHVzaCh7IGV2ZW50LCBjb2x1bW5LZXksIHJvdzogcm93ICsgMSwgY29sU3RhcnQ6IGNvbFN0YXJ0ICsgMSwgY29sRW5kOiBjb2xFbmQgKyAxIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYXlvdXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCdWlsZCBjb2x1bW5LZXkgZnJvbSBldmVudCB1c2luZyBGaWx0ZXJUZW1wbGF0ZVxuICAgICAqIFVzZXMgdGhlIHNhbWUgdGVtcGxhdGUgdGhhdCBjb2x1bW5zIHVzZSBmb3IgbWF0Y2hpbmdcbiAgICAgKi9cbiAgICBidWlsZENvbHVtbktleUZyb21FdmVudChldmVudCwgZGF0ZSkge1xuICAgICAgICBpZiAoIXRoaXMuZmlsdGVyVGVtcGxhdGUpIHtcbiAgICAgICAgICAgIC8vIEZhbGxiYWNrIGlmIG5vIHRlbXBsYXRlIC0gc2hvdWxkbid0IGhhcHBlbiBpbiBub3JtYWwgZmxvd1xuICAgICAgICAgICAgY29uc3QgZGF0ZVN0ciA9IHRoaXMuZGF0ZVNlcnZpY2UuZ2V0RGF0ZUtleShkYXRlIHx8IGV2ZW50LnN0YXJ0KTtcbiAgICAgICAgICAgIHJldHVybiBkYXRlU3RyO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZvciBtdWx0aS1kYXkgZXZlbnRzLCB3ZSBuZWVkIHRvIG92ZXJyaWRlIHRoZSBkYXRlIGluIHRoZSBldmVudFxuICAgICAgICBpZiAoZGF0ZSAmJiBkYXRlLmdldFRpbWUoKSAhPT0gZXZlbnQuc3RhcnQuZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgdGVtcG9yYXJ5IGV2ZW50IHdpdGggb3ZlcnJpZGRlbiBzdGFydCBmb3Iga2V5IGdlbmVyYXRpb25cbiAgICAgICAgICAgIGNvbnN0IHRlbXBFdmVudCA9IHsgLi4uZXZlbnQsIHN0YXJ0OiBkYXRlIH07XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXJUZW1wbGF0ZS5idWlsZEtleUZyb21FdmVudCh0ZW1wRXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmZpbHRlclRlbXBsYXRlLmJ1aWxkS2V5RnJvbUV2ZW50KGV2ZW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBhdmFpbGFibGUgcm93IGZvciBldmVudCBzcGFubmluZyBjb2x1bW5zIFtjb2xTdGFydCwgY29sRW5kKVxuICAgICAqL1xuICAgIGZpbmRBdmFpbGFibGVSb3codHJhY2tzLCBjb2xTdGFydCwgY29sRW5kKSB7XG4gICAgICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRyYWNrcy5sZW5ndGg7IHJvdysrKSB7XG4gICAgICAgICAgICBsZXQgYXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSBjb2xTdGFydDsgYyA8IGNvbEVuZDsgYysrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRyYWNrc1tyb3ddW2NdKSB7XG4gICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYXZhaWxhYmxlKVxuICAgICAgICAgICAgICAgIHJldHVybiByb3c7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTnkgclx1MDBFNmtrZVxuICAgICAgICB0cmFja3MucHVzaChuZXcgQXJyYXkodHJhY2tzWzBdLmxlbmd0aCkuZmlsbChmYWxzZSkpO1xuICAgICAgICByZXR1cm4gdHJhY2tzLmxlbmd0aCAtIDE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBjb2xvciBjbGFzcyBiYXNlZCBvbiBldmVudCBtZXRhZGF0YSBvciB0eXBlXG4gICAgICovXG4gICAgZ2V0Q29sb3JDbGFzcyhldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQubWV0YWRhdGE/LmNvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gYGlzLSR7ZXZlbnQubWV0YWRhdGEuY29sb3J9YDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0eXBlQ29sb3JzID0ge1xuICAgICAgICAgICAgJ2N1c3RvbWVyJzogJ2lzLWJsdWUnLFxuICAgICAgICAgICAgJ3ZhY2F0aW9uJzogJ2lzLWdyZWVuJyxcbiAgICAgICAgICAgICdicmVhayc6ICdpcy1hbWJlcicsXG4gICAgICAgICAgICAnbWVldGluZyc6ICdpcy1wdXJwbGUnLFxuICAgICAgICAgICAgJ2Jsb2NrZWQnOiAnaXMtcmVkJ1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdHlwZUNvbG9yc1tldmVudC50eXBlXSB8fCAnaXMtYmx1ZSc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHVwIGV2ZW50IGxpc3RlbmVycyBmb3IgZHJhZyBldmVudHNcbiAgICAgKi9cbiAgICBzZXR1cExpc3RlbmVycygpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfRU5URVJfSEVBREVSLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW50ZXIocGF5bG9hZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19NT1ZFX0hFQURFUiwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRHJhZ01vdmUocGF5bG9hZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19MRUFWRV9IRUFERVIsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZURyYWdMZWF2ZShwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBlLmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRHJhZ0VuZChwYXlsb2FkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0NBTkNFTCwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgZHJhZyBlbnRlcmluZyBoZWFkZXIgem9uZSAtIGNyZWF0ZSBwcmV2aWV3IGl0ZW1cbiAgICAgKi9cbiAgICBoYW5kbGVEcmFnRW50ZXIocGF5bG9hZCkge1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItZHJhd2VyJyk7XG4gICAgICAgIGlmICghdGhpcy5jb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIFJlbWVtYmVyIGlmIGRyYXdlciB3YXMgYWxyZWFkeSBleHBhbmRlZFxuICAgICAgICB0aGlzLndhc0V4cGFuZGVkQmVmb3JlRHJhZyA9IHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5pc0V4cGFuZGVkKCk7XG4gICAgICAgIC8vIEV4cGFuZCB0byBhdCBsZWFzdCAxIHJvdyBpZiBjb2xsYXBzZWQsIG90aGVyd2lzZSBrZWVwIGN1cnJlbnQgaGVpZ2h0XG4gICAgICAgIGlmICghdGhpcy53YXNFeHBhbmRlZEJlZm9yZURyYWcpIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5leHBhbmRUb1Jvd3MoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RvcmUgcmVmZXJlbmNlIHRvIHNvdXJjZSBlbGVtZW50XG4gICAgICAgIHRoaXMuc291cmNlRWxlbWVudCA9IHBheWxvYWQuZWxlbWVudDtcbiAgICAgICAgLy8gQ3JlYXRlIGhlYWRlciBpdGVtXG4gICAgICAgIGNvbnN0IGl0ZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtaGVhZGVyLWl0ZW0nKTtcbiAgICAgICAgaXRlbS5kYXRhc2V0LmV2ZW50SWQgPSBwYXlsb2FkLmV2ZW50SWQ7XG4gICAgICAgIGl0ZW0uZGF0YXNldC5pdGVtVHlwZSA9IHBheWxvYWQuaXRlbVR5cGU7XG4gICAgICAgIGl0ZW0uZGF0YXNldC5kdXJhdGlvbiA9IFN0cmluZyhwYXlsb2FkLmR1cmF0aW9uKTtcbiAgICAgICAgaXRlbS5kYXRhc2V0LmNvbHVtbktleSA9IHBheWxvYWQuc291cmNlQ29sdW1uS2V5O1xuICAgICAgICBpdGVtLnRleHRDb250ZW50ID0gcGF5bG9hZC50aXRsZTtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgY2xhc3MgaWYgcHJlc2VudFxuICAgICAgICBpZiAocGF5bG9hZC5jb2xvckNsYXNzKSB7XG4gICAgICAgICAgICBpdGVtLmNsYXNzTGlzdC5hZGQocGF5bG9hZC5jb2xvckNsYXNzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBZGQgZHJhZ2dpbmcgc3RhdGVcbiAgICAgICAgaXRlbS5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xuICAgICAgICAvLyBJbml0aWFsIHBsYWNlbWVudCAoZHVyYXRpb24gZGV0ZXJtaW5lcyBjb2x1bW4gc3BhbilcbiAgICAgICAgLy8gZ3JpZEFyZWEgZm9ybWF0OiBcInJvdyAvIGNvbC1zdGFydCAvIHJvdysxIC8gY29sLWVuZFwiXG4gICAgICAgIGNvbnN0IGNvbCA9IHBheWxvYWQuc291cmNlQ29sdW1uSW5kZXggKyAxO1xuICAgICAgICBjb25zdCBlbmRDb2wgPSBjb2wgKyBwYXlsb2FkLmR1cmF0aW9uO1xuICAgICAgICBpdGVtLnN0eWxlLmdyaWRBcmVhID0gYDEgLyAke2NvbH0gLyAyIC8gJHtlbmRDb2x9YDtcbiAgICAgICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoaXRlbSk7XG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW0gPSBpdGVtO1xuICAgICAgICAvLyBIaWRlIG9yaWdpbmFsIGVsZW1lbnQgd2hpbGUgaW4gaGVhZGVyXG4gICAgICAgIHBheWxvYWQuZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBkcmFnIG1vdmluZyB3aXRoaW4gaGVhZGVyIC0gdXBkYXRlIGNvbHVtbiBwb3NpdGlvblxuICAgICAqL1xuICAgIGhhbmRsZURyYWdNb3ZlKHBheWxvYWQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRJdGVtKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBVcGRhdGUgY29sdW1uIHBvc2l0aW9uXG4gICAgICAgIGNvbnN0IGNvbCA9IHBheWxvYWQuY29sdW1uSW5kZXggKyAxO1xuICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHBhcnNlSW50KHRoaXMuY3VycmVudEl0ZW0uZGF0YXNldC5kdXJhdGlvbiB8fCAnMScsIDEwKTtcbiAgICAgICAgY29uc3QgZW5kQ29sID0gY29sICsgZHVyYXRpb247XG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW0uc3R5bGUuZ3JpZEFyZWEgPSBgMSAvICR7Y29sfSAvIDIgLyAke2VuZENvbH1gO1xuICAgICAgICAvLyBVcGRhdGUgY29sdW1uS2V5IHRvIG5ldyBwb3NpdGlvblxuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtLmRhdGFzZXQuY29sdW1uS2V5ID0gcGF5bG9hZC5jb2x1bW5LZXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBkcmFnIGxlYXZpbmcgaGVhZGVyIC0gY2xlYW51cCBmb3IgZ3JpZFx1MjE5MmhlYWRlciBkcmFnIG9ubHlcbiAgICAgKi9cbiAgICBoYW5kbGVEcmFnTGVhdmUocGF5bG9hZCkge1xuICAgICAgICAvLyBPbmx5IGNsZWFudXAgZm9yIGdyaWRcdTIxOTJoZWFkZXIgZHJhZyAod2hlbiBncmlkIGV2ZW50IGxlYXZlcyBoZWFkZXIgYmFjayB0byBncmlkKVxuICAgICAgICAvLyBGb3IgaGVhZGVyXHUyMTkyZ3JpZCBkcmFnLCB0aGUgaGVhZGVyIGl0ZW0gc3RheXMgYXMgZ2hvc3QgdW50aWwgZHJvcFxuICAgICAgICBpZiAocGF5bG9hZC5zb3VyY2UgPT09ICdncmlkJykge1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yIGhlYWRlciBzb3VyY2UsIGRvIG5vdGhpbmcgLSBnaG9zdCBzdGF5cyB1bnRpbCBFVkVOVF9EUkFHX0VORFxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgZHJhZyBlbmQgLSBmaW5hbGl6ZSBiYXNlZCBvbiBkcm9wIHRhcmdldFxuICAgICAqL1xuICAgIGhhbmRsZURyYWdFbmQocGF5bG9hZCkge1xuICAgICAgICBpZiAocGF5bG9hZC50YXJnZXQgPT09ICdoZWFkZXInKSB7XG4gICAgICAgICAgICAvLyBHcmlkXHUyMTkySGVhZGVyOiBGaW5hbGl6ZSB0aGUgaGVhZGVyIGl0ZW0gKGl0IHN0YXlzIGluIGhlYWRlcilcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRJdGVtKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50SXRlbS5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2luZycpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVjYWxjdWxhdGVEcmF3ZXJMYXlvdXQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRJdGVtID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLnNvdXJjZUVsZW1lbnQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gSGVhZGVyXHUyMTkyR3JpZDogUmVtb3ZlIGdob3N0IGhlYWRlciBpdGVtIGFuZCByZWNhbGN1bGF0ZVxuICAgICAgICAgICAgY29uc3QgZ2hvc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBzd3AtaGVhZGVyLWl0ZW0uZHJhZy1naG9zdFtkYXRhLWV2ZW50LWlkPVwiJHtwYXlsb2FkLnN3cEV2ZW50LmV2ZW50SWR9XCJdYCk7XG4gICAgICAgICAgICBnaG9zdD8ucmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLnJlY2FsY3VsYXRlRHJhd2VyTGF5b3V0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVjYWxjdWxhdGUgbGF5b3V0IGZvciBhbGwgaXRlbXMgY3VycmVudGx5IGluIHRoZSBkcmF3ZXJcbiAgICAgKiBDYWxsZWQgYWZ0ZXIgZHJvcCB0byByZXBvc2l0aW9uIGl0ZW1zIGFuZCBhZGp1c3QgaGVpZ2h0XG4gICAgICovXG4gICAgcmVjYWxjdWxhdGVEcmF3ZXJMYXlvdXQoKSB7XG4gICAgICAgIGNvbnN0IGRyYXdlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1oZWFkZXItZHJhd2VyJyk7XG4gICAgICAgIGlmICghZHJhd2VyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCBpdGVtcyA9IEFycmF5LmZyb20oZHJhd2VyLnF1ZXJ5U2VsZWN0b3JBbGwoJ3N3cC1oZWFkZXItaXRlbScpKTtcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gR2V0IHZpc2libGUgY29sdW1uIGtleXMgZm9yIGNvcnJlY3QgbXVsdGktcmVzb3VyY2UgcG9zaXRpb25pbmdcbiAgICAgICAgY29uc3QgdmlzaWJsZUNvbHVtbktleXMgPSB0aGlzLmdldFZpc2libGVDb2x1bW5LZXlzRnJvbURPTSgpO1xuICAgICAgICBpZiAodmlzaWJsZUNvbHVtbktleXMubGVuZ3RoID09PSAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBCdWlsZCBsYXlvdXQgZGF0YSBmcm9tIERPTSBpdGVtcyAtIHVzZSBjb2x1bW5LZXkgZGlyZWN0bHkgKG9wYXF1ZSBtYXRjaGluZylcbiAgICAgICAgY29uc3QgaXRlbURhdGEgPSBpdGVtcy5tYXAoaXRlbSA9PiAoe1xuICAgICAgICAgICAgZWxlbWVudDogaXRlbSxcbiAgICAgICAgICAgIGNvbHVtbktleTogaXRlbS5kYXRhc2V0LmNvbHVtbktleSB8fCAnJyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiBwYXJzZUludChpdGVtLmRhdGFzZXQuZHVyYXRpb24gfHwgJzEnLCAxMClcbiAgICAgICAgfSkpO1xuICAgICAgICAvLyBDYWxjdWxhdGUgbmV3IGxheW91dCB1c2luZyB0cmFjayBhbGdvcml0aG1cbiAgICAgICAgY29uc3QgdHJhY2tzID0gW25ldyBBcnJheSh2aXNpYmxlQ29sdW1uS2V5cy5sZW5ndGgpLmZpbGwoZmFsc2UpXTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1EYXRhKSB7XG4gICAgICAgICAgICAvLyBEaXJlY3QgY29sdW1uS2V5IG1hdGNoaW5nIC0gbm8gcGFyc2luZyBvciBjb25zdHJ1Y3Rpb24gbmVlZGVkXG4gICAgICAgICAgICBjb25zdCBzdGFydENvbCA9IHZpc2libGVDb2x1bW5LZXlzLmluZGV4T2YoaXRlbS5jb2x1bW5LZXkpO1xuICAgICAgICAgICAgaWYgKHN0YXJ0Q29sID09PSAtMSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGNvbFN0YXJ0ID0gc3RhcnRDb2w7XG4gICAgICAgICAgICBjb25zdCBjb2xFbmQgPSBNYXRoLm1pbihzdGFydENvbCArIGl0ZW0uZHVyYXRpb24sIHZpc2libGVDb2x1bW5LZXlzLmxlbmd0aCk7XG4gICAgICAgICAgICBjb25zdCByb3cgPSB0aGlzLmZpbmRBdmFpbGFibGVSb3codHJhY2tzLCBjb2xTdGFydCwgY29sRW5kKTtcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSBjb2xTdGFydDsgYyA8IGNvbEVuZDsgYysrKSB7XG4gICAgICAgICAgICAgICAgdHJhY2tzW3Jvd11bY10gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVXBkYXRlIGVsZW1lbnQgcG9zaXRpb25cbiAgICAgICAgICAgIGl0ZW0uZWxlbWVudC5zdHlsZS5ncmlkQXJlYSA9IGAke3JvdyArIDF9IC8gJHtjb2xTdGFydCArIDF9IC8gJHtyb3cgKyAyfSAvICR7Y29sRW5kICsgMX1gO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVwZGF0ZSBkcmF3ZXIgaGVpZ2h0XG4gICAgICAgIGNvbnN0IHJvd0NvdW50ID0gdHJhY2tzLmxlbmd0aDtcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXJNYW5hZ2VyLmV4cGFuZFRvUm93cyhyb3dDb3VudCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB2aXNpYmxlIGNvbHVtbiBrZXlzIGZyb20gRE9NIChwcmVzZXJ2ZXMgb3JkZXIgZm9yIG11bHRpLXJlc291cmNlIHZpZXdzKVxuICAgICAqIFVzZXMgZmlsdGVyVGVtcGxhdGUuYnVpbGRLZXlGcm9tQ29sdW1uKCkgZm9yIGNvbnNpc3RlbnQga2V5IGZvcm1hdCB3aXRoIGV2ZW50c1xuICAgICAqL1xuICAgIGdldFZpc2libGVDb2x1bW5LZXlzRnJvbURPTSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZpbHRlclRlbXBsYXRlKVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICBjb25zdCBjb2x1bW5zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgY29uc3QgY29sdW1uS2V5cyA9IFtdO1xuICAgICAgICBjb2x1bW5zLmZvckVhY2goY29sID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbktleSA9IHRoaXMuZmlsdGVyVGVtcGxhdGUuYnVpbGRLZXlGcm9tQ29sdW1uKGNvbCk7XG4gICAgICAgICAgICBpZiAoY29sdW1uS2V5KVxuICAgICAgICAgICAgICAgIGNvbHVtbktleXMucHVzaChjb2x1bW5LZXkpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNvbHVtbktleXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFudXAgcHJldmlldyBpdGVtIGFuZCByZXN0b3JlIHNvdXJjZSB2aXNpYmlsaXR5XG4gICAgICovXG4gICAgY2xlYW51cCgpIHtcbiAgICAgICAgLy8gUmVtb3ZlIHByZXZpZXcgaXRlbVxuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtPy5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50SXRlbSA9IG51bGw7XG4gICAgICAgIC8vIFJlc3RvcmUgc291cmNlIGVsZW1lbnQgdmlzaWJpbGl0eVxuICAgICAgICBpZiAodGhpcy5zb3VyY2VFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUVsZW1lbnQuc3R5bGUudmlzaWJpbGl0eSA9ICcnO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAvLyBDb2xsYXBzZSBkcmF3ZXIgaWYgaXQgd2Fzbid0IGV4cGFuZGVkIGJlZm9yZSBkcmFnXG4gICAgICAgIGlmICghdGhpcy53YXNFeHBhbmRlZEJlZm9yZURyYWcpIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVyRHJhd2VyTWFuYWdlci5jb2xsYXBzZSgpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwgIi8qKlxuICogU2NoZWR1bGVPdmVycmlkZVN0b3JlIC0gSW5kZXhlZERCIE9iamVjdFN0b3JlIGZvciBzY2hlZHVsZSBvdmVycmlkZXNcbiAqXG4gKiBTdG9yZXMgZGF0ZS1zcGVjaWZpYyBzY2hlZHVsZSBvdmVycmlkZXMgZm9yIHJlc291cmNlcy5cbiAqIEluZGV4ZXM6IHJlc291cmNlSWQsIGRhdGUsIGNvbXBvdW5kIChyZXNvdXJjZUlkICsgZGF0ZSlcbiAqL1xuZXhwb3J0IGNsYXNzIFNjaGVkdWxlT3ZlcnJpZGVTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVOYW1lID0gU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUU7XG4gICAgfVxuICAgIGNyZWF0ZShkYikge1xuICAgICAgICBjb25zdCBzdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKFNjaGVkdWxlT3ZlcnJpZGVTdG9yZS5TVE9SRV9OQU1FLCB7IGtleVBhdGg6ICdpZCcgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdyZXNvdXJjZUlkJywgJ3Jlc291cmNlSWQnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdkYXRlJywgJ2RhdGUnLCB7IHVuaXF1ZTogZmFsc2UgfSk7XG4gICAgICAgIHN0b3JlLmNyZWF0ZUluZGV4KCdyZXNvdXJjZUlkX2RhdGUnLCBbJ3Jlc291cmNlSWQnLCAnZGF0ZSddLCB7IHVuaXF1ZTogdHJ1ZSB9KTtcbiAgICAgICAgc3RvcmUuY3JlYXRlSW5kZXgoJ3N5bmNTdGF0dXMnLCAnc3luY1N0YXR1cycsIHsgdW5pcXVlOiBmYWxzZSB9KTtcbiAgICB9XG59XG5TY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRSA9ICdzY2hlZHVsZU92ZXJyaWRlcyc7XG4iLCAiaW1wb3J0IHsgU2NoZWR1bGVPdmVycmlkZVN0b3JlIH0gZnJvbSAnLi9TY2hlZHVsZU92ZXJyaWRlU3RvcmUnO1xuLyoqXG4gKiBTY2hlZHVsZU92ZXJyaWRlU2VydmljZSAtIENSVUQgZm9yIHNjaGVkdWxlIG92ZXJyaWRlc1xuICpcbiAqIFByb3ZpZGVzIGFjY2VzcyB0byBkYXRlLXNwZWNpZmljIHNjaGVkdWxlIG92ZXJyaWRlcyBmb3IgcmVzb3VyY2VzLlxuICovXG5leHBvcnQgY2xhc3MgU2NoZWR1bGVPdmVycmlkZVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG4gICAgZ2V0IGRiKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmdldERhdGFiYXNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBvdmVycmlkZSBmb3IgYSBzcGVjaWZpYyByZXNvdXJjZSBhbmQgZGF0ZVxuICAgICAqL1xuICAgIGFzeW5jIGdldE92ZXJyaWRlKHJlc291cmNlSWQsIGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUUpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5pbmRleCgncmVzb3VyY2VJZF9kYXRlJyk7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXguZ2V0KFtyZXNvdXJjZUlkLCBkYXRlXSk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlcXVlc3QucmVzdWx0IHx8IG51bGwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IG92ZXJyaWRlIGZvciAke3Jlc291cmNlSWR9IG9uICR7ZGF0ZX06ICR7cmVxdWVzdC5lcnJvcn1gKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBvdmVycmlkZXMgZm9yIGEgcmVzb3VyY2VcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeVJlc291cmNlKHJlc291cmNlSWQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUVdLCAncmVhZG9ubHknKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUUpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5pbmRleCgncmVzb3VyY2VJZCcpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGluZGV4LmdldEFsbChyZXNvdXJjZUlkKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUocmVxdWVzdC5yZXN1bHQgfHwgW10pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IG92ZXJyaWRlcyBmb3IgJHtyZXNvdXJjZUlkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgb3ZlcnJpZGVzIGZvciBhIGRhdGUgcmFuZ2VcbiAgICAgKi9cbiAgICBhc3luYyBnZXRCeURhdGVSYW5nZShyZXNvdXJjZUlkLCBzdGFydERhdGUsIGVuZERhdGUpIHtcbiAgICAgICAgY29uc3QgYWxsID0gYXdhaXQgdGhpcy5nZXRCeVJlc291cmNlKHJlc291cmNlSWQpO1xuICAgICAgICByZXR1cm4gYWxsLmZpbHRlcihvID0+IG8uZGF0ZSA+PSBzdGFydERhdGUgJiYgby5kYXRlIDw9IGVuZERhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTYXZlIGFuIG92ZXJyaWRlXG4gICAgICovXG4gICAgYXN5bmMgc2F2ZShvdmVycmlkZSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0aGlzLmRiLnRyYW5zYWN0aW9uKFtTY2hlZHVsZU92ZXJyaWRlU3RvcmUuU1RPUkVfTkFNRV0sICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUUpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLnB1dChvdmVycmlkZSk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpID0+IHJlc29sdmUoKTtcbiAgICAgICAgICAgIHJlcXVlc3Qub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gc2F2ZSBvdmVycmlkZSAke292ZXJyaWRlLmlkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZWxldGUgYW4gb3ZlcnJpZGVcbiAgICAgKi9cbiAgICBhc3luYyBkZWxldGUoaWQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5kYi50cmFuc2FjdGlvbihbU2NoZWR1bGVPdmVycmlkZVN0b3JlLlNUT1JFX05BTUVdLCAncmVhZHdyaXRlJyk7XG4gICAgICAgICAgICBjb25zdCBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKFNjaGVkdWxlT3ZlcnJpZGVTdG9yZS5TVE9SRV9OQU1FKTtcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5kZWxldGUoaWQpO1xuICAgICAgICAgICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSAoKSA9PiByZXNvbHZlKCk7XG4gICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBvdmVycmlkZSAke2lkfTogJHtyZXF1ZXN0LmVycm9yfWApKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFJlc291cmNlU2NoZWR1bGVTZXJ2aWNlIC0gR2V0IGVmZmVjdGl2ZSBzY2hlZHVsZSBmb3IgYSByZXNvdXJjZSBvbiBhIGRhdGVcbiAqXG4gKiBMb2dpYzpcbiAqIDEuIENoZWNrIGZvciBvdmVycmlkZSBvbiB0aGlzIGRhdGVcbiAqIDIuIEZhbGwgYmFjayB0byBkZWZhdWx0IHNjaGVkdWxlIGZvciB0aGUgd2Vla2RheVxuICovXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VTY2hlZHVsZVNlcnZpY2Uge1xuICAgIGNvbnN0cnVjdG9yKHJlc291cmNlU2VydmljZSwgb3ZlcnJpZGVTZXJ2aWNlLCBkYXRlU2VydmljZSkge1xuICAgICAgICB0aGlzLnJlc291cmNlU2VydmljZSA9IHJlc291cmNlU2VydmljZTtcbiAgICAgICAgdGhpcy5vdmVycmlkZVNlcnZpY2UgPSBvdmVycmlkZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2UgPSBkYXRlU2VydmljZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGVmZmVjdGl2ZSBzY2hlZHVsZSBmb3IgYSByZXNvdXJjZSBvbiBhIHNwZWNpZmljIGRhdGVcbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gUmVzb3VyY2UgSURcbiAgICAgKiBAcGFyYW0gZGF0ZSAtIERhdGUgc3RyaW5nIFwiWVlZWS1NTS1ERFwiXG4gICAgICogQHJldHVybnMgSVRpbWVTbG90IG9yIG51bGwgKGZyaS9jbG9zZWQpXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U2NoZWR1bGVGb3JEYXRlKHJlc291cmNlSWQsIGRhdGUpIHtcbiAgICAgICAgLy8gMS4gQ2hlY2sgZm9yIG92ZXJyaWRlXG4gICAgICAgIGNvbnN0IG92ZXJyaWRlID0gYXdhaXQgdGhpcy5vdmVycmlkZVNlcnZpY2UuZ2V0T3ZlcnJpZGUocmVzb3VyY2VJZCwgZGF0ZSk7XG4gICAgICAgIGlmIChvdmVycmlkZSkge1xuICAgICAgICAgICAgcmV0dXJuIG92ZXJyaWRlLnNjaGVkdWxlO1xuICAgICAgICB9XG4gICAgICAgIC8vIDIuIFVzZSBkZWZhdWx0IHNjaGVkdWxlIGZvciB3ZWVrZGF5XG4gICAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgdGhpcy5yZXNvdXJjZVNlcnZpY2UuZ2V0KHJlc291cmNlSWQpO1xuICAgICAgICBpZiAoIXJlc291cmNlIHx8ICFyZXNvdXJjZS5kZWZhdWx0U2NoZWR1bGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdlZWtEYXkgPSB0aGlzLmRhdGVTZXJ2aWNlLmdldElTT1dlZWtEYXkoZGF0ZSk7XG4gICAgICAgIHJldHVybiByZXNvdXJjZS5kZWZhdWx0U2NoZWR1bGVbd2Vla0RheV0gfHwgbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHNjaGVkdWxlcyBmb3IgbXVsdGlwbGUgZGF0ZXNcbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gUmVzb3VyY2UgSURcbiAgICAgKiBAcGFyYW0gZGF0ZXMgLSBBcnJheSBvZiBkYXRlIHN0cmluZ3MgXCJZWVlZLU1NLUREXCJcbiAgICAgKiBAcmV0dXJucyBNYXAgb2YgZGF0ZSAtPiBJVGltZVNsb3QgfCBudWxsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U2NoZWR1bGVzRm9yRGF0ZXMocmVzb3VyY2VJZCwgZGF0ZXMpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyBHZXQgcmVzb3VyY2Ugb25jZVxuICAgICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IHRoaXMucmVzb3VyY2VTZXJ2aWNlLmdldChyZXNvdXJjZUlkKTtcbiAgICAgICAgLy8gR2V0IGFsbCBvdmVycmlkZXMgaW4gZGF0ZSByYW5nZVxuICAgICAgICBjb25zdCBvdmVycmlkZXMgPSBkYXRlcy5sZW5ndGggPiAwXG4gICAgICAgICAgICA/IGF3YWl0IHRoaXMub3ZlcnJpZGVTZXJ2aWNlLmdldEJ5RGF0ZVJhbmdlKHJlc291cmNlSWQsIGRhdGVzWzBdLCBkYXRlc1tkYXRlcy5sZW5ndGggLSAxXSlcbiAgICAgICAgICAgIDogW107XG4gICAgICAgIC8vIEJ1aWxkIG92ZXJyaWRlIG1hcFxuICAgICAgICBjb25zdCBvdmVycmlkZU1hcCA9IG5ldyBNYXAob3ZlcnJpZGVzLm1hcChvID0+IFtvLmRhdGUsIG8uc2NoZWR1bGVdKSk7XG4gICAgICAgIC8vIFJlc29sdmUgZWFjaCBkYXRlXG4gICAgICAgIGZvciAoY29uc3QgZGF0ZSBvZiBkYXRlcykge1xuICAgICAgICAgICAgLy8gQ2hlY2sgb3ZlcnJpZGUgZmlyc3RcbiAgICAgICAgICAgIGlmIChvdmVycmlkZU1hcC5oYXMoZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuc2V0KGRhdGUsIG92ZXJyaWRlTWFwLmdldChkYXRlKSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBGYWxsIGJhY2sgdG8gZGVmYXVsdFxuICAgICAgICAgICAgaWYgKHJlc291cmNlPy5kZWZhdWx0U2NoZWR1bGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3ZWVrRGF5ID0gdGhpcy5kYXRlU2VydmljZS5nZXRJU09XZWVrRGF5KGRhdGUpO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5zZXQoZGF0ZSwgcmVzb3VyY2UuZGVmYXVsdFNjaGVkdWxlW3dlZWtEYXldIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnNldChkYXRlLCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cbiIsICIvKipcbiAqIFN3cEV2ZW50IC0gV3JhcHBlciBjbGFzcyBmb3IgY2FsZW5kYXIgZXZlbnQgZWxlbWVudHNcbiAqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gSFRNTEVsZW1lbnQgYW5kIHByb3ZpZGVzIGNvbXB1dGVkIHByb3BlcnRpZXNcbiAqIGZvciBzdGFydC9lbmQgdGltZXMgYmFzZWQgb24gZWxlbWVudCBwb3NpdGlvbiBhbmQgZ3JpZCBjb25maWcuXG4gKlxuICogVXNhZ2U6XG4gKiAtIGV2ZW50SWQgaXMgcmVhZCBmcm9tIGVsZW1lbnQuZGF0YXNldFxuICogLSBjb2x1bW5LZXkgaWRlbnRpZmllcyB0aGUgY29sdW1uIHVuaWZvcm1seVxuICogLSBQb3NpdGlvbiAodG9wLCBoZWlnaHQpIGlzIHJlYWQgZnJvbSBlbGVtZW50LnN0eWxlXG4gKiAtIEZhY3RvcnkgbWV0aG9kIGBmcm9tRWxlbWVudCgpYCBjYWxjdWxhdGVzIERhdGUgb2JqZWN0c1xuICovXG5leHBvcnQgY2xhc3MgU3dwRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQsIGNvbHVtbktleSwgc3RhcnQsIGVuZCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLmNvbHVtbktleSA9IGNvbHVtbktleTtcbiAgICAgICAgdGhpcy5fc3RhcnQgPSBzdGFydDtcbiAgICAgICAgdGhpcy5fZW5kID0gZW5kO1xuICAgIH1cbiAgICAvKiogRXZlbnQgSUQgZnJvbSBlbGVtZW50LmRhdGFzZXQuZXZlbnRJZCAqL1xuICAgIGdldCBldmVudElkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmRhdGFzZXQuZXZlbnRJZCB8fCAnJztcbiAgICB9XG4gICAgZ2V0IHN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnQ7XG4gICAgfVxuICAgIGdldCBlbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbmQ7XG4gICAgfVxuICAgIC8qKiBEdXJhdGlvbiBpbiBtaW51dGVzICovXG4gICAgZ2V0IGR1cmF0aW9uTWludXRlcygpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9lbmQuZ2V0VGltZSgpIC0gdGhpcy5fc3RhcnQuZ2V0VGltZSgpKSAvICgxMDAwICogNjApO1xuICAgIH1cbiAgICAvKiogRHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzICovXG4gICAgZ2V0IGR1cmF0aW9uTXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbmQuZ2V0VGltZSgpIC0gdGhpcy5fc3RhcnQuZ2V0VGltZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGYWN0b3J5OiBDcmVhdGUgU3dwRXZlbnQgZnJvbSBlbGVtZW50ICsgY29sdW1uS2V5XG4gICAgICogUmVhZHMgdG9wL2hlaWdodCBmcm9tIGVsZW1lbnQuc3R5bGUgdG8gY2FsY3VsYXRlIHN0YXJ0L2VuZFxuICAgICAqIEBwYXJhbSBjb2x1bW5LZXkgLSBPcGFxdWUgY29sdW1uIGlkZW50aWZpZXIgKGRvIE5PVCBwYXJzZSAtIHVzZSBvbmx5IGZvciBtYXRjaGluZylcbiAgICAgKiBAcGFyYW0gZGF0ZSAtIERhdGUgc3RyaW5nIChZWVlZLU1NLUREKSBmb3IgdGltZSBjYWxjdWxhdGlvbnNcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUVsZW1lbnQoZWxlbWVudCwgY29sdW1uS2V5LCBkYXRlLCBncmlkQ29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHRvcFBpeGVscyA9IHBhcnNlRmxvYXQoZWxlbWVudC5zdHlsZS50b3ApIHx8IDA7XG4gICAgICAgIGNvbnN0IGhlaWdodFBpeGVscyA9IHBhcnNlRmxvYXQoZWxlbWVudC5zdHlsZS5oZWlnaHQpIHx8IDA7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBzdGFydCBmcm9tIHRvcCBwb3NpdGlvblxuICAgICAgICBjb25zdCBzdGFydE1pbnV0ZXNGcm9tR3JpZCA9ICh0b3BQaXhlbHMgLyBncmlkQ29uZmlnLmhvdXJIZWlnaHQpICogNjA7XG4gICAgICAgIGNvbnN0IHRvdGFsTWludXRlcyA9IChncmlkQ29uZmlnLmRheVN0YXJ0SG91ciAqIDYwKSArIHN0YXJ0TWludXRlc0Zyb21HcmlkO1xuICAgICAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICBzdGFydC5zZXRIb3VycyhNYXRoLmZsb29yKHRvdGFsTWludXRlcyAvIDYwKSwgdG90YWxNaW51dGVzICUgNjAsIDAsIDApO1xuICAgICAgICAvLyBDYWxjdWxhdGUgZW5kIGZyb20gaGVpZ2h0XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uTWludXRlcyA9IChoZWlnaHRQaXhlbHMgLyBncmlkQ29uZmlnLmhvdXJIZWlnaHQpICogNjA7XG4gICAgICAgIGNvbnN0IGVuZCA9IG5ldyBEYXRlKHN0YXJ0LmdldFRpbWUoKSArIGR1cmF0aW9uTWludXRlcyAqIDYwICogMTAwMCk7XG4gICAgICAgIHJldHVybiBuZXcgU3dwRXZlbnQoZWxlbWVudCwgY29sdW1uS2V5LCBzdGFydCwgZW5kKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcbmltcG9ydCB7IHNuYXBUb0dyaWQgfSBmcm9tICcuLi91dGlscy9Qb3NpdGlvblV0aWxzJztcbmltcG9ydCB7IFN3cEV2ZW50IH0gZnJvbSAnLi4vdHlwZXMvU3dwRXZlbnQnO1xuLyoqXG4gKiBEcmFnRHJvcE1hbmFnZXIgLSBIYW5kbGVzIGRyYWctZHJvcCBmb3IgY2FsZW5kYXIgZXZlbnRzXG4gKlxuICogU3RyYXRlZ3k6IERyYWcgb3JpZ2luYWwgZWxlbWVudCwgbGVhdmUgZ2hvc3QtY2xvbmUgaW4gcGxhY2VcbiAqIC0gbW91c2Vkb3duOiBTdG9yZSBpbml0aWFsIHN0YXRlLCB3YWl0IGZvciBtb3ZlbWVudFxuICogLSBtb3VzZW1vdmUgKD41cHgpOiBDcmVhdGUgZ2hvc3QsIHN0YXJ0IGRyYWdnaW5nIG9yaWdpbmFsXG4gKiAtIG1vdXNldXA6IFNuYXAgdG8gZ3JpZCwgcmVtb3ZlIGdob3N0LCBlbWl0IGRyYWc6ZW5kXG4gKiAtIGNhbmNlbDogQW5pbWF0ZSBiYWNrIHRvIHN0YXJ0WSwgcmVtb3ZlIGdob3N0XG4gKi9cbmV4cG9ydCBjbGFzcyBEcmFnRHJvcE1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50QnVzLCBncmlkQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgICAgICAgdGhpcy5ncmlkQ29uZmlnID0gZ3JpZENvbmZpZztcbiAgICAgICAgdGhpcy5kcmFnU3RhdGUgPSBudWxsO1xuICAgICAgICB0aGlzLm1vdXNlRG93blBvc2l0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5wZW5kaW5nRWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMucGVuZGluZ01vdXNlT2Zmc2V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmluSGVhZGVyID0gZmFsc2U7XG4gICAgICAgIHRoaXMuRFJBR19USFJFU0hPTEQgPSA1O1xuICAgICAgICB0aGlzLklOVEVSUE9MQVRJT05fRkFDVE9SID0gMC4zO1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgLy8gSWdub3JlIGlmIGNsaWNraW5nIG9uIHJlc2l6ZSBoYW5kbGVcbiAgICAgICAgICAgIGlmICh0YXJnZXQuY2xvc2VzdCgnc3dwLXJlc2l6ZS1oYW5kbGUnKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBNYXRjaCBib3RoIHN3cC1ldmVudCBhbmQgc3dwLWhlYWRlci1pdGVtXG4gICAgICAgICAgICBjb25zdCBldmVudEVsZW1lbnQgPSB0YXJnZXQuY2xvc2VzdCgnc3dwLWV2ZW50Jyk7XG4gICAgICAgICAgICBjb25zdCBoZWFkZXJJdGVtID0gdGFyZ2V0LmNsb3Nlc3QoJ3N3cC1oZWFkZXItaXRlbScpO1xuICAgICAgICAgICAgY29uc3QgZHJhZ2dhYmxlID0gZXZlbnRFbGVtZW50IHx8IGhlYWRlckl0ZW07XG4gICAgICAgICAgICBpZiAoIWRyYWdnYWJsZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBTdG9yZSBmb3IgcG90ZW50aWFsIGRyYWdcbiAgICAgICAgICAgIHRoaXMubW91c2VEb3duUG9zaXRpb24gPSB7IHg6IGUuY2xpZW50WCwgeTogZS5jbGllbnRZIH07XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdFbGVtZW50ID0gZHJhZ2dhYmxlO1xuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIG1vdXNlIG9mZnNldCB3aXRoaW4gZWxlbWVudFxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IGRyYWdnYWJsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ01vdXNlT2Zmc2V0ID0ge1xuICAgICAgICAgICAgICAgIHg6IGUuY2xpZW50WCAtIHJlY3QubGVmdCxcbiAgICAgICAgICAgICAgICB5OiBlLmNsaWVudFkgLSByZWN0LnRvcFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIENhcHR1cmUgcG9pbnRlciBmb3IgcmVsaWFibGUgdHJhY2tpbmdcbiAgICAgICAgICAgIGRyYWdnYWJsZS5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmUgPSAoZSkgPT4ge1xuICAgICAgICAgICAgLy8gTm90IGluIHBvdGVudGlhbCBkcmFnIHN0YXRlXG4gICAgICAgICAgICBpZiAoIXRoaXMubW91c2VEb3duUG9zaXRpb24gfHwgIXRoaXMucGVuZGluZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IGRyYWdnaW5nIC0gdXBkYXRlIHRhcmdldFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRyYWdTdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURyYWdUYXJnZXQoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENoZWNrIHRocmVzaG9sZFxuICAgICAgICAgICAgY29uc3QgZGVsdGFYID0gTWF0aC5hYnMoZS5jbGllbnRYIC0gdGhpcy5tb3VzZURvd25Qb3NpdGlvbi54KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhWSA9IE1hdGguYWJzKGUuY2xpZW50WSAtIHRoaXMubW91c2VEb3duUG9zaXRpb24ueSk7XG4gICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGguc3FydChkZWx0YVggKiBkZWx0YVggKyBkZWx0YVkgKiBkZWx0YVkpO1xuICAgICAgICAgICAgaWYgKGRpc3RhbmNlIDwgdGhpcy5EUkFHX1RIUkVTSE9MRClcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBTdGFydCBkcmFnXG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVEcmFnKHRoaXMucGVuZGluZ0VsZW1lbnQsIHRoaXMucGVuZGluZ01vdXNlT2Zmc2V0LCBlKTtcbiAgICAgICAgICAgIHRoaXMubW91c2VEb3duUG9zaXRpb24gPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nRWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdNb3VzZU9mZnNldCA9IG51bGw7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlclVwID0gKF9lKSA9PiB7XG4gICAgICAgICAgICAvLyBDbGVhciBwZW5kaW5nIHN0YXRlXG4gICAgICAgICAgICB0aGlzLm1vdXNlRG93blBvc2l0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ0VsZW1lbnQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nTW91c2VPZmZzZXQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBTdG9wIGFuaW1hdGlvblxuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5kcmFnU3RhdGUuYW5pbWF0aW9uSWQpO1xuICAgICAgICAgICAgLy8gSGFuZGxlIGJhc2VkIG9uIGRyYWcgc291cmNlIGFuZCB0YXJnZXRcbiAgICAgICAgICAgIGlmICh0aGlzLmRyYWdTdGF0ZS5kcmFnU291cmNlID09PSAnaGVhZGVyJykge1xuICAgICAgICAgICAgICAgIC8vIEhlYWRlciBpdGVtIGRyYWcgZW5kXG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVIZWFkZXJJdGVtRHJhZ0VuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gR3JpZCBldmVudCBkcmFnIGVuZFxuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlR3JpZEV2ZW50RHJhZ0VuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2xlYW51cFxuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2luZycpO1xuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5pbkhlYWRlciA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmFuaW1hdGVEcmFnID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gdGhpcy5kcmFnU3RhdGUudGFyZ2V0WSAtIHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZO1xuICAgICAgICAgICAgLy8gU3RvcCBhbmltYXRpb24gd2hlbiBjbG9zZSBlbm91Z2ggdG8gdGFyZ2V0XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoZGlmZikgPD0gMC41KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuYW5pbWF0aW9uSWQgPSAwO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEludGVycG9sYXRlIHRvd2FyZHMgdGFyZ2V0XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50WSArPSBkaWZmICogdGhpcy5JTlRFUlBPTEFUSU9OX0ZBQ1RPUjtcbiAgICAgICAgICAgIC8vIFVwZGF0ZSBlbGVtZW50IHBvc2l0aW9uXG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LnN0eWxlLnRvcCA9IGAke3RoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZfXB4YDtcbiAgICAgICAgICAgIC8vIEVtaXQgZHJhZzptb3ZlIChvbmx5IGlmIHdlIGhhdmUgYSBjb2x1bW4pXG4gICAgICAgICAgICBpZiAodGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHRoaXMuZHJhZ1N0YXRlLmV2ZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRZOiB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50WSxcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uRWxlbWVudDogdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19NT1ZFLCBwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENvbnRpbnVlIGFuaW1hdGlvblxuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuYW5pbWF0aW9uSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRlRHJhZyk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0dXBTY3JvbGxMaXN0ZW5lcigpO1xuICAgIH1cbiAgICBzZXR1cFNjcm9sbExpc3RlbmVyKCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRURHRV9TQ1JPTExfVElDSywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5kcmFnU3RhdGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgeyBzY3JvbGxEZWx0YSB9ID0gZS5kZXRhaWw7XG4gICAgICAgICAgICAvLyBFbGVtZW50IHNrYWwgZmx5dHRlIG1lZCBzY3JvbGwgZm9yIGF0IGZvcmJsaXZlIHVuZGVyIG11c2VuXG4gICAgICAgICAgICAvLyAoZWxlbWVudGV0cyB0b3AgZXIgcmVsYXRpdiB0aWwga29sb25uZW4sIHNvbSBzY3JvbGxlciBtZWQgdmlld3BvcnQpXG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS50YXJnZXRZICs9IHNjcm9sbERlbHRhO1xuICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuY3VycmVudFkgKz0gc2Nyb2xsRGVsdGE7XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5lbGVtZW50LnN0eWxlLnRvcCA9IGAke3RoaXMuZHJhZ1N0YXRlLmN1cnJlbnRZfXB4YDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZHJhZy1kcm9wIG9uIGEgY29udGFpbmVyIGVsZW1lbnRcbiAgICAgKi9cbiAgICBpbml0KGNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5oYW5kbGVQb2ludGVyTW92ZSk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMuaGFuZGxlUG9pbnRlclVwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFuZGxlIGRyYWcgZW5kIGZvciBoZWFkZXIgaXRlbXNcbiAgICAgKi9cbiAgICBoYW5kbGVIZWFkZXJJdGVtRHJhZ0VuZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gSWYgZHJvcHBlZCBpbiBncmlkIChub3QgaW4gaGVhZGVyKSwgdGhlIHN3cC1ldmVudCB3YXMgYWxyZWFkeSBjcmVhdGVkXG4gICAgICAgIC8vIGJ5IEV2ZW50UmVuZGVyZXIgbGlzdGVuaW5nIHRvIEVWRU5UX0RSQUdfTEVBVkVfSEVBREVSXG4gICAgICAgIC8vIEp1c3QgZW1pdCBkcmFnOmVuZCBmb3IgcGVyc2lzdGVuY2VcbiAgICAgICAgaWYgKCF0aGlzLmluSGVhZGVyICYmIHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4pIHtcbiAgICAgICAgICAgIC8vIERyb3BwZWQgaW4gZ3JpZCAtIGVtaXQgZHJhZzplbmQgd2l0aCB0aGUgbmV3IHN3cC1ldmVudCBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCBncmlkRXZlbnQgPSB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uLnF1ZXJ5U2VsZWN0b3IoYHN3cC1ldmVudFtkYXRhLWV2ZW50LWlkPVwiJHt0aGlzLmRyYWdTdGF0ZS5ldmVudElkfVwiXWApO1xuICAgICAgICAgICAgaWYgKGdyaWRFdmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbHVtbktleSA9IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4uZGF0YXNldC5jb2x1bW5LZXkgfHwgJyc7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4uZGF0YXNldC5kYXRlIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN3cEV2ZW50ID0gU3dwRXZlbnQuZnJvbUVsZW1lbnQoZ3JpZEV2ZW50LCBjb2x1bW5LZXksIGRhdGUsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3dwRXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogdGhpcy5kcmFnU3RhdGUuc291cmNlQ29sdW1uS2V5LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6ICdncmlkJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19FTkQsIHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIElmIHN0aWxsIGluIGhlYWRlciwgbm8gcGVyc2lzdGVuY2UgbmVlZGVkIChzdGF5ZWQgaW4gaGVhZGVyKVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgZHJhZyBlbmQgZm9yIGdyaWQgZXZlbnRzXG4gICAgICovXG4gICAgaGFuZGxlR3JpZEV2ZW50RHJhZ0VuZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSB8fCAhdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gU25hcCB0byBncmlkXG4gICAgICAgIGNvbnN0IHNuYXBwZWRZID0gc25hcFRvR3JpZCh0aGlzLmRyYWdTdGF0ZS5jdXJyZW50WSwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgdGhpcy5kcmFnU3RhdGUuZWxlbWVudC5zdHlsZS50b3AgPSBgJHtzbmFwcGVkWX1weGA7XG4gICAgICAgIC8vIFJlbW92ZSBnaG9zdFxuICAgICAgICB0aGlzLmRyYWdTdGF0ZS5naG9zdEVsZW1lbnQ/LnJlbW92ZSgpO1xuICAgICAgICAvLyBHZXQgY29sdW1uS2V5IGFuZCBkYXRlIGZyb20gdGFyZ2V0IGNvbHVtblxuICAgICAgICBjb25zdCBjb2x1bW5LZXkgPSB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50LmRhdGFzZXQuY29sdW1uS2V5IHx8ICcnO1xuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudC5kYXRhc2V0LmRhdGUgfHwgJyc7XG4gICAgICAgIC8vIENyZWF0ZSBTd3BFdmVudCBmcm9tIGVsZW1lbnQgKHJlYWRzIHRvcC9oZWlnaHQvZXZlbnRJZCBmcm9tIGVsZW1lbnQpXG4gICAgICAgIGNvbnN0IHN3cEV2ZW50ID0gU3dwRXZlbnQuZnJvbUVsZW1lbnQodGhpcy5kcmFnU3RhdGUuZWxlbWVudCwgY29sdW1uS2V5LCBkYXRlLCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICAvLyBFbWl0IGRyYWc6ZW5kXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICBzd3BFdmVudCxcbiAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogdGhpcy5kcmFnU3RhdGUuc291cmNlQ29sdW1uS2V5LFxuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmluSGVhZGVyID8gJ2hlYWRlcicgOiAnZ3JpZCdcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19FTkQsIHBheWxvYWQpO1xuICAgIH1cbiAgICBpbml0aWFsaXplRHJhZyhlbGVtZW50LCBtb3VzZU9mZnNldCwgZSkge1xuICAgICAgICBjb25zdCBldmVudElkID0gZWxlbWVudC5kYXRhc2V0LmV2ZW50SWQgfHwgJyc7XG4gICAgICAgIGNvbnN0IGlzSGVhZGVySXRlbSA9IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnc3dwLWhlYWRlci1pdGVtJztcbiAgICAgICAgY29uc3QgY29sdW1uRWxlbWVudCA9IGVsZW1lbnQuY2xvc2VzdCgnc3dwLWRheS1jb2x1bW4nKTtcbiAgICAgICAgLy8gRm9yIGdyaWQgZXZlbnRzLCB3ZSBuZWVkIGEgY29sdW1uXG4gICAgICAgIGlmICghaXNIZWFkZXJJdGVtICYmICFjb2x1bW5FbGVtZW50KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAoaXNIZWFkZXJJdGVtKSB7XG4gICAgICAgICAgICAvLyBIZWFkZXIgaXRlbSBkcmFnIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVIZWFkZXJJdGVtRHJhZyhlbGVtZW50LCBtb3VzZU9mZnNldCwgZXZlbnRJZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBHcmlkIGV2ZW50IGRyYWcgaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUdyaWRFdmVudERyYWcoZWxlbWVudCwgbW91c2VPZmZzZXQsIGUsIGNvbHVtbkVsZW1lbnQsIGV2ZW50SWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZHJhZyBmb3IgYSBoZWFkZXIgaXRlbSAoYWxsRGF5IGV2ZW50KVxuICAgICAqL1xuICAgIGluaXRpYWxpemVIZWFkZXJJdGVtRHJhZyhlbGVtZW50LCBtb3VzZU9mZnNldCwgZXZlbnRJZCkge1xuICAgICAgICAvLyBNYXJrIGFzIGRyYWdnaW5nXG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZ2dpbmcnKTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBkcmFnIHN0YXRlIGZvciBoZWFkZXIgaXRlbVxuICAgICAgICB0aGlzLmRyYWdTdGF0ZSA9IHtcbiAgICAgICAgICAgIGV2ZW50SWQsXG4gICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgZ2hvc3RFbGVtZW50OiBudWxsLCAvLyBObyBnaG9zdCBmb3IgaGVhZGVyIGl0ZW1zXG4gICAgICAgICAgICBzdGFydFk6IDAsXG4gICAgICAgICAgICBtb3VzZU9mZnNldCxcbiAgICAgICAgICAgIGNvbHVtbkVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICBjdXJyZW50Q29sdW1uOiBudWxsLFxuICAgICAgICAgICAgdGFyZ2V0WTogMCxcbiAgICAgICAgICAgIGN1cnJlbnRZOiAwLFxuICAgICAgICAgICAgYW5pbWF0aW9uSWQ6IDAsXG4gICAgICAgICAgICBzb3VyY2VDb2x1bW5LZXk6ICcnLCAvLyBXaWxsIGJlIHNldCBmcm9tIGhlYWRlciBpdGVtIGRhdGFcbiAgICAgICAgICAgIGRyYWdTb3VyY2U6ICdoZWFkZXInXG4gICAgICAgIH07XG4gICAgICAgIC8vIFN0YXJ0IGluIGhlYWRlciBtb2RlXG4gICAgICAgIHRoaXMuaW5IZWFkZXIgPSB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGRyYWcgZm9yIGEgZ3JpZCBldmVudFxuICAgICAqL1xuICAgIGluaXRpYWxpemVHcmlkRXZlbnREcmFnKGVsZW1lbnQsIG1vdXNlT2Zmc2V0LCBlLCBjb2x1bW5FbGVtZW50LCBldmVudElkKSB7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBhYnNvbHV0ZSBZIHBvc2l0aW9uIHVzaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdFxuICAgICAgICBjb25zdCBlbGVtZW50UmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IGNvbHVtblJlY3QgPSBjb2x1bW5FbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCBzdGFydFkgPSBlbGVtZW50UmVjdC50b3AgLSBjb2x1bW5SZWN0LnRvcDtcbiAgICAgICAgLy8gSWYgZXZlbnQgaXMgaW5zaWRlIGEgZ3JvdXAsIG1vdmUgaXQgdG8gZXZlbnRzLWxheWVyIGZvciBjb3JyZWN0IHBvc2l0aW9uaW5nIGR1cmluZyBkcmFnXG4gICAgICAgIGNvbnN0IGdyb3VwID0gZWxlbWVudC5jbG9zZXN0KCdzd3AtZXZlbnQtZ3JvdXAnKTtcbiAgICAgICAgaWYgKGdyb3VwKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudHNMYXllciA9IGNvbHVtbkVsZW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50cy1sYXllcicpO1xuICAgICAgICAgICAgaWYgKGV2ZW50c0xheWVyKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2V0IGNvbnNpc3RlbnQgcG9zaXRpb25pbmcgZm9yIGRyYWcgKHdvcmtzIGZvciBib3RoIGdyb3VwZWQgYW5kIHN0YWNrZWQgZXZlbnRzKVxuICAgICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtzdGFydFl9cHhgO1xuICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSAnMnB4JztcbiAgICAgICAgZWxlbWVudC5zdHlsZS5yaWdodCA9ICcycHgnO1xuICAgICAgICBlbGVtZW50LnN0eWxlLm1hcmdpbkxlZnQgPSAnMCc7IC8vIFJlc2V0IHN0YWNraW5nIG1hcmdpblxuICAgICAgICAvLyBDcmVhdGUgZ2hvc3QgY2xvbmVcbiAgICAgICAgY29uc3QgZ2hvc3RFbGVtZW50ID0gZWxlbWVudC5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICAgIGdob3N0RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnLWdob3N0Jyk7XG4gICAgICAgIGdob3N0RWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gJzAuMyc7XG4gICAgICAgIGdob3N0RWxlbWVudC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgICAgICAvLyBJbnNlcnQgZ2hvc3QgYmVmb3JlIG9yaWdpbmFsXG4gICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZT8uaW5zZXJ0QmVmb3JlKGdob3N0RWxlbWVudCwgZWxlbWVudCk7XG4gICAgICAgIC8vIFNldHVwIGVsZW1lbnQgZm9yIGRyYWdnaW5nXG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZHJhZ2dpbmcnKTtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGluaXRpYWwgdGFyZ2V0IGZyb20gbW91c2UgcG9zaXRpb25cbiAgICAgICAgY29uc3QgdGFyZ2V0WSA9IGUuY2xpZW50WSAtIGNvbHVtblJlY3QudG9wIC0gbW91c2VPZmZzZXQueTtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBkcmFnIHN0YXRlXG4gICAgICAgIHRoaXMuZHJhZ1N0YXRlID0ge1xuICAgICAgICAgICAgZXZlbnRJZCxcbiAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICBnaG9zdEVsZW1lbnQsXG4gICAgICAgICAgICBzdGFydFksXG4gICAgICAgICAgICBtb3VzZU9mZnNldCxcbiAgICAgICAgICAgIGNvbHVtbkVsZW1lbnQsXG4gICAgICAgICAgICBjdXJyZW50Q29sdW1uOiBjb2x1bW5FbGVtZW50LFxuICAgICAgICAgICAgdGFyZ2V0WTogTWF0aC5tYXgoMCwgdGFyZ2V0WSksXG4gICAgICAgICAgICBjdXJyZW50WTogc3RhcnRZLFxuICAgICAgICAgICAgYW5pbWF0aW9uSWQ6IDAsXG4gICAgICAgICAgICBzb3VyY2VDb2x1bW5LZXk6IGNvbHVtbkVsZW1lbnQuZGF0YXNldC5jb2x1bW5LZXkgfHwgJycsXG4gICAgICAgICAgICBkcmFnU291cmNlOiAnZ3JpZCdcbiAgICAgICAgfTtcbiAgICAgICAgLy8gRW1pdCBkcmFnOnN0YXJ0XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICBldmVudElkLFxuICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgIGdob3N0RWxlbWVudCxcbiAgICAgICAgICAgIHN0YXJ0WSxcbiAgICAgICAgICAgIG1vdXNlT2Zmc2V0LFxuICAgICAgICAgICAgY29sdW1uRWxlbWVudFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX1NUQVJULCBwYXlsb2FkKTtcbiAgICAgICAgLy8gU3RhcnQgYW5pbWF0aW9uIGxvb3BcbiAgICAgICAgdGhpcy5hbmltYXRlRHJhZygpO1xuICAgIH1cbiAgICB1cGRhdGVEcmFnVGFyZ2V0KGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gQ2hlY2sgaGVhZGVyIHpvbmUgZmlyc3RcbiAgICAgICAgdGhpcy5jaGVja0hlYWRlclpvbmUoZSk7XG4gICAgICAgIC8vIFNraXAgbm9ybWFsIGdyaWQgaGFuZGxpbmcgaWYgaW4gaGVhZGVyXG4gICAgICAgIGlmICh0aGlzLmluSGVhZGVyKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBDaGVjayBmb3IgY29sdW1uIGNoYW5nZVxuICAgICAgICBjb25zdCBjb2x1bW5BdFBvaW50ID0gdGhpcy5nZXRDb2x1bW5BdFBvaW50KGUuY2xpZW50WCk7XG4gICAgICAgIC8vIEZvciBoZWFkZXIgaXRlbXMgZW50ZXJpbmcgZ3JpZCwgc2V0IGluaXRpYWwgY29sdW1uXG4gICAgICAgIGlmICh0aGlzLmRyYWdTdGF0ZS5kcmFnU291cmNlID09PSAnaGVhZGVyJyAmJiBjb2x1bW5BdFBvaW50ICYmICF0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uKSB7XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uID0gY29sdW1uQXRQb2ludDtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQgPSBjb2x1bW5BdFBvaW50O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2x1bW5BdFBvaW50ICYmIGNvbHVtbkF0UG9pbnQgIT09IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4gJiYgdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbikge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICBldmVudElkOiB0aGlzLmRyYWdTdGF0ZS5ldmVudElkLFxuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgcHJldmlvdXNDb2x1bW46IHRoaXMuZHJhZ1N0YXRlLmN1cnJlbnRDb2x1bW4sXG4gICAgICAgICAgICAgICAgbmV3Q29sdW1uOiBjb2x1bW5BdFBvaW50LFxuICAgICAgICAgICAgICAgIGN1cnJlbnRZOiB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50WVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfQ09MVU1OX0NIQU5HRSwgcGF5bG9hZCk7XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jdXJyZW50Q29sdW1uID0gY29sdW1uQXRQb2ludDtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXRlLmNvbHVtbkVsZW1lbnQgPSBjb2x1bW5BdFBvaW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIFNraXAgZ3JpZCBwb3NpdGlvbiB1cGRhdGVzIGlmIG5vIGNvbHVtbiB5ZXRcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCBjb2x1bW5SZWN0ID0gdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0WSA9IGUuY2xpZW50WSAtIGNvbHVtblJlY3QudG9wIC0gdGhpcy5kcmFnU3RhdGUubW91c2VPZmZzZXQueTtcbiAgICAgICAgdGhpcy5kcmFnU3RhdGUudGFyZ2V0WSA9IE1hdGgubWF4KDAsIHRhcmdldFkpO1xuICAgICAgICAvLyBTdGFydCBhbmltYXRpb24gaWYgbm90IHJ1bm5pbmdcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZS5hbmltYXRpb25JZCkge1xuICAgICAgICAgICAgdGhpcy5hbmltYXRlRHJhZygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHBvaW50ZXIgaXMgaW4gaGVhZGVyIHpvbmUgYW5kIGVtaXQgYXBwcm9wcmlhdGUgZXZlbnRzXG4gICAgICovXG4gICAgY2hlY2tIZWFkZXJab25lKGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRyYWdTdGF0ZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgaGVhZGVyVmlld3BvcnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzd3AtaGVhZGVyLXZpZXdwb3J0Jyk7XG4gICAgICAgIGlmICghaGVhZGVyVmlld3BvcnQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IHJlY3QgPSBoZWFkZXJWaWV3cG9ydC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgaXNJbkhlYWRlciA9IGUuY2xpZW50WSA8IHJlY3QuYm90dG9tO1xuICAgICAgICBpZiAoaXNJbkhlYWRlciAmJiAhdGhpcy5pbkhlYWRlcikge1xuICAgICAgICAgICAgLy8gRW50ZXJlZCBoZWFkZXIgKGZyb20gZ3JpZClcbiAgICAgICAgICAgIHRoaXMuaW5IZWFkZXIgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlLmRyYWdTb3VyY2UgPT09ICdncmlkJyAmJiB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRJZDogdGhpcy5kcmFnU3RhdGUuZXZlbnRJZCxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudCxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlQ29sdW1uSW5kZXg6IHRoaXMuZ2V0Q29sdW1uSW5kZXgodGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudCksXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogdGhpcy5kcmFnU3RhdGUuY29sdW1uRWxlbWVudC5kYXRhc2V0LmNvbHVtbktleSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50LXRpdGxlJyk/LnRleHRDb250ZW50IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICBjb2xvckNsYXNzOiBbLi4udGhpcy5kcmFnU3RhdGUuZWxlbWVudC5jbGFzc0xpc3RdLmZpbmQoYyA9PiBjLnN0YXJ0c1dpdGgoJ2lzLScpKSxcbiAgICAgICAgICAgICAgICAgICAgaXRlbVR5cGU6ICdldmVudCcsXG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAxXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VOVEVSX0hFQURFUiwgcGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBGb3IgaGVhZGVyIHNvdXJjZSByZS1lbnRlcmluZyBoZWFkZXIsIGp1c3QgdXBkYXRlIGluSGVhZGVyIGZsYWdcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaXNJbkhlYWRlciAmJiB0aGlzLmluSGVhZGVyKSB7XG4gICAgICAgICAgICAvLyBMZWZ0IGhlYWRlciAoZW50ZXJpbmcgZ3JpZClcbiAgICAgICAgICAgIHRoaXMuaW5IZWFkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldENvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uQXRQb2ludChlLmNsaWVudFgpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ1N0YXRlLmRyYWdTb3VyY2UgPT09ICdoZWFkZXInKSB7XG4gICAgICAgICAgICAgICAgLy8gSGVhZGVyIGl0ZW0gbGVhdmluZyBoZWFkZXIgXHUyMTkyIGNyZWF0ZSBzd3AtZXZlbnQgaW4gZ3JpZFxuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHRoaXMuZHJhZ1N0YXRlLmV2ZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogJ2hlYWRlcicsXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldENvbHVtbjogdGFyZ2V0Q29sdW1uIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuZGF0YXNldC5zdGFydCA/IG5ldyBEYXRlKHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuZGF0YXNldC5zdGFydCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGVuZDogdGhpcy5kcmFnU3RhdGUuZWxlbWVudC5kYXRhc2V0LmVuZCA/IG5ldyBEYXRlKHRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuZGF0YXNldC5lbmQpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogdGhpcy5kcmFnU3RhdGUuZWxlbWVudC50ZXh0Q29udGVudCB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgY29sb3JDbGFzczogWy4uLnRoaXMuZHJhZ1N0YXRlLmVsZW1lbnQuY2xhc3NMaXN0XS5maW5kKGMgPT4gYy5zdGFydHNXaXRoKCdpcy0nKSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX0RSQUdfTEVBVkVfSEVBREVSLCBwYXlsb2FkKTtcbiAgICAgICAgICAgICAgICAvLyBSZS1hdHRhY2ggdG8gdGhlIG5ldyBzd3AtZXZlbnQgY3JlYXRlZCBieSBFdmVudFJlbmRlcmVyXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldENvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdFbGVtZW50ID0gdGFyZ2V0Q29sdW1uLnF1ZXJ5U2VsZWN0b3IoYHN3cC1ldmVudFtkYXRhLWV2ZW50LWlkPVwiJHt0aGlzLmRyYWdTdGF0ZS5ldmVudElkfVwiXWApO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV3RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuZWxlbWVudCA9IG5ld0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGF0ZS5jb2x1bW5FbGVtZW50ID0gdGFyZ2V0Q29sdW1uO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnU3RhdGUuY3VycmVudENvbHVtbiA9IHRhcmdldENvbHVtbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGFuaW1hdGlvbiBmb3IgdGhlIG5ldyBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFuaW1hdGVEcmFnKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBHcmlkIGV2ZW50IGxlYXZpbmcgaGVhZGVyIFx1MjE5MiByZXN0b3JlIHRvIGdyaWRcbiAgICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICBldmVudElkOiB0aGlzLmRyYWdTdGF0ZS5ldmVudElkLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6ICdncmlkJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfRFJBR19MRUFWRV9IRUFERVIsIHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzSW5IZWFkZXIpIHtcbiAgICAgICAgICAgIC8vIE1vdmluZyB3aXRoaW4gaGVhZGVyXG4gICAgICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmdldENvbHVtbkF0WChlLmNsaWVudFgpO1xuICAgICAgICAgICAgaWYgKGNvbHVtbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHRoaXMuZHJhZ1N0YXRlLmV2ZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbkluZGV4OiB0aGlzLmdldENvbHVtbkluZGV4KGNvbHVtbiksXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbktleTogY29sdW1uLmRhdGFzZXQuY29sdW1uS2V5IHx8ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkVfSEVBREVSLCBwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY29sdW1uIGluZGV4ICgwLWJhc2VkKSBmb3IgYSBjb2x1bW4gZWxlbWVudFxuICAgICAqL1xuICAgIGdldENvbHVtbkluZGV4KGNvbHVtbikge1xuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyIHx8ICFjb2x1bW4pXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IEFycmF5LmZyb20odGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnc3dwLWRheS1jb2x1bW4nKSk7XG4gICAgICAgIHJldHVybiBjb2x1bW5zLmluZGV4T2YoY29sdW1uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGNvbHVtbiBhdCBYIGNvb3JkaW5hdGUgKGFsaWFzIGZvciBnZXRDb2x1bW5BdFBvaW50KVxuICAgICAqL1xuICAgIGdldENvbHVtbkF0WChjbGllbnRYKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldENvbHVtbkF0UG9pbnQoY2xpZW50WCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmQgY29sdW1uIGVsZW1lbnQgYXQgZ2l2ZW4gWCBjb29yZGluYXRlXG4gICAgICovXG4gICAgZ2V0Q29sdW1uQXRQb2ludChjbGllbnRYKSB7XG4gICAgICAgIGlmICghdGhpcy5jb250YWluZXIpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJ3N3cC1kYXktY29sdW1uJyk7XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3QgPSBjb2wuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBpZiAoY2xpZW50WCA+PSByZWN0LmxlZnQgJiYgY2xpZW50WCA8PSByZWN0LnJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGRyYWcgYW5kIGFuaW1hdGUgYmFjayB0byBzdGFydCBwb3NpdGlvblxuICAgICAqL1xuICAgIGNhbmNlbERyYWcoKSB7XG4gICAgICAgIGlmICghdGhpcy5kcmFnU3RhdGUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIFN0b3AgYW5pbWF0aW9uXG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuZHJhZ1N0YXRlLmFuaW1hdGlvbklkKTtcbiAgICAgICAgY29uc3QgeyBlbGVtZW50LCBnaG9zdEVsZW1lbnQsIHN0YXJ0WSwgZXZlbnRJZCB9ID0gdGhpcy5kcmFnU3RhdGU7XG4gICAgICAgIC8vIEFuaW1hdGUgYmFjayB0byBzdGFydFxuICAgICAgICBlbGVtZW50LnN0eWxlLnRyYW5zaXRpb24gPSAndG9wIDIwMG1zIGVhc2Utb3V0JztcbiAgICAgICAgZWxlbWVudC5zdHlsZS50b3AgPSBgJHtzdGFydFl9cHhgO1xuICAgICAgICAvLyBSZW1vdmUgZ2hvc3QgYWZ0ZXIgYW5pbWF0aW9uIChpZiBleGlzdHMpXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgZ2hvc3RFbGVtZW50Py5yZW1vdmUoKTtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbiA9ICcnO1xuICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdkcmFnZ2luZycpO1xuICAgICAgICB9LCAyMDApO1xuICAgICAgICAvLyBFbWl0IGRyYWc6Y2FuY2VsXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAgICAgICBldmVudElkLFxuICAgICAgICAgICAgZWxlbWVudCxcbiAgICAgICAgICAgIHN0YXJ0WVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0NBTkNFTCwgcGF5bG9hZCk7XG4gICAgICAgIHRoaXMuZHJhZ1N0YXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbkhlYWRlciA9IGZhbHNlO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBDb3JlRXZlbnRzIH0gZnJvbSAnLi4vY29uc3RhbnRzL0NvcmVFdmVudHMnO1xuZXhwb3J0IGNsYXNzIEVkZ2VTY3JvbGxNYW5hZ2VyIHtcbiAgICBjb25zdHJ1Y3RvcihldmVudEJ1cykge1xuICAgICAgICB0aGlzLmV2ZW50QnVzID0gZXZlbnRCdXM7XG4gICAgICAgIHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLnRpbWVHcmlkID0gbnVsbDtcbiAgICAgICAgdGhpcy5kcmFnZ2VkRWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuc2Nyb2xsUkFGID0gbnVsbDtcbiAgICAgICAgdGhpcy5tb3VzZVkgPSAwO1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc1Njcm9sbGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxhc3RUcyA9IDA7XG4gICAgICAgIHRoaXMucmVjdCA9IG51bGw7XG4gICAgICAgIHRoaXMuaW5pdGlhbFNjcm9sbFRvcCA9IDA7XG4gICAgICAgIHRoaXMuT1VURVJfWk9ORSA9IDEwMDtcbiAgICAgICAgdGhpcy5JTk5FUl9aT05FID0gNTA7XG4gICAgICAgIHRoaXMuU0xPV19TUEVFRCA9IDE0MDtcbiAgICAgICAgdGhpcy5GQVNUX1NQRUVEID0gNjQwO1xuICAgICAgICB0aGlzLnRyYWNrTW91c2UgPSAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIHRoaXMubW91c2VZID0gZS5jbGllbnRZO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNjcm9sbFRpY2sgPSAodHMpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nIHx8ICF0aGlzLnNjcm9sbGFibGVDb250ZW50KVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGR0ID0gdGhpcy5sYXN0VHMgPyAodHMgLSB0aGlzLmxhc3RUcykgLyAxMDAwIDogMDtcbiAgICAgICAgICAgIHRoaXMubGFzdFRzID0gdHM7XG4gICAgICAgICAgICB0aGlzLnJlY3QgPz8gKHRoaXMucmVjdCA9IHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICAgICAgICAgICAgY29uc3QgdmVsb2NpdHkgPSB0aGlzLmNhbGN1bGF0ZVZlbG9jaXR5KCk7XG4gICAgICAgICAgICBpZiAodmVsb2NpdHkgIT09IDAgJiYgIXRoaXMuaXNBdEJvdW5kYXJ5KHZlbG9jaXR5KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjcm9sbERlbHRhID0gdmVsb2NpdHkgKiBkdDtcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbGFibGVDb250ZW50LnNjcm9sbFRvcCArPSBzY3JvbGxEZWx0YTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY3QgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVER0VfU0NST0xMX1RJQ0ssIHsgc2Nyb2xsRGVsdGEgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY3JvbGxpbmdTdGF0ZSh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U2Nyb2xsaW5nU3RhdGUoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zY3JvbGxSQUYgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5zY3JvbGxUaWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVUb0V2ZW50cygpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMudHJhY2tNb3VzZSk7XG4gICAgfVxuICAgIGluaXQoc2Nyb2xsYWJsZUNvbnRlbnQpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxhYmxlQ29udGVudCA9IHNjcm9sbGFibGVDb250ZW50O1xuICAgICAgICB0aGlzLnRpbWVHcmlkID0gc2Nyb2xsYWJsZUNvbnRlbnQucXVlcnlTZWxlY3Rvcignc3dwLXRpbWUtZ3JpZCcpO1xuICAgICAgICB0aGlzLnNjcm9sbGFibGVDb250ZW50LnN0eWxlLnNjcm9sbEJlaGF2aW9yID0gJ2F1dG8nO1xuICAgIH1cbiAgICBzdWJzY3JpYmVUb0V2ZW50cygpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfU1RBUlQsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICAgIHRoaXMuZHJhZ2dlZEVsZW1lbnQgPSBwYXlsb2FkLmVsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0RHJhZygpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfRU5ELCAoKSA9PiB0aGlzLnN0b3BEcmFnKCkpO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19DQU5DRUwsICgpID0+IHRoaXMuc3RvcERyYWcoKSk7XG4gICAgfVxuICAgIHN0YXJ0RHJhZygpIHtcbiAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pc1Njcm9sbGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxhc3RUcyA9IDA7XG4gICAgICAgIHRoaXMuaW5pdGlhbFNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQ/LnNjcm9sbFRvcCA/PyAwO1xuICAgICAgICBpZiAodGhpcy5zY3JvbGxSQUYgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsUkFGID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuc2Nyb2xsVGljayk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RvcERyYWcoKSB7XG4gICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNldFNjcm9sbGluZ1N0YXRlKGZhbHNlKTtcbiAgICAgICAgaWYgKHRoaXMuc2Nyb2xsUkFGICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnNjcm9sbFJBRik7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbFJBRiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWN0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0VHMgPSAwO1xuICAgICAgICB0aGlzLmluaXRpYWxTY3JvbGxUb3AgPSAwO1xuICAgIH1cbiAgICBjYWxjdWxhdGVWZWxvY2l0eSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlY3QpXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgY29uc3QgZGlzdFRvcCA9IHRoaXMubW91c2VZIC0gdGhpcy5yZWN0LnRvcDtcbiAgICAgICAgY29uc3QgZGlzdEJvdCA9IHRoaXMucmVjdC5ib3R0b20gLSB0aGlzLm1vdXNlWTtcbiAgICAgICAgaWYgKGRpc3RUb3AgPCB0aGlzLklOTkVSX1pPTkUpXG4gICAgICAgICAgICByZXR1cm4gLXRoaXMuRkFTVF9TUEVFRDtcbiAgICAgICAgaWYgKGRpc3RUb3AgPCB0aGlzLk9VVEVSX1pPTkUpXG4gICAgICAgICAgICByZXR1cm4gLXRoaXMuU0xPV19TUEVFRDtcbiAgICAgICAgaWYgKGRpc3RCb3QgPCB0aGlzLklOTkVSX1pPTkUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5GQVNUX1NQRUVEO1xuICAgICAgICBpZiAoZGlzdEJvdCA8IHRoaXMuT1VURVJfWk9ORSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLlNMT1dfU1BFRUQ7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpc0F0Qm91bmRhcnkodmVsb2NpdHkpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNjcm9sbGFibGVDb250ZW50IHx8ICF0aGlzLnRpbWVHcmlkIHx8ICF0aGlzLmRyYWdnZWRFbGVtZW50KVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBjb25zdCBhdFRvcCA9IHRoaXMuc2Nyb2xsYWJsZUNvbnRlbnQuc2Nyb2xsVG9wIDw9IDAgJiYgdmVsb2NpdHkgPCAwO1xuICAgICAgICBjb25zdCBhdEJvdHRvbSA9IHZlbG9jaXR5ID4gMCAmJlxuICAgICAgICAgICAgdGhpcy5kcmFnZ2VkRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b20gPj1cbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVHcmlkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmJvdHRvbTtcbiAgICAgICAgcmV0dXJuIGF0VG9wIHx8IGF0Qm90dG9tO1xuICAgIH1cbiAgICBzZXRTY3JvbGxpbmdTdGF0ZShzY3JvbGxpbmcpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNTY3JvbGxpbmcgPT09IHNjcm9sbGluZylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdGhpcy5pc1Njcm9sbGluZyA9IHNjcm9sbGluZztcbiAgICAgICAgaWYgKHNjcm9sbGluZykge1xuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRURHRV9TQ1JPTExfU1RBUlRFRCwge30pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsU2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxhYmxlQ29udGVudD8uc2Nyb2xsVG9wID8/IDA7XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FREdFX1NDUk9MTF9TVE9QUEVELCB7fSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgcGl4ZWxzVG9NaW51dGVzLCBtaW51dGVzVG9QaXhlbHMsIHNuYXBUb0dyaWQgfSBmcm9tICcuLi91dGlscy9Qb3NpdGlvblV0aWxzJztcbmltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG5pbXBvcnQgeyBTd3BFdmVudCB9IGZyb20gJy4uL3R5cGVzL1N3cEV2ZW50JztcbmV4cG9ydCBjbGFzcyBSZXNpemVNYW5hZ2VyIHtcbiAgICBjb25zdHJ1Y3RvcihldmVudEJ1cywgZ3JpZENvbmZpZywgZGF0ZVNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICAgICAgICB0aGlzLmdyaWRDb25maWcgPSBncmlkQ29uZmlnO1xuICAgICAgICB0aGlzLmRhdGVTZXJ2aWNlID0gZGF0ZVNlcnZpY2U7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5yZXNpemVTdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuWl9JTkRFWF9SRVNJWklORyA9ICcxMDAwJztcbiAgICAgICAgdGhpcy5BTklNQVRJT05fU1BFRUQgPSAwLjM1O1xuICAgICAgICB0aGlzLk1JTl9IRUlHSFRfTUlOVVRFUyA9IDE1O1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIG1vdXNlb3ZlciAtIGNyZWF0ZSByZXNpemUgaGFuZGxlIGlmIG5vdCBleGlzdHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFuZGxlTW91c2VPdmVyID0gKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICAgICAgY29uc3QgZXZlbnRFbGVtZW50ID0gdGFyZ2V0LmNsb3Nlc3QoJ3N3cC1ldmVudCcpO1xuICAgICAgICAgICAgaWYgKCFldmVudEVsZW1lbnQgfHwgdGhpcy5yZXNpemVTdGF0ZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBoYW5kbGUgYWxyZWFkeSBleGlzdHNcbiAgICAgICAgICAgIGlmICghZXZlbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJzpzY29wZSA+IHN3cC1yZXNpemUtaGFuZGxlJykpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSB0aGlzLmNyZWF0ZVJlc2l6ZUhhbmRsZSgpO1xuICAgICAgICAgICAgICAgIGV2ZW50RWxlbWVudC5hcHBlbmRDaGlsZChoYW5kbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogSGFuZGxlIHBvaW50ZXJkb3duIC0gc3RhcnQgcmVzaXplIGlmIG9uIGhhbmRsZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyRG93biA9IChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBoYW5kbGUgPSBlLnRhcmdldC5jbG9zZXN0KCdzd3AtcmVzaXplLWhhbmRsZScpO1xuICAgICAgICAgICAgaWYgKCFoYW5kbGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IGhhbmRsZS5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgaWYgKCFlbGVtZW50KVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50SWQgPSBlbGVtZW50LmRhdGFzZXQuZXZlbnRJZCB8fCAnJztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0SGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCBzdGFydER1cmF0aW9uTWludXRlcyA9IHBpeGVsc1RvTWludXRlcyhzdGFydEhlaWdodCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgICAgIC8vIFN0b3JlIHByZXZpb3VzIHotaW5kZXhcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGVsZW1lbnQuY2xvc2VzdCgnc3dwLWV2ZW50LWdyb3VwJykgPz8gZWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IHByZXZaSW5kZXggPSBjb250YWluZXIuc3R5bGUuekluZGV4O1xuICAgICAgICAgICAgLy8gU2V0IHJlc2l6ZSBzdGF0ZVxuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICBldmVudElkLFxuICAgICAgICAgICAgICAgIGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgaGFuZGxlRWxlbWVudDogaGFuZGxlLFxuICAgICAgICAgICAgICAgIHN0YXJ0WTogZS5jbGllbnRZLFxuICAgICAgICAgICAgICAgIHN0YXJ0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIHN0YXJ0RHVyYXRpb25NaW51dGVzLFxuICAgICAgICAgICAgICAgIHBvaW50ZXJJZDogZS5wb2ludGVySWQsXG4gICAgICAgICAgICAgICAgcHJldlpJbmRleCxcbiAgICAgICAgICAgICAgICAvLyBBbmltYXRpb24gc3RhdGVcbiAgICAgICAgICAgICAgICBjdXJyZW50SGVpZ2h0OiBzdGFydEhlaWdodCxcbiAgICAgICAgICAgICAgICB0YXJnZXRIZWlnaHQ6IHN0YXJ0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIGFuaW1hdGlvbklkOiBudWxsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gRWxldmF0ZSB6LWluZGV4XG4gICAgICAgICAgICBjb250YWluZXIuc3R5bGUuekluZGV4ID0gdGhpcy5aX0lOREVYX1JFU0laSU5HO1xuICAgICAgICAgICAgLy8gQ2FwdHVyZSBwb2ludGVyIGZvciBzbW9vdGggdHJhY2tpbmdcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1BvaW50ZXIgY2FwdHVyZSBmYWlsZWQ6JywgZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFkZCBnbG9iYWwgcmVzaXppbmcgY2xhc3NcbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzd3AtLXJlc2l6aW5nJyk7XG4gICAgICAgICAgICAvLyBFbWl0IHJlc2l6ZSBzdGFydCBldmVudFxuICAgICAgICAgICAgdGhpcy5ldmVudEJ1cy5lbWl0KENvcmVFdmVudHMuRVZFTlRfUkVTSVpFX1NUQVJULCB7XG4gICAgICAgICAgICAgICAgZXZlbnRJZCxcbiAgICAgICAgICAgICAgICBlbGVtZW50LFxuICAgICAgICAgICAgICAgIHN0YXJ0SGVpZ2h0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZSBwb2ludGVybW92ZSAtIHVwZGF0ZSB0YXJnZXQgaGVpZ2h0IGR1cmluZyByZXNpemVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlck1vdmUgPSAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnJlc2l6ZVN0YXRlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhWSA9IGUuY2xpZW50WSAtIHRoaXMucmVzaXplU3RhdGUuc3RhcnRZO1xuICAgICAgICAgICAgY29uc3QgbWluSGVpZ2h0ID0gKHRoaXMuTUlOX0hFSUdIVF9NSU5VVEVTIC8gNjApICogdGhpcy5ncmlkQ29uZmlnLmhvdXJIZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heChtaW5IZWlnaHQsIHRoaXMucmVzaXplU3RhdGUuc3RhcnRIZWlnaHQgKyBkZWx0YVkpO1xuICAgICAgICAgICAgLy8gU2V0IHRhcmdldCBoZWlnaHQgZm9yIGFuaW1hdGlvblxuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS50YXJnZXRIZWlnaHQgPSBuZXdIZWlnaHQ7XG4gICAgICAgICAgICAvLyBTdGFydCBhbmltYXRpb24gaWYgbm90IHJ1bm5pbmdcbiAgICAgICAgICAgIGlmICh0aGlzLnJlc2l6ZVN0YXRlLmFuaW1hdGlvbklkID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hbmltYXRlSGVpZ2h0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSQUYgYW5pbWF0aW9uIGxvb3AgZm9yIHNtb290aCBoZWlnaHQgaW50ZXJwb2xhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hbmltYXRlSGVpZ2h0ID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnJlc2l6ZVN0YXRlKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGRpZmYgPSB0aGlzLnJlc2l6ZVN0YXRlLnRhcmdldEhlaWdodCAtIHRoaXMucmVzaXplU3RhdGUuY3VycmVudEhlaWdodDtcbiAgICAgICAgICAgIC8vIFN0b3AgYW5pbWF0aW9uIHdoZW4gY2xvc2UgZW5vdWdoXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoZGlmZikgPCAwLjUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZVN0YXRlLmFuaW1hdGlvbklkID0gbnVsbDtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJbnRlcnBvbGF0ZSB0b3dhcmRzIHRhcmdldCAoMzUlIHBlciBmcmFtZSBsaWtlIFYxKVxuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5jdXJyZW50SGVpZ2h0ICs9IGRpZmYgKiB0aGlzLkFOSU1BVElPTl9TUEVFRDtcbiAgICAgICAgICAgIHRoaXMucmVzaXplU3RhdGUuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHt0aGlzLnJlc2l6ZVN0YXRlLmN1cnJlbnRIZWlnaHR9cHhgO1xuICAgICAgICAgICAgLy8gVXBkYXRlIHRpbWVzdGFtcCBkaXNwbGF5IChzbmFwcGVkKVxuICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lc3RhbXBEaXNwbGF5KCk7XG4gICAgICAgICAgICAvLyBDb250aW51ZSBhbmltYXRpb25cbiAgICAgICAgICAgIHRoaXMucmVzaXplU3RhdGUuYW5pbWF0aW9uSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRlSGVpZ2h0KTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZSBwb2ludGVydXAgLSBmaW5pc2ggcmVzaXplXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJVcCA9IChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucmVzaXplU3RhdGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIGFuaW1hdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMucmVzaXplU3RhdGUuYW5pbWF0aW9uSWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnJlc2l6ZVN0YXRlLmFuaW1hdGlvbklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbGVhc2UgcG9pbnRlciBjYXB0dXJlXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplU3RhdGUuaGFuZGxlRWxlbWVudC5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUG9pbnRlciByZWxlYXNlIGZhaWxlZDonLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU25hcCBmaW5hbCBoZWlnaHQgdG8gZ3JpZFxuICAgICAgICAgICAgdGhpcy5zbmFwVG9HcmlkRmluYWwoKTtcbiAgICAgICAgICAgIC8vIFVwZGF0ZSB0aW1lc3RhbXAgb25lIGZpbmFsIHRpbWVcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVGltZXN0YW1wRGlzcGxheSgpO1xuICAgICAgICAgICAgLy8gUmVzdG9yZSB6LWluZGV4XG4gICAgICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQuY2xvc2VzdCgnc3dwLWV2ZW50LWdyb3VwJykgPz8gdGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50O1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnpJbmRleCA9IHRoaXMucmVzaXplU3RhdGUucHJldlpJbmRleDtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBnbG9iYWwgcmVzaXppbmcgY2xhc3NcbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdzd3AtLXJlc2l6aW5nJyk7XG4gICAgICAgICAgICAvLyBHZXQgY29sdW1uS2V5IGFuZCBkYXRlIGZyb20gcGFyZW50IGNvbHVtblxuICAgICAgICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50LmNsb3Nlc3QoJ3N3cC1kYXktY29sdW1uJyk7XG4gICAgICAgICAgICBjb25zdCBjb2x1bW5LZXkgPSBjb2x1bW4/LmRhdGFzZXQuY29sdW1uS2V5IHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgZGF0ZSA9IGNvbHVtbj8uZGF0YXNldC5kYXRlIHx8ICcnO1xuICAgICAgICAgICAgLy8gQ3JlYXRlIFN3cEV2ZW50IGZyb20gZWxlbWVudCAocmVhZHMgdG9wL2hlaWdodC9ldmVudElkIGZyb20gZWxlbWVudClcbiAgICAgICAgICAgIGNvbnN0IHN3cEV2ZW50ID0gU3dwRXZlbnQuZnJvbUVsZW1lbnQodGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50LCBjb2x1bW5LZXksIGRhdGUsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgICAgICAvLyBFbWl0IHJlc2l6ZSBlbmQgZXZlbnRcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX1JFU0laRV9FTkQsIHtcbiAgICAgICAgICAgICAgICBzd3BFdmVudFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBSZXNldCBzdGF0ZVxuICAgICAgICAgICAgdGhpcy5yZXNpemVTdGF0ZSA9IG51bGw7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgcmVzaXplIGZ1bmN0aW9uYWxpdHkgb24gY29udGFpbmVyXG4gICAgICovXG4gICAgaW5pdChjb250YWluZXIpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICAgIC8vIE1vdXNlb3ZlciBsaXN0ZW5lciBmb3IgaGFuZGxlIGNyZWF0aW9uIChjYXB0dXJlIHBoYXNlIGxpa2UgVjEpXG4gICAgICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0aGlzLmhhbmRsZU1vdXNlT3ZlciwgdHJ1ZSk7XG4gICAgICAgIC8vIFBvaW50ZXIgbGlzdGVuZXJzIGZvciByZXNpemUgKGNhcHR1cmUgcGhhc2UgbGlrZSBWMSlcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLmhhbmRsZVBvaW50ZXJEb3duLCB0cnVlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlLCB0cnVlKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5oYW5kbGVQb2ludGVyVXAsIHRydWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgcmVzaXplIGhhbmRsZSBlbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlUmVzaXplSGFuZGxlKCkge1xuICAgICAgICBjb25zdCBoYW5kbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtcmVzaXplLWhhbmRsZScpO1xuICAgICAgICBoYW5kbGUuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgJ1Jlc2l6ZSBldmVudCcpO1xuICAgICAgICBoYW5kbGUuc2V0QXR0cmlidXRlKCdyb2xlJywgJ3NlcGFyYXRvcicpO1xuICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGltZXN0YW1wIGRpc3BsYXkgd2l0aCBzbmFwcGVkIGVuZCB0aW1lXG4gICAgICovXG4gICAgdXBkYXRlVGltZXN0YW1wRGlzcGxheSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlc2l6ZVN0YXRlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zdCB0aW1lRWwgPSB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQucXVlcnlTZWxlY3Rvcignc3dwLWV2ZW50LXRpbWUnKTtcbiAgICAgICAgaWYgKCF0aW1lRWwpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIEdldCBzdGFydCB0aW1lIGZyb20gZWxlbWVudCBwb3NpdGlvblxuICAgICAgICBjb25zdCB0b3AgPSBwYXJzZUZsb2F0KHRoaXMucmVzaXplU3RhdGUuZWxlbWVudC5zdHlsZS50b3ApIHx8IDA7XG4gICAgICAgIGNvbnN0IHN0YXJ0TWludXRlc0Zyb21HcmlkID0gcGl4ZWxzVG9NaW51dGVzKHRvcCwgdGhpcy5ncmlkQ29uZmlnKTtcbiAgICAgICAgY29uc3Qgc3RhcnRNaW51dGVzID0gKHRoaXMuZ3JpZENvbmZpZy5kYXlTdGFydEhvdXIgKiA2MCkgKyBzdGFydE1pbnV0ZXNGcm9tR3JpZDtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHNuYXBwZWQgZW5kIHRpbWUgZnJvbSBjdXJyZW50IGhlaWdodFxuICAgICAgICBjb25zdCBzbmFwcGVkSGVpZ2h0ID0gc25hcFRvR3JpZCh0aGlzLnJlc2l6ZVN0YXRlLmN1cnJlbnRIZWlnaHQsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uTWludXRlcyA9IHBpeGVsc1RvTWludXRlcyhzbmFwcGVkSGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICBjb25zdCBlbmRNaW51dGVzID0gc3RhcnRNaW51dGVzICsgZHVyYXRpb25NaW51dGVzO1xuICAgICAgICAvLyBGb3JtYXQgYW5kIHVwZGF0ZVxuICAgICAgICBjb25zdCBzdGFydCA9IHRoaXMubWludXRlc1RvRGF0ZShzdGFydE1pbnV0ZXMpO1xuICAgICAgICBjb25zdCBlbmQgPSB0aGlzLm1pbnV0ZXNUb0RhdGUoZW5kTWludXRlcyk7XG4gICAgICAgIHRpbWVFbC50ZXh0Q29udGVudCA9IHRoaXMuZGF0ZVNlcnZpY2UuZm9ybWF0VGltZVJhbmdlKHN0YXJ0LCBlbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IG1pbnV0ZXMgc2luY2UgbWlkbmlnaHQgdG8gRGF0ZVxuICAgICAqL1xuICAgIG1pbnV0ZXNUb0RhdGUobWludXRlcykge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgZGF0ZS5zZXRIb3VycyhNYXRoLmZsb29yKG1pbnV0ZXMgLyA2MCkgJSAyNCwgbWludXRlcyAlIDYwLCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICAgIDtcbiAgICAvKipcbiAgICAgKiBTbmFwIGZpbmFsIGhlaWdodCB0byBncmlkIGludGVydmFsXG4gICAgICovXG4gICAgc25hcFRvR3JpZEZpbmFsKCkge1xuICAgICAgICBpZiAoIXRoaXMucmVzaXplU3RhdGUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSB0aGlzLnJlc2l6ZVN0YXRlLmVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBjb25zdCBzbmFwcGVkSGVpZ2h0ID0gc25hcFRvR3JpZChjdXJyZW50SGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xuICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSBtaW51dGVzVG9QaXhlbHModGhpcy5NSU5fSEVJR0hUX01JTlVURVMsIHRoaXMuZ3JpZENvbmZpZyk7XG4gICAgICAgIGNvbnN0IGZpbmFsSGVpZ2h0ID0gTWF0aC5tYXgobWluSGVpZ2h0LCBzbmFwcGVkSGVpZ2h0KTtcbiAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5lbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke2ZpbmFsSGVpZ2h0fXB4YDtcbiAgICAgICAgdGhpcy5yZXNpemVTdGF0ZS5jdXJyZW50SGVpZ2h0ID0gZmluYWxIZWlnaHQ7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IENvcmVFdmVudHMgfSBmcm9tICcuLi9jb25zdGFudHMvQ29yZUV2ZW50cyc7XG5leHBvcnQgY2xhc3MgRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50U2VydmljZSwgZXZlbnRCdXMsIGRhdGVTZXJ2aWNlKSB7XG4gICAgICAgIHRoaXMuZXZlbnRTZXJ2aWNlID0gZXZlbnRTZXJ2aWNlO1xuICAgICAgICB0aGlzLmV2ZW50QnVzID0gZXZlbnRCdXM7XG4gICAgICAgIHRoaXMuZGF0ZVNlcnZpY2UgPSBkYXRlU2VydmljZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZSBkcmFnIGVuZCAtIHVwZGF0ZSBldmVudCBwb3NpdGlvbiBpbiBJbmRleGVkREJcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGFuZGxlRHJhZ0VuZCA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gZS5kZXRhaWw7XG4gICAgICAgICAgICBjb25zdCB7IHN3cEV2ZW50IH0gPSBwYXlsb2FkO1xuICAgICAgICAgICAgLy8gR2V0IGV4aXN0aW5nIGV2ZW50IHRvIG1lcmdlIHdpdGhcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UuZ2V0KHN3cEV2ZW50LmV2ZW50SWQpO1xuICAgICAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXI6IEV2ZW50ICR7c3dwRXZlbnQuZXZlbnRJZH0gbm90IGZvdW5kYCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUGFyc2UgcmVzb3VyY2VJZCBmcm9tIGNvbHVtbktleSBpZiBwcmVzZW50XG4gICAgICAgICAgICBjb25zdCB7IHJlc291cmNlIH0gPSB0aGlzLmRhdGVTZXJ2aWNlLnBhcnNlQ29sdW1uS2V5KHN3cEV2ZW50LmNvbHVtbktleSk7XG4gICAgICAgICAgICAvLyBVcGRhdGUgYW5kIHNhdmUgLSBzdGFydC9lbmQgYWxyZWFkeSBjYWxjdWxhdGVkIGluIFN3cEV2ZW50XG4gICAgICAgICAgICAvLyBTZXQgYWxsRGF5IGJhc2VkIG9uIGRyb3AgdGFyZ2V0OlxuICAgICAgICAgICAgLy8gLSBoZWFkZXI6IGFsbERheSA9IHRydWVcbiAgICAgICAgICAgIC8vIC0gZ3JpZDogYWxsRGF5ID0gZmFsc2UgKGNvbnZlcnRzIGFsbERheSBldmVudCB0byB0aW1lZClcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgICAgICBzdGFydDogc3dwRXZlbnQuc3RhcnQsXG4gICAgICAgICAgICAgICAgZW5kOiBzd3BFdmVudC5lbmQsXG4gICAgICAgICAgICAgICAgcmVzb3VyY2VJZDogcmVzb3VyY2UgPz8gZXZlbnQucmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBhbGxEYXk6IHBheWxvYWQudGFyZ2V0ID09PSAnaGVhZGVyJyxcbiAgICAgICAgICAgICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5zYXZlKHVwZGF0ZWRFdmVudCk7XG4gICAgICAgICAgICAvLyBFbWl0IEVWRU5UX1VQREFURUQgZm9yIEV2ZW50UmVuZGVyZXIgdG8gcmUtcmVuZGVyIGFmZmVjdGVkIGNvbHVtbnNcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVBheWxvYWQgPSB7XG4gICAgICAgICAgICAgICAgZXZlbnRJZDogdXBkYXRlZEV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZUNvbHVtbktleTogcGF5bG9hZC5zb3VyY2VDb2x1bW5LZXksXG4gICAgICAgICAgICAgICAgdGFyZ2V0Q29sdW1uS2V5OiBzd3BFdmVudC5jb2x1bW5LZXlcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmV2ZW50QnVzLmVtaXQoQ29yZUV2ZW50cy5FVkVOVF9VUERBVEVELCB1cGRhdGVQYXlsb2FkKTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhhbmRsZSByZXNpemUgZW5kIC0gdXBkYXRlIGV2ZW50IGR1cmF0aW9uIGluIEluZGV4ZWREQlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oYW5kbGVSZXNpemVFbmQgPSBhc3luYyAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGUuZGV0YWlsO1xuICAgICAgICAgICAgY29uc3QgeyBzd3BFdmVudCB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgIC8vIEdldCBleGlzdGluZyBldmVudCB0byBtZXJnZSB3aXRoXG4gICAgICAgICAgICBjb25zdCBldmVudCA9IGF3YWl0IHRoaXMuZXZlbnRTZXJ2aWNlLmdldChzd3BFdmVudC5ldmVudElkKTtcbiAgICAgICAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEV2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyOiBFdmVudCAke3N3cEV2ZW50LmV2ZW50SWR9IG5vdCBmb3VuZGApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFVwZGF0ZSBhbmQgc2F2ZSAtIGVuZCBhbHJlYWR5IGNhbGN1bGF0ZWQgaW4gU3dwRXZlbnRcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgICAgICBlbmQ6IHN3cEV2ZW50LmVuZCxcbiAgICAgICAgICAgICAgICBzeW5jU3RhdHVzOiAncGVuZGluZydcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5zYXZlKHVwZGF0ZWRFdmVudCk7XG4gICAgICAgICAgICAvLyBFbWl0IEVWRU5UX1VQREFURUQgZm9yIEV2ZW50UmVuZGVyZXIgdG8gcmUtcmVuZGVyIHRoZSBjb2x1bW5cbiAgICAgICAgICAgIC8vIFJlc2l6ZSBzdGF5cyBpbiBzYW1lIGNvbHVtbiwgc28gc291cmNlIGFuZCB0YXJnZXQgYXJlIHRoZSBzYW1lXG4gICAgICAgICAgICBjb25zdCB1cGRhdGVQYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50SWQ6IHVwZGF0ZWRFdmVudC5pZCxcbiAgICAgICAgICAgICAgICBzb3VyY2VDb2x1bW5LZXk6IHN3cEV2ZW50LmNvbHVtbktleSxcbiAgICAgICAgICAgICAgICB0YXJnZXRDb2x1bW5LZXk6IHN3cEV2ZW50LmNvbHVtbktleVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXMuZW1pdChDb3JlRXZlbnRzLkVWRU5UX1VQREFURUQsIHVwZGF0ZVBheWxvYWQpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNldHVwTGlzdGVuZXJzKCk7XG4gICAgfVxuICAgIHNldHVwTGlzdGVuZXJzKCkge1xuICAgICAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19FTkQsIHRoaXMuaGFuZGxlRHJhZ0VuZCk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9SRVNJWkVfRU5ELCB0aGlzLmhhbmRsZVJlc2l6ZUVuZCk7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IENvbnRhaW5lciB9IGZyb20gJ0Bub3ZhZGkvY29yZSc7XG5pbXBvcnQgeyBEYXRlUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL2RhdGUvRGF0ZVJlbmRlcmVyJztcbmltcG9ydCB7IERhdGVTZXJ2aWNlIH0gZnJvbSAnLi9jb3JlL0RhdGVTZXJ2aWNlJztcbmltcG9ydCB7IFJlc291cmNlUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL3Jlc291cmNlL1Jlc291cmNlUmVuZGVyZXInO1xuaW1wb3J0IHsgVGVhbVJlbmRlcmVyIH0gZnJvbSAnLi9mZWF0dXJlcy90ZWFtL1RlYW1SZW5kZXJlcic7XG5pbXBvcnQgeyBEZXBhcnRtZW50UmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL2RlcGFydG1lbnQvRGVwYXJ0bWVudFJlbmRlcmVyJztcbmltcG9ydCB7IENhbGVuZGFyT3JjaGVzdHJhdG9yIH0gZnJvbSAnLi9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yJztcbmltcG9ydCB7IENhbGVuZGFyQXBwIH0gZnJvbSAnLi9jb3JlL0NhbGVuZGFyQXBwJztcbmltcG9ydCB7IFRpbWVBeGlzUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL3RpbWVheGlzL1RpbWVBeGlzUmVuZGVyZXInO1xuaW1wb3J0IHsgU2Nyb2xsTWFuYWdlciB9IGZyb20gJy4vY29yZS9TY3JvbGxNYW5hZ2VyJztcbmltcG9ydCB7IEhlYWRlckRyYXdlck1hbmFnZXIgfSBmcm9tICcuL2NvcmUvSGVhZGVyRHJhd2VyTWFuYWdlcic7XG5pbXBvcnQgeyBNb2NrVGVhbVN0b3JlLCBNb2NrUmVzb3VyY2VTdG9yZSB9IGZyb20gJy4vZGVtby9Nb2NrU3RvcmVzJztcbmltcG9ydCB7IERlbW9BcHAgfSBmcm9tICcuL2RlbW8vRGVtb0FwcCc7XG4vLyBFdmVudCBzeXN0ZW1cbmltcG9ydCB7IEV2ZW50QnVzIH0gZnJvbSAnLi9jb3JlL0V2ZW50QnVzJztcbi8vIFN0b3JhZ2VcbmltcG9ydCB7IEluZGV4ZWREQkNvbnRleHQgfSBmcm9tICcuL3N0b3JhZ2UvSW5kZXhlZERCQ29udGV4dCc7XG5pbXBvcnQgeyBFdmVudFN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL2V2ZW50cy9FdmVudFN0b3JlJztcbmltcG9ydCB7IEV2ZW50U2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9ldmVudHMvRXZlbnRTZXJ2aWNlJztcbmltcG9ydCB7IFJlc291cmNlU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2UvcmVzb3VyY2VzL1Jlc291cmNlU3RvcmUnO1xuaW1wb3J0IHsgUmVzb3VyY2VTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL3Jlc291cmNlcy9SZXNvdXJjZVNlcnZpY2UnO1xuaW1wb3J0IHsgQm9va2luZ1N0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL2Jvb2tpbmdzL0Jvb2tpbmdTdG9yZSc7XG5pbXBvcnQgeyBCb29raW5nU2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9ib29raW5ncy9Cb29raW5nU2VydmljZSc7XG5pbXBvcnQgeyBDdXN0b21lclN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL2N1c3RvbWVycy9DdXN0b21lclN0b3JlJztcbmltcG9ydCB7IEN1c3RvbWVyU2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9jdXN0b21lcnMvQ3VzdG9tZXJTZXJ2aWNlJztcbmltcG9ydCB7IFRlYW1TdG9yZSB9IGZyb20gJy4vc3RvcmFnZS90ZWFtcy9UZWFtU3RvcmUnO1xuaW1wb3J0IHsgVGVhbVNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2UvdGVhbXMvVGVhbVNlcnZpY2UnO1xuaW1wb3J0IHsgRGVwYXJ0bWVudFN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL2RlcGFydG1lbnRzL0RlcGFydG1lbnRTdG9yZSc7XG5pbXBvcnQgeyBEZXBhcnRtZW50U2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9kZXBhcnRtZW50cy9EZXBhcnRtZW50U2VydmljZSc7XG5pbXBvcnQgeyBTZXR0aW5nc1N0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL3NldHRpbmdzL1NldHRpbmdzU3RvcmUnO1xuaW1wb3J0IHsgU2V0dGluZ3NTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL3NldHRpbmdzL1NldHRpbmdzU2VydmljZSc7XG5pbXBvcnQgeyBWaWV3Q29uZmlnU3RvcmUgfSBmcm9tICcuL3N0b3JhZ2Uvdmlld2NvbmZpZ3MvVmlld0NvbmZpZ1N0b3JlJztcbmltcG9ydCB7IFZpZXdDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL3ZpZXdjb25maWdzL1ZpZXdDb25maWdTZXJ2aWNlJztcbi8vIEF1ZGl0XG5pbXBvcnQgeyBBdWRpdFN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL2F1ZGl0L0F1ZGl0U3RvcmUnO1xuaW1wb3J0IHsgQXVkaXRTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL2F1ZGl0L0F1ZGl0U2VydmljZSc7XG5pbXBvcnQgeyBNb2NrRXZlbnRSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja0V2ZW50UmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrUmVzb3VyY2VSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja1Jlc291cmNlUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrQm9va2luZ1JlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrQm9va2luZ1JlcG9zaXRvcnknO1xuaW1wb3J0IHsgTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSB9IGZyb20gJy4vcmVwb3NpdG9yaWVzL01vY2tDdXN0b21lclJlcG9zaXRvcnknO1xuaW1wb3J0IHsgTW9ja0F1ZGl0UmVwb3NpdG9yeSB9IGZyb20gJy4vcmVwb3NpdG9yaWVzL01vY2tBdWRpdFJlcG9zaXRvcnknO1xuaW1wb3J0IHsgTW9ja1RlYW1SZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja1RlYW1SZXBvc2l0b3J5JztcbmltcG9ydCB7IE1vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSB9IGZyb20gJy4vcmVwb3NpdG9yaWVzL01vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrU2V0dGluZ3NSZXBvc2l0b3J5IH0gZnJvbSAnLi9yZXBvc2l0b3JpZXMvTW9ja1NldHRpbmdzUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkgfSBmcm9tICcuL3JlcG9zaXRvcmllcy9Nb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnknO1xuLy8gV29ya2Vyc1xuaW1wb3J0IHsgRGF0YVNlZWRlciB9IGZyb20gJy4vd29ya2Vycy9EYXRhU2VlZGVyJztcbi8vIEZlYXR1cmVzXG5pbXBvcnQgeyBFdmVudFJlbmRlcmVyIH0gZnJvbSAnLi9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyJztcbmltcG9ydCB7IFNjaGVkdWxlUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL3NjaGVkdWxlL1NjaGVkdWxlUmVuZGVyZXInO1xuaW1wb3J0IHsgSGVhZGVyRHJhd2VyUmVuZGVyZXIgfSBmcm9tICcuL2ZlYXR1cmVzL2hlYWRlcmRyYXdlci9IZWFkZXJEcmF3ZXJSZW5kZXJlcic7XG4vLyBTY2hlZHVsZVxuaW1wb3J0IHsgU2NoZWR1bGVPdmVycmlkZVN0b3JlIH0gZnJvbSAnLi9zdG9yYWdlL3NjaGVkdWxlcy9TY2hlZHVsZU92ZXJyaWRlU3RvcmUnO1xuaW1wb3J0IHsgU2NoZWR1bGVPdmVycmlkZVNlcnZpY2UgfSBmcm9tICcuL3N0b3JhZ2Uvc2NoZWR1bGVzL1NjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlJztcbmltcG9ydCB7IFJlc291cmNlU2NoZWR1bGVTZXJ2aWNlIH0gZnJvbSAnLi9zdG9yYWdlL3NjaGVkdWxlcy9SZXNvdXJjZVNjaGVkdWxlU2VydmljZSc7XG4vLyBNYW5hZ2Vyc1xuaW1wb3J0IHsgRHJhZ0Ryb3BNYW5hZ2VyIH0gZnJvbSAnLi9tYW5hZ2Vycy9EcmFnRHJvcE1hbmFnZXInO1xuaW1wb3J0IHsgRWRnZVNjcm9sbE1hbmFnZXIgfSBmcm9tICcuL21hbmFnZXJzL0VkZ2VTY3JvbGxNYW5hZ2VyJztcbmltcG9ydCB7IFJlc2l6ZU1hbmFnZXIgfSBmcm9tICcuL21hbmFnZXJzL1Jlc2l6ZU1hbmFnZXInO1xuaW1wb3J0IHsgRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIgfSBmcm9tICcuL21hbmFnZXJzL0V2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyJztcbmNvbnN0IGRlZmF1bHRUaW1lRm9ybWF0Q29uZmlnID0ge1xuICAgIHRpbWV6b25lOiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmUsXG4gICAgdXNlMjRIb3VyRm9ybWF0OiB0cnVlLFxuICAgIGxvY2FsZTogJ2RhLURLJyxcbiAgICBkYXRlRm9ybWF0OiAnbG9jYWxlJyxcbiAgICBzaG93U2Vjb25kczogZmFsc2Vcbn07XG5jb25zdCBkZWZhdWx0R3JpZENvbmZpZyA9IHtcbiAgICBob3VySGVpZ2h0OiA2NCxcbiAgICBkYXlTdGFydEhvdXI6IDYsXG4gICAgZGF5RW5kSG91cjogMTgsXG4gICAgc25hcEludGVydmFsOiAxNSxcbiAgICBncmlkU3RhcnRUaHJlc2hvbGRNaW51dGVzOiAzMFxufTtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVWMkNvbnRhaW5lcigpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG4gICAgY29uc3QgYnVpbGRlciA9IGNvbnRhaW5lci5idWlsZGVyKCk7XG4gICAgLy8gQ29uZmlnXG4gICAgYnVpbGRlci5yZWdpc3Rlckluc3RhbmNlKGRlZmF1bHRUaW1lRm9ybWF0Q29uZmlnKS5hcyhcIklUaW1lRm9ybWF0Q29uZmlnXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJJbnN0YW5jZShkZWZhdWx0R3JpZENvbmZpZykuYXMoXCJJR3JpZENvbmZpZ1wiKTtcbiAgICAvLyBDb3JlIC0gRXZlbnRCdXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXMoXCJFdmVudEJ1c1wiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudEJ1cykuYXMoXCJJRXZlbnRCdXNcIik7XG4gICAgLy8gU2VydmljZXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEYXRlU2VydmljZSkuYXMoXCJEYXRlU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSVRpbWVGb3JtYXRDb25maWdcIiksXG4gICAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIFN0b3JhZ2UgaW5mcmFzdHJ1Y3R1cmVcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShJbmRleGVkREJDb250ZXh0KS5hcyhcIkluZGV4ZWREQkNvbnRleHRcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZUFsbChcIklTdG9yZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gU3RvcmVzIChmb3IgSW5kZXhlZERCIHNjaGVtYSBjcmVhdGlvbilcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShCb29raW5nU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEN1c3RvbWVyU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFRlYW1TdG9yZSkuYXMoXCJJU3RvcmVcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVwYXJ0bWVudFN0b3JlKS5hcyhcIklTdG9yZVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShTY2hlZHVsZU92ZXJyaWRlU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEF1ZGl0U3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNldHRpbmdzU3RvcmUpLmFzKFwiSVN0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFZpZXdDb25maWdTdG9yZSkuYXMoXCJJU3RvcmVcIik7XG4gICAgLy8gRW50aXR5IHNlcnZpY2VzIChmb3IgRGF0YVNlZWRlciBwb2x5bW9ycGhpYyBhcnJheSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEV2ZW50U2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRXZlbnRTZXJ2aWNlKS5hcyhcIkV2ZW50U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoUmVzb3VyY2VTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFJlc291cmNlU2VydmljZSkuYXMoXCJSZXNvdXJjZVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEJvb2tpbmdTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShCb29raW5nU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQm9va2luZ1NlcnZpY2UpLmFzKFwiQm9va2luZ1NlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEN1c3RvbWVyU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQ3VzdG9tZXJTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShDdXN0b21lclNlcnZpY2UpLmFzKFwiQ3VzdG9tZXJTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShUZWFtU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGVhbVNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFRlYW1TZXJ2aWNlKS5hcyhcIlRlYW1TZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEZXBhcnRtZW50U2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVwYXJ0bWVudFNlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKERlcGFydG1lbnRTZXJ2aWNlKS5hcyhcIkRlcGFydG1lbnRTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShTZXR0aW5nc1NlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNldHRpbmdzU2VydmljZSkuYXMoXCJJRW50aXR5U2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoU2V0dGluZ3NTZXJ2aWNlKS5hcyhcIlNldHRpbmdzU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVmlld0NvbmZpZ1NlcnZpY2UpLmFzKFwiSUVudGl0eVNlcnZpY2VcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkluZGV4ZWREQkNvbnRleHRcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFZpZXdDb25maWdTZXJ2aWNlKS5hcyhcIklFbnRpdHlTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShWaWV3Q29uZmlnU2VydmljZSkuYXMoXCJWaWV3Q29uZmlnU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSW5kZXhlZERCQ29udGV4dFwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gUmVwb3NpdG9yaWVzIChmb3IgRGF0YVNlZWRlciBwb2x5bW9ycGhpYyBhcnJheSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrRXZlbnRSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tFdmVudFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1Jlc291cmNlUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrUmVzb3VyY2VSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tCb29raW5nUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrQm9va2luZ1JlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja0N1c3RvbWVyUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrQ3VzdG9tZXJSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tBdWRpdFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja0F1ZGl0UmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVGVhbVJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1RlYW1SZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tEZXBhcnRtZW50UmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrRGVwYXJ0bWVudFJlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoTW9ja1NldHRpbmdzUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrU2V0dGluZ3NSZXBvc2l0b3J5KS5hcyhcIklBcGlSZXBvc2l0b3J5XCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tWaWV3Q29uZmlnUmVwb3NpdG9yeSkuYXMoXCJJQXBpUmVwb3NpdG9yeVwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVmlld0NvbmZpZ1JlcG9zaXRvcnkpLmFzKFwiSUFwaVJlcG9zaXRvcnlcIik7XG4gICAgLy8gQXVkaXQgc2VydmljZSAobGlzdGVucyB0byBFTlRJVFlfU0FWRUQvREVMRVRFRCBldmVudHMgYXV0b21hdGljYWxseSlcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShBdWRpdFNlcnZpY2UpLmFzKFwiQXVkaXRTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBXb3JrZXJzXG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGF0YVNlZWRlcikuYXMoXCJEYXRhU2VlZGVyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJRW50aXR5U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZUFsbChcIklBcGlSZXBvc2l0b3J5XCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBTY2hlZHVsZSBzZXJ2aWNlc1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlKS5hcyhcIlNjaGVkdWxlT3ZlcnJpZGVTZXJ2aWNlXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShSZXNvdXJjZVNjaGVkdWxlU2VydmljZSkuYXMoXCJSZXNvdXJjZVNjaGVkdWxlU2VydmljZVwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiUmVzb3VyY2VTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2NoZWR1bGVPdmVycmlkZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgLy8gRmVhdHVyZXNcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShFdmVudFJlbmRlcmVyKS5hcyhcIkV2ZW50UmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjaGVkdWxlUmVuZGVyZXIpLmFzKFwiU2NoZWR1bGVSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiUmVzb3VyY2VTY2hlZHVsZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklHcmlkQ29uZmlnXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShIZWFkZXJEcmF3ZXJSZW5kZXJlcikuYXMoXCJIZWFkZXJEcmF3ZXJSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJIZWFkZXJEcmF3ZXJNYW5hZ2VyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRXZlbnRTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIFJlbmRlcmVycyAtIHJlZ2lzdHJlcmVzIHNvbSBSZW5kZXJlciAoYXJyYXkgaW5qZWN0aW9uIHRpbCBDYWxlbmRhck9yY2hlc3RyYXRvcilcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShEYXRlUmVuZGVyZXIpLmFzKFwiSVJlbmRlcmVyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoUmVzb3VyY2VSZW5kZXJlcikuYXMoXCJJUmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIlJlc291cmNlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGVhbVJlbmRlcmVyKS5hcyhcIklSZW5kZXJlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVGVhbVNlcnZpY2VcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKERlcGFydG1lbnRSZW5kZXJlcikuYXMoXCJJUmVuZGVyZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRlcGFydG1lbnRTZXJ2aWNlXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBTdG9yZXMgLSByZWdpc3RyZXJlcyBzb20gSUdyb3VwaW5nU3RvcmVcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShNb2NrVGVhbVN0b3JlKS5hcyhcIklHcm91cGluZ1N0b3JlXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKE1vY2tSZXNvdXJjZVN0b3JlKS5hcyhcIklHcm91cGluZ1N0b3JlXCIpO1xuICAgIC8vIENhbGVuZGFyT3JjaGVzdHJhdG9yIG1vZHRhZ2VyIElHcm91cGluZ1N0b3JlW10gYXV0b21hdGlzayAoYXJyYXkgaW5qZWN0aW9uKVxuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKENhbGVuZGFyT3JjaGVzdHJhdG9yKS5hcyhcIkNhbGVuZGFyT3JjaGVzdHJhdG9yXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJUmVuZGVyZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJFdmVudFJlbmRlcmVyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2NoZWR1bGVSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkhlYWRlckRyYXdlclJlbmRlcmVyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGVBbGwoXCJJRW50aXR5U2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoVGltZUF4aXNSZW5kZXJlcikuYXMoXCJUaW1lQXhpc1JlbmRlcmVyXCIpO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFNjcm9sbE1hbmFnZXIpLmFzKFwiU2Nyb2xsTWFuYWdlclwiKTtcbiAgICBidWlsZGVyLnJlZ2lzdGVyVHlwZShIZWFkZXJEcmF3ZXJNYW5hZ2VyKS5hcyhcIkhlYWRlckRyYXdlck1hbmFnZXJcIik7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRHJhZ0Ryb3BNYW5hZ2VyKS5hcyhcIkRyYWdEcm9wTWFuYWdlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKEVkZ2VTY3JvbGxNYW5hZ2VyKS5hcyhcIkVkZ2VTY3JvbGxNYW5hZ2VyXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIGJ1aWxkZXIucmVnaXN0ZXJUeXBlKFJlc2l6ZU1hbmFnZXIpLmFzKFwiUmVzaXplTWFuYWdlclwiKS5hdXRvV2lyZSh7XG4gICAgICAgIG1hcFJlc29sdmVyczogW1xuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUV2ZW50QnVzXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiSUdyaWRDb25maWdcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEYXRlU2VydmljZVwiKVxuICAgICAgICBdXG4gICAgfSk7XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXIpLmFzKFwiRXZlbnRQZXJzaXN0ZW5jZU1hbmFnZXJcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIklFdmVudEJ1c1wiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpXG4gICAgICAgIF1cbiAgICB9KTtcbiAgICAvLyBDYWxlbmRhckFwcCAtIGdlbmJydWdlbGlnIGthbGVuZGVya29tcG9uZW50XG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoQ2FsZW5kYXJBcHApLmFzKFwiQ2FsZW5kYXJBcHBcIikuYXV0b1dpcmUoe1xuICAgICAgICBtYXBSZXNvbHZlcnM6IFtcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkNhbGVuZGFyT3JjaGVzdHJhdG9yXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVGltZUF4aXNSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkRhdGVTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2Nyb2xsTWFuYWdlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkhlYWRlckRyYXdlck1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJEcmFnRHJvcE1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJFZGdlU2Nyb2xsTWFuYWdlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIlJlc2l6ZU1hbmFnZXJcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJIZWFkZXJEcmF3ZXJSZW5kZXJlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkV2ZW50UGVyc2lzdGVuY2VNYW5hZ2VyXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiU2V0dGluZ3NTZXJ2aWNlXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiVmlld0NvbmZpZ1NlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIC8vIERlbW8gYXBwXG4gICAgYnVpbGRlci5yZWdpc3RlclR5cGUoRGVtb0FwcCkuYXMoXCJEZW1vQXBwXCIpLmF1dG9XaXJlKHtcbiAgICAgICAgbWFwUmVzb2x2ZXJzOiBbXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJbmRleGVkREJDb250ZXh0XCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0YVNlZWRlclwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkF1ZGl0U2VydmljZVwiKSxcbiAgICAgICAgICAgIGMgPT4gYy5yZXNvbHZlVHlwZShcIkNhbGVuZGFyQXBwXCIpLFxuICAgICAgICAgICAgYyA9PiBjLnJlc29sdmVUeXBlKFwiRGF0ZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJSZXNvdXJjZVNlcnZpY2VcIiksXG4gICAgICAgICAgICBjID0+IGMucmVzb2x2ZVR5cGUoXCJJRXZlbnRCdXNcIilcbiAgICAgICAgXVxuICAgIH0pO1xuICAgIHJldHVybiBidWlsZGVyLmJ1aWxkKCk7XG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlVjJDb250YWluZXIgfSBmcm9tICcuLi9WMkNvbXBvc2l0aW9uUm9vdCc7XG5jb25zdCBjb250YWluZXIgPSBjcmVhdGVWMkNvbnRhaW5lcigpO1xuY29udGFpbmVyLnJlc29sdmVUeXBlKFwiRGVtb0FwcFwiKS5pbml0KCkuY2F0Y2goY29uc29sZS5lcnJvcik7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBLEtBQUMsU0FBUyxHQUFFLEdBQUU7QUFBQyxrQkFBVSxPQUFPLFdBQVMsZUFBYSxPQUFPLFNBQU8sT0FBTyxVQUFRLEVBQUUsSUFBRSxjQUFZLE9BQU8sVUFBUSxPQUFPLE1BQUksT0FBTyxDQUFDLEtBQUcsSUFBRSxlQUFhLE9BQU8sYUFBVyxhQUFXLEtBQUcsTUFBTSxRQUFNLEVBQUU7QUFBQSxJQUFDLEVBQUUsU0FBTSxXQUFVO0FBQUM7QUFBYSxVQUFJLElBQUUsS0FBSSxJQUFFLEtBQUksSUFB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V0FBVztBQUFBLElBQ2xDO0FBQUEsRUFDSixDQUFDO0FBRUQsVUFBUSxhQUFhLE9BQU8sRUFBRSxHQUFHLFNBQVMsRUFBRSxTQUFTO0FBQUEsSUFDakQsY0FBYztBQUFBLE1BQ1YsT0FBSyxFQUFFLFlBQVksa0JBQWtCO0FBQUEsTUFDckMsT0FBSyxFQUFFLFlBQVksWUFBWTtBQUFBLE1BQy9CLE9BQUssRUFBRSxZQUFZLGNBQWM7QUFBQSxNQUNqQyxPQUFLLEVBQUUsWUFBWSxhQUFhO0FBQUEsTUFDaEMsT0FBSyxFQUFFLFlBQVksYUFBYTtBQUFBLE1BQ2hDLE9BQUssRUFBRSxZQUFZLGlCQUFpQjtBQUFBLE1BQ3BDLE9BQUssRUFBRSxZQUFZLFdBQVc7QUFBQSxJQUNsQztBQUFBLEVBQ0osQ0FBQztBQUNELFNBQU8sUUFBUSxNQUFNO0FBQ3pCO0FBdlZnQjs7O0FDekVoQixJQUFNLFlBQVksa0JBQWtCO0FBQ3BDLFVBQVUsWUFBWSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sUUFBUSxLQUFLOyIsCiAgIm5hbWVzIjogWyJ0IiwgImUiLCAibiIsICJyIiwgImkiLCAicyIsICJ1IiwgImEiLCAiTSIsICJtIiwgImYiLCAibCIsICIkIiwgInkiLCAidiIsICJnIiwgIkQiLCAibyIsICJkIiwgImMiLCAiaCIsICJ0IiwgImkiLCAiZSIsICJzIiwgImYiLCAibiIsICJ1IiwgInIiLCAibyIsICJ0IiwgIm4iLCAiaSIsICJvIiwgInIiLCAiZSIsICJ1IiwgImYiLCAicyIsICJhIiwgInQiLCAiaSIsICJkIiwgIm4iLCAiZSIsICJzIiwgInRva2VuIiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAidG9rZW4iLCAiY29udGFpbmVyIiwgImRheWpzIiwgInV0YyIsICJ0aW1lem9uZSIsICJpc29XZWVrIiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImdldEtleSIsICJza2lwUGF0aCIsICJrZXkiLCAiY29udGFpbmVyIiwgImNvbnRhaW5lciIsICJjb250YWluZXIiLCAiZGlmZiIsICJjb250YWluZXIiLCAiY29udGFpbmVyIiwgImRpZmYiLCAiY29udGFpbmVyIl0KfQo= diff --git a/wwwroot/js/workers/SyncManager.d.ts b/wwwroot/js/workers/SyncManager.d.ts new file mode 100644 index 0000000..dfc7f40 --- /dev/null +++ b/wwwroot/js/workers/SyncManager.d.ts @@ -0,0 +1,78 @@ +import { IEventBus } from '../types/CalendarTypes'; +import { OperationQueue } from '../storage/OperationQueue'; +import { IndexedDBService } from '../storage/IndexedDBService'; +import { ApiEventRepository } from '../repositories/ApiEventRepository'; +/** + * SyncManager - Background sync worker + * Processes operation queue and syncs with API when online + * + * Features: + * - Monitors online/offline status + * - Processes queue with FIFO order + * - Exponential backoff retry logic + * - Updates syncStatus in IndexedDB after successful sync + * - Emits sync events for UI feedback + */ +export declare class SyncManager { + private eventBus; + private queue; + private indexedDB; + private apiRepository; + private isOnline; + private isSyncing; + private syncInterval; + private maxRetries; + private intervalId; + constructor(eventBus: IEventBus, queue: OperationQueue, indexedDB: IndexedDBService, apiRepository: ApiEventRepository); + /** + * Setup online/offline event listeners + */ + private setupNetworkListeners; + /** + * Start background sync worker + */ + startSync(): void; + /** + * Stop background sync worker + */ + stopSync(): void; + /** + * Process operation queue + * Sends pending operations to API + */ + private processQueue; + /** + * Process a single operation + */ + private processOperation; + /** + * Mark event as synced in IndexedDB + */ + private markEventAsSynced; + /** + * Mark event as error in IndexedDB + */ + private markEventAsError; + /** + * Calculate exponential backoff delay + * @param retryCount Current retry count + * @returns Delay in milliseconds + */ + private calculateBackoff; + /** + * Manually trigger sync (for testing or manual sync button) + */ + triggerManualSync(): Promise; + /** + * Get current sync status + */ + getSyncStatus(): { + isOnline: boolean; + isSyncing: boolean; + isRunning: boolean; + }; + /** + * Cleanup - stop sync and remove listeners + */ + destroy(): void; +} diff --git a/wwwroot/js/workers/SyncManager.js b/wwwroot/js/workers/SyncManager.js new file mode 100644 index 0000000..4e67e87 --- /dev/null +++ b/wwwroot/js/workers/SyncManager.js @@ -0,0 +1,229 @@ +import { CoreEvents } from '../constants/CoreEvents'; +/** + * SyncManager - Background sync worker + * Processes operation queue and syncs with API when online + * + * Features: + * - Monitors online/offline status + * - Processes queue with FIFO order + * - Exponential backoff retry logic + * - Updates syncStatus in IndexedDB after successful sync + * - Emits sync events for UI feedback + */ +export class SyncManager { + constructor(eventBus, queue, indexedDB, apiRepository) { + this.isOnline = navigator.onLine; + this.isSyncing = false; + this.syncInterval = 5000; // 5 seconds + this.maxRetries = 5; + this.intervalId = null; + this.eventBus = eventBus; + this.queue = queue; + this.indexedDB = indexedDB; + this.apiRepository = apiRepository; + this.setupNetworkListeners(); + this.startSync(); + console.log('SyncManager initialized and started'); + } + /** + * Setup online/offline event listeners + */ + setupNetworkListeners() { + window.addEventListener('online', () => { + this.isOnline = true; + this.eventBus.emit(CoreEvents.OFFLINE_MODE_CHANGED, { + isOnline: true + }); + console.log('SyncManager: Network online - starting sync'); + this.startSync(); + }); + window.addEventListener('offline', () => { + this.isOnline = false; + this.eventBus.emit(CoreEvents.OFFLINE_MODE_CHANGED, { + isOnline: false + }); + console.log('SyncManager: Network offline - pausing sync'); + this.stopSync(); + }); + } + /** + * Start background sync worker + */ + startSync() { + if (this.intervalId) { + return; // Already running + } + console.log('SyncManager: Starting background sync'); + // Process immediately + this.processQueue(); + // Then poll every syncInterval + this.intervalId = window.setInterval(() => { + this.processQueue(); + }, this.syncInterval); + } + /** + * Stop background sync worker + */ + stopSync() { + if (this.intervalId) { + window.clearInterval(this.intervalId); + this.intervalId = null; + console.log('SyncManager: Stopped background sync'); + } + } + /** + * Process operation queue + * Sends pending operations to API + */ + async processQueue() { + // Don't sync if offline + if (!this.isOnline) { + return; + } + // Don't start new sync if already syncing + if (this.isSyncing) { + return; + } + // Check if queue is empty + if (await this.queue.isEmpty()) { + return; + } + this.isSyncing = true; + try { + const operations = await this.queue.getAll(); + this.eventBus.emit(CoreEvents.SYNC_STARTED, { + operationCount: operations.length + }); + // Process operations one by one (FIFO) + for (const operation of operations) { + await this.processOperation(operation); + } + this.eventBus.emit(CoreEvents.SYNC_COMPLETED, { + operationCount: operations.length + }); + } + catch (error) { + console.error('SyncManager: Queue processing error:', error); + this.eventBus.emit(CoreEvents.SYNC_FAILED, { + error: error instanceof Error ? error.message : 'Unknown error' + }); + } + finally { + this.isSyncing = false; + } + } + /** + * Process a single operation + */ + async processOperation(operation) { + // Check if max retries exceeded + if (operation.retryCount >= this.maxRetries) { + console.error(`SyncManager: Max retries exceeded for operation ${operation.id}`, operation); + await this.queue.remove(operation.id); + await this.markEventAsError(operation.eventId); + return; + } + try { + // Send to API based on operation type + switch (operation.type) { + case 'create': + await this.apiRepository.sendCreate(operation.data); + break; + case 'update': + await this.apiRepository.sendUpdate(operation.eventId, operation.data); + break; + case 'delete': + await this.apiRepository.sendDelete(operation.eventId); + break; + default: + console.error(`SyncManager: Unknown operation type ${operation.type}`); + await this.queue.remove(operation.id); + return; + } + // Success - remove from queue and mark as synced + await this.queue.remove(operation.id); + await this.markEventAsSynced(operation.eventId); + console.log(`SyncManager: Successfully synced operation ${operation.id}`); + } + catch (error) { + console.error(`SyncManager: Failed to sync operation ${operation.id}:`, error); + // Increment retry count + await this.queue.incrementRetryCount(operation.id); + // Calculate backoff delay + const backoffDelay = this.calculateBackoff(operation.retryCount + 1); + this.eventBus.emit(CoreEvents.SYNC_RETRY, { + operationId: operation.id, + retryCount: operation.retryCount + 1, + nextRetryIn: backoffDelay + }); + } + } + /** + * Mark event as synced in IndexedDB + */ + async markEventAsSynced(eventId) { + try { + const event = await this.indexedDB.getEvent(eventId); + if (event) { + event.syncStatus = 'synced'; + await this.indexedDB.saveEvent(event); + } + } + catch (error) { + console.error(`SyncManager: Failed to mark event ${eventId} as synced:`, error); + } + } + /** + * Mark event as error in IndexedDB + */ + async markEventAsError(eventId) { + try { + const event = await this.indexedDB.getEvent(eventId); + if (event) { + event.syncStatus = 'error'; + await this.indexedDB.saveEvent(event); + } + } + catch (error) { + console.error(`SyncManager: Failed to mark event ${eventId} as error:`, error); + } + } + /** + * Calculate exponential backoff delay + * @param retryCount Current retry count + * @returns Delay in milliseconds + */ + calculateBackoff(retryCount) { + // Exponential backoff: 2^retryCount * 1000ms + // Retry 1: 2s, Retry 2: 4s, Retry 3: 8s, Retry 4: 16s, Retry 5: 32s + const baseDelay = 1000; + const exponentialDelay = Math.pow(2, retryCount) * baseDelay; + const maxDelay = 60000; // Max 1 minute + return Math.min(exponentialDelay, maxDelay); + } + /** + * Manually trigger sync (for testing or manual sync button) + */ + async triggerManualSync() { + console.log('SyncManager: Manual sync triggered'); + await this.processQueue(); + } + /** + * Get current sync status + */ + getSyncStatus() { + return { + isOnline: this.isOnline, + isSyncing: this.isSyncing, + isRunning: this.intervalId !== null + }; + } + /** + * Cleanup - stop sync and remove listeners + */ + destroy() { + this.stopSync(); + // Note: We don't remove window event listeners as they're global + } +} +//# sourceMappingURL=SyncManager.js.map \ No newline at end of file diff --git a/wwwroot/js/workers/SyncManager.js.map b/wwwroot/js/workers/SyncManager.js.map new file mode 100644 index 0000000..3bdd938 --- /dev/null +++ b/wwwroot/js/workers/SyncManager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"SyncManager.js","sourceRoot":"","sources":["../../../src/workers/SyncManager.ts"],"names":[],"mappings":"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"} \ No newline at end of file
  • 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 diff --git a/app/wwwroot/fonts/Poppins-Thin.woff b/app/wwwroot/fonts/Poppins-Thin.woff deleted file mode 100644 index d21fbd390b7a41a04b87dced622dd81712c78f99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62572 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

    Dh6*vDu5_sTuCjR@cqW$%hjY)AYf1c1|i51;=TY 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 V&$H+$_#YeQF-!me00961001|7vu6MR diff --git a/app/wwwroot/fonts/Poppins-Light.woff b/app/wwwroot/fonts/Poppins-Light.woff deleted file mode 100644 index 61f6a5cba6be466b39019a62feba066080a53910..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66392 zcmZsCV{|4>7wr?=vN5m+0HB5d01#6E0CXViB;Lu)!0CrOcK-4Ce|ZtjtUZ3l(Ubvz9#H^LKc@3A zX|}nEf$>i~^&daB|A1m{0B-(6{%~DApd^i0G2;ge`*E*Rs?ILKkq)Lpb0?n zeoP1e@P8}-;0|P@Z>+B$|JE8t6cYJ*U7B01eJ6l~+D8lvh`RvW{Vy&k3Lq5#3kdz0 z4WJ(#J^<`T_;cp~Pyo<>dINalB?EmEef=}T2z`D1n?G|=4zOZTSFi$o0{{@X3)tU% z%tO<;`v8zZJ2Lcgzer3)^}F;4G)zpgpucHJX-@!3FmQCh1q)2uPd&{kKF+BoSfjnq zpFBpe$>G3sY;4AaGJW;UasEyt{^5P#AT9aCEU=J+gSR0}Tn9LR`T}% z42XCClzeRVckPFA^7WW z8SYzN-|!hwJzH|<=dLRD0r%AdnaZbp!*26WW?eut<^|j#yO2hoaqgs76;#iVvNjp? zS9!?0?XTVgFI`fSsOw*6dC;GTGI`pv?F+N2@#n=f{K|Sag~``u6{Wp8>~FQg7%um2 zmUX>S!w!GQ+LbEo@stmJ%QHCiOnl>OPIzt|BGR&n{ZXhLV%HW!h* zX#dtx{be}WJ*w0As!k)eA3lljh$rVL2~6<_q}Dnn zH|%mH2azK?OEf*)e_@>RK2R9im0KcL+skgl;e%>4|HjQRMeIde6ZU|(0?rOYI3RuD z%+V3sN`FC4ZmLw0=ptA_)|1+_EDK!qZ+8p(#~syk6rfYbT}Q&eceB`MmuAPh1td<% zy@hmqQ^Oc1@j>Q`>xZRF(gV>8F9novcMH0P(79)`2I{u)4mjZNGgy;&MgLXhBA7>S zMFEa93-&~_18lTUNK;}9@I^T3F9zJ=^B{@|K_AK4gKfdPvbFR{E%`;|`m+xC^-~)F zZ)I>G(GM!+lRaqp=LYK7qg0*fxD6%`5%ixARndBQ)=gVc-=+e(E>Ay(-f!K#33!Gy zv8cJM5N8W^DK@zev~I1{v7XBLyQDs?ZtyS#eZ*CUAoTIfUU9kz3PSD04nVBEEY1N3 zIOgY~+Lkb2w~FJ1kv*>k+>pFMTWr zi#$ZOP%fu{BcRQmDUiJ`pj)J~-9O7o%nrh9z2w%~6X$8-AYUjhAp6Mwz%-f&`ksZo z4l-}m^r2aV*wqJ}RI{z-@Xie(U4u?Ewz=i?~_g(G0bKsQpQ5|z5xIq?e;_sc-p*;-{ zpS|7AoQF@I?h=2_~+PqXv_L8!=YMnY_eA){UDU?$!X`vonKI@45n&$;L&v6YE9z1(;Szdn@_ZL`2YED7K4w3hX~Ni}bEk0; zW*uu)E72=f>=m+@r;g&+n*Lr@V%m^ocx9Aw*ua?B1j&6qcXF85Cr~z*? z%&B+piLN!^%HTMF*P3!aIprq6ho7CF^@(oJ9%W7v+f>i3UZPMd|9FyoR6Epsy5k&? zGUU%ytAAHtZR1P0I%#&XKQN!Q!444K!M*)EVtFi4n)N5 z9C+t`eQy~9n2mx);?Z5w!mIA%eXb*clgE?S*#!diYPU#M74dt?#`fc= zONd?>9ak!c@h)_4hTSm{T+n_Gf{)iJ)vlV3PLae$8U98^&qgKir@Gpv+wxg;Ok3|Z z7;m}sKU>%GGx+o`=*Lg;wed2wpFKKyUQ1p@1sDA0`;AX1)gM-E-+$AEO)x46Bz=t$ zg<7FYOKzIw@C8u@A)5118U1kSuhh?_rbdb@Bh?~ZiG@5#pgm|~=eSF*PmEil00(jE zVh+lp6umd|H|x2V#=X`(29m6F55;X@p1g7wxqffhMI3Dc#X4~Uv6$r&YH}&Ga(YH> z#nP_|&E>MyCCoedP!w}f3>+4h1lf5DE+vd}MP4-s=VIL&wR0EG?wS?3GnqHabJEHk z?7BZP5#ua;Mp&Du>57egG>pxrxtx|~pIE+|dVh0`24$O+E}gk2pVm`!4As_gF3tw@ z4K^VS8RMZ+^;|10CKQJ&w856Bnss@v+Qs4z+cS7qv1W@OXt^{>&tS8Q&CZ#4<>;3t zA0%fV>vr-8B0F2uT~vEr21znu6OHbo!#jadYJPn?6?@cdeQU>#=u9}3ujx+>FSlp(eKxMAk!+o~2c&D3OvKE|4#Z{yFHy#EvWx>qeJJa4!hR=ewSYe*5zzvLfa< z7+<&eUa)z<);_u|*4oc|fp7o(B(epK)XK7iWQhPK94(vcv>eW1K>qiEBYVc;B(HID zeO<@5MIw?S-8<*Tw9q=k97nY49j1YGr$zQIWc*meLyS$Tp=i=sB3W948cmUs^)Aa; zqGc)$cN{JEZ#ZqrR6^iOOKvKOM7(!8CH*Az9aZh`f({~L%>toU_N4LPwLh0@0jsy* zJ43QvA+7Z=*Lyk_BlumR&$mE)L%QC}9&+6AcuJ<3#8f@=MbgR$0=g0-x z83fZF^U~-S)t-8P0Z_LGOKA+7Xb&fAPqR8hX^#^A!P-|&QD7Lbk{*(YVGM2bNc_uT z6y^y1&N+6@GmI3)q!H}q1h&ZF?*QMJQ;6G#spJm-DQ$*scgSXI2En~96{>S_dykFgw?N%3@xjw{3)l!!%C~L$m z*YHY!5lrm+-`hEW?0?M_5D4f6Oag%dDFGD#LjoHDFM@!AAc7ErFo5uY{0316u>gq& zX$9E;1qLMn)c~ykLjt1!lL6BJGXV<(ivha;7YDZouLOUBpn~v(D1_i+zTtwVOJV!!6VnVV<@l8O z7h4l&5f>4c7cUpT{w@65_xGp-vIM?_nM935hs1~^lVr9Ol$5d5rqqeFvUG~{t_+7v zpv=51yKJcJzMP<3vD~M;nf$T>g94AjZv|xqeFbX;cZFbuI7MK^C?!axG-X(2f8{q7 z5*2%uAyr&e6V)*_5H%6Cc6D@h9rYm%I1Me0UX4jjT+L)HFfBi=Gi`b8ZXF;UDV;i< zTU`ZR1KnmlBt0TMOTBu%H+?hxa|1PlenSRBenTn4JR^J~XQMUaU&isq2PPUOL#7I* zM`nCx`R1tRu@a`z}H*u`XM#%&x+&g|6RjFmBFn6Yj$9O71NlY##ZZ7@kg^ zexA=>R$gviL0%u;+1}+oxIT%#2)?eq&wk;4$^KyeHvXFdd;t}K41xK9=RpEN*+Jz& z&A~Xqr6DLGE+OB4O#gg_DuNni{)=;u+lUv7&rU#3h)DQIG)f#w5=&Z77E9hq5liV#B~0~BeMnPH>rIzS z*GlhBAJ3r92+p|5RLShf;>pU+D$gd$F3i5nG017i#mKeJJTI8~%x^iu3rJY0fZVpg(NN>-Xv240p>_OD#LJf-}+Lc3zH62CI7@}kPH zYN(p1+O7JqMy{r=mZ~uno;n@pQ`TV>luJ5)PIyIFfmdsF*p`%{N_M@q-Pj>k^qPKHj!PP0yz zPM^-i&ce=_&h0LsF0L-suJEqDuBC3mZuM^CZu@Tk?xgOb?#&*-9<83Zo}Qllp4VQ4 zUXfm%Ud!G;y?MR0y;HpheJFiQeU^RkeG7em`+@t>`&s(s`_1~j`(ygE`)m69`ltIh z1`r3t2Al^f2KEQO2E_&~2LB9J4Gs;?4}lGl4XF)94-F1&3}X*-3~LNq4TldG4z~?Y zkD!eZjp&a={Iuke;gRoA-cjRGx6zf+_c6t>z_HA+im`@qpmF$dwsE;}xAEHXuJOI` z*9n9PstL{slL_C6@`-~<)=BdE%W;mP^Q?a9;0$0?vGxGAhD z(J6%~ohgecm#KiM=&91FyQ!~f=xOw6;%T~R`RRn|oau_`mg#}%ndyxg-WiD*l^KH> zn;DOp;F;K&jG5w@iFJ#<||P$$8{??0JoOlX?4j@ALuYNxh1V7 z|E0R6uBEZ1rKP>4i=~%k&}GDB#pSx?uI16?_Z6ZQ+7*r!krlZWtrfEsrxo9oh?Sm| ziIvw?uvMg0yj6--mQ{gO=~eYr<5l}r@71u?q}9CDs@2xj!PVK-jn(7TyVb8Xs5RC# z!8Mt+thKXsn01bIfpz(HgLRAbfc4b%?)8lg;0?45nhlN(kq!9`?G5t{=MDdjsExFZ zqK&$Z&W*8+<&A@l>y774kWJ)GyiN8^%}x7F|IMq-uPyj3{4Im6n637${;kt(qHUG! znC;T-p6#ve)9u^s*B!(ijUDfuu$_vX{+-pGi(TAZid~*v`CaW@+uhLJ#@(LX(cSso zuRZWR+&!i}^*!&sD0iUlZU}en;YW6Fvn%v=t?uWB3Tm6$je=!#3$^ZN+xCfWjEH)f z`u?RkFIIga;9!4Y|6p`$uKZ`@J^}w=`Ks=>>Sk2$G`DJ5MW72V0a_7c`irBP?fqu*|{nb;v;yJvIptyXF zH)BZdQ+iOdx%#@9Y5IivHxSVBtf-=`eRdST&Y0P_nYb0vF>rp3&rD1%mKh!>OIC|z zlTW4`nV4D4Aza9*}EHpodD9UiE}J5Lgw2bCM?tQh!sSQQu2Q9%a=R%~gv z({|68Td-Jl$W&Wdr!2kr4ahZriOs?PeOp1Rpi8W-Ur8y7_yd+^c9`|IQh%E~8Xp(aSy%w?Fb`U%L=5V-f%?mctDg#2IT2 z^A;rQRSN;uaAQWS)Mc8tX_Ld4~kH`C6kQN=EKrg@6gZ0_O7nax1J?h7!h8riA1rhB4QgYImq(Ur^) zMSq=jDU~S=gO4o{a|Hz(@H%*md=p&K$F z6IIx9jvUg?PY)X}Zq&dLFr`^*TB|bon%mLbwA}8nJXf`+^Y*N)_3;I6TR+_%hJCF0 zXQ|o!*;T!VUG4gOCunX=i{uOPiQFI(Sx+h%#IC5^XIk)NO(hfj7srr0s25{exK|FN zS^AUr^ciBIHfaL*TJd&kcOK`|Z~w%BTStNvboUv=V%GGXsFz=G*hoUY50+n)R++_= zi^*%7XwG2_I@WUDvX58rdHz~H{NMG#!Og#ebyAgmR;YDqmQnr3ZEBltjJFw2NL(&s zUT4TI2awMg&niyG@=DrP6Sy;|N4F?G9>B-KQI|#0C)LZAC*O zB`Q=()3VVX_B|y(YsNVA{r#kIfJD#^%UD@CHJPlUX_IDdjtp@iaW8Kj3DJ(a5fuvM z1nQZgNx7mCD_t6Ww6%GyoB8zpK5%8fYNG(LTE%@DpG17omb@j3_=puQYYP~RH7k7e zJe-t(Uv=#uS?VTNHzz0QdV_aF@tj{)2cCj@C3keHRz)(rYW~dmVBh!5nikg;^zKWib&CsvWZMxF-JN;{23fk7lOD8_D_tQupeO0;qCP; zi-pwBYtpYwLCfXJ9n~3u-t%2ico-GX80gcpv}cx4w5GJ;Fx=O5q7g?l$iGL?i&Jbc zreRu2gOnqD?zfvVs6_9bDN7PBIO;=^jC(h9%iL5Zsx3MOTyd)D9??=e8k;PJdlXwn zG3IjF3wmK6(!d(#-NrPL<5AbKNmcr1e0az%XpSx;$2y{|f!DEbG3=qc`CcH2A;?Bt zR5IS3H~5@9HI*YO8^^Q?Dre|o&)qb^UEYWyE4g#xBOE^ld$w?M1$C7c)WBkWt6Q*A zIJc;s6`R{y6?C-9ET|0dJ>^W8tL)Wc&S)#>T)Ox`NNIa8sY%2r=`M>nwBUT?JycaF^`QbK| z+LUXwRQ4A+U6hKFr$ufxL)!@Z_*Gj7AjA^SOvUuLY8in>-E?F&Z-{m394@JFsAP+M ztc3gZZ_aDMP|_ZQK2N*R+!^z<5>x+EmA|MRpS^injm5UaJ4;xht^8BDis_H$-0bds z88dJeKcCSp&AXM5hKU#b_3Md%LOwNlsaeg9dINUFvvZ=RvZ_MJ7W`h!5cU1HGI9Ks zTv!E74@n(G9I84p)VKOr`c0{DOVT{_qQ63^H+I#S@+umf`;v^~H^C{UDzIJo5KITg|^20me)y!R1Dij zQ%v^*^s$j?lnarcAAy zfAJTWC;KGF%YDbwa^>cA+n}P7QTw3*E&escDO%YmkEFy~()5|&LVTj7U@eES&+x{& z;v%|+ZQ81)O>J2%S&T7A_xDTqdsJ0rxLyw^Dw|r9I+N|EgqjKE@@5$SxN}fFgt}eg zjoIK5;upGb3bGLRI-H4LkkSizC;_eP(|b^U^lB zQfkFkPw`6YwuX1?pq$rM}wjIZoaZxrnlC`3Y^Ncmb6#X21LDV`F>*AH^-EU zHFngIiwxUoTK#xx&?8#qMD}L)j?K&+8rsz7P0;4@wwQ3L=C%ogYi0b(?@OyJ6`ZPn zqBE>)r$E&yuSTJY>jrafRLR+%(0d+RK_`r8tff#4HBC?8zY&dYp# zPMD*@=A@h&B5ite(qHu z5iM1%^vo=4No+Q^17X9F)jP7W`8o>io%K#?uXNQL5p$T2x%ZoS-jq^NXIhAChG7j>F&uf)-%3@#Ea zz(O|M`Ijc#vQ~}fMOPr+(X#0x7CJ_uyHaLD!{_I7s@Udg@)`zJOZmODs@KKMmtUZ9 z=$f8VL^{F_pUhVA2cmC|OeGi2dO%y|1M(Shm&SZTIT-)z<@fq+KHKxkQM;7PN*Y~| zkI41Tv5oP>KI`5@5aL72%A+X<>J$q7*hEvI?5^Y^di9fT%Bm_!dn{6|WB_YaSrCg> zXnKyJ$}g3h!=RNV8<+0Q%49A(x#m_lssM#zI=kDmW_-KWQ67DF{8|fiH?zWGF=z}{ zu5F#_ng@~g;Tj4zi>eIA%9dSVHgJ|g#8^XHecVH#W+W{+N$&RcVi<(=9mz?BCJVT1 zD%4&Om#@#JOo@teMh#1=DtGs9?CW?d94SdH=MnT*5Y6v%-NN}3*361A?px1}v*UGu5^%g`#Q%cDs(y8u7VnUD7T`VOpTZN-AM&VB0Yr^=dqT{Zup+?y)Z>5kgN zZVEQ$7cvR$*u|yV#ivZC1j9rfJke!RPrVk_o^ggI??{S~Z{+)k+7XRdcDpwd_*rP3 zV9AA1+npv_lPN}d?J5qdPj<~qcDx{7*@%&kZvSd6a25YY4RdkI1mFfqN%hP;kOcLY z0YRw)rdXruZLZ@oY?(VhKtVGhGgn93^c{vwX^Y@=7x`et$DavP?Mv5MMwK%D#r<~H(+EYAHzn?88aE+B=` zlSyaD-D6~y&upu^ZjNhv4b-e#QNS22uyogt%Pw%-T}K;fX-UJZ+eRQdgo&Jn%N5l< zlCs#&;0a=|8{MX%)$?cL<3-5#JJ}9nPs(OWI^X7p6i$pfz6a%{Y2hZGPu-^ONzWUJ znwJuA9w?=1y?gBOyb57RMAw1=r+Ym&sX;ACk8quId8y8D4CMdX4()1ib=j>iM!g2? zmeAC4@CeQ??<|{Xg?a7!|EY?G#y2AI3&MFK-02s9c)_CWhY<{k()QM`OUq9F_L`lm zXrVKOWy@*zg?-RIu&u5P)BY)PvQLkDL(QVOa>b?}y*Z{QJ#r&(4G}M=e>4kwyQ8N< zqj7+np2$>J$t*c2xPc32T|UJv#MDO4<=(KZZDXH5^oyCt)BJWtb~OzRd#|Cy617FM zsm#lzw$=j6vM#1w%*}O8nidJeJgD=UyiRwrWciGN9;#hJ4!4Oc#vON3<{0g%VqfH& zeXnA~TSKY6K|*1pXvFe?&e2`1omvgE>depl6Tu26(!WbWX)AA;9Zf0jEcYe7g-C`j zPZErjt}DmXiOa8WQst^8$`!V{qspdw)%12j^;X^Oc>|;}?<)?@y+x&&odccrN~hc9 z?^OwxnNIdEJ|fN*D{E`}bxnI(Vt7XB325-~H{X{e~LMP2gPK z86H@k$@3H@ITkj9VcG=hXB(lF$XC-_yb`9m8w8zSS)sQmI+31oFq-?)L~I^hSrV)G z4U7)1nd=rBD?8jQYa7$n#cJ6vUcT^S1GSnig`LeiJ^BtO6|_O4@7NH{8-hw+$fdn% zg95$3lQk?{kQ`Jbz)YwlQUvBiF?So1o zz|Y1lwY8&lO%0q?w1Yu5PxxUIu5Y9{8$^{=iAV=#f`QU)ic5}M%7MtBR7%>c?bLnzILUD;Q(GNsLyXQV(s;tVNH46xK@F@szbO2^~!Wby6AJ_ zid?dE_JD}EFFnMgq2b=-!aW1-HCtWMIawMCgvr699H&$_Y+#@&^JIe<(Rd=5A!O^o zp>KRL1#XOos?C*ef@p5a-l@m02ZL0u4k3`r=-wF zVH(;i)+~(3Zyfz-+dLM#r0CPh><5@Uu18#T+{c0kR!E?B!dWF`Sx!-?kXlOz$Q`^W zExyAfi892iFfIIS4|KM^2ztH+Zn`vq^J^RNtRD?t;u0w zBeT0kdMJ3`YVmE}sc*DsDwJ3YX;F{UaHU~)mfb9flO+PW*S0{K4f+%M zDdSUh;>~t{?f(mo@HY3>xuZ$62Cif71T@Rcno~Desy;TTn&Y_xdee{BCg@}zAfl#hZI5({?i>YbMW9LS*4anj*_{ydRu0anyG&>LLGK|<2 zg+oy3tv`q?Wy*^t#~*PTykC-rgW0?446khV`=JEjczW(Y_ZD;KyyfW+9_a`Y&sBWZ zA%$7=l3?V&{7zG4Yg7tjvR%w{rZ_uqaE~{W2XR7SKe>L5X_-JQ3dP`|k!q2uM z2t7%3_QRoE8|9ptqu?(h&m@GkLD6S#%g7XOj$VWAHm{^_Oj<9tmzpc{+lrqU3#^eA zn|DcCg{hi2vB-beuqA|m{oyDmubcNn9ja+mUv0-(v23zBpNuEiP_MC6NMf~G^SS($ zg`(L$VXUoDzQTqk!_tPSTiUP4;4%nz#89Z0N&yu8#iMO|$spio_nD!c|ab4@Bd@Cz?`ho*Gu zqy8W}CiKNyv&S#Be-k-h0TnIF6XbW0ug=yT7xhq20uU zIWuTSNFW6&Pd3&E3#d?xz3Mym(GfZwY?Q{O71b&UGX*59vjSJ@PtS`4()x?<%)dPe zEIO(wbk#%TW@<3hE@>U`rg=Sw^IyrU?BBfE!4-XeH>)HfI*!iHOinylenQT`B$V7Q zkUL{B=<8(Tf8!8J!sUY2j9I)Dv`tx3)1h%L^B^>VzkULO%!w~vCgE8@yS=HHw_H-oc`J)v1NH&Wt^gC z64O8pPt{)cQyCYmm*Az-YfEhWMmDJ~zwK@nJv<<{xAduM=~ta`=2vD+Wqvbc zP9e-=jL>OBaFIZlPS30~K%1?1AI`O(%&dx4X?jVx)y^&`=~-TC2NBIh!y84?t!7y~ z8h$i(NtoGafr`So#Eeq@ZkCS?IwuVI2m~d;7$8JP(7l69?VDderMyRbQnt{ct1cPH z|D#;GxvU^h>gIy3TDFYl+MKaWb_TvQ`F_K!nyEY%(Ph_MKtM6p5`^Q>ne;Bh^1MmD z4)HPm!v07h_Ri^zTC3{XH6UWPXk8SJN5x1+%AFbUYl05yc3>=cPn>8!p{K`8lR)p% z)8$_ExGz7YLkmIBB1hMxMv;hlrCH$&NlnXT#XE7~pF&Ctj+UClmSL!d9SD1sW?vW3 zU0UmY;duvLO?g++t15bGM4HKvEef6^<+sDpq!C%>fV4-BG7RQ}$JKQb2b4!=f*B4XQS99lg5hlA1+2=r1+VbfOdt>qZNHsUP^`TqT z*2gwk6l_`S-pW*#R4wUUkht*$IW(|Nta;bX zck!%xrz6^9mTTzFDvYM?U9FDRVFzW79(oKet#Tzm2X)p5~UEqio!1a zA<5d14xxy3=b>`DBSlx<)%lncP+9x+dEL(ZN6p?^RZ3;rTb9bCl~ZvkRG^HRWubiO z^dQ8*UL((2Vq^1)nB6a?vce=)%#BYVGqf^*eQ$VBGr3S4>3Cl!e--SsjIUXCZzBO__wn?-ekVOL zVY1(fPd!s(cB>*5!Nil|nk}Cy^B`(j&p z;mMlH1tZawoY^i1QPGei;HA9-Dc{nrPIxQ?z=fE3Q>Lc8uYf@8U>yzQg~7s}-XZg( z2fAQVE|VH>=kkdvXU*_D!*C*Z_q3x7CFR^xOvSB?GqyPOCz;6WP1tdpezq!9ecudt zeb);QQ*UGg*J02yjXFYCwlu8cZy--RuNHx_!H+}t({Kt75pz(m`>Kp69o-_O3oR;*fQ!p(+4w;$q zRe?`J5nA#m;(>|;3{Rcw4oZlk z0Ur-`JQJtP#H3J-e@Qy?b97m$4lUi=vwxt@Uhh@-3o03_!T@bD*i%LR;S?o1@A`+Z zC0-m!cB`ZYv8N07 zSXl0;7@vKfh9w`udV#bNa##u0<-x*TGT|~eN`Nr z)xo(}Rpi`q#ZsrL09DF!ErC7_XGc04X7F(x$h>;TsD?tm2jgBm*>9y|ZLg62>&nvN z1EPle5PcfR>(Nv5qjFW?Z~|*jEzVNJQ$FUQF>XQMGK_dCq7Rq{Rr!?&<=z1e)3>8C z22LQhg2fTf#sFl_MNUq>kb=56~T& z`L6che$J&gZ>guC#oCYgGNi}IM9ui38lJRPlfJJ3#W}@qxf>gn1z)I=^pgJ4x;N2S za?o@`#SnO_tdaEd6`A?=&|+G~>K=-^+Fxc%$$z#OIBc+H5i?%>KIdKLd_|{5qKNY( zv-w2$NzX8gIbFz@svW?6C9&KSWDYX%ae+ymhFPkIO5ud0=Jz$@CcVL6n8gRb^I$}% zixS%0HGSqboEKn^F;*Ima(?ztk z+ZPp7?F3BBaM>HP#eR6Y{{R-g0Li&4}UxQ?8CYc*BN~TY4Q54FYm&3%lw1^e@V7D$1 z^$n7!YrxR-s>#Lqcd^;e=qpHQrTRjv*Jua064sAJ&5IT$wTV`1{Ye7xD|ofC(LPHP zCD2z0Hz7U;4?vn)O!BHKVne@+b*WnB-4FwAbw~^{B0#&Cbbhx?gjtr=@M@Uqxf#Qf zq+M|ntqudjGn|6PHd>KHstO!5;OK`WK7LOr!=Q!1h?`40nDp5yUlvngl|6>grK#8W z(sU~imsw!f^LCbr@v7_uBC5dh#3&UWyUsL8<)Eos5|%4z6npLn$}=;@LVn9Z8=qcl z6zU{UOVGsOb?`|L;r;ciYEa`$7`~LoBtF=Kg^`hrjFA!>|5MQf>5j)_d=`Rd*71nn zJ;$sX+$(2i2$L-XaWMNj7D;ONs@kfK11LOv(j@1C`v_4CiiG3Oc4U1ls)!>Q(7 zW^TF6(Ym@Tf4Jn>+u6&t+8Uxn^5`StE)O{;A7$OfMoP&?pxWlVm*}#2v(K{DVTIA3 zpn_LP6Esa%sf9!GGPi!LbKuFVaetb&f53c<6a_Tif0w>d73*XOB=f$9M4*C^#qgXE zhy-|isiK0Kq+?44>Vp@9l}SrQOyXYpvjS8?)<4DsDY_y8)eDy}^+Fm?L4SeH6QT<| zI{3Qp>C~maa%%z${Q~)dtZPZ|$Ud-S)bCOWVAz31*qBPIY)FXRMkpeMIjotQY}jp= znhMq3PaJ^pUEn3{G=uIpXc3BUfe@_El~)ZX1*9A(aQ2l(}S;Mx0BhaCRU^bC#wKfgc> zpg0F4z{fiRc??Q6aXjGeom8Y0KbIre&kus0nD7@8(9<)&^j6I4H>j=L%(v+eB$@ep(4NrMJ=919nK!uwC z(m~R9Bk=v51dOsnO+2{;jV`m?V_%MGu%!Yhd3am3!OkO~`R;hKR5*B0SYU=+ih8|b zoyDBdNew^o@R_LH=+>&-Sw@%-8Wn&3cQN}YB41-ErcT3J2_cRM zEw!HeI^aSKpEL~n=b*ms8ull~Ybe#%JoZp#GG!dv_U@0G!qTkxbQ|6dC2jlYRdT-V>Xm=9=v4bB5W7SwP;fJ&PtMwGpOX>GfIo84j4EeAbA1m+ zDl;BE=PmyiW%F#X@7=kfCf<}yq6SNoNe!v0rI(sYsM)%;()bb8!zqjkXJbUJJ&I}N(BGC!uIq0xSHb>$gvRlhT4JoO+3yhP(P!8s2vAFNshjr@6Rs~GfPbn8Usg|2 ztR*Ls71|W_BGfA)jKts^%UyQC(C@RTzt1EmyDhjfk|B~JFV8?Uqv*ca4}I) z(7-r-MAm3J^KDkkY5sG*n+n36*v~#8s3_n8prW}B0)dDs(=-kz$L&xR0JF-7XM@}o z5s%W9&~#Z!BVA5Brc7aix3Xw8ZwNB{#5e zZx{Q_(hF{3)o_bUge)zcvQY#AgO*o{>(18uX-amtuS8(Rsw{Lhm+2J`RXqrr#14w6 zPOSj(1205z%L!RlX(bC$b`Y~RWTXvaSu0MFNFk|40ids;S)aMb4XkLauY07#lpN4+ zgv5&w410|%5|&1SrAtBYjOHmXBG`zVFqgdvSjn$6QAZ$nnH(~^KNeCK26W^083myU z@Y3y z%H?|iH6(0PCf5OD>4i-^80?501HT|TQT|j;hDQG}K@$y6uXp*p%TSamtoqoCu%U)H zTxh{(DUS)z`}9N04*BOTX2V?LTyV$yug|YdWl_GWoZgVEuiJ+gFX&9iN+&3Mqt~K2 zEBC4HCH6)sEBT^u1B|-yUz1Zh?d|W{5^0n#!+UXE0}RHp<|X$5wDarH&*Ay#m583< zaPSpq?QV2J*X@anA5x*CTVJWIA*1EI8b>P?I z{)pIidwE|%+KLK4h?Tb{0N4}csqE>~i zbGo^YyqJ9CaU90()IEY!7pQ9ycSc|yK#{j{>hL%F|B~LJM(4z*?u~A+*xD9n?`a0t z@oHe4dMHFFq#TB!l+28UaqGvXD8ctxx#&#!i!x(lgG$BR6;d)o%$E~cITs;M*@U#9 zC#-VEOg2~mLd3>|NtjU@E4b5_EIMe5+t%K+-5$|mnqrpepAs`PjU^Z0SmP@5h}nO9 zWU0D)n_U;1#Aw5|_3%@jzX=s>s@TyOVf0L~(er{(q<$;d^xN7BHdHAE>~3jIxCADC z6z|1nz7v%SwtE}> zYr=Tt)r&eVlWRwvVxgt>UX8X)rP(sYQ=!Oet3^DPP)0N#T7{}P;Un%jO!p}pq#Ry= zRHEgTe}b^JV(Qx4bYlFsh`)-Sn3N_Zs2hhow<1-zOw@uXZ>Qk?$!<>1V(#EGn-GY! z60XHNalL>NN=v!;m04tS*h`Kcj?r%?MnYXIdd|)*$TenU{mAA zcw@vr|=Q4i3)hInO?bv9t0l`eEAAUhT^kEUD2<^@*u*xte*6_2a(b z;^X5F^F%O139!*_0g-5T6yN@(%De*yVVGa|G9h_(SSDH250iOzlmxeb%9GU?wd4OE zdGU65A)o&>tsL7%7A~&SPL(4VFVQfsvU2>E$ng(6IlfJ{fPMw}Fq345JGA8jk}bJo z8p-AbwuhsE4G7J#t$76?QLq~RhA9(z#y-STUJ!frzA!uS57 z_Js7YN)~mv1W62XsKa`#pT9t~20)1Zn}RY66oP{Si^Wl$LTg6&M0T;blfx&LF^}=( zw1vPGnZJa@Tad7n*am4R1Jb|d@S1J9ycxwrmPovPp0Z5lP9B9wl%&YpLb}yHbq%Q- ze|IRVta{Y{AS;m@o_cCr!dpcYQ>(${rg__^nxr~c&dD#80A6>N-Xg+v$J<2=S@vwt0CTs1_u zRU`fMqK;8CgW~2znVLC?p?&*rLxjfdUnL6UX{sqB<)yli%)$>YXOdZH;YPlzDd=+1 zhuv&x$K|NLhJb8nCN&F{+E@(@hiv}eEnm>xHs-aZ#4<%;j#o$p$TI|FF^^XX^0$Lc zY`G5UR3B5sR*ewn!*3}wKc{g#!8ig{xOi4^65SDBAQfBNOl zphTW(>S4}?m%p`o07v8e@?pIj7q>+dN0Gd5OLwI?@svsmz|Ei12L6o}wW!lX1%L(Av7LZug;6Gs@!Crhyaix2Nt4 z%3|M}FYs&M9^4u+E7yoo9^dN+pNyE-y9RMgIDHs#YNu+b-q4uSY3PG0XdL+LPFYGs z4+oYG5i>F4oOnKIeHB_lm<{BK{y+aVcSt!{(B_!Bc^LMuZteCzfDB;OvZdfhTq^d| z_xxoctZeM1l~Xqh%pVYZ1f7jERf1?Xqk@^b2K*#_5OM5AJLx`Z?R4i_rzHX$e-rb? zkb^hf!lH-^J@t|>su|@XedU8LzkX6OFydfe2D1=JC+?Jg`oplSv{@vjeXutmDsT0k zX=L>;DVsZ4hxVVN)K(;`8Sf>KO%>YzmCWV~-g02-iewfBgf}cCyQ?p`)4z_VRX>mV zcKd%qvdcO3PoC_iUXf5#I-B?&=nIIi#=dWg_=u*xi=!m9R0p*}__XVPnQEM@v;s$A z(sy~sUvW(K%nJ6)sW&D?L|@>)49Q2EyTy0SuU-7v$2$$PDo=A778Zsckx`Tw%jbS1 zA2W_3krR@Tc;f#coLu%{Rz6_5V3PFy$$(?yvM45NW+A;W4taX?5qvy92Oi?0kiYI1 zjzZQ~%~?vKghgMmaso?)!jo85^V5;6dZ?AuMruEG#p!s1GRf&rPGMo@V80RfqnpNW zoR>Vk-#D;kvAVy06v=v~Nju;C%VpuBrhh_y<+C+48qeYdtD0H2@|VInx|PdYEsfQ) zO=jks@R5)qrxPKabtP>>;Z7$({q*39)#X$RH9)PKg8GpORXYwKe2C}8!}w%Oi~YgF zB#8UzVR1jE*l2W3*0M9_C)X?awUQ+}P8D-GKTT^Em3#cxW2g`OfGZTDGc{oJk7%HY zc^Iesw7B3)LeQTz18M1#WtIJnBrB+;nszl^z(IYcV1F*ai9zT;2*dqMFyi$X9c-n% z0`^cQATsHsER;OyVXMcJjd=Yb+m$P}B6LE^s=bR11BuC#q7YwrV*ChZ-@1%3fT=ybxfGi;sITKQa^<|I@_d6a*0zw{9}x zkFa)F1kbuKk8@`rW1o9jTw<#Z z)cX$;uEBLRHD(t3GkMm9+~%?(xqtxhm|G3GGUl0p03y6blb1W^5@U`(#y2tettWJ@gE1=!A&a#sn>u}pih6%8If{RCTl?E}tGOorT1;K*g$ls3ZE9j_7 zs-9;RPSYN6`)IN+4H@&>+1OOmFExHIXZYUbxlzocK~Z3Ls?uB}7m$Ur zRA)gR6eo;jA-+>?m^@a8$YTjbk<-%GQM9QTc~=co&y;ABuv9{$Oneyy!%f1g1Fd1J zwpy2W^sj=+b!B`5NZ*l^!CfhG&^~?^X9HW;F6e1n>q9Xo|1m5f&`E?63_10zSv#1L zHYpeqYC@<7_^H22_yw4uLC1jac6$K`+8|puk$cFiuccj5{ zMmGjtXuc{C+?{%;$kK4X)m(=+0n$Qku#GDAR$opU-QTfm;IYVhOLk z2;3fQPvf;K1N}_=C@SK$Yrwq}MUaB$q7kYRyy;6Pd{M$|b!$ZD@-6^N|9!}%3g@Jz z&*?%iLt*&c3-e~UAxtugcxVefFO~hzyvPDsOWA?SA3-K1qlawC8yZ@-r=@Ib8{RV~ zM*G}@Yam?O)&C^C{luFqhX9U(6HuMc>1*j|nj`ZT%Q>q>OH+agQ6edh;}KaHu`HH{ z#I$7pt1NUH3!Lr-C5aIm{B!tzlY8|!KWYJmt>o%8b35J=A; zs2J7>UC%^j(FZ*3*MSEq(k{7gvK`#Vn{_*R&l~Ys@C-ndMqj*4YI2oc&PNg2)cN55kCD=LB8%%oE!B5<#n@Mx73X%nadV z#90(0mOmAQW8D{D$i}*NoevI%R-{jRGK90k$(hadN1D6ef`2;k=BlA}BWN1q!z|HJ;{QO6Fx2~fc!rsZu^%r%zDQ?L}0oYx|P)zdL zroN51-hzlZF@Cwbwy?CJzN50CGl8Bz)(GmDe+Z!LEZQoY&@IQc{qwyo%%8(hb)wG@ z{V9|RaZnNNYlKlxv3fq00}y&{CHf2_9?IJzwKw!_#>9)EKX<@6>c7NYt1o96sOgW9 zz!ag|{!FTMJldJ-DozH-ukgl${y< zG|aphSm$um7CW*7ddk*HQ&Cm{%ONBiteV1g1x3FEtcIy4A#uoI9x?`5F0Lwew$8&B zxSslhI8N{aS5=ALR@xP0sLYkyY>No1I!Nr@IL00;D08^Am}Y|Mw8F*aMB~^_7+Ru} zdu^z|OpxAAhofb&bi_A0{-8Kf@Jdj%T&XMT;!U(VtGj;69ie#Lk_YJ2%reQQEl($U z7q3LE+tQOZ`m7^{Af3Ig+T~()T^j#N^h@|!R9#tD8)6H<>h-ZxtJjh2jV-vAsDp>X z5?ns0aP8;EJ9x7M;4z8Uk*J4w3*ul+O~a;)^grzwcTM^zL9s8n15a9U1Q2p;B2f3=sxUh8Sae+qw9h-`p(8&W`VNF zYP@9cC=cEoK~p(U7WBZb!jZosXkhI+`+M%D3EVE@?wDY|i=IH=`OguLOzgq4ivlxU zgqSH@`B&^YWci26jB3zZdgH8SX|JuKZg~T9fABgq_{*tf;t{NoPsF!db*-h^g1f-t zN^i5x*Ro;CP4kH5L7c(j4BbIaR-c(lNAQE7T1p2G+LAZc@3;UaUOR$P8lMZ223&R> z`YP?}|8-b;#_=~-4-&=19?}ix*0rr!-CkSE(ztIQOC$Met7CPuvyF~ecLo_XmhRNx z=wwrE(7^4BMBQXG9u!}IN2wTQ1*H$M^mXJkoX;=P-5GAAB)UvkmBt3tSBJ45+xO0! zXIJhMxUMqE(i~IUIDS~%eEiK55i18KnZ5Mv+>)tRSjuH$Uo*?=WAnu;H?geZoA5=) zvA#@mjx8`iyh2TMN$6R0{%e!N;q>ju7*~tFoO)4yyP1ERo)KS~&)r`yV(T~CvUu`L@a`|aM}}Dp{XVM`5-x9 zNZWRB8S};Dl)4iwPqF;t(M=ba*068B^;Y)Hx8fV*aSVpVa%zP0duEo2lpU*r(A(UT zo}UzjI%k=waXd!!SD~xjD@yrt$jHJaiix&Y6J#;Z+RQ{x`1&obK4g6-EtgHU=}>9@ zJ}Hx5PmPF2c}q67H&yHbLus?VS-CF6()eHUacgxo*&lzyv#ds#P6gJRTAWE!K&eC5 zaA8^n)^0Jnl=$h+286_Vc~W+##)rkLPO#WBo(~FsJJLDO1x4FD?(ruK-h|n#MY+X10amf`fJx%HMfDOuBZG9tm2RuM@jYynzj1Utk$S29PBs z#OQUj6Qf5~m;$^~*~9NL5`D^(rwwMa-?0sBM(qlWj+?UD%wFhCI$8BSQyuOOikkx) zyXxgjZl9(GoOt~Se-&2?9>_I4#%UZwpM9G0aJV+Sp}BoEQ%*QDz*M2lV7mttvFtjh;D|YNmeSA8m9R9Wl9LzYxu|=nZ?Hubp(-ra0FTfi} z!W3^8N%lKZ#FvfF6DcPvT-P5Lmlbq|#Zv738v0G}x&@p11#U@o4r%EdBGd)^>WioD z66X*E327yM)JYWywI&BH?cZ=An%^6J7;zn0EQ%N4vjf2ey~2;Upp zA}8-PY|@2*sPS6ugD23ZQnFSDO5MnP-MaOm9`bO7kwYPK9t${C-JeN=^ zNYb;=+oSS$cXh&%k?!8%a)-_8I=FfBL8sMLxqpp|se#}6&pJNZ*)_VnvvZUqrqk;j zN{H)l^sQLY=je!y@3C@(Fs(H;ZdYxMJFwn~uv7xOV@!oE;F4qsZ9ug_v#NGW-77V8FY)#i%ovs*Hlc5x>2PN)Acp#IiX-`v2? z(m!q9y(S~OSeu1+q>6TZ)p{%1kv4BJ?a}(L*ft0{&pKc$0c;yyOv4UX|>SLG-gZkM~>{E1Ruxy|d{ z<}6=P!Q3w{Vnsrdn)fUJ0QRZIw!p(!NoueZiZNn~AWm8YRMd`|fN5_z`hqR3Onj%$MyV2GW6W3YM zxlB5y)&3LBBR7)sAELY-6iTbiW~~hKFs{v5Nl{VwWt<8~c%S)>6Up?`gtqV$_ehm% zWbLy4rkZN^@-;(!EBAqN(B0~AG}iWx_Ny%14=uj#<$b8jlDXz zs5r%3TT#_kt8plb4KjtjDIv02p{Z1q=w+%3yAkQ}wd{KRPv%+JjWg1CG)wVFPj}ZW zrgBEY?_de<@9o>UVaV61Q50!l35|%U-?VJoKBDOR_nY)!zOR$zgZUipAdw0@5^?c-?VeTS(R>ZRLsqUDSXHQtt5MetS7;1Q zPT;Mztt(l9x53}sf7f}%nwD;#sl=KNqZ%^O=K*N(mFF;Bhja6KYD|qwBkNRZhoZ!g zuW)g~X1W$tR+yYJQyPVJ{Ta5JG(Lx#L0J&0LyQtfTNWOEf$4&Qoz1B@H&ZXf2fXF)^)t+&blnA}RnD4WtD?|EE9kb0>Mp}7SM!0IntiP$OeMEg-tuF|itf7RMpmmH zRhxE?#m=W?CHmYg>+Q=74K}4sTf8u0@nWmD(_?5?RPJu<+*Q5{sn^9BJB!uP9gKp}XZ^<1MxqTX{~N5ZLzh_z7RU|EoSMdDhMl*LGXs-oz{L*>ke;VFsreNFwG9L`)hynIQ# z%jD|H^*;=+Nz21oitjR}V0Iz~CY?Pc6*0ec_i!I(d&e0Y+tW+ZP+p>~L_42LOazL_ zq(qA31+?JkRwdOWP(L+Km^&Ovnd8-|;+BK9*m|}|>iYV%XU}V>?iuA+Jh-K0RgAUT zZxnCvzd({B*jrTladHH(qgzyQPDE=3JH96i*qn$xYe$OgWLS6YsZc{_%VoUFRF#FF zT(h!kW$0z9QX^xE{T2bG0)fy#3gjjjGP7NxajfFIvHyi;1$KhVh% zQazlc#YGOa+R5^U0c^x7e6nPkx!NBlY|?s7%@|%4tlqbqFON^!D^~~-2{4^kqR5>+6eT*vzA6Pnbm2Aku0+bVwPW{%aL4fa<^4$++b+25jBlQ2 z@9q$rM0x%<;LfxxZDa8{>(o)`0uNMFkGsE9Uw_3}_4W1b>W!;buDD29;Wox3rbW3+ zwew196$3qBt z`=#slB0c>Gae>d;h+Jdvox=G|On41H*y1&fh!h!C4*tD@yn2Pc%G!)8JzL8~QE zhiV*k=p!ic^T;{gPol4Jop;l;^*_{tyV6kPVW#NoLsllXg3YiRZSNV*_8KPloOLVX z&8zhBW5J=Lw1Z^5G)-#KV}YGD)l@N1L62K9H$QTi1K8o z%c%&lIcb5UvDv{SrrXejLHQczLB>7{pHGh8hS-cir~l`|3*Y=hTo9M?vf6&$mYLc6 zxIM|!v3vdc1HW6c0CulJCo}>6`bq7F&agU{r^_MWxkFOXl=P(jz*d^^&BEqx|KX_Z z&8(mQV15ov72ID-XXciBE0La5k^kW<(531AdXsG6wq69 zcS8EkhI1|#ygqN^n%2z`Y8FxL{|bI0jHs5I92cJxZ@d+5-;tWSyZx+71Q}YhVstZz?CO6W-iLGQa552D6>B}U?bF>5xNoCu zO8Ok(C@yy#}2W2=v|+fzP)jp>kT)oZd+Pm6Igl_3sb#^;kC5LfFg@JUcNx zAy`$GT%nvvn8wyzCxFeI%%yue+cu!|$g2MC;`Y3pAw#1-oqqJ1gKy~bt#*5*&n1;s zdK#=1150=a&J(iIc^xBNP1ZUIz0hl`>`X~YOJ@O`%+1T3_4*uJnbxYR&{%AZ9wgm2 zCtijI4!05&P7da03M;`%On+;0+q-+Lj@k-eyVerj;cQ-RS8E*Wd#vfqHaKwgA(&RC zEz*}6%M6z08s_U83pB0O26qIUSE2Daz!2IrQ4|Qu(mgjx#>eJO5gYy$PrlQOF>1cA zh9@?a-o4FBggU(l9i2cUwyT3;OIhahtyHrjC3l8$cz>*+GHN&6HSr#sGYWkKHEDp` zaU`OQG7u>fCTGNyAiE}wN7@XvIvHm4-vb5Cf*e?e#Ueb;yj&DI>`~jtfXQ}@wowy+9fIXR_;I z>8XA&2NS&j2IM~sznLO`6EqR|=h1dtU!xGCmZv1)20oB&X>eMq_;+mDFSI?<==HSr z`C7I#FCS?cWwy}0FFbpL$yH@K^2m?v3X8tD6fOGW+knB|+1FHAUAMZvs?o=4i4ukH zZ_;W@i!>Ex)_VMczPy1bN+Pi-!AVAlk!q%z2@QM$xl((2`?uA~OKV1}WYNrP@crX= znL%QCbA#RPsHp9#UVR3;sQuCHYWCT!B3goC^(HW=)t&)iu|`>@L}O&$ydB#z3)~#Q zBu7n|fzu86B;e`$fkr1W_3DOEb)nYA8dVp(a{v&T{#N@2%6UyuFNkPtk*Wg zM0Hrn$bM2F61nu{?gC533*2qhVi6iq2URyqrm1@740OSLkLaN7ZM^TX^~WXe>=+Wh zlo#cjub&Usw}X2BC-6(M@2L%`dt+2pxTe3Zx1|9z4~Fi1XqGd{D~Pjd^l30G26*}$ z>a=r+4!(jT1v@Taql1c8ZRJRG>ZaCdnSL-$vaSWxcK7?`q6dQ^!+2Enhj7mi8CDpz zhUo=xZbOf)J~WDmi~m$}au5R~2OIKL>UeYVGzWOPggY_7VH|y9Y}%HVp`Fv*y4<;X z9u$w%E@QrgpNB?w2;N#zRH~VtziN}z)5uT7<1|%5hRPEEWeEw<6X7K!2v?_H zGJ^0kdxZ$X(`A^ah8ZeE{I{hbM3?bPK@gt)m(mZ2vD2*dAZGCDJ%sbVa==eGyK5+r z4Ig0%{+0%S{Vj<-J%)EprYUz3@~`2>o>xe%lkii9#|~MOmsgYz7&K+f)9HC!{2pbn z!sg8S-T}9!S$^t!(L3Y&d4AX1YKy$xtZhw*t1iWXd!4aWu5NcY>y@o6+}!`J&&ZxS z7|~3_xN{%QW38jQLbI?DQZ0;Bc92dlB{_tb6&QVf(NQ{fRb@(+qK&X(>b@*H%2}*) z`1gocV9>cYKCZRpf-RjFHe?$x=sc>SoOdok(C1^zI#w@;cNcRp5#&d9cIK5zX=$|^ zML@>v6`EQe_B>y&Qq?p`nTvzw7GiAA<#?A~K5edB_+ar?IX-XjKcQJ~MenEO1Q`V9 zdpBo{uM+(ZRbBm(a1ovW*I~oXGT}taCcrU|^Jzu6q6$Q7IaM`#E}Q__)6xCnG^j$+ z6MP0*6Me_+>avNr@WFYgOTo2SNI4Y;URC#P1U5Fr-Z-nsy1`H5s6>T%gN*2h$j`& z6Ew%CSfQ&A;+yX_#ST|0TN6*Rs-ZJw*M?qWoL7(c=nd=B%j2#jbe%Sz*_ z*jrKM&8!`gms#aNto2{UN#9saB6lp7&WUTh%^WYDaU_HS$ox_GXu4o>1M@Gw8p*|6 z0PojNBn%f@K2=Isn<>bAj-9V!yin|WL1xMM86Aw-#ZGg~i+65wIV%s@yVB?;x~(0% zE`pDz<#6n5=mghyZwsEBuZEweW}&?)?>f3ggtN&b^!Tb0j*GTswg!dWWr|6RNnuaX zi_s~1Z{QT&e<90NHM?OWGw4&qRSnf0in@}WE_1Vo@j}AupYlR_XI>1S;4ywfFdioJ zuY&(b$(}LBcdCR4f*0&Nv=ixWKo*nnF;*5c#Qm7>$#@4Pb2pMq9o5g>xbnY?X2zf( zUpRO30)%H>8mbjM;b5(pL&R`Ag@}kBI-FTXGe!{&ym^7MnOBi2AVT@fGp=jW@OAB* z(9Gu4m-x%shMXZ|<9NO3T$J1FX9!PIlAN6i{#usK#mF8GS(Bd^t;8oPE=(~&MDimd zvl1RFNO%?vbBavXdC?!Zk4hI!OaFl>uV8pVZ>x5 z#?lLW_@~E3PDlU%zA+^NusCFU(Um@E?HunHZM*VvCb-QzdzRQhVb&DR?qU8A;H;P* zG9atq^Jo^UJl_5V;ZU6faIhqB#8f2aKc)1&>EEr zeyDmVHl=s_X$c5dy9`yGuX9qrJR<67oVz@xC=bz{-B@>4Q`6s-#ima*PYrg zc8>>-UroZmfo4_kW7xTCSS>usuf#8|qFScMB5K3PpFP~j=SK4D6kuX%(vQ4-IPL51 z|Mi44J`iU-6(8WrI4wr8(3u$gj93)LDF(h1OxR(9S5)&6i<&8{h2jSJv-dDYFD_sG zXa1t5@!u%Am*5BeJeL&X824@n83=+S{62JD{uxuoVjA^)RO9JW7eqMDnM8thJZt@o zWD*Vk7^5znRKpzcfEr=yV>5-wr@x;T95}T6aXvR%{|(}a06Nfr31Md@nBZCK=@9-1 zRPdjC{w99H{MqnKn4Lc9^S{Zr z(coGRkth!aKH8SGPL^_IYq!>bXy##?1_j$45BRv?PIbVZeU8tI8m4%sr_bKZMQg)$ zKA-ao*doTU14bApwQMotGZnB6%7ItO7E6NXckzna&QQhn0qn8!r1Aj#2BW1$sP$8B zEIWP4XtmQV=+lYk0kpOcdmJlFl54Si{>76|Pf$JxZOqE&zLYgi4_e6`prR>1ztN&> zDl2VLF~)$H-Xdb+-DsAcJiDm$R)IzQhj4*md5MiU)}O~kjKNIPgAX4To(;x>9F(~D zNB(RW-zsi9&K)+nLnpye;W_Z0R{NeNOzFvOp7VL=;?@waXF959#up1SBAw628W;bR z&I_dVjc<|4rUx7Q-yqC|qK-XsbaD~2R5JjN9|()Hh)&`0k%v`WKHW`<=v3&&gxKAh z?*8%P;)IzKC1%`s1nK-Uj({6NYaj{^#|#-gIee1;9DpPyzQ ze7ktX2^^Xoe~Pd&z7knech&3NLvC@!`d1?$ewDoi<}QBqG7# zk*N$O3t!ha6StB#KIr;3cuU{-%YS|H0_$J)ts?urip(S_>Cdk8eHLK~$tcZkf<(U^^Rw5Z45|OJMjG}usghbRczHOfD*Bc9RK#|fn z%9O(sVMgbdfX0i41ydc0ayZF}=S?fRSKE?hUkvW&8Kcms!JC{_BKP!(@UGZJHBo&b z*68$ADI9MtAULTAC!_B=4>0ywbxE4Z17BZ6E#dPe^R^YEdIT(`g`cDjr)hR7Gww1far|&Hjt{B7DtJl9!y(w`P%LeuKTX zt*zGDu+S2r@3vHps!dv%5{AS}dtyB$7mfFc)*gOj^7ztUB+o8eAnBqcV8lCGh}3FIod^-55hG(mpA=go7_@; z|H^e+M3o(>sts1{ zAfbk7x2dYTBMu;n2KbedNW9gIb9D2C&UrOK`lP%RHNxH%sBchu zB9kv1y(Z*D7nWcm(9275Yio%A@+15dOT#|HDK1YsqRE=kO5M~e%YO_%w%v44q-sTE zNuvA?bY44tpuS;wR_u-*xP99Eq;2a}ES+!TLt5l>4b?Z?%1cxtJA&UJx)Z2eN+Ez~ z6B1SE`Rs23aUsw0rK+~kRa-<4oEU$xrnaYb~8(K5FiPX5x=U6c#jgZMKts@w3WW(O$J2#hL;>T}`? z1vPBL>&(EJ2}v!+(bZc-myeIvNN^QTQB4ip9#+A#r=_Tr8{)e1IJROZ(lu}=zg{QA zH;}~OTru})XU-ymg%f2(OJ_-xMYM|*r=J>&mB~sNP4x*_nK4Ld?lnG@Vp`t0L zwmQ6jZ`mHH8)n7Y?AKN;TDYf!%^X7K(%{ciGlzN_+?;4_nzrR=vyLcQ846#+dt1>% zc$Jb$@?pvf`1dF9OONovg`}1hna;!%1S=s+e21*Bpvv$4t+VTA{Z4Ohn(xx+1fJjW`pVzgmS<$$-wuddM!bJkVL6Yoo0tuSG;La~p<=R0@ zBrYaRYVBicv%r%Sg)8nKpe|!8B8xXtwZvN8jZt)3$}yb}!M9eSn*+icxviR06w$&^ zCjr1FUoh^uMf@znl1VUwaM{_-8UAgk3Xh{VA>1E`oYywQ3wM5lb`bv}T>jIv=cL+d z4c@%)62bP{gmGEfWG>D;E+mmf{1R^+2LQHK^GN^Z)E$^``V~J!R9B5e=WeeHUD_8* zQx*)5V8R7P=WDgKzD8a$F%hIY3p|A@RO4|Wv8_CeS(j5L%FSC-Lx*E_X2P>M^LQsP z0JNY=hyjIjoNC|{PBwmTY-@#WASR_rHGK|eMxFtYTh@ZM8v3=yE;S zuD47xA|;A@zEYO&#EUnP{%aT);h?;;*BzUQjo9h=5PdT3a^5zAF19gE@+SHI*IPn( z1OJ+RaUbf?hVqM6`7nm@T954m;W!IC7iJ%Z1Ntcbf>=8Z*fML1x9LF5;Mdp)=B3$AH)_2ON6y1yx_gIJ(>|;AGB`S{M6f%w-3@Dph4hfalwP{g$&S z2hfWCcxsjIZmMa9Sl$dKGnaq6 zJJ~t#?@Eek6=rx_PV@}{Yw59l6Y+FUuXe9VI2fX})@a?Gh(se=mc{$o` ze6BDyIl0XS^KRf)RI<)3z)^8ERX*LVO=NeWhzq}=0z+m&4%@B+l34MAL$;R(TeQBI zwDmRa4R+f)Ps4g0z}t+ar*0GHkN+dOxZRTHOahtA&Dsu4qnde7M)n`=t4j(DPSa|) zdyUz(#w51*@VymGq$RDaL!X$yoHDe?l|Za^k^KjzI}5zXt#cwJRZA@GtGH&X4O?3N z-g8#IgztC~U{vxdz8`w$1@J*(cJU26|B`&i-mtTNhz%y46y%)5$?Jre=Uuw9_Dp1N zc25xmxwD{zpx_(H_)T+LK`7(#u^dl`!(gTw9XXlICqjH;!zwO0Xnob%(NfzQY0_~w z7I-}^B@4HYa4Z)W7R&NoNvu=3qW0qP%f!{szy26|eSw3yT*17bhnU49yaZpxP@WmQ zx}dOs2gmTD(#43Y@iecjl)KCTjNy9>j;erI#iqlPx*B`ANCtQS=bJ1G-nwhR?HceX zX%9qO_9M&W3q@-Pi$Hf;D5ZcBi1y<yR4ck&AiJAQ%m+Jf1Q0f|B`33Cyo~1sa=VCUg>0)>5JX5|t<5 zKj;z1ozyC7Qz$y=f9HH=a8htu=qHg$HS6NjRybxB%bdYUr=AbUiib|psFcF;IxTS0 zHX=fzV_#!k(t#&~x+KQ!=i+m;VoHZ`4?-HnU#fA8nw?u%PCQeo4JuFY!?_17iOW2m zO{ppCYPlKJIF^#K!BaJwG@dKEjmg)7%;@OiHVgAZ(1i4AI<*a~1z{@rw&V?!&0#hL z%!twKs8D~ZeYuP|m55A7yPo+tXhBS^CD?+Pi6tS?nZG0bQBW4N<~8!r4gzcjui}-( z@?Z{>PA6b2`KP3RKWMwJqfy@!lfK-=F*~>|TG_r#i7w}j_7B4w;?vNvw*R{b2n5XK z^;2%@RTP!!Id+GAO7_ZL2m`nDrk2f@E(tT3RucGOcP@{JzJcH1xM(%i5|}R_8)#u$ssbZVch_keW7Ai8IIah_#V9*RRqFUie?7cD0bN7RpIwGiLg2=0ni4qq1*hVXoTDF+NnS9H^|8vTV15G$y@tzC=7fjPDAQvdo0}W=Hw= z7~NHd>y^!*$-Ko79mbFw1BKT^(eH6sxPDW5(&i?P!=`m9&7J-j(M!kQ+%PH@f%y?* zeP|tI76`6`cnfYb*=sqTs!Y(=j`12JQS(9XifLCr6e(+kpJILOn(O{sh}Y1fQIrsi zjZ-$?4ma6+*Q`uPUtL8e@4A$Pb|Wbyb?PPY#_?+fIi6t)?y+dfIXSpZWtu>7DaJiT z0;IZc8maBc;JL> zR8TbJxF90Ww6b>wvDi8)(8+jnr&i1QWCLTuNv1QZ-oygXZEZ;uo~(Q+Wl_}NFwOQ z^sHIkQ>^58U(dNLA%2X|9+^9H#rTgR#9=w*;(IYOGRcP_2+sCXoa170A;+b?Uz9Oo z=eXSk}@zLT^}a_cqrbPp*-JdjDtei(p+RW*I?Sg+;T9^1^Rdujxh$ zQ*sI)WBfWlu^&||HmN5SS4ofRqLEAmmEyI=7 z<(kNN#8%f-w$jO>NkKF^b>iy~U)|K`oL8B-t0aHv0X%N6Br8r_L}RC?(p{}}V;eg^ zCSjg;g?8SJQ-|}x6O!3F8D%59y9s~9nRSKO zmJ4SC3XnAkx#H6XzYfg>l-@T<-T{;W`0AeeM*sL`5x`6`8gKPgF@{ zHwJr4?A=@Tne8-Rd|K7Cb~%P`myZUC6)R5o-LIz9$a#kfOdlay&>j=PCZ{le4zs~z zpYR(@`Ep#lQxCo;F@~Q*+V5i9DRB_Dm`cfz-8S;Di-K(Oiztc%g(0L8A+O=j*e7(X zwM!qE9GQ3hm#1xTBe&3h6|BS_VZF9I=m@?~*d~6UakV=uImj{dfvE!df+s)Y9Ko{V z#QiHL!zRJegIlrAmr-^cHR%tr-?QYk8vhdglvH&==+mg*8hE+m&SkKx-)Lk ze?8W(r^UZ|4K%Jio#7_4bUw1;GVBMsLcM(fo`OCv$RvAUUQPpls?NtAe%(OX--F!1 zmlM)iuf85UrBp{pGtZcVc7?$iLur%Pr?i z0B=jM3<4ni(47}wCOEDk&OkCLqEuL0d2x-ojV(L0KzL{~*jR=K45L^Es`vfUB+IWR zq&J}eh8{dK8Xw6#3!cIJX-$4V{=kb}bZ^HyFMH9{F}_gBe1vygP8Y`x8R2UYH+qtj zu}*luF%wh44abymo@ocdAL?s)n-QV04(><%J9xuQKg-*kj2nU@F0@M#8g;x$2_1L; zw?aFXcD}U4N%%w@LFf(@DqbxMSP4?WAMd zw$-t1J9%TW_8ga5ahPgIGLrYjg8#Yhb@I@sqhq^{o36DkkXSV(VR601ujV@kx~eW>`-cq5+~h?SvIZ2^wqmB1DK zHEWeY{!W33+G6rp_Lhb9N)^^2R|lBjo!MQQbc0DlMpsFC(%nTAFm7)JGt!&m9EZ85 z%BIuuK!)(c%}j^6%2TJmluF8CbA67^HIGN8weo*Uw5I#ilirPlIUVTanKTgv%@ z$AsF)_>LT$o?=$PI7#ivMacW4UoIvTWnEZSwb=+IEF>S4mVcF2L#R1-il!@AX^{_1 zVFElhQ_l>ucUv|6A+s|F z>=+)6qWN%rpD{6hclsXPX6U-B{oZa`J^;Ao%#FvN12;l)et#k@bb7-U^~cws`p^&i zoCMEKpgRk%6T9=t??ggxc<^1WgH2BGh9!x-+l>sIwqD98%GZ=4-;#vr!Km{VW9VP- zVc;e^Bq$jW;{!@}XQQOr)NNH=GAD7DlU^JD$;v-l7T!Yf(*;pT@7`$H+=59u7A;K@ zX~Vop`~(_Z|4^TJyA}U4cN~S|zvk|VNzXYkZ<$j*tM_A6H1S@xHx@O?DPiRD7z(F; zW?Lq9vb}KAk)l2AS*@H-BV=~z5U!+^c0Dld%aLSqX>XW_pRPakNFO!Y_D8icKax!@ zpePS2mHM$CYag+tb}-%P1Ry^{SW-{>pmbB)yY6LQM|&n*3#)n;>cX@en$`^J@Kx1r zenn1QJ0u%-0Dro*<>Yi}*VxqtT-$-7{rf?L^lH=1#3iPNQ7MQh;kA1C&D&pKVLx|0 z?9-|BtQ?$+r@hvsbDF|?cO^k3$YW39=1&yrlpvwA+g+O7xt@z%+sIUPFPXLU$aS*MTJ zX$X+wuEKs|OSW~~j>dK3A6k8;LY%?!JdGI(CNiDTZlFS7HA^a_qmq#`%h<^sh1VHM zTz5x=p@iXeNYa_>!SJCYl;W&b&|5u$J8>Ic@@~N=_!qFLC}_azI96LNuLakRMT1*q z*!o#bt+h7g5mhwV2<)4Z8aX-f%tzSeaG(N9n-Mv#3##A)V_gI_Lksu^!!hCufz5KFbgdItvl@*Z^y ztE0nelOs1VS}=qbVbS)G90Me2GopL(d2UIzEXB+jh}(io`3Y@kV0Q|TTGspK3^V+#BgR9?Z)sI zlVQv5X}(uXn%Ly%B!k!;t@mibu3S&y_I!I|vjdOTr#nb71)RiTB0qTO=vC=CNpx6X z{sK2+8h2oRFQLO#R4F7;tjl`90_zZ|OFFdi)5;2ol^M5Km~$gkY+?B^bzjmPccUTQSbMbOe7%TMA;N|BY7gLJJI{*7HqNXGrAz6Fff zTJT|NUn8M&s%MsC<+j&;3)?P?4eXMJuD@YaIO6ZAjaY>#5asa9UZDnpKpY+;IXyT< zO&f|2I~k|!5%Z~QJyi+uxhLF+CakM<&l#=>8PIv6A2#&~`%sz6L9H;h&hP51Q4gvn(}wL8x30FI%3gBM+R~hUw?V9bwd9>#Zlo38D+&P;E~1mVoeHY+=D|^uSpd__0x>}#*V>L3qheJwnO9(vRd;f zsx0=8Emg5qc6Vm~(7&UJwvPUEWrDM+BMt`k!}#6iCH-edWA?SvjO8Cyu1ga9U1dh7 zYg4TriY2Boo`d>%mQu7i+%~|}bb|b25oO*ls*PGQMw7v*I`s}F%DN7oIPm)t_a%3W z|ES=m>o^YHHBFR~owPgPq;&LIpZu^5sYf}g`pQIt{4$ipG&z_tl`N|(`>cY!TpaHm z=|{rsJf!ZiFf@M;UllxjNqfln`^o5#T8m`|7H;J;ua0H(7II%Un|eP#lWiY)oahre z2h~uL2_%poq!E}^ad9Ndf(&z=oI5^5M8GePdVYx>*v*+==PFVuR;sWh#VlK0AkQ~0 zr2icaC|>z##cJ37Tjb(JT{|B)UY<^9}m-uxP#of+#;J(ntWlI8@S}mIW9Nj zDDIdWDw&8aaDJOuUv?z;`QN>kQxb3AQqdDPOiJkm^;o5tbK<0tmo^$OuCKhIC6t+{ zIlp_vrNiU*$Kp$9B?;uOE$ew`SUHK9E3AQZ@`>(08c&6UBW}^BzyBG;z2H|T%_$B0)jq^=M*#c$Hk71jIL9yE~GM?LsF0n(FBfP ziJF)ONETWN7d2`jm-ARu0e=h;B;|&~FzBb`DV5=0?-B8H+=Oj&i&xeDT+%MHQoH(- zr=^~pY#dpv!+C{|XO7=JH@K5eU^hV=1i>0mz9X!;&M{V^ER_}_aSD;+dN<|zb{f!d zuGg-%)Qe*;nY9!#`vno>J5TWdUP5!MSnL@024MRK#M2;0&Ta{QNs_@$=2hC^*6Xwx zUX1s(HrhbeY9BFgnG?2M{!21qc?-5m(!}x zNDCg&zK`~l3bY_=fG-P~|J;ulrXptBWp$JlOzvz~JM1>zmi6fRQMgr>Vc3{nt!wAI ziCikEg;cvkm-E#u42{-1t`|g2j}`Z1l|g(TqUWV3f^I_~*ntB7i^9FMz%B#bP^pEF zsa!PDGCtx46JPy8_%~7y3`eLX2FP)Ztn6++XMiQw1(V4KTfU~x3~OF-`r8Ss7$)tH z$nRNRo?oEfz3u~Q3_aGOzhA8D>?v=;3|({HXbyxC44NAR-Vz#Hw%jDpS1Mzrasu4^ z4E&!eD}xixR)GZEZ$lS?ne;|j(B_&_e?iq-469en*W$bLn8O8NHx;0RA3 zUI!HmD@2BV-T>fJyIA2|3GZ(xX}d9|7u|8P4+OByN#GI-!1unIK(Fn$!xL|!-)+uKTp-%5kEo( zmlc}7lTKlWZkM6gtjz~PqbLu zB8v$?8E17bD$6Kc4>u!Rq@oqup_Q=`TG&w2`%7_mlgXtj!2X&f`W=E$BumUCUetw! zey$W(KE3k4SMq^c4aG6+i!lFEa6g`K%zXq|u%_-c#M=v$k)RtTy;X|3Y(}Q%x5gKM zsez4~QKZj%`MW7W$7w8i3cwM4=sl`t_bXUbvpuLIYr9bfGnIXOk?X;Mb6n>qm@MtN zlgxIxh**8Qw3g7ab*srWPJiQ_r~?*P3Fkd^`j`{Z+&1SD_wtE}>4c9+is^{)Gu**~ zYwY|bc-9lUa!@9kZapMk5HjTpn-r02Y?9yGIIE-Cp0UK)LGe%uo>=GtYlm{SxCWu4 zE`-&vlc^QPFn6cioGV9TE`)sL%`T)vPpj%}=uvtgFd!U}+{va%K|GFJRaDfBjv{Zw zL_Phbb8g5&pej`8`n9TgcP@4$fDU@?z~&$J{g%%@1+QVQS2ev#3UI{Jy+P#q?BMN+ z;6%9%E0%LiC}DfLVp)nPQ_&f~%t=!mlecex5F9(GBjJx+j<--UeCl7(u+Bijx3)}%6n*8LB(XeV?qYWomBm=h??DMd1Ci%+)_lNK%YA$JY^ zc#We&f@0u)Ljre%qJ+hDa&VO1Q^STvC1k8%qk@`wq}Xw70!Fn_w*#P-8`<_>Egzas ziy&B~^)i9=tF%wn$jaYZ+a8k@E>A)(RUKo?*&d4vL52XChBg7vW8(Fc;6bHuI(kx7 z>g4faDbr>x0b;_02`CABN~`wD=j)SZAW;79p zQcXk*U1?#(dW<_X-2=)H=->HPK@xGB6e!WBjtWo8z{~FixYSAeff*-yiR6r0@8He! zdo&OuSiC^^W>;n{Qj>!~tFB7BI}GPdaDh+l1=JL=TZEyQgF^aC?Omo!C5EROi2}*u zlDW1Iy=E8f&lS#6eYFQHOwrmg>#S* z_lA|+5jA4Rh-<)=jtXzryUfo+=eA}U6M;lrl?{`WP#Gsiy&4JET}JQW>OQwA`KjeJ zU44C~1FINLtbHR4O+zdh3PKN~uhq3EQf03Fmf@O-sxp&m>d^qvDF+y^@kxf25r!_| zCl2O;`1rnw$=7BH*$qY0;o}MN;#+sW11wsn+%A(HEF~`{Cut82qUkXO3?E;6jS)<1 zxe#vl8Cgdrf@5FiZ4B(!i|0veX-@dLvcGTe`%@e(`7Zv7K@QGi4*Vj-v`uS|o{;KT zG8XDvIZUDxYXMdrffeyHb7Y3%Vxk(yzLCo;Ehcm23p;Va&}dylJqT9ATD38uo1SQS zk0{zzdh}7>IVvfy)fw{c{x=+C+%gG^4nUJIHk)g7J#!ncia!bo!NJBytuQ;~$3+?a zj3Q2C3EGx{l-Z7@(T9LIZX1Rt*xw#$lHOq*+sERAf|~1TZXp*o)0?WQzlVRdU4$G- z6&`K52ph}W_ALBb3$%vcH7sZd&nDm%@#9mT?p%Ok8;ViZ{3u8}Wms~5@c`oAJAEhC zmjEnT&?5OlJ=A`RH72VD=AFW$OH+y#?L-#el&lXl^qtW7)TP*^23yw^vFm#sOsA;^ zkZ^zbN!}!8;<)3M3sObvhy3^**FZyS;=Le^s#+P@KkyT^X_x=-&B+<#De*8CbUNHNXnvf1b z8&p}W3=Lzj%u|uVPT&Hs0E%|lBXDmQUAICYc~Q$gB_=52Ly1hk*MU__t(25)G7GV0 zB)Foe6U%h|*oh%?O-_pYIMKF4znxeRo!lj>yq}i1cW2%a1r_X=;K=fofrt-+3i4y6 z*#fVCC8h-V&8+8dab>JjQAQ1edY>&I!GGE4V1hr{RYMa;crt2FsZ&I1e?l_5FYf*B zVPvUyd`E>Sq;Vom{Hb|fVM?4lc?jot;d-FmfMU9;17)wkWpi5W$`GOP+cauoB(xVh zEI-n0O7z!nSlWlLzpr*22o5|U%G5sCH;0Q!!J+RtDq}zVJdh|_NjEFlv z2z=FuwahNC1}B0)rL^+H|H;slAj{j~O>k;uc#u@hA}_}$>P#sqZQQ@F;4W|NAgAC5 zc2iN{d|3*iGwZSsjLiE}QdDA@Oka~2UUhQ@PW-ji(w!Xb8SIJVz3W87EIEtCQ|eOA zq1GI-@t*eAET1JXg15~8@DGhJeqDHsDwDdpmVfD|tCHm7ePW3Y6~Ik*XAEnN1Ss zrH?aA=kzy)X}@uz)D29xY15-%;7-$5iw??>R8$P0*G|a)(%Su`r~Sc7`u;4Up9uY1 zFAdjy$4_I^6erB<*IIybpUx5T4-|heM~?Laj8+Rd?NB=+M#vSL!zEclUr*PvycuMQ zJ*7~B%^{o+ucAUX^YQVnb)Yf3kzm9!e2zyK0k-k}TaTPGin#mAIBnp{7E5sWcZuyZ zDk7Fi&HD46ih! z<-EC!>eT!9d(~+Cv{GZM@1q~Q9)IjxBMC1(wNeTxn6E}YC+G1!?Mb$q%h}DNTZHJ}tjB*NkgDek;J;m#I z_eF+cu^I9Jn*_U~f|K(N&5Qo)MNt#&G)qR8e&8UnB^-y3Sbeui2CY&c%7H{=ggTBz z8}3f|1e)t!T**_{=f)I+o}NLhHbt%#TQkLH_K4;yYlhxlagpopTKidR!u!Jqm3X>1 zv>AOrNuS9O^(2~8;S-4goD3a1eL@qUrhX$9|Lq-aK41bim0as%Z~nt17;`9cUmMSgleT&3APa)r z_#kCu z@))Aibn{9NQ$U0z%56x)0M#DsA?M)GaIhY$od4swK8F-?wA+tu7tC<#>?Wgl=R@^q zoAkNXNzD$PoER-#Gh8`~OO7Wm$+f!{)fg$F<;U74pT#Ym?elFzJm26)P3QP3__~%jW}V&tFtt6ncSR`wKFD zqNG0`bXlo#d`;_Jar3xK5OrD)nm6211HVUV2KFG_mAPx2rZT1n7xkX)vFD8|R=Df6WP z>y|ceQVo4#g3mR*1q42pLV7tMKBQMm#nU)tKRreC#z^DiBQZq9==vX3(CZ(YUQ_4{ zGtp^9zq&c^2)tvz1B8*35@{+7$>}Hl!0faRE%;vdx9kRDx!c0d{+?(I!LIIz?V_n@ zwUO4dvRN@~5S%}&vM&(n1AL=3d0}F_Dp@%}rw|}xd+!G zk*t9#uZu#ULeEfh3|dA4I<<`~&eoG!6!c_r%Un@YERW!`wo%u#G%v}7XWnzNh+y{F zbs~0((k?n)|AM+C6R}dnqb1$#bSO5@5~)EB-CIVJ_AHhG;ED6JR2|un!28|y+h)U# zh0rheCqP?ngs(Uo=2O!N31FBUKe7+EIJTt)Jbd$YAcbp-UI5 zk&wZGUtVZrIV8VnKjR9{QsY#M>h9<*KWcM9TU|h!3f@pe%?FV9I47rHPO%>BfIZAnX=mndb-HuP_8NyXjoVYs~vhW&(z9{rG}qz zGPBv6%$g54wvWOn1i=B3Xu}-$G56=^^Oh~Y??&$hdiI;pEhpFaK|cX7F9r9v!OR_vC^!S^HN#7TJ~kX8LzbSdZKylhI{llm@H$+i_G1Uu)? zmY2^UGizs&D#5Uk$0z76ti$LdEst|yE@3;Zm_3T392o8=mqKC4|Asfqt0CMsjpDWI%UR;&O#8Q?`QN_M`*s%WIX}GSeKEhJ zYJI>hYD_+aKf&LnA_qJbyU{!|r7*kS#urWGZ|(|KR|2cqJyW09NX&{zFOOZ;>r zrc8zSRQ@{=9>q7Q?7t$bBiqeZu4y@cUbT^IP1lzG^IthUlJoReuM-)HF;XpKO?~Ug z*_mxwxuqtX!qF1tlIB3(5EskYvO?PO1!I*QUzPhglI8(YRsVS0FZUy;mTb8;e$9oX8<+?-zSfs%wP{Y>rCD*I8AIL-3; z*_u$|_M6!eFg@^!g+v{?=&D#^`y;x!L&~<577r|R3jtk50~-&~lqOAqO&Cl~x0e%m z{;-kBLzcms6)la6RoY8`l&ocf8(W1=Dp$*vwkMDK8R-`+U*Xl7R8W(o1sH_h>?l$} zYY6Ms^24QTm#!HPjp-?4$~80&jCI}r6Vswitv0To7x?@X{57-LNfHMrVjWhYh;9d` zs%y-jTjm4SZ_xjzs6`T2u&5=5FNXMreb8G43rZ>Fg1H&hDEO@F1G_^#j(+RAe{%Rz zxye{#-YR22H9jG!mYD&_KF+$NZnmwr23&Egi)!Q40d-!_RgYQs_oLXxo$g`LQE6(^ zSP(pqu6<7|r73T-7kb^GZ(IM|vNqyN8ms9S_^505iKgl71APP|i#;byAf@tD84dSU2}QpG_k!VspfMB45;sI&Qc1uL@Hx*sQy<9-n599y_?*L}_ua zEHDo|*Re0hqcSrvfu$3th-t;rs?R5l@2%DC!%0Q-iY#A*$)k#-D3_JD z(ic0r?Yk1NXEwKO*k_0{99Gckjg|y0Qxi`sZK`OeGqQdxPJT8!8oD2^?1;_r-ywQk zso$qEn>+e=*N6+H2#+n9-|olX(^xItz#A>Ro89+7;+wDd@7KzPRR7?LP?NszWr&Xt z+%M>4k$gmLKTzCl*umw!mTTbELw3=`9DPm!Kd0A?VeRaK4v`h&b2;?m8~7BF)Ldw* z1^3p^U5Ja*lUQ7@E^NoH>em(O$I@fjD(O{Q=?C%-c;y4>V*bpkm5RRospVvT9^j;S zSJ8^fB;=!6imXj!FQ~k{hJgae1!x!Bz2{WUdWC9cVF5m*V%f3ELquHgKg=C23luQnH_4EzmuW3|T(DAL5=*iR_p8=VuxayTaXMzHt!N&aX^Hv2F!sAw#D*ow* z*E?)C%g>L04$|~x+R2Z}naLh;$(>9ALUkcO192bv+sAS#vN1M$Ug`T&dg1cv$+USV z$g*v#t?ACm&rnRWZf(K$ZO}!6;O}}vs}E3ynT48oH)Zfswm(HLbng`!Ui@H<*DcqE zIfmWF-DcZ*vYtB-l?1up<9*L~dziE1+@OCnFfP9g-w!Lhb|6Bg8*=)1COb#GhdY_X zJa?c00U3N6ZB;ge1wI05Ar>Ql86iFWGQK^Rw{sz_5Z9*-uMKpKw@q_&#GSfsAgX$$ z{H`{)`S2wwAf6)hZ!QA6ax;W)`2BG)G+r3l8T?G-82r`+Ja@n#1mM4#V4o0*a|DHJ zU#mfW3c7Nts6j&*6(`l5eo)Z6rJ*Kl`5Ug#o&0>Us(4czED`;LlHn!D>(8#7{ij zOG({NBYYZSTKH>OT2(c-b8YbXk@BQeP{mg)-6NwB*HksF%>sX*y+bzvR_|sqUomx| zfpTd7EBWE%zQpA>-bh=MC{b} zi719m`MTdU=SPKSzf4y*f!rRAO;p7E%@hLsZtRCILHxm^V8w63P5O%SmaJtyj z%Rp$0`)beQtXDb)o>vrSz&9!?E-ws>nv{m;qCRKqk8Wwv0{s2ryFVJ<&HuX`Y!2a{ z&6%o~(?AWdJi}~D)y?o4o(E94M^EY3y6Cy-*ai0~%z16Ol*Lk65<3q(ErPPa#Im5v z{wyk{I`!ST+xCii5nKqx*W~+*%LekxM=AcBr_#J|adE%jmKAuSJW$8gzO7s2fp3B$ zD8+rxc+r@Eo3rUjz}I&T-yPRQP8vAa-xru2p=9rZ_#kf33vfXpFz9g$qWa8~7Z!-A zGGC&=CH18$>WxW=@yNm%iz8pPdL4~FObY{fyNgJ2LqA~jd@rxP@ID^4-1to^I15Wp zCNnaay*#JO@2t78uNcomlf94xL(C91#0o@+WaZ-O+qQ%^?qebmOsXF z`y&P_ohZ6uzestDb%II!4?lJ(?(jIsIQlqIo4%;JW9>x2@Y_5AT!xheU8p6omRD`T z4n}@hYOYjby0R>3RkK_%w{NkLRMC(y;d{qq$kPfP6#W25;NY%^1WwY_wp%PwkwN+uj150`+xS>I_w6XoAM;jA z$DUStEpw`BeY@Wjj;JCXP@M}A+cYH-Q8?ibd`x0k7Ilq`0PdSTgiILCu8{-tepeOttg3Uj-)de$8l2{CA z00#CW@Ed4chts0I>T9XU&+hakQn5c5p}o=f492}?tDc?10j?`btp>V`W&2!P;eG4P zo{0u^nEJo~clK;kG*v+2j4f|s(k0BUZv$;j@C~@6)Z=AxE$nJ3XkItHR(N$ue1`fH z5e}uu#~aJ^C#QE~w2k9?S}#JK0j=O~ZVD3p(XywCavnH82++f@$*4-SIFPe~H-*sW zD}ZaIOf?B=>215d`omTC@ws^>SHt_RgBww9(^t$Z+GBQB(FBKW;bAz3%j&kowu#9# zV97@J;JU4It#dO4$M5S;U4fX`D<>q0LD|DpY7O$A#c;9ev$eSwT zh;Vd}WGQufd)xP;1VgX$5KuwKdBgK+{_td_s<#rP(#TRhqBXar`OsmkhP%7|r8-8u zRXnEDC-M{232-}5X7PN7!T5lB$5d!T>G7AYbIt2+{ihSeBkC&-jHV^F&0{`mI(_q7 zMvQ94=0St`EonYFcpzv3Dg&bM10=^#R}3}DmBH`lQg0stB8ZP8a|;7IibcIq*yUfj zV3G3nebfiDRJqU$iP+LOTl&LRAv&-PT9DhM3w{8w70?G->#t%>@z4YA^mUUrBd%|? zOaIZTI6gT%=r4hG>BQK9MC+w9d*TN&2PAm>^DB0~)I2GrmKy@e@0r-AzW0|pHbrYU zZ1lqJQ+DCtgU&=v+kdy4g%by`pzG1=c&^GHs~q(QN3l9twLsm!YD9a-mo{uCz{ z*C6ksb0|5v#L#AZ{!}~n-y(-7YOU5RJre)Cq%y?oz2u7CtoGAQh}RQMGHcj4)uRjv zH?|>%i5k*TY^O8S5ugpBO3x4K%y#L1FCT3eQD&+8>*FPWzxKn6qz3oYjubT+PK5v) z&hH(O{y~ZN0p(BK#I7Yz)oR!H;7=do_fbpcKPH+|6$SBiF(r21?a$qimN}1Gw;%0Z zc7qGGbAG73M&B2^aX<);-s|SEO~Vs6miLWI^Usmq7tO1iYk<$w()!M}4y0$A)~X=L zS6-wCzHz?z8d8wO=?&4U8`1Jw&tD7tcD`z_TfspYSg%Ba*3350O5qo~Mnqs`k|DbK>(aztZ;)e*Ie8_GR^nwcr^cu{8F=7M$@O zxq2TG0H3wOa|j&Y5RER4DcEV2b^f#C#5>r~;q=&3Rd{f|A^X@t_6Xuh6x)uCwR@x9 zc76*Gi}mQP_f>g%-BLIQf^UxSEpR!|T4%T;_5^PIt4cdJZ^_jag8D3)u?#-LgER4Q z|Cm{}ZE}1#Gh6)$TTYRqb8J=^gh4^+Wc{>UE$`fxu)Lyb=i>j;$m?m;BDP?&_+s8y z&zyz##RmM?cv7im&b%7Xd{QVj5-G&3&RcB@+HU&cE47VQe`Gp@P6^|+Vz;v5-ok;S zRbjP4&Y8Unb4|Jl+c$!Dg85HM+rA0m>;m_oyby=gRcxqUfoVWklSa=XYcHY2N_n4=Ul%hdi*ckoarYcp7 zCvRqgPW2!>t1e-B+oQmZ{F(t229`%E_+9*HcVvQTiJ*{o*xo_Js}%EGVHEWF`cg8l zG{EQ?Vd>Id^}4KT%i5)UeF>mS3qSo6wtyD*9>(Vj%CO{UQfh>(w5{v+mW7-tR9qi^ zT`2Bgu(?XzZ%R;OvsUl!YLn!4=3f3Zky}J1UGWADot)68us8PQLbxdUKCZ!+5_Jmf z*yC0P=zs=xlJ?6?fSUHNvnZ_cd6rbtDl^gGq$}C(TK#IQY5D*q_#S+_?7L5mWVYBRu}7* zgxnX|3m~XfCArr9LrhM60wRqaY{x*gMoLM;zzw2UZ}LjC)D_XUg___)5cZ6g;Jp&B zIONoanC9@A(1H0z*mw2p`4UjRcJ+K&KIe-4xTR^+BDYc;tUFc!dJrCestt`DTxFeXyYbqgA4<1r_{+vZpk6PmEdqZ0Yn#uk5fPsFb@|WI>P#n8gQ}A& zGEXE0wa}lOhmgZl)pBudBlcA%=i;NKjCnSn56k#S*Ni6DbVY+(3Mnmkq^l(pF&zUb zxy%0IGjx}LhP*;m1H}m@n0*X-N#+!^j(bYm9+1mhTdItuC4D(N66lGc?QAvE2URa` zz8AF7b zaV^tK9RLD`qIcTzH*CYI3M;#2@G~LRucz9V?02_L+gpU3@mEYPFjH_hsm3aYN%vPgwJS1)M3a5t`4m8Ns`Na9EOP>PclhKb2(hTN z>o35qQ7d+^0!cocpG!HSLz*FDxglEgc=6is*L~`mL&?+9chjN6?E`qPV5!lqPib`Pd_E%fr{Q6#(3`ojQt0in@jDn2Th;3v+UIh7|<-#)|Tnt zg?y7rFZmn^SCFzP%9{M!nVcuT(M!rSV?m?JnB*iKH}vXm(`w4!QdLvQHcF(Pm{+NK ztBkJ5^M%a`O~zSHFdTTGVL})>nUh}o&FfX4ADK!d9t$}H*)zprmLV;3Y^YSiN!-BG z(79?Hm&rWQ;L1rQHBq_Dq%Xvu(ZDo!6M6Z(@AwG!p=Bky1my%|E*({`_1-INarGu)f^d*Kl7YuNi60{&c;sMex*siE zeGVi}zISz6F|Cu{uVhgz%J0}#WAmJvo=0$65v!9vbWFpspxcN*gI@xk0q&Yym&*VT z8CQV*@y}pxwGh{;pt){x>(JV$@zx< zg8DtpIFQ`jc7DZsKCOhr!ooQq*yT%6k$EdRaPlM8xG4R1DA3<;n7Ro%+I#g+%E0|J zER~ji7{zOc#%pZzg_u~i)j{_=`zylpBhI6Po>x?$>5Y1$Pq>=m+_Gx^Jx!B%O%)p= zR-Y2PtLrugm#321iELq4DhrGD{DjX_<>HFRc#=<5mCrbnS)gw*5U7ARCTW=G&E#$A_ac0X5*R|sIHZl#~146UzqgUD;6pe;>P}6@27Zf z*C@kLk)%k`7e@-47dgM^9oRGI%B+Zki?mT&Yp{B;@c_-Pp2+y+%66dcO`q=d#g^*^ zXGsHKoUTT2qcDD{LVWiCm!0+`sN=H)!Ow4Nulrm2{G9IWhFcr5xs6o*>#1g!v!%SE zBJqLwB~XRJSHkJet~R0#18{l z#ZfdJ&GqqRrTik|h<-$+*nS zqzpA{=FwXU54N-*%svI~6FKo`5WWj|fp8zz=KLj2sqWR7l=PHKCR{R+PY^G04MAZg zjc`h)t!7bhDC=-RV?Pu}4Fj=WjY`HsqSCy{8KorVxIMluV9v*N|L5m~>Qy>wFSiEg zpoB?1V!xOA_CK(~RY=vuCu?C%M{Qx~T4g!2D%fOFkt@{0%N%nZ9<3fHzXymq^c%gw zK}dUoS)mTs+tQ{<%zC@sW}(AA)Q^7@=i*X(VpzgIiVKde2t8>17b2%8NWDM*!2Aru z;>&1(7;-YaM93GOSL{LwrtQ?!^C+5YaHoh;Mw)VSQwFGn-Ftc9?cJEu#9|YKy9Klp zvBKWk<_|gnquQUj$q=;By~<)LT*}eKCYNfQ6b|Jo(^5_A;MuaIq_Uc_iQ3y`O=>D@ zS9r16O;_gVH;9w_=9pd*iIF|JZIjWa4C>=PiQpx5VO25EDrwUmqbE^_3KIoz1#QI= zq0UNVDq|~Hy&jXK2({1J#oqy1fTVx9A_6$H+SVUHa9g+M8KCbW(zA5|YSjT)(F)C? z8QTV>{zsNvpm<{$5O*>eq4u-9ynV8(477Y^s9B?GNva7pkYqUfWkRjipH-}=1mu() z*@y%Lz9jIe5OOMMb|3#H=({k-^Z1}6)TdGBX*p*<*_pe-*q8kV$;CBp31M8MXCOTz zY(`F4(^^8IXD%3IJ6-#kdwd`_B?&8=hDdkthHtw8@mf-Ol>HiD=YI5T=>Mm{R9~1>M2Jcm|S8@ z;~aMradLg?^JjcwX!HeK;<0kQ`g5|GdLg{j6igB;Q9IiLnTK^@2aa?~14dXKl(( zx!u@P>w7LOgY>wHh1iHy^4o3V$2S*u^a)$>Gx*Q@W>>qj=Bh{+11u{ar$jQ;Q5O5o-;#Kwv%flx4X?Zw>@IZb)#9z>8=Kt77i8Lt^l|n ziR^QL?RYi}-QYwhHn>C9?&~&N4I|o9qHftK*&S3=RP6Qn=LygEx%T$aB3+=*itrlO z-_vX2=Ya$(=rl|0;f=8{O$*4r+$qnQBI{~*>$zqd;mS27WqG(FU$fkEaKXKkD91AK41O2_F8^J_i9Xjb$VFnHnPyQEQ z-x!=(7i=Bdb|$v%i6^#g+t$Q+V%twLv2EL&*qYe9dGD?IetzfA>DuSiuCA`tRlBiQ zx9RcWpLwXN+t-xq=C+F&c=w%ohD!QfN;|~KuT(8~SS{v2oe1#Ozt@g5v@|(+lng0< z-;tyn1{Ny$CbHkLcoToEK~cXv~y1!zVQqn`?retXaJKh5@U zd284vAlZ)UW4q5LAlHscxd-vQGDI8R&Jq4`2770dUt&FC&ZD*(AA^mZ`ZP?(+gq?f z^K<=g^pld%fO#>o)2NN{K&)7yuZ%Q;Rc|aBTl;9F@%X?J1)hdEQWQ&^ddi=S3)1*1 z$slvW*2V}ggMqN@J{t}l#hA6S$}vLLqWA`>AzgcrW>yS4doJdMdgA9-*$3Q) zkOau?@z>8>$v55U{sD#S6QD{-@No)8N6m_(IF_2@(SXdePa8jr{Fb9{DVwaLOs;xD zQhM@<$?`1{6-r7UA#rg-Szw9D)$%V=E<#x?hX@UYP@OiJ%HO21-67C=>faN(MZh#( zYj(=4%p-j&Tbq{yM4#K0qMy3Dcl>b_*Yjf-u5s#~;-RvrJpOhBD+tNBUFUvg`ej-k zrgUz4iC(`Pm%Rm(+4qrsQd)gs#d&`GM&gg%eq{z)Eoz9l(B9xOdl5DDNHD-X_6V$g zEvQn(;!!_53|G+^+Cu z$*ZN`PwRU{piuT?X0oJEMw33F#IX+gjtfpFUAjSP% z0BA90PEgUZ2bIo^{*6Q>{zwE8w&Gie#f(;G!!i9M0b-HRJPavgEPx48*lErw$s2^N zBLt)k6ZIlKJn&%nHn=F}Z2-7eEac2gv`+l&L(D_&vA;!$JWdSjDtF^ClraZ7Hv;9L#i`X8k@~vVkAz z+IWzX=e$1E)leIeZbwU<5|*!;Tf~_E*ubBkXJ4p+E(^hA6E-Bq4Gs;C$k-l~jpkaf zS2WEmojl~r&<|8ju!Nt8)vRPk+ZcUsYg%gZX_1Gv)xy;3?e(oJQ)IqM>=8k|Rd6Dg zkJ1V5L81m4IbzcZ6H(2P1;@r9 z_DRaeA|TVfG2*5^!);yJ2!Tr87Va|I&9<^W`Ywzs2TA!Y_d3$A= z0W+D*`lNf-l&@6@7qRf*dUB4K?jG*ApVSx3PI~TuwPctoVNW*u(}ORKaN{~4pd0lO zqqhx#Y7&&G-jo!olf$-HE5PCBAv(o~?Tm@%UIM(Z6`Q3CKt@gkV>%4fM9B`~*8>~; zQ*pcKqL{)P2b`{(bBl^o16_YiOmwHiJ%*@UQ$U>(M2p$tFr4~~x#QA70czrdk1o-x zH@xhqY5fSsH}*r%1pm2=&5d(@MW*R@9Hga2pSWZ&)G{zyirOh9g0uH~+XKZfm?I}# z*l3Tno<|h>z|kju09ZZ|On@}N6ha_qXYzntWL3wXOL^PMpC7QJMISfA<7GRfz=klq zwFh*H+2M&AL}CVm5(50aDh=*3(axo8%;s6+lYu||I2F!D4fB3MtI3&(*VjA`RuJg@ z(U~=6i5i;YeQ@K*xCVL=O^;RVY(b)RIp4{T_3R889i&AMn;U(hscUq=%#4EqPJ8pF zrOQ`rdOR{V_Ks%0 zjSCHC+LV13KjxB9l5b-`82Mo?Fg$AAp^!4~2{I3Q(W~<~F5#F2(Oq8fe_eiYvlG~Z zbRWB3bNujshg>FEK?Q86T*-e5*SXsm-{^1)Uikw42b;XHJKmV+;hFu97nZ#^8zYv< z{%@JbGUw+PcMO{!NYfV}+ArAojCU~>ReZJPE9&{7M_HBmv5gGnP3&I>i@+*ycqU*< zJeE^la1+xL?^8N=xYdlGPCj0%4!Xsp5hWLM8=_L|`ZR23VTPo}DPYH{bL1C+&+JO{@pRn+< zht!@iq7&^xWC}EGWwhbaDuR>I;0JFy3(8*G?gc0c;0=i!H74)iAwJN12gU!iA4e#2 z1P1wPB}gNRc`@&+A?9MopPJBD#HsH06ORu3+fSrSD&x!F{DP0K-xZgEZ7zH~e8i0_ zpSi1^!C&y@vgkG7Ja21M{?Y#18!`8^5e9+mKLn7#aWmbbXBCRmv7`eVAuEXUa3n8yK^BEEOho!(16blx^!-9q9`Aze+$TMSL;;w#i znNd-gnNd-i4FsIJQc#=(NSm8WJFBa+zHKeS5Hs@@`g`+o((9#rjq) zmy}{tlJ7feq>!SztRgnz@Nf_w$z|qH&O}N_X`{7Jvj#C@&^Q++6=97qjwfLB!H;7x z=+^!atk$fvoC|)TNUuOr1QViIrC}f1pZlT>-LzKsL`~ighG#T9WhkM3#*c|6=S_)x zfcq@%8{+?G9jN6^iR3%4w=_OV(CG#qkh(2 zK2!AQzjZee{P7iaanB*l_u*UnWl(P5OKo5u;U2g0xm#Jcu+ew_z|Yh`-1OXZXoQR z6k|U9k9!+2Ztg719rGCi6|t2^+&^T}4f++)_g+p+jhUE8gdo)X4FrlH&oi!s$gc~d zWkRt7y(w+}D#(BC0p_X|;^PwHb?}NJ`XA)eP&Y@OQ7`^ISS51(i7mU&TCzW(=YIMk zjX+pWAXCZb&^2_q@av|Ba<)s{=aJk!7tTjT^w1DUJhJrn{JUZTK1wGE0?{wh>_n3t zzEY4chF7qyA9;#QNN0A6Fu8`?lT3@=`StaxyN=Xb?#XrA;{+IKObFejQ02Cs=mBKQ%}!kJ5Y=)w2x1{%cnX1VuY~Kcx&1n8c%x7haDR8LB#5?5l!jU zp18c{l-R%kBeHNF;kyuZnC0LC2mZw$)snq?foyA*xp1Y08=7l`S!!4udL*=Sv23V$!J?}z?#ew|NM-AOc#K9E}kaxVKKJRmHNOfN>*L6}L{ zg@%udHH&hs(DLx586HO%yHgFk8N*(^qvc<4+(ZU;pmJ=WaCCY=Pzg1Bb>0g`ts%4Q zgNCK5^BNqJGL|`ZrZ;Mwwrb}A!n2ysrbD`e?ZE39+xgkdJx-YIlz13;5?jS?f zrP8o=^{BlXll%ojlc>X=f*+$Q+PG*X5)}C!^XNPBh^O~p>?u=PSZVp7zRe>Cpz9Ns zZ0lAzT*U2A%fDzB^rMK-RP8*8#h>=|eHm^Fuqzj=Xs&BJim`^P-v@mvLZ@Y!798C9 z#hV00Cmi)96910(d~a}aVwEQk?eY55SJ;c^CB)BZ2IwTNN_fiWxJ}>cfzKWITu}jW zx~FapHHEea)(pG@4WvZh=;x0eet2j6|KuDWPBA&n6Dk*_i?XOLVlU}q*QjBD6K z4HqpFujY;YLM47LuFBp#PfPPgnH%mL+QqMrmXl3+7D?SgF1@FWJ}BUtw3eL7=U-XB zk*@yJWSb9JtDDM@C7fR}YIm(@$m)QEtrbBzsW@tsZ8*wse;wKsROHu_j^;xkYqu)i-bxtS07 z(Q`INm1~OEh!fI-tBdcc4KzVyc{3hi>T!Mh5V#m{$hXL&HqV;^E{DKsivLl|FGw0b zH#OWlPcks@nQB@I%&nR0v8m}w4Zirq@P!N@=ku%#D`*Si=^XF#01G`QhnuSR3jPsZ zJi2><<3GKVLrEBK z$#u9Cp602F(7i9os)OEK6lEo*g~Xl6E@c#jFu(e;M|chf;VeTs#*jh_J^6^1lkfbn zeo+0`atafa66|jU$@Rz^>hHvT1|7-E4_}v$rl!^wF^Yru=mcQx(zAcQ=+MG34;9{p zRRy6N!#M`Xv` zJerdSInqA5Qw^tFTPhte4s1)w9>5oCXjNW(Hzhx`R1!rGg4of13eBbXzk`5)c!H)R zZCa}+p@goS#&JifDWMjRw!y4N*(unV1pHntY#h$cw2amuEw%C=Yz#YKr)bfC7?&X) zfWD3#1YWza{X+62%j&Y2%FJkDdy^&CTSAtj&1Ajyy6A2Tk0UqVT@*w5GSv z7X5Jc1r>DhReCCP87cL6J$tU_RCDyDh@$G|$(=hpz#dt-)-_mhlkye4K8Y9)5G%PxEG>lSG! zxZp23xBkEi^%jXZUA8PWA~zr;afiUA0OI)&>PE!YXsuJ8S;q4g5wsXq8Qa6PQE%ck zOzraT>F;@!zZ~LNv|zm}v>h9vG>Ci_G@(EL)VVufNh=g&VO=Z-_=bDwv_Sqf&|jC!Z@Khc|E8zB-K&o3E!+&up8dHR@{%t_<)`4phKd(qEoW4pTX zgoK&w32+Fbd=B{JNdk$F51Q+vz0b$4sDrYpLmDv@h#hj`CZgIA%l@6@M4^kT(WmAF zR~=TdkJn0B9cr`B+sarSe!dUYN@D*Tf1k3I#y%`-AFGu@eyFMz6u%BO%Lz|@1S>m; z%?ZmM@OP)VmC!zpZzuLdRH)e)A^&_x%hdg2RqtbQ{Jt6fYHFlRg5%r^2b{{;!w<5T9r##`e zqFQ$Uc|vbRdhBj`B5y@M?S4Fi2u2|94m`sMM#b&!KSKycD(o&iBM3&%?A|?tbw@Dm zPCUbPN7d|}KSOm#I_&;^M(U2f+I@Ql^^YLl9eIZJkILIUeungqG}v8vM)Z%~-hFxo z|BMjYoq2};jOy9FdWQat4A|X%M*fuf`AbX|Ni89~Q&o;bRmP1y?97TDP;|o{L^)5M zDN8pu-UwGEtzyZcowJtxWJsaeTLMR(PTi}XAC@(pi;EF*gH!@r2NQb8%?e^Ge zApVI&d!&7-&WU zdB^4gu}{RkBlSx)PSm^s`arG|Iq&GLQjZfo@3<`>@`>ncgkY({iOOq?Adu-q<~6Fj z)Zs+uHMSc_d?NW8>0fGaqVWpw2MV1iyheYP2Ami`Nl==*w?+wE99mcJYFF>G=+2mU z5yTzC@+VN;n0{mHNX=6%x4+`%?7Ja+%;sjj6RBq6{N}Y2)L|6=X1Ej9VLa>Rs1wp* zOvQ`Nen-N7&pdZ{p)J(nS~hn`=Z>?J!C~a@9a1OR+v-de!47Bc)IWj)B%~VxB$wYs z8)Gb6k^9*@*v`mL&bdzq;u|9$x;vyy zM-;kypo}h|&|VSYUNlVmU7ikG;ZKJjo&kb^$Oj?MhJwG54+owd1%u-bik>Y6!{QG2 zpFIVG6b_PlgJ`b0!MlRNQ;3(N7Otp$$orClxzs0-Z)2uJh{-pSjksVl1tlVJWF77h{R)6$00YCDJ2(m9URWIE& zS|>u+HH9ytWN&VKxcDrxpJL!$K8%bZOR^ydtzwukPB4=pPHLa>D*R(m*DfbF@neXe zQ2;kccd)|_(kF4=Fz^o7mog7BU_i*1GY|ZW^t#QLC@*dl`#RJY)nGF1y2KaPU|Qok ztW`e0!AZX37_S8!n)?!WVyg+T%LM7khi^>AK68cpI6xH~bw$ zXcYNo;2lP2Jnm-y9YSbK;by^+PxjvgW$t8r65Q=H~nzs%OmM z=I=XF&&1Wu+dF8$DDln6J8Zys-p%nlWB{zkt;Rb?z`%At)isT7|Mtz(JNVbA(9O&{ zd?(b^UClM+H(CdLu6aA*Ep8p&`M&xBZVleKz6QQ{ck)G%1`r*|Ho#i?MIF&M5ReCg zu0aT(H2TRLkvHHycw$u!Jqefy{;BeDIA*HATlAh@SE(Gw1V!(PalKhUp>KmdO{;&;cO=)dv4Me(!4lLpwU*yjy1qf2`CZC)r z7Rp323Lp$u+@q|pR+@2F_S?1pJa)65Q!C=%%n)f#RvPCjCkY=s-acyP9_@;+3gPGj|!a&dHW34y>&Sz|Q!QN*#s_NYj&;-n)tADxnh zPm&t4mcxgEXcS$TiW!HH(lI=SUv;%vFHZL~Sw6>JaF~kt!2koVoR|coO*v?1)U{i? zc~|QSw8!YMnTSUml+7O}NR*uZh5K(j9{qL{^c1;=MVo@eG$vl|7v1QbC&yp~@^FPw zQei1GO*yN~Pqd+U&&gKfy<7YNCW*lqE4Hwy^zQ+-it)^XxI>sobfdVQhcJ`X5F|Il zgB8s}BN}$jOD+R8-_U*5fh4)1OzO8(-7rR?Q^$AlU&nOPD7G!hVfs<~z%rKj_A@%a zu|OPvIpB`ilPp$=i^}$&=Bx(NZHF0Uz&Y8ncV3P1vU9y^WmeIC-h1^bIEcl{y}PBT zS;V-}+708^(M}2Sp@KMZ0;P!v{0L3Sb+_UwGBd*JctXoK^(FPO<5s;DYKS3(NL)Y^ zE(%-zS*UqUp>iVH5;|>JMBRt-o(6>o7Yb@Ih0taDKydO8BVxMmoy@d}n5x!Q6_eoI za@3WC#o{@w<||9}=-C5ee-wMqdN^2WQdsH)Y^y~(hiCF^&RXivcl%u_%4on!!<7n?Q>3O{Mp?6jkg3=-+DNB- zo4wSvqFHd>Bn@Ap-{$tK-mMF!JWj&Q4^`M{ESXeSL)Aes`dcq*4F;MSc*w&RQv1;H zGE@==a%sq_5y91@TUaH>ibIwHaYeMkJ&lPdLUf&g%Ssp-;Ylp9L1HKPi$SLqBzWcE z-(u+Xu~=3bzsO#};1@*75z3JDnu7T2l3}8Rewg=WDg_zTf7mx~hmi$0{xA#n9>Xhu zi=ZNPwX-6n4JTfrqHq4RwSov8D^|R8Hj`;5h(dMJAh!)|7ZFL>r|r=E=?re4a9{FtDwCP;L#abN*tI4c!lLGaD z>a2@-fD(oQPAXIkqaN7z+mojW=S<}SF~vP8;h&wa?XYh9+T!1b(uo(F_8K#*Abo>@ zCY8jz+6wX*s}^$X8RqI_&;C>zuPzxlu;8+v#J|JdkWR35xJX3olOh_+Y3L%OI>zX*%6qReOy>G3gnbK7iWb{Cgk>Zw9Y0$l?B%qGAqHV3tZCQ|7k;R^ zbj7T~wrgBqk^N5W+WjVURktRrAwPBRu_&!MAyvdmp<5HctXEON07Md`R8d_La5w>TG#3M?F7X7M z(q!qKRhu8z@@gbrc)#}V&J5y?o;=ia+)r)jkqWRtDWLXWq2Tc-SWrLC_Bh$w3&$|0 zs?(36POB}Qh7dF+U5DuD@bGo#PNFC^*gK3f=}J4knbX;HSr#xaC*=^UEnUTv=rZ+K zrgUfy@bP>RQ$Y&?+E-TcP8l)bw_;}Z7kV}h_;JB&YF1U~53s!0`q!6j>#|QTr!mKy zHp%AEPo_`iD}Ur4jU{*4x$kAqE>NN$BUt}URY-Oz`BOJ>_&b*~gT+GeZ+B;@g;*wl zos&b0(}#EbrQ3EoiR;>ZmGM?2Ysnh-Tf)2(x#4QjoWB0ewwdBQy~LUsIM2$MlU zcbTTDcKRM`0ynp{QU#5i+{18a5Zr$6c7%Q_X0+uW8nJy*}R}ic67wAq(CYmgAFDx>I|8*Wd4cC8d z;5X0#r;c1oHh%i&n~$osSJ%lc z!Gq^EVlZ-`TwP?OHe@$TmzM!bp?YRm4OdrJ>20mc#}Jd3y1sAj1AyfP;;Y=7&gy#h ztsP7YLT-ln1$E6GtJ`@j_4ZEH$xP;Y9tL%W2dhE40sd`TJ;jCCwaeTYv^oT6K8ceB zamsdzN0~e7F{VpqcOfsf(j zD03)^AExGIre$D>O+UYR>|tRtGK|yrf=qc;kmBjhY0V9xKq6eA_`h>wOKCQasY|FM zPqznNqGDnYs$#{sVqyozDwO|B*JpBa?j~{td>$`ykEgn4WMsvp z*ke-@W94#~L)&LsxvqGnIpu)`7^}46sF5FY?rfYN8p^M-1RW29fpk{yaxkae4#`yo_nzwAv7@n_Ezkz$cfa(n{0E|yguqhF|T>d_eDKF|0kf8}(>HE^r2r94WoIPL`f zPf3!hf`JlQP9f!MYG{gR_wTnG4*rOmeN+^R? z;sfdGJu=_y^Jg~uy@ic_3vr5g2v`cK>7=`oto!)rlC=BOiITYclq;!#Hf^YJ4(BR_ zR1#L%>a+w_>ETiCj2}s6QKqAMw{&Ak;if_K$wTfHVlIcG@$17q|+C)_3K*a20LxHeSRIAwx&n+xC7H%kH(% ze9s^nO;4d5(@t`GQ1;C})~E?$r=*+z>|fV&5Lnyf?c?WI)!A$F&%D4knzn?3Bszi&dM`ZPPUDE)oUm4YpE6oyEc@Bzb>AkHYd;-G;JTM`ow0BeF|% zWZo}sWmZm1TGS$~pk@}9w~J9(wwtG$o+3=mwPgY+%=L`@58IVj(kr=W=Hw`uPHiX; z+jXAKvb4*?AIgZh$~nqcY9d}Z%h_Vx#vQM5HL*kj=5b{qfW5gz=aZk^Dp&5e@}Bx| zM}Z{I9NbU@hX)?LaeX~~`e(AOVBVDSF9fy_3Pum&7M>U}e0&e?XS~lb&<#jENqkehBrbuzP?7L=DZE|r-M@h8j8+^aTx za9?cIUTzpIt$w;vTd8RGPEXqmsShi zf-D=X5aH@zu0u2z-5Xkm!RrVyOP5w-&H3uqHBAPVW0r{E(LA7n+r*i@E3t$?11fg$ zSFqw>g7Rj-gN|Crk5AB^d1+oD67vijpb!RY&-OK&=%=)emM%kxJo?()yeE%V z@m;z4?5tDHn|n05_6Rl*NVO=4V4H@Go?w$W!$N2$ktWO4eY@QPsElsM>{;U5BWEiu>HVaXG4PW9wPP!TCP?n6U$!E=0>^ z)k_86ax6H?5lj1{l~2`dt|LEK?49`j)&a$JqU*N%M!uX<-c##O4B4SxL#1;xQmxw6 zOE^Gl`geK_)ROZkJ@lc#UTsCE$>aX?HD@`y58Xwy9&-1U_jTtRbVK(1Z}hiu=s^Mx z%E_cZk9xmk00LIjTc%6}6Lu8jaLpdv%ao1I2A6S9ZTOz9+&>5=O?UuTJLTD9Yy8ny z$1j}`cV0X-N2FVZ=Ovw?28b#HutvNN$9hH*>6p_n7S}{uGY)qof@swTanE9!X!d(a z@8X)%0N+fV0cqI&qC|4N0q;{>PALbeR8Us#Wx2442u)(CNW|pD)rYzQPKoi~s|2oa1;}#D8fi>c@Qb6IY7))fqa>YC36B z>Y#WCY*LGyb*)SEyQMEEd#&y(1r`WEcE-nOWFabi&UbBA=+HR}#Es z_M8cUNfBQ1_c1pB%elXNG}iy861AAld$tO9)PYdx^1VEZL=!cSIqVG0@z zzm)_o5F>bSSlCeR(js`ES)d03vc2?C{9;E?ef4qf!xL`oYbN z7-b;XgXB3{!#z@RhX`NyK(+au10k$(b!zcZDR<>d_wKEqfh04?`BZO&*5J4FBH1go z?L6x?sjM~fxNG%7gpuzU`?3Kxy=N+`O^`EwM&~QT8ogj9Z(PCl=J?YzgOtdBHUIWq zH3z&cJ#PCKeHeUFb`<{8SX2Aj_gGVSPs3$t$CM0x^kA@Pxsp2(I*~Jfx>Q|M3NUu1 zx{~RXnQnX_ccr+J+KR*3`~`L;Hh*WJH|i5#{OgZdNGur}M9#1ezynXqM49xwYau;< z0p>O4aZXT~CR}dX4bMs>O*l`<759o|%b>Hx(_)T>a^c>BSH;CGmvOd)a_F1h>-LGU zGy3K49Oq_`16?P$6~`9N+4a<6&SCdSvJ;b@y{_0m47_FQjs7Z^qJ^DlY%<%%5yibT2p3X;es+Ra&fzpQilzO%V z*-=*kk+5)0KcBEma?ypE(hV(u+vFRmz5HXHPIHqW=YjFG!g={Z;%o8*t|#CnHjJ<6 z!#pEIwpuKk3blYso*3+nGH&>;=%yKON9UTW`mRW6T?hnpl63FCnrmnVvgfqf+t>Eh zoy%2C#$4u_?a>wj8ylMq78@Cs4Y`zzh_(nCTOz*zkwP30II<7?g_d|=kVr12ES0F5 zNM26<-z$0BEqmmcJ5FJH-?MvrU+}S8f5lJl*ehqn>*K{YcJoJ|=H!mNr+~LQ($BpJ zoijMa16Ld<5(p4%CQ_up@Lz-6)`1eO7-PT0@mRqGPPpOf%Hkk&gUQ*2Rf>ze^22|C z&6S0FvWt=8kwH$ONKn>?A=YFCh6K#dk&WzG{!~CBW-EuX0P~(cg?L9@Oc)qmWX71~ z2AZriH!jYo~_V_<6X&r zt*aZd&59j%LE{~BWLL6LdrRaa*O>EmL1)oOCWE+{mPu(wB?1uos27cR&5b})O$3^a zu^;zg2#K90x&JCj4uMB;DBW9z*91@1~lt42>UZP%p`o2Gn*^T{;^Nnz} zz3LaT=W$)!zfHIScL*%GW2Y1dY-!^3CRdGkNINL82cGhWe%Vuyrxd*ELJ`C>OA;S| zYL@n8%ltVviIA9TE<9t`q&dZ+T?sCH0CW3L+3<;aQG!GZE`Sry#I<8ivxqO|k{!>1 zy{~N9vQQ~!j=X40y6{Ps7)0$PT0N*KE7GRg^2#HuPGRVAC0!77P0?yNL|!e7ijb7EBVA`yqf!0f$fSukfJ5gmht z&%olnVOc(hE-?|4%dTyIpF9Uwlp;|PqmEz2;=OKJHOD4#9+S(V?Qowx2UT?ZZT2q1 z#<3IeqA3X`Tss!;HOq=QI*GqA`W)U9Lc;Si zb{#!YDH@Q-!}Y5sk9e(7nD=i*T*CqIDTQgvN-(WzRp-TU;!OH?8q^o74o|4^T*+%B zaE;<$2^>^C$cI0M%S+zJrDMJ5s~Rmfo)n+#oq*3#8M}{U0|+sE3bv-bkM~8Ks`lXa zBnGFVbx>RAE?qZXUJG7tEThowe^NjhGD{dDShHX*u%I{SHp16JOw>W0*TL%45q4Y? zJ?^8#?r_VqDCcpK&0{7b+Nij@ZXVH!1!$antCrBzx_=YuJ^ujP`?7{o}@jY#X zjODch)MPjJu>ifE*R4Qf`Thl7Wn=9nFT_4?otkm~Ys9h0cJJ2$<~U7TVZWa>(oOR* z3_t=me*rgdsus+i`%b0BNI<15qnNcxkV9jFqXXw0$yl(a`Of>iO#QgyYT(D}1Opp-yEXhX9&u<_)biQJ7pk4#z7+@ zJ|BZ&{X(qmUSotDN31K5!uIIinR6w*A5SH9q1v_}!R-8(ze{as?ot_>KFN* zQG*#HKZ2_|4@#psK9I+@g44@-LEbI`&{Kh=?rf+ z8!Oy)Gob7H+7Nco))Q{)tiN;$=U~QuNn$zYd+k5)`ZvWohrHrfs&k$FL7vmvEG7#3 z6OIuOu4eQjEFa25Dcq_R8QBo&$OJXj2y@wpta*pyVvy)!K-hPB_j-2b1*gCa*C8ZV zI(EK3rsb`}@jLD-KZMYTb$#f#XV)L5(RSb6)J}CuuQmnb0utKoi*m4>W2%QVfkT}O zR#dSoxQk~9XRa3V^Bmb1jeHJH>q%UEITJcL)BA+-8ro36KRrH+-kH-vNHn8AIh~aP zjgt$Zy^DyUjG4a*sg7&BolDOdU$b&kanJUz+S5J@fM%t`_X-c*JrXW83*laQ3ri6{ z3D63Pu0e&EzLbf-)H}4SpNIjJ_-Z)63veQx(qnwSVa-A;Qww%p3;WlQF3^NKl8rlD z2*;QnJ$nvrD0#^r;(7Z>2QCHj&yyjq9;~A(uy8(bu6>C?r2DGRO3zPXN`&&Q-Aq-qi};l@sAU{?uX%-W3ht zDW5{~El}c<|MCcu)m2gM9?oeQrCD zzk_=}Ng>={j8e>AOq9G*CeCcTT^YEpi|nxLoHPPF%|~3KkgWN3ArZT(v2s zLd4{__DAz#b}EaUYIa%uS|3k3it|6F+cOrH6L;AqGtc?^@!U$ir{-I=%dTu6HkJKa zoY&>%bJQUoC5HmmR$e<3bUn-5{cjuTlYBL{cFqWOc?MI4X7MGpZFKF}Q{6Kcz<`j- zWo>lx8+xTqZu70u?1d9KsWPz(ZS%{g##UFZk*@uN@!gQX{C#5!=ZD z5&9vx${{G*Va|(q<&!&wcF`-eHjxR|)59x3w|`>}$9i=;)wnB{>%!;+N3?+3KRVZc zHH$Hi%UY^u^wsl(iX|?mK$kXcmkk38S3tENc8(GnR!0iT(!N@48+>WO z?aV6PyIo&_88y+`XM4^sL@57e--8=pcQFb2xvMpH9uA44CLwU3xb zpMreFr)?jOz>AZ2^S;|}2!SQQy{f@pV@H7ZL{rnORbDTkQS{%_$!UPzRiz$p)HIkq z#wQeVL(U;2gHLO_rQEFOae~!V!9M^co?kh6gs_k<_>T5Q=@(g61ZDc~vC;mJ%OpVB zCXhnkEl+**P_U|Q#m^Z9_6M$bE4GbO4DQ9usqVlBKb04&#G_Zq);fv^xCom_mZ&6I zA}KBDusD4nbYNZhPj)a+avr(4V@kW|AgZ!PnfOok}X?!a>FaMe8WwuQ# z@~Z>;6VgiBi_lN0{aO?G1{0Zov$I59^B0x(k6 z0zUQHS$_tfJ1Xg!Sa4Weck;L`CH$qSSlZ>3eAD;*(0p^l%7*e*nbRmeW6}s4X~%GD zc#dG;rt(m1*@^Smg(q(huKIx2{%FECl=xbdXore_*uhgoWL|8ZT#qqndS0CN-AURm zyLN#fSZ*z5Dq|?sc4*mlK)2Zhw8MqkVV8Y+k6?Nqjq$MJJw5yxw`Z^AJyz(hlRec` zDxntRSKEF3*1RO`A?+zLA&qq&Ao;YBfsr+G&31y{-CX0*7_!D#NPi@YJLBp4yX}Se z0IYhC%{T4phK%Uon7^OND;ww;CUi^nNt-M7t9VdaU@RGHUgdSHiFKBE=256VyL8`! z(_GTsm}X)XaCk9Bl09zbn>pjm)U%_Md!+SA>ZEMIN-k4hlA=qa=G>&a?_+C9q{D3& zR>U2q!VMsHgc91Ll3)u%Oz-t=wm{bJqg%`3=uBaIMz%ke?;g^7*DEB~M=L=%V{@)} znOsJ{hK$|8U$)@qtBoJ(RQfSDuh{;;uAqFfAl%hnpyS^>luFHjyAZaV~m$QME3>MxFA2> zkuH+%1#2CY4Qa#}!?AhtQC-^$PCg{kz03FP#{VI>^tE+~)VOe!^}21b_Vn`Vm&uBXC|v!S z_$N>33kjb$lpF-?+xvnoA*}ko=1sVa<71eml>oexb2`r)ewWChJB*$Y5@3l3=8`Us zX$T?QgqN%os##yK>c> zVV*Hc=9 z71Ar*xIEO0byvYZAYU0t(Mf)#@&e@=?V_4rzAWOU)_HNO)h?H@NPovti*wz>43^UY ztfLcQ$l!DC0}Nd1;4V-90AE`JWH3$|_T{ISJG`R<=oYa(xX$m2eq9|)6IRtBB<(u8 z7z$?1foP42vWzQ52H`|0l?|~^4ieB0I#;T6fIj*tG|eGOgaGW>@yyxBEwjJFjsF*8 z*cXKeas+n0SYr7=YjqC@K^kiV4Mr>V@J$^+WNY z2BCyd!%!m-3G$FEmdE93Su5-1M=!=}=w0b;_dfLwd!Kt>c*kH_<81pa`9Wwj)>0xh zfm*KI8mOhq$UrSYZVS{zM!{Pc0g_q)ON|(Ky8cM5vZ+|ae>+rxie6k zBjW?L88RVItCQM5ZKO;L)T*T}P^*+lfm*3d4%G7Hu0Sm;Qv$U_xjRscl&MaMq`;cR zLgYcGbex3JpzXzXg0>g;sIB$T{?T#+>dTEXL~fE1a*NbxOJkHm&$H+$`2V#KFk%1z K000310001^Eh5JN diff --git a/app/wwwroot/fonts/Poppins-LightItalic.woff b/app/wwwroot/fonts/Poppins-LightItalic.woff deleted file mode 100644 index 2706cd41c8616f15a6c057408d5ffa1407fe1584..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76520 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ɲSD;H&r=zK(C;oA?&K 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 XS@abA4~6J3O#lD@0000100000&qPNf diff --git a/app/wwwroot/fonts/Poppins-MediumItalic.woff b/app/wwwroot/fonts/Poppins-MediumItalic.woff deleted file mode 100644 index d8101a7dd159ba7e91d4080bc68435c0b0fbe1ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74920 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 literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-Thin.woff b/app/wwwroot/fonts/Poppins-Thin.woff new file mode 100644 index 0000000000000000000000000000000000000000..d21fbd390b7a41a04b87dced622dd81712c78f99 GIT binary patch literal 62572 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

    Dh6*vDu5_sTuCjR@cqW$%hjY)AYf1c1|i51;=TY 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 V&$H+$_#YeQF-!me00961001|7vu6MR literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-Light.woff b/app/wwwroot/fonts/Poppins-Light.woff new file mode 100644 index 0000000000000000000000000000000000000000..61f6a5cba6be466b39019a62feba066080a53910 GIT binary patch literal 66392 zcmZsCV{|4>7wr?=vN5m+0HB5d01#6E0CXViB;Lu)!0CrOcK-4Ce|ZtjtUZ3l(Ubvz9#H^LKc@3A zX|}nEf$>i~^&daB|A1m{0B-(6{%~DApd^i0G2;ge`*E*Rs?ILKkq)Lpb0?n zeoP1e@P8}-;0|P@Z>+B$|JE8t6cYJ*U7B01eJ6l~+D8lvh`RvW{Vy&k3Lq5#3kdz0 z4WJ(#J^<`T_;cp~Pyo<>dINalB?EmEef=}T2z`D1n?G|=4zOZTSFi$o0{{@X3)tU% z%tO<;`v8zZJ2Lcgzer3)^}F;4G)zpgpucHJX-@!3FmQCh1q)2uPd&{kKF+BoSfjnq zpFBpe$>G3sY;4AaGJW;UasEyt{^5P#AT9aCEU=J+gSR0}Tn9LR`T}% z42XCClzeRVckPFA^7WW z8SYzN-|!hwJzH|<=dLRD0r%AdnaZbp!*26WW?eut<^|j#yO2hoaqgs76;#iVvNjp? zS9!?0?XTVgFI`fSsOw*6dC;GTGI`pv?F+N2@#n=f{K|Sag~``u6{Wp8>~FQg7%um2 zmUX>S!w!GQ+LbEo@stmJ%QHCiOnl>OPIzt|BGR&n{ZXhLV%HW!h* zX#dtx{be}WJ*w0As!k)eA3lljh$rVL2~6<_q}Dnn zH|%mH2azK?OEf*)e_@>RK2R9im0KcL+skgl;e%>4|HjQRMeIde6ZU|(0?rOYI3RuD z%+V3sN`FC4ZmLw0=ptA_)|1+_EDK!qZ+8p(#~syk6rfYbT}Q&eceB`MmuAPh1td<% zy@hmqQ^Oc1@j>Q`>xZRF(gV>8F9novcMH0P(79)`2I{u)4mjZNGgy;&MgLXhBA7>S zMFEa93-&~_18lTUNK;}9@I^T3F9zJ=^B{@|K_AK4gKfdPvbFR{E%`;|`m+xC^-~)F zZ)I>G(GM!+lRaqp=LYK7qg0*fxD6%`5%ixARndBQ)=gVc-=+e(E>Ay(-f!K#33!Gy zv8cJM5N8W^DK@zev~I1{v7XBLyQDs?ZtyS#eZ*CUAoTIfUU9kz3PSD04nVBEEY1N3 zIOgY~+Lkb2w~FJ1kv*>k+>pFMTWr zi#$ZOP%fu{BcRQmDUiJ`pj)J~-9O7o%nrh9z2w%~6X$8-AYUjhAp6Mwz%-f&`ksZo z4l-}m^r2aV*wqJ}RI{z-@Xie(U4u?Ewz=i?~_g(G0bKsQpQ5|z5xIq?e;_sc-p*;-{ zpS|7AoQF@I?h=2_~+PqXv_L8!=YMnY_eA){UDU?$!X`vonKI@45n&$;L&v6YE9z1(;Szdn@_ZL`2YED7K4w3hX~Ni}bEk0; zW*uu)E72=f>=m+@r;g&+n*Lr@V%m^ocx9Aw*ua?B1j&6qcXF85Cr~z*? z%&B+piLN!^%HTMF*P3!aIprq6ho7CF^@(oJ9%W7v+f>i3UZPMd|9FyoR6Epsy5k&? zGUU%ytAAHtZR1P0I%#&XKQN!Q!444K!M*)EVtFi4n)N5 z9C+t`eQy~9n2mx);?Z5w!mIA%eXb*clgE?S*#!diYPU#M74dt?#`fc= zONd?>9ak!c@h)_4hTSm{T+n_Gf{)iJ)vlV3PLae$8U98^&qgKir@Gpv+wxg;Ok3|Z z7;m}sKU>%GGx+o`=*Lg;wed2wpFKKyUQ1p@1sDA0`;AX1)gM-E-+$AEO)x46Bz=t$ zg<7FYOKzIw@C8u@A)5118U1kSuhh?_rbdb@Bh?~ZiG@5#pgm|~=eSF*PmEil00(jE zVh+lp6umd|H|x2V#=X`(29m6F55;X@p1g7wxqffhMI3Dc#X4~Uv6$r&YH}&Ga(YH> z#nP_|&E>MyCCoedP!w}f3>+4h1lf5DE+vd}MP4-s=VIL&wR0EG?wS?3GnqHabJEHk z?7BZP5#ua;Mp&Du>57egG>pxrxtx|~pIE+|dVh0`24$O+E}gk2pVm`!4As_gF3tw@ z4K^VS8RMZ+^;|10CKQJ&w856Bnss@v+Qs4z+cS7qv1W@OXt^{>&tS8Q&CZ#4<>;3t zA0%fV>vr-8B0F2uT~vEr21znu6OHbo!#jadYJPn?6?@cdeQU>#=u9}3ujx+>FSlp(eKxMAk!+o~2c&D3OvKE|4#Z{yFHy#EvWx>qeJJa4!hR=ewSYe*5zzvLfa< z7+<&eUa)z<);_u|*4oc|fp7o(B(epK)XK7iWQhPK94(vcv>eW1K>qiEBYVc;B(HID zeO<@5MIw?S-8<*Tw9q=k97nY49j1YGr$zQIWc*meLyS$Tp=i=sB3W948cmUs^)Aa; zqGc)$cN{JEZ#ZqrR6^iOOKvKOM7(!8CH*Az9aZh`f({~L%>toU_N4LPwLh0@0jsy* zJ43QvA+7Z=*Lyk_BlumR&$mE)L%QC}9&+6AcuJ<3#8f@=MbgR$0=g0-x z83fZF^U~-S)t-8P0Z_LGOKA+7Xb&fAPqR8hX^#^A!P-|&QD7Lbk{*(YVGM2bNc_uT z6y^y1&N+6@GmI3)q!H}q1h&ZF?*QMJQ;6G#spJm-DQ$*scgSXI2En~96{>S_dykFgw?N%3@xjw{3)l!!%C~L$m z*YHY!5lrm+-`hEW?0?M_5D4f6Oag%dDFGD#LjoHDFM@!AAc7ErFo5uY{0316u>gq& zX$9E;1qLMn)c~ykLjt1!lL6BJGXV<(ivha;7YDZouLOUBpn~v(D1_i+zTtwVOJV!!6VnVV<@l8O z7h4l&5f>4c7cUpT{w@65_xGp-vIM?_nM935hs1~^lVr9Ol$5d5rqqeFvUG~{t_+7v zpv=51yKJcJzMP<3vD~M;nf$T>g94AjZv|xqeFbX;cZFbuI7MK^C?!axG-X(2f8{q7 z5*2%uAyr&e6V)*_5H%6Cc6D@h9rYm%I1Me0UX4jjT+L)HFfBi=Gi`b8ZXF;UDV;i< zTU`ZR1KnmlBt0TMOTBu%H+?hxa|1PlenSRBenTn4JR^J~XQMUaU&isq2PPUOL#7I* zM`nCx`R1tRu@a`z}H*u`XM#%&x+&g|6RjFmBFn6Yj$9O71NlY##ZZ7@kg^ zexA=>R$gviL0%u;+1}+oxIT%#2)?eq&wk;4$^KyeHvXFdd;t}K41xK9=RpEN*+Jz& z&A~Xqr6DLGE+OB4O#gg_DuNni{)=;u+lUv7&rU#3h)DQIG)f#w5=&Z77E9hq5liV#B~0~BeMnPH>rIzS z*GlhBAJ3r92+p|5RLShf;>pU+D$gd$F3i5nG017i#mKeJJTI8~%x^iu3rJY0fZVpg(NN>-Xv240p>_OD#LJf-}+Lc3zH62CI7@}kPH zYN(p1+O7JqMy{r=mZ~uno;n@pQ`TV>luJ5)PIyIFfmdsF*p`%{N_M@q-Pj>k^qPKHj!PP0yz zPM^-i&ce=_&h0LsF0L-suJEqDuBC3mZuM^CZu@Tk?xgOb?#&*-9<83Zo}Qllp4VQ4 zUXfm%Ud!G;y?MR0y;HpheJFiQeU^RkeG7em`+@t>`&s(s`_1~j`(ygE`)m69`ltIh z1`r3t2Al^f2KEQO2E_&~2LB9J4Gs;?4}lGl4XF)94-F1&3}X*-3~LNq4TldG4z~?Y zkD!eZjp&a={Iuke;gRoA-cjRGx6zf+_c6t>z_HA+im`@qpmF$dwsE;}xAEHXuJOI` z*9n9PstL{slL_C6@`-~<)=BdE%W;mP^Q?a9;0$0?vGxGAhD z(J6%~ohgecm#KiM=&91FyQ!~f=xOw6;%T~R`RRn|oau_`mg#}%ndyxg-WiD*l^KH> zn;DOp;F;K&jG5w@iFJ#<||P$$8{??0JoOlX?4j@ALuYNxh1V7 z|E0R6uBEZ1rKP>4i=~%k&}GDB#pSx?uI16?_Z6ZQ+7*r!krlZWtrfEsrxo9oh?Sm| ziIvw?uvMg0yj6--mQ{gO=~eYr<5l}r@71u?q}9CDs@2xj!PVK-jn(7TyVb8Xs5RC# z!8Mt+thKXsn01bIfpz(HgLRAbfc4b%?)8lg;0?45nhlN(kq!9`?G5t{=MDdjsExFZ zqK&$Z&W*8+<&A@l>y774kWJ)GyiN8^%}x7F|IMq-uPyj3{4Im6n637${;kt(qHUG! znC;T-p6#ve)9u^s*B!(ijUDfuu$_vX{+-pGi(TAZid~*v`CaW@+uhLJ#@(LX(cSso zuRZWR+&!i}^*!&sD0iUlZU}en;YW6Fvn%v=t?uWB3Tm6$je=!#3$^ZN+xCfWjEH)f z`u?RkFIIga;9!4Y|6p`$uKZ`@J^}w=`Ks=>>Sk2$G`DJ5MW72V0a_7c`irBP?fqu*|{nb;v;yJvIptyXF zH)BZdQ+iOdx%#@9Y5IivHxSVBtf-=`eRdST&Y0P_nYb0vF>rp3&rD1%mKh!>OIC|z zlTW4`nV4D4Aza9*}EHpodD9UiE}J5Lgw2bCM?tQh!sSQQu2Q9%a=R%~gv z({|68Td-Jl$W&Wdr!2kr4ahZriOs?PeOp1Rpi8W-Ur8y7_yd+^c9`|IQh%E~8Xp(aSy%w?Fb`U%L=5V-f%?mctDg#2IT2 z^A;rQRSN;uaAQWS)Mc8tX_Ld4~kH`C6kQN=EKrg@6gZ0_O7nax1J?h7!h8riA1rhB4QgYImq(Ur^) zMSq=jDU~S=gO4o{a|Hz(@H%*md=p&K$F z6IIx9jvUg?PY)X}Zq&dLFr`^*TB|bon%mLbwA}8nJXf`+^Y*N)_3;I6TR+_%hJCF0 zXQ|o!*;T!VUG4gOCunX=i{uOPiQFI(Sx+h%#IC5^XIk)NO(hfj7srr0s25{exK|FN zS^AUr^ciBIHfaL*TJd&kcOK`|Z~w%BTStNvboUv=V%GGXsFz=G*hoUY50+n)R++_= zi^*%7XwG2_I@WUDvX58rdHz~H{NMG#!Og#ebyAgmR;YDqmQnr3ZEBltjJFw2NL(&s zUT4TI2awMg&niyG@=DrP6Sy;|N4F?G9>B-KQI|#0C)LZAC*O zB`Q=()3VVX_B|y(YsNVA{r#kIfJD#^%UD@CHJPlUX_IDdjtp@iaW8Kj3DJ(a5fuvM z1nQZgNx7mCD_t6Ww6%GyoB8zpK5%8fYNG(LTE%@DpG17omb@j3_=puQYYP~RH7k7e zJe-t(Uv=#uS?VTNHzz0QdV_aF@tj{)2cCj@C3keHRz)(rYW~dmVBh!5nikg;^zKWib&CsvWZMxF-JN;{23fk7lOD8_D_tQupeO0;qCP; zi-pwBYtpYwLCfXJ9n~3u-t%2ico-GX80gcpv}cx4w5GJ;Fx=O5q7g?l$iGL?i&Jbc zreRu2gOnqD?zfvVs6_9bDN7PBIO;=^jC(h9%iL5Zsx3MOTyd)D9??=e8k;PJdlXwn zG3IjF3wmK6(!d(#-NrPL<5AbKNmcr1e0az%XpSx;$2y{|f!DEbG3=qc`CcH2A;?Bt zR5IS3H~5@9HI*YO8^^Q?Dre|o&)qb^UEYWyE4g#xBOE^ld$w?M1$C7c)WBkWt6Q*A zIJc;s6`R{y6?C-9ET|0dJ>^W8tL)Wc&S)#>T)Ox`NNIa8sY%2r=`M>nwBUT?JycaF^`QbK| z+LUXwRQ4A+U6hKFr$ufxL)!@Z_*Gj7AjA^SOvUuLY8in>-E?F&Z-{m394@JFsAP+M ztc3gZZ_aDMP|_ZQK2N*R+!^z<5>x+EmA|MRpS^injm5UaJ4;xht^8BDis_H$-0bds z88dJeKcCSp&AXM5hKU#b_3Md%LOwNlsaeg9dINUFvvZ=RvZ_MJ7W`h!5cU1HGI9Ks zTv!E74@n(G9I84p)VKOr`c0{DOVT{_qQ63^H+I#S@+umf`;v^~H^C{UDzIJo5KITg|^20me)y!R1Dij zQ%v^*^s$j?lnarcAAy zfAJTWC;KGF%YDbwa^>cA+n}P7QTw3*E&escDO%YmkEFy~()5|&LVTj7U@eES&+x{& z;v%|+ZQ81)O>J2%S&T7A_xDTqdsJ0rxLyw^Dw|r9I+N|EgqjKE@@5$SxN}fFgt}eg zjoIK5;upGb3bGLRI-H4LkkSizC;_eP(|b^U^lB zQfkFkPw`6YwuX1?pq$rM}wjIZoaZxrnlC`3Y^Ncmb6#X21LDV`F>*AH^-EU zHFngIiwxUoTK#xx&?8#qMD}L)j?K&+8rsz7P0;4@wwQ3L=C%ogYi0b(?@OyJ6`ZPn zqBE>)r$E&yuSTJY>jrafRLR+%(0d+RK_`r8tff#4HBC?8zY&dYp# zPMD*@=A@h&B5ite(qHu z5iM1%^vo=4No+Q^17X9F)jP7W`8o>io%K#?uXNQL5p$T2x%ZoS-jq^NXIhAChG7j>F&uf)-%3@#Ea zz(O|M`Ijc#vQ~}fMOPr+(X#0x7CJ_uyHaLD!{_I7s@Udg@)`zJOZmODs@KKMmtUZ9 z=$f8VL^{F_pUhVA2cmC|OeGi2dO%y|1M(Shm&SZTIT-)z<@fq+KHKxkQM;7PN*Y~| zkI41Tv5oP>KI`5@5aL72%A+X<>J$q7*hEvI?5^Y^di9fT%Bm_!dn{6|WB_YaSrCg> zXnKyJ$}g3h!=RNV8<+0Q%49A(x#m_lssM#zI=kDmW_-KWQ67DF{8|fiH?zWGF=z}{ zu5F#_ng@~g;Tj4zi>eIA%9dSVHgJ|g#8^XHecVH#W+W{+N$&RcVi<(=9mz?BCJVT1 zD%4&Om#@#JOo@teMh#1=DtGs9?CW?d94SdH=MnT*5Y6v%-NN}3*361A?px1}v*UGu5^%g`#Q%cDs(y8u7VnUD7T`VOpTZN-AM&VB0Yr^=dqT{Zup+?y)Z>5kgN zZVEQ$7cvR$*u|yV#ivZC1j9rfJke!RPrVk_o^ggI??{S~Z{+)k+7XRdcDpwd_*rP3 zV9AA1+npv_lPN}d?J5qdPj<~qcDx{7*@%&kZvSd6a25YY4RdkI1mFfqN%hP;kOcLY z0YRw)rdXruZLZ@oY?(VhKtVGhGgn93^c{vwX^Y@=7x`et$DavP?Mv5MMwK%D#r<~H(+EYAHzn?88aE+B=` zlSyaD-D6~y&upu^ZjNhv4b-e#QNS22uyogt%Pw%-T}K;fX-UJZ+eRQdgo&Jn%N5l< zlCs#&;0a=|8{MX%)$?cL<3-5#JJ}9nPs(OWI^X7p6i$pfz6a%{Y2hZGPu-^ONzWUJ znwJuA9w?=1y?gBOyb57RMAw1=r+Ym&sX;ACk8quId8y8D4CMdX4()1ib=j>iM!g2? zmeAC4@CeQ??<|{Xg?a7!|EY?G#y2AI3&MFK-02s9c)_CWhY<{k()QM`OUq9F_L`lm zXrVKOWy@*zg?-RIu&u5P)BY)PvQLkDL(QVOa>b?}y*Z{QJ#r&(4G}M=e>4kwyQ8N< zqj7+np2$>J$t*c2xPc32T|UJv#MDO4<=(KZZDXH5^oyCt)BJWtb~OzRd#|Cy617FM zsm#lzw$=j6vM#1w%*}O8nidJeJgD=UyiRwrWciGN9;#hJ4!4Oc#vON3<{0g%VqfH& zeXnA~TSKY6K|*1pXvFe?&e2`1omvgE>depl6Tu26(!WbWX)AA;9Zf0jEcYe7g-C`j zPZErjt}DmXiOa8WQst^8$`!V{qspdw)%12j^;X^Oc>|;}?<)?@y+x&&odccrN~hc9 z?^OwxnNIdEJ|fN*D{E`}bxnI(Vt7XB325-~H{X{e~LMP2gPK z86H@k$@3H@ITkj9VcG=hXB(lF$XC-_yb`9m8w8zSS)sQmI+31oFq-?)L~I^hSrV)G z4U7)1nd=rBD?8jQYa7$n#cJ6vUcT^S1GSnig`LeiJ^BtO6|_O4@7NH{8-hw+$fdn% zg95$3lQk?{kQ`Jbz)YwlQUvBiF?So1o zz|Y1lwY8&lO%0q?w1Yu5PxxUIu5Y9{8$^{=iAV=#f`QU)ic5}M%7MtBR7%>c?bLnzILUD;Q(GNsLyXQV(s;tVNH46xK@F@szbO2^~!Wby6AJ_ zid?dE_JD}EFFnMgq2b=-!aW1-HCtWMIawMCgvr699H&$_Y+#@&^JIe<(Rd=5A!O^o zp>KRL1#XOos?C*ef@p5a-l@m02ZL0u4k3`r=-wF zVH(;i)+~(3Zyfz-+dLM#r0CPh><5@Uu18#T+{c0kR!E?B!dWF`Sx!-?kXlOz$Q`^W zExyAfi892iFfIIS4|KM^2ztH+Zn`vq^J^RNtRD?t;u0w zBeT0kdMJ3`YVmE}sc*DsDwJ3YX;F{UaHU~)mfb9flO+PW*S0{K4f+%M zDdSUh;>~t{?f(mo@HY3>xuZ$62Cif71T@Rcno~Desy;TTn&Y_xdee{BCg@}zAfl#hZI5({?i>YbMW9LS*4anj*_{ydRu0anyG&>LLGK|<2 zg+oy3tv`q?Wy*^t#~*PTykC-rgW0?446khV`=JEjczW(Y_ZD;KyyfW+9_a`Y&sBWZ zA%$7=l3?V&{7zG4Yg7tjvR%w{rZ_uqaE~{W2XR7SKe>L5X_-JQ3dP`|k!q2uM z2t7%3_QRoE8|9ptqu?(h&m@GkLD6S#%g7XOj$VWAHm{^_Oj<9tmzpc{+lrqU3#^eA zn|DcCg{hi2vB-beuqA|m{oyDmubcNn9ja+mUv0-(v23zBpNuEiP_MC6NMf~G^SS($ zg`(L$VXUoDzQTqk!_tPSTiUP4;4%nz#89Z0N&yu8#iMO|$spio_nD!c|ab4@Bd@Cz?`ho*Gu zqy8W}CiKNyv&S#Be-k-h0TnIF6XbW0ug=yT7xhq20uU zIWuTSNFW6&Pd3&E3#d?xz3Mym(GfZwY?Q{O71b&UGX*59vjSJ@PtS`4()x?<%)dPe zEIO(wbk#%TW@<3hE@>U`rg=Sw^IyrU?BBfE!4-XeH>)HfI*!iHOinylenQT`B$V7Q zkUL{B=<8(Tf8!8J!sUY2j9I)Dv`tx3)1h%L^B^>VzkULO%!w~vCgE8@yS=HHw_H-oc`J)v1NH&Wt^gC z64O8pPt{)cQyCYmm*Az-YfEhWMmDJ~zwK@nJv<<{xAduM=~ta`=2vD+Wqvbc zP9e-=jL>OBaFIZlPS30~K%1?1AI`O(%&dx4X?jVx)y^&`=~-TC2NBIh!y84?t!7y~ z8h$i(NtoGafr`So#Eeq@ZkCS?IwuVI2m~d;7$8JP(7l69?VDderMyRbQnt{ct1cPH z|D#;GxvU^h>gIy3TDFYl+MKaWb_TvQ`F_K!nyEY%(Ph_MKtM6p5`^Q>ne;Bh^1MmD z4)HPm!v07h_Ri^zTC3{XH6UWPXk8SJN5x1+%AFbUYl05yc3>=cPn>8!p{K`8lR)p% z)8$_ExGz7YLkmIBB1hMxMv;hlrCH$&NlnXT#XE7~pF&Ctj+UClmSL!d9SD1sW?vW3 zU0UmY;duvLO?g++t15bGM4HKvEef6^<+sDpq!C%>fV4-BG7RQ}$JKQb2b4!=f*B4XQS99lg5hlA1+2=r1+VbfOdt>qZNHsUP^`TqT z*2gwk6l_`S-pW*#R4wUUkht*$IW(|Nta;bX zck!%xrz6^9mTTzFDvYM?U9FDRVFzW79(oKet#Tzm2X)p5~UEqio!1a zA<5d14xxy3=b>`DBSlx<)%lncP+9x+dEL(ZN6p?^RZ3;rTb9bCl~ZvkRG^HRWubiO z^dQ8*UL((2Vq^1)nB6a?vce=)%#BYVGqf^*eQ$VBGr3S4>3Cl!e--SsjIUXCZzBO__wn?-ekVOL zVY1(fPd!s(cB>*5!Nil|nk}Cy^B`(j&p z;mMlH1tZawoY^i1QPGei;HA9-Dc{nrPIxQ?z=fE3Q>Lc8uYf@8U>yzQg~7s}-XZg( z2fAQVE|VH>=kkdvXU*_D!*C*Z_q3x7CFR^xOvSB?GqyPOCz;6WP1tdpezq!9ecudt zeb);QQ*UGg*J02yjXFYCwlu8cZy--RuNHx_!H+}t({Kt75pz(m`>Kp69o-_O3oR;*fQ!p(+4w;$q zRe?`J5nA#m;(>|;3{Rcw4oZlk z0Ur-`JQJtP#H3J-e@Qy?b97m$4lUi=vwxt@Uhh@-3o03_!T@bD*i%LR;S?o1@A`+Z zC0-m!cB`ZYv8N07 zSXl0;7@vKfh9w`udV#bNa##u0<-x*TGT|~eN`Nr z)xo(}Rpi`q#ZsrL09DF!ErC7_XGc04X7F(x$h>;TsD?tm2jgBm*>9y|ZLg62>&nvN z1EPle5PcfR>(Nv5qjFW?Z~|*jEzVNJQ$FUQF>XQMGK_dCq7Rq{Rr!?&<=z1e)3>8C z22LQhg2fTf#sFl_MNUq>kb=56~T& z`L6che$J&gZ>guC#oCYgGNi}IM9ui38lJRPlfJJ3#W}@qxf>gn1z)I=^pgJ4x;N2S za?o@`#SnO_tdaEd6`A?=&|+G~>K=-^+Fxc%$$z#OIBc+H5i?%>KIdKLd_|{5qKNY( zv-w2$NzX8gIbFz@svW?6C9&KSWDYX%ae+ymhFPkIO5ud0=Jz$@CcVL6n8gRb^I$}% zixS%0HGSqboEKn^F;*Ima(?ztk z+ZPp7?F3BBaM>HP#eR6Y{{R-g0Li&4}UxQ?8CYc*BN~TY4Q54FYm&3%lw1^e@V7D$1 z^$n7!YrxR-s>#Lqcd^;e=qpHQrTRjv*Jua064sAJ&5IT$wTV`1{Ye7xD|ofC(LPHP zCD2z0Hz7U;4?vn)O!BHKVne@+b*WnB-4FwAbw~^{B0#&Cbbhx?gjtr=@M@Uqxf#Qf zq+M|ntqudjGn|6PHd>KHstO!5;OK`WK7LOr!=Q!1h?`40nDp5yUlvngl|6>grK#8W z(sU~imsw!f^LCbr@v7_uBC5dh#3&UWyUsL8<)Eos5|%4z6npLn$}=;@LVn9Z8=qcl z6zU{UOVGsOb?`|L;r;ciYEa`$7`~LoBtF=Kg^`hrjFA!>|5MQf>5j)_d=`Rd*71nn zJ;$sX+$(2i2$L-XaWMNj7D;ONs@kfK11LOv(j@1C`v_4CiiG3Oc4U1ls)!>Q(7 zW^TF6(Ym@Tf4Jn>+u6&t+8Uxn^5`StE)O{;A7$OfMoP&?pxWlVm*}#2v(K{DVTIA3 zpn_LP6Esa%sf9!GGPi!LbKuFVaetb&f53c<6a_Tif0w>d73*XOB=f$9M4*C^#qgXE zhy-|isiK0Kq+?44>Vp@9l}SrQOyXYpvjS8?)<4DsDY_y8)eDy}^+Fm?L4SeH6QT<| zI{3Qp>C~maa%%z${Q~)dtZPZ|$Ud-S)bCOWVAz31*qBPIY)FXRMkpeMIjotQY}jp= znhMq3PaJ^pUEn3{G=uIpXc3BUfe@_El~)ZX1*9A(aQ2l(}S;Mx0BhaCRU^bC#wKfgc> zpg0F4z{fiRc??Q6aXjGeom8Y0KbIre&kus0nD7@8(9<)&^j6I4H>j=L%(v+eB$@ep(4NrMJ=919nK!uwC z(m~R9Bk=v51dOsnO+2{;jV`m?V_%MGu%!Yhd3am3!OkO~`R;hKR5*B0SYU=+ih8|b zoyDBdNew^o@R_LH=+>&-Sw@%-8Wn&3cQN}YB41-ErcT3J2_cRM zEw!HeI^aSKpEL~n=b*ms8ull~Ybe#%JoZp#GG!dv_U@0G!qTkxbQ|6dC2jlYRdT-V>Xm=9=v4bB5W7SwP;fJ&PtMwGpOX>GfIo84j4EeAbA1m+ zDl;BE=PmyiW%F#X@7=kfCf<}yq6SNoNe!v0rI(sYsM)%;()bb8!zqjkXJbUJJ&I}N(BGC!uIq0xSHb>$gvRlhT4JoO+3yhP(P!8s2vAFNshjr@6Rs~GfPbn8Usg|2 ztR*Ls71|W_BGfA)jKts^%UyQC(C@RTzt1EmyDhjfk|B~JFV8?Uqv*ca4}I) z(7-r-MAm3J^KDkkY5sG*n+n36*v~#8s3_n8prW}B0)dDs(=-kz$L&xR0JF-7XM@}o z5s%W9&~#Z!BVA5Brc7aix3Xw8ZwNB{#5e zZx{Q_(hF{3)o_bUge)zcvQY#AgO*o{>(18uX-amtuS8(Rsw{Lhm+2J`RXqrr#14w6 zPOSj(1205z%L!RlX(bC$b`Y~RWTXvaSu0MFNFk|40ids;S)aMb4XkLauY07#lpN4+ zgv5&w410|%5|&1SrAtBYjOHmXBG`zVFqgdvSjn$6QAZ$nnH(~^KNeCK26W^083myU z@Y3y z%H?|iH6(0PCf5OD>4i-^80?501HT|TQT|j;hDQG}K@$y6uXp*p%TSamtoqoCu%U)H zTxh{(DUS)z`}9N04*BOTX2V?LTyV$yug|YdWl_GWoZgVEuiJ+gFX&9iN+&3Mqt~K2 zEBC4HCH6)sEBT^u1B|-yUz1Zh?d|W{5^0n#!+UXE0}RHp<|X$5wDarH&*Ay#m583< zaPSpq?QV2J*X@anA5x*CTVJWIA*1EI8b>P?I z{)pIidwE|%+KLK4h?Tb{0N4}csqE>~i zbGo^YyqJ9CaU90()IEY!7pQ9ycSc|yK#{j{>hL%F|B~LJM(4z*?u~A+*xD9n?`a0t z@oHe4dMHFFq#TB!l+28UaqGvXD8ctxx#&#!i!x(lgG$BR6;d)o%$E~cITs;M*@U#9 zC#-VEOg2~mLd3>|NtjU@E4b5_EIMe5+t%K+-5$|mnqrpepAs`PjU^Z0SmP@5h}nO9 zWU0D)n_U;1#Aw5|_3%@jzX=s>s@TyOVf0L~(er{(q<$;d^xN7BHdHAE>~3jIxCADC z6z|1nz7v%SwtE}> zYr=Tt)r&eVlWRwvVxgt>UX8X)rP(sYQ=!Oet3^DPP)0N#T7{}P;Un%jO!p}pq#Ry= zRHEgTe}b^JV(Qx4bYlFsh`)-Sn3N_Zs2hhow<1-zOw@uXZ>Qk?$!<>1V(#EGn-GY! z60XHNalL>NN=v!;m04tS*h`Kcj?r%?MnYXIdd|)*$TenU{mAA zcw@vr|=Q4i3)hInO?bv9t0l`eEAAUhT^kEUD2<^@*u*xte*6_2a(b z;^X5F^F%O139!*_0g-5T6yN@(%De*yVVGa|G9h_(SSDH250iOzlmxeb%9GU?wd4OE zdGU65A)o&>tsL7%7A~&SPL(4VFVQfsvU2>E$ng(6IlfJ{fPMw}Fq345JGA8jk}bJo z8p-AbwuhsE4G7J#t$76?QLq~RhA9(z#y-STUJ!frzA!uS57 z_Js7YN)~mv1W62XsKa`#pT9t~20)1Zn}RY66oP{Si^Wl$LTg6&M0T;blfx&LF^}=( zw1vPGnZJa@Tad7n*am4R1Jb|d@S1J9ycxwrmPovPp0Z5lP9B9wl%&YpLb}yHbq%Q- ze|IRVta{Y{AS;m@o_cCr!dpcYQ>(${rg__^nxr~c&dD#80A6>N-Xg+v$J<2=S@vwt0CTs1_u zRU`fMqK;8CgW~2znVLC?p?&*rLxjfdUnL6UX{sqB<)yli%)$>YXOdZH;YPlzDd=+1 zhuv&x$K|NLhJb8nCN&F{+E@(@hiv}eEnm>xHs-aZ#4<%;j#o$p$TI|FF^^XX^0$Lc zY`G5UR3B5sR*ewn!*3}wKc{g#!8ig{xOi4^65SDBAQfBNOl zphTW(>S4}?m%p`o07v8e@?pIj7q>+dN0Gd5OLwI?@svsmz|Ei12L6o}wW!lX1%L(Av7LZug;6Gs@!Crhyaix2Nt4 z%3|M}FYs&M9^4u+E7yoo9^dN+pNyE-y9RMgIDHs#YNu+b-q4uSY3PG0XdL+LPFYGs z4+oYG5i>F4oOnKIeHB_lm<{BK{y+aVcSt!{(B_!Bc^LMuZteCzfDB;OvZdfhTq^d| z_xxoctZeM1l~Xqh%pVYZ1f7jERf1?Xqk@^b2K*#_5OM5AJLx`Z?R4i_rzHX$e-rb? zkb^hf!lH-^J@t|>su|@XedU8LzkX6OFydfe2D1=JC+?Jg`oplSv{@vjeXutmDsT0k zX=L>;DVsZ4hxVVN)K(;`8Sf>KO%>YzmCWV~-g02-iewfBgf}cCyQ?p`)4z_VRX>mV zcKd%qvdcO3PoC_iUXf5#I-B?&=nIIi#=dWg_=u*xi=!m9R0p*}__XVPnQEM@v;s$A z(sy~sUvW(K%nJ6)sW&D?L|@>)49Q2EyTy0SuU-7v$2$$PDo=A778Zsckx`Tw%jbS1 zA2W_3krR@Tc;f#coLu%{Rz6_5V3PFy$$(?yvM45NW+A;W4taX?5qvy92Oi?0kiYI1 zjzZQ~%~?vKghgMmaso?)!jo85^V5;6dZ?AuMruEG#p!s1GRf&rPGMo@V80RfqnpNW zoR>Vk-#D;kvAVy06v=v~Nju;C%VpuBrhh_y<+C+48qeYdtD0H2@|VInx|PdYEsfQ) zO=jks@R5)qrxPKabtP>>;Z7$({q*39)#X$RH9)PKg8GpORXYwKe2C}8!}w%Oi~YgF zB#8UzVR1jE*l2W3*0M9_C)X?awUQ+}P8D-GKTT^Em3#cxW2g`OfGZTDGc{oJk7%HY zc^Iesw7B3)LeQTz18M1#WtIJnBrB+;nszl^z(IYcV1F*ai9zT;2*dqMFyi$X9c-n% z0`^cQATsHsER;OyVXMcJjd=Yb+m$P}B6LE^s=bR11BuC#q7YwrV*ChZ-@1%3fT=ybxfGi;sITKQa^<|I@_d6a*0zw{9}x zkFa)F1kbuKk8@`rW1o9jTw<#Z z)cX$;uEBLRHD(t3GkMm9+~%?(xqtxhm|G3GGUl0p03y6blb1W^5@U`(#y2tettWJ@gE1=!A&a#sn>u}pih6%8If{RCTl?E}tGOorT1;K*g$ls3ZE9j_7 zs-9;RPSYN6`)IN+4H@&>+1OOmFExHIXZYUbxlzocK~Z3Ls?uB}7m$Ur zRA)gR6eo;jA-+>?m^@a8$YTjbk<-%GQM9QTc~=co&y;ABuv9{$Oneyy!%f1g1Fd1J zwpy2W^sj=+b!B`5NZ*l^!CfhG&^~?^X9HW;F6e1n>q9Xo|1m5f&`E?63_10zSv#1L zHYpeqYC@<7_^H22_yw4uLC1jac6$K`+8|puk$cFiuccj5{ zMmGjtXuc{C+?{%;$kK4X)m(=+0n$Qku#GDAR$opU-QTfm;IYVhOLk z2;3fQPvf;K1N}_=C@SK$Yrwq}MUaB$q7kYRyy;6Pd{M$|b!$ZD@-6^N|9!}%3g@Jz z&*?%iLt*&c3-e~UAxtugcxVefFO~hzyvPDsOWA?SA3-K1qlawC8yZ@-r=@Ib8{RV~ zM*G}@Yam?O)&C^C{luFqhX9U(6HuMc>1*j|nj`ZT%Q>q>OH+agQ6edh;}KaHu`HH{ z#I$7pt1NUH3!Lr-C5aIm{B!tzlY8|!KWYJmt>o%8b35J=A; zs2J7>UC%^j(FZ*3*MSEq(k{7gvK`#Vn{_*R&l~Ys@C-ndMqj*4YI2oc&PNg2)cN55kCD=LB8%%oE!B5<#n@Mx73X%nadV z#90(0mOmAQW8D{D$i}*NoevI%R-{jRGK90k$(hadN1D6ef`2;k=BlA}BWN1q!z|HJ;{QO6Fx2~fc!rsZu^%r%zDQ?L}0oYx|P)zdL zroN51-hzlZF@Cwbwy?CJzN50CGl8Bz)(GmDe+Z!LEZQoY&@IQc{qwyo%%8(hb)wG@ z{V9|RaZnNNYlKlxv3fq00}y&{CHf2_9?IJzwKw!_#>9)EKX<@6>c7NYt1o96sOgW9 zz!ag|{!FTMJldJ-DozH-ukgl${y< zG|aphSm$um7CW*7ddk*HQ&Cm{%ONBiteV1g1x3FEtcIy4A#uoI9x?`5F0Lwew$8&B zxSslhI8N{aS5=ALR@xP0sLYkyY>No1I!Nr@IL00;D08^Am}Y|Mw8F*aMB~^_7+Ru} zdu^z|OpxAAhofb&bi_A0{-8Kf@Jdj%T&XMT;!U(VtGj;69ie#Lk_YJ2%reQQEl($U z7q3LE+tQOZ`m7^{Af3Ig+T~()T^j#N^h@|!R9#tD8)6H<>h-ZxtJjh2jV-vAsDp>X z5?ns0aP8;EJ9x7M;4z8Uk*J4w3*ul+O~a;)^grzwcTM^zL9s8n15a9U1Q2p;B2f3=sxUh8Sae+qw9h-`p(8&W`VNF zYP@9cC=cEoK~p(U7WBZb!jZosXkhI+`+M%D3EVE@?wDY|i=IH=`OguLOzgq4ivlxU zgqSH@`B&^YWci26jB3zZdgH8SX|JuKZg~T9fABgq_{*tf;t{NoPsF!db*-h^g1f-t zN^i5x*Ro;CP4kH5L7c(j4BbIaR-c(lNAQE7T1p2G+LAZc@3;UaUOR$P8lMZ223&R> z`YP?}|8-b;#_=~-4-&=19?}ix*0rr!-CkSE(ztIQOC$Met7CPuvyF~ecLo_XmhRNx z=wwrE(7^4BMBQXG9u!}IN2wTQ1*H$M^mXJkoX;=P-5GAAB)UvkmBt3tSBJ45+xO0! zXIJhMxUMqE(i~IUIDS~%eEiK55i18KnZ5Mv+>)tRSjuH$Uo*?=WAnu;H?geZoA5=) zvA#@mjx8`iyh2TMN$6R0{%e!N;q>ju7*~tFoO)4yyP1ERo)KS~&)r`yV(T~CvUu`L@a`|aM}}Dp{XVM`5-x9 zNZWRB8S};Dl)4iwPqF;t(M=ba*068B^;Y)Hx8fV*aSVpVa%zP0duEo2lpU*r(A(UT zo}UzjI%k=waXd!!SD~xjD@yrt$jHJaiix&Y6J#;Z+RQ{x`1&obK4g6-EtgHU=}>9@ zJ}Hx5PmPF2c}q67H&yHbLus?VS-CF6()eHUacgxo*&lzyv#ds#P6gJRTAWE!K&eC5 zaA8^n)^0Jnl=$h+286_Vc~W+##)rkLPO#WBo(~FsJJLDO1x4FD?(ruK-h|n#MY+X10amf`fJx%HMfDOuBZG9tm2RuM@jYynzj1Utk$S29PBs z#OQUj6Qf5~m;$^~*~9NL5`D^(rwwMa-?0sBM(qlWj+?UD%wFhCI$8BSQyuOOikkx) zyXxgjZl9(GoOt~Se-&2?9>_I4#%UZwpM9G0aJV+Sp}BoEQ%*QDz*M2lV7mttvFtjh;D|YNmeSA8m9R9Wl9LzYxu|=nZ?Hubp(-ra0FTfi} z!W3^8N%lKZ#FvfF6DcPvT-P5Lmlbq|#Zv738v0G}x&@p11#U@o4r%EdBGd)^>WioD z66X*E327yM)JYWywI&BH?cZ=An%^6J7;zn0EQ%N4vjf2ey~2;Upp zA}8-PY|@2*sPS6ugD23ZQnFSDO5MnP-MaOm9`bO7kwYPK9t${C-JeN=^ zNYb;=+oSS$cXh&%k?!8%a)-_8I=FfBL8sMLxqpp|se#}6&pJNZ*)_VnvvZUqrqk;j zN{H)l^sQLY=je!y@3C@(Fs(H;ZdYxMJFwn~uv7xOV@!oE;F4qsZ9ug_v#NGW-77V8FY)#i%ovs*Hlc5x>2PN)Acp#IiX-`v2? z(m!q9y(S~OSeu1+q>6TZ)p{%1kv4BJ?a}(L*ft0{&pKc$0c;yyOv4UX|>SLG-gZkM~>{E1Ruxy|d{ z<}6=P!Q3w{Vnsrdn)fUJ0QRZIw!p(!NoueZiZNn~AWm8YRMd`|fN5_z`hqR3Onj%$MyV2GW6W3YM zxlB5y)&3LBBR7)sAELY-6iTbiW~~hKFs{v5Nl{VwWt<8~c%S)>6Up?`gtqV$_ehm% zWbLy4rkZN^@-;(!EBAqN(B0~AG}iWx_Ny%14=uj#<$b8jlDXz zs5r%3TT#_kt8plb4KjtjDIv02p{Z1q=w+%3yAkQ}wd{KRPv%+JjWg1CG)wVFPj}ZW zrgBEY?_de<@9o>UVaV61Q50!l35|%U-?VJoKBDOR_nY)!zOR$zgZUipAdw0@5^?c-?VeTS(R>ZRLsqUDSXHQtt5MetS7;1Q zPT;Mztt(l9x53}sf7f}%nwD;#sl=KNqZ%^O=K*N(mFF;Bhja6KYD|qwBkNRZhoZ!g zuW)g~X1W$tR+yYJQyPVJ{Ta5JG(Lx#L0J&0LyQtfTNWOEf$4&Qoz1B@H&ZXf2fXF)^)t+&blnA}RnD4WtD?|EE9kb0>Mp}7SM!0IntiP$OeMEg-tuF|itf7RMpmmH zRhxE?#m=W?CHmYg>+Q=74K}4sTf8u0@nWmD(_?5?RPJu<+*Q5{sn^9BJB!uP9gKp}XZ^<1MxqTX{~N5ZLzh_z7RU|EoSMdDhMl*LGXs-oz{L*>ke;VFsreNFwG9L`)hynIQ# z%jD|H^*;=+Nz21oitjR}V0Iz~CY?Pc6*0ec_i!I(d&e0Y+tW+ZP+p>~L_42LOazL_ zq(qA31+?JkRwdOWP(L+Km^&Ovnd8-|;+BK9*m|}|>iYV%XU}V>?iuA+Jh-K0RgAUT zZxnCvzd({B*jrTladHH(qgzyQPDE=3JH96i*qn$xYe$OgWLS6YsZc{_%VoUFRF#FF zT(h!kW$0z9QX^xE{T2bG0)fy#3gjjjGP7NxajfFIvHyi;1$KhVh% zQazlc#YGOa+R5^U0c^x7e6nPkx!NBlY|?s7%@|%4tlqbqFON^!D^~~-2{4^kqR5>+6eT*vzA6Pnbm2Aku0+bVwPW{%aL4fa<^4$++b+25jBlQ2 z@9q$rM0x%<;LfxxZDa8{>(o)`0uNMFkGsE9Uw_3}_4W1b>W!;buDD29;Wox3rbW3+ zwew196$3qBt z`=#slB0c>Gae>d;h+Jdvox=G|On41H*y1&fh!h!C4*tD@yn2Pc%G!)8JzL8~QE zhiV*k=p!ic^T;{gPol4Jop;l;^*_{tyV6kPVW#NoLsllXg3YiRZSNV*_8KPloOLVX z&8zhBW5J=Lw1Z^5G)-#KV}YGD)l@N1L62K9H$QTi1K8o z%c%&lIcb5UvDv{SrrXejLHQczLB>7{pHGh8hS-cir~l`|3*Y=hTo9M?vf6&$mYLc6 zxIM|!v3vdc1HW6c0CulJCo}>6`bq7F&agU{r^_MWxkFOXl=P(jz*d^^&BEqx|KX_Z z&8(mQV15ov72ID-XXciBE0La5k^kW<(531AdXsG6wq69 zcS8EkhI1|#ygqN^n%2z`Y8FxL{|bI0jHs5I92cJxZ@d+5-;tWSyZx+71Q}YhVstZz?CO6W-iLGQa552D6>B}U?bF>5xNoCu zO8Ok(C@yy#}2W2=v|+fzP)jp>kT)oZd+Pm6Igl_3sb#^;kC5LfFg@JUcNx zAy`$GT%nvvn8wyzCxFeI%%yue+cu!|$g2MC;`Y3pAw#1-oqqJ1gKy~bt#*5*&n1;s zdK#=1150=a&J(iIc^xBNP1ZUIz0hl`>`X~YOJ@O`%+1T3_4*uJnbxYR&{%AZ9wgm2 zCtijI4!05&P7da03M;`%On+;0+q-+Lj@k-eyVerj;cQ-RS8E*Wd#vfqHaKwgA(&RC zEz*}6%M6z08s_U83pB0O26qIUSE2Daz!2IrQ4|Qu(mgjx#>eJO5gYy$PrlQOF>1cA zh9@?a-o4FBggU(l9i2cUwyT3;OIhahtyHrjC3l8$cz>*+GHN&6HSr#sGYWkKHEDp` zaU`OQG7u>fCTGNyAiE}wN7@XvIvHm4-vb5Cf*e?e#Ueb;yj&DI>`~jtfXQ}@wowy+9fIXR_;I z>8XA&2NS&j2IM~sznLO`6EqR|=h1dtU!xGCmZv1)20oB&X>eMq_;+mDFSI?<==HSr z`C7I#FCS?cWwy}0FFbpL$yH@K^2m?v3X8tD6fOGW+knB|+1FHAUAMZvs?o=4i4ukH zZ_;W@i!>Ex)_VMczPy1bN+Pi-!AVAlk!q%z2@QM$xl((2`?uA~OKV1}WYNrP@crX= znL%QCbA#RPsHp9#UVR3;sQuCHYWCT!B3goC^(HW=)t&)iu|`>@L}O&$ydB#z3)~#Q zBu7n|fzu86B;e`$fkr1W_3DOEb)nYA8dVp(a{v&T{#N@2%6UyuFNkPtk*Wg zM0Hrn$bM2F61nu{?gC533*2qhVi6iq2URyqrm1@740OSLkLaN7ZM^TX^~WXe>=+Wh zlo#cjub&Usw}X2BC-6(M@2L%`dt+2pxTe3Zx1|9z4~Fi1XqGd{D~Pjd^l30G26*}$ z>a=r+4!(jT1v@Taql1c8ZRJRG>ZaCdnSL-$vaSWxcK7?`q6dQ^!+2Enhj7mi8CDpz zhUo=xZbOf)J~WDmi~m$}au5R~2OIKL>UeYVGzWOPggY_7VH|y9Y}%HVp`Fv*y4<;X z9u$w%E@QrgpNB?w2;N#zRH~VtziN}z)5uT7<1|%5hRPEEWeEw<6X7K!2v?_H zGJ^0kdxZ$X(`A^ah8ZeE{I{hbM3?bPK@gt)m(mZ2vD2*dAZGCDJ%sbVa==eGyK5+r z4Ig0%{+0%S{Vj<-J%)EprYUz3@~`2>o>xe%lkii9#|~MOmsgYz7&K+f)9HC!{2pbn z!sg8S-T}9!S$^t!(L3Y&d4AX1YKy$xtZhw*t1iWXd!4aWu5NcY>y@o6+}!`J&&ZxS z7|~3_xN{%QW38jQLbI?DQZ0;Bc92dlB{_tb6&QVf(NQ{fRb@(+qK&X(>b@*H%2}*) z`1gocV9>cYKCZRpf-RjFHe?$x=sc>SoOdok(C1^zI#w@;cNcRp5#&d9cIK5zX=$|^ zML@>v6`EQe_B>y&Qq?p`nTvzw7GiAA<#?A~K5edB_+ar?IX-XjKcQJ~MenEO1Q`V9 zdpBo{uM+(ZRbBm(a1ovW*I~oXGT}taCcrU|^Jzu6q6$Q7IaM`#E}Q__)6xCnG^j$+ z6MP0*6Me_+>avNr@WFYgOTo2SNI4Y;URC#P1U5Fr-Z-nsy1`H5s6>T%gN*2h$j`& z6Ew%CSfQ&A;+yX_#ST|0TN6*Rs-ZJw*M?qWoL7(c=nd=B%j2#jbe%Sz*_ z*jrKM&8!`gms#aNto2{UN#9saB6lp7&WUTh%^WYDaU_HS$ox_GXu4o>1M@Gw8p*|6 z0PojNBn%f@K2=Isn<>bAj-9V!yin|WL1xMM86Aw-#ZGg~i+65wIV%s@yVB?;x~(0% zE`pDz<#6n5=mghyZwsEBuZEweW}&?)?>f3ggtN&b^!Tb0j*GTswg!dWWr|6RNnuaX zi_s~1Z{QT&e<90NHM?OWGw4&qRSnf0in@}WE_1Vo@j}AupYlR_XI>1S;4ywfFdioJ zuY&(b$(}LBcdCR4f*0&Nv=ixWKo*nnF;*5c#Qm7>$#@4Pb2pMq9o5g>xbnY?X2zf( zUpRO30)%H>8mbjM;b5(pL&R`Ag@}kBI-FTXGe!{&ym^7MnOBi2AVT@fGp=jW@OAB* z(9Gu4m-x%shMXZ|<9NO3T$J1FX9!PIlAN6i{#usK#mF8GS(Bd^t;8oPE=(~&MDimd zvl1RFNO%?vbBavXdC?!Zk4hI!OaFl>uV8pVZ>x5 z#?lLW_@~E3PDlU%zA+^NusCFU(Um@E?HunHZM*VvCb-QzdzRQhVb&DR?qU8A;H;P* zG9atq^Jo^UJl_5V;ZU6faIhqB#8f2aKc)1&>EEr zeyDmVHl=s_X$c5dy9`yGuX9qrJR<67oVz@xC=bz{-B@>4Q`6s-#ima*PYrg zc8>>-UroZmfo4_kW7xTCSS>usuf#8|qFScMB5K3PpFP~j=SK4D6kuX%(vQ4-IPL51 z|Mi44J`iU-6(8WrI4wr8(3u$gj93)LDF(h1OxR(9S5)&6i<&8{h2jSJv-dDYFD_sG zXa1t5@!u%Am*5BeJeL&X824@n83=+S{62JD{uxuoVjA^)RO9JW7eqMDnM8thJZt@o zWD*Vk7^5znRKpzcfEr=yV>5-wr@x;T95}T6aXvR%{|(}a06Nfr31Md@nBZCK=@9-1 zRPdjC{w99H{MqnKn4Lc9^S{Zr z(coGRkth!aKH8SGPL^_IYq!>bXy##?1_j$45BRv?PIbVZeU8tI8m4%sr_bKZMQg)$ zKA-ao*doTU14bApwQMotGZnB6%7ItO7E6NXckzna&QQhn0qn8!r1Aj#2BW1$sP$8B zEIWP4XtmQV=+lYk0kpOcdmJlFl54Si{>76|Pf$JxZOqE&zLYgi4_e6`prR>1ztN&> zDl2VLF~)$H-Xdb+-DsAcJiDm$R)IzQhj4*md5MiU)}O~kjKNIPgAX4To(;x>9F(~D zNB(RW-zsi9&K)+nLnpye;W_Z0R{NeNOzFvOp7VL=;?@waXF959#up1SBAw628W;bR z&I_dVjc<|4rUx7Q-yqC|qK-XsbaD~2R5JjN9|()Hh)&`0k%v`WKHW`<=v3&&gxKAh z?*8%P;)IzKC1%`s1nK-Uj({6NYaj{^#|#-gIee1;9DpPyzQ ze7ktX2^^Xoe~Pd&z7knech&3NLvC@!`d1?$ewDoi<}QBqG7# zk*N$O3t!ha6StB#KIr;3cuU{-%YS|H0_$J)ts?urip(S_>Cdk8eHLK~$tcZkf<(U^^Rw5Z45|OJMjG}usghbRczHOfD*Bc9RK#|fn z%9O(sVMgbdfX0i41ydc0ayZF}=S?fRSKE?hUkvW&8Kcms!JC{_BKP!(@UGZJHBo&b z*68$ADI9MtAULTAC!_B=4>0ywbxE4Z17BZ6E#dPe^R^YEdIT(`g`cDjr)hR7Gww1far|&Hjt{B7DtJl9!y(w`P%LeuKTX zt*zGDu+S2r@3vHps!dv%5{AS}dtyB$7mfFc)*gOj^7ztUB+o8eAnBqcV8lCGh}3FIod^-55hG(mpA=go7_@; z|H^e+M3o(>sts1{ zAfbk7x2dYTBMu;n2KbedNW9gIb9D2C&UrOK`lP%RHNxH%sBchu zB9kv1y(Z*D7nWcm(9275Yio%A@+15dOT#|HDK1YsqRE=kO5M~e%YO_%w%v44q-sTE zNuvA?bY44tpuS;wR_u-*xP99Eq;2a}ES+!TLt5l>4b?Z?%1cxtJA&UJx)Z2eN+Ez~ z6B1SE`Rs23aUsw0rK+~kRa-<4oEU$xrnaYb~8(K5FiPX5x=U6c#jgZMKts@w3WW(O$J2#hL;>T}`? z1vPBL>&(EJ2}v!+(bZc-myeIvNN^QTQB4ip9#+A#r=_Tr8{)e1IJROZ(lu}=zg{QA zH;}~OTru})XU-ymg%f2(OJ_-xMYM|*r=J>&mB~sNP4x*_nK4Ld?lnG@Vp`t0L zwmQ6jZ`mHH8)n7Y?AKN;TDYf!%^X7K(%{ciGlzN_+?;4_nzrR=vyLcQ846#+dt1>% zc$Jb$@?pvf`1dF9OONovg`}1hna;!%1S=s+e21*Bpvv$4t+VTA{Z4Ohn(xx+1fJjW`pVzgmS<$$-wuddM!bJkVL6Yoo0tuSG;La~p<=R0@ zBrYaRYVBicv%r%Sg)8nKpe|!8B8xXtwZvN8jZt)3$}yb}!M9eSn*+icxviR06w$&^ zCjr1FUoh^uMf@znl1VUwaM{_-8UAgk3Xh{VA>1E`oYywQ3wM5lb`bv}T>jIv=cL+d z4c@%)62bP{gmGEfWG>D;E+mmf{1R^+2LQHK^GN^Z)E$^``V~J!R9B5e=WeeHUD_8* zQx*)5V8R7P=WDgKzD8a$F%hIY3p|A@RO4|Wv8_CeS(j5L%FSC-Lx*E_X2P>M^LQsP z0JNY=hyjIjoNC|{PBwmTY-@#WASR_rHGK|eMxFtYTh@ZM8v3=yE;S zuD47xA|;A@zEYO&#EUnP{%aT);h?;;*BzUQjo9h=5PdT3a^5zAF19gE@+SHI*IPn( z1OJ+RaUbf?hVqM6`7nm@T954m;W!IC7iJ%Z1Ntcbf>=8Z*fML1x9LF5;Mdp)=B3$AH)_2ON6y1yx_gIJ(>|;AGB`S{M6f%w-3@Dph4hfalwP{g$&S z2hfWCcxsjIZmMa9Sl$dKGnaq6 zJJ~t#?@Eek6=rx_PV@}{Yw59l6Y+FUuXe9VI2fX})@a?Gh(se=mc{$o` ze6BDyIl0XS^KRf)RI<)3z)^8ERX*LVO=NeWhzq}=0z+m&4%@B+l34MAL$;R(TeQBI zwDmRa4R+f)Ps4g0z}t+ar*0GHkN+dOxZRTHOahtA&Dsu4qnde7M)n`=t4j(DPSa|) zdyUz(#w51*@VymGq$RDaL!X$yoHDe?l|Za^k^KjzI}5zXt#cwJRZA@GtGH&X4O?3N z-g8#IgztC~U{vxdz8`w$1@J*(cJU26|B`&i-mtTNhz%y46y%)5$?Jre=Uuw9_Dp1N zc25xmxwD{zpx_(H_)T+LK`7(#u^dl`!(gTw9XXlICqjH;!zwO0Xnob%(NfzQY0_~w z7I-}^B@4HYa4Z)W7R&NoNvu=3qW0qP%f!{szy26|eSw3yT*17bhnU49yaZpxP@WmQ zx}dOs2gmTD(#43Y@iecjl)KCTjNy9>j;erI#iqlPx*B`ANCtQS=bJ1G-nwhR?HceX zX%9qO_9M&W3q@-Pi$Hf;D5ZcBi1y<yR4ck&AiJAQ%m+Jf1Q0f|B`33Cyo~1sa=VCUg>0)>5JX5|t<5 zKj;z1ozyC7Qz$y=f9HH=a8htu=qHg$HS6NjRybxB%bdYUr=AbUiib|psFcF;IxTS0 zHX=fzV_#!k(t#&~x+KQ!=i+m;VoHZ`4?-HnU#fA8nw?u%PCQeo4JuFY!?_17iOW2m zO{ppCYPlKJIF^#K!BaJwG@dKEjmg)7%;@OiHVgAZ(1i4AI<*a~1z{@rw&V?!&0#hL z%!twKs8D~ZeYuP|m55A7yPo+tXhBS^CD?+Pi6tS?nZG0bQBW4N<~8!r4gzcjui}-( z@?Z{>PA6b2`KP3RKWMwJqfy@!lfK-=F*~>|TG_r#i7w}j_7B4w;?vNvw*R{b2n5XK z^;2%@RTP!!Id+GAO7_ZL2m`nDrk2f@E(tT3RucGOcP@{JzJcH1xM(%i5|}R_8)#u$ssbZVch_keW7Ai8IIah_#V9*RRqFUie?7cD0bN7RpIwGiLg2=0ni4qq1*hVXoTDF+NnS9H^|8vTV15G$y@tzC=7fjPDAQvdo0}W=Hw= z7~NHd>y^!*$-Ko79mbFw1BKT^(eH6sxPDW5(&i?P!=`m9&7J-j(M!kQ+%PH@f%y?* zeP|tI76`6`cnfYb*=sqTs!Y(=j`12JQS(9XifLCr6e(+kpJILOn(O{sh}Y1fQIrsi zjZ-$?4ma6+*Q`uPUtL8e@4A$Pb|Wbyb?PPY#_?+fIi6t)?y+dfIXSpZWtu>7DaJiT z0;IZc8maBc;JL> zR8TbJxF90Ww6b>wvDi8)(8+jnr&i1QWCLTuNv1QZ-oygXZEZ;uo~(Q+Wl_}NFwOQ z^sHIkQ>^58U(dNLA%2X|9+^9H#rTgR#9=w*;(IYOGRcP_2+sCXoa170A;+b?Uz9Oo z=eXSk}@zLT^}a_cqrbPp*-JdjDtei(p+RW*I?Sg+;T9^1^Rdujxh$ zQ*sI)WBfWlu^&||HmN5SS4ofRqLEAmmEyI=7 z<(kNN#8%f-w$jO>NkKF^b>iy~U)|K`oL8B-t0aHv0X%N6Br8r_L}RC?(p{}}V;eg^ zCSjg;g?8SJQ-|}x6O!3F8D%59y9s~9nRSKO zmJ4SC3XnAkx#H6XzYfg>l-@T<-T{;W`0AeeM*sL`5x`6`8gKPgF@{ zHwJr4?A=@Tne8-Rd|K7Cb~%P`myZUC6)R5o-LIz9$a#kfOdlay&>j=PCZ{le4zs~z zpYR(@`Ep#lQxCo;F@~Q*+V5i9DRB_Dm`cfz-8S;Di-K(Oiztc%g(0L8A+O=j*e7(X zwM!qE9GQ3hm#1xTBe&3h6|BS_VZF9I=m@?~*d~6UakV=uImj{dfvE!df+s)Y9Ko{V z#QiHL!zRJegIlrAmr-^cHR%tr-?QYk8vhdglvH&==+mg*8hE+m&SkKx-)Lk ze?8W(r^UZ|4K%Jio#7_4bUw1;GVBMsLcM(fo`OCv$RvAUUQPpls?NtAe%(OX--F!1 zmlM)iuf85UrBp{pGtZcVc7?$iLur%Pr?i z0B=jM3<4ni(47}wCOEDk&OkCLqEuL0d2x-ojV(L0KzL{~*jR=K45L^Es`vfUB+IWR zq&J}eh8{dK8Xw6#3!cIJX-$4V{=kb}bZ^HyFMH9{F}_gBe1vygP8Y`x8R2UYH+qtj zu}*luF%wh44abymo@ocdAL?s)n-QV04(><%J9xuQKg-*kj2nU@F0@M#8g;x$2_1L; zw?aFXcD}U4N%%w@LFf(@DqbxMSP4?WAMd zw$-t1J9%TW_8ga5ahPgIGLrYjg8#Yhb@I@sqhq^{o36DkkXSV(VR601ujV@kx~eW>`-cq5+~h?SvIZ2^wqmB1DK zHEWeY{!W33+G6rp_Lhb9N)^^2R|lBjo!MQQbc0DlMpsFC(%nTAFm7)JGt!&m9EZ85 z%BIuuK!)(c%}j^6%2TJmluF8CbA67^HIGN8weo*Uw5I#ilirPlIUVTanKTgv%@ z$AsF)_>LT$o?=$PI7#ivMacW4UoIvTWnEZSwb=+IEF>S4mVcF2L#R1-il!@AX^{_1 zVFElhQ_l>ucUv|6A+s|F z>=+)6qWN%rpD{6hclsXPX6U-B{oZa`J^;Ao%#FvN12;l)et#k@bb7-U^~cws`p^&i zoCMEKpgRk%6T9=t??ggxc<^1WgH2BGh9!x-+l>sIwqD98%GZ=4-;#vr!Km{VW9VP- zVc;e^Bq$jW;{!@}XQQOr)NNH=GAD7DlU^JD$;v-l7T!Yf(*;pT@7`$H+=59u7A;K@ zX~Vop`~(_Z|4^TJyA}U4cN~S|zvk|VNzXYkZ<$j*tM_A6H1S@xHx@O?DPiRD7z(F; zW?Lq9vb}KAk)l2AS*@H-BV=~z5U!+^c0Dld%aLSqX>XW_pRPakNFO!Y_D8icKax!@ zpePS2mHM$CYag+tb}-%P1Ry^{SW-{>pmbB)yY6LQM|&n*3#)n;>cX@en$`^J@Kx1r zenn1QJ0u%-0Dro*<>Yi}*VxqtT-$-7{rf?L^lH=1#3iPNQ7MQh;kA1C&D&pKVLx|0 z?9-|BtQ?$+r@hvsbDF|?cO^k3$YW39=1&yrlpvwA+g+O7xt@z%+sIUPFPXLU$aS*MTJ zX$X+wuEKs|OSW~~j>dK3A6k8;LY%?!JdGI(CNiDTZlFS7HA^a_qmq#`%h<^sh1VHM zTz5x=p@iXeNYa_>!SJCYl;W&b&|5u$J8>Ic@@~N=_!qFLC}_azI96LNuLakRMT1*q z*!o#bt+h7g5mhwV2<)4Z8aX-f%tzSeaG(N9n-Mv#3##A)V_gI_Lksu^!!hCufz5KFbgdItvl@*Z^y ztE0nelOs1VS}=qbVbS)G90Me2GopL(d2UIzEXB+jh}(io`3Y@kV0Q|TTGspK3^V+#BgR9?Z)sI zlVQv5X}(uXn%Ly%B!k!;t@mibu3S&y_I!I|vjdOTr#nb71)RiTB0qTO=vC=CNpx6X z{sK2+8h2oRFQLO#R4F7;tjl`90_zZ|OFFdi)5;2ol^M5Km~$gkY+?B^bzjmPccUTQSbMbOe7%TMA;N|BY7gLJJI{*7HqNXGrAz6Fff zTJT|NUn8M&s%MsC<+j&;3)?P?4eXMJuD@YaIO6ZAjaY>#5asa9UZDnpKpY+;IXyT< zO&f|2I~k|!5%Z~QJyi+uxhLF+CakM<&l#=>8PIv6A2#&~`%sz6L9H;h&hP51Q4gvn(}wL8x30FI%3gBM+R~hUw?V9bwd9>#Zlo38D+&P;E~1mVoeHY+=D|^uSpd__0x>}#*V>L3qheJwnO9(vRd;f zsx0=8Emg5qc6Vm~(7&UJwvPUEWrDM+BMt`k!}#6iCH-edWA?SvjO8Cyu1ga9U1dh7 zYg4TriY2Boo`d>%mQu7i+%~|}bb|b25oO*ls*PGQMw7v*I`s}F%DN7oIPm)t_a%3W z|ES=m>o^YHHBFR~owPgPq;&LIpZu^5sYf}g`pQIt{4$ipG&z_tl`N|(`>cY!TpaHm z=|{rsJf!ZiFf@M;UllxjNqfln`^o5#T8m`|7H;J;ua0H(7II%Un|eP#lWiY)oahre z2h~uL2_%poq!E}^ad9Ndf(&z=oI5^5M8GePdVYx>*v*+==PFVuR;sWh#VlK0AkQ~0 zr2icaC|>z##cJ37Tjb(JT{|B)UY<^9}m-uxP#of+#;J(ntWlI8@S}mIW9Nj zDDIdWDw&8aaDJOuUv?z;`QN>kQxb3AQqdDPOiJkm^;o5tbK<0tmo^$OuCKhIC6t+{ zIlp_vrNiU*$Kp$9B?;uOE$ew`SUHK9E3AQZ@`>(08c&6UBW}^BzyBG;z2H|T%_$B0)jq^=M*#c$Hk71jIL9yE~GM?LsF0n(FBfP ziJF)ONETWN7d2`jm-ARu0e=h;B;|&~FzBb`DV5=0?-B8H+=Oj&i&xeDT+%MHQoH(- zr=^~pY#dpv!+C{|XO7=JH@K5eU^hV=1i>0mz9X!;&M{V^ER_}_aSD;+dN<|zb{f!d zuGg-%)Qe*;nY9!#`vno>J5TWdUP5!MSnL@024MRK#M2;0&Ta{QNs_@$=2hC^*6Xwx zUX1s(HrhbeY9BFgnG?2M{!21qc?-5m(!}x zNDCg&zK`~l3bY_=fG-P~|J;ulrXptBWp$JlOzvz~JM1>zmi6fRQMgr>Vc3{nt!wAI ziCikEg;cvkm-E#u42{-1t`|g2j}`Z1l|g(TqUWV3f^I_~*ntB7i^9FMz%B#bP^pEF zsa!PDGCtx46JPy8_%~7y3`eLX2FP)Ztn6++XMiQw1(V4KTfU~x3~OF-`r8Ss7$)tH z$nRNRo?oEfz3u~Q3_aGOzhA8D>?v=;3|({HXbyxC44NAR-Vz#Hw%jDpS1Mzrasu4^ z4E&!eD}xixR)GZEZ$lS?ne;|j(B_&_e?iq-469en*W$bLn8O8NHx;0RA3 zUI!HmD@2BV-T>fJyIA2|3GZ(xX}d9|7u|8P4+OByN#GI-!1unIK(Fn$!xL|!-)+uKTp-%5kEo( zmlc}7lTKlWZkM6gtjz~PqbLu zB8v$?8E17bD$6Kc4>u!Rq@oqup_Q=`TG&w2`%7_mlgXtj!2X&f`W=E$BumUCUetw! zey$W(KE3k4SMq^c4aG6+i!lFEa6g`K%zXq|u%_-c#M=v$k)RtTy;X|3Y(}Q%x5gKM zsez4~QKZj%`MW7W$7w8i3cwM4=sl`t_bXUbvpuLIYr9bfGnIXOk?X;Mb6n>qm@MtN zlgxIxh**8Qw3g7ab*srWPJiQ_r~?*P3Fkd^`j`{Z+&1SD_wtE}>4c9+is^{)Gu**~ zYwY|bc-9lUa!@9kZapMk5HjTpn-r02Y?9yGIIE-Cp0UK)LGe%uo>=GtYlm{SxCWu4 zE`-&vlc^QPFn6cioGV9TE`)sL%`T)vPpj%}=uvtgFd!U}+{va%K|GFJRaDfBjv{Zw zL_Phbb8g5&pej`8`n9TgcP@4$fDU@?z~&$J{g%%@1+QVQS2ev#3UI{Jy+P#q?BMN+ z;6%9%E0%LiC}DfLVp)nPQ_&f~%t=!mlecex5F9(GBjJx+j<--UeCl7(u+Bijx3)}%6n*8LB(XeV?qYWomBm=h??DMd1Ci%+)_lNK%YA$JY^ zc#We&f@0u)Ljre%qJ+hDa&VO1Q^STvC1k8%qk@`wq}Xw70!Fn_w*#P-8`<_>Egzas ziy&B~^)i9=tF%wn$jaYZ+a8k@E>A)(RUKo?*&d4vL52XChBg7vW8(Fc;6bHuI(kx7 z>g4faDbr>x0b;_02`CABN~`wD=j)SZAW;79p zQcXk*U1?#(dW<_X-2=)H=->HPK@xGB6e!WBjtWo8z{~FixYSAeff*-yiR6r0@8He! zdo&OuSiC^^W>;n{Qj>!~tFB7BI}GPdaDh+l1=JL=TZEyQgF^aC?Omo!C5EROi2}*u zlDW1Iy=E8f&lS#6eYFQHOwrmg>#S* z_lA|+5jA4Rh-<)=jtXzryUfo+=eA}U6M;lrl?{`WP#Gsiy&4JET}JQW>OQwA`KjeJ zU44C~1FINLtbHR4O+zdh3PKN~uhq3EQf03Fmf@O-sxp&m>d^qvDF+y^@kxf25r!_| zCl2O;`1rnw$=7BH*$qY0;o}MN;#+sW11wsn+%A(HEF~`{Cut82qUkXO3?E;6jS)<1 zxe#vl8Cgdrf@5FiZ4B(!i|0veX-@dLvcGTe`%@e(`7Zv7K@QGi4*Vj-v`uS|o{;KT zG8XDvIZUDxYXMdrffeyHb7Y3%Vxk(yzLCo;Ehcm23p;Va&}dylJqT9ATD38uo1SQS zk0{zzdh}7>IVvfy)fw{c{x=+C+%gG^4nUJIHk)g7J#!ncia!bo!NJBytuQ;~$3+?a zj3Q2C3EGx{l-Z7@(T9LIZX1Rt*xw#$lHOq*+sERAf|~1TZXp*o)0?WQzlVRdU4$G- z6&`K52ph}W_ALBb3$%vcH7sZd&nDm%@#9mT?p%Ok8;ViZ{3u8}Wms~5@c`oAJAEhC zmjEnT&?5OlJ=A`RH72VD=AFW$OH+y#?L-#el&lXl^qtW7)TP*^23yw^vFm#sOsA;^ zkZ^zbN!}!8;<)3M3sObvhy3^**FZyS;=Le^s#+P@KkyT^X_x=-&B+<#De*8CbUNHNXnvf1b z8&p}W3=Lzj%u|uVPT&Hs0E%|lBXDmQUAICYc~Q$gB_=52Ly1hk*MU__t(25)G7GV0 zB)Foe6U%h|*oh%?O-_pYIMKF4znxeRo!lj>yq}i1cW2%a1r_X=;K=fofrt-+3i4y6 z*#fVCC8h-V&8+8dab>JjQAQ1edY>&I!GGE4V1hr{RYMa;crt2FsZ&I1e?l_5FYf*B zVPvUyd`E>Sq;Vom{Hb|fVM?4lc?jot;d-FmfMU9;17)wkWpi5W$`GOP+cauoB(xVh zEI-n0O7z!nSlWlLzpr*22o5|U%G5sCH;0Q!!J+RtDq}zVJdh|_NjEFlv z2z=FuwahNC1}B0)rL^+H|H;slAj{j~O>k;uc#u@hA}_}$>P#sqZQQ@F;4W|NAgAC5 zc2iN{d|3*iGwZSsjLiE}QdDA@Oka~2UUhQ@PW-ji(w!Xb8SIJVz3W87EIEtCQ|eOA zq1GI-@t*eAET1JXg15~8@DGhJeqDHsDwDdpmVfD|tCHm7ePW3Y6~Ik*XAEnN1Ss zrH?aA=kzy)X}@uz)D29xY15-%;7-$5iw??>R8$P0*G|a)(%Su`r~Sc7`u;4Up9uY1 zFAdjy$4_I^6erB<*IIybpUx5T4-|heM~?Laj8+Rd?NB=+M#vSL!zEclUr*PvycuMQ zJ*7~B%^{o+ucAUX^YQVnb)Yf3kzm9!e2zyK0k-k}TaTPGin#mAIBnp{7E5sWcZuyZ zDk7Fi&HD46ih! z<-EC!>eT!9d(~+Cv{GZM@1q~Q9)IjxBMC1(wNeTxn6E}YC+G1!?Mb$q%h}DNTZHJ}tjB*NkgDek;J;m#I z_eF+cu^I9Jn*_U~f|K(N&5Qo)MNt#&G)qR8e&8UnB^-y3Sbeui2CY&c%7H{=ggTBz z8}3f|1e)t!T**_{=f)I+o}NLhHbt%#TQkLH_K4;yYlhxlagpopTKidR!u!Jqm3X>1 zv>AOrNuS9O^(2~8;S-4goD3a1eL@qUrhX$9|Lq-aK41bim0as%Z~nt17;`9cUmMSgleT&3APa)r z_#kCu z@))Aibn{9NQ$U0z%56x)0M#DsA?M)GaIhY$od4swK8F-?wA+tu7tC<#>?Wgl=R@^q zoAkNXNzD$PoER-#Gh8`~OO7Wm$+f!{)fg$F<;U74pT#Ym?elFzJm26)P3QP3__~%jW}V&tFtt6ncSR`wKFD zqNG0`bXlo#d`;_Jar3xK5OrD)nm6211HVUV2KFG_mAPx2rZT1n7xkX)vFD8|R=Df6WP z>y|ceQVo4#g3mR*1q42pLV7tMKBQMm#nU)tKRreC#z^DiBQZq9==vX3(CZ(YUQ_4{ zGtp^9zq&c^2)tvz1B8*35@{+7$>}Hl!0faRE%;vdx9kRDx!c0d{+?(I!LIIz?V_n@ zwUO4dvRN@~5S%}&vM&(n1AL=3d0}F_Dp@%}rw|}xd+!G zk*t9#uZu#ULeEfh3|dA4I<<`~&eoG!6!c_r%Un@YERW!`wo%u#G%v}7XWnzNh+y{F zbs~0((k?n)|AM+C6R}dnqb1$#bSO5@5~)EB-CIVJ_AHhG;ED6JR2|un!28|y+h)U# zh0rheCqP?ngs(Uo=2O!N31FBUKe7+EIJTt)Jbd$YAcbp-UI5 zk&wZGUtVZrIV8VnKjR9{QsY#M>h9<*KWcM9TU|h!3f@pe%?FV9I47rHPO%>BfIZAnX=mndb-HuP_8NyXjoVYs~vhW&(z9{rG}qz zGPBv6%$g54wvWOn1i=B3Xu}-$G56=^^Oh~Y??&$hdiI;pEhpFaK|cX7F9r9v!OR_vC^!S^HN#7TJ~kX8LzbSdZKylhI{llm@H$+i_G1Uu)? zmY2^UGizs&D#5Uk$0z76ti$LdEst|yE@3;Zm_3T392o8=mqKC4|Asfqt0CMsjpDWI%UR;&O#8Q?`QN_M`*s%WIX}GSeKEhJ zYJI>hYD_+aKf&LnA_qJbyU{!|r7*kS#urWGZ|(|KR|2cqJyW09NX&{zFOOZ;>r zrc8zSRQ@{=9>q7Q?7t$bBiqeZu4y@cUbT^IP1lzG^IthUlJoReuM-)HF;XpKO?~Ug z*_mxwxuqtX!qF1tlIB3(5EskYvO?PO1!I*QUzPhglI8(YRsVS0FZUy;mTb8;e$9oX8<+?-zSfs%wP{Y>rCD*I8AIL-3; z*_u$|_M6!eFg@^!g+v{?=&D#^`y;x!L&~<577r|R3jtk50~-&~lqOAqO&Cl~x0e%m z{;-kBLzcms6)la6RoY8`l&ocf8(W1=Dp$*vwkMDK8R-`+U*Xl7R8W(o1sH_h>?l$} zYY6Ms^24QTm#!HPjp-?4$~80&jCI}r6Vswitv0To7x?@X{57-LNfHMrVjWhYh;9d` zs%y-jTjm4SZ_xjzs6`T2u&5=5FNXMreb8G43rZ>Fg1H&hDEO@F1G_^#j(+RAe{%Rz zxye{#-YR22H9jG!mYD&_KF+$NZnmwr23&Egi)!Q40d-!_RgYQs_oLXxo$g`LQE6(^ zSP(pqu6<7|r73T-7kb^GZ(IM|vNqyN8ms9S_^505iKgl71APP|i#;byAf@tD84dSU2}QpG_k!VspfMB45;sI&Qc1uL@Hx*sQy<9-n599y_?*L}_ua zEHDo|*Re0hqcSrvfu$3th-t;rs?R5l@2%DC!%0Q-iY#A*$)k#-D3_JD z(ic0r?Yk1NXEwKO*k_0{99Gckjg|y0Qxi`sZK`OeGqQdxPJT8!8oD2^?1;_r-ywQk zso$qEn>+e=*N6+H2#+n9-|olX(^xItz#A>Ro89+7;+wDd@7KzPRR7?LP?NszWr&Xt z+%M>4k$gmLKTzCl*umw!mTTbELw3=`9DPm!Kd0A?VeRaK4v`h&b2;?m8~7BF)Ldw* z1^3p^U5Ja*lUQ7@E^NoH>em(O$I@fjD(O{Q=?C%-c;y4>V*bpkm5RRospVvT9^j;S zSJ8^fB;=!6imXj!FQ~k{hJgae1!x!Bz2{WUdWC9cVF5m*V%f3ELquHgKg=C23luQnH_4EzmuW3|T(DAL5=*iR_p8=VuxayTaXMzHt!N&aX^Hv2F!sAw#D*ow* z*E?)C%g>L04$|~x+R2Z}naLh;$(>9ALUkcO192bv+sAS#vN1M$Ug`T&dg1cv$+USV z$g*v#t?ACm&rnRWZf(K$ZO}!6;O}}vs}E3ynT48oH)Zfswm(HLbng`!Ui@H<*DcqE zIfmWF-DcZ*vYtB-l?1up<9*L~dziE1+@OCnFfP9g-w!Lhb|6Bg8*=)1COb#GhdY_X zJa?c00U3N6ZB;ge1wI05Ar>Ql86iFWGQK^Rw{sz_5Z9*-uMKpKw@q_&#GSfsAgX$$ z{H`{)`S2wwAf6)hZ!QA6ax;W)`2BG)G+r3l8T?G-82r`+Ja@n#1mM4#V4o0*a|DHJ zU#mfW3c7Nts6j&*6(`l5eo)Z6rJ*Kl`5Ug#o&0>Us(4czED`;LlHn!D>(8#7{ij zOG({NBYYZSTKH>OT2(c-b8YbXk@BQeP{mg)-6NwB*HksF%>sX*y+bzvR_|sqUomx| zfpTd7EBWE%zQpA>-bh=MC{b} zi719m`MTdU=SPKSzf4y*f!rRAO;p7E%@hLsZtRCILHxm^V8w63P5O%SmaJtyj z%Rp$0`)beQtXDb)o>vrSz&9!?E-ws>nv{m;qCRKqk8Wwv0{s2ryFVJ<&HuX`Y!2a{ z&6%o~(?AWdJi}~D)y?o4o(E94M^EY3y6Cy-*ai0~%z16Ol*Lk65<3q(ErPPa#Im5v z{wyk{I`!ST+xCii5nKqx*W~+*%LekxM=AcBr_#J|adE%jmKAuSJW$8gzO7s2fp3B$ zD8+rxc+r@Eo3rUjz}I&T-yPRQP8vAa-xru2p=9rZ_#kf33vfXpFz9g$qWa8~7Z!-A zGGC&=CH18$>WxW=@yNm%iz8pPdL4~FObY{fyNgJ2LqA~jd@rxP@ID^4-1to^I15Wp zCNnaay*#JO@2t78uNcomlf94xL(C91#0o@+WaZ-O+qQ%^?qebmOsXF z`y&P_ohZ6uzestDb%II!4?lJ(?(jIsIQlqIo4%;JW9>x2@Y_5AT!xheU8p6omRD`T z4n}@hYOYjby0R>3RkK_%w{NkLRMC(y;d{qq$kPfP6#W25;NY%^1WwY_wp%PwkwN+uj150`+xS>I_w6XoAM;jA z$DUStEpw`BeY@Wjj;JCXP@M}A+cYH-Q8?ibd`x0k7Ilq`0PdSTgiILCu8{-tepeOttg3Uj-)de$8l2{CA z00#CW@Ed4chts0I>T9XU&+hakQn5c5p}o=f492}?tDc?10j?`btp>V`W&2!P;eG4P zo{0u^nEJo~clK;kG*v+2j4f|s(k0BUZv$;j@C~@6)Z=AxE$nJ3XkItHR(N$ue1`fH z5e}uu#~aJ^C#QE~w2k9?S}#JK0j=O~ZVD3p(XywCavnH82++f@$*4-SIFPe~H-*sW zD}ZaIOf?B=>215d`omTC@ws^>SHt_RgBww9(^t$Z+GBQB(FBKW;bAz3%j&kowu#9# zV97@J;JU4It#dO4$M5S;U4fX`D<>q0LD|DpY7O$A#c;9ev$eSwT zh;Vd}WGQufd)xP;1VgX$5KuwKdBgK+{_td_s<#rP(#TRhqBXar`OsmkhP%7|r8-8u zRXnEDC-M{232-}5X7PN7!T5lB$5d!T>G7AYbIt2+{ihSeBkC&-jHV^F&0{`mI(_q7 zMvQ94=0St`EonYFcpzv3Dg&bM10=^#R}3}DmBH`lQg0stB8ZP8a|;7IibcIq*yUfj zV3G3nebfiDRJqU$iP+LOTl&LRAv&-PT9DhM3w{8w70?G->#t%>@z4YA^mUUrBd%|? zOaIZTI6gT%=r4hG>BQK9MC+w9d*TN&2PAm>^DB0~)I2GrmKy@e@0r-AzW0|pHbrYU zZ1lqJQ+DCtgU&=v+kdy4g%by`pzG1=c&^GHs~q(QN3l9twLsm!YD9a-mo{uCz{ z*C6ksb0|5v#L#AZ{!}~n-y(-7YOU5RJre)Cq%y?oz2u7CtoGAQh}RQMGHcj4)uRjv zH?|>%i5k*TY^O8S5ugpBO3x4K%y#L1FCT3eQD&+8>*FPWzxKn6qz3oYjubT+PK5v) z&hH(O{y~ZN0p(BK#I7Yz)oR!H;7=do_fbpcKPH+|6$SBiF(r21?a$qimN}1Gw;%0Z zc7qGGbAG73M&B2^aX<);-s|SEO~Vs6miLWI^Usmq7tO1iYk<$w()!M}4y0$A)~X=L zS6-wCzHz?z8d8wO=?&4U8`1Jw&tD7tcD`z_TfspYSg%Ba*3350O5qo~Mnqs`k|DbK>(aztZ;)e*Ie8_GR^nwcr^cu{8F=7M$@O zxq2TG0H3wOa|j&Y5RER4DcEV2b^f#C#5>r~;q=&3Rd{f|A^X@t_6Xuh6x)uCwR@x9 zc76*Gi}mQP_f>g%-BLIQf^UxSEpR!|T4%T;_5^PIt4cdJZ^_jag8D3)u?#-LgER4Q z|Cm{}ZE}1#Gh6)$TTYRqb8J=^gh4^+Wc{>UE$`fxu)Lyb=i>j;$m?m;BDP?&_+s8y z&zyz##RmM?cv7im&b%7Xd{QVj5-G&3&RcB@+HU&cE47VQe`Gp@P6^|+Vz;v5-ok;S zRbjP4&Y8Unb4|Jl+c$!Dg85HM+rA0m>;m_oyby=gRcxqUfoVWklSa=XYcHY2N_n4=Ul%hdi*ckoarYcp7 zCvRqgPW2!>t1e-B+oQmZ{F(t229`%E_+9*HcVvQTiJ*{o*xo_Js}%EGVHEWF`cg8l zG{EQ?Vd>Id^}4KT%i5)UeF>mS3qSo6wtyD*9>(Vj%CO{UQfh>(w5{v+mW7-tR9qi^ zT`2Bgu(?XzZ%R;OvsUl!YLn!4=3f3Zky}J1UGWADot)68us8PQLbxdUKCZ!+5_Jmf z*yC0P=zs=xlJ?6?fSUHNvnZ_cd6rbtDl^gGq$}C(TK#IQY5D*q_#S+_?7L5mWVYBRu}7* zgxnX|3m~XfCArr9LrhM60wRqaY{x*gMoLM;zzw2UZ}LjC)D_XUg___)5cZ6g;Jp&B zIONoanC9@A(1H0z*mw2p`4UjRcJ+K&KIe-4xTR^+BDYc;tUFc!dJrCestt`DTxFeXyYbqgA4<1r_{+vZpk6PmEdqZ0Yn#uk5fPsFb@|WI>P#n8gQ}A& zGEXE0wa}lOhmgZl)pBudBlcA%=i;NKjCnSn56k#S*Ni6DbVY+(3Mnmkq^l(pF&zUb zxy%0IGjx}LhP*;m1H}m@n0*X-N#+!^j(bYm9+1mhTdItuC4D(N66lGc?QAvE2URa` zz8AF7b zaV^tK9RLD`qIcTzH*CYI3M;#2@G~LRucz9V?02_L+gpU3@mEYPFjH_hsm3aYN%vPgwJS1)M3a5t`4m8Ns`Na9EOP>PclhKb2(hTN z>o35qQ7d+^0!cocpG!HSLz*FDxglEgc=6is*L~`mL&?+9chjN6?E`qPV5!lqPib`Pd_E%fr{Q6#(3`ojQt0in@jDn2Th;3v+UIh7|<-#)|Tnt zg?y7rFZmn^SCFzP%9{M!nVcuT(M!rSV?m?JnB*iKH}vXm(`w4!QdLvQHcF(Pm{+NK ztBkJ5^M%a`O~zSHFdTTGVL})>nUh}o&FfX4ADK!d9t$}H*)zprmLV;3Y^YSiN!-BG z(79?Hm&rWQ;L1rQHBq_Dq%Xvu(ZDo!6M6Z(@AwG!p=Bky1my%|E*({`_1-INarGu)f^d*Kl7YuNi60{&c;sMex*siE zeGVi}zISz6F|Cu{uVhgz%J0}#WAmJvo=0$65v!9vbWFpspxcN*gI@xk0q&Yym&*VT z8CQV*@y}pxwGh{;pt){x>(JV$@zx< zg8DtpIFQ`jc7DZsKCOhr!ooQq*yT%6k$EdRaPlM8xG4R1DA3<;n7Ro%+I#g+%E0|J zER~ji7{zOc#%pZzg_u~i)j{_=`zylpBhI6Po>x?$>5Y1$Pq>=m+_Gx^Jx!B%O%)p= zR-Y2PtLrugm#321iELq4DhrGD{DjX_<>HFRc#=<5mCrbnS)gw*5U7ARCTW=G&E#$A_ac0X5*R|sIHZl#~146UzqgUD;6pe;>P}6@27Zf z*C@kLk)%k`7e@-47dgM^9oRGI%B+Zki?mT&Yp{B;@c_-Pp2+y+%66dcO`q=d#g^*^ zXGsHKoUTT2qcDD{LVWiCm!0+`sN=H)!Ow4Nulrm2{G9IWhFcr5xs6o*>#1g!v!%SE zBJqLwB~XRJSHkJet~R0#18{l z#ZfdJ&GqqRrTik|h<-$+*nS zqzpA{=FwXU54N-*%svI~6FKo`5WWj|fp8zz=KLj2sqWR7l=PHKCR{R+PY^G04MAZg zjc`h)t!7bhDC=-RV?Pu}4Fj=WjY`HsqSCy{8KorVxIMluV9v*N|L5m~>Qy>wFSiEg zpoB?1V!xOA_CK(~RY=vuCu?C%M{Qx~T4g!2D%fOFkt@{0%N%nZ9<3fHzXymq^c%gw zK}dUoS)mTs+tQ{<%zC@sW}(AA)Q^7@=i*X(VpzgIiVKde2t8>17b2%8NWDM*!2Aru z;>&1(7;-YaM93GOSL{LwrtQ?!^C+5YaHoh;Mw)VSQwFGn-Ftc9?cJEu#9|YKy9Klp zvBKWk<_|gnquQUj$q=;By~<)LT*}eKCYNfQ6b|Jo(^5_A;MuaIq_Uc_iQ3y`O=>D@ zS9r16O;_gVH;9w_=9pd*iIF|JZIjWa4C>=PiQpx5VO25EDrwUmqbE^_3KIoz1#QI= zq0UNVDq|~Hy&jXK2({1J#oqy1fTVx9A_6$H+SVUHa9g+M8KCbW(zA5|YSjT)(F)C? z8QTV>{zsNvpm<{$5O*>eq4u-9ynV8(477Y^s9B?GNva7pkYqUfWkRjipH-}=1mu() z*@y%Lz9jIe5OOMMb|3#H=({k-^Z1}6)TdGBX*p*<*_pe-*q8kV$;CBp31M8MXCOTz zY(`F4(^^8IXD%3IJ6-#kdwd`_B?&8=hDdkthHtw8@mf-Ol>HiD=YI5T=>Mm{R9~1>M2Jcm|S8@ z;~aMradLg?^JjcwX!HeK;<0kQ`g5|GdLg{j6igB;Q9IiLnTK^@2aa?~14dXKl(( zx!u@P>w7LOgY>wHh1iHy^4o3V$2S*u^a)$>Gx*Q@W>>qj=Bh{+11u{ar$jQ;Q5O5o-;#Kwv%flx4X?Zw>@IZb)#9z>8=Kt77i8Lt^l|n ziR^QL?RYi}-QYwhHn>C9?&~&N4I|o9qHftK*&S3=RP6Qn=LygEx%T$aB3+=*itrlO z-_vX2=Ya$(=rl|0;f=8{O$*4r+$qnQBI{~*>$zqd;mS27WqG(FU$fkEaKXKkD91AK41O2_F8^J_i9Xjb$VFnHnPyQEQ z-x!=(7i=Bdb|$v%i6^#g+t$Q+V%twLv2EL&*qYe9dGD?IetzfA>DuSiuCA`tRlBiQ zx9RcWpLwXN+t-xq=C+F&c=w%ohD!QfN;|~KuT(8~SS{v2oe1#Ozt@g5v@|(+lng0< z-;tyn1{Ny$CbHkLcoToEK~cXv~y1!zVQqn`?retXaJKh5@U zd284vAlZ)UW4q5LAlHscxd-vQGDI8R&Jq4`2770dUt&FC&ZD*(AA^mZ`ZP?(+gq?f z^K<=g^pld%fO#>o)2NN{K&)7yuZ%Q;Rc|aBTl;9F@%X?J1)hdEQWQ&^ddi=S3)1*1 z$slvW*2V}ggMqN@J{t}l#hA6S$}vLLqWA`>AzgcrW>yS4doJdMdgA9-*$3Q) zkOau?@z>8>$v55U{sD#S6QD{-@No)8N6m_(IF_2@(SXdePa8jr{Fb9{DVwaLOs;xD zQhM@<$?`1{6-r7UA#rg-Szw9D)$%V=E<#x?hX@UYP@OiJ%HO21-67C=>faN(MZh#( zYj(=4%p-j&Tbq{yM4#K0qMy3Dcl>b_*Yjf-u5s#~;-RvrJpOhBD+tNBUFUvg`ej-k zrgUz4iC(`Pm%Rm(+4qrsQd)gs#d&`GM&gg%eq{z)Eoz9l(B9xOdl5DDNHD-X_6V$g zEvQn(;!!_53|G+^+Cu z$*ZN`PwRU{piuT?X0oJEMw33F#IX+gjtfpFUAjSP% z0BA90PEgUZ2bIo^{*6Q>{zwE8w&Gie#f(;G!!i9M0b-HRJPavgEPx48*lErw$s2^N zBLt)k6ZIlKJn&%nHn=F}Z2-7eEac2gv`+l&L(D_&vA;!$JWdSjDtF^ClraZ7Hv;9L#i`X8k@~vVkAz z+IWzX=e$1E)leIeZbwU<5|*!;Tf~_E*ubBkXJ4p+E(^hA6E-Bq4Gs;C$k-l~jpkaf zS2WEmojl~r&<|8ju!Nt8)vRPk+ZcUsYg%gZX_1Gv)xy;3?e(oJQ)IqM>=8k|Rd6Dg zkJ1V5L81m4IbzcZ6H(2P1;@r9 z_DRaeA|TVfG2*5^!);yJ2!Tr87Va|I&9<^W`Ywzs2TA!Y_d3$A= z0W+D*`lNf-l&@6@7qRf*dUB4K?jG*ApVSx3PI~TuwPctoVNW*u(}ORKaN{~4pd0lO zqqhx#Y7&&G-jo!olf$-HE5PCBAv(o~?Tm@%UIM(Z6`Q3CKt@gkV>%4fM9B`~*8>~; zQ*pcKqL{)P2b`{(bBl^o16_YiOmwHiJ%*@UQ$U>(M2p$tFr4~~x#QA70czrdk1o-x zH@xhqY5fSsH}*r%1pm2=&5d(@MW*R@9Hga2pSWZ&)G{zyirOh9g0uH~+XKZfm?I}# z*l3Tno<|h>z|kju09ZZ|On@}N6ha_qXYzntWL3wXOL^PMpC7QJMISfA<7GRfz=klq zwFh*H+2M&AL}CVm5(50aDh=*3(axo8%;s6+lYu||I2F!D4fB3MtI3&(*VjA`RuJg@ z(U~=6i5i;YeQ@K*xCVL=O^;RVY(b)RIp4{T_3R889i&AMn;U(hscUq=%#4EqPJ8pF zrOQ`rdOR{V_Ks%0 zjSCHC+LV13KjxB9l5b-`82Mo?Fg$AAp^!4~2{I3Q(W~<~F5#F2(Oq8fe_eiYvlG~Z zbRWB3bNujshg>FEK?Q86T*-e5*SXsm-{^1)Uikw42b;XHJKmV+;hFu97nZ#^8zYv< z{%@JbGUw+PcMO{!NYfV}+ArAojCU~>ReZJPE9&{7M_HBmv5gGnP3&I>i@+*ycqU*< zJeE^la1+xL?^8N=xYdlGPCj0%4!Xsp5hWLM8=_L|`ZR23VTPo}DPYH{bL1C+&+JO{@pRn+< zht!@iq7&^xWC}EGWwhbaDuR>I;0JFy3(8*G?gc0c;0=i!H74)iAwJN12gU!iA4e#2 z1P1wPB}gNRc`@&+A?9MopPJBD#HsH06ORu3+fSrSD&x!F{DP0K-xZgEZ7zH~e8i0_ zpSi1^!C&y@vgkG7Ja21M{?Y#18!`8^5e9+mKLn7#aWmbbXBCRmv7`eVAuEXUa3n8yK^BEEOho!(16blx^!-9q9`Aze+$TMSL;;w#i znNd-gnNd-i4FsIJQc#=(NSm8WJFBa+zHKeS5Hs@@`g`+o((9#rjq) zmy}{tlJ7feq>!SztRgnz@Nf_w$z|qH&O}N_X`{7Jvj#C@&^Q++6=97qjwfLB!H;7x z=+^!atk$fvoC|)TNUuOr1QViIrC}f1pZlT>-LzKsL`~ighG#T9WhkM3#*c|6=S_)x zfcq@%8{+?G9jN6^iR3%4w=_OV(CG#qkh(2 zK2!AQzjZee{P7iaanB*l_u*UnWl(P5OKo5u;U2g0xm#Jcu+ew_z|Yh`-1OXZXoQR z6k|U9k9!+2Ztg719rGCi6|t2^+&^T}4f++)_g+p+jhUE8gdo)X4FrlH&oi!s$gc~d zWkRt7y(w+}D#(BC0p_X|;^PwHb?}NJ`XA)eP&Y@OQ7`^ISS51(i7mU&TCzW(=YIMk zjX+pWAXCZb&^2_q@av|Ba<)s{=aJk!7tTjT^w1DUJhJrn{JUZTK1wGE0?{wh>_n3t zzEY4chF7qyA9;#QNN0A6Fu8`?lT3@=`StaxyN=Xb?#XrA;{+IKObFejQ02Cs=mBKQ%}!kJ5Y=)w2x1{%cnX1VuY~Kcx&1n8c%x7haDR8LB#5?5l!jU zp18c{l-R%kBeHNF;kyuZnC0LC2mZw$)snq?foyA*xp1Y08=7l`S!!4udL*=Sv23V$!J?}z?#ew|NM-AOc#K9E}kaxVKKJRmHNOfN>*L6}L{ zg@%udHH&hs(DLx586HO%yHgFk8N*(^qvc<4+(ZU;pmJ=WaCCY=Pzg1Bb>0g`ts%4Q zgNCK5^BNqJGL|`ZrZ;Mwwrb}A!n2ysrbD`e?ZE39+xgkdJx-YIlz13;5?jS?f zrP8o=^{BlXll%ojlc>X=f*+$Q+PG*X5)}C!^XNPBh^O~p>?u=PSZVp7zRe>Cpz9Ns zZ0lAzT*U2A%fDzB^rMK-RP8*8#h>=|eHm^Fuqzj=Xs&BJim`^P-v@mvLZ@Y!798C9 z#hV00Cmi)96910(d~a}aVwEQk?eY55SJ;c^CB)BZ2IwTNN_fiWxJ}>cfzKWITu}jW zx~FapHHEea)(pG@4WvZh=;x0eet2j6|KuDWPBA&n6Dk*_i?XOLVlU}q*QjBD6K z4HqpFujY;YLM47LuFBp#PfPPgnH%mL+QqMrmXl3+7D?SgF1@FWJ}BUtw3eL7=U-XB zk*@yJWSb9JtDDM@C7fR}YIm(@$m)QEtrbBzsW@tsZ8*wse;wKsROHu_j^;xkYqu)i-bxtS07 z(Q`INm1~OEh!fI-tBdcc4KzVyc{3hi>T!Mh5V#m{$hXL&HqV;^E{DKsivLl|FGw0b zH#OWlPcks@nQB@I%&nR0v8m}w4Zirq@P!N@=ku%#D`*Si=^XF#01G`QhnuSR3jPsZ zJi2><<3GKVLrEBK z$#u9Cp602F(7i9os)OEK6lEo*g~Xl6E@c#jFu(e;M|chf;VeTs#*jh_J^6^1lkfbn zeo+0`atafa66|jU$@Rz^>hHvT1|7-E4_}v$rl!^wF^Yru=mcQx(zAcQ=+MG34;9{p zRRy6N!#M`Xv` zJerdSInqA5Qw^tFTPhte4s1)w9>5oCXjNW(Hzhx`R1!rGg4of13eBbXzk`5)c!H)R zZCa}+p@goS#&JifDWMjRw!y4N*(unV1pHntY#h$cw2amuEw%C=Yz#YKr)bfC7?&X) zfWD3#1YWza{X+62%j&Y2%FJkDdy^&CTSAtj&1Ajyy6A2Tk0UqVT@*w5GSv z7X5Jc1r>DhReCCP87cL6J$tU_RCDyDh@$G|$(=hpz#dt-)-_mhlkye4K8Y9)5G%PxEG>lSG! zxZp23xBkEi^%jXZUA8PWA~zr;afiUA0OI)&>PE!YXsuJ8S;q4g5wsXq8Qa6PQE%ck zOzraT>F;@!zZ~LNv|zm}v>h9vG>Ci_G@(EL)VVufNh=g&VO=Z-_=bDwv_Sqf&|jC!Z@Khc|E8zB-K&o3E!+&up8dHR@{%t_<)`4phKd(qEoW4pTX zgoK&w32+Fbd=B{JNdk$F51Q+vz0b$4sDrYpLmDv@h#hj`CZgIA%l@6@M4^kT(WmAF zR~=TdkJn0B9cr`B+sarSe!dUYN@D*Tf1k3I#y%`-AFGu@eyFMz6u%BO%Lz|@1S>m; z%?ZmM@OP)VmC!zpZzuLdRH)e)A^&_x%hdg2RqtbQ{Jt6fYHFlRg5%r^2b{{;!w<5T9r##`e zqFQ$Uc|vbRdhBj`B5y@M?S4Fi2u2|94m`sMM#b&!KSKycD(o&iBM3&%?A|?tbw@Dm zPCUbPN7d|}KSOm#I_&;^M(U2f+I@Ql^^YLl9eIZJkILIUeungqG}v8vM)Z%~-hFxo z|BMjYoq2};jOy9FdWQat4A|X%M*fuf`AbX|Ni89~Q&o;bRmP1y?97TDP;|o{L^)5M zDN8pu-UwGEtzyZcowJtxWJsaeTLMR(PTi}XAC@(pi;EF*gH!@r2NQb8%?e^Ge zApVI&d!&7-&WU zdB^4gu}{RkBlSx)PSm^s`arG|Iq&GLQjZfo@3<`>@`>ncgkY({iOOq?Adu-q<~6Fj z)Zs+uHMSc_d?NW8>0fGaqVWpw2MV1iyheYP2Ami`Nl==*w?+wE99mcJYFF>G=+2mU z5yTzC@+VN;n0{mHNX=6%x4+`%?7Ja+%;sjj6RBq6{N}Y2)L|6=X1Ej9VLa>Rs1wp* zOvQ`Nen-N7&pdZ{p)J(nS~hn`=Z>?J!C~a@9a1OR+v-de!47Bc)IWj)B%~VxB$wYs z8)Gb6k^9*@*v`mL&bdzq;u|9$x;vyy zM-;kypo}h|&|VSYUNlVmU7ikG;ZKJjo&kb^$Oj?MhJwG54+owd1%u-bik>Y6!{QG2 zpFIVG6b_PlgJ`b0!MlRNQ;3(N7Otp$$orClxzs0-Z)2uJh{-pSjksVl1tlVJWF77h{R)6$00YCDJ2(m9URWIE& zS|>u+HH9ytWN&VKxcDrxpJL!$K8%bZOR^ydtzwukPB4=pPHLa>D*R(m*DfbF@neXe zQ2;kccd)|_(kF4=Fz^o7mog7BU_i*1GY|ZW^t#QLC@*dl`#RJY)nGF1y2KaPU|Qok ztW`e0!AZX37_S8!n)?!WVyg+T%LM7khi^>AK68cpI6xH~bw$ zXcYNo;2lP2Jnm-y9YSbK;by^+PxjvgW$t8r65Q=H~nzs%OmM z=I=XF&&1Wu+dF8$DDln6J8Zys-p%nlWB{zkt;Rb?z`%At)isT7|Mtz(JNVbA(9O&{ zd?(b^UClM+H(CdLu6aA*Ep8p&`M&xBZVleKz6QQ{ck)G%1`r*|Ho#i?MIF&M5ReCg zu0aT(H2TRLkvHHycw$u!Jqefy{;BeDIA*HATlAh@SE(Gw1V!(PalKhUp>KmdO{;&;cO=)dv4Me(!4lLpwU*yjy1qf2`CZC)r z7Rp323Lp$u+@q|pR+@2F_S?1pJa)65Q!C=%%n)f#RvPCjCkY=s-acyP9_@;+3gPGj|!a&dHW34y>&Sz|Q!QN*#s_NYj&;-n)tADxnh zPm&t4mcxgEXcS$TiW!HH(lI=SUv;%vFHZL~Sw6>JaF~kt!2koVoR|coO*v?1)U{i? zc~|QSw8!YMnTSUml+7O}NR*uZh5K(j9{qL{^c1;=MVo@eG$vl|7v1QbC&yp~@^FPw zQei1GO*yN~Pqd+U&&gKfy<7YNCW*lqE4Hwy^zQ+-it)^XxI>sobfdVQhcJ`X5F|Il zgB8s}BN}$jOD+R8-_U*5fh4)1OzO8(-7rR?Q^$AlU&nOPD7G!hVfs<~z%rKj_A@%a zu|OPvIpB`ilPp$=i^}$&=Bx(NZHF0Uz&Y8ncV3P1vU9y^WmeIC-h1^bIEcl{y}PBT zS;V-}+708^(M}2Sp@KMZ0;P!v{0L3Sb+_UwGBd*JctXoK^(FPO<5s;DYKS3(NL)Y^ zE(%-zS*UqUp>iVH5;|>JMBRt-o(6>o7Yb@Ih0taDKydO8BVxMmoy@d}n5x!Q6_eoI za@3WC#o{@w<||9}=-C5ee-wMqdN^2WQdsH)Y^y~(hiCF^&RXivcl%u_%4on!!<7n?Q>3O{Mp?6jkg3=-+DNB- zo4wSvqFHd>Bn@Ap-{$tK-mMF!JWj&Q4^`M{ESXeSL)Aes`dcq*4F;MSc*w&RQv1;H zGE@==a%sq_5y91@TUaH>ibIwHaYeMkJ&lPdLUf&g%Ssp-;Ylp9L1HKPi$SLqBzWcE z-(u+Xu~=3bzsO#};1@*75z3JDnu7T2l3}8Rewg=WDg_zTf7mx~hmi$0{xA#n9>Xhu zi=ZNPwX-6n4JTfrqHq4RwSov8D^|R8Hj`;5h(dMJAh!)|7ZFL>r|r=E=?re4a9{FtDwCP;L#abN*tI4c!lLGaD z>a2@-fD(oQPAXIkqaN7z+mojW=S<}SF~vP8;h&wa?XYh9+T!1b(uo(F_8K#*Abo>@ zCY8jz+6wX*s}^$X8RqI_&;C>zuPzxlu;8+v#J|JdkWR35xJX3olOh_+Y3L%OI>zX*%6qReOy>G3gnbK7iWb{Cgk>Zw9Y0$l?B%qGAqHV3tZCQ|7k;R^ zbj7T~wrgBqk^N5W+WjVURktRrAwPBRu_&!MAyvdmp<5HctXEON07Md`R8d_La5w>TG#3M?F7X7M z(q!qKRhu8z@@gbrc)#}V&J5y?o;=ia+)r)jkqWRtDWLXWq2Tc-SWrLC_Bh$w3&$|0 zs?(36POB}Qh7dF+U5DuD@bGo#PNFC^*gK3f=}J4knbX;HSr#xaC*=^UEnUTv=rZ+K zrgUfy@bP>RQ$Y&?+E-TcP8l)bw_;}Z7kV}h_;JB&YF1U~53s!0`q!6j>#|QTr!mKy zHp%AEPo_`iD}Ur4jU{*4x$kAqE>NN$BUt}URY-Oz`BOJ>_&b*~gT+GeZ+B;@g;*wl zos&b0(}#EbrQ3EoiR;>ZmGM?2Ysnh-Tf)2(x#4QjoWB0ewwdBQy~LUsIM2$MlU zcbTTDcKRM`0ynp{QU#5i+{18a5Zr$6c7%Q_X0+uW8nJy*}R}ic67wAq(CYmgAFDx>I|8*Wd4cC8d z;5X0#r;c1oHh%i&n~$osSJ%lc z!Gq^EVlZ-`TwP?OHe@$TmzM!bp?YRm4OdrJ>20mc#}Jd3y1sAj1AyfP;;Y=7&gy#h ztsP7YLT-ln1$E6GtJ`@j_4ZEH$xP;Y9tL%W2dhE40sd`TJ;jCCwaeTYv^oT6K8ceB zamsdzN0~e7F{VpqcOfsf(j zD03)^AExGIre$D>O+UYR>|tRtGK|yrf=qc;kmBjhY0V9xKq6eA_`h>wOKCQasY|FM zPqznNqGDnYs$#{sVqyozDwO|B*JpBa?j~{td>$`ykEgn4WMsvp z*ke-@W94#~L)&LsxvqGnIpu)`7^}46sF5FY?rfYN8p^M-1RW29fpk{yaxkae4#`yo_nzwAv7@n_Ezkz$cfa(n{0E|yguqhF|T>d_eDKF|0kf8}(>HE^r2r94WoIPL`f zPf3!hf`JlQP9f!MYG{gR_wTnG4*rOmeN+^R? z;sfdGJu=_y^Jg~uy@ic_3vr5g2v`cK>7=`oto!)rlC=BOiITYclq;!#Hf^YJ4(BR_ zR1#L%>a+w_>ETiCj2}s6QKqAMw{&Ak;if_K$wTfHVlIcG@$17q|+C)_3K*a20LxHeSRIAwx&n+xC7H%kH(% ze9s^nO;4d5(@t`GQ1;C})~E?$r=*+z>|fV&5Lnyf?c?WI)!A$F&%D4knzn?3Bszi&dM`ZPPUDE)oUm4YpE6oyEc@Bzb>AkHYd;-G;JTM`ow0BeF|% zWZo}sWmZm1TGS$~pk@}9w~J9(wwtG$o+3=mwPgY+%=L`@58IVj(kr=W=Hw`uPHiX; z+jXAKvb4*?AIgZh$~nqcY9d}Z%h_Vx#vQM5HL*kj=5b{qfW5gz=aZk^Dp&5e@}Bx| zM}Z{I9NbU@hX)?LaeX~~`e(AOVBVDSF9fy_3Pum&7M>U}e0&e?XS~lb&<#jENqkehBrbuzP?7L=DZE|r-M@h8j8+^aTx za9?cIUTzpIt$w;vTd8RGPEXqmsShi zf-D=X5aH@zu0u2z-5Xkm!RrVyOP5w-&H3uqHBAPVW0r{E(LA7n+r*i@E3t$?11fg$ zSFqw>g7Rj-gN|Crk5AB^d1+oD67vijpb!RY&-OK&=%=)emM%kxJo?()yeE%V z@m;z4?5tDHn|n05_6Rl*NVO=4V4H@Go?w$W!$N2$ktWO4eY@QPsElsM>{;U5BWEiu>HVaXG4PW9wPP!TCP?n6U$!E=0>^ z)k_86ax6H?5lj1{l~2`dt|LEK?49`j)&a$JqU*N%M!uX<-c##O4B4SxL#1;xQmxw6 zOE^Gl`geK_)ROZkJ@lc#UTsCE$>aX?HD@`y58Xwy9&-1U_jTtRbVK(1Z}hiu=s^Mx z%E_cZk9xmk00LIjTc%6}6Lu8jaLpdv%ao1I2A6S9ZTOz9+&>5=O?UuTJLTD9Yy8ny z$1j}`cV0X-N2FVZ=Ovw?28b#HutvNN$9hH*>6p_n7S}{uGY)qof@swTanE9!X!d(a z@8X)%0N+fV0cqI&qC|4N0q;{>PALbeR8Us#Wx2442u)(CNW|pD)rYzQPKoi~s|2oa1;}#D8fi>c@Qb6IY7))fqa>YC36B z>Y#WCY*LGyb*)SEyQMEEd#&y(1r`WEcE-nOWFabi&UbBA=+HR}#Es z_M8cUNfBQ1_c1pB%elXNG}iy861AAld$tO9)PYdx^1VEZL=!cSIqVG0@z zzm)_o5F>bSSlCeR(js`ES)d03vc2?C{9;E?ef4qf!xL`oYbN z7-b;XgXB3{!#z@RhX`NyK(+au10k$(b!zcZDR<>d_wKEqfh04?`BZO&*5J4FBH1go z?L6x?sjM~fxNG%7gpuzU`?3Kxy=N+`O^`EwM&~QT8ogj9Z(PCl=J?YzgOtdBHUIWq zH3z&cJ#PCKeHeUFb`<{8SX2Aj_gGVSPs3$t$CM0x^kA@Pxsp2(I*~Jfx>Q|M3NUu1 zx{~RXnQnX_ccr+J+KR*3`~`L;Hh*WJH|i5#{OgZdNGur}M9#1ezynXqM49xwYau;< z0p>O4aZXT~CR}dX4bMs>O*l`<759o|%b>Hx(_)T>a^c>BSH;CGmvOd)a_F1h>-LGU zGy3K49Oq_`16?P$6~`9N+4a<6&SCdSvJ;b@y{_0m47_FQjs7Z^qJ^DlY%<%%5yibT2p3X;es+Ra&fzpQilzO%V z*-=*kk+5)0KcBEma?ypE(hV(u+vFRmz5HXHPIHqW=YjFG!g={Z;%o8*t|#CnHjJ<6 z!#pEIwpuKk3blYso*3+nGH&>;=%yKON9UTW`mRW6T?hnpl63FCnrmnVvgfqf+t>Eh zoy%2C#$4u_?a>wj8ylMq78@Cs4Y`zzh_(nCTOz*zkwP30II<7?g_d|=kVr12ES0F5 zNM26<-z$0BEqmmcJ5FJH-?MvrU+}S8f5lJl*ehqn>*K{YcJoJ|=H!mNr+~LQ($BpJ zoijMa16Ld<5(p4%CQ_up@Lz-6)`1eO7-PT0@mRqGPPpOf%Hkk&gUQ*2Rf>ze^22|C z&6S0FvWt=8kwH$ONKn>?A=YFCh6K#dk&WzG{!~CBW-EuX0P~(cg?L9@Oc)qmWX71~ z2AZriH!jYo~_V_<6X&r zt*aZd&59j%LE{~BWLL6LdrRaa*O>EmL1)oOCWE+{mPu(wB?1uos27cR&5b})O$3^a zu^;zg2#K90x&JCj4uMB;DBW9z*91@1~lt42>UZP%p`o2Gn*^T{;^Nnz} zz3LaT=W$)!zfHIScL*%GW2Y1dY-!^3CRdGkNINL82cGhWe%Vuyrxd*ELJ`C>OA;S| zYL@n8%ltVviIA9TE<9t`q&dZ+T?sCH0CW3L+3<;aQG!GZE`Sry#I<8ivxqO|k{!>1 zy{~N9vQQ~!j=X40y6{Ps7)0$PT0N*KE7GRg^2#HuPGRVAC0!77P0?yNL|!e7ijb7EBVA`yqf!0f$fSukfJ5gmht z&%olnVOc(hE-?|4%dTyIpF9Uwlp;|PqmEz2;=OKJHOD4#9+S(V?Qowx2UT?ZZT2q1 z#<3IeqA3X`Tss!;HOq=QI*GqA`W)U9Lc;Si zb{#!YDH@Q-!}Y5sk9e(7nD=i*T*CqIDTQgvN-(WzRp-TU;!OH?8q^o74o|4^T*+%B zaE;<$2^>^C$cI0M%S+zJrDMJ5s~Rmfo)n+#oq*3#8M}{U0|+sE3bv-bkM~8Ks`lXa zBnGFVbx>RAE?qZXUJG7tEThowe^NjhGD{dDShHX*u%I{SHp16JOw>W0*TL%45q4Y? zJ?^8#?r_VqDCcpK&0{7b+Nij@ZXVH!1!$antCrBzx_=YuJ^ujP`?7{o}@jY#X zjODch)MPjJu>ifE*R4Qf`Thl7Wn=9nFT_4?otkm~Ys9h0cJJ2$<~U7TVZWa>(oOR* z3_t=me*rgdsus+i`%b0BNI<15qnNcxkV9jFqXXw0$yl(a`Of>iO#QgyYT(D}1Opp-yEXhX9&u<_)biQJ7pk4#z7+@ zJ|BZ&{X(qmUSotDN31K5!uIIinR6w*A5SH9q1v_}!R-8(ze{as?ot_>KFN* zQG*#HKZ2_|4@#psK9I+@g44@-LEbI`&{Kh=?rf+ z8!Oy)Gob7H+7Nco))Q{)tiN;$=U~QuNn$zYd+k5)`ZvWohrHrfs&k$FL7vmvEG7#3 z6OIuOu4eQjEFa25Dcq_R8QBo&$OJXj2y@wpta*pyVvy)!K-hPB_j-2b1*gCa*C8ZV zI(EK3rsb`}@jLD-KZMYTb$#f#XV)L5(RSb6)J}CuuQmnb0utKoi*m4>W2%QVfkT}O zR#dSoxQk~9XRa3V^Bmb1jeHJH>q%UEITJcL)BA+-8ro36KRrH+-kH-vNHn8AIh~aP zjgt$Zy^DyUjG4a*sg7&BolDOdU$b&kanJUz+S5J@fM%t`_X-c*JrXW83*laQ3ri6{ z3D63Pu0e&EzLbf-)H}4SpNIjJ_-Z)63veQx(qnwSVa-A;Qww%p3;WlQF3^NKl8rlD z2*;QnJ$nvrD0#^r;(7Z>2QCHj&yyjq9;~A(uy8(bu6>C?r2DGRO3zPXN`&&Q-Aq-qi};l@sAU{?uX%-W3ht zDW5{~El}c<|MCcu)m2gM9?oeQrCD zzk_=}Ng>={j8e>AOq9G*CeCcTT^YEpi|nxLoHPPF%|~3KkgWN3ArZT(v2s zLd4{__DAz#b}EaUYIa%uS|3k3it|6F+cOrH6L;AqGtc?^@!U$ir{-I=%dTu6HkJKa zoY&>%bJQUoC5HmmR$e<3bUn-5{cjuTlYBL{cFqWOc?MI4X7MGpZFKF}Q{6Kcz<`j- zWo>lx8+xTqZu70u?1d9KsWPz(ZS%{g##UFZk*@uN@!gQX{C#5!=ZD z5&9vx${{G*Va|(q<&!&wcF`-eHjxR|)59x3w|`>}$9i=;)wnB{>%!;+N3?+3KRVZc zHH$Hi%UY^u^wsl(iX|?mK$kXcmkk38S3tENc8(GnR!0iT(!N@48+>WO z?aV6PyIo&_88y+`XM4^sL@57e--8=pcQFb2xvMpH9uA44CLwU3xb zpMreFr)?jOz>AZ2^S;|}2!SQQy{f@pV@H7ZL{rnORbDTkQS{%_$!UPzRiz$p)HIkq z#wQeVL(U;2gHLO_rQEFOae~!V!9M^co?kh6gs_k<_>T5Q=@(g61ZDc~vC;mJ%OpVB zCXhnkEl+**P_U|Q#m^Z9_6M$bE4GbO4DQ9usqVlBKb04&#G_Zq);fv^xCom_mZ&6I zA}KBDusD4nbYNZhPj)a+avr(4V@kW|AgZ!PnfOok}X?!a>FaMe8WwuQ# z@~Z>;6VgiBi_lN0{aO?G1{0Zov$I59^B0x(k6 z0zUQHS$_tfJ1Xg!Sa4Weck;L`CH$qSSlZ>3eAD;*(0p^l%7*e*nbRmeW6}s4X~%GD zc#dG;rt(m1*@^Smg(q(huKIx2{%FECl=xbdXore_*uhgoWL|8ZT#qqndS0CN-AURm zyLN#fSZ*z5Dq|?sc4*mlK)2Zhw8MqkVV8Y+k6?Nqjq$MJJw5yxw`Z^AJyz(hlRec` zDxntRSKEF3*1RO`A?+zLA&qq&Ao;YBfsr+G&31y{-CX0*7_!D#NPi@YJLBp4yX}Se z0IYhC%{T4phK%Uon7^OND;ww;CUi^nNt-M7t9VdaU@RGHUgdSHiFKBE=256VyL8`! z(_GTsm}X)XaCk9Bl09zbn>pjm)U%_Md!+SA>ZEMIN-k4hlA=qa=G>&a?_+C9q{D3& zR>U2q!VMsHgc91Ll3)u%Oz-t=wm{bJqg%`3=uBaIMz%ke?;g^7*DEB~M=L=%V{@)} znOsJ{hK$|8U$)@qtBoJ(RQfSDuh{;;uAqFfAl%hnpyS^>luFHjyAZaV~m$QME3>MxFA2> zkuH+%1#2CY4Qa#}!?AhtQC-^$PCg{kz03FP#{VI>^tE+~)VOe!^}21b_Vn`Vm&uBXC|v!S z_$N>33kjb$lpF-?+xvnoA*}ko=1sVa<71eml>oexb2`r)ewWChJB*$Y5@3l3=8`Us zX$T?QgqN%os##yK>c> zVV*Hc=9 z71Ar*xIEO0byvYZAYU0t(Mf)#@&e@=?V_4rzAWOU)_HNO)h?H@NPovti*wz>43^UY ztfLcQ$l!DC0}Nd1;4V-90AE`JWH3$|_T{ISJG`R<=oYa(xX$m2eq9|)6IRtBB<(u8 z7z$?1foP42vWzQ52H`|0l?|~^4ieB0I#;T6fIj*tG|eGOgaGW>@yyxBEwjJFjsF*8 z*cXKeas+n0SYr7=YjqC@K^kiV4Mr>V@J$^+WNY z2BCyd!%!m-3G$FEmdE93Su5-1M=!=}=w0b;_dfLwd!Kt>c*kH_<81pa`9Wwj)>0xh zfm*KI8mOhq$UrSYZVS{zM!{Pc0g_q)ON|(Ky8cM5vZ+|ae>+rxie6k zBjW?L88RVItCQM5ZKO;L)T*T}P^*+lfm*3d4%G7Hu0Sm;Qv$U_xjRscl&MaMq`;cR zLgYcGbex3JpzXzXg0>g;sIB$T{?T#+>dTEXL~fE1a*NbxOJkHm&$H+$`2V#KFk%1z K000310001^Eh5JN literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-LightItalic.woff b/app/wwwroot/fonts/Poppins-LightItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..2706cd41c8616f15a6c057408d5ffa1407fe1584 GIT binary patch literal 76520 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ɲSD;H&r=zK(C;oA?&K zjql*Q_#VEGAK-`h5q^xH;HUT*evV(@m-rQajo;w6_#J+aKj4q}6aI|9;IH@_{*Hg( zpZFL4jsM`k1cXGy#W2m0S(l{DV6KEn$qRF%ptxT)Xsx*aGqt$5* zT9ekIwP_t%m)4{8X#?7jHlmGb6WWwEqs?gx+LETyR@6X^)I`lRjiyrz&7heyi?*h1 zXj|Hjwx=CvNAi)MS}8znG@IHfNF5ZSITWS{MX8fwv=hZCK}qVO6wRfbDNXZe7uuC} zqupsf?Liq@K;4w394(|C>ZLsGNsFkD`l&!gT1-o*L<3Z&3JuZ_4bxIuMtjlTv=8k| z`_cY%03ApN(ZO^G9ZHAM;dBHYNk`GqbPOF!$IJccx`ZyJ%jj~tg07^i=xVx#uBGefdb)vbq?_nwx`l3~+vs+> zgYKle=x(})?xp+aetLi&q=)EXdW0UO$LMi-f}W(O=xKU}o~7sLd3u3fq?hPrdWBx4 z*XVV6gWjaK=xut3-lg~Gefoetq>t!h`h-5E&**ddg1)4$=xh3hzNPQzd-{QXq@U<# z`h|X_-{^PxgZ`wy=x_Rm{$*ffVrGY{*u!3~<{GZ$Iv&IIJeJ4tc%Hx$c@j_Nm3U=d zg;(V%yc)00Yw()97O&0g@VdMnug@FshP)AP%$xA0ycuuKTkw`VmAB#sZsaCz=4m{g zTX+V~xuz9OIoh&IwL(7pHhG z@62hQ$Gh;Zyc_S%^LY=>@B;4UEa!M3_i!)gc~4%%ecaClF7jet!X+NyGFNzzhj^Hm z@-p6w_vU?gU*3=R=L7gaK8O$IL-R=4i!&n#x<6#0!gh?C^x!e+2JYyn%sRM-j{pb?s&8K%K>Xn`3p6K28IunlYr+rjn$tSD30umkJ}KJY^; z1fUIOLpuba141wd!VrNdbV3Yvf;c1~30;taxv(>&VIJ%PyTWd;JIseYAj2oag>Wz& z0(Zly@EIHm$HGx?He3!D@hNa5ya5NnN$>;w2*>cLa5y{&@4)wP4qO30!%y%FTmV&5fzM$fya><1^KdQnz;|#0yaF%5%g_s7!q;#F z>%dV{KIGSIq)w6pUda*`G|Z0U&t5n#e4~0%9ruwd<9<#zrpW(6<^KQ z@U?s$U(Yx2jeHZ|%(w8Z@CUrgxAEd>zs_&)oBS5P&F}EL{2ss0 zAMl6#5r52|@TdG4f6iaY1@Q?fx|IEL@Yw$k*3U9(& z@HV^$ufw}=CjZ92^B?>t|HXgvKm4x)4m#v8+yFPiEpRJ51UJFW@Gu+*55Qq?B|HN6 zz`byn<2Y50$MM3^PPJ15r#ZE72AmGxI(5z%xEM}^v*1!V4o-$s;C8qV?sw{)vCcSW zyfeX>=uC1ZJ1aRWJF7UWI#Zn0oYkE*oM=}#Os#Rw4*DGR@hQ=vL`R1bT}pK6VK82$ zhq#tuEyH0o-KG zBW#RtSO>M4R1@E6WLK^BN?9%K3MycZuSyL;y-d57?Lj?8+qI)r%T_ZN(lR7-X+0*B zK93%aD-ckI8f8AJ6Oty#aePy-k z6VUFE-oJ6D9ld3YN5R`y=86q^@g>Gs83pb^ev?Cij<>w zsfUEJ^hX=vutzrNk^MP(dsSw4x=%fXw5|4{E~&3j85qozGWDuyb8Q#o3)xDIDxM$6 zlzK8cWH8fH%JgQcwX>Az&v;dXl||)@T3}wTR8+M(3pu^Jp`urfy`@}EP0cP=N*eh= zJ(tK2d)1g5%oP;d@;$v}H5ttpa*j&xpQx5uu%MJ1%xB8^VqqZPQ>e3Pw*{rq&#P#A3&cdMAKHYy}$$c;)1lS##DO*;_? zXosd78I=M_n_%k&Y`8UTP)xir>-CH2w`N3;7K8;UiAe-46XLe8-f-CNd04trH;Uc0 zWyns%%tVzrB#)et{<zG@Sz zo*Q0c2YtrhDhP=;nG{B&;udpQvD%pP)2@iSB4smey@0^x$0SPb11*Bmh88te4BIvQ zk`l3IM9j1xEJ#Vclyb{6QJ2w7sQ5Zpsae;%T&1K!!aDR;tqKHGRq^?1Md*e{WLR!7 zePmuElH$LU$q}NK1U&b%zDETEae7qLvZMv^-u~wW*+r3w54WQ9(qI zHeu4Nrd=#Fe~uuedeC=oXjlg*TmQYQ7Uc@L=aevO=?EzsQWsSyf2Nf!uvS#y7eoY- zIV^3srDd0z5ut=d(`uX5!k~48#9=RAGATEf2pywUTBwTGY6i_zwaBz9Qu3VDz1LWw z^R-F~C11Jqltk-%5t1K`%K9RL;*ydgTvt?YP>YCVS}0d7DbEW9<+mbkg^H*VA#Wr~ z1+B+E*pu=NQLx$am@pzJ0a5X*WyOw(t-p6xge4(n6C&b|*aWw5+_l4klprCq3B8Vp zv@4_$xxkufp=1Wsm#*4Co>)o*#UBteV9lt&FVTKC+Ha>Lg0vuICiRjvLNy_th|smA ziKrZYRG+Ze`n#nO6eg2GxyzMp!sWC@#9fiF8R`lNRgA0bVgZQ_xJlBl7B4? z-1MkqsXd7u6I&knTBs^Q*W(wDJby&F)#NfOxYY#iY{G=g!@E|Lj;t1GW6dGObV#*O zUlT2?t>d(a3Str-vr!R&jR^}c4C6|PCv2IL*Sn-3AczX|L1?(|fPS%c6C&g`iAbB8vXZE{tK2mrg0vtk zNJ#~0Tv1@GwDgfy8DmD?sYe+S7nU!fg6vKS>u(q6YoakM)VG^3C=UHrA+&i(8>qG= z)J<#U2HN*vxg!;9o?lGAH6sF>8qhK~UbUqk^;`EJz80^4=}`)*QBu zR_kaD8XFewoKW?gshQJYt#tkp_8!RXb~!XM8=oPl;oHbu5*=&U9R0) z(WuRmKWj$DBwPN%h;o~W*r~`!u*;MUO_)s(Bsp;+~hnN1Fx^xQ!L~bc{9S=)@-qy>F&-I%C+4i z(i7;;=+vwrpz37G-Zon}C-k&Q;haHj+wwv=SE?MlTu$g|lZrWm+V! zR!up5YVbrQtFS`WwCR>Do~UFM47{DTv!c*OwOP)t@9eDE5^22&K9;bSvGr;l2jIS$(dH-mwV#Ey1Dviy-NSWzT9x#&O)#Zk} z`!fAg2L>7%YrBj6{TU|jF^Vyuy6Elm81Lab2ac{2QE9$Nqa00962|Nj6FcmZQzWME+6VSoT81`Y-Z26+Z% z1|=Y5W~gMS0+O{r$jmSa2$`8;nBswCI#UjiEM_WZU3sUh`_NcZ~sSh!)ltA^4lttaB2hF8!sTj?cwm3Gpfsg8Ej9%`fm^bs}F zA^MzRbeN9NKUmmtz!{v)=W!qI$GJS1FXnu{oC|mikL7V($XD`JJf4er0#D?txrEF3 z8lK6scsAd|^LYU;`s{BCCl+KbVT_sDp%URM>&XwMBo}4c^a)DeZ z17(O@EW;&V3S^uVNwG|j+hw-gA#-G|{7kD#l&fu+wvmZepsi3_v9{87ZECwVjX2yR z2bFJvZ-H-vOTks(!{CG9{mSS0dcKKo<9R$^yjJ1?uHZ_oKozg!YTbPkH*<@maJ|$> zCf7hMZ~n7_ZcM6u=iDR2t{=G7DCfZb z4gC8+Uk|+_^sk{$1UrFiVXuL{&*%_AZUv`+0eq^VcL95Wml>1Fz;algfZhk}4<0l| zGQjhVr<58U_T?W0=Yey<1z>M*EQno8DwqbQ8~J%~Gc2cp-N9tA8;Es1=DK?5+2C+k zn!pc{=N9N2F?zL8Mu3Bj{4qxJVL2-izd;#?o`qTCK-AM624k?Kff-;&5S0nKLO%tb zi@+RkC+wFatBznc_$o#ZVDtg-EwB@~6C|VTfPXS9o50CnCHN4IBv00-KGp5Ud1CjNA&nA9x1%u(JIxQ@S#b zrYfCGl2VyWLJ`WQvFfvewo)HDz)4id5w4*-cmp5jvpJMho*`*6kr$97!daT8tut|m zOu`oMkR0SXpYAsK6rbW&ft4!NZdF1mb+p=5sJ&XX3iPVY7kz7$<^?O_SYM?=qy0x* zpNz2+;=s?=8JVs4#_`Aq9;ONiR4bUah3qsq8z_TIIs z7K4}#eh`h?uGivPyjSn-sx_%!tFG9fY|^G<$_B(TX)(gP6%kqyD~=WHZv%W=TwEE4 zz|Z>LL(?j#mLR01t*5iMYiqGcwu1IzXo#V^Z?REiS?g+jrqc8l$abC4teH0@=2o~0 ztEM)rsnmL69aIK$G_vhmr4?~>1Th*QS_jy*mhe^^^hRY2G2%KJQ|l(5tm|i57Oob4 zrfKz6P-T2C71Qi1d5@Li@N2QYveko#XgX?^$Q4ypK~9OejTlC?Rq%~8k81p9)M3@O zsP)>9nJ+w%k$I>VQzpKv?E`C6<2xb)Yv^l@bhJsE?X^jpRtDC@H-L_s;(zPg>LFLl zur(p5ol-TQjtwOH6xA~EJM*^kxV%Nohou3(C%ct%|PaoASuBiNf+F! zB7xnjA{mk!$(CV}fswx2hRDdsh)8~9jNpzHxmHRew?yVd=Cs|lA}j5-6_@|N&r_$=6Gs^?(L8f`mu zIhZ@scIqZt{z?52|6L=m4|A0j;rVJom0YIHm49N^A8i*&m%;L7I6}D|`m>0<6WIWH!(fSk1>kU_G}~PMozZ=W-1Z~F60CCAa!YckhJ$6cd3wU!S(x<~tD9UEZd3g? zmZ!e~qeZYxvVF;Bst;l zxf9=VD^GmOeeY{7jhK6dhn4fGt8xfks2ofKlxM?UOs5jdWE!h_r|>b=H_$YkO@-ze zPFL%O@CP*#;vl&*&#+adY952EEXBp6+Sv z`mAuA?H61Zo~b+&`eR`iV)`t;O?4lC!*&;MHqW^2Zi(qGA2BCb#au2T-(?kZrC4zi zvb_ZP^oQjm(|JocT3MsCRqXfoZ>Y@j@FLa6hdpru4psj*F$-VEor|@iSmg!e{~~xV zJpWypBJ+`BR$Hls{sMB#L!7;~y1&%yel`3HklP~EtrJFzVc7!9XwxNzFSXg|7b8v! zGWisdD=i;SwrhVoW=%lk)A5Z`knIA@?SN=^n(hwZ%T5W8BXir`Rmkdg_)Lbq3_d%s ziyHfna$W7~$SX7eC;oP;Ir8}g9FMHtM@_yki=TmNXNQ-o|BLutEHa(@hNJ!k-&i?j zcmai(4|vYy9{=C(&-dA1GsDbmHaweQW@cta%*w>NhL`oN%`H+=lWjv_3d|E=l8pwYw!DYfA9PAxj&!#-}kxp zfB?cVhx_3a3@j=|bj2NYnaDOe1|#4DfU8##0l+~p!VEP*GqgY~;*o&1o*pzDf^alO z6q+Ljtg~*oo6BalxaP zj84HHUacB4v64QIMi{MTGp|-polwhIuTHADV+s@hq*H3AFvY7i6KX1%=IW%XN@jX> z%9M<5%<*d7nA)k#)me)~6GQXvk{qy`w{q_E>{yqLf{uBPQ{>w?BNij*uNtsD`NySNHlV&E(OIqQM8w#S* zXbjpS6l4xvvJ>(WhF~jpVShp?4&!5-#(7+(kCBW`>_b1(n9V#6NvL8eN3n`EoXH2ckjoPL z=vc!cZamjpDzS8fr5i1kS-Q#62un9x8fED=OQS7~wRF3s3QKobscr7BC~EKRU9 z(b8R(sx94ZX|kmnOH(Y>TAFI9&eAkX)0IT;nV|rRF$^6&Yd04udM{RDQv5c|z#J^V zQml^O9p4atB>n_8VjFhHpFsnT-~`U#0+$kMx(4qJN9(h*DVTRLj#153v& zeQ4<;OCMYM#L@{%pIZ7%NkA;d4ghv#oFyp23arHz?8H7C!f~9!Ib5PJf-!8%RAw=k zg)HGnR&o+&a1Ix6DOYnNw{bTcc!Vc-h8K86f+b4gBw5lWNAjge%4D>Rms*)6b7he% zmwMSOJ7ljMlw)#I&dNmxPPh~8Bsv|POs9`C&>8NOI~7i~Gu@f(%y-`mf`^orSbEsf zQcI6mT4w1{OUo@iW@&|`m6ldndfd`#OHWu@W9dmt^_HHpwARu(OY1Fdu(Z+A)0Q?_ zddAXbOV3)`V(B?cTP;0rX`7`NEN!>+qNN>{Ub3{)(#w{1S$f6NZcDFP+GFW8OM5N7 zZfT#TH!SV9^roc-OK({^VCij32Q9s0>5!#&EgiP>o~0v}-nVqr(g&7~S^Ch@aZ4Xr z`q09ixmaMLU4~Vt$3|?ycI?7lG~f`9 znv75449+oF-!>KKhi~BEHuS|=E%Wf3DJP;Y1&-;FPDjfO`n2rMAT8J7bA79PVYEF? z8SR8GjdsRqqv`m{XeQ1W?T+t^X5pOC9{Ap9PnR{)Mad0r!SjKCa#{^T}Zt87Kd8a9(AxL2hqa7F%$e1ky zxiU78A6psCW^0Wj(P(eBF?tQ#X-s~NDLIfO+iPSgnxBJEL?W6U)UKoU?W8jjj7ZpQ znFa@C#ws;1-|TEOm0i>(U2VFm4dG*kQWLZ_b{WV=^Kpnb2^ zUIR5QAHt!l$U&M(p=L5z#~q?;WqWX_Mo?t5E3eZriUVU<@58iZxVBucE!LJL8utxG zyRlSz+z792nYP@dEhDrg6wMHeL?j~>I&ZvL$1m4WZc%?D)#_GV^--GDZR%mPdWds( zSTV{l3YDlv9cJMH%*P@u#R{y!dThov?8F}I$3YyyaeT(Ha4_8XsL(Qx=LGsM2+tU^I&pbuFrm=5VsnUaZj! zYBhs8-I>#L4W}C&z&nf%5nc(>7Yb_Qpvzx&jBmgXOUIJ89y(vXQ9f_&Pw?OUwqtT?G7$YzmRhWe7xF2(|5KFNNYq1&Iu^V;;a2jWE0hjOxeGF$5 zW7wL0c4RuUX!bYaOcTUC%{&S{~HX@{sP!#kwPx=n5~>6@E--c9qWT z8l9DTUG25H+Us?GpVoPLM(1g>&hN9j+Rqy;;8LS&xWZ^XR~vnbPZ?dubw=0g`nq>7 zdLs|^F6E2vTx`?GUeFV>T_f9}alE8)?9@13)(CcK1h43>+pTfDs`p_SqW|w*#65aD z>{Z{dtJgQw>wfk6rh0u#{T)z$Z+q{2?>@v>RG}KRn1TDD=aTQb_ux@?bv`lW1XF)U z$2_bz;d?sf5uM%lb#_0{@sH`g{ZQxiBOU)^9sh*p^QpeYKGWGfWOOKx8{O!+qdr$J zC)M(lT7IcJx4GWjIfnipZ!0Y0SvaUPw%@xu=?8Zwoz{52(sp5eXH@F(|9lF zD*UKp|DMmO-hW*`Vg1bVL zJdnRc1TvS#MtezQAb)8R$X}uY`AgG4^wKPlzeF3&lbAr}(lU^_h|!_a$Y{OZJns8J zVgs2=E47VN+jzBY9kBY}x1c0IjCC8MousYNRB5Mq_%-Sz^_r}4wO8LM>bryb?r5~X zBpNOB?2p3#v9I-gBWZ9@Zv3QcnI{>hyv5YJn{t#XbD%elbkevwYb;%LPBV>WN|w%D zw$5EojjNZ&)mtOF#%R8z8eJ@1jINY!MpsD>eM`h56TOj-At>>F@4zg~!8|O)5-i7R zti>j5#SZMoKFNi?|6~C4E|F`s%#%Ux-WcXa+ef4Ar+Xq#cSC=TJYQ#VpsszPuKi%0 z(IJ{ek!Eq7?to&=Ww_>Yz0ProW^{wDeP7L}z~~wos<{Ls682V-Qk|O{)pwbCx=B5a zP)|4O2_}3}Zolv7zQG^R`0;zd23Pgu0d8;V%>H>Kd>zOLKL#Sl&w*0dC?^UX*mHmLpD{v)Knbkj3hgzGR2k6J^R360Mnlj8y-1WsfP zYdMv5{0|p$DeL(ZckmUy$M<=RAMrH5<~RIVe9}r1BvE=wFXT$ zwqZLavjaP_6FW1FU75)N9L+m8iwn4jOSp=wxtXu>Lw?Lp`6a*Qcf2e?(o$k2PW+N7 z`BET5WT+I$by5NyE98hBE6HdVTxASfGKF23&OYqNK`i8T9L}3~8>jO={)_+SgIvaE z_zn;810LsRJjpM3if4F^7x*K8;;-UJu!Kt^Ns{(5P=?EmQs$0VVaH20ntX+F!t{G8``k-tcUG?uoKEGg1a21~JAFE_aUqOHI7M%&;NPU9TT z;|E;8kNAn93}X{UF@xP$z-u{}Ls-c>Ifwt?Uhe0cY~b$_B9Rg;c~GChyRFX@-Tj~A zB)(>2MzTAzn8RBI5-LrlpWA<-?cYJ^Tl|d63}+)ouqm6dIbY{Kz9kfqCK4shB*wKY zvz8r=hT=P1;v~MvH+X<=OS#)C!}jWAG!kFodtAgX_!U=3hA^Ic_!62w%w_1Rq(b=blb*j+XQ&q?snVm(za@N+iKjlN!m79+X7Kd3DlKpEsb<3 z3?XQVM6^L$w1Xc>-Wh=)TK7~I;LfDLK{AE``s+m+K9_QoKtP!(4{9&R_+2C;J@Zwp zYaEMIWa-%VKoAH0HX>6Yh?P2{t+Z{1wz>alkZIaFJ>Ag?j(*bnk`6f%{qCBiVXG7wKp%WsHoK+dcX0 zKocY*9XZHH5y~(c<57!Qn2SYNj(TiXyHfj$Pr0RAERD2utEDlP##@?X=@m<_TiR#o z4NLni9k6uVr6#c7eRLKJJl}ijvDI@zQV`{Hd_G^0FW4923-yKh!hMZ=5x&O0NM93Q zl&`6;8Hgx(NLI?@^0aJ{E%Kui<}`H%JA0i^oDjXu z(&SE0Em5jGwI~_qsfmn-t>Gt`;HjOKiJsaqxyw^)kZMnDr`+wSZIVfz+A5jssV$Nk zPi>A&@zm<1)>EsJsh(Q7)Ol(}GR;%VmFb>ZhTP++`DKQu7A^OBYQZwoC=ugXvv7z! zXq1Lykn6R*`nK2h>Or-&J+yzQ+=9k(tBjJ{q(bhHN^NP0T*n>)5`+qP$iZ@%yR-hc1*;e#eYG782pZEXw5mA;D|B+k$X@vYA0Evr;iU9xzmp?Sm4+ub^Lt%+4 z$SVT?hm-&Svi{zfvkNmIAQ}i9dlf4# zz&tFIe*g$PWJiWp=^LG?sP2#jjfRm?27HXEoaG8s2^y9bz)b_2^5aiainoKx5>{`I z_w|-8vWNF z7ZjJEsXEN%a4$?okP_9p7+&U&NCm8za1&kIXSVnBvZ-OoW31URN6(GV%eANPiOupq znLvJuncZzVNBf*X)k%I7h5eQ`Hor`a;p$mX`G2-n$$j2oFM=a>>EYQvJyXn5MJ(_* zdtjW9%C!2yhH}642fSYp`6WANK3P6_#doqD0PMf<-APsYWH1G3pRBscMdeDJ*%^ujsz>XoY5cX=#R4_@*ljJ&eGCr=`f`NixmB?Z z!o9kcyJ0(~4*EET462CT`&_<0lIfYYS4T>ORYCv ztT^Z@!L^WIS<-DATWeTbb262OFp#b=mixI&v6k)ZGrSCRT%EUjetwT=*~*ryK18oX zcq&r73KgiYK(*`Z5~OAXzi4&ev;>#z@#=&+r@KeJI`+^pgMTOJK==_D4I=4SLfSXm zQZKU2-dQkmEY1#Gft%c3U^2ndM3N^07KOWejyK=zN zJNc}|>8H1A@QG%VAv!_f2mj;o;z=2*rXeXeLUGH=qkg;n_o5Afvj*7x8>ka-$*DDR|Cr>&d5)t>1+jbWhff%afyy8R@#$aS5codUtE z-d@j%>`>+J4#Y3=lad9*?w#kRKd(qS5Y~^K4yZBl{wRK+2cs{^lH2dMu;!j%pTZ8Y zPM<96`N4zEa9&&29{VewGpcaD*{S2VG)iZ_Ky(UZ$wbqVsjNBm9QlsTHEXxl!|yVH!HZ_wS+DJen{Q?Og?FhF!wv!k!MLg zo~ql8TR2W&|6s8Py&`@`u&jW@Luk_LY?h$q{j0i#tkhY+hce6yNhf%Z$gjv(R{Thg zecpS5Jv0v*{OWpdNA$<ak^uAGdeeWmR+Kq=i?3BNtUHPBM;ml%5dJI2St;XtDU z8g39uU6c;N8?Jy4#?8yXB8$d=^=(=WjoB|dmb($9YDZ@>?21Gyd!8)Pm1H-pdil<= zU%4`qYYQGo!5gMR4|O-g`JgC}Xxn>Y>*83@$`FR$*1cJci9%8^WC(m@T{U zhr+K6e+e4AJNgjMdpoAK#dO~B?ohX*#2wY$5Z%*0oitn4VczsU6~FP@o%99?NQe(^ z?b+TqQogcH0NauV{v>3WDFH8539S@BGt2wFc2LG{0&T_T6W{T?-``5)jalK$tJw_c zR>4VS{1P$iE z5jxX0ZLlW12NtEHK5@?Wa#HcF=pHKKuPX#1vYZ>#@ZziGDp|`Y$R@gUQzT1^D$T-$ zf-{QYU`WqZq;d)Ugkoo~J6@})S0;xpraKNbHxxd(!nomDTMl`4;=gz!EAJAnW8z&- zl;2_x+|&F^Xq}B31fJr#sKpxscWy5E9W!Y19Xi+`~kvRfrgw^Of95Z$M5?)iw$AGJQ3%)Iix&-VYi2}UqM z^yXK(d4F>7C+7h3md8slyyC$5fVWT|A*E9cRawN>3}kVkOMtQxoKlHgYq{7<-q)<# zwW`7Lr}ESewO*xvF;tE;DHBy-!L3TYQ<_@G;$J$pY2T{Tb8pivcw!jzM`z>PWCEo#!u_Ddx~CC_j+yfOUx=<;z1FC)HK! z6Kxgnrl&3V{!B>6WLXN=BAXg|C49NUU`}Lu>lfgnB`Ott<7OClz^jyG7LqlK5jUmx z)*StH%*mC2AX*_L*8YcVAe&rw33+Um%{f$>;6-iPJQP+v@s4I*Is3pbC*H=l<;lIG zyTh*hQK{!ZZ|5?1eh2M5VX?AI24OT+#BF@(L|VQ zE_cD4R3NCVRzbQ{#c%M4o`|RaduE89(^gPb#Rb3pe)}bq8UU-l7qH>VE*O;rlD^7> zLZjHJEkDJ2@QNsl5Y6?Zf_|`gDE)(KX{NX_Q7_P!SSpYPI)FBIjJf9e#<(X6a1y63 z{+wrl%Oh$e%Pq82xvfqP=9a$pQg)W=mQSdwe*Ue<~TgbD>vY69A zeBHu(!Nxv&+sKw!OCR4QzQfD2$R;#W3+p116#|%Wv|O(9QaGm}#o;4o_O#_mUgN~t znyz27WF%#}PtL7bp-qMbj%epQOat3?v)p~~*s-Rk7`t>s(S(a+vWzATni3V;eU^!2 z^JE>WVG z@954IVsCEwux~+P@{va7g3Pi6V6>11CI9B*mEMxb9Z-Bk>EF`$4cxqfnBP)N7l34+ z3UPSN!axwULXreJbH>87hDoYNIKcV7Y6q=l_30ef2MlEmv~?!B*JnL&<^pXG zfa#2SYxariOuoMYXxf6LHHS=fhLUxr*j%7=MhHW&_Eb_78T+ke24!QILK{634>^s) zoS@&iMlX1WkfNA1gWR3L78nB@;Tv-baeFb9J>WlO%+c)+*zL?Ac-EvtbuW+aLHGXf z4oY`U!gQwPA@?$}d1LN-nla~MWl0j4&&|q52Gb(%Rd;5)*9B#+4YE@=*Ch+e8S}_D z{3E~!BKG@PXaE5D|B5rfAJ7RH1$+TX0wn=G0V@Fa0pA0Efxv^{gHVI8gNT8sg9Lz- zfQ*6Mfg*#7gQkIgf}w(Ofr)}Cf?0vNflYyvfXje~g3mz!L&!sTK=eSoLXtshLMA}Y zLw-P!K$%0OLTy8%L-RrZfgXT?fZ>I)gGq-ug(ZSDfsKb9frE!Lg=>Smg8KE@f z2Tujh1}_LN3!egihyaPehaidIj?jZ}gh+;{g=mK8gy@GDfmnk$hXjj+iKK=UfmDIC zhfIL1gB*$6hCGA3%eD25PKGT6Z;eg14jra5~mv%8dn0>3AY3H3r`#`5U(9?7#|2<2HzLI zodA@;h+vjri{PB#g;0SopYV~0kVuQjiYSYyjA)gZkXV=4me`j#nmC(yl=zl}k%X7z zH%T|iJ}EA#0cjEGCK&=50hu;gD%k+pJ2?b73b_mUZ}J%OO!6ZN7fMpfCMpanU#b&o zY3dXjXqp6?f3%@=Ky)^AyYxczWeijdYz)hcMvTi$T1=zND$FA+S}cpK(yZHTifl9N zLhLgf<{WpNzFa(9Gu$lP{M>(eXm~hyDtMZC8F+bkTX+ZfB=}VL4ESvLJotk6PJUVc zdieFt55teaZ^wVl|0Vz~peA4>U?<=uup-DIC@dH$_$>5WXjzz2*hBb8_)hp!1WE)? z#6+Y=WJY8|lugt_bW99HOj0aSELZGQoL-z;Tui)90!JcPVqH>JQd4qR3Q|f*s!Zx$ zT12`~`d&s>rdk$W)EsXu2pVOZdPtn?o{qkUQd2UK|x_zQ9`jriCRfj zDNpG^Sz0+!`9+0U#X;pjl}|ND^-PUX%}Z@l?NpsZy-EXHBUa;CQ(d!H3q(s=t4`}q zTV7jVyIu!O2Tey`r&#AkS4($SPgbuAabO*|oWtdAkL;g{nobCB0>a6^T`=HG*}p^_mTbO}Z_*ZMz+}U9sK1 zJ(azQeXj$ggQ!Ek!-XTWW4z;r6Pc5rQ;gGzGoQ1hbBzm-i?hogmwi_q*HJfKw|KW~ zcX)R{_XzhC4@8d|k9JQA&r~lsFKe%3Zzpd*?^7QspC(^)Uq3%kKPSIVe*}L^e^>wC z{>K590kglEf42t`2LAm6^GE;Bd=O($X3%4>PH=q)cnE(;awu+SdzfHYO4wc4XSjBF zUj%hTcEoF>Y2+ z@@$9fz8uJ$z+8~rj6Bpl!@P#P?|j?*wgUQs#Pa6~n~H>r-ion`!%DqK98>+jj$E)Y7w`&M%G-_&Up=yO|Q){p4(Cc{X4C_MbD(YtHp6c=H#p@mG zv+Kv|pBji8)%nJ-$7eJ>5OCJ=eXEy?DJ$ zy-vM;y*<5WKjpEHv`?!qt*@tVzMr9ArN6R&qyKRLWB_JBXTWkGVW4tgX%KM`Z%|-R zYtUgZdN6BnbZ~D7c1V0Ed#H4%aj0i#VrXUPVCZHTWtd=?W|(7GcvyZ|d)R!~dDwrr zVz_y@e|UO$efW6zegt+zWyD~_X2fG8Xe4f=dE{*rd=z;Uf0TNZeN<>PZ?tN(b#!oa zc64*}Wb}UYa}07!ZcJ;;Y|LrQZ!BUgWvq7WcI;yuavXJ>aGZABXxwhxYdmB;VLWGi za(s3CaQt@sV*+vlb%Jn$cEVx8W1?kZU}Ab=ed2iHe&TBqdJ=t-c#?jSds1vtX;N>p zVDf1SXbN@;bBbh&VTyZ7bV^}LXUcLacB*lzXKG^VbQ)}$aGHBsY}$C*cRFRdV7g{{ zZU$%uZU$?HY=&`$cSd4HWyWA8Z{~FtbQWP&c-CUpW!8T-ayE6gaJF`~V|I9Uehz#N zc}`$XW=>QSn6AvTjpApT-IE+TrOW;UIANyTVYq#ovwFJ*v4*$Cyk@v&yY_o6X)SN9VQpgVX&tZ*wT`kb zur9H#y>7Q2yI#BA^K)m`1>vJJ^u+IFevLjMn^LTLLu0w**3`xEw7pUBV$~*DT{D z#5I@C4BxG!J5r}d%G<;xEf`QRKVkqS5o80HpD?CkF0y4Bs|-3-IHII73$sf`m_)Qz z?ZS9bJ8Zd1D8IRcvM6%7TJ1{N*~wtSD5Wgs8Z)2Q-8@`27)i;OP}g)fEcuGLDV7a; zFmsRminX=AJ=>6Y54?QGW@Z37DQQcLbw|~?PX{@Xl7&^X$x%8iw6e6Ge^>c0)Cjde zcHp@XN|a0Sq+(>?K!Hvv35coJ%aKNeUO|tHQL?ZlVyFVeLNmz}B5>CDc-nlW!9caz zxl<(ekLT3kX&igqI88WYbT)LVbpwYU~@$ami-o@`8)P;vx9l@jHe<>MF!mUDiF*bUZ}xi zflKZyE)uL_nbh=5vg-}q{prBXJp+;OG?R5$;_gc)uXP^ZK!G$v4bH>#Xdxb zY5PS9F%!o@3=ciWpiw*cW%M*D6^`oP>u>fQaVEy15}VdPxTCMrBV|*+t~yp%F@`+sBSTC7$`}Vb22#zYOO}?T>hPewk|E^ zCTp_;)!auha?VX$&^G`+!PwMNQO@f>_53HZPcGHk#wF-dY&q5wC{Cfu>`X`?xRy_c4?c%s)D$$S++JQhYt$>Ot(z zZNdeUQ0&#O*;S2&uls8Ec%G7xlG43Zkc&}!JRa?SA(#x4Xx}oL_JL}2tvBws?6MKe z$Atw5dC%K*QlO!-T-`RYLZeoHp8}j5v-VNumF0|wYU2*Km{KIrJgKr&DCFouP{mZk z*|1l1luWhr=*Us}hUVT~1+$T%CYS1~d_BF!<~jvBd1W>iH8z)pu1%RP(MRNP)>y_r z#e_mK&f~eYjh`3mZa1KG)vDN`znmo>BQVdaOU^Tp%8PTXEi2E!OhasveKZH8+CxvM1}-_uLR~gN zI3{jUVL35&uouiu$~LM*p_sk&j!e&Bxg3WTSZgVT6~hB_aJ_=Jj06|R+sL{2=q$_Y z+{Tn1ORS{ibok%V3`H;QKGeclv@UJTh6cZ$W-HQK`^kmrC&wqJsivpLQ!bM83*uDi z_-u!?-l1Cy1oUScWRhrRq>Gm$p@YHL+gM0Rb?h9@g@j$@{sT5ecP}Jm+n!fQ z%TGwiND^5vS_SjO%2_rzO?QfIcAO6Hv%XCzYU1 zBy9GCfw|>tRLdqu=5g|{Y0HHKO$~^d$haiwqM?Lyj{PB+*$y-NX7*C4PayB7Jd<~e zRLfD`T2^Ef7>6OFBeZmhIMxQ|Pwzrn3zXn}C@6vsTf+7=`K8#hyJ?(`%b8VzD?_I$^#-sz1V_a!z!H(j%FT0&b8Ddy6lgg?--)jn814nl{)|Vd68W;z^h}bfR1j?@WG9l?9X3S z{7pYmzpJ1LzGRwcXDnLXjHo2z4RLU==%FbdYSr@y;KJfKgR2J6IqV6|xjIO(6F6)r z79&F{Zl#}X)7x6x8Ur(Byg{kVTvJ$Tiaq9;O)`ai>~Fgap-a6n7{36YRG7>ng;_TL zl8c2eV(IHDeiyu7oiDGYtl@VIbM|^W)|W%XTOpTz&4jz!#!|GD$7Qav5F~QICbn>db;*> zmaaX5VzZt6bSsBVYe}ke(a}d{(nzPZ08M(@3(N-OE}{rVk4{>CLunCLoVNb19cT_Rh!TVwJ>=0=WRt+2N@qF zXeJVxf(ZBTbCjGaqNW?e)uP=<`vz~Vk8 zt69Wx7p3CYQtoV=75xzHqM~Ne)0V~{J$Q$~xxD}4vf$y)QokV^@PcJM>&2%>Wh-3T zLZZLQ{1omf@o>FfX-4MoCkRq_^e5u%Nlf|FyaLAV&+5O9w7s)^$>(|-e3}}I2Fu6v zxe*(RYppNFfnNTZ5SZ~6*b>(Yk}R?#+#|?UATHdNX4vTOfCwfFtl`3~) zVu(b!tE;#opv$Z*UDH$X^sptZL&x@X0(GvhYpl;HYj&~iaH%Txtg)Xv@kKUK;{1y7 ziXl{b)e7n`)wLBf#N6)v>eempsHk*Lxjrq{`{VCd($P@BQ>vx828U1!x5c5ub>twU z3V)^DgswTPjE86Hsk)|X3fk-Z7imV(=&3(3(e${d&+L$~38rSvoxp?VR>g&HeE87i zu*kslxb`zGNPt;ptNhvxy-fv+3c4Y~hN1kb+o0mfL3iovSfv8v*ZnTytHs})#Tt6X z(Z#j$iIkvfCp8xpmny2wt;2Og0*AJ1)0Jwx)6dGf)Nzhl318(PC3d~Mt}O^LZ*MV< zICX`7bJsQ}INqqMi~?(ZRF& zGTA9v9vCn_3N|jM>^$*2JC-!9q|oN#fo*u_SfpB%8_RKMcQ&#i-8fs;!{FiJ+6LB% z)&U$_8b=TPKIT z=-sCbWb@<&p==LIE?o{CHMSZYr?wn1A2p(K-|*K(P_0Bx^{oJ|XYH(h*4qhNV@Vtu zFZUFxr=w4{CcHXy%7%s{*MDYRY(3+4Hmd$Y6ECXO#f@WXO+h+yDk^JBdd};7X22J`Ur|8bkd`@$A~z>@5z!=l?x3&>#xG+{cw)}AeXIr$@Gr?GbZGky z6|Dc{=!@}t&E>c^O?+~6NS!&9sj$1rc4KtelOYXtBlJXSN7c9PbuAP! z!G+vC72XERm)l25Wtq0>D{3A0mAmWIxL0Ul+xpnkCMwYFM&Id?NXC0@Cn7IdHMv>4 z@-06OLWb8@_3NlGqw7{ z$eeg;i5TXFAqH`FL!LtpFUXRq8u;xa@LQv71gJD@Sy#AS0$ARTAmYpowc4F~8EviO zU<)-&9e_wzIlom{HbygDyvd~Dc{8)Dv67M^r@^*1qSIs2omo6tKK-6Y%yOZdo)f@n zL@(r(+&3E7v$)rGYHmYHsm$GioG8jOT!VG$Qk`yNJv}Lv2r~@YMb}lml4Yr&`MBnU zMh+x{hEPjjXLDt{pt;1gXE;}R{@xOm6v%lVrj}FbiiyP)XJ#`{2(|w2mMkcn2b<_- z>-emm2cli)0B1w1>|!)T*?n8`bFu7i!Ar%S;kLDWs}6-$8b^IQ>qIqrXPZeLkLeBy z(J^kv+FAYJ-Tec6JdIXHnf+*)@<{Hf{Zf-b?zKtHb;g6S@%Y6Rz4}(+1gPwv2ynV) zaDG9s#^qq|4=}hB!Ll`2>aE*4EwUB3Xjk~C=xsS&aOq{+RbVN1ENGjI(c9}M?e{Ma z;lhcfR!a_JF4;rdGIbRH#x3|+_vel+IS#>Dv$(&Xj)atcjYoz9qC{_-3lr#ivDw#{B(k-nzRXVYT zvT_I&BQB(WBo2+zjTZ*$@nQ;)NTf#Ad5p_dcMJ9x7mZx~q@97(vc;X)mctYJnIgGg zEK}cyHVa(h6tfl-G&ThU3LKx!8-UL2*z;j&&2yXP8#S1%zLNTi*x_q0ur^#Y2hudF z*#{JVH#79uKg37Z8F}HJzE2hZYfsMiy>O5ErK42h&iP2QkD|Wb&WaPdBKQ0K6tK_A z^M_!lnJOv_${;(4xQhtS`Tg`!LZ;Bu$O`rA4&_`qZdJD-;jN(x^@4hGl)DoQs~o{z z-L%WO3|yR8B61Xa(HZ%qxY$8P?7r-m?VNWDQDcFvuB0hHr#%_>*Hh8G z^+(3~XNXXyS(}ID$ZK=AdggehPE83r%kpZaA%RzF#*=NqZ5)xl3w=+4CKR7s@=VDf zmaUPE&*kp0=^vthTH2cBy1I2P3O3iyDYZ=JDwbqgZo(#dSl4+`DY6n;%?8)}UEPJDwJLt^*dBGIVgc|N&v6=r5#n;)Ys_fdX(P;fvmDLrQ}f0~8#LiNyU$)_y;p7}c)a3a z8sEEGxH#pWU%wx-lvxjelvoZyuGKr0Sqg(;icJW!vNi`nf?wbSgo)X{FHesaJy%T8K*eV*PM7M06EipR11-c+&_Z(*i54vGKET5Hm zueT64T!``S0wMLI_0Mx}XM3q$%se1hIac7Wj!t;i74357?dWi?j!(E1%ymkHPbRYc z1u!^aocbAxnbfN774J|8ZtMKH3!608lur{M2^nh_ZaI(HB9`w^@gU>&0!FqxZ{_`S zC+t!4!*2@k4^P-{*Y5zG2;${At(>9_4t9Swrob=cz$LAFF}{bd%~!zWEL-tSJ<5YQ z4E2;S_2N{QBm&J?cV(}k9iEnxSM)JBvjrbs4<(c{<%$3Fq8o#CqFKiTE@d%H}fG z=G0fG1yNhWx9TzX^qb^-dMdBSE%M<00R((Ow`ub71Ev#vLTqFd+%EGIQM?z=0aB5K z0`ha8Sby23)1A;@cEi9K&MoEI`s&mI3i;MbC0dlyq5o?XvJ+^6B~Zf5#fA;14QM6taM@rQ#iQtY5ZMQ zYyGv;TvKFHUCn#ZMT;gi=c|w&{>##Fa~(XE&{m?v7o<*LbUYS&FFy6-U@5iCeKmkh zqUs!qpgwA2mxxzP5;LCY4o;cO;M#Wgg}|pbxa`*L926rr$09vauACw5dQH`VB9rVX zTAGZivsDGeJ>}B&mjfM2Nb$0eO?hUKw-7Wo{ePM@RAedNlz8x?I7YPy0Bd8u*`}xTujG;HxV7 zVn!9jO>fNT24THZOgQb$mw;krw~>;h zH0=a>VMAj@M-o8*w_T95!=^+L11_BxIrOXQu0ef549N}@GWkAc!dynE0sOu_So0-S z07qp$#jnYH_}^0@_4jl<;)Z*lWD{lnNy#J+U+Mj(MaII^%87T|d+TcKJwKns?Et7x zlE>jNWJ(S__vYirC@B3T6#4a2oBIR^%o$Gjmjf9}gI43=Ykz`zQBwDk)#TFB9JQtv zAU+0Y)DC!t$2w=`0*lT4v-bMyTjP~R!d&SUDoqBMZzb4JQs@4>B~V~DCZ`QYtU^|A zp(LoT<8o3O6El0DikhScq0bZ!4H_jR!Rj%BtAWQ3bm!rB&Z30ha zNKyBZfN4!7au0(Z)Q58IQU}{9`MJOkSx9%dlligF5E$KEGi0oOg5jHd@a(m73PV3| z1=l@?!5g!o?ORam-}s3zC8{hzF;{bSX+LIuSM$r>e4i+t_SY{GlAOP$dAW}mK%3`Eq3|^`B41g1#a2qS|^;DN#%%|M{12sudr=Vi9D0BHfgXj(79kUA??_5uSTK>& z%^~Y3KAag*W>Mu1CacWP%4p-IA{WdhVNpNg#dy83lad`E&g2Rvn?y^p7w-~s?h<6$fQ*RV_cHsk!K4Pg zX44O+FVeH~+g}|;+7R{w@$<|2qr=G!T&$mA?xv@&hbFE!WHul2`E4H^8qa z^5tFq^rhqOCjIoK_}2FEo$u9s+5ug4Rk z6BJiRq}nU|#aALo`aEzw4Y4_Nw5nWd>ImMNU?@q>V<(E9gpe+`b~@5jq$DA`om?A+Q38oS1mGCIsRo<$2=Xfjcu$_i&MYQzww9Banofb^LA`IyUy&Ib5WCW;Y@(J{99i)GhS zoS@vf^~6A0uzN(u!^EO=p zU6Ec5tHcwub+82;(^kqO>nO0gFo}#|E6(yZV@+wE8g5qbHhX z_LOEsRT5`A(R78P%9uB{f-o~3$k1hM9XLM8yvB|-naQ$wc8IRR(r81W=}hBuSC6Gv zx~;Hwj-v-`6&AKuqn}D+kQe@;vi!iIETfyLuwnJ0p@SS;v<+svg{Yg}!1(yE7_0I( z7ml<@B9})=h-H7l{V$B5>`x55u^U1EHDPMYL&H|saCusmQCP(gN=FrWO+7~`b$Kay zdnbDa6}9P2ndjt#ketJ9eBiU+*wq`hjQAT=TC+j%}>-VkAsjbb1HPzb>XZkq^JZ(L` zsAy>TG2KdQxzNw%K<|x7pPDmYRfhh{|30?*z835Fl~;2gDYf=;!>z{%P8CU+Dk<3l z{$g`=%y77~HYa8?@>JL4PFia3=;s#e?Zo(U&O+DpR=!X#3ukANgp^r0fUrT<(9WFl zgF*;qDyNVMSF%3soqyE>TbCsRl1!e>lFY609AAvEpf%YPLrY32?6`cack+c1_y$cr zzN1)@tqKgfvn83XM#2;koSo+xAZpk#3xExV?qT{AEMD)%q@${-@pUf2=@Juknzaa_ zqcFXh-JS?yASXfK>4nQHl^LO=D1$KB*n=B8?t(%bJPL;q%ee=>LvUgA@tWUaai$?o z0Qk~LAG$7kzpEn$V}Fj4&NJco5kpG7cD(lsY1~mnIKLY4Y#vAAeI3!G01ML2Sh8!@ zKeu1jn3CwihhA>jL)ffVk-~{|xpMC03#y8r%7=}tM1$!2a38jjbM zF5e`dbRuV%%Nyi;!gE=j^Wd*3T5!0kLl9|q#1=!xLJF}h2SZQ?A7|6#8rp(ulKnRXXN**K9=CE8be2HKw%@MlW5}n z6ZEJ&nC3K?qI%;?yvt_FP@#?C;nMP1d@6as@#(zn=QL2Ffq+iYUNOxEN2u06|`i9v|!}`Dxy<>;l zGpOCp2%jE^Hi@if(jCJAuD+gr@`3N-uV`CO z2>g(O;wdG?6-HgEB;F&U=A7oShL3R}jq3Z9L=CDZ07B@*gvD5I{cW!~V9bI?&fEG^ zx4EMYjD93Oh!*3sx81P1qgzo=M~Q-B>AuFqm5${GjeFtrB9{J!L+c`{K5D6~p0v2I(gUlrz7wv+ti;KD!D>QkFLrmGG*Zpp zHtTHI8QqDJTthj{e{vz{yX?T8@)XgnaGZbzVAex!dUw^?t}IOFlM*k4D5_gNKCLpZsf%o#gEc{x6L;roF9@qNGf7@|+}-!Q%=U9HQ*J#L z(zD}E@FXmaFGWGa2!H0sak{CM%ff4M!}>z?YH`yip}IQCO_o1|&rEO7X-gLp3_p46N-Y=SN!zwbLhFj|WMy53B{854hUIcu8po5O3RTKKz?%6EHB|qGMcRjEK}X-r0nfrAy8{q(X`i}jCzAPG{p?+@Y?nFctXYOR`s1mMJ550)moUqS#l6nbJf3t^RY5(AN`HZx`Hly9W~@+p;zi;+ zp9*P3YrP^$(E$yU!B+06>hvz6_$48fmL2;fI4{6unpNpK@6{XAsuFVcmJ8rFeI~J1 zv~ZPdc0Fp#_oH4J+VnY{jjp^*hY|K?yz)mkX}r^#`W77|-_1QaJr=iD{Cibe*m9&e zLe9X}etJ5!jC=Hzn%CUmCR+?RSZc0rXql>|lS%zjS422fAX_HGX{% z>R`>rH2}1YvrEE3!3Y(;{qt5ZZW&!8LEQowpV1puGyFF>~M9~wh{3KJ6h*E>TahvD=$c&)Lb(CZ^7!)Q)q{qLZl z6}})68wa?UT3v&CSfgp0<`U$-9J<9=TEC9;K3KgT{C0+x>Wpb30UHan|#R z_7UjjrTP1}2@4umejL42+d34^<}W@mgt29i(KfS3Vy&i<8?826nR7b%6#oD@BhB2YN}%wBFQtJ7+VH;T(XaK< z`OL=&n$<$ngAHrPXO-a*96HPer!W%wB)BN9`&a`o&Op}&H~RF^{rs5Q3-mv{;|X|~ zoV0pvfVa`rOs9P#M9ct@I2YJRBne3o_WZo^G=49%hd{A)Py)|22B#~-12v3Q;ZKOp zZCpw#TQeawD;SL(ao-uS8eDwIc0yvP9^B2BmL5kS8X+>i8L`T(UF>uF+uKiB=Q-*l zvjSBs5YAa~UjYDa<8}Wk%1q~U8br}w>B6E-Z@J5kb%N3)wuI;3r((C2zQ60GGCkre zqM}viXvtG&uKRU*V6Upsiy&5j!p?3*s%NjeL-D_({+4p+ki%CGpXTc~p;kmFDMzS+ zRX>grh{q9`YL8o|0)q>Re3lcnaN*Nk@(t5SN~b3nFb5R_zG zv_hg4xpk3$H4js8Plc5K)6p0=D|K>E!JgU=9X#B$A>#$23PB_z`{4C-!V*JL#7IrP zup~u_CP_danntEzOgimU!{hr zz$E(gwO6_Us*;&wH0&B6iq1Dl6iKeY69eq{F2>GsM;qTKqH&n3!O-ad#Q(9`UvbyF zhx$+c#s5#Ja$)cZsu+?D?$EAX&SPw$0oK=q@|PoOWS8eOe+=>Wu$B(o%yEwKWzbda z9}MRB@B9SdAej#FY}E&GDNHo6u&+Q1rvl8@KbX2E!IA%BlpzavduI8N^e~yf82aOO zhZv=z{=w%CU=-AvpTj~uSv^L+`$%?$w~sla{?Tbl^TLWbSL?VDjLt7WrFy%SX^v z-xpms^tnuWv2q}x)XIv32RQtyFC9*Ik4{C}Bpd3Zg4DLQcV?r9k)6 zh%bAue*$s!HT*WRCCszSA=3pE}tYG!! z!$YAhtX|?3sj}DlJo+Gz08bl@YehZft&WcOJL&ycLLG>)h^OMbs<@iP|G{BA1qADI zkxh(awTz={%%R5^G_FUn{u^p(xBE}E);t~;6XBpX4`!Gj6Mqr#D>Zp8!%Z4Vkh zCZMz#ncGG7me^oK+svGv|!BCSjb566>J5B;~ zI6M*6UMtLys65y`5gTx~OH!Fa44y;(e@!fewCt};WS!SXaPsmgA?@FRoD0h%?dE*E zo*1hdSeCW7<`o01A{8-sbIUbGvQqb=;kM1u zT^iU32LjhDg2GQ$s(W$g*6?_F9n@Vi7q)9T;JH~)hzl;4me5@V?`N-5fYgOWw3bQ& zBXIg&t~tQMx;2T_jqzwi+MG>rts}Et*MiR)cNJ_^J%tPXifpRKTuUd0L?SR??1$Sh zSj3{hDzXe`8F--z;>0>e7|7SYjJ1wNF8cFgY{j^219J z+1WV%i*;<)N=!}3k5@G3GUF}m0A67zGx`*%4W!dMs8pWf=@fb`(%YkA zt@G&;ANZ|$!{2*$y^?tTFl%Mq=L;f;^1aoXLFqlHja8%L2I_U6Dd4<@IfIy}NazUtH3j3KlV%F?L6 z_^yPBv_Fd1!TJF8aSV%^wwe?osNb15S4;s%EC(%>G}4}t>#vsMtEQjL%p1pPh;KO&Fejfx z%dutGAIWB|64lzsN3uFKZ8iEb#%oFdyc=<{xoAw|DKlG6O7bOaZ_jEeMD+Ts-oYj1o2g*d zXtB^sUTK~bJ;8TKf9t7n707s>aFZ!#6ZyE%RLqCzxIay+*yp&pn_yCu6I2nurq4+RtrrXUr=Y zcJabmdIGPcfDh_FcKuOW_^4_%SU!WK7e@ZouP-Z_)RWoCr_<*-uX%*Fmz z#b$^*@myBk_zCI@j^PuYGtYSZefaG9|ASNh;Qt?RJ@Yv?=>I$W)MwmyGi%=acpk8^ zJ6N2X#+3Qt1P~E85D~tQON}*bbwII2?JV%s`0w5FrUbroo>@hh}-1qx^+z)p*CT5J6QR4mEr;Ec+2}r9?Y1a!wV-4D;Gaw6W?P zifFuRj2Y4Z zgglT|n?LpO=Y-eeG1n4>MBU=;9^dTE8=VNR$I(gQNI)m`A@>1oVy6+sBmxgc(VR zEA|)wy5qUTtg`vuGkBsA{hu z&8vjnZ~zH}@G99oS6ft4rgMsX!ZZPWmR{HbzeOCEpxCt8&+ad-)L9CvBpi?F-au+$ z3rfS%g*lR_59TR>2A-xqCRdyt_8h+_AG_-=>PNbEM;2b?road`^NySaN~68m`WbgH zzw=F0-XlkcmO3HLtvCsB>pGN(zI)-MI~T9aPaX;qhGErPD>j>xUW( zZcHVp)5s` z7%6Sskx%^;Tn5jVH9Y~JKKmdigEhx{I{RCZQDA3({?@wrxkU`}`0cFi7+V7CdJ(e> zmx32qU1;~t$t+s$HQe;)^Xju22wvDe65C-f8ZnX7_wyA1j7R&=9kJ8^waLRVJb|za zJjngSxoVV?ij*v%{#uJV=MOx_scGKIz*xGUMCt4vMKRG3p#J2-_Kx6XV43B>d+8UY zdl#z=v;kvt-&Id7K}&sMXSe{ogz8w%q;MAAucGBnga3{N^%#O6yqJ|&YW+7t!T;CC zp8q61fVe~);=S2`dokz4G)_th_>8Av*Vm7E;V=A+8j|XtR}SKvUf$r|!;{1}7qo{` zO67Mm34u3nq9f;*3*O1`2&S}PlrI`KGa^RV1iYg7cmrghvxrf`rsoVdf)vU@ngI_o8?s7{7Ur3Oyryjk!|h=m0(r+WXaJp zNBC2U+rd%F&TVd`XYltqg;<9U!_#>0qK0TC27U5t|1aXu>1cZrIQ=F*%%u&9u&t2U>$WTDCVZ@$#qO-U%4LxNXiGsg092q-505A;ul~Q?L3>t9>J)a2L!|>Jw1;xeH+Uy*hg>FI34Upji#byP??)7 z71@2+#$(*QPLr3EOug@69BAuFp?KQkm1!wA1Ik9nk zRc6_=n`9?g#-Z-SFCKnxXL5B+l{3t(jHz!%K(LG(Z~Cso1j0ZRd1Z0t6#$pg;7b5~ zVs~4;2K$cfbQa?ZM_h-6&%W@tVeO$=d2W1IPN1U<4lhZB5^M%X_$kWZs#!u=X88PLRvgO|l|)u(WF&y&1C`|$9z zdy27s<@t04N|CQ&XXJtTP6c6jZ;X+O5VwDaGy4TZ8Q#|k9O(sK7U>`UHlGXjc(U-? z*ZFSyI8~`;{j#>vWk#=MK(xetcfEUhZXu``mqdUUpHP0~zMho{Me#HHwb(nrPFZgq zZ)L!~nAhr1fc@0JdgMZV;>qpP5<=?nIaddfBr?FC2!d_DiPtUzCp_&!1+P5^oaEX| zcH?sQ z6yGxKA@kh`B-)3#z_AbCy8J(LBl8?Ck@{3Z5beWh8+99R^i4YsykNFPPH z2j1s%k&E4AFYahrEbAK8`cBewaOJV3OoEJ+Lot#=D>3YqF_Qg1%fVoWfeSH+igEU+ zd~K}l&au6V5<{b-rhf%#8Oo=#NgF^mV}x5EFM0x=4< zaOJHdRz}7M#ssTw^a1N+*+{+OgZ2{q1N+Zf!blYQ#}MA66AY~y zoi_`>d(%ho54^|k=!{GpDeT{ji5C(xm(_=h!^X;6+^?AP)n=Lr_ycm$ZFmr9=jsggX3H!=812v0~N%>tf6LB{Cn^ri2RXg z$9X;5(FuO|Z}tTLOr_u&x3*^0GRLR(>KZe9>cOO2Kich6D9`=pYI}7y{X0WXj4%`< zy=%PhJqmpHszJ}nJY^9Vr3!5LqSURwNkFGt2Q7022lRC-mKG{iR`<(7*+RFcmX}m0 z+U;{ZSmk-PW%J#piuInl9CKwN+K6F}FR|C1vi~P6k|L>y^MYu88!Ee_YPHr5b#CU~ zjB{suh1KdTD>Y`D6Bq%sACyrQ2h-7!0)w_8M%r7gzb+>nC_Oz#0N40?*D)Yy>qm^S6-h8>sX#eb=acpE;mNu8fhy`|DCBg zkK1KTt$F&V;Cl3v{~Q}J3A^EGeExO5Ys^vt*Ax|YPmesAsmN>68JeO;21HeQLw>W9 zI>uddL@qhIMz{rQ-u2P7dR$`vN)Tai6zlB8_4M6GzrLM5)^+=h?42v(A$S_+mApK? zxvCugbZ{SdDku`ODkvV>PNM*}99kkDrHQ(gqYP}&(Z|r1w=|tOAl~)q<9%)T@Ci-; z%XOFS%BG3S%%s1czlSDq5A)qtOen(4!B(#@9^{DmU|{`%}6g%P~0 z{mzYR%|5rH1DqAP9nWQ-^B)V3j+mB(*6S+eRX5McptN+OeMT>MBEYrE2-?e|!+@)z zvbx>LR-*G+kLTgvYj>k_dhC7$b1)|Dnanh^rqt)n*0?xD5?Hy@i@j@wXR8?BNZ;0S%XgR zVpJ7cfwR~Z_)u-%_&}XKr;sM~S69)bUiDj->$fes+#H=*?U9}wQ=|@J2Q~9rJ)wO2 zc+yxIvU-Zqxlvr!(lql2VezSBeeHc7T+fTS8rIaEAIQA1D~TMhNcsG`ORzLQ;z`p9 zW%N&M?dXwL5>BGZ&lg*`#+8`!EHv~~_0tLLoK>t_y*J23cfw7l+-=MS{vc(^c30qN zt*S7{EqJ)TbYquS#D;m=h$9I*Q9xAlb!1UI5%}jEU%*FsHeyGvZX_fqQy00Hj#so$ z)huHu(b9#8vEq0W6xde_a!1w)xQoJ6yrW3CX z#*@WeBEWfthZwF%!rK?DC=S9+e@rUQGO#Rho+0bch!9U!FMj5!3yw1Efg)3(2uGu} zQ!B0w+uRo5X2YT(qu|O=(_Edovo8n}+0eA9qPEBDzC&ZbqcDRXsIt-ND89wAnIE0f za-Fw~`MCtCS39fmrIxTS@b!#cTUTC|qC!#I2H~ECg4K;{mPPnn<2cfkG;fH;`llCS zE78Ve_F)Q}rTSSohO&Bsvxc=I$ShbGMUm zNwR#$%h7$L$i){8H`U)X-O`|KF$_X1gH!&FoPk@o??@sDD z^NHr91P?IwcZHJa5#83|EkI^4In~tFP2=sQWv)Tz=IZL{;Ebfh}*IU|ET7|)OXtRQvfX}^jiPc(CRcg$#BzWXE z?x5@!rDto}Os2Nz*k1d=>}8J~vb@;>;xH%SIek%(W% zmp`%xdN=7*DqZ20>gp|p^rxwA>Sg%ab4?W$P56uXUI7nxFQ4eLx5vk}*wE0b`wDF> zvGMKp&WRP>F4vF6#Ws6!v7Jg`e%gvzPbv}nEjprrKgwFqFiXAZog3X0c69lu4|=E* zr-yahhR{&!O^&>isp-W#s;hUF?&zgn6Y8lyHn>Yb7dyu8AG^CNE4p*4@%nLF&(?L} zAqmp#grrt&*#?JWs&Z)Gs3zH+2SIqOQQ6H=s+j{1@sS6!|?Gd(X!UzDL;5nh;+ZOBSfB$Q_tc`nB_dG#iD@A701Pbls}6o-}rL#nt`^$`s|F zc??(4C=H;`*lNuaerkOTm`B5pZ6DQbLH0{(v~Hn(FAp4pj#dv-y994if2?=^^4mYx zSHLoC#%}4_wtn@}r1UEPShS*K4XfX4FGcEYEhn%odke0^Sq3{Z29Z&GyE%ltg&Jpf0nM*hHqP(S4S3BApiS4;@6FK zm$k|>({ssEvZ<`L_56vpDSlIFP21khO&3&_Ih>_M+p6?bC;Zb}Q{dmOhU#`&W6}~r zmLvkRqpqO3v#qhZO(##yNlREJMs3de{Mrt~n#zjNSmg9pj_F)3*Y%!AE*^1YC#rq) zCz7}9Ex=1)EfU6WAJNlVlwxocsHyt~cdEOcMJ`oFih`^r+tF#03#M8R*H!IrPNjN< zTH09N|I6!*rR;KeQ^$_U@DP}ip-3L>H?^w^3^H|g>arzatDF@b6&-5|cQ?6q*awh8 z_0)s%;Y+PHXs=@R=_b7YP(1%A1z0Qtu9i9-9-5-MENNN}8i&S`ilz*yE2>hB%4Zl= zwh}ZJN~#||`qa9toVwORjU}HM6TKpZ8k?2Rg5Jex($7JSBQ&x1L*ou2*MdF@J=!9Gt4UgNc^U>=u^y^Ytd zhBB_bjn{64NnHDCUb_v3b9yE*1a=GeXlF$mv-bMtnLb4#BTY- z+}-BCv9=>v^31P=huo8kDfFjEuVWzaJ9eRnbBGs-%2C^)I(e>oJaka2hX8y0su7?1W# zf=}VMEK(XrtAUQc>AY}DJp8O7gBS5K=iD2>0LN(?9mYa`Pl&=ELgx@#$O1`cG- zoquBy?`=47ShRq5Pq z!j10dJYfG433WbmyP?guF66=OwhVoJEu*{VnN&*(3b*p_IZS?RKY~1#p?eN1)GVAI zb2o*#%OgtgX+EFJ8UGI%TrEj>dc)rT2NpBp-=MFOIA<=|TjD5uf0*A62Dh1x?}?*4 zrx4PrHWy^2-3(^kual9?W<_&7Q-06d7Vo-&&U$@75Q5uqWUcew^9oP`Q0=|Z#hLTl zumwj4dt(MFn%MW|UjZ8To1J#IP4LpG<8&c8oJYh4`rzh*y4ng%$E3-HOU0oScgLWJ zsS?NTcaO5Q;euCE^o~G>3wu1cpvc}1^6XT}ROf7R^fHu<=lGmi~A88n1?%!jjdM{hy zBfuVzFWvr7jC+}EzroUDOypT^I5Cqbc!65tq_g_@>=ux=+_MG5*<{cDk3*%jd#ZA5 z!}FFshr@|*e!BQOEP+ldh_+#c+;VZqEuQ_VbuGQkbulcpt&L|li7rE0*&!Tgq>C)1 z(3@A7a-8SB;=H;2tJ2bv>c*{8lauBmT1lIFmb8r_9et1EgOzI}zVkDam1|%{V7F7a zvemd8SpT{ut#hL6pz;I?{>6K!?AMlIo&?$J_n1f+zcq!(_BngF@O$wI!tSx)Z{`Yh zP4)S`9CHjsTd;@Ja*pTw0uv_@_@CJm9+~%;-r%GU^`c8Dt?x0sg%00s9pZC$l7F&} z_3qnoWL2KPY#^CFy_|MEkDRL0i|wr;rxh4~D|HpmFI-`=S& zfq`~T1<$b6DxyZ_Xabwv62ZHETc^8=hBpj1>N3kqOKZ?9*|h1H%XJLzn>vi1x@{NZ z6BtUuPLzAi@dc;?3zU-(U5qFB^daHZbS0&z^^M(4b+L%pYtI8a+!3PNW`6fnSta#* zxbb*@8-oOvbK7%xnqRU5Q?Jh~DK0E;oZ7H)!;3EJQ)ijI&bKNAJID88ETuZ=I*Ex7 zwn*;vFT{FiGg=`X?s37jpL$BI`W0B+v6EXLhlF11)Qx523dg1UiG$@#=z^At9!^MdO+Br9} zZX!OmzQHXL5~t8{AUwT_w$B|6Zi&%KIiFD{Zz@Ndd_8T591_>F_y}hqDv8!WEBiSU zi|ZBmZuW~lnybtSs5SF*A^Pc*yGHqW+@L-1em`1VL&XcTm#gG${4<>1f=}HS5)EFO zf37SF5rcdKgs1VD-4<`J_gt9+bFqwA;B%m+(c=+QQw#97#{H|Pjn#A* z{*DrSAHYeTpGE4?!W!f@qe1-6%WsCXuP0O@zu8Vy1jYt0e3O``PsYB)!&yJ~-c%eQKK%kAxhEPNOrL1wuT z(AAACd>?l4oah1{02BPkq{X%*OLx^>81S;N?vCCKAhfmV7<>YQcCq&1<)gr!Uv|ab zfY*m@8cJu-yT?M9C649bUc`Y7o z(^}&|=~wZ`Y0_JQT!q$9;TSNW^RfXVv)LR-N3}}+ZZUS##QrC3d^i1-4Mk>ERYzY$ zer97+O*3edW@M(=iY}ZiqO|bw3+@1K*eyDTRp)*e+!ZGkjMfgcRYWX}OI2xQTfzs6 z2PY8b?kP+K^&d=y*Pbzefb+)b_hP1erL3@G5pAc{`R$ zc>qKrAF9n|NO;r`Y^KZa_#RaDR6Es7G3xlZRr|U-wv?*0r9=HWtr=;3M!VZgK5_U) z>a&KG*?F-#mClS#doM9q^0i)-s739gT}}2Hv0z1ov$P{FIx&%kE>g1c{Dj_orz%F1 znX7Kp<*2c*@$u}_uz?DR)rB_dn@dx&nkw|AOURHyO=Tfyb-8Xt6mYUES(GHBBpJSB z`fb1j6{BRCBi|!36D>q^5k4!_;1X;HEdp&0D>5uY_KJMw_CS0`M=G83A!O|Bfh1vo zl`LW~3hu^;^EWTr0wHR|bo~&hH^>-Z!;*$_t-7+KGqPT5X;#!yt>G1PMv*emKqoE}-y2;!(LhCK{Wx9ZjxG*~AVe0w# z=p%`lrXoxu^&zG)16Q~9rV+=%^AjmR4`VtxB3H#;zIJO}Zy+kEU&>8Vno=H}2@%(A z5l_?wru63`Oew+2`XKzqPu3P#L@<2(K(=CxLpIL9`5pfBxuD%M`NUo~wYTmZyRECW zp?|HbaLBcOO?xeM8M*$mhwo7u&C18Y?UcJb+n~(I%!P+%Mu1Y&zox6UrKzK}uB{Of z{)g-wS@!)c^6WH)NkeVL31u3m#^%u4%59w+>80xW&COL-hnN(bbWUTV%e51Pgb32pWU{)i%e*M`y#89#^$^{nF5b*KfL6?9Yuw?N=tz@!w}C|(LY`& zO;_Emn41KTi<|tV)eNRUdyZz2aBlbHCr8Q6ze;yLs<5RBP^U%11} zEtsf#!;`4HnNBMfjz%Y~s}9QYH7QHBwE;(Kle<9h?0nffoO*N^UIFH(THSyW8|%+G$r zkCUjKrzXMwR(wFP-?#VxX6M|C4RAc2TWx`F@ESdU&oHHd8GKS{z;gzBNecH@5&-6} zIDhdpdq0Oy#SMN!fOq#9K8f#}=YJYwt-ChM(tcJk@xE!m4y)6hm9>`g)|uskcV_lD zxk-nwJafs*qqNm**1SEhu~=_(^jFeHfIo34*&`n$##lGveI1;s;GY3Td24S9=`lG6 zY_%5ydmS{+`mzVak``ko$APi;s?5|PmCb!XxQ0eo8*GsgMa7#Y_FQAkN;ibIuBx!O zletvI`p_{NW<5So(z8-qgiI>KS#7O$6&X^Jj{u>qdSkOw`!IVkS6)rTw+d~i(bA1I z!IIL0uHj0YNftaaa}6hK?k28Wxu(Lmv3ei?XR1htT z&(HcvKR~{gFZffza<`h7dE!?HnFQL|WumimBKNG*!EK8M&FBs|@i-{4HqB)}|4ws= zO(%!fXR~JfmCjFz0_`??Z#H{*oD%xlEPCVldIis{;8cx}-grI;PbW%S#|~{zL;KF= z9;17OXN8E!rzXJJ8{g;W6|M^l(G}D7yjezR72Xe2Y(;xQIco8M0WG7MVrk zkKebvjM{nEhFs6HMVGRPDa`F>iPGR1wzE2xd0wh*-zN1O|6HDm=08}{ZN^6yG>V{_ z=w$8}K6ha(Iv>Xu#~r-f+}>+LuH&yMbKH^bzSHn_*6|72 zbvR>X^@;u#T0zCWE7GjjVcPK9cjN50{2o9jrwCS1+DsfmhHCzx4~cL$2lVFp@u6G_zSSec%piiDzwEw?Hs1jrU>cDeB)ImX`4& zbau7+5Y4G7!sX=$>wtXo2B%qPW2@244DeRuS9RvjCSWXErY`3AD=o-m>yrhkOUDb{SsU^Q;+L+vyvf&| z2IqURjN^!JLHqiMSM=v6lQ2aTEtKow%ZsX9cXl05L|k;}C#HyK0Vk)01ICB=zWMAQ zu#Rx|J+U+OoaD85MOhgJ-k-W96f4W31rtD9UW*F*{FaW!MGL}TVOV|Hig<7L+!x1F zm~-cU;fOk5z38p{=z0OEEH3Dt$@d6~AAK(@s)YjbNT0bTG~_bwl5rSB=emw z^W2_#(qnTLk}NoTRM;>h^6;YzxPxAx;F&~zI?t!NnOKNpP_7y@H`w#gy>Rx9&xcs( z3%N@^uHbRg+IZ#*al%~E?rfsRW6%Y|-sLNK5mt~~oe!E&K;LDR$cqF6J5b(mIQ~4n z9z*g5*9-ZJRhIi6!9y%E&V3<&AP_ij#~6PIScKduzP_ON8q<}GZcJ1v*4x9Q#m|B;Z^SLAMB;lM&vvX6kUny~nxxQK;?q|o}U z#xMJd3QJ1Zfb-!Q{8c%)e7G%{z;mEsJH0*Qnuz8t$*^u_pKu)2@52yS%+m+lgbu9v z$6c=DEjkP#&=EZ-U}id^F$tR^k&W%YlA~%+2P99 zcw=Ra*;+hQ*f<44%U;H-yl~#lQyE(b_okr7(5@F#iH>1nWIK zj`0L+_1bxJ3|xLQxO*#j+yk@={T**X*lz2f&z-Ck{F!&|#68PXBxY`?GkME^ZeEWR zSLCh3(Y%!?3x1oK6w&6x$^02lVV(CKX24#MImgQV)f2Iy4fQiO3rA1USC_rT^5B1S z*~Tm_e+vSoH=A58RIC0oA7tkPxGq5>(Gz&DE)VL^$HN%_T-;1RS2gx_bx;TsO-5!&zCO(`$F z$g?!OIR1XdH#`H^Bq_?>G;=^Oa?!(- z!ZS_YOHGeW3la8JNVU}#Yo%JMtWlVU@@+lw85KMxqoPM#u7{{Ee0ES{SbUV9Rgkem z$&f6-gOxhg}UD?E>Yz#=S|*;cICmTchK|{_l}|v zNtuOLglvHty;*|SF5X@>|Fr~D!Wq9cjg=Rs5YF`ND&18*czJ}rg?@L1+v!{xHdRNZ z7neW*{A?o6_Q=@{~Q|_UnqFnn5kZ`E~C~s49-I^3k0(y0}w7isEz1f?j zG(>)|olO4g1$YCKPlM0Zr~mNXy&ONZTwRXn5)tkqv~fA}m%<{IWjTo5*#^6VoQfG8 zOrr@sjW;Y&e5A=KD?L27ZON|Yw<5ZuaP4z`jwYb6{7cW@%BE$C$0N116O*HY;ykIA>xPu9L#_2=06$EM-=wP zM0c00*)S?_xNoQaRaBB+0(N+x5j1OcCR!%cpWZ?5Z?1d~2m0&?uEE(K1L0g;d@tgw zH#?YsJHvK;kdQvV9T8cKh!pOdi7BC}1piv#2%Ax(HLyz0Pz<)?XxCGd|5teSVV|Dw z(ep=;@D$??RDu6jxQb)t(8}D(zL8PE{WDMNS4aj6Td0*5E8HKbUSm~$?!L93x~ROY zRITB}r=@jZJHI|7qG>B0#Z)5CFU!smgj3}lMZ9GBR=i$x>`aKO*G{0Bcw}bADZ&L8 zOY-w!n>QM&t~@pEqDeHOc_oH4l*Pv4nX9Y_@x2Wz@QzdQIiA79ga$ftDae@j$R(m# zn11euED;wzXDfL#A{@z5#mO?j*kVr`&q<%XOd0mCYd1z3TWDcA+{KQiq1#&N^D2}1 z`QX>S2UhA!G>kkA@`iroP$O!__@FE7g9;wSnK}ib4em$t2;^0}_S_5gsJG9ot)JL5 zD)=LP)9=#!d{cfazUSB9M~=zE#L>4pA;KyRBKk5XHdF7wk!=oP=gk6U+2&7OK2>*zqvlVQAHe0RlHm$@Je%VUr48`C%g2468D~aFG zb!vq+qMx-$m*Psy8p0XK)7Po|xndW1mNWKFT}C?ufbYr|If_bHwuHYyn5bl$G1$7f zBGi2%s?lO-it+Z@SC%)k<_NRpdiEH@*Jrt-h_SpJ&noy7j@NN+!Eg0N6zdlr3HH80 z;Zr=c5h$_Fk^9%P$7o{7TivB}eVERus)I+pFh{GFMKm;FYW)V`xonl)RDh-bZ%k_{ zcmY=j#?ohVNl7fGA0xfI*F>6!#j@aiC@^Vm1EbhjlKgRhXW!C{X{%)tE+G`UR~QKRxY#U zI50N(LlXa`+cihx6~BJ%v_G8Gee-DTyCDyQL9w~VM?c;yX3 zzQmt?E+hTVAWLz}*otM=IgUhsI`br-qvsb`mIqt1lzbM^^6bqcUZfda!#t*fmwje> zxJT!N?{hmcPQI02V5ovsjuO7l6^mM8RTXe!_WjxGF^8|U(B+{j(DZ@oAk#0}foMT}#)4I+3Lu??B5dt_S7WQ=dlEJJ9&GFMfr^)?mJI#McvJWr*@rI=Et< zGtR(awL3i{dHI>M*hFkbYw&*~YYhX+_y!eTgBLjOEGVxHIHV7tWf_%6s!B<%HZwO! zilivxEJx#2g!h92rX0MP^R4wO;N2aG8Rb|fFEP?pfWdlH2DoI-Sdi}}rZJU%x36(O z+Z*9TWq>u|tEnPMjgdM|GwiAVD_%ku0Pb>Bbrey5^Dx7&_xoyv6W`o(f87SfSBaQ&UUsAuSHkZQ)Fa=xv)1JVqf6w zU%C4p{jU5smItzn2a%KTY^I{zM*9fVo9JKTdmdS@YKA)%#rK(I{L8a($w}TV2V$Wf zdsZU4)sQZd2xd?Xh|#VAWy-qps!dMErmBWb76`QT1s(JzRm6-?1z?PuaFLic38%4AztQnJ=ou*Rx&;IjW`v);>6p?LR$%1rc0%X$fz(p2yUvrdt}5dEy( zJi*q4DfT&|Fdrv@>+YxdaV9#keLQizZ0n&VR|Vt`UqEs;Q}n^9d(OL#zA_ov6gS zvogG=O;l{wYMr*ed_~yw0K=(FF3T)c05Wy7_JWzmgsx9sev_{D-s-*(@mHvzW}<2S ze#E8T6>*+Y?=Yc#J;Uho@)cR{=_+JQ<#$kmi@qCa{xWrVWZ5W5N@&2Z@tK8T?vBuO z+^z$^W!ibSlzoG5(dUo0AL}B-yFqhqARJDi_uwl-ox^d-gU;g3#rcz^IZ27BskSIU zt`>tOh1oRNR0ndzBwhP}G{ zO!|sV2teP9+O{yM;{IihTuG&o$i_01jZj6 zYE#$8ri>Ode70?g(>1qbWk;-ZH^NKe(z;y_&U}X0TrGrNjBaenL)+MS45RnELB|?> z|72=XuA1Ss#*x{qw}@#@3qcg(G)cN@$sDgnRd%M5s`hfbinZN5XtW|>q9y@O$)$hf4u6yGkj zURd89VCf=p#>vUOYQkS?y$+ixWlDG@hQWF440J?$#L~+w&c&* zABC>7&-(MYD`HcNw^Ll+!8*kjT~;2$xlt+0^wa>l-G^xwKc~T5HxL~@rxh~Jk!9b4 zOp>5}idaKOI%T^K!w_Ar-M)|v!dfd$u1J&d%rSB0spF4h$K}ieK^&J$cO)t1m4&(5 zq+V85Q0{Wk5m9XbZD8&20Jg(U-g=H>2*H=MwZgG)dEi^JV#(IFM`!(-CQEh){a<`dbscU;o1ggLTg#!8j(ag`j zjBtShbCRgJJUNZwrm4`gwO-`schc*jumt1Aiip~I?f}EyrGNc!i6#J)m1kguC2a8> zR2*{ICEPvD7$Vf$(%bs7xeYknU%(l*PNY*ym9y9&?`%+73VT5_2L-C{M?fGsAK&^A zyLe!(1a7QtzV+o6VrLuXq^cq5a z;ia84g3o|H)pLIS;@Mpot;a{``LMVEBF`U)=gU%X?41X1{XDk+*@SN1TNU{=NRbus z+M|1(mkp1*i3Xf(Y-^#e6a4Lz`;8xp#*Vtz^7iPsOn9-LC77;mAlv1UH;ys4<9d^- zz$eB6QZNAxAg<&Tip<}Sj zchi~ZOT~_s2*>JoVLeyksIr!5_gZHb;E2s+r}N$Tc{vo_<>k@y`4l~K_SuvTWsHNr zOc2TW_mm7VU7!MxddcG?P!DlT^F4hp#?=PK>pyXV^ZEy9uOaI_nOBg8GpHx=cqXB_ zr6w#~bdACD3yr8y&oV3uGNLP&J-gwGqIE&XG%Fepswv=z-WRd#r6cGjfB<9q_bfc9 z5Anv7n}HVi4c1M}3qPU`zzY{;f)v(S<)P>K6VWowfal}y;TVCR#z}i!*SKBazRc{< zRn&=o5ACbi4{Y>|sW)YEOfX?H^%)&Sd)AZ+<_9~&ME^xRs9D7Pu$NXY$O`K@03WQl zG$n{X#MjXOdbvh1ch2$p@f=3}%oB)V79#$Tpr7?H&RRL{13FE{tU3N!F9S=!0}A)? zpDMhv2*L&=j~tvwDCcJp7B{Z+u!6wD+OVT%W(tfyG}P9*CW^=I=dsf6)`#3S@IX_< zO6mphK(i933EbcChxWc1&@pQ0-`HEL$?)P1kM2e>^-ttIshmbL!wfsNk6~Y(!TzuF z_Z=2uiE|$OMmV@P!5`ztc#cJ&LFRl5_YU4Tlh1ID#>^^iqyu{#{-cc@4)5`%68*i8 z3cj3#g?NV%qlEA+qw`N>fWA^NPAK3&7fz31Mq_T7TSYr&)`B~!Hu(EH@0|J8!&8Va zbcoLkV&TMz7GDj;)Cw?$FNMe>%)z6TMd18}0zOKYr8IuAHLqLyf|j~w^E|g=By9!J zy!bqizqmP+5vz?}p5Np1Yt{7F*7WmqtL{l+=18g}1ZPmTT;y!eFb>zPyh$=q^? zw*$M2nJztFx~M-il~;fHWmB8J6VDU_o+&Km+Js~GMWU{Kr%2%NV*${0Uie)cGc?xv zc(Zd8RdX{n%d#>L8bg1giEZfzuX8W}jX-k0O?H2id<|FAO!vth%QO*z)4}9xOcC;n zm-Jr<2fA#{4OB9D+NWIJfz86fA-fHL@;WRh&np3~m1HWu<8Uz=DPwPT#;F*e0>n?u ztAk5&3-moUFi@pm9lFd_vB~`qX};*;c{EQLliN{Xv5+wdwgMXI&qzmf8KSk77+l;9 zda{h*%a2cg-&Lu6)KG1 zOaKi!vn3$GEoFudEdz2s^R{UD9ME~F)ln9ZWOH?1n{~O)?$F+OgNwm0VX9LhVDL+V z?}>iQO`6bw+Dn5Vn-@Q4IV(&)$OkxE%t5tGT^F0Ntt#~Fd&1V2H+aLG5&kd8NMvQo z^XQ_G*cN9CUD)q0_d4&CAzL)rY-S$vk3tDj@lmMC9c9pFu>>BF#!_uVTw;r6Mj_nr zjQ{B<+xqgVh9C^&=AAAsJ(V-fBVy-wJb7>&N=!XmNZr+%mmwoR1ExK@{_=4?>50Wh1S%2XA zb7maZZd?yTTbdq&kAHgn3H~v{0$YCRWxE$C2(ES`&!-3UK9exQ*UEFlzIYww?Ld*g z=506in=OW5idwFyj!oNGVn6$WFcu5~jGbECX^_Qo!LL$uOOP`mO(UW4 zwL$qZWV>TT2N%3^u&1#;2&3^wyzd|s4q@N3ghiVCk149_NOuqkA2mFQhf^($A;bdu-eJ*KmMaLnOGcz2LR*Y1#`y$8=O z(-HnDSK*h~3v?2dh`axpxd7K5e2LTR3o+H&a`sCRJmq^pcVT|K?>fMoT!pi9d@S(d zl`v3hMtBttj&~wlo<7HJ59o=zs!YuivvHo%M?|yiM>{|w{dn-xGvyL+E7;zG_#YV^aB{N)%!5wHjC&Z)-MphdF3n9 z@Dw?B39Q!Z`JDeX@Z|-g)x*EsD6T};7357BO;e54Q}%g9QxluAwpfcrQs`m$Q@e9Z(q%|aMa7Nmt)#-gU@x>f_+H7vQz8&rRrnY0 zlWZnU;P`JkRz!{{3M4a_zb}!yy@9(wq_gMmi z$5Xg%jKHPF-eUJ!bZzm8eNLp8_Q{Hh(FBxF0gkgj3%;6ppjrfAby-1cOCh-4f5#;& zJy(OYuV~cb&?O~bjb>zxK2&UN2~_)5a5;N=!MeD!3;Z0jOqZeKI1pTpO>EiP)cB!N zhUSKKF*cjKU2xASHf!uYQIrDUk{TOLIcq(YaOzfk#uxGXlM%+@4c<_?1#aAnGwG74DT!or7?;N#!Ll5yj)l<0kY{`OiUdD3b zH>X9kDd3>QuqD_GFB>-jm9uoM)iPev?+C9@Z*oVIf4%78yOj17xy{a|=7RdXfYaJI z=!iq>SmBtZAR&pKzc0lnTdENY^%jC88qtYqA>N6nYp)aGe%FrpW$Czm_=PvS@Z*7Z zv7R!}C#lz=gVdLy)6!}+y%VqP%cqY~ld8x@tF2o@Z*aw}h^Aw}g2KTlm&4wx)Au`U zEm72Y=RD`N zi#0ooWO6Z-0Q>3v<@=R8)2kq0NB0U8QCF zT31r9!l9SfFEEH#@iznNH`|zuKc@d{On=ci(H|f+%aT8zUY_1Ddbnkvtsz`WU)X+> zs)1K6sC&Fj?9QDi*Gkg6=)zcx^D`1feru;Jfa0*lQ}O<16jmV_BHil_oY?K-_vX@v zSGwbVynEZ5rRAy)>q8c3`Ij@T0T$YE-Lpl_sQ2u+!_-Xu7~?t}=JWz7@A* z^*goADrJM(+?H2rZ&zIH`XoOlB&8rX+X`&i)KTu@XaUwK7nZ#PV|dP4{v41baIihk zNC@iC@&0~<>f6}XOnpKwKXun#Tv6M_jK~xZEzZT;B<3iJ<*4eM`QdCqz=ZI8+=Sv> z@p*>@2(9r)_$N=gcM+VN%tc6(uvDJ}FT|W2!<-DB8y|~@%K5kz^Ua%=3#v`)YDDqK z$Cx|Xf`ifZ9{)77#N_^(>|c=O`H!|>Ka~x?>6teBciLWKFV(@f*eq~lVH>>~NsU{b zX@ebAZ_qZ#+e$Y7X49)>0nPMmQBHb>zSzz{XLXr*IaPVZ-OCO8R^A}%wy{RKPUUN) zsp01Q=!lhObh?_g*S$P@oex(M9t7qlwi+J30dwI+*sC6%(6bz`)*BFTl;+9{IziqY z1Y1%u9uZ%wT(@OZcz9+oX1E9;CESzGPq924{t$r)IPD~BQylH zM=6EEcMjFIc5(|ZgMt1t=8rycQAjk-$Df$HD0yKH`G>U(Q306DF9buO;m0R0arTBM z)CJ}96)nT&veg1nU{;@uUHyk6!U|hlQb2Ai>l6&LPzV{%H%*X?F`Q{c?gI5eS&*Gj zq&Hx;;1%4q`sn51))qvxz=&%69%u`7zX-C23zt&gmX-6i(Z}1gm?*l2?-$o<)89n| zu@y_M#CL9LkjyLjHzpfcX{V$HB}|C^XG-Lt;2lYxJtdOH5-GZJdPKK%cngpjOind* zb<=ozX_;%#xw(4i(r{ZdqFMC2nNFJC)B|mBPlNl8+5Qdn<*>A9riWpGUZSq+*)bWP zAkB%Vd1))Hm~@P_X=q-a8U4amK#dHyfa0|!6$ZP&QMH$44Ci5P5G1oFywu*(6-P;B zQmj0Sl5to4fwfyjTPF?_wyj)9(w+Nat~z+|YDsrN0CCgurp^f1>ghPM%co21WuOpk zL5S0_n$0T~qJ!tRx7Iea4i@)D)$1+oDy_nvn9!)DiPgSz$%ngK3inA6*KH4_{)>qH zgSDip)R<*S0B`5p%%#=&;||JxQF^wf&17nejyENzW8xo;D(L#)*RrILRewh0Ushx? z7NnVz4l=eVTVTc&F5~doqJR}<@q{$s*_iHEW0n*!HD)i9SY0%k4emSR`)yS0^X$lL z{ecuCtvXEC7b?fnwbUL)sskKwf;o9`6J0?FNBBiVz1I!k9)*?$pcG(28AVRgsAn;I;-MB`Ute5~^x9Iko#FN3uCg+QUFP)Kb$AS9#FgZ`vu6ni z^E~T>fWAK@l88ZTNVYeIilp9`kAp9Mr zlzEBrM!I^83R8&myh9k?`W}x~(UCI_j#hZT=PIs`=7`1~6NbG8Bp$?bZqx|F2P@4e zTqB*l#7C4-cvE(pDYnZ-OEPcfW+3pCzNPFORd^e=Er(IB zhd}aBkR9JCeQcK%(JP!f+kxmE#e2I{JxgxTJ>J%AElWJ!&%Ky-GsXR}-uz zFQCmVK4gPv#6)_XkvNX`0LuqMjn%X?|KyhIJ6hcTB$MyF(|wI?g^2p8xD*`r-S{iB z<=~n9i1NgVr*e{3zKe(&@j9b>IWfP=Gl(6yN|(g@a+{VTDg!`;nX^(Gr@q0bX5u^ldw? zIvj_1QwFI!3^-Q&=evLb^tSIzh;P)u9;k$`3MU%tHb%x*=h1YPyKjn}D5Fox3_ZmV1n%}tFgCEB zFm=*Wgwl)D9)_xZerl1`)+9_}6cNjx^#P3KoWGLnAv9@vB&N~q=!|FPkianWD?ow^ zs82y+cgafX%d%4HMc%}R8CfbhJ8|B48*{_^sq`?YxTj zZ@#bdj+*>A^}rJmow#;Xx7vd%2KB5*F1t!Ive8^cg+{4^ zym>0($F6veoWM19bUydC;_148e7N&Hi@@y*PwW_xl&Zs5B~R6CJ4B88$V2$S%tgtC z<p8+b5|OjhQqxJH=%sqy6)aJRKG7Thflc^m2Zus z%9eVtlEt}qO-*(S{nZ!^ROKB^8E;IP;C@_P-n!`9cmiL$L#773Y6p`jcxmopo%!z5 zd6j>G4ol(3IG1A#j1^u;g804@!N)v&@N%lnm$;u#xgS)5Rq2x@-nF=uvVa0i&tUH| zI)ZVDXx@7xR~Anqcaw(L{}v6=5wBY`FzsTh+t5x@q#ML7HofZdg#9wfo+l|gQ;mH749qY_da(2 zQTf-zH6_lTB%0PAeh`9=ER9JUP~sYcM#jp#65HBRqQ&M^=E%Rwf(C0?NuqFdrU`0{;|2Ynd9 zFzVrns&Yp$FdQ+yMdT%I*1O`?p-e6Tlmd<@J6z z^7>XI?=t+lVGI;9NX+E6*c1D^WKrp=x}E`nvn}yOprX8z5d= z62LcF^$w!%3!ETeF>jbM8Qz=VXDH5@Hk_`g>|YdhIAZ~;3g#z}ou@1C>B^D?Z`55_ zq!J-ZHTq} zbM?plt2qh&kaJ6?M(yVI2wfLJ47k9@Yj~%h^y@o@+aggTBl}Zp!Ut?GSqZe05B_kk{_`1S? zwN>yqiP(Esyb*Ns^B9mhk>3S`+yEu|UpE-=mcds8T`S0X8FylA={Z#TU0|qiF&LgB zs1ZCf-^CYxPKfYnTneT|`S;i%=VETXh*;{!DlP?sW{}ZZZT74P$5;zc@W0J}->lX# zkB>-A`A+^f-PgygtDvLnca-4!06yWe0F&Nc#<+rK{cfugR>RY{BCRuUMcVm!AlUdK zg{_-X%@s=-?;cp=Kj(+&ORUC}ARWAj%F^PQ-hPBFLW`(9|3ZJ#n<~m_bKBISWBi+3 zNLP%+H|(yaT{BvUj2_9j+qLi(QIy29hv$XxPKgwI_{orduQF-!FF#nFk!LpMO?$pcg z)4{Te1I?A2q+zyflVc3Q`<@g$la!H>^o)S1?;<3zeR2|2epsWxz+|tYjm#s6Pk)z( zWL=)h4XfUDBA}usp9e)w%SQDys7=DSQ|@CAXJbs`Uzcxb3GDyW6<1lUm6|kFt->_y zwD-iXwq`R0HW)Z#jmzr>CCpVg-i5Fuov-Gv6^r1Cz`SU59CN^D*$BtWM*ZlLzc_-i zl`|ub{oCr%(iZ9g%pIu?w1&7U1M@{qSnMYl-ax)*Il=msLLS9_X<@)!%haH%g$BlR zl}40)ZWo?Bx}#G&*)sx{*lmUCj$z}Vv*XellU{~2?Dv#|yqo%a*@NH6R63=pYh#5? zSY(2SXa0U+$GYaF5gD><*@pIlK_jfFzNocwOWJB%7Oh}2XNK#+PY)%f=0%29R$A>s zm7PJqXG0px-^rU9QP}D(SUMN8!D5LrxII>hDBuJ_lSWlIuw!+mvZP?SSh!T0nG%})$!V=`vuHJ4HDf5ETMr%vM8Bw5v3 zw#2EnRsaLYmL_G&GeSbr6|$tXY}8PJ>f>Z3MW%-2=r(ud4;qSL#f2>uo6@*h=CKD? zBc9DfDUWMx5JWt_IG&=S0vm%z=h|@d~5LyUh17gDQIuJd^}Ph883H? zS}Y@u(vf&FZlu)G7jLzlofQdBJ<-ua3VR#qnk$1N(b-=T$U#5lpn{8*)KC(BvwOefP)5OCsXqBS?MMXjVz?%5=3| z-&@MGN#Y5F|FV!a;u-Q;f+V&B2|>@V$Iu9UMxG)<(YtWJVyT{eQ+aJ=X*KKusYxm6 z<)o^1psg}JN24kwApNgEJfd+G5%2kTk%37pA8ORs$;f)BMiiFc9ucu>r9`rlrchp; zM-y1@hzJdhpubSRAJ0AjzZC%HzII}+OO1rJLj3biNYK0^PdweHKZx|)gF1M)A2b79 zu3C51I_R}FLvODtMLiNRRfKUzCZO@Ye?`;8uf2|#zfOkZHFcHygh z8am6nwFyT7p|NXa8aY{3M&I;P)4usG{B*no;U?(V`C{^0B9(~32=DFSquHMcfZHEH z?dc3xdX}qzs)AwsV6SUA$u$}k!~NsC^Fpn8rVBzn{T zjWoCy*Df!&1eXR!!?e;eCk-kOeoSPOA0XXGq_bGW_VdmV0Jm;Jt#QcG)6-n!aCM*sII31$7mWWq|yowOpn%Dl_HyO{*<7 zThm7TCnN^MoeX|LNIyq^jB6VrulBBe%lCYx4hE8J@;vK*7D1M`w z<$a-dM)2fdZ)D}LTIBcs{PGI5sHTLINLwkAh+3Mqj7Nr~uFX`%35Lc}brA$`;c=%e zu9Qdw3U)T!J9~!x`)%CcNjOUXoo#=b{Df;CW83MSlQuyt*IyFIX8XHu_Gk9**K&U+ z;TrnyZ2J?u_6eq)x{_29PJxbq#I%Th?pgHQT7k~<95D^(xdZ69iX6lkS_05Fez_ zI|9Ftx(4>)>>l>RB3VaF%K0B$Wg&w`8>Y38=QFZ14wH^Z6$kW@4MFHNAaaNDzyK_8*viVCyLN#VSCz)0%aSaMU0&Ir zlBm|{lxbOB6ssbI)?S0QveIO&1h<@*nb$q4%9hDN6>P4`E{clpw4jqD9NBn8XW<%r z>oKv~=dw1PM&zMT=R@4%4lN2UY$eu`rZ#Y3YGhBDQdu@ovzr=&`wkulrz+DjYqGL) zRb_<}>zZmz`C@WOp|+&3$K|@4K5s=mN7mqzGA4o$_(~)287sVAupoXJBT#t0!Ku!Y zW@;NZl{%@nf3xk6C1uR<7_H^hC(|j^LC747QRZbEvQ_eB4J%vP9BrWoZrZ!z=4{V_ z7)!fyJNT!|T>(x)&v}@f{8&cYQ{kg?+Q%LO3=rc)EiSy7+$}C}Wo2tJvXZ1~M|)jm zdhV*)(uuW>$@0N#8kkV#XZL^MAIGTI*-&O2b(wQ{fzw<9vobez77iQBVAaKK zUO@}4^aQ^}en%|5&a%@IZ+>zMtsQEh@QRj^{9!}KUUCOoPp4t)<(=fWj-4%Gq4~|S zre0?KbZs*eOpjz5`7a`x*P~a5Xn0`GEp5Y>tyy~!)1Tm}TgZPocDAk#?dxvpV|u&b z0NYn5`5pGkf^~J-Ya`d5xBGIorxzY1zq{;$u$6<|jRQs* zUv@3q(;rWe|2}#kY~@f-6Wi0l3p_o&Ony&9ay_N^cJ$>(Bh-Dj-O6_K_Fu{Gj~)zL z`C`)`)6Yd*KeOZy^HD@b{bS^@#~!*{z;yJ{7vv8|53O1`($~!Pbg`!=fu8LtOd?}C z^6p8XA9?20{kPXc+>`K&U&tS*Q>(y=vEH=$BBrlH`#pV4kpCfKFjan?VRaxko*jPm z!=v{#FbtAoA3aR|=kiNJ!Sb>GbWeBPTP>dcZYTeX^-I9?7ofu%foP=brCV<}-pqEn z=F4Zu|6XxvC|Fk7k(=J&>2n*`=lkT33-tL4ST)l7m;3I1zLo8B-G5#uf4uSt>a(mv zo>5=S^x3o3%JwM?BYz^|=ssD-{lu82Auk0hwu}sZ{KO+~w6ooA1jKvfPsMwC=#D!T zGOpuoR<_?V@@KAJX^?&&0q6qDk#9~u`+gVO?+7HOu>EcUk>8WQlL+uy$egjDvZvKra0`%%}pXOWbg;mHE`Eb#5Q0aP9s+eCdj^Bwie2s@{C z0|SU6XUZ-ZSiZEfN1Z*_vz_g^jdXkWoZ{c}cF=m!=r-!F)X#3}U*l}odqDw^lJ4>Y zgUdoH`!qRR*W2v`+xHQY@|H(RvR~h~fPup!JE)V?SJcncskLn9`#=rIBdLl5L(9OD zsy=N_6Wja1T<Ti-i49i z;MJoSP`6RfBgsFvh3)+?SPz;6L>2D6WHTtW0hkcL z>WfE15bZ-o#a!=BPw(#v$OU^p4DP*o^fGD}brba!Rf~D=73uCcKXRBOo1PlDQbyjy?gJXoLvBUpfu`(unaF zDgYP64r>sF6hCnhY{YB9suQ9c|I9#{QuMCae1j zOubvCNkvX^vvo_aseP?@nv|y%H(9C6GNjO&DptNu2#KuOAK~5bIbs=-Z48l4sE}{S%U7fW zDG*2^*hqx`7d`eGnf9#a!op_y3p%Kc8^96jVno8d$1F|F**Q5`R6E<)l!bnyzvwYfoBbJH$L<#rDZBz31{vR#7E5`jU;!U| z3RibX#tY27Ms>4Bl$w&;Y&JK`LpChQPD##M6$#c-hw}3kc@C#yhp9r}XEk-{$tCjg z^xUdEd3jcR)auA&q(YL+cq*}_Sfwf|QmN@G?}FWy4l{?Mm8c7FPhW!XBAbJv|9XD$Bs z4loKHfgjWV9z=&7bzwso#B(pg9jCxBf28topl;bL;KOA zoy{6mL;K~Iqdta-aX1J^3A#fm(oi~|rIBdh;L8&)qyK^awbzDUdyRgZaCS3slDLSL zgMpNWpWI$idJ*+Ch@i8=t-uVv2iFl0`9k!wN;H3;B@WTOM)GEEJ3DK|+;m0H+Ggv) zQ{?aIegV=w@D%kOf`yU4KYOd7ht>-#0bvn*k64B?Ts$2_bB15z;epMYj~qc?4yQ!o zbTHrHd(Yi{&vVb+bN6$jCF^SI&{dx6>T1`Opts5qoo@IdAw;7}1Hr=NZ%)DPQMVa( zqra+&r7#A5NWalwhpay=odf2G#V9SH+ts_S++?%l!*%4oA#}pKe6U6VY*g%x4dWXP zrh-bxN;;f!VER`7;3BM$A5FcD%$N>QO<+rf)^t{%&Z@6SwTcEHM=*KH2 z4hh!@Djc?gw$9kN`eu56RMri;+93S;>uXxTr&P|sHP?XWshjDssUQd>`wxg@ z^b5wss{>Gri404DtEmShjd@LDa?{3!wfk4BUsh!*EiEfi6^2fLV{q$B@fl_7Y!y=l z6K#2hmeR6nRW|rF0oiwa#bg=@+?&^nGIXm_=%`i18+vfutgWqqv4iG{EqNs1NkvMM@Ogu3XG)%(XE>NaogUF z2d8qzyVqj?ZgZ461aj{p#hpmLi7bMaeoaX(ASEgp;JRcbUzzVKc6%GglnSE+PvX1x*u3Y zcZ2%Loc#rS0iQ+DrWDbIEeyTfa~rx+daNMN{(y-cd&UI=!j!%dn_h2UqaP~l@i-FC zZs;2tuDwxPuCto82ruV0@_Y)_EFsuR#t;^whJF(#Vh=RO4%x+tt+T@wfns)7#q@f= zI!y!73c>w_d6dk4duzkK5{Cm;?6D4-$mJauR-scRWF&}Kom#GP-8FUi@4E+&pBHu2 zXM1h~@%NR~7?wb(B`pj6BrA<%%$n!-4d2~YWY}R{R}vM|u&2a0lph&&m2gRfqY^$G~y7W?b%w6^cD5Z|mGoz9qU@`L1R^hXs1i=U;B`k%V z9qArhwwn1N(SV<745P)=mms8cSnJeN)FnoT!+6PG3QEjZUk5t+?Yd?ad`wxdw$_E` z=#?si`>a{3vHhLah4k4o@KyK>kwDu{CXF>GU<|2Xr$Bno?S1R-m0c9q>nNVE*(Qn| zy>S=G?p@!1TMsyKTgTc#t$AgdutA zyYIkCY7f{0d){(=&<2mSvCp1HZw$fu&u%4w)6{#Pe?AExYkSK@y$&B^x&9b&of3>| zIytuz24=i#^K$AeIB!|kRULlJkF~e8)gP><`3IQ)E$}hy1JF<>^rb=H;g(72_~axg zMSPY64NVgD7m&;HN<4-Ab0Qo){nRA=2&Om}&B+(hr%<{t#&2X7iZJlv#?H=-Q$U`Z zt3X{X>zbJ8Qs@nG@L!gO9y|s_3cv&a4FKR3>IX!@$|KaD(XR&TW%Tb(02_4&^=np& zcfrSK`(V%@VQZfHin@KWwG}lne86hzS7hKG}~$-mV8b#ljle!zVFjY^}x z(C3d}3c*rx03M^qCPj)#0bv?=V3N8UQPMgI#qM9wJU9bIxbD_3@GJNX;x>u%0lB3M zI}UTB1!TAPpdsqNy}SGNerAN2@8XWzhlg+LKw~j{d&h`lsZS^FLGPtt zy_AOGSBN~*3aZrWT6Rx5H1J)``-gz2erjKeTLKQS^BtLaWbH{!ltBY7es|A} zSL}HgeZO)K=%9W*GXpw6r`wGlqvtcMLH}k6{XXP3(yxOxpHF^q-YvHvR*KQHPf+)Q zMuO=d%rMr?K>Nvnwo=DIA*BZe)E~er0|RZ~>;P>Cubiy|gXHf$GNtVx7#tdUll*=6 zOjnPfm+tM3*?Q@D=aPb2PvYv3_jq6WOKk=JecX5!nezq<>ra(@R7(9i6iT?cfG-&$h77A8VyakIgKV$i#)g4M9{Mdy=xCV z?Rgj94X4ExCh&RJ`$P8fEk#9J%bWuV$ZFN*Rp;hZ<5yMZ0k@`PZ)4-WaV|zSAJ*4j+lLYwYy4-ch%QS7i|Tt1=eOU5XBVNS6B5R zCYtw_6iwI07uM7i(lUxh-_)c4N8TI?M6Z!xTnJDPPvz$iO=z=+(fXwauXM?JT6<(l z8I}a~9oCv8g06>xHO4!h((x#b^brdf8;GBBZg1Lf<wY6xhJxAA6*D2E>F*WWfJ;jq0yV4cnll<80L40uMOf+<`2ksm&ZLDxQD<>xt z+H_EF!4D-yiP)#Pa^nvx+v7oFza3$C*cNeR*$O61>8*YD*C>OR-I3W(6{7>C|n{tMy;RX$?9hL_R!Nd08O7Y8C?FijhH?CwyO9&vOQt>XCQrdK_%mZM9%Mne7(D@ zVoz=Do{Fk{wYk+w1yY&{c}{t52vYH;^Giz3Z)!Tfv^N*6l+8Ig=zB{JwmxX_*#nh< ztPdvD&-x4^t)#7wqd&>d`pjrc_t4fylR@1>%Ih!WTOT|>&IGioVe?oD=Rn-lRNQcW z>E-~ILYrPU^A>1H_q7zP|JaY-wH$LL;Y9y-qbZ@V7*YO--ir87peKY>%| z=^QL&F8wjT1M;U~E8Ifb6iS`dVXHQ(dz{@XOsIddDvChR0{CP+)#s~ht3 zrw$;i^F~r!Pgy-sbzO8(7XgS8lv}k!8Leqx&gzC~JU$AvPsX*X@>yMmGWUD=sWPN) zpon^%RyUx*Yau~E1C-G#X?nN@c^w*%e8Y}EU;L-(Vel-T)c6@P56U>dMC$QN@_xH* z{rYXc+cdR#>xN1C4d7SQ7?e@P$ZseG$JzeDKcUReFEKp0ck70&59042iu&ghPk>Mm z{lpXa-%xI7LH|a~`b**DMc3cDg}QIc21F0l3GSGA8!U&3bYy}azXv@T!bA(YaJuf# z@6S-@pFIn9cXf4vwOw6|FCYWYkrU-IDR;PJL-pQ)y?8tfV)jwRP!bS@>;%G9H`(b;+$e`AOe zGa((v)oV!>wLRBr%C&0D2}xFsU2ZhV?P^QXl?Z2(sn=x!TaHCzi;b~rEIC#?`fQJh zv1=@H>w2?JXR+vX<~hF|dn_7>Sd1)%C(SQIs)J`IcyRaKNheQEo;;a!_pTd|L%#5wiN1{B4hkpbqz6_ZPwget2LMAZz-Gr3V7PzBT@4{%cato z81!`o`x8#!pS&+59|c;KzhE;17BuQU%T}6CirWtT%d@k8f?v398Xmsc<+^!z_$HTo zd-;VO9S6$GFKq9)u)M}JXsekBA6=@;&^evDOy!Ev@O4$T0W&y3N9H3Vw|8{hKGJ=- zy83W;*CjPImvo`J;?*U|sa0iV)v3t^^`@~Rn(rjg0d9gXpj9_9NGvmlsY{YqE9CjB z+S;oCQ?#j!dFMac35i9vZdr`%E4V_ z1+}rcu~BgmtCi+tZDN`+HIE*_)rc=0>NCr4x66OCi=FFYX>5%>BR@SgE8yb+ zL3~tHLSl4!YD_|0boSC_c&RB~nUE-30+(hbW}7UimuR%)nIj_*GTk>`7wZgPeE1=J zVr|nj0k9Wa=;q}({?SWd4$f;4DNN-` z7DAZ{Lg`Ci>rKfrxkkTth7Lwkh3gWCKK=hz9#JXTS<% zU01Uz%t?p-AbFvz%&>oLJo?X2sWhn7maYJlmjZq@5s)f$&x-=YGkmaHt3F)PaoOB&?4je1?9T;8D9+pI>t z#Y!W-)o5lv>6zK#GJ2aP9e+RCgZ!zrAc^@Q^Gt04-fP&0=?uX&VM)cF(OycgtckN;|?eE+}z%aD~u6Sxl*7OKDg{I=WZ-H23#0zS(2Dn)%t z=}rONXHb21>Cp>bq%N5NQy&G=Z021q{Hh~?lw3gP<>6~s$K`~Pu$+sg`}3Q%knRsq z>(+qF@8^Uu?__B85)rbQn%Ob%Jya2)@Ie?0v!5YQ8{YRJ?t z@@hZIwZA|-&ubs%+Fv7n&uibz^?!zVme>9=_xvlw=fqJ0(oqB1igIH`PWR1m{z`X};1aX155Tp9$0@xfCQ5 zbUWUo!F(NK`8|N?;kC2;^4pIx?U>)Sy!OpZJLYQ~x6`%Izry`I$@VYsZ^!-P_Syf^ zkq+*kX@6n%E8PA)YLCSIGyR;I{Rfs0ie2D6*!slrcdC$Hal2JmXc}<$Z#p`Dv;K5- z_37>BpTB+MgAa1MRv>*0WHB38uaEtal?pt7NAFp7^q$02Yk2U`e2MQsmWs zlxfG(`WLT#m}$rTf52TutY2kLB1Xs-kOO+o$MN`HdYc{@tbE=^jhV?v2O-G)Bdsj>pF zR*tqkItr;P6lfEKmMPu|z%n|?YQlS%XP{J>ZVf#`EU3jAY#wG=(ls)?pZZiqiIdnZXbDMfClxJnD)3RzOSjYLQlZ5p zBUhWAqL1k{u3Du?$ue40?oVJs??zRfTvi>Yq-BY-$7DR>^)K{nMzVa12+&T7yxIw_ z{RQIjxpw$huKhLQH@x=Ko^~YT$9Vl1x#wRY{zm_#+Xc~3Nn{f$A|L0N6Cp1QmU!PW z6ouAp@2s=P#~Bqw3#f9Dx-{KTx^idCd7akLgf%GxRywmgUAe7bjjY>RxuswW=qR#x zE&Z-4k4tf(1a)4KG+SELr^#w;%+k3S-(_X|NT7C70Go!gEGYWoseC&z}COsOTkZ;Yj#U`h$j>xjb zxli)*q#iq3i1q6eR=;k;yyFZlmf@$YY@ZI)PKvzR39kJGtfy={?*CJ^|I2ypr<=)cF+NuJSU+yo@s-=uE-{qQ7b{Uk%ewSrL$!73Y z^(4wJYjYZ_Hz8r_a;e|RfhY}$&n~BaNkPJ-dBK@VER%n*vU-6C&`yfH+6kr|%j$P? z?N}!NU}bVQZpZmT+|SocKUh{c#~o~kEiBLu+j|4~OpZIh-+zbgzZNFPZPQR!kY7@t zY~dxjJv3n2zGi8=keKtv`Z%u$pgDDvvrlhwb_fuc^Paz)d;TO|8$5Okc%Db?4`Cit zXXWrtcnsHVCIp_-Uj`Y2_Yq_6G|M2|mzI&EudP(D*dJ9AI(B&V(ryHuK+n3Rd^iUX2;=oyyrJ_&%X?; zbI-%m-19FJpYxtS%02%g@c~{xp}fLZM~BkH{M(iA?;BOR5$cEeHZ8%G**n!nNgp-F+mo1`P_t&wJJ>hHIuC}n$Ftjx^Oj)RRcxwl&aX-kA(nwRbsi3LJ{R)4vnDdwWIR6(A z#hi4DutvU%Ei~9P_w?o5(BrBb_7%)nQs1*^F2y47T=Zgw6i$ydZXs~j4JKnuv~DCA$cwUM*&XWm z1W7NVhvi2{EJZqHMwIEaXy+OiG>AOc4Qa^+rFNural6tND|XQupT3yQX|&#>H591G zVJdxw7db<}Dh`?#mU>65dk z@zYE@;GRBtntuAnSq1SLe2jfsM85hpU|R9+bt?SZTq~|R@{A{P!#Zszj&eKBGTx4} zjNUQBE6?{V@=ZeLlsNEPcqC_VV9!+?4laM?2Bppm3b$38w@Yo3^fG<1yWkS9eQY9*T(*cqe`pBbn8FwSQ`I8>86F{`}0toEk$O`fruzoh+B! zD?dS^!f(V9;{Meh{JxdU`vkmyGYNF)U$8IJDzSm)q_LTk#>>PtIM(uvHAX)0Ps-59 zhceG*0NSHyV0Q+Z>3&gX829-QqJ0J4eF{TPDm_dRu>?Fs-CkWi)!EtF3X)^SVt|7B zIdMGkTlU`&cyEFLsIb519|59pvY=qH5V)eKr$KDgcqHhfUW}TH>+j{_dJ$e5SwEGG z=loO=@diOKW5FUHBfPMWoP>BV$d9m~I4tDM=X@PxQ4L8!a1A`o_J%k_(7GK6=it7L z9YKz(qa0T+5^wUjB0OB7cH|LoS%y9?`v8cS@blPf#%tK8jAht8_w?o5(*nt6 zn>%ZF=YT!b_wEPzs7!Fk^?uuWi-mz^noZ+v)WbYnCL6l~jBn8pW*$B&=&i<)5`m9v zkA`08%hz5%00x3q+lIz<=dJ>9#oap zXs|JHl~u2|B6QVj{CMhgQGH!8JE~T!!!NKp{3Mrw>&H6$8522fL{i4O=RuvO(mLz~ zJe7IUuzb^MJ;-5D-(nD`zh8kCH9icrj>e$6H?iiCohdAGB+3Un!n3p<7)c1N)jTW- zwajCVIR1`u{Jlur&hfX0Bsl(FbkR>^6fBm;i*s2Y)Q+(!SQ?+RGx`vLpQp}X)GU4; zNBghib~$whV_ER?xczQ|>mO6|B1_HHy#5LNJf>!nep-flUyj$sm)Kq&B`{J2^*#)L zPoGW^`0iow5Gzs-ibW;?iE|qpRvN-`fJU>dS~9oCadBD?gJ!|d7NDZvj}f_;+Lu^r z_hP$DBV{fnSE12KrY#U}ArkZ6>Y)T26ycTW_smN%ga&?>E*VvahK2V1vx|qN;qr0A zT%PVV6t^7Z;?2K$;!V_!(vsZsecbZ^wa-2OCigrb_Vb>{L#Z-}|) zk8;nyNbKhIPH?@yNaLSpPtMAKgB0M(6=0U1^?01BaCC}h~U zq`5kB>8j`$(vTlgAXvI?Vk!JJ0*iLJe{3l2j!%M1F?^J!0`HEH_apB#nvJFJBd$R0 zI3J0#XhvrCgOBlAW2U}mG4sZALe2AM%wiDqHave8gQM?Y9Y2f-puT7EbjEW*)J5|B z!^ObsOpFJ)2$Wq9&%2aS-?M1{)g0cRp8~+pf1pAx^oZvGz|7|gj}H`&cw?}7NrBON zBu~aXd(;vwD>nMf9e9~|59bH|PB8o3O(2totuy=GQIczq9618-X=!V0 zZ1ed$5X*E?29SA#e&SB__m&oJ0xl7zewg^O%UjwINv>PxgSObqini})1;9_+3-)8^Y)>aIuvswf^Pu4w9qZTH-B4^27J40scZcEtLXf^`huRK1aMPgX%$ z8>I$+q`%rYyLvCStIS?pBXN|otMS;bGWpUU2!eb5LHxYOR$T4>JZf*}J-?Of{|xH? z3eWTKwC8!$4tTknVJ^4w8qvnf-Tc*)TS4sy3BqT;3e%507r%TgYQLTL{4n!8?*II` z=W+jEGtvJRLR;L($*d=o7z}RJs@37yVWh@}{E5P^=HKa4DM2^f7(|jCyhTU|9&YxX~X^-r2PQJkGKE;iayzYDgpKQ-@SnT!~gtUsvZ5?AAUgJz;BpdXe{I) z@hTVxZ_?|FK7%)TpR-7-^v0?x8^IBHjHZJAd+h8P zQjAt)`pp&h?Tfh0yw9X0$D>~C2-Mo&@5%xIB zHYEJ@E0X-`uL6&4`SjK_ zh;8UtySAgD4HTixXXoyff}m=Z`kz z&aY=w?5@Z#M2SkBsd9z7dabG9aAW%<*lkoQDzXgG3=2{A;BRKkNK^MFQPT^uV_s?*5ltpOG%_U$kZNj)d4F;0om;`Zmb~W+sDn^exE}k*H1tKQ)#q zOEOeBSsMI7lbfUcEIlzZQ-%s#(_a}W85snaeH+ClcJf9d99v|Kn0^;8I=Qe32P4sf z_K@akNk~|9G}%G6l=j3W&pd_05weh$Od9bZ6hZ@$0sl?BNQlvQg17@oXge_mFM(sI zcbwaztE8|cmC(k9K?7}dcdr9c)Y1B;`ue-qQU3%R>YCt+q1{8Bo%A;X63s**_!F-A zfMgyXB}En&pkBWI?CQ@yznZ!jY^08WBTxU~4^(xF@6!eYZGP!@HlIFy)fZnJr5}Ft z>8Jki2Lt_V5-|c-!WOpb1R6YXltBhp{`B+D=cE5X&(A;q^wYk5=hK#iAYcqBV7+&& zg5GER_~pr81GdRm+4Fv%BQz(COB>{hdrK;Koz!Mb?Ez_ z;BibJu6Y%XtmW&d*43`P@HiC%zHq;~e?RS=%x*!k|0M01>F45+U+>o2Hs{F?8}g&p z(z>ccy**0o$JKgJKacL+kNzmaVC%T(fsV>O*N^*)t2=$>!|jtO4h2gp>_$m7l{Nfp}uAw37e$OxT`xBs(xSUKTpn#5#0QWl@jn#Ae zXbCtwzKKoqc|FCG<>mOPua!GhCP^Ow>8C&zek#(dH$DC+n(O%@9B_O3_e6(m581c} ziPxJVeO~&TjjFjfo3rr`EL|k&3Zyluv~&rnK!`m&QXoVUC;mSmrx8B@cmb7@%W9KB z6vzKxFXBP1ii(>e-=b(+Y;HETjSy3m)|kXpTU@zG(_F;d$gSiJ#FZ@z>(Iq7I+DgoLMv44!km#v#P0n2fl({ z2z*r!qpyKYAM`EoHRXt$bt8(Gz6V~@?(&zww}?W2-PUzI2z*CBqF;KahFY4aqnd^~ zQC|bbNA)yPtP1W0(L`N6Q9@~@7|&GHnT}M27AtlZD%u(|2Ix5@8RWQEV;^gV(@>N8 ziR(j@gzCgyz46={YOE4_M-6CGFWINWcxo|+HvMhAhQmm`?$e!cnQUB&0dwrgn34H9%Iz1~y>v$W)`$SpWaCL*3 zV$FxnxZYzkXxoNQ%dg7)~(h#okA4;a90I{{dM{qqzV8cmZvg1$0`;_s6fiK%}X!blrWs zkv47DA*3M`2n&QRUFp(56SfJo1d_Dt?k>M|cXxMpcXxO9{m;yumo|I;Jty<|UYofy z@9}sA2+Y5KZ-yrLfBrd>0FaP@(ZMS8pckvL25Yen$6!5<#c?!jth7JQe?k zr{U>%2A+v$;n{c&o{Q(<`FH_dh!^3-cnMyLm*M4j1zw3);njEzUW?b^^>_o`h&SQQ zcnjW&x8d!02i}Qy;oW!--i!C){rCVrh!5ez_y|6VkKyC^1U`vR;nVmGK8w%c^Y{Y3 zh%e#G_zJ#?ui@+X2EK`J;oJBQzKieS`}hHVh#%p{_z8ZBpW)~D1%8QN;n(;Lev9AX z_xJ<;h(F=a_zV7uzv1ur2mXnF;otZV{!2heL`)7=6JTAwzc4QV6Vm^PtJX*1fKwxBI(Ds4p# z)JRR#Ow(vOwa^TjNwa8c+J?5J?Pz=2fp#Px`Kgrx)JC(Zor2UsA(}&Bicpj~DMmX{ zoD!6zE=ti{+L_Wck9MJ5X*b%P=F=XOp#{`US<2Bu>Y-lB)1I`5`lz1@RHVhUgi16( zWvb914bdbwT8$!qc2ybiC+>+$-$0dL3~@y5IfZ_1nT z=DY=O$y0eNZs104;%1)4)47Fb@Jyb?Tk|%&EpNx$^A5Zt``FK|9N;#d&FviI4i51g z4s(Q~+{rQCiQ}B$BzJL&=km^+=6Spe@5;OJ?mVCO;0!O|Zq9O!7jh5xa-R3(Mcl{z zT;L)v<|SO>0WNce2YHBxc_}aBy?Aflhxg_Ecz-^C59EXRU_OKo<-_=JK7xk8lj13Wvjk@D6+r z=fD;4GyDX;dscxlaPbQ;0bsZo`R?08TcF)!i(@6JP+4G4}1qF zz$@?)ybQhYC43D>z@CtYMbHm@P=NEG2uolwlwbfVP=-Mmf-hhgmcdfk3-*D%;WjuQ z_Je(4e>ecXf^Xms{vV&lr}G(nCZ7d=!#{jBp9B9Q@VR^*pO45F@P&L4U(A>ArFd>h}+ckrEj7vIhI@V$H=-wz+a zhx`CP$Pe+u{0KkFkMZOD1V717@zZb}T+h$&v-})C&oA(c{1U&+ukfqz5q!+A@$38s zzsYa$+x!l{%kS~~`~iQ+AMwZh34h9;@#p*ne+hT;SNt`9!{5Ru@F`rv-|_eS1OLcB z@z4AVyaw;{uka?k1#iQ9@H)H;XYz0SJO9Cd@?ZQn|HJ<};Gjbe!wqmF+yb}4LvRz^ z3=hMB@BkbJSHdH358MlPIgV51cpNVr?NmE8aGFyKXTa(3tyAZWfs5fpI14U?Iz_3fexF{VzeCH8 z4lTR1>@wqE++)VLF~Y_Ohjmh$DK+_>Mt0R|uS~0@T|p(x@l~lIsF!KivOTEBXuEc_ zYT0UHAuU4^OY1S2^m+7XT!DZx)F|<&E=ZarQyVZTMw(De+c9JNwe%Yq(L-7faXp0f zkka8q(2NP~FoUtfVV_quK41A2L-VDpIm14W-p;VuiWx)0(%Z1kQ!N@ZCK>TzAFFgn zm#`{u^!^>aePy-k6VUFE-oJ6D9ld3YiB9bpYf^&D~rk*wZObwsi@}aEadd=hKgP_ z_Lg!v6`EbFlr-{#I+n-}d)1g5%oP;d@;$v}6^!N!IY*WEPgKh+SWwCh<}>Adu`rPD zDO6=uKbg90v9h2qXLMDmvN)HkQw`=b1*0b}Q|k}qv*q4Gv9M=R%~l#W;u3pIwpcFb zvfcSocb{%6o?G0jKR-)zeVKvYdgV|kmoj=ub8vBUg9H_o*)C>#P#A3&cdMAKHY+4% z$jwR%lS##DO&bUVv_sR)jLHN_TVUr4*mP^!q?mYP*6SD3Z_S7xEeH!zl9LEpCd6%F zz2UIk^RRTMZWOy~%a9GkOrXjfl1I)+8SToD6Y|Ib=?}j#S|uT5jF3%8E6CA!HN>kA z#;akIqNXq@sWMAI62*{s%(!CW@*Bf1M#PM1GltEWGT}r}kT5>~FCeh>G0Bqq zK#QQXp+$`q!*&h7ltio<5i>0a3sN#)O1b5ksHf3PsQfxtsi^B+u2M2X!aDR;tqKIx ztm5<4iqH*@$gtdE`pCRSB*meRMI2Gfh#QDlN7{9yts`X}u8+FT*C+(V z42c<3nBuk9Cq7~sr4>}5uv0-(`uX5!k~48tV1qeGATEf2%V!$OS?rCzypNV0Xk2&s=oWqlDramkb-Tvt?YP>YCVS}0d7DbEW9 z<+mbkh03TAA#Wr~1+B+E*pu=JQE;o}F`-3J5~AW)%ZeQnTYv7X2unfC7DU7!aSQCk zan}wDQi6m;6S9sLX;(-i`T`5nLa7X>4_&o^Jh7Aria#J`z?xBkU$Xsfw%>*$g0vuI zf_ljsp$dp6B6MwOA}WU;)h8^r{%mOkg~_B)?s8>Ix*UoTaaSa4g}OpQmE$VASU_?E zZjtn>g)K7uxhn1|w>&CUYENRv#Fj_C7HSru>+y?6o!@E|L z&a4(`bIl>ebV{{QUlT2?t@E^q3SyETvsn>=%?S%qf`omU3HfR?%|ohMD|1CexNjY< zBWf9wfL^CoGSr`qr7goYClM53zX|;E==aNVno^-eP~u5JK)m|833cOIMFoC|%lT`% zuVrb0USGqtQ<9&st0atRws{y-NxLf~Y_rgogVL=oeczAwq7Gh_tCG zD~XD`%3UKONDIP(l*}NFD+-L2mOj#|V$8@p^(aH~!txtS~D^x)$$D^%55fMLlHOGrSz?sFsGQ1qmiyf$epG{P!d97 z%1;K0lBRcLMcfrqD0hRQ$}u$oK~xZve0iE`VHffXA`*_c#TH>fN|4Z{L3wf16hs7R zL0DkA3Ww!X)$cGWbiVsP@3GlIS5D3JchpK)%Sod$C0wt6Fj}#;e+9Ev zOkFfdf$yux}wPy&90c{is`Osam5T*%yh*pD;gVI(dddMS2Vj~nk%NeqQw<6TrtxX?#xXM zu4r^clPj8CG0j^kGs4=| zY_Xi_?#>m;wcR7q6X?$9(ySn$=E;=3ZFb_E(9!yo7HL=@OIc0^Fr}Aw^+{bgfrcha?aCd zV7-3JR!>;^>oah|swt;W4W6h}6;`O4Hr=wt6P2ohfw$9kRutN-Hp|)doxPPpPo`Aq z@5@xm^~Dt}Ph8e1t+3AY7Rwo)xU5qWBqVoW#oRW_*}|44%Vtkfipqj6In#=qX_won zrjE*$tr%2wmGXt2s)`=#yGHe1S<&)#xhF2Ho2!4;tMo7I%MI5Jt)SB@=%vfGXP)e5 znL+Km<@d(2|J)n1TP*{IO^q`xXIc6z{X&1MuyvMaZcizrb~YrKD=Q8e)XdH1bEVus zexPQ^Rl2URP1Oqnp0pG$H4yLYnU=Ghwo0j}jiv^_&oW@x*w`#=YN^Q$l-0dk&Sj0K zsi8&KINfqqU2eF$FVjDDV4$I~w!7HhpE0s-ajujvW?gq*v0&ubfn0xnxmmxYq8G5% zIGHM291?qy%%P7`ZBXW#;8u)e)n)U8`E1VUiJ8U4fpV$1xHs2t7azN%QY`2Catq6{ zhA~U}M`M}K*x3brBN-E2&+?@DTwh;)u{vR6{U7p&9A*Fj00962|Nj6FcmZQzWME+6 zVSoT81`Y-Z26+Z%1|=Y5W~gMS0+O{r$jmSa2$`8;nBswCI#UjiEM_WZUQpF5S zy`(XPh%qoWDxzXUid@3Qa51JdA|lm@l13WQIYmqnQ$1gIpC&Wu$h3cVcD`Ts+uiqh z_kBZ_bBKv3l}6Aa(qY3#PM}UXGxGXTrg0kerNFWjMI`n^+q^LaZQg`p6i%C-H=BC2 z<@DTnv#EDm5Sr)^VsYrPz~3y@*J9iv7{&`J7|n&@j5Rt`CxyYnU7i~I2){s|A}5qv$5PmbGD&Wddn8Zh$$VKL_u8!z4YgPFW+@Nj4wg!~7Dj;v-tm8+eUJ z@V=)_ewF3Ey9O(GGw*0yi)e${aX!JP?4G{SR1ry$v!#=qtK+m%EA4iANH6IpSIQ6> zrj53Cj7*elv*|KZ=E&WeFAHUf*)l1RLRn$= z?JXzev?MjqL7HmTK|AaD=4Wb8?XCUI8>+)~r1db#Y^vtyEWJA{Jm?uhuaWdH8l$V{sL*Q=^U!;Gq_$N-C@8lh* z>;WzSyMbSWQ^6Tn`!4t%_$hc2*)7gkJM6Lvk^AAl3!*Ys>I}DmyPfUgPOU`EX!zfP zA0cucSnT8v!6V=@umF4qtObvON1^Z~_zD!#;XjKW9*4gi@hhBi0aoFbvO0&q1nr#Qp)h>U|yfA|AI#Pt;Xx8XkzP6T7%zt#G{{{;L7k-^|jr(6$0 zUoxD$3p@<|74aL4ZD)ID;}9BWRJmEE$}J=mQg@rgWV3g(&Hketqj4PP3Yy0o_*=e+ zBbm&zNr^Ct@Ys5i27WW>sGD@1mbCnJRJfTB3(_pRE=boBW5*!f-YQyZ*SYVH`B>AU zgSEDz=sUWb+Ui0v-Q#U_TU9OZswJ*~pS5O(?5PV#>+HQ+o9w9%GVHw!S(wG_Z#&2^ zT7`L}O+ly$dv9v7IJW>!-jkQv^rs@dPPN}GKa*t&9y7@?3bHo~(yZM4U7csD&G zv`oL=)XDN*YkHn{Ra;Nyg>G2kw-B}x*4+ALtE;esDPo5zZNig)Qi)=JbXjRuW>3O= z#I(x%a`aE=Al)ntH(u+$*7|*#*K#hbGG+6t%uL7L>+P)`ie}JD;O6Ts2SdIbw~JF^ zZdU0g+odYVKo^zh(mZ?Wu)5l;<#&bOkQr{H9QRdePZ|12xTbkc?&Hi>g`2c&K)yfv zw2XC1z8?9O-yTk7|8CG#b?a{ys`l^0JBHaCaz=}hJ>EAe{Uq3>!m7|u%MKN;kL)3P z{IrMc@m?xn&A2nG!0IOauhNLT-5>4@{lgO2v$gMz=qU|<3mL?`Q)=-4#GAyi64^!^ z4wfwzSta|72V^g?UM+i!d9vI1qEuOBFWF8UoRS?@AD68bsm0oRWV6*Y$Qza&E4wW6 zg1m12d5CQH`XFC+T1`9Gls-~T%wNe{rZ8P9+fE-{VeCwO@d-AaF0f2U6s$et^Jwfe zU&uZ1Iqpgx5@v=yc^F^EV|XHG^K_ocbNFsv$V+$`7jPl3uzV>$!)wE#;qY)Iujh^7 zq;P7O6Xx(%-o^WPKOYR2^85U8SQM7|WJ*uz z9Z!?~GAN!dL*w0Lc)V{s%bo!;GJaM3+V}_=CzE7q{8q_{-xkk}=gKT8m${M`e^Bm| zrSW3Pmq+4jq)1BQ8>Gx~>*6(1A)BO9s^Z6`I(|ZG<&e}#y)>qDl7xoRB+W`1ru5S^ z?WpM~!!$#?r%X)A)-3ItGBah44$!Momgu!Qf|wUZg~o%?W@BNr$M{H8W1Js7Zd@Pv zr;Dx85%cq+LFS*1zB2ZRR(MVFu-7C%w@A0>9mJ19vo|zvgyu|W&VXibXkKHL>Cs=H zd=ZqpLb=F4b+~eHmv<5zcg(D6c)Ff<*?NhA#xMA8{Fd59Ng^{&Y&;qFGW|Up+CyI3M#P66x_xn zbo(Ca$D_jo@CV}d($HZAblygGUsU0r5d2(vj>nBNjb}$S;4N0!2iY>L+Ucu!b<%d^ zonWc4?Pq|F7VFPLiOue}=g~8KQ~QtaY5(n8+5hFYu&yoN!!G_G-^6b8?_$K5Qyi7r z&qsNB+o^=fgQ;Y3pG$>jnoNwj1@#!N&Ww>>N zStB_z%O{MPO&FgqW+hT&PnlrCw9Xf)HnZtsR;O7$VI(1#E@q)(y7+AIx#Ba$CyI{J z31*Y^R=rJg^-i6yi_D7kL0zto+0RvGYxFsNNjK_+68(PC)c>zcloOhtT#GuF--8JQMK&A1-#*S@H*~U~&;!aR(ZkP3jTKn68p`AGyBLeJ{~2qq$4RT<4}?w(XL$i? z)yVFPnte**q^TA+MthCLNsq^|V?3%f7C@m7Dodb{iQNYy{<^F2%II>-c8+G5|GN8J z9QFSfB|QDCcmai(4|tAc`^UfE^M3Z%%*>kEZ06YvGcz+YVrCY@nk6kQ39U7M5;G&o z+w1lAdV9TIuaG1p$-kB)Ns=T$v+JN59|k9Q$6M>$$G; zyw3Cbci+b|5I{I)b03_dekDT@Q+az`Hgb)Q!Z7#%;K~(50B{hDFhflcjjIrc1SBHa z(}RXX5RS%(LNmmo1zI8rtvx*iK?p@7M4~BT&>Zn-1wT@dI%;&?WE}g0j;o%4FFg9~ z=5o6s5VoDwuGaR z)}mE?s*Y-mY8X1B5+@nQ9vtc{a5g&!g64$y!_UMOCnYD%OIn?Dpw-q^my<^%A85VF zFaDPPbbp?|pMR)-w11+1rhl$~sei41tACIGkiWry#(y~_JS8qAEhQ(VFr_S|GG%7U z+?18>xS=4bjK(4v>BvDoiZKMkLHG;_W-1M^G|}gNHYI_$d$9d-!P&Z}RXn9^UNXXFa^d!_RqmtB0TW@HP*> z;Nk5qi{VuC0?-@RARfgSgw`lEpEh>)=pQ0M5cjI}LWp-Sw`$PRZSn3qu0}d4P>Bhc zmY9lJn2W_&iS>z@iFt{Ii6thVo!FOHjzjnuCvg^+=wl?~lJe>AhHm zi3!^<9kVeHORy?ocfx^$BMA-Ih^^R_a2oq@7{_r6=Wv<9jAA@fnaMmBCY)yp%Q=!` zSxdbc@uD4lhozS+?X=~GJ$N&;dLwga#$<19uAmSZh8V+Zz{=#SwGoWVs3 zBN)qMrZb26EangnXB8)MI%jhpmv9v~aw~UnKM(UbPw^ZtORz*qyrfE|xagv;NPPWt2>F1O=6;7oy!I|dFa^|{E z2Ejt5#g-njw8YZGmX=z2#L_ZLk6K!8X@#YgmL9XT%F^SOR$F?)(i%%oT3Tyqou&1b zHdxwd=_yO~mY%k>$f zmUdfu)zThIuUXn_>2*u{EWKfAzoj=V9kBG4rGu8@}a4UM@TP+Llt0~8$7X^;#kx56(Ec&$U!XPcz z;WK@zd~UQ2zA)MzUmERzlSVV~mC8b+p1kV z?b}{wBp8vf*)jtT%8gZeV7}SGXgWKpO{Us(QX9g@ETtw$Hg;LaMNbr>7^N7B3XDV* z#-j$)mpIY zYP7%2s!01@qrLiRTt0+DSCRcSlVZ(efQ~y**UI+bAdR5JXeVB)W0VHQu-*r2OPRJ@ zr!Cf&Lp1K|jdtcx?QsLVw&mJ#qqYpwmQX|^4oOHwI&|K6la61Zqui|ihO5;ry6Ph| zt6SB>Nc9l!?yypnV+5)&0d<&(`!N>_umsDo8tbtMTd@PXu@47v7{}1S(Qr^^d{k;# zz%kHM$+21%@J@FZPBf)CwVZ6qYE!>kPh&Su*RmJy(XxP}bS10wY*g#IjWe3V@wyfh zjOKBY(eA9#3~DulI^CI5bq%K(?aSMZ_Tz0v7x50Gi+PvPb#?}4sK0yFdZy+dfp{b% z4H?Kr9`aFyfha>chVw6aa{j6(XO`}wzv*e2tv>#)d+8r~TIOg>|5UFJXf*d3eTerP z-GCrOAO<=L=eqOqFZJNv~iE2#5G~9}-2>a7`=_y6iT_2onEIz6mqUp`{Wk*2;(%L1-2 zZgJOjzOLs2JuMIFX<4ZIa*^)H#k#^v zb%h_*nO&(fyIN;ujjr}uUG4Qczfb8rJ+1S!N$2+&UG3+L7IBHu)m(0L4Oba`l2004 z$8|>6>-xHPFM6N=_AccM?p$ou$ez~|vrQx0u5rAmaqQ4IUeXA5Y6LIquG^(?yrTDE z7-IhSF5+&z9rmd2*VOCl>UE!beM7yzss0YAzqh=1zIPvDG^#NHwV00kpy!hBy7%A_ zcXd87rFW1rWtf6}NgXw*Mz)E9M6oYo!iozV?Es~HG_5y4;7^Ci926Exal zlzC(Q|KCXXJM`|8FzDHlX3*J}tMpAIi@)jKzhbnFz-XG#Xa{kOW{S^fCkZl|CBa5J zOGqGd2{oD{;eq@mB9OT>Hribx1NlpnK>iXH$X}WUqL=7E{t^?&Ut$B9OY=bHB1Q*E zBcp5d=5e175*Nr^TBvQj+9s%N%YfCN--40|G1je&wwGk1>C#&B@N3j5>NQp4YNNi> z)OTC;-OgwqNitgO*&oG!vaj`dBN=c|VfOODQ6uFhRIjjOxH)k7n?+GwGq8(kzFjjoW+MpsH#eM-b38$D2nff(X_@4!sV z#sip-#aM<_Sc`gW!FKGzUde|(|D-SUE|F`rERg>0-Wcpg+f$?Mt$U(CcS9eIyijMc zpRRqeuKfU=(Se#piDq%F?toIwrA%|VPUm=tW^}!-eJ{HpCd>zOLKL#SlPl3qs zv)Z1}U2xuL=^rf^rYAo_&vvAa5T&O&T2FPeKz{D&E!5T=qk}v*(q6ScsHgu`y|eb~ zD4IoJ6#fba^NrXeZ;UJc#MoZM(B#}D8(AA=U;dq|IYjQfZXKvt+svRj7B0AU67~G&q5Sq z5!PV?Hes_2m0_+$uC-`kGzx9e9_h$MFD$`QJc8AD67|@M?Ks71{?oOBwTd?yfi&cx z8+xKQ2I3(+fv4~^w&}V73_E0dCm4-E2V|flu0|j9#Wm=M{uqR1`a9G{JcH-(0_R98 zY3o|s{L#{A7_#v=p5)4$@IF-M$63 zZ<5haPT*af#2q{=Inq^f-CpswS1Y4U8OI8a;%%JDgo1u9;iFv672L`9_&$&FIKPtC(p~yUvFl-__0ZaAIee1;SF0%!39&f!O#XDGv%#m>xQ0k7cz4&-e9gZuaf_e+RG zN>eF-dJ5idJ*DYs{TkokCtPA^8nxCK^}2?`)%*`dXm1xR}5hS z@8RRz%-wvISM-SqFzABqn{Ko*K4(1dah*G_1QlXg1g}$ zH1J%N+YBwh-7*SdbhOb0wrz~tc89iA!`n9AZ5yj?5N(&Hb%GrfTc7K&#xNErbtU zk&iwo^2DhtjS3qj;YTXE>+fHSus-n2)Vtx7doN_`vtttH>pi_Aa3AnDX{sP{?Dhv(#@8JTe`*4 zC`)54O|Wc;uB@1PRJSI;`y=;~roiL}VGr-y7eBvB;8l2CZld!YK z`S$_2EnlX2YFTo(r{XU)PP@}N-~jzzxL_R3pc+bajv*7nf;p>i`C%PlfOZk0;8U8=ODIr5?B XS@abA4~6J3O#lD@0000100000&qPNf literal 0 HcmV?d00001 diff --git a/app/wwwroot/fonts/Poppins-MediumItalic.woff b/app/wwwroot/fonts/Poppins-MediumItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..d8101a7dd159ba7e91d4080bc68435c0b0fbe1ef GIT binary patch literal 74920 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