yakmesh 2.8.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/CHANGELOG.md +637 -0
  2. package/CONTRIBUTING.md +42 -0
  3. package/Caddyfile +77 -0
  4. package/README.md +119 -29
  5. package/adapters/adapter-mlv-bible/README.md +124 -0
  6. package/adapters/adapter-mlv-bible/index.js +400 -0
  7. package/adapters/chat-mod-adapter.js +532 -0
  8. package/adapters/content-adapter.js +273 -0
  9. package/content/api.js +50 -41
  10. package/content/index.js +2 -2
  11. package/content/store.js +355 -173
  12. package/dashboard/index.html +19 -3
  13. package/database/replication.js +117 -37
  14. package/docs/CRYPTO-AGILITY.md +204 -0
  15. package/docs/MTLS-RESEARCH.md +367 -0
  16. package/docs/NAMCHE-SPEC.md +681 -0
  17. package/docs/PEERQUANTA-YAKMESH-INTEGRATION.md +407 -0
  18. package/docs/PRECISION-DISCLOSURE.md +96 -0
  19. package/docs/README.md +76 -0
  20. package/docs/ROADMAP-2.4.0.md +447 -0
  21. package/docs/ROADMAP-2.5.0.md +244 -0
  22. package/docs/SECURITY-AUDIT-REPORT.md +306 -0
  23. package/docs/SST-INTEGRATION.md +712 -0
  24. package/docs/STEADYWATCH-IMPLEMENTATION.md +303 -0
  25. package/docs/TERNARY-AUDIT-REPORT.md +247 -0
  26. package/docs/TME-FAQ.md +221 -0
  27. package/docs/WHITEPAPER.md +623 -0
  28. package/docs/adapters.html +1001 -0
  29. package/docs/advanced-systems.html +1045 -0
  30. package/docs/annex.html +1046 -0
  31. package/docs/api.html +970 -0
  32. package/docs/business/response-templates.md +160 -0
  33. package/docs/c2c.html +1225 -0
  34. package/docs/cli.html +1332 -0
  35. package/docs/configuration.html +1248 -0
  36. package/docs/darshan.html +1085 -0
  37. package/docs/dharma.html +966 -0
  38. package/docs/docs-bundle.html +1075 -0
  39. package/docs/docs.css +3120 -0
  40. package/docs/docs.js +556 -0
  41. package/docs/doko.html +969 -0
  42. package/docs/geo-proof.html +858 -0
  43. package/docs/getting-started.html +840 -0
  44. package/docs/gumba-tutorial.html +1144 -0
  45. package/docs/gumba.html +1098 -0
  46. package/docs/index.html +914 -0
  47. package/docs/jhilke.html +1312 -0
  48. package/docs/karma.html +1100 -0
  49. package/docs/katha.html +1037 -0
  50. package/docs/lama.html +978 -0
  51. package/docs/mandala.html +1067 -0
  52. package/docs/mani.html +964 -0
  53. package/docs/mantra.html +967 -0
  54. package/docs/mesh.html +1409 -0
  55. package/docs/nakpak.html +869 -0
  56. package/docs/namche.html +928 -0
  57. package/docs/nav-order.json +53 -0
  58. package/docs/prahari.html +1043 -0
  59. package/docs/prism-bash.min.js +1 -0
  60. package/docs/prism-javascript.min.js +1 -0
  61. package/docs/prism-json.min.js +1 -0
  62. package/docs/prism-tomorrow.min.css +1 -0
  63. package/docs/prism.min.js +1 -0
  64. package/docs/privacy.html +699 -0
  65. package/docs/quick-reference.html +1181 -0
  66. package/docs/sakshi.html +1402 -0
  67. package/docs/sandboxing.md +386 -0
  68. package/docs/seva.html +911 -0
  69. package/docs/sherpa.html +871 -0
  70. package/docs/studio.html +860 -0
  71. package/docs/stupa.html +995 -0
  72. package/docs/tailwind.min.css +2 -0
  73. package/docs/tattva.html +1332 -0
  74. package/docs/terms.html +686 -0
  75. package/docs/time-server-deployment.md +166 -0
  76. package/docs/time-sources.html +1392 -0
  77. package/docs/tivra.html +1127 -0
  78. package/docs/trademark-policy.html +686 -0
  79. package/docs/tribhuj.html +1183 -0
  80. package/docs/trust-security.html +1029 -0
  81. package/docs/tutorials/backup-recovery.html +654 -0
  82. package/docs/tutorials/dashboard.html +604 -0
  83. package/docs/tutorials/domain-setup.html +605 -0
  84. package/docs/tutorials/host-website.html +456 -0
  85. package/docs/tutorials/mesh-network.html +505 -0
  86. package/docs/tutorials/mobile-access.html +445 -0
  87. package/docs/tutorials/privacy.html +467 -0
  88. package/docs/tutorials/raspberry-pi.html +600 -0
  89. package/docs/tutorials/security-basics.html +539 -0
  90. package/docs/tutorials/share-files.html +431 -0
  91. package/docs/tutorials/troubleshooting.html +637 -0
  92. package/docs/tutorials/trust-karma.html +419 -0
  93. package/docs/tutorials/yak-protocol.html +456 -0
  94. package/docs/tutorials.html +1034 -0
  95. package/docs/vani.html +1270 -0
  96. package/docs/webserver.html +809 -0
  97. package/docs/yak-protocol.html +940 -0
  98. package/docs/yak-timeserver-design.md +475 -0
  99. package/docs/yakapp.html +1015 -0
  100. package/docs/ypc27.html +1069 -0
  101. package/docs/yurt.html +1344 -0
  102. package/embedded-docs/bundle.js +334 -74
  103. package/gossip/protocol.js +247 -27
  104. package/identity/key-resolver.js +262 -0
  105. package/identity/machine-seed.js +632 -0
  106. package/identity/node-key.js +669 -368
  107. package/identity/tribhuj-ratchet.js +506 -0
  108. package/knowledge-base.js +37 -8
  109. package/launcher/yakmesh.bat +62 -0
  110. package/launcher/yakmesh.sh +70 -0
  111. package/mesh/annex.js +462 -108
  112. package/mesh/beacon-broadcast.js +113 -1
  113. package/mesh/darshan.js +1718 -0
  114. package/mesh/gumba.js +1567 -0
  115. package/mesh/jhilke.js +651 -0
  116. package/mesh/katha.js +1012 -0
  117. package/mesh/nakpak-routing.js +8 -5
  118. package/mesh/network.js +724 -34
  119. package/mesh/pulse-sync.js +4 -1
  120. package/mesh/rate-limiter.js +127 -15
  121. package/mesh/seva.js +526 -0
  122. package/mesh/sherpa-discovery.js +89 -8
  123. package/mesh/sybil-defense.js +19 -5
  124. package/mesh/temporal-encoder.js +4 -3
  125. package/mesh/vani.js +1364 -0
  126. package/mesh/yurt.js +1340 -0
  127. package/models/entropy-sentinel.onnx +0 -0
  128. package/models/karma-trust.onnx +0 -0
  129. package/models/manifest.json +43 -0
  130. package/models/sakshi-anomaly.onnx +0 -0
  131. package/oracle/code-proof-protocol.js +7 -6
  132. package/oracle/codebase-lock.js +257 -28
  133. package/oracle/index.js +74 -15
  134. package/oracle/ma902-snmp.js +678 -0
  135. package/oracle/module-sealer.js +5 -3
  136. package/oracle/network-identity.js +16 -0
  137. package/oracle/packet-checksum.js +201 -0
  138. package/oracle/sst.js +579 -0
  139. package/oracle/ternary-144t.js +714 -0
  140. package/oracle/ternary-ml.js +481 -0
  141. package/oracle/time-api.js +239 -0
  142. package/oracle/time-source.js +137 -47
  143. package/oracle/validation-oracle-hardened.js +1111 -1071
  144. package/oracle/validation-oracle.js +4 -2
  145. package/oracle/ypc27.js +211 -0
  146. package/package.json +20 -3
  147. package/protocol/yak-handler.js +35 -9
  148. package/protocol/yak-protocol.js +28 -13
  149. package/reference/cpp/yakmesh_mceliece_shard.cpp +168 -0
  150. package/reference/cpp/yakmesh_ypc27.cpp +179 -0
  151. package/sbom.json +87 -0
  152. package/scripts/security-audit.mjs +264 -0
  153. package/scripts/update-docs-nav.js +194 -0
  154. package/scripts/update-docs-sidebar.cjs +164 -0
  155. package/security/crypto-config.js +4 -3
  156. package/security/dharma-moderation.js +517 -0
  157. package/security/doko-identity.js +193 -143
  158. package/security/domain-consensus.js +86 -85
  159. package/security/fs-hardening.js +620 -0
  160. package/security/hardware-attestation.js +5 -3
  161. package/security/hybrid-trust.js +227 -87
  162. package/security/karma-rate-limiter.js +692 -0
  163. package/security/khata-protocol.js +22 -21
  164. package/security/khata-trust-integration.js +277 -150
  165. package/security/memory-safety.js +635 -0
  166. package/security/mesh-auth.js +11 -10
  167. package/security/mesh-revocation.js +373 -5
  168. package/security/namche-gateway.js +298 -69
  169. package/security/sakshi.js +460 -3
  170. package/security/sangha.js +770 -0
  171. package/security/secure-config.js +473 -0
  172. package/security/silicon-parity.js +13 -10
  173. package/security/steadywatch.js +1142 -0
  174. package/security/strike-system.js +32 -3
  175. package/security/temporal-signing.js +488 -0
  176. package/security/trit-commitment.js +464 -0
  177. package/server/crypto/annex.js +247 -0
  178. package/server/darshan-api.js +343 -0
  179. package/server/index.js +3259 -362
  180. package/server/komm-api.js +668 -0
  181. package/utils/accel.js +2273 -0
  182. package/utils/ternary-id.js +79 -0
  183. package/utils/verify-worker.js +57 -0
  184. package/webserver/index.js +95 -5
  185. package/assets/yakmesh-logo.png +0 -0
  186. package/assets/yakmesh-logo.svg +0 -80
  187. package/assets/yakmesh-logo2.png +0 -0
  188. package/assets/yakmesh-logo2sm.png +0 -0
  189. package/assets/ymsm.png +0 -0
  190. package/website/assets/silhouettes/adapters.svg +0 -107
  191. package/website/assets/silhouettes/api-endpoints.svg +0 -115
  192. package/website/assets/silhouettes/atomic-clock.svg +0 -83
  193. package/website/assets/silhouettes/base-camp.svg +0 -81
  194. package/website/assets/silhouettes/bridge.svg +0 -69
  195. package/website/assets/silhouettes/docs-bundle.svg +0 -113
  196. package/website/assets/silhouettes/doko-basket.svg +0 -70
  197. package/website/assets/silhouettes/fortress.svg +0 -93
  198. package/website/assets/silhouettes/gateway.svg +0 -54
  199. package/website/assets/silhouettes/gears.svg +0 -93
  200. package/website/assets/silhouettes/globe-satellite.svg +0 -67
  201. package/website/assets/silhouettes/karma-wheel.svg +0 -137
  202. package/website/assets/silhouettes/lama-council.svg +0 -141
  203. package/website/assets/silhouettes/mandala-network.svg +0 -169
  204. package/website/assets/silhouettes/mani-stones.svg +0 -149
  205. package/website/assets/silhouettes/mantra-wheel.svg +0 -116
  206. package/website/assets/silhouettes/mesh-nodes.svg +0 -113
  207. package/website/assets/silhouettes/nakpak.svg +0 -56
  208. package/website/assets/silhouettes/peak-lightning.svg +0 -73
  209. package/website/assets/silhouettes/sherpa.svg +0 -69
  210. package/website/assets/silhouettes/stupa-tower.svg +0 -119
  211. package/website/assets/silhouettes/tattva-eye.svg +0 -78
  212. package/website/assets/silhouettes/terminal.svg +0 -74
  213. package/website/assets/silhouettes/webserver.svg +0 -145
  214. package/website/assets/silhouettes/yak.svg +0 -78
  215. package/website/assets/yakmesh-logo.png +0 -0
  216. package/website/assets/yakmesh-logo.webp +0 -0
  217. package/website/assets/yakmesh-logo128x140.webp +0 -0
  218. package/website/assets/yakmesh-logo2.png +0 -0
  219. package/website/assets/yakmesh-logo2.svg +0 -51
  220. package/website/assets/yakmesh-logo40x44.webp +0 -0
  221. package/website/assets/yakmesh.gif +0 -0
  222. package/website/assets/yakmesh.ico +0 -0
  223. package/website/assets/yakmesh.jpg +0 -0
  224. package/website/assets/yakmesh.pdf +0 -0
  225. package/website/assets/yakmesh.png +0 -0
  226. package/website/assets/yakmesh.svg +0 -70
  227. package/website/assets/yakmesh128.webp +0 -0
  228. package/website/assets/yakmesh32.png +0 -0
  229. package/website/assets/yakmesh32.svg +0 -65
  230. package/website/assets/yakmesh32o.ico +0 -2
  231. package/website/assets/yakmesh32o.svg +0 -65
  232. package/website/assets/yakmesh32o.svgz +0 -0
