@convai/web-sdk 1.8.0-beta.7 → 1.8.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 +44 -194
- package/dist/core/ConvaiClient.d.ts +1 -190
- package/dist/core/ConvaiClient.d.ts.map +1 -1
- package/dist/core/ConvaiClient.js +286 -1306
- package/dist/core/ConvaiClient.js.map +1 -1
- package/dist/core/MessageHandler.d.ts +1 -19
- package/dist/core/MessageHandler.d.ts.map +1 -1
- package/dist/core/MessageHandler.js +27 -378
- package/dist/core/MessageHandler.js.map +1 -1
- package/dist/core/connectRequest.d.ts +4 -17
- package/dist/core/connectRequest.d.ts.map +1 -1
- package/dist/core/connectRequest.js +17 -28
- package/dist/core/connectRequest.js.map +1 -1
- package/dist/core/index.d.ts +1 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/logicalTurn.d.ts +6 -4
- package/dist/core/logicalTurn.d.ts.map +1 -1
- package/dist/core/logicalTurn.js +4 -29
- package/dist/core/logicalTurn.js.map +1 -1
- package/dist/core/modelOutput.d.ts.map +1 -1
- package/dist/core/modelOutput.js +2 -2
- package/dist/core/modelOutput.js.map +1 -1
- package/dist/core/types.d.ts +22 -860
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/embed/chat-embed-v1.js +9 -10
- package/dist/embed/chat-embed-v1.js.map +4 -4
- package/dist/react/components/ConvaiWidget.d.ts.map +1 -1
- package/dist/react/components/ConvaiWidget.js +1 -6
- package/dist/react/components/ConvaiWidget.js.map +1 -1
- package/dist/react/components/rtc-widget/components/AudioVisualizer.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/AudioVisualizer.js +1 -28
- package/dist/react/components/rtc-widget/components/AudioVisualizer.js.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js +44 -39
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js.map +1 -1
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js +49 -93
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js.map +1 -1
- package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
- package/dist/react/hooks/useConvaiClient.js +2 -17
- package/dist/react/hooks/useConvaiClient.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/vanilla/AudioRenderer.d.ts +1 -3
- package/dist/vanilla/AudioRenderer.d.ts.map +1 -1
- package/dist/vanilla/AudioRenderer.js +2 -8
- package/dist/vanilla/AudioRenderer.js.map +1 -1
- package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
- package/dist/vanilla/ConvaiWidget.js +300 -994
- package/dist/vanilla/ConvaiWidget.js.map +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.d.ts +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.d.ts.map +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.js +0 -5
- package/dist/vanilla/WidgetEventSubscriptions.js.map +1 -1
- package/dist/vanilla/icons.d.ts.map +1 -1
- package/dist/vanilla/icons.js +15 -62
- package/dist/vanilla/icons.js.map +1 -1
- package/dist/vanilla/index.d.ts +2 -4
- package/dist/vanilla/index.d.ts.map +1 -1
- package/dist/vanilla/index.js +1 -3
- package/dist/vanilla/index.js.map +1 -1
- package/dist/vanilla/styles.d.ts +1 -18
- package/dist/vanilla/styles.d.ts.map +1 -1
- package/dist/vanilla/styles.js +29 -129
- package/dist/vanilla/styles.js.map +1 -1
- package/dist/vanilla/types.d.ts +0 -74
- package/dist/vanilla/types.d.ts.map +1 -1
- package/dist/vanilla/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +8 -13
- package/dist/core/CharacterRoster.d.ts +0 -84
- package/dist/core/CharacterRoster.d.ts.map +0 -1
- package/dist/core/CharacterRoster.js +0 -348
- package/dist/core/CharacterRoster.js.map +0 -1
- package/dist/core/CharacterVersionManager.d.ts +0 -100
- package/dist/core/CharacterVersionManager.d.ts.map +0 -1
- package/dist/core/CharacterVersionManager.js +0 -227
- package/dist/core/CharacterVersionManager.js.map +0 -1
- package/dist/core/ConvaiRoomError.d.ts +0 -48
- package/dist/core/ConvaiRoomError.d.ts.map +0 -1
- package/dist/core/ConvaiRoomError.js +0 -111
- package/dist/core/ConvaiRoomError.js.map +0 -1
- package/dist/core/SSESession.d.ts +0 -59
- package/dist/core/SSESession.d.ts.map +0 -1
- package/dist/core/SSESession.js +0 -289
- package/dist/core/SSESession.js.map +0 -1
- package/dist/core/characterReference.d.ts +0 -40
- package/dist/core/characterReference.d.ts.map +0 -1
- package/dist/core/characterReference.js +0 -72
- package/dist/core/characterReference.js.map +0 -1
- package/dist/core/rosterRequest.d.ts +0 -57
- package/dist/core/rosterRequest.d.ts.map +0 -1
- package/dist/core/rosterRequest.js +0 -210
- package/dist/core/rosterRequest.js.map +0 -1
- package/dist/utils/inlineMarkdown.d.ts +0 -38
- package/dist/utils/inlineMarkdown.d.ts.map +0 -1
- package/dist/utils/inlineMarkdown.js +0 -106
- package/dist/utils/inlineMarkdown.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvaiWidget.d.ts","sourceRoot":"","sources":["../../../src/react/components/ConvaiWidget.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAwC1E,UAAU,iBAAiB;IACzB,wCAAwC;IACxC,YAAY,EAAE,aAAa,GAAG;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,gEAAgE;IAChE,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,2EAA2E;IAC3E,uBAAuB,CAAC,EAAE,IAAI,CAC5B,uBAAuB,EACvB,cAAc,GAAG,WAAW,CAC7B,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ConvaiWidget.d.ts","sourceRoot":"","sources":["../../../src/react/components/ConvaiWidget.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,aAAa,EACb,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAI1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAwC1E,UAAU,iBAAiB;IACzB,wCAAwC;IACxC,YAAY,EAAE,aAAa,GAAG;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,gEAAgE;IAChE,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,2EAA2E;IAC3E,uBAAuB,CAAC,EAAE,IAAI,CAC5B,uBAAuB,EACvB,cAAc,GAAG,WAAW,CAC7B,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAs6BpD,CAAC"}
|
|
@@ -76,12 +76,7 @@ export const ConvaiWidget = ({ convaiClient, showVideo = true, showScreenShare =
|
|
|
76
76
|
const isStartingConnectionRef = useRef(false);
|
|
77
77
|
/** Avoid opening a room after this widget has been removed from the tree. */
|
|
78
78
|
const isUnmountedRef = useRef(false);
|
|
79
|
-
|
|
80
|
-
// authenticated text session still uses the text-only layout, but can send
|
|
81
|
-
// as soon as it connects.
|
|
82
|
-
const requiresBotReadyForText = Boolean(requestPublicationGrant) || convaiClient.isPublishedChatSession;
|
|
83
|
-
const canSendText = convaiClient.state.isConnected &&
|
|
84
|
-
(!requiresBotReadyForText || convaiClient.isBotReady);
|
|
79
|
+
const canSendText = convaiClient.state.isConnected && convaiClient.isBotReady;
|
|
85
80
|
// Character info from API (using client's stored values)
|
|
86
81
|
const selectedCharacter = {
|
|
87
82
|
id: convaiClient.characterId || "unknown",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvaiWidget.js","sourceRoot":"","sources":["../../../src/react/components/ConvaiWidget.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAe,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,cAAc,EAAS,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAK5C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAExE,qDAAqD;AACrD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,IAAI,EACJ,WAAW,EACX,MAAM,EACN,KAAK,EACL,WAAW,EACX,cAAc,EACd,OAAO,EACP,MAAM,EACN,cAAc,EACd,KAAK,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,4BAA4B;AAC5B,OAAO,EACL,WAAW,EACX,YAAY,EACZ,gBAAgB,EAEhB,aAAa,GACd,MAAM,cAAc,CAAC;AA6CtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,MAAM,YAAY,GAAgC,CAAC,EACxD,YAAY,EACZ,SAAS,GAAG,IAAI,EAChB,eAAe,GAAG,IAAI,EACtB,gBAAgB,GAAG,IAAI,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,GACxB,EAAE,EAAE;IACH,MAAM,UAAU,GACd,OAAO,CAAC,uBAAuB,CAAC,IAAI,YAAY,CAAC,cAAc,KAAK,MAAM,CAAC;IAC7E,sEAAsE;IACtE,MAAM,EACJ,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,qBAAqB,EAC5B,SAAS,EAAE,yBAAyB,GACrC,GAAG,gBAAgB,CAClB,YAAY,CAAC,WAAW,IAAI,SAAS,EACrC,YAAY,CAAC,MAAM,IAAI,SAAS,EAChC,YAAY,CAAC,SAAS,IAAI,SAAS,CACpC,CAAC;IACF,MAAM,aAAa,GACjB,uBAAuB,EAAE,YAAY,IAAI,oBAAoB,CAAC;IAChE,MAAM,cAAc,GAClB,uBAAuB,EAAE,SAAS,IAAI,qBAAqB,CAAC;IAC9D,MAAM,kBAAkB,GAAG,uBAAuB;QAChD,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,yBAAyB,CAAC;IAE9B,WAAW;IACX,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAC5C,gBAAgB,IAAI,CAAC,UAAU,CAChC,CAAC;IACF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,iCAAiC;IAChF,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,CAAC,0BAA0B,EAAE,6BAA6B,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpF,MAAM,iBAAiB,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAC1D,8HAA8H;IAC9H,MAAM,qBAAqB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,sFAAsF;IACtF,MAAM,uBAAuB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9C,6EAA6E;IAC7E,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAErC,wEAAwE;IACxE,2EAA2E;IAC3E,0BAA0B;IAC1B,MAAM,uBAAuB,GAC3B,OAAO,CAAC,uBAAuB,CAAC,IAAI,YAAY,CAAC,sBAAsB,CAAC;IAC1E,MAAM,WAAW,GACf,YAAY,CAAC,KAAK,CAAC,WAAW;QAC9B,CAAC,CAAC,uBAAuB,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;IAExD,yDAAyD;IACzD,MAAM,iBAAiB,GAAG;QACxB,EAAE,EAAE,YAAY,CAAC,WAAW,IAAI,SAAS;QACzC,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,cAAc;KACtB,CAAC;IAEF,kDAAkD;IAClD,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC7B,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACpC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM;QAC5D,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;YAChE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,gBAAgB;QACpE,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,uBAAuB;QAC1E,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ;IAC3D,CAAC,CAAC;IAEF,8BAA8B;IAC9B,MAAM,cAAc,GAAG,GAAqB,EAAE;QAC5C,wEAAwE;QACxE,MAAM,gBAAgB,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,CACvD,CAAC,GAAG,EAAE,EAAE,CACN,CAAC,GAAG,CAAC,IAAI,KAAK,oBAAoB;YAChC,GAAG,CAAC,IAAI,KAAK,eAAe;YAC5B,GAAG,CAAC,IAAI,KAAK,cAAc;YAC3B,GAAG,CAAC,IAAI,KAAK,YAAY;YACzB,GAAG,CAAC,IAAI,KAAK,aAAa,CAAC;YAC7B,GAAG,CAAC,OAAO,IAAI,wBAAwB;YACvC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAChC,CAAC;QAEF,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,OAAO;YACjB,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACjC,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,kBAAkB,CAAC,EAAE,EAAE;gBACxD,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,SAAS;aAClB,CAAC;YACF,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI;YAClE,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC,CAAC;IACN,CAAC,CAAC;IAEF,iBAAiB;IACjB,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;QAC9B,IAAI,uBAAuB,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,6DAA6D;QAC7D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACxE,uBAAuB,CAAC,OAAO,GAAG,IAAI,CAAC;YACvC,IAAI,CAAC;gBACH,IAAI,uBAAuB,IAAI,YAAY,CAAC,sBAAsB,EAAE,CAAC;oBACnE,IAAI,CAAC,uBAAuB,EAAE,CAAC;wBAC7B,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;oBACJ,CAAC;oBACD,IAAI,CAAC,YAAY,CAAC,2BAA2B,EAAE,CAAC;wBAC9C,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;oBACJ,CAAC;oBACD,MAAM,WAAW,GAAG,MAAM,uBAAuB,EAAE,CAAC;oBACpD,IAAI,cAAc,CAAC,OAAO;wBAAE,OAAO;oBACnC,MAAM,YAAY,CAAC,2BAA2B,CAC5C,WAAW,EACX,4BAA4B,CAAC,2BAA2B,CAAC,CAC1D,CAAC;gBACJ,CAAC;qBAAM,IACL,qBAAqB,CAAC,OAAO;oBAC7B,OAAO,YAAY,CAAC,SAAS,KAAK,UAAU,EAC5C,CAAC;oBACD,MAAM,YAAY,CAAC,SAAS,EAAE,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACN,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC/B,CAAC;gBACD,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;oBAC3B,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;oBAChC,OAAO;gBACT,CAAC;gBACD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,0CAA0C;YAC7D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC;oBAAS,CAAC;gBACT,uBAAuB,CAAC,OAAO,GAAG,KAAK,CAAC;YAC1C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,8CAA8C;YAC9C,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,CAAsC,EAAE,EAAE;QACnE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC;YACrC,YAAY,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;YAC7C,aAAa,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,CAAsB,EAAE,EAAE;QAChD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IAGF,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC;QAE/B,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;YAC7C,uDAAuD;YACvD,MAAM,kBAAkB,GAAG,KAAK,CAAC,IAAI,CACnC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAC9C,CAAC;YACF,kBAAkB,CAAC,OAAO,CAAC,CAAC,WAAgB,EAAE,EAAE;gBAC9C,WAAW,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,WAAgB,EAAE,EAAE;oBAC9D,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;wBACtB,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,6EAA6E;YAC7E,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAmB,uBAAuB,CAAC,CAAC;YACxF,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,UAAU,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;QAC7B,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEzB,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;YAEhC,4DAA4D;YAC5D,YAAY,CAAC,YAAY,EAAE,CAAC;YAE5B,8BAA8B;YAC9B,UAAU,CAAC,KAAK,CAAC,CAAC;YAClB,cAAc,CAAC,KAAK,CAAC,CAAC;YAEtB,yDAAyD;YACzD,qDAAqD;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAEhC,8BAA8B;QAC9B,UAAU,CAAC,KAAK,CAAC,CAAC;QAClB,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;QACnC,0CAA0C;QAC1C,IAAI,YAAY,CAAC,cAAc,KAAK,OAAO,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YACxE,OAAO;QACT,CAAC;QAED,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,YAAY,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QACjD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,uBAAuB,GAAG,KAAK,IAAI,EAAE;QACzC,MAAM,YAAY,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,CAAC;IAC7D,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAChC,iBAAiB,CAAC,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,mGAAmG;IACnG,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACnC,qBAAqB,CAAC,OAAO,GAAG,IAAI,CAAC;QACvC,CAAC;IACH,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAErC,kCAAkC;IAClC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACxE,IAAI,MAAM,EAAE,CAAC;gBACX,SAAS,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;YACD,gCAAgC;YAChC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB;YAC1C,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;YAC1C,6BAA6B,CAAC,KAAK,CAAC,CAAC,CAAC,6DAA6D;QACrG,CAAC;IACH,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAE9E,kDAAkD;IAClD,SAAS,CAAC,GAAG,EAAE;QACb,iBAAiB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC;IAElC,oDAAoD;IACpD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;YAC9B,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAE9B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;YAChC,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;gBAC/C,oCAAoC;gBACpC,MAAM,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC;QACF,cAAc,EAAE,CAAC;IACnB,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhC,0DAA0D;IAC1D,SAAS,CAAC,GAAG,EAAE;QACb,IACE,MAAM;YACN,gBAAgB;YAChB,CAAC,UAAU;YACX,YAAY,CAAC,KAAK,CAAC,WAAW;YAC9B,CAAC,0BAA0B;YAC3B,CAAC,WAAW,EACZ,CAAC;YACD,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;gBAChC,IAAI,CAAC;oBACH,MAAM,YAAY,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;oBAC/C,cAAc,CAAC,IAAI,CAAC,CAAC;oBACrB,6BAA6B,CAAC,IAAI,CAAC,CAAC;gBACtC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC,CAAC;YACF,cAAc,EAAE,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,WAAW,EAAE,0BAA0B,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAElI,uCAAuC;IACvC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,kBAAkB,GAAG,CAAC,KAAiB,EAAE,EAAE;YAC/C,IAAI,cAAc,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;gBAChD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAc,CAAC;gBACpC,MAAM,cAAc,GAAG,iBAAiB,CAAC,OAAO,CAAC;gBACjD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrC,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;oBACpE,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;wBACnD,iBAAiB,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QAChE,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,iCAAiC;IACjC,MAAM,YAAY,GAAG,GAAwC,EAAE;QAC7D,IAAI,YAAY,CAAC,KAAK,CAAC,YAAY;YAAE,OAAO,YAAY,CAAC;QACzD,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW;YAAE,OAAO,WAAW,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,YAAY,CAAC,KAAK,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,uBAAuB;QACjG,IAAI,YAAY,CAAC,KAAK,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gCAAgC;QAC3G,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB;IACxD,CAAC,CAAC;IAEF,gFAAgF;IAChF,MAAM,gBAAgB,GAAG,MAAM,CAAuB,IAAI,CAAC,CAAC;IAE5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO;QAE1E,gBAAgB,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAEhE,OAAO,GAAG,EAAE;YACV,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC7B,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC;YAClC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAExD,OAAO,CACL,MAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,aAGnG,MAAC,eAAe,IACd,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EACnC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EACjC,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,aAE9C,MAAC,iBAAiB,IAChB,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAC3C,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,EACjD,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,EAC/C,OAAO,EAAE;4BACP,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;4BAChC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;4BACjC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;yBACzD,EACD,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,EAChD,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,aAGlD,KAAC,aAAa,IACZ,OAAO,EAAE;oCACP,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oCACvB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;iCACxB,EACD,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,YAE7B,KAAC,IAAI,cACH,KAAC,UAAU,IACT,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,YAAY,EACxC,KAAK,EAAE,YAAY,EAAE,GACrB,GACG,GACO,EAGf,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CACjC,MAAC,WAAW,IACV,OAAO,EAAE;oCACP,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oCACvB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;iCACxB,EACD,UAAU,EAAE;oCACV,QAAQ,EAAE,GAAG;oCACb,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;iCACxB,EACD,KAAK,EAAE;oCACL,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;iCACxC,aAGD,MAAC,MAAM,IACL,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAC/B,OAAO,EAAE;4CACP,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4CACvB,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;yCACpB,EACD,UAAU,EAAE;4CACV,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;4CACvB,GAAG,cAAc,CAAC,UAAU;yCAC7B,EACD,KAAK,EAAE;4CACL,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;4CACvC,SAAS,EAAE,QAAQ,EAAE,2BAA2B;yCACjD,aAED,KAAC,WAAW,IACV,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAC1B,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,UAAU,EAAE,cAAc,CAAC,MAAM,EACjC,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,YAEnD,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,GAAG,GACb,EAEd,MAAC,KAAK,eACH,iBAAiB,CAAC,KAAK,IAAI,CAAC,WAAW,IAAI,CAC1C,KAAC,MAAM,CAAC,GAAG,IAET,GAAG,EAAE,iBAAiB,CAAC,KAAK,EAC5B,GAAG,EAAE,iBAAiB,CAAC,IAAI,EAC3B,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EACnC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EACjC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EAChC,UAAU,EAAE,cAAc,CAAC,OAAO,EAClC,KAAK,EAAE;4DACL,KAAK,EAAE,QAAQ;4DACf,MAAM,EAAE,QAAQ;4DAChB,YAAY,EAAE,KAAK;4DACnB,SAAS,EAAE,OAAO;4DAClB,WAAW,EAAE,QAAQ;4DACrB,MAAM,EAAE,eAAe,iBAAiB,EAAE,CAAC,KAAK,EAAE;4DAClD,SAAS,EAAE,WAAW,iBAAiB,EAAE,CAAC,KAAK,IAAI;4DACnD,UAAU,EAAE,eAAe;yDAC5B,IAhBG,eAAe,CAAC,wDAAwD;qDAiB5E,CACH,EACA,iBAAiB,CAAC,IAAI,EACvB,KAAC,MAAM,CAAC,MAAM,IACZ,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAC1B,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,UAAU,EAAE,cAAc,CAAC,MAAM,EACjC,KAAK,EAAE;4DACL,MAAM,EAAE,SAAS;4DACjB,aAAa,EAAE,MAAM;4DACrB,UAAU,EAAE,aAAa;4DACzB,MAAM,EAAE,MAAM;4DACd,SAAS,EAAE,MAAM;4DACjB,KAAK,EAAE,MAAM;4DACb,MAAM,EAAE,MAAM;4DACd,OAAO,EAAE,GAAG;4DACZ,OAAO,EAAE,aAAa;4DACtB,UAAU,EAAE,QAAQ;4DACpB,UAAU,EAAE,QAAQ;4DACpB,OAAO,EAAE,MAAM;yDAChB,gBACW,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EACvC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,YAEjC,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,YAAY,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC,WAAW,GAAG,CAC7C,CAAC,CAAC,CAAC,CACF,KAAC,YAAY,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC,SAAS,GAAG,CAC3C,GACa,EACf,WAAW,IAAI,CACd,eACE,KAAK,EAAE;4DACL,QAAQ,EAAE,MAAM;4DAChB,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK;4DACpC,UAAU,EAAE,GAAG;4DACf,UAAU,EAAE,KAAK;4DACjB,OAAO,EAAE,SAAS;4DAClB,YAAY,EAAE,KAAK;4DACnB,eAAe,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI;yDACtD,sBAGI,CACR,EACA,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,CAChC,MAAC,MAAM,CAAC,IAAI,IACV,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EACnC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EACjC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EAChC,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAC7B,KAAK,EAAE;4DACL,QAAQ,EAAE,MAAM;4DAChB,KAAK,EAAE,SAAS;4DAChB,UAAU,EAAE,GAAG;4DACf,UAAU,EAAE,KAAK;4DACjB,OAAO,EAAE,SAAS;4DAClB,YAAY,EAAE,KAAK;4DACnB,eAAe,EAAE,WAAW;4DAC5B,MAAM,EAAE,qBAAqB;4DAC7B,OAAO,EAAE,aAAa;4DACtB,UAAU,EAAE,QAAQ;4DACpB,GAAG,EAAE,KAAK;yDACX,aAED,KAAC,MAAM,CAAC,IAAI,IACV,OAAO,EAAE;oEACP,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;oEAClB,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;iEACrB,EACD,UAAU,EAAE;oEACV,QAAQ,EAAE,GAAG;oEACb,MAAM,EAAE,QAAQ;oEAChB,IAAI,EAAE,WAAW;iEAClB,EACD,KAAK,EAAE;oEACL,KAAK,EAAE,KAAK;oEACZ,MAAM,EAAE,KAAK;oEACb,YAAY,EAAE,KAAK;oEACnB,eAAe,EAAE,SAAS;oEAC1B,OAAO,EAAE,cAAc;iEACxB,GACD,gBAEU,CACf,EACA,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,CACnE,MAAC,MAAM,CAAC,IAAI,IACV,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EACnC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EACjC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EAChC,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAC7B,KAAK,EAAE;4DACL,QAAQ,EAAE,MAAM;4DAChB,KAAK,EAAE,SAAS;4DAChB,UAAU,EAAE,GAAG;4DACf,UAAU,EAAE,KAAK;4DACjB,OAAO,EAAE,SAAS;4DAClB,YAAY,EAAE,KAAK;4DACnB,eAAe,EAAE,WAAW;4DAC5B,MAAM,EAAE,qBAAqB;4DAC7B,OAAO,EAAE,aAAa;4DACtB,UAAU,EAAE,QAAQ;4DACpB,GAAG,EAAE,KAAK;yDACX,aAED,KAAC,MAAM,CAAC,IAAI,IACV,OAAO,EAAE;oEACP,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;oEAClB,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;iEACrB,EACD,UAAU,EAAE;oEACV,QAAQ,EAAE,GAAG;oEACb,MAAM,EAAE,QAAQ;oEAChB,IAAI,EAAE,WAAW;iEAClB,EACD,KAAK,EAAE;oEACL,KAAK,EAAE,KAAK;oEACZ,MAAM,EAAE,KAAK;oEACb,YAAY,EAAE,KAAK;oEACnB,eAAe,EAAE,SAAS;oEAC1B,OAAO,EAAE,cAAc;iEACxB,GACD,iBAEU,CACf,IACK,EAER,cACE,KAAK,EAAE;oDACL,OAAO,EAAE,MAAM;oDACf,UAAU,EAAE,QAAQ;oDACpB,GAAG,EAAE,QAAQ;oDACb,QAAQ,EAAE,UAAU;iDACrB,YAED,KAAC,cAAc,IACb,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAC1B,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,UAAU,EAAE,cAAc,CAAC,MAAM,EACjC,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAE5B,KAAC,cAAc,IAAC,IAAI,EAAE,EAAE,GAAI,GACb,GACb,IACC,EAGT,MAAC,OAAO,IACN,KAAK,EAAE;4CACL,UAAU,EAAE,WAAW;gDACrB,CAAC,CAAC,2BAA2B;gDAC7B,CAAC,CAAC,aAAa;4CACjB,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;4CAC7C,QAAQ,EAAE,UAAU;yCACrB,aAGD,KAAC,eAAe,cACb,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,UAAU,IAAI,CAC7D,MAAC,MAAM,CAAC,GAAG,IACT,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EACvB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EACvB,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EACpB,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAC7B,KAAK,EAAE;wDACL,QAAQ,EAAE,UAAU;wDACpB,GAAG,EAAE,CAAC;wDACN,IAAI,EAAE,CAAC;wDACP,KAAK,EAAE,CAAC;wDACR,MAAM,EAAE,CAAC;wDACT,OAAO,EAAE,MAAM;wDACf,aAAa,EAAE,QAAQ;wDACvB,UAAU,EAAE,QAAQ;wDACpB,cAAc,EAAE,QAAQ;wDACxB,eAAe,EAAE,2BAA2B;wDAC5C,MAAM,EAAE,GAAG;wDACX,GAAG,EAAE,MAAM;qDACZ,aAED,KAAC,MAAM,CAAC,GAAG,IACT,OAAO,EAAE;gEACP,MAAM,EAAE,GAAG;6DACZ,EACD,UAAU,EAAE;gEACV,QAAQ,EAAE,CAAC;gEACX,MAAM,EAAE,QAAQ;gEAChB,IAAI,EAAE,QAAQ;6DACf,YAED,KAAC,UAAU,IACT,IAAI,EAAC,IAAI,EACT,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EACpC,KAAK,EAAC,YAAY,GAClB,GACS,EACb,MAAC,MAAM,CAAC,GAAG,IACT,OAAO,EAAE;gEACP,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC;6DACvB,EACD,UAAU,EAAE;gEACV,QAAQ,EAAE,CAAC;gEACX,MAAM,EAAE,QAAQ;gEAChB,IAAI,EAAE,WAAW;6DAClB,EACD,KAAK,EAAE;gEACL,QAAQ,EAAE,MAAM;gEAChB,UAAU,EAAE,GAAG;gEACf,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS;6DACvC,+BAEc,iBAAiB,CAAC,IAAI,WAC1B,IACF,CACd,GACe,EAEjB,WAAW,IAAI,CACd,KAAC,gBAAgB,IACf,QAAQ,EAAE,CAAC,YAAY,CAAC,YAAY,EACpC,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,EACxC,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,WAAW,EAC3C,YAAY,EAAE,IAAI,EAClB,cAAc,EAAE,cAAc,IAAI,SAAS,EAC3C,aAAa,EAAE,aAAa,IAAI,SAAS,EACzC,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GACzE,CACH,EACA,CAAC,WAAW,IAAI,CACf,KAAC,WAAW,IACV,QAAQ,EAAE,cAAc,EAAE,EAC1B,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,EAC1C,kBAAkB,EAAE,GAAG,MAAM,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,GACnE,CACH,IACO,EAGV,KAAC,MAAM,IACL,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAC9B,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE;4CACV,KAAK,EAAE,GAAG;4CACV,GAAG,cAAc,CAAC,UAAU;yCAC7B,EACD,KAAK,EAAE;4CACL,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;4CAC7C,UAAU,EAAE,kBAAkB;4CAC9B,OAAO,EAAE,MAAM;4CACf,GAAG,EAAE,QAAQ;4CACb,UAAU,EAAE,QAAQ;4CACpB,QAAQ,EAAE,UAAU;4CACpB,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY;4CACrD,SAAS,EAAE,QAAQ,EAAE,2BAA2B;yCACjD,YAGA,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,MAAM,CAAC,MAAM,IAEZ,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EACnC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EACjC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,EAChC,UAAU,EAAE;gDACV,QAAQ,EAAE,GAAG;gDACb,IAAI,EAAE,SAAS;6CAChB,EACD,OAAO,EAAE,KAAK,IAAI,EAAE;gDAClB,YAAY,CAAC,oBAAoB,EAAE,CAAC;gDACpC,MAAM,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;gDAC7C,yDAAyD;gDACzD,gEAAgE;gDAChE,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;oDAC7C,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gDAChC,CAAC;gDACD,cAAc,CAAC,KAAK,CAAC,CAAC;4CACxB,CAAC,EACD,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAC1B,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,KAAK,EAAE;gDACL,MAAM,EAAE,SAAS;gDACjB,eAAe,EAAE,SAAS;gDAC1B,KAAK,EAAE,SAAS;gDAChB,MAAM,EAAE,MAAM;gDACd,YAAY,EAAE,KAAK;gDACnB,KAAK,EAAE,SAAS;gDAChB,MAAM,EAAE,SAAS;gDACjB,QAAQ,EAAE,SAAS;gDACnB,SAAS,EAAE,SAAS;gDACpB,OAAO,EAAE,MAAM;gDACf,UAAU,EAAE,QAAQ;gDACpB,cAAc,EAAE,QAAQ;gDACxB,UAAU,EAAE,CAAC;gDACb,OAAO,EAAE,CAAC;gDACV,OAAO,EAAE,MAAM;6CAChB,gBACU,iBAAiB,EAC5B,KAAK,EAAC,iBAAiB,YAEvB,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,IAxCpB,iBAAiB,CAyCP,CACjB,CAAC,CAAC,CAAC,CACF,4BAEE,MAAC,cAAc,IAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,aAEtD,KAAC,KAAK,IACJ,IAAI,EAAC,MAAM,EACX,WAAW,EAAC,cAAc,EAC1B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,CAAC,WAAW,EACtB,KAAK,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,GAClC,EAGF,cACE,KAAK,EAAE;4DACL,QAAQ,EAAE,UAAU;4DACpB,KAAK,EAAE,UAAU;4DACjB,GAAG,EAAE,KAAK;4DACV,SAAS,EAAE,kBAAkB;4DAC7B,KAAK,EAAE,SAAS;4DAChB,MAAM,EAAE,SAAS;4DACjB,QAAQ,EAAE,SAAS;4DACnB,SAAS,EAAE,SAAS;4DACpB,UAAU,EAAE,CAAC;4DACb,QAAQ,EAAE,SAAS;4DACnB,OAAO,EAAE,MAAM;4DACf,UAAU,EAAE,QAAQ;4DACpB,cAAc,EAAE,QAAQ;4DACxB,MAAM,EAAE,CAAC;yDACV,YAED,KAAC,eAAe,IAAC,IAAI,EAAC,MAAM,YACzB,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CACrC,KAAC,YAAY,IAEX,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EACpB,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EACpB,UAAU,EAAE;oEACV,QAAQ,EAAE,GAAG;oEACb,IAAI,EAAE,QAAQ;iEACf,EACD,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,EACjD,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,KAAK,EAAE;oEACL,QAAQ,EAAE,UAAU;oEACpB,GAAG,EAAE,CAAC;oEACN,IAAI,EAAE,CAAC;oEACP,MAAM,EAAE,SAAS;iEAClB,YAED,KAAC,MAAM,IAAC,IAAI,EAAE,EAAE,GAAI,IAlBhB,MAAM,CAmBG,CAChB,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,CAAC,MAAM,IAEZ,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EACpB,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,EACpB,UAAU,EAAE;oEACV,QAAQ,EAAE,GAAG;oEACb,IAAI,EAAE,QAAQ;iEACf,EACD,OAAO,EAAE,KAAK,IAAI,EAAE;oEAClB,YAAY,CAAC,oBAAoB,EAAE,CAAC;oEACpC,mDAAmD;oEACnD,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;wEAC7C,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oEAC/B,CAAC;oEACD,MAAM,YAAY,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;oEAC/C,cAAc,CAAC,IAAI,CAAC,CAAC;gEACvB,CAAC,EACD,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAC1B,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EACxB,KAAK,EAAE;oEACL,QAAQ,EAAE,UAAU;oEACpB,GAAG,EAAE,CAAC;oEACN,IAAI,EAAE,CAAC;oEACP,MAAM,EAAE,SAAS;oEACjB,eAAe,EAAE,aAAa;oEAC9B,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;oEACpC,MAAM,EAAE,aAAa,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;oEACpD,YAAY,EAAE,KAAK;oEACnB,KAAK,EAAE,SAAS;oEAChB,MAAM,EAAE,SAAS;oEACjB,QAAQ,EAAE,SAAS;oEACnB,SAAS,EAAE,SAAS;oEACpB,OAAO,EAAE,MAAM;oEACf,UAAU,EAAE,QAAQ;oEACpB,cAAc,EAAE,QAAQ;oEACxB,UAAU,EAAE,CAAC;oEACb,OAAO,EAAE,CAAC;oEACV,OAAO,EAAE,MAAM;iEAChB,gBACU,kBAAkB,EAC7B,KAAK,EAAC,gBAAgB,YAEtB,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,GAAI,IA1CpB,OAAO,CA2CG,CACjB,GACe,GACd,IACS,GAChB,CACJ,GACM,IACG,CACf,IACiB,EAGnB,YAAY,CAAC,KAAK,CAAC,WAAW,IAAI,CACjC,KAAC,YAAY,IACX,MAAM,EAAE,cAAc,EACtB,OAAO,EACL,YAAY,CAAC,sBAAsB,IAAI,CAAC,uBAAuB;4BAC7D,CAAC,CAAC,SAAS;4BACX,CAAC,CAAC,WAAW,EAEjB,YAAY,EACV,YAAY,CAAC,sBAAsB,IAAI,CAAC,uBAAuB;4BAC7D,CAAC,CAAC,SAAS;4BACX,CAAC,CAAC,gBAAgB,EAEtB,aAAa,EACX,YAAY,CAAC,cAAc,KAAK,OAAO,IAAI,SAAS;4BAClD,CAAC,CAAC,iBAAiB;4BACnB,CAAC,CAAC,SAAS,EAEf,cAAc,EAAE,cAAc,EAC9B,mBAAmB,EACjB,YAAY,CAAC,cAAc,KAAK,OAAO,IAAI,eAAe;4BACxD,CAAC,CAAC,uBAAuB;4BACzB,CAAC,CAAC,SAAS,EAEf,mBAAmB,EACjB,YAAY,CAAC,mBAAmB,GAElC,CACH,IACe,EAGjB,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,WAAW,IAAI,CAC3C,KAAC,aAAa,IACZ,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,MAAM,YAAY,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;gBAClD,CAAC,EACD,MAAM,EAAE,IAAI,GACZ,CACH,IACoB,CACxB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useCallback, useState, useRef, useEffect } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { FiMoreVertical, FiMic, FiSend, FiPhoneOff } from \"react-icons/fi\";\nimport { IoVolumeMute, IoVolumeHigh } from \"react-icons/io5\";\nimport { PiWaveform } from \"react-icons/pi\";\nimport type {\n IConvaiClient,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\nimport { RoomContext } from \"@livekit/components-react\";\nimport { useCharacterInfo } from \"../hooks/useCharacterInfo\";\nimport { AudioRenderer } from \"../../vanilla/AudioRenderer\";\nimport type { PublishedChatDescriptor } from \"../../embed/publicationApi\";\nimport { freshPublicationGrantOptions } from \"../../core/publishedChat\";\n\n// Import styled components and theme from rtc-widget\nimport {\n ConvaiContainer,\n MorphingContainer,\n ButtonContent,\n Logo,\n ChatContent,\n Header,\n Title,\n CloseButton,\n SettingsButton,\n Content,\n Footer,\n InputContainer,\n Input,\n ActionButton,\n aeroTheme,\n iosTransitions,\n ConvaiLogo,\n ChevronDown,\n} from \"./rtc-widget\";\n\n// Import message components\nimport {\n MessageList,\n SettingsTray,\n VoiceModeOverlay,\n RTCChatMessage,\n FloatingVideo,\n} from \"./rtc-widget\";\n\ninterface Character {\n id: string;\n name?: string;\n image?: string;\n}\n\ninterface ConvaiWidgetProps {\n /** Convai client instance (required) */\n convaiClient: IConvaiClient & { \n activity?: string;\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n };\n /**\n * Show video toggle button in settings (default: true).\n * Only works if connection type is \"video\". If false, hides the video button.\n */\n showVideo?: boolean;\n /**\n * Show screen share toggle button in settings (default: true).\n * Only works if connection type is \"video\". If false, hides the screen share button.\n */\n showScreenShare?: boolean;\n /**\n * Start in voice mode by default when widget opens (default: true).\n * When true, the widget will open directly in voice mode with microphone enabled.\n */\n defaultVoiceMode?: boolean;\n /**\n * Mint a fresh single-use grant when a published-chat session is reopened.\n * Required when using this widget with connectWithPublicationGrant().\n */\n requestPublicationGrant?: () => Promise<string>;\n /** Core endpoint override used with requestPublicationGrant. */\n publishedChatConnectOptions?: PublishedChatConnectOptions;\n /** Public descriptor used to label a credential-free published session. */\n publishedChatDescriptor?: Pick<\n PublishedChatDescriptor,\n \"display_name\" | \"image_url\"\n >;\n}\n\n/**\n * ConvaiWidget - A consolidated chat widget component for real-time conversations\n *\n * This component provides a complete UI for interacting with Convai characters.\n * Connection configuration should be handled via useConvaiClient.connect().\n *\n * Features:\n * - Collapsed circular button with status indicator\n * - Expandable/collapsible chat interface\n * - Voice mode support\n * - Real-time message streaming\n * - Audio controls (mute/unmute)\n * - Settings tray with session reset\n * - Optional video and screen share (when connection type supports it)\n *\n * @param {ConvaiWidgetProps} props - Component props\n * @param {ConvaiClient} props.convaiClient - Convai client instance (required)\n * @param {boolean} props.showVideo - Show video toggle in settings (default: true)\n * @param {boolean} props.showScreenShare - Show screen share toggle in settings (default: true)\n * @param {boolean} props.defaultVoiceMode - Start in voice mode when widget opens (default: true)\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget\n * convaiClient={convaiClient}\n * showVideo={true}\n * showScreenShare={true}\n * />\n * );\n * }\n * ```\n */\nexport const ConvaiWidget: React.FC<ConvaiWidgetProps> = ({\n convaiClient,\n showVideo = true,\n showScreenShare = true,\n defaultVoiceMode = true,\n requestPublicationGrant,\n publishedChatConnectOptions,\n publishedChatDescriptor,\n}) => {\n const isTextOnly =\n Boolean(requestPublicationGrant) || convaiClient.connectionType === \"text\";\n // Fetch character information dynamically from client's stored values\n const {\n name: fetchedCharacterName,\n image: fetchedCharacterImage,\n isLoading: isFetchedCharacterLoading,\n } = useCharacterInfo(\n convaiClient.characterId || undefined,\n convaiClient.apiKey || undefined,\n convaiClient.authToken || undefined,\n );\n const characterName =\n publishedChatDescriptor?.display_name || fetchedCharacterName;\n const characterImage =\n publishedChatDescriptor?.image_url ?? fetchedCharacterImage;\n const isCharacterLoading = publishedChatDescriptor\n ? false\n : isFetchedCharacterLoading;\n\n // UI State\n const [isOpen, setIsOpen] = useState(false);\n const [inputValue, setInputValue] = useState(\"\");\n const [isSettingsOpen, setIsSettingsOpen] = useState(false);\n const [isVoiceMode, setIsVoiceMode] = useState(\n defaultVoiceMode && !isTextOnly,\n );\n const [isMuted, setIsMuted] = useState(false); // Character audio starts unmuted\n const [isVideoVisible, setIsVideoVisible] = useState(false);\n const [hasEnteredDefaultVoiceMode, setHasEnteredDefaultVoiceMode] = useState(false);\n\n const settingsButtonRef = useRef<HTMLButtonElement>(null);\n /** True after we have connected at least once; used to call reconnect() instead of connect() when opening after disconnect */\n const hasConnectedBeforeRef = useRef(false);\n /** Prevent repeated open clicks from minting multiple one-time publication grants. */\n const isStartingConnectionRef = useRef(false);\n /** Avoid opening a room after this widget has been removed from the tree. */\n const isUnmountedRef = useRef(false);\n\n // Only published sessions wait for Core's bot-ready handshake. A normal\n // authenticated text session still uses the text-only layout, but can send\n // as soon as it connects.\n const requiresBotReadyForText =\n Boolean(requestPublicationGrant) || convaiClient.isPublishedChatSession;\n const canSendText =\n convaiClient.state.isConnected &&\n (!requiresBotReadyForText || convaiClient.isBotReady);\n\n // Character info from API (using client's stored values)\n const selectedCharacter = {\n id: convaiClient.characterId || \"unknown\",\n name: characterName,\n image: characterImage,\n };\n\n // Get bot status color for character image border\n const getBotStatusColor = () => {\n if (!convaiClient.state.isConnected) {\n return { color: \"#ef4444\", label: \"Disconnected\" }; // Red\n }\n if (convaiClient.state.isConnecting || !convaiClient.isBotReady) {\n return { color: \"#f59e0b\", label: \"Connecting\" }; // Yellow/Orange\n }\n if (convaiClient.state.isListening) {\n return { color: \"#3b82f6\", label: \"Listening\" }; // Blue - user speaking\n }\n return { color: \"#10b981\", label: \"Connected\" }; // Green\n };\n\n // Format chat messages for UI\n const formatMessages = (): RTCChatMessage[] => {\n // Filter to only show relevant message types and exclude empty messages\n const filteredMessages = convaiClient.chatMessages.filter(\n (msg) =>\n (msg.type === \"user-transcription\" ||\n msg.type === \"user-llm-text\" ||\n msg.type === \"bot-llm-text\" ||\n msg.type === \"bot-output\" ||\n msg.type === \"bot-emotion\") &&\n msg.content && // Ensure content exists\n msg.content.trim().length > 0, // Ensure content is not empty or just whitespace\n );\n\n return filteredMessages.map((msg) => ({\n id: msg.id,\n text: msg.content,\n isUser: msg.type.includes(\"user\"),\n timestamp: new Date(msg.timestamp).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }),\n sender: msg.type.includes(\"user\") ? \"You\" : selectedCharacter.name,\n showLogo: msg.type.includes(\"bot\"),\n }));\n };\n\n // Event Handlers\n const handleToggle = async () => {\n if (isStartingConnectionRef.current) {\n return;\n }\n\n // Connect on first click if not already connected/connecting\n if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {\n isStartingConnectionRef.current = true;\n try {\n if (requestPublicationGrant || convaiClient.isPublishedChatSession) {\n if (!requestPublicationGrant) {\n throw new Error(\n \"Published chat widgets require requestPublicationGrant to start a new session\",\n );\n }\n if (!convaiClient.connectWithPublicationGrant) {\n throw new Error(\n \"This Convai client does not support published chat connections\",\n );\n }\n const launchToken = await requestPublicationGrant();\n if (isUnmountedRef.current) return;\n await convaiClient.connectWithPublicationGrant(\n launchToken,\n freshPublicationGrantOptions(publishedChatConnectOptions),\n );\n } else if (\n hasConnectedBeforeRef.current &&\n typeof convaiClient.reconnect === \"function\"\n ) {\n await convaiClient.reconnect();\n } else {\n await convaiClient.connect();\n }\n if (isUnmountedRef.current) {\n await convaiClient.disconnect();\n return;\n }\n setIsOpen(true); // Open widget after successful connection\n } catch (error) {\n console.error(\"Failed to connect:\", error);\n } finally {\n isStartingConnectionRef.current = false;\n }\n } else {\n // Just toggle open/close if already connected\n setIsOpen(!isOpen);\n }\n };\n const handleClose = () => {\n setIsOpen(false);\n };\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(e.target.value);\n };\n\n const handleSend = () => {\n if (inputValue.trim() && canSendText) {\n convaiClient.sendUserTextMessage(inputValue);\n setInputValue(\"\");\n }\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleSend();\n }\n };\n\n\n const handleToggleMute = () => {\n const newMutedState = !isMuted;\n\n if (convaiClient.room?.state === \"connected\") {\n // LiveKit: mute/unmute remote participant audio tracks\n const remoteParticipants = Array.from(\n convaiClient.room.remoteParticipants.values(),\n );\n remoteParticipants.forEach((participant: any) => {\n participant.audioTrackPublications.forEach((publication: any) => {\n if (publication.track) {\n publication.track.setMuted(newMutedState);\n }\n });\n });\n } else {\n // WebSocket: mute/unmute the hidden <audio> element added by useConvaiClient\n const wsAudioEls = document.querySelectorAll<HTMLAudioElement>(\"audio[data-convai-ws]\");\n wsAudioEls.forEach((el) => { el.muted = newMutedState; });\n }\n\n setIsMuted(newMutedState);\n };\n\n const handleReset = async () => {\n setIsSettingsOpen(false);\n\n try {\n // Disconnect current session\n await convaiClient.disconnect();\n\n // Reset session ID so next connection creates a new session\n convaiClient.resetSession();\n\n // Reset UI states immediately\n setIsMuted(false);\n setIsVoiceMode(false);\n\n // Note: User is responsible for reconnecting after reset\n // They should call convaiClient.connect() themselves\n } catch (error) {\n console.error(\"Failed to reset:\", error);\n }\n };\n\n const handleDisconnect = async () => {\n setIsSettingsOpen(false);\n await convaiClient.disconnect();\n\n // Reset UI states immediately\n setIsMuted(false);\n setIsVoiceMode(false);\n };\n\n const handleToggleVideo = async () => {\n // Only toggle if connection type is video\n if (convaiClient.connectionType !== \"video\") {\n console.warn(\"Video capability requires connection type to be 'video'\");\n return;\n }\n\n if (convaiClient.isVideoEnabled) {\n await convaiClient.videoControls.disableVideo();\n } else {\n await convaiClient.videoControls.enableVideo();\n }\n };\n\n const handleToggleScreenShare = async () => {\n await convaiClient.screenShareControls.toggleScreenShare();\n };\n\n const handleSettingsToggle = () => {\n setIsSettingsOpen(!isSettingsOpen);\n };\n\n useEffect(() => {\n isUnmountedRef.current = false;\n return () => {\n isUnmountedRef.current = true;\n };\n }, []);\n\n // Remember that we have connected at least once (so we use reconnect() next time after disconnect)\n useEffect(() => {\n if (convaiClient.state.isConnected) {\n hasConnectedBeforeRef.current = true;\n }\n }, [convaiClient.state.isConnected]);\n\n // Auto-collapse when disconnected\n useEffect(() => {\n if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {\n if (isOpen) {\n setIsOpen(false);\n }\n // Reset UI states on disconnect\n setIsMuted(false); // Reset character mute\n setIsVoiceMode(false); // Reset voice mode\n setHasEnteredDefaultVoiceMode(false); // Reset flag so voice mode can be entered again on reconnect\n }\n }, [convaiClient.state.isConnected, convaiClient.state.isConnecting, isOpen]);\n\n // Sync video visibility with video controls state\n useEffect(() => {\n setIsVideoVisible(convaiClient.isVideoEnabled);\n }, [convaiClient.isVideoEnabled]);\n\n // Ensure microphone is muted when not in voice mode\n useEffect(() => {\n if (isTextOnly && isVoiceMode) {\n setIsVoiceMode(false);\n }\n }, [isTextOnly, isVoiceMode]);\n\n useEffect(() => {\n const ensureMicState = async () => {\n if (!isVoiceMode && !convaiClient.isAudioMuted) {\n // Mute microphone when in text mode\n await convaiClient.audioControls.muteAudio();\n }\n };\n ensureMicState();\n }, [isVoiceMode, convaiClient]);\n\n // Handle default voice mode when widget opens (only once)\n useEffect(() => {\n if (\n isOpen &&\n defaultVoiceMode &&\n !isTextOnly &&\n convaiClient.state.isConnected &&\n !hasEnteredDefaultVoiceMode &&\n !isVoiceMode\n ) {\n const enterVoiceMode = async () => {\n try {\n await convaiClient.audioControls.unmuteAudio();\n setIsVoiceMode(true);\n setHasEnteredDefaultVoiceMode(true);\n } catch (error) {\n console.error(\"Failed to enter voice mode:\", error);\n }\n };\n enterVoiceMode();\n }\n }, [isOpen, defaultVoiceMode, isTextOnly, convaiClient.state.isConnected, hasEnteredDefaultVoiceMode, isVoiceMode, convaiClient]);\n\n // Close settings when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (isSettingsOpen && settingsButtonRef.current) {\n const target = event.target as Node;\n const settingsButton = settingsButtonRef.current;\n if (!settingsButton.contains(target)) {\n const settingsTray = document.querySelector(\"[data-settings-tray]\");\n if (settingsTray && !settingsTray.contains(target)) {\n setIsSettingsOpen(false);\n }\n }\n }\n };\n\n if (isSettingsOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isSettingsOpen]);\n\n // Determine logo state and color\n const getLogoState = (): \"idle\" | \"connecting\" | \"connected\" => {\n if (convaiClient.state.isConnecting) return \"connecting\";\n if (convaiClient.state.isConnected) return \"connected\";\n return \"idle\";\n };\n\n const getLogoColor = () => {\n if (convaiClient.state.isConnected) return aeroTheme.colors.primary[500]; // Green when connected\n if (convaiClient.state.isConnecting) return aeroTheme.colors.primary[300]; // Lighter green when connecting\n return aeroTheme.colors.primary[500]; // Default green\n };\n\n // Audio renderer for LiveKit direct audio playback (not used in WebSocket mode)\n const audioRendererRef = useRef<AudioRenderer | null>(null);\n\n useEffect(() => {\n if (!convaiClient.room || convaiClient.room.state !== \"connected\") return;\n\n audioRendererRef.current = new AudioRenderer(convaiClient.room);\n\n return () => {\n if (audioRendererRef.current) {\n audioRendererRef.current.destroy();\n audioRendererRef.current = null;\n }\n };\n }, [convaiClient.room, convaiClient.state.isConnected]);\n\n return (\n <RoomContext.Provider value={convaiClient.room?.state === \"connected\" ? convaiClient.room : undefined}>\n\n {/* Convai Widget Chat UI - Always visible */}\n <ConvaiContainer\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.4, ease: \"easeOut\" }}\n >\n <MorphingContainer\n onClick={!isOpen ? handleToggle : undefined}\n whileHover={!isOpen ? { scale: 1.05 } : undefined}\n whileTap={!isOpen ? { scale: 0.95 } : undefined}\n animate={{\n width: isOpen ? \"400px\" : \"4rem\",\n height: isOpen ? \"600px\" : \"4rem\",\n borderRadius: isOpen ? aeroTheme.borderRadius.xl : \"50%\",\n }}\n transition={{ duration: 0.3, ease: \"easeInOut\" }}\n style={{ cursor: !isOpen ? \"pointer\" : \"default\" }}\n >\n {/* Button Content - fades out when chat opens */}\n <ButtonContent\n animate={{\n opacity: isOpen ? 0 : 1,\n scale: isOpen ? 0.8 : 1,\n }}\n transition={{ duration: 0.3 }}\n >\n <Logo>\n <ConvaiLogo\n size=\"xl\"\n color={getLogoColor()}\n animate={convaiClient.state.isConnecting}\n state={getLogoState()}\n />\n </Logo>\n </ButtonContent>\n\n {/* Chat Content - fades in when chat opens (only show if connected) */}\n {convaiClient.state.isConnected && (\n <ChatContent\n animate={{\n opacity: isOpen ? 1 : 0,\n scale: isOpen ? 1 : 0.8,\n }}\n transition={{\n duration: 0.2,\n delay: isOpen ? 0.2 : 0,\n }}\n style={{\n pointerEvents: isOpen ? \"auto\" : \"none\",\n }}\n >\n {/* Header */}\n <Header\n initial={{ opacity: 0, y: -20 }}\n animate={{\n opacity: isOpen ? 1 : 0,\n y: isOpen ? 0 : -20,\n }}\n transition={{\n delay: isOpen ? 0.4 : 0,\n ...iosTransitions.modalSlide,\n }}\n style={{ \n pointerEvents: isOpen ? \"auto\" : \"none\",\n minHeight: \"3.5rem\", // Ensure consistent height\n }}\n >\n <CloseButton\n onClick={handleClose}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{ cursor: \"pointer\", pointerEvents: \"auto\" }}\n >\n <ChevronDown size=\"md\" />\n </CloseButton>\n\n <Title>\n {selectedCharacter.image && !isVoiceMode && (\n <motion.img\n key=\"header-avatar\" // Use key instead of layoutId for independent animation\n src={selectedCharacter.image}\n alt={selectedCharacter.name}\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"1.5rem\",\n height: \"1.5rem\",\n borderRadius: \"50%\",\n objectFit: \"cover\",\n marginRight: \"0.5rem\",\n border: `1.5px solid ${getBotStatusColor().color}`,\n boxShadow: `0 0 6px ${getBotStatusColor().color}40`,\n transition: \"all 0.3s ease\",\n }}\n />\n )}\n {selectedCharacter.name}\n <motion.button\n onClick={handleToggleMute}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{\n cursor: \"pointer\",\n pointerEvents: \"auto\",\n background: \"transparent\",\n border: \"none\",\n boxShadow: \"none\",\n width: \"auto\",\n height: \"auto\",\n padding: \"0\",\n display: \"inline-flex\",\n alignItems: \"center\",\n marginLeft: \"0.5rem\",\n outline: \"none\",\n }}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted ? (\n <IoVolumeMute size={16} color=\"#919EABA6\" />\n ) : (\n <IoVolumeHigh size={16} color=\"#0E7360\" />\n )}\n </motion.button>\n {isVoiceMode && (\n <span\n style={{\n fontSize: \"10px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 500,\n marginLeft: \"8px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n }}\n >\n VOICE\n </span>\n )}\n {convaiClient.state.isSpeaking && (\n <motion.span\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{ duration: 0.2 }}\n style={{\n fontSize: \"10px\",\n color: \"#10b981\",\n fontWeight: 600,\n marginLeft: \"8px\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n backgroundColor: \"#10b98120\",\n border: \"1px solid #10b98140\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n <motion.span\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.7, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"#10b981\",\n display: \"inline-block\",\n }}\n />\n SPEAKING\n </motion.span>\n )}\n {convaiClient.state.isListening && !convaiClient.state.isSpeaking && (\n <motion.span\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{ duration: 0.2 }}\n style={{\n fontSize: \"10px\",\n color: \"#3b82f6\",\n fontWeight: 600,\n marginLeft: \"8px\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n backgroundColor: \"#3b82f620\",\n border: \"1px solid #3b82f640\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n <motion.span\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.7, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"#3b82f6\",\n display: \"inline-block\",\n }}\n />\n LISTENING\n </motion.span>\n )}\n </Title>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n position: \"relative\",\n }}\n >\n <SettingsButton\n ref={settingsButtonRef}\n onClick={handleSettingsToggle}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{ cursor: \"pointer\" }}\n >\n <FiMoreVertical size={20} />\n </SettingsButton>\n </div>\n </Header>\n\n {/* Content Area */}\n <Content\n style={{\n background: isVoiceMode\n ? \"rgba(255, 255, 255, 0.98)\"\n : \"transparent\",\n filter: isSettingsOpen ? \"blur(3px)\" : \"none\",\n position: \"relative\",\n }}\n >\n {/* Connecting Overlay - shown until bot is ready */}\n <AnimatePresence>\n {convaiClient.state.isConnected && !convaiClient.isBotReady && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n zIndex: 100,\n gap: \"1rem\",\n }}\n >\n <motion.div\n animate={{\n rotate: 360,\n }}\n transition={{\n duration: 2,\n repeat: Infinity,\n ease: \"linear\",\n }}\n >\n <ConvaiLogo\n size=\"xl\"\n color={aeroTheme.colors.convai.light}\n state=\"connecting\"\n />\n </motion.div>\n <motion.div\n animate={{\n opacity: [0.5, 1, 0.5],\n }}\n transition={{\n duration: 2,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n fontSize: \"14px\",\n fontWeight: 500,\n color: aeroTheme.colors.text.secondary,\n }}\n >\n Connecting to {selectedCharacter.name}...\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {isVoiceMode && (\n <VoiceModeOverlay\n isActive={!convaiClient.isAudioMuted}\n isTalking={convaiClient.state.isSpeaking}\n isListening={convaiClient.state.isListening}\n convaiClient={null}\n characterImage={characterImage || undefined}\n characterName={characterName || undefined}\n room={convaiClient.room?.state === \"connected\" ? convaiClient.room : null}\n />\n )}\n {!isVoiceMode && (\n <MessageList\n messages={formatMessages()}\n isStreaming={convaiClient.state.isSpeaking}\n forceToBottomToken={`${isOpen}-${convaiClient.chatMessages.length}`}\n />\n )}\n </Content>\n\n {/* Footer */}\n <Footer\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n transition={{\n delay: 0.7,\n ...iosTransitions.modalSlide,\n }}\n style={{\n filter: isSettingsOpen ? \"blur(3px)\" : \"none\",\n transition: \"filter 0.2s ease\",\n display: \"flex\",\n gap: \"0.5rem\",\n alignItems: \"center\",\n position: \"relative\",\n justifyContent: isVoiceMode ? \"center\" : \"flex-start\",\n minHeight: \"3.5rem\", // Ensure consistent height\n }}\n >\n {/* In Voice Mode: Show only centered exit button */}\n {isVoiceMode ? (\n <motion.button\n key=\"voice-mode-exit\"\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{\n duration: 0.3,\n ease: \"easeOut\",\n }}\n onClick={async () => {\n convaiClient.sendInterruptMessage();\n await convaiClient.audioControls.muteAudio();\n // WebSocket: tell server to stop processing audio so the\n // character doesn't prompt \"tap microphone to talk\" on silence.\n if (convaiClient.room?.state !== \"connected\") {\n convaiClient.toggleStt(false);\n }\n setIsVoiceMode(false);\n }}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n style={{\n cursor: \"pointer\",\n backgroundColor: \"#ef4444\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n padding: 0,\n outline: \"none\",\n }}\n aria-label=\"Exit Voice Mode\"\n title=\"Exit voice mode\"\n >\n <FiPhoneOff size={20} />\n </motion.button>\n ) : (\n <>\n {/* Input Container */}\n <InputContainer style={{ flex: 1, position: \"relative\" }}>\n {/* Input field */}\n <Input\n type=\"text\"\n placeholder=\"Conversation\"\n value={inputValue}\n onChange={handleInputChange}\n onKeyPress={handleKeyPress}\n disabled={!canSendText}\n style={{ paddingRight: \"2.75rem\" }}\n />\n\n {/* Send/Voice Mode button */}\n <div\n style={{\n position: \"absolute\",\n right: \"0.375rem\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n flexShrink: 0,\n overflow: \"visible\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 2,\n }}\n >\n <AnimatePresence mode=\"wait\">\n {inputValue.length > 0 || isTextOnly ? (\n <ActionButton\n key=\"send\"\n initial={{ y: \"100%\" }}\n animate={{ y: \"0%\" }}\n exit={{ y: \"-100%\" }}\n transition={{\n duration: 0.1,\n ease: \"linear\",\n }}\n onClick={handleSend}\n disabled={inputValue.length === 0 || !canSendText}\n whileTap={{ scale: 0.9 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n cursor: \"pointer\",\n }}\n >\n <FiSend size={20} />\n </ActionButton>\n ) : (\n <motion.button\n key=\"voice\"\n initial={{ y: \"100%\" }}\n animate={{ y: \"0%\" }}\n exit={{ y: \"-100%\" }}\n transition={{\n duration: 0.1,\n ease: \"linear\",\n }}\n onClick={async () => {\n convaiClient.sendInterruptMessage();\n // WebSocket: re-enable server STT before unmuting.\n if (convaiClient.room?.state !== \"connected\") {\n convaiClient.toggleStt(true);\n }\n await convaiClient.audioControls.unmuteAudio();\n setIsVoiceMode(true);\n }}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: aeroTheme.colors.text.primary,\n border: `1px solid ${aeroTheme.colors.neutral[300]}`,\n borderRadius: \"50%\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n padding: 0,\n outline: \"none\",\n }}\n aria-label=\"Enter Voice Mode\"\n title=\"Use voice mode\"\n >\n <PiWaveform size={20} />\n </motion.button>\n )}\n </AnimatePresence>\n </div>\n </InputContainer>\n </>\n )}\n </Footer>\n </ChatContent>\n )}\n </MorphingContainer>\n\n {/* Settings Tray - only show when connected */}\n {convaiClient.state.isConnected && (\n <SettingsTray\n isOpen={isSettingsOpen}\n onReset={\n convaiClient.isPublishedChatSession && !requestPublicationGrant\n ? undefined\n : handleReset\n }\n onDisconnect={\n convaiClient.isPublishedChatSession && !requestPublicationGrant\n ? undefined\n : handleDisconnect\n }\n onToggleVideo={\n convaiClient.connectionType === \"video\" && showVideo\n ? handleToggleVideo\n : undefined\n }\n isVideoVisible={isVideoVisible}\n onToggleScreenShare={\n convaiClient.connectionType === \"video\" && showScreenShare\n ? handleToggleScreenShare\n : undefined\n }\n isScreenShareActive={\n convaiClient.isScreenShareActive\n }\n />\n )}\n </ConvaiContainer>\n\n {/* Floating Video - only rendered in LiveKit mode (requires RoomContext) */}\n {convaiClient.room?.state === \"connected\" && (\n <FloatingVideo\n isVisible={isVideoVisible}\n onClose={async () => {\n await convaiClient.videoControls.disableVideo();\n }}\n mirror={true}\n />\n )}\n </RoomContext.Provider>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ConvaiWidget.js","sourceRoot":"","sources":["../../../src/react/components/ConvaiWidget.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useState, useRef, useEffect } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { FiMoreVertical, FiMic, FiSend, FiPhoneOff } from \"react-icons/fi\";\nimport { IoVolumeMute, IoVolumeHigh } from \"react-icons/io5\";\nimport { PiWaveform } from \"react-icons/pi\";\nimport type {\n IConvaiClient,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\nimport { RoomContext } from \"@livekit/components-react\";\nimport { useCharacterInfo } from \"../hooks/useCharacterInfo\";\nimport { AudioRenderer } from \"../../vanilla/AudioRenderer\";\nimport type { PublishedChatDescriptor } from \"../../embed/publicationApi\";\nimport { freshPublicationGrantOptions } from \"../../core/publishedChat\";\n\n// Import styled components and theme from rtc-widget\nimport {\n ConvaiContainer,\n MorphingContainer,\n ButtonContent,\n Logo,\n ChatContent,\n Header,\n Title,\n CloseButton,\n SettingsButton,\n Content,\n Footer,\n InputContainer,\n Input,\n ActionButton,\n aeroTheme,\n iosTransitions,\n ConvaiLogo,\n ChevronDown,\n} from \"./rtc-widget\";\n\n// Import message components\nimport {\n MessageList,\n SettingsTray,\n VoiceModeOverlay,\n RTCChatMessage,\n FloatingVideo,\n} from \"./rtc-widget\";\n\ninterface Character {\n id: string;\n name?: string;\n image?: string;\n}\n\ninterface ConvaiWidgetProps {\n /** Convai client instance (required) */\n convaiClient: IConvaiClient & { \n activity?: string;\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n };\n /**\n * Show video toggle button in settings (default: true).\n * Only works if connection type is \"video\". If false, hides the video button.\n */\n showVideo?: boolean;\n /**\n * Show screen share toggle button in settings (default: true).\n * Only works if connection type is \"video\". If false, hides the screen share button.\n */\n showScreenShare?: boolean;\n /**\n * Start in voice mode by default when widget opens (default: true).\n * When true, the widget will open directly in voice mode with microphone enabled.\n */\n defaultVoiceMode?: boolean;\n /**\n * Mint a fresh single-use grant when a published-chat session is reopened.\n * Required when using this widget with connectWithPublicationGrant().\n */\n requestPublicationGrant?: () => Promise<string>;\n /** Core endpoint override used with requestPublicationGrant. */\n publishedChatConnectOptions?: PublishedChatConnectOptions;\n /** Public descriptor used to label a credential-free published session. */\n publishedChatDescriptor?: Pick<\n PublishedChatDescriptor,\n \"display_name\" | \"image_url\"\n >;\n}\n\n/**\n * ConvaiWidget - A consolidated chat widget component for real-time conversations\n *\n * This component provides a complete UI for interacting with Convai characters.\n * Connection configuration should be handled via useConvaiClient.connect().\n *\n * Features:\n * - Collapsed circular button with status indicator\n * - Expandable/collapsible chat interface\n * - Voice mode support\n * - Real-time message streaming\n * - Audio controls (mute/unmute)\n * - Settings tray with session reset\n * - Optional video and screen share (when connection type supports it)\n *\n * @param {ConvaiWidgetProps} props - Component props\n * @param {ConvaiClient} props.convaiClient - Convai client instance (required)\n * @param {boolean} props.showVideo - Show video toggle in settings (default: true)\n * @param {boolean} props.showScreenShare - Show screen share toggle in settings (default: true)\n * @param {boolean} props.defaultVoiceMode - Start in voice mode when widget opens (default: true)\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget\n * convaiClient={convaiClient}\n * showVideo={true}\n * showScreenShare={true}\n * />\n * );\n * }\n * ```\n */\nexport const ConvaiWidget: React.FC<ConvaiWidgetProps> = ({\n convaiClient,\n showVideo = true,\n showScreenShare = true,\n defaultVoiceMode = true,\n requestPublicationGrant,\n publishedChatConnectOptions,\n publishedChatDescriptor,\n}) => {\n const isTextOnly =\n Boolean(requestPublicationGrant) || convaiClient.connectionType === \"text\";\n // Fetch character information dynamically from client's stored values\n const {\n name: fetchedCharacterName,\n image: fetchedCharacterImage,\n isLoading: isFetchedCharacterLoading,\n } = useCharacterInfo(\n convaiClient.characterId || undefined,\n convaiClient.apiKey || undefined,\n convaiClient.authToken || undefined,\n );\n const characterName =\n publishedChatDescriptor?.display_name || fetchedCharacterName;\n const characterImage =\n publishedChatDescriptor?.image_url ?? fetchedCharacterImage;\n const isCharacterLoading = publishedChatDescriptor\n ? false\n : isFetchedCharacterLoading;\n\n // UI State\n const [isOpen, setIsOpen] = useState(false);\n const [inputValue, setInputValue] = useState(\"\");\n const [isSettingsOpen, setIsSettingsOpen] = useState(false);\n const [isVoiceMode, setIsVoiceMode] = useState(\n defaultVoiceMode && !isTextOnly,\n );\n const [isMuted, setIsMuted] = useState(false); // Character audio starts unmuted\n const [isVideoVisible, setIsVideoVisible] = useState(false);\n const [hasEnteredDefaultVoiceMode, setHasEnteredDefaultVoiceMode] = useState(false);\n\n const settingsButtonRef = useRef<HTMLButtonElement>(null);\n /** True after we have connected at least once; used to call reconnect() instead of connect() when opening after disconnect */\n const hasConnectedBeforeRef = useRef(false);\n /** Prevent repeated open clicks from minting multiple one-time publication grants. */\n const isStartingConnectionRef = useRef(false);\n /** Avoid opening a room after this widget has been removed from the tree. */\n const isUnmountedRef = useRef(false);\n\n const canSendText =\n convaiClient.state.isConnected && convaiClient.isBotReady;\n\n // Character info from API (using client's stored values)\n const selectedCharacter = {\n id: convaiClient.characterId || \"unknown\",\n name: characterName,\n image: characterImage,\n };\n\n // Get bot status color for character image border\n const getBotStatusColor = () => {\n if (!convaiClient.state.isConnected) {\n return { color: \"#ef4444\", label: \"Disconnected\" }; // Red\n }\n if (convaiClient.state.isConnecting || !convaiClient.isBotReady) {\n return { color: \"#f59e0b\", label: \"Connecting\" }; // Yellow/Orange\n }\n if (convaiClient.state.isListening) {\n return { color: \"#3b82f6\", label: \"Listening\" }; // Blue - user speaking\n }\n return { color: \"#10b981\", label: \"Connected\" }; // Green\n };\n\n // Format chat messages for UI\n const formatMessages = (): RTCChatMessage[] => {\n // Filter to only show relevant message types and exclude empty messages\n const filteredMessages = convaiClient.chatMessages.filter(\n (msg) =>\n (msg.type === \"user-transcription\" ||\n msg.type === \"user-llm-text\" ||\n msg.type === \"bot-llm-text\" ||\n msg.type === \"bot-output\" ||\n msg.type === \"bot-emotion\") &&\n msg.content && // Ensure content exists\n msg.content.trim().length > 0, // Ensure content is not empty or just whitespace\n );\n\n return filteredMessages.map((msg) => ({\n id: msg.id,\n text: msg.content,\n isUser: msg.type.includes(\"user\"),\n timestamp: new Date(msg.timestamp).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }),\n sender: msg.type.includes(\"user\") ? \"You\" : selectedCharacter.name,\n showLogo: msg.type.includes(\"bot\"),\n }));\n };\n\n // Event Handlers\n const handleToggle = async () => {\n if (isStartingConnectionRef.current) {\n return;\n }\n\n // Connect on first click if not already connected/connecting\n if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {\n isStartingConnectionRef.current = true;\n try {\n if (requestPublicationGrant || convaiClient.isPublishedChatSession) {\n if (!requestPublicationGrant) {\n throw new Error(\n \"Published chat widgets require requestPublicationGrant to start a new session\",\n );\n }\n if (!convaiClient.connectWithPublicationGrant) {\n throw new Error(\n \"This Convai client does not support published chat connections\",\n );\n }\n const launchToken = await requestPublicationGrant();\n if (isUnmountedRef.current) return;\n await convaiClient.connectWithPublicationGrant(\n launchToken,\n freshPublicationGrantOptions(publishedChatConnectOptions),\n );\n } else if (\n hasConnectedBeforeRef.current &&\n typeof convaiClient.reconnect === \"function\"\n ) {\n await convaiClient.reconnect();\n } else {\n await convaiClient.connect();\n }\n if (isUnmountedRef.current) {\n await convaiClient.disconnect();\n return;\n }\n setIsOpen(true); // Open widget after successful connection\n } catch (error) {\n console.error(\"Failed to connect:\", error);\n } finally {\n isStartingConnectionRef.current = false;\n }\n } else {\n // Just toggle open/close if already connected\n setIsOpen(!isOpen);\n }\n };\n const handleClose = () => {\n setIsOpen(false);\n };\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(e.target.value);\n };\n\n const handleSend = () => {\n if (inputValue.trim() && canSendText) {\n convaiClient.sendUserTextMessage(inputValue);\n setInputValue(\"\");\n }\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleSend();\n }\n };\n\n\n const handleToggleMute = () => {\n const newMutedState = !isMuted;\n\n if (convaiClient.room?.state === \"connected\") {\n // LiveKit: mute/unmute remote participant audio tracks\n const remoteParticipants = Array.from(\n convaiClient.room.remoteParticipants.values(),\n );\n remoteParticipants.forEach((participant: any) => {\n participant.audioTrackPublications.forEach((publication: any) => {\n if (publication.track) {\n publication.track.setMuted(newMutedState);\n }\n });\n });\n } else {\n // WebSocket: mute/unmute the hidden <audio> element added by useConvaiClient\n const wsAudioEls = document.querySelectorAll<HTMLAudioElement>(\"audio[data-convai-ws]\");\n wsAudioEls.forEach((el) => { el.muted = newMutedState; });\n }\n\n setIsMuted(newMutedState);\n };\n\n const handleReset = async () => {\n setIsSettingsOpen(false);\n\n try {\n // Disconnect current session\n await convaiClient.disconnect();\n\n // Reset session ID so next connection creates a new session\n convaiClient.resetSession();\n\n // Reset UI states immediately\n setIsMuted(false);\n setIsVoiceMode(false);\n\n // Note: User is responsible for reconnecting after reset\n // They should call convaiClient.connect() themselves\n } catch (error) {\n console.error(\"Failed to reset:\", error);\n }\n };\n\n const handleDisconnect = async () => {\n setIsSettingsOpen(false);\n await convaiClient.disconnect();\n\n // Reset UI states immediately\n setIsMuted(false);\n setIsVoiceMode(false);\n };\n\n const handleToggleVideo = async () => {\n // Only toggle if connection type is video\n if (convaiClient.connectionType !== \"video\") {\n console.warn(\"Video capability requires connection type to be 'video'\");\n return;\n }\n\n if (convaiClient.isVideoEnabled) {\n await convaiClient.videoControls.disableVideo();\n } else {\n await convaiClient.videoControls.enableVideo();\n }\n };\n\n const handleToggleScreenShare = async () => {\n await convaiClient.screenShareControls.toggleScreenShare();\n };\n\n const handleSettingsToggle = () => {\n setIsSettingsOpen(!isSettingsOpen);\n };\n\n useEffect(() => {\n isUnmountedRef.current = false;\n return () => {\n isUnmountedRef.current = true;\n };\n }, []);\n\n // Remember that we have connected at least once (so we use reconnect() next time after disconnect)\n useEffect(() => {\n if (convaiClient.state.isConnected) {\n hasConnectedBeforeRef.current = true;\n }\n }, [convaiClient.state.isConnected]);\n\n // Auto-collapse when disconnected\n useEffect(() => {\n if (!convaiClient.state.isConnected && !convaiClient.state.isConnecting) {\n if (isOpen) {\n setIsOpen(false);\n }\n // Reset UI states on disconnect\n setIsMuted(false); // Reset character mute\n setIsVoiceMode(false); // Reset voice mode\n setHasEnteredDefaultVoiceMode(false); // Reset flag so voice mode can be entered again on reconnect\n }\n }, [convaiClient.state.isConnected, convaiClient.state.isConnecting, isOpen]);\n\n // Sync video visibility with video controls state\n useEffect(() => {\n setIsVideoVisible(convaiClient.isVideoEnabled);\n }, [convaiClient.isVideoEnabled]);\n\n // Ensure microphone is muted when not in voice mode\n useEffect(() => {\n if (isTextOnly && isVoiceMode) {\n setIsVoiceMode(false);\n }\n }, [isTextOnly, isVoiceMode]);\n\n useEffect(() => {\n const ensureMicState = async () => {\n if (!isVoiceMode && !convaiClient.isAudioMuted) {\n // Mute microphone when in text mode\n await convaiClient.audioControls.muteAudio();\n }\n };\n ensureMicState();\n }, [isVoiceMode, convaiClient]);\n\n // Handle default voice mode when widget opens (only once)\n useEffect(() => {\n if (\n isOpen &&\n defaultVoiceMode &&\n !isTextOnly &&\n convaiClient.state.isConnected &&\n !hasEnteredDefaultVoiceMode &&\n !isVoiceMode\n ) {\n const enterVoiceMode = async () => {\n try {\n await convaiClient.audioControls.unmuteAudio();\n setIsVoiceMode(true);\n setHasEnteredDefaultVoiceMode(true);\n } catch (error) {\n console.error(\"Failed to enter voice mode:\", error);\n }\n };\n enterVoiceMode();\n }\n }, [isOpen, defaultVoiceMode, isTextOnly, convaiClient.state.isConnected, hasEnteredDefaultVoiceMode, isVoiceMode, convaiClient]);\n\n // Close settings when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (isSettingsOpen && settingsButtonRef.current) {\n const target = event.target as Node;\n const settingsButton = settingsButtonRef.current;\n if (!settingsButton.contains(target)) {\n const settingsTray = document.querySelector(\"[data-settings-tray]\");\n if (settingsTray && !settingsTray.contains(target)) {\n setIsSettingsOpen(false);\n }\n }\n }\n };\n\n if (isSettingsOpen) {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isSettingsOpen]);\n\n // Determine logo state and color\n const getLogoState = (): \"idle\" | \"connecting\" | \"connected\" => {\n if (convaiClient.state.isConnecting) return \"connecting\";\n if (convaiClient.state.isConnected) return \"connected\";\n return \"idle\";\n };\n\n const getLogoColor = () => {\n if (convaiClient.state.isConnected) return aeroTheme.colors.primary[500]; // Green when connected\n if (convaiClient.state.isConnecting) return aeroTheme.colors.primary[300]; // Lighter green when connecting\n return aeroTheme.colors.primary[500]; // Default green\n };\n\n // Audio renderer for LiveKit direct audio playback (not used in WebSocket mode)\n const audioRendererRef = useRef<AudioRenderer | null>(null);\n\n useEffect(() => {\n if (!convaiClient.room || convaiClient.room.state !== \"connected\") return;\n\n audioRendererRef.current = new AudioRenderer(convaiClient.room);\n\n return () => {\n if (audioRendererRef.current) {\n audioRendererRef.current.destroy();\n audioRendererRef.current = null;\n }\n };\n }, [convaiClient.room, convaiClient.state.isConnected]);\n\n return (\n <RoomContext.Provider value={convaiClient.room?.state === \"connected\" ? convaiClient.room : undefined}>\n\n {/* Convai Widget Chat UI - Always visible */}\n <ConvaiContainer\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.4, ease: \"easeOut\" }}\n >\n <MorphingContainer\n onClick={!isOpen ? handleToggle : undefined}\n whileHover={!isOpen ? { scale: 1.05 } : undefined}\n whileTap={!isOpen ? { scale: 0.95 } : undefined}\n animate={{\n width: isOpen ? \"400px\" : \"4rem\",\n height: isOpen ? \"600px\" : \"4rem\",\n borderRadius: isOpen ? aeroTheme.borderRadius.xl : \"50%\",\n }}\n transition={{ duration: 0.3, ease: \"easeInOut\" }}\n style={{ cursor: !isOpen ? \"pointer\" : \"default\" }}\n >\n {/* Button Content - fades out when chat opens */}\n <ButtonContent\n animate={{\n opacity: isOpen ? 0 : 1,\n scale: isOpen ? 0.8 : 1,\n }}\n transition={{ duration: 0.3 }}\n >\n <Logo>\n <ConvaiLogo\n size=\"xl\"\n color={getLogoColor()}\n animate={convaiClient.state.isConnecting}\n state={getLogoState()}\n />\n </Logo>\n </ButtonContent>\n\n {/* Chat Content - fades in when chat opens (only show if connected) */}\n {convaiClient.state.isConnected && (\n <ChatContent\n animate={{\n opacity: isOpen ? 1 : 0,\n scale: isOpen ? 1 : 0.8,\n }}\n transition={{\n duration: 0.2,\n delay: isOpen ? 0.2 : 0,\n }}\n style={{\n pointerEvents: isOpen ? \"auto\" : \"none\",\n }}\n >\n {/* Header */}\n <Header\n initial={{ opacity: 0, y: -20 }}\n animate={{\n opacity: isOpen ? 1 : 0,\n y: isOpen ? 0 : -20,\n }}\n transition={{\n delay: isOpen ? 0.4 : 0,\n ...iosTransitions.modalSlide,\n }}\n style={{ \n pointerEvents: isOpen ? \"auto\" : \"none\",\n minHeight: \"3.5rem\", // Ensure consistent height\n }}\n >\n <CloseButton\n onClick={handleClose}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{ cursor: \"pointer\", pointerEvents: \"auto\" }}\n >\n <ChevronDown size=\"md\" />\n </CloseButton>\n\n <Title>\n {selectedCharacter.image && !isVoiceMode && (\n <motion.img\n key=\"header-avatar\" // Use key instead of layoutId for independent animation\n src={selectedCharacter.image}\n alt={selectedCharacter.name}\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"1.5rem\",\n height: \"1.5rem\",\n borderRadius: \"50%\",\n objectFit: \"cover\",\n marginRight: \"0.5rem\",\n border: `1.5px solid ${getBotStatusColor().color}`,\n boxShadow: `0 0 6px ${getBotStatusColor().color}40`,\n transition: \"all 0.3s ease\",\n }}\n />\n )}\n {selectedCharacter.name}\n <motion.button\n onClick={handleToggleMute}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{\n cursor: \"pointer\",\n pointerEvents: \"auto\",\n background: \"transparent\",\n border: \"none\",\n boxShadow: \"none\",\n width: \"auto\",\n height: \"auto\",\n padding: \"0\",\n display: \"inline-flex\",\n alignItems: \"center\",\n marginLeft: \"0.5rem\",\n outline: \"none\",\n }}\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n title={isMuted ? \"Unmute\" : \"Mute\"}\n >\n {isMuted ? (\n <IoVolumeMute size={16} color=\"#919EABA6\" />\n ) : (\n <IoVolumeHigh size={16} color=\"#0E7360\" />\n )}\n </motion.button>\n {isVoiceMode && (\n <span\n style={{\n fontSize: \"10px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 500,\n marginLeft: \"8px\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n }}\n >\n VOICE\n </span>\n )}\n {convaiClient.state.isSpeaking && (\n <motion.span\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{ duration: 0.2 }}\n style={{\n fontSize: \"10px\",\n color: \"#10b981\",\n fontWeight: 600,\n marginLeft: \"8px\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n backgroundColor: \"#10b98120\",\n border: \"1px solid #10b98140\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n <motion.span\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.7, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"#10b981\",\n display: \"inline-block\",\n }}\n />\n SPEAKING\n </motion.span>\n )}\n {convaiClient.state.isListening && !convaiClient.state.isSpeaking && (\n <motion.span\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{ duration: 0.2 }}\n style={{\n fontSize: \"10px\",\n color: \"#3b82f6\",\n fontWeight: 600,\n marginLeft: \"8px\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n backgroundColor: \"#3b82f620\",\n border: \"1px solid #3b82f640\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n <motion.span\n animate={{\n scale: [1, 1.2, 1],\n opacity: [1, 0.7, 1],\n }}\n transition={{\n duration: 1.5,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"#3b82f6\",\n display: \"inline-block\",\n }}\n />\n LISTENING\n </motion.span>\n )}\n </Title>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n position: \"relative\",\n }}\n >\n <SettingsButton\n ref={settingsButtonRef}\n onClick={handleSettingsToggle}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={iosTransitions.snappy}\n style={{ cursor: \"pointer\" }}\n >\n <FiMoreVertical size={20} />\n </SettingsButton>\n </div>\n </Header>\n\n {/* Content Area */}\n <Content\n style={{\n background: isVoiceMode\n ? \"rgba(255, 255, 255, 0.98)\"\n : \"transparent\",\n filter: isSettingsOpen ? \"blur(3px)\" : \"none\",\n position: \"relative\",\n }}\n >\n {/* Connecting Overlay - shown until bot is ready */}\n <AnimatePresence>\n {convaiClient.state.isConnected && !convaiClient.isBotReady && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n zIndex: 100,\n gap: \"1rem\",\n }}\n >\n <motion.div\n animate={{\n rotate: 360,\n }}\n transition={{\n duration: 2,\n repeat: Infinity,\n ease: \"linear\",\n }}\n >\n <ConvaiLogo\n size=\"xl\"\n color={aeroTheme.colors.convai.light}\n state=\"connecting\"\n />\n </motion.div>\n <motion.div\n animate={{\n opacity: [0.5, 1, 0.5],\n }}\n transition={{\n duration: 2,\n repeat: Infinity,\n ease: \"easeInOut\",\n }}\n style={{\n fontSize: \"14px\",\n fontWeight: 500,\n color: aeroTheme.colors.text.secondary,\n }}\n >\n Connecting to {selectedCharacter.name}...\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {isVoiceMode && (\n <VoiceModeOverlay\n isActive={!convaiClient.isAudioMuted}\n isTalking={convaiClient.state.isSpeaking}\n isListening={convaiClient.state.isListening}\n convaiClient={null}\n characterImage={characterImage || undefined}\n characterName={characterName || undefined}\n room={convaiClient.room?.state === \"connected\" ? convaiClient.room : null}\n />\n )}\n {!isVoiceMode && (\n <MessageList\n messages={formatMessages()}\n isStreaming={convaiClient.state.isSpeaking}\n forceToBottomToken={`${isOpen}-${convaiClient.chatMessages.length}`}\n />\n )}\n </Content>\n\n {/* Footer */}\n <Footer\n initial={{ y: 20, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n transition={{\n delay: 0.7,\n ...iosTransitions.modalSlide,\n }}\n style={{\n filter: isSettingsOpen ? \"blur(3px)\" : \"none\",\n transition: \"filter 0.2s ease\",\n display: \"flex\",\n gap: \"0.5rem\",\n alignItems: \"center\",\n position: \"relative\",\n justifyContent: isVoiceMode ? \"center\" : \"flex-start\",\n minHeight: \"3.5rem\", // Ensure consistent height\n }}\n >\n {/* In Voice Mode: Show only centered exit button */}\n {isVoiceMode ? (\n <motion.button\n key=\"voice-mode-exit\"\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={{\n duration: 0.3,\n ease: \"easeOut\",\n }}\n onClick={async () => {\n convaiClient.sendInterruptMessage();\n await convaiClient.audioControls.muteAudio();\n // WebSocket: tell server to stop processing audio so the\n // character doesn't prompt \"tap microphone to talk\" on silence.\n if (convaiClient.room?.state !== \"connected\") {\n convaiClient.toggleStt(false);\n }\n setIsVoiceMode(false);\n }}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n style={{\n cursor: \"pointer\",\n backgroundColor: \"#ef4444\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: \"50%\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n padding: 0,\n outline: \"none\",\n }}\n aria-label=\"Exit Voice Mode\"\n title=\"Exit voice mode\"\n >\n <FiPhoneOff size={20} />\n </motion.button>\n ) : (\n <>\n {/* Input Container */}\n <InputContainer style={{ flex: 1, position: \"relative\" }}>\n {/* Input field */}\n <Input\n type=\"text\"\n placeholder=\"Conversation\"\n value={inputValue}\n onChange={handleInputChange}\n onKeyPress={handleKeyPress}\n disabled={!canSendText}\n style={{ paddingRight: \"2.75rem\" }}\n />\n\n {/* Send/Voice Mode button */}\n <div\n style={{\n position: \"absolute\",\n right: \"0.375rem\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n flexShrink: 0,\n overflow: \"visible\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 2,\n }}\n >\n <AnimatePresence mode=\"wait\">\n {inputValue.length > 0 || isTextOnly ? (\n <ActionButton\n key=\"send\"\n initial={{ y: \"100%\" }}\n animate={{ y: \"0%\" }}\n exit={{ y: \"-100%\" }}\n transition={{\n duration: 0.1,\n ease: \"linear\",\n }}\n onClick={handleSend}\n disabled={inputValue.length === 0 || !canSendText}\n whileTap={{ scale: 0.9 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n cursor: \"pointer\",\n }}\n >\n <FiSend size={20} />\n </ActionButton>\n ) : (\n <motion.button\n key=\"voice\"\n initial={{ y: \"100%\" }}\n animate={{ y: \"0%\" }}\n exit={{ y: \"-100%\" }}\n transition={{\n duration: 0.1,\n ease: \"linear\",\n }}\n onClick={async () => {\n convaiClient.sendInterruptMessage();\n // WebSocket: re-enable server STT before unmuting.\n if (convaiClient.room?.state !== \"connected\") {\n convaiClient.toggleStt(true);\n }\n await convaiClient.audioControls.unmuteAudio();\n setIsVoiceMode(true);\n }}\n whileHover={{ scale: 1.1 }}\n whileTap={{ scale: 0.9 }}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: aeroTheme.colors.text.primary,\n border: `1px solid ${aeroTheme.colors.neutral[300]}`,\n borderRadius: \"50%\",\n width: \"2.25rem\",\n height: \"2.25rem\",\n minWidth: \"2.25rem\",\n minHeight: \"2.25rem\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n padding: 0,\n outline: \"none\",\n }}\n aria-label=\"Enter Voice Mode\"\n title=\"Use voice mode\"\n >\n <PiWaveform size={20} />\n </motion.button>\n )}\n </AnimatePresence>\n </div>\n </InputContainer>\n </>\n )}\n </Footer>\n </ChatContent>\n )}\n </MorphingContainer>\n\n {/* Settings Tray - only show when connected */}\n {convaiClient.state.isConnected && (\n <SettingsTray\n isOpen={isSettingsOpen}\n onReset={\n convaiClient.isPublishedChatSession && !requestPublicationGrant\n ? undefined\n : handleReset\n }\n onDisconnect={\n convaiClient.isPublishedChatSession && !requestPublicationGrant\n ? undefined\n : handleDisconnect\n }\n onToggleVideo={\n convaiClient.connectionType === \"video\" && showVideo\n ? handleToggleVideo\n : undefined\n }\n isVideoVisible={isVideoVisible}\n onToggleScreenShare={\n convaiClient.connectionType === \"video\" && showScreenShare\n ? handleToggleScreenShare\n : undefined\n }\n isScreenShareActive={\n convaiClient.isScreenShareActive\n }\n />\n )}\n </ConvaiContainer>\n\n {/* Floating Video - only rendered in LiveKit mode (requires RoomContext) */}\n {convaiClient.room?.state === \"connected\" && (\n <FloatingVideo\n isVisible={isVideoVisible}\n onClose={async () => {\n await convaiClient.videoControls.disableVideo();\n }}\n mirror={true}\n />\n )}\n </RoomContext.Provider>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioVisualizer.d.ts","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/AudioVisualizer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAkBtC,UAAU,oBAAoB;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"AudioVisualizer.d.ts","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/AudioVisualizer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAkBtC,UAAU,oBAAoB;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4R1D,CAAC"}
|
|
@@ -161,36 +161,9 @@ export const AudioVisualizer = ({ room, size = 350, color = '#10b981', opacity =
|
|
|
161
161
|
*/
|
|
162
162
|
const bufferLength = analyser.frequencyBinCount;
|
|
163
163
|
const dataArray = new Uint8Array(bufferLength);
|
|
164
|
-
let frameParity = 0;
|
|
165
|
-
let idleFramesPainted = 0;
|
|
166
164
|
const draw = () => {
|
|
167
|
-
|
|
168
|
-
// settled — every canvas update forces the compositor to re-blend
|
|
169
|
-
// the widget panel over the host page's WebGL canvas, which judders
|
|
170
|
-
// the 3D scene if done at 60fps continuously.
|
|
171
|
-
frameParity ^= 1;
|
|
172
|
-
if (frameParity) {
|
|
173
|
-
animationFrameRef.current = requestAnimationFrame(draw);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
timeRef.current += 0.16;
|
|
165
|
+
timeRef.current += 0.08;
|
|
177
166
|
analyser.getByteFrequencyData(dataArray);
|
|
178
|
-
{
|
|
179
|
-
let t = 0;
|
|
180
|
-
for (let i = 0; i < bufferLength; i++)
|
|
181
|
-
t += dataArray[i] || 0;
|
|
182
|
-
if (!isActiveRef.current || t / (bufferLength * 255) < 0.01) {
|
|
183
|
-
// Fade the ring out over a few frames, then hold it static.
|
|
184
|
-
if (idleFramesPainted > 20) {
|
|
185
|
-
animationFrameRef.current = requestAnimationFrame(draw);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
idleFramesPainted++;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
idleFramesPainted = 0;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
167
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
195
168
|
const centerX = canvas.width / 2;
|
|
196
169
|
const centerY = canvas.height / 2;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioVisualizer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/AudioVisualizer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef } from 'react';\nimport styled from 'styled-components';\nimport { Room } from 'livekit-client';\n\nconst VisualizerContainer = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n z-index: 1;\n pointer-events: none;\n border-radius: 50%;\n overflow: visible;\n`;\n\nconst Canvas = styled.canvas`\n display: block;\n width: 100%;\n height: 100%;\n`;\n\ninterface AudioVisualizerProps {\n /** LiveKit room instance containing the remote participant's audio track */\n room: Room | null;\n /** Canvas size in pixels (width and height) */\n size?: number;\n /** CSS color value for the bars */\n color?: string;\n /** Base opacity of the bars (0-1), actual opacity varies with audio intensity */\n opacity?: number;\n /** Radius of the circular visualization area in pixels */\n avatarRadius?: number;\n /** Number of radial bars to display around the circle */\n barCount?: number;\n /** Callback function called when speaking state changes */\n onSpeakingChange?: (isSpeaking: boolean) => void;\n}\n\n/**\n * Circular Audio Visualizer Component\n * \n * A real-time circular audio visualization component that displays radial bars arranged\n * in a circle around an avatar. The visualization reacts to the remote participant's\n * (bot) audio output from a LiveKit room, using logarithmic frequency bands and a\n * traveling wave animation effect.\n * \n * Features:\n * - Circular radial bar visualization with configurable bar count\n * - Logarithmic frequency band distribution (low frequencies distributed around the ring)\n * - Traveling wave animation that propagates around the circle\n * - Speaking detection with callback support\n * - Automatic track detection and reconnection\n * - Canvas-based rendering for smooth animations\n */\nexport const AudioVisualizer: React.FC<AudioVisualizerProps> = ({\n room,\n size = 350,\n color = '#10b981',\n opacity = 0.4,\n avatarRadius = 80,\n barCount = 64,\n onSpeakingChange,\n}) => {\n // Refs for canvas and Web Audio API nodes\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const animationFrameRef = useRef<number | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const sourceNodeRef = useRef<MediaStreamAudioSourceNode | null>(null);\n const isActiveRef = useRef(false);\n \n // Refs for animation and state management\n const timeRef = useRef(0);\n const previousSpeakingStateRef = useRef(false);\n const bandEdgesRef = useRef<number[] | null>(null);\n\n useEffect(() => {\n if (!room) return;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n canvas.width = size;\n canvas.height = size;\n\n // Initialize Web Audio API context and analyser\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n analyser.smoothingTimeConstant = 0.6;\n\n audioContextRef.current = audioContext;\n analyserRef.current = analyser;\n\n /**\n * Builds logarithmically-spaced frequency band edges.\n * This distributes low-frequency energy (which has more power) evenly around\n * the circular visualization, rather than clustering it at the start.\n */\n const buildLogBands = () => {\n const nyquist = audioContext.sampleRate / 2;\n const bufferLength = analyser.frequencyBinCount;\n const minHz = 60;\n const maxHz = Math.min(8000, nyquist);\n const edges = Array.from({ length: barCount + 1 }, (_, k) => {\n const hz = minHz * Math.pow(maxHz / minHz, k / barCount);\n const bin = Math.max(\n 0,\n Math.min(bufferLength - 1, Math.floor((hz / nyquist) * bufferLength))\n );\n return bin;\n });\n // Ensure strictly increasing edges (no zero-width bands)\n for (let i = 1; i < edges.length; i++) {\n if (edges[i] <= edges[i - 1]) edges[i] = Math.min(edges[i - 1] + 1, bufferLength - 1);\n }\n bandEdgesRef.current = edges;\n };\n\n /**\n * Finds the bot participant from remote participants.\n */\n const findBotParticipant = (remoteParticipants: Map<string, any>, localParticipant: any) => {\n const participants = Array.from(remoteParticipants.values()).filter(\n (p) => p !== localParticipant && p !== room.localParticipant\n );\n\n if (participants.length === 0) {\n return null;\n }\n\n // Prefer participants with audio tracks (bot typically has audio)\n const participantsWithAudio = participants.filter((participant) => {\n if (!participant.trackPublications) return false;\n const audioTracks = Array.from(participant.trackPublications.values()).filter(\n (p: any) => p.kind === 'audio' && p.track\n );\n return audioTracks.length > 0;\n });\n\n return participantsWithAudio.length > 0 ? participantsWithAudio[0] : participants[0];\n };\n\n /**\n * Sets up the audio source by connecting the remote participant's (bot) audio track\n * to the Web Audio API analyser.\n */\n const setupAudioSource = async () => {\n try {\n if (audioContext.state === 'suspended') await audioContext.resume();\n\n const remoteParticipants = room.remoteParticipants;\n if (remoteParticipants.size === 0) {\n isActiveRef.current = false;\n return;\n }\n\n const botParticipant = findBotParticipant(remoteParticipants, room.localParticipant);\n if (!botParticipant) {\n isActiveRef.current = false;\n return;\n }\n \n const audioTracks = Array.from(botParticipant.trackPublications.values()).filter(\n (p: any) => p.kind === 'audio' && p.track\n );\n \n if (audioTracks.length === 0) {\n isActiveRef.current = false;\n return;\n }\n\n const liveKitTrack = (audioTracks[0] as any).track;\n const mediaStreamTrack = liveKitTrack.mediaStreamTrack;\n if (!mediaStreamTrack) {\n isActiveRef.current = false;\n return;\n }\n\n const mediaStream = new MediaStream([mediaStreamTrack]);\n\n if (sourceNodeRef.current) sourceNodeRef.current.disconnect();\n const source = audioContext.createMediaStreamSource(mediaStream);\n source.connect(analyser);\n sourceNodeRef.current = source;\n\n // Build bands after context is ready\n buildLogBands();\n\n isActiveRef.current = true;\n } catch {\n isActiveRef.current = false;\n }\n };\n\n setupAudioSource();\n const setupTimeout = setTimeout(setupAudioSource, 500);\n\n const handleTrackSubscribed = (track: any, publication: any, participant: any) => {\n if (track && track.kind === 'audio' && participant !== room.localParticipant) {\n setTimeout(setupAudioSource, 200);\n }\n };\n \n const handleParticipantConnected = (participant: any) => {\n if (participant !== room.localParticipant) setTimeout(setupAudioSource, 200);\n };\n\n room.on('trackSubscribed', handleTrackSubscribed);\n room.on('participantConnected', handleParticipantConnected);\n\n /**\n * Main rendering function that draws the circular audio visualization.\n */\n const bufferLength = analyser.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n\n let frameParity = 0;\n let idleFramesPainted = 0;\n const draw = () => {\n // THROTTLE: 30fps, and stop repainting once the idle state has\n // settled — every canvas update forces the compositor to re-blend\n // the widget panel over the host page's WebGL canvas, which judders\n // the 3D scene if done at 60fps continuously.\n frameParity ^= 1;\n if (frameParity) {\n animationFrameRef.current = requestAnimationFrame(draw);\n return;\n }\n timeRef.current += 0.16;\n analyser.getByteFrequencyData(dataArray);\n {\n let t = 0;\n for (let i = 0; i < bufferLength; i++) t += dataArray[i] || 0;\n if (!isActiveRef.current || t / (bufferLength * 255) < 0.01) {\n // Fade the ring out over a few frames, then hold it static.\n if (idleFramesPainted > 20) {\n animationFrameRef.current = requestAnimationFrame(draw);\n return;\n }\n idleFramesPainted++;\n } else {\n idleFramesPainted = 0;\n }\n }\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n const centerX = canvas.width / 2;\n const centerY = canvas.height / 2;\n // The bars should surround the character, not be clipped inside\n // Character is 120px (radius 60px), visualizer canvas is 220px (radius 110px)\n const characterRadius = 60; // Half of 120px character image\n const innerRadius = characterRadius; // Start bars at edge of character\n const outerRadius = avatarRadius; // Extend to edge of visualizer canvas\n const maxBarLength = outerRadius - innerRadius;\n\n ctx.save();\n // No clipping - let bars render freely around the circle\n\n const angleStep = (Math.PI * 2) / barCount;\n\n // Calculate overall audio level for speaking detection\n let total = 0;\n for (let i = 0; i < bufferLength; i++) total += isActiveRef.current ? (dataArray[i] || 0) : 0;\n const overallLevel = total / (bufferLength * 255);\n\n // Speaking detection\n const speakingThreshold = 0.1;\n const isSpeaking = isActiveRef.current && overallLevel > speakingThreshold;\n if (onSpeakingChange && isSpeaking !== previousSpeakingStateRef.current) {\n previousSpeakingStateRef.current = isSpeaking;\n onSpeakingChange(isSpeaking);\n }\n\n // Precompute band edges if not ready yet\n if (!bandEdgesRef.current) {\n bandEdgesRef.current = Array.from({ length: barCount + 1 }, (_, k) =>\n Math.floor((k / barCount) * bufferLength)\n );\n }\n const edges = bandEdgesRef.current;\n\n // Traveling wave parameters\n const waveRevolutions = 2;\n const phasePerBar = (Math.PI * 2 * waveRevolutions) / barCount;\n const baseWaveAmp = 0.35;\n const waveAmp = baseWaveAmp * (0.3 + 0.7 * overallLevel);\n\n for (let i = 0; i < barCount; i++) {\n const angle = i * angleStep - Math.PI / 2;\n\n // Calculate average energy for this bar's frequency band\n const startFreq = edges[i];\n const endFreq = edges[i + 1];\n let sum = 0;\n let count = 0;\n for (let f = startFreq; f < endFreq && f < bufferLength; f++) {\n sum += isActiveRef.current ? (dataArray[f] || 0) : 0;\n count++;\n }\n const bandAvg = count > 0 ? sum / (count * 255) : 0;\n\n // Mix band-specific energy with overall level\n const energy = 0.4 * bandAvg + 0.6 * overallLevel;\n\n // Apply traveling wave modulation\n const wavePhase = i * phasePerBar;\n const wave = 1 + waveAmp * Math.sin(timeRef.current + wavePhase);\n\n // Final intensity\n const intensity = Math.min(1, energy * wave);\n\n // Convert to bar length\n const length = Math.max(maxBarLength * 0.03, intensity * maxBarLength * 0.95);\n\n // Coordinates\n const startX = centerX + Math.cos(angle) * innerRadius;\n const startY = centerY + Math.sin(angle) * innerRadius;\n const endX = centerX + Math.cos(angle) * (innerRadius + length);\n const endY = centerY + Math.sin(angle) * (innerRadius + length);\n\n // Draw\n ctx.strokeStyle = color;\n ctx.lineWidth = 5;\n ctx.lineCap = 'round';\n ctx.globalAlpha = opacity * (0.5 + 0.5 * intensity);\n\n ctx.beginPath();\n ctx.moveTo(startX, startY);\n ctx.lineTo(endX, endY);\n ctx.stroke();\n }\n\n ctx.globalAlpha = 1;\n ctx.restore();\n\n animationFrameRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n clearTimeout(setupTimeout);\n if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);\n if (sourceNodeRef.current) sourceNodeRef.current.disconnect();\n if (analyserRef.current) analyserRef.current.disconnect();\n if (audioContextRef.current && audioContextRef.current.state !== 'closed') {\n audioContextRef.current.close();\n }\n room.off('trackSubscribed', handleTrackSubscribed);\n room.off('participantConnected', handleParticipantConnected);\n };\n }, [room, size, color, opacity, avatarRadius, barCount, onSpeakingChange]);\n\n return (\n <VisualizerContainer style={{ width: size, height: size }}>\n <Canvas ref={canvasRef} />\n </VisualizerContainer>\n );\n};\n\n"]}
|
|
1
|
+
{"version":3,"file":"AudioVisualizer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/AudioVisualizer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef } from 'react';\nimport styled from 'styled-components';\nimport { Room } from 'livekit-client';\n\nconst VisualizerContainer = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n z-index: 1;\n pointer-events: none;\n border-radius: 50%;\n overflow: visible;\n`;\n\nconst Canvas = styled.canvas`\n display: block;\n width: 100%;\n height: 100%;\n`;\n\ninterface AudioVisualizerProps {\n /** LiveKit room instance containing the remote participant's audio track */\n room: Room | null;\n /** Canvas size in pixels (width and height) */\n size?: number;\n /** CSS color value for the bars */\n color?: string;\n /** Base opacity of the bars (0-1), actual opacity varies with audio intensity */\n opacity?: number;\n /** Radius of the circular visualization area in pixels */\n avatarRadius?: number;\n /** Number of radial bars to display around the circle */\n barCount?: number;\n /** Callback function called when speaking state changes */\n onSpeakingChange?: (isSpeaking: boolean) => void;\n}\n\n/**\n * Circular Audio Visualizer Component\n * \n * A real-time circular audio visualization component that displays radial bars arranged\n * in a circle around an avatar. The visualization reacts to the remote participant's\n * (bot) audio output from a LiveKit room, using logarithmic frequency bands and a\n * traveling wave animation effect.\n * \n * Features:\n * - Circular radial bar visualization with configurable bar count\n * - Logarithmic frequency band distribution (low frequencies distributed around the ring)\n * - Traveling wave animation that propagates around the circle\n * - Speaking detection with callback support\n * - Automatic track detection and reconnection\n * - Canvas-based rendering for smooth animations\n */\nexport const AudioVisualizer: React.FC<AudioVisualizerProps> = ({\n room,\n size = 350,\n color = '#10b981',\n opacity = 0.4,\n avatarRadius = 80,\n barCount = 64,\n onSpeakingChange,\n}) => {\n // Refs for canvas and Web Audio API nodes\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const animationFrameRef = useRef<number | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const sourceNodeRef = useRef<MediaStreamAudioSourceNode | null>(null);\n const isActiveRef = useRef(false);\n \n // Refs for animation and state management\n const timeRef = useRef(0);\n const previousSpeakingStateRef = useRef(false);\n const bandEdgesRef = useRef<number[] | null>(null);\n\n useEffect(() => {\n if (!room) return;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n canvas.width = size;\n canvas.height = size;\n\n // Initialize Web Audio API context and analyser\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n analyser.smoothingTimeConstant = 0.6;\n\n audioContextRef.current = audioContext;\n analyserRef.current = analyser;\n\n /**\n * Builds logarithmically-spaced frequency band edges.\n * This distributes low-frequency energy (which has more power) evenly around\n * the circular visualization, rather than clustering it at the start.\n */\n const buildLogBands = () => {\n const nyquist = audioContext.sampleRate / 2;\n const bufferLength = analyser.frequencyBinCount;\n const minHz = 60;\n const maxHz = Math.min(8000, nyquist);\n const edges = Array.from({ length: barCount + 1 }, (_, k) => {\n const hz = minHz * Math.pow(maxHz / minHz, k / barCount);\n const bin = Math.max(\n 0,\n Math.min(bufferLength - 1, Math.floor((hz / nyquist) * bufferLength))\n );\n return bin;\n });\n // Ensure strictly increasing edges (no zero-width bands)\n for (let i = 1; i < edges.length; i++) {\n if (edges[i] <= edges[i - 1]) edges[i] = Math.min(edges[i - 1] + 1, bufferLength - 1);\n }\n bandEdgesRef.current = edges;\n };\n\n /**\n * Finds the bot participant from remote participants.\n */\n const findBotParticipant = (remoteParticipants: Map<string, any>, localParticipant: any) => {\n const participants = Array.from(remoteParticipants.values()).filter(\n (p) => p !== localParticipant && p !== room.localParticipant\n );\n\n if (participants.length === 0) {\n return null;\n }\n\n // Prefer participants with audio tracks (bot typically has audio)\n const participantsWithAudio = participants.filter((participant) => {\n if (!participant.trackPublications) return false;\n const audioTracks = Array.from(participant.trackPublications.values()).filter(\n (p: any) => p.kind === 'audio' && p.track\n );\n return audioTracks.length > 0;\n });\n\n return participantsWithAudio.length > 0 ? participantsWithAudio[0] : participants[0];\n };\n\n /**\n * Sets up the audio source by connecting the remote participant's (bot) audio track\n * to the Web Audio API analyser.\n */\n const setupAudioSource = async () => {\n try {\n if (audioContext.state === 'suspended') await audioContext.resume();\n\n const remoteParticipants = room.remoteParticipants;\n if (remoteParticipants.size === 0) {\n isActiveRef.current = false;\n return;\n }\n\n const botParticipant = findBotParticipant(remoteParticipants, room.localParticipant);\n if (!botParticipant) {\n isActiveRef.current = false;\n return;\n }\n \n const audioTracks = Array.from(botParticipant.trackPublications.values()).filter(\n (p: any) => p.kind === 'audio' && p.track\n );\n \n if (audioTracks.length === 0) {\n isActiveRef.current = false;\n return;\n }\n\n const liveKitTrack = (audioTracks[0] as any).track;\n const mediaStreamTrack = liveKitTrack.mediaStreamTrack;\n if (!mediaStreamTrack) {\n isActiveRef.current = false;\n return;\n }\n\n const mediaStream = new MediaStream([mediaStreamTrack]);\n\n if (sourceNodeRef.current) sourceNodeRef.current.disconnect();\n const source = audioContext.createMediaStreamSource(mediaStream);\n source.connect(analyser);\n sourceNodeRef.current = source;\n\n // Build bands after context is ready\n buildLogBands();\n\n isActiveRef.current = true;\n } catch {\n isActiveRef.current = false;\n }\n };\n\n setupAudioSource();\n const setupTimeout = setTimeout(setupAudioSource, 500);\n\n const handleTrackSubscribed = (track: any, publication: any, participant: any) => {\n if (track && track.kind === 'audio' && participant !== room.localParticipant) {\n setTimeout(setupAudioSource, 200);\n }\n };\n \n const handleParticipantConnected = (participant: any) => {\n if (participant !== room.localParticipant) setTimeout(setupAudioSource, 200);\n };\n\n room.on('trackSubscribed', handleTrackSubscribed);\n room.on('participantConnected', handleParticipantConnected);\n\n /**\n * Main rendering function that draws the circular audio visualization.\n */\n const bufferLength = analyser.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n\n const draw = () => {\n timeRef.current += 0.08;\n analyser.getByteFrequencyData(dataArray);\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n const centerX = canvas.width / 2;\n const centerY = canvas.height / 2;\n // The bars should surround the character, not be clipped inside\n // Character is 120px (radius 60px), visualizer canvas is 220px (radius 110px)\n const characterRadius = 60; // Half of 120px character image\n const innerRadius = characterRadius; // Start bars at edge of character\n const outerRadius = avatarRadius; // Extend to edge of visualizer canvas\n const maxBarLength = outerRadius - innerRadius;\n\n ctx.save();\n // No clipping - let bars render freely around the circle\n\n const angleStep = (Math.PI * 2) / barCount;\n\n // Calculate overall audio level for speaking detection\n let total = 0;\n for (let i = 0; i < bufferLength; i++) total += isActiveRef.current ? (dataArray[i] || 0) : 0;\n const overallLevel = total / (bufferLength * 255);\n\n // Speaking detection\n const speakingThreshold = 0.1;\n const isSpeaking = isActiveRef.current && overallLevel > speakingThreshold;\n if (onSpeakingChange && isSpeaking !== previousSpeakingStateRef.current) {\n previousSpeakingStateRef.current = isSpeaking;\n onSpeakingChange(isSpeaking);\n }\n\n // Precompute band edges if not ready yet\n if (!bandEdgesRef.current) {\n bandEdgesRef.current = Array.from({ length: barCount + 1 }, (_, k) =>\n Math.floor((k / barCount) * bufferLength)\n );\n }\n const edges = bandEdgesRef.current;\n\n // Traveling wave parameters\n const waveRevolutions = 2;\n const phasePerBar = (Math.PI * 2 * waveRevolutions) / barCount;\n const baseWaveAmp = 0.35;\n const waveAmp = baseWaveAmp * (0.3 + 0.7 * overallLevel);\n\n for (let i = 0; i < barCount; i++) {\n const angle = i * angleStep - Math.PI / 2;\n\n // Calculate average energy for this bar's frequency band\n const startFreq = edges[i];\n const endFreq = edges[i + 1];\n let sum = 0;\n let count = 0;\n for (let f = startFreq; f < endFreq && f < bufferLength; f++) {\n sum += isActiveRef.current ? (dataArray[f] || 0) : 0;\n count++;\n }\n const bandAvg = count > 0 ? sum / (count * 255) : 0;\n\n // Mix band-specific energy with overall level\n const energy = 0.4 * bandAvg + 0.6 * overallLevel;\n\n // Apply traveling wave modulation\n const wavePhase = i * phasePerBar;\n const wave = 1 + waveAmp * Math.sin(timeRef.current + wavePhase);\n\n // Final intensity\n const intensity = Math.min(1, energy * wave);\n\n // Convert to bar length\n const length = Math.max(maxBarLength * 0.03, intensity * maxBarLength * 0.95);\n\n // Coordinates\n const startX = centerX + Math.cos(angle) * innerRadius;\n const startY = centerY + Math.sin(angle) * innerRadius;\n const endX = centerX + Math.cos(angle) * (innerRadius + length);\n const endY = centerY + Math.sin(angle) * (innerRadius + length);\n\n // Draw\n ctx.strokeStyle = color;\n ctx.lineWidth = 5;\n ctx.lineCap = 'round';\n ctx.globalAlpha = opacity * (0.5 + 0.5 * intensity);\n\n ctx.beginPath();\n ctx.moveTo(startX, startY);\n ctx.lineTo(endX, endY);\n ctx.stroke();\n }\n\n ctx.globalAlpha = 1;\n ctx.restore();\n\n animationFrameRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n clearTimeout(setupTimeout);\n if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current);\n if (sourceNodeRef.current) sourceNodeRef.current.disconnect();\n if (analyserRef.current) analyserRef.current.disconnect();\n if (audioContextRef.current && audioContextRef.current.state !== 'closed') {\n audioContextRef.current.close();\n }\n room.off('trackSubscribed', handleTrackSubscribed);\n room.off('participantConnected', handleParticipantConnected);\n };\n }, [room, size, color, opacity, avatarRadius, barCount, onSpeakingChange]);\n\n return (\n <VisualizerContainer style={{ width: size, height: size }}>\n <Canvas ref={canvasRef} />\n </VisualizerContainer>\n );\n};\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAmG5D,CAAC"}
|
|
@@ -1,42 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { parseInlineMarkdown } from "../../../../utils/inlineMarkdown.js";
|
|
4
|
-
const linkStyle = {
|
|
5
|
-
color: "#10b981",
|
|
6
|
-
textDecoration: "underline",
|
|
7
|
-
wordBreak: "break-all",
|
|
8
|
-
};
|
|
9
|
-
const mediaStyle = {
|
|
10
|
-
display: "block",
|
|
11
|
-
maxWidth: "100%",
|
|
12
|
-
maxHeight: 240,
|
|
13
|
-
marginTop: 6,
|
|
14
|
-
borderRadius: 8,
|
|
15
|
-
};
|
|
16
|
-
/** Inline preview for an image or video URL, shown under its link. */
|
|
17
|
-
const MediaPreview = ({ node }) => {
|
|
18
|
-
if (node.media === "image") {
|
|
19
|
-
return _jsx("img", { src: node.href, alt: node.label, loading: "lazy", style: mediaStyle });
|
|
20
|
-
}
|
|
21
|
-
if (node.media === "video") {
|
|
22
|
-
return _jsx("video", { src: node.href, controls: true, preload: "metadata", style: mediaStyle });
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
};
|
|
26
|
-
const renderNode = (node, key) => {
|
|
27
|
-
switch (node.kind) {
|
|
28
|
-
case "strong":
|
|
29
|
-
return _jsx("strong", { children: node.text }, key);
|
|
30
|
-
case "em":
|
|
31
|
-
return _jsx("em", { children: node.text }, key);
|
|
32
|
-
case "link":
|
|
33
|
-
return (_jsxs(React.Fragment, { children: [_jsx("a", { href: node.href, target: "_blank", rel: "noopener noreferrer", style: linkStyle, children: node.label }), _jsx(MediaPreview, { node: node })] }, key));
|
|
34
|
-
case "image":
|
|
35
|
-
return _jsx("img", { src: node.src, alt: node.alt, loading: "lazy", style: mediaStyle }, key);
|
|
36
|
-
default:
|
|
37
|
-
return _jsx(React.Fragment, { children: node.text }, key);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
3
|
export const MarkdownRenderer = ({ text }) => {
|
|
41
4
|
// Convert markdown to JSX elements
|
|
42
5
|
const renderMarkdown = (input) => {
|
|
@@ -48,8 +11,50 @@ export const MarkdownRenderer = ({ text }) => {
|
|
|
48
11
|
// Split by actual newlines
|
|
49
12
|
const lines = normalizedText.split('\n');
|
|
50
13
|
return lines.map((line, lineIndex) => {
|
|
51
|
-
//
|
|
52
|
-
const
|
|
14
|
+
// Process markdown within each line
|
|
15
|
+
const processLine = (text) => {
|
|
16
|
+
const parts = [];
|
|
17
|
+
let remaining = text;
|
|
18
|
+
let keyCounter = 0;
|
|
19
|
+
// Process bold and italic markdown
|
|
20
|
+
// Bold: **text** or __text__
|
|
21
|
+
// Italic: *text* or _text_
|
|
22
|
+
const markdownRegex = /(\*\*|__)(.*?)\1|\*([^*]+)\*|_([^_]+)_/g;
|
|
23
|
+
let lastIndex = 0;
|
|
24
|
+
let match;
|
|
25
|
+
while ((match = markdownRegex.exec(remaining)) !== null) {
|
|
26
|
+
// Add text before the match
|
|
27
|
+
if (match.index > lastIndex) {
|
|
28
|
+
const textBefore = remaining.substring(lastIndex, match.index);
|
|
29
|
+
if (textBefore) {
|
|
30
|
+
parts.push(_jsx(React.Fragment, { children: textBefore }, `text-${lineIndex}-${keyCounter++}`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Determine if it's bold or italic
|
|
34
|
+
if (match[1] && match[2]) {
|
|
35
|
+
// Bold text (** or __)
|
|
36
|
+
parts.push(_jsx("strong", { children: match[2] }, `bold-${lineIndex}-${keyCounter++}`));
|
|
37
|
+
}
|
|
38
|
+
else if (match[3]) {
|
|
39
|
+
// Italic text (*)
|
|
40
|
+
parts.push(_jsx("em", { children: match[3] }, `italic-${lineIndex}-${keyCounter++}`));
|
|
41
|
+
}
|
|
42
|
+
else if (match[4]) {
|
|
43
|
+
// Italic text (_)
|
|
44
|
+
parts.push(_jsx("em", { children: match[4] }, `italic-${lineIndex}-${keyCounter++}`));
|
|
45
|
+
}
|
|
46
|
+
lastIndex = match.index + match[0].length;
|
|
47
|
+
}
|
|
48
|
+
// Add remaining text
|
|
49
|
+
if (lastIndex < remaining.length) {
|
|
50
|
+
const textAfter = remaining.substring(lastIndex);
|
|
51
|
+
if (textAfter) {
|
|
52
|
+
parts.push(_jsx(React.Fragment, { children: textAfter }, `text-${lineIndex}-${keyCounter++}`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return parts;
|
|
56
|
+
};
|
|
57
|
+
const processedLine = processLine(line);
|
|
53
58
|
// Handle empty lines (creates paragraph spacing)
|
|
54
59
|
if (line.trim() === "" && lineIndex > 0) {
|
|
55
60
|
return _jsx("br", {}, `br-${lineIndex}`);
|