@davi-ai/retorik-framework 4.0.4 → 5.0.1

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 (84) hide show
  1. package/README.md +13 -0
  2. package/dist/{AttachmentDetail.637ad44f.js → AttachmentDetail.3f9c113d.js} +15 -6
  3. package/dist/AttachmentDetail.3f9c113d.js.map +1 -0
  4. package/dist/{AttachmentDetail.83788045.js → AttachmentDetail.57c5579a.js} +15 -6
  5. package/dist/AttachmentDetail.57c5579a.js.map +1 -0
  6. package/dist/{CustomView.bf84bdf3.js → CustomView.6b96f53f.js} +8 -4
  7. package/dist/CustomView.6b96f53f.js.map +1 -0
  8. package/dist/{CustomView.9930c671.js → CustomView.b32a608f.js} +8 -4
  9. package/dist/CustomView.b32a608f.js.map +1 -0
  10. package/dist/{Emergency.1112c09f.js → Emergency.43605d14.js} +11 -2
  11. package/dist/Emergency.43605d14.js.map +1 -0
  12. package/dist/{Emergency.d5810ff2.js → Emergency.f1287bd5.js} +11 -2
  13. package/dist/Emergency.f1287bd5.js.map +1 -0
  14. package/dist/FullScreenImage.17df27bf.js.map +1 -1
  15. package/dist/FullScreenImage.99e19e10.js.map +1 -1
  16. package/dist/{HistoryList.3b4b1ffb.js → HistoryList.c19556a7.js} +8 -2
  17. package/dist/HistoryList.c19556a7.js.map +1 -0
  18. package/dist/{HistoryList.e5c01f21.js → HistoryList.e7262d62.js} +8 -2
  19. package/dist/HistoryList.e7262d62.js.map +1 -0
  20. package/dist/{LanguageChoice.1d866cfa.js → LanguageChoice.54fae1dc.js} +19 -8
  21. package/dist/LanguageChoice.54fae1dc.js.map +1 -0
  22. package/dist/{LanguageChoice.cce361a3.js → LanguageChoice.6e8b74f6.js} +19 -8
  23. package/dist/LanguageChoice.6e8b74f6.js.map +1 -0
  24. package/dist/LittleWeatherContainer.7e41105e.js.map +1 -1
  25. package/dist/LittleWeatherContainer.ee087e22.js.map +1 -1
  26. package/dist/{MapContainer.14c28128.js → MapContainer.25c8f4b4.js} +20 -5
  27. package/dist/MapContainer.25c8f4b4.js.map +1 -0
  28. package/dist/{MapContainer.f22ad81f.js → MapContainer.d00ab5b2.js} +20 -5
  29. package/dist/MapContainer.d00ab5b2.js.map +1 -0
  30. package/dist/{NewsContainer.d9de093c.js → NewsContainer.a39630c3.js} +33 -26
  31. package/dist/NewsContainer.a39630c3.js.map +1 -0
  32. package/dist/{NewsContainer.463e74de.js → NewsContainer.ec15c3bb.js} +33 -26
  33. package/dist/NewsContainer.ec15c3bb.js.map +1 -0
  34. package/dist/PrintingPreview.375e62b0.js.map +1 -1
  35. package/dist/PrintingPreview.c0ca7706.js.map +1 -1
  36. package/dist/RecognitionManager.c58b8a3d.js +298 -0
  37. package/dist/RecognitionManager.c58b8a3d.js.map +1 -0
  38. package/dist/RecognitionManager.cdfb39fc.js +314 -0
  39. package/dist/RecognitionManager.cdfb39fc.js.map +1 -0
  40. package/dist/SpiritEngineWrapper.21ea10d4.js.map +1 -1
  41. package/dist/SpiritEngineWrapper.39627300.js.map +1 -1
  42. package/dist/SynthesisPonyfillManager.10888d6d.js +888 -0
  43. package/dist/SynthesisPonyfillManager.10888d6d.js.map +1 -0
  44. package/dist/SynthesisPonyfillManager.f9f9a915.js +920 -0
  45. package/dist/SynthesisPonyfillManager.f9f9a915.js.map +1 -0
  46. package/dist/{ThreeJsWrapper.dd4906ff.js → ThreeJsWrapper.0285d280.js} +24 -12
  47. package/dist/ThreeJsWrapper.0285d280.js.map +1 -0
  48. package/dist/{ThreeJsWrapper.c02a077f.js → ThreeJsWrapper.ad746197.js} +24 -11
  49. package/dist/ThreeJsWrapper.ad746197.js.map +1 -0
  50. package/dist/{VeilleManager.f3bafdec.js → VeilleManager.0b3f2454.js} +11 -13
  51. package/dist/VeilleManager.0b3f2454.js.map +1 -0
  52. package/dist/{VeilleManager.85967e7c.js → VeilleManager.340a7825.js} +11 -13
  53. package/dist/VeilleManager.340a7825.js.map +1 -0
  54. package/dist/{Weather.7e945307.js → Weather.abc13d88.js} +9 -3
  55. package/dist/Weather.abc13d88.js.map +1 -0
  56. package/dist/{Weather.e81b7205.js → Weather.b9d9f82e.js} +9 -3
  57. package/dist/Weather.b9d9f82e.js.map +1 -0
  58. package/dist/index.d.ts +21 -951
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +52952 -33750
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.modern.js +53468 -34269
  63. package/dist/index.modern.js.map +1 -1
  64. package/package.json +21 -21
  65. package/dist/AttachmentDetail.637ad44f.js.map +0 -1
  66. package/dist/AttachmentDetail.83788045.js.map +0 -1
  67. package/dist/CustomView.9930c671.js.map +0 -1
  68. package/dist/CustomView.bf84bdf3.js.map +0 -1
  69. package/dist/Emergency.1112c09f.js.map +0 -1
  70. package/dist/Emergency.d5810ff2.js.map +0 -1
  71. package/dist/HistoryList.3b4b1ffb.js.map +0 -1
  72. package/dist/HistoryList.e5c01f21.js.map +0 -1
  73. package/dist/LanguageChoice.1d866cfa.js.map +0 -1
  74. package/dist/LanguageChoice.cce361a3.js.map +0 -1
  75. package/dist/MapContainer.14c28128.js.map +0 -1
  76. package/dist/MapContainer.f22ad81f.js.map +0 -1
  77. package/dist/NewsContainer.463e74de.js.map +0 -1
  78. package/dist/NewsContainer.d9de093c.js.map +0 -1
  79. package/dist/ThreeJsWrapper.c02a077f.js.map +0 -1
  80. package/dist/ThreeJsWrapper.dd4906ff.js.map +0 -1
  81. package/dist/VeilleManager.85967e7c.js.map +0 -1
  82. package/dist/VeilleManager.f3bafdec.js.map +0 -1
  83. package/dist/Weather.7e945307.js.map +0 -1
  84. package/dist/Weather.e81b7205.js.map +0 -1
