latchkey 3.6.0 → 3.8.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 (77) hide show
  1. package/dist/src/oauthUtils.d.ts +2 -2
  2. package/dist/src/oauthUtils.d.ts.map +1 -1
  3. package/dist/src/oauthUtils.js +36 -15
  4. package/dist/src/oauthUtils.js.map +1 -1
  5. package/dist/src/playwrightUtils.d.ts +57 -0
  6. package/dist/src/playwrightUtils.d.ts.map +1 -1
  7. package/dist/src/playwrightUtils.js +247 -8
  8. package/dist/src/playwrightUtils.js.map +1 -1
  9. package/dist/src/serviceRegistry.d.ts.map +1 -1
  10. package/dist/src/serviceRegistry.js +3 -1
  11. package/dist/src/serviceRegistry.js.map +1 -1
  12. package/dist/src/services/core/base.d.ts +55 -16
  13. package/dist/src/services/core/base.d.ts.map +1 -1
  14. package/dist/src/services/core/base.js +119 -31
  15. package/dist/src/services/core/base.js.map +1 -1
  16. package/dist/src/services/fastmail-dav.d.ts +55 -0
  17. package/dist/src/services/fastmail-dav.d.ts.map +1 -0
  18. package/dist/src/services/fastmail-dav.js +98 -0
  19. package/dist/src/services/fastmail-dav.js.map +1 -0
  20. package/dist/src/services/fastmail.d.ts +79 -0
  21. package/dist/src/services/fastmail.d.ts.map +1 -0
  22. package/dist/src/services/fastmail.js +298 -0
  23. package/dist/src/services/fastmail.js.map +1 -0
  24. package/dist/src/services/github.d.ts +2 -1
  25. package/dist/src/services/github.d.ts.map +1 -1
  26. package/dist/src/services/github.js +13 -0
  27. package/dist/src/services/github.js.map +1 -1
  28. package/dist/src/services/huggingface.d.ts +2 -1
  29. package/dist/src/services/huggingface.d.ts.map +1 -1
  30. package/dist/src/services/huggingface.js +13 -0
  31. package/dist/src/services/huggingface.js.map +1 -1
  32. package/dist/src/services/index.d.ts +2 -0
  33. package/dist/src/services/index.d.ts.map +1 -1
  34. package/dist/src/services/index.js +2 -0
  35. package/dist/src/services/index.js.map +1 -1
  36. package/dist/src/services/linear.d.ts +2 -1
  37. package/dist/src/services/linear.d.ts.map +1 -1
  38. package/dist/src/services/linear.js +14 -0
  39. package/dist/src/services/linear.js.map +1 -1
  40. package/dist/src/services/ngrok.d.ts +2 -1
  41. package/dist/src/services/ngrok.d.ts.map +1 -1
  42. package/dist/src/services/ngrok.js +12 -0
  43. package/dist/src/services/ngrok.js.map +1 -1
  44. package/dist/src/services/openrouter.d.ts +2 -1
  45. package/dist/src/services/openrouter.d.ts.map +1 -1
  46. package/dist/src/services/openrouter.js +12 -0
  47. package/dist/src/services/openrouter.js.map +1 -1
  48. package/dist/src/services/tailscale.d.ts +2 -1
  49. package/dist/src/services/tailscale.d.ts.map +1 -1
  50. package/dist/src/services/tailscale.js +18 -0
  51. package/dist/src/services/tailscale.js.map +1 -1
  52. package/dist/src/services/todoist.d.ts +2 -1
  53. package/dist/src/services/todoist.d.ts.map +1 -1
  54. package/dist/src/services/todoist.js +6 -0
  55. package/dist/src/services/todoist.js.map +1 -1
  56. package/dist/src/services/zoom.d.ts +2 -1
  57. package/dist/src/services/zoom.d.ts.map +1 -1
  58. package/dist/src/services/zoom.js +55 -55
  59. package/dist/src/services/zoom.js.map +1 -1
  60. package/dist/src/sharedOperations.d.ts +1 -1
  61. package/dist/src/sharedOperations.d.ts.map +1 -1
  62. package/dist/src/sharedOperations.js +12 -1
  63. package/dist/src/sharedOperations.js.map +1 -1
  64. package/dist/src/version.d.ts +1 -1
  65. package/dist/src/version.js +1 -1
  66. package/dist/tests/lint.test.js +1 -1
  67. package/dist/tests/manualCompletion.test.d.ts +10 -0
  68. package/dist/tests/manualCompletion.test.d.ts.map +1 -0
  69. package/dist/tests/manualCompletion.test.js +221 -0
  70. package/dist/tests/manualCompletion.test.js.map +1 -0
  71. package/dist/tests/manualCredentialForms.test.d.ts +8 -0
  72. package/dist/tests/manualCredentialForms.test.d.ts.map +1 -0
  73. package/dist/tests/manualCredentialForms.test.js +64 -0
  74. package/dist/tests/manualCredentialForms.test.js.map +1 -0
  75. package/dist/tests/serviceRegistry.test.js +32 -1
  76. package/dist/tests/serviceRegistry.test.js.map +1 -1
  77. package/package.json +2 -2