package/docs/vani.html ADDED
@@ -0,0 +1,1270 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-theme="vani">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <link rel="icon" href="favicon.ico" sizes="32x32">
7
+ <link rel="icon" href="icon.svg" type="image/svg+xml">
8
+ <link rel="apple-touch-icon" href="apple-touch-icon.png">
9
+ <title>VANI Protocol | YAKMESH Documentation</title>
10
+ <meta name="description" content="VANI - Voice And Networked Interaction. WebRTC voice and video calling for the Yakmesh network.">
11
+ <link rel="stylesheet" href="tailwind.min.css">
12
+ <link rel="stylesheet" href="prism-tomorrow.min.css" media="print" onload="this.media='all'">
13
+ <noscript><link rel="stylesheet" href="prism-tomorrow.min.css"></noscript>
14
+ <link rel="stylesheet" href="docs.css">
15
+ <style>
16
+ .theme-accent { color: #fb7185; }
17
+ .theme-accent-hover:hover { color: #f43f5e; }
18
+ .theme-badge { background: rgba(244, 63, 94, 0.2); color: #fb7185; }
19
+ .theme-border { border-color: #f43f5e; }
20
+ .theme-callout { background: rgba(244, 63, 94, 0.1); border-color: #e11d48; }
21
+ .active-link { background: rgba(244, 63, 94, 0.2) !important; color: #fb7185 !important; }
22
+ </style>
23
+
24
+ <!-- Open Graph -->
25
+ <meta property="og:type" content="article">
26
+ <meta property="og:site_name" content="Yakmesh Documentation">
27
+ <meta property="og:title" content="VANI — Yakmesh">
28
+ <meta property="og:description" content="VANI voice and video calls — real-time communication over the mesh network.">
29
+ </head>
30
+ <body class="bg-mountain-900 text-white min-h-screen">
31
+ <!-- YAKMESH-ICON-SPRITE-START -->
32
+ <svg xmlns="http://www.w3.org/2000/svg" style="display:none">
33
+ <!--
34
+ Yakmesh Docs Icon Sprite Sheet
35
+ 24×24 viewBox — stroke/fill set via .doc-icon CSS
36
+ Usage: <svg class="doc-icon"><use href="#icon-name"/></svg>
37
+ -->
38
+
39
+ <!-- ═══ GUIDES ═══ -->
40
+
41
+ <symbol id="icon-home" viewBox="0 0 24 24">
42
+ <path d="M3 9.5L12 3l9 6.5V20a1 1 0 01-1 1H4a1 1 0 01-1-1V9.5z"/>
43
+ <polyline points="9 22 9 12 15 12 15 22"/>
44
+ </symbol>
45
+
46
+ <symbol id="icon-rocket" viewBox="0 0 24 24">
47
+ <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 00-2.91-.09z"/>
48
+ <path d="M12 15l-3-3a22 22 0 012-3.95A12.88 12.88 0 0122 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 01-4 2z"/>
49
+ <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/>
50
+ <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>
51
+ </symbol>
52
+
53
+ <symbol id="icon-book" viewBox="0 0 24 24">
54
+ <path d="M4 19.5A2.5 2.5 0 016.5 17H20"/>
55
+ <path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/>
56
+ <line x1="8" y1="7" x2="16" y2="7"/>
57
+ <line x1="8" y1="11" x2="13" y2="11"/>
58
+ </symbol>
59
+
60
+ <!-- ═══ PROTOCOL STACK ═══ -->
61
+
62
+ <!-- YAK:// — Content addressing (yak horns) -->
63
+ <symbol id="icon-yak" viewBox="0 0 24 24">
64
+ <path d="M4 4c1 3 3 5 5 6"/>
65
+ <path d="M20 4c-1 3-3 5-5 6"/>
66
+ <circle cx="12" cy="14" r="5"/>
67
+ <circle cx="10" cy="13" r="0.5" fill="currentColor"/>
68
+ <circle cx="14" cy="13" r="0.5" fill="currentColor"/>
69
+ <path d="M10 16c1 1 3 1 4 0"/>
70
+ </symbol>
71
+
72
+ <!-- ANNEX — Encrypted bridge -->
73
+ <symbol id="icon-annex" viewBox="0 0 24 24">
74
+ <path d="M4 18h3a4 4 0 004-4V8"/>
75
+ <path d="M20 18h-3a4 4 0 01-4-4V8"/>
76
+ <circle cx="7" cy="6" r="2"/>
77
+ <circle cx="17" cy="6" r="2"/>
78
+ <line x1="7" y1="8" x2="7" y2="18"/>
79
+ <line x1="17" y1="8" x2="17" y2="18"/>
80
+ </symbol>
81
+
82
+ <!-- JHILKE — Cricket / steganographic key lifecycle -->
83
+ <symbol id="icon-jhilke" viewBox="0 0 24 24">
84
+ <ellipse cx="12" cy="14" rx="4" ry="6"/>
85
+ <path d="M8 10c-2-3-4-6-3-8"/>
86
+ <path d="M16 10c2-3 4-6 3-8"/>
87
+ <line x1="10" y1="20" x2="8" y2="23"/>
88
+ <line x1="14" y1="20" x2="16" y2="23"/>
89
+ <path d="M9 12l-4 2"/>
90
+ <path d="M15 12l4 2"/>
91
+ </symbol>
92
+
93
+ <!-- NAKPAK — Onion layers / backpack -->
94
+ <symbol id="icon-nakpak" viewBox="0 0 24 24">
95
+ <circle cx="12" cy="12" r="10" opacity="0.3"/>
96
+ <circle cx="12" cy="12" r="7" opacity="0.5"/>
97
+ <circle cx="12" cy="12" r="4" opacity="0.8"/>
98
+ <circle cx="12" cy="12" r="1.5" fill="currentColor"/>
99
+ </symbol>
100
+
101
+ <!-- NAMCHE — Gateway door -->
102
+ <symbol id="icon-namche" viewBox="0 0 24 24">
103
+ <rect x="3" y="3" width="18" height="18" rx="2"/>
104
+ <path d="M9 3v18"/>
105
+ <path d="M15 3v18"/>
106
+ <line x1="3" y1="8" x2="9" y2="8"/>
107
+ <line x1="15" y1="8" x2="21" y2="8"/>
108
+ <circle cx="12" cy="14" r="1" fill="currentColor"/>
109
+ </symbol>
110
+
111
+ <!-- DOKO — Basket / certificate -->
112
+ <symbol id="icon-doko" viewBox="0 0 24 24">
113
+ <path d="M6 8l-2 12h16l-2-12"/>
114
+ <path d="M6 8c0-3 2.7-5 6-5s6 2 6 5"/>
115
+ <line x1="8" y1="10" x2="10" y2="18"/>
116
+ <line x1="16" y1="10" x2="14" y2="18"/>
117
+ <line x1="12" y1="10" x2="12" y2="18"/>
118
+ </symbol>
119
+
120
+ <!-- SHERPA — Mountain climber -->
121
+ <symbol id="icon-sherpa" viewBox="0 0 24 24">
122
+ <path d="M4 20L10 6l3 6 3-4 4 12"/>
123
+ <line x1="4" y1="20" x2="20" y2="20"/>
124
+ <circle cx="13" cy="4" r="1.5"/>
125
+ </symbol>
126
+
127
+ <!-- MANDALA — Network topology web -->
128
+ <symbol id="icon-mandala" viewBox="0 0 24 24">
129
+ <circle cx="12" cy="12" r="9"/>
130
+ <circle cx="12" cy="12" r="4.5"/>
131
+ <line x1="12" y1="3" x2="12" y2="21"/>
132
+ <line x1="3" y1="12" x2="21" y2="12"/>
133
+ <line x1="5.6" y1="5.6" x2="18.4" y2="18.4"/>
134
+ <line x1="18.4" y1="5.6" x2="5.6" y2="18.4"/>
135
+ </symbol>
136
+
137
+ <!-- MANTRA — Gossip / prayer wheel -->
138
+ <symbol id="icon-mantra" viewBox="0 0 24 24">
139
+ <circle cx="12" cy="10" r="7"/>
140
+ <path d="M12 3v14"/>
141
+ <path d="M8 7c2 1.5 6 1.5 8 0"/>
142
+ <path d="M8 13c2-1.5 6-1.5 8 0"/>
143
+ <line x1="12" y1="17" x2="12" y2="22"/>
144
+ <line x1="9" y1="22" x2="15" y2="22"/>
145
+ </symbol>
146
+
147
+ <!-- GUMBA — Temple / access control -->
148
+ <symbol id="icon-gumba" viewBox="0 0 24 24">
149
+ <path d="M12 2L3 9h18z"/>
150
+ <line x1="5" y1="9" x2="5" y2="19"/>
151
+ <line x1="9" y1="9" x2="9" y2="19"/>
152
+ <line x1="15" y1="9" x2="15" y2="19"/>
153
+ <line x1="19" y1="9" x2="19" y2="19"/>
154
+ <line x1="3" y1="19" x2="21" y2="19"/>
155
+ <line x1="3" y1="21" x2="21" y2="21"/>
156
+ </symbol>
157
+
158
+ <!-- YURT — Camp / room -->
159
+ <symbol id="icon-yurt" viewBox="0 0 24 24">
160
+ <path d="M3 20L12 4l9 16"/>
161
+ <line x1="3" y1="20" x2="21" y2="20"/>
162
+ <path d="M10 20v-5a2 2 0 014 0v5"/>
163
+ <path d="M6 14h12"/>
164
+ </symbol>
165
+
166
+ <!-- KATHA — Chat / story scroll -->
167
+ <symbol id="icon-katha" viewBox="0 0 24 24">
168
+ <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
169
+ <line x1="8" y1="8" x2="16" y2="8"/>
170
+ <line x1="8" y1="12" x2="13" y2="12"/>
171
+ </symbol>
172
+
173
+ <!-- VANI — Voice / microphone -->
174
+ <symbol id="icon-vani" viewBox="0 0 24 24">
175
+ <rect x="9" y="2" width="6" height="11" rx="3"/>
176
+ <path d="M5 10a7 7 0 0014 0"/>
177
+ <line x1="12" y1="17" x2="12" y2="22"/>
178
+ <line x1="8" y1="22" x2="16" y2="22"/>
179
+ </symbol>
180
+
181
+ <!-- DARSHAN — Eye / viewing -->
182
+ <symbol id="icon-darshan" viewBox="0 0 24 24">
183
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z"/>
184
+ <circle cx="12" cy="12" r="3"/>
185
+ </symbol>
186
+
187
+ <!-- STUPA — Tower / distributed storage -->
188
+ <symbol id="icon-stupa" viewBox="0 0 24 24">
189
+ <line x1="12" y1="2" x2="12" y2="5"/>
190
+ <path d="M10 5h4l1 3H9z"/>
191
+ <ellipse cx="12" cy="11" rx="5" ry="3"/>
192
+ <ellipse cx="12" cy="15" rx="6" ry="3"/>
193
+ <ellipse cx="12" cy="19" rx="7" ry="3"/>
194
+ </symbol>
195
+
196
+ <!-- LAMA — Crystal ball / consensus -->
197
+ <symbol id="icon-lama" viewBox="0 0 24 24">
198
+ <circle cx="12" cy="10" r="7"/>
199
+ <path d="M12 3c-1.5 2-2 5 0 7s4.5 2 6 0"/>
200
+ <path d="M7 19h10"/>
201
+ <path d="M9 22h6"/>
202
+ <line x1="9" y1="17" x2="9" y2="19"/>
203
+ <line x1="15" y1="17" x2="15" y2="19"/>
204
+ </symbol>
205
+
206
+ <!-- MANI — Prayer stone / time sync -->
207
+ <symbol id="icon-mani" viewBox="0 0 24 24">
208
+ <circle cx="12" cy="12" r="9"/>
209
+ <polyline points="12 6 12 12 16 14"/>
210
+ <circle cx="12" cy="12" r="1" fill="currentColor"/>
211
+ </symbol>
212
+
213
+ <!-- KARMA — Yin-yang / reputation -->
214
+ <symbol id="icon-karma" viewBox="0 0 24 24">
215
+ <circle cx="12" cy="12" r="9"/>
216
+ <path d="M12 3a4.5 4.5 0 010 9 4.5 4.5 0 000 9"/>
217
+ <circle cx="12" cy="7.5" r="1.5" fill="currentColor"/>
218
+ <circle cx="12" cy="16.5" r="1.5"/>
219
+ </symbol>
220
+
221
+ <!-- TATTVA — Quantum elements / atom -->
222
+ <symbol id="icon-tattva" viewBox="0 0 24 24">
223
+ <circle cx="12" cy="12" r="2.5" fill="currentColor" stroke="none"/>
224
+ <ellipse cx="12" cy="12" rx="10" ry="4"/>
225
+ <ellipse cx="12" cy="12" rx="10" ry="4" transform="rotate(60 12 12)"/>
226
+ <ellipse cx="12" cy="12" rx="10" ry="4" transform="rotate(120 12 12)"/>
227
+ </symbol>
228
+
229
+ <!-- TRIBHUJ — Triangle / balanced ternary -->
230
+ <symbol id="icon-tribhuj" viewBox="0 0 24 24">
231
+ <polygon points="12,3 21,20 3,20"/>
232
+ <line x1="12" y1="3" x2="12" y2="20"/>
233
+ <line x1="7.5" y1="11.5" x2="16.5" y2="11.5"/>
234
+ <circle cx="12" cy="14" r="1" fill="currentColor"/>
235
+ </symbol>
236
+
237
+ <!-- YPC-27 — Lock / cipher -->
238
+ <symbol id="icon-ypc27" viewBox="0 0 24 24">
239
+ <rect x="5" y="11" width="14" height="10" rx="2"/>
240
+ <path d="M8 11V7a4 4 0 118 0v4"/>
241
+ <circle cx="12" cy="16" r="1" fill="currentColor"/>
242
+ <line x1="12" y1="17" x2="12" y2="19"/>
243
+ </symbol>
244
+
245
+ <!-- SAKSHI — Witness / aperture eye -->
246
+ <symbol id="icon-sakshi" viewBox="0 0 24 24">
247
+ <circle cx="12" cy="12" r="9"/>
248
+ <path d="M12 3l3 9-3 9"/>
249
+ <path d="M12 3l-3 9 3 9"/>
250
+ <circle cx="12" cy="12" r="2.5"/>
251
+ <circle cx="12" cy="12" r="0.8" fill="currentColor"/>
252
+ </symbol>
253
+
254
+ <!-- PRAMAAN — Globe / geographic proof -->
255
+ <symbol id="icon-pramaan" viewBox="0 0 24 24">
256
+ <circle cx="12" cy="12" r="9"/>
257
+ <ellipse cx="12" cy="12" rx="4" ry="9"/>
258
+ <line x1="3" y1="9" x2="21" y2="9"/>
259
+ <line x1="3" y1="15" x2="21" y2="15"/>
260
+ <path d="M18 4l-2 2 1 3"/>
261
+ <path d="M6 18l2-1 3 1"/>
262
+ </symbol>
263
+
264
+ <!-- SURAKSHA — Shield / security -->
265
+ <symbol id="icon-suraksha" viewBox="0 0 24 24">
266
+ <path d="M12 2l8 4v6c0 5.5-3.8 10.7-8 12-4.2-1.3-8-6.5-8-12V6z"/>
267
+ <polyline points="9 12 11 14 15 10"/>
268
+ </symbol>
269
+
270
+ <!-- TIVRA — Lightning bolt / acceleration -->
271
+ <symbol id="icon-tivra" viewBox="0 0 24 24">
272
+ <polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/>
273
+ </symbol>
274
+
275
+ <!-- PRAHARI — Satellite / sentinel -->
276
+ <symbol id="icon-prahari" viewBox="0 0 24 24">
277
+ <rect x="9" y="9" width="6" height="6" rx="1" transform="rotate(45 12 12)"/>
278
+ <line x1="12" y1="5" x2="12" y2="2"/>
279
+ <line x1="19" y1="12" x2="22" y2="12"/>
280
+ <line x1="12" y1="19" x2="12" y2="22"/>
281
+ <line x1="5" y1="12" x2="2" y2="12"/>
282
+ <path d="M7 7L5 5"/>
283
+ <path d="M17 7l2-2"/>
284
+ </symbol>
285
+
286
+ <!-- DHARMA — Balance scale / content moderation -->
287
+ <symbol id="icon-dharma" viewBox="0 0 24 24">
288
+ <line x1="12" y1="3" x2="12" y2="21"/>
289
+ <line x1="4" y1="7" x2="20" y2="7"/>
290
+ <path d="M4 7l2 7h0a3 3 0 006 0h0l2-7"/>
291
+ <path d="M14 7l2 7h0a3 3 0 006 0h0l2-7"/>
292
+ <line x1="10" y1="21" x2="14" y2="21"/>
293
+ </symbol>
294
+
295
+ <!-- SEVA — Helping hands / NPU sharing -->
296
+ <symbol id="icon-seva" viewBox="0 0 24 24">
297
+ <path d="M12 22c-4 0-8-2-8-6 0-2 1-3 3-4l5-3 5 3c2 1 3 2 3 4 0 4-4 6-8 6z"/>
298
+ <path d="M12 11V5"/>
299
+ <path d="M9 8l3-3 3 3"/>
300
+ <circle cx="12" cy="16" r="2"/>
301
+ </symbol>
302
+
303
+ <!-- ═══ APPLICATIONS ═══ -->
304
+
305
+ <!-- YakApp — Messenger -->
306
+ <symbol id="icon-yakapp" viewBox="0 0 24 24">
307
+ <path d="M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z"/>
308
+ </symbol>
309
+
310
+ <!-- C2C — Core to Cosmos -->
311
+ <symbol id="icon-c2c" viewBox="0 0 24 24">
312
+ <circle cx="12" cy="12" r="3"/>
313
+ <circle cx="12" cy="12" r="9"/>
314
+ <path d="M12 3v3"/>
315
+ <path d="M12 18v3"/>
316
+ <path d="M3 12h3"/>
317
+ <path d="M18 12h3"/>
318
+ </symbol>
319
+
320
+ <!-- Studio — Creative suite -->
321
+ <symbol id="icon-studio" viewBox="0 0 24 24">
322
+ <circle cx="13.5" cy="6.5" r="2.5"/>
323
+ <path d="M6 21l4-10 3 5 4-7 4 12"/>
324
+ <rect x="2" y="2" width="20" height="20" rx="2"/>
325
+ </symbol>
326
+
327
+
328
+ <!-- ═══ REFERENCE ═══ -->
329
+
330
+ <!-- Quick Reference — Clipboard -->
331
+ <symbol id="icon-quickref" viewBox="0 0 24 24">
332
+ <path d="M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2"/>
333
+ <rect x="8" y="2" width="8" height="4" rx="1"/>
334
+ <line x1="8" y1="10" x2="16" y2="10"/>
335
+ <line x1="8" y1="14" x2="16" y2="14"/>
336
+ <line x1="8" y1="18" x2="12" y2="18"/>
337
+ </symbol>
338
+
339
+ <!-- GRANTH — Docs bundle -->
340
+ <symbol id="icon-granth" viewBox="0 0 24 24">
341
+ <path d="M4 19.5A2.5 2.5 0 016.5 17H20"/>
342
+ <path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/>
343
+ <path d="M8 7h8"/>
344
+ <path d="M8 11h5"/>
345
+ <path d="M8 15h3"/>
346
+ </symbol>
347
+
348
+ <!-- API — Signal tower -->
349
+ <symbol id="icon-api" viewBox="0 0 24 24">
350
+ <line x1="12" y1="10" x2="12" y2="22"/>
351
+ <path d="M8 6a6 6 0 018 0"/>
352
+ <path d="M5 3a10 10 0 0114 0"/>
353
+ <circle cx="12" cy="10" r="2"/>
354
+ </symbol>
355
+
356
+ <!-- Adapters — Plug connector -->
357
+ <symbol id="icon-adapters" viewBox="0 0 24 24">
358
+ <path d="M6 3v4"/>
359
+ <path d="M10 3v4"/>
360
+ <path d="M4 7h8v3a4 4 0 01-8 0V7z"/>
361
+ <line x1="8" y1="14" x2="8" y2="17"/>
362
+ <path d="M14 10h4v3a2 2 0 01-4 0v-3z"/>
363
+ <line x1="16" y1="7" x2="16" y2="10"/>
364
+ <line x1="16" y1="13" x2="16" y2="17"/>
365
+ <line x1="8" y1="17" x2="16" y2="17"/>
366
+ <line x1="12" y1="17" x2="12" y2="21"/>
367
+ </symbol>
368
+
369
+ <!-- ═══ EXTRA (pages outside nav-order) ═══ -->
370
+
371
+ <!-- Terminal / CLI -->
372
+ <symbol id="icon-terminal" viewBox="0 0 24 24">
373
+ <rect x="2" y="3" width="20" height="18" rx="2"/>
374
+ <polyline points="7 9 10 12 7 15"/>
375
+ <line x1="13" y1="15" x2="17" y2="15"/>
376
+ </symbol>
377
+
378
+ <!-- Gear / Configuration -->
379
+ <symbol id="icon-gear" viewBox="0 0 24 24">
380
+ <circle cx="12" cy="12" r="3"/>
381
+ <path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/>
382
+ </symbol>
383
+
384
+ <!-- Server / Web hosting -->
385
+ <symbol id="icon-server" viewBox="0 0 24 24">
386
+ <rect x="2" y="2" width="20" height="8" rx="2"/>
387
+ <rect x="2" y="14" width="20" height="8" rx="2"/>
388
+ <line x1="6" y1="6" x2="6.01" y2="6"/>
389
+ <line x1="6" y1="18" x2="6.01" y2="18"/>
390
+ </symbol>
391
+
392
+ <!-- ═══ CHROME / UI ═══ -->
393
+
394
+ <!-- Mountain peak — logo icon (replaces 🏔️) -->
395
+ <symbol id="icon-mountain" viewBox="0 0 24 24">
396
+ <path d="M8 21l4.5-9 3 5.5L19 12l3 9H2l6-9z"/>
397
+ <path d="M12 12l1.5-3L16 14"/>
398
+ </symbol>
399
+
400
+ <!-- Dashboard / bar chart (replaces 📊) -->
401
+ <symbol id="icon-dashboard" viewBox="0 0 24 24">
402
+ <line x1="18" y1="20" x2="18" y2="10"/>
403
+ <line x1="12" y1="20" x2="12" y2="4"/>
404
+ <line x1="6" y1="20" x2="6" y2="14"/>
405
+ <rect x="2" y="2" width="20" height="20" rx="2" stroke-opacity="0.4"/>
406
+ </symbol>
407
+
408
+ <!-- ═══ GENERIC / CONTENT ICONS ═══ -->
409
+
410
+ <!-- Lock / encrypted (replaces 🔐) -->
411
+ <symbol id="icon-lock" viewBox="0 0 24 24">
412
+ <rect x="3" y="11" width="18" height="11" rx="2"/>
413
+ <path d="M7 11V7a5 5 0 0110 0v4"/>
414
+ </symbol>
415
+
416
+ <!-- Signal / broadcast (replaces 📡) -->
417
+ <symbol id="icon-signal" viewBox="0 0 24 24">
418
+ <path d="M2 12a10 10 0 0118 0"/>
419
+ <path d="M5 12a7 7 0 0112 0"/>
420
+ <path d="M8 12a4 4 0 016 0"/>
421
+ <circle cx="11" cy="12" r="1"/>
422
+ </symbol>
423
+
424
+ <!-- Link / chain (replaces 🔗) -->
425
+ <symbol id="icon-link" viewBox="0 0 24 24">
426
+ <path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/>
427
+ <path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/>
428
+ </symbol>
429
+
430
+ <!-- Globe / network (replaces 🌐) -->
431
+ <symbol id="icon-globe" viewBox="0 0 24 24">
432
+ <circle cx="12" cy="12" r="10"/>
433
+ <line x1="2" y1="12" x2="22" y2="12"/>
434
+ <path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/>
435
+ </symbol>
436
+
437
+ <!-- Sync / refresh (replaces 🔄) -->
438
+ <symbol id="icon-sync" viewBox="0 0 24 24">
439
+ <polyline points="23 4 23 10 17 10"/>
440
+ <polyline points="1 20 1 14 7 14"/>
441
+ <path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
442
+ </symbol>
443
+
444
+ <!-- Users / group (replaces 👥) -->
445
+ <symbol id="icon-users" viewBox="0 0 24 24">
446
+ <path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/>
447
+ <circle cx="9" cy="7" r="4"/>
448
+ <path d="M23 21v-2a4 4 0 00-3-3.87"/>
449
+ <path d="M16 3.13a4 4 0 010 7.75"/>
450
+ </symbol>
451
+
452
+ <!-- Shield / protection (replaces 🛡) -->
453
+ <symbol id="icon-shield" viewBox="0 0 24 24">
454
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
455
+ </symbol>
456
+
457
+ <!-- Heartbeat / pulse (replaces 💓) -->
458
+ <symbol id="icon-heartbeat" viewBox="0 0 24 24">
459
+ <path d="M3 12h4l3-9 4 18 3-9h4"/>
460
+ </symbol>
461
+
462
+ <!-- Map pin / location (replaces 📍) -->
463
+ <symbol id="icon-pin" viewBox="0 0 24 24">
464
+ <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z"/>
465
+ <circle cx="12" cy="10" r="3"/>
466
+ </symbol>
467
+
468
+ <!-- Traffic light / status (replaces 🚦) -->
469
+ <symbol id="icon-traffic" viewBox="0 0 24 24">
470
+ <rect x="7" y="2" width="10" height="20" rx="3"/>
471
+ <circle cx="12" cy="7" r="1.5"/>
472
+ <circle cx="12" cy="12" r="1.5"/>
473
+ <circle cx="12" cy="17" r="1.5"/>
474
+ </symbol>
475
+
476
+ <!-- Check circle (replaces ✅) -->
477
+ <symbol id="icon-check" viewBox="0 0 24 24">
478
+ <path d="M22 11.08V12a10 10 0 11-5.93-9.14"/>
479
+ <polyline points="22 4 12 14.01 9 11.01"/>
480
+ </symbol>
481
+
482
+ <!-- Megaphone / broadcast (replaces 📢) -->
483
+ <symbol id="icon-megaphone" viewBox="0 0 24 24">
484
+ <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/>
485
+ </symbol>
486
+
487
+ <!-- Pen / signed (replaces ✍) -->
488
+ <symbol id="icon-pen" viewBox="0 0 24 24">
489
+ <path d="M12 20h9"/>
490
+ <path d="M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/>
491
+ </symbol>
492
+
493
+ <!-- Warning / alert (replaces ⚠) -->
494
+ <symbol id="icon-warning" viewBox="0 0 24 24">
495
+ <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>
496
+ <line x1="12" y1="9" x2="12" y2="13"/>
497
+ <line x1="12" y1="17" x2="12.01" y2="17"/>
498
+ </symbol>
499
+
500
+ <!-- Hourglass / timer (replaces ⏳) -->
501
+ <symbol id="icon-hourglass" viewBox="0 0 24 24">
502
+ <path d="M6 2h12v5l-4 4 4 4v5H6v-5l4-4-4-4V2z"/>
503
+ </symbol>
504
+
505
+ <!-- Scroll / document (replaces 📜) -->
506
+ <symbol id="icon-scroll" viewBox="0 0 24 24">
507
+ <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/>
508
+ <polyline points="14 2 14 8 20 8"/>
509
+ <line x1="16" y1="13" x2="8" y2="13"/>
510
+ <line x1="16" y1="17" x2="8" y2="17"/>
511
+ </symbol>
512
+
513
+ <!-- Bolt / lightning (replaces ⚡) -->
514
+ <symbol id="icon-bolt" viewBox="0 0 24 24">
515
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
516
+ </symbol>
517
+
518
+ <!-- Target / crosshair (replaces 🎯) -->
519
+ <symbol id="icon-target" viewBox="0 0 24 24">
520
+ <circle cx="12" cy="12" r="10"/>
521
+ <circle cx="12" cy="12" r="6"/>
522
+ <circle cx="12" cy="12" r="2"/>
523
+ </symbol>
524
+
525
+ <!-- Handshake / trust (replaces 🤝) -->
526
+ <symbol id="icon-handshake" viewBox="0 0 24 24">
527
+ <path d="M11 17l-3.5-3.5a2.12 2.12 0 013-3L14 14"/>
528
+ <path d="M20.88 7.12l-3.17 3.17"/>
529
+ <path d="M3.12 7.12l3.17 3.17"/>
530
+ <path d="M2 12h4"/>
531
+ <path d="M18 12h4"/>
532
+ <path d="M7.76 4.25L12 2l4.24 2.25"/>
533
+ </symbol>
534
+
535
+ <!-- Leaf / organic (replaces 🌿) -->
536
+ <symbol id="icon-leaf" viewBox="0 0 24 24">
537
+ <path d="M17 8C8 10 5.9 16.17 3.82 21.34l1.89.66.95-2.3c.48.17.98.3 1.34.3C19 20 22 3 22 3c-1 0-8 0-10 2"/>
538
+ <path d="M7 15c2-2 5.5-3 9-3"/>
539
+ </symbol>
540
+
541
+ <!-- Satellite (replaces 🛰) -->
542
+ <symbol id="icon-satellite" viewBox="0 0 24 24">
543
+ <path d="M13 7L9 3 5 7l4 4"/>
544
+ <path d="M17 11l4 4-4 4-4-4"/>
545
+ <line x1="8" y1="11" x2="13" y2="16"/>
546
+ <line x1="3" y1="21" x2="3.01" y2="21"/>
547
+ <path d="M6 18a3 3 0 000 0"/>
548
+ <path d="M9 15a6 6 0 000 0"/>
549
+ </symbol>
550
+
551
+ <!-- Phone / mobile (replaces 📱) -->
552
+ <symbol id="icon-phone" viewBox="0 0 24 24">
553
+ <rect x="5" y="2" width="14" height="20" rx="2"/>
554
+ <line x1="12" y1="18" x2="12.01" y2="18"/>
555
+ </symbol>
556
+
557
+ <!-- Masks / theater (replaces 🎭) -->
558
+ <symbol id="icon-masks" viewBox="0 0 24 24">
559
+ <circle cx="12" cy="12" r="10"/>
560
+ <path d="M8 14s1.5 2 4 2 4-2 4-2"/>
561
+ <line x1="9" y1="9" x2="9.01" y2="9"/>
562
+ <line x1="15" y1="9" x2="15.01" y2="9"/>
563
+ </symbol>
564
+
565
+ <!-- Stars / cosmos (replaces 🌌) -->
566
+ <symbol id="icon-cosmos" viewBox="0 0 24 24">
567
+ <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
568
+ </symbol>
569
+
570
+ <!-- Gem / diamond (replaces 💎) -->
571
+ <symbol id="icon-gem" viewBox="0 0 24 24">
572
+ <polygon points="6 3 18 3 22 9 12 22 2 9 6 3"/>
573
+ <line x1="2" y1="9" x2="22" y2="9"/>
574
+ <line x1="12" y1="22" x2="8" y2="9"/>
575
+ <line x1="12" y1="22" x2="16" y2="9"/>
576
+ <line x1="8" y1="9" x2="10" y2="3"/>
577
+ <line x1="16" y1="9" x2="14" y2="3"/>
578
+ </symbol>
579
+
580
+ <!-- Search / magnifying glass (replaces 🔍) -->
581
+ <symbol id="icon-search" viewBox="0 0 24 24">
582
+ <circle cx="11" cy="11" r="8"/>
583
+ <line x1="21" y1="21" x2="16.65" y2="16.65"/>
584
+ </symbol>
585
+
586
+ </svg>
587
+ <!-- YAKMESH-ICON-SPRITE-END -->
588
+ <a href="#mainContent" class="skip-link">Skip to main content</a>
589
+ <nav class="docs-sidebar" id="sidebar">
590
+ <a href="index.html" class="sidebar-logo">
591
+ <span class="logo-icon"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mountain"/></svg></span>
592
+ <span class="logo-text">Yakmesh</span>
593
+ </a>
594
+ <a href="/dashboard" class="sidebar-dashboard-link"><svg class="doc-icon" aria-hidden="true"><use href="#icon-dashboard"/></svg> <span>Dashboard</span></a>
595
+ <ul class="sidebar-nav">
596
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-book"/></svg> Guides</span></li>
597
+ <li><a href="index.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-home"/></svg> <span>Overview</span></a></li>
598
+ <li><a href="getting-started.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-rocket"/></svg> <span>Getting Started</span></a></li>
599
+ <li><a href="tutorials.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-book"/></svg> <span>Tutorials</span></a></li>
600
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-yak"/></svg> Protocol Stack</span></li>
601
+ <li><a href="yak-protocol.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-yak"/></svg> <span>YAK://</span></a></li>
602
+ <li><a href="annex.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-annex"/></svg> <span>ANNEX</span></a></li>
603
+ <li><a href="jhilke.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-jhilke"/></svg> <span>JHILKE</span></a></li>
604
+ <li><a href="nakpak.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-nakpak"/></svg> <span>NAKPAK</span></a></li>
605
+ <li><a href="namche.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-namche"/></svg> <span>NAMCHE</span></a></li>
606
+ <li><a href="doko.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-doko"/></svg> <span>DOKO</span></a></li>
607
+ <li><a href="sherpa.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-sherpa"/></svg> <span>SHERPA</span></a></li>
608
+ <li><a href="mandala.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mandala"/></svg> <span>MANDALA</span></a></li>
609
+ <li><a href="mantra.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mantra"/></svg> <span>MANTRA</span></a></li>
610
+ <li><a href="gumba.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-gumba"/></svg> <span>GUMBA</span></a></li>
611
+ <li><a href="yurt.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-yurt"/></svg> <span>YURT</span></a></li>
612
+ <li><a href="katha.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-katha"/></svg> <span>KATHA</span></a></li>
613
+ <li><a href="vani.html" class="active"><svg class="doc-icon" aria-hidden="true"><use href="#icon-vani"/></svg> <span>VANI</span></a></li>
614
+ <li><a href="darshan.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-darshan"/></svg> <span>DARSHAN</span></a></li>
615
+ <li><a href="stupa.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-stupa"/></svg> <span>STUPA</span></a></li>
616
+ <li><a href="lama.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-lama"/></svg> <span>LAMA</span></a></li>
617
+ <li><a href="mani.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mani"/></svg> <span>MANI</span></a></li>
618
+ <li><a href="karma.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-karma"/></svg> <span>KARMA</span></a></li>
619
+ <li><a href="tattva.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-tattva"/></svg> <span>TATTVA</span></a></li>
620
+ <li><a href="tribhuj.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-tribhuj"/></svg> <span>TRIBHUJ</span></a></li>
621
+ <li><a href="ypc27.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-ypc27"/></svg> <span>YPC-27</span></a></li>
622
+ <li><a href="sakshi.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-sakshi"/></svg> <span>SAKSHI</span></a></li>
623
+ <li><a href="geo-proof.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-pramaan"/></svg> <span>PRAMAAN</span></a></li>
624
+ <li><a href="trust-security.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-suraksha"/></svg> <span>SURAKSHA</span></a></li>
625
+ <li><a href="tivra.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-tivra"/></svg> <span>TIVRA</span></a></li>
626
+ <li><a href="prahari.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-prahari"/></svg> <span>PRAHARI</span></a></li>
627
+ <li><a href="dharma.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-dharma"/></svg> <span>DHARMA</span></a></li>
628
+ <li><a href="seva.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-seva"/></svg> <span>SEVA</span></a></li>
629
+ <li><a href="docs-bundle.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-granth"/></svg> <span>GRANTH</span></a></li>
630
+ <li><a href="api.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-api"/></svg> <span>API</span></a></li>
631
+ <li><a href="adapters.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-adapters"/></svg> <span>Adapters</span></a></li>
632
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-rocket"/></svg> Applications</span></li>
633
+ <li><a href="yakapp.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-yakapp"/></svg> <span>YakApp</span></a></li>
634
+ <li><a href="c2c.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-c2c"/></svg> <span>C2C</span></a></li>
635
+ <li><a href="studio.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-studio"/></svg> <span>Studio</span></a></li>
636
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-gear"/></svg> Infrastructure</span></li>
637
+ <li><a href="cli.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-terminal"/></svg> <span>CLI</span></a></li>
638
+ <li><a href="configuration.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-gear"/></svg> <span>Configuration</span></a></li>
639
+ <li><a href="mesh.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mandala"/></svg> <span>Mesh Network</span></a></li>
640
+ <li><a href="time-sources.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-mani"/></svg> <span>Time Sources</span></a></li>
641
+ <li><a href="webserver.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-server"/></svg> <span>Web Server</span></a></li>
642
+ <li><a href="advanced-systems.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-tivra"/></svg> <span>Advanced Systems</span></a></li>
643
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-book"/></svg> Tutorials</span></li>
644
+ <li><a href="gumba-tutorial.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-gumba"/></svg> <span>GUMBA Tutorial</span></a></li>
645
+ <li class="sidebar-section"><span><svg class="doc-icon" aria-hidden="true"><use href="#icon-quickref"/></svg> Reference</span></li>
646
+ <li><a href="quick-reference.html"><svg class="doc-icon" aria-hidden="true"><use href="#icon-quickref"/></svg> <span>Quick Ref</span></a></li>
647
+ </ul>
648
+ </nav>
649
+
650
+ <button class="sidebar-toggle" id="sidebarToggle" title="Toggle sidebar">
651
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
652
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
653
+ </svg>
654
+ </button>
655
+
656
+ <div class="sidebar-overlay" id="sidebarOverlay"></div>
657
+
658
+ <main class="docs-main" id="mainContent">
659
+ <div class="docs-content">
660
+ <div class="flex items-center gap-3 mb-4">
661
+ <svg class="doc-icon hero-icon" aria-hidden="true"><use href="#icon-vani"/></svg>
662
+ <div>
663
+ <h1 class="text-4xl font-bold">VANI <span class="text-xl text-mountain-400">वाणी</span></h1>
664
+ <p class="theme-accent">Voice And Networked Interaction</p>
665
+ </div>
666
+ </div>
667
+ <p class="text-xl text-mountain-300 mb-4">WebRTC voice and video calling for the Yakmesh network.</p>
668
+ <span class="inline-block text-xs theme-badge px-2 py-1 rounded mb-8">v1.0.0</span>
669
+
670
+ <!-- Architecture -->
671
+ <section class="callout theme-callout" id="architecture">
672
+ <h2><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-gear"/></svg> Architecture</h2>
673
+ <p>VANI provides real-time voice and video communication using WebRTC for media transport and the Yakmesh mesh network for signaling:</p>
674
+ <pre><code class="language-text">
675
+ ┌──────────────────────────────────────────────────────────────────┐
676
+ │ VANI ARCHITECTURE │
677
+ ├──────────────────────────────────────────────────────────────────┤
678
+ │ │
679
+ │ ┌─────────────┐ Mesh Signaling ┌─────────────┐ │
680
+ │ │ Alice │ ◄────── SDP, ICE ────────────► │ Bob │ │
681
+ │ │ VaniHub │ OFFER/ANSWER │ VaniHub │ │
682
+ │ └──────┬──────┘ └──────┬──────┘ │
683
+ │ │ │ │
684
+ │ │ WebRTC P2P │ │
685
+ │ └──────────── Media Stream ──────────────────────┘ │
686
+ │ (Audio/Video/Screen) │
687
+ │ │
688
+ ├──────────────────────────────────────────────────────────────────┤
689
+ │ Key Benefits: │
690
+ │ • No central media server - P2P encrypted streams │
691
+ │ • Signaling via mesh - no STUN/TURN dependency for setup │
692
+ │ • GUMBA integration - private calls in access-controlled rooms │
693
+ │ • Multi-party support - group calls up to 10 participants │
694
+ └──────────────────────────────────────────────────────────────────┘
695
+ </code></pre>
696
+ </section>
697
+
698
+ <!-- How It Works -->
699
+ <section class="mt-8" id="how-it-works">
700
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-phone"/></svg> How It Works</h2>
701
+ <div class="card-grid">
702
+ <div class="card">
703
+ <h3>1. Call Initiation</h3>
704
+ <p>Caller sends a <code>CALL_OFFER</code> signal through the mesh network with media preferences and caller info.</p>
705
+ </div>
706
+ <div class="card">
707
+ <h3>2. Call Answer</h3>
708
+ <p>Callee accepts with <code>CALL_ANSWER</code> or rejects with <code>CALL_REJECT</code>. Both signals route through mesh.</p>
709
+ </div>
710
+ <div class="card">
711
+ <h3>3. WebRTC Negotiation</h3>
712
+ <p><code>SDP_OFFER</code> and <code>SDP_ANSWER</code> exchange session descriptions. <code>ICE_CANDIDATE</code> signals help establish connectivity.</p>
713
+ </div>
714
+ <div class="card">
715
+ <h3>4. Media Streaming</h3>
716
+ <p>Once ICE completes, WebRTC creates a direct P2P connection for encrypted audio/video streams.</p>
717
+ </div>
718
+ </div>
719
+ </section>
720
+
721
+ <!-- Quick Start -->
722
+ <section class="mt-8" id="quick-start">
723
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-rocket"/></svg> Quick Start</h2>
724
+ <pre><code class="language-javascript">
725
+ import { VaniHub, MEDIA_TYPE, CALL_STATE } from 'yakmesh/mesh/vani.js';
726
+
727
+ // Create hub with local peer ID
728
+ const hub = new VaniHub({
729
+ localPeerId: meshNode.id,
730
+ onSignal: (signal) => meshNode.broadcast(signal)
731
+ });
732
+
733
+ // Handle incoming mesh signals
734
+ meshNode.on('message', (msg) => {
735
+ if (msg.type?.startsWith('vani:')) {
736
+ hub.handleSignal(msg);
737
+ }
738
+ });
739
+
740
+ // Listen for incoming calls
741
+ hub.on('incomingCall', ({ call }) => {
742
+ console.log('Incoming call from:', call.participants.keys());
743
+ // Show UI to accept/reject
744
+ });
745
+
746
+ // Start a video call
747
+ const call = await hub.startCall({
748
+ targetPeerIds: 'peer-bob-123',
749
+ mediaType: [MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO]
750
+ });
751
+
752
+ // Handle remote streams
753
+ hub.on('remoteStream', ({ peerId, stream }) => {
754
+ const video = document.getElementById('remoteVideo');
755
+ video.srcObject = stream;
756
+ });
757
+ </code></pre>
758
+ </section>
759
+
760
+ <!-- Call States -->
761
+ <section class="mt-8" id="call-states">
762
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-dashboard"/></svg> Call States</h2>
763
+ <table class="docs-table">
764
+ <thead>
765
+ <tr>
766
+ <th>State</th>
767
+ <th>Description</th>
768
+ <th>Next States</th>
769
+ </tr>
770
+ </thead>
771
+ <tbody>
772
+ <tr>
773
+ <td><code>idle</code></td>
774
+ <td>No active call</td>
775
+ <td>initiating, incoming</td>
776
+ </tr>
777
+ <tr>
778
+ <td><code>initiating</code></td>
779
+ <td>Creating call offer</td>
780
+ <td>ringing</td>
781
+ </tr>
782
+ <tr>
783
+ <td><code>ringing</code></td>
784
+ <td>Waiting for callee to answer</td>
785
+ <td>connecting, ended</td>
786
+ </tr>
787
+ <tr>
788
+ <td><code>incoming</code></td>
789
+ <td>Received call, awaiting user action</td>
790
+ <td>connecting, ended</td>
791
+ </tr>
792
+ <tr>
793
+ <td><code>connecting</code></td>
794
+ <td>Exchanging SDP and ICE candidates</td>
795
+ <td>connected, failed</td>
796
+ </tr>
797
+ <tr>
798
+ <td><code>connected</code></td>
799
+ <td>Media streaming active</td>
800
+ <td>reconnecting, ended</td>
801
+ </tr>
802
+ <tr>
803
+ <td><code>reconnecting</code></td>
804
+ <td>Connection temporarily lost</td>
805
+ <td>connected, failed</td>
806
+ </tr>
807
+ <tr>
808
+ <td><code>ended</code></td>
809
+ <td>Call terminated normally</td>
810
+ <td>idle</td>
811
+ </tr>
812
+ <tr>
813
+ <td><code>failed</code></td>
814
+ <td>Call failed to connect</td>
815
+ <td>idle</td>
816
+ </tr>
817
+ </tbody>
818
+ </table>
819
+ </section>
820
+
821
+ <!-- Signal Types -->
822
+ <section class="mt-8" id="signal-types">
823
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-signal"/></svg> Signal Types</h2>
824
+ <table class="docs-table">
825
+ <thead>
826
+ <tr>
827
+ <th>Signal</th>
828
+ <th>Purpose</th>
829
+ <th>Payload</th>
830
+ </tr>
831
+ </thead>
832
+ <tbody>
833
+ <tr>
834
+ <td><code>vani:call:offer</code></td>
835
+ <td>Initiate a call</td>
836
+ <td>mediaType, displayName, groupCall, bundleId</td>
837
+ </tr>
838
+ <tr>
839
+ <td><code>vani:call:answer</code></td>
840
+ <td>Accept a call</td>
841
+ <td>displayName, mediaType</td>
842
+ </tr>
843
+ <tr>
844
+ <td><code>vani:call:reject</code></td>
845
+ <td>Decline a call</td>
846
+ <td>reason</td>
847
+ </tr>
848
+ <tr>
849
+ <td><code>vani:call:end</code></td>
850
+ <td>Terminate a call</td>
851
+ <td>reason</td>
852
+ </tr>
853
+ <tr>
854
+ <td><code>vani:call:busy</code></td>
855
+ <td>Callee is in another call</td>
856
+ <td>-</td>
857
+ </tr>
858
+ <tr>
859
+ <td><code>vani:sdp:offer</code></td>
860
+ <td>WebRTC SDP offer</td>
861
+ <td>sdp</td>
862
+ </tr>
863
+ <tr>
864
+ <td><code>vani:sdp:answer</code></td>
865
+ <td>WebRTC SDP answer</td>
866
+ <td>sdp</td>
867
+ </tr>
868
+ <tr>
869
+ <td><code>vani:ice:candidate</code></td>
870
+ <td>ICE candidate for NAT traversal</td>
871
+ <td>candidate, sdpMid, sdpMLineIndex</td>
872
+ </tr>
873
+ <tr>
874
+ <td><code>vani:mute:audio</code></td>
875
+ <td>Audio mute state change</td>
876
+ <td>muted</td>
877
+ </tr>
878
+ <tr>
879
+ <td><code>vani:mute:video</code></td>
880
+ <td>Video mute state change</td>
881
+ <td>muted</td>
882
+ </tr>
883
+ </tbody>
884
+ </table>
885
+ </section>
886
+
887
+ <!-- API Reference -->
888
+ <section class="mt-8" id="api">
889
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-book"/></svg> API Reference</h2>
890
+
891
+ <h3 class="mt-6 text-xl font-semibold">VaniHub</h3>
892
+ <p class="text-mountain-300 mb-4">Multi-call manager - the main entry point for voice/video.</p>
893
+
894
+ <pre><code class="language-javascript">
895
+ // Constructor
896
+ new VaniHub({
897
+ localPeerId: string, // Your mesh node ID
898
+ iceServers?: RTCIceServer[], // Optional custom STUN/TURN servers
899
+ onSignal: (signal) => void // Callback to send signals via mesh
900
+ })
901
+
902
+ // Methods
903
+ hub.startCall(options) → Promise&lt;VaniCall&gt; // Start outgoing call
904
+ hub.handleSignal(signal) // Process incoming signal
905
+ hub.acceptCall(callId) → Promise&lt;VaniCall&gt; // Accept incoming call
906
+ hub.rejectCall(callId, reason?) // Reject incoming call
907
+ hub.endCall(callId, reason?) // End active call
908
+ hub.getCall(callId) → VaniCall | null // Get call by ID
909
+ hub.getActiveCall() → VaniCall | null // Get current active call
910
+ hub.getStats() → object // Get hub statistics
911
+ hub.cleanup() // Clean up all resources
912
+
913
+ // Events
914
+ hub.on('incomingCall', ({ call, signal }) => {}) // New incoming call
915
+ hub.on('stateChange', ({ callId, state }) => {}) // Call state changed
916
+ hub.on('remoteStream', ({ peerId, stream }) => {})// Remote media stream
917
+ hub.on('participantJoin', ({ participant }) => {})// Participant joined
918
+ hub.on('participantLeave', ({ participant }) => {})// Participant left
919
+ hub.on('error', ({ callId, code, error }) => {}) // Error occurred
920
+ </code></pre>
921
+
922
+ <h3 class="mt-6 text-xl font-semibold">VaniCall</h3>
923
+ <p class="text-mountain-300 mb-4">Individual call session with WebRTC management.</p>
924
+
925
+ <pre><code class="language-javascript">
926
+ // Properties
927
+ call.id // Unique call ID
928
+ call.state // Current call state
929
+ call.isInitiator // true if we started the call
930
+ call.isGroupCall // true if multi-party call
931
+ call.bundleId // GUMBA bundle ID for private calls
932
+ call.mediaType // Array of MEDIA_TYPE values
933
+ call.participants// Map of peerId → VaniParticipant
934
+ call.localStream // Local MediaStream
935
+ call.createdAt // Timestamp when call was created
936
+ call.connectedAt // Timestamp when call connected (null if not yet)
937
+ call.duration // Call duration in ms
938
+
939
+ // Methods
940
+ call.initiate(peerIds) // Start call to peer(s)
941
+ call.accept(callerPeerId) // Accept incoming call
942
+ call.reject(reason?) // Reject incoming call
943
+ call.end(reason?) // Hang up
944
+ call.handleSignal(signal) // Process signaling message
945
+ call.setAudioEnabled(bool) // Mute/unmute audio
946
+ call.setVideoEnabled(bool) // Enable/disable video
947
+ call.cleanup() // Release all resources
948
+ call.getDuration() → number// Get call duration
949
+ call.toJSON() → object // Serialize call info
950
+ </code></pre>
951
+
952
+ <h3 class="mt-6 text-xl font-semibold">VaniSignal</h3>
953
+ <p class="text-mountain-300 mb-4">Signaling message builders.</p>
954
+
955
+ <pre><code class="language-javascript">
956
+ // Static factory methods
957
+ VaniSignal.offer(options) // Create call offer
958
+ VaniSignal.answer(options) // Create call answer
959
+ VaniSignal.reject(options) // Create call rejection
960
+ VaniSignal.end(options) // Create call end
961
+ VaniSignal.sdpOffer(options) // Create SDP offer
962
+ VaniSignal.sdpAnswer(options) // Create SDP answer
963
+ VaniSignal.iceCandidate(options)// Create ICE candidate
964
+
965
+ // Instance methods
966
+ signal.validate() → { valid, errors } // Validate signal
967
+ signal.toJSON() → object // Serialize
968
+ VaniSignal.fromJSON(json) // Deserialize
969
+ </code></pre>
970
+
971
+ <h3 class="mt-6 text-xl font-semibold">VaniParticipant</h3>
972
+ <p class="text-mountain-300 mb-4">Represents a participant in a call.</p>
973
+
974
+ <pre><code class="language-javascript">
975
+ // Properties
976
+ participant.id // Unique participant ID
977
+ participant.peerId // Mesh peer ID
978
+ participant.displayName // Display name
979
+ participant.joinedAt // When they joined
980
+ participant.audioEnabled // Audio is on
981
+ participant.videoEnabled // Video is on
982
+ participant.screenSharing // Screen sharing active
983
+ participant.connectionState // WebRTC connection state
984
+ participant.remoteStream // Their MediaStream
985
+ </code></pre>
986
+ </section>
987
+
988
+ <!-- Group Calls -->
989
+ <section class="mt-8" id="group-calls">
990
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-users"/></svg> Group Calls</h2>
991
+ <p class="text-mountain-300 mb-4">VANI supports multi-party calls with up to 10 participants using mesh topology.</p>
992
+
993
+ <pre><code class="language-javascript">
994
+ // Start a group call
995
+ const call = await hub.startCall({
996
+ targetPeerIds: ['peer-alice', 'peer-bob', 'peer-charlie'],
997
+ mediaType: [MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO],
998
+ isGroupCall: true
999
+ });
1000
+
1001
+ // Track participants
1002
+ hub.on('participantJoin', ({ callId, participant }) => {
1003
+ console.log(participant.displayName, 'joined');
1004
+ });
1005
+
1006
+ hub.on('participantLeave', ({ callId, participant, reason }) => {
1007
+ console.log(participant.displayName, 'left:', reason);
1008
+ });
1009
+
1010
+ // Each participant has their own stream
1011
+ hub.on('remoteStream', ({ callId, peerId, stream }) => {
1012
+ // Create video element for this participant
1013
+ const video = document.createElement('video');
1014
+ video.id = 'video-' + peerId;
1015
+ video.srcObject = stream;
1016
+ video.autoplay = true;
1017
+ document.getElementById('participants').appendChild(video);
1018
+ });
1019
+ </code></pre>
1020
+ </section>
1021
+
1022
+ <!-- GUMBA Integration -->
1023
+ <section class="mt-8" id="gumba-integration">
1024
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-lock"/></svg> Private Room Calls (GUMBA)</h2>
1025
+ <p class="text-mountain-300 mb-4">VANI integrates with GUMBA for access-controlled voice/video in private rooms.</p>
1026
+
1027
+ <pre><code class="language-javascript">
1028
+ // Start a call in a private GUMBA room
1029
+ const call = await hub.startCall({
1030
+ targetPeerIds: roomMemberPeerIds,
1031
+ bundleId: gumbaBundle.id, // Links call to GUMBA access control
1032
+ mediaType: [MEDIA_TYPE.AUDIO]
1033
+ });
1034
+
1035
+ // The bundleId is included in CALL_OFFER signals
1036
+ // Receivers can verify membership before accepting
1037
+ call.bundleId // → 'gumba-bundle-123'
1038
+ </code></pre>
1039
+ </section>
1040
+
1041
+ <!-- Configuration -->
1042
+ <section class="mt-8" id="configuration">
1043
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" aria-hidden="true"><use href="#icon-gear"/></svg> Configuration</h2>
1044
+
1045
+ <pre><code class="language-javascript">
1046
+ import { VANI_CONFIG } from 'yakmesh/mesh/vani.js';
1047
+
1048
+ // Default configuration
1049
+ VANI_CONFIG.callTimeout // 30000ms - ring timeout
1050
+ VANI_CONFIG.iceGatheringTimeout// 10000ms - ICE gathering
1051
+ VANI_CONFIG.reconnectTimeout // 15000ms - reconnection window
1052
+ VANI_CONFIG.maxParticipants // 10 - max group size
1053
+
1054
+ // Default STUN servers
1055
+ VANI_CONFIG.iceServers // Google STUN servers
1056
+
1057
+ // Custom STUN/TURN servers
1058
+ const hub = new VaniHub({
1059
+ localPeerId: myId,
1060
+ iceServers: [
1061
+ { urls: 'stun:stun.example.com:3478' },
1062
+ {
1063
+ urls: 'turn:turn.example.com:3478',
1064
+ username: 'user',
1065
+ credential: 'pass'
1066
+ }
1067
+ ],
1068
+ onSignal: sendViaMesh
1069
+ });
1070
+
1071
+ // Media constraints
1072
+ VANI_CONFIG.defaultConstraints.audio.echoCancellation // true
1073
+ VANI_CONFIG.defaultConstraints.audio.noiseSuppression // true
1074
+ VANI_CONFIG.defaultConstraints.video.width.ideal // 1280
1075
+ VANI_CONFIG.defaultConstraints.video.height.ideal // 720
1076
+ VANI_CONFIG.defaultConstraints.video.frameRate.ideal // 30
1077
+ </code></pre>
1078
+ </section>
1079
+
1080
+ <!-- Error Handling -->
1081
+ <section class="mt-8" id="error-handling">
1082
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" aria-hidden="true"><use href="#icon-warning"/></svg> Error Handling</h2>
1083
+
1084
+ <pre><code class="language-javascript">
1085
+ hub.on('error', ({ callId, code, error }) => {
1086
+ switch (code) {
1087
+ case 'MEDIA_ACCESS_DENIED':
1088
+ // User denied camera/microphone access
1089
+ alert('Please allow camera and microphone access');
1090
+ break;
1091
+ case 'SDP_CREATE_FAILED':
1092
+ // WebRTC SDP creation failed
1093
+ console.error('Failed to create offer/answer:', error);
1094
+ break;
1095
+ case 'SDP_NEGOTIATION_FAILED':
1096
+ // SDP exchange failed
1097
+ console.error('Connection negotiation failed:', error);
1098
+ break;
1099
+ case 'SDP_ANSWER_FAILED':
1100
+ // Failed to set remote SDP answer
1101
+ console.error('Failed to process answer:', error);
1102
+ break;
1103
+ }
1104
+ });
1105
+
1106
+ // Call end reasons
1107
+ import { CALL_END_REASON } from 'yakmesh/mesh/vani.js';
1108
+
1109
+ CALL_END_REASON.NORMAL // Normal hangup
1110
+ CALL_END_REASON.REJECTED // Callee rejected
1111
+ CALL_END_REASON.BUSY // Callee in another call
1112
+ CALL_END_REASON.TIMEOUT // No answer (30s)
1113
+ CALL_END_REASON.FAILED // Connection failed
1114
+ CALL_END_REASON.NETWORK_ERROR // Network issue
1115
+ CALL_END_REASON.PARTICIPANT_LEFT // Group participant left
1116
+ </code></pre>
1117
+ </section>
1118
+
1119
+ <!-- NAT & Firewall -->
1120
+ <section class="callout theme-callout mt-8" id="nat-traversal">
1121
+ <h2><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-globe"/></svg> NAT Traversal</h2>
1122
+ <p>VANI uses ICE (Interactive Connectivity Establishment) for NAT traversal with three connection strategies:</p>
1123
+ <ul class="list-disc list-inside mt-2 space-y-1">
1124
+ <li><strong>Direct P2P</strong>: When both peers are on public IPs or same LAN</li>
1125
+ <li><strong>STUN</strong>: Discovers public IP and port mapping for NAT punch-through</li>
1126
+ <li><strong>Mesh Relay (preferred)</strong>: Fallback to Yakmesh mesh network for media relay — no external servers needed</li>
1127
+ <li><strong>TURN</strong>: Optional external relay for symmetric NAT (configure your own if needed)</li>
1128
+ </ul>
1129
+ <p class="mt-4 text-yellow-300"><svg class="doc-icon inline-icon" aria-hidden="true"><use href="#icon-warning"/></svg> <strong>Ethos Note:</strong> The default configuration uses empty ICE servers, relying on mesh relay instead of external STUN/TURN. For hybrid deployments, you may optionally configure your own STUN/TURN servers — but Yakmesh's mesh relay is the recommended, fully decentralized approach.</p>
1130
+ </section>
1131
+
1132
+ <!-- Integration Example -->
1133
+ <section class="mt-8" id="full-example">
1134
+ <h2 class="section-title theme-border"><svg class="doc-icon inline-icon" width="24" height="24" aria-hidden="true"><use href="#icon-scroll"/></svg> Complete Example</h2>
1135
+
1136
+ <pre><code class="language-javascript">
1137
+ import { VaniHub, MEDIA_TYPE, CALL_STATE, CALL_END_REASON } from 'yakmesh/mesh/vani.js';
1138
+
1139
+ class CallManager {
1140
+ constructor(meshNode) {
1141
+ this.meshNode = meshNode;
1142
+ this.hub = new VaniHub({
1143
+ localPeerId: meshNode.id,
1144
+ onSignal: (signal) => meshNode.send(signal.toPeer, signal)
1145
+ });
1146
+
1147
+ this.setupEventHandlers();
1148
+ this.setupMeshHandlers();
1149
+ }
1150
+
1151
+ setupEventHandlers() {
1152
+ // Incoming call notification
1153
+ this.hub.on('incomingCall', ({ call }) => {
1154
+ const caller = Array.from(call.participants.values())[0];
1155
+ this.showIncomingCallUI(call.id, caller.displayName);
1156
+ });
1157
+
1158
+ // State changes
1159
+ this.hub.on('stateChange', ({ callId, state }) => {
1160
+ this.updateCallUI(callId, state);
1161
+ });
1162
+
1163
+ // Remote video
1164
+ this.hub.on('remoteStream', ({ peerId, stream }) => {
1165
+ this.attachRemoteStream(peerId, stream);
1166
+ });
1167
+ }
1168
+
1169
+ setupMeshHandlers() {
1170
+ this.meshNode.on('message', (msg) => {
1171
+ if (msg.type?.startsWith('vani:')) {
1172
+ this.hub.handleSignal(msg);
1173
+ }
1174
+ });
1175
+ }
1176
+
1177
+ async startVideoCall(peerId) {
1178
+ const call = await this.hub.startCall({
1179
+ targetPeerIds: peerId,
1180
+ mediaType: [MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO]
1181
+ });
1182
+
1183
+ // Attach local preview
1184
+ const preview = document.getElementById('localVideo');
1185
+ preview.srcObject = call.localStream;
1186
+
1187
+ return call;
1188
+ }
1189
+
1190
+ async acceptCall(callId) {
1191
+ const call = await this.hub.acceptCall(callId);
1192
+ document.getElementById('localVideo').srcObject = call.localStream;
1193
+ }
1194
+
1195
+ rejectCall(callId) {
1196
+ this.hub.rejectCall(callId, CALL_END_REASON.REJECTED);
1197
+ }
1198
+
1199
+ hangUp() {
1200
+ const call = this.hub.getActiveCall();
1201
+ if (call) {
1202
+ this.hub.endCall(call.id);
1203
+ }
1204
+ }
1205
+
1206
+ toggleMute() {
1207
+ const call = this.hub.getActiveCall();
1208
+ if (call) {
1209
+ const audioTrack = call.localStream?.getAudioTracks()[0];
1210
+ if (audioTrack) {
1211
+ audioTrack.enabled = !audioTrack.enabled;
1212
+ call.setAudioEnabled(audioTrack.enabled);
1213
+ }
1214
+ }
1215
+ }
1216
+
1217
+ attachRemoteStream(peerId, stream) {
1218
+ let video = document.getElementById('remote-' + peerId);
1219
+ if (!video) {
1220
+ video = document.createElement('video');
1221
+ video.id = 'remote-' + peerId;
1222
+ video.autoplay = true;
1223
+ document.getElementById('remoteVideos').appendChild(video);
1224
+ }
1225
+ video.srcObject = stream;
1226
+ }
1227
+ }
1228
+
1229
+ // Usage
1230
+ const meshNode = await createMeshNode();
1231
+ const callManager = new CallManager(meshNode);
1232
+
1233
+ // Start a call
1234
+ document.getElementById('callBtn').onclick = () => {
1235
+ callManager.startVideoCall('peer-bob-123');
1236
+ };
1237
+ </code></pre>
1238
+ </section>
1239
+
1240
+ <!-- Journey Navigation -->
1241
+ <div class="border-t border-mountain-700 mt-12 pt-8">
1242
+ <h2 class="text-xl font-bold mb-6">Continue the Journey</h2>
1243
+ <div class="flex flex-col sm:flex-row gap-4">
1244
+ <a href="katha.html" class="flex-1 block bg-mountain-800 border border-mountain-700 rounded-xl p-4 hover:border-theme-accent transition group">
1245
+ <div class="text-xs text-mountain-400 mb-1">← Previous</div>
1246
+ <div class="flex items-center gap-2">
1247
+ <svg class="doc-icon journey-icon" aria-hidden="true"><use href="#icon-katha"/></svg>
1248
+ <span class="font-semibold group-hover:text-theme-accent">KATHA</span>
1249
+ </div>
1250
+ <p class="text-mountain-400 text-sm mt-1">Rich chat features</p>
1251
+ </a>
1252
+ <a href="darshan.html" class="flex-1 block bg-mountain-800 border border-theme-primary rounded-xl p-4 hover:border-theme-accent transition group">
1253
+ <div class="text-xs text-mountain-400 mb-1">Next →</div>
1254
+ <div class="flex items-center gap-2">
1255
+ <svg class="doc-icon journey-icon" aria-hidden="true"><use href="#icon-darshan"/></svg>
1256
+ <span class="font-semibold group-hover:text-theme-accent">DARSHAN</span>
1257
+ </div>
1258
+ <p class="text-mountain-400 text-sm mt-1">Content streaming</p>
1259
+ </a>
1260
+ </div>
1261
+ </div>
1262
+ </main>
1263
+
1264
+ <footer class="docs-footer"><p>© 2026 YAKMESH™</p></footer>
1265
+
1266
+ <script src="prism.min.js" defer></script>
1267
+ <script src="prism-javascript.min.js" defer></script>
1268
+ <script src="docs.js" defer></script>
1269
+ </body>
1270
+ </html>