import{type TemplateResult,type PropertyValues}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';export type AudioVisualizerMode='bars'|'waveform';export type AudioVisualizerState='idle'|'listening'|'thinking'|'speaking'; /** * `` — a presentational, canvas-drawn voice-activity visualization. Its * `mode` is `"bars"` (default) or `"waveform"`. Driven by a `MediaStream` * (lazily wired to a WebAudio `AnalyserNode`), a numeric `level` for hosts that already compute * levels (e.g. `lr-push-to-talk`'s `lr-level`), or `state` alone for an ambient animation when no * real signal exists. A real signal (`stream` or `level`) always drives amplitude regardless of * `prefers-reduced-motion` — that is live, user-controlled feedback, not decorative motion; only the * signal-less ambient animation is throttled and simplified under reduced motion. * * Animation frames are only scheduled while the drawn output is actually time-varying (live analyser * data, or a non-reduced ambient pulse/sweep). Static output — a constant `level`, idle bars, or the * flattened reduced-motion ambient patterns — draws once and stops; any change that could alter the * next frame (properties, stream/`AudioContext` state, size, theme, motion preference) re-enters the * loop via `scheduleDraw()`. The loop is also paused while the host is scrolled off-screen (an * `IntersectionObserver`-gated `visible` flag, mirroring ``'s own `draw()` gating), so a * live-signal visualizer buried behind later transcript messages doesn't keep repainting for nobody. * Canvas-bound theme colors are materialized through a live DOM color probe before drawing, so * `currentColor`, inherited expressions, and invalid values cannot silently paint as stale black. * * @customElement lr-audio-visualizer * @csspart base - The root wrapper. * @csspart canvas - The drawing surface (`aria-hidden`; the host itself carries `role="img"` and the * accessible name). * @cssprop [--lr-audio-visualizer-color=var(--lr-color-brand)] - Active bar/waveform color. * @cssprop [--lr-audio-visualizer-quiet-color=var(--lr-color-brand-border-normal)] - Inactive/idle * color. Chosen over `--lr-color-brand-quiet` for its WCAG 1.4.11 non-text contrast against * `--lr-color-surface` (the idle bars have no other distinguishing shape or border). * @cssprop [--lr-audio-visualizer-height=var(--lr-size-3rem)] - The host's block size, which the * canvas fills at 100%. * @cssprop [--lr-audio-visualizer-ambient-duration=var(--lr-duration-ambient)] - Time-only * duration of one signal-less ambient pulse or sweep cycle. * @status stable * @since 4.0.0 */ export declare class LyraAudioVisualizer extends LyraElement{static styles:import("lit").CSSResultGroup[];static get observedAttributes():string[];stream:MediaStream|null; /** Externally-computed amplitude, `[0, 1]`, for a host that already derives its own level * (e.g. `lr-push-to-talk`'s `lr-level`). `null` (the default) means "no external signal" -- * see `effectiveLevel` for how a non-null value is clamped/NaN-guarded before it feeds `draw()`. */ level:number|null;private _state;get state():AudioVisualizerState;set state(next:AudioVisualizerState);private _mode; /** Drawing vocabulary: discrete `bars` or a continuous `waveform`. */ get mode():AudioVisualizerMode;set mode(next:AudioVisualizerMode);barCount:number; /** Amplitude multiplier applied in `draw()`. NaN/non-finite falls back to `1` via `effectiveGain`. */ gain:number; /** Accessible-name override. Unset (the default) auto-generates "Voice activity: {state}". */ label:string;private canvas?;private resizeObserver?;private dprQuery?;private dprChangeListener?;private motionQuery?;private motionChangeListener?;private drawFrameRequest?;private lastAmbientDrawMs;private generatedAriaLabel?; /** Host size cached from the `ResizeObserver` so `draw()` never forces a per-frame layout read. */ private hostSize?; /** Token colors resolved once per theme change so `draw()` never calls `getComputedStyle` per frame. */ private resolvedColors?; /** Time-only ambient cycle duration resolved once per theme scope, avoiding a style read per frame. */ private ambientDurationMs?;private audioCtx?;private analyser?;private sourceNode?;private timeDomainData?; /** Whether the host is currently on-screen, per `intersectionObserver` below. Gates * `scheduleDraw()` so a visualizer scrolled out of view (e.g. behind later transcript messages) * while still driven by a live `stream`/non-idle `state` stops burning CPU on a redraw loop * nobody can see -- mirrors ``'s own `visible`-gated `draw()`. Not `@state()`: nothing * in `render()` depends on it, so making it reactive would only schedule pointless extra update * passes. */ private visible; /** An owner-realm observer starts unknown so no canvas work can race ahead of its first entry. */ private visibilityKnown;private intersectionObserver?;private intersectionGeneration;private get effectiveBarCount(); /** `level` normalized to `[0, 1]`, or `null` when no external signal is set. A non-null-but-NaN * `level` (e.g. a bad attribute) still counts as "level-driven" (see `hasLiveSignal`) but * clamps to `0` here rather than flowing NaN into the canvas draw. */ private get effectiveLevel();private get effectiveGain();constructor();connectedCallback():void;disconnectedCallback():void;adoptedCallback():void; /** Binds visibility in the current document. If the platform cannot safely provide an observer, * retain the established eager draw behavior rather than making the visualizer permanently blank. */ private bindVisibilityObserver;private clearVisibilityObserver;private restoreImmediateVisibility;private watchDpr;private clearDprWatcher;private clearMotionWatcher; /** Redraws canvas content after an upstream token or theme change. */ refreshTheme():void;private get hasUsableAudioStream(); /** Lazily creates (or tears down) the `AudioContext`/`AnalyserNode` pair to match `stream`. * Clearing `stream` suspends the context (cheap to resume if reassigned soon); `disconnectedCallback` * is what actually closes it. */ private syncAnalyser;private onAudioCtxStateChange;private closeAudioContext;private get hasLiveSignal();private stateLabel;protected willUpdate(changed:PropertyValues):void;attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void;private syncDefaultRole;protected updated(changed:PropertyValues):void; /** Whether the next frame's content differs from the current one with no external change — i.e. * the drawing is a function of time: live analyser data, or a non-reduced ambient pulse/sweep. * A constant `level`, the flat idle pattern, and every reduced-motion ambient pattern are all * time-independent, so re-rendering them each frame would produce identical pixels. */ private get isTimeDriven();private scheduleDraw;private drawFrame;private cancelDrawFrame;private barsFromTimeDomain; /** The static, reduced-motion-aware ambient pattern used when neither `stream` nor `level` * supplies a real signal. `idle` is quiet and flat; `listening`/`speaking` are a gentle ready * pulse; `thinking` sweeps a moving peak across the array unless `reduced`, in which case it * collapses to a flat mid-height pattern (never a frozen mid-sweep frame). */ private ambientAmplitudes; /** Resolves the time-only ambient duration once per theme scope, alongside the cached colors. * `getComputedStyle` returns custom-property text, so only complete `ms`/`s` values can become * a cycle duration; malformed, zero, negative, or non-finite values retain the shared default. */ private resolveAmbientDuration;private currentAmplitudes; /** Resolves and validates the two drawing colors once; the theme/color-scheme observers and * `refreshTheme()` invalidate the cached pair, so steady-state frames never pay for the DOM * color probe or `getComputedStyle`. */ private resolveColors;private draw;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-audio-visualizer':LyraAudioVisualizer;}}