@sage-rsc/talking-head-react 1.0.30 → 1.0.31

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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-BFQNNYmP.cjs");exports.CurriculumLearning=i.CurriculumLearning;exports.TalkingHeadAvatar=i.TalkingHeadAvatar;exports.TalkingHeadComponent=i.TalkingHeadComponent;exports.animations=i.animations;exports.getActiveTTSConfig=i.getActiveTTSConfig;exports.getAnimation=i.getAnimation;exports.getVoiceOptions=i.getVoiceOptions;exports.hasAnimation=i.hasAnimation;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index-WXvj5jje.cjs");exports.CurriculumLearning=i.CurriculumLearning;exports.TalkingHeadAvatar=i.TalkingHeadAvatar;exports.TalkingHeadComponent=i.TalkingHeadComponent;exports.animations=i.animations;exports.getActiveTTSConfig=i.getActiveTTSConfig;exports.getAnimation=i.getAnimation;exports.getVoiceOptions=i.getVoiceOptions;exports.hasAnimation=i.hasAnimation;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as n, T as s, a as t, d as e, b as o, g, c as m, h as r } from "./index-V_d1NQ-5.js";
1
+ import { C as n, T as s, a as t, d as e, b as o, g, c as m, h as r } from "./index-iUfJQ70v.js";
2
2
  export {
3
3
  n as CurriculumLearning,
4
4
  s as TalkingHeadAvatar,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sage-rsc/talking-head-react",
3
- "version": "1.0.30",
3
+ "version": "1.0.31",
4
4
  "description": "A reusable React component for 3D talking avatars with lip-sync and text-to-speech",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -58,45 +58,74 @@ const CurriculumLearning = forwardRef(({
58
58
  const nextQuestionRef = useRef(null);
59
59
  const completeCurriculumRef = useRef(null);
60
60
  const startQuestionsRef = useRef(null);
61
-
62
- // Update callbacks ref when they change
63
- useEffect(() => {
64
- callbacksRef.current = {
65
- onLessonStart,
66
- onLessonComplete,
67
- onQuestionAnswer,
68
- onCurriculumComplete,
69
- onCustomAction
70
- };
71
- }, [onLessonStart, onLessonComplete, onQuestionAnswer, onCurriculumComplete, onCustomAction]);
72
-
73
- const curriculum = curriculumData?.curriculum || {
61
+ const handleAnswerSelectRef = useRef(null);
62
+
63
+ // Store curriculum in ref to avoid dependency issues - initialize early
64
+ const curriculumRef = useRef(curriculumData?.curriculum || {
74
65
  title: "Default Curriculum",
75
66
  description: "No curriculum data provided",
76
67
  language: "en",
77
68
  modules: []
78
- };
79
-
80
- const defaultAvatarConfig = {
69
+ });
70
+
71
+ // Store avatar config in ref to avoid dependency issues - initialize early
72
+ const defaultAvatarConfigRef = useRef({
81
73
  avatarUrl: avatarConfig.avatarUrl || "/avatars/brunette.glb",
82
74
  avatarBody: avatarConfig.avatarBody || "F",
83
75
  mood: avatarConfig.mood || "happy",
84
76
  ttsLang: avatarConfig.ttsLang || "en",
85
- ttsService: avatarConfig.ttsService || null, // Don't default to "edge" - let config decide
86
- ttsVoice: avatarConfig.ttsVoice || null, // Don't default - let config decide
77
+ ttsService: avatarConfig.ttsService || null,
78
+ ttsVoice: avatarConfig.ttsVoice || null,
87
79
  ttsApiKey: avatarConfig.ttsApiKey || null,
88
80
  bodyMovement: avatarConfig.bodyMovement || "gesturing",
89
81
  movementIntensity: avatarConfig.movementIntensity || 0.7,
90
82
  showFullAvatar: avatarConfig.showFullAvatar !== undefined ? avatarConfig.showFullAvatar : true,
91
83
  animations: animations,
92
- lipsyncLang: 'en' // Default lipsync language
93
- };
84
+ lipsyncLang: 'en'
85
+ });
86
+
87
+ // Update callbacks ref when they change
88
+ useEffect(() => {
89
+ callbacksRef.current = {
90
+ onLessonStart,
91
+ onLessonComplete,
92
+ onQuestionAnswer,
93
+ onCurriculumComplete,
94
+ onCustomAction
95
+ };
96
+ }, [onLessonStart, onLessonComplete, onQuestionAnswer, onCurriculumComplete, onCustomAction]);
97
+
98
+ // Update curriculum and config refs when they change
99
+ useEffect(() => {
100
+ curriculumRef.current = curriculumData?.curriculum || {
101
+ title: "Default Curriculum",
102
+ description: "No curriculum data provided",
103
+ language: "en",
104
+ modules: []
105
+ };
106
+
107
+ defaultAvatarConfigRef.current = {
108
+ avatarUrl: avatarConfig.avatarUrl || "/avatars/brunette.glb",
109
+ avatarBody: avatarConfig.avatarBody || "F",
110
+ mood: avatarConfig.mood || "happy",
111
+ ttsLang: avatarConfig.ttsLang || "en",
112
+ ttsService: avatarConfig.ttsService || null,
113
+ ttsVoice: avatarConfig.ttsVoice || null,
114
+ ttsApiKey: avatarConfig.ttsApiKey || null,
115
+ bodyMovement: avatarConfig.bodyMovement || "gesturing",
116
+ movementIntensity: avatarConfig.movementIntensity || 0.7,
117
+ showFullAvatar: avatarConfig.showFullAvatar !== undefined ? avatarConfig.showFullAvatar : true,
118
+ animations: animations,
119
+ lipsyncLang: 'en'
120
+ };
121
+ }, [curriculumData, avatarConfig, animations]);
94
122
 
95
123
  // Helper to get current lesson/question
96
124
  const getCurrentLesson = useCallback(() => {
125
+ const curriculum = curriculumRef.current || { modules: [] };
97
126
  const module = curriculum.modules[stateRef.current.currentModuleIndex];
98
127
  return module?.lessons[stateRef.current.currentLessonIndex];
99
- }, [curriculum]);
128
+ }, []);
100
129
 
101
130
  const getCurrentQuestion = useCallback(() => {
102
131
  const lesson = getCurrentLesson();
@@ -130,7 +159,7 @@ const CurriculumLearning = forwardRef(({
130
159
  let feedbackMessage = `Congratulations! You've completed this lesson`;
131
160
  if (stateRef.current.totalQuestions > 0) {
132
161
  feedbackMessage += ` with a score of ${stateRef.current.score} out of ${stateRef.current.totalQuestions} (${percentage}%). `;
133
- } else {
162
+ } else {
134
163
  feedbackMessage += `! `;
135
164
  }
136
165
 
@@ -161,23 +190,26 @@ const CurriculumLearning = forwardRef(({
161
190
  });
162
191
 
163
192
  if (avatarRef.current) {
164
- avatarRef.current.setMood("happy");
193
+ avatarRef.current.setMood("happy");
165
194
  if (animations.lessonComplete) {
166
195
  try {
167
196
  avatarRef.current.playAnimation(animations.lessonComplete, true);
168
197
  } catch (error) {
169
- avatarRef.current.playCelebration();
198
+ avatarRef.current.playCelebration();
170
199
  }
171
200
  }
172
201
 
173
202
  // Check if there's a next lesson available
203
+ const curriculum = curriculumRef.current || { modules: [] };
174
204
  const currentModule = curriculum.modules[stateRef.current.currentModuleIndex];
175
205
  const hasNextLesson = stateRef.current.currentLessonIndex < (currentModule?.lessons?.length || 0) - 1;
176
206
 
207
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
208
+
177
209
  if (hasNextLesson) {
178
210
  // Wait for speech to finish, then automatically move to next lesson
179
211
  avatarRef.current.speakText(feedbackMessage, {
180
- lipsyncLang: defaultAvatarConfig.lipsyncLang,
212
+ lipsyncLang: config.lipsyncLang,
181
213
  onSpeechEnd: () => {
182
214
  // Add a small delay after speech ends for natural flow
183
215
  setTimeout(() => {
@@ -188,10 +220,10 @@ const CurriculumLearning = forwardRef(({
188
220
  }, 1000);
189
221
  }
190
222
  });
191
- } else {
223
+ } else {
192
224
  // This is the last lesson, complete curriculum instead
193
225
  avatarRef.current.speakText(feedbackMessage, {
194
- lipsyncLang: defaultAvatarConfig.lipsyncLang,
226
+ lipsyncLang: config.lipsyncLang,
195
227
  onSpeechEnd: () => {
196
228
  // Add a small delay after speech ends for natural flow
197
229
  setTimeout(() => {
@@ -203,18 +235,19 @@ const CurriculumLearning = forwardRef(({
203
235
  });
204
236
  }
205
237
  }
206
- }, [animations.lessonComplete, curriculum, defaultAvatarConfig]);
238
+ }, [animations.lessonComplete]);
207
239
 
208
240
  // Complete entire curriculum
209
241
  const completeCurriculum = useCallback(() => {
210
242
  stateRef.current.curriculumCompleted = true;
211
243
 
244
+ const curriculum = curriculumRef.current || { modules: [] };
212
245
  callbacksRef.current.onCurriculumComplete({
213
246
  modules: curriculum.modules.length,
214
247
  totalLessons: curriculum.modules.reduce((sum, mod) => sum + mod.lessons.length, 0)
215
248
  });
216
-
217
- if (avatarRef.current) {
249
+
250
+ if (avatarRef.current) {
218
251
  avatarRef.current.setMood("celebrating");
219
252
  if (animations.curriculumComplete) {
220
253
  try {
@@ -223,9 +256,10 @@ const CurriculumLearning = forwardRef(({
223
256
  avatarRef.current.playCelebration();
224
257
  }
225
258
  }
226
- avatarRef.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: defaultAvatarConfig.lipsyncLang });
259
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
260
+ avatarRef.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: config.lipsyncLang });
227
261
  }
228
- }, [animations.curriculumComplete, curriculum, defaultAvatarConfig]);
262
+ }, [animations.curriculumComplete]);
229
263
 
230
264
  // Start asking questions
231
265
  const startQuestions = useCallback(() => {
@@ -260,20 +294,23 @@ const CurriculumLearning = forwardRef(({
260
294
  }
261
295
  }
262
296
 
297
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
298
+
263
299
  // Introduce the first question properly based on type
264
300
  if (firstQuestion.type === 'code_test') {
265
- avatarRef.current.speakText(`Let's test your coding skills! Here's your first challenge: ${firstQuestion.question}`, { lipsyncLang: defaultAvatarConfig.lipsyncLang });
301
+ avatarRef.current.speakText(`Let's test your coding skills! Here's your first challenge: ${firstQuestion.question}`, { lipsyncLang: config.lipsyncLang });
266
302
  } else if (firstQuestion.type === 'multiple_choice') {
267
- avatarRef.current.speakText(`Now let me ask you some questions. Here's the first one: ${firstQuestion.question}`, { lipsyncLang: defaultAvatarConfig.lipsyncLang });
303
+ avatarRef.current.speakText(`Now let me ask you some questions. Here's the first one: ${firstQuestion.question}`, { lipsyncLang: config.lipsyncLang });
268
304
  } else if (firstQuestion.type === 'true_false') {
269
- avatarRef.current.speakText(`Let's start with some true or false questions. First question: ${firstQuestion.question}`, { lipsyncLang: defaultAvatarConfig.lipsyncLang });
270
- } else {
271
- avatarRef.current.speakText(`Now let me ask you some questions. Here's the first one: ${firstQuestion.question}`, { lipsyncLang: defaultAvatarConfig.lipsyncLang });
305
+ avatarRef.current.speakText(`Let's start with some true or false questions. First question: ${firstQuestion.question}`, { lipsyncLang: config.lipsyncLang });
306
+ } else {
307
+ avatarRef.current.speakText(`Now let me ask you some questions. Here's the first one: ${firstQuestion.question}`, { lipsyncLang: config.lipsyncLang });
272
308
  }
273
309
  } else if (avatarRef.current) {
274
- avatarRef.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: defaultAvatarConfig.lipsyncLang });
310
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
311
+ avatarRef.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: config.lipsyncLang });
275
312
  }
276
- }, [animations.questionStart, getCurrentLesson, getCurrentQuestion, defaultAvatarConfig]);
313
+ }, [animations.questionStart, getCurrentLesson, getCurrentQuestion]);
277
314
 
278
315
  // Move to next question
279
316
  const nextQuestion = useCallback(() => {
@@ -296,34 +333,36 @@ const CurriculumLearning = forwardRef(({
296
333
  }
297
334
 
298
335
  if (avatarRef.current && nextQuestionObj) {
299
- avatarRef.current.setMood("happy");
336
+ avatarRef.current.setMood("happy");
300
337
  avatarRef.current.setBodyMovement("idle");
301
338
 
302
339
  // Play custom animation if available
303
340
  if (animations.nextQuestion) {
304
- try {
341
+ try {
305
342
  avatarRef.current.playAnimation(animations.nextQuestion, true);
306
- } catch (error) {
343
+ } catch (error) {
307
344
  console.warn('Failed to play nextQuestion animation:', error);
308
345
  }
309
346
  }
310
347
 
348
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
349
+
311
350
  // Speak the question text with proper introduction
312
351
  if (nextQuestionObj.type === 'code_test') {
313
352
  avatarRef.current.speakText(`Great! Now let's move on to your next coding challenge: ${nextQuestionObj.question}`, {
314
- lipsyncLang: defaultAvatarConfig.lipsyncLang
353
+ lipsyncLang: config.lipsyncLang
315
354
  });
316
355
  } else if (nextQuestionObj.type === 'multiple_choice') {
317
356
  avatarRef.current.speakText(`Alright! Here's your next question: ${nextQuestionObj.question}`, {
318
- lipsyncLang: defaultAvatarConfig.lipsyncLang
357
+ lipsyncLang: config.lipsyncLang
319
358
  });
320
359
  } else if (nextQuestionObj.type === 'true_false') {
321
360
  avatarRef.current.speakText(`Now let's try this one: ${nextQuestionObj.question}`, {
322
- lipsyncLang: defaultAvatarConfig.lipsyncLang
361
+ lipsyncLang: config.lipsyncLang
323
362
  });
324
363
  } else {
325
364
  avatarRef.current.speakText(`Here's the next question: ${nextQuestionObj.question}`, {
326
- lipsyncLang: defaultAvatarConfig.lipsyncLang
365
+ lipsyncLang: config.lipsyncLang
327
366
  });
328
367
  }
329
368
  }
@@ -333,10 +372,11 @@ const CurriculumLearning = forwardRef(({
333
372
  completeLessonRef.current();
334
373
  }
335
374
  }
336
- }, [animations.nextQuestion, getCurrentLesson, getCurrentQuestion, defaultAvatarConfig]);
375
+ }, [animations.nextQuestion, getCurrentLesson, getCurrentQuestion]);
337
376
 
338
377
  // Move to next lesson
339
378
  const nextLesson = useCallback(() => {
379
+ const curriculum = curriculumRef.current || { modules: [] };
340
380
  const currentModule = curriculum.modules[stateRef.current.currentModuleIndex];
341
381
  if (stateRef.current.currentLessonIndex < (currentModule?.lessons?.length || 0) - 1) {
342
382
  stateRef.current.currentLessonIndex += 1;
@@ -355,7 +395,7 @@ const CurriculumLearning = forwardRef(({
355
395
  });
356
396
 
357
397
  if (avatarRef.current) {
358
- avatarRef.current.setMood("happy");
398
+ avatarRef.current.setMood("happy");
359
399
  avatarRef.current.setBodyMovement("idle");
360
400
 
361
401
  // Automatically start teaching the next lesson after a brief pause
@@ -370,7 +410,7 @@ const CurriculumLearning = forwardRef(({
370
410
  completeCurriculumRef.current();
371
411
  }
372
412
  }
373
- }, [curriculum]);
413
+ }, []);
374
414
 
375
415
  // Start teaching the lesson
376
416
  const startTeaching = useCallback(() => {
@@ -384,10 +424,10 @@ const CurriculumLearning = forwardRef(({
384
424
  // Play animation if available (can be overridden via custom action)
385
425
  let animationPlayed = false;
386
426
  if (animations.teaching) {
387
- try {
427
+ try {
388
428
  avatarRef.current.playAnimation(animations.teaching, true);
389
429
  animationPlayed = true;
390
- } catch (error) {
430
+ } catch (error) {
391
431
  console.warn('Failed to play teaching animation:', error);
392
432
  }
393
433
  }
@@ -396,7 +436,8 @@ const CurriculumLearning = forwardRef(({
396
436
  avatarRef.current.setBodyMovement("gesturing");
397
437
  }
398
438
 
399
- avatarRef.current.speakText(currentLesson.avatar_script, { lipsyncLang: defaultAvatarConfig.lipsyncLang });
439
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
440
+ avatarRef.current.speakText(currentLesson.avatar_script, { lipsyncLang: config.lipsyncLang });
400
441
 
401
442
  callbacksRef.current.onLessonStart({
402
443
  moduleIndex: stateRef.current.currentModuleIndex,
@@ -420,7 +461,7 @@ const CurriculumLearning = forwardRef(({
420
461
  if (startQuestionsRef.current) {
421
462
  startQuestionsRef.current();
422
463
  }
423
- } else {
464
+ } else {
424
465
  // No questions, complete the lesson using ref to avoid circular dependency
425
466
  if (completeLessonRef.current) {
426
467
  completeLessonRef.current();
@@ -428,7 +469,7 @@ const CurriculumLearning = forwardRef(({
428
469
  }
429
470
  }, 8000);
430
471
  }
431
- }, [animations.teaching, getCurrentLesson, defaultAvatarConfig]);
472
+ }, [animations.teaching, getCurrentLesson]);
432
473
 
433
474
  // Handle answer selection
434
475
  const handleAnswerSelect = useCallback((answer) => {
@@ -450,11 +491,11 @@ const CurriculumLearning = forwardRef(({
450
491
 
451
492
  if (avatarRef.current) {
452
493
  if (isCorrect) {
453
- avatarRef.current.setMood("happy");
494
+ avatarRef.current.setMood("happy");
454
495
  if (animations.correct) {
455
- try {
496
+ try {
456
497
  avatarRef.current.playReaction("happy");
457
- } catch (error) {
498
+ } catch (error) {
458
499
  avatarRef.current.setBodyMovement("happy");
459
500
  }
460
501
  }
@@ -463,9 +504,11 @@ const CurriculumLearning = forwardRef(({
463
504
  ? `Great job! Your code passed all the tests! ${currentQuestion.explanation || ''}`
464
505
  : `Excellent! That's correct! ${currentQuestion.explanation || ''}`;
465
506
 
507
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
508
+
466
509
  // Wait for speech to finish before moving to next question
467
510
  avatarRef.current.speakText(successMessage, {
468
- lipsyncLang: defaultAvatarConfig.lipsyncLang,
511
+ lipsyncLang: config.lipsyncLang,
469
512
  onSpeechEnd: () => {
470
513
  // Add a small delay after speech ends for natural flow
471
514
  setTimeout(() => {
@@ -475,12 +518,12 @@ const CurriculumLearning = forwardRef(({
475
518
  }, 500);
476
519
  }
477
520
  });
478
- } else {
521
+ } else {
479
522
  avatarRef.current.setMood("sad");
480
523
  if (animations.incorrect) {
481
524
  try {
482
525
  avatarRef.current.playAnimation(animations.incorrect, true);
483
- } catch (error) {
526
+ } catch (error) {
484
527
  avatarRef.current.setBodyMovement("idle");
485
528
  }
486
529
  }
@@ -489,9 +532,11 @@ const CurriculumLearning = forwardRef(({
489
532
  ? `Your code didn't pass all the tests. ${currentQuestion.explanation || 'Try again!'}`
490
533
  : `Not quite right, but don't worry! ${currentQuestion.explanation || ''} Let's move on to the next question.`;
491
534
 
535
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
536
+
492
537
  // Wait for speech to finish before moving to next question
493
538
  avatarRef.current.speakText(failureMessage, {
494
- lipsyncLang: defaultAvatarConfig.lipsyncLang,
539
+ lipsyncLang: config.lipsyncLang,
495
540
  onSpeechEnd: () => {
496
541
  // Add a small delay after speech ends for natural flow
497
542
  setTimeout(() => {
@@ -508,7 +553,7 @@ const CurriculumLearning = forwardRef(({
508
553
  nextQuestionRef.current();
509
554
  }
510
555
  }
511
- }, [animations.correct, animations.incorrect, getCurrentQuestion, checkAnswer, defaultAvatarConfig]);
556
+ }, [animations.correct, animations.incorrect, getCurrentQuestion, checkAnswer]);
512
557
 
513
558
  // Handle code test result submission
514
559
  const handleCodeTestResult = useCallback((testResult) => {
@@ -552,7 +597,7 @@ const CurriculumLearning = forwardRef(({
552
597
  if (handleAnswerSelectRef.current) {
553
598
  handleAnswerSelectRef.current(codeTestAnswer);
554
599
  }
555
- }, [getCurrentQuestion, checkAnswer, defaultAvatarConfig]);
600
+ }, [getCurrentQuestion, checkAnswer]);
556
601
 
557
602
  // Reset curriculum
558
603
  const resetCurriculum = useCallback(() => {
@@ -615,7 +660,8 @@ const CurriculumLearning = forwardRef(({
615
660
  speakText: async (text, options = {}) => {
616
661
  // Ensure audio context is resumed before speaking
617
662
  await avatarRef.current?.resumeAudioContext?.();
618
- avatarRef.current?.speakText(text, { ...options, lipsyncLang: options.lipsyncLang || defaultAvatarConfig.lipsyncLang });
663
+ const config = defaultAvatarConfigRef.current || { lipsyncLang: 'en' };
664
+ avatarRef.current?.speakText(text, { ...options, lipsyncLang: options.lipsyncLang || config.lipsyncLang });
619
665
  },
620
666
  resumeAudioContext: async () => {
621
667
  // Try to resume through avatar ref first
@@ -667,6 +713,22 @@ const CurriculumLearning = forwardRef(({
667
713
  isAvatarReady: () => avatarRef.current?.isReady || false
668
714
  }), [startTeaching, startQuestions, handleAnswerSelect, handleCodeTestResult, nextQuestion, nextLesson, completeLesson, completeCurriculum, resetCurriculum, getCurrentQuestion, getCurrentLesson]);
669
715
 
716
+ // Get current config for render
717
+ const defaultAvatarConfig = defaultAvatarConfigRef.current || {
718
+ avatarUrl: "/avatars/brunette.glb",
719
+ avatarBody: "F",
720
+ mood: "happy",
721
+ ttsLang: "en",
722
+ ttsService: null,
723
+ ttsVoice: null,
724
+ ttsApiKey: null,
725
+ bodyMovement: "gesturing",
726
+ movementIntensity: 0.7,
727
+ showFullAvatar: true,
728
+ animations: animations,
729
+ lipsyncLang: 'en'
730
+ };
731
+
670
732
  return (
671
733
  <div style={{ width: '100%', height: '100%' }}>
672
734
  <TalkingHeadAvatar
@@ -697,4 +759,4 @@ const CurriculumLearning = forwardRef(({
697
759
 
698
760
  CurriculumLearning.displayName = 'CurriculumLearning';
699
761
 
700
- export default CurriculumLearning;
762
+ export default CurriculumLearning;