{"version":3,"file":"yuuvis-client-framework.mjs","sources":["../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-excluded-elements.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-navigation-keys.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-offset.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/halo-focus-defaults/halo-focus-styles.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/pwa-update/pwa-update-default-check-interval.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/session/session-default-duration.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/session/session-activity-window-before-end.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/config/session/session-popup-before-end.const.ts","../../../../../libs/yuuvis/client-framework/src/lib/enums/channel-message.enum.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/halo-focus/halo-focus.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/halo-utility/halo-utility.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/pwa-update/pwa-update.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/snack-bar/snack-bar.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/services/session/session.service.ts","../../../../../libs/yuuvis/client-framework/src/lib/providers/halo-focus/provide-halo-focus.ts","../../../../../libs/yuuvis/client-framework/src/lib/providers/pwa-update/provide-pwa-update.ts","../../../../../libs/yuuvis/client-framework/src/lib/providers/session/provide-session.provider.ts","../../../../../libs/yuuvis/client-framework/src/lib/yuuvis-client-framework.module.ts","../../../../../libs/yuuvis/client-framework/src/yuuvis-client-framework.ts"],"sourcesContent":["/**\n * List of element selectors that should be excluded from halo focus\n * when they are inside a Material form field component (mat-form-field).\n *\n * These elements typically have their own built-in focus indicators provided\n * by Angular Material, making the halo focus redundant or visually conflicting.\n *\n * **Included Selectors:**\n * - `input` - Text inputs, number inputs, etc. inside mat-form-field\n * - `textarea` - Multi-line text inputs inside mat-form-field\n * - `mat-select` - Material select dropdowns inside mat-form-field\n *\n * **Why Exclude These:**\n * Angular Material form fields provide their own focus styling with floating labels,\n * underlines, and color changes. Adding a halo around these elements would:\n * - Create visual clutter and redundancy\n * - Potentially conflict with Material's focus styling\n * - Reduce the clarity of Material Design's established patterns\n *\n * **Note:** These elements will still receive halo focus if they appear OUTSIDE\n * of mat-form-field containers. The exclusion only applies when they're wrapped\n * in a mat-form-field.\n *\n * @see {@link HaloUtilityService.shouldSkipElementInMatFormField} for implementation\n */\nexport const haloExcludedElementsInMatFormField = ['input', 'textarea', 'mat-select'];\n","/**\n * List of keyboard navigation keys that trigger halo position updates.\n *\n * When any of these keys are pressed while an element is focused, the halo service\n * schedules an immediate position update to ensure the halo follows the focused element\n * if it moves within the page (e.g., scrolling a list, moving through a table).\n *\n * **Included Keys:**\n * - `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown` - Directional navigation\n * - `Home`, `End` - Jump to start/end of content\n * - `PageUp`, `PageDown` - Page-level scrolling\n *\n * **Why This Matters:**\n * Arrow keys and navigation keys can cause the focused element to scroll or move within\n * its container (e.g., scrolling a select dropdown, moving focus in a grid). By tracking\n * these keys, the halo can immediately update its position to follow the element, preventing\n * visual misalignment.\n *\n * **Performance Note:**\n * Updates are scheduled using requestAnimationFrame, so even rapid key presses won't\n * cause performance issues.\n *\n * @see {@link HaloFocusService} for the implementation of keydown handling\n */\nexport const haloFocusNavigationKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown'];\n","/**\n * Default offset (in pixels) between the halo border and the focused element's edges.\n *\n * This value determines how far the halo appears from the focused element:\n * - **Positive value** (default: 3): Halo appears outside the element\n * - **Zero (0)**: Halo aligns exactly with element edges (neutral offset)\n * - **Negative value**: Halo appears inside the element (inset)\n *\n * **Override Methods:**\n * - **Per-element**: Use `halo-offset=\"value\"` attribute\n * - **Per-container**: Use `halo-container-offset=\"value\"` or preset attributes\n *\n * @example\n * ```html\n * <!-- Uses default 3px offset (outside) -->\n * <button>Default</button>\n *\n * <!-- Custom 5px offset -->\n * <input halo-offset=\"5\" />\n *\n * ```\n *\n * @default 3\n */\nexport const defaultHaloFocusOffset = 3;\n","/**\n * Default CSS styles for the halo focus element.\n *\n * These styles define the visual appearance and behavior of the halo border that\n * highlights keyboard-focused elements. The halo is a fixed-position overlay that\n * follows the focused element across the page.\n *\n * **Style Properties:**\n * - `position: 'fixed'` - Keeps halo in viewport regardless of scroll position\n * - `pointerEvents: 'none'` - Allows click-through; halo doesn't block interactions\n * - `zIndex: '9999'` - Ensures halo appears above most other elements\n * - `border` - Primary border using CSS variable `--ymt-primary` (2px solid)\n * - `boxShadow` - Soft shadow with 20% opacity for subtle depth effect\n * - `borderRadius` - Default 8px rounded corners for modern appearance\n * - `opacity: '0'` - Initially hidden; visibility controlled by service\n * - `transform: 'translateZ(0)'` - Creates GPU layer for smoother animations\n *\n * **CSS Variable Dependencies:**\n * - `--ymt-primary` - Primary theme color for border and shadow\n *\n * **Note:** These are base styles that can be overridden globally via HaloFocusConfig\n * or per-element using halo-* attributes.\n *\n * @see {@link HaloFocusConfig} for global style customization\n */\nexport const haloFocusStyles: Partial<CSSStyleDeclaration> = {\n  position: 'fixed',\n  pointerEvents: 'none',\n  zIndex: '9999',\n  border: '2px solid var(--ymt-primary)',\n  boxShadow: '0 0 0 4px rgba(from var(--ymt-primary) r g b / 0.2)',\n  borderRadius: '8px',\n  opacity: '0',\n  transform: 'translateZ(0)'\n};\n","/**\n * Default interval (in milliseconds) for periodic PWA update checks.\n *\n * After the application stabilizes, {@link PwaUpdateService} polls the service\n * worker for a newer deployed version on this interval. This complements the\n * `VERSION_READY` event, which only fires while the tab is open and the service\n * worker happens to detect a change — long-running sessions would otherwise\n * never learn about a new release.\n *\n * Override via `providePwaUpdate({ checkInterval })`. Set `checkInterval` to `0`\n * to disable polling and rely solely on `VERSION_READY`.\n *\n * @default 6 hours (21600000 milliseconds)\n */\nexport const pwaUpdateDefaultCheckInterval = 6 * 60 * 60 * 1000; // 6 hours\n","/**\n * Default session duration (in milliseconds) when no explicit duration is provided.\n *\n * This value is used as the fallback session lifetime when:\n * - `provideSession()` is called without a duration parameter\n * - Before `startSession(duration)` is called with a backend-provided value\n *\n * **Timeline:**\n * ```\n * [Session Start] ──────────────────────────────► [Session Expires]\n *                 ← sessionDefaultDuration →\n * ```\n *\n * **Override Methods:**\n * - **At startup (known duration)**: `provideSession(customDuration)`\n * - **After login (dynamic duration)**: `sessionService.startSession(backendDuration)`\n *\n * **Usage Scenarios:**\n *\n * Scenario 1 - Fixed duration:\n * ```ts\n * // app.config.ts\n * providers: [\n *   provideSession(45 * 60 * 1000) // Override to 45 minutes\n * ]\n * ```\n *\n * Scenario 2 - Backend-provided duration:\n * ```ts\n * // app.config.ts\n * providers: [\n *   provideSession() // Uses default 30 minutes initially\n * ]\n *\n * // auth.service.ts (after login)\n * login().subscribe(response => {\n *   sessionService.startSession(response.sessionExpiresIn); // Update to backend value\n * });\n * ```\n *\n * **Related Constants:**\n * - {@link sessionActivityWindowBeforeEnd} - When to start tracking user activity\n * - {@link sessionPopupBeforeEnd} - When to show the expiry warning popup\n *\n * @default 30 minutes (1800000 milliseconds)\n */\nexport const sessionDefaultDuration = 30 * 60 * 1000; // 30 minutes","/**\n * Time window (in milliseconds) before session expiry when user activity triggers auto-extension.\n *\n * During this window, the service tracks user interactions (mouse, keyboard, scroll) and HTTP activity.\n * If any activity is detected, the session is automatically extended, preventing the expiry warning popup.\n *\n * **Session Timeline:**\n * ```\n * [Session Start] ──────────────────────────────► [Session Expires]\n *                                     ▲         ▲\n *                                     │         └─ sessionPopupBeforeEnd (1 min)\n *                                     └─ Activity window starts (2 min)\n *\n * ┌─────────────────────────────────────────────┐\n * │ Activity Window (2 minutes)                 │\n * │ • Tracks: mousemove, keydown, click, scroll │\n * │ • Tracks: HTTP requests (debounced)         │\n * │ • If activity detected → auto-extend        │\n * │ • If no activity → show warning popup       │\n * └─────────────────────────────────────────────┘\n * ```\n *\n * **Why This Matters:**\n * - Prevents unnecessary interruptions for active users\n * - Reduces server-side session renewal traffic by batching extensions\n * - Provides a grace period before showing the expiry warning\n *\n * **Tracked Activities:**\n * - **User interactions**: `mousemove`, `keydown`, `click`, `scroll` on `window`\n * - **HTTP traffic**: Any request via `BackendService.httpCommunicationOccurred$` (debounced 500ms)\n *\n * **Interaction with Other Constants:**\n * - Must be **greater than** {@link sessionPopupBeforeEnd} to allow the activity window before the popup\n * - Typical relationship: `activityWindow > popupWarning` (e.g., 2 min > 1 min)\n *\n * **Performance Note:**\n * Activity tracking is only active during this window, not throughout the entire session,\n * minimizing performance impact of event listeners.\n *\n * @default 2 minutes (120000 milliseconds)\n * @see {@link SessionService.setupUserActivityTracking} for implementation details\n */\nexport const sessionActivityWindowBeforeEnd = 2 * 60 * 1000; // 2 minutes","/**\n * Time (in milliseconds) before session expiry when the warning popup is displayed.\n *\n * When this threshold is reached without detected user activity during the activity window,\n * a snackbar notification appears, warning the user that their session will expire soon\n * and providing an \"Extend session\" action button.\n *\n * **Session Timeline:**\n * ```\n * [Session Start] ──────────────────────────────► [Session Expires]\n *                            ▲                 ▲\n *                            │                 └─ Popup appears (1 min before expiry)\n *                            └─ Activity window starts (2 min before expiry)\n *\n * User has no activity during the 2-minute window:\n * ├─ 2 min before: Activity tracking starts\n * ├─ 1 min before: ⚠️ Popup shows \"Session expires in one minute\"\n * └─ 0 min: Auto-logout if no action taken\n * ```\n *\n * **Popup Behavior:**\n * - Displays a warning message: \"Session expires in one minute\"\n * - Provides an action button: \"Extend session\"\n * - Clicking \"Extend session\" → extends session by the full session duration\n * - Ignoring the popup → automatic logout when timer reaches zero\n * - Only one popup is shown at a time (subsequent extensions dismiss the existing popup)\n *\n * **Cross-Tab Synchronization:**\n * If the user extends the session in one browser tab, all other tabs:\n * - Automatically dismiss their popups (if shown)\n * - Reset their timers to the new expiry time\n * - Avoid showing redundant warnings\n *\n * **Interaction with Other Constants:**\n * - Must be **less than** {@link sessionActivityWindowBeforeEnd}\n * - Typical relationship: `activityWindow > popupWarning` (e.g., 2 min > 1 min)\n * - The gap between them determines how long the activity window runs before the popup\n *\n * **UX Considerations:**\n * - **1 minute** gives users enough time to react without being too intrusive\n * - Too short (e.g., 10 seconds): Users may not have time to respond\n * - Too long (e.g., 5 minutes): Users may be unnecessarily interrupted if they return\n *\n * @default 1 minute (60000 milliseconds)\n * @see {@link SessionService.showPopup} for popup implementation\n */\nexport const sessionPopupBeforeEnd = 60 * 1000; // 1 minute","export enum ChannelMessage {\n  SessionExtended = 'SessionExtended',\n  SessionLogout = 'SessionLogout'\n}\n","import { inject, Injectable } from '@angular/core';\nimport { HaloUtilityService } from '..';\nimport { haloFocusNavigationKeys } from '../../config';\nimport { HaloFocusConfig } from '../../models';\n\n/**\n * Service that creates and manages a visual \"halo\" border around keyboard-focused elements\n * to enhance navigation visibility and improve accessibility.\n *\n * This service operates globally across the application, automatically tracking focus events\n * and dynamically positioning a halo element around the currently focused element. The halo\n * responds to window scrolls, resizes, and DOM mutations to maintain accurate positioning.\n *\n * **Key Features:**\n * - Keyboard-only focus indication (respects :focus-visible)\n * - Performance-optimized with requestAnimationFrame and runs outside Angular zone\n * - Element-level and container-level customization support\n * - Automatic visibility detection (handles clipping, hidden elements, etc.)\n * - Responsive to dynamic DOM changes via ResizeObserver and MutationObserver\n * - Smart exclusion for Angular Material form fields (prevents redundant styling)\n *\n * **Usage:**\n * 1. Add `provideHaloFocus()` to your providers array in app.config.ts\n * 2. The service initializes automatically and appends a halo element to the DOM\n * 3. Optionally customize appearance globally or per-element using attributes\n *\n * **Element-Level Attributes:**\n * - `halo-skip` - Excludes element from halo highlighting\n * - `halo-color=\"color\"` - Custom halo color (e.g., \"blue\", \"#00ff00\", \"rgb(255,0,0)\")\n * - `halo-offset=\"value\"` - Custom numeric offset in pixels (default: 3)\n *\n * **Container-Level Attributes:**\n * Define default halo styles for all focused children. Child elements can override\n * container settings with their own halo-* attributes.\n *\n * - `halo-container` - Marks element as a halo container (required for other attributes)\n * - `halo-container-skip` - Excludes all focused children from halo highlighting\n * - `halo-container-color=\"color\"` - Default halo color for focused children\n * - `halo-container-offset=\"value\"` - Default offset for focused children\n *\n * **Material Form Field Integration:**\n * Elements inside Angular Material form fields (mat-form-field) are automatically excluded\n * from halo focus to prevent visual conflicts with Material's built-in focus styling.\n * Excluded elements: input, mat-select (configurable via haloExcludedElementsInMatFormField)\n *\n * @example\n * ```html\n * <!-- Element-level customization -->\n * <button halo-color=\"red\">Custom Red Halo</button>\n * <input halo-offset=\"5\" />\n * <select halo-skip>No Halo</select>\n *\n * <!-- Container-level defaults -->\n * <form halo-container halo-container-color=\"blue\" halo-container-offset=\"5\">\n *   <input /> <!-- Inherits blue color and 5px offset -->\n *   <button halo-color=\"red\">Submit</button> <!-- Overrides with red, keeps 5px offset -->\n * </form>\n * ```\n *\n * **Performance Notes:**\n * - Service runs outside Angular's zone to prevent unnecessary change detection\n * - Uses requestAnimationFrame for smooth rendering\n * - Only shows halo for keyboard interactions (respects :focus-visible)\n *\n * @see {@link provideHaloFocus} for initialization and configuration\n * @see {@link HaloFocusConfig} for global configuration options\n */\n@Injectable({\n  providedIn: 'root'\n})\nexport class HaloFocusService {\n  //#region  Properties\n\n  #utility = inject(HaloUtilityService);\n  #config: HaloFocusConfig | undefined;\n\n  #haloElement: HTMLDivElement | null = null;\n  #currentElement: HTMLElement | null = null;\n  #lastInteractionWasKeyboard = false;\n\n  #rafId: number | null = null; //Request Animation Frame ID\n  #resizeObserver?: ResizeObserver;\n  #mutationObserver?: MutationObserver;\n\n  //#endregion\n\n  //#region Init\n\n  /**\n   * Initializes the Halo Focus service and sets up the global halo tracking system.\n   *\n   * This method performs the following initialization steps:\n   * 1. Applies optional configuration for halo appearance (inner and outer colors)\n   * 2. Creates and appends the halo DIV element to the document body\n   * 3. Attaches global event listeners for focus, blur, keyboard, mouse, scroll, and resize events\n   * 4. Sets up ResizeObserver and MutationObserver for tracking dynamic DOM changes\n   *\n   * **Lifecycle:**\n   * - Called automatically by `provideHaloFocus()` during app initialization\n   * - Runs outside Angular's zone to prevent triggering change detection\n   * - Initializes only once per application lifecycle\n   *\n   * **Performance:**\n   * - Uses passive event listeners where applicable\n   * - Leverages requestAnimationFrame for efficient rendering\n   * - Observers are conditionally created only if browser supports them\n   *\n   * @param config - Optional configuration object for customizing halo appearance\n   * @param config.innerColor - Custom inner color (overrides default primary color)\n   * @param config.outerColor - Custom outer color (overrides default shadow)\n   *\n   * @internal This method should not be called manually; use `provideHaloFocus()` instead\n   */\n  init(config?: HaloFocusConfig): void {\n    this.#initConfig(config);\n    this.#appendHaloElementToDOM();\n    this.#initListeners();\n    this.#initObservers();\n  }\n\n  #initConfig(config?: HaloFocusConfig): void {\n    this.#config = config;\n  }\n\n  #appendHaloElementToDOM(): void {\n    this.#haloElement = document.createElement('div');\n    this.#haloElement.id = 'focus-halo';\n    this.#haloElement.setAttribute('aria-hidden', 'true');\n    Object.assign(this.#haloElement.style, this.#utility.getHaloFocusStyles(this.#config));\n    document.body.appendChild(this.#haloElement);\n  }\n\n  #initListeners(): void {\n    document.addEventListener('focus', this.#onFocus, true);\n    document.addEventListener('blur', this.#onBlur, true);\n    window.addEventListener('scroll', this.#scheduleUpdate, true);\n    window.addEventListener('resize', this.#scheduleUpdate);\n    document.addEventListener('keydown', this.#onKeydown, true);\n    document.addEventListener('mousedown', this.#onMouseDown, true);\n  }\n\n  #initObservers(): void {\n    if ('ResizeObserver' in window) {\n      this.#resizeObserver = new ResizeObserver(() => {\n        if (this.#currentElement) this.#scheduleUpdate();\n      });\n    }\n\n    if ('MutationObserver' in window) {\n      this.#mutationObserver = new MutationObserver(() => {\n        if (this.#currentElement) this.#scheduleUpdate();\n      });\n    }\n  }\n\n  // #endregion\n\n  //#region Rendering\n\n  readonly #updateHaloRect = (): void => {\n    if (!this.#currentElement || !this.#haloElement || !document.contains(this.#currentElement)) {\n      if (this.#haloElement) {\n        this.#haloElement.style.opacity = '0';\n      }\n      this.#currentElement = null;\n      return;\n    }\n\n    // Check if element is actually visible\n    if (!this.#utility.isElementVisible(this.#currentElement)) {\n      this.#haloElement.style.opacity = '0';\n      return;\n    }\n\n    this.#utility.setHaloElementSize(this.#currentElement, this.#haloElement);\n    this.#utility.setCustomColor(this.#currentElement, this.#haloElement, this.#config);\n    this.#haloElement.style.opacity = '1';\n  };\n\n  readonly #scheduleUpdate = (): void => {\n    if (this.#rafId != null) cancelAnimationFrame(this.#rafId);\n    this.#rafId = requestAnimationFrame(this.#updateHaloRect);\n  };\n\n  #startTracking(target: HTMLElement): void {\n    this.#currentElement = target;\n    this.#scheduleUpdate();\n\n    // Track size changes on target element\n    if (this.#resizeObserver) {\n      this.#resizeObserver.observe(target);\n\n      // Also observe all parent elements with overflow (they might clip the element)\n      let parent = target.parentElement;\n      while (parent && parent !== document.body) {\n        const style = getComputedStyle(parent);\n        const overflow = style.overflow + style.overflowX + style.overflowY;\n        if (\n          overflow.includes('hidden') ||\n          overflow.includes('clip') ||\n          overflow.includes('auto') ||\n          overflow.includes('scroll')\n        ) {\n          this.#resizeObserver.observe(parent);\n        }\n        parent = parent.parentElement;\n      }\n    }\n\n    // Track style/attribute changes (for position, transform changes)\n    if (this.#mutationObserver) {\n      this.#mutationObserver.observe(target, {\n        attributes: true,\n        attributeFilter: ['style', 'class'],\n        subtree: false\n      });\n    }\n  }\n\n  #stopTracking(): void {\n    if (this.#resizeObserver) this.#resizeObserver.disconnect();\n    if (this.#mutationObserver) this.#mutationObserver.disconnect();\n  }\n  //#endregion\n\n  //#region Event handlers\n\n  readonly #onKeydown = (event: KeyboardEvent): void => {\n    this.#lastInteractionWasKeyboard = true;\n    // Track arrow keys and other navigation keys that might move focused element\n    if (this.#currentElement && haloFocusNavigationKeys.includes(event.key)) {\n      this.#scheduleUpdate();\n    }\n  };\n\n  readonly #onMouseDown = (): void => {\n    this.#lastInteractionWasKeyboard = false;\n    if (this.#haloElement) {\n      this.#haloElement.style.opacity = '0';\n      this.#currentElement = null;\n      this.#stopTracking();\n    }\n  };\n\n  readonly #onFocus = (focusEvent: FocusEvent): void => {\n    const target = focusEvent.target as HTMLElement;\n    if (!this.#utility.isFocusable(target)) return;\n\n    const container = this.#utility.getHaloContainer(target);\n\n    // Check all skip conditions\n    if (\n      target.hasAttribute('halo-skip') ||\n      this.#utility.shouldSkipElementInMatFormField(target) ||\n      container?.hasAttribute('halo-container-skip') ||\n      !this.#utility.matchesFocusVisible(target, this.#lastInteractionWasKeyboard)\n    ) {\n      if (this.#haloElement) {\n        this.#haloElement.style.opacity = '0';\n      }\n      this.#currentElement = null;\n      return;\n    }\n\n    this.#stopTracking();\n    this.#startTracking(target);\n  };\n\n  readonly #onBlur = (focusEvent: FocusEvent): void => {\n    if ((focusEvent.target as HTMLElement) === this.#currentElement && this.#haloElement) {\n      this.#haloElement.style.opacity = '0';\n      this.#currentElement = null;\n      this.#stopTracking();\n    }\n  };\n\n  //#endregion\n\n  /** Optional: allow manual control from directives/components */\n  // public showFor(el: HTMLElement) {\n  //   this.#currentEl = el;\n  //   this.#scheduleUpdate();\n  //   if (this.#ro) {\n  //     this.#ro.disconnect();\n  //     this.#ro.observe(el);\n  //   }\n  // }\n\n  // public hide() {\n  //   if (this.#haloEl) this.#haloEl.style.opacity = '0';\n  //   this.#currentEl = null;\n  //   if (this.#ro) this.#ro.disconnect();\n  // }\n}\n","import { Injectable } from '@angular/core';\nimport { defaultHaloFocusOffset, haloFocusStyles, haloExcludedElementsInMatFormField } from '../../config';\nimport { HaloFocusConfig } from '../../models';\n\n/**\n * Utility service providing helper methods for the Halo Focus feature.\n *\n * This service contains pure utility functions for:\n * - Element validation (focusability, visibility, focus-visible state)\n * - Material form field detection and exclusion logic\n * - Style calculations (colors, offsets, positioning)\n * - DOM traversal (finding halo containers, checking parent visibility)\n * - Halo element manipulation (size, color, position)\n *\n * **Scope & Performance:**\n * This service is intentionally NOT provided in root (`providedIn: 'root'` is omitted).\n * Instead, it's provided locally via `provideHaloFocus()`, ensuring it's only instantiated\n * when the Halo Focus feature is actually used. This optimization prevents unnecessary\n * service creation in applications that don't use halo focus.\n *\n * **Note:** This service is used exclusively by `HaloFocusService` and should not be\n * injected or used elsewhere in the application.\n *\n * @internal\n */\n@Injectable()\nexport class HaloUtilityService {\n  //#region Validations\n\n  /**\n   * Checks if an element is focusable (can receive keyboard focus).\n   *\n   * An element is considered focusable if:\n   * - It has a non-negative tabIndex (>= 0), OR\n   * - It's a natively focusable element (A, BUTTON, INPUT, SELECT, TEXTAREA), OR\n   * - It has contentEditable enabled\n   *\n   * @param element - Element to check\n   * @returns true if element can receive focus, false otherwise\n   */\n  isFocusable(element: Element | null): element is HTMLElement {\n    if (!element) return false;\n    const h = element as HTMLElement;\n    if (h.tabIndex >= 0) return true;\n    return /^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(h.tagName) || h.isContentEditable;\n  }\n\n  /**\n   * Checks if an element is inside a Material form field (mat-form-field).\n   *\n   * Traverses up the DOM tree from the element to check if any parent\n   * has the `mat-form-field` tag name. This is used to determine if\n   * certain elements should skip halo focus because they're already\n   * styled by Angular Material.\n   *\n   * **Search Scope:**\n   * - Starts from element itself\n   * - Stops at document.body\n   * - Returns true on first mat-form-field match\n   *\n   * @param element - The element to check\n   * @returns true if element is inside a mat-form-field, false otherwise\n   */\n  isElementInsideMatFormField(element: HTMLElement): boolean {\n    let current: HTMLElement | null = element;\n    while (current && current !== document.body) {\n      if (current.tagName.toLowerCase() === 'mat-form-field') {\n        return true;\n      }\n      current = current.parentElement;\n    }\n    return false;\n  }\n\n  /**\n   * Determines if an element should be excluded from halo focus when inside mat-form-field.\n   *\n   * Checks two conditions:\n   * 1. Element tag name matches one of the excluded selectors (input, mat-select, etc.)\n   * 2. Element is inside a mat-form-field component\n   *\n   * If both conditions are true, the element should skip halo focus because\n   * Angular Material already provides adequate focus styling.\n   *\n   * **Excluded Elements (configurable via haloExcludedElementsInMatFormField):**\n   * - `input` elements inside mat-form-field\n   * - `textarea` elements inside mat-form-field\n   * - `mat-select` elements inside mat-form-field\n   *\n   * **Note:** Elements outside mat-form-field will NOT be skipped, even if\n   * their tag matches the exclusion list.\n   *\n   * @param element - The focused element to check\n   * @returns true if element should be skipped (no halo), false if halo should be shown\n   */\n  shouldSkipElementInMatFormField(element: HTMLElement): boolean {\n    const tagName = element.tagName.toLowerCase();\n    const isExcludedElement = haloExcludedElementsInMatFormField.includes(tagName);\n\n    if (!isExcludedElement) {\n      return false;\n    }\n\n    return this.isElementInsideMatFormField(element);\n  }\n\n  /**\n   * Determines if an element should display the halo based on :focus-visible state.\n   *\n   * This method respects the CSS :focus-visible pseudo-class, which indicates that\n   * focus was triggered by keyboard navigation (not mouse clicks). The halo only appears\n   * when both conditions are met:\n   * 1. Element matches :focus-visible (browser determines this)\n   * 2. Last user interaction was via keyboard (tracked by service)\n   *\n   * **Fallback:** If browser doesn't support :focus-visible, falls back to checking\n   * lastInteractionWasKeyboard only.\n   *\n   * @param element - The currently focused element\n   * @param lastInteractionWasKeyboard - Whether the last interaction was a keyboard event\n   * @returns true if halo should be visible, false otherwise\n   */\n  matchesFocusVisible(element: HTMLElement, lastInteractionWasKeyboard: boolean): boolean {\n    try {\n      const matches = element.matches(':focus-visible');\n      if (!matches) return false;\n      return matches && lastInteractionWasKeyboard;\n    } catch {\n      return lastInteractionWasKeyboard;\n    }\n  }\n\n  /**\n   * Checks if an element is actually visible on the page.\n   *\n   * Performs comprehensive visibility checks including:\n   * - Element has non-zero dimensions (width and height > 0)\n   * - Element is not hidden via CSS (display: none, visibility: hidden, opacity: 0)\n   * - Element is not clipped by parent containers with overflow: hidden/clip\n   * - All parent elements in the hierarchy are visible\n   *\n   * This prevents the halo from appearing around technically focused but visually\n   * hidden elements (e.g., elements in collapsed sections, off-screen elements).\n   *\n   * @param element - Element to check for visibility\n   * @returns true if element is visible to the user, false otherwise\n   */\n  isElementVisible(element: HTMLElement): boolean {\n    const rect = element.getBoundingClientRect();\n\n    // Check if element has dimensions\n    if (rect.width === 0 || rect.height === 0) {\n      return false;\n    }\n\n    // Check computed style on element itself\n    const style = getComputedStyle(element);\n    if (style.visibility === 'hidden' || style.display === 'none' || parseFloat(style.opacity) === 0) {\n      return false;\n    }\n\n    // Check if element is clipped by overflow:hidden parent OR if any parent is hidden\n    return this.isParentVisible(element, rect);\n  }\n\n  /**\n   * Calculates the visible portion of an element considering overflow clipping from parent containers.\n   *\n   * Traverses up the DOM tree checking for parents with overflow clipping (hidden/clip/auto/scroll).\n   * For each clipping parent, calculates the intersection between the element's current visible area\n   * and the parent's boundaries, progressively clipping the visible rectangle.\n   *\n   * This is essential for showing halo focus only around the visible portion of elements that are\n   * partially scrolled out of view.\n   *\n   * @param element - The element to calculate visible rectangle for\n   * @returns The visible rectangle, or null if element is completely hidden\n   */\n  getVisibleRect(element: HTMLElement): DOMRect | null {\n    let rect = element.getBoundingClientRect();\n    let visibleRect = {\n      left: rect.left,\n      top: rect.top,\n      right: rect.right,\n      bottom: rect.bottom,\n      width: rect.width,\n      height: rect.height\n    };\n\n    let parent = element.parentElement;\n    while (parent && parent !== document.body) {\n      const parentStyle = getComputedStyle(parent);\n\n      // Check if parent is hidden\n      if (parentStyle.display === 'none' || parentStyle.visibility === 'hidden' || parseFloat(parentStyle.opacity) === 0) {\n        return null;\n      }\n\n      const parentOverflow = parentStyle.overflow + parentStyle.overflowX + parentStyle.overflowY;\n\n      if (parentOverflow.includes('hidden') || parentOverflow.includes('clip') || parentOverflow.includes('auto') || parentOverflow.includes('scroll')) {\n        const parentRect = parent.getBoundingClientRect();\n        // Calculate intersection with this parent\n        visibleRect.right = Math.min(visibleRect.right, parentRect.right);\n        visibleRect.left = Math.max(visibleRect.left, parentRect.left);\n        visibleRect.bottom = Math.min(visibleRect.bottom, parentRect.bottom);\n        visibleRect.top = Math.max(visibleRect.top, parentRect.top);\n\n        visibleRect.width = visibleRect.right - visibleRect.left;\n        visibleRect.height = visibleRect.bottom - visibleRect.top;\n\n        // If no intersection or intersection is too small, element is completely hidden\n        if (visibleRect.width <= 0 || visibleRect.height <= 0) {\n          return null;\n        }\n      }\n      parent = parent.parentElement;\n    }\n\n    return visibleRect as DOMRect;\n  }\n\n  /**\n   * Recursively checks if all parent elements are visible and not clipping the target element.\n   *\n   * Traverses up the DOM tree from the element to document.body, checking each parent for:\n   * - Hidden state (display: none, visibility: hidden, opacity: 0)\n   * - Overflow clipping (overflow: hidden/clip) that completely hides the element\n   *\n   * If any parent has overflow clipping, calculates the visible intersection area.\n   * Returns false if element is completely clipped (no visible area).\n   *\n   * @param element - The element whose parents should be checked\n   * @param rect - The bounding rectangle of the element\n   * @returns true if element has visible area within all parent containers, false otherwise\n   */\n  isParentVisible(element: HTMLElement, rect: DOMRect): boolean {\n    const visibleRect = this.getVisibleRect(element);\n    return visibleRect !== null;\n  }\n\n  //#endregion\n\n  // #region Utilities\n\n  /**\n   * Generates the complete CSS styles for the halo element, merging defaults with custom config.\n   *\n   * Takes the base styles from `haloFocusStyles` constant and overrides specific properties\n   * if custom configuration is provided. This allows global style customization while\n   * maintaining all required base styles.\n   *\n   * **Configurable Properties:**\n   * - Inner color (via config.innerColor)\n   * - Outer color (via config.outerColor)\n   *\n   * **Non-configurable Properties:**\n   * - position, pointerEvents, zIndex, opacity, transform (always use defaults)\n   *\n   * @param config - Optional global configuration object\n   * @returns Complete CSS style declaration object for the halo element\n   */\n  getHaloFocusStyles(config?: HaloFocusConfig): Partial<CSSStyleDeclaration> {\n    return {\n      ...haloFocusStyles,\n      border: config?.innerColor ? `2px solid ${config.innerColor}` : haloFocusStyles.border,\n      boxShadow: config?.outerColor ? `0 0 0 4px ${config.outerColor}` : haloFocusStyles.boxShadow\n    };\n  }\n\n  /**\n   * Finds the nearest parent element marked as a halo container.\n   *\n   * Traverses up the DOM tree looking for an element with the `halo-container` attribute.\n   * Container elements can define default halo styles (color, offset) that apply to all\n   * their focused children, unless overridden by child-specific halo-* attributes.\n   *\n   * **Search Scope:**\n   * - Starts from element's immediate parent\n   * - Stops at document.body (does not check body itself)\n   * - Returns first matching ancestor\n   *\n   * @param element - The focused element to search from\n   * @returns The nearest halo container element, or null if none found\n   */\n  getHaloContainer(element: HTMLElement): HTMLElement | null {\n    let parent = element.parentElement;\n    while (parent && parent !== document.body) {\n      if (parent.hasAttribute('halo-container')) {\n        return parent;\n      }\n      parent = parent.parentElement;\n    }\n    return null;\n  }\n\n  /**\n   * Converts any CSS color format to rgba with specified alpha transparency.\n   *\n   * Handles multiple color formats:\n   * - **rgba**: Replaces existing alpha value\n   * - **rgb**: Converts to rgba by appending alpha\n   * - **Hex** (#RRGGBB): Converts to rgba format\n   * - **Named colors**: Uses modern CSS `color-mix` function with alpha\n   *\n   * Used internally to create outer colors with reduced opacity from inner colors.\n   *\n   * @param color - CSS color in any valid format (rgba, rgb, hex, named)\n   * @param alpha - Alpha transparency value (0-1)\n   * @returns Color in rgba format with specified alpha\n   */\n  getColorWithAlpha(color: string, alpha: number): string {\n    // If already rgba, try to replace alpha\n    if (color.startsWith('rgba')) {\n      return color.replace(/[\\d.]+\\)$/, `${alpha})`);\n    }\n\n    // If rgb, convert to rgba\n    if (color.startsWith('rgb')) {\n      return color.replace('rgb', 'rgba').replace(')', `, ${alpha})`);\n    }\n\n    // If hex color, convert to rgba\n    if (color.startsWith('#')) {\n      const hex = color.replace('#', '');\n      const r = parseInt(hex.substring(0, 2), 16);\n      const g = parseInt(hex.substring(2, 4), 16);\n      const b = parseInt(hex.substring(4, 6), 16);\n      return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n    }\n\n    // For named colors or other formats, wrap in rgba with color-mix (modern approach)\n    // Fallback to appending alpha as hex if browser doesn't support color-mix\n    return `rgba(from ${color} r g b / ${alpha})`;\n  }\n\n  /**\n   * Calculates the offset (distance) between the halo border and element edges.\n   *\n   * Determines offset using the following priority order:\n   * 1. **Element's own attributes** (highest priority):\n   *    - `halo-offset=\"value\"` - Custom numeric value\n   * 2. **Parent container attributes** (if element has no offset):\n   *    - `halo-container-offset=\"value\"`\n   * 3. **Default offset** (if nothing specified): 3px\n   *\n   * @param element - The focused element to calculate offset for\n   * @returns Offset value in pixels\n   */\n  getTargetOffset(element: HTMLElement | null): number {\n    if (!element) return defaultHaloFocusOffset;\n\n    // 1. Check element's own attributes first\n    const customOffset = element.getAttribute('halo-offset');\n    if (customOffset !== null) {\n      const parsed = parseFloat(customOffset);\n      if (!isNaN(parsed)) return parsed;\n    }\n\n    // 2. Check container attributes as fallback\n    const container = this.getHaloContainer(element);\n    if (container) {\n      const containerOffset = container.getAttribute('halo-container-offset');\n      if (containerOffset !== null) {\n        const parsed = parseFloat(containerOffset);\n        if (!isNaN(parsed)) return parsed;\n      }\n    }\n\n    // 3. Default: positive offset (halo outside element)\n    return defaultHaloFocusOffset;\n  }\n\n  /**\n   * Applies custom color styling to the halo element based on element or container attributes.\n   *\n   * Color resolution priority:\n   * 1. **Element's own color**: `halo-color=\"color\"` attribute (highest priority)\n   * 2. **Container's color**: `halo-container-color=\"color\"` from nearest halo container\n   * 3. **Default color**: From global config or base styles (if no custom color found)\n   *\n   * When custom color is found:\n   * - Sets inner color (2px solid border) with the custom color\n   * - Sets outer color (shadow) to match, with 20% alpha transparency for subtle depth\n   *\n   * When no custom color:\n   * - Resets to default styles from config or haloFocusStyles constant\n   *\n   * @param element - The focused element (checked for halo-color attribute)\n   * @param haloElement - The halo DIV element to apply styles to\n   * @param config - Optional global config for default colors\n   */\n  setCustomColor(element: HTMLElement, haloElement: HTMLDivElement, config?: HaloFocusConfig): void {\n    // 1. Check element's own color first\n    let customColor = element.getAttribute('halo-color');\n\n    // 2. If not found, check container color\n    if (!customColor) {\n      const container = this.getHaloContainer(element);\n      if (container) {\n        customColor = container.getAttribute('halo-container-color');\n      }\n    }\n    // Apply color or reset to default\n    if (customColor) {\n      haloElement.style.border = `2px solid ${customColor}`;\n      haloElement.style.boxShadow = `0 0 0 4px ${this.getColorWithAlpha(customColor, 0.2)}`;\n    } else {\n      // Reset to default styles\n      haloElement.style.border = this.getHaloFocusStyles(config).border!;\n      haloElement.style.boxShadow = this.getHaloFocusStyles(config).boxShadow!;\n    }\n  }\n\n  /**\n   * Positions and sizes the halo element to surround the focused element.\n   *\n   * Calculates halo dimensions and position based on:\n   * - Element's visible bounding rectangle (considering overflow clipping)\n   * - Calculated offset from getTargetOffset() (custom or default)\n   * - Element's border-radius for matching rounded corners\n   *\n   * **Calculation Details:**\n   * - Uses getVisibleRect to get only the visible portion of the element\n   * - Position: Visible rect's top/left minus offset (for outside positioning)\n   * - Size: Visible rect's width/height plus 2× offset (to extend on all sides)\n   * - Border radius: Inherited from focused element's computed style\n   *\n   * Uses Math.floor for position and Math.ceil for dimensions to prevent\n   * subpixel rendering issues and ensure full element coverage.\n   *\n   * @param currentElement - The currently focused element to surround\n   * @param haloElement - The halo DIV element to position and size\n   */\n  setHaloElementSize(currentElement: HTMLElement, haloElement: HTMLDivElement): void {\n    const visibleRect = this.getVisibleRect(currentElement);\n\n    // If element is not visible, hide the halo\n    if (!visibleRect) {\n      haloElement.style.opacity = '0';\n      return;\n    }\n\n    const offset = this.getTargetOffset(currentElement);\n\n    const left = Math.floor(visibleRect.left - offset);\n    const top = Math.floor(visibleRect.top - offset);\n    const width = Math.ceil(visibleRect.width + offset * 2);\n    const height = Math.ceil(visibleRect.height + offset * 2);\n\n    const cs = getComputedStyle(currentElement);\n    haloElement.style.left = `${left}px`;\n    haloElement.style.top = `${top}px`;\n    haloElement.style.width = `${width}px`;\n    haloElement.style.height = `${height}px`;\n    haloElement.style.borderRadius = cs.borderRadius || '8px';\n  }\n\n  //#endregion\n}\n","import { ApplicationRef, DestroyRef, inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { SwUpdate, VersionReadyEvent } from '@angular/service-worker';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ConfirmService } from '@yuuvis/client-framework/common';\nimport { concat, filter, first, interval } from 'rxjs';\nimport { pwaUpdateDefaultCheckInterval } from '../../config';\nimport { PwaUpdateConfig } from '../../models';\n\n/**\n * Detects newly deployed versions of the application (PWA) and lets the user\n * decide when to apply them.\n *\n * **Flow (per the Angular `SwUpdate` documentation):**\n * 1. **Check** — listens for the `VERSION_READY` event and, additionally, polls\n *    `checkForUpdate()` on an interval once the app is stable. The update is\n *    *not* applied automatically.\n * 2. **Ask** — when a new version is ready, prompts the user via the framework\n *    {@link ConfirmService} dialog instead of reloading silently.\n * 3. **Apply** — only after the user confirms, calls `activateUpdate()` and then\n *    reloads the page so the new version takes effect.\n *\n * The service is a no-op when the service worker is disabled (e.g. dev mode),\n * so it is safe to provide unconditionally.\n *\n * Wire it up via `providePwaUpdate()` in `app.config.ts`. The service worker\n * itself must still be registered separately via `provideServiceWorker(...)`.\n *\n * @see https://angular.dev/ecosystem/service-workers/communications\n */\n@Injectable({ providedIn: 'root' })\nexport class PwaUpdateService {\n  #swUpdate = inject(SwUpdate);\n  #confirm = inject(ConfirmService);\n  #translate = inject(TranslateService);\n  #appRef = inject(ApplicationRef);\n  #destroyRef = inject(DestroyRef);\n\n  /** Guards against opening multiple confirm dialogs while one is already open. */\n  #prompting = false;\n\n  /**\n   * Starts listening for updates. Called automatically by `providePwaUpdate()`.\n   * Does nothing when the service worker is not enabled.\n   */\n  init(config?: PwaUpdateConfig): void {\n    if (!this.#swUpdate.isEnabled) {\n      return;\n    }\n\n    // 1a. React when the service worker has already downloaded a new version.\n    this.#swUpdate.versionUpdates\n      .pipe(\n        filter((event): event is VersionReadyEvent => event.type === 'VERSION_READY'),\n        takeUntilDestroyed(this.#destroyRef)\n      )\n      .subscribe(() => this.#promptUpdate(config));\n\n    // 1b. Poll for updates: first once the app is stable, then on an interval.\n    const checkInterval = config?.checkInterval ?? pwaUpdateDefaultCheckInterval;\n    if (checkInterval > 0) {\n      const appStable$ = this.#appRef.isStable.pipe(first((stable) => stable));\n      concat(appStable$, interval(checkInterval))\n        .pipe(takeUntilDestroyed(this.#destroyRef))\n        .subscribe(() => void this.checkForUpdate());\n    }\n\n    // 1c. Offer a reload when the service worker is in a broken, unrecoverable state.\n    this.#swUpdate.unrecoverable\n      .pipe(takeUntilDestroyed(this.#destroyRef))\n      .subscribe(() => this.#promptUpdate(config, true));\n  }\n\n  /**\n   * Manually triggers an update check (e.g. from a \"check for updates\" button).\n   * Resolves to `true` when a new version was found. Network errors are swallowed\n   * and resolve to `false`.\n   */\n  checkForUpdate(): Promise<boolean> {\n    if (!this.#swUpdate.isEnabled) {\n      return Promise.resolve(false);\n    }\n    return this.#swUpdate.checkForUpdate().catch(() => false);\n  }\n\n  #promptUpdate(config?: PwaUpdateConfig, unrecoverable = false): void {\n    if (this.#prompting) {\n      return;\n    }\n    this.#prompting = true;\n\n    const messageKey = unrecoverable\n      ? (config?.unrecoverableMessage ?? 'yuv.pwa.update.unrecoverable.message')\n      : (config?.message ?? 'yuv.pwa.update.message');\n\n    this.#confirm\n      .confirm({\n        title: this.#translate.instant(config?.title ?? 'yuv.pwa.update.title'),\n        message: this.#translate.instant(messageKey),\n        confirmLabel: this.#translate.instant(config?.confirmLabel ?? 'yuv.pwa.update.confirm'),\n        cancelLabel: this.#translate.instant(config?.cancelLabel ?? 'yuv.pwa.update.cancel'),\n        // An unrecoverable worker cannot keep serving the app, so reloading is the only option.\n        hideCancelButton: unrecoverable,\n        level: 'info'\n      })\n      .subscribe((confirmed) => {\n        this.#prompting = false;\n        if (confirmed) {\n          this.#applyUpdate(unrecoverable);\n        }\n      });\n  }\n\n  #applyUpdate(unrecoverable: boolean): void {\n    // In an unrecoverable state there is no pending version to activate — just reload.\n    if (unrecoverable) {\n      document.location.reload();\n      return;\n    }\n    void this.#swUpdate\n      .activateUpdate()\n      .catch(() => false)\n      .finally(() => document.location.reload());\n  }\n}\n","import { ChangeDetectionStrategy, Component, inject, Injectable, Signal, signal } from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n  MAT_SNACK_BAR_DATA,\n  MatSnackBar,\n  MatSnackBarAction,\n  MatSnackBarActions,\n  MatSnackBarLabel,\n  MatSnackBarRef\n} from '@angular/material/snack-bar';\nimport { TranslateService } from '@ngx-translate/core';\nimport { SnackBarData, SnackBarLevel, SnackBarMessage, SnackBarOptions } from '../../models';\n\nconst SNACK_BAR_DEFAULT_DURATION = 3000;\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class SnackBarService {\n  #snackBar = inject(MatSnackBar);\n  private translate = inject(TranslateService);\n\n  constructor() {\n    this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe(() => this.#snackBar.dismiss());\n  }\n\n  info(message: SnackBarMessage, action?: SnackBarMessage, duration?: number): MatSnackBarRef<SnackBarComponent> {\n    return this.snack(message, {\n      action,\n      level: 'info',\n      ...(duration ? { duration } : { duration: SNACK_BAR_DEFAULT_DURATION })\n    });\n  }\n\n  success(message: SnackBarMessage, action?: SnackBarMessage, duration?: number): MatSnackBarRef<SnackBarComponent> {\n    return this.snack(message, {\n      action,\n      level: 'success',\n      ...(duration ? { duration } : { duration: SNACK_BAR_DEFAULT_DURATION })\n    });\n  }\n\n  warning(message: SnackBarMessage, action?: SnackBarMessage, duration?: number): MatSnackBarRef<SnackBarComponent> {\n    return this.snack(message, {\n      action,\n      level: 'warning',\n      ...(duration ? { duration } : { duration: SNACK_BAR_DEFAULT_DURATION })\n    });\n  }\n\n  danger(message: SnackBarMessage, action?: SnackBarMessage, duration?: number): MatSnackBarRef<SnackBarComponent> {\n    return this.snack(message, {\n      action,\n      level: 'danger',\n      ...(duration ? { duration } : { duration: SNACK_BAR_DEFAULT_DURATION })\n    });\n  }\n\n  snack(message: SnackBarMessage, options: SnackBarOptions): MatSnackBarRef<SnackBarComponent> {\n    return this.#snackBar.openFromComponent(SnackBarComponent, {\n      data: {\n        level: options.level,\n        message,\n        action: options.action\n      },\n      ...(options.duration ? { duration: options.duration } : {}),\n      horizontalPosition: options.horizontalPosition,\n      verticalPosition: options.verticalPosition,\n      panelClass: ['yuv-snack-bar', 'level-' + options.level]\n    });\n  }\n}\n\n@Component({\n  selector: 'yuv-snack-bar-component',\n  template: `\n    @let a = action();\n    <span\n      matSnackBarLabel\n      [attr.role]=\"a ? null : 'button'\"\n      [attr.tabindex]=\"a ? null : 0\"\n      (click)=\"dismiss()\"\n      (keydown.enter)=\"dismiss()\"\n      (keydown.space)=\"dismiss(); $event.preventDefault()\"\n    >\n      {{ message() }}\n    </span>\n    @if (a) {\n      <span matSnackBarActions>\n        <button mat-button matSnackBarAction (click)=\"dismiss(true)\">{{ a }}</button>\n      </span>\n    }\n  `,\n  styles: `\n    :host {\n      display: flex;\n    }\n  `,\n  imports: [MatButtonModule, MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction],\n  host: {\n    '[class.info]': \"level() === 'info'\",\n    '[class.success]': \"level() === 'success'\",\n    '[class.warning]': \"level() === 'warning'\",\n    '[class.danger]': \"level() === 'danger'\"\n  },\n  changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SnackBarComponent {\n  #snackBarRef = inject(MatSnackBarRef);\n  #snackData = inject<SnackBarData>(MAT_SNACK_BAR_DATA);\n  #translate = inject(TranslateService);\n\n  level = signal<SnackBarLevel>(this.#snackData.level);\n  message: Signal<string> = bindMessage(this.#snackData.message, this.#translate, '') as Signal<string>;\n  action: Signal<string | undefined> = bindMessage(this.#snackData.action, this.#translate, undefined);\n\n  dismiss(withAction = false): void {\n    if (withAction) {\n      this.#snackBarRef.dismissWithAction();\n    } else if (!this.action()) {\n      this.#snackBarRef.dismiss();\n    }\n  }\n}\n\ninterface MessageDescriptor {\n  key: string;\n  params?: Record<string, unknown>;\n}\n\nfunction isMessageDescriptor(value: SnackBarMessage | undefined): value is MessageDescriptor {\n  return typeof value === 'object';\n}\n\nfunction bindMessage(\n  value: SnackBarMessage | undefined,\n  translate: TranslateService,\n  fallback: string | undefined\n): Signal<string | undefined> {\n  if (isMessageDescriptor(value)) {\n    return toSignal(translate.stream(value.key, value.params), { initialValue: fallback ?? '' });\n  }\n  const literal: string | undefined = value;\n  return signal<string | undefined>(literal ?? fallback);\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatSnackBarRef } from '@angular/material/snack-bar';\nimport { TranslateService } from '@ngx-translate/core';\nimport { AppCacheService, BackendService, EventService, UserService, YuvEventType } from '@yuuvis/client-core';\nimport { debounceTime, finalize, map, Observable, Subscription, switchMap, timer } from 'rxjs';\nimport { sessionActivityWindowBeforeEnd, sessionDefaultDuration, sessionPopupBeforeEnd } from '../../config';\nimport { ChannelMessage } from '../../enums';\nimport { ChannelPayload } from '../../models';\nimport { SnackBarComponent, SnackBarService } from '../snack-bar/snack-bar.service';\n\n/**\n * Manages client-side session expiry: persists expiration, tracks user and HTTP activity,\n * shows a pre-expiry popup with an extend CTA, and syncs state across tabs via BroadcastChannel.\n *\n * Key behaviors\n * - Persists `expiresAt` in AppCacheService so multiple tabs share the same deadline\n * - Automatically listens to BackendService HTTP activity (debounced) to extend sessions\n * - Extends backend session by calling `/api-web/api/idm/whoami` endpoint` (skipped when triggered by HTTP activity)\n * - User activity (mouse, keyboard, scroll) inside a defined window will auto-extend the session\n * - Displays a snack popup shortly before expiry; user can extend from the popup\n * - Broadcasts `SessionExtended` / `SessionLogout` to keep tabs in sync\n *\n * Setup options\n *\n * Option 1: Known session duration at startup\n * Use when the session duration is known in advance and remains constant.\n * ```ts\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideSession(30 * 60 * 1000), // 30 minutes - set at app startup\n *   ]\n * };\n * ```\n *\n * Option 2: Dynamic session duration from backend\n * Use when the session duration is determined after login (e.g., from backend response).\n * ```ts\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideSession(), // Initialize without duration (defaults to 30 minutes)\n *   ]\n * };\n *\n * // After login in AuthService:\n * login().subscribe(response => {\n *   const sessionDuration = response.sessionExpiresIn; // from backend\n *   sessionService.startSession(sessionDuration);\n * });\n * ```\n * Note: If no duration is provided to provideSession(), a default of 30 minutes is used until startSession() is called.\n *\n * Lifecycle notes\n * - HTTP activity is automatically tracked via BackendService.httpCommunicationOccurred$\n * - Backend session is extended via whoami endpoint, except when triggered by HTTP activity or cross-tab sync\n * - Internal flag prevents recursive whoami calls when the endpoint itself triggers httpCommunicationOccurred$\n * - Warning and logout timers are reset on every extend\n * - All timers and the popup are cleared on logout\n * - Broadcast messages are listened for and mirrored across tabs\n * - For UI activity, this service listens to DOM events (mousemove, keydown, click, scroll)\n */\n@Injectable({ providedIn: 'root' })\nexport class SessionService {\n  //#region Dependencies\n\n  /**\n   * AppCacheService is used to persist the session expiry timestamp in localStorage.\n   *\n   * Why persist to storage instead of runtime memory:\n   * - Single source of truth: All browser tabs can read the same expiry value directly\n   *   from storage without inter-tab communication\n   * - Avoids master/slave tab pattern: No need to elect one \"master\" tab to hold the\n   *   authoritative expiry time and sync it to others\n   * - Survives page refresh: Users don't lose their session when refreshing the page\n   * - Simplifies synchronization: BroadcastChannel is only used for notifications about\n   *   changes (extend/logout), not for maintaining shared state\n   * - Consistent behavior: Every tab independently calculates timers based on the same\n   *   persisted expiry value, ensuring uniform warning/logout timing\n   */\n  #appCacheService = inject(AppCacheService);\n  #snackBarService = inject(SnackBarService);\n  #backendService = inject(BackendService);\n  #userService = inject(UserService);\n  #eventService = inject(EventService);\n  #destroyRef = inject(DestroyRef);\n  private translate = inject(TranslateService);\n\n  //#endregion\n\n  //#region Properties\n\n  #sessionDuration = sessionDefaultDuration;\n\n  readonly #sessionStorageKey = 'session-expires-at';\n  readonly #activityWindowBeforeEnd = sessionActivityWindowBeforeEnd;\n  readonly #popupBeforeEnd = sessionPopupBeforeEnd;\n\n  #activityWindowSchedule$?: Subscription;\n  #activityWindowStart$?: Subscription;\n  #activityWindowEnd$?: Subscription;\n  #logoutTimer$?: Subscription;\n  #httpActivitySubscription$?: Subscription;\n\n  #activityDetectedInWindow = false;\n  #trackingWindowActivity = false;\n  #userActivityTrackingInitialized = false;\n  #extendingSessionViaBackend = false;\n  #isLoggingOut = false;\n\n  #sessionChannel = new BroadcastChannel('session_channel');\n  #snackReference?: MatSnackBarRef<SnackBarComponent>;\n\n  //#endregion\n\n  //#region Public methods\n\n  /**\n   * Initializes cross-tab listeners and activity hooks.\n   *\n   * IMPORTANT: This is automatically called by `provideSession()` via APP_INITIALIZER.\n   * You should NOT call this manually - just add `provideSession()` to your app providers.\n   *\n   * What it does:\n   * - Initializes session with provided or default duration value\n   * - Wires BroadcastChannel subscriptions for cross-tab sync\n   * - Subscribes to BackendService.httpCommunicationOccurred$ for automatic HTTP activity tracking\n   * - Attaches DOM event listeners (mousemove, keydown, click, scroll) for the activity window\n   */\n  init(sessionDuration?: number): void {\n    this.startSession(sessionDuration ?? sessionDefaultDuration);\n    this.listenToChannel();\n    this.listenToGlobalLogout();\n    this.setupHttpDebounce();\n    this.setupUserActivityTracking();\n  }\n\n  /**\n   * Sets the session duration and starts the session lifecycle.\n   *\n   * Use this method when you need to set or update the session duration dynamically,\n   * typically after receiving authentication/session information from the backend.\n   *\n   * This is the correct approach when:\n   * - Session duration is not known at application startup\n   * - Duration comes from a backend API response after login\n   * - You need to manually override the duration set via provideSession()\n   *\n   * Example:\n   * ```ts\n   * // After login in AuthService\n   * login().subscribe(response => {\n   *   this.sessionService.startSession(response.sessionExpiresIn);\n   * });\n   * ```\n   *\n   * @param duration Total session length in milliseconds\n   */\n  startSession(duration: number): void {\n    this.#sessionDuration = duration;\n    this.extendSession(false, undefined, true);\n  }\n\n  /**\n   * Extends the session expiry, resets all timers, and optionally broadcasts to other tabs.\n   *\n   * @param broadcast When true (default), posts a BroadcastChannel message so other tabs sync\n   * @param expiresAt Optional custom expiry timestamp; if not provided, calculates based on session duration\n   * @param skipBackendCall When true, skips the whoami backend call (used when already triggered by HTTP activity)\n   */\n  extendSession(broadcast = true, expiresAt?: number, skipBackendCall = false): void {\n    if (this.#isLoggingOut) return;\n\n    const newExpiresAt = expiresAt ?? Date.now() + this.#sessionDuration;\n\n    this.setExpiresAt(newExpiresAt);\n    this.resetAllTimers();\n\n    if (skipBackendCall) {\n      if (broadcast) {\n        this.#sessionChannel.postMessage({\n          type: ChannelMessage.SessionExtended,\n          expiresAt: newExpiresAt\n        });\n      }\n      return;\n    }\n\n    // The #extendingSessionViaBackend flag is intentionally NOT checked here:\n    // user-initiated extends (popup click, user activity at window end) must always\n    // touch the backend so its session matches the freshly bumped local expiresAt.\n    // The flag's sole purpose is to filter the HTTP debounce subscriber so the\n    // whoami response itself doesn't trigger a recursive extend.\n    this.#extendingSessionViaBackend = true;\n    this.#backendService\n      .get<unknown>('/idm/whoami')\n      .pipe(\n        finalize(() => {\n          // Keep flag true longer than debounce time to suppress the debounce\n          // emission caused by the whoami response itself.\n          setTimeout(() => {\n            this.#extendingSessionViaBackend = false;\n            // eslint-disable-next-line @typescript-eslint/no-magic-numbers\n          }, 600);\n          if (broadcast) {\n            this.#sessionChannel.postMessage({\n              type: ChannelMessage.SessionExtended,\n              expiresAt: newExpiresAt\n            });\n          }\n        })\n      )\n      .subscribe();\n  }\n\n  //#endregion\n\n  //#region Core Logic\n\n  private listenToChannel(): void {\n    this.#sessionChannel.onmessage = (event: MessageEvent<ChannelPayload>): void => {\n      const message = event.data;\n\n      switch (message.type) {\n        case ChannelMessage.SessionExtended:\n          this.extendSession(false, message.expiresAt, true);\n          break;\n\n        case ChannelMessage.SessionLogout:\n          this.performLogout(false);\n          break;\n      }\n    };\n  }\n\n  /**\n   * Listens to the global LOGOUT event emitted by AuthService.\n   *\n   * Covers logout paths that bypass SessionService.performLogout — e.g.,\n   * 401 caught by AuthInterceptor or any manual `AuthService.logout()` call.\n   * Without this, other tabs would not receive a SessionLogout broadcast and\n   * the HTTP activity subscription would briefly stay alive after auth dies.\n   *\n   * Note: UI buttons that call only `UserService.logout()` (e.g. sidebar-nav)\n   * do not emit this event — for those, the system still converges via the\n   * 401 interceptor or local expiry.\n   */\n  private listenToGlobalLogout(): void {\n    this.#eventService\n      .on(YuvEventType.LOGOUT)\n      .pipe(takeUntilDestroyed(this.#destroyRef))\n      .subscribe(() => this.performLogout(true));\n  }\n\n  private scheduleActivityWindow(): void {\n    // Capture the outer subscription so clearTimers can cancel a pending\n    // async getExpiresAt() resolution. Without this, two extendSession calls\n    // in quick succession could leak the inner timers of the first call when\n    // its getExpiresAt resolves after the second call's clearTimers has run.\n    this.#activityWindowSchedule$ = this.getExpiresAt().subscribe((expiresAt) => {\n      const activityWindowStartIn = expiresAt - Date.now() - this.#activityWindowBeforeEnd;\n      const activityWindowEndIn = expiresAt - Date.now() - this.#popupBeforeEnd;\n\n      this.#activityWindowStart$ = timer(Math.max(activityWindowStartIn, 0)).subscribe(() => {\n        this.#trackingWindowActivity = true;\n        this.#activityDetectedInWindow = false;\n      });\n\n      this.#activityWindowEnd$ = timer(Math.max(activityWindowEndIn, 0)).subscribe(() => {\n        this.#trackingWindowActivity = false;\n\n        if (this.#activityDetectedInWindow) {\n          this.extendSession();\n        } else {\n          this.showPopup();\n        }\n      });\n    });\n  }\n\n  private showPopup(): void {\n    if (this.#snackReference) return;\n\n    const message = this.translate.instant('yuv.session.expires.message');\n    const action = this.translate.instant('yuv.session.extend.action');\n    this.#snackReference = this.#snackBarService.warning(message, action);\n\n    this.scheduleLogout();\n\n    this.#snackReference.onAction().subscribe(() => {\n      this.#snackReference?.dismiss();\n      this.extendSession();\n    });\n\n    this.#snackReference.afterDismissed().subscribe(() => {\n      this.#snackReference = undefined;\n    });\n  }\n\n  private scheduleLogout(): void {\n    this.#logoutTimer$?.unsubscribe();\n\n    this.#logoutTimer$ = this.getExpiresAt()\n      .pipe(switchMap((expiresAt) => timer(Math.max(expiresAt - Date.now(), 0)).pipe(map(() => expiresAt))))\n      .subscribe((expiresAt) => {\n        if (Date.now() >= expiresAt) {\n          this.performLogout(true);\n        }\n      });\n  }\n\n  private performLogout(broadcast = true): void {\n    if (this.#isLoggingOut) return;\n    this.#isLoggingOut = true;\n\n    this.clearTimers();\n    this.#httpActivitySubscription$?.unsubscribe();\n    this.#snackReference?.dismiss();\n\n    if (broadcast) {\n      this.#sessionChannel.postMessage({\n        type: ChannelMessage.SessionLogout\n      });\n    }\n\n    this.#userService.logout();\n  }\n\n  //#endregion\n\n  //#region Activity + HTTP\n\n  private setupHttpDebounce(): void {\n    this.#httpActivitySubscription$?.unsubscribe();\n    this.#httpActivitySubscription$ = this.#backendService.httpCommunicationOccurred$\n      .pipe(debounceTime(500))\n      .subscribe(() => {\n        if (!this.#extendingSessionViaBackend) {\n          this.extendSession(true, undefined, true);\n        }\n      });\n  }\n\n  private setupUserActivityTracking(): void {\n    if (this.#userActivityTrackingInitialized) return;\n\n    const handler = (): void => {\n      if (this.#trackingWindowActivity) {\n        this.#activityDetectedInWindow = true;\n      }\n    };\n\n    const events = ['mousemove', 'keydown', 'click', 'scroll'];\n    events.forEach((event) => window.addEventListener(event, handler, { passive: true }));\n    this.#destroyRef.onDestroy(() => events.forEach((event) => window.removeEventListener(event, handler)));\n\n    this.#userActivityTrackingInitialized = true;\n  }\n\n  //#endregion\n\n  //#region Utilities\n\n  private resetAllTimers(): void {\n    this.clearTimers();\n    this.scheduleActivityWindow();\n    this.#snackReference?.dismiss();\n  }\n\n  private getExpiresAt(): Observable<number> {\n    return this.#appCacheService.getItem(this.#sessionStorageKey);\n  }\n\n  private setExpiresAt(expiresAt: number): void {\n    this.#appCacheService.setItem(this.#sessionStorageKey, expiresAt).subscribe();\n  }\n\n  private clearTimers(): void {\n    this.#activityWindowSchedule$?.unsubscribe();\n    this.#activityWindowStart$?.unsubscribe();\n    this.#activityWindowEnd$?.unsubscribe();\n    this.#logoutTimer$?.unsubscribe();\n  }\n\n  //#endregion\n}\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, NgZone, provideAppInitializer } from '@angular/core';\nimport { HaloFocusService, HaloUtilityService } from '../../services';\nimport { HaloFocusConfig } from '../../models';\n\n/**\n * Provides and initializes the Halo Focus feature for the Angular application.\n *\n * This function sets up a global visual accessibility enhancement that creates a\n * \"halo\" border around keyboard-focused elements, making navigation more visible\n * and improving the user experience for keyboard users.\n *\n * **What It Does:**\n * - Registers HaloFocusService and HaloUtility as application-wide providers\n * - Automatically initializes the service during app startup via APP_INITIALIZER\n * - Runs initialization outside Angular zone for optimal performance\n * - Creates a persistent halo element that tracks focus throughout the application\n *\n * **Key Features:**\n * - Keyboard-only focus indication (respects CSS :focus-visible)\n * - Performance-optimized with requestAnimationFrame and zone-free execution\n * - Fully customizable via global config or per-element attributes\n * - Supports container-level defaults for consistent styling\n * - Automatic visibility detection and responsive to DOM changes\n *\n * **Configuration Options:**\n * @param config - Optional global configuration object\n * @param config.innerColor - Inner color of the halo (default: 'var(--ymt-primary)')\n * @param config.outerColor - Outer color around the halo (default: 'rgba(from var(--ymt-primary) r g b / 0.2)')\n *\n * @returns EnvironmentProviders for the Halo Focus feature\n *\n * @example\n * // Basic usage in app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideHaloFocus()\n *   ]\n * };\n *\n * @example\n * // With custom configuration\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideHaloFocus({\n *       innerColor: '#007bff',\n *       outerColor: 'rgba(0, 123, 255, 0.25)'\n *     })\n *   ]\n * };\n *\n * @example\n * // Using element-level attributes in your template\n * <button halo-color=\"red\">Custom Red Halo</button>\n * <input halo-offset=\"5\" />\n * <select halo-skip>No Halo</select>\n *\n * @example\n * // Using container-level attributes\n * <form halo-container halo-container-color=\"blue\" halo-container-offset=\"5\">\n *   <input /> <!-- Will use blue color and 5px offset -->\n *   <button halo-color=\"red\">Submit</button> <!-- Overrides with red -->\n * </form>\n */\nexport function provideHaloFocus(config?: HaloFocusConfig): EnvironmentProviders {\n  return makeEnvironmentProviders([\n    HaloUtilityService,\n    provideAppInitializer(() => {\n      const zone = inject(NgZone);\n      const haloFocus = inject(HaloFocusService);\n      zone.runOutsideAngular(() => haloFocus.init(config));\n    })\n  ]);\n}\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { PwaUpdateConfig } from '../../models';\nimport { PwaUpdateService } from '../../services';\n\n/**\n * Provides and initializes PWA update detection for the application.\n *\n * On startup it boots {@link PwaUpdateService}, which watches for newly deployed\n * versions of the app and, instead of reloading silently, asks the user to\n * confirm before activating the update and reloading the page.\n *\n * **Detection:** reacts to the service worker `VERSION_READY` event and also\n * polls `checkForUpdate()` on an interval (default 6 hours) once the app is\n * stable, so long-running sessions still pick up new releases.\n *\n * **Prerequisite:** the service worker must be registered separately via\n * `provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode() })`. When the\n * service worker is disabled (e.g. dev mode) this provider is a harmless no-op.\n *\n * @param config - Optional configuration (check interval, custom dialog labels/messages).\n * @returns EnvironmentProviders for the PWA update feature.\n *\n * @example\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode() }),\n *     providePwaUpdate()\n *   ]\n * };\n *\n * @example\n * // Custom check interval (1 hour) and labels\n * providePwaUpdate({\n *   checkInterval: 60 * 60 * 1000,\n *   message: 'A new version is available. Reload now?'\n * });\n */\nexport function providePwaUpdate(config?: PwaUpdateConfig): EnvironmentProviders {\n  return makeEnvironmentProviders([\n    provideAppInitializer(() => {\n      inject(PwaUpdateService).init(config);\n    })\n  ]);\n}\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';\nimport { SessionService } from '../../services/session/session.service';\n\n\n/**\n * Provides and initializes the SessionService at application startup.\n *\n * What it does\n * - Registers SessionService as a singleton to manage session expiry across the app\n * - Runs `session.init()` via APP_INITIALIZER when the app boots\n * - Initializes cross-tab BroadcastChannel sync, HTTP debounce hooks, and user-activity listeners\n * - Automatically tracks HTTP activity and user interactions to extend sessions\n *\n * Usage scenarios\n *\n * Scenario 1: Known session duration at startup\n * When the session duration is predetermined and constant, provide it here.\n * ```ts\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideSession(30 * 60 * 1000), // 30 minutes\n *   ]\n * };\n * ```\n *\n * Scenario 2: Dynamic session duration from backend\n * When the session duration is determined after login (e.g., from backend response),\n * omit the parameter here and call `startSession()` after receiving the duration.\n * ```ts\n * // app.config.ts\n * export const appConfig: ApplicationConfig = {\n *   providers: [\n *     provideSession(), // Defaults to 30 minutes until startSession() is called\n *   ]\n * };\n *\n * // After login in AuthService:\n * login().subscribe(response => {\n *   sessionService.startSession(response.sessionExpiresIn); // Set actual duration\n * });\n * ```\n *\n * @param sessionDuration Optional session duration in milliseconds. If omitted, defaults to 30 minutes (1800000ms).\n */\nexport function provideSession(sessionDuration?: number): EnvironmentProviders {\n  return makeEnvironmentProviders([\n    provideAppInitializer(() => {\n      const session = inject(SessionService);\n      session.init(sessionDuration);\n    })\n  ]);\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n  imports: [CommonModule],\n})\nexport class YuuvisClientFrameworkModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}