@weaveprotocol/core 0.1.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 (430) hide show
  1. package/README.md +1106 -0
  2. package/dist/elements/auth-styles.d.ts +18 -0
  3. package/dist/elements/auth-styles.d.ts.map +1 -0
  4. package/dist/elements/auth-styles.js +150 -0
  5. package/dist/elements/auth-styles.js.map +1 -0
  6. package/dist/elements/dom.d.ts +28 -0
  7. package/dist/elements/dom.d.ts.map +1 -0
  8. package/dist/elements/dom.js +74 -0
  9. package/dist/elements/dom.js.map +1 -0
  10. package/dist/elements/index.d.ts +13 -0
  11. package/dist/elements/index.d.ts.map +1 -0
  12. package/dist/elements/index.js +11 -0
  13. package/dist/elements/index.js.map +1 -0
  14. package/dist/elements/weave-auth.d.ts +52 -0
  15. package/dist/elements/weave-auth.d.ts.map +1 -0
  16. package/dist/elements/weave-auth.js +427 -0
  17. package/dist/elements/weave-auth.js.map +1 -0
  18. package/dist/identity/account-store.d.ts +113 -0
  19. package/dist/identity/account-store.d.ts.map +1 -0
  20. package/dist/identity/account-store.js +305 -0
  21. package/dist/identity/account-store.js.map +1 -0
  22. package/dist/identity/account-vault.d.ts +199 -0
  23. package/dist/identity/account-vault.d.ts.map +1 -0
  24. package/dist/identity/account-vault.js +251 -0
  25. package/dist/identity/account-vault.js.map +1 -0
  26. package/dist/identity/agent-note.d.ts +19 -0
  27. package/dist/identity/agent-note.d.ts.map +1 -0
  28. package/dist/identity/agent-note.js +29 -0
  29. package/dist/identity/agent-note.js.map +1 -0
  30. package/dist/identity/crypto-p256.d.ts +7 -0
  31. package/dist/identity/crypto-p256.d.ts.map +1 -0
  32. package/dist/identity/crypto-p256.js +84 -0
  33. package/dist/identity/crypto-p256.js.map +1 -0
  34. package/dist/identity/device-key.d.ts +60 -0
  35. package/dist/identity/device-key.d.ts.map +1 -0
  36. package/dist/identity/device-key.js +103 -0
  37. package/dist/identity/device-key.js.map +1 -0
  38. package/dist/identity/did.d.ts +22 -0
  39. package/dist/identity/did.d.ts.map +1 -0
  40. package/dist/identity/did.js +37 -0
  41. package/dist/identity/did.js.map +1 -0
  42. package/dist/identity/folder-account.d.ts +65 -0
  43. package/dist/identity/folder-account.d.ts.map +1 -0
  44. package/dist/identity/folder-account.js +115 -0
  45. package/dist/identity/folder-account.js.map +1 -0
  46. package/dist/identity/identity-manager.d.ts +36 -0
  47. package/dist/identity/identity-manager.d.ts.map +1 -0
  48. package/dist/identity/identity-manager.js +115 -0
  49. package/dist/identity/identity-manager.js.map +1 -0
  50. package/dist/identity/index.d.ts +10 -0
  51. package/dist/identity/index.d.ts.map +1 -0
  52. package/dist/identity/index.js +10 -0
  53. package/dist/identity/index.js.map +1 -0
  54. package/dist/identity/keys.d.ts +24 -0
  55. package/dist/identity/keys.d.ts.map +1 -0
  56. package/dist/identity/keys.js +38 -0
  57. package/dist/identity/keys.js.map +1 -0
  58. package/dist/identity/pairing.d.ts +83 -0
  59. package/dist/identity/pairing.d.ts.map +1 -0
  60. package/dist/identity/pairing.js +120 -0
  61. package/dist/identity/pairing.js.map +1 -0
  62. package/dist/identity/passkey-diagnostics.d.ts +54 -0
  63. package/dist/identity/passkey-diagnostics.d.ts.map +1 -0
  64. package/dist/identity/passkey-diagnostics.js +178 -0
  65. package/dist/identity/passkey-diagnostics.js.map +1 -0
  66. package/dist/identity/recovery-code.d.ts +50 -0
  67. package/dist/identity/recovery-code.d.ts.map +1 -0
  68. package/dist/identity/recovery-code.js +116 -0
  69. package/dist/identity/recovery-code.js.map +1 -0
  70. package/dist/identity/root-signer.d.ts +59 -0
  71. package/dist/identity/root-signer.d.ts.map +1 -0
  72. package/dist/identity/root-signer.js +44 -0
  73. package/dist/identity/root-signer.js.map +1 -0
  74. package/dist/identity/ucan.d.ts +164 -0
  75. package/dist/identity/ucan.d.ts.map +1 -0
  76. package/dist/identity/ucan.js +273 -0
  77. package/dist/identity/ucan.js.map +1 -0
  78. package/dist/identity/webauthn.d.ts +87 -0
  79. package/dist/identity/webauthn.d.ts.map +1 -0
  80. package/dist/identity/webauthn.js +155 -0
  81. package/dist/identity/webauthn.js.map +1 -0
  82. package/dist/index.d.ts +116 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +85 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/network/index.d.ts +17 -0
  87. package/dist/network/index.d.ts.map +1 -0
  88. package/dist/network/index.js +10 -0
  89. package/dist/network/index.js.map +1 -0
  90. package/dist/network/introductions.d.ts +85 -0
  91. package/dist/network/introductions.d.ts.map +1 -0
  92. package/dist/network/introductions.js +94 -0
  93. package/dist/network/introductions.js.map +1 -0
  94. package/dist/network/local-transport.d.ts +22 -0
  95. package/dist/network/local-transport.d.ts.map +1 -0
  96. package/dist/network/local-transport.js +55 -0
  97. package/dist/network/local-transport.js.map +1 -0
  98. package/dist/network/mesh.d.ts +31 -0
  99. package/dist/network/mesh.d.ts.map +1 -0
  100. package/dist/network/mesh.js +332 -0
  101. package/dist/network/mesh.js.map +1 -0
  102. package/dist/network/multi-signaling.d.ts +29 -0
  103. package/dist/network/multi-signaling.d.ts.map +1 -0
  104. package/dist/network/multi-signaling.js +125 -0
  105. package/dist/network/multi-signaling.js.map +1 -0
  106. package/dist/network/network-manager.d.ts +37 -0
  107. package/dist/network/network-manager.d.ts.map +1 -0
  108. package/dist/network/network-manager.js +64 -0
  109. package/dist/network/network-manager.js.map +1 -0
  110. package/dist/network/peer-auth.d.ts +98 -0
  111. package/dist/network/peer-auth.d.ts.map +1 -0
  112. package/dist/network/peer-auth.js +86 -0
  113. package/dist/network/peer-auth.js.map +1 -0
  114. package/dist/network/rtc-transport.d.ts +18 -0
  115. package/dist/network/rtc-transport.d.ts.map +1 -0
  116. package/dist/network/rtc-transport.js +149 -0
  117. package/dist/network/rtc-transport.js.map +1 -0
  118. package/dist/network/signaling.d.ts +40 -0
  119. package/dist/network/signaling.d.ts.map +1 -0
  120. package/dist/network/signaling.js +124 -0
  121. package/dist/network/signaling.js.map +1 -0
  122. package/dist/network/transport.d.ts +50 -0
  123. package/dist/network/transport.d.ts.map +1 -0
  124. package/dist/network/transport.js +13 -0
  125. package/dist/network/transport.js.map +1 -0
  126. package/dist/network/ws-transport.d.ts +42 -0
  127. package/dist/network/ws-transport.d.ts.map +1 -0
  128. package/dist/network/ws-transport.js +194 -0
  129. package/dist/network/ws-transport.js.map +1 -0
  130. package/dist/node/actions.d.ts +62 -0
  131. package/dist/node/actions.d.ts.map +1 -0
  132. package/dist/node/actions.js +500 -0
  133. package/dist/node/actions.js.map +1 -0
  134. package/dist/node/carrier.d.ts +85 -0
  135. package/dist/node/carrier.d.ts.map +1 -0
  136. package/dist/node/carrier.js +192 -0
  137. package/dist/node/carrier.js.map +1 -0
  138. package/dist/node/copy.d.ts +38 -0
  139. package/dist/node/copy.d.ts.map +1 -0
  140. package/dist/node/copy.js +53 -0
  141. package/dist/node/copy.js.map +1 -0
  142. package/dist/node/index.d.ts +16 -0
  143. package/dist/node/index.d.ts.map +1 -0
  144. package/dist/node/index.js +11 -0
  145. package/dist/node/index.js.map +1 -0
  146. package/dist/node/node.d.ts +12 -0
  147. package/dist/node/node.d.ts.map +1 -0
  148. package/dist/node/node.js +872 -0
  149. package/dist/node/node.js.map +1 -0
  150. package/dist/node/space-runtime.d.ts +144 -0
  151. package/dist/node/space-runtime.d.ts.map +1 -0
  152. package/dist/node/space-runtime.js +1221 -0
  153. package/dist/node/space-runtime.js.map +1 -0
  154. package/dist/node/stores.d.ts +45 -0
  155. package/dist/node/stores.d.ts.map +1 -0
  156. package/dist/node/stores.js +31 -0
  157. package/dist/node/stores.js.map +1 -0
  158. package/dist/node/types.d.ts +508 -0
  159. package/dist/node/types.d.ts.map +1 -0
  160. package/dist/node/types.js +2 -0
  161. package/dist/node/types.js.map +1 -0
  162. package/dist/privacy/index.d.ts +4 -0
  163. package/dist/privacy/index.d.ts.map +1 -0
  164. package/dist/privacy/index.js +4 -0
  165. package/dist/privacy/index.js.map +1 -0
  166. package/dist/privacy/key-distribution.d.ts +42 -0
  167. package/dist/privacy/key-distribution.d.ts.map +1 -0
  168. package/dist/privacy/key-distribution.js +50 -0
  169. package/dist/privacy/key-distribution.js.map +1 -0
  170. package/dist/privacy/privacy-guard.d.ts +24 -0
  171. package/dist/privacy/privacy-guard.d.ts.map +1 -0
  172. package/dist/privacy/privacy-guard.js +87 -0
  173. package/dist/privacy/privacy-guard.js.map +1 -0
  174. package/dist/privacy/space-encryption.d.ts +48 -0
  175. package/dist/privacy/space-encryption.d.ts.map +1 -0
  176. package/dist/privacy/space-encryption.js +61 -0
  177. package/dist/privacy/space-encryption.js.map +1 -0
  178. package/dist/query/engine.d.ts +27 -0
  179. package/dist/query/engine.d.ts.map +1 -0
  180. package/dist/query/engine.js +84 -0
  181. package/dist/query/engine.js.map +1 -0
  182. package/dist/query/filter.d.ts +15 -0
  183. package/dist/query/filter.d.ts.map +1 -0
  184. package/dist/query/filter.js +207 -0
  185. package/dist/query/filter.js.map +1 -0
  186. package/dist/query/types.d.ts +144 -0
  187. package/dist/query/types.d.ts.map +1 -0
  188. package/dist/query/types.js +22 -0
  189. package/dist/query/types.js.map +1 -0
  190. package/dist/react/context.d.ts +81 -0
  191. package/dist/react/context.d.ts.map +1 -0
  192. package/dist/react/context.js +95 -0
  193. package/dist/react/context.js.map +1 -0
  194. package/dist/react/index.d.ts +40 -0
  195. package/dist/react/index.d.ts.map +1 -0
  196. package/dist/react/index.js +36 -0
  197. package/dist/react/index.js.map +1 -0
  198. package/dist/react/use-live.d.ts +16 -0
  199. package/dist/react/use-live.d.ts.map +1 -0
  200. package/dist/react/use-live.js +55 -0
  201. package/dist/react/use-live.js.map +1 -0
  202. package/dist/react/use-query.d.ts +17 -0
  203. package/dist/react/use-query.d.ts.map +1 -0
  204. package/dist/react/use-query.js +23 -0
  205. package/dist/react/use-query.js.map +1 -0
  206. package/dist/react/use-space.d.ts +29 -0
  207. package/dist/react/use-space.d.ts.map +1 -0
  208. package/dist/react/use-space.js +48 -0
  209. package/dist/react/use-space.js.map +1 -0
  210. package/dist/react/use-spaces.d.ts +19 -0
  211. package/dist/react/use-spaces.d.ts.map +1 -0
  212. package/dist/react/use-spaces.js +55 -0
  213. package/dist/react/use-spaces.js.map +1 -0
  214. package/dist/react/use-weave-auth.d.ts +10 -0
  215. package/dist/react/use-weave-auth.d.ts.map +1 -0
  216. package/dist/react/use-weave-auth.js +15 -0
  217. package/dist/react/use-weave-auth.js.map +1 -0
  218. package/dist/react/weave-auth.d.ts +17 -0
  219. package/dist/react/weave-auth.d.ts.map +1 -0
  220. package/dist/react/weave-auth.js +38 -0
  221. package/dist/react/weave-auth.js.map +1 -0
  222. package/dist/records/describe.d.ts +38 -0
  223. package/dist/records/describe.d.ts.map +1 -0
  224. package/dist/records/describe.js +101 -0
  225. package/dist/records/describe.js.map +1 -0
  226. package/dist/records/links.d.ts +14 -0
  227. package/dist/records/links.d.ts.map +1 -0
  228. package/dist/records/links.js +25 -0
  229. package/dist/records/links.js.map +1 -0
  230. package/dist/records/rules.d.ts +59 -0
  231. package/dist/records/rules.d.ts.map +1 -0
  232. package/dist/records/rules.js +118 -0
  233. package/dist/records/rules.js.map +1 -0
  234. package/dist/records/version.d.ts +54 -0
  235. package/dist/records/version.d.ts.map +1 -0
  236. package/dist/records/version.js +70 -0
  237. package/dist/records/version.js.map +1 -0
  238. package/dist/schema/collection-def.d.ts +96 -0
  239. package/dist/schema/collection-def.d.ts.map +1 -0
  240. package/dist/schema/collection-def.js +272 -0
  241. package/dist/schema/collection-def.js.map +1 -0
  242. package/dist/schema/expression.d.ts +69 -0
  243. package/dist/schema/expression.d.ts.map +1 -0
  244. package/dist/schema/expression.js +92 -0
  245. package/dist/schema/expression.js.map +1 -0
  246. package/dist/schema/index.d.ts +4 -0
  247. package/dist/schema/index.d.ts.map +1 -0
  248. package/dist/schema/index.js +4 -0
  249. package/dist/schema/index.js.map +1 -0
  250. package/dist/schema/schema-engine.d.ts +42 -0
  251. package/dist/schema/schema-engine.d.ts.map +1 -0
  252. package/dist/schema/schema-engine.js +36 -0
  253. package/dist/schema/schema-engine.js.map +1 -0
  254. package/dist/schema/signer.d.ts +27 -0
  255. package/dist/schema/signer.d.ts.map +1 -0
  256. package/dist/schema/signer.js +36 -0
  257. package/dist/schema/signer.js.map +1 -0
  258. package/dist/schemas/apps.d.ts +88 -0
  259. package/dist/schemas/apps.d.ts.map +1 -0
  260. package/dist/schemas/apps.js +168 -0
  261. package/dist/schemas/apps.js.map +1 -0
  262. package/dist/schemas/index.d.ts +410 -0
  263. package/dist/schemas/index.d.ts.map +1 -0
  264. package/dist/schemas/index.js +208 -0
  265. package/dist/schemas/index.js.map +1 -0
  266. package/dist/schemas/screens.d.ts +67 -0
  267. package/dist/schemas/screens.d.ts.map +1 -0
  268. package/dist/schemas/screens.js +242 -0
  269. package/dist/schemas/screens.js.map +1 -0
  270. package/dist/session/agent-link.d.ts +79 -0
  271. package/dist/session/agent-link.d.ts.map +1 -0
  272. package/dist/session/agent-link.js +251 -0
  273. package/dist/session/agent-link.js.map +1 -0
  274. package/dist/session/auth.d.ts +233 -0
  275. package/dist/session/auth.d.ts.map +1 -0
  276. package/dist/session/auth.js +783 -0
  277. package/dist/session/auth.js.map +1 -0
  278. package/dist/session/connect.d.ts +211 -0
  279. package/dist/session/connect.d.ts.map +1 -0
  280. package/dist/session/connect.js +355 -0
  281. package/dist/session/connect.js.map +1 -0
  282. package/dist/session/connection.d.ts +70 -0
  283. package/dist/session/connection.d.ts.map +1 -0
  284. package/dist/session/connection.js +120 -0
  285. package/dist/session/connection.js.map +1 -0
  286. package/dist/session/credentials.d.ts +44 -0
  287. package/dist/session/credentials.d.ts.map +1 -0
  288. package/dist/session/credentials.js +60 -0
  289. package/dist/session/credentials.js.map +1 -0
  290. package/dist/session/index.d.ts +25 -0
  291. package/dist/session/index.d.ts.map +1 -0
  292. package/dist/session/index.js +18 -0
  293. package/dist/session/index.js.map +1 -0
  294. package/dist/session/pairing.d.ts +59 -0
  295. package/dist/session/pairing.d.ts.map +1 -0
  296. package/dist/session/pairing.js +144 -0
  297. package/dist/session/pairing.js.map +1 -0
  298. package/dist/session/places.d.ts +62 -0
  299. package/dist/session/places.d.ts.map +1 -0
  300. package/dist/session/places.js +101 -0
  301. package/dist/session/places.js.map +1 -0
  302. package/dist/session/stay-signed-in.d.ts +37 -0
  303. package/dist/session/stay-signed-in.d.ts.map +1 -0
  304. package/dist/session/stay-signed-in.js +124 -0
  305. package/dist/session/stay-signed-in.js.map +1 -0
  306. package/dist/space/account-registry.d.ts +64 -0
  307. package/dist/space/account-registry.d.ts.map +1 -0
  308. package/dist/space/account-registry.js +66 -0
  309. package/dist/space/account-registry.js.map +1 -0
  310. package/dist/space/index.d.ts +3 -0
  311. package/dist/space/index.d.ts.map +1 -0
  312. package/dist/space/index.js +3 -0
  313. package/dist/space/index.js.map +1 -0
  314. package/dist/space/pass.d.ts +63 -0
  315. package/dist/space/pass.d.ts.map +1 -0
  316. package/dist/space/pass.js +54 -0
  317. package/dist/space/pass.js.map +1 -0
  318. package/dist/space/presets.d.ts +31 -0
  319. package/dist/space/presets.d.ts.map +1 -0
  320. package/dist/space/presets.js +24 -0
  321. package/dist/space/presets.js.map +1 -0
  322. package/dist/space/roles.d.ts +186 -0
  323. package/dist/space/roles.d.ts.map +1 -0
  324. package/dist/space/roles.js +500 -0
  325. package/dist/space/roles.js.map +1 -0
  326. package/dist/space/space-access.d.ts +80 -0
  327. package/dist/space/space-access.d.ts.map +1 -0
  328. package/dist/space/space-access.js +135 -0
  329. package/dist/space/space-access.js.map +1 -0
  330. package/dist/space/space-manager.d.ts +87 -0
  331. package/dist/space/space-manager.d.ts.map +1 -0
  332. package/dist/space/space-manager.js +187 -0
  333. package/dist/space/space-manager.js.map +1 -0
  334. package/dist/storage/directory-access.d.ts +78 -0
  335. package/dist/storage/directory-access.d.ts.map +1 -0
  336. package/dist/storage/directory-access.js +164 -0
  337. package/dist/storage/directory-access.js.map +1 -0
  338. package/dist/storage/encrypted-adapter.d.ts +49 -0
  339. package/dist/storage/encrypted-adapter.d.ts.map +1 -0
  340. package/dist/storage/encrypted-adapter.js +106 -0
  341. package/dist/storage/encrypted-adapter.js.map +1 -0
  342. package/dist/storage/folder-adapter.d.ts +105 -0
  343. package/dist/storage/folder-adapter.d.ts.map +1 -0
  344. package/dist/storage/folder-adapter.js +280 -0
  345. package/dist/storage/folder-adapter.js.map +1 -0
  346. package/dist/storage/folder-reconcile.d.ts +53 -0
  347. package/dist/storage/folder-reconcile.d.ts.map +1 -0
  348. package/dist/storage/folder-reconcile.js +65 -0
  349. package/dist/storage/folder-reconcile.js.map +1 -0
  350. package/dist/storage/index.d.ts +10 -0
  351. package/dist/storage/index.d.ts.map +1 -0
  352. package/dist/storage/index.js +9 -0
  353. package/dist/storage/index.js.map +1 -0
  354. package/dist/storage/indexeddb-adapter.d.ts +12 -0
  355. package/dist/storage/indexeddb-adapter.d.ts.map +1 -0
  356. package/dist/storage/indexeddb-adapter.js +190 -0
  357. package/dist/storage/indexeddb-adapter.js.map +1 -0
  358. package/dist/storage/mst.d.ts +121 -0
  359. package/dist/storage/mst.d.ts.map +1 -0
  360. package/dist/storage/mst.js +402 -0
  361. package/dist/storage/mst.js.map +1 -0
  362. package/dist/storage/storage-provider.d.ts +85 -0
  363. package/dist/storage/storage-provider.d.ts.map +1 -0
  364. package/dist/storage/storage-provider.js +220 -0
  365. package/dist/storage/storage-provider.js.map +1 -0
  366. package/dist/sync/anti-entropy.d.ts +49 -0
  367. package/dist/sync/anti-entropy.d.ts.map +1 -0
  368. package/dist/sync/anti-entropy.js +62 -0
  369. package/dist/sync/anti-entropy.js.map +1 -0
  370. package/dist/sync/index.d.ts +4 -0
  371. package/dist/sync/index.d.ts.map +1 -0
  372. package/dist/sync/index.js +4 -0
  373. package/dist/sync/index.js.map +1 -0
  374. package/dist/sync/sync-engine.d.ts +71 -0
  375. package/dist/sync/sync-engine.d.ts.map +1 -0
  376. package/dist/sync/sync-engine.js +309 -0
  377. package/dist/sync/sync-engine.js.map +1 -0
  378. package/dist/sync/sync-messages.d.ts +75 -0
  379. package/dist/sync/sync-messages.d.ts.map +1 -0
  380. package/dist/sync/sync-messages.js +12 -0
  381. package/dist/sync/sync-messages.js.map +1 -0
  382. package/dist/types.d.ts +243 -0
  383. package/dist/types.d.ts.map +1 -0
  384. package/dist/types.js +7 -0
  385. package/dist/types.js.map +1 -0
  386. package/dist/utils/encoding.d.ts +63 -0
  387. package/dist/utils/encoding.d.ts.map +1 -0
  388. package/dist/utils/encoding.js +130 -0
  389. package/dist/utils/encoding.js.map +1 -0
  390. package/dist/utils/errors.d.ts +43 -0
  391. package/dist/utils/errors.d.ts.map +1 -0
  392. package/dist/utils/errors.js +28 -0
  393. package/dist/utils/errors.js.map +1 -0
  394. package/dist/utils/events.d.ts +19 -0
  395. package/dist/utils/events.d.ts.map +1 -0
  396. package/dist/utils/events.js +27 -0
  397. package/dist/utils/events.js.map +1 -0
  398. package/dist/utils/hash.d.ts +23 -0
  399. package/dist/utils/hash.d.ts.map +1 -0
  400. package/dist/utils/hash.js +49 -0
  401. package/dist/utils/hash.js.map +1 -0
  402. package/dist/utils/index.d.ts +9 -0
  403. package/dist/utils/index.d.ts.map +1 -0
  404. package/dist/utils/index.js +9 -0
  405. package/dist/utils/index.js.map +1 -0
  406. package/dist/validation/capability-gate.d.ts +50 -0
  407. package/dist/validation/capability-gate.d.ts.map +1 -0
  408. package/dist/validation/capability-gate.js +71 -0
  409. package/dist/validation/capability-gate.js.map +1 -0
  410. package/dist/validation/crypto-gate.d.ts +16 -0
  411. package/dist/validation/crypto-gate.d.ts.map +1 -0
  412. package/dist/validation/crypto-gate.js +37 -0
  413. package/dist/validation/crypto-gate.js.map +1 -0
  414. package/dist/validation/index.d.ts +6 -0
  415. package/dist/validation/index.d.ts.map +1 -0
  416. package/dist/validation/index.js +6 -0
  417. package/dist/validation/index.js.map +1 -0
  418. package/dist/validation/stateful-gate.d.ts +15 -0
  419. package/dist/validation/stateful-gate.d.ts.map +1 -0
  420. package/dist/validation/stateful-gate.js +50 -0
  421. package/dist/validation/stateful-gate.js.map +1 -0
  422. package/dist/validation/structural-gate.d.ts +18 -0
  423. package/dist/validation/structural-gate.d.ts.map +1 -0
  424. package/dist/validation/structural-gate.js +54 -0
  425. package/dist/validation/structural-gate.js.map +1 -0
  426. package/dist/validation/validation-engine.d.ts +28 -0
  427. package/dist/validation/validation-engine.d.ts.map +1 -0
  428. package/dist/validation/validation-engine.js +38 -0
  429. package/dist/validation/validation-engine.js.map +1 -0
  430. package/package.json +107 -0
