2 lines
112 KiB
Plaintext
Executable File
2 lines
112 KiB
Plaintext
Executable File
javascript:javascript:(function(){ if(window.__KANTINE_LOADED){alert('Kantine Wrapper already loaded!');return;} var s=document.createElement('style');s.textContent=':root { /* Premium Slate/Gray-Blue Palette - Light Mode */ --bg-body: #f1f5f9; /* Slate 100 */ --bg-card: #ffffff; --text-primary: #334155; /* Slate 700 */ --text-secondary: #64748b; --accent-color: #2563eb; /* Blue 600 – visible accent, distinguishable from text */ --border-color: #cbd5e1; /* Slate 300 */ --banner-bg: #e2e8f0; --banner-text: #1e293b; --success-color: #059669; --error-color: #dc2626; --card-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.05); /* Reduced opacity for visible glassmorphism blur effect */ --header-bg: rgba(255, 255, 255, 0.72); --header-border: 1px solid rgba(203, 213, 225, 0.6); } [data-theme="dark"] { /* Premium Slate/Gray-Blue Palette - Dark Mode */ --bg-body: #1e293b; /* Deep Slate Gray (Requested) */ --bg-card: #283548; /* Darker than Slate 700 → more layer contrast vs bg-body */ --text-primary: #f8fafc; /* Slate 50 */ --text-secondary: #cbd5e1; /* Slate 300 */ --accent-color: #60a5fa; /* Blue 400 */ --border-color: #526377; /* Slightly lighter → visible border on darker card bg */ --banner-bg: #475569; --banner-text: #e2e8f0; /* Reduced opacity for visible glassmorphism blur effect */ --header-bg: rgba(30, 41, 59, 0.72); --header-border: 1px solid rgba(71, 85, 105, 0.6); --card-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.4); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: \'Inter\', system-ui, -apple-system, sans-serif; background-color: var(--bg-body); color: var(--text-primary); transition: background-color 0.3s ease, color 0.3s ease; line-height: 1.5; -webkit-font-smoothing: antialiased; } /* Fix scrolling bug: Reset html/body styles from host page */ /* IMPORTANT: html must NOT have overflow set, or it creates a scroll container that breaks position: sticky */ html { height: auto !important; min-height: 100% !important; overflow: visible !important; position: static !important; margin: 0 !important; padding: 0 !important; } body { height: auto !important; min-height: 100% !important; overflow-x: clip !important; /* clip prevents horizontal overflow without breaking sticky */ overflow-y: visible !important; position: static !important; margin: 0 !important; padding: 0 !important; } /* Header */ .app-header { flex-shrink: 0; z-index: 100; backdrop-filter: blur(12px); background-color: var(--header-bg); border-bottom: var(--header-border); padding: 1rem 0; } .header-content { width: 100%; /* Full width */ padding: 0 2rem; /* Comfortable padding */ display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; } .brand { display: flex; align-items: center; gap: 0.75rem; } .brand-text { display: flex; flex-direction: column; } .brand h1 { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: 0; } .subtitle { font-size: 0.85rem; color: var(--text-secondary); font-weight: 400; margin-left: 2px; } .logo-icon { font-size: 1.5rem; color: var(--accent-color); } /* Controls */ .controls { display: flex; align-items: center; gap: 1.5rem; justify-self: end; } /* Header Week Info (centered) */ .header-week-info { text-align: center; line-height: 1.3; } .header-center-wrapper { display: flex; flex-direction: row; align-items: center; gap: 1.5rem; justify-content: center; } .header-week-title { font-size: 1.1rem; font-weight: 600; color: var(--text-primary); } .header-week-subtitle { font-size: 0.85rem; color: var(--text-secondary); } /* Language Toggle (FR-100) */ .lang-toggle { display: inline-flex; gap: 0; border-radius: 6px; overflow: hidden; border: 1px solid var(--border-color); background: var(--bg-card); } .lang-btn { padding: 3px 10px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.03em; background: transparent; color: var(--text-secondary); border: none; cursor: pointer; transition: all 0.2s; } .lang-btn:hover { color: var(--text-primary); background: rgba(100, 116, 139, 0.1); } .lang-btn.active { background: var(--accent-color); color: white; } .nav-group { display: flex; background-color: var(--bg-card); border: 1px solid var(--border-color); padding: 0.25rem; border-radius: 8px; } .nav-btn { background: none; border: none; padding: 0.5rem 1rem; font-size: 0.875rem; font-weight: 500; color: var(--text-secondary); cursor: pointer; border-radius: 6px; transition: all 0.2s; display: flex; align-items: center; gap: 0.5rem; } .nav-btn:hover { color: var(--text-primary); background-color: rgba(100, 116, 139, 0.1); } .nav-btn.active { background-color: var(--accent-color); color: white; } /* Notification state for Next Week */ .nav-btn.new-week-available { animation: goldPulse 2s infinite; border-color: #f59e0b; color: var(--accent-color); } .nav-btn.new-week-available.active { color: white; } @keyframes goldPulse { 0% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.7); } 70% { box-shadow: 0 0 0 10px rgba(245, 158, 11, 0); } 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); } } /* Badge for nav buttons (day count indicator) */ .nav-badge { background-color: var(--error-color); color: white; font-size: 0.75rem; font-weight: 600; padding: 0 6px; border-radius: 10px; min-width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; margin-left: 8px; gap: 3px; line-height: 1; } .nav-badge .orderable { color: #fff; font-weight: 800; } .nav-badge .separator { opacity: 0.6; font-weight: 400; } .nav-badge .total { opacity: 0.8; font-weight: 400; } .nav-btn.active .nav-badge { background: rgba(255, 255, 255, 0.3); } /* Primary style for Login Button to match header */ #btn-login-open { background-color: var(--accent-color); color: white; padding: 0.5rem 1.25rem; border-radius: 8px; font-weight: 600; letter-spacing: 0.025em; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } #btn-login-open:hover { background-color: #334155; /* Slightly lighter than slate-900 */ transform: translateY(-1px); box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } /* User Badge Button (Login) */ .user-badge-btn { display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 20px; font-size: 0.9rem; font-weight: 500; color: var(--text-primary); cursor: pointer; transition: all 0.2s; } .user-badge-btn:hover { background: rgba(100, 116, 139, 0.1); border-color: var(--accent-color); } .user-badge-btn .material-icons-round { font-size: 1.25rem; color: var(--accent-color); } .icon-btn { background: none; border: none; color: var(--text-primary); cursor: pointer; padding: 0.5rem; border-radius: 50%; transition: background-color 0.2s; display: flex; align-items: center; justify-content: center; } .icon-btn:hover { background-color: rgba(100, 116, 139, 0.1); } /* Refresh button animation */ #btn-refresh.refreshing .material-icons-round, #alarm-bell.refreshing .material-icons-round { animation: rotate 1s linear infinite; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Progress Modal */ .progress-container { margin-bottom: 1.5rem; } .progress-bar { width: 100%; height: 8px; background-color: var(--border-color); border-radius: 4px; overflow: hidden; margin-bottom: 0.75rem; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--accent-color) 0%, #60a5fa 100%); width: 0%; transition: width 0.3s ease; border-radius: 4px; } .progress-percent { text-align: center; font-size: 1.5rem; font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem; } .progress-message { text-align: center; color: var(--text-secondary); font-size: 0.9rem; font-weight: 500; } /* Container - flex column, full width so child scrollbar is at edge */ .container { flex: 1; width: 100%; overflow: hidden; padding: 0 0 0 0; /* Only top padding, no horizontal so child fills width */ display: flex; flex-direction: column; } /* Add horizontal padding to direct children of container to maintain layout */ .container>*:not(.menu-grid) { padding-left: 2rem; padding-right: 2rem; } /* Banner */ .banner { background-color: var(--banner-bg); color: var(--banner-text); padding: 0.75rem 1rem; border-radius: 8px; display: flex; align-items: center; gap: 0.5rem; margin-bottom: 2rem; font-size: 0.875rem; font-weight: 500; border: 1px solid var(--border-color); max-width: fit-content; } /* User Badge */ .user-badge { display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--bg-card); /* Changed from --surface */ border: 1px solid var(--border-color); /* Changed from --border */ border-radius: 20px; font-size: 0.9rem; font-weight: 500; } /* Language Toggle */ .lang-toggle-dropdown { position: relative; display: flex; align-items: center; } #btn-lang-toggle { padding: 0; min-width: 42px; } .lang-dropdown-menu { position: absolute; top: calc(100% + 8px); right: 0; background: var(--bg-card); backdrop-filter: blur(12px); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); z-index: 1001; min-width: 120px; padding: 8px; display: flex; flex-direction: column; gap: 4px; animation: modalSlide 0.2s ease-out; } .lang-dropdown-menu .lang-btn { background: none; border: none; padding: 10px 14px; border-radius: 8px; color: var(--text-primary); font-size: 0.9rem; font-weight: 500; cursor: pointer; text-align: left; transition: all 0.2s; display: flex; align-items: center; gap: 8px; white-space: nowrap; } .lang-dropdown-menu .lang-btn:hover { background: rgba(59, 130, 246, 0.1); color: var(--accent-color); } .lang-dropdown-menu .lang-btn.active { background: rgba(59, 130, 246, 0.15); color: var(--accent-color); font-weight: 700; } .icon-btn-small { background: none; border: none; padding: 4px; cursor: pointer; color: var(--text-secondary); /* Changed from --text-muted */ display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: all 0.2s; } .icon-btn-small:hover { color: var(--error-color); /* Changed from --danger */ background: rgba(239, 68, 68, 0.1); } /* Modal */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 1000; transition: all 0.3s; } .modal.hidden { opacity: 0; pointer-events: none; } .modal-content { background: var(--bg-card); width: 90%; max-width: 400px; border-radius: 16px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); overflow: hidden; animation: modalSlide 0.3s ease-out; } /* History Modal specific */ .history-modal-content { max-width: 600px; max-height: 85vh; display: flex; flex-direction: column; } .history-modal-content .modal-body { overflow-y: auto; padding: 0; /* Padding is handled by inner elements */ } /* History Styles */ .history-year-group { margin-bottom: 16px; } .history-year-header { background: var(--bg-card); padding: 12px 20px; margin: 0; font-size: 1.2rem; font-weight: 700; color: var(--text-primary); border-bottom: 2px solid var(--border-color); position: sticky; top: 0; z-index: 12; } .history-month-group { border-bottom: 1px solid var(--border-color); } .history-month-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 20px; margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--text-primary); background: var(--bg-body); cursor: pointer; transition: background 0.2s; } .history-month-header:hover { background: var(--border-color); /* Slight hover effect */ } .history-month-summary { display: flex; align-items: center; gap: 12px; font-size: 0.95rem; color: var(--text-secondary); } .history-month-content { display: none; /* Collapsed by default */ background: var(--bg-card); } .history-month-group.open .history-month-content { display: block; /* Expanded when open class is present */ } .history-month-group.open .history-month-header .material-icons-round { transform: rotate(180deg); } .history-month-header .material-icons-round { transition: transform 0.3s; font-size: 20px; } .history-week-group { padding: 12px 20px; border-bottom: 1px dashed var(--border-color); } .history-week-group:last-child { border-bottom: none; } .history-week-header { display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 10px; } .history-week-summary { font-size: 0.85rem; font-weight: 500; background: rgba(100, 116, 139, 0.1); padding: 4px 10px; border-radius: 12px; } .history-items { display: flex; flex-direction: column; gap: 8px; } .history-item { display: grid; grid-template-columns: 50px 1fr auto; align-items: center; gap: 12px; padding: 10px 12px; background: var(--bg-body); border-radius: 8px; border: 1px solid var(--border-color); } .history-item-date { font-size: 0.85rem; color: var(--text-secondary); font-weight: 500; } .history-item-details { display: flex; flex-direction: column; gap: 4px; } .history-item-name { font-size: 0.95rem; font-weight: 500; color: var(--text-primary); } .history-item-price { font-weight: 600; color: var(--text-primary); } .history-item-status { font-size: 0.8rem; font-weight: 600; color: var(--text-primary); text-transform: uppercase; letter-spacing: 0.5px; } .history-item-cancelled { opacity: 0.5; filter: grayscale(1); } .history-item-price-cancelled { text-decoration: line-through; color: var(--text-secondary); } @keyframes modalSlide { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .modal-header { display: flex; align-items: center; justify-content: space-between; padding: 20px; border-bottom: 1px solid var(--border-color); } .modal-header h2 { margin: 0; font-size: 1.25rem; } .modal-body { padding: 20px; } #login-form { padding: 20px; } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 6px; font-weight: 500; font-size: 0.9rem; } .form-group input { width: 100%; padding: 10px 12px; border: 1px solid var(--border-color); /* Changed from --border */ border-radius: 8px; background: var(--bg-body); /* Changed from --bg */ color: var(--text-primary); /* Changed from --text */ font-family: inherit; transition: border-color 0.2s; } .form-group input:focus { outline: none; border-color: var(--accent-color); /* Changed from --primary */ } .help-text { display: block; margin-top: 4px; color: var(--text-secondary); /* Changed from --text-muted */ font-size: 0.75rem; } .error-msg { margin-bottom: 16px; padding: 10px; background: rgba(239, 68, 68, 0.1); color: var(--error-color); /* Changed from --danger */ border-radius: 8px; font-size: 0.85rem; text-align: center; } .modal-actions { margin-top: 24px; } .btn-primary.wide { width: 100%; justify-content: center; } .hidden { display: none !important; } /* Menu Grid Container */ .menu-grid { display: flex; flex-direction: column; flex: 1; overflow: hidden; gap: 1rem; } .week-section { margin-bottom: 2rem; } .week-header { margin-bottom: 1.5rem; border-bottom: 1px solid var(--border-color); padding-bottom: 1rem; text-align: center; } .week-title { font-size: 1.75rem; font-weight: 700; color: var(--text-primary); } .week-range { color: var(--text-secondary); font-size: 0.9rem; margin-top: 0.25rem; } /* Full-viewport layout: header + scrollable content + footer */ #kantine-wrapper { display: flex; flex-direction: column; height: 100vh; height: 100dvh; /* Dynamic viewport height for mobile browsers */ overflow: hidden; } .days-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 0.5rem; flex: 1; overflow-y: auto; /* This is the scroll container at the window edge */ align-content: start; padding: 0 2rem 2rem 2rem; } /* Card */ .menu-card { background-color: var(--bg-card); border-radius: 12px; border: 1px solid var(--border-color); box-shadow: var(--card-shadow); overflow: clip; /* Clips scrolling content behind sticky header */ transition: box-shadow 0.2s ease; display: flex; flex-direction: column; } /* Past Day Styling - Target specific elements so ordered items can remain visible AND preserve sticky context */ /* We MUST apply filter/opacity to children, not the parent .menu-card, or else position: sticky breaks */ /* Header keeps fully opaque background to hide scrolling items, only grayscales */ .menu-card.past-day .card-header { filter: grayscale(0.8); transition: filter 0.3s; } /* Items become semi-transparent */ .menu-card.past-day .menu-item:not(.ordered) { opacity: 0.6; filter: grayscale(0.8); transition: opacity 0.3s, filter 0.3s; } .menu-card.past-day:hover .card-header { filter: grayscale(0.4); } .menu-card.past-day:hover .menu-item:not(.ordered) { opacity: 0.8; filter: grayscale(0.4); } /* Past ordered items get no special frame or shadow, but remain visually distinct by staying fully opaque (via the :not(.ordered) selector above) */ .menu-item.today-ordered { border: 2px solid #8b5cf6; box-shadow: 0 0 30px rgba(139, 92, 246, 0.6); border-radius: 8px; padding: 1rem; margin: 0; display: flex; flex-direction: column; background: var(--bg-card); position: relative; z-index: 5; animation: pulse-glow-strong 3s infinite; } @keyframes pulse-glow-strong { 0% { box-shadow: 0 0 20px rgba(139, 92, 246, 0.4); } 50% { box-shadow: 0 0 40px rgba(139, 92, 246, 0.8); } 100% { box-shadow: 0 0 20px rgba(139, 92, 246, 0.4); } } .menu-card:hover { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); } .card-header { padding: 1rem 1.25rem; border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: baseline; background-color: var(--bg-card); /* Removed border-radius: 12px 12px 0 0; .menu-card\'s overflow: clip will round the corners initially. When sticky at the top, it will be square and perfectly hide scrolling content! */ /* Sticky within .container scroll area */ position: sticky; top: 0; z-index: 90; } .card-body { padding: 1.25rem; display: grid; grid-template-columns: 1fr; row-gap: 1.5rem; align-content: start; } .day-name { font-size: 1.125rem; font-weight: 600; } .day-date { font-size: 0.8rem; font-weight: 400; color: var(--text-secondary); opacity: 0.75; /* Visually subordinate to day-name */ } .empty-state { color: var(--text-secondary); font-style: italic; text-align: center; padding: 1rem; } /* Menu Items */ .menu-item { /* Spacing now handled by .card-body grid gap */ display: flex; flex-direction: column; /* Subtle separator between items */ border-bottom: 1px solid var(--border-color); padding-bottom: 0.25rem; } .menu-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .item-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.5rem; gap: 1rem; } .item-name { font-weight: 600; color: var(--text-primary); font-size: 0.95rem; /* Slightly smaller to reduce visual competition with day header */ } .item-price { font-weight: 700; color: var(--accent-color); white-space: nowrap; } .item-desc { font-size: 0.875rem; color: var(--text-secondary); line-height: 1.5; /* Consistent with body line-height */ margin-bottom: 0.75rem; white-space: pre-wrap; } .badges { display: flex; gap: 0.5rem; margin-left: auto; flex-wrap: wrap; } .item-status-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; flex-wrap: wrap; } .badge { display: inline-flex; align-items: center; justify-content: center; height: 24px; font-size: 0.75rem; padding: 0 10px; border-radius: 6px; /* Unified radius matching buttons and tag-badge-small */ font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; line-height: normal; white-space: nowrap; } .badge.available { background-color: rgba(16, 185, 129, 0.1); /* Emerald 500 / 10% */ color: var(--success-color); border: 1px solid rgba(16, 185, 129, 0.2); } .badge.sold-out { background-color: rgba(239, 68, 68, 0.1); /* Red 500 / 10% */ color: var(--error-color); border: 1px solid rgba(239, 68, 68, 0.2); } .badge.ordered { background-color: rgba(139, 92, 246, 0.1); /* Violet 500 / 10% */ color: #8b5cf6; border: 1px solid rgba(139, 92, 246, 0.2); gap: 4px; } .badge.ordered .material-icons-round { font-size: 1rem; } /* Loading */ .loading-state { text-align: center; padding: 4rem; color: var(--text-secondary); } .spinner { width: 40px; height: 40px; border: 3px solid var(--border-color); border-top-color: var(--accent-color); border-radius: 50%; margin: 0 auto 1rem; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Footer */ .app-footer { flex-shrink: 0; text-align: center; padding: 0.4rem 2rem; color: var(--text-secondary); font-size: 0.8rem; border-top: 1px solid var(--border-color); } /* === Order / Cancel Buttons (inline in status row) === */ .btn-order { display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; border: none; border-radius: 6px; background: var(--success-color); color: white; font-size: 0.75rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .btn-order .material-icons-round { font-size: 16px; } .btn-order:hover:not(:disabled) { filter: brightness(1.15); transform: translateY(-1px); } .btn-order:active:not(:disabled) { transform: scale(0.97); filter: brightness(0.95); } .btn-order:disabled { opacity: 0.5; cursor: not-allowed; } .btn-order.loading { pointer-events: none; opacity: 0.6; } .btn-order-compact { padding: 2px 4px; gap: 0; } .btn-order-compact .material-icons-round { font-size: 16px; } .btn-cancel { display: inline-flex; align-items: center; justify-content: center; padding: 4px 6px; border: none; border-radius: 6px; background: var(--error-color); color: white; font-size: 0.75rem; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .btn-cancel .material-icons-round { font-size: 16px; } .btn-cancel:hover:not(:disabled) { filter: brightness(1.15); transform: translateY(-1px); } .btn-cancel:active:not(:disabled) { transform: scale(0.97); filter: brightness(0.95); } .btn-cancel:disabled { opacity: 0.5; cursor: not-allowed; } /* Past days: hide action buttons */ .past-day .item-actions { display: none; } /* Order count badge (for multi-orders) */ .order-count-badge { display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, 0.3); color: white; font-size: 0.65rem; font-weight: 700; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; margin-left: 4px; line-height: 1; } /* === Toast Notifications === */ #toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 10000; display: flex; flex-direction: column; gap: 8px; pointer-events: none; } .toast { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 8px; font-size: 0.85rem; font-weight: 500; font-family: \'Inter\', sans-serif; color: white; backdrop-filter: blur(10px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); pointer-events: auto; transform: translateX(120%); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; } .toast.show { transform: translateX(0); opacity: 1; } .toast .material-icons-round { font-size: 18px; } .toast-success { background: rgba(5, 150, 105, 0.95); } .toast-error { background: rgba(220, 38, 38, 0.95); } .toast-info { background: rgba(59, 130, 246, 0.95); } /* === Mobile Responsiveness === */ /* 768px covers tablets (e.g. iPad Mini); 600px was too narrow-only */ @media (max-width: 768px) { .header-content { display: grid; /* Ensure grid is active, prevents flex-only fallback */ grid-template-columns: 1fr; gap: 1rem; padding: 0.75rem; } .week-nav { width: 100%; justify-content: center; } .nav-pills { width: 100%; justify-content: space-between; } .nav-btn { flex: 1; justify-content: center; padding: 0.5rem; font-size: 0.85rem; } .days-grid { display: grid; /* Explicit grid declaration to prevent flex-context override */ grid-template-columns: 1fr; } .main-content { padding: 1rem; } .week-title { font-size: 1.5rem; } /* Adjust toast position for mobile */ .toast-container { bottom: 1rem; right: 1rem; left: 1rem; /* Center on mobile */ width: auto; } .menu-card { margin-bottom: 1rem; } } /* Tighter layout for high column counts (e.g., 5-day landscape) */ @media (min-width: 1024px) { .card-body { padding: 1rem 0.75rem; } .item-header { gap: 0.5rem; } } /* === Accessibility: Respect prefers-reduced-motion === */ @media (prefers-reduced-motion: reduce) { /* Disable all decorative pulse/glow animations */ .menu-item.today-ordered, .menu-item.flagged-sold-out, .menu-item.flagged-available, .menu-item.highlight-glow, .nav-btn.new-week-available, .update-icon, #order-countdown.urgent { animation: none; } /* Keep functional animations (modal slide, spinner) */ .toast { transition: none; } } /* === Focus Visibility (A11y: Keyboard Navigation) === */ :focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; border-radius: 4px; } /* === Flagging & Notification Styles === */ .btn-flag { display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid var(--text-secondary); color: var(--text-secondary); border-radius: 6px; padding: 4px; cursor: pointer; transition: all 0.2s; margin-right: 0.5rem; width: 28px; height: 28px; } .btn-flag:hover { background: rgba(234, 179, 8, 0.1); /* Yellow-500 / 10% */ color: #eab308; border-color: #eab308; } .btn-flag.active { background: rgba(234, 179, 8, 0.1); color: #eab308; border-color: #eab308; } .btn-flag:active { transform: scale(0.97); } .btn-flag .material-icons-round { font-size: 1.1rem; } /* Flagged & Sold Out (Yellow Glow) */ .menu-item.flagged-sold-out { border: 1px solid #eab308; box-shadow: 0 0 10px rgba(234, 179, 8, 0.2); border-radius: 8px; padding: 1rem; margin: 0; display: flex; flex-direction: column; background: var(--bg-card); position: relative; z-index: 5; animation: yellow-pulse 3s infinite; } @keyframes yellow-pulse { 0% { box-shadow: 0 0 8px rgba(234, 179, 8, 0.2); } 50% { box-shadow: 0 0 16px rgba(234, 179, 8, 0.5); } 100% { box-shadow: 0 0 8px rgba(234, 179, 8, 0.2); } } /* Flagged & Available (Green Glow) */ .menu-item.flagged-available { border: 2px solid var(--success-color); box-shadow: 0 0 15px rgba(16, 185, 129, 0.3); border-radius: 8px; padding: 1rem; margin: 0; display: flex; flex-direction: column; background: var(--bg-card); position: relative; z-index: 5; animation: green-pulse 3s infinite; } @keyframes green-pulse { 0% { box-shadow: 0 0 10px rgba(16, 185, 129, 0.3); } 50% { box-shadow: 0 0 20px rgba(16, 185, 129, 0.6); } 100% { box-shadow: 0 0 10px rgba(16, 185, 129, 0.3); } } /* Day Header Badges */ .day-header-left { display: flex; align-items: center; gap: 0.75rem; } .menu-code-badge { font-size: 0.75rem; font-weight: 700; color: #8b5cf6; /* Violet 500 */ background-color: rgba(139, 92, 246, 0.15); border: 1px solid rgba(139, 92, 246, 0.3); padding: 2px 6px; border-radius: 6px; line-height: normal; display: inline-block; } /* Detailed Badge Colors */ .nav-badge.badge-violet { background-color: #8b5cf6; } .nav-badge.badge-green { background-color: var(--success-color); } .nav-badge.badge-red { background-color: var(--error-color); } .nav-badge.badge-blue { background-color: var(--accent-color); } /* Day Header Status Colors (User Request) */ .card-header.header-violet { background-color: var(--bg-card); background-image: linear-gradient(rgba(139, 92, 246, 0.15), rgba(139, 92, 246, 0.15)); border-bottom: 2px solid #8b5cf6; } .card-header.header-green { background-color: var(--bg-card); background-image: linear-gradient(rgba(16, 185, 129, 0.15), rgba(16, 185, 129, 0.15)); border-bottom: 2px solid var(--success-color); } .card-header.header-red { background-color: var(--bg-card); background-image: linear-gradient(rgba(239, 68, 68, 0.15), rgba(239, 68, 68, 0.15)); border-bottom: 2px solid var(--error-color); } .card-header.header-violet .day-name, .card-header.header-green .day-name, .card-header.header-red .day-name { font-weight: 700; color: var(--text-primary); /* Ensure text remains standard color */ } /* Update Icon */ .update-icon { display: inline-flex; align-items: center; justify-content: center; margin-left: 8px; background-color: rgba(16, 185, 129, 0.2); /* Green tint */ color: var(--success-color); border-radius: 50%; width: 24px; height: 24px; cursor: pointer; font-size: 14px; transition: all 0.2s; text-decoration: none; animation: pulse 2s infinite; } .update-icon:hover { background-color: var(--success-color); color: white; transform: scale(1.1); } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); } 70% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); } 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); } } /* Order Countdown */ #order-countdown { background: rgba(255, 255, 255, 0.1); padding: 0.25rem 0.75rem; border-radius: 99px; font-size: 0.85rem; display: flex; align-items: center; gap: 0.5rem; white-space: nowrap; border: 1px solid var(--border-color); } #order-countdown span { opacity: 0.7; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; } #order-countdown.urgent { background: rgba(239, 68, 68, 0.2); border-color: rgba(239, 68, 68, 0.5); color: #ef4444; animation: pulse-red 2s infinite; } @keyframes pulse-red { 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); } 70% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } } /* Smart Highlights (Blue Glow - matches today-ordered/flagged pattern) */ .menu-item.highlight-glow { border: 2px solid rgba(59, 130, 246, 0.7); box-shadow: 0 0 20px rgba(59, 130, 246, 0.4); border-radius: 8px; padding: 1rem; margin: 0; display: flex; flex-direction: column; background: var(--bg-card); position: relative; z-index: 5; animation: blue-pulse 3s infinite; } @keyframes blue-pulse { 0% { box-shadow: 0 0 15px rgba(59, 130, 246, 0.3); } 50% { box-shadow: 0 0 25px rgba(59, 130, 246, 0.6); } 100% { box-shadow: 0 0 15px rgba(59, 130, 246, 0.3); } } /* Nav Badge with Count */ .nav-badge.has-highlights { background-color: var(--bg-card); /* Neutral background */ color: var(--text-primary); border: 1px solid var(--border-color); padding: 2px 6px; } .nav-badge .highlight-count { color: #3b82f6; /* Blue 500 */ font-weight: 700; margin-left: 4px; } /* Tag Management Modal */ #tags-list { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; min-height: 50px; } /* Tag badges styled consistently with .badge (verfügbar/ausverkauft) */ .tag-badge { display: inline-flex; align-items: center; justify-content: center; height: 24px; font-size: 0.75rem; padding: 0 10px; border-radius: 4px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; line-height: normal; white-space: nowrap; background-color: rgba(59, 130, 246, 0.1); color: #3b82f6; border: 1px solid rgba(59, 130, 246, 0.2); gap: 4px; } .tag-remove { cursor: pointer; opacity: 0.7; font-size: 1.1em; line-height: 1; transition: all 0.2s; } .tag-remove:hover { opacity: 1; color: #ef4444; } .input-group { display: flex; gap: 0.5rem; } .input-group input { flex: 1; padding: 0.75rem; background: var(--bg-body); border: 1px solid var(--border-color); color: var(--text-primary); border-radius: 8px; font-family: inherit; } /* Add tag button - styled like .btn-order with nav-btn.active color */ #btn-add-tag { display: inline-flex; align-items: center; gap: 4px; padding: 0.5rem 1rem; border: none; border-radius: 6px; background: var(--accent-color); color: white; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; white-space: nowrap; } #btn-add-tag:hover { filter: brightness(1.15); transform: translateY(-1px); } .matched-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; /* Space between tags and title */ margin-top: -5px; /* Pull closer to header */ } .tag-badge-small { display: inline-flex; align-items: center; font-size: 0.7rem; padding: 2px 8px; border-radius: 6px; /* Unified with .badge and button border-radius */ background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } [data-theme="light"] .tag-badge-small { background: rgba(37, 99, 235, 0.1); color: #2563eb; border: 1px solid rgba(37, 99, 235, 0.2); } /* Installer Changelog */ .changelog-container ul { padding-left: 1.5rem; margin: 0.5rem 0; } .changelog-container li { margin-bottom: 0.4rem; line-height: 1.5; } .changelog-container h3 { margin-top: 1.5rem; margin-bottom: 0.5rem; font-size: 1.1em; color: var(--accent-color); } /* === Version Menu === */ .version-tag { cursor: pointer; transition: opacity 0.2s ease, text-decoration 0.2s ease; } .version-tag:hover { opacity: 1 !important; text-decoration: underline; } .version-list { list-style: none; padding: 0; margin: 0; } .version-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; border-radius: 8px; margin-bottom: 4px; transition: background 0.2s; } .version-item:hover { background: rgba(100, 116, 139, 0.08); } .version-item.current { background: rgba(2, 154, 168, 0.1); border: 1px solid rgba(2, 154, 168, 0.25); } [data-theme="dark"] .version-item:hover { background: rgba(255, 255, 255, 0.05); } [data-theme="dark"] .version-item.current { background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.25); } .version-info { display: flex; align-items: center; gap: 10px; } .badge-current { font-size: 0.75rem; font-weight: 600; color: var(--success-color); padding: 2px 8px; border-radius: 4px; background: rgba(5, 150, 105, 0.1); } .badge-new { font-size: 0.75rem; font-weight: 600; color: #029aa8; padding: 2px 8px; border-radius: 4px; background: rgba(2, 154, 168, 0.1); } [data-theme="dark"] .badge-new { color: #60a5fa; background: rgba(96, 165, 250, 0.12); } .install-link { font-size: 0.8rem; font-weight: 500; padding: 4px 12px; border-radius: 6px; background: rgba(2, 154, 168, 0.1); color: #029aa8; text-decoration: none; border: 1px solid rgba(2, 154, 168, 0.25); transition: all 0.2s; white-space: nowrap; } .install-link:hover { background: rgba(2, 154, 168, 0.2); border-color: rgba(2, 154, 168, 0.4); } [data-theme="dark"] .install-link { color: #60a5fa; background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.25); } [data-theme="dark"] .install-link:hover { background: rgba(96, 165, 250, 0.2); border-color: rgba(96, 165, 250, 0.4); } .dev-toggle { padding: 10px 14px; border-radius: 8px; background: rgba(100, 116, 139, 0.05); border: 1px solid var(--border-color); } .dev-toggle input[type="checkbox"] { accent-color: #029aa8; width: 16px; height: 16px; } [data-theme="dark"] .dev-toggle input[type="checkbox"] { accent-color: #60a5fa; } ';document.head.appendChild(s); // Inject JS logic var sc=document.createElement('script'); sc.textContent="(()=>{\"use strict\";var e={367(e,t,n){n.d(t,{A0:()=>v,Aq:()=>m,BM:()=>S,Et:()=>E,Gb:()=>u,H:()=>b,KG:()=>B,N4:()=>p,P0:()=>H,PQ:()=>y,VL:()=>D,Y1:()=>L,g8:()=>w,i_:()=>c,m9:()=>x,oL:()=>k,wH:()=>h});var a=n(901),o=n(413),s=n(521),i=n(672),r=n(842),l=n(646);let d=null;function c(){if(!a.gX)try{const e=localStorage.getItem(\"AkitaStores\");if(e){const t=JSON.parse(e);t.auth&&t.auth.token&&((0,a.O5)(t.auth.token),localStorage.setItem(s.LS.AUTH_TOKEN,t.auth.token),t.auth.user&&((0,a.lt)(t.auth.user.id||\"unknown\"),localStorage.setItem(s.LS.CURRENT_USER,t.auth.user.id||\"unknown\"),t.auth.user.firstName&&localStorage.setItem(s.LS.FIRST_NAME,t.auth.user.firstName),t.auth.user.lastName&&localStorage.setItem(s.LS.LAST_NAME,t.auth.user.lastName)))}}catch(e){console.warn(\"Failed to parse AkitaStores:\",e)}(0,a.O5)(localStorage.getItem(s.LS.AUTH_TOKEN)),(0,a.lt)(localStorage.getItem(s.LS.CURRENT_USER));const e=localStorage.getItem(s.LS.FIRST_NAME),t=document.getElementById(\"btn-login-open\"),n=document.getElementById(\"user-info\"),o=document.getElementById(\"user-id-display\");a.gX?(t.classList.add(\"hidden\"),n.classList.remove(\"hidden\"),o.textContent=e||(a.Ny?`User ${a.Ny}`:(0,l.t)(\"loggedIn\")),u()):(t.classList.remove(\"hidden\"),n.classList.add(\"hidden\"),o.textContent=\"\"),(0,r.OR)()}async function u(){if(a.gX)try{const e=await fetch(`${s.tE}/user/orders/?venue=${s.eW}&ordering=-created&limit=50`,{headers:(0,i.H)(a.gX)}),t=await e.json();if(e.ok){const e=new Map,n=t.results||[];for(const t of n){if(9===t.order_state)continue;const n=t.date.split(\"T\")[0];for(const a of t.items||[]){const o=`${n}_${a.article}`;e.has(o)||e.set(o,[]),e.get(o).push(t.id)}}(0,a.di)(e),(0,r.OR)(),(0,r.gJ)()}}catch(e){console.error(\"Error fetching orders:\",e)}}async function m(){const e=document.getElementById(\"history-loading\"),t=document.getElementById(\"history-content\"),n=document.getElementById(\"history-progress-fill\"),o=document.getElementById(\"history-progress-text\");let r=[];if(d)r=d;else{const e=localStorage.getItem(s.LS.HISTORY_CACHE);if(e)try{r=JSON.parse(e),d=r}catch(e){console.warn(\"History cache parse error\",e)}}if(r.length>0&&g(r),!a.gX)return;0===r.length&&(t.innerHTML=\"\",e.classList.remove(\"hidden\")),n.style.width=\"0%\",o.textContent=r.length>0?(0,l.t)(\"historyLoadingDelta\"):(0,l.t)(\"historyLoadingFull\"),r.length>0&&e.classList.remove(\"hidden\");let c=r.length>0?`${s.tE}/user/orders/?venue=${s.eW}&ordering=-created&limit=5`:`${s.tE}/user/orders/?venue=${s.eW}&ordering=-created&limit=50`,u=[],m=0,h=0===r.length,p=!1;try{for(;c&&!p;){const e=await fetch(c,{headers:(0,i.H)(a.gX)});if(!e.ok)throw new Error(`Fetch failed: ${e.status}`);const t=await e.json();t.count&&0===m&&(m=t.count);const s=t.results||[];for(const e of s){const t=r.findIndex(t=>t.id===e.id);if(!h&&-1!==t){const n=r[t];if(n.updated===e.updated&&n.order_state===e.order_state){p=!0;break}}u.push(e)}if(!p&&h)if(m>0){const e=Math.round(u.length/m*100);n.style.width=`${e}%`,o.textContent=`${(0,l.t)(\"historyLoadingItem\")} ${u.length} ${(0,l.t)(\"historyLoadingOf\")} ${m}...`}else o.textContent=`${(0,l.t)(\"historyLoadingItem\")} ${u.length}...`;else p||(o.textContent=`${u.length} ${(0,l.t)(\"historyLoadingNew\")}`);c=p?null:t.next}if(u.length>0){const e=new Map(r.map(e=>[e.id,e]));for(const t of u)e.set(t.id,t);const t=Array.from(e.values());t.sort((e,t)=>new Date(t.created)-new Date(e.created)),d=t;try{localStorage.setItem(s.LS.HISTORY_CACHE,JSON.stringify(t))}catch(e){console.warn(\"History cache write error\",e)}g(d)}}catch(e){console.error(\"Error in history sync:\",e),0===r.length?t.innerHTML=`<p style=\"color:var(--error-color);text-align:center;\">${(0,l.t)(\"historyLoadError\")}</p>`:H((0,l.t)(\"bgSyncFailed\"),\"error\")}finally{e.classList.add(\"hidden\")}}function g(e){const t=document.getElementById(\"history-content\");if(!e||0===e.length)return void(t.innerHTML=`<p style=\"text-align:center;color:var(--text-secondary);padding:20px;\">${(0,l.t)(\"noOrders\")}</p>`);const n={};e.forEach(e=>{const t=new Date(e.date),s=t.getFullYear(),i=t.getMonth(),r=`${s}-${i.toString().padStart(2,\"0\")}`,l=\"en\"===a.Kl?\"en-US\":\"de-AT\",d=t.toLocaleString(l,{month:\"long\"}),c=(0,o.sn)(t);n[s]||(n[s]={year:s,months:{}}),n[s].months[r]||(n[s].months[r]={name:d,year:s,monthIndex:i,count:0,total:0,weeks:{}}),n[s].months[r].weeks[c]||(n[s].months[r].weeks[c]={label:\"en\"===a.Kl?`CW ${c}`:`KW ${c}`,items:[],count:0,total:0});(e.items||[]).forEach(t=>{const a=parseFloat(t.price||e.total||0);n[s].months[r].weeks[c].items.push({date:e.date,name:t.name||\"Men\u00fc\",price:a,state:e.order_state}),9!==e.order_state&&(n[s].months[r].weeks[c].count++,n[s].months[r].weeks[c].total+=a,n[s].months[r].count++,n[s].months[r].total+=a)})}),t.innerHTML=\"\";Object.keys(n).sort((e,t)=>t-e).forEach(e=>{const o=n[e],s=document.createElement(\"div\");s.className=\"history-year-group\";const i=document.createElement(\"h2\");i.className=\"history-year-header\",i.textContent=o.year,s.appendChild(i);Object.keys(o.months).sort((e,t)=>t.localeCompare(e)).forEach(e=>{const t=o.months[e],n=document.createElement(\"div\");n.className=\"history-month-group\";const i=document.createElement(\"div\");i.className=\"history-month-header\",i.setAttribute(\"tabindex\",\"0\"),i.setAttribute(\"role\",\"button\"),i.setAttribute(\"aria-expanded\",\"false\"),i.setAttribute(\"title\",(0,l.t)(\"historyMonthToggle\"));const r=document.createElement(\"div\");r.style.display=\"flex\",r.style.flexDirection=\"column\",r.style.gap=\"4px\";const d=document.createElement(\"span\");d.textContent=t.name,r.appendChild(d);const c=document.createElement(\"div\");c.className=\"history-month-summary\";const u=document.createElement(\"span\");u.innerHTML=`${t.count} ${(0,l.t)(\"orders\")} • <strong>\u20ac${t.total.toFixed(2)}</strong>`,c.appendChild(u),r.appendChild(c),i.appendChild(r);const m=document.createElement(\"span\");m.className=\"material-icons-round\",m.textContent=\"expand_more\",i.appendChild(m),i.addEventListener(\"click\",()=>{const e=i.parentElement;e.classList.contains(\"open\")?(e.classList.remove(\"open\"),i.setAttribute(\"aria-expanded\",\"false\")):(e.classList.add(\"open\"),i.setAttribute(\"aria-expanded\",\"true\"))}),n.appendChild(i);const g=document.createElement(\"div\");g.className=\"history-month-content\";Object.keys(t.weeks).sort((e,t)=>parseInt(t)-parseInt(e)).forEach(e=>{const n=t.weeks[e],o=document.createElement(\"div\");o.className=\"history-week-group\";const s=document.createElement(\"div\");s.className=\"history-week-header\";const i=document.createElement(\"strong\");i.textContent=n.label,s.appendChild(i);const r=document.createElement(\"span\");r.innerHTML=`${n.count} ${(0,l.t)(\"orders\")} • <strong>\u20ac${n.total.toFixed(2)}</strong>`,s.appendChild(r),o.appendChild(s),n.items.forEach(e=>{const t=new Date(e.date),n=\"en\"===a.Kl?\"en-US\":\"de-AT\",s=t.toLocaleDateString(n,{weekday:\"short\",day:\"2-digit\",month:\"2-digit\"}),i=document.createElement(\"div\");i.className=\"history-item\",9===e.state&&i.classList.add(\"history-item-cancelled\");const r=document.createElement(\"div\");r.style.fontSize=\"0.85rem\",r.style.color=\"var(--text-secondary)\",r.textContent=s,i.appendChild(r);const d=document.createElement(\"div\");d.className=\"history-item-details\";const c=document.createElement(\"span\");c.className=\"history-item-name\",c.textContent=e.name,d.appendChild(c);const u=document.createElement(\"div\"),m=document.createElement(\"span\");m.className=\"history-item-status\",9===e.state?m.textContent=(0,l.t)(\"stateCancelled\"):8===e.state?m.textContent=(0,l.t)(\"stateCompleted\"):m.textContent=(0,l.t)(\"stateTransferred\"),u.appendChild(m),d.appendChild(u),i.appendChild(d);const g=document.createElement(\"div\");g.className=\"history-item-price\",9===e.state&&g.classList.add(\"history-item-price-cancelled\"),g.textContent=`\u20ac${e.price.toFixed(2)}`,i.appendChild(g),o.appendChild(i)}),g.appendChild(o)}),n.appendChild(g),s.appendChild(n)}),t.appendChild(s)})}async function h(e,t,n,o,r){if(a.gX)try{const c=await fetch(`${s.tE}/auth/user/`,{headers:(0,i.H)(a.gX)});if(!c.ok)return void H(\"Fehler: Benutzerdaten konnten nicht geladen werden\",\"error\");const m=await c.json(),g=(new Date).toISOString(),h={uuid:crypto.randomUUID(),created:g,updated:g,order_type:7,items:[{article:t,course_group:null,modifiers:[],uuid:crypto.randomUUID(),name:n,description:r||\"\",price:String(parseFloat(o)),amount:1,vat:\"10.00\",comment:\"\"}],table:null,total:parseFloat(o),tip:0,currency:\"EUR\",venue:s.eW,states:[],order_state:1,date:`${e}T10:30:00Z`,payment_method:\"payroll\",customer:{first_name:m.first_name,last_name:m.last_name,email:m.email,newsletter:!1},preorder:!0,delivery_fee:0,cash_box_table_name:null,take_away:!1},p=await fetch(`${s.tE}/user/orders/`,{method:\"POST\",headers:(0,i.H)(a.gX),body:JSON.stringify(h)});if(p.ok||201===p.status)H(`${(0,l.t)(\"orderSuccess\")}: ${n}`,\"success\"),d=null,await u();else{const e=await p.json();H(`Fehler: ${e.detail||e.non_field_errors?.[0]||\"Bestellung fehlgeschlagen\"}`,\"error\")}}catch(e){console.error(\"Order error:\",e),H(\"Netzwerkfehler bei Bestellung\",\"error\")}}async function p(e,t,n){if(!a.gX)return;const o=`${e}_${t}`,r=a.L.get(o);if(!r||0===r.length)return;const c=r[r.length-1];try{const e=await fetch(`${s.tE}/user/orders/${c}/cancel/`,{method:\"PATCH\",headers:(0,i.H)(a.gX),body:JSON.stringify({})});if(e.ok)H(`${(0,l.t)(\"cancelSuccess\")}: ${n}`,\"success\"),d=null,await u();else{H(`Fehler: ${(await e.json()).detail||\"Stornierung fehlgeschlagen\"}`,\"error\")}}catch(e){console.error(\"Cancel error:\",e),H(\"Netzwerkfehler bei Stornierung\",\"error\")}}function f(){localStorage.setItem(\"kantine_flags\",JSON.stringify([...a.BY]))}async function v(){if(0===a.BY.size)return;const e=a.gX;if(!e){const e=document.getElementById(\"alarm-bell\");return void(e&&e.classList.remove(\"refreshing\"))}const t=new Set;for(const e of a.BY){const[n]=e.split(\"_\");t.add(n)}let n=!1;const o=document.getElementById(\"alarm-bell\");o&&o.classList.add(\"refreshing\");try{for(const o of t)try{const t=await fetch(`${s.tE}/venues/${s.eW}/menu/${s.YU}/${o}/`,{headers:(0,i.H)(e)});if(!t.ok)continue;const r=(await t.json()).results||[],l=new Map;for(const e of r)if(e.items&&Array.isArray(e.items))for(const t of e.items)l.set(t.id,t);for(let e of a.p_){if(!e.days)continue;const t=e.days.find(e=>e.date===o);if(t&&t.items)for(let e=0;e<t.items.length;e++){const s=t.items[e],i=`${o}_${s.articleId}`;if(!a.BY.has(i))continue;const r=l.get(s.articleId);if(r){const e=!1===r.amount_tracking,t=parseInt(r.available_amount)>0;s.available=e||t,s.availableAmount=parseInt(r.available_amount)||0,s.amountTracking=!1!==r.amount_tracking,n=!0}}}}catch(e){console.error(\"Error refreshing flag date\",o,e)}n&&T(),localStorage.setItem(\"kantine_flagged_items_last_checked\",(new Date).toISOString()),(0,r.Mb)(),(0,r.OR)(),H(`${a.BY.size} ${1===a.BY.size?(0,l.t)(\"menuSingular\"):(0,l.t)(\"menuPlural\")} ${(0,l.t)(\"menuChecked\")}`,\"info\")}finally{o&&o.classList.remove(\"refreshing\")}}function y(e,t,n,o){const s=`${e}_${t}`;let i=!1;a.BY.has(s)?(a.BY.delete(s),H(`${(0,l.t)(\"flagRemoved\")} ${n}`,\"success\")):(a.BY.add(s),i=!0,H(`${(0,l.t)(\"flagActivated\")} ${n}`,\"success\"),\"default\"===Notification.permission&&Notification.requestPermission()),f(),(0,r.Mb)(),(0,r.OR)(),i&&v()}function b(){const e=new Date,t=e.toISOString().split(\"T\")[0];let n=!1;for(const o of[...a.BY]){const[s]=o.split(\"_\");let i=!1;if(s<t)i=!0;else if(s===t){const t=new Date(s);t.setHours(10,0,0,0),e>=t&&(i=!0)}i&&(a.BY.delete(o),n=!0)}n&&f()}function w(){a.K8||a.gX&&(0,a.cc)(setInterval(()=>async function(){if(0===a.BY.size||!a.gX)return;for(const e of a.BY){const[t,n]=e.split(\"_\"),o=parseInt(n);try{const e=await fetch(`${s.tE}/venues/${s.eW}/menu/${s.YU}/${t}/`,{headers:(0,i.H)(a.gX)});if(!e.ok)continue;const n=(await e.json()).results||[];let r=null;for(const e of n)if(e.items&&(r=e.items.find(e=>e.id===o||e.article===o),r))break;if(r){if(!1===r.amount_tracking||parseInt(r.available_amount)>0){const e=r.name||\"Unbekannt\";H(`${e} ist jetzt verf\u00fcgbar!`,\"success\"),\"granted\"===Notification.permission&&new Notification(\"Kantine Wrapper\",{body:`${e} ist jetzt verf\u00fcgbar!`,icon:\"\ud83c\udf7d\ufe0f\"}),x()}}}catch(t){console.error(`Poll error for ${e}:`,t),await new Promise(e=>setTimeout(e,200))}}localStorage.setItem(\"kantine_flagged_items_last_checked\",(new Date).toISOString()),(0,r.Mb)()}(),s.fv))}function E(){a.K8&&(clearInterval(a.K8),(0,a.cc)(null))}function A(){localStorage.setItem(\"kantine_highlightTags\",JSON.stringify(a.yz)),(0,r.OR)(),(0,r.gJ)()}function k(e){if(!e)return!1;if((e=e.trim()).length<2)return H(\"Tag muss mindestens 2 Zeichen lang sein.\",\"error\"),!1;if(e.length>20)return H(\"Tag darf maximal 20 Zeichen lang sein.\",\"error\"),!1;if(!/^[a-zA-Z0-9\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df\\s\\-\\.]+$/.test(e))return H(\"Ung\u00fcltige Zeichen im Tag.\",\"error\"),!1;if(a.yz.includes(e))return!1;const t=[...a.yz,e];return(0,a.iw)(t),A(),!0}function L(){const e=document.getElementById(\"tags-list\");e&&(e.innerHTML=\"\",a.yz.forEach(t=>{const n=document.createElement(\"span\");n.className=\"tag-badge\";const o=document.createElement(\"span\");o.textContent=t,n.appendChild(o);const s=document.createElement(\"span\");s.className=\"tag-remove\",s.innerHTML=\"×\",s.title=(0,l.t)(\"removeTagTooltip\")||\"Entfernen\",s.onclick=()=>{!function(e){const t=a.yz.filter(t=>t!==e);(0,a.iw)(t),A()}(t),L()},n.appendChild(s),e.appendChild(n)}))}function S(e){return e?(e=e.toLowerCase(),a.yz.filter(t=>e.includes(t))):[]}const I=\"kantine_menuCache\",C=\"kantine_menuCacheTs\";function T(){try{localStorage.setItem(I,JSON.stringify(a.p_)),localStorage.setItem(C,(new Date).toISOString())}catch(e){console.warn(\"Failed to cache menu data:\",e)}}function B(){try{const e=localStorage.getItem(I),t=localStorage.getItem(C);if(e){(0,a.tn)(JSON.parse(e)),(0,a.Xt)((0,o.sn)(new Date)),(0,a.pK)((new Date).getFullYear()),(0,r.OR)(),(0,r.gJ)(),(0,r.Mb)(),t&&N(t);try{const e=new Set;a.p_.forEach(t=>{(t.days||[]).forEach(t=>{(t.items||[]).forEach(t=>{let n=(t.description||\"\").replace(/\\s+/g,\" \").trim();n&&n.includes(\" / \")&&e.add(n)})})})}catch(e){}return!0}}catch(e){console.warn(\"Failed to load cached menu:\",e)}return!1}function D(){const e=localStorage.getItem(C);if(!e)return!1;if(Date.now()-new Date(e).getTime()>36e5)return!1;const t=(0,o.sn)(new Date),n=(0,o.Ao)(new Date);return a.p_.some(e=>e.weekNumber===t&&e.year===n&&e.days&&e.days.length>0)}async function x(){const e=document.getElementById(\"loading\"),t=document.getElementById(\"progress-modal\"),l=document.getElementById(\"progress-fill\"),d=document.getElementById(\"progress-percent\"),u=document.getElementById(\"progress-message\");e.classList.remove(\"hidden\");const m=a.gX;if(m)try{t.classList.remove(\"hidden\"),u.textContent=\"Hole verf\u00fcgbare Daten...\",l.style.width=\"0%\",d.textContent=\"0%\";const e=await fetch(`${s.tE}/venues/${s.eW}/menu/dates/`,{headers:(0,i.H)(m)});if(!e.ok)throw new Error(`Failed to fetch dates: ${e.status}`);let n=(await e.json()).results||[];const g=new Date;g.setDate(g.getDate()-7);const h=g.toISOString().split(\"T\")[0];n=n.filter(e=>e.date>=h).sort((e,t)=>e.date.localeCompare(t.date)).slice(0,30);const p=n.length;u.textContent=`${p} Tage gefunden. Lade Details...`;const f=[];let v=0;const y=5;for(let e=0;e<p;e+=y){const t=n.slice(e,e+y),a=await Promise.all(t.map(async e=>{const t=e.date;let n=null;try{const a=await fetch(`${s.tE}/venues/${s.eW}/menu/${s.YU}/${t}/`,{headers:(0,i.H)(m)});if(a.ok){const o=(await a.json()).results||[];let s=[];for(const e of o)e.items&&Array.isArray(e.items)&&(s=s.concat(e.items));s.length>0&&(n={date:t,menu_items:s,orders:e.orders||[]})}}catch(e){console.error(`Failed to fetch details for ${t}:`,e)}finally{v++;const e=Math.round(v/p*100);l.style.width=`${e}%`,d.textContent=`${e}%`,u.textContent=`Lade Men\u00fc f\u00fcr ${t}...`}return n}));for(const e of a)e&&f.push(e)}const b=new Map;a.p_&&a.p_.length>0&&a.p_.forEach(e=>{const t=`${e.year}-${e.weekNumber}`;try{b.set(t,{year:e.year,weekNumber:e.weekNumber,days:e.days?e.days.map(e=>({...e,items:e.items?[...e.items]:[]})):[]})}catch(e){console.warn(\"Error hydrating week:\",e)}});for(const e of f){const t=new Date(e.date),n=(0,o.sn)(t),a=(0,o.Ao)(t),s=`${a}-${n}`;b.has(s)||b.set(s,{year:a,weekNumber:n,days:[]});const i=b.get(s),r=t.toLocaleDateString(\"en-US\",{weekday:\"long\"}),l=new Date(e.date);l.setHours(10,0,0,0);const d={date:e.date,weekday:r,orderCutoff:l.toISOString(),items:e.menu_items.map(t=>{const n=!1===t.amount_tracking,a=parseInt(t.available_amount)>0;return{id:`${e.date}_${t.id}`,articleId:t.id,name:t.name||\"Unknown\",description:t.description||\"\",price:parseFloat(t.price)||0,available:n||a,availableAmount:parseInt(t.available_amount)||0,amountTracking:!1!==t.amount_tracking}})},c=i.days.findIndex(t=>t.date===e.date);c>=0?i.days[c]=d:i.days.push(d)}const w=Array.from(b.values()).sort((e,t)=>e.year!==t.year?e.year-t.year:e.weekNumber-t.weekNumber);w.forEach(e=>{e.days&&e.days.sort((e,t)=>e.date.localeCompare(t.date))}),(0,a.tn)(w),T(),N((new Date).toISOString()),(0,a.Xt)((0,o.sn)(new Date)),(0,a.pK)((new Date).getFullYear()),c(),(0,r.OR)(),(0,r.gJ)(),(0,r.Mb)(),u.textContent=\"Fertig!\",setTimeout(()=>t.classList.add(\"hidden\"),500)}catch(e){console.error(\"Error fetching menu:\",e),t.classList.add(\"hidden\"),Promise.resolve().then(n.bind(n,842)).then(t=>{t.showErrorModal(\"Keine Verbindung\",\"Die Men\u00fcdaten konnten nicht geladen werden. M\u00f6glicherweise besteht keine Verbindung zur API oder zur Bessa-Webseite.\",e.message,\"Zur Original-Seite\",\"https://web.bessa.app/knapp-kantine\")})}finally{e.classList.add(\"hidden\")}else e.classList.add(\"hidden\")}let O=null,M=null;function N(e){const t=document.getElementById(\"last-updated-subtitle\");if(e){O=e,localStorage.setItem(\"kantine_last_updated\",e),localStorage.setItem(\"kantine_last_checked\",e);try{const n=new Date(e),a=n.toLocaleTimeString(\"de-DE\",{hour:\"2-digit\",minute:\"2-digit\"}),s=n.toLocaleDateString(\"de-DE\",{day:\"2-digit\",month:\"2-digit\"}),i=(0,o.gs)(n);t.textContent=`Aktualisiert: ${s} ${a} (${i})`}catch(e){t.textContent=\"\"}M||(M=setInterval(()=>{O&&(N(O),(0,r.Mb)())},6e4))}}function H(e,t=\"info\"){let n=document.getElementById(\"toast-container\");n||(n=document.createElement(\"div\"),n.id=\"toast-container\",document.body.appendChild(n));const a=document.createElement(\"div\");a.className=`toast toast-${t}`;const s=\"success\"===t?\"check_circle\":\"error\"===t?\"error\":\"info\";a.innerHTML=`<span class=\"material-icons-round\">${s}</span><span>${(0,o.ZD)(e)}</span>`,n.appendChild(a),requestAnimationFrame(()=>a.classList.add(\"show\")),setTimeout(()=>{a.classList.remove(\"show\"),setTimeout(()=>a.remove(),300)},3e3)}},672(e,t,n){n.d(t,{H:()=>o,O:()=>s});var a=n(521);function o(e){const t={Accept:\"application/json\",\"Content-Type\":\"application/json\",\"X-Client-Version\":a.fZ};return e&&(t.Authorization=`Token ${e}`),t}function s(){return{Accept:\"application/vnd.github.v3+json\"}}},521(e,t,n){n.d(t,{LS:()=>u,YU:()=>i,d_:()=>c,eW:()=>s,fZ:()=>o,fv:()=>r,pe:()=>d,tE:()=>a});const a=\"https://api.bessa.app/v1\",o=\"v1.7.1\",s=591,i=7,r=3e5,l=\"TauNeutrino/kantine-overview\",d=`https://api.github.com/repos/${l}`,c=`https://htmlpreview.github.io/?https://github.com/${l}/blob`,u={AUTH_TOKEN:\"kantine_authToken\",CURRENT_USER:\"kantine_currentUser\",FIRST_NAME:\"kantine_firstName\",LAST_NAME:\"kantine_lastName\",LANG:\"kantine_lang\",FLAGS:\"kantine_flags\",FLAGGED_LAST_CHECKED:\"kantine_flagged_items_last_checked\",LAST_CHECKED:\"kantine_last_checked\",MENU_CACHE:\"kantine_menuCache\",MENU_CACHE_TS:\"kantine_menuCacheTs\",HISTORY_CACHE:\"kantine_history_cache\",HIGHLIGHT_TAGS:\"kantine_highlightTags\",LAST_UPDATED:\"kantine_last_updated\",VERSION_CACHE:\"kantine_version_cache\",DEV_MODE:\"kantine_dev_mode\"}},646(e,t,n){n.d(t,{t:()=>s});var a=n(901);const o={de:{thisWeek:\"Diese Woche\",nextWeek:\"N\u00e4chste Woche\",nextWeekTooltipDefault:\"Men\u00fc n\u00e4chster Woche anzeigen\",thisWeekTooltip:\"Men\u00fc dieser Woche anzeigen\",appTitle:\"Kantinen \u00dcbersicht\",updatedAt:\"Aktualisiert\",langTooltip:\"Sprache der Men\u00fcbeschreibung\",weekLabel:\"Woche\",refresh:\"Men\u00fcdaten neu laden\",history:\"Bestellhistorie\",highlights:\"Pers\u00f6nliche Highlights verwalten\",themeTooltip:\"Erscheinungsbild (Hell/Dunkel) wechseln\",login:\"Anmelden\",loginTooltip:\"Mit Bessa.app Account anmelden\",logout:\"Abmelden\",logoutTooltip:\"Von Bessa.app abmelden\",loginTitle:\"Login\",employeeId:\"Mitarbeiternummer\",employeeIdPlaceholder:\"z.B. 2041\",employeeIdHelp:\"Deine offizielle Knapp Mitarbeiternummer.\",password:\"Passwort\",passwordPlaceholder:\"Bessa Passwort\",passwordHelp:\"Das Passwort f\u00fcr deinen Bessa Account.\",loginButton:\"Einloggen\",loggingIn:\"Wird eingeloggt...\",highlightsTitle:\"Meine Highlights\",highlightsDesc:\"Markiere Men\u00fcs automatisch, wenn sie diese Schlagw\u00f6rter enthalten.\",tagInputPlaceholder:\"z.B. Schnitzel, Vegetarisch...\",tagInputTooltip:\"Neues Schlagwort zum Hervorheben eingeben\",addTag:\"Hinzuf\u00fcgen\",addTagTooltip:\"Schlagwort zur Liste hinzuf\u00fcgen\",removeTagTooltip:\"Schlagwort entfernen\",historyTitle:\"Bestellhistorie\",loadingHistory:\"Lade Historie...\",noOrders:\"Keine Bestellungen gefunden.\",orders:\"Bestellungen\",historyMonthToggle:\"Klicken, um die Bestellungen f\u00fcr diesen Monat ein-/auszublenden\",available:\"Verf\u00fcgbar\",soldOut:\"Ausverkauft\",ordered:\"Bestellt\",orderButton:\"Bestellen\",orderAgainTooltip:\"nochmal bestellen\",orderTooltip:\"bestellen\",cancelOrder:\"Bestellung stornieren\",cancelOneOrder:\"Eine Bestellung stornieren\",flagActivate:\"Benachrichtigen wenn verf\u00fcgbar\",flagDeactivate:\"Benachrichtigung deaktivieren\",alarmTooltipNone:\"Keine beobachteten Men\u00fcs\",alarmLastChecked:\"Zuletzt gepr\u00fcft\",versionsTitle:\"\ud83d\udce6 Versionen\",currentVersion:\"Aktuell\",devModeLabel:\"Dev-Mode (alle Tags anzeigen)\",loadingVersions:\"Lade Versionen...\",noVersions:\"Keine Versionen gefunden.\",installed:\"\u2713 Installiert\",newVersion:\"\u2b06 Neu!\",installLink:\"Installieren\",reportBug:\"Fehler melden\",reportBugTooltip:\"Melde einen Fehler auf GitHub\",featureRequest:\"Feature vorschlagen\",featureRequestTooltip:\"Schlage ein neues Feature auf GitHub vor\",clearCache:\"Lokalen Cache leeren\",clearCacheTooltip:\"L\u00f6scht alle lokalen Daten & erzwingt einen Neuladen\",clearCacheConfirm:\"M\u00f6chtest du wirklich alle lokalen Daten (inkl. Login-Session, Cache und Einstellungen) l\u00f6schen? Die Seite wird danach neu geladen.\",versionMenuTooltip:\"Klick f\u00fcr Versionsmen\u00fc\",progressTitle:\"Men\u00fcdaten aktualisieren\",progressInit:\"Initialisierung...\",noMenuData:\"Keine Men\u00fcdaten f\u00fcr KW\",noMenuDataHint:\"Versuchen Sie eine andere Woche oder schauen Sie sp\u00e4ter vorbei.\",orderDeadline:\"Bestellschluss\",flagRemoved:\"Flag entfernt f\u00fcr\",flagActivated:\"Benachrichtigung aktiviert f\u00fcr\",menuChecked:\"gepr\u00fcft\",menuSingular:\"Men\u00fc\",menuPlural:\"Men\u00fcs\",newMenuDataAvailable:\"Neue Men\u00fcdaten f\u00fcr n\u00e4chste Woche verf\u00fcgbar!\",orderSuccess:\"Bestellt\",cancelSuccess:\"Storniert\",bgSyncFailed:\"Hintergrund-Synchronisation fehlgeschlagen\",historyLoadError:\"Fehler beim Laden der Historie.\",historyLoadingFull:\"Lade Bestellhistorie...\",historyLoadingDelta:\"Suche nach neuen Bestellungen...\",historyLoadingItem:\"Lade Bestellung\",historyLoadingOf:\"von\",historyLoadingNew:\"neue/ge\u00e4nderte Bestellungen gefunden...\",badgeOrdered:\"bestellt\",badgeOrderable:\"bestellbar\",badgeTotal:\"gesamt\",badgeHighlights:\"Highlights gefunden\",stateCancelled:\"Storniert\",stateCompleted:\"Abgeschlossen\",stateTransferred:\"\u00dcbertragen\",close:\"Schlie\u00dfen\",noConnection:\"Keine Verbindung\",toOriginalPage:\"Zur Original-Seite\",loggedIn:\"Angemeldet\"},en:{thisWeek:\"This Week\",nextWeek:\"Next Week\",nextWeekTooltipDefault:\"Show next week's menu\",thisWeekTooltip:\"Show this week's menu\",appTitle:\"Canteen Overview\",updatedAt:\"Updated\",langTooltip:\"Menu description language\",weekLabel:\"Week\",refresh:\"Reload menu data\",history:\"Order history\",highlights:\"Manage personal highlights\",themeTooltip:\"Toggle appearance (Light/Dark)\",login:\"Sign in\",loginTooltip:\"Sign in with Bessa.app account\",logout:\"Sign out\",logoutTooltip:\"Sign out from Bessa.app\",loginTitle:\"Login\",employeeId:\"Employee ID\",employeeIdPlaceholder:\"e.g. 2041\",employeeIdHelp:\"Your official Knapp employee number.\",password:\"Password\",passwordPlaceholder:\"Bessa password\",passwordHelp:\"The password for your Bessa account.\",loginButton:\"Log in\",loggingIn:\"Logging in...\",highlightsTitle:\"My Highlights\",highlightsDesc:\"Automatically highlight menus containing these keywords.\",tagInputPlaceholder:\"e.g. Schnitzel, Vegetarian...\",tagInputTooltip:\"Enter new keyword to highlight\",addTag:\"Add\",addTagTooltip:\"Add keyword to list\",removeTagTooltip:\"Remove keyword\",historyTitle:\"Order History\",loadingHistory:\"Loading history...\",noOrders:\"No orders found.\",orders:\"Orders\",historyMonthToggle:\"Click to expand/collapse orders for this month\",available:\"Available\",soldOut:\"Sold out\",ordered:\"Ordered\",orderButton:\"Order\",orderAgainTooltip:\"order again\",orderTooltip:\"order\",cancelOrder:\"Cancel order\",cancelOneOrder:\"Cancel one order\",flagActivate:\"Notify when available\",flagDeactivate:\"Deactivate notification\",alarmTooltipNone:\"No flagged menus\",alarmLastChecked:\"Last checked\",versionsTitle:\"\ud83d\udce6 Versions\",currentVersion:\"Current\",devModeLabel:\"Dev mode (show all tags)\",loadingVersions:\"Loading versions...\",noVersions:\"No versions found.\",installed:\"\u2713 Installed\",newVersion:\"\u2b06 New!\",installLink:\"Install\",reportBug:\"Report a bug\",reportBugTooltip:\"Report a bug on GitHub\",featureRequest:\"Request a feature\",featureRequestTooltip:\"Suggest a new feature on GitHub\",clearCache:\"Clear local cache\",clearCacheTooltip:\"Deletes all local data & forces a reload\",clearCacheConfirm:\"Do you really want to delete all local data (including login session, cache, and settings)? The page will reload afterwards.\",versionMenuTooltip:\"Click for version menu\",progressTitle:\"Updating menu data\",progressInit:\"Initializing...\",noMenuData:\"No menu data for CW\",noMenuDataHint:\"Try another week or check back later.\",orderDeadline:\"Order deadline\",flagRemoved:\"Flag removed for\",flagActivated:\"Notification activated for\",menuChecked:\"checked\",menuSingular:\"menu\",menuPlural:\"menus\",newMenuDataAvailable:\"New menu data available for next week!\",orderSuccess:\"Ordered\",cancelSuccess:\"Cancelled\",bgSyncFailed:\"Background synchronisation failed\",historyLoadError:\"Error loading history.\",historyLoadingFull:\"Loading order history...\",historyLoadingDelta:\"Checking for new orders...\",historyLoadingItem:\"Loading order\",historyLoadingOf:\"of\",historyLoadingNew:\"new/updated orders found...\",badgeOrdered:\"ordered\",badgeOrderable:\"orderable\",badgeTotal:\"total\",badgeHighlights:\"highlights found\",stateCancelled:\"Cancelled\",stateCompleted:\"Completed\",stateTransferred:\"Transferred\",close:\"Close\",noConnection:\"No connection\",toOriginalPage:\"Go to original page\",loggedIn:\"Logged in\"}};function s(e){const t=\"en\"===a.Kl?\"en\":\"de\";return o[t][e]||o.de[e]||e}},901(e,t,n){n.d(t,{BT:()=>i,BY:()=>m,K8:()=>g,Kl:()=>h,L:()=>u,Ny:()=>c,O5:()=>b,UD:()=>S,Xt:()=>v,cc:()=>A,di:()=>E,gX:()=>d,iw:()=>k,lt:()=>w,pK:()=>y,p_:()=>s,qo:()=>L,sw:()=>l,tn:()=>f,vW:()=>r,yz:()=>p});var a=n(413),o=n(521);let s=[],i=(0,a.sn)(new Date),r=(new Date).getFullYear(),l=\"this-week\",d=localStorage.getItem(o.LS.AUTH_TOKEN),c=localStorage.getItem(o.LS.CURRENT_USER),u=new Map,m=new Set(JSON.parse(localStorage.getItem(o.LS.FLAGS)||\"[]\")),g=null,h=localStorage.getItem(o.LS.LANG)||\"de\",p=JSON.parse(localStorage.getItem(o.LS.HIGHLIGHT_TAGS)||\"[]\");function f(e){s=e}function v(e){i=e}function y(e){r=e}function b(e){d=e}function w(e){c=e}function E(e){u=e}function A(e){g=e}function k(e){p=e}function L(e){\"this-week\"===e||\"next-week\"===e?l=e:console.warn(`[state] Invalid displayMode: \"${e}\". Ignoring.`)}function S(e){[\"de\",\"en\",\"all\"].includes(e)?h=e:console.warn(`[state] Invalid langMode: \"${e}\". Ignoring.`)}},842(e,t,n){n.d(t,{Gk:()=>h,Mb:()=>y,OR:()=>c,Ux:()=>g,gJ:()=>d,showErrorModal:()=>v,wy:()=>u});var a=n(901),o=n(413),s=n(521),i=n(672),r=n(367),l=n(646);function d(){const e=document.getElementById(\"btn-next-week\");let t=a.BT+1,n=a.vW;t>52&&(t=1,n++);const o=a.p_.find(e=>e.weekNumber===t&&e.year===n);let s=0,i=0,d=0,c=0;o&&o.days&&o.days.forEach(e=>{if(e.items&&e.items.length>0){s++;const t=e.items.some(e=>e.available);t&&i++;let n=!1;e.items.forEach(t=>{const o=t.articleId||parseInt(t.id.split(\"_\")[1]),s=`${e.date}_${o}`;a.L.has(s)&&a.L.get(s).length>0&&(n=!0)}),n&&d++;const o=new Date(e.date).getDay();o>=1&&o<=4&&t&&!n&&c++}});const u=e.querySelector(\".nav-badge\");if(u&&u.remove(),s>0){let a=0;o&&o.days&&o.days.forEach(e=>{e.items.forEach(e=>{const t=(0,r.BM)(e.name),n=(0,r.BM)(e.description);(t.length>0||n.length>0)&&a++})});let u=[`${d} ${(0,l.t)(\"badgeOrdered\")} / ${i} ${(0,l.t)(\"badgeOrderable\")} / ${s} ${(0,l.t)(\"badgeTotal\")}`];if(a>0&&u.push(`${a} ${(0,l.t)(\"badgeHighlights\")}`),e.title=u.join(\" \u2022 \"),c>0){e.classList.add(\"new-week-available\");const a=`kantine_notified_nextweek_${n}_${t}`;localStorage.getItem(a)||(localStorage.setItem(a,\"true\"),(0,r.P0)((0,l.t)(\"newMenuDataAvailable\"),\"info\"))}else e.classList.remove(\"new-week-available\")}else e.title=(0,l.t)(\"nextWeekTooltipDefault\"),e.classList.remove(\"new-week-available\")}function c(){const e=document.getElementById(\"menu-container\");if(!e)return;e.innerHTML=\"\";let t=a.BT,n=a.vW;\"next-week\"===a.sw&&(t++,t>52&&(t=1,n++));const s=a.p_.flatMap(e=>e.days||[]).filter(e=>{const a=new Date(e.date);return(0,o.sn)(a)===t&&(0,o.Ao)(a)===n});if(0===s.length)return void(e.innerHTML=`\\n <div class=\"empty-state\">\\n <p>${(0,l.t)(\"noMenuData\")} ${t} (${n}).</p>\\n <small>${(0,l.t)(\"noMenuDataHint\")}</small>\\n </div>`);const i=document.getElementById(\"header-week-info\"),d=\"this-week\"===a.sw?(0,l.t)(\"thisWeek\"):(0,l.t)(\"nextWeek\");i.innerHTML=`\\n <div class=\"header-week-title\">${d}</div>\\n <div class=\"header-week-subtitle\">${(0,l.t)(\"weekLabel\")} ${t} \u2022 ${n}</div>`;const c=document.createElement(\"div\");c.className=\"days-grid\",s.sort((e,t)=>e.date.localeCompare(t.date));s.filter(e=>{const t=new Date(e.date).getDay();return 0!==t&&6!==t}).forEach(e=>{const t=function(e){if(!e.items||0===e.items.length)return null;const t=document.createElement(\"div\");t.className=\"menu-card\";const n=new Date,s=new Date(e.date);let i=!1;if(e.orderCutoff)i=n>=new Date(e.orderCutoff);else{const t=new Date;t.setHours(0,0,0,0);const n=new Date(e.date);n.setHours(0,0,0,0),i=n<t}i&&t.classList.add(\"past-day\");const d=[];e.items&&e.items.forEach(t=>{const n=t.articleId||parseInt(t.id.split(\"_\")[1]),o=`${e.date}_${n}`,s=(a.L.get(o)||[]).length;if(s>0){const e=t.name.match(/([M][1-9][Ff]?)/);if(e){let t=e[1];s>1&&(t+=\"+\"),d.push(t)}}});const c=document.createElement(\"div\");c.className=\"card-header\";const u=s.toLocaleDateString(\"de-DE\",{day:\"2-digit\",month:\"2-digit\"}),m=d.reduce((e,t)=>e+`<span class=\"menu-code-badge\">${t}</span>`,\"\");let g=\"\";const h=e.items&&e.items.some(t=>{const n=t.articleId||parseInt(t.id.split(\"_\")[1]),o=`${e.date}_${n}`;return a.L.has(o)&&a.L.get(o).length>0}),p=e.items&&e.items.some(e=>e.available);g=h?\"header-violet\":p&&!i?\"header-green\":\"header-red\";g&&c.classList.add(g);c.innerHTML=`\\n <div class=\"day-header-left\">\\n <span class=\"day-name\">${(0,o.FS)(e.weekday)}</span>\\n <div class=\"day-badges\">${m}</div>\\n </div>\\n <span class=\"day-date\">${u}</span>`,t.appendChild(c);const f=document.createElement(\"div\");f.className=\"card-body\";const v=(new Date).toISOString().split(\"T\")[0],y=e.date===v,b=[...e.items].sort((t,n)=>{if(y){const o=t.articleId||parseInt(t.id.split(\"_\")[1]),s=n.articleId||parseInt(n.id.split(\"_\")[1]),i=a.L.has(`${e.date}_${o}`),r=a.L.has(`${e.date}_${s}`);if(i&&!r)return-1;if(!i&&r)return 1}return t.name.localeCompare(n.name)});return b.forEach(t=>{const s=document.createElement(\"div\");s.className=\"menu-item\";const d=t.articleId||parseInt(t.id.split(\"_\")[1]),c=`${e.date}_${d}`,u=(a.L.get(c)||[]).length;let m=\"\";m=t.available?t.amountTracking?`<span class=\"badge available\">${(0,l.t)(\"available\")} (${t.availableAmount})</span>`:`<span class=\"badge available\">${(0,l.t)(\"available\")}</span>`:`<span class=\"badge sold-out\">${(0,l.t)(\"soldOut\")}</span>`;let g=\"\";if(u>0){const t=u>1?`<span class=\"order-count-badge\">${u}</span>`:\"\";g=`<span class=\"badge ordered\"><span class=\"material-icons-round\">check_circle</span> ${(0,l.t)(\"ordered\")}${t}</span>`,s.classList.add(\"ordered\"),new Date(e.date).toDateString()===n.toDateString()&&s.classList.add(\"today-ordered\")}const h=`${e.date}_${d}`,p=a.BY.has(h);p&&s.classList.add(t.available?\"flagged-available\":\"flagged-sold-out\");const v=[...new Set([...(0,r.BM)(t.name),...(0,r.BM)(t.description)])];v.length>0&&s.classList.add(\"highlight-glow\");let y=\"\",b=\"\",w=\"\";if(a.gX&&!i){const n=p?\"notifications_active\":\"notifications_none\",a=p?\"btn-flag active\":\"btn-flag\",s=p?(0,l.t)(\"flagDeactivate\"):(0,l.t)(\"flagActivate\");if(t.available&&!p||(w=`<button class=\"${a}\" data-date=\"${e.date}\" data-article=\"${d}\" data-name=\"${(0,o.ZD)(t.name)}\" data-cutoff=\"${e.orderCutoff}\" title=\"${s}\"><span class=\"material-icons-round\">${n}</span></button>`),t.available&&(y=u>0?`<button class=\"btn-order btn-order-compact\" data-date=\"${e.date}\" data-article=\"${d}\" data-name=\"${(0,o.ZD)(t.name)}\" data-price=\"${t.price}\" data-desc=\"${(0,o.ZD)(t.description||\"\")}\" title=\"${(0,o.ZD)(t.name)} \u2013 ${(0,l.t)(\"orderAgainTooltip\")}\"><span class=\"material-icons-round\">add</span></button>`:`<button class=\"btn-order\" data-date=\"${e.date}\" data-article=\"${d}\" data-name=\"${(0,o.ZD)(t.name)}\" data-price=\"${t.price}\" data-desc=\"${(0,o.ZD)(t.description||\"\")}\" title=\"${(0,o.ZD)(t.name)} \u2013 ${(0,l.t)(\"orderTooltip\")}\"><span class=\"material-icons-round\">add_shopping_cart</span> ${(0,l.t)(\"orderButton\")}</button>`),u>0){const n=1===u?\"close\":\"remove\",a=1===u?(0,l.t)(\"cancelOrder\"):(0,l.t)(\"cancelOneOrder\");b=`<button class=\"btn-cancel\" data-date=\"${e.date}\" data-article=\"${d}\" data-name=\"${(0,o.ZD)(t.name)}\" title=\"${a}\"><span class=\"material-icons-round\">${n}</span></button>`}}let E=\"\";if(v.length>0){E=`<div class=\"matched-tags\">${v.reduce((e,t)=>e+`<span class=\"tag-badge-small\"><span class=\"material-icons-round\" style=\"font-size:10px;margin-right:2px\">star</span>${(0,o.ZD)(t)}</span>`,\"\")}</div>`}s.innerHTML=`\\n <div class=\"item-header\">\\n <span class=\"item-name\">${(0,o.ZD)(t.name)}</span>\\n <span class=\"item-price\">${t.price.toFixed(2)} \u20ac</span>\\n </div>\\n <div class=\"item-status-row\">\\n ${g}\\n ${b}\\n ${y}\\n ${w}\\n <div class=\"badges\">${m}</div>\\n </div>\\n ${E}\\n <p class=\"item-desc\">${(0,o.ZD)((0,o.PC)(t.description))}</p>`;const A=s.querySelector(\".btn-order\");A&&A.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;t.disabled=!0,t.classList.add(\"loading\"),(0,r.wH)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name,parseFloat(t.dataset.price),t.dataset.desc||\"\").finally(()=>{t.disabled=!1,t.classList.remove(\"loading\")})});const k=s.querySelector(\".btn-cancel\");k&&k.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;t.disabled=!0,(0,r.N4)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name).finally(()=>{t.disabled=!1})});const L=s.querySelector(\".btn-flag\");L&&L.addEventListener(\"click\",e=>{e.stopPropagation();const t=e.currentTarget;(0,r.PQ)(t.dataset.date,parseInt(t.dataset.article),t.dataset.name,t.dataset.cutoff)}),f.appendChild(s)}),t.appendChild(f),t}(e);t&&c.appendChild(t)}),e.appendChild(c),setTimeout(()=>u(c),0)}function u(e){const t=e.querySelectorAll(\".menu-card\");if(0===t.length)return;const n=[];let a=0;const o=Array.from(t).map(e=>{const t=Array.from(e.querySelectorAll(\".menu-item\"));return a=Math.max(a,t.length),t});for(let e=0;e<a;e++)n[e]=o.map(t=>t[e]).filter(e=>!!e);n.flat().forEach(e=>{e.style.height=\"auto\"});const s=n.map(e=>Math.max(...e.map(e=>e.offsetHeight)));n.forEach((e,t)=>{const n=`${s[t]}px`;e.forEach(e=>{e.style.height=n})})}async function m(e){const t=e?`${s.pe}/tags?per_page=20`:`${s.pe}/releases?per_page=20`,n=await fetch(t,{headers:(0,i.O)()});if(!n.ok){if(403===n.status)throw new Error(\"API Rate Limit erreicht (403). Bitte sp\u00e4ter erneut versuchen.\");throw new Error(`GitHub API ${n.status}`)}return(await n.json()).map(t=>{const n=e?t.name:t.tag_name;return{tag:n,name:e?n:t.name||n,url:`${s.d_}/${n}/dist/install.html`,body:t.body||\"\"}})}async function g(){const e=\"true\"===localStorage.getItem(s.LS.DEV_MODE);try{const t=await m(e);if(!t.length)return;localStorage.setItem(s.LS.VERSION_CACHE,JSON.stringify({timestamp:Date.now(),devMode:e,versions:t}));const n=t[0].tag;if(!(0,o.U4)(n,\"v1.7.1\"))return;const a=document.querySelector(\".header-left h1\");if(a&&!a.querySelector(\".update-icon\")){const e=document.createElement(\"a\");e.className=\"update-icon\",e.href=t[0].url,e.target=\"_blank\",e.innerHTML=\"\ud83c\udd95\",e.title=`Update: ${n} \u2014 Klick zum Installieren`,e.style.cssText=\"margin-left:8px;font-size:1em;text-decoration:none;cursor:pointer;vertical-align:middle;\",a.appendChild(e)}}catch(e){console.warn(\"[Kantine] Version check failed:\",e)}}function h(){const e=document.getElementById(\"version-modal\"),t=document.getElementById(\"version-list-container\"),n=document.getElementById(\"dev-mode-toggle\"),a=\"v1.7.1\";if(!e)return;e.classList.remove(\"hidden\");const i=document.getElementById(\"version-current\");i&&(i.textContent=a);const r=\"true\"===localStorage.getItem(s.LS.DEV_MODE);async function l(e){const i=n.checked;function r(e){if(!e||!e.length)return void(t.innerHTML='<p style=\"color:var(--text-secondary);\">Keine Versionen gefunden.</p>');t.innerHTML='<ul class=\"version-list\"></ul>';const n=t.querySelector(\".version-list\");e.forEach(e=>{const t=e.tag===a,s=(0,o.U4)(e.tag,a),i=document.createElement(\"li\");i.className=\"version-item\"+(t?\" current\":\"\");let r=\"\";t?r='<span class=\"badge-current\">\u2713 Installiert</span>':s&&(r='<span class=\"badge-new\">\u2b06 Neu!</span>');let l=\"\";t||(l=`<a href=\"${(0,o.ZD)(e.url)}\" target=\"_blank\" class=\"install-link\" title=\"${(0,o.ZD)(e.tag)} installieren\">Installieren</a>`),i.innerHTML=`\\n <div class=\"version-info\">\\n <strong>${(0,o.ZD)(e.tag)}</strong>\\n ${r}\\n </div>\\n ${l}\\n `,n.appendChild(i)})}t.innerHTML='<p style=\"color:var(--text-secondary);\">Lade Versionen...</p>';try{const e=localStorage.getItem(s.LS.VERSION_CACHE);let t=null;if(e)try{t=JSON.parse(e)}catch(e){}t&&t.devMode===i&&t.versions&&r(t.versions);const n=await m(i),a=JSON.stringify(n);a!==(t?JSON.stringify(t.versions):\"\")&&(localStorage.setItem(s.LS.VERSION_CACHE,JSON.stringify({timestamp:Date.now(),devMode:i,versions:n})),r(n))}catch(e){t.innerHTML=`<p style=\"color:#e94560;\">Fehler: ${(0,o.ZD)(e.message)}</p>`}}n.checked=r,l(),n.onchange=()=>{localStorage.setItem(s.LS.DEV_MODE,n.checked),localStorage.removeItem(s.LS.VERSION_CACHE),l()}}function p(){if(!a.gX||!a.Ny)return void f();const e=new Date,t=e.getDay();if(0===t||6===t)return void f();const n=e.toISOString().split(\"T\")[0];let o=!1;for(const e of a.L.keys())if(e.startsWith(n)){o=!0;break}if(o)return void f();const s=new Date;s.setHours(10,0,0,0);const i=s-e;if(i<=0)return void f();const r=Math.floor(i/36e5),d=Math.floor(i%36e5/6e4),c=document.querySelector(\".header-center-wrapper\");if(!c)return;let u=document.getElementById(\"order-countdown\");if(u||(u=document.createElement(\"div\"),u.id=\"order-countdown\",c.insertBefore(u,c.firstChild)),u.innerHTML=`<span>${(0,l.t)(\"orderDeadline\")}:</span> <strong>${r}h ${d}m</strong>`,i<36e5){u.classList.add(\"urgent\");const e=`kantine_notified_${n}`;localStorage.getItem(e)||(\"granted\"===Notification.permission?new Notification(\"Kantine: Bestellschluss naht!\",{body:\"Du hast heute noch nichts bestellt. Nur noch 1 Stunde!\",icon:\"\u23f3\"}):\"default\"===Notification.permission&&Notification.requestPermission(),localStorage.setItem(e,\"true\"))}else u.classList.remove(\"urgent\")}function f(){const e=document.getElementById(\"order-countdown\");e&&e.remove()}function v(e,t,n,a,o){const s=\"error-modal\";let i=document.getElementById(s);i&&i.remove(),i=document.createElement(\"div\"),i.id=s,i.className=\"modal\";const r=document.createElement(\"div\");r.className=\"modal-content\";const l=document.createElement(\"div\");l.className=\"modal-header\";const d=document.createElement(\"h2\");d.style.cssText=\"color: var(--error-color); display: flex; align-items: center; gap: 10px;\";const c=document.createElement(\"span\");c.className=\"material-icons-round\",c.textContent=\"signal_wifi_off\",d.appendChild(c);const u=document.createElement(\"span\");u.textContent=e,d.appendChild(u),l.appendChild(d),r.appendChild(l);const m=document.createElement(\"div\");m.style.padding=\"20px\";const g=document.createElement(\"p\");if(g.style.cssText=\"margin-bottom: 15px; color: var(--text-primary);\",g.textContent=t,m.appendChild(g),n){const e=document.createElement(\"small\");e.style.cssText=\"display: block; margin-top: 10px; color: var(--text-secondary);\",e.textContent=n,m.appendChild(e)}const h=document.createElement(\"div\");h.style.cssText=\"margin-top: 20px; display: flex; justify-content: center;\";const p=document.createElement(\"button\");p.style.cssText=\"\\n background-color: var(--accent-color);\\n color: white;\\n padding: 12px 24px;\\n border-radius: 8px;\\n border: none;\\n font-weight: 600;\\n cursor: pointer;\\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n box-shadow: 0 4px 12px rgba(233, 69, 96, 0.3);\\n \",p.textContent=a||\"Zur Original-Seite\",p.onclick=()=>{window.open(o||\"https://web.bessa.app/knapp-kantine\",\"_blank\"),i.classList.add(\"hidden\")},h.appendChild(p),m.appendChild(h),r.appendChild(m),i.appendChild(r),document.body.appendChild(i)}function y(){const e=document.getElementById(\"alarm-bell\"),t=document.getElementById(\"alarm-bell-icon\");if(!e||!t)return;if(0===a.BY.size)return e.classList.add(\"hidden\"),e.style.display=\"none\",t.style.color=\"var(--text-secondary)\",void(t.style.textShadow=\"none\");e.classList.remove(\"hidden\"),e.style.display=\"inline-flex\";let n=!1;for(const e of a.p_)if(e.days){for(const t of e.days)if(t.items){for(const e of t.items)if(e.available&&a.BY.has(e.id)){n=!0;break}if(n)break}if(n)break}const i=localStorage.getItem(s.LS.LAST_CHECKED),r=localStorage.getItem(s.LS.FLAGGED_LAST_CHECKED);let d=0;i&&(d=Math.max(d,new Date(i).getTime())),r&&(d=Math.max(d,new Date(r).getTime()));let c=\"gerade eben\";if(0===d){const e=(new Date).toISOString();localStorage.setItem(s.LS.LAST_CHECKED,e),d=new Date(e).getTime()}c=(0,o.gs)(new Date(d)),e.title=`${(0,l.t)(\"alarmLastChecked\")}: ${c}`,n?(t.style.color=\"#10b981\",t.style.textShadow=\"0 0 10px rgba(16, 185, 129, 0.4)\"):(t.style.color=\"#f59e0b\",t.style.textShadow=\"0 0 10px rgba(245, 158, 11, 0.4)\")}setInterval(p,6e4),setTimeout(p,1e3)},413(e,t,n){n.d(t,{Ao:()=>s,FS:()=>i,PC:()=>m,U4:()=>l,ZD:()=>r,gs:()=>d,sg:()=>g,sn:()=>o});var a=n(901);function o(e){const t=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate())),n=t.getUTCDay()||7;t.setUTCDate(t.getUTCDate()+4-n);const a=new Date(Date.UTC(t.getUTCFullYear(),0,1));return Math.ceil(((t-a)/864e5+1)/7)}function s(e){const t=new Date(e.getTime());return t.setDate(t.getDate()+3-(t.getDay()+6)%7),t.getFullYear()}function i(e){if(\"en\"===a.Kl)return e;return{Monday:\"Montag\",Tuesday:\"Dienstag\",Wednesday:\"Mittwoch\",Thursday:\"Donnerstag\",Friday:\"Freitag\",Saturday:\"Samstag\",Sunday:\"Sonntag\"}[e]||e}function r(e){const t=document.createElement(\"div\");return t.textContent=e||\"\",t.innerHTML}function l(e,t){if(!e||!t)return!1;const n=e.replace(/^v/,\"\").split(\".\").map(Number),a=t.replace(/^v/,\"\").split(\".\").map(Number);for(let e=0;e<Math.max(n.length,a.length);e++){if((n[e]||0)>(a[e]||0))return!0;if((n[e]||0)<(a[e]||0))return!1}return!1}function d(e){const t=Date.now()-e.getTime(),n=Math.floor(t/6e4);if(n<1)return\"gerade eben\";if(1===n)return\"vor 1 min.\";if(n<60)return`vor ${n} min.`;const a=Math.floor(n/60);return 1===a?\"vor 1 Std.\":`vor ${a} Std.`}const c=[\"apfel\",\"achtung\",\"aubergine\",\"auflauf\",\"beere\",\"blumenkohl\",\"bohne\",\"braten\",\"brokkoli\",\"brot\",\"brust\",\"br\u00f6tchen\",\"butter\",\"chili\",\"dessert\",\"dip\",\"eier\",\"eintopf\",\"eis\",\"erbse\",\"erdbeer\",\"essig\",\"filet\",\"fisch\",\"fisole\",\"fleckerl\",\"fleisch\",\"fl\u00fcgel\",\"frucht\",\"f\u00fcr\",\"gebraten\",\"gem\u00fcse\",\"gew\u00fcrz\",\"gratin\",\"grie\u00df\",\"gulasch\",\"gurke\",\"himbeer\",\"honig\",\"huhn\",\"h\u00e4hnchen\",\"jambalaya\",\"joghurt\",\"karotte\",\"kartoffel\",\"keule\",\"kirsch\",\"knacker\",\"knoblauch\",\"kn\u00f6del\",\"kompott\",\"kraut\",\"kr\u00e4uter\",\"kuchen\",\"k\u00e4se\",\"k\u00fcrbis\",\"lauch\",\"mandel\",\"milch\",\"mild\",\"mit\",\"mohn\",\"most\",\"m\u00f6hre\",\"natur\",\"nockerl\",\"nudel\",\"nuss\",\"nu\u00df\",\"obst\",\"oder\",\"olive\",\"paprika\",\"pfanne\",\"pfannkuchen\",\"pfeffer\",\"pikant\",\"pilz\",\"plunder\",\"p\u00fcree\",\"ragout\",\"rahm\",\"reis\",\"rind\",\"sahne\",\"salami\",\"salat\",\"salz\",\"sauer\",\"scharf\",\"schinken\",\"schnitte\",\"schnitzel\",\"schoko\",\"schupf\",\"schwein\",\"sellerie\",\"senf\",\"sosse\",\"so\u00dfe\",\"spargel\",\"sp\u00e4tzle\",\"speck\",\"spie\u00df\",\"spinat\",\"steak\",\"suppe\",\"s\u00fc\u00df\",\"tofu\",\"tomate\",\"topfen\",\"torte\",\"tr\u00fcffel\",\"und\",\"vanille\",\"vogerl\",\"vom\",\"wien\",\"wurst\",\"zucchini\",\"zum\",\"zur\",\"zwiebel\",\"\u00f6l\"],u=[\"almond\",\"and\",\"apple\",\"asparagus\",\"bacon\",\"baked\",\"ball\",\"bean\",\"beef\",\"berry\",\"bread\",\"breast\",\"broccoli\",\"bun\",\"butter\",\"cabbage\",\"cake\",\"caper\",\"carrot\",\"casserole\",\"cauliflower\",\"celery\",\"cheese\",\"cherry\",\"chicken\",\"chili\",\"choco\",\"chocolate\",\"cider\",\"cilantro\",\"coffee\",\"compote\",\"cream\",\"cucumber\",\"curd\",\"danish\",\"dessert\",\"dip\",\"dumpling\",\"egg\",\"eggplant\",\"filet\",\"fish\",\"for\",\"fried\",\"from\",\"fruit\",\"garlic\",\"goulash\",\"gratin\",\"ham\",\"herb\",\"honey\",\"hot\",\"ice\",\"jambalaya\",\"leek\",\"leg\",\"mash\",\"meat\",\"mexican\",\"mild\",\"milk\",\"mint\",\"mushroom\",\"mustard\",\"noodle\",\"nut\",\"oat\",\"oil\",\"olive\",\"onion\",\"or\",\"oven\",\"pan\",\"pancake\",\"pea\",\"pepper\",\"plain\",\"plate\",\"poppy\",\"pork\",\"potato\",\"pumpkin\",\"radish\",\"ragout\",\"raspberry\",\"rice\",\"roast\",\"roll\",\"salad\",\"salami\",\"salt\",\"sauce\",\"sausage\",\"shrimp\",\"skewer\",\"slice\",\"soup\",\"sour\",\"spice\",\"spicy\",\"spinach\",\"steak\",\"stew\",\"strawberr\",\"strawberry\",\"strudel\",\"sweet\",\"tart\",\"thyme\",\"to\",\"tofu\",\"tomat\",\"tomato\",\"truffle\",\"trukey\",\"turkey\",\"vanilla\",\"vegan\",\"vegetable\",\"vinegar\",\"wedge\",\"wing\",\"with\",\"wok\",\"yogurt\",\"zucchini\"];function m(e){if(\"all\"===a.Kl)return e||\"\";const t=function(e){if(!e)return{de:\"\",en:\"\",raw:\"\"};let t=e.replace(/(?:\\(|(?:\\/|\\s|^))([A-Z,]+)\\)\\s*(?=\\S)(?!\\s*\\/)/g,\"($1)\\n\u2022 \");function n(e){let t=0,n=0;return e.forEach(e=>{const a=e.toLowerCase().replace(/[^a-z\u00e4\u00f6\u00fc\u00df]/g,\"\");if(a){let o=0,s=0;c.includes(a)?o=a.length:c.forEach(e=>{a.includes(e)&&e.length>o&&(o=e.length)}),u.includes(a)?s=a.length:u.forEach(e=>{a.includes(e)&&e.length>s&&(s=e.length)}),o>0&&(t+=o/a.length),s>0&&(n+=s/a.length),/^[A-Z\u00c4\u00d6\u00dc]/.test(e)&&(t+=.5)}}),{de:t,en:n}}function a(e){const t=e.trim().split(/\\s+/);if(t.length<2)return{enPart:e,nextDe:\"\"};let a=-1,o=-9999;for(let e=1;e<t.length;e++){const s=t.slice(0,e),i=t.slice(e),r=n(s),l=n(i),d=i[0];let c=0;/^[A-Z\u00c4\u00d6\u00dc]/.test(d)&&(c=1);const u=r.en-r.de+(l.de-l.en)+c,m=r.en>r.de||r.en>0,g=l.de+c>l.en;m&&g&&u>o&&(o=u,a=e)}return-1!==a?{enPart:t.slice(0,a).join(\" \"),nextDe:t.slice(a).join(\" \")}:{enPart:e,nextDe:\"\"}}t.startsWith(\"\u2022 \")||(t=\"\u2022 \"+t);const o=/(.*?)(?:\\(|(?:\\/|\\s|^))([A-Z,]+)\\)\\s*(?!\\s*[/])/g;let s;const i=[];let r=0;for(;null!==(s=o.exec(e));)s.index>r&&i.push(e.substring(r,s.index).trim()),i.push(s[0].trim()),r=o.lastIndex;r<e.length&&i.push(e.substring(r).trim()),0===i.length&&\"\"!==e.trim()&&i.push(e.trim());const l=[],d=[];for(let e of i){let t=e.match(/(.*?)(?:\\(|(?:\\/|\\s|^))([A-Z,]+)\\)\\s*$/),n=e,o=\"\",s=\"\";t&&(n=t[1].trim(),s=t[2],o=` (${s})`);const i=n.split(/\\s*\\/\\s*(?![A-Z,]+$)/);if(i.length>=2){const e=i[0].trim();let t=i.slice(1).join(\" / \").trim();const n=a(t);if(n.nextDe){l.push(e+o),d.push(n.enPart+o);const t=n.nextDe+o;l.push(t),d.push(t)}else{const n=t+o,a=e.includes(o.trim())?e:e+o;l.push(a),d.push(n)}}else{const e=a(n);e.nextDe?(d.push(e.enPart+o),l.push(e.nextDe+o)):(l.push(n+o),d.push(n+o))}}let m=l.join(\"\\n\u2022 \");l.length>0&&!m.startsWith(\"\u2022 \")&&(m=\"\u2022 \"+m);let g=d.join(\"\\n\u2022 \");return d.length>0&&!g.startsWith(\"\u2022 \")&&(g=\"\u2022 \"+g),{de:m,en:g,raw:t}}(e);return\"en\"===a.Kl?t.en||t.raw:t.de||t.raw}function g(e,t){let n;return function(...a){clearTimeout(n),n=setTimeout(()=>{clearTimeout(n),e(...a)},t)}}}},t={};function n(a){var o=t[a];if(void 0!==o)return o.exports;var s=t[a]={exports:{}};return e[a](s,s.exports,n),s.exports}n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var a=n(901);var o=n(367),s=n(842),i=n(521),r=n(672),l=n(646),d=n(413);if(!window.__KANTINE_LOADED){window.__KANTINE_LOADED=!0,function(){document.title=\"Kantine Weekly Menu\",document.querySelectorAll&&document.querySelectorAll('link[rel*=\"icon\"]').forEach(e=>e.remove());const e=document.createElement(\"link\");if(e.rel=\"icon\",e.type=\"image/png\",e.href=\"data:image/png;base64,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\",document.head.appendChild(e),!document.querySelector('link[href*=\"fonts.googleapis.com/css2?family=Inter\"]')){const e=document.createElement(\"link\");e.rel=\"stylesheet\",e.href=\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap\",document.head.appendChild(e)}if(!document.querySelector('link[href*=\"Material+Icons+Round\"]')){const e=document.createElement(\"link\");e.rel=\"stylesheet\",e.href=\"https://fonts.googleapis.com/icon?family=Material+Icons+Round\",document.head.appendChild(e)}const t=`\\n <div id=\"kantine-wrapper\">\\n <header class=\"app-header\">\\n <div class=\"header-content\">\\n <div class=\"brand\">\\n <img src=\"data:image/png;base64,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\" alt=\"Logo\" class=\"logo-img\" style=\"height: 2em; width: 2em; object-fit: contain;\">\\n <div class=\"header-left\">\\n <h1>Kantinen \u00dcbersicht <small class=\"version-tag\" style=\"font-size: 0.6em; opacity: 0.7; font-weight: 400; cursor: pointer;\" title=\"Klick f\u00fcr Versionsmen\u00fc\">v1.7.1</small></h1>\\n <div id=\"last-updated-subtitle\" class=\"subtitle\"></div>\\n </div>\\n <div class=\"nav-group\" style=\"margin-left: 1rem;\">\\n <button id=\"btn-this-week\" class=\"nav-btn active\" title=\"Men\u00fc dieser Woche anzeigen\">Diese Woche</button>\\n <button id=\"btn-next-week\" class=\"nav-btn\" title=\"Men\u00fc n\u00e4chster Woche anzeigen\">N\u00e4chste Woche</button>\\n </div>\\n <button id=\"alarm-bell\" class=\"icon-btn hidden\" aria-label=\"Benachrichtigungen\" title=\"Keine beobachteten Men\u00fcs\" style=\"margin-left: -0.5rem;\">\\n <span class=\"material-icons-round\" id=\"alarm-bell-icon\" style=\"color:var(--text-secondary); transition: color 0.3s;\">notifications</span>\\n </button>\\n </div>\\n <div class=\"header-center-wrapper\">\\n <div id=\"header-week-info\" class=\"header-week-info\"></div>\\n </div>\\n <div class=\"controls\">\\n <button id=\"btn-refresh\" class=\"icon-btn\" aria-label=\"Men\u00fcdaten aktualisieren\" title=\"Men\u00fcdaten neu laden\">\\n <span class=\"material-icons-round\">refresh</span>\\n </button>\\n <button id=\"btn-history\" class=\"icon-btn\" aria-label=\"Bestellhistorie\" title=\"Bestellhistorie\">\\n <span class=\"material-icons-round\">receipt_long</span>\\n </button>\\n <button id=\"btn-highlights\" class=\"icon-btn\" aria-label=\"Pers\u00f6nliche Highlights verwalten\" title=\"Pers\u00f6nliche Highlights verwalten\">\\n <span class=\"material-icons-round\">label</span>\\n </button>\\n <button id=\"theme-toggle\" class=\"icon-btn\" aria-label=\"Toggle Theme\" title=\"Erscheinungsbild (Hell/Dunkel) wechseln\">\\n <span class=\"material-icons-round theme-icon\">light_mode</span>\\n </button>\\n <div id=\"lang-toggle\" class=\"lang-toggle-dropdown\" title=\"Sprache der Men\u00fcbeschreibung\">\\n <button id=\"btn-lang-toggle\" class=\"icon-btn\" aria-label=\"Sprache w\u00e4hlen\" title=\"Sprache der Men\u00fcbeschreibung\">\\n <span class=\"material-icons-round\">translate</span>\\n </button>\\n <div id=\"lang-dropdown\" class=\"lang-dropdown-menu hidden\">\\n <button class=\"lang-btn${\"de\"===a.Kl?\" active\":\"\"}\" data-lang=\"de\">\ud83c\udde6\ud83c\uddf9 DE</button>\\n <button class=\"lang-btn${\"en\"===a.Kl?\" active\":\"\"}\" data-lang=\"en\">\ud83c\uddec\ud83c\udde7 EN</button>\\n <button class=\"lang-btn${\"all\"===a.Kl?\" active\":\"\"}\" data-lang=\"all\">\ud83c\udf10 ALL</button>\\n </div>\\n </div>\\n <button id=\"btn-login-open\" class=\"user-badge-btn icon-btn-small\" title=\"Mit Bessa.app Account anmelden\">\\n <span class=\"material-icons-round\">login</span>\\n <span>Anmelden</span>\\n </button>\\n <div id=\"user-info\" class=\"user-badge hidden\">\\n <span class=\"material-icons-round\">person</span>\\n <span id=\"user-id-display\"></span>\\n <button id=\"btn-logout\" class=\"icon-btn-small\" aria-label=\"Logout\" title=\"Von Bessa.app abmelden\">\\n <span class=\"material-icons-round\">logout</span>\\n </button>\\n </div>\\n </div>\\n </div>\\n </header>\\n\\n <div id=\"login-modal\" class=\"modal hidden\">\\n <div class=\"modal-content\">\\n <div class=\"modal-header\">\\n <h2>Login</h2>\\n <button id=\"btn-login-close\" class=\"icon-btn\" aria-label=\"Close\" title=\"Schlie\u00dfen\">\\n <span class=\"material-icons-round\">close</span>\\n </button>\\n </div>\\n <form id=\"login-form\">\\n <div class=\"form-group\">\\n <label for=\"employee-id\">Mitarbeiternummer</label>\\n <input type=\"text\" id=\"employee-id\" name=\"employee-id\" placeholder=\"z.B. 2041\" required>\\n <small class=\"help-text\">Deine offizielle Knapp Mitarbeiternummer.</small>\\n </div>\\n <div class=\"form-group\">\\n <label for=\"password\">Passwort</label>\\n <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Bessa Passwort\" required>\\n <small class=\"help-text\">Das Passwort f\u00fcr deinen Bessa Account.</small>\\n </div>\\n <div id=\"login-error\" class=\"error-msg hidden\"></div>\\n <div class=\"modal-actions\">\\n <button type=\"submit\" class=\"btn-primary wide\">Einloggen</button>\\n </div>\\n </form>\\n </div>\\n </div>\\n\\n <div id=\"progress-modal\" class=\"modal hidden\">\\n <div class=\"modal-content\">\\n <div class=\"modal-header\">\\n <h2>Men\u00fcdaten aktualisieren</h2>\\n </div>\\n <div class=\"modal-body\" style=\"padding: 20px;\">\\n <div class=\"progress-container\">\\n <div class=\"progress-bar\">\\n <div id=\"progress-fill\" class=\"progress-fill\"></div>\\n </div>\\n <div id=\"progress-percent\" class=\"progress-percent\">0%</div>\\n </div>\\n <p id=\"progress-message\" class=\"progress-message\">Initialisierung...</p>\\n </div>\\n </div>\\n </div>\\n\\n <div id=\"highlights-modal\" class=\"modal hidden\">\\n <div class=\"modal-content\">\\n <div class=\"modal-header\">\\n <h2>Meine Highlights</h2>\\n <button id=\"btn-highlights-close\" class=\"icon-btn\" aria-label=\"Close\" title=\"Schlie\u00dfen\">\\n <span class=\"material-icons-round\">close</span>\\n </button>\\n </div>\\n <div class=\"modal-body\">\\n <p style=\"margin-bottom: 1rem; color: var(--text-secondary);\">\\n Markiere Men\u00fcs automatisch, wenn sie diese Schlagw\u00f6rter enthalten.\\n </p>\\n <div class=\"input-group\">\\n <input type=\"text\" id=\"tag-input\" placeholder=\"z.B. Schnitzel, Vegetarisch...\" title=\"Neues Schlagwort zum Hervorheben eingeben\">\\n <button id=\"btn-add-tag\" class=\"btn-primary\" title=\"Schlagwort zur Liste hinzuf\u00fcgen\">Hinzuf\u00fcgen</button>\\n </div>\\n <div id=\"tags-list\"></div>\\n </div>\\n </div>\\n </div>\\n\\n <div id=\"history-modal\" class=\"modal hidden\">\\n <div class=\"modal-content history-modal-content\">\\n <div class=\"modal-header\">\\n <h2>Bestellhistorie</h2>\\n <button id=\"btn-history-close\" class=\"icon-btn\" aria-label=\"Close\" title=\"Schlie\u00dfen\">\\n <span class=\"material-icons-round\">close</span>\\n </button>\\n </div>\\n <div class=\"modal-body\">\\n <div id=\"history-loading\" class=\"hidden\">\\n <p id=\"history-progress-text\" style=\"text-align: center; margin-bottom: 1rem; color: var(--text-secondary);\">Lade Historie...</p>\\n <div class=\"progress-container\">\\n <div class=\"progress-bar\">\\n <div id=\"history-progress-fill\" class=\"progress-fill\"></div>\\n </div>\\n </div>\\n </div>\\n <div id=\"history-content\">\\n </div>\\n </div>\\n </div>\\n </div>\\n\\n <div id=\"version-modal\" class=\"modal hidden\">\\n <div class=\"modal-content\">\\n <div class=\"modal-header\">\\n <h2>\ud83d\udce6 Versionen</h2>\\n <button id=\"btn-version-close\" class=\"icon-btn\" aria-label=\"Close\" title=\"Schlie\u00dfen\">\\n <span class=\"material-icons-round\">close</span>\\n </button>\\n </div>\\n <div class=\"modal-body\">\\n <div style=\"margin-bottom: 1rem;\">\\n <strong>Aktuell:</strong> <span id=\"version-current\">v1.7.1</span>\\n </div>\\n <div class=\"dev-toggle\">\\n <label style=\"display:flex;align-items:center;gap:8px;cursor:pointer;\">\\n <input type=\"checkbox\" id=\"dev-mode-toggle\">\\n <span>Dev-Mode (alle Tags anzeigen)</span>\\n </label>\\n </div>\\n <div id=\"version-list-container\" style=\"margin-top:1rem; max-height: 250px; overflow-y: auto;\">\\n <p style=\"color:var(--text-secondary);\">Lade Versionen...</p>\\n </div>\\n <div style=\"margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border-color); display: flex; flex-direction: column; gap: 0.75rem; font-size: 0.9em;\">\\n <a href=\"https://github.com/TauNeutrino/kantine-overview/issues\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"color: var(--primary-color); text-decoration: none; display: flex; align-items: center; gap: 0.5rem;\" title=\"Melde einen Fehler auf GitHub\">\\n <span class=\"material-icons-round\" style=\"font-size: 1.2em;\">bug_report</span> Fehler melden\\n </a>\\n <a href=\"https://github.com/TauNeutrino/kantine-overview/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"color: var(--primary-color); text-decoration: none; display: flex; align-items: center; gap: 0.5rem;\" title=\"Schlage ein neues Feature auf GitHub vor\">\\n <span class=\"material-icons-round\" style=\"font-size: 1.2em;\">lightbulb</span> Feature vorschlagen\\n </a>\\n <button id=\"btn-clear-cache\" style=\"background: none; border: none; padding: 0; color: var(--error-color); text-decoration: none; display: flex; align-items: center; gap: 0.5rem; cursor: pointer; text-align: left; font-size: inherit; font-family: inherit;\" title=\"L\u00f6scht alle lokalen Daten & erzwingt einen Neuladen\">\\n <span class=\"material-icons-round\" style=\"font-size: 1.2em;\">delete_forever</span> Lokalen Cache leeren\\n </button>\\n </div>\\n </div>\\n </div>\\n </div>\\n\\n <main class=\"container\">\\n <div id=\"last-updated-banner\" class=\"banner hidden\">\\n <span class=\"material-icons-round\">update</span>\\n <span id=\"last-updated-text\">Gerade aktualisiert</span>\\n </div>\\n <div id=\"loading\" class=\"loading-state\">\\n <div class=\"spinner\"></div>\\n <p>Lade Men\u00fcdaten...</p>\\n </div>\\n <div id=\"menu-container\" class=\"menu-grid\"></div>\\n </main>\\n\\n <footer class=\"app-footer\">\\n <p>Jetzt Bessa Einfach! • Knapp-Kantine Wrapper • <span id=\"current-year\">${(new Date).getFullYear()}</span> by Kaufi \ud83d\ude03\ud83d\udc4d mit Hilfe von KI \ud83e\udd16</p>\\n </footer>\\n </div>`;document.body.innerHTML=t}(),function(){const e=document.getElementById(\"btn-this-week\"),t=document.getElementById(\"btn-next-week\"),n=document.getElementById(\"btn-refresh\"),c=document.getElementById(\"theme-toggle\"),u=document.getElementById(\"btn-login-open\"),m=document.getElementById(\"btn-login-close\"),g=document.getElementById(\"btn-logout\"),h=document.getElementById(\"login-form\"),p=document.getElementById(\"login-modal\"),f=document.getElementById(\"btn-highlights\"),v=document.getElementById(\"highlights-modal\"),y=document.getElementById(\"btn-highlights-close\"),b=document.getElementById(\"btn-add-tag\"),w=document.getElementById(\"tag-input\"),E=document.getElementById(\"btn-history\"),A=document.getElementById(\"history-modal\"),k=document.getElementById(\"btn-history-close\"),L=document.getElementById(\"btn-lang-toggle\"),S=document.getElementById(\"lang-dropdown\");L&&S&&L.addEventListener(\"click\",e=>{e.stopPropagation(),S.classList.toggle(\"hidden\")}),document.querySelectorAll(\".lang-btn\").forEach(e=>{e.addEventListener(\"click\",()=>{(0,a.UD)(e.dataset.lang),localStorage.setItem(i.LS.LANG,e.dataset.lang),document.querySelectorAll(\".lang-btn\").forEach(e=>e.classList.remove(\"active\")),e.classList.add(\"active\"),S&&S.classList.add(\"hidden\"),function(){const e=document.getElementById(\"btn-this-week\"),t=document.getElementById(\"btn-next-week\");e&&(e.textContent=(0,l.t)(\"thisWeek\"),e.title=(0,l.t)(\"thisWeekTooltip\")),t&&(t.textContent=(0,l.t)(\"nextWeek\"));const n=document.querySelector(\".header-left h1\");if(n){const e=n.querySelector(\".version-tag\"),t=n.querySelector(\".update-icon\");n.textContent=(0,l.t)(\"appTitle\")+\" \",e&&n.appendChild(e),t&&n.appendChild(t)}const o=document.getElementById(\"btn-refresh\");o&&o.setAttribute(\"aria-label\",(0,l.t)(\"refresh\")),o&&(o.title=(0,l.t)(\"refresh\"));const i=document.getElementById(\"btn-history\");i&&i.setAttribute(\"aria-label\",(0,l.t)(\"history\")),i&&(i.title=(0,l.t)(\"history\"));const r=document.getElementById(\"btn-highlights\");r&&r.setAttribute(\"aria-label\",(0,l.t)(\"highlights\")),r&&(r.title=(0,l.t)(\"highlights\"));const d=document.getElementById(\"theme-toggle\");d&&(d.title=(0,l.t)(\"themeTooltip\"));const c=document.getElementById(\"btn-login-open\");if(c){c.title=(0,l.t)(\"loginTooltip\");const e=c.querySelector(\"span:last-child\");e&&!e.classList.contains(\"material-icons-round\")&&(e.textContent=(0,l.t)(\"login\"))}const u=document.getElementById(\"btn-logout\");u&&(u.title=(0,l.t)(\"logoutTooltip\"));const m=document.getElementById(\"lang-toggle\");m&&(m.title=(0,l.t)(\"langTooltip\"));const g=document.querySelector(\"#highlights-modal .modal-header h2\");g&&(g.textContent=(0,l.t)(\"highlightsTitle\"));const h=document.querySelector(\"#highlights-modal .modal-body > p\");h&&(h.textContent=(0,l.t)(\"highlightsDesc\"));const p=document.getElementById(\"tag-input\");p&&(p.placeholder=(0,l.t)(\"tagInputPlaceholder\"),p.title=(0,l.t)(\"tagInputTooltip\"));const f=document.getElementById(\"btn-add-tag\");f&&(f.textContent=(0,l.t)(\"addTag\"),f.title=(0,l.t)(\"addTagTooltip\"));const v=document.querySelector(\"#history-modal .modal-header h2\");v&&(v.textContent=(0,l.t)(\"historyTitle\"));const y=document.querySelector(\"#login-modal .modal-header h2\");y&&(y.textContent=(0,l.t)(\"loginTitle\"));const b=document.getElementById(\"alarm-bell\");b&&0===a.BY.size&&(b.title=(0,l.t)(\"alarmTooltipNone\")),(0,s.OR)(),(0,s.gJ)(),(0,s.Mb)()}()})}),f&&f.addEventListener(\"click\",()=>{(0,o.Y1)(),v.classList.remove(\"hidden\")}),y&&y.addEventListener(\"click\",()=>{v.classList.add(\"hidden\")}),E.addEventListener(\"click\",()=>{a.gX?(A.classList.remove(\"hidden\"),(0,o.Aq)()):p.classList.remove(\"hidden\")}),k.addEventListener(\"click\",()=>{A.classList.add(\"hidden\")}),window.addEventListener(\"click\",e=>{e.target===A&&A.classList.add(\"hidden\"),e.target===v&&v.classList.add(\"hidden\"),!S||S.classList.contains(\"hidden\")||e.target.closest(\"#lang-toggle\")||S.classList.add(\"hidden\")});const I=document.querySelector(\".version-tag\"),C=document.getElementById(\"version-modal\"),T=document.getElementById(\"btn-version-close\");I&&I.addEventListener(\"click\",e=>{e.preventDefault(),e.stopPropagation(),(0,s.Gk)()}),T&&T.addEventListener(\"click\",()=>{C.classList.add(\"hidden\")});const B=document.getElementById(\"btn-clear-cache\");B&&B.addEventListener(\"click\",()=>{confirm(\"M\u00f6chtest du wirklich alle lokalen Daten (inkl. Login-Session, Cache und Einstellungen) l\u00f6schen? Die Seite wird danach neu geladen.\")&&(Object.keys(localStorage).forEach(e=>{e.startsWith(\"kantine_\")&&localStorage.removeItem(e)}),window.location.reload())}),window.addEventListener(\"click\",e=>{e.target===C&&C.classList.add(\"hidden\")}),b.addEventListener(\"click\",()=>{const e=w.value;(0,o.oL)(e)&&(w.value=\"\",(0,o.Y1)())}),w.addEventListener(\"keypress\",e=>{\"Enter\"===e.key&&b.click()});const D=localStorage.getItem(\"theme\"),x=window.matchMedia(\"(prefers-color-scheme: dark)\").matches,O=c.querySelector(\".theme-icon\");\"dark\"===D||!D&&x?(document.documentElement.setAttribute(\"data-theme\",\"dark\"),O.textContent=\"dark_mode\"):(document.documentElement.setAttribute(\"data-theme\",\"light\"),O.textContent=\"light_mode\"),c.addEventListener(\"click\",()=>{const e=\"dark\"===document.documentElement.getAttribute(\"data-theme\")?\"light\":\"dark\";document.documentElement.setAttribute(\"data-theme\",e),localStorage.setItem(\"theme\",e),O.textContent=\"dark\"===e?\"dark_mode\":\"light_mode\"}),e.addEventListener(\"click\",()=>{\"this-week\"!==a.sw&&((0,a.qo)(\"this-week\"),e.classList.add(\"active\"),t.classList.remove(\"active\"),(0,s.OR)())}),t.addEventListener(\"click\",()=>{t.classList.remove(\"new-week-available\"),\"next-week\"!==a.sw&&((0,a.qo)(\"next-week\"),t.classList.add(\"active\"),e.classList.remove(\"active\"),(0,s.OR)())}),n.addEventListener(\"click\",()=>{a.gX?(0,o.m9)():p.classList.remove(\"hidden\")});const M=document.getElementById(\"alarm-bell\");M&&M.addEventListener(\"click\",()=>{(0,o.A0)()}),u.addEventListener(\"click\",()=>{p.classList.remove(\"hidden\"),document.getElementById(\"login-error\").classList.add(\"hidden\"),h.reset()}),m.addEventListener(\"click\",()=>{p.classList.add(\"hidden\")}),window.addEventListener(\"click\",e=>{e.target===p&&p.classList.add(\"hidden\")}),h.addEventListener(\"submit\",async e=>{e.preventDefault();const t=document.getElementById(\"employee-id\").value.trim(),n=document.getElementById(\"password\").value,s=document.getElementById(\"login-error\"),l=h.querySelector('button[type=\"submit\"]'),d=l.textContent;l.disabled=!0,l.textContent=\"Wird eingeloggt...\";try{const e=`knapp-${t}@bessa.app`,l=await fetch(`${i.tE}/auth/login/`,{method:\"POST\",headers:(0,r.H)(i.GUEST_TOKEN),body:JSON.stringify({email:e,password:n})}),d=await l.json();if(l.ok){(0,a.O5)(d.key),(0,a.lt)(t),localStorage.setItem(i.LS.AUTH_TOKEN,d.key),localStorage.setItem(i.LS.CURRENT_USER,t);try{const e=await fetch(`${i.tE}/auth/user/`,{headers:(0,r.H)(d.key)});if(e.ok){const t=await e.json();t.first_name&&localStorage.setItem(i.LS.FIRST_NAME,t.first_name),t.last_name&&localStorage.setItem(i.LS.LAST_NAME,t.last_name)}}catch(e){console.error(\"Failed to fetch user info:\",e)}(0,o.i_)(),p.classList.add(\"hidden\"),(0,o.Gb)(),h.reset(),(0,o.g8)(),(0,o.m9)()}else s.textContent=d.non_field_errors?.[0]||d.error||\"Login fehlgeschlagen\",s.classList.remove(\"hidden\")}catch(e){console.error(\"Login error:\",e),s.textContent=\"Ein Fehler ist aufgetreten\",s.classList.remove(\"hidden\")}finally{l.disabled=!1,l.textContent=d}}),g.addEventListener(\"click\",()=>{localStorage.removeItem(i.LS.AUTH_TOKEN),localStorage.removeItem(i.LS.CURRENT_USER),localStorage.removeItem(i.LS.FIRST_NAME),localStorage.removeItem(i.LS.LAST_NAME),(0,a.O5)(null),(0,a.lt)(null),(0,a.di)(new Map),(0,o.Et)(),(0,o.i_)(),(0,s.OR)()}),window.addEventListener(\"resize\",(0,d.sg)(()=>{const e=document.querySelector(\".days-grid\");e&&(0,s.wy)(e)},150))}(),(0,o.i_)(),(0,o.H)();(0,o.KG)()?(document.getElementById(\"loading\").classList.add(\"hidden\"),(0,o.VL)()||(0,o.m9)()):(0,o.m9)(),a.gX&&(0,o.g8)(),(0,s.Ux)(),setInterval(s.Ux,36e5)}})();\n"; document.head.appendChild(sc); })();
|