euclid-ndk 0.2.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 (127) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +603 -0
  3. package/dist/auth/index.d.ts +18 -0
  4. package/dist/auth/index.d.ts.map +1 -0
  5. package/dist/auth/index.js +17 -0
  6. package/dist/auth/index.js.map +1 -0
  7. package/dist/auth/rfc9421.d.ts +112 -0
  8. package/dist/auth/rfc9421.d.ts.map +1 -0
  9. package/dist/auth/rfc9421.js +452 -0
  10. package/dist/auth/rfc9421.js.map +1 -0
  11. package/dist/auth/scheme.d.ts +46 -0
  12. package/dist/auth/scheme.d.ts.map +1 -0
  13. package/dist/auth/scheme.js +44 -0
  14. package/dist/auth/scheme.js.map +1 -0
  15. package/dist/auth/signable.d.ts +37 -0
  16. package/dist/auth/signable.d.ts.map +1 -0
  17. package/dist/auth/signable.js +70 -0
  18. package/dist/auth/signable.js.map +1 -0
  19. package/dist/auth/sigv4.d.ts +72 -0
  20. package/dist/auth/sigv4.d.ts.map +1 -0
  21. package/dist/auth/sigv4.js +227 -0
  22. package/dist/auth/sigv4.js.map +1 -0
  23. package/dist/credentials.d.ts +56 -0
  24. package/dist/credentials.d.ts.map +1 -0
  25. package/dist/credentials.js +135 -0
  26. package/dist/credentials.js.map +1 -0
  27. package/dist/dto/com.d.ts +101 -0
  28. package/dist/dto/com.d.ts.map +1 -0
  29. package/dist/dto/com.js +132 -0
  30. package/dist/dto/com.js.map +1 -0
  31. package/dist/dto/eag.d.ts +104 -0
  32. package/dist/dto/eag.d.ts.map +1 -0
  33. package/dist/dto/eag.js +70 -0
  34. package/dist/dto/eag.js.map +1 -0
  35. package/dist/dto/eam.d.ts +105 -0
  36. package/dist/dto/eam.d.ts.map +1 -0
  37. package/dist/dto/eam.js +98 -0
  38. package/dist/dto/eam.js.map +1 -0
  39. package/dist/dto/eap.d.ts +88 -0
  40. package/dist/dto/eap.d.ts.map +1 -0
  41. package/dist/dto/eap.js +54 -0
  42. package/dist/dto/eap.js.map +1 -0
  43. package/dist/dto/ekm.d.ts +109 -0
  44. package/dist/dto/ekm.d.ts.map +1 -0
  45. package/dist/dto/ekm.js +78 -0
  46. package/dist/dto/ekm.js.map +1 -0
  47. package/dist/dto/ekv.d.ts +73 -0
  48. package/dist/dto/ekv.d.ts.map +1 -0
  49. package/dist/dto/ekv.js +45 -0
  50. package/dist/dto/ekv.js.map +1 -0
  51. package/dist/dto/ens.d.ts +84 -0
  52. package/dist/dto/ens.d.ts.map +1 -0
  53. package/dist/dto/ens.js +72 -0
  54. package/dist/dto/ens.js.map +1 -0
  55. package/dist/dto/eqs.d.ts +160 -0
  56. package/dist/dto/eqs.d.ts.map +1 -0
  57. package/dist/dto/eqs.js +120 -0
  58. package/dist/dto/eqs.js.map +1 -0
  59. package/dist/dto/esm.d.ts +192 -0
  60. package/dist/dto/esm.d.ts.map +1 -0
  61. package/dist/dto/esm.js +147 -0
  62. package/dist/dto/esm.js.map +1 -0
  63. package/dist/dto/ess.d.ts +49 -0
  64. package/dist/dto/ess.d.ts.map +1 -0
  65. package/dist/dto/ess.js +30 -0
  66. package/dist/dto/ess.js.map +1 -0
  67. package/dist/dto/json.d.ts +24 -0
  68. package/dist/dto/json.d.ts.map +1 -0
  69. package/dist/dto/json.js +47 -0
  70. package/dist/dto/json.js.map +1 -0
  71. package/dist/errors.d.ts +40 -0
  72. package/dist/errors.d.ts.map +1 -0
  73. package/dist/errors.js +73 -0
  74. package/dist/errors.js.map +1 -0
  75. package/dist/http/client.d.ts +96 -0
  76. package/dist/http/client.d.ts.map +1 -0
  77. package/dist/http/client.js +258 -0
  78. package/dist/http/client.js.map +1 -0
  79. package/dist/index.d.ts +93 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +110 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/modules/base.d.ts +121 -0
  84. package/dist/modules/base.d.ts.map +1 -0
  85. package/dist/modules/base.js +142 -0
  86. package/dist/modules/base.js.map +1 -0
  87. package/dist/modules/eag.d.ts +166 -0
  88. package/dist/modules/eag.d.ts.map +1 -0
  89. package/dist/modules/eag.js +189 -0
  90. package/dist/modules/eag.js.map +1 -0
  91. package/dist/modules/eam.d.ts +314 -0
  92. package/dist/modules/eam.d.ts.map +1 -0
  93. package/dist/modules/eam.js +641 -0
  94. package/dist/modules/eam.js.map +1 -0
  95. package/dist/modules/eap.d.ts +204 -0
  96. package/dist/modules/eap.d.ts.map +1 -0
  97. package/dist/modules/eap.js +218 -0
  98. package/dist/modules/eap.js.map +1 -0
  99. package/dist/modules/ekm.d.ts +182 -0
  100. package/dist/modules/ekm.d.ts.map +1 -0
  101. package/dist/modules/ekm.js +228 -0
  102. package/dist/modules/ekm.js.map +1 -0
  103. package/dist/modules/ekv.d.ts +189 -0
  104. package/dist/modules/ekv.d.ts.map +1 -0
  105. package/dist/modules/ekv.js +212 -0
  106. package/dist/modules/ekv.js.map +1 -0
  107. package/dist/modules/ens.d.ts +122 -0
  108. package/dist/modules/ens.d.ts.map +1 -0
  109. package/dist/modules/ens.js +167 -0
  110. package/dist/modules/ens.js.map +1 -0
  111. package/dist/modules/eqs.d.ts +283 -0
  112. package/dist/modules/eqs.d.ts.map +1 -0
  113. package/dist/modules/eqs.js +355 -0
  114. package/dist/modules/eqs.js.map +1 -0
  115. package/dist/modules/esm.d.ts +358 -0
  116. package/dist/modules/esm.d.ts.map +1 -0
  117. package/dist/modules/esm.js +660 -0
  118. package/dist/modules/esm.js.map +1 -0
  119. package/dist/modules/ess.d.ts +96 -0
  120. package/dist/modules/ess.d.ts.map +1 -0
  121. package/dist/modules/ess.js +110 -0
  122. package/dist/modules/ess.js.map +1 -0
  123. package/dist/url.d.ts +31 -0
  124. package/dist/url.d.ts.map +1 -0
  125. package/dist/url.js +47 -0
  126. package/dist/url.js.map +1 -0
  127. package/package.json +47 -0