@@ -0,0 +1,305 @@
1
+ /**
2
+ * @module account-store
3
+ * The accounts that live somewhere — in a folder, or in this browser.
4
+ *
5
+ * A folder is a disk, not a person. Several people can keep accounts in one, and
6
+ * one person can keep several: work and personal, or a spare for testing. So the
7
+ * folder holds a list of who has an account in it, and a subtree per account.
8
+ *
9
+ * ```
10
+ * <folder>/
11
+ * accounts.json name, DID and id of each account
12
+ * accounts/<id>/account.json that account's keys, locked
13
+ * accounts/<id>/stores/... that account's spaces
14
+ * ```
15
+ *
16
+ * **The list is readable without unlocking anything**, which it has to be — you
17
+ * cannot offer someone a choice of accounts without knowing their names. So
18
+ * whoever holds the folder can see how many accounts are in it and what they
19
+ * are called. What they cannot do is open one.
20
+ *
21
+ * A browser with no folder keeps the same shape in IndexedDB, so the app above
22
+ * has one model rather than two.
23
+ */
24
+ import { readFolderFile, writeFolderFile } from '../storage/folder-adapter.js';
25
+ import { readFolderVault } from './folder-account.js';
26
+ import { base64UrlEncode, utf8Encode, utf8Decode } from '../utils/encoding.js';
27
+ import { protocolError } from '../utils/errors.js';
28
+ const LIST_FILE = 'accounts.json';
29
+ const ACCOUNTS_DIR = 'accounts';
30
+ const VAULT_FILE = 'account.json';
31
+ /** Where a single-account folder kept its spaces, before there was a list. */
32
+ const LEGACY_DATA_PATH = 'stores';
33
+ /** Where a brand new account keeps its spaces. */
34
+ export function accountDataPath(id) {
35
+ return `${ACCOUNTS_DIR}/${id}/stores`;
36
+ }
37
+ /** A short, stable, filename-safe id for a new account. */
38
+ export function newAccountId() {
39
+ return base64UrlEncode(globalThis.crypto.getRandomValues(new Uint8Array(8)))
40
+ .replace(/[^a-z0-9]/gi, '')
41
+ .toLowerCase()
42
+ .slice(0, 12);
43
+ }
44
+ /**
45
+ * Whether an id has the shape {@link newAccountId} gives one.
46
+ *
47
+ * An id names a directory, and `remove` deletes that directory with everything
48
+ * in it. The list it comes from is a plain file in a folder that may be synced
49
+ * or shared, so an id is checked before it is trusted with a path.
50
+ */
51
+ export function isAccountId(id) {
52
+ return typeof id === 'string' && /^[a-z0-9]{1,12}$/.test(id);
53
+ }
54
+ /**
55
+ * Whether a row points somewhere this store could have put it.
56
+ *
57
+ * `dataPath` is carried, not computed, but there are only two shapes it can
58
+ * honestly have: an account subtree, or the folder's root store from before
59
+ * there was a list. Usually the subtree is the row's own — though a row filed
60
+ * again under a fresh id keeps the one its data already lives in. Anything
61
+ * else, `../../elsewhere` above all, is someone editing the list to aim an
62
+ * account at files outside the folder.
63
+ */
64
+ function isTrustworthy(account) {
65
+ if (!isAccountId(account?.id) || typeof account.dataPath !== 'string')
66
+ return false;
67
+ if (account.dataPath === LEGACY_DATA_PATH)
68
+ return true;
69
+ const [accounts, id, stores, ...more] = account.dataPath.split('/');
70
+ return accounts === ACCOUNTS_DIR && isAccountId(id) && stores === 'stores' && more.length === 0;
71
+ }
72
+ function checkId(id) {
73
+ if (!isAccountId(id))
74
+ throw new TypeError(`Not an account id: ${JSON.stringify(id)}`);
75
+ }
76
+ /** Most recently used first, so the picker opens on the likely one. */
77
+ function byRecency(a, b) {
78
+ return (b.lastUsedAt ?? b.createdAt).localeCompare(a.lastUsedAt ?? a.createdAt);
79
+ }
80
+ /**
81
+ * Most recently used first, one row per identity.
82
+ *
83
+ * A summary is a label on an identity, so two of them for one DID means the
84
+ * same person listed twice — which is confusing at best and, once they point
85
+ * at different data paths, a way to lose track of where anything is.
86
+ *
87
+ * @param accounts Whatever the store had
88
+ * @returns The list to show
89
+ */
90
+ function collapse(accounts) {
91
+ const seen = new Set();
92
+ return [...accounts].sort(byRecency).filter((account) => {
93
+ if (seen.has(account.did))
94
+ return false;
95
+ seen.add(account.did);
96
+ return true;
97
+ });
98
+ }
99
+ function parseList(bytes) {
100
+ if (!bytes)
101
+ return [];
102
+ try {
103
+ const parsed = JSON.parse(utf8Decode(bytes));
104
+ // A row that fails the check is skipped, not repaired: it was not written
105
+ // by this store, so there is no telling what it was meant to be.
106
+ return Array.isArray(parsed?.accounts) ? parsed.accounts.filter(isTrustworthy) : [];
107
+ }
108
+ catch {
109
+ throw protocolError('FOLDER_ACCOUNT_UNREADABLE', `${LIST_FILE} in that folder is not valid JSON.`, 'Move it aside and sign in with your code to write a fresh one — no account ' +
110
+ 'data is lost, only the list of which accounts exist.');
111
+ }
112
+ }
113
+ /**
114
+ * Opens the accounts kept in a folder.
115
+ *
116
+ * @param dir The data folder
117
+ * @returns A store over it
118
+ */
119
+ export function createFolderAccountStore(dir) {
120
+ async function readList() {
121
+ return parseList(await readFolderFile(dir, LIST_FILE));
122
+ }
123
+ async function writeList(accounts) {
124
+ await writeFolderFile(dir, LIST_FILE, utf8Encode(`${JSON.stringify({ version: 1, accounts }, null, 2)}\n`));
125
+ }
126
+ /** The directory holding one account's keys. */
127
+ async function accountDir(id, create) {
128
+ try {
129
+ const accounts = await dir.getDirectoryHandle(ACCOUNTS_DIR, { create });
130
+ return await accounts.getDirectoryHandle(id, { create });
131
+ }
132
+ catch (error) {
133
+ if (error instanceof Error && error.name === 'NotFoundError')
134
+ return null;
135
+ throw error;
136
+ }
137
+ }
138
+ return Object.freeze({
139
+ kind: 'folder',
140
+ async list() {
141
+ return collapse(await readList());
142
+ },
143
+ async read(id) {
144
+ if (!isAccountId(id))
145
+ return null;
146
+ const home = await accountDir(id, false);
147
+ if (!home)
148
+ return null;
149
+ const bytes = await readFolderFile(home, VAULT_FILE);
150
+ if (!bytes)
151
+ return null;
152
+ try {
153
+ return JSON.parse(utf8Decode(bytes));
154
+ }
155
+ catch {
156
+ throw protocolError('FOLDER_ACCOUNT_UNREADABLE', `The keys for that account could not be read.`, 'The file may have been edited by hand. Sign in with your code to write a new one.');
157
+ }
158
+ },
159
+ async write(summary, vault) {
160
+ if (!isTrustworthy(summary)) {
161
+ throw new TypeError(`Account ${JSON.stringify(summary.id)} does not have a valid id and data path`);
162
+ }
163
+ const home = await accountDir(summary.id, true);
164
+ if (!home)
165
+ throw new Error(`Could not open a home for account ${summary.id}`);
166
+ await writeFolderFile(home, VAULT_FILE, utf8Encode(`${JSON.stringify(vault, null, 2)}\n`));
167
+ // Drops any row for the same identity as well as the same id: the caller
168
+ // has just said which account this is.
169
+ const accounts = (await readList()).filter((account) => account.id !== summary.id && account.did !== summary.did);
170
+ await writeList([...accounts, summary]);
171
+ },
172
+ async remove(id) {
173
+ checkId(id);
174
+ await writeList((await readList()).filter((account) => account.id !== id));
175
+ try {
176
+ const accounts = await dir.getDirectoryHandle(ACCOUNTS_DIR);
177
+ await accounts.removeEntry(id, { recursive: true });
178
+ }
179
+ catch (error) {
180
+ // Already gone, or the browser will not recurse. The list no longer
181
+ // mentions it either way.
182
+ if (!(error instanceof Error) || error.name !== 'NotFoundError')
183
+ throw error;
184
+ }
185
+ },
186
+ });
187
+ }
188
+ // ─── Accounts kept in this browser ─────────────────────────────────────
189
+ const DB_NAME = 'weave-accounts';
190
+ const STORE = 'accounts';
191
+ const LIST_KEY = '__list';
192
+ function openDb(dbName) {
193
+ return new Promise((resolve, reject) => {
194
+ const request = globalThis.indexedDB.open(dbName, 1);
195
+ request.onupgradeneeded = () => {
196
+ if (!request.result.objectStoreNames.contains(STORE)) {
197
+ request.result.createObjectStore(STORE);
198
+ }
199
+ };
200
+ request.onsuccess = () => resolve(request.result);
201
+ request.onerror = () => reject(request.error);
202
+ });
203
+ }
204
+ function idbGet(db, key) {
205
+ return new Promise((resolve, reject) => {
206
+ const request = db.transaction(STORE, 'readonly').objectStore(STORE).get(key);
207
+ request.onsuccess = () => resolve(request.result ?? null);
208
+ request.onerror = () => reject(request.error);
209
+ });
210
+ }
211
+ function idbPut(db, key, value) {
212
+ return new Promise((resolve, reject) => {
213
+ const tx = db.transaction(STORE, 'readwrite');
214
+ tx.objectStore(STORE).put(value, key);
215
+ tx.oncomplete = () => resolve();
216
+ tx.onerror = () => reject(tx.error);
217
+ });
218
+ }
219
+ function idbDelete(db, key) {
220
+ return new Promise((resolve, reject) => {
221
+ const tx = db.transaction(STORE, 'readwrite');
222
+ tx.objectStore(STORE).delete(key);
223
+ tx.oncomplete = () => resolve();
224
+ tx.onerror = () => reject(tx.error);
225
+ });
226
+ }
227
+ /**
228
+ * Opens the accounts kept in this browser, for when there is no folder.
229
+ *
230
+ * Same shape as a folder store, so nothing above has to know which it got —
231
+ * the difference is only that no other origin can read this one.
232
+ *
233
+ * @param dbName Overridable for tests
234
+ * @returns A store over this origin's database
235
+ */
236
+ export async function createBrowserAccountStore(dbName = DB_NAME) {
237
+ const db = await openDb(dbName);
238
+ return Object.freeze({
239
+ kind: 'browser',
240
+ async list() {
241
+ return collapse((await idbGet(db, LIST_KEY)) ?? []);
242
+ },
243
+ async read(id) {
244
+ return idbGet(db, id);
245
+ },
246
+ async write(summary, vault) {
247
+ await idbPut(db, summary.id, vault);
248
+ const accounts = ((await idbGet(db, LIST_KEY)) ?? []).filter((account) => account.id !== summary.id && account.did !== summary.did);
249
+ await idbPut(db, LIST_KEY, [...accounts, summary]);
250
+ },
251
+ async remove(id) {
252
+ await idbDelete(db, id);
253
+ const accounts = ((await idbGet(db, LIST_KEY)) ?? []).filter((account) => account.id !== id);
254
+ await idbPut(db, LIST_KEY, accounts);
255
+ },
256
+ });
257
+ }
258
+ // ─── Folders written before they could hold more than one account ──────
259
+ /**
260
+ * Finds the account in a folder that predates the list, so it can join it.
261
+ *
262
+ * Its data stays exactly where it is. Moving it would mean copying every file
263
+ * by hand — the File System Access API cannot rename across directories — for
264
+ * no benefit, so the summary records where the spaces already live instead.
265
+ *
266
+ * @param dir The data folder
267
+ * @param existing Accounts already listed, so one is not adopted twice
268
+ * @returns What to write into the list, or null when there is nothing to adopt
269
+ */
270
+ export async function adoptLegacyFolderAccount(dir, existing) {
271
+ const legacy = await readFolderVault(dir);
272
+ // Nothing there, or a folder from before locking existed — that one cannot
273
+ // be adopted silently, because it has no keys to copy. The app asks the user
274
+ // to put a password on it instead.
275
+ if (!legacy.vault)
276
+ return null;
277
+ if (existing.some((account) => account.did === legacy.vault.did))
278
+ return null;
279
+ return {
280
+ summary: {
281
+ id: newAccountId(),
282
+ name: legacy.label,
283
+ did: legacy.vault.did,
284
+ createdAt: legacy.vault.createdAt,
285
+ dataPath: LEGACY_DATA_PATH,
286
+ },
287
+ vault: legacy.vault,
288
+ };
289
+ }
290
+ /**
291
+ * Lists a folder's accounts, adopting a pre-list one if it finds it.
292
+ *
293
+ * @param dir The data folder
294
+ * @param store The store over it
295
+ * @returns Every account, including one just adopted
296
+ */
297
+ export async function listFolderAccounts(dir, store) {
298
+ const listed = await store.list();
299
+ const adopted = await adoptLegacyFolderAccount(dir, listed);
300
+ if (!adopted)
301
+ return listed;
302
+ await store.write(adopted.summary, adopted.vault);
303
+ return store.list();
304
+ }
305
+ //# sourceMappingURL=account-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-store.js","sourceRoot":"","sources":["../../src/identity/account-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * @module account-vault
3
+ * The lock on a data folder.
4
+ *
5
+ * A folder that holds its seed in the clear is a bearer token: whoever copies it
6
+ * is you, and the AES key for every private space sits in the same directory as
7
+ * the ciphertext it opens. So the seed is never stored — only **wrapped copies**
8
+ * of it are, one per way of unlocking.
9
+ *
10
+ * ```
11
+ * account seed (16 bytes, never written in the clear)
12
+ * ├── HKDF → vault key ──encrypts──> space keys and space records at rest
13
+ * └── stored only as wraps:
14
+ * device a random key in this origin's storage, gated by a passkey
15
+ * passphrase PBKDF2-SHA256 → AES-GCM
16
+ * ```
17
+ *
18
+ * Both wraps are shortcuts for one origin, and neither carries the account
19
+ * anywhere — that is what the code is for. Adding an app means adding a wrap
20
+ * there, and two shortcuts end up meaning one account without a delegation
21
+ * chain anywhere in sight.
22
+ *
23
+ * The recovery code needs no wrap at all: it *is* the seed, in printable form.
24
+ * It is shown once and never stored, and it is the way in when no wrap fits —
25
+ * a phone, Safari, or an origin that has never seen this folder.
26
+ *
27
+ * ## What this does not protect
28
+ *
29
+ * Expression files keep their author DID, timestamps and collection names in
30
+ * the clear, and public spaces keep their bodies that way by design. Locking
31
+ * those too would mean an opaque blob store, which would cost the property that
32
+ * makes a folder worth having — that you can open it and see what is in it.
33
+ */
34
+ /**
35
+ * PBKDF2 rounds for a passphrase wrap.
36
+ *
37
+ * Tuned to roughly a quarter-second in a browser, on the reasoning that this
38
+ * runs once per unlock and the thing it guards is an identity rather than a
39
+ * session.
40
+ */
41
+ export declare const PASSPHRASE_ITERATIONS = 600000;
42
+ /** Fields every wrap carries, whatever unlocks it */
43
+ interface WrapBase {
44
+ /** Distinguishes wraps within one file */
45
+ readonly id: string;
46
+ /** Shown when asking which one to use */
47
+ readonly label: string;
48
+ readonly addedAt: string;
49
+ readonly salt: string;
50
+ readonly iv: string;
51
+ readonly ciphertext: string;
52
+ }
53
+ /**
54
+ * A seed wrapped under a key held on one device.
55
+ *
56
+ * The key is not derived from the passkey — a passkey only yields key material
57
+ * through the PRF extension, which several widely used providers do not
58
+ * implement. It is a random key in this origin's storage, and the passkey in
59
+ * front of it is a user-verification gate rather than the source of the
60
+ * secret. See {@link module:device-key} for what that does and does not
61
+ * protect against.
62
+ */
63
+ export interface DeviceWrap extends WrapBase {
64
+ readonly kind: 'device';
65
+ /**
66
+ * The origin this belongs to. The key it names lives in that origin's
67
+ * storage, so a wrap from another app is not merely likely to fail — it is
68
+ * unreachable from here.
69
+ */
70
+ readonly rpId: string;
71
+ /** Which local key opens it. Missing from this device means unopenable here. */
72
+ readonly deviceKeyId: string;
73
+ /** The passkey that gates it, when one was used */
74
+ readonly credentialId?: string;
75
+ /** That passkey's user handle, base64url — what renaming its label needs */
76
+ readonly userHandle?: string;
77
+ }
78
+ /** A seed wrapped under a passphrase */
79
+ export interface PassphraseWrap extends WrapBase {
80
+ readonly kind: 'passphrase';
81
+ readonly iterations: number;
82
+ }
83
+ export type SeedWrap = DeviceWrap | PassphraseWrap;
84
+ /** The account file at the root of a data folder, in its locked form */
85
+ export interface AccountVault {
86
+ readonly version: 2;
87
+ readonly label: string;
88
+ /** The DID the seed derives. Public, and useful for recognising the folder. */
89
+ readonly did: string;
90
+ readonly createdAt: string;
91
+ readonly wraps: ReadonlyArray<SeedWrap>;
92
+ }
93
+ /**
94
+ * Wraps a seed under this device's key.
95
+ *
96
+ * The key is random and lives in this origin's storage; the passkey recorded
97
+ * alongside is the gate in front of it, not the source of it. See
98
+ * {@link module:device-key}.
99
+ *
100
+ * @param seed The account seed
101
+ * @param deviceKey The local key, from `createDeviceKey`
102
+ * @param meta Which origin this belongs to, and the passkey gating it
103
+ * @returns A wrap ready to append to the account file
104
+ */
105
+ export declare function wrapSeedWithDeviceKey(seed: Uint8Array, deviceKey: {
106
+ id: string;
107
+ key: CryptoKey;
108
+ }, meta: {
109
+ rpId: string;
110
+ credentialId?: string;
111
+ userHandle?: string;
112
+ label?: string;
113
+ }): Promise<DeviceWrap>;
114
+ /**
115
+ * Opens a device wrap.
116
+ * @param wrap The wrap to open
117
+ * @param deviceKey The local key it names
118
+ * @returns The seed
119
+ */
120
+ export declare function unwrapSeedWithDeviceKey(wrap: DeviceWrap, deviceKey: CryptoKey): Promise<Uint8Array>;
121
+ /**
122
+ * Wraps a seed under a passphrase — the portable way back in.
123
+ * @param seed The account seed
124
+ * @param passphrase What the user chose
125
+ * @param label What to call this wrap
126
+ * @returns A wrap ready to append to the account file
127
+ */
128
+ export declare function wrapSeedWithPassphrase(seed: Uint8Array, passphrase: string, label?: string): Promise<PassphraseWrap>;
129
+ /**
130
+ * Opens a passphrase wrap.
131
+ * @param wrap The wrap to open
132
+ * @param passphrase What the user typed
133
+ * @returns The seed
134
+ */
135
+ export declare function unwrapSeedWithPassphrase(wrap: PassphraseWrap, passphrase: string): Promise<Uint8Array>;
136
+ /**
137
+ * The vault key as raw bytes.
138
+ *
139
+ * {@link deriveVaultKey} returns a key that cannot be exported, which is right
140
+ * for a page — it should not be able to leak what it was given. A node derives
141
+ * the account registry from the key, so it is handed the bytes directly
142
+ * rather than the protocol relaxing that for everyone.
143
+ *
144
+ * Identical material to `deriveVaultKey`: same input, same info, same length.
145
+ * If those ever drift, the registry and the folder would be sealed under two
146
+ * different keys.
147
+ *
148
+ * @param seed The account seed
149
+ * @returns 32 bytes, ready to import as AES-GCM
150
+ */
151
+ export declare function deriveVaultKeyBytes(seed: Uint8Array): Promise<Uint8Array>;
152
+ /**
153
+ * Derives the key that encrypts a folder's contents at rest.
154
+ *
155
+ * Separate from the signing key, and from every wrapping key, so that handing
156
+ * one out never implies the others.
157
+ *
158
+ * @param seed The account seed
159
+ * @returns An AES-GCM key for space keys and space records
160
+ */
161
+ export declare function deriveVaultKey(seed: Uint8Array): Promise<CryptoKey>;
162
+ /**
163
+ * The device wraps this origin could actually attempt.
164
+ *
165
+ * The key a wrap names lives in the storage of the origin that made it, so one
166
+ * from another app is not merely likely to fail — it is unreachable from here.
167
+ *
168
+ * @param vault The account file
169
+ * @param rpId This origin's relying-party id, usually its hostname
170
+ * @returns The device wraps belonging to this origin
171
+ */
172
+ export declare function deviceWrapsFor(vault: AccountVault, rpId: string): ReadonlyArray<DeviceWrap>;
173
+ /** Whether a passphrase would get anyone in. */
174
+ export declare function hasPassphraseWrap(vault: AccountVault): boolean;
175
+ /**
176
+ * Adds a wrap, replacing any earlier one for the same passkey.
177
+ *
178
+ * Re-registering on an origin should leave one usable wrap rather than a pile of
179
+ * stale ones, and a wrap whose credential is gone is only clutter.
180
+ *
181
+ * @param vault The account file
182
+ * @param wrap The wrap to add
183
+ * @returns The updated account file
184
+ */
185
+ export declare function withWrap(vault: AccountVault, wrap: SeedWrap): AccountVault;
186
+ /**
187
+ * Removes a wrap by id.
188
+ *
189
+ * Removing the last one is allowed, and leaves the account in the state a new
190
+ * one starts in: openable by its code and nothing else. The wraps are
191
+ * shortcuts, not the keys to the building.
192
+ *
193
+ * @param vault The account file
194
+ * @param id The wrap to remove
195
+ * @returns The updated account file
196
+ */
197
+ export declare function withoutWrap(vault: AccountVault, id: string): AccountVault;
198
+ export {};
199
+ //# sourceMappingURL=account-vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-vault.d.ts","sourceRoot":"","sources":["../../src/identity/account-vault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AASH;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAI7C,qDAAqD;AACrD,UAAU,QAAQ;IAChB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wCAAwC;AACxC,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;AAEnD,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACzC;AAgFD;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,EACzC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,UAAU,CAAC,CAErB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAqB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAqB/E;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAoBzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAI3F;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAE9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,GAAG,YAAY,CAO1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,CAEzE"}