@brass-build/client 0.4.0 → 0.5.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 (327) hide show
  1. package/AGENTS.md +142 -41
  2. package/CHANGELOG.md +93 -4
  3. package/README.md +666 -179
  4. package/dist/acting-organization.d.ts.map +1 -1
  5. package/dist/acting-organization.js +6 -11
  6. package/dist/acting-organization.js.map +1 -1
  7. package/dist/api-fetch.d.ts +8 -0
  8. package/dist/api-fetch.d.ts.map +1 -1
  9. package/dist/api-fetch.js +35 -8
  10. package/dist/api-fetch.js.map +1 -1
  11. package/dist/batched-get.d.ts +11 -0
  12. package/dist/batched-get.d.ts.map +1 -0
  13. package/dist/batched-get.js +92 -0
  14. package/dist/batched-get.js.map +1 -0
  15. package/dist/call-service.d.ts +4 -0
  16. package/dist/call-service.d.ts.map +1 -1
  17. package/dist/call-service.js +66 -3
  18. package/dist/call-service.js.map +1 -1
  19. package/dist/client.d.ts +51 -2
  20. package/dist/client.d.ts.map +1 -1
  21. package/dist/client.js +982 -124
  22. package/dist/client.js.map +1 -1
  23. package/dist/document-checkpoints.d.ts +25 -2
  24. package/dist/document-checkpoints.d.ts.map +1 -1
  25. package/dist/document-checkpoints.js +258 -61
  26. package/dist/document-checkpoints.js.map +1 -1
  27. package/dist/document-commands.d.ts.map +1 -1
  28. package/dist/document-commands.js +5 -3
  29. package/dist/document-commands.js.map +1 -1
  30. package/dist/document-contents.d.ts +10 -0
  31. package/dist/document-contents.d.ts.map +1 -1
  32. package/dist/document-contents.js +23 -1
  33. package/dist/document-contents.js.map +1 -1
  34. package/dist/document-set-subscription.d.ts +56 -0
  35. package/dist/document-set-subscription.d.ts.map +1 -0
  36. package/dist/document-set-subscription.js +240 -0
  37. package/dist/document-set-subscription.js.map +1 -0
  38. package/dist/document-signals.d.ts +6 -0
  39. package/dist/document-signals.d.ts.map +1 -1
  40. package/dist/document-signals.js +31 -1
  41. package/dist/document-signals.js.map +1 -1
  42. package/dist/document-streams.d.ts +36 -2
  43. package/dist/document-streams.d.ts.map +1 -1
  44. package/dist/document-streams.js +69 -18
  45. package/dist/document-streams.js.map +1 -1
  46. package/dist/document-thumbnail-capture.d.ts +12 -2
  47. package/dist/document-thumbnail-capture.d.ts.map +1 -1
  48. package/dist/document-thumbnail-capture.js +103 -27
  49. package/dist/document-thumbnail-capture.js.map +1 -1
  50. package/dist/documents-namespace.d.ts +92 -10
  51. package/dist/documents-namespace.d.ts.map +1 -1
  52. package/dist/documents-namespace.js +285 -39
  53. package/dist/documents-namespace.js.map +1 -1
  54. package/dist/documents.d.ts +173 -8
  55. package/dist/documents.d.ts.map +1 -1
  56. package/dist/documents.js +1778 -310
  57. package/dist/documents.js.map +1 -1
  58. package/dist/errors.d.ts +3 -3
  59. package/dist/errors.d.ts.map +1 -1
  60. package/dist/errors.js.map +1 -1
  61. package/dist/fetch-retry.d.ts +1 -0
  62. package/dist/fetch-retry.d.ts.map +1 -1
  63. package/dist/fetch-retry.js +2 -0
  64. package/dist/fetch-retry.js.map +1 -1
  65. package/dist/file-choice.d.ts +2 -0
  66. package/dist/file-choice.d.ts.map +1 -0
  67. package/dist/file-choice.js +27 -0
  68. package/dist/file-choice.js.map +1 -0
  69. package/dist/guest-link.d.ts +18 -1
  70. package/dist/guest-link.d.ts.map +1 -1
  71. package/dist/guest-link.js +329 -1
  72. package/dist/guest-link.js.map +1 -1
  73. package/dist/handle-types.d.ts +67 -5
  74. package/dist/handle-types.d.ts.map +1 -1
  75. package/dist/handles.d.ts +15 -19
  76. package/dist/handles.d.ts.map +1 -1
  77. package/dist/handles.js +231 -76
  78. package/dist/handles.js.map +1 -1
  79. package/dist/hosted-ui.d.ts +61 -0
  80. package/dist/hosted-ui.d.ts.map +1 -1
  81. package/dist/hosted-ui.js +94 -42
  82. package/dist/hosted-ui.js.map +1 -1
  83. package/dist/import-contract.d.ts +74 -0
  84. package/dist/import-contract.d.ts.map +1 -0
  85. package/dist/import-contract.js +163 -0
  86. package/dist/import-contract.js.map +1 -0
  87. package/dist/import-guest.d.ts +9 -0
  88. package/dist/import-guest.d.ts.map +1 -0
  89. package/dist/import-guest.js +155 -0
  90. package/dist/import-guest.js.map +1 -0
  91. package/dist/import-report.d.ts +17 -0
  92. package/dist/import-report.d.ts.map +1 -0
  93. package/dist/import-report.js +7 -0
  94. package/dist/import-report.js.map +1 -0
  95. package/dist/importer-wait.d.ts +2 -0
  96. package/dist/importer-wait.d.ts.map +1 -0
  97. package/dist/importer-wait.js +5 -0
  98. package/dist/importer-wait.js.map +1 -0
  99. package/dist/importer.d.ts +18 -4
  100. package/dist/importer.d.ts.map +1 -1
  101. package/dist/importer.js +322 -105
  102. package/dist/importer.js.map +1 -1
  103. package/dist/in-development.d.ts +2 -0
  104. package/dist/in-development.d.ts.map +1 -0
  105. package/dist/in-development.js +10 -0
  106. package/dist/in-development.js.map +1 -0
  107. package/dist/index.d.ts +16 -8
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +24 -8
  110. package/dist/index.js.map +1 -1
  111. package/dist/init-keys.d.ts +1 -1
  112. package/dist/init-keys.d.ts.map +1 -1
  113. package/dist/init-keys.js +6 -1
  114. package/dist/init-keys.js.map +1 -1
  115. package/dist/input-documents.d.ts +67 -0
  116. package/dist/input-documents.d.ts.map +1 -0
  117. package/dist/input-documents.js +693 -0
  118. package/dist/input-documents.js.map +1 -0
  119. package/dist/inputs-status.d.ts +80 -0
  120. package/dist/inputs-status.d.ts.map +1 -0
  121. package/dist/inputs-status.js +460 -0
  122. package/dist/inputs-status.js.map +1 -0
  123. package/dist/inputs.d.ts +2 -0
  124. package/dist/inputs.d.ts.map +1 -0
  125. package/dist/inputs.js +793 -0
  126. package/dist/inputs.js.map +1 -0
  127. package/dist/internal.d.ts +6 -1
  128. package/dist/internal.d.ts.map +1 -1
  129. package/dist/internal.js +4 -1
  130. package/dist/internal.js.map +1 -1
  131. package/dist/join-content.d.ts +33 -0
  132. package/dist/join-content.d.ts.map +1 -0
  133. package/dist/join-content.js +114 -0
  134. package/dist/join-content.js.map +1 -0
  135. package/dist/join-stamp.d.ts +3 -0
  136. package/dist/join-stamp.d.ts.map +1 -0
  137. package/dist/join-stamp.js +12 -0
  138. package/dist/join-stamp.js.map +1 -0
  139. package/dist/manifest-drift.d.ts +9 -0
  140. package/dist/manifest-drift.d.ts.map +1 -0
  141. package/dist/manifest-drift.js +46 -0
  142. package/dist/manifest-drift.js.map +1 -0
  143. package/dist/open-document.d.ts +109 -2
  144. package/dist/open-document.d.ts.map +1 -1
  145. package/dist/open-document.js +1822 -811
  146. package/dist/open-document.js.map +1 -1
  147. package/dist/page-restore.d.ts +12 -0
  148. package/dist/page-restore.d.ts.map +1 -0
  149. package/dist/page-restore.js +23 -0
  150. package/dist/page-restore.js.map +1 -0
  151. package/dist/placement.d.ts +13 -0
  152. package/dist/placement.d.ts.map +1 -0
  153. package/dist/placement.js +34 -0
  154. package/dist/placement.js.map +1 -0
  155. package/dist/presence.d.ts +1 -0
  156. package/dist/presence.d.ts.map +1 -1
  157. package/dist/presence.js +16 -4
  158. package/dist/presence.js.map +1 -1
  159. package/dist/read-only-document.d.ts +87 -0
  160. package/dist/read-only-document.d.ts.map +1 -0
  161. package/dist/read-only-document.js +4 -0
  162. package/dist/read-only-document.js.map +1 -0
  163. package/dist/record-paging.d.ts +63 -6
  164. package/dist/record-paging.d.ts.map +1 -1
  165. package/dist/record-paging.js +122 -29
  166. package/dist/record-paging.js.map +1 -1
  167. package/dist/references.d.ts +40 -0
  168. package/dist/references.d.ts.map +1 -0
  169. package/dist/references.js +135 -0
  170. package/dist/references.js.map +1 -0
  171. package/dist/request-lane.d.ts +5 -0
  172. package/dist/request-lane.d.ts.map +1 -0
  173. package/dist/request-lane.js +48 -0
  174. package/dist/request-lane.js.map +1 -0
  175. package/dist/sealed-arrow.d.ts +170 -0
  176. package/dist/sealed-arrow.d.ts.map +1 -0
  177. package/dist/sealed-arrow.js +769 -0
  178. package/dist/sealed-arrow.js.map +1 -0
  179. package/dist/sealed-cache.d.ts +21 -0
  180. package/dist/sealed-cache.d.ts.map +1 -0
  181. package/dist/sealed-cache.js +247 -0
  182. package/dist/sealed-cache.js.map +1 -0
  183. package/dist/sealed-encode.d.ts +87 -0
  184. package/dist/sealed-encode.d.ts.map +1 -0
  185. package/dist/sealed-encode.js +876 -0
  186. package/dist/sealed-encode.js.map +1 -0
  187. package/dist/sealed-handles.d.ts +45 -0
  188. package/dist/sealed-handles.d.ts.map +1 -0
  189. package/dist/sealed-handles.js +408 -0
  190. package/dist/sealed-handles.js.map +1 -0
  191. package/dist/sealed-store.d.ts +242 -0
  192. package/dist/sealed-store.d.ts.map +1 -0
  193. package/dist/sealed-store.js +1155 -0
  194. package/dist/sealed-store.js.map +1 -0
  195. package/dist/serializer.d.ts +6 -15
  196. package/dist/serializer.d.ts.map +1 -1
  197. package/dist/session-toolbar.d.ts +20 -5
  198. package/dist/session-toolbar.d.ts.map +1 -1
  199. package/dist/session-toolbar.js +419 -67
  200. package/dist/session-toolbar.js.map +1 -1
  201. package/dist/session.d.ts +38 -1
  202. package/dist/session.d.ts.map +1 -1
  203. package/dist/session.js +562 -79
  204. package/dist/session.js.map +1 -1
  205. package/dist/sha256.d.ts +3 -0
  206. package/dist/sha256.d.ts.map +1 -0
  207. package/dist/sha256.js +74 -0
  208. package/dist/sha256.js.map +1 -0
  209. package/dist/stable-handles.d.ts +19 -0
  210. package/dist/stable-handles.d.ts.map +1 -0
  211. package/dist/stable-handles.js +193 -0
  212. package/dist/stable-handles.js.map +1 -0
  213. package/dist/staged-seal.d.ts +2 -0
  214. package/dist/staged-seal.d.ts.map +1 -0
  215. package/dist/staged-seal.js +76 -0
  216. package/dist/staged-seal.js.map +1 -0
  217. package/dist/subscriber-delivery.d.ts +8 -0
  218. package/dist/subscriber-delivery.d.ts.map +1 -0
  219. package/dist/subscriber-delivery.js +31 -0
  220. package/dist/subscriber-delivery.js.map +1 -0
  221. package/dist/tail-op-import.d.ts +10 -0
  222. package/dist/tail-op-import.d.ts.map +1 -0
  223. package/dist/tail-op-import.js +33 -0
  224. package/dist/tail-op-import.js.map +1 -0
  225. package/dist/topic-lifecycle.d.ts +6 -0
  226. package/dist/topic-lifecycle.d.ts.map +1 -1
  227. package/dist/topic-lifecycle.js +32 -2
  228. package/dist/topic-lifecycle.js.map +1 -1
  229. package/dist/trial-replace-dialog.d.ts +10 -0
  230. package/dist/trial-replace-dialog.d.ts.map +1 -0
  231. package/dist/trial-replace-dialog.js +153 -0
  232. package/dist/trial-replace-dialog.js.map +1 -0
  233. package/dist/types.d.ts +8 -1
  234. package/dist/types.d.ts.map +1 -1
  235. package/dist/undo.d.ts +60 -5
  236. package/dist/undo.d.ts.map +1 -1
  237. package/dist/undo.js +344 -75
  238. package/dist/undo.js.map +1 -1
  239. package/dist/version-bar.d.ts +1 -0
  240. package/dist/version-bar.d.ts.map +1 -1
  241. package/dist/version-bar.js +2 -1
  242. package/dist/version-bar.js.map +1 -1
  243. package/dist/version.d.ts +2 -2
  244. package/dist/version.js +1 -1
  245. package/dist/ws-client.d.ts +21 -0
  246. package/dist/ws-client.d.ts.map +1 -1
  247. package/dist/ws-client.js +192 -8
  248. package/dist/ws-client.js.map +1 -1
  249. package/dist/ws-frame-limit.d.ts +1 -0
  250. package/dist/ws-frame-limit.d.ts.map +1 -1
  251. package/dist/ws-frame-limit.js.map +1 -1
  252. package/docs/app-manifest.md +121 -17
  253. package/docs/custom-chrome.md +24 -16
  254. package/docs/hosted-ui-advanced.md +38 -6
  255. package/docs/imported-documents.md +104 -51
  256. package/docs/presence.md +16 -4
  257. package/docs/schemas.md +8 -5
  258. package/docs/services.md +6 -6
  259. package/docs/streams.md +139 -150
  260. package/docs/text-fields.md +26 -19
  261. package/package.json +5 -2
  262. package/src/acting-organization.ts +6 -12
  263. package/src/api-fetch.ts +53 -3
  264. package/src/auth-flow.ts +1 -1
  265. package/src/batched-get.ts +117 -0
  266. package/src/call-service.ts +78 -3
  267. package/src/client.ts +1092 -121
  268. package/src/document-checkpoints.ts +307 -65
  269. package/src/document-commands.ts +5 -5
  270. package/src/document-contents.ts +27 -1
  271. package/src/document-set-subscription.ts +274 -0
  272. package/src/document-signals.ts +47 -5
  273. package/src/document-streams.ts +85 -16
  274. package/src/document-thumbnail-capture.ts +118 -32
  275. package/src/documents-namespace.ts +539 -84
  276. package/src/documents.ts +2017 -348
  277. package/src/errors.ts +17 -6
  278. package/src/fetch-retry.ts +5 -0
  279. package/src/file-choice.ts +26 -0
  280. package/src/guest-link.ts +362 -1
  281. package/src/handle-types.ts +73 -47
  282. package/src/handles.ts +253 -83
  283. package/src/hosted-ui.ts +211 -50
  284. package/src/import-contract.ts +227 -0
  285. package/src/import-guest.ts +193 -0
  286. package/src/import-report.ts +24 -0
  287. package/src/importer-wait.ts +4 -0
  288. package/src/importer.ts +386 -131
  289. package/src/in-development.ts +10 -0
  290. package/src/index.ts +76 -16
  291. package/src/init-keys.ts +6 -1
  292. package/src/input-documents.ts +819 -0
  293. package/src/inputs-status.ts +598 -0
  294. package/src/inputs.ts +1090 -0
  295. package/src/internal.ts +7 -0
  296. package/src/join-content.ts +135 -0
  297. package/src/join-stamp.ts +12 -0
  298. package/src/manifest-drift.ts +54 -0
  299. package/src/open-document.ts +2346 -930
  300. package/src/page-restore.ts +38 -0
  301. package/src/placement.ts +54 -0
  302. package/src/presence.ts +21 -5
  303. package/src/read-only-document.ts +133 -0
  304. package/src/record-paging.ts +147 -25
  305. package/src/references.ts +207 -0
  306. package/src/request-lane.ts +59 -0
  307. package/src/sealed-arrow.ts +843 -0
  308. package/src/sealed-cache.ts +267 -0
  309. package/src/sealed-encode.ts +1015 -0
  310. package/src/sealed-handles.ts +486 -0
  311. package/src/sealed-store.ts +1330 -0
  312. package/src/serializer.ts +8 -20
  313. package/src/session-toolbar.ts +463 -72
  314. package/src/session.ts +740 -99
  315. package/src/sha256.ts +65 -0
  316. package/src/stable-handles.ts +235 -0
  317. package/src/staged-seal.ts +90 -0
  318. package/src/subscriber-delivery.ts +37 -0
  319. package/src/tail-op-import.ts +30 -0
  320. package/src/topic-lifecycle.ts +38 -2
  321. package/src/trial-replace-dialog.ts +163 -0
  322. package/src/types.ts +6 -6
  323. package/src/undo.ts +386 -73
  324. package/src/version-bar.ts +5 -1
  325. package/src/version.ts +1 -1
  326. package/src/ws-client.ts +208 -16
  327. package/src/ws-frame-limit.ts +1 -0
