@convai/web-sdk 0.3.1-beta.3 → 0.3.2-beta.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.
Files changed (255) hide show
  1. package/README.md +535 -1077
  2. package/dist/core/AudioManager.d.ts.map +1 -0
  3. package/dist/core/AudioManager.js +262 -0
  4. package/dist/core/AudioManager.js.map +1 -0
  5. package/dist/core/BlendshapeQueue.d.ts +128 -0
  6. package/dist/core/BlendshapeQueue.d.ts.map +1 -0
  7. package/dist/core/BlendshapeQueue.js +229 -0
  8. package/dist/core/BlendshapeQueue.js.map +1 -0
  9. package/dist/{types/core → core}/ConvaiClient.d.ts +19 -15
  10. package/dist/core/ConvaiClient.d.ts.map +1 -0
  11. package/dist/core/ConvaiClient.js +623 -0
  12. package/dist/core/ConvaiClient.js.map +1 -0
  13. package/dist/core/EventEmitter.d.ts.map +1 -0
  14. package/dist/core/EventEmitter.js +68 -0
  15. package/dist/core/EventEmitter.js.map +1 -0
  16. package/dist/{types/core → core}/MessageHandler.d.ts +7 -0
  17. package/dist/core/MessageHandler.d.ts.map +1 -0
  18. package/dist/core/MessageHandler.js +333 -0
  19. package/dist/core/MessageHandler.js.map +1 -0
  20. package/dist/core/ScreenShareManager.d.ts.map +1 -0
  21. package/dist/core/ScreenShareManager.js +207 -0
  22. package/dist/core/ScreenShareManager.js.map +1 -0
  23. package/dist/core/VideoManager.d.ts.map +1 -0
  24. package/dist/core/VideoManager.js +205 -0
  25. package/dist/core/VideoManager.js.map +1 -0
  26. package/dist/{types/core → core}/index.d.ts +2 -0
  27. package/dist/core/index.d.ts.map +1 -0
  28. package/dist/core/index.js +14 -1970
  29. package/dist/core/index.js.map +1 -0
  30. package/dist/{types/core → core}/types.d.ts +12 -21
  31. package/dist/core/types.d.ts.map +1 -0
  32. package/dist/core/types.js +2 -0
  33. package/dist/core/types.js.map +1 -0
  34. package/dist/dev.d.ts +12 -0
  35. package/dist/dev.d.ts.map +1 -0
  36. package/dist/dev.js +12 -0
  37. package/dist/dev.js.map +1 -0
  38. package/dist/index.d.ts +4 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +6 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/lipsync-helpers/arkitBlendshapeHelpers.d.ts.map +1 -0
  43. package/dist/lipsync-helpers/arkitBlendshapeHelpers.js +201 -0
  44. package/dist/lipsync-helpers/arkitBlendshapeHelpers.js.map +1 -0
  45. package/dist/lipsync-helpers/arkitOrder61.d.ts.map +1 -0
  46. package/dist/lipsync-helpers/arkitOrder61.js +287 -0
  47. package/dist/lipsync-helpers/arkitOrder61.js.map +1 -0
  48. package/dist/lipsync-helpers/arkitPhonemeReference.d.ts.map +1 -0
  49. package/dist/lipsync-helpers/arkitPhonemeReference.js +362 -0
  50. package/dist/lipsync-helpers/arkitPhonemeReference.js.map +1 -0
  51. package/dist/{types/lipsync-helpers → lipsync-helpers}/index.d.ts +1 -0
  52. package/dist/lipsync-helpers/index.d.ts.map +1 -0
  53. package/dist/lipsync-helpers/index.js +20 -1165
  54. package/dist/lipsync-helpers/index.js.map +1 -0
  55. package/dist/lipsync-helpers/metahumanOrder251.d.ts +115 -0
  56. package/dist/lipsync-helpers/metahumanOrder251.d.ts.map +1 -0
  57. package/dist/lipsync-helpers/metahumanOrder251.js +432 -0
  58. package/dist/lipsync-helpers/metahumanOrder251.js.map +1 -0
  59. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.d.ts.map +1 -0
  60. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.js +315 -0
  61. package/dist/lipsync-helpers/neurosyncBlendshapeMapper.js.map +1 -0
  62. package/dist/react/components/ConvaiWidget.d.ts +68 -0
  63. package/dist/react/components/ConvaiWidget.d.ts.map +1 -0
  64. package/dist/react/components/ConvaiWidget.js +505 -0
  65. package/dist/react/components/ConvaiWidget.js.map +1 -0
  66. package/dist/react/components/index.d.ts +2 -0
  67. package/dist/react/components/index.d.ts.map +1 -0
  68. package/dist/react/components/index.js +3 -0
  69. package/dist/react/components/index.js.map +1 -0
  70. package/dist/react/components/rtc-widget/components/AudioSettingsPanel.d.ts +10 -0
  71. package/dist/react/components/rtc-widget/components/AudioSettingsPanel.d.ts.map +1 -0
  72. package/dist/react/components/rtc-widget/components/AudioSettingsPanel.js +316 -0
  73. package/dist/react/components/rtc-widget/components/AudioSettingsPanel.js.map +1 -0
  74. package/dist/react/components/rtc-widget/components/AudioVisualizer.d.ts +36 -0
  75. package/dist/react/components/rtc-widget/components/AudioVisualizer.d.ts.map +1 -0
  76. package/dist/react/components/rtc-widget/components/AudioVisualizer.js +259 -0
  77. package/dist/react/components/rtc-widget/components/AudioVisualizer.js.map +1 -0
  78. package/dist/react/components/rtc-widget/components/ConviMessage.d.ts +10 -0
  79. package/dist/react/components/rtc-widget/components/ConviMessage.d.ts.map +1 -0
  80. package/dist/react/components/rtc-widget/components/ConviMessage.js +14 -0
  81. package/dist/react/components/rtc-widget/components/ConviMessage.js.map +1 -0
  82. package/dist/react/components/rtc-widget/components/FloatingVideo.d.ts +9 -0
  83. package/dist/react/components/rtc-widget/components/FloatingVideo.d.ts.map +1 -0
  84. package/dist/react/components/rtc-widget/components/FloatingVideo.js +122 -0
  85. package/dist/react/components/rtc-widget/components/FloatingVideo.js.map +1 -0
  86. package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts +7 -0
  87. package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts.map +1 -0
  88. package/dist/react/components/rtc-widget/components/MarkdownRenderer.js +68 -0
  89. package/dist/react/components/rtc-widget/components/MarkdownRenderer.js.map +1 -0
  90. package/dist/react/components/rtc-widget/components/MessageBubble.d.ts +10 -0
  91. package/dist/react/components/rtc-widget/components/MessageBubble.d.ts.map +1 -0
  92. package/dist/react/components/rtc-widget/components/MessageBubble.js +23 -0
  93. package/dist/react/components/rtc-widget/components/MessageBubble.js.map +1 -0
  94. package/dist/react/components/rtc-widget/components/MessageList.d.ts +11 -0
  95. package/dist/react/components/rtc-widget/components/MessageList.d.ts.map +1 -0
  96. package/dist/react/components/rtc-widget/components/MessageList.js +89 -0
  97. package/dist/react/components/rtc-widget/components/MessageList.js.map +1 -0
  98. package/dist/react/components/rtc-widget/components/UserMessage.d.ts +9 -0
  99. package/dist/react/components/rtc-widget/components/UserMessage.d.ts.map +1 -0
  100. package/dist/react/components/rtc-widget/components/UserMessage.js +15 -0
  101. package/dist/react/components/rtc-widget/components/UserMessage.js.map +1 -0
  102. package/dist/react/components/rtc-widget/components/conviComponents/ConviButton.d.ts +6 -0
  103. package/dist/react/components/rtc-widget/components/conviComponents/ConviButton.d.ts.map +1 -0
  104. package/dist/react/components/rtc-widget/components/conviComponents/ConviButton.js +15 -0
  105. package/dist/react/components/rtc-widget/components/conviComponents/ConviButton.js.map +1 -0
  106. package/dist/react/components/rtc-widget/components/conviComponents/ConviFooter.d.ts +25 -0
  107. package/dist/react/components/rtc-widget/components/conviComponents/ConviFooter.d.ts.map +1 -0
  108. package/dist/react/components/rtc-widget/components/conviComponents/ConviFooter.js +172 -0
  109. package/dist/react/components/rtc-widget/components/conviComponents/ConviFooter.js.map +1 -0
  110. package/dist/react/components/rtc-widget/components/conviComponents/ConviHeader.d.ts +17 -0
  111. package/dist/react/components/rtc-widget/components/conviComponents/ConviHeader.d.ts.map +1 -0
  112. package/dist/react/components/rtc-widget/components/conviComponents/ConviHeader.js +66 -0
  113. package/dist/react/components/rtc-widget/components/conviComponents/ConviHeader.js.map +1 -0
  114. package/dist/react/components/rtc-widget/components/conviComponents/SettingsTray.d.ts +12 -0
  115. package/dist/react/components/rtc-widget/components/conviComponents/SettingsTray.d.ts.map +1 -0
  116. package/dist/react/components/rtc-widget/components/conviComponents/SettingsTray.js +68 -0
  117. package/dist/react/components/rtc-widget/components/conviComponents/SettingsTray.js.map +1 -0
  118. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts +12 -0
  119. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts.map +1 -0
  120. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js +255 -0
  121. package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js.map +1 -0
  122. package/dist/react/components/rtc-widget/components/conviComponents/index.d.ts +6 -0
  123. package/dist/react/components/rtc-widget/components/conviComponents/index.d.ts.map +1 -0
  124. package/dist/react/components/rtc-widget/components/conviComponents/index.js +6 -0
  125. package/dist/react/components/rtc-widget/components/conviComponents/index.js.map +1 -0
  126. package/dist/react/components/rtc-widget/components/index.d.ts +9 -0
  127. package/dist/react/components/rtc-widget/components/index.d.ts.map +1 -0
  128. package/dist/react/components/rtc-widget/components/index.js +15 -0
  129. package/dist/react/components/rtc-widget/components/index.js.map +1 -0
  130. package/dist/react/components/rtc-widget/index.d.ts +6 -0
  131. package/dist/react/components/rtc-widget/index.d.ts.map +1 -0
  132. package/dist/react/components/rtc-widget/index.js +9 -0
  133. package/dist/react/components/rtc-widget/index.js.map +1 -0
  134. package/dist/react/components/rtc-widget/styles/framerConfig.d.ts +116 -0
  135. package/dist/react/components/rtc-widget/styles/framerConfig.d.ts.map +1 -0
  136. package/dist/react/components/rtc-widget/styles/framerConfig.js +73 -0
  137. package/dist/react/components/rtc-widget/styles/framerConfig.js.map +1 -0
  138. package/dist/react/components/rtc-widget/styles/icons.d.ts +28 -0
  139. package/dist/react/components/rtc-widget/styles/icons.d.ts.map +1 -0
  140. package/dist/react/components/rtc-widget/styles/icons.js +257 -0
  141. package/dist/react/components/rtc-widget/styles/icons.js.map +1 -0
  142. package/dist/react/components/rtc-widget/styles/index.d.ts +6 -0
  143. package/dist/react/components/rtc-widget/styles/index.d.ts.map +1 -0
  144. package/dist/react/components/rtc-widget/styles/index.js +9 -0
  145. package/dist/react/components/rtc-widget/styles/index.js.map +1 -0
  146. package/dist/react/components/rtc-widget/styles/styledComponents.d.ts +90 -0
  147. package/dist/react/components/rtc-widget/styles/styledComponents.d.ts.map +1 -0
  148. package/dist/react/components/rtc-widget/styles/styledComponents.js +663 -0
  149. package/dist/react/components/rtc-widget/styles/styledComponents.js.map +1 -0
  150. package/dist/react/components/rtc-widget/styles/theme.d.ts +188 -0
  151. package/dist/react/components/rtc-widget/styles/theme.d.ts.map +1 -0
  152. package/dist/react/components/rtc-widget/styles/theme.js +290 -0
  153. package/dist/react/components/rtc-widget/styles/theme.js.map +1 -0
  154. package/dist/react/components/rtc-widget/types/index.d.ts +60 -0
  155. package/dist/react/components/rtc-widget/types/index.d.ts.map +1 -0
  156. package/dist/react/components/rtc-widget/types/index.js +2 -0
  157. package/dist/react/components/rtc-widget/types/index.js.map +1 -0
  158. package/dist/react/hooks/index.d.ts +4 -0
  159. package/dist/react/hooks/index.d.ts.map +1 -0
  160. package/dist/react/hooks/index.js +6 -0
  161. package/dist/react/hooks/index.js.map +1 -0
  162. package/dist/react/hooks/useCharacterInfo.d.ts +17 -0
  163. package/dist/react/hooks/useCharacterInfo.d.ts.map +1 -0
  164. package/dist/react/hooks/useCharacterInfo.js +60 -0
  165. package/dist/react/hooks/useCharacterInfo.js.map +1 -0
  166. package/dist/react/hooks/useConvaiClient.d.ts +35 -0
  167. package/dist/react/hooks/useConvaiClient.d.ts.map +1 -0
  168. package/dist/react/hooks/useConvaiClient.js +183 -0
  169. package/dist/react/hooks/useConvaiClient.js.map +1 -0
  170. package/dist/react/hooks/useLocalCameraTrack.d.ts +22 -0
  171. package/dist/react/hooks/useLocalCameraTrack.d.ts.map +1 -0
  172. package/dist/react/hooks/useLocalCameraTrack.js +34 -0
  173. package/dist/react/hooks/useLocalCameraTrack.js.map +1 -0
  174. package/dist/react/index.d.ts +7 -0
  175. package/dist/react/index.d.ts.map +1 -0
  176. package/dist/react/index.js +13 -0
  177. package/dist/react/index.js.map +1 -0
  178. package/dist/types/index.d.ts.map +1 -0
  179. package/dist/types/index.js +2 -0
  180. package/dist/types/index.js.map +1 -0
  181. package/dist/utils/LatencyMonitor.d.ts.map +1 -0
  182. package/dist/utils/LatencyMonitor.js +136 -0
  183. package/dist/utils/LatencyMonitor.js.map +1 -0
  184. package/dist/utils/logger.d.ts.map +1 -0
  185. package/dist/utils/logger.js +96 -0
  186. package/dist/utils/logger.js.map +1 -0
  187. package/dist/utils/speakerManagement.d.ts.map +1 -0
  188. package/dist/utils/speakerManagement.js +64 -0
  189. package/dist/utils/speakerManagement.js.map +1 -0
  190. package/dist/{types/vanilla → vanilla}/AudioRenderer.d.ts +5 -0
  191. package/dist/vanilla/AudioRenderer.d.ts.map +1 -0
  192. package/dist/vanilla/AudioRenderer.js +135 -0
  193. package/dist/vanilla/AudioRenderer.js.map +1 -0
  194. package/dist/vanilla/ConvaiWidget.d.ts.map +1 -0
  195. package/dist/vanilla/ConvaiWidget.js +1786 -0
  196. package/dist/vanilla/ConvaiWidget.js.map +1 -0
  197. package/dist/vanilla/icons.d.ts.map +1 -0
  198. package/dist/vanilla/icons.js +222 -0
  199. package/dist/vanilla/icons.js.map +1 -0
  200. package/dist/{types/vanilla → vanilla}/index.d.ts +1 -3
  201. package/dist/vanilla/index.d.ts.map +1 -0
  202. package/dist/vanilla/index.js +20 -5509
  203. package/dist/vanilla/index.js.map +1 -0
  204. package/dist/vanilla/styles.d.ts.map +1 -0
  205. package/dist/vanilla/styles.js +287 -0
  206. package/dist/vanilla/styles.js.map +1 -0
  207. package/dist/vanilla/types.d.ts +43 -0
  208. package/dist/vanilla/types.d.ts.map +1 -0
  209. package/dist/vanilla/types.js +2 -0
  210. package/dist/vanilla/types.js.map +1 -0
  211. package/package.json +33 -38
  212. package/CHANGELOG.md +0 -165
  213. package/dist/core/index.cjs +0 -1977
  214. package/dist/lipsync-helpers/index.cjs +0 -1195
  215. package/dist/types/core/AudioManager.d.ts.map +0 -1
  216. package/dist/types/core/ConvaiClient.d.ts.map +0 -1
  217. package/dist/types/core/EventEmitter.d.ts.map +0 -1
  218. package/dist/types/core/MessageHandler.d.ts.map +0 -1
  219. package/dist/types/core/ScreenShareManager.d.ts.map +0 -1
  220. package/dist/types/core/VideoManager.d.ts.map +0 -1
  221. package/dist/types/core/index.d.ts.map +0 -1
  222. package/dist/types/core/types.d.ts.map +0 -1
  223. package/dist/types/lipsync-helpers/arkitBlendshapeHelpers.d.ts.map +0 -1
  224. package/dist/types/lipsync-helpers/arkitOrder61.d.ts.map +0 -1
  225. package/dist/types/lipsync-helpers/arkitPhonemeReference.d.ts.map +0 -1
  226. package/dist/types/lipsync-helpers/index.d.ts.map +0 -1
  227. package/dist/types/lipsync-helpers/neurosyncBlendshapeMapper.d.ts.map +0 -1
  228. package/dist/types/types/index.d.ts.map +0 -1
  229. package/dist/types/utils/LatencyMonitor.d.ts.map +0 -1
  230. package/dist/types/utils/logger.d.ts.map +0 -1
  231. package/dist/types/utils/speakerManagement.d.ts.map +0 -1
  232. package/dist/types/vanilla/AudioRenderer.d.ts.map +0 -1
  233. package/dist/types/vanilla/ConvaiWidget.d.ts.map +0 -1
  234. package/dist/types/vanilla/icons.d.ts.map +0 -1
  235. package/dist/types/vanilla/index.d.ts.map +0 -1
  236. package/dist/types/vanilla/styles.d.ts.map +0 -1
  237. package/dist/types/vanilla/types.d.ts +0 -106
  238. package/dist/types/vanilla/types.d.ts.map +0 -1
  239. package/dist/umd/convai.umd.js +0 -1
  240. package/dist/vanilla/index.cjs +0 -5559
  241. /package/dist/{types/core → core}/AudioManager.d.ts +0 -0
  242. /package/dist/{types/core → core}/EventEmitter.d.ts +0 -0
  243. /package/dist/{types/core → core}/ScreenShareManager.d.ts +0 -0
  244. /package/dist/{types/core → core}/VideoManager.d.ts +0 -0
  245. /package/dist/{types/lipsync-helpers → lipsync-helpers}/arkitBlendshapeHelpers.d.ts +0 -0
  246. /package/dist/{types/lipsync-helpers → lipsync-helpers}/arkitOrder61.d.ts +0 -0
  247. /package/dist/{types/lipsync-helpers → lipsync-helpers}/arkitPhonemeReference.d.ts +0 -0
  248. /package/dist/{types/lipsync-helpers → lipsync-helpers}/neurosyncBlendshapeMapper.d.ts +0 -0
  249. /package/dist/types/{types/index.d.ts → index.d.ts} +0 -0
  250. /package/dist/{types/utils → utils}/LatencyMonitor.d.ts +0 -0
  251. /package/dist/{types/utils → utils}/logger.d.ts +0 -0
  252. /package/dist/{types/utils → utils}/speakerManagement.d.ts +0 -0
  253. /package/dist/{types/vanilla → vanilla}/ConvaiWidget.d.ts +0 -0
  254. /package/dist/{types/vanilla → vanilla}/icons.d.ts +0 -0
  255. /package/dist/{types/vanilla → vanilla}/styles.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioManager.d.ts","sourceRoot":"","sources":["../../src/core/AudioManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,YAAa,YAAW,aAAa;IACrE,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,WAAW,CAAa;gBAEpB,IAAI,CAAC,EAAE,IAAI;IAOvB,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAczB;;OAEG;IACH,OAAO,CAAC,cAAc;IA2CtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;OAIG;IACH,iBAAiB,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IA0CzD;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBlC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCnC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAQlC;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrD;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAUnD;;OAEG;IACH,yBAAyB,IAAI,IAAI;IAOjC;;OAEG;IACH,wBAAwB,IAAI,IAAI;IAIhC;;OAEG;IACH,KAAK,IAAI,IAAI;CAUd"}