@@ -5,7 +5,25 @@ import type { Browser, BrowserContext, Page, Response } from 'playwright';
5
5
  import type { z, ZodError, ZodTypeAny } from 'zod';
6
6
  import { ApiCredentialStatus, ApiCredentials } from '../../apiCredentials/base.js';
7
7
  import { EncryptedStorage } from '../../encryptedStorage.js';
8
- import { type BrowserLaunchOptions } from '../../playwrightUtils.js';
8
+ import { type BrowserLaunchOptions, type CredentialFormField, type CredentialFormValues } from '../../playwrightUtils.js';
9
+ /**
10
+ * Way out of a failed automation: the values the user can produce by hand and
11
+ * paste back, and how to turn them into credentials.
12
+ *
13
+ * The build step only shapes the values; whether they actually work is decided
14
+ * by the service's credential check, which runs before they are accepted.
15
+ */
16
+ export interface ManualCredentialForm {
17
+ /**
18
+ * What the user can do by hand, e.g. "create a token in Settings →
19
+ * Developer". Shown above the fields, so it should read as instructions
20
+ * rather than as a description. Don't forget that the breakage might have
21
+ * occurred in the middle of the process (not necessarily at the start).
22
+ */
23
+ readonly instructions: string;
24
+ readonly fields: readonly CredentialFormField[];
25
+ buildCredentials(values: CredentialFormValues): ApiCredentials;
26
+ }
9
27
  export declare class NoCurlCredentialsNotSupportedError extends Error {
10
28
  constructor(serviceName: string);
11
29
  }
