latchkey 0.1.4 → 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 (77) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -4
  3. package/dist/integrations/SKILL.md +71 -0
  4. package/dist/package.json +67 -0
  5. package/dist/scripts/encryptFile.d.ts +21 -0
  6. package/dist/scripts/encryptFile.d.ts.map +1 -0
  7. package/dist/scripts/encryptFile.js +101 -0
  8. package/dist/scripts/encryptFile.js.map +1 -0
  9. package/dist/src/apiCredentials.d.ts +83 -1
  10. package/dist/src/apiCredentials.d.ts.map +1 -1
  11. package/dist/src/apiCredentials.js +83 -1
  12. package/dist/src/apiCredentials.js.map +1 -1
  13. package/dist/src/browserState.d.ts +8 -0
  14. package/dist/src/browserState.d.ts.map +1 -0
  15. package/dist/src/browserState.js +21 -0
  16. package/dist/src/browserState.js.map +1 -0
  17. package/dist/src/cli.js +2 -1
  18. package/dist/src/cli.js.map +1 -1
  19. package/dist/src/cliCommands.d.ts.map +1 -1
  20. package/dist/src/cliCommands.js +122 -17
  21. package/dist/src/cliCommands.js.map +1 -1
  22. package/dist/src/oauthUtils.d.ts +49 -0
  23. package/dist/src/oauthUtils.d.ts.map +1 -0
  24. package/dist/src/oauthUtils.js +183 -0
  25. package/dist/src/oauthUtils.js.map +1 -0
  26. package/dist/src/playwrightUtils.d.ts +8 -1
  27. package/dist/src/playwrightUtils.d.ts.map +1 -1
  28. package/dist/src/playwrightUtils.js +25 -8
  29. package/dist/src/playwrightUtils.js.map +1 -1
  30. package/dist/src/registry.d.ts.map +1 -1
  31. package/dist/src/registry.js +2 -2
  32. package/dist/src/registry.js.map +1 -1
  33. package/dist/src/services/base.d.ts +31 -5
  34. package/dist/src/services/base.d.ts.map +1 -1
  35. package/dist/src/services/base.js +12 -8
  36. package/dist/src/services/base.js.map +1 -1
  37. package/dist/src/services/discord.d.ts +2 -0
  38. package/dist/src/services/discord.d.ts.map +1 -1
  39. package/dist/src/services/discord.js +3 -0
  40. package/dist/src/services/discord.js.map +1 -1
  41. package/dist/src/services/dropbox.d.ts +3 -1
  42. package/dist/src/services/dropbox.d.ts.map +1 -1
  43. package/dist/src/services/dropbox.js +7 -5
  44. package/dist/src/services/dropbox.js.map +1 -1
  45. package/dist/src/services/github.d.ts +3 -1
  46. package/dist/src/services/github.d.ts.map +1 -1
  47. package/dist/src/services/github.js +18 -8
  48. package/dist/src/services/github.js.map +1 -1
  49. package/dist/src/services/google.d.ts +35 -0
  50. package/dist/src/services/google.d.ts.map +1 -0
  51. package/dist/src/services/google.js +358 -0
  52. package/dist/src/services/google.js.map +1 -0
  53. package/dist/src/services/index.d.ts +2 -0
  54. package/dist/src/services/index.d.ts.map +1 -1
  55. package/dist/src/services/index.js +2 -0
  56. package/dist/src/services/index.js.map +1 -1
  57. package/dist/src/services/linear.d.ts +3 -1
  58. package/dist/src/services/linear.d.ts.map +1 -1
  59. package/dist/src/services/linear.js +7 -6
  60. package/dist/src/services/linear.js.map +1 -1
  61. package/dist/src/services/notion.d.ts +30 -0
  62. package/dist/src/services/notion.d.ts.map +1 -0
  63. package/dist/src/services/notion.js +121 -0
  64. package/dist/src/services/notion.js.map +1 -0
  65. package/dist/src/services/slack.d.ts +2 -0
  66. package/dist/src/services/slack.d.ts.map +1 -1
  67. package/dist/src/services/slack.js +3 -0
  68. package/dist/src/services/slack.js.map +1 -1
  69. package/dist/src/skillMd.d.ts +2 -0
  70. package/dist/src/skillMd.d.ts.map +1 -0
  71. package/dist/src/skillMd.js +19 -0
  72. package/dist/src/skillMd.js.map +1 -0
  73. package/dist/tests/cli.test.js +38 -1
  74. package/dist/tests/cli.test.js.map +1 -1
  75. package/dist/tests/registry.test.js +16 -3
  76. package/dist/tests/registry.test.js.map +1 -1
  77. package/package.json +5 -5
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Google service implementation with OAuth flow.
3
+ */
4
+ import fs from 'node:fs/promises';
5
+ import { ApiCredentialStatus, OAuthCredentials } from '../apiCredentials.js';
6
+ import { generateLatchkeyAppName, showSpinnerPage, withTempBrowserContext, } from '../playwrightUtils.js';
7
+ import { runCaptured } from '../curl.js';
8
+ import { exchangeCodeForTokens, refreshAccessToken, startOAuthCallbackServer, } from '../oauthUtils.js';
9
+ import { BrowserFollowupServiceSession, LoginFailedError, LoginCancelledError, isBrowserClosedError, } from './base.js';
10
+ const DEFAULT_TIMEOUT_MS = 8000;
11
+ const LOGIN_TIMEOUT_MS = 120000;
12
+ const GOOGLE_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token';
13
+ const APIS = [
14
+ 'gmail.googleapis.com',
15
+ 'calendar-json.googleapis.com',
16
+ 'drive.googleapis.com',
17
+ 'sheets.googleapis.com',
18
+ 'docs.googleapis.com',
19
+ 'people.googleapis.com', // Contacts API
20
+ ];
21
+ const OAUTH_SCOPES = [
22
+ // User info (for credential validation)
23
+ 'https://www.googleapis.com/auth/userinfo.profile',
24
+ 'https://www.googleapis.com/auth/userinfo.email',
25
+ // Gmail API
26
+ 'https://www.googleapis.com/auth/gmail.readonly',
27
+ 'https://www.googleapis.com/auth/gmail.modify',
28
+ 'https://www.googleapis.com/auth/gmail.compose',
29
+ 'https://www.googleapis.com/auth/gmail.send',
30
+ // Calendar API
31
+ 'https://www.googleapis.com/auth/calendar',
32
+ 'https://www.googleapis.com/auth/calendar.events',
33
+ // Drive API
34
+ 'https://www.googleapis.com/auth/drive',
35
+ 'https://www.googleapis.com/auth/drive.file',
36
+ // Sheets API
37
+ 'https://www.googleapis.com/auth/spreadsheets',
38
+ // Docs API
39
+ 'https://www.googleapis.com/auth/documents',
40
+ // Contacts API
41
+ 'https://www.googleapis.com/auth/contacts',
42
+ 'https://www.googleapis.com/auth/contacts.readonly',
43
+ ];
44
+ /**
45
+ * Parse client_secret.json content.
46
+ */
47
+ function parseClientSecretJson(content) {
48
+ try {
49
+ const json = JSON.parse(content);
50
+ const config = json.installed ?? json.web;
51
+ if (!config) {
52
+ throw new LoginFailedError('Invalid client_secret.json: missing "installed" or "web" configuration.');
53
+ }
54
+ return {
55
+ clientId: config.client_id,
56
+ clientSecret: config.client_secret,
57
+ };
58
+ }
59
+ catch (error) {
60
+ if (error instanceof LoginFailedError) {
61
+ throw error;
62
+ }
63
+ throw new LoginFailedError(`Failed to parse client_secret.json: ${error instanceof Error ? error.message : String(error)}`);
64
+ }
65
+ }
66
+ async function createProject(page) {
67
+ // Navigate to the projects page
68
+ await page.goto('https://console.cloud.google.com/projectselector2/home/dashboard', {
69
+ timeout: DEFAULT_TIMEOUT_MS,
70
+ });
71
+ // Always create a new project
72
+ const createProjectButton = page.locator('.projectselector-project-create');
73
+ await createProjectButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
74
+ await createProjectButton.click();
75
+ const projectNameInput = page.locator('proj-name-id-input input');
76
+ await projectNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS * 100 });
77
+ await projectNameInput.fill(generateLatchkeyAppName());
78
+ const createButton = page.locator('button[type="submit"]');
79
+ await createButton.click();
80
+ await page.waitForURL('https://console.cloud.google.com/home/dashboard?project=**', {
81
+ timeout: 16000,
82
+ });
83
+ const urlObj = new URL(page.url());
84
+ const projectId = urlObj.searchParams.get('project');
85
+ if (!projectId) {
86
+ throw new LoginFailedError('Failed to create or retrieve Google Cloud project ID.');
87
+ }
88
+ return projectId;
89
+ }
90
+ async function enableApis(page, projectSlug) {
91
+ for (const api of APIS) {
92
+ await enableApi(page, projectSlug, api);
93
+ }
94
+ }
95
+ async function enableApi(page, projectSlug, apiName) {
96
+ await page.goto(`https://console.cloud.google.com/apis/library/${apiName}?project=${projectSlug}`, {
97
+ timeout: DEFAULT_TIMEOUT_MS,
98
+ });
99
+ const successIcon = page.locator('.cfc-icon-status-success'); // Present when API is already enabled.
100
+ const enableButton = page
101
+ .locator('.mp-details-cta-button-primary button .mdc-button__label')
102
+ .filter({ visible: true });
103
+ const sucessOrEnableButton = successIcon.or(enableButton);
104
+ await sucessOrEnableButton.isVisible({ timeout: DEFAULT_TIMEOUT_MS });
105
+ if (await successIcon.isVisible()) {
106
+ return;
107
+ }
108
+ await enableButton.click();
109
+ const stopIndicator = page.locator('.cfc-icon-stop');
110
+ await stopIndicator.waitFor({ timeout: 18000 });
111
+ }
112
+ async function configureBranding(page, projectSlug) {
113
+ await page.goto(`https://console.cloud.google.com/auth/branding?project=${projectSlug}`, {
114
+ timeout: DEFAULT_TIMEOUT_MS,
115
+ });
116
+ const getStartedButton = page.locator('cfc-empty-state-actions .mdc-button__label');
117
+ await getStartedButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
118
+ await getStartedButton.click();
119
+ const appNameInput = page.locator('input[formcontrolname="displayName"]');
120
+ await appNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
121
+ await appNameInput.fill(generateLatchkeyAppName());
122
+ const emailSelector = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
123
+ await emailSelector.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
124
+ await emailSelector.click();
125
+ const supportEmailOption = page.locator('mat-option > span:nth-child(1)').first();
126
+ await supportEmailOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
127
+ const supportEmailValue = await supportEmailOption.textContent();
128
+ await supportEmailOption.click();
129
+ const nextButton = page.locator('.cfc-stepper-step-button');
130
+ await nextButton.click();
131
+ const internalAudienceRadio = page.locator('.mdc-radio').nth(0);
132
+ await internalAudienceRadio.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
133
+ await internalAudienceRadio.click();
134
+ await nextButton.click();
135
+ const contactEmailInput = page.locator('mat-chip-grid[formcontrolname="emails"] input');
136
+ await contactEmailInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
137
+ await contactEmailInput.fill(supportEmailValue ?? '');
138
+ await nextButton.click();
139
+ const agreeCheckbox = page.locator('input[type="checkbox"]');
140
+ await agreeCheckbox.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
141
+ await agreeCheckbox.click();
142
+ await nextButton.click();
143
+ const createButton = page.locator('.cfc-stepper-submit-button button');
144
+ await createButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
145
+ await createButton.click();
146
+ }
147
+ async function createOAuthClient(page) {
148
+ // Navigate to credentials page
149
+ await page.goto('https://console.cloud.google.com/apis/credentials', {
150
+ timeout: DEFAULT_TIMEOUT_MS,
151
+ });
152
+ // Click "Create Credentials" button
153
+ const createCredentialsButton = page.locator('services-create-credentials-menu button');
154
+ await createCredentialsButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
155
+ await createCredentialsButton.click();
156
+ // Click "OAuth client ID"
157
+ const oauthClientIdOption = page.locator('cfc-menu-item[track-metadata-type="OAUTH_CLIENT"]');
158
+ await oauthClientIdOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
159
+ await oauthClientIdOption.click();
160
+ const applicationTypeDropdown = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
161
+ await applicationTypeDropdown.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
162
+ await applicationTypeDropdown.click();
163
+ const desktopAppOption = page.locator('#_1rif_mat-option-5');
164
+ await desktopAppOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
165
+ await desktopAppOption.click();
166
+ const clientNameInput = page.locator('input[formcontrolname="displayName"]');
167
+ await clientNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
168
+ await clientNameInput.fill(generateLatchkeyAppName());
169
+ // Click Create
170
+ const createButton = page.locator('cfc-progress-button button');
171
+ await createButton.click();
172
+ // Download the JSON file
173
+ const downloadButton = page.locator('cfc-icon[icon="download"]');
174
+ await downloadButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
175
+ const [download] = await Promise.all([page.waitForEvent('download'), downloadButton.click()]);
176
+ const path = await download.path();
177
+ if (!path) {
178
+ throw new LoginFailedError('Failed to download client_secret.json');
179
+ }
180
+ const content = await fs.readFile(path, 'utf-8');
181
+ return parseClientSecretJson(content);
182
+ }
183
+ function checkGoogleLoginResponse(response, loginDetector) {
184
+ if (loginDetector.isLoggedIn) {
185
+ return;
186
+ }
187
+ const request = response.request();
188
+ // Detect successful login by checking for Google account access
189
+ if (request.url().startsWith('https://console.cloud.google.com/')) {
190
+ if (response.status() === 200) {
191
+ void response.text().then((text) => {
192
+ // Check if we're actually logged in (not on login page)
193
+ if (!text.includes('accounts.google.com/signin')) {
194
+ loginDetector.isLoggedIn = true;
195
+ }
196
+ });
197
+ }
198
+ }
199
+ }
200
+ async function waitForGoogleLogin(page) {
201
+ const loginDetector = { isLoggedIn: false };
202
+ const responseHandler = (response) => {
203
+ checkGoogleLoginResponse(response, loginDetector);
204
+ };
205
+ page.on('response', responseHandler);
206
+ while (!loginDetector.isLoggedIn) {
207
+ await page.waitForTimeout(100);
208
+ }
209
+ page.off('response', responseHandler);
210
+ }
211
+ class GoogleServiceSession extends BrowserFollowupServiceSession {
212
+ loginDetector = { isLoggedIn: false };
213
+ onResponse(response) {
214
+ checkGoogleLoginResponse(response, this.loginDetector);
215
+ }
216
+ isLoginComplete() {
217
+ return this.loginDetector.isLoggedIn;
218
+ }
219
+ /**
220
+ * Override to skip the spinner page since the OAuth flow requires user interaction
221
+ * (granting consent on Google's authorization page).
222
+ */
223
+ finalizeCredentials(_browser, context, oldCredentials) {
224
+ return this.performBrowserFollowup(context, oldCredentials);
225
+ }
226
+ async performBrowserFollowup(context, oldCredentials) {
227
+ const page = context.pages()[0];
228
+ if (!page) {
229
+ throw new LoginFailedError('No page available in browser context.');
230
+ }
231
+ // Require existing credentials with client ID and secret
232
+ if (!(oldCredentials instanceof OAuthCredentials)) {
233
+ throw new LoginFailedError('Google login requires existing OAuth client credentials. Run prepare first.');
234
+ }
235
+ const clientId = oldCredentials.clientId;
236
+ const clientSecret = oldCredentials.clientSecret;
237
+ // Perform OAuth flow with localhost server
238
+ const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } = await this.performOAuthFlow(context, page, clientId, clientSecret);
239
+ await page.close();
240
+ return new OAuthCredentials(clientId, clientSecret, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt);
241
+ }
242
+ async performOAuthFlow(context, page, clientId, clientSecret) {
243
+ // Use an AbortController to signal the OAuth callback server to shut down
244
+ // when the browser is closed. Listen to both page and context close events
245
+ // to handle all cases where the user might close the browser.
246
+ const abortController = new AbortController();
247
+ const closeHandler = () => {
248
+ abortController.abort();
249
+ };
250
+ page.on('close', closeHandler);
251
+ context.on('close', closeHandler);
252
+ try {
253
+ // Start the callback server first to get the auto-assigned port
254
+ const { port, codePromise } = await startOAuthCallbackServer(LOGIN_TIMEOUT_MS, abortController.signal);
255
+ const redirectUri = `http://localhost:${port.toString()}/oauth2callback`;
256
+ const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
257
+ authUrl.searchParams.set('client_id', clientId);
258
+ authUrl.searchParams.set('redirect_uri', redirectUri);
259
+ authUrl.searchParams.set('response_type', 'code');
260
+ authUrl.searchParams.set('scope', OAUTH_SCOPES.join(' '));
261
+ authUrl.searchParams.set('access_type', 'offline');
262
+ authUrl.searchParams.set('prompt', 'consent');
263
+ await page.goto(authUrl.toString());
264
+ // Wait for the authorization code from the callback
265
+ const code = await codePromise;
266
+ const tokens = exchangeCodeForTokens(GOOGLE_TOKEN_ENDPOINT, code, clientId, clientSecret, redirectUri);
267
+ const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
268
+ // Google refresh tokens typically don't expire, so we don't set refreshTokenExpiresAt
269
+ return {
270
+ accessToken: tokens.access_token,
271
+ refreshToken: tokens.refresh_token,
272
+ accessTokenExpiresAt,
273
+ };
274
+ }
275
+ catch (error) {
276
+ if (error instanceof Error && isBrowserClosedError(error)) {
277
+ throw new LoginCancelledError();
278
+ }
279
+ throw error;
280
+ }
281
+ finally {
282
+ // Remove the close handlers to prevent them from firing when context
283
+ // is closed normally during cleanup
284
+ page.off('close', closeHandler);
285
+ context.off('close', closeHandler);
286
+ }
287
+ }
288
+ }
289
+ export class Google {
290
+ name = 'google';
291
+ displayName = 'Google Workspace';
292
+ baseApiUrls = ['https://www.googleapis.com/'];
293
+ loginUrl = 'https://console.cloud.google.com/';
294
+ info = 'Supports some Google Workspace APIs: Gmail, Calendar, Drive, Sheets, Docs, and Contacts. ' +
295
+ 'If needed, run "latchkey prepare google" to create an OAuth client first. ' +
296
+ 'It may take a few minutes before the OAuth client is ready to use.';
297
+ credentialCheckCurlArguments = [
298
+ 'https://www.googleapis.com/oauth2/v1/userinfo',
299
+ ];
300
+ getSession() {
301
+ return new GoogleServiceSession(this);
302
+ }
303
+ checkApiCredentials(apiCredentials) {
304
+ if (!(apiCredentials instanceof OAuthCredentials)) {
305
+ return ApiCredentialStatus.Invalid;
306
+ }
307
+ // Credentials from prepare() don't have tokens yet
308
+ if (apiCredentials.accessToken === undefined) {
309
+ return ApiCredentialStatus.Missing;
310
+ }
311
+ const result = runCaptured([
312
+ '-s',
313
+ '-o',
314
+ '/dev/null',
315
+ '-w',
316
+ '%{http_code}',
317
+ ...apiCredentials.asCurlArguments(),
318
+ ...this.credentialCheckCurlArguments,
319
+ ], 10);
320
+ if (result.stdout === '200') {
321
+ return ApiCredentialStatus.Valid;
322
+ }
323
+ return ApiCredentialStatus.Invalid;
324
+ }
325
+ async prepare(encryptedStorage, launchOptions) {
326
+ return withTempBrowserContext(encryptedStorage, launchOptions ?? {}, async ({ context }) => {
327
+ const page = await context.newPage();
328
+ await page.goto(this.loginUrl);
329
+ await waitForGoogleLogin(page);
330
+ await showSpinnerPage(context, `Finalizing ${this.displayName} login...\nThis can take a few minutes.`);
331
+ const projectSlug = await createProject(page);
332
+ await enableApis(page, projectSlug);
333
+ await configureBranding(page, projectSlug);
334
+ const { clientId, clientSecret } = await createOAuthClient(page);
335
+ await page.close();
336
+ return new OAuthCredentials(clientId, clientSecret);
337
+ });
338
+ }
339
+ refreshCredentials(apiCredentials) {
340
+ if (!(apiCredentials instanceof OAuthCredentials)) {
341
+ return Promise.resolve(null);
342
+ }
343
+ if (!apiCredentials.refreshToken) {
344
+ return Promise.resolve(null);
345
+ }
346
+ const tokens = refreshAccessToken(GOOGLE_TOKEN_ENDPOINT, apiCredentials.refreshToken, apiCredentials.clientId, apiCredentials.clientSecret);
347
+ if (tokens === null) {
348
+ return Promise.resolve(null);
349
+ }
350
+ // Calculate access token expiration from the expires_in field
351
+ const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
352
+ // Return new credentials with refreshed access token
353
+ // Keep the same refresh token unless a new one is provided
354
+ return Promise.resolve(new OAuthCredentials(apiCredentials.clientId, apiCredentials.clientSecret, tokens.access_token, tokens.refresh_token, accessTokenExpiresAt, apiCredentials.refreshTokenExpiresAt));
355
+ }
356
+ }
357
+ export const GOOGLE = new Google();
358
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/services/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAkB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,6BAA6B,EAC7B,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAGnB,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAChC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,qBAAqB,GAAG,qCAAqC,CAAC;AACpE,MAAM,IAAI,GAAG;IACX,sBAAsB;IACtB,8BAA8B;IAC9B,sBAAsB;IACtB,uBAAuB;IACvB,qBAAqB;IACrB,uBAAuB,EAAE,eAAe;CACzC,CAAC;AACF,MAAM,YAAY,GAAG;IACnB,wCAAwC;IACxC,kDAAkD;IAClD,gDAAgD;IAChD,YAAY;IACZ,gDAAgD;IAChD,8CAA8C;IAC9C,+CAA+C;IAC/C,4CAA4C;IAC5C,eAAe;IACf,0CAA0C;IAC1C,iDAAiD;IACjD,YAAY;IACZ,uCAAuC;IACvC,4CAA4C;IAC5C,aAAa;IACb,8CAA8C;IAC9C,WAAW;IACX,2CAA2C;IAC3C,eAAe;IACf,0CAA0C;IAC1C,mDAAmD;CAC3C,CAAC;AAeX;;GAEG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAC5C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC;QAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,gBAAgB,CACxB,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,SAAS;YAC1B,YAAY,EAAE,MAAM,CAAC,aAAa;SACnC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,gBAAgB,CACxB,uCAAuC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAChG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAU;IACrC,gCAAgC;IAChC,MAAM,IAAI,CAAC,IAAI,CAAC,kEAAkE,EAAE;QAClF,OAAO,EAAE,kBAAkB;KAC5B,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IAC5E,MAAM,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACnE,MAAM,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAElC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAClE,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IACtE,MAAM,gBAAgB,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAEvD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC3D,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAE3B,MAAM,IAAI,CAAC,UAAU,CAAC,4DAA4D,EAAE;QAClF,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CAAC,uDAAuD,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAU,EAAE,WAAmB;IACvD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAU,EAAE,WAAmB,EAAE,OAAe;IACvE,MAAM,IAAI,CAAC,IAAI,CACb,iDAAiD,OAAO,YAAY,WAAW,EAAE,EACjF;QACE,OAAO,EAAE,kBAAkB;KAC5B,CACF,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,uCAAuC;IACrG,MAAM,YAAY,GAAG,IAAI;SACtB,OAAO,CAAC,0DAA0D,CAAC;SACnE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7B,MAAM,oBAAoB,GAAG,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,oBAAoB,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAEtE,IAAI,MAAM,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrD,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,IAAU,EAAE,WAAmB;IAC9D,MAAM,IAAI,CAAC,IAAI,CAAC,0DAA0D,WAAW,EAAE,EAAE;QACvF,OAAO,EAAE,kBAAkB;KAC5B,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;IACpF,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAChE,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IAC1E,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC5D,MAAM,YAAY,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC7D,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;IAC5B,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,KAAK,EAAE,CAAC;IAClF,MAAM,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAClE,MAAM,iBAAiB,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,CAAC;IACjE,MAAM,kBAAkB,CAAC,KAAK,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC5D,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IAEzB,MAAM,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,qBAAqB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrE,MAAM,qBAAqB,CAAC,KAAK,EAAE,CAAC;IACpC,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IAEzB,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;IACxF,MAAM,iBAAiB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACjE,MAAM,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IAEzB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC7D,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC7D,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;IAC5B,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;IACvE,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC5D,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,IAAU;IACzC,+BAA+B;IAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,mDAAmD,EAAE;QACnE,OAAO,EAAE,kBAAkB;KAC5B,CAAC,CAAC;IAEH,oCAAoC;IACpC,MAAM,uBAAuB,GAAG,IAAI,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;IACxF,MAAM,uBAAuB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACvE,MAAM,uBAAuB,CAAC,KAAK,EAAE,CAAC;IAEtC,0BAA0B;IAC1B,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;IAC9F,MAAM,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACnE,MAAM,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAElC,MAAM,uBAAuB,GAAG,IAAI,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,uBAAuB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACvE,MAAM,uBAAuB,CAAC,KAAK,EAAE,CAAC;IAEtC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC7D,MAAM,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAChE,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAE/B,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;IAC7E,MAAM,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC/D,MAAM,eAAe,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC;IAEtD,eAAe;IACf,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAChE,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAE3B,yBAAyB;IACzB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACjE,MAAM,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,gBAAgB,CAAC,uCAAuC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEjD,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,wBAAwB,CAC/B,QAAkB,EAClB,aAAsC;IAEtC,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnC,gEAAgE;IAChE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,mCAAmC,CAAC,EAAE,CAAC;QAClE,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC;YAC9B,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBACjC,wDAAwD;gBACxD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;oBACjD,aAAa,CAAC,UAAU,GAAG,IAAI,CAAC;gBAClC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAU;IAC1C,MAAM,aAAa,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAE5C,MAAM,eAAe,GAAG,CAAC,QAAkB,EAAE,EAAE;QAC7C,wBAAwB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpD,CAAC,CAAC;IAEF,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAErC,OAAO,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,oBAAqB,SAAQ,6BAA6B;IAC7C,aAAa,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAEvD,UAAU,CAAC,QAAkB;QAC3B,wBAAwB,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IAES,eAAe;QACvB,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;;OAGG;IACgB,mBAAmB,CACpC,QAAiB,EACjB,OAAuB,EACvB,cAA+B;QAE/B,OAAO,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC9D,CAAC;IAES,KAAK,CAAC,sBAAsB,CACpC,OAAuB,EACvB,cAA+B;QAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,gBAAgB,CAAC,uCAAuC,CAAC,CAAC;QACtE,CAAC;QAED,yDAAyD;QACzD,IAAI,CAAC,CAAC,cAAc,YAAY,gBAAgB,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,gBAAgB,CACxB,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC;QACzC,MAAM,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC;QAEjD,2CAA2C;QAC3C,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAC9E,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAErE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,OAAO,IAAI,gBAAgB,CACzB,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,CACtB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,OAAuB,EACvB,IAAU,EACV,QAAgB,EAChB,YAAoB;QAOpB,0EAA0E;QAC1E,2EAA2E;QAC3E,8DAA8D;QAC9D,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC9C,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,eAAe,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAElC,IAAI,CAAC;YACH,gEAAgE;YAChE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,wBAAwB,CAC1D,gBAAgB,EAChB,eAAe,CAAC,MAAM,CACvB,CAAC;YACF,MAAM,WAAW,GAAG,oBAAoB,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC;YAEzE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,8CAA8C,CAAC,CAAC;YACxE,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAChD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;YACtD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;YAClD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;YACnD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAE9C,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAEpC,oDAAoD;YACpD,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC/B,MAAM,MAAM,GAAG,qBAAqB,CAClC,qBAAqB,EACrB,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,WAAW,CACZ,CAAC;YACF,MAAM,oBAAoB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAE3F,sFAAsF;YACtF,OAAO;gBACL,WAAW,EAAE,MAAM,CAAC,YAAY;gBAChC,YAAY,EAAE,MAAM,CAAC,aAAa;gBAClC,oBAAoB;aACrB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,KAAK,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1D,MAAM,IAAI,mBAAmB,EAAE,CAAC;YAClC,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,qEAAqE;YACrE,oCAAoC;YACpC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,MAAM;IACR,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,kBAAkB,CAAC;IACjC,WAAW,GAAG,CAAC,6BAA6B,CAAU,CAAC;IACvD,QAAQ,GAAG,mCAAmC,CAAC;IAC/C,IAAI,GACX,2FAA2F;QAC3F,4EAA4E;QAC5E,oEAAoE,CAAC;IAE9D,4BAA4B,GAAG;QACtC,+CAA+C;KACvC,CAAC;IAEX,UAAU;QACR,OAAO,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,mBAAmB,CAAC,cAA8B;QAChD,IAAI,CAAC,CAAC,cAAc,YAAY,gBAAgB,CAAC,EAAE,CAAC;YAClD,OAAO,mBAAmB,CAAC,OAAO,CAAC;QACrC,CAAC;QAED,mDAAmD;QACnD,IAAI,cAAc,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,mBAAmB,CAAC,OAAO,CAAC;QACrC,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CACxB;YACE,IAAI;YACJ,IAAI;YACJ,WAAW;YACX,IAAI;YACJ,cAAc;YACd,GAAG,cAAc,CAAC,eAAe,EAAE;YACnC,GAAG,IAAI,CAAC,4BAA4B;SACrC,EACD,EAAE,CACH,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC5B,OAAO,mBAAmB,CAAC,KAAK,CAAC;QACnC,CAAC;QACD,OAAO,mBAAmB,CAAC,OAAO,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,gBAAkC,EAClC,aAAoC;QAEpC,OAAO,sBAAsB,CAAC,gBAAgB,EAAE,aAAa,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACzF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAE/B,MAAM,eAAe,CACnB,OAAO,EACP,cAAc,IAAI,CAAC,WAAW,yCAAyC,CACxE,CAAC;YACF,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACpC,MAAM,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC3C,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACjE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,IAAI,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,CAAC,cAA8B;QAC/C,IAAI,CAAC,CAAC,cAAc,YAAY,gBAAgB,CAAC,EAAE,CAAC;YAClD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,MAAM,MAAM,GAAG,kBAAkB,CAC/B,qBAAqB,EACrB,cAAc,CAAC,YAAY,EAC3B,cAAc,CAAC,QAAQ,EACvB,cAAc,CAAC,YAAY,CAC5B,CAAC;QAEF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,8DAA8D;QAC9D,MAAM,oBAAoB,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAE3F,qDAAqD;QACrD,2DAA2D;QAC3D,OAAO,OAAO,CAAC,OAAO,CACpB,IAAI,gBAAgB,CAClB,cAAc,CAAC,QAAQ,EACvB,cAAc,CAAC,YAAY,EAC3B,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,aAAa,EACpB,oBAAoB,EACpB,cAAc,CAAC,qBAAqB,CACrC,CACF,CAAC;IACJ,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
@@ -9,4 +9,6 @@ export { Discord, DISCORD } from './discord.js';
9
9
  export { Github, GITHUB } from './github.js';