@@ -0,0 +1,888 @@
1
+ import {jsx as $cMDfV$jsx, jsxs as $cMDfV$jsxs} from "react/jsx-runtime";
2
+ import $cMDfV$react, {useState as $cMDfV$useState, useRef as $cMDfV$useRef, useEffect as $cMDfV$useEffect} from "react";
3
+ import {createSpeechSynthesisPonyfill as $cMDfV$createSpeechSynthesisPonyfill, SpeechSynthesisUtterance as $cMDfV$SpeechSynthesisUtterance} from "@davi-ai/web-speech-cognitive-services-davi";
4
+ import {useDispatch as $cMDfV$useDispatch, useSelector as $cMDfV$useSelector} from "react-redux";
5
+ import {SpeechMarkdown as $cMDfV$SpeechMarkdown} from "@davi-ai/speechmarkdown-davi-js";
6
+
7
+
8
+ function $parcel$defineInteropFlag(a) {
9
+ Object.defineProperty(a, '__esModule', {value: true, configurable: true});
10
+ }
11
+
12
+ function $parcel$export(e, n, v, s) {
13
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
14
+ }
15
+
16
+ var $parcel$global = globalThis;
17
+ var parcelRequire = $parcel$global["parcelRequirea39d"];
18
+ var parcelRegister = parcelRequire.register;
19
+ parcelRegister("jv4ce", function(module, exports) {
20
+
21
+ $parcel$defineInteropFlag(module.exports);
22
+
23
+ $parcel$export(module.exports, "default", () => $982637234a32cc59$export$2e2bcd8739ae039);
24
+
25
+
26
+
27
+
28
+
29
+ var $8ItUL = parcelRequire("8ItUL");
30
+
31
+ var $d1wbP = parcelRequire("d1wbP");
32
+
33
+ var $1mU9f = parcelRequire("1mU9f");
34
+
35
+ var $3S6OO = parcelRequire("3S6OO");
36
+ const $982637234a32cc59$var$SynthesisPonyfillManager = ({ isRetorikNews: isRetorikNews })=>{
37
+ const dispatch = (0, $cMDfV$useDispatch)();
38
+ const customVoice = (0, $cMDfV$useSelector)((state)=>state.speechReducer.customVoice);
39
+ const ponyfillCredentials = (0, $cMDfV$useSelector)((state)=>state.speechReducer.ponyfillCredentials);
40
+ const locale = (0, $cMDfV$useSelector)((state)=>state.localeReducer.locale);
41
+ const agentData = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.agentData);
42
+ const [ponyfillCreated, setPonyfillCreated] = (0, $cMDfV$useState)(false);
43
+ const ponyfillRef = (0, $cMDfV$useRef)(undefined);
44
+ const refreshTimerRef = (0, $cMDfV$useRef)(null);
45
+ /**
46
+ * Async function to retrieve a new token and assign it to the speechConfig inside ponyfill.speechSynthesis
47
+ * @param {string} region
48
+ * @param {string} key
49
+ */ const refreshTokenInNineMinutes = async (region, key)=>{
50
+ // A token is valid during 10 minutes, let's refresh it after 9 minutes
51
+ refreshTimerRef.current = setTimeout(async ()=>{
52
+ const token = await (0, $d1wbP.fetchSpeechServicesToken)(region, key);
53
+ if (token && ponyfillRef.current?.speechSynthesis?.speechConfig) {
54
+ ponyfillRef.current.speechSynthesis.speechConfig.authorizationToken = token;
55
+ refreshTokenInNineMinutes(region, key);
56
+ }
57
+ }, 540000) // 9 minutes
58
+ ;
59
+ };
60
+ /**
61
+ * Fetch speech synthesis token and create the ponyfill containing all data
62
+ * @param {string} region
63
+ * @param {string} key
64
+ */ const fetchTokenAndCreatePonyfill = async (region, key)=>{
65
+ const token = await (0, $d1wbP.fetchSpeechServicesToken)(region, key);
66
+ if (token) {
67
+ ponyfillRef.current = (0, $cMDfV$createSpeechSynthesisPonyfill)({
68
+ credentials: {
69
+ region: ponyfillCredentials?.region,
70
+ authorizationToken: token
71
+ }
72
+ });
73
+ // Launch token refresh after ponyfill creation
74
+ refreshTokenInNineMinutes(region, key);
75
+ setPonyfillCreated(true);
76
+ }
77
+ };
78
+ (0, $cMDfV$useEffect)(()=>{
79
+ if (ponyfillCredentials?.authorizationToken && ponyfillCredentials.region) {
80
+ const data = {
81
+ credentials: ponyfillCredentials
82
+ };
83
+ ponyfillRef.current = (0, $cMDfV$createSpeechSynthesisPonyfill)(data);
84
+ setPonyfillCreated(true);
85
+ } else if (ponyfillCredentials?.subscriptionKey && ponyfillCredentials.region) fetchTokenAndCreatePonyfill(ponyfillCredentials.region, ponyfillCredentials.subscriptionKey);
86
+ else if (ponyfillCredentials?.speechSynthesisHostname) {
87
+ // To use self-hosted voice containers, we need no 'region', and 'speechSynthesisHostname' and 'speechRecognitionHostname' must both be defined
88
+ // As this ponyfill is for speech synthesis only, we put a mock 'speechRecognitionHostname'
89
+ const data = {
90
+ credentials: {
91
+ // @ts-ignore
92
+ speechSynthesisHostname: new URL(ponyfillCredentials.speechSynthesisHostname),
93
+ speechRecognitionHostname: ponyfillCredentials.speechRecognitionHostname || 'mandatory_recognition_host_name',
94
+ subscriptionKey: ponyfillCredentials.subscriptionKey || 'mandatory_subscription_key'
95
+ }
96
+ };
97
+ ponyfillRef.current = (0, $cMDfV$createSpeechSynthesisPonyfill)(data);
98
+ setPonyfillCreated(true);
99
+ }
100
+ }, [
101
+ ponyfillCredentials
102
+ ]);
103
+ const onVoicesChanged = ()=>{
104
+ const voices = ponyfillRef.current?.speechSynthesis.getVoices();
105
+ if (voices && Array.isArray(voices) && voices.length) dispatch((0, $8ItUL.storeActions).speech.setVoice((0, $1mU9f.selectVoice)(voices, locale, customVoice, agentData) || undefined));
106
+ };
107
+ (0, $cMDfV$useEffect)(()=>{
108
+ if (ponyfillRef.current) {
109
+ const voices = ponyfillRef.current.speechSynthesis.getVoices();
110
+ if (voices && Array.isArray(voices) && voices.length) dispatch((0, $8ItUL.storeActions).speech.setVoice((0, $1mU9f.selectVoice)(voices, locale, customVoice, agentData) || undefined));
111
+ else ponyfillRef.current.speechSynthesis.onvoiceschanged = onVoicesChanged;
112
+ }
113
+ }, [
114
+ ponyfillCreated,
115
+ customVoice,
116
+ agentData,
117
+ locale
118
+ ]);
119
+ (0, $cMDfV$useEffect)(()=>{
120
+ return ()=>{
121
+ refreshTimerRef.current && clearTimeout(refreshTimerRef.current);
122
+ };
123
+ }, []);
124
+ return ponyfillCreated && ponyfillRef.current ? /*#__PURE__*/ (0, $cMDfV$jsx)((0, $3S6OO.default), {
125
+ ponyfill: ponyfillRef.current,
126
+ isRetorikNews: isRetorikNews
127
+ }) : /*#__PURE__*/ (0, $cMDfV$jsx)((0, $cMDfV$react).Fragment, {});
128
+ };
129
+ var $982637234a32cc59$export$2e2bcd8739ae039 = $982637234a32cc59$var$SynthesisPonyfillManager;
130
+
131
+ });
132
+ parcelRegister("d1wbP", function(module, exports) {
133
+
134
+ $parcel$export(module.exports, "fetchSpeechServicesToken", () => $f9d43385082cde31$export$a2ce4fdd6972d6a7);
135
+ const $f9d43385082cde31$export$a2ce4fdd6972d6a7 = async (region, key)=>{
136
+ const tokenRes = await fetch(`https://${region}.api.cognitive.microsoft.com/sts/v1.0/issueToken`, {
137
+ method: 'POST',
138
+ headers: {
139
+ 'Ocp-Apim-Subscription-Key': key
140
+ }
141
+ }).then((value)=>{
142
+ return value.text();
143
+ }).catch((error)=>{
144
+ console.log('Error : ', error);
145
+ return undefined;
146
+ });
147
+ return tokenRes;
148
+ };
149
+
150
+ });
151
+
152
+ parcelRegister("1mU9f", function(module, exports) {
153
+
154
+ $parcel$export(module.exports, "selectVoice", () => $e3b82aafad2d0e5e$export$4bf371fc4fa74a28);
155
+ const $e3b82aafad2d0e5e$export$4bf371fc4fa74a28 = (voices, locale, customVoice, agentData)=>{
156
+ let voice = null;
157
+ // Check if a custom voice is defined in the props
158
+ if (customVoice) {
159
+ if (customVoice.voice) {
160
+ // Search voice with its full name (ex: AriaNeural, GuyNeural)
161
+ const neuralVoice = new RegExp(customVoice.voice, 'iu');
162
+ voice = voices.find(({ name: name })=>neuralVoice.test(name) || name === customVoice.voice);
163
+ } else if (customVoice.gender) // Search voice depending on given gender and locale
164
+ voice = voices.find(({ gender: gender, lang: lang })=>{
165
+ return gender.toLowerCase() === customVoice?.gender?.toLowerCase() && lang === locale;
166
+ });
167
+ }
168
+ // Get voice depending on locale and gender
169
+ if (!voice) voice = voices.find(({ gender: gender, lang: lang })=>{
170
+ return gender.toLowerCase() === (agentData?.gender?.toLowerCase() || 'female') && lang === locale;
171
+ });
172
+ // No voice found, fall back to US default voices : female => Aria / male => Guy
173
+ if (!voice) {
174
+ const genderedVoice = agentData?.gender?.toLowerCase() === 'female' ? 'AriaNeural' : 'GuyNeural';
175
+ const neuralVoice = new RegExp(genderedVoice, 'iu');
176
+ voice = voices.find(({ name: name })=>neuralVoice.test(name));
177
+ }
178
+ return voice;
179
+ };
180
+
181
+ });
182
+
183
+ parcelRegister("3S6OO", function(module, exports) {
184
+
185
+ $parcel$export(module.exports, "default", () => $0b8e5d756ffed1ac$export$2e2bcd8739ae039);
186
+
187
+
188
+
189
+
190
+ var $8ItUL = parcelRequire("8ItUL");
191
+
192
+ var $712C3 = parcelRequire("712C3");
193
+
194
+ var $4ucVo = parcelRequire("4ucVo");
195
+
196
+ var $1mU9f = parcelRequire("1mU9f");
197
+
198
+ var $7UkSC = parcelRequire("7UkSC");
199
+
200
+ var $b56Ud = parcelRequire("b56Ud");
201
+ const $0b8e5d756ffed1ac$var$SynthesisManager = ({ ponyfill: ponyfill, isRetorikNews: isRetorikNews })=>{
202
+ const dispatch = (0, $cMDfV$useDispatch)();
203
+ const cancel = (0, $cMDfV$useSelector)((state)=>state.speechReducer.cancel);
204
+ const streamingQueue = (0, $cMDfV$useSelector)((state)=>state.speechReducer.streamingQueue);
205
+ const voice = (0, $cMDfV$useSelector)((state)=>state.speechReducer.voice);
206
+ const customVoice = (0, $cMDfV$useSelector)((state)=>state.speechReducer.customVoice);
207
+ const activeRecognitionState = (0, $cMDfV$useSelector)((state)=>state.speechReducer.activeRecognitionState);
208
+ const externalTextToSpeech = (0, $cMDfV$useSelector)((state)=>state.speechReducer.externalTextToSpeech);
209
+ const isMicrophoneAllowed = (0, $cMDfV$useSelector)((state)=>state.speechReducer.isMicrophoneAllowed);
210
+ const mode = (0, $cMDfV$useSelector)((state)=>state.speechReducer.mode);
211
+ const route = (0, $cMDfV$useSelector)((state)=>state.viewReducer.route);
212
+ const locale = (0, $cMDfV$useSelector)((state)=>state.localeReducer.locale);
213
+ const replacementLocales = (0, $cMDfV$useSelector)((state)=>state.localeReducer.replacementLocales);
214
+ const agentData = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.agentData);
215
+ const appAvailable = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.appAvailable);
216
+ const preventExpectedInputHint = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.configuration.preventExpectedInputHint);
217
+ const speechSynthesisOptions = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.configuration.speechSynthesisOptions);
218
+ const sendTrace = (0, $712C3.useTelemetry)().sendTrace;
219
+ const [utterance, setUtterance] = (0, $cMDfV$useState)(null);
220
+ const [nextUtterance, setNextUtterance] = (0, $cMDfV$useState)(null);
221
+ const [forceSpeechCaching, setForceSpeechCaching] = (0, $cMDfV$useState)(false);
222
+ const isNewsViewRef = (0, $cMDfV$useRef)(!!isRetorikNews);
223
+ const lastListTextPlayedRef = (0, $cMDfV$useRef)('');
224
+ const streamingQueueRef = (0, $cMDfV$useRef)([]);
225
+ const currentActivityRef = (0, $cMDfV$useRef)(null);
226
+ /**
227
+ * Check activity locale in case of voice change during the speech, to keep the language defined in activity
228
+ * instead of switching languages between answers that are written in the same language
229
+ * @param {string} activityLocale
230
+ * @returns {SpeechSynthesisVoice | null}
231
+ */ const getVoiceAfterCheckingActivityLocale = (activityLocale)=>{
232
+ return activityLocale === locale ? voice : (0, $1mU9f.selectVoice)(ponyfill.speechSynthesis.getVoices(), activityLocale, customVoice, agentData);
233
+ };
234
+ /**
235
+ * Check if the activity is a list one, to prevent text re-reading on state update
236
+ * @param {CreateUtteranceParams} params
237
+ * @returns {SpeechSynthesisUtterance}
238
+ */ const checkActivityAndCreateUtterance = (params)=>{
239
+ if (params.activity.attachmentLayout && params.activity.attachmentLayout.toLowerCase() === 'davilist') {
240
+ const textToSpeak = params.activity.speak || params.activity.text;
241
+ if (textToSpeak) {
242
+ if (textToSpeak === lastListTextPlayedRef.current) return (0, $7UkSC.checkSayAsWordsAndCreateUtterance)({
243
+ ...params,
244
+ voice: null
245
+ }, speechSynthesisOptions?.sayAs);
246
+ else lastListTextPlayedRef.current = textToSpeak;
247
+ }
248
+ }
249
+ return (0, $7UkSC.checkSayAsWordsAndCreateUtterance)(params, speechSynthesisOptions?.sayAs);
250
+ };
251
+ const resetData = ()=>{
252
+ // Set all activities currently in the queue as ended
253
+ streamingQueueRef.current?.forEach((activity)=>{
254
+ dispatch((0, $8ItUL.storeActions).activity.addEndedActivity(activity.id));
255
+ });
256
+ streamingQueueRef.current = [];
257
+ dispatch((0, $8ItUL.storeActions).speech.killCurrentStreaming());
258
+ currentActivityRef.current = null;
259
+ setUtterance(null);
260
+ setNextUtterance(null);
261
+ dispatch((0, $8ItUL.storeActions).speech.resetCancelCurrentUtterance());
262
+ dispatch((0, $8ItUL.storeActions).speech.setSpeaking(false));
263
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData([]));
264
+ };
265
+ const checkReplacementLocaleAndGetUtterance = (activity, checkReplacement = true)=>{
266
+ const replacementLocale = checkReplacement ? replacementLocales?.[locale] || locale : locale;
267
+ const params = {
268
+ activity: activity,
269
+ voice: getVoiceAfterCheckingActivityLocale(replacementLocale),
270
+ locale: replacementLocale
271
+ };
272
+ return checkActivityAndCreateUtterance(params);
273
+ };
274
+ /**
275
+ * Check if the microphone can be opened automatically
276
+ */ const checkDictateState = ()=>{
277
+ if (!preventExpectedInputHint && mode === (0, $8ItUL.Mode).vocal && activeRecognitionState === (0, $8ItUL.RecognitionState).Closed) {
278
+ if (!isMicrophoneAllowed) dispatch((0, $8ItUL.storeActions).speech.askPermission());
279
+ else dispatch((0, $8ItUL.storeActions).speech.toggleMicrophone(true));
280
+ }
281
+ };
282
+ /**
283
+ * On route change, reset all data and check if we are on the news view
284
+ */ (0, $cMDfV$useEffect)(()=>{
285
+ resetData();
286
+ if (!isRetorikNews) isNewsViewRef.current = route === (0, $8ItUL.Routes).News || route === (0, $8ItUL.Routes).NewsInVeille;
287
+ // Force speech caching when using Retorik News or when using news in veille
288
+ setForceSpeechCaching(isRetorikNews || route === (0, $8ItUL.Routes).NewsInVeille);
289
+ }, [
290
+ route
291
+ ]);
292
+ /**
293
+ * On cancel call, reset all data and kill current streaming
294
+ */ (0, $cMDfV$useEffect)(()=>{
295
+ cancel && resetData();
296
+ }, [
297
+ cancel
298
+ ]);
299
+ /**
300
+ * Play external speech immediately but don't add it to the history
301
+ */ (0, $cMDfV$useEffect)(()=>{
302
+ if (externalTextToSpeech) {
303
+ const activity = {
304
+ speak: externalTextToSpeech,
305
+ locale: locale
306
+ };
307
+ currentActivityRef.current = activity;
308
+ setUtterance(checkReplacementLocaleAndGetUtterance(activity, false));
309
+ }
310
+ }, [
311
+ externalTextToSpeech
312
+ ]);
313
+ const dispatchSpeechEvent = (start)=>{
314
+ const speechEvent = start ? new Event('retorikSpeakStart') : new Event('retorikSpeakStop');
315
+ document.dispatchEvent(speechEvent);
316
+ };
317
+ /**
318
+ * Called when utterance's "start" event is fired
319
+ */ const handleUtteranceStart = ()=>{
320
+ sendTrace((0, $4ucVo.TraceType).utteranceStart, {
321
+ activityId: currentActivityRef.current?.id,
322
+ text: currentActivityRef.current?.speak || currentActivityRef.current?.text
323
+ });
324
+ dispatch((0, $8ItUL.storeActions).speech.setSpeaking(true));
325
+ if (!isNewsViewRef.current && currentActivityRef?.current) {
326
+ dispatch((0, $8ItUL.storeActions).speech.setCurrentOrLastPlayedActivity(currentActivityRef.current));
327
+ currentActivityRef.current.id && dispatch((0, $8ItUL.storeActions).directline.dispatchMarkActivity({
328
+ id: currentActivityRef.current.id,
329
+ speaking: true
330
+ }));
331
+ }
332
+ dispatchSpeechEvent(true);
333
+ // Set next utterance to prepare synthesis data in order to improve fluidity
334
+ if (streamingQueueRef.current.length && !streamingQueueRef.current[0].value?.streamingCount) {
335
+ const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[0], false);
336
+ setNextUtterance((current)=>utt.text === current?.text ? null : utt);
337
+ } else setNextUtterance(null);
338
+ };
339
+ /**
340
+ * Called when utterance's "end" event is fired
341
+ */ const handleUtteranceEnd = ()=>{
342
+ sendTrace((0, $4ucVo.TraceType).utteranceEnd, {
343
+ activityId: currentActivityRef.current?.id
344
+ });
345
+ dispatch((0, $8ItUL.storeActions).speech.setSpeaking(false));
346
+ dispatchSpeechEvent(false);
347
+ if (isNewsViewRef.current) {
348
+ dispatch((0, $8ItUL.storeActions).utils.setRetorikNewsEnded(true));
349
+ currentActivityRef.current = null;
350
+ } else handleEnded();
351
+ };
352
+ const handleEnded = ()=>{
353
+ // Add played activity id to context's endedActivities
354
+ if (currentActivityRef.current?.id) {
355
+ dispatch((0, $8ItUL.storeActions).activity.addEndedActivity(currentActivityRef.current.id));
356
+ dispatch((0, $8ItUL.storeActions).directline.dispatchMarkActivity({
357
+ id: currentActivityRef.current.id,
358
+ speaking: false
359
+ }));
360
+ }
361
+ if (streamingQueueRef.current?.length) {
362
+ // Check if this is the message sent after streaming activities
363
+ if (streamingQueueRef.current[0].value?.streamingCount) {
364
+ dispatch((0, $8ItUL.storeActions).activity.addEndedActivity(streamingQueueRef.current[0].id));
365
+ // If there is another activity after this message, play it. If not, let's check if the microphone should be opened
366
+ if (streamingQueueRef.current?.length > 1) {
367
+ const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[1]);
368
+ currentActivityRef.current = streamingQueueRef.current[1];
369
+ setUtterance(utt);
370
+ dispatch((0, $8ItUL.storeActions).speech.removeFirstFromStreamingQueue(true));
371
+ } else {
372
+ streamingQueueRef.current[0].inputHint === 'expectingInput' && checkDictateState();
373
+ currentActivityRef.current = null;
374
+ setUtterance(null);
375
+ setNextUtterance(null);
376
+ dispatch((0, $8ItUL.storeActions).speech.removeFirstFromStreamingQueue(false));
377
+ }
378
+ } else {
379
+ const utt = checkReplacementLocaleAndGetUtterance(streamingQueueRef.current[0]);
380
+ currentActivityRef.current = streamingQueueRef.current[0];
381
+ setUtterance(utt);
382
+ dispatch((0, $8ItUL.storeActions).speech.removeFirstFromStreamingQueue(false));
383
+ }
384
+ } else {
385
+ currentActivityRef.current?.inputHint === 'expectingInput' && checkDictateState();
386
+ currentActivityRef.current = null;
387
+ setUtterance(null);
388
+ setNextUtterance(null);
389
+ }
390
+ };
391
+ /**
392
+ * Wait for app loading and voice selection to begin playing speech
393
+ */ (0, $cMDfV$useEffect)(()=>{
394
+ // Set ref from the state to use in events
395
+ streamingQueueRef.current = streamingQueue;
396
+ if (appAvailable && voice && streamingQueue.length && !currentActivityRef.current) handleEnded();
397
+ }, [
398
+ appAvailable,
399
+ voice,
400
+ streamingQueue
401
+ ]);
402
+ return /*#__PURE__*/ (0, $cMDfV$jsx)((0, $b56Ud.default), {
403
+ ponyfill: ponyfill,
404
+ appAvailable: appAvailable,
405
+ utterance: utterance,
406
+ nextUtterance: nextUtterance,
407
+ forceSpeechCaching: forceSpeechCaching,
408
+ onStart: handleUtteranceStart,
409
+ onError: handleUtteranceEnd,
410
+ onEnd: handleUtteranceEnd
411
+ });
412
+ };
413
+ var $0b8e5d756ffed1ac$export$2e2bcd8739ae039 = $0b8e5d756ffed1ac$var$SynthesisManager;
414
+
415
+ });
416
+ parcelRegister("7UkSC", function(module, exports) {
417
+
418
+ $parcel$export(module.exports, "checkSayAsWordsAndCreateUtterance", () => $66dccbb634d6ce27$export$f969af62bba9a48b);
419
+
420
+ var $jvc7U = parcelRequire("jvc7U");
421
+ /**
422
+ * Check if there are some replacement codes for this language, to improve speech synthesis, and then create the utterance
423
+ * @param {CreateUtteranceParams} params - data needed to create an utterance
424
+ * @param {SayAs} sayAs - string that should be replaced by their ipa codes
425
+ * @returns {SpeechSynthesisUtterance}
426
+ */ const $66dccbb634d6ce27$export$f969af62bba9a48b = (params, sayAs)=>{
427
+ let sayAsWords = [];
428
+ if (sayAs) {
429
+ sayAs.common?.length && (sayAsWords = [
430
+ ...sayAs.common
431
+ ]);
432
+ sayAs.localized && sayAs.localized[params.locale]?.length && (sayAsWords = [
433
+ ...sayAsWords,
434
+ ...sayAs.localized[params.locale]
435
+ ]);
436
+ }
437
+ return (0, $jvc7U.default)({
438
+ ...params,
439
+ sayAsWords: sayAsWords
440
+ });
441
+ };
442
+
443
+ });
444
+ parcelRegister("jvc7U", function(module, exports) {
445
+
446
+ $parcel$export(module.exports, "default", () => $972cc4ac7a9f8914$export$2e2bcd8739ae039);
447
+
448
+
449
+ const $972cc4ac7a9f8914$var$buildSSML = (activity, locale, speechMarkdownParser, sayAsWords)=>{
450
+ let speech = activity.speak || activity.text;
451
+ // Replace character not recognized in Microsoft TTS
452
+ speech = speech.replaceAll("\u2019", "'");
453
+ let textParsedAsSSML = '';
454
+ try {
455
+ if (sayAsWords?.length) {
456
+ const wordsUsed = [];
457
+ sayAsWords.forEach((tuple)=>{
458
+ if (!wordsUsed.includes(tuple.text.toLocaleLowerCase(locale))) {
459
+ const regex = new RegExp(`\\b${tuple.text}\\b`, 'gi');
460
+ speech = speech.replaceAll(regex, `(${tuple.text})[ipa:"${tuple.ipa}"]`);
461
+ wordsUsed.push(tuple.text.toLocaleLowerCase(locale));
462
+ }
463
+ });
464
+ }
465
+ textParsedAsSSML = speechMarkdownParser.toSSML(speech);
466
+ } catch (e) {
467
+ console.warn('Retorik Framework > error in speechmarkdown parser : ', e);
468
+ }
469
+ return `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" xml:lang="${locale}">` + textParsedAsSSML + '</speak>';
470
+ };
471
+ const $972cc4ac7a9f8914$var$createUtterance = ({ activity: activity, voice: voice, locale: locale, sayAsWords: sayAsWords })=>{
472
+ // If there is no text to be read, create an empty utterance that will be put in the array of ended activities
473
+ if (!voice || !activity.speak && !activity.text) return new (0, $cMDfV$SpeechSynthesisUtterance)('');
474
+ return new (0, $cMDfV$SpeechSynthesisUtterance)($972cc4ac7a9f8914$var$buildSSML(activity, locale, new (0, $cMDfV$SpeechMarkdown)({
475
+ platform: 'microsoft-azure',
476
+ includeSpeakTag: false,
477
+ globalVoiceAndLang: {
478
+ voice: voice.name,
479
+ lang: voice.name.toLowerCase().includes('multilingual') ? locale : undefined
480
+ }
481
+ }), sayAsWords));
482
+ };
483
+ var $972cc4ac7a9f8914$export$2e2bcd8739ae039 = $972cc4ac7a9f8914$var$createUtterance;
484
+
485
+ });
486
+
487
+
488
+ parcelRegister("b56Ud", function(module, exports) {
489
+
490
+ $parcel$export(module.exports, "default", () => $637384b103093c58$export$2e2bcd8739ae039);
491
+
492
+
493
+
494
+
495
+ var $8ItUL = parcelRequire("8ItUL");
496
+
497
+ var $9RfWh = parcelRequire("9RfWh");
498
+
499
+ var $eAy5f = parcelRequire("eAy5f");
500
+
501
+ var $6zM6Q = parcelRequire("6zM6Q");
502
+ const $637384b103093c58$var$DBManager = new (0, $eAy5f.default)();
503
+ const $637384b103093c58$var$tagsRemoverRegex = /<[^<>]+>/g;
504
+ const $637384b103093c58$var$RetorikSpeech = ({ ponyfill: ponyfill, onEnd: onEnd, onError: onError, onStart: onStart, utterance: utterance, nextUtterance: nextUtterance, appAvailable: appAvailable, forceSpeechCaching: forceSpeechCaching })=>{
505
+ const dispatch = (0, $cMDfV$useDispatch)();
506
+ const locale = (0, $cMDfV$useSelector)((state)=>state.localeReducer.locale);
507
+ const loaderClosed = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.loaderClosed);
508
+ const enableSpeechCaching = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.configuration.enableSpeechCaching);
509
+ const speechRecognitionOptions = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.configuration.speechRecognitionOptions);
510
+ const useOldRemote = (0, $cMDfV$useSelector)((state)=>state.retorikReducer.configuration.useOldRemote);
511
+ const voice = (0, $cMDfV$useSelector)((state)=>state.speechReducer.voice);
512
+ const muted = (0, $cMDfV$useSelector)((state)=>state.speechReducer.muted);
513
+ const activeRecognitionState = (0, $cMDfV$useSelector)((state)=>state.speechReducer.activeRecognitionState);
514
+ const boundaryRef = (0, $cMDfV$useRef)(null);
515
+ const visemeRef = (0, $cMDfV$useRef)(null);
516
+ const bookmarkRef = (0, $cMDfV$useRef)(null);
517
+ const audioRef = (0, $cMDfV$useRef)(null);
518
+ const speechRecognitionAudioRef = (0, $cMDfV$useRef)(null);
519
+ const microphoneOpenAudioRef = (0, $cMDfV$useRef)(null);
520
+ const microphoneCloseAudioRef = (0, $cMDfV$useRef)(null);
521
+ const [DBReady, setDBReady] = (0, $cMDfV$useState)(false);
522
+ const [playingBlob, setPlayingBlob] = (0, $cMDfV$useState)(false);
523
+ const nextUtteranceDataRef = (0, $cMDfV$useRef)(null);
524
+ const nextUtteranceTextRef = (0, $cMDfV$useRef)(null);
525
+ const nextUtteranceBoundariesRef = (0, $cMDfV$useRef)([]);
526
+ const nextUtteranceVisemesRef = (0, $cMDfV$useRef)([]);
527
+ const nextUtteranceBookmarksRef = (0, $cMDfV$useRef)([]);
528
+ const emptyTextUtteranceRef = (0, $cMDfV$useRef)(null);
529
+ (0, $cMDfV$useEffect)(()=>{
530
+ $637384b103093c58$var$DBManager.checkDB().then((result)=>setDBReady(result));
531
+ return ()=>{
532
+ stopCurrentPlaying();
533
+ emptyTextUtteranceRef?.current && clearTimeout(emptyTextUtteranceRef.current);
534
+ };
535
+ }, []);
536
+ const stopCurrentPlaying = ()=>{
537
+ if (appAvailable || loaderClosed) {
538
+ // Cancel synthesis if using synthesizer
539
+ if (!playingBlob) ponyfill.speechSynthesis.cancel();
540
+ resetNextUtteranceData();
541
+ if (audioRef.current && !audioRef.current?.paused) {
542
+ audioRef.current.pause();
543
+ handleEnd();
544
+ }
545
+ }
546
+ };
547
+ const attachEvents = (tempUtterance, isMainUtterance)=>{
548
+ tempUtterance.onerror = (event)=>{
549
+ isMainUtterance ? handleError(event) : nextUtteranceDataRef.current = null;
550
+ };
551
+ tempUtterance.onsynthesiscompleted = ()=>{
552
+ const endBoundary = {
553
+ word: '',
554
+ startTime: 0,
555
+ endTime: 0,
556
+ boundaryType: 'EndBoundary'
557
+ };
558
+ if (isMainUtterance) {
559
+ const tempBoundaries = boundaryRef?.current || [];
560
+ boundaryRef.current = [
561
+ ...tempBoundaries,
562
+ endBoundary
563
+ ];
564
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData([
565
+ ...tempBoundaries,
566
+ endBoundary
567
+ ]));
568
+ } else nextUtteranceBoundariesRef.current = [
569
+ ...nextUtteranceBoundariesRef.current,
570
+ endBoundary
571
+ ];
572
+ };
573
+ tempUtterance.onboundary = (event)=>{
574
+ if (event.boundaryType !== 'Viseme') {
575
+ const newBoundary = {
576
+ word: event.name,
577
+ startTime: event.elapsedTime,
578
+ endTime: event.elapsedTime + event.duration,
579
+ boundaryType: event.boundaryType
580
+ };
581
+ if (isMainUtterance) {
582
+ // Update the boundaryData state with the new data.
583
+ const tempBoundaries = boundaryRef?.current || [];
584
+ boundaryRef.current = [
585
+ ...tempBoundaries,
586
+ newBoundary
587
+ ];
588
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData([
589
+ ...tempBoundaries,
590
+ newBoundary
591
+ ]));
592
+ } else nextUtteranceBoundariesRef.current = [
593
+ ...nextUtteranceBoundariesRef.current,
594
+ newBoundary
595
+ ];
596
+ }
597
+ };
598
+ tempUtterance.onviseme = (event)=>{
599
+ if (isMainUtterance) {
600
+ // Collect visemes locally - they will be dispatched when audio starts playing
601
+ const tempVisemes = visemeRef?.current || [];
602
+ visemeRef.current = [
603
+ ...tempVisemes,
604
+ event
605
+ ];
606
+ } else nextUtteranceVisemesRef.current = [
607
+ ...nextUtteranceVisemesRef.current,
608
+ event
609
+ ];
610
+ };
611
+ tempUtterance.onmark = (event)=>{
612
+ console.log('Retorik Framework > onmark event', event);
613
+ const bookmark = {
614
+ name: event.name,
615
+ time: event.elapsedTime
616
+ };
617
+ if (isMainUtterance) {
618
+ // Collect bookmarks locally - they will be dispatched when audio starts playing
619
+ const tempBookmarks = bookmarkRef?.current || [];
620
+ bookmarkRef.current = [
621
+ ...tempBookmarks,
622
+ bookmark
623
+ ];
624
+ } else nextUtteranceBookmarksRef.current = [
625
+ ...nextUtteranceBookmarksRef.current,
626
+ bookmark
627
+ ];
628
+ };
629
+ return tempUtterance;
630
+ };
631
+ const processNextData = (data)=>{
632
+ nextUtteranceDataRef.current = data?.byteLength && nextUtteranceTextRef.current ? {
633
+ text: nextUtteranceTextRef.current,
634
+ data: {
635
+ speechData: data,
636
+ boundaries: nextUtteranceBoundariesRef.current,
637
+ visemes: nextUtteranceVisemesRef.current,
638
+ bookmarks: nextUtteranceBookmarksRef.current
639
+ }
640
+ } : null;
641
+ // Reset boundary / viseme data
642
+ resetNextUtteranceData(true);
643
+ };
644
+ const resetNextUtteranceData = (keepArrayBufferData)=>{
645
+ !keepArrayBufferData && (nextUtteranceDataRef.current = null);
646
+ nextUtteranceTextRef.current = null;
647
+ nextUtteranceBoundariesRef.current = [];
648
+ nextUtteranceVisemesRef.current = [];
649
+ nextUtteranceBookmarksRef.current = [];
650
+ };
651
+ (0, $cMDfV$useEffect)(()=>{
652
+ if (utterance) {
653
+ if (utterance.text) {
654
+ if (audioRef?.current) {
655
+ if (nextUtteranceDataRef.current?.text === utterance.text && nextUtteranceDataRef.current.data) {
656
+ boundaryRef.current = nextUtteranceDataRef.current.data.boundaries;
657
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData(nextUtteranceDataRef.current.data.boundaries));
658
+ // Store visemes locally - they will be dispatched when audio starts playing
659
+ visemeRef.current = nextUtteranceDataRef.current.data.visemes;
660
+ processData(nextUtteranceDataRef.current.data.speechData, true);
661
+ } else // Play utterance whether by asking for a speech synthesis, or by retrieving data from indexedDB
662
+ playUtterance(attachEvents(utterance, true));
663
+ } else stopCurrentPlaying();
664
+ } else handleEmptyTextUtterance();
665
+ } else stopCurrentPlaying();
666
+ }, [
667
+ utterance
668
+ ]);
669
+ (0, $cMDfV$useEffect)(()=>{
670
+ // If there are data in nextUtteranceTextRef, this means the previous synthesis data retrieval is not finished, so we don't begin a new one
671
+ if (nextUtterance?.text && !nextUtteranceTextRef.current) {
672
+ const tempUtterance = attachEvents(nextUtterance);
673
+ nextUtteranceTextRef.current = nextUtterance.text;
674
+ ponyfill.speechSynthesis.synthesizeAndGetArrayData(tempUtterance, processNextData);
675
+ } else resetNextUtteranceData();
676
+ }, [
677
+ nextUtterance
678
+ ]);
679
+ const playUtterance = async (utt)=>{
680
+ if (DBReady && (enableSpeechCaching !== false || forceSpeechCaching) && utt) {
681
+ const dataFromIndexedDB = await $637384b103093c58$var$DBManager.getSpeechData(`${locale}.${voice?.name}.${utt.text.replace($637384b103093c58$var$tagsRemoverRegex, '')}`);
682
+ if (dataFromIndexedDB) {
683
+ boundaryRef.current = dataFromIndexedDB.boundaries;
684
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData(dataFromIndexedDB.boundaries));
685
+ // Store visemes locally - they will be dispatched when audio starts playing
686
+ visemeRef.current = dataFromIndexedDB.visemes || [];
687
+ processData(dataFromIndexedDB.value, true);
688
+ } else ponyfill.speechSynthesis.synthesizeAndGetArrayData(utt, processData);
689
+ } else ponyfill.speechSynthesis.synthesizeAndGetArrayData(utt, processData);
690
+ };
691
+ const processData = (data, alreadyExistsInDB)=>{
692
+ if (data?.byteLength) {
693
+ const blob = new Blob([
694
+ data
695
+ ], {
696
+ type: 'audio/mp3'
697
+ });
698
+ !alreadyExistsInDB && (enableSpeechCaching !== false || forceSpeechCaching) && DBReady && boundaryRef?.current && utterance && $637384b103093c58$var$DBManager.addSpeechData({
699
+ id: `${locale}.${voice?.name}.${utterance.text.replace($637384b103093c58$var$tagsRemoverRegex, '')}`,
700
+ value: data,
701
+ boundaries: boundaryRef.current,
702
+ visemes: visemeRef.current || []
703
+ });
704
+ const url = URL.createObjectURL(blob);
705
+ if (audioRef?.current) {
706
+ setPlayingBlob(true);
707
+ audioRef.current.src = url;
708
+ audioRef.current.play().catch((e)=>console.warn(e));
709
+ }
710
+ } else handleEmptyTextUtterance();
711
+ };
712
+ const resetData = ()=>{
713
+ boundaryRef.current = [];
714
+ visemeRef.current = [];
715
+ dispatch((0, $8ItUL.storeActions).speech.setBoundaryData([]));
716
+ dispatch((0, $8ItUL.storeActions).speech.setVisemeData([]));
717
+ dispatch((0, $8ItUL.storeActions).speech.setBookmarkData([]));
718
+ setPlayingBlob(false);
719
+ };
720
+ const handleStart = ()=>{
721
+ if (appAvailable || loaderClosed) {
722
+ // Dispatch visemes now that audio is playing, ensuring lip sync timing is correct
723
+ if (visemeRef.current?.length) {
724
+ dispatch((0, $8ItUL.storeActions).speech.setVisemeData(visemeRef.current));
725
+ dispatch((0, $8ItUL.storeActions).speech.setBookmarkData(bookmarkRef.current || []));
726
+ }
727
+ onStart?.();
728
+ }
729
+ };
730
+ const handleEnd = ()=>{
731
+ if (appAvailable || loaderClosed) {
732
+ onEnd?.();
733
+ resetData();
734
+ } else dispatch((0, $8ItUL.storeActions).retorik.setLoaderClosed(true));
735
+ };
736
+ const handleError = (error)=>{
737
+ console.log('Retorik Framework > speech synthesis error ', error);
738
+ onError?.();
739
+ resetData();
740
+ };
741
+ const handleEmptyTextUtterance = ()=>{
742
+ handleStart();
743
+ emptyTextUtteranceRef?.current && clearTimeout(emptyTextUtteranceRef.current);
744
+ emptyTextUtteranceRef.current = setTimeout(()=>{
745
+ handleEnd();
746
+ }, 50);
747
+ };
748
+ /**
749
+ * On call :
750
+ * - play 1 second muted sound to prime audio output
751
+ * - MANDATORY FOR SAFARI IN VOCAL MODE
752
+ */ const primeRetorikSpeech = ()=>{
753
+ if (audioRef.current) {
754
+ audioRef.current.play().catch((e)=>console.warn(e));
755
+ speechRecognitionAudioRef?.current && speechRecognitionAudioRef.current.play().catch((e)=>console.warn(e));
756
+ // Send animation start event to secure animation not playing on safari if permissions are not sufficient
757
+ window.dispatchEvent(new Event('retorikSpiritEnginePlay'));
758
+ }
759
+ };
760
+ /**
761
+ * Play sound on speech recognition activation if it isn't disabled in configuration
762
+ */ (0, $cMDfV$useEffect)(()=>{
763
+ if (useOldRemote) {
764
+ if (!!speechRecognitionOptions?.enableActivationSound && activeRecognitionState === (0, $8ItUL.RecognitionState).Listening) speechRecognitionAudioRef?.current?.play().catch((e)=>console.warn(e));
765
+ } else if (!!speechRecognitionOptions?.enableActivationSound) switch(activeRecognitionState){
766
+ case (0, $8ItUL.RecognitionState).Listening:
767
+ microphoneOpenAudioRef?.current?.play().catch((e)=>console.warn(e));
768
+ break;
769
+ case (0, $8ItUL.RecognitionState).Closing:
770
+ case (0, $8ItUL.RecognitionState).ForceClosing:
771
+ microphoneCloseAudioRef?.current?.play().catch((e)=>console.warn(e));
772
+ break;
773
+ default:
774
+ break;
775
+ }
776
+ }, [
777
+ useOldRemote,
778
+ activeRecognitionState,
779
+ speechRecognitionOptions
780
+ ]);
781
+ return /*#__PURE__*/ (0, $cMDfV$jsxs)((0, $cMDfV$react).Fragment, {
782
+ children: [
783
+ /*#__PURE__*/ (0, $cMDfV$jsx)("audio", {
784
+ ref: audioRef,
785
+ src: (0, $9RfWh.audioFiles).onesecond,
786
+ muted: appAvailable || loaderClosed ? muted : true,
787
+ onPlay: handleStart,
788
+ onEnded: handleEnd
789
+ }),
790
+ /*#__PURE__*/ (0, $cMDfV$jsx)("audio", {
791
+ ref: speechRecognitionAudioRef,
792
+ src: (0, $9RfWh.audioFiles).speechrecognition,
793
+ preload: "auto",
794
+ muted: appAvailable || loaderClosed ? muted : true
795
+ }),
796
+ /*#__PURE__*/ (0, $cMDfV$jsx)("audio", {
797
+ ref: microphoneOpenAudioRef,
798
+ src: (0, $9RfWh.audioFiles).microphoneopen,
799
+ preload: "auto",
800
+ muted: appAvailable || loaderClosed ? muted : true
801
+ }),
802
+ /*#__PURE__*/ (0, $cMDfV$jsx)("audio", {
803
+ ref: microphoneCloseAudioRef,
804
+ src: (0, $9RfWh.audioFiles).microphoneclose,
805
+ preload: "auto",
806
+ muted: appAvailable || loaderClosed ? muted : true
807
+ }),
808
+ /*#__PURE__*/ (0, $cMDfV$jsx)((0, $6zM6Q.default), {
809
+ appAvailable: appAvailable,
810
+ handleValidation: primeRetorikSpeech
811
+ })
812
+ ]
813
+ });
814
+ };
815
+ var $637384b103093c58$export$2e2bcd8739ae039 = $637384b103093c58$var$RetorikSpeech;
816
+
817
+ });
818
+ parcelRegister("eAy5f", function(module, exports) {
819
+
820
+ $parcel$export(module.exports, "default", () => $f8b1c4b1ab628567$export$2e2bcd8739ae039);
821
+ class $f8b1c4b1ab628567$var$IndexedDbManager {
822
+ constructor(){
823
+ this.version = 1;
824
+ this.storeName = 'speechSynthesisData';
825
+ this.checkDB = async ()=>{
826
+ return new Promise((resolve)=>{
827
+ const request = indexedDB.open('retorik-framework-db', this.version);
828
+ request.onsuccess = ()=>{
829
+ resolve(true);
830
+ };
831
+ request.onerror = ()=>{
832
+ resolve(false);
833
+ };
834
+ request.onupgradeneeded = ()=>{
835
+ const db = request.result;
836
+ // If the data object store doesn't exist, create it
837
+ if (!db.objectStoreNames.contains(this.storeName)) db.createObjectStore(this.storeName, {
838
+ keyPath: 'id'
839
+ });
840
+ };
841
+ });
842
+ };
843
+ this.addSpeechData = async (data)=>{
844
+ return new Promise((resolve)=>{
845
+ const request = indexedDB.open('retorik-framework-db', this.version);
846
+ request.onsuccess = ()=>{
847
+ const db = request.result;
848
+ const tx = db.transaction(this.storeName, 'readwrite');
849
+ const store = tx.objectStore(this.storeName);
850
+ // Base 64 encode
851
+ data.id = window.btoa(encodeURI(data.id));
852
+ store.add(data);
853
+ resolve(true);
854
+ };
855
+ request.onerror = ()=>{
856
+ resolve(false);
857
+ };
858
+ });
859
+ };
860
+ this.getSpeechData = async (id)=>{
861
+ return new Promise((resolve)=>{
862
+ const request = indexedDB.open('retorik-framework-db', this.version);
863
+ request.onsuccess = ()=>{
864
+ const db = request.result;
865
+ const tx = db.transaction(this.storeName, 'readonly');
866
+ const store = tx.objectStore(this.storeName);
867
+ // Base 64 encode
868
+ const data = store.get(window.btoa(encodeURI(id)));
869
+ data.onsuccess = ()=>{
870
+ resolve(data.result);
871
+ };
872
+ };
873
+ request.onerror = ()=>{
874
+ resolve(null);
875
+ };
876
+ });
877
+ };
878
+ }
879
+ }
880
+ var $f8b1c4b1ab628567$export$2e2bcd8739ae039 = $f8b1c4b1ab628567$var$IndexedDbManager;
881
+
882
+ });
883
+
884
+
885
+
886
+
887
+
888
+ //# sourceMappingURL=SynthesisPonyfillManager.10888d6d.js.map