atlury commited on
Commit
0f89d2c
·
verified ·
1 Parent(s): daf5836

Upload finalwork2.html

Browse files
Files changed (1) hide show
  1. finalwork2.html +945 -0
finalwork2.html ADDED
@@ -0,0 +1,945 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Aged Guru</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <!-- Google Fonts for better typography -->
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Roboto:wght@400;500&display=swap" rel="stylesheet">
9
+ <!-- Include necessary CSS styles -->
10
+ <style>
11
+ /* Reset and base styles */
12
+ * {
13
+ box-sizing: border-box;
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ body {
19
+ font-family: 'Inter', sans-serif;
20
+ background: linear-gradient(135deg, #f0f4f8, #d9e2ec);
21
+ display: flex;
22
+ min-height: 100vh;
23
+ color: #333;
24
+ overflow: hidden;
25
+ }
26
+
27
+ /* Sidebar styling */
28
+ .sidebar {
29
+ width: 260px;
30
+ background: linear-gradient(135deg, #ffffff, #e0f7fa);
31
+ box-shadow: 2px 0 10px rgba(0,0,0,0.1);
32
+ flex-shrink: 0;
33
+ display: flex;
34
+ flex-direction: column;
35
+ padding: 30px 20px;
36
+ position: fixed;
37
+ height: 100%;
38
+ overflow-y: auto;
39
+ transition: width 0.3s ease, background 0.3s ease;
40
+ }
41
+
42
+ .sidebar h2 {
43
+ text-align: center;
44
+ margin-bottom: 40px;
45
+ font-family: 'Roboto', sans-serif;
46
+ font-weight: 700;
47
+ font-size: 1.8em;
48
+ color: #00796B;
49
+ background: linear-gradient(90deg, #00796B, #004D40);
50
+ -webkit-background-clip: text;
51
+ -webkit-text-fill-color: transparent;
52
+ }
53
+
54
+ .sidebar a {
55
+ color: #555555;
56
+ padding: 12px 15px;
57
+ text-decoration: none;
58
+ font-size: 1em;
59
+ border-radius: 8px;
60
+ margin-bottom: 10px;
61
+ transition: background-color 0.3s, color 0.3s, transform 0.2s, box-shadow 0.3s;
62
+ display: flex;
63
+ align-items: center;
64
+ background: linear-gradient(135deg, #ffffff, #f9f9f9);
65
+ }
66
+
67
+ .sidebar a:hover {
68
+ background: linear-gradient(135deg, #e0f7fa, #ffffff);
69
+ color: #00796B;
70
+ transform: translateX(5px);
71
+ box-shadow: 0 4px 12px rgba(0,0,0,0.05);
72
+ }
73
+
74
+ .sidebar a.active {
75
+ background: linear-gradient(135deg, #80deea, #4dd0e1);
76
+ color: #004d40;
77
+ font-weight: 600;
78
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
79
+ }
80
+
81
+ .sidebar a::before {
82
+ content: '';
83
+ display: inline-block;
84
+ width: 8px;
85
+ height: 8px;
86
+ background-color: #004d40;
87
+ border-radius: 50%;
88
+ margin-right: 12px;
89
+ opacity: 0;
90
+ transition: opacity 0.3s;
91
+ }
92
+
93
+ .sidebar a.active::before {
94
+ opacity: 1;
95
+ }
96
+
97
+ /* Main content styling */
98
+ .main-content {
99
+ margin-left: 260px;
100
+ padding: 30px;
101
+ flex: 1;
102
+ background: linear-gradient(135deg, #f9f9f9, #e0f2f1);
103
+ overflow-y: auto;
104
+ height: 100vh;
105
+ transition: margin-left 0.3s ease, background 0.3s ease;
106
+ }
107
+
108
+ /* Header */
109
+ .header {
110
+ display: flex;
111
+ justify-content: space-between;
112
+ align-items: center;
113
+ margin-bottom: 25px;
114
+ background: linear-gradient(90deg, #80deea, #4dd0e1);
115
+ padding: 15px 20px;
116
+ border-radius: 12px;
117
+ box-shadow: 0 4px 10px rgba(0,0,0,0.05);
118
+ }
119
+
120
+ .header h1 {
121
+ font-family: 'Roboto', sans-serif;
122
+ font-size: 2em;
123
+ color: #ffffff;
124
+ background: linear-gradient(90deg, #ffffff, #e0f7fa);
125
+ -webkit-background-clip: text;
126
+ -webkit-text-fill-color: transparent;
127
+ }
128
+
129
+ /* Card Styling */
130
+ .card {
131
+ background: linear-gradient(135deg, #ffffff, #f1f8e9);
132
+ border-radius: 16px;
133
+ box-shadow: 0 4px 20px rgba(0,0,0,0.05);
134
+ padding: 25px;
135
+ margin-bottom: 25px;
136
+ transition: transform 0.3s, box-shadow 0.3s, background 0.3s;
137
+ }
138
+
139
+ .card:hover {
140
+ transform: translateY(-5px);
141
+ box-shadow: 0 6px 25px rgba(0,0,0,0.1);
142
+ background: linear-gradient(135deg, #e0f7fa, #ffffff);
143
+ }
144
+
145
+ /* Button Styling */
146
+ button {
147
+ background: linear-gradient(135deg, #00796B, #004D40);
148
+ border: none;
149
+ color: white;
150
+ padding: 12px 20px;
151
+ font-size: 1em;
152
+ border-radius: 8px;
153
+ cursor: pointer;
154
+ transition: background 0.3s, transform 0.2s, box-shadow 0.3s;
155
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
156
+ }
157
+
158
+ button:hover {
159
+ background: linear-gradient(135deg, #005D56, #00332E);
160
+ transform: translateY(-2px);
161
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
162
+ }
163
+
164
+ button:disabled {
165
+ background: linear-gradient(135deg, #A5D6A7, #81C784);
166
+ cursor: not-allowed;
167
+ box-shadow: none;
168
+ }
169
+
170
+ /* Select Dropdown Styling */
171
+ select {
172
+ width: 100%;
173
+ padding: 10px 15px;
174
+ border: 1px solid #cccccc;
175
+ border-radius: 8px;
176
+ font-size: 1em;
177
+ background-color: #ffffff;
178
+ transition: border-color 0.3s, box-shadow 0.3s;
179
+ margin-bottom: 15px;
180
+ }
181
+
182
+ select:focus {
183
+ border-color: #00796B;
184
+ box-shadow: 0 0 5px rgba(0, 121, 107, 0.5);
185
+ outline: none;
186
+ }
187
+
188
+ /* Chat Box Styling */
189
+ #chat-box {
190
+ height: 400px;
191
+ border: 1px solid #e0e0e0;
192
+ border-radius: 12px;
193
+ overflow-y: auto;
194
+ padding: 20px;
195
+ background-color: #ffffff;
196
+ margin-bottom: 20px;
197
+ position: relative;
198
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
199
+ }
200
+
201
+ .message-container {
202
+ margin-bottom: 20px;
203
+ display: flex;
204
+ }
205
+
206
+ .message {
207
+ padding: 12px 18px;
208
+ border-radius: 20px;
209
+ max-width: 75%;
210
+ position: relative;
211
+ word-wrap: break-word;
212
+ box-shadow: 0 2px 8px rgba(0,0,0,0.05);
213
+ font-size: 0.95em;
214
+ line-height: 1.4;
215
+ background-color: #f1f8e9;
216
+ transition: background-color 0.3s, box-shadow 0.3s;
217
+ }
218
+
219
+ .user .message {
220
+ background: #DCF8C6;
221
+ border-bottom-right-radius: 0;
222
+ }
223
+
224
+ .assistant .message {
225
+ background: #e3f2fd;
226
+ border-bottom-left-radius: 0;
227
+ }
228
+
229
+ /* Microphone Button Styling */
230
+ #mic-container {
231
+ text-align: center;
232
+ margin-bottom: 20px;
233
+ }
234
+
235
+ /* Updated Start Button */
236
+ #start_button {
237
+ background: linear-gradient(135deg, #00796B, #004D40);
238
+ border: none;
239
+ color: white;
240
+ padding: 15px;
241
+ border-radius: 50%;
242
+ cursor: pointer;
243
+ transition: background 0.3s, transform 0.2s, box-shadow 0.3s;
244
+ width: 60px;
245
+ height: 60px;
246
+ display: flex;
247
+ justify-content: center;
248
+ align-items: center;
249
+ position: relative;
250
+ overflow: hidden;
251
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
252
+ }
253
+
254
+ #start_button::before {
255
+ content: '';
256
+ position: absolute;
257
+ width: 200%;
258
+ height: 200%;
259
+ background: rgba(255, 255, 255, 0.3);
260
+ top: 50%;
261
+ left: 50%;
262
+ transform: translate(-50%, -50%) scale(0);
263
+ border-radius: 50%;
264
+ transition: transform 0.5s ease-out;
265
+ }
266
+
267
+ #start_button:active::before {
268
+ transform: translate(-50%, -50%) scale(1);
269
+ }
270
+
271
+ #start_button:disabled {
272
+ background: linear-gradient(135deg, #A5D6A7, #81C784);
273
+ cursor: not-allowed;
274
+ box-shadow: none;
275
+ }
276
+
277
+ #start_button:hover:not(:disabled) {
278
+ background: linear-gradient(135deg, #005D56, #00332E);
279
+ transform: scale(1.05);
280
+ box-shadow: 0 6px 15px rgba(0,0,0,0.15);
281
+ }
282
+
283
+ /* Icon Styling */
284
+ .mic-icon {
285
+ width: 30px;
286
+ height: 30px;
287
+ transition: transform 0.3s;
288
+ fill: #ffffff;
289
+ }
290
+
291
+ /* Animation for Mic Icon */
292
+ .mic-animate {
293
+ animation: pulse 2s infinite;
294
+ }
295
+
296
+ @keyframes pulse {
297
+ 0% {
298
+ transform: scale(1);
299
+ }
300
+ 50% {
301
+ transform: scale(1.2);
302
+ }
303
+ 100% {
304
+ transform: scale(1);
305
+ }
306
+ }
307
+
308
+ /* Logs Styling */
309
+ #logs {
310
+ height: 120px;
311
+ border: 1px solid #e0e0e0;
312
+ border-radius: 12px;
313
+ overflow-y: auto;
314
+ padding: 15px;
315
+ background-color: #f1f1f1;
316
+ font-size: 0.85em;
317
+ margin-bottom: 10px;
318
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
319
+ }
320
+
321
+ #clear-logs {
322
+ background: linear-gradient(135deg, #FF5252, #E53935);
323
+ border: none;
324
+ color: white;
325
+ padding: 10px 18px;
326
+ font-size: 0.9em;
327
+ cursor: pointer;
328
+ border-radius: 8px;
329
+ transition: background 0.3s, transform 0.2s, box-shadow 0.3s;
330
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
331
+ }
332
+
333
+ #clear-logs:hover {
334
+ background: linear-gradient(135deg, #E53935, #D32F2F);
335
+ transform: scale(1.02);
336
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
337
+ }
338
+
339
+ /* Chat Stats */
340
+ #chat-stats {
341
+ font-size: 0.85em;
342
+ color: #555555;
343
+ text-align: center;
344
+ margin-top: 10px;
345
+ }
346
+
347
+ /* Voice Selection Container */
348
+ #tts-voice-container label {
349
+ display: block;
350
+ margin-bottom: 8px;
351
+ color: #555555;
352
+ font-weight: 500;
353
+ }
354
+
355
+ /* Hidden Class */
356
+ .hidden {
357
+ display: none;
358
+ }
359
+
360
+ /* Scrollbar Styling */
361
+ #chat-box::-webkit-scrollbar,
362
+ #logs::-webkit-scrollbar {
363
+ width: 8px;
364
+ }
365
+
366
+ #chat-box::-webkit-scrollbar-track,
367
+ #logs::-webkit-scrollbar-track {
368
+ background: #f1f1f1;
369
+ border-radius: 4px;
370
+ }
371
+
372
+ #chat-box::-webkit-scrollbar-thumb,
373
+ #logs::-webkit-scrollbar-thumb {
374
+ background: #cccccc;
375
+ border-radius: 4px;
376
+ }
377
+
378
+ #chat-box::-webkit-scrollbar-thumb:hover,
379
+ #logs::-webkit-scrollbar-thumb:hover {
380
+ background: #a8a8a8;
381
+ }
382
+
383
+ /* Responsive Adjustments */
384
+ @media (max-width: 768px) {
385
+ .sidebar {
386
+ width: 220px;
387
+ }
388
+
389
+ .main-content {
390
+ margin-left: 220px;
391
+ }
392
+ }
393
+
394
+ @media (max-width: 600px) {
395
+ .sidebar {
396
+ position: relative;
397
+ width: 100%;
398
+ height: auto;
399
+ flex-direction: row;
400
+ overflow-x: auto;
401
+ padding: 15px 10px;
402
+ }
403
+
404
+ .sidebar h2 {
405
+ display: none;
406
+ }
407
+
408
+ .sidebar a {
409
+ margin-right: 10px;
410
+ margin-bottom: 0;
411
+ padding: 10px 12px;
412
+ font-size: 0.9em;
413
+ }
414
+
415
+ .main-content {
416
+ margin-left: 0;
417
+ padding: 20px 15px;
418
+ }
419
+
420
+ .header {
421
+ flex-direction: column;
422
+ align-items: flex-start;
423
+ }
424
+
425
+ .header h1 {
426
+ margin-bottom: 10px;
427
+ font-size: 1.5em;
428
+ }
429
+ }
430
+
431
+ /* Controls Container Styling */
432
+ #controls {
433
+ display: flex;
434
+ gap: 10px;
435
+ margin-bottom: 15px;
436
+ flex-wrap: wrap;
437
+ }
438
+
439
+ /* Initialize Button Styling */
440
+ #download {
441
+ flex: 0 0 auto;
442
+ background: linear-gradient(135deg, #00796B, #004D40);
443
+ border: none;
444
+ color: white;
445
+ padding: 10px 20px;
446
+ font-size: 1em;
447
+ border-radius: 8px;
448
+ cursor: pointer;
449
+ transition: background 0.3s, transform 0.2s, box-shadow 0.3s;
450
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
451
+ }
452
+
453
+ #download:hover {
454
+ background: linear-gradient(135deg, #005D56, #00332E);
455
+ transform: translateY(-2px);
456
+ box-shadow: 0 4px 12px rgba(0,0,0,0.2);
457
+ }
458
+
459
+ #download:disabled {
460
+ background: linear-gradient(135deg, #A5D6A7, #81C784);
461
+ cursor: not-allowed;
462
+ box-shadow: none;
463
+ }
464
+
465
+ /* Enhanced Layout for Digital Human Mentor Voice Section */
466
+ #voice .card {
467
+ display: grid;
468
+ grid-template-columns: 1fr 1fr;
469
+ grid-gap: 20px;
470
+ }
471
+
472
+ /* Adjust controls and voice selection */
473
+ #model-selection-container,
474
+ #tts-voice-container {
475
+ display: flex;
476
+ flex-direction: column;
477
+ }
478
+
479
+ #model-selection-container label,
480
+ #tts-voice-container label {
481
+ margin-bottom: 5px;
482
+ font-weight: 500;
483
+ color: #555555;
484
+ }
485
+
486
+ /* Chat and Controls Layout */
487
+ #chat-container {
488
+ display: flex;
489
+ flex-direction: column;
490
+ }
491
+
492
+ /* Ensure chat-box takes full width */
493
+ #chat-box {
494
+ width: 100%;
495
+ }
496
+
497
+ /* Adjust microphone container */
498
+ #mic-container {
499
+ display: flex;
500
+ justify-content: center;
501
+ margin-bottom: 20px;
502
+ }
503
+
504
+ /* Configuration Info */
505
+ #configuration {
506
+ margin-top: 15px;
507
+ font-size: 0.9em;
508
+ color: #555555;
509
+ }
510
+
511
+ /* Responsive Grid Adjustments */
512
+ @media (max-width: 800px) {
513
+ #voice .card {
514
+ grid-template-columns: 1fr;
515
+ }
516
+ }
517
+ </style>
518
+ </head>
519
+ <body>
520
+
521
+ <!-- Sidebar -->
522
+ <div class="sidebar">
523
+ <h2>AGED GURU</h2>
524
+ <a href="#" class="active" data-content="voice">Digital Human Voice</a>
525
+ <a href="#" data-content="video">Digital Human Video</a>
526
+ <a href="#" data-content="coder">Young Coder</a>
527
+ <a href="#" data-content="advanced-math">Advanced Mathematics & Problem Solving</a>
528
+ <a href="#" data-content="interdisciplinary">Interdisciplinary Studies Assistant</a>
529
+ <a href="#" data-content="insights">Insights</a>
530
+ <a href="#" data-content="3d-explorer">3D Explorer</a>
531
+ <a href="#" data-content="knowledge-base">Knowledge Base</a>
532
+ <a href="#" data-content="digital-twin">Digital Twin</a>
533
+ </div>
534
+
535
+ <!-- Main Content -->
536
+ <div class="main-content" id="main-content">
537
+ <div class="header">
538
+ <h1>5-MIN SCIENTIST PORTAL</h1>
539
+ <!-- You can add user profile or settings here -->
540
+ </div>
541
+ <!-- Content will be loaded here -->
542
+ <div id="content-area">
543
+ <!-- Digital Human Mentor Voice Content Starts -->
544
+ <div id="voice" class="content-section">
545
+ <div class="card">
546
+ <!-- Model Selection Section -->
547
+ <div id="model-selection-container">
548
+ <label for="model-selection">Select Language Model:</label>
549
+ <select id="model-selection"></select>
550
+ <button id="download">Initialize</button>
551
+ </div>
552
+
553
+ <!-- Voice Selection Section -->
554
+ <div id="tts-voice-container">
555
+ <label for="voices">Select Voice:</label>
556
+ <select id="voices"></select>
557
+ </div>
558
+ </div>
559
+
560
+ <div id="chat-container">
561
+ <div id="configuration" class="hidden">
562
+ <div id="model-info">
563
+ <strong>LLM:</strong> <span id="selected-model">Not Initialized</span>
564
+ </div>
565
+ </div>
566
+ <div id="chat-box"></div>
567
+
568
+ <!-- Microphone button -->
569
+ <div id="mic-container">
570
+ <button id="start_button" disabled>
571
+ <svg class="mic-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
572
+ <path d="M12 14a3 3 0 003-3V5a3 3 0 00-6 0v6a3 3 0 003 3zm5-3a5 5 0 01-10 0H5a7 7 0 0014 0h-2z"/>
573
+ </svg>
574
+ </button>
575
+ </div>
576
+
577
+ <div id="chat-stats" class="hidden"></div>
578
+ </div>
579
+
580
+ <h3>Logs</h3>
581
+ <div id="logs">
582
+ <div id="download-status" class="hidden"></div>
583
+ </div>
584
+ <button id="clear-logs">Clear Logs</button>
585
+ </div>
586
+ <!-- Digital Human Mentor Voice Content Ends -->
587
+
588
+ <!-- Placeholder for other sections -->
589
+ <div id="video" class="content-section hidden">
590
+ <div class="card">
591
+ <h2>Interactive Digital Human Mentor Video</h2>
592
+ <p>Content for Video Mentor will go here.</p>
593
+ </div>
594
+ </div>
595
+
596
+ <div id="coder" class="content-section hidden">
597
+ <div class="card">
598
+ <h2>Young coder</h2>
599
+ <p>Young coder with python, javascript and language of choice interpreter.</p>
600
+ </div>
601
+ </div>
602
+
603
+ <div id="advanced-math" class="content-section hidden">
604
+ <div class="card">
605
+ <h2>Advanced Mathematics & Problem Solving</h2>
606
+ <p>Content for Advanced Mathematics & Problem Solving will go here.</p>
607
+ </div>
608
+ </div>
609
+
610
+ <div id="interdisciplinary" class="content-section hidden">
611
+ <div class="card">
612
+ <h2>Interdisciplinary Studies Assistant</h2>
613
+ <p>Content for Interdisciplinary Studies Assistant will go here.</p>
614
+ </div>
615
+ </div>
616
+
617
+ <div id="insights" class="content-section hidden">
618
+ <div class="card">
619
+ <h2>Insights</h2>
620
+ <p>Content for Document Insights will go here. Document Insights (PDF, Image), Translator, Youtube Summarizer, </p>
621
+ </div>
622
+ </div>
623
+
624
+ <div id="3d-explorer" class="content-section hidden">
625
+ <div class="card">
626
+ <h2>3D Explorer</h2>
627
+ <p>Content for 3D Explorer will go here.</p>
628
+ </div>
629
+ </div>
630
+
631
+ <div id="knowledge-base" class="content-section hidden">
632
+ <div class="card">
633
+ <h2>Knowledge Base</h2>
634
+ <p>Content for Knowledge Base will go here, Treasured Teachings, Vintage Papers, Digital Dustbin.</p>
635
+ </div>
636
+ </div>
637
+
638
+ <div id="digital-twin" class="content-section hidden">
639
+ <div class="card">
640
+ <h2>Digital Twin</h2>
641
+ <p>Persona, Memory, Social Graph, Class Notes, Homework, Tracker.</p>
642
+ </div>
643
+ </div>
644
+
645
+
646
+
647
+ </div>
648
+ </div>
649
+
650
+ <!-- Include the necessary scripts -->
651
+ <script type="module">
652
+ import * as webllm from "https://esm.run/@mlc-ai/web-llm";
653
+
654
+ // Sidebar navigation
655
+ const sidebarLinks = document.querySelectorAll('.sidebar a');
656
+ const contentSections = document.querySelectorAll('.content-section');
657
+
658
+ sidebarLinks.forEach(link => {
659
+ link.addEventListener('click', (e) => {
660
+ e.preventDefault();
661
+ // Remove active class from all links
662
+ sidebarLinks.forEach(l => l.classList.remove('active'));
663
+ // Add active class to the clicked link
664
+ link.classList.add('active');
665
+
666
+ // Hide all content sections
667
+ contentSections.forEach(section => section.classList.add('hidden'));
668
+
669
+ // Show the selected content section
670
+ const target = link.getAttribute('data-content');
671
+ document.getElementById(target).classList.remove('hidden');
672
+ });
673
+ });
674
+
675
+ // Initialize the Digital Human Mentor Voice section
676
+ const messages = [
677
+ {
678
+ content: "You are Chatbot, a friendly, helpful robot called Aged Guru. Respond to what the user said in a creative and helpful way, but keep your responses brief.\n" +
679
+ "Keep responses brief and legible. Your output will be converted to audio.\n" +
680
+ "Your responses will converted to audio. Please do not include any special characters in your response other than '!' or '?'.",
681
+ role: "system"
682
+ }
683
+ ];
684
+
685
+ const availableModels = webllm.prebuiltAppConfig.model_list.map(
686
+ (m) => m.model_id
687
+ );
688
+ let selectedModel = "TinyLlama-1.1B-Chat-v0.4-q4f32_1-MLC-1k";
689
+
690
+ function updateEngineInitProgressCallback(report) {
691
+ console.log("initialize", report.progress);
692
+ document.getElementById("download-status").textContent = report.text;
693
+ }
694
+
695
+ const engine = new webllm.MLCEngine();
696
+ engine.setInitProgressCallback(updateEngineInitProgressCallback);
697
+
698
+ async function initializeWebLLMEngine() {
699
+ document.getElementById("download-status").classList.remove("hidden");
700
+ selectedModel = document.getElementById("model-selection").value;
701
+ const config = {
702
+ temperature: 1.0,
703
+ top_p: 1
704
+ };
705
+ await engine.reload(selectedModel, config);
706
+ document.getElementById("selected-model").textContent = selectedModel;
707
+ document.getElementById("start_button").disabled = false;
708
+ document.getElementById("configuration").classList.remove("hidden");
709
+ }
710
+
711
+ async function streamingGenerating(messages, onUpdate, onFinish, onError) {
712
+ try {
713
+ let curMessage = "";
714
+ const completion = await engine.chat.completions.create({
715
+ stream: true,
716
+ messages
717
+ });
718
+ for await (const chunk of completion) {
719
+ const curDelta = chunk.choices[0].delta.content;
720
+ if (curDelta) {
721
+ curMessage += curDelta;
722
+ }
723
+ onUpdate(curMessage);
724
+ }
725
+ const finalMessage = await engine.getMessage();
726
+ onFinish(finalMessage);
727
+ } catch (err) {
728
+ onError(err);
729
+ }
730
+ }
731
+
732
+ function appendMessage(message) {
733
+ const chatBox = document.getElementById("chat-box");
734
+ const container = document.createElement("div");
735
+ container.classList.add("message-container");
736
+ const newMessage = document.createElement("div");
737
+ newMessage.classList.add("message");
738
+ newMessage.textContent = message.content;
739
+
740
+ if (message.role === "user") {
741
+ container.classList.add("user");
742
+ } else {
743
+ container.classList.add("assistant");
744
+ }
745
+
746
+ container.appendChild(newMessage);
747
+ chatBox.appendChild(container);
748
+ chatBox.scrollTop = chatBox.scrollHeight;
749
+
750
+ // If the message is from the assistant and not a placeholder, trigger TTS
751
+ if (message.role === "assistant" && message.content !== "typing...") {
752
+ speak(message.content);
753
+ }
754
+ }
755
+
756
+ function updateLastMessage(content) {
757
+ const messageDoms = document.getElementById("chat-box").querySelectorAll(".message");
758
+ const lastMessageDom = messageDoms[messageDoms.length - 1];
759
+ lastMessageDom.textContent = content;
760
+ }
761
+
762
+ function onSpeechRecognized(transcript) {
763
+ const input = transcript.trim();
764
+ const message = {
765
+ content: input,
766
+ role: "user"
767
+ };
768
+ if (input.length === 0) {
769
+ return;
770
+ }
771
+ document.getElementById("start_button").disabled = true;
772
+
773
+ messages.push(message);
774
+ appendMessage(message);
775
+
776
+ // Append "typing..." placeholder
777
+ const aiPlaceholder = {
778
+ content: "typing...",
779
+ role: "assistant"
780
+ };
781
+ appendMessage(aiPlaceholder);
782
+
783
+ const onFinishGenerating = (finalMessage) => {
784
+ // Remove the "typing..." placeholder
785
+ const chatBox = document.getElementById("chat-box");
786
+ const lastMessageContainer = chatBox.lastElementChild;
787
+ if (lastMessageContainer && lastMessageContainer.querySelector(".message").textContent === "typing...") {
788
+ chatBox.removeChild(lastMessageContainer);
789
+ }
790
+
791
+ // Append the final message
792
+ const aiMessage = {
793
+ content: finalMessage,
794
+ role: "assistant"
795
+ };
796
+ appendMessage(aiMessage);
797
+
798
+ document.getElementById("start_button").disabled = false;
799
+ engine.runtimeStatsText().then((statsText) => {
800
+ document.getElementById("chat-stats").classList.remove("hidden");
801
+ document.getElementById("chat-stats").textContent = statsText;
802
+ });
803
+ };
804
+
805
+ streamingGenerating(
806
+ messages,
807
+ updateLastMessage,
808
+ onFinishGenerating,
809
+ console.error
810
+ );
811
+ }
812
+
813
+ // Speech recognition code
814
+ var recognizing = false;
815
+ var ignore_onend;
816
+ var final_transcript = '';
817
+ var recognition;
818
+
819
+ function startButton(event) {
820
+ if (recognizing) {
821
+ recognition.stop();
822
+ return;
823
+ }
824
+ final_transcript = '';
825
+ recognition.lang = 'en-US';
826
+ recognition.start();
827
+ ignore_onend = false;
828
+ document.getElementById("start_button").classList.add("mic-animate");
829
+ }
830
+
831
+ if (!('webkitSpeechRecognition' in window)) {
832
+ alert("Web Speech API is not supported by this browser.");
833
+ } else {
834
+ recognition = new webkitSpeechRecognition();
835
+ recognition.continuous = false; // Non-continuous recognition
836
+ recognition.interimResults = false; // Get only final results
837
+
838
+ recognition.onstart = function() {
839
+ recognizing = true;
840
+ };
841
+
842
+ recognition.onerror = function(event) {
843
+ if (event.error == 'no-speech') {
844
+ document.getElementById("start_button").classList.remove("mic-animate");
845
+ alert('No speech was detected.');
846
+ ignore_onend = true;
847
+ }
848
+ if (event.error == 'audio-capture') {
849
+ document.getElementById("start_button").classList.remove("mic-animate");
850
+ alert('No microphone was found.');
851
+ ignore_onend = true;
852
+ }
853
+ if (event.error == 'not-allowed') {
854
+ alert('Permission to use microphone was denied.');
855
+ ignore_onend = true;
856
+ }
857
+ };
858
+
859
+ recognition.onend = function() {
860
+ recognizing = false;
861
+ document.getElementById("start_button").classList.remove("mic-animate");
862
+ if (ignore_onend) {
863
+ return;
864
+ }
865
+ if (!final_transcript) {
866
+ return;
867
+ }
868
+ // Process the final transcript
869
+ onSpeechRecognized(final_transcript);
870
+ };
871
+
872
+ recognition.onresult = function(event) {
873
+ for (var i = event.resultIndex; i < event.results.length; ++i) {
874
+ if (event.results[i].isFinal) {
875
+ final_transcript += event.results[i][0].transcript;
876
+ }
877
+ }
878
+ final_transcript = final_transcript.trim();
879
+ };
880
+ }
881
+
882
+ document.getElementById("start_button").addEventListener("click", function(event) {
883
+ startButton(event);
884
+ });
885
+
886
+ // Initialize model selection
887
+ availableModels.forEach((modelId) => {
888
+ const option = document.createElement("option");
889
+ option.value = modelId;
890
+ option.textContent = modelId;
891
+ document.getElementById("model-selection").appendChild(option);
892
+ });
893
+ document.getElementById("model-selection").value = selectedModel;
894
+ document.getElementById("download").addEventListener("click", function () {
895
+ initializeWebLLMEngine().then(() => {
896
+ document.getElementById("start_button").disabled = false;
897
+ });
898
+ });
899
+
900
+ document.getElementById("clear-logs").addEventListener("click", function () {
901
+ document.getElementById("logs").innerHTML = '';
902
+ });
903
+
904
+ // ===== TTS Integration =====
905
+
906
+ // Initialize Speech Synthesis
907
+ let speech = new SpeechSynthesisUtterance();
908
+ speech.lang = "en";
909
+
910
+ let voices = [];
911
+ window.speechSynthesis.onvoiceschanged = () => {
912
+ voices = window.speechSynthesis.getVoices();
913
+ populateVoices();
914
+ };
915
+
916
+ function populateVoices() {
917
+ const voiceSelect = document.getElementById("voices");
918
+ voiceSelect.innerHTML = ''; // Clear existing options
919
+ voices.forEach((voice, i) => {
920
+ const option = new Option(voice.name, i);
921
+ voiceSelect.appendChild(option);
922
+ });
923
+ if (voices.length > 0) {
924
+ speech.voice = voices[0];
925
+ }
926
+ }
927
+
928
+ // Voice Selection Event Listener
929
+ document.getElementById("voices").addEventListener("change", () => {
930
+ const selectedVoiceIndex = document.getElementById("voices").value;
931
+ speech.voice = voices[selectedVoiceIndex];
932
+ });
933
+
934
+ // Function to speak text
935
+ function speak(text) {
936
+ if (window.speechSynthesis.speaking) {
937
+ window.speechSynthesis.cancel(); // Cancel previous speech
938
+ }
939
+ speech.text = text;
940
+ window.speechSynthesis.speak(speech);
941
+ }
942
+ </script>
943
+
944
+ </body>
945
+ </html>