10
10
  export { Dropbox, DROPBOX } from './dropbox.js';
11
11
  export { Linear, LINEAR } from './linear.js';
12
+ export { Google, GOOGLE } from './google.js';
13
+ export { Notion, NOTION } from './notion.js';
12
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -8,4 +8,6 @@ export { Discord, DISCORD } from './discord.js';
8
8
  export { Github, GITHUB } from './github.js';
9
9
  export { Dropbox, DROPBOX } from './dropbox.js';
10
10
  export { Linear, LINEAR } from './linear.js';
11
+ export { Google, GOOGLE } from './google.js';
12
+ export { Notion, NOTION } from './notion.js';
11
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
@@ -8,12 +8,14 @@ declare class LinearServiceSession extends BrowserFollowupServiceSession {
8
8
  private isLoggedIn;
9
9
  onResponse(response: Response): void;
10
10
  protected isLoginComplete(): boolean;
11
- protected performBrowserFollowup(context: BrowserContext): Promise<ApiCredentials | null>;
11
+ protected performBrowserFollowup(context: BrowserContext, _oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
12
12
  }
13
13
  export declare class Linear implements Service {
14
14
  readonly name = "linear";
15
+ readonly displayName = "Linear";
15
16
  readonly baseApiUrls: readonly ["https://api.linear.app/"];
16
17
  readonly loginUrl = "https://linear.app/imbue/settings/account/security/api-keys/new";
18
+ readonly info = "https://linear.app/developers/graphql";
17
19
  readonly credentialCheckCurlArguments: readonly ["-X", "POST", "-H", "Content-Type: application/json", "-d", "{\"query\": \"{ viewer { id } }\"}", "https://api.linear.app/graphql"];
18
20
  getSession(): LinearServiceSession;
19
21
  checkApiCredentials(apiCredentials: ApiCredentials): ApiCredentialStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAqB,MAAM,sBAAsB,CAAC;AAG9F,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAoB,MAAM,WAAW,CAAC;AAOrF,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA+BpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgChG;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,uCAAwC;IAC5D,QAAQ,CAAC,QAAQ,qEAA0B;IAE3C,QAAQ,CAAC,4BAA4B,gJAQ1B;IAEX,UAAU,IAAI,oBAAoB;IAIlC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,mBAAmB;CAwBzE;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
1
+ {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAqB,MAAM,sBAAsB,CAAC;AAG9F,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAoB,MAAM,WAAW,CAAC;AAOrF,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA+BpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,eAAe,CAAC,EAAE,cAAc,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgClC;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;IAChC,QAAQ,CAAC,WAAW,uCAAwC;IAC5D,QAAQ,CAAC,QAAQ,qEAA0B;IAC3C,QAAQ,CAAC,IAAI,2CAA2C;IAExD,QAAQ,CAAC,4BAA4B,gJAQ1B;IAEX,UAAU,IAAI,oBAAoB;IAIlC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,mBAAmB;CAwBzE;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * Linear service implementation.
3
3
  */
4
- import { randomUUID } from 'node:crypto';
5
4
  import { ApiCredentialStatus, AuthorizationBare } from '../apiCredentials.js';
6
5
  import { runCaptured } from '../curl.js';
7
- import { typeLikeHuman } from '../playwrightUtils.js';
6
+ import { generateLatchkeyAppName, typeLikeHuman } from '../playwrightUtils.js';
8
7
  import { BrowserFollowupServiceSession, LoginFailedError } from './base.js';
9
8
  const DEFAULT_TIMEOUT_MS = 8000;
10
9
  // URL for creating a new personal API key (also used as login URL)
@@ -44,19 +43,19 @@ class LinearServiceSession extends BrowserFollowupServiceSession {
44
43
  isLoginComplete() {
45
44
  return this.isLoggedIn;
46
45
  }
47
- async performBrowserFollowup(context) {
46
+ async performBrowserFollowup(context, _oldCredentials) {
48
47
  const page = context.pages()[0];
49
48
  if (!page) {
50
49
  throw new LoginFailedError('No page available in browser context.');
51
50
  }
52
51
  await page.goto(LINEAR_NEW_API_KEY_URL);
53
52
  // Fill in the key name
54
- const keyName = `Latchkey-${randomUUID().slice(0, 8)}`;
55
- const keyNameInput = page.getByRole('textbox', { name: 'Key name' });
53
+ const keyName = generateLatchkeyAppName();
54
+ const keyNameInput = page.locator('//*[@id="label"]');
56
55
  await keyNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
57
56
  await typeLikeHuman(page, keyNameInput, keyName);
58
57
  // Click the Create button
59
- const createButton = page.getByRole('button', { name: 'Create' });
58
+ const createButton = page.locator('button[type="submit"]');
60
59
  await createButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
61
60
  await createButton.click();
62
61
  // Wait for and extract the token from span element containing lin_api_ prefix
@@ -72,8 +71,10 @@ class LinearServiceSession extends BrowserFollowupServiceSession {
72
71
  }
73
72
  export class Linear {
74
73
  name = 'linear';
74
+ displayName = 'Linear';
75
75
  baseApiUrls = ['https://api.linear.app/'];
76
76
  loginUrl = LINEAR_NEW_API_KEY_URL;
77
+ info = 'https://linear.app/developers/graphql';
77
78
  credentialCheckCurlArguments = [
78
79
  '-X',
79
80
  'POST',
@@ -1 +1 @@
1
- {"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Notion service implementation.
3
+ *
4
+ * This has some severe limitations:
5
+ *
6
+ * - It requires the UI to be in English.
7
+ * - It only grants access to the private pages that existed at the time of login.
8
+ */
9
+ import type { Response, BrowserContext } from 'playwright';
10
+ import { ApiCredentialStatus, ApiCredentials } from '../apiCredentials.js';
11
+ import { Service, BrowserFollowupServiceSession } from './base.js';
12
+ declare class NotionServiceSession extends BrowserFollowupServiceSession {
13
+ private isLoggedIn;
14
+ onResponse(response: Response): void;
15
+ protected isLoginComplete(): boolean;
16
+ protected performBrowserFollowup(context: BrowserContext): Promise<ApiCredentials | null>;
17
+ }
18
+ export declare class Notion implements Service {
19
+ readonly name = "notion";
20
+ readonly displayName = "Notion";
21
+ readonly baseApiUrls: readonly ["https://api.notion.com/"];
22
+ readonly loginUrl = "https://www.notion.so/profile/integrations/form/new-integration";
23
+ readonly info: string;
24
+ readonly credentialCheckCurlArguments: readonly ["-H", "Notion-Version: 2022-06-28", "https://api.notion.com/v1/users/me"];
25
+ getSession(): NotionServiceSession;
26
+ checkApiCredentials(apiCredentials: ApiCredentials): ApiCredentialStatus;
27
+ }
28
+ export declare const NOTION: Notion;
29
+ export {};
30
+ //# sourceMappingURL=notion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion.d.ts","sourceRoot":"","sources":["../../../src/services/notion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAGhG,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAoB,MAAM,WAAW,CAAC;AAMrF,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IASpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgEhG;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;IAChC,QAAQ,CAAC,WAAW,uCAAwC;IAC5D,QAAQ,CAAC,QAAQ,qEAA2B;IAC5C,QAAQ,CAAC,IAAI,SAG2E;IAExF,QAAQ,CAAC,4BAA4B,sFAI1B;IAEX,UAAU,IAAI,oBAAoB;IAIlC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,mBAAmB;CAuBzE;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}