@@ -0,0 +1,262 @@
1
+ import { EventEmitter } from "./EventEmitter";
2
+ /**
3
+ * Manages audio controls for LiveKit room
4
+ * Provides methods to enable/disable microphone, manage audio devices,
5
+ * and control audio state.
6
+ */
7
+ export class AudioManager extends EventEmitter {
8
+ constructor(room) {
9
+ super();
10
+ this.room = null;
11
+ this._isAudioEnabled = false;
12
+ this._isAudioMuted = false;
13
+ this._audioLevel = 0;
14
+ if (room) {
15
+ this.setRoom(room);
16
+ }
17
+ }
18
+ get isAudioEnabled() {
19
+ return this._isAudioEnabled;
20
+ }
21
+ get isAudioMuted() {
22
+ return this._isAudioMuted;
23
+ }
24
+ get audioLevel() {
25
+ return this._audioLevel;
26
+ }
27
+ /**
28
+ * Set the LiveKit room instance
29
+ */
30
+ setRoom(room) {
31
+ // Clean up previous room listeners
32
+ if (this.room) {
33
+ this.cleanupListeners();
34
+ }
35
+ this.room = room;
36
+ if (room && room.state !== 'disconnected') {
37
+ this.setupListeners();
38
+ this.updateState();
39
+ }
40
+ }
41
+ /**
42
+ * Setup event listeners for room
43
+ */
44
+ setupListeners() {
45
+ if (!this.room)
46
+ return;
47
+ const localParticipant = this.room.localParticipant;
48
+ const handleTrackMuted = (track) => {
49
+ if (track.source === 'microphone') {
50
+ this._isAudioMuted = true;
51
+ this._isAudioEnabled = false;
52
+ this.emit('audioStateChange', { isAudioMuted: true, isAudioEnabled: false });
53
+ }
54
+ };
55
+ const handleTrackUnmuted = (track) => {
56
+ if (track.source === 'microphone') {
57
+ this._isAudioMuted = false;
58
+ this._isAudioEnabled = true;
59
+ this.emit('audioStateChange', { isAudioMuted: false, isAudioEnabled: true });
60
+ }
61
+ };
62
+ const handleTrackPublished = (track) => {
63
+ if (track.source === 'microphone') {
64
+ this._isAudioEnabled = true;
65
+ this._isAudioMuted = false;
66
+ this.emit('audioStateChange', { isAudioMuted: false, isAudioEnabled: true });
67
+ }
68
+ };
69
+ const handleTrackUnpublished = (track) => {
70
+ if (track.source === 'microphone') {
71
+ this._isAudioEnabled = false;
72
+ this._isAudioMuted = true;
73
+ this.emit('audioStateChange', { isAudioMuted: true, isAudioEnabled: false });
74
+ }
75
+ };
76
+ localParticipant.on('trackMuted', handleTrackMuted);
77
+ localParticipant.on('trackUnmuted', handleTrackUnmuted);
78
+ localParticipant.on('trackPublished', handleTrackPublished);
79
+ localParticipant.on('trackUnpublished', handleTrackUnpublished);
80
+ }
81
+ /**
82
+ * Clean up event listeners
83
+ */
84
+ cleanupListeners() {
85
+ if (!this.room)
86
+ return;
87
+ // LiveKit handles cleanup automatically when participant is removed
88
+ }
89
+ /**
90
+ * Force-sync the stored audio state with the underlying LiveKit room.
91
+ * Useful right after a connection completes so the UI can reflect
92
+ * the current microphone permission without waiting for a toggle event.
93
+ */
94
+ syncStateFromRoom(options = {}) {
95
+ const { emit = false } = options;
96
+ if (!this.room || this.room.state === 'disconnected') {
97
+ const stateChanged = this._isAudioEnabled !== false ||
98
+ this._isAudioMuted !== true ||
99
+ this._audioLevel !== 0;
100
+ this._isAudioEnabled = false;
101
+ this._isAudioMuted = true;
102
+ this._audioLevel = 0;
103
+ if (emit && stateChanged) {
104
+ this.emit('audioStateChange', {
105
+ isAudioMuted: this._isAudioMuted,
106
+ isAudioEnabled: this._isAudioEnabled,
107
+ audioLevel: this._audioLevel,
108
+ });
109
+ }
110
+ return;
111
+ }
112
+ const localParticipant = this.room.localParticipant;
113
+ const isMicEnabled = localParticipant?.isMicrophoneEnabled ?? false;
114
+ const nextMutedState = !isMicEnabled;
115
+ const stateChanged = this._isAudioEnabled !== isMicEnabled ||
116
+ this._isAudioMuted !== nextMutedState;
117
+ this._isAudioEnabled = isMicEnabled;
118
+ this._isAudioMuted = nextMutedState;
119
+ if (emit && stateChanged) {
120
+ this.emit('audioStateChange', {
121
+ isAudioMuted: this._isAudioMuted,
122
+ isAudioEnabled: this._isAudioEnabled,
123
+ audioLevel: this._audioLevel,
124
+ });
125
+ }
126
+ }
127
+ /**
128
+ * Update audio state from room
129
+ */
130
+ updateState() {
131
+ this.syncStateFromRoom();
132
+ }
133
+ /**
134
+ * Enable audio
135
+ */
136
+ async enableAudio() {
137
+ if (!this.room) {
138
+ throw new Error('Room not initialized');
139
+ }
140
+ try {
141
+ await this.room.localParticipant.setMicrophoneEnabled(true);
142
+ this._isAudioEnabled = true;
143
+ this._isAudioMuted = false;
144
+ this.emit('audioStateChange', {
145
+ isAudioMuted: false,
146
+ isAudioEnabled: true,
147
+ audioLevel: this._audioLevel,
148
+ });
149
+ }
150
+ catch (error) {
151
+ throw error;
152
+ }
153
+ }
154
+ /**
155
+ * Disable audio and completely release microphone
156
+ */
157
+ async disableAudio() {
158
+ if (!this.room) {
159
+ throw new Error('Room not initialized');
160
+ }
161
+ try {
162
+ // Get the microphone track before disabling
163
+ const micTrack = Array.from(this.room.localParticipant.audioTrackPublications.values()).find((publication) => publication.source === 'microphone' && publication.track)?.track;
164
+ // Disable microphone (unpublishes the track)
165
+ await this.room.localParticipant.setMicrophoneEnabled(false);
166
+ // Explicitly stop the underlying MediaStreamTrack to release hardware
167
+ // This removes the browser recording indicator
168
+ if (micTrack) {
169
+ micTrack.stop();
170
+ }
171
+ this._isAudioEnabled = false;
172
+ this._isAudioMuted = true;
173
+ this.emit('audioStateChange', {
174
+ isAudioMuted: true,
175
+ isAudioEnabled: false,
176
+ audioLevel: 0,
177
+ });
178
+ }
179
+ catch (error) {
180
+ throw error;
181
+ }
182
+ }
183
+ /**
184
+ * Mute audio
185
+ */
186
+ async muteAudio() {
187
+ await this.disableAudio();
188
+ }
189
+ /**
190
+ * Unmute audio
191
+ */
192
+ async unmuteAudio() {
193
+ await this.enableAudio();
194
+ }
195
+ /**
196
+ * Toggle audio
197
+ */
198
+ async toggleAudio() {
199
+ if (this._isAudioMuted) {
200
+ await this.unmuteAudio();
201
+ }
202
+ else {
203
+ await this.muteAudio();
204
+ }
205
+ }
206
+ /**
207
+ * Set audio device
208
+ */
209
+ async setAudioDevice(deviceId) {
210
+ if (!this.room) {
211
+ throw new Error('Room not initialized');
212
+ }
213
+ try {
214
+ await this.room.localParticipant.setMicrophoneEnabled(true, { deviceId });
215
+ }
216
+ catch (error) {
217
+ throw error;
218
+ }
219
+ }
220
+ /**
221
+ * Get available audio devices
222
+ */
223
+ async getAudioDevices() {
224
+ try {
225
+ const devices = await navigator.mediaDevices.enumerateDevices();
226
+ const audioDevices = devices.filter(device => device.kind === 'audioinput');
227
+ return audioDevices;
228
+ }
229
+ catch (error) {
230
+ throw error;
231
+ }
232
+ }
233
+ /**
234
+ * Start audio level monitoring
235
+ */
236
+ startAudioLevelMonitoring() {
237
+ if (!this.room) {
238
+ return;
239
+ }
240
+ // TODO: Implement audio level monitoring when LiveKit provides the API
241
+ }
242
+ /**
243
+ * Stop audio level monitoring
244
+ */
245
+ stopAudioLevelMonitoring() {
246
+ this._audioLevel = 0;
247
+ }
248
+ /**
249
+ * Reset state on disconnect
250
+ */
251
+ reset() {
252
+ this._isAudioEnabled = false;
253
+ this._isAudioMuted = false;
254
+ this._audioLevel = 0;
255
+ this.emit('audioStateChange', {
256
+ isAudioMuted: false,
257
+ isAudioEnabled: false,
258
+ audioLevel: 0
259
+ });
260
+ }
261
+ }
262
+ //# sourceMappingURL=AudioManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioManager.js","sourceRoot":"","sources":["../../src/core/AudioManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Post-processor function that can modify blendshape frames
3
+ * @param frame - The blendshape frame to process
4
+ * @param frameIndex - Index of the frame in the sequence
5
+ * @param totalFrames - Total number of frames in the sequence
6
+ * @returns Modified frame
7
+ */
8
+ export type BlendshapePostProcessor = (frame: Float32Array, frameIndex: number, totalFrames: number) => Float32Array;
9
+ /**
10
+ * BlendshapeQueue - Manages buffering and lifecycle of blendshape frames
11
+ *
12
+ * This queue buffers blendshape chunks (typically 10 frames each) as they arrive from the server,
13
+ * before the bot starts speaking. Playback begins when bot-started-speaking is triggered.
14
+ *
15
+ * Flow:
16
+ * 1. Blendshapes arrive in chunks and are buffered in the queue
17
+ * 2. bot-started-speaking triggers conversation start
18
+ * 3. Consumer reads frames from queue using time-based indexing (elapsed_time * 60fps)
19
+ * 4. blendshape-turn-stats marks conversation end
20
+ * 5. Queue drains remaining frames and resets for next conversation
21
+ *
22
+ * Features:
23
+ * - Zero frame blending for smooth transitions (always enabled)
24
+ * - Frame interpolation for smooth animation (always enabled)
25
+ * - Post-processing hooks for custom frame modifications
26
+ */
27
+ export declare class BlendshapeQueue {
28
+ private queue;
29
+ private conversationActive;
30
+ private conversationEnded;
31
+ private postProcessors;
32
+ private static readonly ZERO_FRAME;
33
+ private static readonly TARGET_FPS;
34
+ /**
35
+ * Add a chunk of blendshapes to the queue
36
+ * @param blendshapes - Array of blendshape frames (each frame is an array of numbers)
37
+ */
38
+ addChunk(blendshapes: number[][]): void;
39
+ /**
40
+ * Get all frames currently in the queue
41
+ * @returns Array of blendshape frames as Float32Arrays
42
+ */
43
+ getFrames(): Float32Array[];
44
+ /**
45
+ * Get a specific frame by index
46
+ * @param index - Frame index
47
+ * @returns The frame at the given index, or null if out of bounds
48
+ */
49
+ getFrame(index: number): Float32Array | null;
50
+ /**
51
+ * Remove frames from the beginning of the queue (consume frames)
52
+ * @param count - Number of frames to remove
53
+ */
54
+ consumeFrames(count: number): void;
55
+ /**
56
+ * Get the number of frames currently in the queue
57
+ */
58
+ get length(): number;
59
+ /**
60
+ * Check if queue has frames
61
+ */
62
+ hasFrames(): boolean;
63
+ /**
64
+ * Check if conversation is active
65
+ */
66
+ isConversationActive(): boolean;
67
+ /**
68
+ * Check if conversation has ended (blendshape-turn-stats received)
69
+ */
70
+ isConversationEnded(): boolean;
71
+ /**
72
+ * Mark conversation start (called when bot-started-speaking)
73
+ */
74
+ startConversation(): void;
75
+ /**
76
+ * Mark conversation end (called when blendshape-turn-stats received)
77
+ * Queue should be drained after this point
78
+ */
79
+ endConversation(): void;
80
+ /**
81
+ * Reset queue for new conversation
82
+ * Should be called after all frames have been consumed
83
+ */
84
+ reset(): void;
85
+ /**
86
+ * Add a post-processor to modify frames during playback
87
+ */
88
+ addPostProcessor(processor: BlendshapePostProcessor): void;
89
+ /**
90
+ * Remove a post-processor
91
+ */
92
+ removePostProcessor(processor: BlendshapePostProcessor): void;
93
+ /**
94
+ * Clear all post-processors
95
+ */
96
+ clearPostProcessors(): void;
97
+ /**
98
+ * Apply all post-processors to a frame
99
+ */
100
+ private applyPostProcessing;
101
+ /**
102
+ * Get interpolated frame with zero-frame blending (always enabled)
103
+ * @param elapsedTime - Elapsed time in seconds
104
+ * @returns Interpolated frame with blending info
105
+ */
106
+ getInterpolatedFrame(elapsedTime: number): {
107
+ frame: Float32Array;
108
+ frameIndex: number;
109
+ isBlendingToZero: boolean;
110
+ } | null;
111
+ /**
112
+ * Interpolate between two frames
113
+ */
114
+ private interpolate;
115
+ /**
116
+ * Get the zero frame (neutral pose)
117
+ */
118
+ static getZeroFrame(): Float32Array;
119
+ /**
120
+ * Get debug info about the queue state
121
+ */
122
+ getDebugInfo(): {
123
+ frameCount: number;
124
+ conversationActive: boolean;
125
+ conversationEnded: boolean;
126
+ };
127
+ }
128
+ //# sourceMappingURL=BlendshapeQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlendshapeQueue.d.ts","sourceRoot":"","sources":["../../src/core/BlendshapeQueue.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,KAChB,YAAY,CAAC;AAElB;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAkB;IAG3C,OAAO,CAAC,cAAc,CAAiC;IAGvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAM;IAExC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IASvC;;;OAGG;IACH,SAAS,IAAI,YAAY,EAAE;IAI3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAO5C;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,oBAAoB,IAAI,OAAO;IAI/B;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAKzB;;;OAGG;IACH,eAAe,IAAI,IAAI;IAKvB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,uBAAuB,GAAG,IAAI;IAI1D;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,uBAAuB,GAAG,IAAI;IAO7D;;OAEG;IACH,mBAAmB,IAAI,IAAI;IAI3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;OAIG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG;QACzC,KAAK,EAAE,YAAY,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,OAAO,CAAC;KAC3B,GAAG,IAAI;IA6DR;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,YAAY;IAInC;;OAEG;IACH,YAAY,IAAI;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,iBAAiB,EAAE,OAAO,CAAC;KAC5B;CAOF"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * BlendshapeQueue - Manages buffering and lifecycle of blendshape frames
3
+ *
4
+ * This queue buffers blendshape chunks (typically 10 frames each) as they arrive from the server,
5
+ * before the bot starts speaking. Playback begins when bot-started-speaking is triggered.
6
+ *
7
+ * Flow:
8
+ * 1. Blendshapes arrive in chunks and are buffered in the queue
9
+ * 2. bot-started-speaking triggers conversation start
10
+ * 3. Consumer reads frames from queue using time-based indexing (elapsed_time * 60fps)
11
+ * 4. blendshape-turn-stats marks conversation end
12
+ * 5. Queue drains remaining frames and resets for next conversation
13
+ *
14
+ * Features:
15
+ * - Zero frame blending for smooth transitions (always enabled)
16
+ * - Frame interpolation for smooth animation (always enabled)
17
+ * - Post-processing hooks for custom frame modifications
18
+ */
19
+ export class BlendshapeQueue {
20
+ constructor() {
21
+ this.queue = [];
22
+ this.conversationActive = false;
23
+ this.conversationEnded = false;
24
+ // Post-processing
25
+ this.postProcessors = [];
26
+ }
27
+ /**
28
+ * Add a chunk of blendshapes to the queue
29
+ * @param blendshapes - Array of blendshape frames (each frame is an array of numbers)
30
+ */
31
+ addChunk(blendshapes) {
32
+ const before = this.queue.length;
33
+ for (let i = 0; i < blendshapes.length; i++) {
34
+ this.queue.push(new Float32Array(blendshapes[i]));
35
+ }
36
+ const after = this.queue.length;
37
+ // console.log(`[BlendshapeQueue] Added ${blendshapes.length} frames. Queue: ${before} -> ${after}`);
38
+ }
39
+ /**
40
+ * Get all frames currently in the queue
41
+ * @returns Array of blendshape frames as Float32Arrays
42
+ */
43
+ getFrames() {
44
+ return this.queue;
45
+ }
46
+ /**
47
+ * Get a specific frame by index
48
+ * @param index - Frame index
49
+ * @returns The frame at the given index, or null if out of bounds
50
+ */
51
+ getFrame(index) {
52
+ if (index < 0 || index >= this.queue.length) {
53
+ return null;
54
+ }
55
+ return this.queue[index];
56
+ }
57
+ /**
58
+ * Remove frames from the beginning of the queue (consume frames)
59
+ * @param count - Number of frames to remove
60
+ */
61
+ consumeFrames(count) {
62
+ if (count <= 0)
63
+ return;
64
+ this.queue.splice(0, Math.min(count, this.queue.length));
65
+ }
66
+ /**
67
+ * Get the number of frames currently in the queue
68
+ */
69
+ get length() {
70
+ return this.queue.length;
71
+ }
72
+ /**
73
+ * Check if queue has frames
74
+ */
75
+ hasFrames() {
76
+ return this.queue.length > 0;
77
+ }
78
+ /**
79
+ * Check if conversation is active
80
+ */
81
+ isConversationActive() {
82
+ return this.conversationActive;
83
+ }
84
+ /**
85
+ * Check if conversation has ended (blendshape-turn-stats received)
86
+ */
87
+ isConversationEnded() {
88
+ return this.conversationEnded;
89
+ }
90
+ /**
91
+ * Mark conversation start (called when bot-started-speaking)
92
+ */
93
+ startConversation() {
94
+ this.conversationActive = true;
95
+ this.conversationEnded = false;
96
+ }
97
+ /**
98
+ * Mark conversation end (called when blendshape-turn-stats received)
99
+ * Queue should be drained after this point
100
+ */
101
+ endConversation() {
102
+ this.conversationEnded = true;
103
+ // Note: Don't set conversationActive to false yet - let consumer drain remaining frames
104
+ }
105
+ /**
106
+ * Reset queue for new conversation
107
+ * Should be called after all frames have been consumed
108
+ */
109
+ reset() {
110
+ this.queue = [];
111
+ this.conversationActive = false;
112
+ this.conversationEnded = false;
113
+ }
114
+ /**
115
+ * Add a post-processor to modify frames during playback
116
+ */
117
+ addPostProcessor(processor) {
118
+ this.postProcessors.push(processor);
119
+ }
120
+ /**
121
+ * Remove a post-processor
122
+ */
123
+ removePostProcessor(processor) {
124
+ const index = this.postProcessors.indexOf(processor);
125
+ if (index !== -1) {
126
+ this.postProcessors.splice(index, 1);
127
+ }
128
+ }
129
+ /**
130
+ * Clear all post-processors
131
+ */
132
+ clearPostProcessors() {
133
+ this.postProcessors = [];
134
+ }
135
+ /**
136
+ * Apply all post-processors to a frame
137
+ */
138
+ applyPostProcessing(frame, frameIndex) {
139
+ return this.postProcessors.reduce((processedFrame, processor) => processor(processedFrame, frameIndex, this.queue.length), frame);
140
+ }
141
+ /**
142
+ * Get interpolated frame with zero-frame blending (always enabled)
143
+ * @param elapsedTime - Elapsed time in seconds
144
+ * @returns Interpolated frame with blending info
145
+ */
146
+ getInterpolatedFrame(elapsedTime) {
147
+ if (this.queue.length === 0) {
148
+ return null;
149
+ }
150
+ const totalDuration = this.queue.length / BlendshapeQueue.TARGET_FPS;
151
+ const frameDuration = 1 / BlendshapeQueue.TARGET_FPS;
152
+ const halfFrameDuration = frameDuration * 0.5;
153
+ let startFrame;
154
+ let endFrame;
155
+ let alpha;
156
+ let frameIndex;
157
+ let isBlendingToZero = false;
158
+ // Beginning: blend from zero to first frame
159
+ if (elapsedTime <= halfFrameDuration) {
160
+ startFrame = BlendshapeQueue.ZERO_FRAME;
161
+ endFrame = this.queue[0];
162
+ alpha = elapsedTime / halfFrameDuration;
163
+ frameIndex = 0;
164
+ }
165
+ // End: blend from last frame to zero
166
+ else if (elapsedTime >= totalDuration - halfFrameDuration) {
167
+ startFrame = this.queue[this.queue.length - 1];
168
+ endFrame = BlendshapeQueue.ZERO_FRAME;
169
+ alpha =
170
+ (elapsedTime - (totalDuration - halfFrameDuration)) / halfFrameDuration;
171
+ frameIndex = this.queue.length - 1;
172
+ isBlendingToZero = true;
173
+ }
174
+ // Middle: normal interpolation
175
+ else {
176
+ const adjustedTime = elapsedTime - halfFrameDuration;
177
+ const currentFrameIndex = Math.floor(adjustedTime / frameDuration);
178
+ const nextFrameIndex = Math.min(currentFrameIndex + 1, this.queue.length - 1);
179
+ startFrame = this.queue[currentFrameIndex];
180
+ endFrame = this.queue[nextFrameIndex];
181
+ alpha = (adjustedTime % frameDuration) / frameDuration;
182
+ frameIndex = currentFrameIndex;
183
+ }
184
+ // Always interpolate for smooth animation
185
+ let resultFrame = this.interpolate(startFrame, endFrame, alpha);
186
+ // Apply post-processing
187
+ if (this.postProcessors.length > 0) {
188
+ resultFrame = this.applyPostProcessing(resultFrame, frameIndex);
189
+ }
190
+ return {
191
+ frame: resultFrame,
192
+ frameIndex,
193
+ isBlendingToZero,
194
+ };
195
+ }
196
+ /**
197
+ * Interpolate between two frames
198
+ */
199
+ interpolate(start, end, alpha) {
200
+ const result = new Float32Array(Math.max(start.length, end.length));
201
+ const minLength = Math.min(start.length, end.length);
202
+ for (let i = 0; i < minLength; i++) {
203
+ const startVal = start[i] || 0;
204
+ const endVal = end[i] || 0;
205
+ result[i] = startVal + (endVal - startVal) * alpha;
206
+ }
207
+ return result;
208
+ }
209
+ /**
210
+ * Get the zero frame (neutral pose)
211
+ */
212
+ static getZeroFrame() {
213
+ return new Float32Array(BlendshapeQueue.ZERO_FRAME);
214
+ }
215
+ /**
216
+ * Get debug info about the queue state
217
+ */
218
+ getDebugInfo() {
219
+ return {
220
+ frameCount: this.queue.length,
221
+ conversationActive: this.conversationActive,
222
+ conversationEnded: this.conversationEnded,
223
+ };
224
+ }
225
+ }
226
+ // Constants
227
+ BlendshapeQueue.ZERO_FRAME = new Float32Array(52).fill(0);
228
+ BlendshapeQueue.TARGET_FPS = 60;
229
+ //# sourceMappingURL=BlendshapeQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlendshapeQueue.js","sourceRoot":"","sources":["../../src/core/BlendshapeQueue.ts"],"names":[],"mappings":"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"}