@@ -5,9 +5,337 @@
5
5
  //
6
6
  // Pure + search-string-in so it stays testable, mirroring
7
7
  // `isExportMode(search)`.
8
- export const GUEST_LINK_PARAM = 'brass_link';
8
+ const GUEST_LINK_PARAM = 'brass_link';
9
9
  export function readGuestLinkToken(search) {
10
10
  const value = new URLSearchParams(search).get(GUEST_LINK_PARAM);
11
11
  return value && value.trim() !== '' ? value : null;
12
12
  }
13
+ // Pin the token into the page URL (`replaceState`, never a history entry):
14
+ // a document created while signed out is reached again only through its
15
+ // token, so a reload restores it from here, and `signIn()` carries this URL
16
+ // as its return address.
17
+ export function writeGuestLinkToken(token) {
18
+ if (typeof window === 'undefined')
19
+ return;
20
+ try {
21
+ const url = new URL(window.location.href);
22
+ url.searchParams.set(GUEST_LINK_PARAM, token);
23
+ const next = url.toString();
24
+ if (next === window.location.href)
25
+ return;
26
+ window.history.replaceState(window.history.state, '', next);
27
+ }
28
+ catch {
29
+ // History API unavailable or URL exotic: leave the URL alone.
30
+ }
31
+ }
32
+ export function clearGuestLinkToken() {
33
+ if (typeof window === 'undefined')
34
+ return;
35
+ try {
36
+ const url = new URL(window.location.href);
37
+ if (!url.searchParams.has(GUEST_LINK_PARAM))
38
+ return;
39
+ url.searchParams.delete(GUEST_LINK_PARAM);
40
+ window.history.replaceState(window.history.state, '', url.toString());
41
+ }
42
+ catch {
43
+ // See `writeGuestLinkToken`.
44
+ }
45
+ }
46
+ // The last document a visitor created without an account, per app. The URL
47
+ // is that document's only handle, so a visitor who closes the tab and comes
48
+ // back to the app's root would have no way back to it; the app's signed-out
49
+ // gate offers it from here. localStorage, since the return is in a new tab.
50
+ // The expiry is stored beside the token so the gate can say when the work
51
+ // is lost without a request, and an entry past it reads as absent.
52
+ //
53
+ // The token is a credential to an editable document, which is why the
54
+ // session hands an app the expiry alone and opens the document itself.
55
+ const UNSAVED_KEY_PREFIX = 'brass:unsaved:';
56
+ function unsavedStorage() {
57
+ if (typeof localStorage === 'undefined')
58
+ return null;
59
+ try {
60
+ return localStorage;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ function unsavedKey(appId) {
67
+ return `${UNSAVED_KEY_PREFIX}${appId}`;
68
+ }
69
+ export function storeUnsavedWork(appId, token, expiresAt) {
70
+ const storage = unsavedStorage();
71
+ if (!storage)
72
+ return;
73
+ try {
74
+ storage.setItem(unsavedKey(appId), JSON.stringify({ token, expires_at: expiresAt.toISOString() }));
75
+ }
76
+ catch {
77
+ // Quota / disabled storage. The way back is a niceness; the open that
78
+ // just succeeded must not fail on it.
79
+ }
80
+ }
81
+ export function readUnsavedWork(appId, now = Date.now()) {
82
+ const storage = unsavedStorage();
83
+ if (!storage)
84
+ return null;
85
+ let raw;
86
+ try {
87
+ raw = storage.getItem(unsavedKey(appId));
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ if (raw === null)
93
+ return null;
94
+ let parsed;
95
+ try {
96
+ parsed = JSON.parse(raw);
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ const entry = parsed;
102
+ const expiresAt = typeof entry?.expires_at === 'string' ? new Date(entry.expires_at) : null;
103
+ if (typeof entry?.token !== 'string' ||
104
+ entry.token === '' ||
105
+ expiresAt === null ||
106
+ Number.isNaN(expiresAt.getTime())) {
107
+ return null;
108
+ }
109
+ // The platform removes the document at the expiry, so an entry past it
110
+ // names nothing and is dropped here rather than offered.
111
+ if (expiresAt.getTime() <= now) {
112
+ clearUnsavedWork(appId);
113
+ return null;
114
+ }
115
+ return { token: entry.token, expiresAt };
116
+ }
117
+ export function clearUnsavedWork(appId) {
118
+ const storage = unsavedStorage();
119
+ if (!storage)
120
+ return;
121
+ try {
122
+ storage.removeItem(unsavedKey(appId));
123
+ }
124
+ catch {
125
+ // See `storeUnsavedWork`.
126
+ }
127
+ }
128
+ // Whether this browser has edited a document it made without an account. New
129
+ // and Upload ask before replacing one, so the marker outlives a reload; it
130
+ // carries the document's expiry so an entry past it is dropped on read.
131
+ const EDITED_KEY_PREFIX = 'brass:trial-edited:';
132
+ export function markTrialEdited(token, expiresAt) {
133
+ const storage = unsavedStorage();
134
+ if (!storage)
135
+ return;
136
+ try {
137
+ storage.setItem(`${EDITED_KEY_PREFIX}${token}`, expiresAt.toISOString());
138
+ }
139
+ catch {
140
+ // See `storeUnsavedWork`.
141
+ }
142
+ }
143
+ export function trialWasEdited(token, now = Date.now()) {
144
+ const storage = unsavedStorage();
145
+ if (!storage)
146
+ return false;
147
+ let raw;
148
+ try {
149
+ raw = storage.getItem(`${EDITED_KEY_PREFIX}${token}`);
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ if (raw === null)
155
+ return false;
156
+ const expiresAt = Date.parse(raw);
157
+ if (Number.isNaN(expiresAt) || expiresAt <= now) {
158
+ try {
159
+ storage.removeItem(`${EDITED_KEY_PREFIX}${token}`);
160
+ }
161
+ catch {
162
+ // See `storeUnsavedWork`.
163
+ }
164
+ return false;
165
+ }
166
+ return true;
167
+ }
168
+ // The claim secret the mint handed this browser, one per document, keyed by
169
+ // the app and the document's link token. Only the browser that made the
170
+ // document has one, so a sign-in here keeps the document and a sign-in
171
+ // wherever its link was shared does not. Written at the mint alone, so opening
172
+ // a shared link leaves it alone. Every mint prunes the secrets whose document
173
+ // has expired, since nothing else removes the secret of a document nobody
174
+ // came back to.
175
+ const CLAIM_KEY_PREFIX = 'brass:claim:';
176
+ function claimKey(appId, token) {
177
+ return `${CLAIM_KEY_PREFIX}${appId}:${token}`;
178
+ }
179
+ // Collected before any removal, since removing a key renumbers the rest.
180
+ function claimKeys(storage, prefix) {
181
+ const keys = [];
182
+ try {
183
+ for (let i = 0; i < storage.length; i++) {
184
+ const key = storage.key(i);
185
+ if (key !== null && key.startsWith(prefix))
186
+ keys.push(key);
187
+ }
188
+ }
189
+ catch {
190
+ // See `storeUnsavedWork`.
191
+ }
192
+ return keys;
193
+ }
194
+ function readClaimEntry(storage, key, now) {
195
+ let entry;
196
+ try {
197
+ entry = JSON.parse(storage.getItem(key) ?? 'null');
198
+ }
199
+ catch {
200
+ entry = null;
201
+ }
202
+ const expiresAt = typeof entry?.expires_at === 'string' ? Date.parse(entry.expires_at) : NaN;
203
+ if (typeof entry?.secret !== 'string' || Number.isNaN(expiresAt) || expiresAt <= now) {
204
+ try {
205
+ storage.removeItem(key);
206
+ }
207
+ catch {
208
+ // See `storeUnsavedWork`.
209
+ }
210
+ return null;
211
+ }
212
+ return entry.secret;
213
+ }
214
+ function pruneClaimSecrets(storage, now) {
215
+ for (const key of claimKeys(storage, CLAIM_KEY_PREFIX))
216
+ readClaimEntry(storage, key, now);
217
+ }
218
+ export function storeClaimSecret(appId, token, secret, expiresAt, now = Date.now()) {
219
+ const storage = unsavedStorage();
220
+ if (!storage)
221
+ return;
222
+ pruneClaimSecrets(storage, now);
223
+ try {
224
+ storage.setItem(claimKey(appId, token), JSON.stringify({ secret, expires_at: expiresAt.toISOString() }));
225
+ }
226
+ catch {
227
+ // See `storeUnsavedWork`.
228
+ }
229
+ }
230
+ export function readClaimSecret(appId, token, now = Date.now()) {
231
+ const storage = unsavedStorage();
232
+ if (!storage)
233
+ return null;
234
+ return readClaimEntry(storage, claimKey(appId, token), now);
235
+ }
236
+ // One document's secret, or with no token every secret this browser holds
237
+ // for the app.
238
+ export function clearClaimSecret(appId, token) {
239
+ const storage = unsavedStorage();
240
+ if (!storage)
241
+ return;
242
+ const keys = token === undefined
243
+ ? claimKeys(storage, `${CLAIM_KEY_PREFIX}${appId}:`)
244
+ : [claimKey(appId, token)];
245
+ for (const key of keys) {
246
+ try {
247
+ storage.removeItem(key);
248
+ }
249
+ catch {
250
+ // See `storeUnsavedWork`.
251
+ }
252
+ }
253
+ }
254
+ // That this tab started a sign-in from a guest page, and on which token. Per
255
+ // tab (sessionStorage), written by `signIn()` and taken once on the return,
256
+ // so a URL carrying `brass_code` that this tab did not ask for claims nothing.
257
+ const SIGN_IN_INTENT_PREFIX = 'brass:claim-intent:';
258
+ function tabStorage() {
259
+ if (typeof sessionStorage === 'undefined')
260
+ return null;
261
+ try {
262
+ return sessionStorage;
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ }
268
+ export function markClaimIntent(appId, token) {
269
+ try {
270
+ tabStorage()?.setItem(`${SIGN_IN_INTENT_PREFIX}${appId}`, token);
271
+ }
272
+ catch {
273
+ // See `storeUnsavedWork`.
274
+ }
275
+ }
276
+ export function takeClaimIntent(appId) {
277
+ const storage = tabStorage();
278
+ if (!storage)
279
+ return null;
280
+ try {
281
+ const token = storage.getItem(`${SIGN_IN_INTENT_PREFIX}${appId}`);
282
+ storage.removeItem(`${SIGN_IN_INTENT_PREFIX}${appId}`);
283
+ return token;
284
+ }
285
+ catch {
286
+ return null;
287
+ }
288
+ }
289
+ // The documents this browser claimed, per app, by the mint link each claim
290
+ // revoked. Reading that link again answers 410 for everyone, and a page that
291
+ // holds no session cannot ask the platform where it leads, so this is how a
292
+ // signed-out page on it knows to offer sign-in to the document instead. It
293
+ // confers no access (the open after sign-in is checked like any other), so a
294
+ // sign-out keeps it. Entries lapse after `CLAIMED_LINK_TTL_MS`.
295
+ const CLAIMED_KEY_PREFIX = 'brass:claimed:';
296
+ const CLAIMED_LINK_TTL_MS = 30 * 24 * 60 * 60 * 1000;
297
+ function claimedKey(appId, token) {
298
+ return `${CLAIMED_KEY_PREFIX}${appId}:${token}`;
299
+ }
300
+ function readClaimedEntry(storage, key, now) {
301
+ let entry;
302
+ try {
303
+ entry = JSON.parse(storage.getItem(key) ?? 'null');
304
+ }
305
+ catch {
306
+ entry = null;
307
+ }
308
+ const claimedAt = typeof entry?.claimed_at === 'number' ? entry.claimed_at : NaN;
309
+ if (typeof entry?.doc_id !== 'string' ||
310
+ Number.isNaN(claimedAt) ||
311
+ claimedAt + CLAIMED_LINK_TTL_MS <= now) {
312
+ try {
313
+ storage.removeItem(key);
314
+ }
315
+ catch {
316
+ // See `storeUnsavedWork`.
317
+ }
318
+ return null;
319
+ }
320
+ return entry.doc_id;
321
+ }
322
+ export function storeClaimedLink(appId, token, docId, now = Date.now()) {
323
+ const storage = unsavedStorage();
324
+ if (!storage)
325
+ return;
326
+ for (const key of claimKeys(storage, CLAIMED_KEY_PREFIX))
327
+ readClaimedEntry(storage, key, now);
328
+ try {
329
+ storage.setItem(claimedKey(appId, token), JSON.stringify({ doc_id: docId, claimed_at: now }));
330
+ }
331
+ catch {
332
+ // See `storeUnsavedWork`.
333
+ }
334
+ }
335
+ export function readClaimedLink(appId, token, now = Date.now()) {
336
+ const storage = unsavedStorage();
337
+ if (!storage)
338
+ return null;
339
+ return readClaimedEntry(storage, claimedKey(appId, token), now);
340
+ }
13
341
  //# sourceMappingURL=guest-link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guest-link.js","sourceRoot":"","sources":["../src/guest-link.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,yEAAyE;AACzE,mEAAmE;AACnE,2EAA2E;AAC3E,EAAE;AACF,0DAA0D;AAC1D,0BAA0B;AAE1B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAChE,OAAO,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"guest-link.js","sourceRoot":"","sources":["../src/guest-link.ts"],"names":[],"mappings":"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"}
@@ -23,8 +23,9 @@ export interface Splice<E> {
23
23
  readonly inserted: readonly E[];
24
24
  }
25
25
  /**
26
- * What changed in a list. Fires once on registration carrying the whole list
27
- * as a single splice, then on every change carrying only what moved.
26
+ * What changed in a list. Fires once on registration carrying the whole list,
27
+ * then on every change carrying only what moved. No splice inserts more than
28
+ * 10,000 elements, so a spread apply stays inside the engine's argument limit.
28
29
  *
29
30
  * A registration fire and a resync are not special cases a subscriber has to
30
31
  * recognise: both arrive as splices that replace what it was last told, so
@@ -41,13 +42,36 @@ export interface HandleOwner {
41
42
  assertReadable(): void;
42
43
  ensureLocalUpdatesSubscribed(): void;
43
44
  commitMutate(): void;
45
+ runMutate(options: MutateOptions | undefined, fn: () => void): void;
44
46
  originOf(event: unknown): ChangeSource;
47
+ reportSubscriberThrow(err: unknown): void;
48
+ }
49
+ /** Options every `mutate` takes. */
50
+ export interface MutateOptions {
51
+ /**
52
+ * `false` keeps the write off the reader's Undo stack, for a pass the app
53
+ * runs on its own rather than one the reader asked for. Defaults to true.
54
+ */
55
+ undoable?: boolean;
45
56
  }
46
57
  export interface MapHandle<T = unknown> {
58
+ /** Per-entry read. Returns undefined when missing. */
47
59
  get(entryKey: string): T | undefined;
60
+ /** Keys currently in the map. */
48
61
  keys(): string[];
62
+ /** Whether an entry exists at `entryKey`. */
49
63
  has(entryKey: string): boolean;
50
- mutate(fn: (draft: Record<string, T>) => void): void;
64
+ /** Every `[key, value]`, as a walk. Each step hands over one entry, so a
65
+ * caller that does not keep them never holds the whole map at once. */
66
+ entries(): IterableIterator<[string, T]>;
67
+ /** Mutate through a typed JS-proxy, scoped to this container; same
68
+ * ergonomics as `doc.mutate(d => { d.entities[id].field = ... })`. */
69
+ mutate(fn: (draft: Record<string, T>) => void, options?: MutateOptions): void;
70
+ /** ONE channel for every change whatever produced it (local / remote / undo
71
+ * / redo / checkout): the projection reconciles by value. The callback gets
72
+ * `change` and optional `origin` a render ignores. Fires once on
73
+ * registration with the whole map as `change.set`, then on every change
74
+ * (each later fire proportional to what that change wrote). */
51
75
  subscribe(cb: MapSubscriber<T>): HandleUnsubscribe;
52
76
  /**
53
77
  * Report each time this container has been delivered whole: on
@@ -63,6 +87,10 @@ export interface MapHandle<T = unknown> {
63
87
  * began, which is the only claim available: more always arrives afterwards.
64
88
  */
65
89
  onSettled(cb: () => void): HandleUnsubscribe;
90
+ /** Child handle for `entries[entryKey]` when that entry is itself a map /
91
+ * list. Reads see empty until the container exists; the first mutate
92
+ * creates it, and a subscription taken before that delivers the container
93
+ * whole on whichever write creates it. */
66
94
  map<U>(entryKey: string): MapHandle<U>;
67
95
  list<U>(entryKey: string): ListHandle<U>;
68
96
  }
@@ -84,7 +112,16 @@ export interface ListDraft<T> extends Array<T> {
84
112
  }
85
113
  export interface ListHandle<T = unknown> {
86
114
  length(): number;
87
- mutate(fn: (draft: ListDraft<T>) => void): void;
115
+ /** The element at `index`, or undefined outside the list. */
116
+ get(index: number): T | undefined;
117
+ /** Every element in order, as a walk. */
118
+ values(): IterableIterator<T>;
119
+ mutate(fn: (draft: ListDraft<T>) => void, options?: MutateOptions): void;
120
+ /** Fires once on registration carrying the whole list, then on
121
+ * every change carrying only what moved, so a subscriber applies splices to
122
+ * what it already holds and never re-reads. A keyed collection belongs in a
123
+ * map (or `orderedMap`), which reconciles by key; a list is for ordering
124
+ * keys and small positional data. */
88
125
  subscribe(cb: ListSubscriber<T>): HandleUnsubscribe;
89
126
  /**
90
127
  * Report each time this container has been delivered whole: on
@@ -121,16 +158,41 @@ export type OrderedMapPosition = {
121
158
  index: number;
122
159
  };
123
160
  export interface OrderedMapHandle<T = unknown> {
161
+ /** Per-entry read. Returns undefined when missing. */
124
162
  get(entryKey: string): T | undefined;
163
+ /** Whether an entry exists in the map. */
125
164
  has(entryKey: string): boolean;
165
+ /** Keys in order-list order, filtered to keys still present in the map. */
126
166
  keys(): string[];
167
+ /** Every `[key, value]` in order, as a walk. */
168
+ entries(): IterableIterator<[string, T]>;
169
+ /** @deprecated Use `entries()`, which walks the same records in the same
170
+ * order without building the array. */
127
171
  ordered(): {
128
172
  key: string;
129
173
  value: T;
130
174
  }[];
131
- mutate(fn: (draft: Record<string, T>) => void): void;
175
+ /** Mutate the map; the sibling order list reconciles in the same commit
176
+ * (new keys appended in insertion order, deleted keys pruned). Drive it
177
+ * like `MapHandle.mutate`: `m[key] = record`, `delete m[key]`,
178
+ * `m[key].field = ...`. */
179
+ mutate(fn: (draft: Record<string, T>) => void, options?: MutateOptions): void;
180
+ /** Write `value` under `entryKey` and put that key at `at`, both in ONE
181
+ * commit (one undo step) like every other structural edit here. A key the
182
+ * map already holds is written and repositioned rather than named twice. */
132
183
  insert(entryKey: string, value: T, at: OrderedMapPosition): void;
184
+ /** Reposition a key the map already holds, writing the order list alone. A
185
+ * key the map does not hold does nothing, so a reorder racing a peer's
186
+ * delete of the same key leaves the delete standing. */
133
187
  move(entryKey: string, to: OrderedMapPosition): void;
188
+ /** Fires once on registration (the whole map as `change.set` in order),
189
+ * then on every change. A field edit carries only `set` / `deleted`; a
190
+ * change that moves the order also carries `change.order` (live keys in
191
+ * order) so the app re-sequences the views it holds. A move the map does
192
+ * not see (an edit of the sibling order list, a merge that resequences
193
+ * keys already present) arrives as an `order` of its own with an empty
194
+ * `set`. Content stays proportional to what the change wrote; re-sequencing
195
+ * happens only when the order moves, and at most once per change. */
134
196
  subscribe(cb: MapSubscriber<T>): HandleUnsubscribe;
135
197
  /**
136
198
  * Report each time this container has been delivered whole: on
@@ -1 +1 @@
1
- {"version":3,"file":"handle-types.d.ts","sourceRoot":"","sources":["../src/handle-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handle-types.d.ts","sourceRoot":"","sources":["../src/handle-types.ts"],"names":[],"mappings":"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"}
package/dist/handles.d.ts CHANGED
@@ -1,24 +1,6 @@
1
1
  import { LoroMovableList, LoroMap } from './wasm-runtime.js';
2
- import { MutateBatcher } from './mutate-batching.js';
3
2
  import type { Change, ChangeOrigin, ChangeSource, HandleOwner, HandleUnsubscribe, ListDraft, ListHandle, ListSubscriber, MapHandle, MapSubscriber, OrderedMapHandle, OrderedMapPosition } from './handle-types.js';
4
3
  export type { Change, ChangeOrigin, ChangeSource, HandleOwner, ListDraft, HandleUnsubscribe, ListHandle, ListSubscriber, MapHandle, MapSubscriber, OrderedMapHandle, OrderedMapPosition, };
5
- /**
6
- * Where a root map's ADDITIONS go once the map has paged itself part-way
7
- * through a mutation.
8
- *
9
- * A mutation large enough to need paging usually starts against a map that
10
- * is not yet paged, so the decision cannot be made once at the top. The
11
- * proxy consults this on every assignment; while it declines, the mutation
12
- * runs exactly as an unpaged one does.
13
- */
14
- interface WriteDivert {
15
- take(key: string, value: unknown): boolean;
16
- holds(key: string): boolean;
17
- peek(key: string): unknown;
18
- drop(key: string): void;
19
- keys(): string[];
20
- }
21
- export declare function wrapLoroMapProxy(loroMap: LoroMap, batcher?: MutateBatcher, divert?: WriteDivert, guardKeys?: boolean): Record<string, unknown>;
22
4
  /**
23
5
  * What a ROOT map handle needs from its owning Document to present a paged
24
6
  * store. Bundled rather than passed one by one: every member is read off the
@@ -46,7 +28,21 @@ export interface PagedRootHooks {
46
28
  sessionToken(): string;
47
29
  stateVersion(): StateVersion;
48
30
  }
49
- export declare function createRootMapHandle<T>(root: LoroMap, owner: HandleOwner, paging?: PagedRootHooks): MapHandle<T>;
31
+ /**
32
+ * Hide a handle's own fields from enumeration.
33
+ *
34
+ * A handle is a VIEW onto a container, not the container, so `Object.keys` on
35
+ * one is a natural thing to reach for and it type-checks. Enumerable, it
36
+ * answers with the handle's own fields, which look enough like record keys to
37
+ * pass and are the same handful whatever the document holds, so the mistake
38
+ * reads as a small document rather than as a mistake. Hidden, the answer is
39
+ * empty, and the reader goes looking for `keys()`.
40
+ *
41
+ * Every field is declared with an initialiser, so they all exist by the time
42
+ * this runs and a later assignment keeps the descriptor this sets.
43
+ */
44
+ export declare function hideOwnFields(handle: object): void;
45
+ export declare function createRootMapHandle<T>(root: LoroMap, owner: HandleOwner, paging?: PagedRootHooks, rootKey?: string): MapHandle<T>;
50
46
  export declare function createRootListHandle<T>(root: LoroMovableList, owner: HandleOwner): ListHandle<T>;
51
47
  export declare function rebindRootMapAnchor(handle: MapHandle<unknown>, next: LoroMap): void;
52
48
  export declare function rebindRootListAnchor(handle: ListHandle<unknown>, next: LoroMovableList): void;
@@ -1 +1 @@
1
- {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,eAAe,EACf,OAAO,EAIR,MAAM,mBAAmB,CAAC;AA8B3B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAGV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,EAGjB,SAAS,EACT,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,CAAC;AAwSF;;;;;;;;GAQG;AACH,UAAU,WAAW;IAInB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAG3C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,IAAI,MAAM,EAAE,CAAC;CAClB;AAOD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAKhB,OAAO,CAAC,EAAE,aAAa,EACvB,MAAM,CAAC,EAAE,WAAW,EAKpB,SAAS,UAAQ,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8FzB;AAosED;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAYxE,MAAM,WAAW,cAAc;IAE7B,OAAO,IAAI,OAAO,CAAC;IAGnB,IAAI,IAAI,IAAI,CAAC;IAEb,YAAY,IAAI,MAAM,CAAC;IAEvB,YAAY,IAAI,YAAY,CAAC;CAC9B;AAmiDD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,WAAW,EAClB,MAAM,CAAC,EAAE,cAAc,GACtB,SAAS,CAAC,CAAC,CAAC,CAEd;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,UAAU,CAAC,CAAC,CAAC,CAEf;AAgBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAC1B,IAAI,EAAE,OAAO,GACZ,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,EAC3B,IAAI,EAAE,eAAe,GACpB,IAAI,CAEN;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAEpE;AAMD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAOD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAKD,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,WAAW,GACjB,gBAAgB,CAAC,CAAC,CAAC,CAMrB"}
1
+ {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,eAAe,EACf,OAAO,EAIR,MAAM,mBAAmB,CAAC;AAmC3B,OAAO,KAAK,EAGV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,EAGjB,SAAS,EACT,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EAEb,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,CAAC;AA8pFF;;;;;GAKG;AACH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC;AAYxE,MAAM,WAAW,cAAc;IAE7B,OAAO,IAAI,OAAO,CAAC;IAGnB,IAAI,IAAI,IAAI,CAAC;IAEb,YAAY,IAAI,MAAM,CAAC;IAEvB,YAAY,IAAI,YAAY,CAAC;CAC9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAIlD;AAkoDD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,WAAW,EAClB,MAAM,CAAC,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,CAAC,CAAC,CAAC,CAQd;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,WAAW,GACjB,UAAU,CAAC,CAAC,CAAC,CAEf;AAgBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAC1B,IAAI,EAAE,OAAO,GACZ,IAAI,CAEN;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,EAC3B,IAAI,EAAE,eAAe,GACpB,IAAI,CAEN;AAcD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAEpE;AAMD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAOD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAC/C,IAAI,CAEN;AAKD,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,KAAK,EAAE,WAAW,GACjB,gBAAgB,CAAC,CAAC,CAAC,CAMrB"}