@@ -0,0 +1,641 @@
1
+ /**
2
+ * EAM - euclid's access management module: login, users, groups, accounts, namespaces, keys.
3
+ *
4
+ * Two objects. {@link EuclidEam} is the login builder: it collects the server, the credentials and
5
+ * the options, and hands back a session. {@link EuclidSession} is that session - the authenticated
6
+ * client every other call goes through, and the thing that holds the token and the access key the
7
+ * login produced.
8
+ *
9
+ * The split exists because logging in and being logged in need different arguments. A builder that
10
+ * also carried the operations would let a caller write `.listUsers()` on an object that has not
11
+ * authenticated yet, and a session that also carried the login options would have a namespace field
12
+ * that means one thing before login and another after.
13
+ */
14
+ import { SIGV4, SignableRequest } from "../auth/index.js";
15
+ import { emptyCredentials, isTokenValid, load as loadCredentials, save as saveCredentials, updateNamespace as updateCachedNamespace, } from "../credentials.js";
16
+ import { toAccessKey, toAccount, toCreateAccessKeyResult, toLoginResult, toNamespace, toPage, toUser, toUserGroup, } from "../dto/eam.js";
17
+ import { EuclidAuthenticationError, EuclidServiceError } from "../errors.js";
18
+ import { DEFAULT_CA_CERT_PATH, DEFAULT_TIMEOUT_MS, EuclidHttpClient } from "../http/client.js";
19
+ import { authorityOf, hostHeaderOf, schemeOf, stripTrailingSlash } from "../url.js";
20
+ import { listPayload } from "./base.js";
21
+ // This module imports the clients and they import nothing of it but its types, which is what keeps the
22
+ // two-way relationship - a client needs the session it authenticates as, a session hands out the
23
+ // clients - out of the runtime module graph. See EuclidSession.alwaysSigns for the one place that
24
+ // would otherwise have put it back.
25
+ import { EuclidEag } from "./eag.js";
26
+ import { EuclidEap } from "./eap.js";
27
+ import { EuclidEkm } from "./ekm.js";
28
+ import { EuclidEkv } from "./ekv.js";
29
+ import { EuclidEns } from "./ens.js";
30
+ import { EuclidEqs } from "./eqs.js";
31
+ import { EuclidEsm } from "./esm.js";
32
+ import { EuclidEss } from "./ess.js";
33
+ export const TARGET = "eam";
34
+ /**
35
+ * Authenticate with a signature when there is an access key to sign with, and with the bearer token
36
+ * otherwise. euclid accepts either for every action (`HttpActionServer::Authenticate`).
37
+ */
38
+ export const AUTH_AUTO = "auto";
39
+ /**
40
+ * Always sign. Fails loudly if the session has no access key, rather than quietly falling back to a
41
+ * token - which is what a caller who asked for signatures wants to know about.
42
+ */
43
+ export const AUTH_SIGNATURE = "signature";
44
+ /** Always present the bearer token, even when an access key is available. */
45
+ export const AUTH_BEARER = "bearer";
46
+ /**
47
+ * Builder for authenticating against a euclid server.
48
+ *
49
+ * ```ts
50
+ * const session = await EuclidEam.forServer("https://euclid.example.com")
51
+ * .credentials("jens", "secret")
52
+ * .login();
53
+ * ```
54
+ */
55
+ export class EuclidEam {
56
+ #baseUrl;
57
+ #loginPath = "/";
58
+ #username = null;
59
+ #email = null;
60
+ #password = null;
61
+ #namespace = null;
62
+ // Applied only when the file is actually there, so this default is a no-op on a machine with no
63
+ // euclid deployment and the right thing on one that has.
64
+ #caCertPath = DEFAULT_CA_CERT_PATH;
65
+ #verify = true;
66
+ #timeoutMs = DEFAULT_TIMEOUT_MS;
67
+ #signingScheme = SIGV4;
68
+ #auth = AUTH_AUTO;
69
+ #useCache = true;
70
+ constructor(baseUrl) {
71
+ this.#baseUrl = stripTrailingSlash(baseUrl);
72
+ }
73
+ /** Targets a euclid server, e.g. `https://euclid.example.com`. */
74
+ static forServer(baseUrl) {
75
+ if (!baseUrl)
76
+ throw new Error("baseUrl must not be empty");
77
+ return new EuclidEam(baseUrl);
78
+ }
79
+ // -- builder ---------------------------------------------------------------------------------
80
+ /** The user ID to log in as. */
81
+ username(username) {
82
+ this.#username = username;
83
+ return this;
84
+ }
85
+ /**
86
+ * The email address to log in with, when there is no user ID.
87
+ *
88
+ * The server resolves the user by ID first and only falls back to the email, so setting both
89
+ * silently ignores the email; {@link login} sends whichever one identifies the account.
90
+ */
91
+ email(email) {
92
+ this.#email = email;
93
+ return this;
94
+ }
95
+ /** The password. */
96
+ password(password) {
97
+ this.#password = password;
98
+ return this;
99
+ }
100
+ /** User ID and password together. */
101
+ credentials(username, password) {
102
+ return this.username(username).password(password);
103
+ }
104
+ /**
105
+ * The namespace to make active once login succeeds.
106
+ *
107
+ * Applied with a follow-up `change-namespace` call, mirroring euclid-cli's `eam login
108
+ * --namespace`, and applied whether the login was fresh or served from the cache - a cached
109
+ * session may have been established before this was ever asked for, or scoped to another
110
+ * namespace.
111
+ */
112
+ namespace(namespace) {
113
+ this.#namespace = namespace;
114
+ return this;
115
+ }
116
+ /** The path to post the login to. `/` unless a deployment puts the gateway elsewhere. */
117
+ loginPath(path) {
118
+ this.#loginPath = path.startsWith("/") ? path : `/${path}`;
119
+ return this;
120
+ }
121
+ /** A PEM CA certificate to trust alongside the system store, or null for the store alone. */
122
+ caCertPath(path) {
123
+ this.#caCertPath = path;
124
+ return this;
125
+ }
126
+ /** Whether to verify the server's certificate. Turn it off for development servers only. */
127
+ verify(verify) {
128
+ this.#verify = verify;
129
+ return this;
130
+ }
131
+ /** How long to wait for a response, in milliseconds. */
132
+ timeout(milliseconds) {
133
+ this.#timeoutMs = milliseconds;
134
+ return this;
135
+ }
136
+ /**
137
+ * Which signing scheme the session signs with. SigV4 unless told otherwise, as euclid's server
138
+ * has understood that one from the start.
139
+ */
140
+ signingScheme(scheme) {
141
+ this.#signingScheme = scheme;
142
+ return this;
143
+ }
144
+ /** How the session authenticates: {@link AUTH_AUTO}, {@link AUTH_SIGNATURE} or {@link AUTH_BEARER}. */
145
+ auth(mode) {
146
+ if (mode !== AUTH_AUTO && mode !== AUTH_SIGNATURE && mode !== AUTH_BEARER) {
147
+ throw new Error(`auth must be one of "${AUTH_AUTO}", "${AUTH_SIGNATURE}", "${AUTH_BEARER}"`);
148
+ }
149
+ this.#auth = mode;
150
+ return this;
151
+ }
152
+ /**
153
+ * Whether `~/.euclid/credentials` may be read and written. On by default, which is what makes a
154
+ * login shared with euclid-cli, euclid-jdk and euclid-pdk.
155
+ */
156
+ useCache(useCache) {
157
+ this.#useCache = useCache;
158
+ return this;
159
+ }
160
+ // -- login -----------------------------------------------------------------------------------
161
+ /**
162
+ * Authenticates, and answers with the session every other call goes through.
163
+ *
164
+ * A still-valid cached session for this server is reused rather than re-authenticating, so
165
+ * calling this repeatedly costs nothing after the first time. Pass `useCache(false)` to force a
166
+ * fresh login.
167
+ *
168
+ * @throws {EuclidAuthenticationError} if the server refuses the credentials.
169
+ * @throws {Error} if no password, or neither a username nor an email, was set and there is no
170
+ * cached session to fall back on.
171
+ */
172
+ async login() {
173
+ const cached = await this.#cachedSession();
174
+ if (cached !== null) {
175
+ if (this.#namespace !== null && this.#namespace !== cached.namespace) {
176
+ await cached.changeNamespace(this.#namespace);
177
+ }
178
+ return cached;
179
+ }
180
+ if (!this.#username && !this.#email)
181
+ throw new Error("username or email must be set before calling login()");
182
+ if (this.#password === null)
183
+ throw new Error("password must be set before calling login()");
184
+ // Only one identifier goes out: the server takes the user ID when it is present and only falls
185
+ // back to the email, so sending both would silently ignore the email.
186
+ const body = JSON.stringify({
187
+ userId: this.#username ?? "",
188
+ password: this.#password,
189
+ email: this.#username ? "" : (this.#email ?? ""),
190
+ });
191
+ const client = new EuclidHttpClient({
192
+ caCertPath: this.#caCertPath,
193
+ timeoutMs: this.#timeoutMs,
194
+ verify: this.#verify,
195
+ });
196
+ let response;
197
+ try {
198
+ response = await client.post(this.#baseUrl + this.#loginPath, body, TARGET, "login", {
199
+ "content-type": "application/json",
200
+ host: hostHeaderOf(this.#baseUrl),
201
+ });
202
+ }
203
+ finally {
204
+ client.close();
205
+ }
206
+ if (!response.ok)
207
+ throw new EuclidAuthenticationError(response.status, response.text);
208
+ const result = toLoginResult(response.json());
209
+ const session = new EuclidSession({
210
+ baseUrl: this.#baseUrl,
211
+ token: result.token,
212
+ userId: result.metadata.user,
213
+ accountId: result.metadata.accountId,
214
+ region: result.metadata.region,
215
+ accessKeyId: result.accessKeyId,
216
+ secretAccessKey: result.secretAccessKey,
217
+ isAdmin: result.isAdmin,
218
+ namespace: "",
219
+ raw: result.raw,
220
+ caCertPath: this.#caCertPath,
221
+ verify: this.#verify,
222
+ timeoutMs: this.#timeoutMs,
223
+ signingScheme: this.#signingScheme,
224
+ auth: this.#auth,
225
+ cache: this.#useCache,
226
+ });
227
+ if (this.#namespace)
228
+ await session.changeNamespace(this.#namespace);
229
+ if (this.#useCache)
230
+ await saveCredentials(session.toCachedCredentials());
231
+ return session;
232
+ }
233
+ /**
234
+ * A session rebuilt from `~/.euclid/credentials`, if one is cached for this server and its token
235
+ * has not expired.
236
+ */
237
+ async #cachedSession() {
238
+ if (!this.#useCache)
239
+ return null;
240
+ const cached = await loadCredentials();
241
+ if (cached === null || !cached.token || cached.baseUrl !== this.#baseUrl)
242
+ return null;
243
+ if (!isTokenValid(cached.token))
244
+ return null;
245
+ return new EuclidSession({
246
+ baseUrl: this.#baseUrl,
247
+ token: cached.token,
248
+ userId: cached.userId,
249
+ accountId: cached.accountId,
250
+ region: cached.region,
251
+ accessKeyId: cached.accessKeyId,
252
+ secretAccessKey: cached.secretAccessKey,
253
+ isAdmin: cached.isAdmin,
254
+ namespace: cached.namespace,
255
+ raw: cached.raw,
256
+ caCertPath: this.#caCertPath,
257
+ verify: this.#verify,
258
+ timeoutMs: this.#timeoutMs,
259
+ signingScheme: this.#signingScheme,
260
+ auth: this.#auth,
261
+ cache: this.#useCache,
262
+ });
263
+ }
264
+ }
265
+ /**
266
+ * An authenticated session, and every EAM operation that needs one.
267
+ *
268
+ * Holds two credentials, because the server accepts two. The bearer token is what a login always
269
+ * produces; the access key and secret are what it produces when the user has one, and they are what
270
+ * a signature is made with. Which of the two a request presents is decided per session by
271
+ * {@link EuclidSession.auth} - see {@link AUTH_AUTO}.
272
+ *
273
+ * Sessions are mutable: {@link EuclidSession.changeNamespace} changes this session rather than
274
+ * answering with a new one, since the namespace is a property of what the caller is doing next
275
+ * rather than of the login.
276
+ */
277
+ export class EuclidSession {
278
+ baseUrl;
279
+ token;
280
+ userId;
281
+ accountId;
282
+ region;
283
+ accessKeyId;
284
+ secretAccessKey;
285
+ isAdmin;
286
+ namespace;
287
+ raw;
288
+ signingScheme;
289
+ auth;
290
+ /**
291
+ * Where the bearer token comes from, when it does not simply come from {@link EuclidSession.token}.
292
+ *
293
+ * A process that runs for days holds a token that does not last that long. euclid rewrites an
294
+ * application's credentials file before the token in it expires, so an application that cached the
295
+ * first token it saw would start collecting 401s about an hour in. Setting this to something that
296
+ * re-reads that file makes the session follow the rotation, and is what the retry on "credentials
297
+ * expired" then has something new to retry with.
298
+ */
299
+ tokenProvider = null;
300
+ #cache;
301
+ #hostHeader;
302
+ #scheme;
303
+ // Kept so that a module client this session hands out reaches the same server on the same terms,
304
+ // rather than having to be told the connection settings again.
305
+ #connection;
306
+ #modules = new Map();
307
+ #client;
308
+ constructor(options) {
309
+ this.baseUrl = options.baseUrl;
310
+ this.token = options.token;
311
+ this.userId = options.userId;
312
+ this.accountId = options.accountId;
313
+ this.region = options.region;
314
+ this.accessKeyId = options.accessKeyId;
315
+ this.secretAccessKey = options.secretAccessKey;
316
+ this.isAdmin = options.isAdmin;
317
+ this.namespace = options.namespace;
318
+ this.raw = options.raw;
319
+ this.signingScheme = options.signingScheme;
320
+ this.auth = options.auth;
321
+ this.#cache = options.cache;
322
+ this.#hostHeader = hostHeaderOf(options.baseUrl);
323
+ this.#scheme = schemeOf(options.baseUrl);
324
+ this.#connection = { caCertPath: options.caCertPath, timeoutMs: options.timeoutMs, verify: options.verify };
325
+ this.#client = this.newClient((action, body) => this.authHeaders(TARGET, action, body));
326
+ }
327
+ // -- identity --------------------------------------------------------------------------------
328
+ /** This session in the shape `~/.euclid/credentials` holds it. */
329
+ toCachedCredentials() {
330
+ return {
331
+ ...emptyCredentials(),
332
+ token: this.token,
333
+ userId: this.userId,
334
+ accountId: this.accountId,
335
+ region: this.region,
336
+ accessKeyId: this.accessKeyId,
337
+ secretAccessKey: this.secretAccessKey,
338
+ isAdmin: this.isAdmin,
339
+ baseUrl: this.baseUrl,
340
+ namespace: this.namespace || "",
341
+ };
342
+ }
343
+ /** The `@authority` this session's signatures are made over, for diagnostics. */
344
+ get authority() {
345
+ return authorityOf(this.baseUrl);
346
+ }
347
+ /**
348
+ * Whether this session signs even the requests that would otherwise present the token.
349
+ *
350
+ * What {@link AUTH_SIGNATURE} means to a module whose action carries raw bytes: those present the
351
+ * token by default, and a session that asked for signatures gets them anyway. Asked of the session
352
+ * rather than read off {@link auth} by each module client, so that "what this mode means" is decided
353
+ * in one place - and so that a module client needs no value out of this module at all, which is what
354
+ * keeps the import between the two one-directional.
355
+ */
356
+ get alwaysSigns() {
357
+ return this.auth === AUTH_SIGNATURE;
358
+ }
359
+ /** Releases the connections this session was holding, its module clients' included. */
360
+ close() {
361
+ this.#client.close();
362
+ for (const module of this.#modules.values())
363
+ module.close();
364
+ this.#modules.clear();
365
+ }
366
+ // -- the other modules -----------------------------------------------------------------------
367
+ /**
368
+ * ESM - euclid's storage module - on this session's credentials.
369
+ *
370
+ * The same client each time, so an application that reaches for this inside a loop pays for one
371
+ * connection rather than one per iteration. It follows this session: a {@link changeNamespace}
372
+ * between two calls scopes the second one, and a {@link tokenProvider} set here is the token it
373
+ * presents.
374
+ */
375
+ esm() {
376
+ return this.#module("esm", () => new EuclidEsm(this));
377
+ }
378
+ /** EQS - euclid's queue module - on this session's credentials. */
379
+ eqs() {
380
+ return this.#module("eqs", () => new EuclidEqs(this));
381
+ }
382
+ /** ENS - euclid's notification module - on this session's credentials. */
383
+ ens() {
384
+ return this.#module("ens", () => new EuclidEns(this));
385
+ }
386
+ /** EKM - euclid's key management module - on this session's credentials. */
387
+ ekm() {
388
+ return this.#module("ekm", () => new EuclidEkm(this));
389
+ }
390
+ /** EKV - euclid's key-value store - on this session's credentials. */
391
+ ekv() {
392
+ return this.#module("ekv", () => new EuclidEkv(this));
393
+ }
394
+ /** EAP - euclid's application platform - on this session's credentials. */
395
+ eap() {
396
+ return this.#module("eap", () => new EuclidEap(this));
397
+ }
398
+ /** ESS - euclid's secret store - on this session's credentials. */
399
+ ess() {
400
+ return this.#module("ess", () => new EuclidEss(this));
401
+ }
402
+ /** EAG - euclid's API gateway - on this session's credentials. */
403
+ eag() {
404
+ return this.#module("eag", () => new EuclidEag(this));
405
+ }
406
+ /** One client per module rather than one per call, built the first time it is asked for. */
407
+ #module(name, factory) {
408
+ const existing = this.#modules.get(name);
409
+ if (existing !== undefined)
410
+ return existing;
411
+ const client = factory();
412
+ this.#modules.set(name, client);
413
+ return client;
414
+ }
415
+ // -- users -----------------------------------------------------------------------------------
416
+ /** One page of users, and how many exist in total. */
417
+ async listUsers(options = {}) {
418
+ return toPage(await this.call("list-users", listPayload(options, "userId")), "users", toUser);
419
+ }
420
+ /** Creates a user. `accountId` and `region` default to this session's own. */
421
+ async register(userId, password, options = {}) {
422
+ const response = await this.call("register", {
423
+ userId,
424
+ password,
425
+ email: options.email ?? "",
426
+ accountId: options.accountId || this.accountId,
427
+ region: options.region || this.region,
428
+ isAdmin: options.isAdmin ?? false,
429
+ });
430
+ return toUser(response.user);
431
+ }
432
+ /** Deletes a user. */
433
+ async deleteUser(userId) {
434
+ await this.call("delete-user", { userId });
435
+ }
436
+ // -- namespace scoping -----------------------------------------------------------------------
437
+ /**
438
+ * Switches the namespace every namespace-scoped call is restricted to, until changed again.
439
+ *
440
+ * The server validates it against the current account and the caller's grants, so this is a round
441
+ * trip rather than a local assignment. An empty string clears the scope.
442
+ *
443
+ * Answers with this session, so it can be chained onto a login.
444
+ */
445
+ async changeNamespace(namespace) {
446
+ await this.call("change-namespace", { namespace });
447
+ this.namespace = namespace;
448
+ if (this.#cache)
449
+ await updateCachedNamespace(this.baseUrl, namespace);
450
+ return this;
451
+ }
452
+ // -- access keys -----------------------------------------------------------------------------
453
+ /**
454
+ * Creates an access key for this session's user.
455
+ *
456
+ * The secret comes back here and nowhere else - {@link listAccessKeys} will never show it again -
457
+ * so a caller that does not store it has to create another key.
458
+ */
459
+ async createAccessKey() {
460
+ return toCreateAccessKeyResult(await this.call("create-access-key"));
461
+ }
462
+ /** This user's own access keys, without their secrets. */
463
+ async listAccessKeys() {
464
+ const response = await this.call("list-access-keys");
465
+ const keys = response.accessKeys;
466
+ return Array.isArray(keys) ? keys.map(toAccessKey) : [];
467
+ }
468
+ /** Deletes one of this user's own access keys. */
469
+ async deleteAccessKey(accessKeyId) {
470
+ await this.call("delete-access-key", { accessKeyId });
471
+ }
472
+ // -- user groups -----------------------------------------------------------------------------
473
+ /** Creates an empty user group. Administrator only. */
474
+ async createUserGroup(name, description = "") {
475
+ const response = await this.call("create-user-group", { name, description });
476
+ return toUserGroup(response.userGroup);
477
+ }
478
+ /** One page of user groups, and how many exist in total. */
479
+ async listUserGroups(options = {}) {
480
+ return toPage(await this.call("list-user-groups", listPayload(options, "name")), "userGroups", toUserGroup);
481
+ }
482
+ /** Adds a user to a group. Both are ERNs. */
483
+ async addUserToUserGroup(userGroup, user) {
484
+ await this.call("user-group-add-user", { userGroup, user });
485
+ }
486
+ /** Removes a user from a group. Both are ERNs. */
487
+ async removeUserFromUserGroup(userGroup, user) {
488
+ await this.call("user-group-remove-user", { userGroup, user });
489
+ }
490
+ /** Deletes a user group. Administrator only. */
491
+ async deleteUserGroup(name) {
492
+ await this.call("delete-user-group", { name });
493
+ }
494
+ // -- accounts --------------------------------------------------------------------------------
495
+ /**
496
+ * Creates an account. Administrator only - account creation is platform-level and is not
497
+ * delegated to account owners.
498
+ */
499
+ async createAccount(accountId, name, description = "") {
500
+ const response = await this.call("create-account", { accountId, name, description });
501
+ return toAccount(response.account);
502
+ }
503
+ /** One page of accounts, and how many exist in total. */
504
+ async listAccounts(options = {}) {
505
+ return toPage(await this.call("list-accounts", listPayload(options, "accountId")), "accounts", toAccount);
506
+ }
507
+ /** Deletes an account. Administrator only, and it must have no namespaces or grants left. */
508
+ async deleteAccount(accountId) {
509
+ await this.call("delete-account", { accountId });
510
+ }
511
+ // -- namespaces ------------------------------------------------------------------------------
512
+ /** Creates a namespace under an account. Requires admin rights on that account. */
513
+ async createNamespace(accountId, name, description = "") {
514
+ const response = await this.call("create-namespace", { accountId, name, description });
515
+ return toNamespace(response.namespace);
516
+ }
517
+ /** One page of an account's namespaces, and how many exist in total. */
518
+ async listNamespaces(accountId, options = {}) {
519
+ const payload = { accountId, ...listPayload(options, "name") };
520
+ return toPage(await this.call("list-namespaces", payload), "namespaces", toNamespace);
521
+ }
522
+ /** Deletes a namespace. Requires admin rights on the account, and no grants may remain. */
523
+ async deleteNamespace(accountId, name) {
524
+ await this.call("delete-namespace", { accountId, name });
525
+ }
526
+ /** Grants a user access to a namespace. Requires admin rights on the account. */
527
+ async grantNamespaceAccess(user, accountId, namespace) {
528
+ await this.call("grant-namespace-access", { user, accountId, namespace });
529
+ }
530
+ /** Revokes a user's access to a namespace. Requires admin rights on the account. */
531
+ async revokeNamespaceAccess(user, accountId, namespace) {
532
+ await this.call("revoke-namespace-access", { user, accountId, namespace });
533
+ }
534
+ // -- monitoring ------------------------------------------------------------------------------
535
+ /**
536
+ * EAM's own metrics, as the server collects them. Answered unparsed - the shape belongs to the
537
+ * monitoring module rather than to EAM.
538
+ */
539
+ async metrics() {
540
+ return this.call("get-metrics");
541
+ }
542
+ // -- transport -------------------------------------------------------------------------------
543
+ /**
544
+ * Sends any EAM action, for one this SDK does not wrap yet.
545
+ *
546
+ * Public on purpose: a server that gains an action should be reachable without waiting for a
547
+ * release here.
548
+ */
549
+ async call(action, payload = {}, timeoutMs) {
550
+ const body = Buffer.from(JSON.stringify(payload), "utf8");
551
+ const response = await this.#client.post(`${this.baseUrl}/`, body, TARGET, action, this.requestHeaders(TARGET, action, body), timeoutMs);
552
+ if (!response.ok)
553
+ throw new EuclidServiceError(TARGET, action, response.status, response.text);
554
+ const result = response.json();
555
+ return result !== null && typeof result === "object" && !Array.isArray(result)
556
+ ? result
557
+ : { result };
558
+ }
559
+ /**
560
+ * Every header a request to one of this session's modules goes out with, signature included.
561
+ *
562
+ * Takes the target rather than assuming EAM because the target is signed: a client for another
563
+ * module has to sign for *its* module, and signing here rather than in each module client is what
564
+ * keeps one implementation of how this session authenticates.
565
+ */
566
+ requestHeaders(target, action, body) {
567
+ return { ...this.routingHeaders(), ...this.authHeaders(target, action, body) };
568
+ }
569
+ /** Who is asking and what they are scoped to. Signed, apart from the namespace. */
570
+ routingHeaders() {
571
+ const headers = { "content-type": "application/json", host: this.#hostHeader };
572
+ if (this.region)
573
+ headers["x-euclid-region"] = this.region;
574
+ if (this.accountId)
575
+ headers["x-euclid-account-id"] = this.accountId;
576
+ if (this.userId)
577
+ headers["x-euclid-user-id"] = this.userId;
578
+ // Not covered by either signature scheme - see the note in auth/rfc9421.ts.
579
+ if (this.namespace)
580
+ headers["x-euclid-namespace"] = this.namespace;
581
+ return headers;
582
+ }
583
+ /**
584
+ * The authentication headers alone, rebuilt per request.
585
+ *
586
+ * Rebuilt rather than cached because a signature is only valid around the moment it was made, and
587
+ * because this is what the client calls again when the server says the credentials it just
588
+ * presented had expired.
589
+ */
590
+ authHeaders(target, action, body) {
591
+ if (!this.#shouldSign())
592
+ return this.bearerHeaders();
593
+ const request = new SignableRequest("POST", "/");
594
+ request.headersFrom(this.routingHeaders());
595
+ request.header("x-euclid-target", target);
596
+ request.header("x-euclid-action", action);
597
+ request.setBody(body);
598
+ request.setScheme(this.#scheme);
599
+ this.signingScheme.sign(request, this.accessKeyId, this.secretAccessKey, this.region, target);
600
+ const headers = {};
601
+ for (const name of this.signingScheme.signatureHeaderNames())
602
+ headers[name] = request.get(name);
603
+ return headers;
604
+ }
605
+ /**
606
+ * The bearer token, presented as an `Authorization` header.
607
+ *
608
+ * Its own method because a request is not always free to sign: a module whose action carries raw
609
+ * bytes presents the token whatever this session would otherwise do.
610
+ */
611
+ bearerHeaders() {
612
+ return { authorization: `Bearer ${this.currentToken()}` };
613
+ }
614
+ /** The bearer token to present now - {@link tokenProvider}'s, or {@link token}. */
615
+ currentToken() {
616
+ return this.tokenProvider === null ? this.token : this.tokenProvider();
617
+ }
618
+ /**
619
+ * A connection to this session's server, on the TLS and timeout settings it logged in with.
620
+ *
621
+ * The factory is what a request whose credentials expired in flight is rebuilt with, so a module
622
+ * client passes the one that rebuilds *its* headers - see {@link authHeaders}.
623
+ */
624
+ newClient(headerFactory) {
625
+ return new EuclidHttpClient(this.#connection).headerFactory(headerFactory);
626
+ }
627
+ #shouldSign() {
628
+ const hasKey = Boolean(this.accessKeyId && this.secretAccessKey);
629
+ if (this.auth === AUTH_BEARER)
630
+ return false;
631
+ if (this.auth === AUTH_SIGNATURE) {
632
+ if (!hasKey) {
633
+ throw new Error("auth='signature' was requested but this session has no access key - the login returned none, " +
634
+ "so there is nothing to sign with");
635
+ }
636
+ return true;
637
+ }
638
+ return hasKey;
639
+ }
640
+ }
641
+ //# sourceMappingURL=eam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eam.js","sourceRoot":"","sources":["../../src/modules/eam.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,EAAE,eAAe,EAAsB,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAEL,gBAAgB,EAChB,YAAY,EACZ,IAAI,IAAI,eAAe,EACvB,IAAI,IAAI,eAAe,EACvB,eAAe,IAAI,qBAAqB,GACzC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAML,WAAW,EACX,SAAS,EACT,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,GAGZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,gBAAgB,EAAsB,MAAM,mBAAmB,CAAC;AACnH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpF,OAAO,EAAE,WAAW,EAAuC,MAAM,WAAW,CAAC;AAC7E,uGAAuG;AACvG,iGAAiG;AACjG,kGAAkG;AAClG,oCAAoC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAIrC,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC;AAE5B;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAChC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAC1C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAyBpC;;;;;;;;GAQG;AACH,MAAM,OAAO,SAAS;IACpB,QAAQ,CAAS;IACjB,UAAU,GAAG,GAAG,CAAC;IACjB,SAAS,GAAkB,IAAI,CAAC;IAChC,MAAM,GAAkB,IAAI,CAAC;IAC7B,SAAS,GAAkB,IAAI,CAAC;IAChC,UAAU,GAAkB,IAAI,CAAC;IACjC,gGAAgG;IAChG,yDAAyD;IACzD,WAAW,GAAkB,oBAAoB,CAAC;IAClD,OAAO,GAAG,IAAI,CAAC;IACf,UAAU,GAAG,kBAAkB,CAAC;IAChC,cAAc,GAAkB,KAAK,CAAC;IACtC,KAAK,GAAa,SAAS,CAAC;IAC5B,SAAS,GAAG,IAAI,CAAC;IAEjB,YAAY,OAAe;QACzB,IAAI,CAAC,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,kEAAkE;IAClE,MAAM,CAAC,SAAS,CAAC,OAAe;QAC9B,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC3D,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,+FAA+F;IAE/F,gCAAgC;IAChC,QAAQ,CAAC,QAAgB;QACvB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oBAAoB;IACpB,QAAQ,CAAC,QAAgB;QACvB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,WAAW,CAAC,QAAgB,EAAE,QAAgB;QAC5C,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,SAAiB;QACzB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yFAAyF;IACzF,SAAS,CAAC,IAAY;QACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6FAA6F;IAC7F,UAAU,CAAC,IAAmB;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4FAA4F;IAC5F,MAAM,CAAC,MAAe;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wDAAwD;IACxD,OAAO,CAAC,YAAoB;QAC1B,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,MAAqB;QACjC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uGAAuG;IACvG,IAAI,CAAC,IAAc;QACjB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,wBAAwB,SAAS,OAAO,cAAc,OAAO,WAAW,GAAG,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,QAAiB;QACxB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+FAA+F;IAE/F;;;;;;;;;;OAUG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrE,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC7G,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAE5F,+FAA+F;QAC/F,sEAAsE;QACtE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,MAAM,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YAC5B,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;SACjD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC;YAClC,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,MAAM,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;gBACnF,cAAc,EAAE,kBAAkB;gBAClC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,yBAAyB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEtF,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC;YAChC,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;YAC5B,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;YACpC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;YAC9B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,EAAE;YACb,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,KAAK,EAAE,IAAI,CAAC,SAAS;SACtB,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,UAAU;YAAE,MAAM,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,IAAI,IAAI,CAAC,SAAS;YAAE,MAAM,eAAe,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACzE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;QACvC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QACtF,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7C,OAAO,IAAI,aAAa,CAAC;YACvB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,KAAK,EAAE,IAAI,CAAC,SAAS;SACtB,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,aAAa;IACf,OAAO,CAAS;IACzB,KAAK,CAAS;IACL,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,MAAM,CAAS;IACf,WAAW,CAAS;IACpB,eAAe,CAAS;IACxB,OAAO,CAAU;IAC1B,SAAS,CAAS;IACT,GAAG,CAA0B;IACtC,aAAa,CAAgB;IACpB,IAAI,CAAW;IAExB;;;;;;;;OAQG;IACH,aAAa,GAA0B,IAAI,CAAC;IAEnC,MAAM,CAAU;IAChB,WAAW,CAAS;IACpB,OAAO,CAAS;IACzB,iGAAiG;IACjG,+DAA+D;IACtD,WAAW,CAAoE;IAC/E,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC3C,OAAO,CAAmB;IAEnC,YAAY,OAAuB;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAEzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QAC5G,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1F,CAAC;IAED,+FAA+F;IAE/F,kEAAkE;IAClE,mBAAmB;QACjB,OAAO;YACL,GAAG,gBAAgB,EAAE;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;SAChC,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,IAAI,SAAS;QACX,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;;OAQG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;IACtC,CAAC;IAED,uFAAuF;IACvF,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC5D,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,+FAA+F;IAE/F;;;;;;;OAOG;IACH,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,mEAAmE;IACnE,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,0EAA0E;IAC1E,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,4EAA4E;IAC5E,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,sEAAsE;IACtE,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,2EAA2E;IAC3E,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,mEAAmE;IACnE,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,kEAAkE;IAClE,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,4FAA4F;IAC5F,OAAO,CAAyB,IAAY,EAAE,OAAgB;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAa,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+FAA+F;IAE/F,sDAAsD;IACtD,KAAK,CAAC,SAAS,CAAC,UAAuB,EAAE;QACvC,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAChG,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,QAAQ,CACZ,MAAc,EACd,QAAgB,EAChB,UAAsF,EAAE;QAExF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAC3C,MAAM;YACN,QAAQ;YACR,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;YACrC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;SAClC,CAAC,CAAC;QACH,OAAO,MAAM,CAAE,QAA+B,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,sBAAsB;IACtB,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,+FAA+F;IAE/F;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,qBAAqB,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+FAA+F;IAE/F;;;;;OAKG;IACH,KAAK,CAAC,eAAe;QACnB,OAAO,uBAAuB,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,cAAc;QAClB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACrD,MAAM,IAAI,GAAI,QAAqC,CAAC,UAAU,CAAC;QAC/D,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,eAAe,CAAC,WAAmB;QACvC,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,+FAA+F;IAE/F,uDAAuD;IACvD,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,WAAW,GAAG,EAAE;QAClD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7E,OAAO,WAAW,CAAE,QAAoC,CAAC,SAAS,CAAC,CAAC;IACtE,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,cAAc,CAAC,UAAuB,EAAE;QAC5C,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC9G,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,kBAAkB,CAAC,SAAiB,EAAE,IAAY;QACtD,MAAM,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,uBAAuB,CAAC,SAAiB,EAAE,IAAY;QAC3D,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,gDAAgD;IAChD,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,+FAA+F;IAE/F;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,IAAY,EAAE,WAAW,GAAG,EAAE;QACnE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACrF,OAAO,SAAS,CAAE,QAAkC,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,YAAY,CAAC,UAAuB,EAAE;QAC1C,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAC5G,CAAC;IAED,6FAA6F;IAC7F,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,+FAA+F;IAE/F,mFAAmF;IACnF,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,IAAY,EAAE,WAAW,GAAG,EAAE;QACrE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACvF,OAAO,WAAW,CAAE,QAAoC,CAAC,SAAS,CAAC,CAAC;IACtE,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,UAAuB,EAAE;QAC/D,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/D,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACxF,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,IAAY;QACnD,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,oBAAoB,CAAC,IAAY,EAAE,SAAiB,EAAE,SAAiB;QAC3E,MAAM,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,qBAAqB,CAAC,IAAY,EAAE,SAAiB,EAAE,SAAiB;QAC5E,MAAM,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,+FAA+F;IAE/F;;;OAGG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;IAED,+FAA+F;IAE/F;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CACR,MAAc,EACd,UAAmC,EAAE,EACrC,SAAkB;QAElB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CACtC,GAAG,IAAI,CAAC,OAAO,GAAG,EAClB,IAAI,EACJ,MAAM,EACN,MAAM,EACN,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EACzC,SAAS,CACV,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE/F,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5E,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,MAAc,EAAE,MAAc,EAAE,IAAY;QACzD,OAAO,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;IACjF,CAAC;IAED,mFAAmF;IACnF,cAAc;QACZ,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;QACvG,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1D,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QACpE,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3D,4EAA4E;QAC5E,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QACnE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,MAAc,EAAE,MAAc,EAAE,IAAY;QACtD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9F,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChG,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACH,aAAa;QACX,OAAO,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED,mFAAmF;IACnF,YAAY;QACV,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,aAA4B;QACpC,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC7E,CAAC;IAED,WAAW;QACT,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,+FAA+F;oBAC7F,kCAAkC,CACrC,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}