{"version":3,"file":"ngx-theme-stack.mjs","sources":["../../../projects/ngx-theme-stack/src/lib/errors.ts","../../../projects/ngx-theme-stack/src/lib/types.ts","../../../projects/ngx-theme-stack/src/lib/config/index.ts","../../../projects/ngx-theme-stack/src/lib/core/core-theme.service.ts","../../../projects/ngx-theme-stack/src/lib/services/theme-cycle.service.ts","../../../projects/ngx-theme-stack/src/lib/services/theme-select.service.ts","../../../projects/ngx-theme-stack/src/lib/services/theme-toggle.service.ts","../../../projects/ngx-theme-stack/src/public-api.ts","../../../projects/ngx-theme-stack/src/ngx-theme-stack.ts"],"sourcesContent":["/**\n * Base error class for `ngx-theme-stack`.\n *\n * Thrown when the library configuration is invalid.\n * Consumers can use `instanceof NgxThemeStackError` to catch only\n * errors originating from this library.\n *\n * @example\n * try {\n *   bootstrapApplication(AppComponent, appConfig);\n * } catch (e) {\n *   if (e instanceof NgxThemeStackError) {\n *     console.error('Bad ngx-theme-stack config:', e.message);\n *   }\n * }\n */\nexport class NgxThemeStackError extends Error {\n  override readonly name = 'NgxThemeStackError';\n\n  constructor(message: string) {\n    super(`[ngx-theme-stack] ${message}`);\n  }\n}\n","/**\n * Runtime list of built-in themes.\n *\n * Lives here (and not in config/index.ts) because it defines a type:\n * config/index.ts already imports from types.ts, so placing DEFAULT_THEMES\n * here avoids any circular dependency.\n *\n * ⚠ KEEP IN SYNC with the duplicate in:\n * projects/ngx-theme-stack/schematics/ng-add/constants.ts → DEFAULT_THEMES\n *\n * Schematics compile to CommonJS and cannot import from this ESM file,\n * so the values are intentionally duplicated. Change both at the same time.\n */\nexport const DEFAULT_THEMES = ['system', 'light', 'dark'] as const;\n\n/** Literal union of built-in themes: `'system' | 'light' | 'dark'`. */\nexport type DefaultNgTheme = (typeof DEFAULT_THEMES)[number];\n\n/**\n * Theme type.\n *\n * - **Without** `T`: open union — accepts any `string` with IDE autocomplete\n *   hints for the built-in themes (`'system' | 'light' | 'dark'`).\n * - **With** `T`: closed union — exactly `DefaultNgTheme | T`, enabling\n *   full type-safety for custom theme sets.\n *\n * @example\n * NgTheme            // 'system' | 'light' | 'dark' | (string & {})\n * NgTheme<'sepia'>   // 'system' | 'light' | 'dark' | 'sepia'\n */\nexport type NgTheme<T extends string = string & {}> = DefaultNgTheme | T;\n\n/**\n * Resolved theme — always `'light'` or `'dark'`, never `'system'`.\n * Represents the value that comes from `matchMedia`, not user selection.\n */\nexport type NgSystemTheme = Exclude<DefaultNgTheme, 'system'>;\n\n/**\n * Theme application mode.\n * - `'attribute'`: sets `data-theme` attribute on `<html>`\n * - `'class'`: adds theme class to `<html>`\n * - `'both'`: uses both attribute and class\n */\nexport type NgMode = 'attribute' | 'class' | 'both';\n\n/**\n * Theme application strategy.\n * - `'blocking'`: theme CSS is loaded synchronously before rendering\n * - `'critters'`: theme CSS is inlined using Critters for SSR/SSG\n */\nexport type NgStrategy = 'blocking' | 'critters';\n\n/**\n * Library configuration.\n *\n * @typeParam T - Custom theme literals. Defaults to open `string`, preserving\n * backwards compatibility. Pass specific literals (e.g. `'sepia' | 'ocean'`)\n * via {@link provideThemeStack} to get a closed, type-safe theme union.\n */\nexport interface NgConfig<T extends string = string & {}> {\n  /** The theme to use on first visit or when no preference is saved. Default: 'system'. */\n  defaultTheme: NgTheme<T>;\n\n  /** Key used to persist theme preference in localStorage. Default: 'ngx-theme-stack'. */\n  storageKey: string;\n\n  /** \n   * How the theme should be applied to the document (via class, attribute or both). \n   * Default: 'class'.\n   */\n  mode: NgMode;\n\n  /** \n   * Performance strategy for anti-flash.\n   * Use 'critters' (default) to inline all theme CSS in <head> — works for CSR, SSR, and SSG.\n   * Use 'blocking' to load themes.css as a render-blocking stylesheet (HTTP-cacheable).\n   */\n  strategy: NgStrategy;\n\n  /**\n   * The **resolved** list of supported theme identifiers, always including the\n   * built-in themes (`'light'`, `'dark'`, `'system'`).\n   *\n   * When you pass custom themes to {@link provideThemeStack}, they are **merged**\n   * with the built-in defaults — your custom values are appended after them.\n   *\n   * @example\n   * // Input to provideThemeStack:\n   * themes: ['sepia', 'ocean'] as const\n   *\n   * // Resolved value stored in NgConfig:\n   * // ['system', 'light', 'dark', 'sepia', 'ocean']\n   *\n   * Default (no custom themes): `['system', 'light', 'dark']`.\n   */\n  themes: NgTheme<T>[];\n}\n","import { InjectionToken } from '@angular/core';\nimport { NgxThemeStackError } from '../errors';\nimport { DEFAULT_THEMES, DefaultNgTheme, NgConfig } from '../types';\n\n/**\n * ⚠ ATTENTION: SHARED CONFIGURATION VALUES\n *\n * These defaults MUST match the schematic defaults in:\n * projects/ngx-theme-stack/schematics/ng-add/constants.ts → DEFAULTS\n *\n * Schematics compile to CommonJS and cannot import from this ESM file,\n * so the values are intentionally duplicated. Change both at the same time.\n *\n * If you change defaults here, also update:\n * schematics/ng-add/constants.ts → DEFAULTS + DEFAULT_THEMES\n */\n\nexport const DEFAULT_NG_CONFIG = {\n  defaultTheme: 'system',\n  storageKey: 'ngx-theme-stack',\n  mode: 'class',\n  strategy: 'critters',\n  themes: [...DEFAULT_THEMES],\n} satisfies NgConfig;\n\n// The token uses NgConfig<string> because Angular DI resolves types at runtime\n// and cannot carry generic parameters. Type-safety is enforced at the\n// provideThemeStack() call site instead.\nexport const NGX_THEME_STACK_CONFIG = new InjectionToken<NgConfig<string>>(\n  'NGX_THEME_STACK_CONFIG',\n  {\n    factory: () => DEFAULT_NG_CONFIG,\n  },\n);\n\n/**\n * Provides Theme Stack configuration to Angular's DI system.\n *\n * The `themes` option accepts **additional** theme identifiers beyond the\n * built-in defaults. They are merged with `'light'`, `'dark'`, and `'system'`\n * so that the resolved {@link NgConfig.themes} array always includes all of\n * them — your custom values are appended after the built-ins.\n *\n * **Defaults:**\n * - `themes`: `['light', 'dark', 'system']`\n * - `defaultTheme`: `'system'`\n * - `storageKey`: `'ngx-theme-stack'`\n * - `mode`: `'class'`\n * - `strategy`: `'critters'`\n\n *\n * The type parameter `T` is **inferred automatically** from the `themes` array\n * when passed as a `const` — no need to specify it manually.\n *\n * @typeParam T - Custom theme string literals, inferred from the `themes` option.\n *\n * @param config - Optional partial configuration. Omitted fields fall back to\n *   {@link DEFAULT_NG_CONFIG}.\n *\n * @throws {@link NgxThemeStackError}\n *   - If any entry in `themes` is an empty or whitespace-only string.\n *   - If `defaultTheme` is not present in the resolved (merged) themes array.\n *   - If `storageKey` is an empty or whitespace-only string.\n *\n * @example\n * // Default — uses built-in themes and sensible defaults\n * provideThemeStack()\n *\n * @example\n * // Critters strategy — inlines all theme CSS in <head> (works for CSR, SSR, and SSG)\n * provideThemeStack({\n *   strategy: 'critters',\n *   mode: 'class',\n * })\n *\n * @example\n * // Closed union: TypeScript infers 'sepia' | 'ocean' from the array\n * provideThemeStack({\n *   themes: ['sepia', 'ocean'] as const,\n *   defaultTheme: 'sepia',   // ✅ in resolved themes\n *   // defaultTheme: 'nope', // ❌ throws NgxThemeStackError at runtime\n * })\n *\n * @example\n * // Custom storage key and mode\n * provideThemeStack({\n *   storageKey: 'my-app-theme',\n *   mode: 'attribute',\n * })\n */\nexport function provideThemeStack<const T extends string = DefaultNgTheme>(\n  config: Partial<NgConfig<T>> = {},\n) {\n  config.themes?.forEach((t) => {\n    if (t.trim() === '') throw new NgxThemeStackError('Theme cannot be empty or whitespace.');\n  });\n\n  const themes = config.themes\n    ? Array.from(new Set([...DEFAULT_NG_CONFIG.themes, ...config.themes]))\n    : DEFAULT_NG_CONFIG.themes;\n\n  if (config.defaultTheme && !(themes as string[]).includes(config.defaultTheme as string)) {\n    throw new NgxThemeStackError(\n      `\"defaultTheme\" must be one of the resolved themes: [${themes.join(', ')}].`,\n    );\n  }\n\n  if (config.storageKey !== undefined && config.storageKey.trim() === '') {\n    throw new NgxThemeStackError('\"storageKey\" cannot be empty or whitespace.');\n  }\n\n  return {\n    provide: NGX_THEME_STACK_CONFIG,\n    useValue: {\n      ...DEFAULT_NG_CONFIG,\n      ...config,\n      themes,\n    } as NgConfig<string>,\n  };\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n  afterNextRender,\n  computed,\n  DestroyRef,\n  DOCUMENT,\n  effect,\n  inject,\n  Injectable,\n  PLATFORM_ID,\n  signal,\n} from '@angular/core';\nimport { NGX_THEME_STACK_CONFIG } from '../config';\nimport { NgxThemeStackError } from '../errors';\nimport { NgSystemTheme, NgTheme } from '../types';\n\n/**\n * Core service for managing the application's color theme.\n *\n * Handles theme persistence, system preference detection, and DOM updates.\n * Supports built-in themes ('dark', 'light', 'system') and custom extensions.\n */\n@Injectable({ providedIn: 'root' })\nexport class CoreThemeService {\n  // ── Dependencies ──────────────────────────────────────────────────────────\n\n  readonly #config = inject(NGX_THEME_STACK_CONFIG);\n  readonly #destroyRef = inject(DestroyRef);\n  readonly #document = inject(DOCUMENT);\n  readonly #isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n  // ── Theme configuration ───────────────────────────────────────────────────\n\n  /** The initial stored theme read from localStorage on startup. */\n  readonly #initialStoredTheme = this.readStoredTheme();\n\n  /** List of available themes for Select/Cycle services. Defaults to ['system', 'light', 'dark']. */\n  readonly availableThemes = this.#config.themes;\n\n  /** Internal Set for O(1) existence checks. */\n  readonly #validThemes = new Set<NgTheme>(this.availableThemes);\n\n  /**\n   * The anti-flash class to remove from the host element.\n   * Internal mechanism to bridge the gap between the blocking script's\n   * initial DOM state and Angular's first effect run.\n   */\n  #antiFlashClass: string | null = null;\n\n  // ── System preference ─────────────────────────────────────────────────────\n\n  /** MediaQueryList for OS color scheme, created once and reused. Null in SSR. */\n  readonly #mediaQuery: MediaQueryList | null = this.#isBrowser\n    ? (this.#document.defaultView?.matchMedia('(prefers-color-scheme: dark)') ?? null)\n    : null;\n\n  readonly #systemPreference = signal<NgSystemTheme>(this.resolveSystemPreference());\n\n  // ── Theme state ───────────────────────────────────────────────────────────\n\n  readonly #selectedTheme = signal<NgTheme>(this.resolveInitialTheme());\n\n  /** The theme explicitly selected by the user. May be `'system'`. */\n  readonly selectedTheme = this.#selectedTheme.asReadonly();\n\n  /** Resolved theme applied to the DOM. Always `'dark'` or `'light'` (or custom) — never `'system'`. */\n  readonly resolvedTheme = computed(() => {\n    const theme = this.#selectedTheme();\n    return theme === 'system' ? this.#systemPreference() : theme;\n  });\n\n  /**\n   * Whether the currently applied theme is dark.\n   *\n   * Returns `false` when a custom theme (e.g. `'sunset'`) is active — use\n   * `resolvedTheme()` directly if you need to inspect the current custom theme.\n   */\n  readonly isDark = computed(() => this.resolvedTheme() === 'dark');\n\n  /**\n   * Whether the currently applied theme is light.\n   *\n   * Returns `false` when a custom theme (e.g. `'sepia'`) is active — use\n   * `resolvedTheme()` directly if you need to inspect the current custom theme.\n   */\n  readonly isLight = computed(() => this.resolvedTheme() === 'light');\n\n  /** Whether the currently applied theme is system. */\n  readonly isSystem = computed(() => this.selectedTheme() === 'system');\n\n  /**\n   * Whether the service has completed client-side initialization.\n   *\n   * `false` during SSR and on the very first render pass before the initial theme\n   * is resolved from `localStorage`. Becomes `true` immediately after the\n   * first browser render pass.\n   *\n   * **Important:** Guard template elements that display `selectedTheme()` or\n   * `resolvedTheme()` behind this signal to prevent hydration-mismatch flashes\n   * (e.g. if the server renders the default 'system' but the user has 'dark' stored).\n   *\n   * @example\n   * ```html\n   * {{ theme.isHydrated() ? theme.selectedTheme() : '...' }}\n   * ```\n   */\n  readonly #isHydrated = signal(false);\n\n  readonly isHydrated = this.#isHydrated.asReadonly();\n\n  // ── Event handler ─────────────────────────────────────────────────────────\n\n  readonly #onSystemPreferenceChange = () =>\n    this.#systemPreference.set(this.resolveSystemPreference());\n\n  // ── Lifecycle ─────────────────────────────────────────────────────────────\n\n  constructor() {\n    this.captureAntiFlashClass();\n\n    if (this.#isBrowser && this.#selectedTheme() === 'system') {\n      this.startSystemThemeListener();\n    }\n\n    effect(() => this.applyThemeToDOM(this.resolvedTheme()));\n    afterNextRender(() => this.#isHydrated.set(true));\n    this.#destroyRef.onDestroy(() => this.stopSystemThemeListener());\n  }\n\n  // ── Public API ────────────────────────────────────────────────────────────\n\n  /**\n   * Changes the active theme.\n   *\n   * Persists the choice explicitly so that switching e.g. from `'system'` to\n   * `'light'` is saved even when the resolved theme did not change\n   * (system preference was already `'light'`).\n   *\n   * @param theme - The theme to apply: `'dark'`, `'light'`, `'system'`, or a custom theme name.\n   * @throws If `theme` is not a valid theme according to library configuration.\n   */\n  public setTheme(theme: NgTheme): void {\n    if (!this.#validThemes.has(theme)) {\n      throw new NgxThemeStackError(\n        `Invalid theme: \"${theme}\". Valid values are: ${[...this.#validThemes].join(', ')}.`,\n      );\n    }\n    if (!this.#isBrowser) return;\n    if (theme === this.#selectedTheme()) return;\n    if (theme === 'system') {\n      this.#systemPreference.set(this.resolveSystemPreference());\n      this.startSystemThemeListener();\n    } else {\n      this.stopSystemThemeListener();\n    }\n\n    this.#selectedTheme.set(theme);\n    this.saveTheme(theme);\n  }\n\n  // ── Private ───────────────────────────────────────────────────────────────\n\n  private resolveSystemPreference(): NgSystemTheme {\n    return this.#mediaQuery?.matches ? 'dark' : 'light';\n  }\n\n  private resolveInitialTheme(): NgTheme {\n    const theme = this.#initialStoredTheme;\n    if (theme && this.#validThemes.has(theme as NgTheme)) {\n      return theme as NgTheme;\n    }\n    return this.#config.defaultTheme;\n  }\n\n  private startSystemThemeListener(): void {\n    if (!this.#mediaQuery) return;\n    this.stopSystemThemeListener();\n    this.#mediaQuery.addEventListener('change', this.#onSystemPreferenceChange);\n  }\n\n  private stopSystemThemeListener(): void {\n    this.#mediaQuery?.removeEventListener('change', this.#onSystemPreferenceChange);\n  }\n\n  private applyThemeToDOM(theme: NgTheme): void {\n    if (!this.#isBrowser) return;\n\n    const host = this.#document.documentElement;\n\n    if (this.#antiFlashClass) {\n      host.classList.remove(this.#antiFlashClass);\n      this.#antiFlashClass = null;\n    }\n\n    const { mode } = this.#config;\n\n    if (mode === 'attribute' || mode === 'both') {\n      this.applyThemeAttribute(host, theme);\n    }\n\n    if (mode === 'class' || mode === 'both') {\n      this.applyThemeClasses(host, theme);\n    }\n\n    this.applyColorSchemeHint(host, theme);\n  }\n\n  private applyThemeAttribute(host: HTMLElement, theme: NgTheme): void {\n    host.setAttribute('data-theme', theme);\n  }\n\n  private applyThemeClasses(host: HTMLElement, theme: NgTheme): void {\n    host.classList.remove(...this.availableThemes);\n    host.classList.add(theme);\n  }\n\n  private applyColorSchemeHint(host: HTMLElement, theme: NgTheme): void {\n    if (theme === 'dark' || theme === 'light') {\n      host.style.setProperty('color-scheme', theme);\n      return;\n    }\n\n    host.style.removeProperty('color-scheme');\n  }\n\n  private captureAntiFlashClass(): void {\n    if (!this.#isBrowser || !this.#initialStoredTheme) return;\n\n    if (\n      !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(this.#initialStoredTheme) ||\n      !this.#validThemes.has(this.#initialStoredTheme as NgTheme)\n    ) {\n      this.#antiFlashClass = null;\n      return;\n    }\n\n    if (this.#initialStoredTheme === 'system') {\n      this.#antiFlashClass = this.resolveSystemPreference();\n      return;\n    }\n\n    this.#antiFlashClass = this.#initialStoredTheme;\n  }\n\n  private readStoredTheme(): string | null {\n    if (!this.#isBrowser) return null;\n\n    try {\n      return localStorage.getItem(this.#config.storageKey);\n    } catch (e) {\n      console.warn('[ngx-theme-stack] Could not read theme from localStorage.', e);\n      return null;\n    }\n  }\n\n  private saveTheme(theme: NgTheme): void {\n    if (!this.#isBrowser) return;\n\n    try {\n      localStorage.setItem(this.#config.storageKey, theme);\n    } catch (e) {\n      console.warn('[ngx-theme-stack] Could not save theme to localStorage.', e);\n    }\n  }\n}\n","import { computed, inject, Injectable } from '@angular/core';\nimport { CoreThemeService } from '../core/core-theme.service';\n\n/**\n * Convenience service for cycling through themes in a fixed order.\n *\n * Default cycle: `'system'` → `'light'` → `'dark'` → `'system'` → ...\n *\n * Use this when you want to offer users a single button that rotates\n * through all available theme options.\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeCycleService {\n  readonly #core = inject(CoreThemeService);\n\n  /** List of all configured themes for cycling. Defaults to `['light', 'dark', 'system']`. */\n  readonly availableThemes = this.#core.availableThemes;\n\n  /** The theme explicitly selected by the user. May be `'system'`. */\n  readonly selectedTheme = this.#core.selectedTheme;\n\n  /** Resolved theme currently applied to the DOM. Always concrete — never `'system'`. */\n  readonly resolvedTheme = this.#core.resolvedTheme;\n\n  /** Index of the currently selected theme in the cycle. */\n  readonly cycleIndex = computed(() => {\n    return this.availableThemes.indexOf(this.selectedTheme());\n  });\n\n  /** The theme that comes before the currently selected theme in the cycle. */\n  readonly preceding = computed(() => {\n    const index = this.cycleIndex();\n    const len = this.availableThemes.length;\n    return this.availableThemes[(index - 1 + len) % len];\n  });\n\n  /** The theme that comes after the currently selected theme in the cycle. */\n  readonly upcoming = computed(() => {\n    const index = this.cycleIndex();\n    return this.availableThemes[(index + 1) % this.availableThemes.length];\n  });\n\n  /** Whether the currently applied theme is `'dark'`. */\n  readonly isDark = this.#core.isDark;\n\n  /** Whether the currently applied theme is `'light'`. */\n  readonly isLight = this.#core.isLight;\n\n  /** Whether the user has explicitly selected `'system'` preference. */\n  readonly isSystem = this.#core.isSystem;\n\n  /**\n   * Whether the service has completed client-side initialization and\n   * resolved the real persisted theme. Use to prevent hydration flashes.\n   */\n  readonly isHydrated = this.#core.isHydrated;\n\n  /**\n   * Advances to the next theme in the cycle.\n   *\n   * Cycle order is determined by the configured `themes` property in `NgConfig`.\n   *\n   * If the current theme is not found in the cycle (e.g. set externally),\n   * the cycle restarts from the first theme.\n   */\n  cycle(): void {\n    this.#core.setTheme(this.upcoming());\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CoreThemeService } from '../core/core-theme.service';\nimport { NgTheme } from '../types';\n\n/**\n * Convenience service for selecting a theme from a list.\n *\n * Use this when you want to bind a `<select>` or a group of radio/tab\n * buttons to the full set of available themes.\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeSelectService {\n  readonly #core = inject(CoreThemeService);\n\n  /** List of all configured themes. Defaults to `['light', 'dark', 'system']`. */\n  readonly availableThemes = this.#core.availableThemes;\n\n  /** The theme explicitly selected by the user. May be `'system'`. */\n  readonly selectedTheme = this.#core.selectedTheme;\n\n  /** Resolved theme currently applied to the DOM. Always concrete — never `'system'`. */\n  readonly resolvedTheme = this.#core.resolvedTheme;\n\n  /** Whether the currently applied theme is `'dark'`. */\n  readonly isDark = this.#core.isDark;\n\n  /** Whether the currently applied theme is `'light'`. */\n  readonly isLight = this.#core.isLight;\n\n  /** Whether the user has explicitly selected `'system'` preference. */\n  readonly isSystem = this.#core.isSystem;\n\n  /**\n   * Whether the service has completed client-side initialization and\n   * resolved the real persisted theme. Use to prevent hydration flashes.\n   */\n  readonly isHydrated = this.#core.isHydrated;\n\n  /**\n   * Applies the given theme.\n   *\n   * @param theme - The theme to apply: `'dark'`, `'light'`, `'system'`, or custom.\n   * @throws If `theme` is not a valid theme according to library configuration.\n   */\n  select(theme: NgTheme): void {\n    this.#core.setTheme(theme);\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CoreThemeService } from '../core/core-theme.service';\n\n/**\n * Convenience service for toggling between `'dark'` and `'light'`.\n *\n * Use this when you only need a simple on/off switch and do not\n * need to manage `'system'` or cycle through themes.\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeToggleService {\n  readonly #core = inject(CoreThemeService);\n\n  /** Resolved theme currently applied to the DOM. Always concrete — never `'system'`. */\n  readonly resolvedTheme = this.#core.resolvedTheme;\n\n  /** The theme explicitly selected by the user. May be `'system'`. */\n  readonly selectedTheme = this.#core.selectedTheme;\n\n  /** Whether the currently applied theme is `'dark'`. */\n  readonly isDark = this.#core.isDark;\n\n  /** Whether the currently applied theme is `'light'`. */\n  readonly isLight = this.#core.isLight;\n\n  /** Whether the user has explicitly selected `'system'` preference. */\n  readonly isSystem = this.#core.isSystem;\n\n  /**\n   * Whether the service has completed client-side initialization and\n   * resolved the real persisted theme. Use to prevent hydration flashes.\n   */\n  readonly isHydrated = this.#core.isHydrated;\n\n  /**\n   * Toggles between `'dark'` and `'light'`.\n   *\n   * If the selected theme is explicitly `'dark'`, switches to `'light'`.\n   * Otherwise (including `'system'`), switches to `'dark'`.\n   */\n  toggle(): void {\n    const next = this.#core.resolvedTheme() === 'dark' ? 'light' : 'dark';\n    this.#core.setTheme(next);\n  }\n}\n","/*\n * Public API Surface of ngx-theme-stack\n */\n\nexport * from './lib/core/core-theme.service';\nexport * from './lib/config';\nexport * from './lib/services/theme-cycle.service';\nexport * from './lib/services/theme-select.service';\nexport * from './lib/services/theme-toggle.service';\nexport * from './lib/types';\nexport * from './lib/errors';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}