@livelayer/react 0.2.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +346 -26
- package/dist/index.d.ts +256 -0
- package/dist/index.js +2 -1
- package/dist/index.mjs +1834 -1040
- package/dist/styles.css +31 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,15 +3,38 @@ import { AgentState } from '@livelayer/sdk';
|
|
|
3
3
|
import { Component } from 'react';
|
|
4
4
|
import { ConnectionState } from '@livelayer/sdk';
|
|
5
5
|
import { CSSProperties } from 'react';
|
|
6
|
+
import { ElementType } from 'react';
|
|
6
7
|
import { ErrorInfo } from 'react';
|
|
7
8
|
import { FC } from 'react';
|
|
9
|
+
import { FormHTMLAttributes } from 'react';
|
|
10
|
+
import { ForwardRefExoticComponent } from 'react';
|
|
11
|
+
import { InputHTMLAttributes } from 'react';
|
|
8
12
|
import { JSX } from 'react/jsx-runtime';
|
|
9
13
|
import { LiveKitSession } from '@livelayer/sdk';
|
|
10
14
|
import { ReactNode } from 'react';
|
|
15
|
+
import { RefAttributes } from 'react';
|
|
11
16
|
import { Room } from 'livekit-client';
|
|
17
|
+
import { SelectHTMLAttributes } from 'react';
|
|
12
18
|
import { SessionOptions } from '@livelayer/sdk';
|
|
19
|
+
import { TextareaHTMLAttributes } from 'react';
|
|
13
20
|
import { TranscriptEntry } from '@livelayer/sdk';
|
|
14
21
|
|
|
22
|
+
/**
|
|
23
|
+
* What the agent's data-channel commands are allowed to do. Pass to
|
|
24
|
+
* `<AvatarWidget capabilities={[...]} />` to restrict.
|
|
25
|
+
*
|
|
26
|
+
* Mapping:
|
|
27
|
+
* "navigate" → navigate command
|
|
28
|
+
* "scroll" → scroll_to + scroll_page commands
|
|
29
|
+
* "click" → click command
|
|
30
|
+
* "fill_forms" → fill_form + focus_field commands
|
|
31
|
+
* "submit_forms" → submit_form command
|
|
32
|
+
* "read_page" → request_page_context + request_routes commands
|
|
33
|
+
*
|
|
34
|
+
* Default (undefined): everything enabled (matches 0.3.x behavior).
|
|
35
|
+
*/
|
|
36
|
+
export declare type AgentCapability = "navigate" | "scroll" | "click" | "fill_forms" | "submit_forms" | "read_page";
|
|
37
|
+
|
|
15
38
|
/**
|
|
16
39
|
* Agent commands streamed over the LiveKit data channel. The base package
|
|
17
40
|
* recognizes universal types (agent_state, avatar_active, etc.) and forwards
|
|
@@ -92,6 +115,78 @@ export declare interface AvatarWidgetProps {
|
|
|
92
115
|
allowScreenShare?: boolean;
|
|
93
116
|
allowTyping?: boolean;
|
|
94
117
|
allowMic?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Patterns where the widget MAY render. If set, widget renders ONLY on
|
|
120
|
+
* matching paths. See `RoutePattern` for accepted forms (string globs,
|
|
121
|
+
* RegExp, or function predicate). Mutually compatible with `hideOn`.
|
|
122
|
+
*
|
|
123
|
+
* Pass `pathname` alongside this prop in Next.js / React Router apps.
|
|
124
|
+
*/
|
|
125
|
+
showOn?: RoutePattern[];
|
|
126
|
+
/**
|
|
127
|
+
* Patterns where the widget will NEVER render. Wins over showOn.
|
|
128
|
+
* Common safe defaults: `["/privacy", "/terms", "/legal/*"]`.
|
|
129
|
+
*/
|
|
130
|
+
hideOn?: RoutePattern[];
|
|
131
|
+
/**
|
|
132
|
+
* Current pathname. REQUIRED for Next.js App Router and React Router v6+
|
|
133
|
+
* because their internal routers update before window.location does.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* import { usePathname } from "next/navigation";
|
|
137
|
+
* <AvatarWidget pathname={usePathname()} hideOn={["/privacy"]} />
|
|
138
|
+
*/
|
|
139
|
+
pathname?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Called when the agent emits a `navigate` command. Wire to your
|
|
142
|
+
* router. If omitted, the widget falls back to (1) clicking a
|
|
143
|
+
* matching anchor (so Next/RR Link interceptors fire) and then
|
|
144
|
+
* (2) `history.pushState` for plain HTML sites. `window.location`
|
|
145
|
+
* is NEVER used — that would trigger a full reload and kill the
|
|
146
|
+
* session.
|
|
147
|
+
*/
|
|
148
|
+
onNavigate?: (href: string) => void;
|
|
149
|
+
/**
|
|
150
|
+
* Called when the agent emits a `scroll_to` command. Default:
|
|
151
|
+
* scrolls the matched element into view smoothly. Override to
|
|
152
|
+
* customize easing or skip the scroll entirely.
|
|
153
|
+
*/
|
|
154
|
+
onScrollToSelector?: (selector: string, behavior?: "smooth" | "instant") => void;
|
|
155
|
+
/**
|
|
156
|
+
* Override the default DOM walker. Receives the consumer's
|
|
157
|
+
* `pageContextExtras` and returns a structured context for the
|
|
158
|
+
* agent. Useful for filtering sensitive content or prepending app
|
|
159
|
+
* state that's not in the DOM.
|
|
160
|
+
*/
|
|
161
|
+
getPageContext?: (extras?: Record<string, unknown>) => PageContext | Promise<PageContext>;
|
|
162
|
+
/** Free-form metadata bag the agent should always know about. */
|
|
163
|
+
pageContextExtras?: Record<string, unknown>;
|
|
164
|
+
/**
|
|
165
|
+
* Called on agent `scroll_page` commands. Default: scrolls window
|
|
166
|
+
* by ±1 viewport height (or to top/bottom). Override to scroll a
|
|
167
|
+
* custom container.
|
|
168
|
+
*/
|
|
169
|
+
onScrollPage?: (direction: "up" | "down" | "top" | "bottom", behavior?: "smooth" | "instant") => void;
|
|
170
|
+
/**
|
|
171
|
+
* Called on agent `click` commands. Default: dispatches click on
|
|
172
|
+
* the matched element. Override to add safety checks or block
|
|
173
|
+
* specific selectors. **Use `onNavigate` for nav-shaped clicks** —
|
|
174
|
+
* `click` here is for non-nav buttons / dialogs / state toggles.
|
|
175
|
+
*/
|
|
176
|
+
onClick?: (selector: string) => void;
|
|
177
|
+
/**
|
|
178
|
+
* Restrict what the agent's commands can do. If undefined, ALL
|
|
179
|
+
* capabilities are allowed (default — matches 0.3.x behavior).
|
|
180
|
+
*
|
|
181
|
+
* Available capabilities:
|
|
182
|
+
* "navigate" — navigate command
|
|
183
|
+
* "scroll" — scroll_to + scroll_page
|
|
184
|
+
* "click" — click
|
|
185
|
+
* "fill_forms" — fill_form + focus_field
|
|
186
|
+
* "submit_forms" — submit_form
|
|
187
|
+
* "read_page" — request_page_context + request_routes
|
|
188
|
+
*/
|
|
189
|
+
capabilities?: AgentCapability[];
|
|
95
190
|
onConnect?: () => void;
|
|
96
191
|
onDisconnect?: () => void;
|
|
97
192
|
onTranscript?: (entries: TranscriptEntry[]) => void;
|
|
@@ -137,6 +232,19 @@ export declare interface CameraStateHandle {
|
|
|
137
232
|
clearError: () => void;
|
|
138
233
|
}
|
|
139
234
|
|
|
235
|
+
export declare function clearPageContextCache(): void;
|
|
236
|
+
|
|
237
|
+
export declare function clearRoutesCache(): void;
|
|
238
|
+
|
|
239
|
+
declare interface CommonFieldProps {
|
|
240
|
+
/** Field identifier. Becomes `data-ll-field` AND the input's `name`. */
|
|
241
|
+
name: string;
|
|
242
|
+
/** Visible label. Wrapped in <label>. */
|
|
243
|
+
label?: ReactNode;
|
|
244
|
+
/** Optional className for the wrapping <label>. */
|
|
245
|
+
labelClassName?: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
140
248
|
export { ConnectionState }
|
|
141
249
|
|
|
142
250
|
/**
|
|
@@ -180,6 +288,28 @@ export declare class ErrorBoundary extends Component<Props, State> {
|
|
|
180
288
|
render(): ReactNode;
|
|
181
289
|
}
|
|
182
290
|
|
|
291
|
+
export declare interface ExtractedRoute {
|
|
292
|
+
href: string;
|
|
293
|
+
text: string;
|
|
294
|
+
/** Same origin as `window.location.origin`. External links surface but flagged. */
|
|
295
|
+
internal: boolean;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
declare interface ExtractOptions {
|
|
299
|
+
/** Override doc — for tests. */
|
|
300
|
+
doc?: Document;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export declare function extractPageContext(extras?: Record<string, unknown>, opts?: ExtractOptions): PageContext;
|
|
304
|
+
|
|
305
|
+
export declare function extractRoutes(doc?: Document): ExtractedRoute[];
|
|
306
|
+
|
|
307
|
+
declare type FieldElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
308
|
+
|
|
309
|
+
export declare function getCachedPageContext(extras?: Record<string, unknown>, opts?: ExtractOptions): PageContext;
|
|
310
|
+
|
|
311
|
+
export declare function getCachedRoutes(): ExtractedRoute[];
|
|
312
|
+
|
|
183
313
|
export declare interface LegacyAgentEventDetail {
|
|
184
314
|
eventName: string;
|
|
185
315
|
data: Record<string, unknown>;
|
|
@@ -187,6 +317,46 @@ export declare interface LegacyAgentEventDetail {
|
|
|
187
317
|
|
|
188
318
|
declare type LevelSubscriber = (level: number) => void;
|
|
189
319
|
|
|
320
|
+
export declare const LiveLayerField: ForwardRefExoticComponent<LiveLayerFieldProps & RefAttributes<FieldElement>>;
|
|
321
|
+
|
|
322
|
+
export declare type LiveLayerFieldProps = (CommonFieldProps & {
|
|
323
|
+
as?: "input";
|
|
324
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, "name">) | (CommonFieldProps & {
|
|
325
|
+
as: "textarea";
|
|
326
|
+
} & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "name">) | (CommonFieldProps & {
|
|
327
|
+
as: "select";
|
|
328
|
+
children: ReactNode;
|
|
329
|
+
} & Omit<SelectHTMLAttributes<HTMLSelectElement>, "name">);
|
|
330
|
+
|
|
331
|
+
export declare const LiveLayerForm: ForwardRefExoticComponent<LiveLayerFormProps & RefAttributes<HTMLFormElement>>;
|
|
332
|
+
|
|
333
|
+
export declare interface LiveLayerFormProps extends FormHTMLAttributes<HTMLFormElement> {
|
|
334
|
+
/** Stable identifier for the form. Becomes `data-ll-form`. */
|
|
335
|
+
id: string;
|
|
336
|
+
/**
|
|
337
|
+
* One-line description the agent sees. e.g. "create account",
|
|
338
|
+
* "request a demo". The agent uses this to decide WHEN to fill the
|
|
339
|
+
* form (matching user intent → form intent).
|
|
340
|
+
*/
|
|
341
|
+
intent?: string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export declare const LiveLayerRegion: ForwardRefExoticComponent<LiveLayerRegionProps & RefAttributes<HTMLElement>>;
|
|
345
|
+
|
|
346
|
+
export declare interface LiveLayerRegionProps {
|
|
347
|
+
/** Stable identifier for the region. Becomes `data-ll-region`. */
|
|
348
|
+
id: string;
|
|
349
|
+
/** One-line description of what the agent should know about this region. */
|
|
350
|
+
intent?: string;
|
|
351
|
+
/** Element to render. Defaults to "div". */
|
|
352
|
+
as?: ElementType;
|
|
353
|
+
/** Extra class name on the wrapper. */
|
|
354
|
+
className?: string;
|
|
355
|
+
/** Inline styles. */
|
|
356
|
+
style?: CSSProperties;
|
|
357
|
+
children: ReactNode;
|
|
358
|
+
}
|
|
359
|
+
|
|
190
360
|
/**
|
|
191
361
|
* React component that renders a `<livelayer-widget>` custom element.
|
|
192
362
|
*
|
|
@@ -220,6 +390,8 @@ export declare interface LiveLayerWidgetProps {
|
|
|
220
390
|
style?: React.CSSProperties;
|
|
221
391
|
}
|
|
222
392
|
|
|
393
|
+
export declare function matchesPattern(pattern: RoutePattern, pathname: string): boolean;
|
|
394
|
+
|
|
223
395
|
export declare interface MediaDevicesHandle {
|
|
224
396
|
mics: MediaDeviceInfo[];
|
|
225
397
|
cameras: MediaDeviceInfo[];
|
|
@@ -257,6 +429,56 @@ declare interface Options_2 {
|
|
|
257
429
|
disablePersistence?: boolean;
|
|
258
430
|
}
|
|
259
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Snapshot of what the user is currently looking at, sent to the agent in
|
|
434
|
+
* response to a `request_page_context` command.
|
|
435
|
+
*
|
|
436
|
+
* Form values, password inputs, and elements marked `data-ll-private="true"`
|
|
437
|
+
* are NEVER included. See README → Privacy.
|
|
438
|
+
*/
|
|
439
|
+
export declare interface PageContext {
|
|
440
|
+
/** Full URL at the moment the snapshot was taken. */
|
|
441
|
+
url: string;
|
|
442
|
+
/** document.title at snapshot time. */
|
|
443
|
+
title: string;
|
|
444
|
+
/** Pathname only (no host, no query, no hash). */
|
|
445
|
+
pathname: string;
|
|
446
|
+
/** Author-curated regions via <LiveLayerRegion> — agent should prefer these. */
|
|
447
|
+
regions: Array<{
|
|
448
|
+
id: string;
|
|
449
|
+
intent?: string;
|
|
450
|
+
text: string;
|
|
451
|
+
}>;
|
|
452
|
+
/** Visible content fallback — auto-extracted text from headings/paragraphs. */
|
|
453
|
+
visibleText: string;
|
|
454
|
+
/** Anchor hrefs visible in viewport, top-to-bottom, max 20. */
|
|
455
|
+
visibleLinks: Array<{
|
|
456
|
+
href: string;
|
|
457
|
+
text: string;
|
|
458
|
+
}>;
|
|
459
|
+
/** Form fields visible in viewport — labels and types only, never values. */
|
|
460
|
+
visibleFields: Array<{
|
|
461
|
+
label: string;
|
|
462
|
+
type: string;
|
|
463
|
+
}>;
|
|
464
|
+
/**
|
|
465
|
+
* Author-curated forms via <LiveLayerForm> / data-ll-form. The agent
|
|
466
|
+
* uses these to call `fill_form` / `submit_form`. Values NEVER included.
|
|
467
|
+
* (0.4.0)
|
|
468
|
+
*/
|
|
469
|
+
forms: Array<{
|
|
470
|
+
id: string;
|
|
471
|
+
intent?: string;
|
|
472
|
+
fields: Array<{
|
|
473
|
+
name: string;
|
|
474
|
+
label: string;
|
|
475
|
+
type: string;
|
|
476
|
+
}>;
|
|
477
|
+
}>;
|
|
478
|
+
/** Free-form metadata bag from the consumer's pageContextExtras prop. */
|
|
479
|
+
extras?: Record<string, unknown>;
|
|
480
|
+
}
|
|
481
|
+
|
|
260
482
|
declare interface Props {
|
|
261
483
|
children: ReactNode;
|
|
262
484
|
/** Callback fired when an error is caught. Useful for telemetry. */
|
|
@@ -265,6 +487,22 @@ declare interface Props {
|
|
|
265
487
|
fallback?: ReactNode;
|
|
266
488
|
}
|
|
267
489
|
|
|
490
|
+
/**
|
|
491
|
+
* Pattern matched against the current pathname to decide if the widget
|
|
492
|
+
* renders.
|
|
493
|
+
*
|
|
494
|
+
* - `string` — exact match OR glob with `*` (one segment) and `**` (any depth)
|
|
495
|
+
* - `RegExp` — full regex flexibility
|
|
496
|
+
* - function — fully custom predicate
|
|
497
|
+
*
|
|
498
|
+
* Glob examples:
|
|
499
|
+
* "/" only the home route
|
|
500
|
+
* "/admin/X" /admin/foo but NOT /admin/foo/bar (X = single star)
|
|
501
|
+
* "/admin/XX" /admin and any descendant (XX = double star)
|
|
502
|
+
* "/blog/X/comments" /blog/x/comments but not deeper paths (X = single star)
|
|
503
|
+
*/
|
|
504
|
+
export declare type RoutePattern = string | RegExp | ((pathname: string) => boolean);
|
|
505
|
+
|
|
268
506
|
export declare interface ScreenShareStateHandle {
|
|
269
507
|
isEnabled: boolean;
|
|
270
508
|
error: string | null;
|
|
@@ -275,6 +513,15 @@ export declare interface ScreenShareStateHandle {
|
|
|
275
513
|
clearError: () => void;
|
|
276
514
|
}
|
|
277
515
|
|
|
516
|
+
/**
|
|
517
|
+
* Pure: should the widget render at this pathname?
|
|
518
|
+
*
|
|
519
|
+
* @param pathname current path, or undefined if not yet known
|
|
520
|
+
* @param showOn if set, restricts rendering to matching paths only
|
|
521
|
+
* @param hideOn if set, blocks rendering on matching paths (wins)
|
|
522
|
+
*/
|
|
523
|
+
export declare function shouldRenderAtPath(pathname: string | undefined, showOn: RoutePattern[] | undefined, hideOn: RoutePattern[] | undefined): boolean;
|
|
524
|
+
|
|
278
525
|
declare interface State {
|
|
279
526
|
hasError: boolean;
|
|
280
527
|
error: Error | null;
|
|
@@ -363,6 +610,15 @@ export declare function useMediaDevices(): MediaDevicesHandle;
|
|
|
363
610
|
|
|
364
611
|
export declare function useMicrophoneState(): MicrophoneStateHandle;
|
|
365
612
|
|
|
613
|
+
/**
|
|
614
|
+
* Returns the current pathname, reactive to SPA navigation.
|
|
615
|
+
* Pass `controlledPathname` to skip internal detection (recommended for
|
|
616
|
+
* Next.js App Router and React Router v6+ consumers).
|
|
617
|
+
*/
|
|
618
|
+
export declare function usePathname(controlledPathname?: string): string;
|
|
619
|
+
|
|
620
|
+
export declare function useRouteMatch(pathname: string | undefined, showOn: RoutePattern[] | undefined, hideOn: RoutePattern[] | undefined): boolean;
|
|
621
|
+
|
|
366
622
|
export declare function useScreenShareState(): ScreenShareStateHandle;
|
|
367
623
|
|
|
368
624
|
export declare function useTranscript(): TranscriptHandle;
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),lt=require("@livelayer/sdk"),xe=require("livekit-client");class Ue extends t.Component{constructor(){super(...arguments),this.state={hasError:!1,error:null},this.reset=()=>{this.setState({hasError:!1,error:null})}}static getDerivedStateFromError(r){return{hasError:!0,error:r}}componentDidCatch(r,l){var a,s;(s=(a=this.props).onError)==null||s.call(a,r,l)}render(){var r;return this.state.hasError?this.props.fallback?this.props.fallback:e.jsxs("div",{className:"ll-error-boundary",role:"alert",children:[e.jsx("p",{className:"ll-error-boundary__title",children:"Widget crashed"}),e.jsx("p",{className:"ll-error-boundary__message",children:((r=this.state.error)==null?void 0:r.message)||"Something went wrong."}),e.jsx("button",{type:"button",className:"ll-error-boundary__retry",onClick:this.reset,children:"Reload widget"})]}):this.props.children}}function $e(n){const[r,l]=t.useState("idle"),[a,s]=t.useState("idle"),[c,d]=t.useState([]),[m,u]=t.useState(null),[x,p]=t.useState(null),[i,o]=t.useState(null),[k,b]=t.useState(!1),[j,N]=t.useState(null),C=t.useRef(null),M=t.useRef(n.onDataMessage);M.current=n.onDataMessage,t.useEffect(()=>{const y={onConnectionStateChange:v=>{l(v),v==="connected"&&N(null)},onAgentStateChange:s,onTranscript:v=>d([...v]),onAgentConfig:u,onAudioTrack:v=>o(v),onVideoTrack:v=>p(v),onVideoTrackRemoved:()=>p(null),onError:v=>N(v),onDataMessage:v=>{var E;(E=M.current)==null||E.call(M,v)},onResumabilityChange:b},_=new lt.LiveKitSession({agentId:n.agentId,baseUrl:n.baseUrl,apiKey:n.apiKey,sessionEndpoint:n.sessionEndpoint,sessionBody:n.sessionBody},y);return C.current=_,l("idle"),s("idle"),d([]),u(null),p(null),o(null),b(!1),N(null),()=>{var v;(v=_.destroy)==null||v.call(_),C.current=null}},[n.agentId,n.baseUrl,n.apiKey,n.sessionEndpoint,JSON.stringify(n.sessionBody??{})]);const L=t.useCallback(async()=>{const y=C.current;if(y)try{await y.connect()}catch(_){throw N(_ instanceof Error?_.message:String(_)),_}},[]),R=t.useCallback(()=>{const y=C.current;y&&y.disconnect()},[]),S=t.useCallback(()=>{var y;return((y=C.current)==null?void 0:y.getRoom())??null},[]);return{connectionState:r,agentState:a,transcript:c,agentConfig:m,videoElement:x,audioElement:i,canResume:k,error:j,connect:L,disconnect:R,getRoom:S,session:C.current}}function Oe(){const n=t.useRef(null),r=t.useRef(null),l=t.useRef(null),a=t.useRef(null),s=t.useRef(new Set),c=t.useRef(null),d=t.useCallback(()=>{const i=r.current;if(!i){a.current=null;return}(!c.current||c.current.length!==i.frequencyBinCount)&&(c.current=new Uint8Array(new ArrayBuffer(i.frequencyBinCount)));const o=c.current;i.getByteFrequencyData(o);let k=0;for(let j=0;j<o.length;j++)k+=o[j];const b=k/o.length/255;for(const j of s.current)try{j(b)}catch(N){console.error("[useAudioLevel] subscriber threw:",N)}a.current=requestAnimationFrame(d)},[]),m=t.useCallback(()=>{if(n.current||typeof window>"u"||typeof AudioContext>"u")return;const i=new AudioContext,o=i.createAnalyser();o.fftSize=64,o.connect(i.destination),n.current=i,r.current=o},[]),u=t.useCallback(i=>{if(m(),!(!n.current||!r.current)){if(l.current){try{l.current.disconnect()}catch{}l.current=null}try{const o=n.current.createMediaElementSource(i);o.connect(r.current),l.current=o}catch(o){console.warn("[useAudioLevel] createMediaElementSource failed:",o);return}a.current===null&&(a.current=requestAnimationFrame(d))}},[m,d]),x=t.useCallback(()=>{if(a.current!==null&&(cancelAnimationFrame(a.current),a.current=null),l.current){try{l.current.disconnect()}catch{}l.current=null}},[]),p=t.useCallback(i=>(s.current.add(i),()=>{s.current.delete(i)}),[]);return t.useEffect(()=>()=>{if(x(),r.current){try{r.current.disconnect()}catch{}r.current=null}if(n.current){try{n.current.close()}catch{}n.current=null}s.current.clear(),c.current=null},[x]),{attach:u,detach:x,subscribe:p}}function Ve(){const[n,r]=t.useState(!1),[l,a]=t.useState(null),s=t.useRef(null),c=t.useRef(null),d=t.useCallback(async p=>{if(s.current&&c.current){try{await c.current.localParticipant.unpublishTrack(s.current)}catch{}s.current.stop(),s.current=null}c.current=p,a(null);try{const i=await xe.createLocalAudioTrack({echoCancellation:!0,noiseSuppression:!0});await p.localParticipant.publishTrack(i),s.current=i,r(i.isMuted)}catch(i){const o=i instanceof Error&&i.name==="NotAllowedError"?"Enable your microphone to talk with the agent.":"Microphone unavailable. Check browser permissions and try again.";throw a(o),i}},[]),m=t.useCallback(()=>{const p=s.current;p&&(p.isMuted?(p.unmute(),r(!1)):(p.mute(),r(!0)))},[]),u=t.useCallback(()=>{const p=s.current,i=c.current;if(p&&i){try{i.localParticipant.unpublishTrack(p)}catch{}p.stop()}s.current=null,c.current=null,r(!1)},[]),x=t.useCallback(()=>a(null),[]);return{isMuted:n,micError:l,toggleMute:m,setupMic:d,teardownMic:u,clearError:x}}const at={resolution:{width:640,height:480,frameRate:24}};function We(){const[n,r]=t.useState(!1),[l,a]=t.useState(null),[s,c]=t.useState(null),[d,m]=t.useState(""),u=t.useRef(null),x=t.useRef(null),p=t.useCallback(C=>{u.current=C},[]),i=t.useCallback(()=>{const C=u.current,M=x.current;if(M&&C){const L=C.localParticipant.getTrackPublication(xe.Track.Source.Camera);if(L!=null&&L.track){try{C.localParticipant.unpublishTrack(L.track)}catch{}L.track.stop()}else M.stop()}x.current=null,c(null),r(!1)},[]),o=t.useCallback(async C=>{const M=u.current;if(M){a(null);try{const L={...at};C&&(L.deviceId=C);const R=await xe.createLocalVideoTrack(L);await M.localParticipant.publishTrack(R),x.current=R;const S=R.attach();c(S),r(!0),C&&m(C);try{M.localParticipant.publishData(new TextEncoder().encode(JSON.stringify({type:"user_camera_on"})),{reliable:!0})}catch{}}catch(L){const R=L instanceof Error&&L.name==="NotAllowedError"?"Enable your camera in the browser to share video.":"Camera unavailable. Check permissions and try again.";a(R)}}},[]),k=t.useCallback(async()=>{n?i():await o(d||void 0)},[n,d,i,o]),b=t.useCallback(async C=>{i(),await o(C)},[i,o]),j=t.useCallback(()=>{i(),u.current=null,a(null),m("")},[i]),N=t.useCallback(()=>a(null),[]);return t.useEffect(()=>()=>{x.current&&x.current.stop()},[]),{isEnabled:n,error:l,previewEl:s,activeDeviceId:d,toggle:k,switchDevice:b,attachRoom:p,teardown:j,clearError:N}}function Fe(){const[n,r]=t.useState(!1),[l,a]=t.useState(null),[s,c]=t.useState(null),d=t.useRef(null),m=t.useCallback(o=>{d.current=o},[]),u=t.useCallback(()=>c(null),[]),x=t.useCallback(async()=>{const o=d.current;if(o){if(n){try{await o.localParticipant.setScreenShareEnabled(!1)}catch{}u(),r(!1);return}a(null);try{await o.localParticipant.setScreenShareEnabled(!0);let k=0;const b=()=>{const j=o.localParticipant.getTrackPublication(xe.Track.Source.ScreenShare);if(j!=null&&j.track){const N=j.track.attach();c(N),r(!0);try{o.localParticipant.publishData(new TextEncoder().encode(JSON.stringify({type:"user_screen_share_on"})),{reliable:!0})}catch{}return}k++<10?setTimeout(b,100):r(!0)};b()}catch(k){const b=k instanceof Error?k.name:"";b!=="NotAllowedError"&&b!=="AbortError"&&a("Screen share unavailable. Try again."),r(!1)}}},[n,u]),p=t.useCallback(()=>{const o=d.current;if(o&&n)try{o.localParticipant.setScreenShareEnabled(!1)}catch{}u(),r(!1),a(null),d.current=null},[n,u]),i=t.useCallback(()=>a(null),[]);return{isEnabled:n,error:l,previewEl:s,toggle:x,attachRoom:m,teardown:p,clearError:i}}function Ke(){const[n,r]=t.useState([]),[l,a]=t.useState([]),s=t.useCallback(async()=>{if(!(typeof navigator>"u"||!navigator.mediaDevices))try{const c=await navigator.mediaDevices.enumerateDevices();r(c.filter(d=>d.kind==="audioinput")),a(c.filter(d=>d.kind==="videoinput"))}catch{}},[]);return t.useEffect(()=>{if(s(),typeof navigator>"u"||!navigator.mediaDevices)return;const c=()=>void s();return navigator.mediaDevices.addEventListener("devicechange",c),()=>navigator.mediaDevices.removeEventListener("devicechange",c)},[s]),{mics:n,cameras:l,refresh:s}}function qe(n,r,l=!1){const[a,s]=t.useState(null),[c,d]=t.useState(null),[m,u]=t.useState(!l&&!!n);return t.useEffect(()=>{if(l||!n){u(!1);return}const x=new AbortController,p=r||"https://app.livelayer.studio";return u(!0),d(null),fetch(`${p}/api/widget/agent/${encodeURIComponent(n)}`,{signal:x.signal}).then(async i=>{if(!i.ok){const o=await i.json().catch(()=>({}));throw new Error(o.error||`HTTP ${i.status}`)}return i.json()}).then(i=>{x.signal.aborted||(s(i),u(!1))}).catch(i=>{x.signal.aborted||(d(i instanceof Error?i.message:"Agent lookup failed"),u(!1))}),()=>x.abort()},[n,r,l]),{info:a,error:c,loading:m}}function it(n){if(typeof window>"u")return null;try{return window.localStorage.getItem(n)}catch{return null}}function ot(n,r){if(!(typeof window>"u"))try{window.localStorage.setItem(n,r)}catch{}}function Ge({value:n,defaultValue:r="expanded",onChange:l}={}){const a=n!==void 0,[s,c]=t.useState(r),d=a?n:s,m=t.useCallback(u=>{u!==d&&(a||c(u),l==null||l(u))},[d,a,l]);return[d,m]}const ct=["hidden","minimized","expanded"];function dt(n){return n&&ct.includes(n)?n:null}function Ye({value:n,defaultValue:r="expanded",onChange:l,persistKey:a="ll-widget",disablePersistence:s=!1}={}){const c=`${a}:display-mode`,d=t.useRef(!1),[m,u]=Ge({value:n,defaultValue:r,onChange:x=>{n===void 0&&!s&&ot(c,x),l==null||l(x)}});return t.useEffect(()=>{if(d.current||(d.current=!0,s||n!==void 0))return;const x=dt(it(c));x&&x!==m&&u(x)},[]),[m,u]}const ut=640;function He(n=ut){const[r,l]=t.useState(!1);return t.useEffect(()=>{if(n===!1){l(!1);return}if(typeof window>"u"||typeof window.matchMedia>"u")return;const a=`(max-width: ${n-1}px)`,s=window.matchMedia(a),c=()=>l(s.matches);return c(),typeof s.addEventListener=="function"?(s.addEventListener("change",c),()=>s.removeEventListener("change",c)):(s.addListener(c),()=>{s.removeListener(c)})},[n]),r}const Ie=({muted:n=!1,className:r})=>n?e.jsxs("svg",{className:r,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:[e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"}),e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2"})]}):e.jsx("svg",{className:r,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4M12 1a3 3 0 00-3 3v4a3 3 0 006 0V4a3 3 0 00-3-3z"})}),Ae=({className:n})=>e.jsx("svg",{className:n,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"})}),ft=({className:n})=>e.jsx("svg",{className:n,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})}),ht={left:180,right:0,up:-90,down:90},pt=({direction:n="right",className:r})=>e.jsx("svg",{className:r,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,style:{transform:`rotate(${ht[n]}deg)`},"aria-hidden":"true",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 6l6 6-6 6"})});function mt(n){return n==="top-left"||n==="bottom-left"?"left":"right"}const Je="ll-hidden-tab-center-y",xt=5,De=16;function gt(){if(typeof window>"u")return null;try{const n=window.localStorage.getItem(Je);if(!n)return null;const r=Number.parseFloat(n);return Number.isFinite(r)?r:null}catch{return null}}function Te(n){if(!(typeof window>"u"))try{window.localStorage.setItem(Je,String(n))}catch{}}const vt=({position:n,isMobile:r,isSpeaking:l,onExpand:a,label:s="Open widget"})=>{const c=mt(n),d=c==="right"?"left":"right",m=r?80:72,[u,x]=t.useState(null),[p,i]=t.useState(!1),o=t.useRef(null),k=t.useRef(!1),b=t.useCallback(y=>{if(typeof window>"u")return y;const _=m/2,v=De+_,E=window.innerHeight-De-_;return E<v?Math.max(v,y):Math.max(v,Math.min(E,y))},[m]);t.useEffect(()=>{const y=gt();x(b(y??window.innerHeight/2));const _=()=>{x(v=>v===null?null:b(v))};return window.addEventListener("resize",_),()=>window.removeEventListener("resize",_)},[b]);const j=t.useCallback(y=>{if(!(y.pointerType==="mouse"&&y.button!==0)&&u!==null){try{y.currentTarget.setPointerCapture(y.pointerId)}catch{}o.current={startClientY:y.clientY,startCenterY:u,moved:!1}}},[u]),N=t.useCallback(y=>{const _=o.current;if(!_)return;const v=y.clientY-_.startClientY;!_.moved&&Math.abs(v)>xt&&(_.moved=!0,i(!0)),_.moved&&x(b(_.startCenterY+v))},[b]),C=t.useCallback(y=>{const _=o.current;if(_){try{y.currentTarget.releasePointerCapture(y.pointerId)}catch{}o.current=null,_.moved&&(i(!1),k.current=!0,x(v=>(v!==null&&Te(v),v)))}},[]),M=t.useCallback(()=>{if(k.current){k.current=!1;return}a()},[a]),L=t.useCallback(y=>{if(y.key==="ArrowUp"||y.key==="ArrowDown"){y.preventDefault();const _=y.key==="ArrowUp"?-8:8;x(v=>{if(v===null)return v;const E=b(v+_);return Te(E),E})}},[b]),R=["ll-hidden",`ll-hidden--${c}`,r?"ll-hidden--mobile":"ll-hidden--desktop",l?"ll-hidden--speaking":null,p?"is-dragging":null].filter(Boolean).join(" "),S=u===null?void 0:{top:`${u-m/2}px`,transform:"none"};return e.jsx("button",{type:"button",className:R,onPointerDown:j,onPointerMove:N,onPointerUp:C,onPointerCancel:C,onClick:M,onKeyDown:L,"aria-label":s,"data-position":n,style:S,children:e.jsx(pt,{direction:d,className:"ll-hidden__chevron"})})},bt=({audioLevel:n,bars:r=20,maxHeight:l=20,minHeight:a=4,className:s,barClassName:c})=>{const d=t.useRef(null),m=t.useRef([]),u=t.useMemo(()=>{const p=(Math.sqrt(5)-1)/2;return Array.from({length:r},(i,o)=>.5+o*p%1*.5)},[r]);t.useEffect(()=>n.subscribe(i=>{for(let o=0;o<r;o++){const k=m.current[o];if(!k)continue;const b=Math.max(a,i*l*u[o]);k.style.height=`${b}px`}}),[n,r,l,a,u]);const x=["ll-waveform",s].filter(Boolean).join(" ");return e.jsx("div",{ref:d,className:x,"aria-hidden":"true",children:Array.from({length:r},(p,i)=>e.jsx("div",{ref:o=>{m.current[i]=o},className:["ll-waveform__bar",c].filter(Boolean).join(" "),style:{height:`${a}px`}},i))})},yt=({position:n,isMobile:r,agentName:l,avatarImageUrl:a,agentState:s,isMuted:c,audioLevel:d,onExpand:m,onToggleMute:u,onClose:x})=>r?e.jsx("div",{className:"ll-minimized ll-minimized--mobile",role:"region","aria-label":`${l} widget`,children:e.jsxs("button",{type:"button",className:"ll-minimized__surface",onClick:m,"aria-label":`Expand ${l} widget`,children:[a?e.jsx("img",{src:a,alt:l,className:"ll-minimized__avatar"}):e.jsx("div",{className:"ll-minimized__avatar ll-minimized__avatar--placeholder"}),e.jsx(bt,{audioLevel:d,bars:16,maxHeight:18,className:"ll-minimized__waveform"}),e.jsx("span",{className:"ll-minimized__name",children:l}),e.jsxs("div",{className:"ll-minimized__controls",children:[e.jsx("span",{className:"ll-minimized__btn",role:"button",tabIndex:0,onClick:p=>{p.stopPropagation(),u()},onKeyDown:p=>{(p.key==="Enter"||p.key===" ")&&(p.stopPropagation(),p.preventDefault(),u())},"aria-label":c?"Unmute microphone":"Mute microphone",children:e.jsx(Ie,{muted:c,className:"ll-minimized__icon"})}),e.jsx(Ae,{className:"ll-minimized__icon ll-minimized__icon--expand"})]})]})}):e.jsx("div",{className:"ll-minimized ll-minimized--desktop","data-position":n,role:"region","aria-label":`${l} widget`,children:e.jsxs("div",{className:"ll-minimized__surface",children:[a?e.jsx("img",{src:a,alt:l,className:"ll-minimized__avatar"}):e.jsx("div",{className:"ll-minimized__avatar ll-minimized__avatar--placeholder"}),e.jsxs("div",{className:"ll-minimized__meta",children:[e.jsx("span",{className:"ll-minimized__name",children:l}),e.jsx("span",{className:"ll-minimized__state",children:s==="speaking"?"Speaking":s==="thinking"?"Thinking":"Listening"})]}),e.jsxs("div",{className:"ll-minimized__controls",children:[e.jsx("button",{type:"button",className:"ll-minimized__btn",onClick:u,"aria-label":c?"Unmute microphone":"Mute microphone",children:e.jsx(Ie,{muted:c,className:"ll-minimized__icon"})}),e.jsx("button",{type:"button",className:"ll-minimized__btn",onClick:m,"aria-label":`Expand ${l} widget`,children:e.jsx(Ae,{className:"ll-minimized__icon"})}),e.jsx("button",{type:"button",className:"ll-minimized__btn ll-minimized__btn--close",onClick:x,"aria-label":"Close widget",children:e.jsx(ft,{className:"ll-minimized__icon"})})]})]})}),_t=({src:n,alt:r,preCannedPlaying:l=!1,className:a,style:s})=>{const[c,d]=t.useState(!1),m=t.useRef(n);if(t.useEffect(()=>{m.current!==n&&(m.current=n,d(!1))},[n]),!n)return null;const u={position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transition:"opacity 500ms ease, transform 500ms ease",transform:l?"scale(1.02)":"scale(1)",opacity:c?1:0,...s};return e.jsx("img",{src:n,alt:r,className:a,style:u,loading:"eager",fetchpriority:"high",onLoad:()=>d(!0)})},kt=({position:n,isMobile:r,agentName:l,avatarImageUrl:a,idleLoopUrl:s,greeting:c,branding:d,teamMembers:m,currentTeamMemberId:u,isSwitchingTeamMember:x,teamSwitcherOpen:p,onToggleTeamSwitcher:i,onSelectTeamMember:o,languageMenuOpen:k,onToggleLanguageMenu:b,connectionState:j,agentState:N,transcript:C,canResume:M,needsUserGesture:L,error:R,isMuted:S,micError:y,micDevices:_,isCameraEnabled:v,cameraPreviewEl:E,cameraDevices:G,activeCameraId:Q,isScreenShareEnabled:T,screenPreviewEl:z,isSpeakerMuted:$,allowCamera:Z,allowScreenShare:I,allowTyping:ge,avatarVideoContainerRef:ve,onConnect:fe,onDisconnect:ie,onRetry:be,onResumeAudio:ye,onToggleMute:Y,onToggleCamera:D,onSwitchCameraDevice:he,onToggleScreenShare:H,onToggleSpeaker:O,onSendMessage:J,onMinimize:ee,onClose:P,onClearMicError:V})=>{var pe;const B=C.length>0?C[C.length-1]:null,W=((m==null?void 0:m.length)??0)>1,te=j==="connecting"||j==="connected",F=j==="connected",oe=j==="idle"||j==="disconnected"||j==="error",ce=t.useRef(null),ne=t.useRef(null);t.useEffect(()=>{const h=ce.current;h&&(h.innerHTML="",E&&(E.style.width="100%",E.style.height="100%",E.style.objectFit="cover",E.style.transform="scaleX(-1)",h.appendChild(E)))},[E]),t.useEffect(()=>{const h=ne.current;h&&(h.innerHTML="",z&&(z.style.width="100%",z.style.height="100%",z.style.objectFit="contain",h.appendChild(z)))},[z]);const[K,re]=t.useState(!1),[se,q]=t.useState(!1);t.useEffect(()=>{if(!K&&!se&&!k&&!p)return;const h=()=>{re(!1),q(!1),k&&b(),p&&i()};return document.addEventListener("click",h),()=>document.removeEventListener("click",h)},[K,se,k,p,b,i]);const[le,ae]=t.useState(""),A=t.useCallback(h=>{h.preventDefault();const U=le.trim();U&&(J(U),ae(""))},[le,J]),f=d.productName||"Live Layer",de=F&&(B!=null&&B.text)?B.text:c||"",_e=["ll-expanded",r?"ll-expanded--mobile":"ll-expanded--desktop"].join(" ");return e.jsxs("div",{className:_e,"data-position":n,"data-state":F?"connected":te?"connecting":"idle",role:"dialog","aria-label":`${l} widget`,children:[e.jsxs("div",{className:"ll-expanded__bg",children:[a?e.jsx(_t,{src:a,alt:l,className:"ll-expanded__bg-img"}):e.jsx("div",{className:"ll-expanded__bg-fallback",children:e.jsx("span",{className:"ll-expanded__bg-initial",children:((pe=l==null?void 0:l.charAt(0))==null?void 0:pe.toUpperCase())||"A"})}),s&&!F&&e.jsx("video",{className:"ll-expanded__bg-idle",src:s,autoPlay:!0,loop:!0,muted:!0,playsInline:!0})]}),e.jsx("div",{ref:ve,className:"ll-expanded__video"}),j==="connecting"&&e.jsxs("div",{className:"ll-expanded__overlay ll-expanded__overlay--connecting",children:[e.jsx("div",{className:"ll-expanded__spinner"}),e.jsx("p",{className:"ll-expanded__overlay-text",children:x?"Switching...":"Connecting..."})]}),L&&F&&e.jsxs("button",{type:"button",className:"ll-expanded__overlay ll-expanded__overlay--gesture",onClick:ye,children:[e.jsx("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:e.jsx("path",{d:"M3 9v6h4l5 5V4L7 9H3zm13.54.12a5 5 0 0 1 0 5.76l-1.41-1.41a3 3 0 0 0 0-2.94L16.54 9.12z"})}),e.jsx("p",{className:"ll-expanded__overlay-text",children:"Tap to enable audio"})]}),te?e.jsxs("div",{className:"ll-expanded__topbar",children:[e.jsxs("div",{className:"ll-expanded__topbar-left",children:[e.jsxs("div",{className:"ll-expanded__pill-wrap",children:[e.jsxs("button",{type:"button",className:"ll-hpill",onClick:h=>{W&&(h.stopPropagation(),i())},"aria-haspopup":W?"listbox":void 0,"aria-expanded":W?p:void 0,children:[e.jsx("span",{className:"ll-hpill__label",children:l}),W&&e.jsx(me,{})]}),W&&p&&e.jsx("div",{className:"ll-hmenu",onClick:h=>h.stopPropagation(),role:"listbox",children:m==null?void 0:m.map(h=>e.jsxs("button",{type:"button",className:`ll-hmenu__item ${h.id===u?"is-active":""}`,onClick:()=>o(h.id),role:"option","aria-selected":h.id===u,children:[h.avatarImageUrl&&e.jsx("img",{src:h.avatarImageUrl,alt:"",className:"ll-hmenu__avatar"}),e.jsx("span",{className:"ll-hmenu__name",children:h.name}),h.role&&e.jsx("span",{className:"ll-hmenu__role",children:h.role})]},h.id))})]}),e.jsxs("div",{className:"ll-expanded__pill-wrap",children:[e.jsxs("button",{type:"button",className:"ll-hpill ll-hpill--compact",onClick:h=>{h.stopPropagation(),b()},"aria-haspopup":"listbox","aria-expanded":k,"aria-label":"Language: English",title:"Language: English",children:[e.jsx("span",{className:"ll-hpill__label",children:"EN"}),e.jsx(me,{})]}),k&&e.jsx("div",{className:"ll-hmenu",onClick:h=>h.stopPropagation(),role:"listbox",children:e.jsx("button",{type:"button",className:"ll-hmenu__item is-active",role:"option","aria-selected":!0,children:e.jsx("span",{className:"ll-hmenu__name",children:"English"})})})]}),e.jsx("span",{className:`ll-expanded__state ll-expanded__state--${N}`,children:N})]}),e.jsxs("div",{className:"ll-expanded__header-actions",children:[e.jsx("button",{type:"button",className:"ll-hbtn",onClick:ee,"aria-label":"Minimize widget",title:"Minimize",children:e.jsx(Pe,{})}),e.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--danger",onClick:P,"aria-label":"End conversation",title:"End conversation",children:e.jsx(ze,{})})]})]}):e.jsxs("div",{className:"ll-expanded__header ll-expanded__header--idle",children:[e.jsx("span",{className:"ll-expanded__brand",children:f}),e.jsxs("div",{className:"ll-expanded__header-actions",children:[e.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--ghost",onClick:ee,"aria-label":"Minimize widget",children:e.jsx(Pe,{})}),e.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--danger",onClick:P,"aria-label":"Close widget",children:e.jsx(ze,{})})]})]}),oe&&e.jsxs("button",{type:"button",className:"ll-expanded__play",onClick:fe,"aria-label":M?"Resume session":"Start video call",children:[e.jsx("div",{className:"ll-expanded__play-circle",children:e.jsx("svg",{width:"22",height:"22",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:e.jsx("polygon",{points:"6 3 20 12 6 21 6 3"})})}),e.jsx("span",{className:"ll-expanded__play-label",children:M?"Restart session":"Start video call"}),M&&e.jsx("span",{className:"ll-expanded__play-sublabel",children:"Pick up where you left off"})]}),e.jsxs("div",{className:`ll-expanded__pip ${te&&(v||T)?"is-visible":""}`,children:[e.jsx("div",{ref:ne,className:T?"ll-expanded__pip-host":"ll-expanded__pip-host is-hidden"}),e.jsx("div",{ref:ce,className:!T&&v?"ll-expanded__pip-host":"ll-expanded__pip-host is-hidden"})]}),te?e.jsxs("div",{className:"ll-expanded__bottom",children:[de&&e.jsx("div",{className:"ll-expanded__transcript",children:e.jsx("p",{className:"ll-expanded__transcript-text",children:de})}),e.jsxs("div",{className:"ll-toolbar",onClick:h=>h.stopPropagation(),children:[I&&e.jsx("button",{type:"button",className:`ll-tool ${T?"is-on":""}`,onClick:H,"aria-label":T?"Stop sharing screen":"Share screen",title:T?"Stop sharing":"Share screen",children:e.jsx(jt,{})}),Z&&e.jsxs("div",{className:"ll-tool-split",children:[e.jsx("button",{type:"button",className:`ll-tool ll-tool--left ${v?"is-on":""}`,onClick:D,"aria-label":v?"Turn off camera":"Turn on camera",title:v?"Stop camera":"Start camera",children:e.jsx(Ct,{})}),e.jsx("button",{type:"button",className:`ll-tool ll-tool--right ${v?"is-on":""}`,onClick:h=>{h.stopPropagation(),q(U=>!U),re(!1)},"aria-label":"Camera devices","aria-haspopup":"listbox","aria-expanded":se,children:e.jsx(me,{})}),se&&G.length>0&&e.jsx(Be,{label:"Camera",devices:G,activeId:Q,onPick:h=>{q(!1),he(h)}})]}),e.jsxs("div",{className:"ll-tool-split",children:[e.jsx("button",{type:"button",className:`ll-tool ll-tool--left ${S?"is-muted":""}`,onClick:Y,"aria-label":S?"Unmute microphone":"Mute microphone",title:S?"Unmute":"Mute",children:e.jsx(wt,{muted:S})}),e.jsx("button",{type:"button",className:`ll-tool ll-tool--right ${S?"is-muted":""}`,onClick:h=>{h.stopPropagation(),re(U=>!U),q(!1)},"aria-label":"Microphone devices","aria-haspopup":"listbox","aria-expanded":K,children:e.jsx(me,{})}),K&&_.length>0&&e.jsx(Be,{label:"Microphone",devices:_,activeId:"",onPick:()=>re(!1)})]}),e.jsx("button",{type:"button",className:`ll-tool ${$?"is-muted":""}`,onClick:O,"aria-label":$?"Unmute speaker":"Mute speaker",title:$?"Unmute speaker":"Mute speaker",children:e.jsx(St,{muted:$})})]}),ge&&e.jsxs("form",{className:"ll-message-input",onSubmit:A,children:[e.jsx("input",{type:"text",className:"ll-message-input__field",placeholder:"Message...",value:le,onChange:h=>ae(h.target.value),"aria-label":"Message the agent"}),le.trim()&&e.jsx("button",{type:"submit",className:"ll-message-input__send","aria-label":"Send message",children:e.jsx(Et,{})})]}),e.jsx("button",{type:"button",className:"ll-expanded__end",onClick:ie,children:"End conversation"})]}):c&&e.jsx("div",{className:"ll-expanded__bottom ll-expanded__bottom--idle",children:e.jsx("div",{className:"ll-expanded__transcript",children:e.jsx("p",{className:"ll-expanded__transcript-text",children:c})})}),(()=>{if(y&&j!=="error")return e.jsxs("div",{className:"ll-expanded__banner",role:"alert",children:[e.jsx("span",{children:y}),e.jsx("button",{type:"button",className:"ll-expanded__banner-x",onClick:V,"aria-label":"Dismiss",children:"×"})]});if(!R||j!=="error")return null;let h="Failed to connect",U="Try again";return R==="MIC_PERMISSION_DENIED"?h="Microphone blocked. Allow access to talk.":R==="MIC_NOT_FOUND"?h="No microphone found. Plug one in + retry.":R==="MIC_UNAVAILABLE"?h="Mic unavailable. Check other apps using it.":R==="AGENT_TIMEOUT"?h="Agent didn't pick up. Try again.":R==="CONNECT_FAILED"?h="Connection failed. Check your network.":R.length<80&&(h=R),e.jsxs("div",{className:"ll-expanded__banner ll-expanded__banner--error",role:"alert",children:[e.jsx("span",{children:h}),e.jsx("button",{type:"button",className:"ll-expanded__banner-retry",onClick:be,children:U})]})})()]})};function me(){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round","aria-hidden":!0,children:e.jsx("polyline",{points:"6 9 12 15 18 9"})})}function ze(){return e.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round","aria-hidden":!0,children:[e.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),e.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function Pe(){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round","aria-hidden":!0,children:e.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})})}function jt(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[e.jsx("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),e.jsx("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),e.jsx("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]})}function Ct(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[e.jsx("path",{d:"M23 7l-7 5 7 5V7z"}),e.jsx("rect",{x:"1",y:"5",width:"15",height:"14",rx:"2"})]})}function wt({muted:n}){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[e.jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),e.jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),e.jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),n&&e.jsx("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]})}function St({muted:n}){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[e.jsx("polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5"}),n?e.jsx("line",{x1:"23",y1:"9",x2:"17",y2:"15"}):e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14"}),e.jsx("path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07"})]})]})}function Et(){return e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[e.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),e.jsx("polyline",{points:"12 5 19 12 12 19"})]})}const Be=({label:n,devices:r,activeId:l,onPick:a})=>e.jsxs("div",{className:"ll-device-menu",onClick:s=>s.stopPropagation(),role:"listbox",children:[e.jsx("p",{className:"ll-device-menu__label",children:n}),r.map((s,c)=>{const d=l===s.deviceId;return e.jsxs("button",{type:"button",className:`ll-device-menu__item ${d?"is-active":""}`,onClick:()=>a(s.deviceId),role:"option","aria-selected":d,children:[d&&e.jsx("span",{className:"ll-device-menu__dot",children:"●"}),e.jsx("span",{className:"ll-device-menu__name",children:s.label||`${n} ${c+1}`})]},s.deviceId||c)})]}),Nt=new Set(["agent_state","avatar_stream_ready","avatar_active","avatar_idle","bot_ready","agent_error","idle_warning","idle_timeout"]);function Mt(n){var Se,Ee,Ne,Me,Le,Re;const{agentId:r,apiKey:l,baseUrl:a="https://app.livelayer.studio",sessionEndpoint:s,sessionBody:c,autoConnect:d=!1,displayMode:m,defaultDisplayMode:u="expanded",onDisplayModeChange:x,position:p="bottom-right",mobileBreakpoint:i=640,persistKey:o="ll-widget",disablePersistence:k=!1,teamMembers:b,currentTeamMemberId:j,onTeamMemberChange:N,idleLoopUrl:C,greeting:M,avatarImageUrl:L,agentName:R,branding:S={},allowCamera:y=!0,allowScreenShare:_=!0,allowTyping:v=!0,onConnect:E,onDisconnect:G,onTranscript:Q,onAgentState:T,onConnectionStateChange:z,onAgentEvent:$,onAgentCommand:Z,controlledSession:I,className:ge,style:ve,zIndex:fe=2147483647}=n,ie=j!==void 0,[be,ye]=t.useState(()=>{var g;return j??((g=b==null?void 0:b[0])==null?void 0:g.id)}),Y=ie?j:be,D=t.useMemo(()=>(b==null?void 0:b.find(g=>g.id===Y))??null,[b,Y]),he=(D==null?void 0:D.agentId)??r,[H,O]=Ye({value:m,defaultValue:u,onChange:x,persistKey:o,disablePersistence:k}),J=He(i),ee=Oe(),P=Ve(),V=We(),B=Fe(),W=Ke(),[te,F]=t.useState(!1),[oe,ce]=t.useState(!1),[ne,K]=t.useState(!1),[re,se]=t.useState(!1),[q,le]=t.useState(!1),ae=t.useCallback(g=>{const w=g;!w.type||typeof w.type!="string"||($==null||$({eventName:w.type,data:g}),Nt.has(w.type)||Z==null||Z(w))},[Z,$]),A=$e({agentId:I?"__controlled__":he,baseUrl:a,apiKey:l,sessionEndpoint:s,sessionBody:c,onDataMessage:I?void 0:ae});t.useEffect(()=>{if(I!=null&&I.subscribeToDataMessages)return I.subscribeToDataMessages(ae)},[I,ae]);const f=t.useMemo(()=>I?{connectionState:I.connectionState,agentState:I.agentState,transcript:I.transcript,videoElement:I.videoElement,audioElement:I.audioElement,canResume:I.canResume,error:I.error,agentConfig:null,connect:async()=>{await I.onConnect()},disconnect:()=>I.onDisconnect(),getRoom:A.getRoom,isControlled:!0}:{connectionState:A.connectionState,agentState:A.agentState,transcript:A.transcript,videoElement:A.videoElement,audioElement:A.audioElement,canResume:A.canResume,error:A.error,agentConfig:A.agentConfig,connect:A.connect,disconnect:A.disconnect,getRoom:A.getRoom,isControlled:!1},[I,A]),de=t.useRef(null);t.useEffect(()=>{const g=f.videoElement,w=de.current;if(!(!g||!w))return w.appendChild(g),()=>{g.parentNode===w&&w.removeChild(g)}},[f.videoElement]),t.useEffect(()=>{const g=f.audioElement;if(!g)return;ee.attach(g);const w=g.play();return w&&typeof w.catch=="function"&&w.catch(X=>{(X==null?void 0:X.name)==="NotAllowedError"&&F(!0)}),()=>{ee.detach()}},[f.audioElement]),t.useEffect(()=>{if(f.isControlled||f.connectionState!=="connected")return;const g=f.getRoom();if(g)return P.setupMic(g).catch(()=>{}),V.attachRoom(g),B.attachRoom(g),W.refresh(),()=>{P.teardownMic(),V.teardown(),B.teardown()}},[f.isControlled,f.connectionState]),t.useEffect(()=>{const g=f.audioElement;g&&(g.muted=q)},[f.audioElement,q]);const _e=t.useCallback(g=>{const w=f.getRoom();if(w)try{const X=new TextEncoder().encode(JSON.stringify({type:"user_message",text:g}));w.localParticipant.publishData(X,{reliable:!0})}catch{}},[f]),pe=t.useCallback(()=>{le(g=>!g)},[]);t.useEffect(()=>{z==null||z(f.connectionState),f.connectionState==="connected"?E==null||E():f.connectionState==="disconnected"&&(G==null||G())},[f.connectionState,E,G,z]),t.useEffect(()=>{Q==null||Q(f.transcript)},[f.transcript,Q]),t.useEffect(()=>{T==null||T(f.agentState)},[f.agentState,T]);const h=t.useRef(!1);t.useEffect(()=>{f.isControlled||!d||h.current||f.connectionState==="idle"&&(h.current=!0,f.connect())},[d,f.connectionState,f]);const U=t.useCallback(g=>{const w=b==null?void 0:b.find(X=>X.id===g);w&&(K(!1),g!==Y&&(ce(!0),f.disconnect(),ie||ye(g),N==null||N(w)))},[b,Y,f,ie,N]);t.useEffect(()=>{oe&&f.connectionState==="connected"&&ce(!1)},[f.connectionState,oe]),t.useEffect(()=>{if(!ne)return;const g=w=>{w.key==="Escape"&&K(!1)};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[ne]);const Xe=!!L||!!(D!=null&&D.avatarImageUrl)||f.isControlled,ke=qe(he,a,Xe),je=(D==null?void 0:D.name)??R??((Se=f.agentConfig)==null?void 0:Se.name)??((Ee=ke.info)==null?void 0:Ee.name)??"Live Layer",Ce=(D==null?void 0:D.avatarImageUrl)??L??((Ne=f.agentConfig)==null?void 0:Ne.avatarImageUrl)??((Me=ke.info)==null?void 0:Me.avatarImageUrl)??null,Qe=C??((Le=f.agentConfig)==null?void 0:Le.idleLoopUrl)??((Re=ke.info)==null?void 0:Re.idleLoopUrl)??null,Ze=M??null,et=t.useCallback(()=>O("expanded"),[O]),tt=t.useCallback(()=>O("minimized"),[O]),we=t.useCallback(()=>{f.disconnect(),O("hidden")},[f,O]),nt=t.useCallback(()=>{const g=f.audioElement;g&&g.play().then(()=>F(!1)).catch(()=>{})},[f.audioElement]),rt=t.useCallback(()=>{F(!1),f.connect()},[f]),ue={...ve,zIndex:fe};S.primaryColor&&(ue["--ll-color-primary"]=S.primaryColor),S.accentColor&&(ue["--ll-color-accent"]=S.accentColor),S.backgroundColor&&(ue["--ll-color-bg"]=S.backgroundColor),S.textColor&&(ue["--ll-color-fg"]=S.textColor);const st=["ll-widget",`ll-widget--${H}`,`ll-widget--${J?"mobile":"desktop"}`,ge].filter(Boolean).join(" ");return e.jsxs("div",{className:st,style:ue,"data-display-mode":H,"data-position":p,children:[H==="hidden"&&e.jsx(vt,{position:p,isMobile:J,isSpeaking:f.agentState==="speaking",onExpand:()=>O("expanded"),label:`Open ${je} widget`}),H==="minimized"&&e.jsx(yt,{position:p,isMobile:J,agentName:je,avatarImageUrl:Ce,agentState:f.agentState,isMuted:P.isMuted,audioLevel:ee,onExpand:et,onToggleMute:P.toggleMute,onClose:we}),H==="expanded"&&e.jsx(kt,{position:p,isMobile:J,agentName:je,avatarImageUrl:Ce,idleLoopUrl:Qe,greeting:Ze,branding:S,teamMembers:b,currentTeamMemberId:Y,isSwitchingTeamMember:oe,teamSwitcherOpen:ne,onToggleTeamSwitcher:()=>K(g=>!g),onSelectTeamMember:U,connectionState:f.connectionState,agentState:f.agentState,transcript:f.transcript,isMuted:P.isMuted,micDevices:W.mics,isCameraEnabled:V.isEnabled,cameraPreviewEl:V.previewEl,cameraDevices:W.cameras,activeCameraId:V.activeDeviceId,isScreenShareEnabled:B.isEnabled,screenPreviewEl:B.previewEl,isSpeakerMuted:q,allowCamera:y,allowScreenShare:_,allowTyping:v,languageMenuOpen:re,onToggleLanguageMenu:()=>se(g=>!g),needsUserGesture:te,canResume:f.canResume,micError:P.micError,error:f.error,avatarVideoContainerRef:de,onConnect:()=>void f.connect(),onDisconnect:()=>f.disconnect(),onRetry:rt,onResumeAudio:nt,onToggleMute:P.toggleMute,onToggleCamera:()=>void V.toggle(),onSwitchCameraDevice:g=>void V.switchDevice(g),onToggleScreenShare:()=>void B.toggle(),onToggleSpeaker:pe,onSendMessage:_e,onMinimize:tt,onClose:we,onClearMicError:P.clearError})]})}function Lt(n){return e.jsx(Ue,{children:e.jsx(Mt,{...n})})}const Rt=({agentId:n,baseUrl:r,apiKey:l,mode:a,onAgentEvent:s,className:c,style:d})=>{const m=t.useRef(null),u=t.useRef(null),x=t.useRef(s);x.current=s;const p=t.useCallback(i=>{var k;const o=i.detail;(k=x.current)==null||k.call(x,o)},[]);return t.useEffect(()=>{const i=m.current;if(!i)return;const o=document.createElement("livelayer-widget");return o.setAttribute("agent-id",n),r&&o.setAttribute("base-url",r),l&&o.setAttribute("api-key",l),a&&o.setAttribute("mode",a),o.addEventListener("agent-event",p),i.appendChild(o),u.current=o,()=>{o.removeEventListener("agent-event",p),i.removeChild(o),u.current=null}},[n]),t.useEffect(()=>{u.current&&(a?u.current.setAttribute("mode",a):u.current.removeAttribute("mode"))},[a]),e.jsx("div",{ref:m,className:c,style:d})};function It(){const[n,r]=t.useState([]),l=t.useCallback(s=>{r(c=>{const d=c.findIndex(m=>m.id===s.id);if(d>=0){const m=c.slice();return m[d]=s,m}return[...c,s]})},[]),a=t.useCallback(()=>r([]),[]);return{entries:n,pushSegment:l,clear:a,latest:n.length>0?n[n.length-1]:null}}exports.AvatarWidget=Lt;exports.ErrorBoundary=Ue;exports.LiveLayerWidget=Rt;exports.useAgentInfo=qe;exports.useAudioLevel=Oe;exports.useCameraState=We;exports.useDisplayMode=Ge;exports.useDisplayModePersistence=Ye;exports.useIsMobile=He;exports.useLiveKitSession=$e;exports.useMediaDevices=Ke;exports.useMicrophoneState=Ve;exports.useScreenShareState=Fe;exports.useTranscript=It;
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),r=require("react"),pn=require("@livelayer/sdk"),Oe=require("livekit-client");class At extends r.Component{constructor(){super(...arguments),this.state={hasError:!1,error:null},this.reset=()=>{this.setState({hasError:!1,error:null})}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,i){var o,s;(s=(o=this.props).onError)==null||s.call(o,n,i)}render(){var n;return this.state.hasError?this.props.fallback?this.props.fallback:t.jsxs("div",{className:"ll-error-boundary",role:"alert",children:[t.jsx("p",{className:"ll-error-boundary__title",children:"Widget crashed"}),t.jsx("p",{className:"ll-error-boundary__message",children:((n=this.state.error)==null?void 0:n.message)||"Something went wrong."}),t.jsx("button",{type:"button",className:"ll-error-boundary__retry",onClick:this.reset,children:"Reload widget"})]}):this.props.children}}function Mt(e){const[n,i]=r.useState("idle"),[o,s]=r.useState("idle"),[l,u]=r.useState([]),[d,f]=r.useState(null),[y,h]=r.useState(null),[a,c]=r.useState(null),[j,C]=r.useState(!1),[E,T]=r.useState(null),N=r.useRef(null),M=r.useRef(e.onDataMessage);M.current=e.onDataMessage,r.useEffect(()=>{const x={onConnectionStateChange:w=>{i(w),w==="connected"&&T(null)},onAgentStateChange:s,onTranscript:w=>u([...w]),onAgentConfig:f,onAudioTrack:w=>c(w),onVideoTrack:w=>h(w),onVideoTrackRemoved:()=>h(null),onError:w=>T(w),onDataMessage:w=>{var I;(I=M.current)==null||I.call(M,w)},onResumabilityChange:C},S=new pn.LiveKitSession({agentId:e.agentId,baseUrl:e.baseUrl,apiKey:e.apiKey,sessionEndpoint:e.sessionEndpoint,sessionBody:e.sessionBody},x);return N.current=S,i("idle"),s("idle"),u([]),f(null),h(null),c(null),C(!1),T(null),()=>{var w;(w=S.destroy)==null||w.call(S),N.current=null}},[e.agentId,e.baseUrl,e.apiKey,e.sessionEndpoint,JSON.stringify(e.sessionBody??{})]);const L=r.useCallback(async()=>{const x=N.current;if(x)try{await x.connect()}catch(S){throw T(S instanceof Error?S.message:String(S)),S}},[]),A=r.useCallback(()=>{const x=N.current;x&&x.disconnect()},[]),g=r.useCallback(()=>{var x;return((x=N.current)==null?void 0:x.getRoom())??null},[]);return{connectionState:n,agentState:o,transcript:l,agentConfig:d,videoElement:y,audioElement:a,canResume:j,error:E,connect:L,disconnect:A,getRoom:g,session:N.current}}function Tt(){const e=r.useRef(null),n=r.useRef(null),i=r.useRef(null),o=r.useRef(null),s=r.useRef(new Set),l=r.useRef(null),u=r.useCallback(()=>{const a=n.current;if(!a){o.current=null;return}(!l.current||l.current.length!==a.frequencyBinCount)&&(l.current=new Uint8Array(new ArrayBuffer(a.frequencyBinCount)));const c=l.current;a.getByteFrequencyData(c);let j=0;for(let E=0;E<c.length;E++)j+=c[E];const C=j/c.length/255;for(const E of s.current)try{E(C)}catch(T){console.error("[useAudioLevel] subscriber threw:",T)}o.current=requestAnimationFrame(u)},[]),d=r.useCallback(()=>{if(e.current||typeof window>"u"||typeof AudioContext>"u")return;const a=new AudioContext,c=a.createAnalyser();c.fftSize=64,c.connect(a.destination),e.current=a,n.current=c},[]),f=r.useCallback(a=>{if(d(),!(!e.current||!n.current)){if(i.current){try{i.current.disconnect()}catch{}i.current=null}try{const c=e.current.createMediaElementSource(a);c.connect(n.current),i.current=c}catch(c){console.warn("[useAudioLevel] createMediaElementSource failed:",c);return}o.current===null&&(o.current=requestAnimationFrame(u))}},[d,u]),y=r.useCallback(()=>{if(o.current!==null&&(cancelAnimationFrame(o.current),o.current=null),i.current){try{i.current.disconnect()}catch{}i.current=null}},[]),h=r.useCallback(a=>(s.current.add(a),()=>{s.current.delete(a)}),[]);return r.useEffect(()=>()=>{if(y(),n.current){try{n.current.disconnect()}catch{}n.current=null}if(e.current){try{e.current.close()}catch{}e.current=null}s.current.clear(),l.current=null},[y]),{attach:f,detach:y,subscribe:h}}function It(){const[e,n]=r.useState(!1),[i,o]=r.useState(null),s=r.useRef(null),l=r.useRef(null),u=r.useCallback(async h=>{if(s.current&&l.current){try{await l.current.localParticipant.unpublishTrack(s.current)}catch{}s.current.stop(),s.current=null}l.current=h,o(null);try{const a=await Oe.createLocalAudioTrack({echoCancellation:!0,noiseSuppression:!0});await h.localParticipant.publishTrack(a),s.current=a,n(a.isMuted)}catch(a){const c=a instanceof Error&&a.name==="NotAllowedError"?"Enable your microphone to talk with the agent.":"Microphone unavailable. Check browser permissions and try again.";throw o(c),a}},[]),d=r.useCallback(()=>{const h=s.current;h&&(h.isMuted?(h.unmute(),n(!1)):(h.mute(),n(!0)))},[]),f=r.useCallback(()=>{const h=s.current,a=l.current;if(h&&a){try{a.localParticipant.unpublishTrack(h)}catch{}h.stop()}s.current=null,l.current=null,n(!1)},[]),y=r.useCallback(()=>o(null),[]);return{isMuted:e,micError:i,toggleMute:d,setupMic:u,teardownMic:f,clearError:y}}const hn={resolution:{width:640,height:480,frameRate:24}};function Pt(){const[e,n]=r.useState(!1),[i,o]=r.useState(null),[s,l]=r.useState(null),[u,d]=r.useState(""),f=r.useRef(null),y=r.useRef(null),h=r.useCallback(N=>{f.current=N},[]),a=r.useCallback(()=>{const N=f.current,M=y.current;if(M&&N){const L=N.localParticipant.getTrackPublication(Oe.Track.Source.Camera);if(L!=null&&L.track){try{N.localParticipant.unpublishTrack(L.track)}catch{}L.track.stop()}else M.stop()}y.current=null,l(null),n(!1)},[]),c=r.useCallback(async N=>{const M=f.current;if(M){o(null);try{const L={...hn};N&&(L.deviceId=N);const A=await Oe.createLocalVideoTrack(L);await M.localParticipant.publishTrack(A),y.current=A;const g=A.attach();l(g),n(!0),N&&d(N);try{M.localParticipant.publishData(new TextEncoder().encode(JSON.stringify({type:"user_camera_on"})),{reliable:!0})}catch{}}catch(L){const A=L instanceof Error&&L.name==="NotAllowedError"?"Enable your camera in the browser to share video.":"Camera unavailable. Check permissions and try again.";o(A)}}},[]),j=r.useCallback(async()=>{e?a():await c(u||void 0)},[e,u,a,c]),C=r.useCallback(async N=>{a(),await c(N)},[a,c]),E=r.useCallback(()=>{a(),f.current=null,o(null),d("")},[a]),T=r.useCallback(()=>o(null),[]);return r.useEffect(()=>()=>{y.current&&y.current.stop()},[]),{isEnabled:e,error:i,previewEl:s,activeDeviceId:u,toggle:j,switchDevice:C,attachRoom:h,teardown:E,clearError:T}}function Dt(){const[e,n]=r.useState(!1),[i,o]=r.useState(null),[s,l]=r.useState(null),u=r.useRef(null),d=r.useCallback(c=>{u.current=c},[]),f=r.useCallback(()=>l(null),[]),y=r.useCallback(async()=>{const c=u.current;if(c){if(e){try{await c.localParticipant.setScreenShareEnabled(!1)}catch{}f(),n(!1);return}o(null);try{await c.localParticipant.setScreenShareEnabled(!0);let j=0;const C=()=>{const E=c.localParticipant.getTrackPublication(Oe.Track.Source.ScreenShare);if(E!=null&&E.track){const T=E.track.attach();l(T),n(!0);try{c.localParticipant.publishData(new TextEncoder().encode(JSON.stringify({type:"user_screen_share_on"})),{reliable:!0})}catch{}return}j++<10?setTimeout(C,100):n(!0)};C()}catch(j){const C=j instanceof Error?j.name:"";C!=="NotAllowedError"&&C!=="AbortError"&&o("Screen share unavailable. Try again."),n(!1)}}},[e,f]),h=r.useCallback(()=>{const c=u.current;if(c&&e)try{c.localParticipant.setScreenShareEnabled(!1)}catch{}f(),n(!1),o(null),u.current=null},[e,f]),a=r.useCallback(()=>o(null),[]);return{isEnabled:e,error:i,previewEl:s,toggle:y,attachRoom:d,teardown:h,clearError:a}}function $t(){const[e,n]=r.useState([]),[i,o]=r.useState([]),s=r.useCallback(async()=>{if(!(typeof navigator>"u"||!navigator.mediaDevices))try{const l=await navigator.mediaDevices.enumerateDevices();n(l.filter(u=>u.kind==="audioinput")),o(l.filter(u=>u.kind==="videoinput"))}catch{}},[]);return r.useEffect(()=>{if(s(),typeof navigator>"u"||!navigator.mediaDevices)return;const l=()=>void s();return navigator.mediaDevices.addEventListener("devicechange",l),()=>navigator.mediaDevices.removeEventListener("devicechange",l)},[s]),{mics:e,cameras:i,refresh:s}}function zt(e,n,i=!1){const[o,s]=r.useState(null),[l,u]=r.useState(null),[d,f]=r.useState(!i&&!!e);return r.useEffect(()=>{if(i||!e){f(!1);return}const y=new AbortController,h=n||"https://app.livelayer.studio";return f(!0),u(null),fetch(`${h}/api/widget/agent/${encodeURIComponent(e)}`,{signal:y.signal}).then(async a=>{if(!a.ok){const c=await a.json().catch(()=>({}));throw new Error(c.error||`HTTP ${a.status}`)}return a.json()}).then(a=>{y.signal.aborted||(s(a),f(!1))}).catch(a=>{y.signal.aborted||(u(a instanceof Error?a.message:"Agent lookup failed"),f(!1))}),()=>y.abort()},[e,n,i]),{info:o,error:l,loading:d}}function mn(e){if(typeof window>"u")return null;try{return window.localStorage.getItem(e)}catch{return null}}function gn(e,n){if(!(typeof window>"u"))try{window.localStorage.setItem(e,n)}catch{}}function Ht({value:e,defaultValue:n="expanded",onChange:i}={}){const o=e!==void 0,[s,l]=r.useState(n),u=o?e:s,d=r.useCallback(f=>{f!==u&&(o||l(f),i==null||i(f))},[u,o,i]);return[u,d]}const yn=["hidden","minimized","expanded"];function xn(e){return e&&yn.includes(e)?e:null}function Ot({value:e,defaultValue:n="expanded",onChange:i,persistKey:o="ll-widget",disablePersistence:s=!1}={}){const l=`${o}:display-mode`,u=r.useRef(!1),[d,f]=Ht({value:e,defaultValue:n,onChange:y=>{e===void 0&&!s&&gn(l,y),i==null||i(y)}});return r.useEffect(()=>{if(u.current||(u.current=!0,s||e!==void 0))return;const y=xn(mn(l));y&&y!==d&&f(y)},[]),[d,f]}const vn=640;function Ft(e=vn){const[n,i]=r.useState(!1);return r.useEffect(()=>{if(e===!1){i(!1);return}if(typeof window>"u"||typeof window.matchMedia>"u")return;const o=`(max-width: ${e-1}px)`,s=window.matchMedia(o),l=()=>i(s.matches);return l(),typeof s.addEventListener=="function"?(s.addEventListener("change",l),()=>s.removeEventListener("change",l)):(s.addListener(l),()=>{s.removeListener(l)})},[e]),n}const xt="__llHistoryPatched",Fe="ll:pathname";function bn(){if(typeof window>"u"||window.history[xt])return;const e=window.history.pushState,n=window.history.replaceState;window.history.pushState=function(...i){const o=e.apply(this,i);return window.dispatchEvent(new Event(Fe)),o},window.history.replaceState=function(...i){const o=n.apply(this,i);return window.dispatchEvent(new Event(Fe)),o},window.history[xt]=!0}function vt(){return typeof window>"u"?"/":window.location.pathname||"/"}function qt(e){const[n,i]=r.useState(()=>e??vt());return r.useEffect(()=>{if(e!==void 0)return;bn();const o=()=>i(vt());return o(),window.addEventListener("popstate",o),window.addEventListener(Fe,o),()=>{window.removeEventListener("popstate",o),window.removeEventListener(Fe,o)}},[e]),e??n}const bt=new Map,wn=/[\\^$+?.()|{}[\]]/g;function _n(e){return e.replace(wn,"\\$&")}function kn(e){const n=bt.get(e);if(n)return n;const i=e.length>1&&e.endsWith("/")?e.slice(0,-1):e,o="",s="",l=i.replace(/\*\*/g,o).replace(/\*/g,s),d=_n(l).replace(new RegExp(`\\/${o}`,"g"),"(?:\\/.*)?").replace(new RegExp(o,"g"),".*").replace(new RegExp(s,"g"),"[^/]+"),f=new RegExp(`^${d}\\/?$`);return bt.set(e,f),f}function Cn(e,n){const i=n.length>1&&n.endsWith("/")?n.slice(0,-1):n;return kn(e).test(i)}function Bt(e,n){return typeof e=="function"?e(n):e instanceof RegExp?e.test(n):Cn(e,n)}function wt(e,n){if(!e||e.length===0)return!1;for(const i of e)if(Bt(i,n))return!0;return!1}function Ut(e,n,i){return e===void 0?!0:wt(i,e)?!1:n&&n.length>0?wt(n,e):!0}function Wt(e,n,i){return r.useMemo(()=>Ut(e,n,i),[e,n,i])}const _t=({muted:e=!1,className:n})=>e?t.jsxs("svg",{className:n,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:[t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"}),t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2"})]}):t.jsx("svg",{className:n,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4M12 1a3 3 0 00-3 3v4a3 3 0 006 0V4a3 3 0 00-3-3z"})}),kt=({className:e})=>t.jsx("svg",{className:e,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"})}),Sn=({className:e})=>t.jsx("svg",{className:e,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,"aria-hidden":"true",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})}),jn={left:180,right:0,up:-90,down:90},En=({direction:e="right",className:n})=>t.jsx("svg",{className:n,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,style:{transform:`rotate(${jn[e]}deg)`},"aria-hidden":"true",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 6l6 6-6 6"})});function Ln(e){return e==="top-left"||e==="bottom-left"?"left":"right"}const Vt="ll-hidden-tab-center-y",Nn=5,Ct=16;function Rn(){if(typeof window>"u")return null;try{const e=window.localStorage.getItem(Vt);if(!e)return null;const n=Number.parseFloat(e);return Number.isFinite(n)?n:null}catch{return null}}function St(e){if(!(typeof window>"u"))try{window.localStorage.setItem(Vt,String(e))}catch{}}const An=({position:e,isMobile:n,isSpeaking:i,onExpand:o,label:s="Open widget"})=>{const l=Ln(e),u=l==="right"?"left":"right",d=n?80:72,[f,y]=r.useState(null),[h,a]=r.useState(!1),c=r.useRef(null),j=r.useRef(!1),C=r.useCallback(x=>{if(typeof window>"u")return x;const S=d/2,w=Ct+S,I=window.innerHeight-Ct-S;return I<w?Math.max(w,x):Math.max(w,Math.min(I,x))},[d]);r.useEffect(()=>{const x=Rn();y(C(x??window.innerHeight/2));const S=()=>{y(w=>w===null?null:C(w))};return window.addEventListener("resize",S),()=>window.removeEventListener("resize",S)},[C]);const E=r.useCallback(x=>{if(!(x.pointerType==="mouse"&&x.button!==0)&&f!==null){try{x.currentTarget.setPointerCapture(x.pointerId)}catch{}c.current={startClientY:x.clientY,startCenterY:f,moved:!1}}},[f]),T=r.useCallback(x=>{const S=c.current;if(!S)return;const w=x.clientY-S.startClientY;!S.moved&&Math.abs(w)>Nn&&(S.moved=!0,a(!0)),S.moved&&y(C(S.startCenterY+w))},[C]),N=r.useCallback(x=>{const S=c.current;if(S){try{x.currentTarget.releasePointerCapture(x.pointerId)}catch{}c.current=null,S.moved&&(a(!1),j.current=!0,y(w=>(w!==null&&St(w),w)))}},[]),M=r.useCallback(()=>{if(j.current){j.current=!1;return}o()},[o]),L=r.useCallback(x=>{if(x.key==="ArrowUp"||x.key==="ArrowDown"){x.preventDefault();const S=x.key==="ArrowUp"?-8:8;y(w=>{if(w===null)return w;const I=C(w+S);return St(I),I})}},[C]),A=["ll-hidden",`ll-hidden--${l}`,n?"ll-hidden--mobile":"ll-hidden--desktop",i?"ll-hidden--speaking":null,h?"is-dragging":null].filter(Boolean).join(" "),g=f===null?void 0:{top:`${f-d/2}px`,transform:"none"};return t.jsx("button",{type:"button",className:A,onPointerDown:E,onPointerMove:T,onPointerUp:N,onPointerCancel:N,onClick:M,onKeyDown:L,"aria-label":s,"data-position":e,style:g,children:t.jsx(En,{direction:u,className:"ll-hidden__chevron"})})},Mn=({audioLevel:e,bars:n=20,maxHeight:i=20,minHeight:o=4,className:s,barClassName:l})=>{const u=r.useRef(null),d=r.useRef([]),f=r.useMemo(()=>{const h=(Math.sqrt(5)-1)/2;return Array.from({length:n},(a,c)=>.5+c*h%1*.5)},[n]);r.useEffect(()=>e.subscribe(a=>{for(let c=0;c<n;c++){const j=d.current[c];if(!j)continue;const C=Math.max(o,a*i*f[c]);j.style.height=`${C}px`}}),[e,n,i,o,f]);const y=["ll-waveform",s].filter(Boolean).join(" ");return t.jsx("div",{ref:u,className:y,"aria-hidden":"true",children:Array.from({length:n},(h,a)=>t.jsx("div",{ref:c=>{d.current[a]=c},className:["ll-waveform__bar",l].filter(Boolean).join(" "),style:{height:`${o}px`}},a))})},Tn=({position:e,isMobile:n,agentName:i,avatarImageUrl:o,agentState:s,isMuted:l,audioLevel:u,onExpand:d,onToggleMute:f,onClose:y})=>n?t.jsx("div",{className:"ll-minimized ll-minimized--mobile",role:"region","aria-label":`${i} widget`,children:t.jsxs("button",{type:"button",className:"ll-minimized__surface",onClick:d,"aria-label":`Expand ${i} widget`,children:[o?t.jsx("img",{src:o,alt:i,className:"ll-minimized__avatar"}):t.jsx("div",{className:"ll-minimized__avatar ll-minimized__avatar--placeholder"}),t.jsx(Mn,{audioLevel:u,bars:16,maxHeight:18,className:"ll-minimized__waveform"}),t.jsx("span",{className:"ll-minimized__name",children:i}),t.jsxs("div",{className:"ll-minimized__controls",children:[t.jsx("span",{className:"ll-minimized__btn",role:"button",tabIndex:0,onClick:h=>{h.stopPropagation(),f()},onKeyDown:h=>{(h.key==="Enter"||h.key===" ")&&(h.stopPropagation(),h.preventDefault(),f())},"aria-label":l?"Unmute microphone":"Mute microphone",children:t.jsx(_t,{muted:l,className:"ll-minimized__icon"})}),t.jsx(kt,{className:"ll-minimized__icon ll-minimized__icon--expand"})]})]})}):t.jsx("div",{className:"ll-minimized ll-minimized--desktop","data-position":e,role:"region","aria-label":`${i} widget`,children:t.jsxs("div",{className:"ll-minimized__surface",children:[o?t.jsx("img",{src:o,alt:i,className:"ll-minimized__avatar"}):t.jsx("div",{className:"ll-minimized__avatar ll-minimized__avatar--placeholder"}),t.jsxs("div",{className:"ll-minimized__meta",children:[t.jsx("span",{className:"ll-minimized__name",children:i}),t.jsx("span",{className:"ll-minimized__state",children:s==="speaking"?"Speaking":s==="thinking"?"Thinking":"Listening"})]}),t.jsxs("div",{className:"ll-minimized__controls",children:[t.jsx("button",{type:"button",className:"ll-minimized__btn",onClick:f,"aria-label":l?"Unmute microphone":"Mute microphone",children:t.jsx(_t,{muted:l,className:"ll-minimized__icon"})}),t.jsx("button",{type:"button",className:"ll-minimized__btn",onClick:d,"aria-label":`Expand ${i} widget`,children:t.jsx(kt,{className:"ll-minimized__icon"})}),t.jsx("button",{type:"button",className:"ll-minimized__btn ll-minimized__btn--close",onClick:y,"aria-label":"Close widget",children:t.jsx(Sn,{className:"ll-minimized__icon"})})]})]})}),In=({src:e,alt:n,preCannedPlaying:i=!1,className:o,style:s})=>{const[l,u]=r.useState(!1),d=r.useRef(e);if(r.useEffect(()=>{d.current!==e&&(d.current=e,u(!1))},[e]),!e)return null;const f={position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transition:"opacity 500ms ease, transform 500ms ease",transform:i?"scale(1.02)":"scale(1)",opacity:l?1:0,...s};return t.jsx("img",{src:e,alt:n,className:o,style:f,loading:"eager",fetchpriority:"high",onLoad:()=>u(!0)})},Pn=({position:e,isMobile:n,agentName:i,avatarImageUrl:o,idleLoopUrl:s,greeting:l,branding:u,teamMembers:d,currentTeamMemberId:f,isSwitchingTeamMember:y,teamSwitcherOpen:h,onToggleTeamSwitcher:a,onSelectTeamMember:c,languageMenuOpen:j,onToggleLanguageMenu:C,connectionState:E,agentState:T,transcript:N,canResume:M,needsUserGesture:L,error:A,isMuted:g,micError:x,micDevices:S,isCameraEnabled:w,cameraPreviewEl:I,cameraDevices:W,activeCameraId:oe,isScreenShareEnabled:V,screenPreviewEl:K,isSpeakerMuted:se,allowCamera:Ae,allowScreenShare:Me,allowTyping:Te,avatarVideoContainerRef:Ie,onConnect:le,onDisconnect:de,onRetry:fe,onResumeAudio:pe,onToggleMute:he,onToggleCamera:me,onSwitchCameraDevice:ge,onToggleScreenShare:D,onToggleSpeaker:Be,onSendMessage:Pe,onMinimize:De,onClose:_e,onClearMicError:ke})=>{var Ee;const Z=N.length>0?N[N.length-1]:null,ae=((d==null?void 0:d.length)??0)>1,ye=E==="connecting"||E==="connected",Y=E==="connected",F=E==="idle"||E==="disconnected"||E==="error",Ce=r.useRef(null),ee=r.useRef(null);r.useEffect(()=>{const m=Ce.current;m&&(m.innerHTML="",I&&(I.style.width="100%",I.style.height="100%",I.style.objectFit="cover",I.style.transform="scaleX(-1)",m.appendChild(I)))},[I]),r.useEffect(()=>{const m=ee.current;m&&(m.innerHTML="",K&&(K.style.width="100%",K.style.height="100%",K.style.objectFit="contain",m.appendChild(K)))},[K]);const[B,Q]=r.useState(!1),[te,q]=r.useState(!1);r.useEffect(()=>{if(!B&&!te&&!j&&!h)return;const m=()=>{Q(!1),q(!1),j&&C(),h&&a()};return document.addEventListener("click",m),()=>document.removeEventListener("click",m)},[B,te,j,h,C,a]);const[U,ne]=r.useState(""),Se=r.useCallback(m=>{m.preventDefault();const H=U.trim();H&&(Pe(H),ne(""))},[U,Pe]),Ue=u.productName||"Live Layer",xe=Y&&(Z!=null&&Z.text)?Z.text:l||"",je=["ll-expanded",n?"ll-expanded--mobile":"ll-expanded--desktop"].join(" ");return t.jsxs("div",{className:je,"data-position":e,"data-state":Y?"connected":ye?"connecting":"idle",role:"dialog","aria-label":`${i} widget`,children:[t.jsxs("div",{className:"ll-expanded__bg",children:[o?t.jsx(In,{src:o,alt:i,className:"ll-expanded__bg-img"}):t.jsx("div",{className:"ll-expanded__bg-fallback",children:t.jsx("span",{className:"ll-expanded__bg-initial",children:((Ee=i==null?void 0:i.charAt(0))==null?void 0:Ee.toUpperCase())||"A"})}),s&&!Y&&t.jsx("video",{className:"ll-expanded__bg-idle",src:s,autoPlay:!0,loop:!0,muted:!0,playsInline:!0})]}),t.jsx("div",{ref:Ie,className:"ll-expanded__video"}),E==="connecting"&&t.jsxs("div",{className:"ll-expanded__overlay ll-expanded__overlay--connecting",children:[t.jsx("div",{className:"ll-expanded__spinner"}),t.jsx("p",{className:"ll-expanded__overlay-text",children:y?"Switching...":"Connecting..."})]}),L&&Y&&t.jsxs("button",{type:"button",className:"ll-expanded__overlay ll-expanded__overlay--gesture",onClick:pe,children:[t.jsx("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:t.jsx("path",{d:"M3 9v6h4l5 5V4L7 9H3zm13.54.12a5 5 0 0 1 0 5.76l-1.41-1.41a3 3 0 0 0 0-2.94L16.54 9.12z"})}),t.jsx("p",{className:"ll-expanded__overlay-text",children:"Tap to enable audio"})]}),ye?t.jsxs("div",{className:"ll-expanded__topbar",children:[t.jsxs("div",{className:"ll-expanded__topbar-left",children:[t.jsxs("div",{className:"ll-expanded__pill-wrap",children:[t.jsxs("button",{type:"button",className:"ll-hpill",onClick:m=>{ae&&(m.stopPropagation(),a())},"aria-haspopup":ae?"listbox":void 0,"aria-expanded":ae?h:void 0,children:[t.jsx("span",{className:"ll-hpill__label",children:i}),ae&&t.jsx(ze,{})]}),ae&&h&&t.jsx("div",{className:"ll-hmenu",onClick:m=>m.stopPropagation(),role:"listbox",children:d==null?void 0:d.map(m=>t.jsxs("button",{type:"button",className:`ll-hmenu__item ${m.id===f?"is-active":""}`,onClick:()=>c(m.id),role:"option","aria-selected":m.id===f,children:[m.avatarImageUrl&&t.jsx("img",{src:m.avatarImageUrl,alt:"",className:"ll-hmenu__avatar"}),t.jsx("span",{className:"ll-hmenu__name",children:m.name}),m.role&&t.jsx("span",{className:"ll-hmenu__role",children:m.role})]},m.id))})]}),t.jsxs("div",{className:"ll-expanded__pill-wrap",children:[t.jsxs("button",{type:"button",className:"ll-hpill ll-hpill--compact",onClick:m=>{m.stopPropagation(),C()},"aria-haspopup":"listbox","aria-expanded":j,"aria-label":"Language: English",title:"Language: English",children:[t.jsx("span",{className:"ll-hpill__label",children:"EN"}),t.jsx(ze,{})]}),j&&t.jsx("div",{className:"ll-hmenu",onClick:m=>m.stopPropagation(),role:"listbox",children:t.jsx("button",{type:"button",className:"ll-hmenu__item is-active",role:"option","aria-selected":!0,children:t.jsx("span",{className:"ll-hmenu__name",children:"English"})})})]}),t.jsx("span",{className:`ll-expanded__state ll-expanded__state--${T}`,children:T})]}),t.jsxs("div",{className:"ll-expanded__header-actions",children:[t.jsx("button",{type:"button",className:"ll-hbtn",onClick:De,"aria-label":"Minimize widget",title:"Minimize",children:t.jsx(Et,{})}),t.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--danger",onClick:_e,"aria-label":"End call",title:"End call",children:t.jsx(jt,{})})]})]}):t.jsxs("div",{className:"ll-expanded__header ll-expanded__header--idle",children:[t.jsx("span",{className:"ll-expanded__brand",children:Ue}),t.jsxs("div",{className:"ll-expanded__header-actions",children:[t.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--ghost",onClick:De,"aria-label":"Minimize widget",children:t.jsx(Et,{})}),t.jsx("button",{type:"button",className:"ll-hbtn ll-hbtn--danger",onClick:_e,"aria-label":"Close widget",children:t.jsx(jt,{})})]})]}),F&&(()=>{const m=M?"Restart paused session":E==="disconnected"?"Reconnect to agent":"Start video call",H=M?"Pick up where you left off":null,We=E==="idle"&&!M&&!A;return t.jsxs(t.Fragment,{children:[We&&t.jsxs("button",{type:"button",className:"ll-expanded__play",onClick:le,"aria-label":m,children:[t.jsx("div",{className:"ll-expanded__play-circle",children:t.jsx("svg",{width:"22",height:"22",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:t.jsx("polygon",{points:"6 3 20 12 6 21 6 3"})})}),t.jsx("span",{className:"ll-expanded__play-label",children:m})]}),t.jsxs("div",{className:"ll-expanded__bottom ll-expanded__bottom--idle",children:[l&&t.jsx("div",{className:"ll-expanded__transcript",children:t.jsx("p",{className:"ll-expanded__transcript-text",children:l})}),H&&t.jsx("p",{className:"ll-expanded__cta-sublabel",children:H}),t.jsx("button",{type:"button",className:"ll-expanded__cta",onClick:le,"aria-label":m,children:m})]})]})})(),t.jsxs("div",{className:`ll-expanded__pip ${ye&&(w||V)?"is-visible":""}`,children:[t.jsx("div",{ref:ee,className:V?"ll-expanded__pip-host":"ll-expanded__pip-host is-hidden"}),t.jsx("div",{ref:Ce,className:!V&&w?"ll-expanded__pip-host":"ll-expanded__pip-host is-hidden"})]}),ye?t.jsxs("div",{className:"ll-expanded__bottom",children:[xe&&t.jsx("div",{className:"ll-expanded__transcript",children:t.jsx("p",{className:"ll-expanded__transcript-text",children:xe})}),t.jsxs("div",{className:"ll-toolbar",onClick:m=>m.stopPropagation(),children:[Me&&t.jsx("button",{type:"button",className:`ll-tool ${V?"is-on":""}`,onClick:D,"aria-label":V?"Stop sharing screen":"Share screen",title:V?"Stop sharing":"Share screen",children:t.jsx(Dn,{})}),Ae&&t.jsxs("div",{className:"ll-tool-split",children:[t.jsx("button",{type:"button",className:`ll-tool ll-tool--left ${w?"is-on":""}`,onClick:me,"aria-label":w?"Turn off camera":"Turn on camera",title:w?"Stop camera":"Start camera",children:t.jsx($n,{})}),t.jsx("button",{type:"button",className:`ll-tool ll-tool--right ${w?"is-on":""}`,onClick:m=>{m.stopPropagation(),q(H=>!H),Q(!1)},"aria-label":"Camera devices","aria-haspopup":"listbox","aria-expanded":te,children:t.jsx(ze,{})}),te&&W.length>0&&t.jsx(Lt,{label:"Camera",devices:W,activeId:oe,onPick:m=>{q(!1),ge(m)}})]}),t.jsxs("div",{className:"ll-tool-split",children:[t.jsx("button",{type:"button",className:`ll-tool ll-tool--left ${g?"is-muted":""}`,onClick:he,"aria-label":g?"Unmute microphone":"Mute microphone",title:g?"Unmute":"Mute",children:t.jsx(zn,{muted:g})}),t.jsx("button",{type:"button",className:`ll-tool ll-tool--right ${g?"is-muted":""}`,onClick:m=>{m.stopPropagation(),Q(H=>!H),q(!1)},"aria-label":"Microphone devices","aria-haspopup":"listbox","aria-expanded":B,children:t.jsx(ze,{})}),B&&S.length>0&&t.jsx(Lt,{label:"Microphone",devices:S,activeId:"",onPick:()=>Q(!1)})]}),t.jsx("button",{type:"button",className:`ll-tool ${se?"is-muted":""}`,onClick:Be,"aria-label":se?"Unmute speaker":"Mute speaker",title:se?"Unmute speaker":"Mute speaker",children:t.jsx(Hn,{muted:se})})]}),Te&&t.jsxs("form",{className:"ll-message-input",onSubmit:Se,children:[t.jsx("input",{type:"text",className:"ll-message-input__field",placeholder:"Message...",value:U,onChange:m=>ne(m.target.value),"aria-label":"Message the agent"}),U.trim()&&t.jsx("button",{type:"submit",className:"ll-message-input__send","aria-label":"Send message",children:t.jsx(On,{})})]}),t.jsx("button",{type:"button",className:"ll-expanded__end",onClick:de,children:"End conversation"})]}):null,(()=>{if(x&&E!=="error")return t.jsxs("div",{className:"ll-expanded__banner",role:"alert",children:[t.jsx("span",{children:x}),t.jsx("button",{type:"button",className:"ll-expanded__banner-x",onClick:ke,"aria-label":"Dismiss",children:"×"})]});if(!A||E!=="error")return null;let m="Failed to connect",H="Try again";return A==="MIC_PERMISSION_DENIED"?m="Microphone blocked. Allow access to talk.":A==="MIC_NOT_FOUND"?m="No microphone found. Plug one in + retry.":A==="MIC_UNAVAILABLE"?m="Mic unavailable. Check other apps using it.":A==="AGENT_TIMEOUT"?m="Agent didn't pick up. Try again.":A==="CONNECT_FAILED"?m="Connection failed. Check your network.":A.length<80&&(m=A),t.jsxs("div",{className:"ll-expanded__banner ll-expanded__banner--error",role:"alert",children:[t.jsx("span",{children:m}),t.jsx("button",{type:"button",className:"ll-expanded__banner-retry",onClick:fe,children:H})]})})()]})};function ze(){return t.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round","aria-hidden":!0,children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})}function jt(){return t.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round","aria-hidden":!0,children:[t.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}function Et(){return t.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round","aria-hidden":!0,children:t.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"})})}function Dn(){return t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("rect",{x:"2",y:"3",width:"20",height:"14",rx:"2"}),t.jsx("line",{x1:"8",y1:"21",x2:"16",y2:"21"}),t.jsx("line",{x1:"12",y1:"17",x2:"12",y2:"21"})]})}function $n(){return t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("path",{d:"M23 7l-7 5 7 5V7z"}),t.jsx("rect",{x:"1",y:"5",width:"15",height:"14",rx:"2"})]})}function zn({muted:e}){return t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("path",{d:"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"}),t.jsx("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),t.jsx("line",{x1:"12",y1:"19",x2:"12",y2:"23"}),e&&t.jsx("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]})}function Hn({muted:e}){return t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5"}),e?t.jsx("line",{x1:"23",y1:"9",x2:"17",y2:"15"}):t.jsxs(t.Fragment,{children:[t.jsx("path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14"}),t.jsx("path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07"})]})]})}function On(){return t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),t.jsx("polyline",{points:"12 5 19 12 12 19"})]})}const Lt=({label:e,devices:n,activeId:i,onPick:o})=>t.jsxs("div",{className:"ll-device-menu",onClick:s=>s.stopPropagation(),role:"listbox",children:[t.jsx("p",{className:"ll-device-menu__label",children:e}),n.map((s,l)=>{const u=i===s.deviceId;return t.jsxs("button",{type:"button",className:`ll-device-menu__item ${u?"is-active":""}`,onClick:()=>o(s.deviceId),role:"option","aria-selected":u,children:[u&&t.jsx("span",{className:"ll-device-menu__dot",children:"●"}),t.jsx("span",{className:"ll-device-menu__name",children:s.label||`${e} ${l+1}`})]},s.deviceId||l)})]}),Fn=['[data-ll-private="true"]',".ll-widget"];function tt(e){let n=e;for(;n;){for(const i of Fn)if(n.matches(i))return!0;n=n.parentElement}return!1}function qe(e){if(tt(e))return!1;if(e instanceof HTMLInputElement){if(e.type==="password")return!1;const n=(e.getAttribute("autocomplete")||"").toLowerCase();if(n==="off"||n.startsWith("cc-"))return!1}return!0}const He=4096,qn=20,Bn=20,Un=10,Wn=10,Vn=30,Nt=500,Kn=['[data-ll-private="true"]',".ll-widget","script","style","noscript","iframe"];function Ne(e){if(e.getAttribute("aria-hidden")==="true"||e.hasAttribute("hidden"))return!0;let n=e;for(;n;){for(const i of Kn)if(n.matches(i))return!0;n=n.parentElement}return!1}function Re(e){if(typeof window>"u")return!0;const n=e.getBoundingClientRect();if(n.width<=0||n.height<=0)return!1;const i=window.innerHeight||document.documentElement.clientHeight,o=window.innerWidth||document.documentElement.clientWidth;return n.bottom>0&&n.right>0&&n.top<i&&n.left<o}function Rt(e){const n=e.getAttribute("id");if(n){const l=document.querySelector(`label[for="${CSS.escape(n)}"]`);if(l!=null&&l.textContent)return l.textContent.trim()}const i=e.getAttribute("aria-label");if(i)return i.trim();const o=e.getAttribute("placeholder");if(o)return o.trim();const s=e.closest("label");return s!=null&&s.textContent?s.textContent.trim():""}function ue(e,n){return e.length<=n?e:e.slice(0,n-1)+"…"}function ve(e){return e.length}function Kt(e,n={}){const i=n.doc??(typeof document<"u"?document:null);if(!i)return{url:"",title:"",pathname:"/",regions:[],visibleText:"",visibleLinks:[],visibleFields:[],forms:[],extras:e};const o=typeof window<"u"&&window.location.href||"",s=typeof window<"u"&&window.location.pathname||"/",l=i.title||"",u=Array.from(i.querySelectorAll("[data-ll-region]")),d=[];for(const g of u){if(d.length>=Un)break;if(Ne(g)||!Re(g))continue;const x=g.getAttribute("data-ll-region")??"",S=g.getAttribute("data-ll-intent")??void 0,w=ue((g.innerText||g.textContent||"").trim(),Nt*2);!x||!w||d.push({id:x,intent:S,text:w})}const f=[],y=["H1","H2","H3","H4","H5","H6"],h=Array.from(i.querySelectorAll("h1, h2, h3, h4, h5, h6"));for(const g of h){if(Ne(g)||!Re(g))continue;const x=(g.textContent||"").trim();x&&f.push(`${g.tagName}: ${ue(x,200)}`)}const a=Array.from(i.querySelectorAll("p, li"));for(const g of a){if(Ne(g)||!Re(g)||y.includes(g.tagName))continue;const x=(g.textContent||"").trim();x.length>10&&f.push(ue(x,Nt))}const c=f.join(`
|
|
2
|
+
`),j=[],C=Array.from(i.querySelectorAll("a[href]"));for(const g of C){if(j.length>=qn)break;if(Ne(g)||!Re(g))continue;const x=g.getAttribute("href")||"",S=(g.textContent||"").trim();!x||!S||j.push({href:x,text:ue(S,100)})}const E=[],T=Array.from(i.querySelectorAll("input, textarea, select"));for(const g of T){if(E.length>=Bn)break;if(Ne(g)||!qe(g)||!Re(g))continue;const x=Rt(g),S=g instanceof HTMLInputElement?g.type:g.tagName.toLowerCase();x&&E.push({label:ue(x,100),type:S})}const N=Array.from(i.querySelectorAll("[data-ll-form]")),M=[];for(const g of N){if(M.length>=Wn)break;if(tt(g))continue;const x=g.getAttribute("data-ll-form")||"";if(!x)continue;const S=g.getAttribute("data-ll-intent")||void 0,w=Array.from(g.querySelectorAll("[data-ll-field]")),I=[];for(const W of w){if(I.length>=Vn)break;if(!qe(W))continue;const oe=W.getAttribute("data-ll-field")||"";if(!oe)continue;const V=Rt(W)||oe,K=W instanceof HTMLInputElement?W.type:W.tagName.toLowerCase();I.push({name:oe,label:ue(V,100),type:K})}M.push({id:x,intent:S,fields:I})}const L={url:o,title:l,pathname:s,regions:d,visibleText:c,visibleLinks:j,visibleFields:E,forms:M,extras:e};let A=ve(JSON.stringify(L.regions))+ve(L.visibleText)+ve(JSON.stringify(L.visibleLinks))+ve(JSON.stringify(L.visibleFields));for(;A>He&&L.visibleFields.length>0;)L.visibleFields.pop(),A=ve(JSON.stringify(L.visibleFields));for(;A>He&&L.visibleLinks.length>0;)L.visibleLinks.pop(),A-=80;return ve(L.visibleText)>He&&(L.visibleText=ue(L.visibleText,He-100)),L}let be=null;function et(e,n={}){const i=Date.now(),s=`${typeof window<"u"&&window.location.pathname||"/"}::${typeof window<"u"?window.scrollY:0}`;if(be&&be.key===s&&i-be.at<1e3)return be.ctx;const l=Kt(e,n);return be={key:s,at:i,ctx:l},l}function Yt(){be=null}const Yn=200;function Gn(e){return!(!e||e.startsWith("#")||e.startsWith("javascript:")||e.startsWith("mailto:")||e.startsWith("tel:"))}function Gt(e){const n=e??(typeof document<"u"?document:null);if(!n)return[];const i=typeof window<"u"&&window.location.origin||"",o=new Set,s=[],l=Array.from(n.querySelectorAll("a[href]"));for(const u of l){if(s.length>=Yn)break;if(tt(u))continue;const d=u.getAttribute("href")||"";if(!Gn(d))continue;let f=d,y=!0;try{if(typeof window<"u"){const a=new URL(d,i);y=a.origin===i,y&&d.startsWith("http")&&(f=a.pathname+a.search+a.hash)}}catch{continue}if(o.has(f))continue;o.add(f);const h=(u.textContent||"").trim().slice(0,120);s.push({href:f,text:h,internal:y})}return s}let we=null;const Xn=5e3;function Xt(){const e=Date.now(),n=typeof window<"u"&&window.location.pathname||"/";if(we&&we.pathname===n&&e-we.at<Xn)return we.routes;const i=Gt();return we={at:e,pathname:n,routes:i},i}function Jt(){we=null}function Jn(e,n){const i=e instanceof HTMLInputElement?HTMLInputElement.prototype:e instanceof HTMLTextAreaElement?HTMLTextAreaElement.prototype:HTMLSelectElement.prototype,o=Object.getOwnPropertyDescriptor(i,"value"),s=o==null?void 0:o.set;s?s.call(e,n):e.value=n}function Qn(e,n,i={}){const o=i.triggerInput??!0,s=i.triggerChange??!0;if(e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")){const l=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"checked"),u=l==null?void 0:l.set,d=n==="true"||n==="1"||n==="on";u?u.call(e,d):e.checked=d,o&&e.dispatchEvent(new Event("input",{bubbles:!0})),s&&e.dispatchEvent(new Event("change",{bubbles:!0}));return}Jn(e,n),o&&e.dispatchEvent(new Event("input",{bubbles:!0})),s&&e.dispatchEvent(new Event("change",{bubbles:!0}))}const Zn=new Set(["agent_state","avatar_stream_ready","avatar_active","avatar_idle","bot_ready","agent_error","idle_warning","idle_timeout","navigate","scroll_to","request_page_context","scroll_page","click","fill_form","focus_field","submit_form","request_routes"]);function er(e){var ct,ut,dt,ft,pt,ht;const{agentId:n,apiKey:i,baseUrl:o="https://app.livelayer.studio",sessionEndpoint:s,sessionBody:l,autoConnect:u=!1,displayMode:d,defaultDisplayMode:f="expanded",onDisplayModeChange:y,position:h="bottom-right",mobileBreakpoint:a=640,persistKey:c="ll-widget",disablePersistence:j=!1,teamMembers:C,currentTeamMemberId:E,onTeamMemberChange:T,idleLoopUrl:N,greeting:M,avatarImageUrl:L,agentName:A,branding:g={},allowCamera:x=!0,allowScreenShare:S=!0,allowTyping:w=!0,showOn:I,hideOn:W,pathname:oe,onNavigate:V,onScrollToSelector:K,getPageContext:se,pageContextExtras:Ae,onScrollPage:Me,onClick:Te,capabilities:Ie,onConnect:le,onDisconnect:de,onTranscript:fe,onAgentState:pe,onConnectionStateChange:he,onAgentEvent:me,onAgentCommand:ge,controlledSession:D,className:Be,style:Pe,zIndex:De=2147483647}=e,_e=qt(oe),ke=Wt(_e,I,W);r.useEffect(()=>{Yt(),Jt()},[_e]);const Z=E!==void 0,[ae,ye]=r.useState(()=>{var v;return E??((v=C==null?void 0:C[0])==null?void 0:v.id)}),Y=Z?E:ae,F=r.useMemo(()=>(C==null?void 0:C.find(v=>v.id===Y))??null,[C,Y]),Ce=(F==null?void 0:F.agentId)??n,[ee,B]=Ot({value:d,defaultValue:f,onChange:y,persistKey:c,disablePersistence:j}),Q=Ft(a),te=Tt(),q=It(),U=Pt(),ne=Dt(),Se=$t(),[Ue,xe]=r.useState(!1),[je,Ee]=r.useState(!1),[m,H]=r.useState(!1),[We,Qt]=r.useState(!1),[Ve,Zt]=r.useState(!1),Ke=r.useRef(V),Ye=r.useRef(K),Ge=r.useRef(Me),Xe=r.useRef(Te),nt=r.useRef(se),rt=r.useRef(Ae),it=r.useRef(Ie),G=r.useRef(null);Ke.current=V,Ye.current=K,Ge.current=Me,Xe.current=Te,nt.current=se,rt.current=Ae,it.current=Ie;function re(v){const p=it.current;return p?p.includes(v):!0}function ie(v,p){console.warn(`[LiveLayer] Agent command "${v}" blocked — capability "${p}" not in allowlist. See https://livelayer.studio/docs/react/capabilities`)}const Je=r.useCallback(v=>{var X,mt,gt,yt;const p=v;if(!(!p.type||typeof p.type!="string")){if(me==null||me({eventName:p.type,data:v}),p.type==="navigate"){if(!re("navigate")){ie("navigate","navigate");return}const _=typeof p.href=="string"?p.href:null;if(!_){console.warn(`[LiveLayer] Agent emitted "navigate" without href. Skipping. Check your agent's tool schema. See https://livelayer.studio/docs/errors/navigate-missing-href`);return}if(Ke.current){try{Ke.current(_)}catch(k){console.warn(`[LiveLayer] onNavigate threw for "${_}". Falling back. Error:`,k)}return}if(typeof document<"u"){const k=document.querySelector(`a[href="${_.replace(/"/g,'\\"')}"]`);if(k){k.click();return}}if(typeof window<"u"&&typeof history<"u")try{history.pushState({},"",_),window.dispatchEvent(new PopStateEvent("popstate"))}catch(k){console.warn(`[LiveLayer] history.pushState fallback failed for "${_}". Pass an onNavigate prop to use your router directly. See https://livelayer.studio/docs/react/navigation`,k)}return}if(p.type==="scroll_to"){if(!re("scroll")){ie("scroll_to","scroll");return}const _=typeof p.selector=="string"?p.selector:null;if(!_)return;const k=p.behavior==="instant"?"instant":"smooth";if(Ye.current){try{Ye.current(_,k)}catch(R){console.warn("[LiveLayer] onScrollToSelector threw.",R)}return}if(typeof document<"u"){let R=null;try{R=document.querySelector(_)}catch{console.warn(`[LiveLayer] scroll_to: invalid selector "${_}".`);return}if(!R){console.warn(`[LiveLayer] scroll_to: no element matched "${_}". The user may be on a different page. See https://livelayer.studio/docs/errors/scroll-no-match`);return}R.scrollIntoView({behavior:k,block:"start"})}return}if(p.type==="request_page_context"){if(!re("read_page")){ie("request_page_context","read_page");return}const _=(X=G.current)==null?void 0:X.call(G),k=$=>{const O=_,J=O==null?void 0:O.localParticipant;if(J!=null&&J.publishData)try{const ce=new TextEncoder().encode(JSON.stringify($));J.publishData(ce,{reliable:!0})}catch(ce){console.warn("[LiveLayer] publishData failed.",ce)}},R=rt.current,P=nt.current;try{if(P){const $=P(R);if($ instanceof Promise){k({type:"page_context_pending"}),$.then(O=>k({type:"page_context",context:O})).catch(O=>{console.warn("[LiveLayer] getPageContext rejected; falling back to default walker.",O),k({type:"page_context",context:et(R)})});return}k({type:"page_context",context:$});return}k({type:"page_context",context:et(R)})}catch($){console.warn("[LiveLayer] page-context extraction threw. Sending empty context.",$),k({type:"page_context",context:{url:"",title:"",pathname:"/",regions:[],visibleText:"",visibleLinks:[],visibleFields:[],extras:R}})}return}if(p.type==="scroll_page"){if(!re("scroll")){ie("scroll_page","scroll");return}const _=p.direction;if(_!=="up"&&_!=="down"&&_!=="top"&&_!=="bottom"){console.warn(`[LiveLayer] scroll_page: invalid direction "${String(_)}". Expected up | down | top | bottom.`);return}const k=p.behavior==="instant"?"instant":"smooth";if(Ge.current){try{Ge.current(_,k)}catch(P){console.warn("[LiveLayer] onScrollPage threw.",P)}return}if(typeof window>"u")return;const R={behavior:k};_==="up"?window.scrollBy({top:-window.innerHeight,...R}):_==="down"?window.scrollBy({top:window.innerHeight,...R}):_==="top"?window.scrollTo({top:0,...R}):window.scrollTo({top:document.body.scrollHeight,...R});return}if(p.type==="click"){if(!re("click")){ie("click","click");return}const _=typeof p.selector=="string"?p.selector:null;if(!_){console.warn("[LiveLayer] click: missing selector.");return}if(Xe.current){try{Xe.current(_)}catch(R){console.warn("[LiveLayer] onClick threw.",R)}return}if(typeof document>"u")return;let k=null;try{k=document.querySelector(_)}catch{console.warn(`[LiveLayer] click: invalid selector "${_}".`);return}if(!k){console.warn(`[LiveLayer] click: no element matched "${_}". See https://livelayer.studio/docs/errors/click-no-match`);return}if(k.closest('[data-ll-private="true"], .ll-widget')){console.warn("[LiveLayer] click: refusing to click element inside a private subtree.");return}(mt=k.click)==null||mt.call(k);return}if(p.type==="fill_form"||p.type==="focus_field"){if(!re("fill_forms")){ie(p.type,"fill_forms");return}if(typeof document>"u")return;const _=typeof p.formId=="string"?p.formId:null;if(!_){console.warn(`[LiveLayer] ${p.type}: missing formId.`);return}const k=document.querySelector(`[data-ll-form="${_.replace(/"/g,'\\"')}"]`);if(!k){console.warn(`[LiveLayer] ${p.type}: no form with data-ll-form="${_}". Tag your form with <LiveLayerForm id> or data-ll-form. See https://livelayer.studio/docs/react/forms`);return}if(k.closest('[data-ll-private="true"], .ll-widget')){console.warn(`[LiveLayer] ${p.type}: refusing to touch a form in a private subtree.`);return}if(p.type==="focus_field"){const P=typeof p.fieldName=="string"?p.fieldName:null;if(!P){console.warn("[LiveLayer] focus_field: missing fieldName.");return}const $=k.querySelector(`[data-ll-field="${P.replace(/"/g,'\\"')}"]`);if(!$){console.warn(`[LiveLayer] focus_field: no field "${P}" in form "${_}".`);return}if(!qe($)){console.warn(`[LiveLayer] focus_field: field "${P}" is privacy-protected and not focusable.`);return}$.focus();return}const R=p.values&&typeof p.values=="object"?p.values:null;if(!R){console.warn("[LiveLayer] fill_form: missing or invalid values.");return}for(const[P,$]of Object.entries(R)){if(typeof $!="string")continue;const O=k.querySelector(`[data-ll-field="${P.replace(/"/g,'\\"')}"]`);if(!O){console.warn(`[LiveLayer] fill_form: no field "${P}" in form "${_}". Skipping.`);continue}if(!qe(O)){console.warn(`[LiveLayer] fill_form: field "${P}" is privacy-protected (password / cc-* / private). Skipping.`);continue}try{Qn(O,$)}catch(J){console.warn(`[LiveLayer] fill_form: failed to set "${P}".`,J)}}return}if(p.type==="submit_form"){if(!re("submit_forms")){ie("submit_form","submit_forms");return}if(typeof document>"u")return;const _=typeof p.formId=="string"?p.formId:null;if(!_){console.warn("[LiveLayer] submit_form: missing formId.");return}const k=document.querySelector(`[data-ll-form="${_.replace(/"/g,'\\"')}"]`);if(!k){console.warn(`[LiveLayer] submit_form: no form with data-ll-form="${_}".`);return}if(k.closest('[data-ll-private="true"], .ll-widget')){console.warn("[LiveLayer] submit_form: refusing to submit a form in a private subtree.");return}const R=(gt=G.current)==null?void 0:gt.call(G),P=J=>{const ce=R,$e=ce==null?void 0:ce.localParticipant;if($e!=null&&$e.publishData)try{const fn=new TextEncoder().encode(JSON.stringify(J));$e.publishData(fn,{reliable:!0})}catch{}};let $=!1;const O=()=>{$=!0,P({type:"form_submitted",formId:_})};k.addEventListener("submit",O,{once:!0});try{typeof k.requestSubmit=="function"?k.requestSubmit():k.submit()}catch(J){console.warn("[LiveLayer] submit_form: requestSubmit threw.",J),k.removeEventListener("submit",O),P({type:"form_submit_blocked",formId:_,reason:"exception"});return}setTimeout(()=>{$||(k.removeEventListener("submit",O),P({type:"form_submit_blocked",formId:_,reason:"validation"}))},500);return}if(p.type==="request_routes"){if(!re("read_page")){ie("request_routes","read_page");return}const k=(yt=G.current)==null?void 0:yt.call(G),R=k==null?void 0:k.localParticipant;if(!(R!=null&&R.publishData))return;try{const P=Xt(),$=new TextEncoder().encode(JSON.stringify({type:"routes",routes:P}));R.publishData($,{reliable:!0})}catch(P){console.warn("[LiveLayer] request_routes: extractRoutes threw.",P)}return}Zn.has(p.type)||ge==null||ge(p)}},[ge,me]),z=Mt({agentId:D?"__controlled__":Ce,baseUrl:o,apiKey:i,sessionEndpoint:s,sessionBody:l,onDataMessage:D?void 0:Je});r.useEffect(()=>{if(D!=null&&D.subscribeToDataMessages)return D.subscribeToDataMessages(Je)},[D,Je]),G.current=()=>{var v;return(v=z.getRoom)==null?void 0:v.call(z)};const b=r.useMemo(()=>D?{connectionState:D.connectionState,agentState:D.agentState,transcript:D.transcript,videoElement:D.videoElement,audioElement:D.audioElement,canResume:D.canResume,error:D.error,agentConfig:null,connect:async()=>{await D.onConnect()},disconnect:()=>D.onDisconnect(),getRoom:z.getRoom,isControlled:!0}:{connectionState:z.connectionState,agentState:z.agentState,transcript:z.transcript,videoElement:z.videoElement,audioElement:z.audioElement,canResume:z.canResume,error:z.error,agentConfig:z.agentConfig,connect:z.connect,disconnect:z.disconnect,getRoom:z.getRoom,isControlled:!1},[D,z]),ot=r.useRef(null);r.useEffect(()=>{const v=b.videoElement,p=ot.current;if(!(!v||!p))return p.appendChild(v),()=>{v.parentNode===p&&p.removeChild(v)}},[b.videoElement]),r.useEffect(()=>{const v=b.audioElement;if(!v)return;te.attach(v);const p=v.play();return p&&typeof p.catch=="function"&&p.catch(X=>{(X==null?void 0:X.name)==="NotAllowedError"&&xe(!0)}),()=>{te.detach()}},[b.audioElement]),r.useEffect(()=>{if(b.isControlled||b.connectionState!=="connected")return;const v=b.getRoom();if(v)return q.setupMic(v).catch(()=>{}),U.attachRoom(v),ne.attachRoom(v),Se.refresh(),()=>{q.teardownMic(),U.teardown(),ne.teardown()}},[b.isControlled,b.connectionState]),r.useEffect(()=>{const v=b.audioElement;v&&(v.muted=Ve)},[b.audioElement,Ve]);const en=r.useCallback(v=>{const p=b.getRoom();if(p)try{const X=new TextEncoder().encode(JSON.stringify({type:"user_message",text:v}));p.localParticipant.publishData(X,{reliable:!0})}catch{}},[b]),tn=r.useCallback(()=>{Zt(v=>!v)},[]);r.useEffect(()=>{he==null||he(b.connectionState),b.connectionState==="connected"?le==null||le():b.connectionState==="disconnected"&&(de==null||de())},[b.connectionState,le,de,he]),r.useEffect(()=>{fe==null||fe(b.transcript)},[b.transcript,fe]),r.useEffect(()=>{pe==null||pe(b.agentState)},[b.agentState,pe]);const st=r.useRef(!1);r.useEffect(()=>{b.isControlled||!u||st.current||ke&&b.connectionState==="idle"&&(st.current=!0,b.connect())},[u,b.connectionState,b,ke]);const nn=r.useCallback(v=>{const p=C==null?void 0:C.find(X=>X.id===v);p&&(H(!1),v!==Y&&(Ee(!0),b.disconnect(),Z||ye(v),T==null||T(p)))},[C,Y,b,Z,T]);r.useEffect(()=>{je&&b.connectionState==="connected"&&Ee(!1)},[b.connectionState,je]),r.useEffect(()=>{if(!m)return;const v=p=>{p.key==="Escape"&&H(!1)};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[m]);const rn=!!L||!!(F!=null&&F.avatarImageUrl)||b.isControlled,Qe=zt(Ce,o,rn),Ze=(F==null?void 0:F.name)??A??((ct=b.agentConfig)==null?void 0:ct.name)??((ut=Qe.info)==null?void 0:ut.name)??"Live Layer",lt=(F==null?void 0:F.avatarImageUrl)??L??((dt=b.agentConfig)==null?void 0:dt.avatarImageUrl)??((ft=Qe.info)==null?void 0:ft.avatarImageUrl)??null,on=N??((pt=b.agentConfig)==null?void 0:pt.idleLoopUrl)??((ht=Qe.info)==null?void 0:ht.idleLoopUrl)??null,sn=M??null,ln=r.useCallback(()=>B("expanded"),[B]),an=r.useCallback(()=>B("minimized"),[B]),at=r.useCallback(()=>{b.disconnect(),B("hidden")},[b,B]),cn=r.useCallback(()=>{const v=b.audioElement;v&&v.play().then(()=>xe(!1)).catch(()=>{})},[b.audioElement]),un=r.useCallback(()=>{xe(!1),b.connect()},[b]),Le={...Pe,zIndex:De};g.primaryColor&&(Le["--ll-color-primary"]=g.primaryColor),g.accentColor&&(Le["--ll-color-accent"]=g.accentColor),g.backgroundColor&&(Le["--ll-color-bg"]=g.backgroundColor),g.textColor&&(Le["--ll-color-fg"]=g.textColor);const dn=["ll-widget",`ll-widget--${ee}`,`ll-widget--${Q?"mobile":"desktop"}`,Be].filter(Boolean).join(" ");return ke?t.jsxs("div",{className:dn,style:Le,"data-display-mode":ee,"data-position":h,children:[ee==="hidden"&&t.jsx(An,{position:h,isMobile:Q,isSpeaking:b.agentState==="speaking",onExpand:()=>B("expanded"),label:`Open ${Ze} widget`}),ee==="minimized"&&t.jsx(Tn,{position:h,isMobile:Q,agentName:Ze,avatarImageUrl:lt,agentState:b.agentState,isMuted:q.isMuted,audioLevel:te,onExpand:ln,onToggleMute:q.toggleMute,onClose:at}),ee==="expanded"&&t.jsx(Pn,{position:h,isMobile:Q,agentName:Ze,avatarImageUrl:lt,idleLoopUrl:on,greeting:sn,branding:g,teamMembers:C,currentTeamMemberId:Y,isSwitchingTeamMember:je,teamSwitcherOpen:m,onToggleTeamSwitcher:()=>H(v=>!v),onSelectTeamMember:nn,connectionState:b.connectionState,agentState:b.agentState,transcript:b.transcript,isMuted:q.isMuted,micDevices:Se.mics,isCameraEnabled:U.isEnabled,cameraPreviewEl:U.previewEl,cameraDevices:Se.cameras,activeCameraId:U.activeDeviceId,isScreenShareEnabled:ne.isEnabled,screenPreviewEl:ne.previewEl,isSpeakerMuted:Ve,allowCamera:x,allowScreenShare:S,allowTyping:w,languageMenuOpen:We,onToggleLanguageMenu:()=>Qt(v=>!v),needsUserGesture:Ue,canResume:b.canResume,micError:q.micError,error:b.error,avatarVideoContainerRef:ot,onConnect:()=>void b.connect(),onDisconnect:()=>b.disconnect(),onRetry:un,onResumeAudio:cn,onToggleMute:q.toggleMute,onToggleCamera:()=>void U.toggle(),onSwitchCameraDevice:v=>void U.switchDevice(v),onToggleScreenShare:()=>void ne.toggle(),onToggleSpeaker:tn,onSendMessage:en,onMinimize:an,onClose:at,onClearMicError:q.clearError})]}):null}function tr(e){return t.jsx(At,{children:t.jsx(er,{...e})})}const nr=({agentId:e,baseUrl:n,apiKey:i,mode:o,onAgentEvent:s,className:l,style:u})=>{const d=r.useRef(null),f=r.useRef(null),y=r.useRef(s);y.current=s;const h=r.useCallback(a=>{var j;const c=a.detail;(j=y.current)==null||j.call(y,c)},[]);return r.useEffect(()=>{const a=d.current;if(!a)return;const c=document.createElement("livelayer-widget");return c.setAttribute("agent-id",e),n&&c.setAttribute("base-url",n),i&&c.setAttribute("api-key",i),o&&c.setAttribute("mode",o),c.addEventListener("agent-event",h),a.appendChild(c),f.current=c,()=>{c.removeEventListener("agent-event",h),a.removeChild(c),f.current=null}},[e]),r.useEffect(()=>{f.current&&(o?f.current.setAttribute("mode",o):f.current.removeAttribute("mode"))},[o]),t.jsx("div",{ref:d,className:l,style:u})},rr=r.forwardRef(function({id:n,intent:i,as:o="div",className:s,style:l,children:u},d){return r.createElement(o,{ref:d,"data-ll-region":n,"data-ll-intent":i,className:s,style:l},u)}),ir=r.forwardRef(function({id:n,intent:i,children:o,...s},l){return t.jsx("form",{ref:l,"data-ll-form":n,"data-ll-intent":i,...s,children:o})}),or=r.forwardRef(function(n,i){const{name:o,label:s,labelClassName:l}=n,u={name:o,"data-ll-field":o};let d;if("as"in n&&n.as==="textarea"){const{name:f,label:y,labelClassName:h,as:a,...c}=n;d=t.jsx("textarea",{ref:i,...u,...c})}else if("as"in n&&n.as==="select"){const{name:f,label:y,labelClassName:h,as:a,children:c,...j}=n;d=t.jsx("select",{ref:i,...u,...j,children:c})}else{const{name:f,label:y,labelClassName:h,as:a,...c}=n;d=t.jsx("input",{ref:i,...u,...c})}return s===void 0?d:t.jsxs("label",{className:l,children:[s,d]})});function sr(){const[e,n]=r.useState([]),i=r.useCallback(s=>{n(l=>{const u=l.findIndex(d=>d.id===s.id);if(u>=0){const d=l.slice();return d[u]=s,d}return[...l,s]})},[]),o=r.useCallback(()=>n([]),[]);return{entries:e,pushSegment:i,clear:o,latest:e.length>0?e[e.length-1]:null}}exports.AvatarWidget=tr;exports.ErrorBoundary=At;exports.LiveLayerField=or;exports.LiveLayerForm=ir;exports.LiveLayerRegion=rr;exports.LiveLayerWidget=nr;exports.clearPageContextCache=Yt;exports.clearRoutesCache=Jt;exports.extractPageContext=Kt;exports.extractRoutes=Gt;exports.getCachedPageContext=et;exports.getCachedRoutes=Xt;exports.matchesPattern=Bt;exports.shouldRenderAtPath=Ut;exports.useAgentInfo=zt;exports.useAudioLevel=Tt;exports.useCameraState=Pt;exports.useDisplayMode=Ht;exports.useDisplayModePersistence=Ot;exports.useIsMobile=Ft;exports.useLiveKitSession=Mt;exports.useMediaDevices=$t;exports.useMicrophoneState=It;exports.usePathname=qt;exports.useRouteMatch=Wt;exports.useScreenShareState=Dt;exports.useTranscript=sr;
|