@@ -193,15 +211,6 @@ export declare abstract class ServiceSession {
193
211
  * Wait until the browser login phase is complete.
194
212
  */
195
213
  private waitForLoginComplete;
196
- /**
197
- * Optionally diagnose a timeout error that occurred during credential finalization.
198
- *
199
- * Services can override this to inspect the page state and return a more
200
- * specific error (e.g., checking for permission denied messages).
201
- * If this returns an error, it will be thrown instead of the generic
202
- * LoginFailedError. If it returns null, the original timeout error message is used.
203
- */
204
- protected diagnoseTimeoutError(_context: BrowserContext, _originalError: Error): Promise<Error | null>;
205
214
  /**
206
215
  * Optional preparation step before login.
207
216
  * Services can override this to perform setup (e.g., creating OAuth clients).
@@ -270,16 +279,26 @@ export declare function buildFollowupSpinnerDetails(displayName: string, followu
270
279
  * (e.g., navigating to settings and creating an API key).
271
280
  */
272
281
  export declare abstract class BrowserFollowupServiceSession extends ServiceSession {
273
- private followupSpinnerPage;
274
282
  /** What the followup does in the user's account, shown on the spinner page. */
275
283
  protected abstract readonly followupWork: FollowupWork;
276
284
  /**
277
- * Spinner page hiding the automation from the user while the followup runs,
278
- * or null when the spinner is disabled. Subclasses that temporarily surface
279
- * a real page to the user (e.g. to have terms accepted) bring this page back
280
- * to the front afterwards.
285
+ * Page hiding the automation from the user, for sessions that show one, or
286
+ * null while none is up (or when the spinner is disabled). It doubles as the
287
+ * place where a failure is explained to the user.
288
+ *
289
+ * Subclasses that temporarily surface a real page to the user (e.g. to have
290
+ * terms accepted) bring this page back to the front afterwards.
281
291
  */
282
- protected get spinnerPage(): Page | null;
292
+ protected spinnerPage: Page | null;
293
+ /**
294
+ * Form shown on the failure notice for the user to paste the credentials they
295
+ * created by hand into.
296
+ *
297
+ * Public so the fields and instructions can be inspected without running a
298
+ * browser — which is how the tests check that every session that should offer
299
+ * one does, and that its builder agrees with its field names.
300
+ */
301
+ readonly manualCredentialForm?: ManualCredentialForm;
283
302
  /**
284
303
  * Perform actions in the browser to finalize and extract API credentials.
285
304
  * This runs in the same browser session used for login.
@@ -288,5 +307,25 @@ export declare abstract class BrowserFollowupServiceSession extends ServiceSessi
288
307
  */
289
308
  protected abstract performBrowserFollowup(context: BrowserContext, oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
290
309
  protected finalizeCredentials(_browser: Browser, context: BrowserContext, oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
310
+ /**
311
+ * Turn a failed followup into an error the user can act on, without taking
312
+ * the browser away from them.
313
+ *
314
+ * A broken automation usually means the service changed, which is precisely
315
+ * the situation where the flow is still perfectly doable by hand: the browser
316
+ * is signed in and sitting on the right page. So the spinner is replaced by
317
+ * an explanation of what failed and what to do about it, and the window stays
318
+ * open for a while, waiting for the user to paste the credentials in.
319
+ *
320
+ * This needs somewhere to put them, so sessions without a
321
+ * {@link manualCredentialForm} report the failure straight away rather than
322
+ * asking for work latchkey could not accept.
323
+ */
324
+ private recoverFromFailedFollowup;
325
+ /**
326
+ * Turn submitted values into credentials, refusing them with a reason the form
327
+ * can show if the service does not accept them.
328
+ */
329
+ private decideOnSubmittedCredentials;
291
330
  }
292
331
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,cAAc,EAEf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAKL,KAAK,oBAAoB,EAEzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAAC;CAChE;AAED,qBAAa,kCAAmC,SAAQ,KAAK;gBAC/C,WAAW,EAAE,MAAM;CAIhC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,SAAwD;CAI5E;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,SAAiD;CAIrE;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,WAAW,EAAE,MAAM;CAOhC;AAED;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,SAAS,UAAU,EAChE,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,OAAO,EACnB,KAAK,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,cAAc,GACzD,cAAc,CAMhB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAO5D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAU1D;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAMpE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,8BAAsB,OAAO;IAC3B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAEnC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,EAAE,SAAS,MAAM,EAAE,CAAC;IAElE;;;;;;OAMG;IACH,iBAAiB,CAAC,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc;IAE/E;;;;;;;OAOG;IACG,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA8BvF;;;;OAIG;IACH,SAAS,CAAC,8BAA8B,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;IAIhG;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,UAAU,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAE3E;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAE3D;;;OAGG;IACH,oBAAoB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc;IAInE;;;;;;;;;OASG;IACH,eAAe,CAAC,CAAC,UAAU,EAAE,OAAO,GAAG,cAAc;IAErD;;;;OAIG;IACH,UAAU,CAAC,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc;IAElD;;;;;OAKG;IACH,kBAAkB,CAAC,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CACpF;AAED;;;GAGG;AACH,8BAAsB,cAAc;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAE7B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM;IAKnD;;OAEG;IACH,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAIlD;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE7D;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,OAAO;IAE7C;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,mBAAmB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAEjC;;OAEG;YACW,oBAAoB;IAMlC;;;;;;;OAOG;IACH,OAAO,CAAC,CACN,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,CAAC,EAAE,oBAAoB,GACnC,OAAO,CAAC,cAAc,CAAC;IAE1B;;;;;OAKG;IACG,KAAK,CACT,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,GAAE,oBAAyB,EACxC,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,WAAW,CAAC;CAsCxB;AAED;;GAEG;AACH,8BAAsB,oBAAqB,SAAQ,cAAc;IAC/D,SAAS,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAQ;IAEvD;;;;;;;;;;OAUG;IACH,IAAI,mBAAmB,IAAI,cAAc,GAAG,IAAI,CAE/C;IAED;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,6BAA6B,CAC9C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAEjC,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB7C,SAAS,CAAC,eAAe,IAAI,OAAO;IAIpC,SAAS,CAAC,mBAAmB,CAC3B,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,cAAc,EACxB,eAAe,CAAC,EAAE,cAAc,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAGlC;AAED;;;;;;;GAOG;AACH,oBAAY,YAAY;IACtB,cAAc,6BAA6B;IAC3C,SAAS,uBAAuB;IAChC,gBAAgB,kCAAkC;CACnD;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,YAAY,EAC1B,gBAAgB,SAA2B,GAC1C,MAAM,CAER;AAkBD;;;;;;GAMG;AACH,8BAAsB,6BAA8B,SAAQ,cAAc;IACxE,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEvD;;;;;;;OAOG;IACH,SAAS,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAE1C;;;;;;;OAOG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAErD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,sBAAsB,CACvC,OAAO,EAAE,cAAc,EACvB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;cAER,mBAAmB,CAC1C,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,cAAc,EACvB,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAmBjC;;;;;;;;;;;;;OAaG;YACW,yBAAyB;IA2CvC;;;OAGG;YACW,4BAA4B;CA6B3C"}
@@ -4,7 +4,7 @@
4
4
  import { ApiCredentialStatus, ApiCredentialsUsageError, } from '../../apiCredentials/base.js';
5
5
  import { DEFAULT_ACCOUNT } from '../../apiCredentials/account.js';
6
6
  import { runCapturedAsync } from '../../curl.js';
7
- import { generateLatchkeyAppName, showSpinnerPage, withTempBrowserContext, } from '../../playwrightUtils.js';
7
+ import { generateLatchkeyAppName, requestCredentialsFromUser, showSpinnerPage, withTempBrowserContext, } from '../../playwrightUtils.js';
8
8
  export class NoCurlCredentialsNotSupportedError extends Error {
9
9
  constructor(serviceName) {
10
10
  super(`Service '${serviceName}' does not support set-nocurl credentials.`);
@@ -176,17 +176,6 @@ export class ServiceSession {
176
176
  await page.waitForTimeout(100);
177
177
  }
178
178
  }
179
- /**
180
- * Optionally diagnose a timeout error that occurred during credential finalization.
181
- *
182
- * Services can override this to inspect the page state and return a more
183
- * specific error (e.g., checking for permission denied messages).
184
- * If this returns an error, it will be thrown instead of the generic
185
- * LoginFailedError. If it returns null, the original timeout error message is used.
186
- */
187
- diagnoseTimeoutError(_context, _originalError) {
188
- return Promise.resolve(null);
189
- }
190
179
  /**
191
180
  * Perform the login flow and return the extracted credentials.
192
181
  * @param encryptedStorage - Storage for managing credentials
@@ -217,13 +206,6 @@ export class ServiceSession {
217
206
  if (error instanceof Error && isBrowserClosedError(error)) {
218
207
  throw new LoginCancelledError();
219
208
  }
220
- if (error instanceof Error && isTimeoutError(error)) {
221
- const diagnosedError = await this.diagnoseTimeoutError(context, error);
222
- if (diagnosedError !== null) {
223
- throw diagnosedError;
224
- }
225
- throw new LoginFailedError(`Login failed: ${error.message}`);
226
- }
227
209
  throw error;
228
210
  }
229
211
  if (apiCredentials === null) {
@@ -297,9 +279,22 @@ export var FollowupWork;
297
279
  * is doing and how to recover when it fails.
298
280
  */
299
281
  export function buildFollowupSpinnerDetails(displayName, followupWork, durationSentence = 'This can take a while.') {
300
- return (`${followupWork} your ${displayName} account. ${durationSentence} ` +
301
- 'If the process fails, click the first browser tab in this window to manually complete it.');
282
+ return `${followupWork} your ${displayName} account. ${durationSentence} `;
302
283
  }
284
+ /**
285
+ * The notice explains what to do, not what went wrong: the automation's error
286
+ * message means nothing to the user, and it is reported on the command line
287
+ * anyway.
288
+ */
289
+ function buildFailureNoticeDetails(form) {
290
+ return [
291
+ form.instructions,
292
+ 'Then paste the credentials into the form below.',
293
+ 'Closing this browser window gives up on the login.',
294
+ ].join('\n\n');
295
+ }
296
+ /** How long the browser is left open for the user to finish a failed flow. */
297
+ const MANUAL_COMPLETION_LIMIT_MS = 30 * 60_000;
303
298
  /**
304
299
  * Service session that requires a browser followup to finalize credentials.
305
300
  *
@@ -308,19 +303,112 @@ export function buildFollowupSpinnerDetails(displayName, followupWork, durationS
308
303
  * (e.g., navigating to settings and creating an API key).
309
304
  */
310
305
  export class BrowserFollowupServiceSession extends ServiceSession {
311
- followupSpinnerPage = null;
312
306
  /**
313
- * Spinner page hiding the automation from the user while the followup runs,
314
- * or null when the spinner is disabled. Subclasses that temporarily surface
315
- * a real page to the user (e.g. to have terms accepted) bring this page back
316
- * to the front afterwards.
307
+ * Page hiding the automation from the user, for sessions that show one, or
308
+ * null while none is up (or when the spinner is disabled). It doubles as the
309
+ * place where a failure is explained to the user.
310
+ *
311
+ * Subclasses that temporarily surface a real page to the user (e.g. to have
312
+ * terms accepted) bring this page back to the front afterwards.
317
313
  */
318
- get spinnerPage() {
319
- return this.followupSpinnerPage;
320
- }
314
+ spinnerPage = null;
315
+ /**
316
+ * Form shown on the failure notice for the user to paste the credentials they
317
+ * created by hand into.
318
+ *
319
+ * Public so the fields and instructions can be inspected without running a
320
+ * browser — which is how the tests check that every session that should offer
321
+ * one does, and that its builder agrees with its field names.
322
+ */
323
+ manualCredentialForm;
321
324
  async finalizeCredentials(_browser, context, oldCredentials) {
322
- this.followupSpinnerPage = await showSpinnerPage(context, `Finalizing ${this.service.displayName} login...`, buildFollowupSpinnerDetails(this.service.displayName, this.followupWork));
323
- return this.performBrowserFollowup(context, oldCredentials);
325
+ this.spinnerPage = await showSpinnerPage(context, `Finalizing ${this.service.displayName} login...`, buildFollowupSpinnerDetails(this.service.displayName, this.followupWork));
326
+ try {
327
+ return await this.performBrowserFollowup(context, oldCredentials);
328
+ }
329
+ catch (error) {
330
+ // A browser the user closed is a cancellation, which login() reports;
331
+ // everything else is the automation breaking, which the user may still be
332
+ // able to work around.
333
+ if (!(error instanceof Error) || isBrowserClosedError(error)) {
334
+ throw error;
335
+ }
336
+ return await this.recoverFromFailedFollowup(context, error);
337
+ }
338
+ }
339
+ /**
340
+ * Turn a failed followup into an error the user can act on, without taking
341
+ * the browser away from them.
342
+ *
343
+ * A broken automation usually means the service changed, which is precisely
344
+ * the situation where the flow is still perfectly doable by hand: the browser
345
+ * is signed in and sitting on the right page. So the spinner is replaced by
346
+ * an explanation of what failed and what to do about it, and the window stays
347
+ * open for a while, waiting for the user to paste the credentials in.
348
+ *
349
+ * This needs somewhere to put them, so sessions without a
350
+ * {@link manualCredentialForm} report the failure straight away rather than
351
+ * asking for work latchkey could not accept.
352
+ */
353
+ async recoverFromFailedFollowup(context, error) {
354
+ // A timeout says nothing beyond "the page did not do what we expected", so
355
+ // it is reported as the login failure it is.
356
+ const failure = isTimeoutError(error)
357
+ ? new LoginFailedError(`Login failed: ${error.message}`)
358
+ : error;
359
+ const form = this.manualCredentialForm;
360
+ if (form === undefined) {
361
+ throw failure;
362
+ }
363
+ console.error(`[latchkey] The ${this.service.displayName} login automation failed. The browser ` +
364
+ 'window is left open so the credentials can be provided by hand; close it to give up.');
365
+ let credentials;
366
+ try {
367
+ credentials = await requestCredentialsFromUser({
368
+ context,
369
+ spinnerPage: this.spinnerPage,
370
+ message: `${this.service.displayName} credentials could not be retrieved automatically.`,
371
+ details: buildFailureNoticeDetails(form),
372
+ fields: form.fields,
373
+ decide: (values) => this.decideOnSubmittedCredentials(form, values),
374
+ timeoutMs: MANUAL_COMPLETION_LIMIT_MS,
375
+ });
376
+ }
377
+ catch {
378
+ // The browser is gone; there is nobody left to ask.
379
+ throw failure;
380
+ }
381
+ if (credentials !== null) {
382
+ return credentials;
383
+ }
384
+ // Nothing came of the request, so the automation failure is what gets reported.
385
+ throw failure;
386
+ }
387
+ /**
388
+ * Turn submitted values into credentials, refusing them with a reason the form
389
+ * can show if the service does not accept them.
390
+ */
391
+ async decideOnSubmittedCredentials(form, values) {
392
+ // A build error is reported to the user as a problem with what they typed:
393
+ // requestCredentialsFromUser turns it into one.
394
+ const built = form.buildCredentials(values);
395
+ // Some pasted values are not usable as they stand — Zoom's server-to-server
396
+ // app credentials have to mint an access token first — so they get the same
397
+ // refresh the stored ones would, or the check below would call a perfectly
398
+ // good app "missing".
399
+ const credentials = built.isExpired() === true && this.service.refreshCredentials
400
+ ? ((await this.service.refreshCredentials(built)) ?? built)
401
+ : built;
402
+ // These were pasted by hand, so they are checked before being taken:
403
+ // finding out now beats storing a typo and failing on the next request.
404
+ const status = await this.service.checkApiCredentials(credentials);
405
+ if (status !== ApiCredentialStatus.Valid) {
406
+ return {
407
+ problem: `${this.service.displayName} did not accept these credentials (${status}). ` +
408
+ 'Please check them and try again.',
409
+ };
410
+ }
411
+ return { accepted: credentials };
324
412
  }
325
413
  }
326
414
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/services/core/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Fastmail CardDAV / CalDAV service implementation.
3
+ *
4
+ * Separate from the `fastmail` service, which speaks JMAP, because the two take
5
+ * different credentials against different hosts. Fastmail's OAuth access tokens
6
+ * are accepted only by the JMAP API; the DAV endpoints refuse them (401 on every
7
+ * collection, including the principal URL) and want an **app password** over
8
+ * HTTP Basic auth instead. Fastmail's own documentation draws the same line: an
9
+ * API token is "for JMAP access", an app password is "for everything else".
10
+ *
11
+ * Splitting by host also keeps URL matching unambiguous. `latchkey curl` picks
12
+ * among services that match a URL by registration order, with no way for a
13
+ * caller to name the one it wants, so two services claiming the same host would
14
+ * be a coin flip. These hosts are disjoint from the JMAP ones.
15
+ *
16
+ * The credential is an app password from Settings → Privacy & Security →
17
+ * "Connected apps & API tokens" → "Manage app passwords and access", used with
18
+ * the account's own e-mail address as the username. Its "DAV" access level is
19
+ * enough.
20
+ *
21
+ * One failure worth recognizing: on an account with no active subscription
22
+ * (observed on a lapsed trial) app passwords appear to be refused for every
23
+ * legacy protocol, and the refusal is a 401 reading "Incorrect username,
24
+ * password or access token" — indistinguishable from a typo — while JMAP over
25
+ * an API token or OAuth keeps working. Subscribing restored DAV with no change
26
+ * to any request. An IMAP login against imap.fastmail.com with the same
27
+ * credential tells the two apart: refused there too points at the account
28
+ * rather than the credential.
29
+ */
30
+ import type { ApiCredentials } from '../apiCredentials/base.js';
31
+ import { Service } from './core/base.js';
32
+ export declare class FastmailDav extends Service {
33
+ readonly name = "fastmail-dav";
34
+ readonly displayName = "Fastmail (CardDAV/CalDAV)";
35
+ /**
36
+ * Contacts and calendars live on their own hosts, and — unlike the JMAP API —
37
+ * these are not region-sharded: `/.well-known/carddav` redirects within
38
+ * `carddav.fastmail.com` rather than off to a shard. The optional prefix is
39
+ * defensive, so a future shard would not need a new registration.
40
+ */
41
+ readonly baseApiUrls: readonly [RegExp, RegExp];
42
+ readonly loginUrl = "https://app.fastmail.com/settings/security";
43
+ readonly info: string;
44
+ readonly credentialCheckCurlArguments: readonly ["-X", "PROPFIND", "-H", "Depth: 0", "-H", "Content-Type: application/xml; charset=utf-8", "--data-binary", string, "https://carddav.fastmail.com/dav/principals/"];
45
+ setCredentialsExample(serviceName: string): string;
46
+ /**
47
+ * WebDAV answers a successful PROPFIND with 207 Multi-Status (RFC 4918 §13),
48
+ * so the inherited 200-only check would report every working app password as
49
+ * invalid.
50
+ */
51
+ protected isCredentialCheckResponseValid(httpStatusCode: string): boolean;
52
+ getAccount(apiCredentials: ApiCredentials): Promise<string | null>;
53
+ }
54
+ export declare const FASTMAIL_DAV: FastmailDav;
55
+ //# sourceMappingURL=fastmail-dav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastmail-dav.d.ts","sourceRoot":"","sources":["../../../src/services/fastmail-dav.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAoCzC,qBAAa,WAAY,SAAQ,OAAO;IACtC,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,WAAW,+BAA+B;IAEnD;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,4BAGT;IAEX,QAAQ,CAAC,QAAQ,gDAAgD;IAEjE,QAAQ,CAAC,IAAI,SAKsB;IAEnC,QAAQ,CAAC,4BAA4B,+KAAkC;IAEvE,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIlD;;;;OAIG;cACgB,8BAA8B,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAIzE,UAAU,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAO5E;AAED,eAAO,MAAM,YAAY,aAAoB,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Fastmail CardDAV / CalDAV service implementation.
3
+ *
4
+ * Separate from the `fastmail` service, which speaks JMAP, because the two take
5
+ * different credentials against different hosts. Fastmail's OAuth access tokens
6
+ * are accepted only by the JMAP API; the DAV endpoints refuse them (401 on every
7
+ * collection, including the principal URL) and want an **app password** over
8
+ * HTTP Basic auth instead. Fastmail's own documentation draws the same line: an
9
+ * API token is "for JMAP access", an app password is "for everything else".
10
+ *
11
+ * Splitting by host also keeps URL matching unambiguous. `latchkey curl` picks
12
+ * among services that match a URL by registration order, with no way for a
13
+ * caller to name the one it wants, so two services claiming the same host would
14
+ * be a coin flip. These hosts are disjoint from the JMAP ones.
15
+ *
16
+ * The credential is an app password from Settings → Privacy & Security →
17
+ * "Connected apps & API tokens" → "Manage app passwords and access", used with
18
+ * the account's own e-mail address as the username. Its "DAV" access level is
19
+ * enough.
20
+ *
21
+ * One failure worth recognizing: on an account with no active subscription
22
+ * (observed on a lapsed trial) app passwords appear to be refused for every
23
+ * legacy protocol, and the refusal is a 401 reading "Incorrect username,
24
+ * password or access token" — indistinguishable from a typo — while JMAP over
25
+ * an API token or OAuth keeps working. Subscribing restored DAV with no change
26
+ * to any request. An IMAP login against imap.fastmail.com with the same
27
+ * credential tells the two apart: refused there too points at the account
28
+ * rather than the credential.
29
+ */
30
+ import { fetchAccountFromEndpoint } from '../apiCredentials/account.js';
31
+ import { Service } from './core/base.js';
32
+ /**
33
+ * A `current-user-principal` PROPFIND (RFC 5397). Depth 0 keeps it to the
34
+ * collection itself, and the response names the principal of whoever
35
+ * authenticated — which is how this doubles as the account lookup.
36
+ */
37
+ const PRINCIPAL_PROPFIND_BODY = '<?xml version="1.0" encoding="utf-8"?>' +
38
+ '<D:propfind xmlns:D="DAV:"><D:prop><D:current-user-principal/></D:prop></D:propfind>';
39
+ const PRINCIPAL_CHECK_CURL_ARGUMENTS = [
40
+ '-X',
41
+ 'PROPFIND',
42
+ '-H',
43
+ 'Depth: 0',
44
+ '-H',
45
+ 'Content-Type: application/xml; charset=utf-8',
46
+ '--data-binary',
47
+ PRINCIPAL_PROPFIND_BODY,
48
+ 'https://carddav.fastmail.com/dav/principals/',
49
+ ];
50
+ /**
51
+ * Pull the account out of a `current-user-principal` response. Fastmail's
52
+ * principal hrefs carry the account's e-mail, e.g.
53
+ * `/dav/principals/user/someone@fastmail.com/`.
54
+ *
55
+ * Matched with a regular expression rather than parsed as XML: latchkey has no
56
+ * XML parser, the shape is fixed by RFC 5397, and the alternative is taking on a
57
+ * dependency to read one href.
58
+ */
59
+ function parseAccountFromPrincipalResponse(responseBody) {
60
+ return /\/dav\/principals\/user\/([^/<>"]+)/.exec(responseBody)?.[1] ?? null;
61
+ }
62
+ export class FastmailDav extends Service {
63
+ name = 'fastmail-dav';
64
+ displayName = 'Fastmail (CardDAV/CalDAV)';
65
+ /**
66
+ * Contacts and calendars live on their own hosts, and — unlike the JMAP API —
67
+ * these are not region-sharded: `/.well-known/carddav` redirects within
68
+ * `carddav.fastmail.com` rather than off to a shard. The optional prefix is
69
+ * defensive, so a future shard would not need a new registration.
70
+ */
71
+ baseApiUrls = [
72
+ /^https:\/\/([a-z0-9-]+[.-])?carddav\.fastmail\.com\//,
73
+ /^https:\/\/([a-z0-9-]+[.-])?caldav\.fastmail\.com\//,
74
+ ];
75
+ loginUrl = 'https://app.fastmail.com/settings/security';
76
+ info = 'https://www.fastmail.com/dev/ — contacts over CardDAV (RFC 6352) and calendars over ' +
77
+ 'CalDAV (RFC 4791), rooted at /dav/addressbooks and /dav/calendars. ' +
78
+ 'Credentials are an app password, rather than the OAuth token the `fastmail` service uses. ' +
79
+ 'The `fastmail` service can also reach contacts over JMAP, which is the better route unless a ' +
80
+ 'caller needs DAV specifically.';
81
+ credentialCheckCurlArguments = PRINCIPAL_CHECK_CURL_ARGUMENTS;
82
+ setCredentialsExample(serviceName) {
83
+ return `latchkey auth set ${serviceName} -u "you@fastmail.com:<app password>"`;
84
+ }
85
+ /**
86
+ * WebDAV answers a successful PROPFIND with 207 Multi-Status (RFC 4918 §13),
87
+ * so the inherited 200-only check would report every working app password as
88
+ * invalid.
89
+ */
90
+ isCredentialCheckResponseValid(httpStatusCode) {
91
+ return httpStatusCode === '207' || httpStatusCode === '200';
92
+ }
93
+ getAccount(apiCredentials) {
94
+ return fetchAccountFromEndpoint(apiCredentials, this.credentialCheckCurlArguments, parseAccountFromPrincipalResponse);
95
+ }
96
+ }
97
+ export const FASTMAIL_DAV = new FastmailDav();
98
+ //# sourceMappingURL=fastmail-dav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastmail-dav.js","sourceRoot":"","sources":["../../../src/services/fastmail-dav.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC;;;;GAIG;AACH,MAAM,uBAAuB,GAC3B,wCAAwC;IACxC,sFAAsF,CAAC;AAEzF,MAAM,8BAA8B,GAAG;IACrC,IAAI;IACJ,UAAU;IACV,IAAI;IACJ,UAAU;IACV,IAAI;IACJ,8CAA8C;IAC9C,eAAe;IACf,uBAAuB;IACvB,8CAA8C;CACtC,CAAC;AAEX;;;;;;;;GAQG;AACH,SAAS,iCAAiC,CAAC,YAAoB;IAC7D,OAAO,qCAAqC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC/E,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,OAAO;IAC7B,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,2BAA2B,CAAC;IAEnD;;;;;OAKG;IACM,WAAW,GAAG;QACrB,sDAAsD;QACtD,qDAAqD;KAC7C,CAAC;IAEF,QAAQ,GAAG,4CAA4C,CAAC;IAExD,IAAI,GACX,sFAAsF;QACtF,qEAAqE;QACrE,4FAA4F;QAC5F,+FAA+F;QAC/F,gCAAgC,CAAC;IAE1B,4BAA4B,GAAG,8BAA8B,CAAC;IAEvE,qBAAqB,CAAC,WAAmB;QACvC,OAAO,qBAAqB,WAAW,uCAAuC,CAAC;IACjF,CAAC;IAED;;;;OAIG;IACgB,8BAA8B,CAAC,cAAsB;QACtE,OAAO,cAAc,KAAK,KAAK,IAAI,cAAc,KAAK,KAAK,CAAC;IAC9D,CAAC;IAEQ,UAAU,CAAC,cAA8B;QAChD,OAAO,wBAAwB,CAC7B,cAAc,EACd,IAAI,CAAC,4BAA4B,EACjC,iCAAiC,CAClC,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Fastmail service implementation.
3
+ *
4
+ * Fastmail's JMAP API is an OAuth 2.1 protected resource: it advertises an
5
+ * authorization server at `https://api.fastmail.com` (RFC 8414 metadata at
6
+ * `/.well-known/oauth-authorization-server`) supporting dynamic client
7
+ * registration, PKCE (S256) and refresh tokens, with public clients
8
+ * (`token_endpoint_auth_method: none`). So no API token has to be created by
9
+ * hand in the account's settings and pasted in — `latchkey auth browser
10
+ * fastmail` is enough.
11
+ */
12
+ import { z } from 'zod';
13
+ import type { Browser, BrowserContext, Response } from 'playwright';
14
+ import { type ApiCredentials } from '../apiCredentials/base.js';
15
+ import { Service, ServiceSession, type LoginResult } from './core/base.js';
16
+ /**
17
+ * JSON accepted by `latchkey auth prepare fastmail`: an OAuth client id to
18
+ * reuse instead of registering a new client dynamically. Fastmail issues
19
+ * public clients, so no secret is needed. `.strict()` rejects unknown keys so
20
+ * typos are reported instead of silently ignored.
21
+ */
22
+ export declare const FastmailPrepareInputSchema: z.ZodObject<{
23
+ clientId: z.ZodString;
24
+ }, "strict", z.ZodTypeAny, {
25
+ clientId: string;
26
+ }, {
27
+ clientId: string;
28
+ }>;
29
+ export type FastmailPrepareInput = z.infer<typeof FastmailPrepareInputSchema>;
30
+ declare class FastmailSession extends ServiceSession {
31
+ onResponse(_response: Response): void;
32
+ protected isLoginComplete(): boolean;
33
+ protected finalizeCredentials(_browser: Browser, _context: BrowserContext, _oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
34
+ login(encryptedStorage: import('../encryptedStorage.js').EncryptedStorage, launchOptions?: import('../playwrightUtils.js').BrowserLaunchOptions, oldCredentials?: ApiCredentials): Promise<LoginResult>;
35
+ }
36
+ export declare class Fastmail extends Service {
37
+ readonly name = "fastmail";
38
+ readonly displayName = "Fastmail";
39
+ /**
40
+ * Four host shapes, which is why these are patterns rather than plain
41
+ * prefixes. Session discovery starts at `api.fastmail.com`, but the `apiUrl`
42
+ * and `downloadUrl` it returns point at the shard the account is homed on
43
+ * (`phl.api.fastmail.com`, `phl-www.fastmailusercontent.com`, …). Which
44
+ * shard that is only becomes known after discovery, so the service has to
45
+ * cover them all up front.
46
+ *
47
+ * The blob pattern is anchored on the `www` label rather than accepting any
48
+ * subdomain: the session document only ever names `www.fastmailusercontent.com`
49
+ * or `<shard>-www.…`, and this is the domain Fastmail uses to serve user
50
+ * content, so matching it loosely would offer the access token to hosts the
51
+ * credential has no business reaching.
52
+ *
53
+ * Deliberately NOT covering carddav.fastmail.com / caldav.fastmail.com. Those
54
+ * advertise `WWW-Authenticate: Basic realm=..., Bearer`, so adding them looks
55
+ * right, but Fastmail's OAuth access tokens are refused there (401 on every
56
+ * path tried, including the principal and per-user collections) — the DAV
57
+ * endpoints want an app password over Basic auth, which is a different
58
+ * credential type than this service issues. Contacts and calendars are
59
+ * reachable over JMAP on the hosts below instead.
60
+ */
61
+ readonly baseApiUrls: readonly [RegExp, RegExp];
62
+ readonly loginUrl = "https://api.fastmail.com/oauth/authorize";
63
+ readonly info: string;
64
+ readonly credentialCheckCurlArguments: readonly ["https://api.fastmail.com/jmap/session"];
65
+ setCredentialsExample(serviceName: string): string;
66
+ /**
67
+ * Fastmail accepts an OAuth client id prepared in advance via
68
+ * `latchkey auth prepare`, stored as token-less OAuth credentials until
69
+ * login. The login flow reuses this client id instead of registering a new
70
+ * client dynamically.
71
+ */
72
+ prepareFromJson(parsedJson: unknown): ApiCredentials;
73
+ getAccount(apiCredentials: ApiCredentials): Promise<string | null>;
74
+ getSession(appNamePrefix: string): FastmailSession;
75
+ refreshCredentials(apiCredentials: ApiCredentials): Promise<ApiCredentials | null>;
76
+ }
77
+ export declare const FASTMAIL: Fastmail;
78
+ export {};
79
+ //# sourceMappingURL=fastmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastmail.d.ts","sourceRoot":"","sources":["../../../src/services/fastmail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,2BAA2B,CAAC;AAclF,OAAO,EACL,OAAO,EACP,cAAc,EACd,KAAK,WAAW,EAKjB,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;;;;EAI5B,CAAC;AAEZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AA8I9E,cAAM,eAAgB,SAAQ,cAAc;IAC1C,UAAU,CAAC,SAAS,EAAE,QAAQ,GAAG,IAAI;IAIrC,SAAS,CAAC,eAAe,IAAI,OAAO;IAKpC,SAAS,CAAC,mBAAmB,CAC3B,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,cAAc,EACxB,eAAe,CAAC,EAAE,cAAc,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAKlB,KAAK,CAClB,gBAAgB,EAAE,OAAO,wBAAwB,EAAE,gBAAgB,EACnE,aAAa,GAAE,OAAO,uBAAuB,EAAE,oBAAyB,EACxE,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,WAAW,CAAC;CAiGxB;AAED,qBAAa,QAAS,SAAQ,OAAO;IACnC,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,cAAc;IAElC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,WAAW,4BAGT;IAEX,QAAQ,CAAC,QAAQ,8CAA0B;IAE3C,QAAQ,CAAC,IAAI,SAI6D;IAE1E,QAAQ,CAAC,4BAA4B,qDAA+B;IAEpE,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIlD;;;;;OAKG;IACM,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,cAAc;IASpD,UAAU,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQlE,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAI5C,kBAAkB,CAC/B,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgClC;AAED,eAAO,MAAM,QAAQ,UAAiB,CAAC"}