fastmode-mcp 1.0.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 (67) hide show
  1. package/README.md +561 -0
  2. package/bin/run.js +50 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +802 -0
  6. package/dist/lib/api-client.d.ts +81 -0
  7. package/dist/lib/api-client.d.ts.map +1 -0
  8. package/dist/lib/api-client.js +237 -0
  9. package/dist/lib/auth-state.d.ts +13 -0
  10. package/dist/lib/auth-state.d.ts.map +1 -0
  11. package/dist/lib/auth-state.js +24 -0
  12. package/dist/lib/context-fetcher.d.ts +67 -0
  13. package/dist/lib/context-fetcher.d.ts.map +1 -0
  14. package/dist/lib/context-fetcher.js +190 -0
  15. package/dist/lib/credentials.d.ts +52 -0
  16. package/dist/lib/credentials.d.ts.map +1 -0
  17. package/dist/lib/credentials.js +196 -0
  18. package/dist/lib/device-flow.d.ts +14 -0
  19. package/dist/lib/device-flow.d.ts.map +1 -0
  20. package/dist/lib/device-flow.js +244 -0
  21. package/dist/tools/cms-items.d.ts +56 -0
  22. package/dist/tools/cms-items.d.ts.map +1 -0
  23. package/dist/tools/cms-items.js +376 -0
  24. package/dist/tools/create-site.d.ts +9 -0
  25. package/dist/tools/create-site.d.ts.map +1 -0
  26. package/dist/tools/create-site.js +202 -0
  27. package/dist/tools/deploy-package.d.ts +9 -0
  28. package/dist/tools/deploy-package.d.ts.map +1 -0
  29. package/dist/tools/deploy-package.js +434 -0
  30. package/dist/tools/generate-samples.d.ts +19 -0
  31. package/dist/tools/generate-samples.d.ts.map +1 -0
  32. package/dist/tools/generate-samples.js +272 -0
  33. package/dist/tools/get-conversion-guide.d.ts +7 -0
  34. package/dist/tools/get-conversion-guide.d.ts.map +1 -0
  35. package/dist/tools/get-conversion-guide.js +1323 -0
  36. package/dist/tools/get-example.d.ts +7 -0
  37. package/dist/tools/get-example.d.ts.map +1 -0
  38. package/dist/tools/get-example.js +1568 -0
  39. package/dist/tools/get-field-types.d.ts +30 -0
  40. package/dist/tools/get-field-types.d.ts.map +1 -0
  41. package/dist/tools/get-field-types.js +154 -0
  42. package/dist/tools/get-schema.d.ts +5 -0
  43. package/dist/tools/get-schema.d.ts.map +1 -0
  44. package/dist/tools/get-schema.js +320 -0
  45. package/dist/tools/get-started.d.ts +21 -0
  46. package/dist/tools/get-started.d.ts.map +1 -0
  47. package/dist/tools/get-started.js +624 -0
  48. package/dist/tools/get-tenant-schema.d.ts +18 -0
  49. package/dist/tools/get-tenant-schema.d.ts.map +1 -0
  50. package/dist/tools/get-tenant-schema.js +158 -0
  51. package/dist/tools/list-projects.d.ts +5 -0
  52. package/dist/tools/list-projects.d.ts.map +1 -0
  53. package/dist/tools/list-projects.js +101 -0
  54. package/dist/tools/sync-schema.d.ts +41 -0
  55. package/dist/tools/sync-schema.d.ts.map +1 -0
  56. package/dist/tools/sync-schema.js +483 -0
  57. package/dist/tools/validate-manifest.d.ts +5 -0
  58. package/dist/tools/validate-manifest.d.ts.map +1 -0
  59. package/dist/tools/validate-manifest.js +311 -0
  60. package/dist/tools/validate-package.d.ts +5 -0
  61. package/dist/tools/validate-package.d.ts.map +1 -0
  62. package/dist/tools/validate-package.js +337 -0
  63. package/dist/tools/validate-template.d.ts +12 -0
  64. package/dist/tools/validate-template.d.ts.map +1 -0
  65. package/dist/tools/validate-template.js +790 -0
  66. package/package.json +54 -0
  67. package/scripts/postinstall.js +129 -0
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getCredentialsPath = getCredentialsPath;
37
+ exports.loadCredentials = loadCredentials;
38
+ exports.saveCredentials = saveCredentials;
39
+ exports.deleteCredentials = deleteCredentials;
40
+ exports.hasCredentials = hasCredentials;
41
+ exports.isTokenExpired = isTokenExpired;
42
+ exports.getApiUrl = getApiUrl;
43
+ exports.refreshAccessToken = refreshAccessToken;
44
+ exports.getValidCredentials = getValidCredentials;
45
+ exports.getAuthToken = getAuthToken;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const os = __importStar(require("os"));
49
+ /**
50
+ * Get the path to the credentials file
51
+ */
52
+ function getCredentialsPath() {
53
+ const configDir = path.join(os.homedir(), '.fastmode');
54
+ return path.join(configDir, 'credentials.json');
55
+ }
56
+ /**
57
+ * Ensure the config directory exists
58
+ */
59
+ function ensureConfigDir() {
60
+ const configDir = path.dirname(getCredentialsPath());
61
+ if (!fs.existsSync(configDir)) {
62
+ fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
63
+ }
64
+ }
65
+ /**
66
+ * Load stored credentials from disk
67
+ */
68
+ function loadCredentials() {
69
+ const credentialsPath = getCredentialsPath();
70
+ try {
71
+ if (!fs.existsSync(credentialsPath)) {
72
+ return null;
73
+ }
74
+ const content = fs.readFileSync(credentialsPath, 'utf-8');
75
+ const credentials = JSON.parse(content);
76
+ // Validate required fields
77
+ if (!credentials.accessToken || !credentials.refreshToken || !credentials.expiresAt || !credentials.email) {
78
+ return null;
79
+ }
80
+ return credentials;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Save credentials to disk
88
+ */
89
+ function saveCredentials(credentials) {
90
+ ensureConfigDir();
91
+ const credentialsPath = getCredentialsPath();
92
+ // Write with restricted permissions (owner read/write only)
93
+ fs.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), { mode: 0o600 });
94
+ }
95
+ /**
96
+ * Delete stored credentials
97
+ */
98
+ function deleteCredentials() {
99
+ const credentialsPath = getCredentialsPath();
100
+ try {
101
+ if (fs.existsSync(credentialsPath)) {
102
+ fs.unlinkSync(credentialsPath);
103
+ }
104
+ }
105
+ catch {
106
+ // Ignore errors
107
+ }
108
+ }
109
+ /**
110
+ * Check if credentials exist
111
+ */
112
+ function hasCredentials() {
113
+ return loadCredentials() !== null;
114
+ }
115
+ /**
116
+ * Check if the access token is expired or about to expire
117
+ */
118
+ function isTokenExpired(credentials, bufferMinutes = 5) {
119
+ const expiresAt = new Date(credentials.expiresAt);
120
+ const bufferMs = bufferMinutes * 60 * 1000;
121
+ return Date.now() >= expiresAt.getTime() - bufferMs;
122
+ }
123
+ /**
124
+ * Get the API URL from environment or default
125
+ */
126
+ function getApiUrl() {
127
+ return process.env.FASTMODE_API_URL || 'https://api.fastmode.ai';
128
+ }
129
+ /**
130
+ * Refresh the access token using the refresh token
131
+ */
132
+ async function refreshAccessToken(credentials) {
133
+ const apiUrl = getApiUrl();
134
+ try {
135
+ const response = await fetch(`${apiUrl}/api/auth/device/refresh`, {
136
+ method: 'POST',
137
+ headers: {
138
+ 'Content-Type': 'application/json',
139
+ },
140
+ body: JSON.stringify({
141
+ refresh_token: credentials.refreshToken,
142
+ grant_type: 'refresh_token',
143
+ }),
144
+ });
145
+ if (!response.ok) {
146
+ // Refresh token is invalid or expired - need to re-authenticate
147
+ return null;
148
+ }
149
+ const data = await response.json();
150
+ if (!data.success || !data.data) {
151
+ return null;
152
+ }
153
+ const newCredentials = {
154
+ accessToken: data.data.access_token,
155
+ refreshToken: data.data.refresh_token,
156
+ expiresAt: new Date(Date.now() + data.data.expires_in * 1000).toISOString(),
157
+ email: data.data.email,
158
+ name: data.data.name,
159
+ };
160
+ // Save the new credentials
161
+ saveCredentials(newCredentials);
162
+ return newCredentials;
163
+ }
164
+ catch {
165
+ return null;
166
+ }
167
+ }
168
+ /**
169
+ * Get valid credentials, refreshing if needed
170
+ * Returns null if no credentials or refresh fails
171
+ */
172
+ async function getValidCredentials() {
173
+ const credentials = loadCredentials();
174
+ if (!credentials) {
175
+ return null;
176
+ }
177
+ // Check if token is expired or about to expire
178
+ if (isTokenExpired(credentials)) {
179
+ // Try to refresh
180
+ const newCredentials = await refreshAccessToken(credentials);
181
+ if (!newCredentials) {
182
+ // Refresh failed - credentials are invalid
183
+ deleteCredentials();
184
+ return null;
185
+ }
186
+ return newCredentials;
187
+ }
188
+ return credentials;
189
+ }
190
+ /**
191
+ * Get the current auth token (access token) if available and valid
192
+ */
193
+ async function getAuthToken() {
194
+ const credentials = await getValidCredentials();
195
+ return credentials?.accessToken || null;
196
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Start the device authorization flow
3
+ * Returns a message describing the flow status
4
+ */
5
+ export declare function startDeviceFlow(): Promise<string>;
6
+ /**
7
+ * Check if device flow authentication is needed and perform it if so
8
+ * Returns the authentication result message
9
+ */
10
+ export declare function ensureAuthenticated(): Promise<{
11
+ authenticated: boolean;
12
+ message: string;
13
+ }>;
14
+ //# sourceMappingURL=device-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/lib/device-flow.ts"],"names":[],"mappings":"AA0DA;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAqGvD;AA0ED;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2BhG"}
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.startDeviceFlow = startDeviceFlow;
37
+ exports.ensureAuthenticated = ensureAuthenticated;
38
+ const child_process_1 = require("child_process");
39
+ const credentials_1 = require("./credentials");
40
+ /**
41
+ * Open a URL in the default browser
42
+ */
43
+ function openBrowser(url) {
44
+ return new Promise((resolve) => {
45
+ // Determine the command based on platform
46
+ let command;
47
+ switch (process.platform) {
48
+ case 'darwin':
49
+ command = `open "${url}"`;
50
+ break;
51
+ case 'win32':
52
+ command = `start "" "${url}"`;
53
+ break;
54
+ default:
55
+ // Linux and others
56
+ command = `xdg-open "${url}"`;
57
+ }
58
+ (0, child_process_1.exec)(command, (error) => {
59
+ if (error) {
60
+ // Don't fail if browser can't open - user can manually navigate
61
+ resolve();
62
+ }
63
+ else {
64
+ resolve();
65
+ }
66
+ });
67
+ });
68
+ }
69
+ /**
70
+ * Start the device authorization flow
71
+ * Returns a message describing the flow status
72
+ */
73
+ async function startDeviceFlow() {
74
+ const apiUrl = (0, credentials_1.getApiUrl)();
75
+ // Step 1: Request device authorization
76
+ let authResponse;
77
+ try {
78
+ const response = await fetch(`${apiUrl}/api/auth/device/authorize`, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ },
83
+ body: JSON.stringify({
84
+ clientName: 'FastMode MCP',
85
+ }),
86
+ });
87
+ if (!response.ok) {
88
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
89
+ return `# Authentication Error
90
+
91
+ Failed to start device authorization: ${error.error || response.statusText}
92
+
93
+ Please check:
94
+ 1. Your network connection
95
+ 2. The API URL is correct (${apiUrl})
96
+ `;
97
+ }
98
+ const data = await response.json();
99
+ authResponse = data.data;
100
+ }
101
+ catch (error) {
102
+ return `# Network Error
103
+
104
+ Unable to connect to FastMode API.
105
+
106
+ **API URL:** ${apiUrl}
107
+ **Error:** ${error instanceof Error ? error.message : 'Unknown error'}
108
+
109
+ Please check your network connection and try again.
110
+ `;
111
+ }
112
+ // Step 2: Open browser for user authorization
113
+ try {
114
+ await openBrowser(authResponse.verification_uri_complete);
115
+ }
116
+ catch {
117
+ // Browser failed to open - user will need to navigate manually
118
+ }
119
+ // Step 3: Poll for authorization
120
+ const pollInterval = (authResponse.interval || 5) * 1000; // seconds to ms
121
+ const expiresAt = Date.now() + authResponse.expires_in * 1000;
122
+ // Log instructions to stderr for user visibility
123
+ console.error(`
124
+ # Device Authorization
125
+
126
+ A browser window should open automatically.
127
+
128
+ If it doesn't, please visit:
129
+ ${authResponse.verification_uri}
130
+
131
+ And enter this code: ${authResponse.user_code}
132
+
133
+ **Don't have a Fast Mode account?**
134
+ Sign up at https://fastmode.ai first, then return here.
135
+
136
+ Waiting for authorization...
137
+ `);
138
+ // Start polling
139
+ const pollResult = await pollForToken(apiUrl, authResponse.device_code, pollInterval, expiresAt);
140
+ if (pollResult.success && pollResult.credentials) {
141
+ // Save credentials
142
+ (0, credentials_1.saveCredentials)(pollResult.credentials);
143
+ return `# Authentication Successful
144
+
145
+ Logged in as: **${pollResult.credentials.email}**${pollResult.credentials.name ? ` (${pollResult.credentials.name})` : ''}
146
+
147
+ Credentials saved to ~/.fastmode/credentials.json
148
+
149
+ You can now use FastMode MCP tools.
150
+ `;
151
+ }
152
+ else {
153
+ return `# Authentication Failed
154
+
155
+ ${pollResult.error || 'Authorization timed out or was denied.'}
156
+
157
+ **Don't have an account?**
158
+ Sign up at https://fastmode.ai and then try again.
159
+
160
+ **To retry:** Call any authenticated tool like \`list_projects\` to start a new auth flow.
161
+ `;
162
+ }
163
+ }
164
+ /**
165
+ * Poll the token endpoint until authorization is complete or timeout
166
+ */
167
+ async function pollForToken(apiUrl, deviceCode, interval, expiresAt) {
168
+ while (Date.now() < expiresAt) {
169
+ // Wait for the polling interval
170
+ await new Promise(resolve => setTimeout(resolve, interval));
171
+ try {
172
+ const response = await fetch(`${apiUrl}/api/auth/device/token`, {
173
+ method: 'POST',
174
+ headers: {
175
+ 'Content-Type': 'application/json',
176
+ },
177
+ body: JSON.stringify({
178
+ device_code: deviceCode,
179
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
180
+ }),
181
+ });
182
+ const data = await response.json();
183
+ if (response.ok && data.success && data.data) {
184
+ // Authorization successful!
185
+ const tokenData = data.data;
186
+ const credentials = {
187
+ accessToken: tokenData.access_token,
188
+ refreshToken: tokenData.refresh_token,
189
+ expiresAt: new Date(Date.now() + tokenData.expires_in * 1000).toISOString(),
190
+ email: tokenData.email,
191
+ name: tokenData.name,
192
+ };
193
+ return { success: true, credentials };
194
+ }
195
+ // Check for specific error codes
196
+ if (data.error === 'authorization_pending') {
197
+ // User hasn't authorized yet - keep polling
198
+ continue;
199
+ }
200
+ if (data.error === 'slow_down') {
201
+ // Server is asking us to slow down
202
+ interval = Math.min(interval * 2, 30000); // Max 30 seconds
203
+ continue;
204
+ }
205
+ if (data.error === 'expired_token') {
206
+ return { success: false, error: 'The authorization request expired. Please try again.' };
207
+ }
208
+ if (data.error === 'access_denied') {
209
+ return { success: false, error: 'Authorization was denied. Please try again.' };
210
+ }
211
+ // Unknown error - keep polling
212
+ }
213
+ catch {
214
+ // Network error - keep trying
215
+ }
216
+ }
217
+ return { success: false, error: 'Authorization timed out. Please try again.' };
218
+ }
219
+ /**
220
+ * Check if device flow authentication is needed and perform it if so
221
+ * Returns the authentication result message
222
+ */
223
+ async function ensureAuthenticated() {
224
+ // Import here to avoid circular dependency
225
+ const { getValidCredentials } = await Promise.resolve().then(() => __importStar(require('./credentials')));
226
+ const { waitForAuth } = await Promise.resolve().then(() => __importStar(require('./auth-state')));
227
+ // Wait for any startup auth that might be in progress
228
+ await waitForAuth();
229
+ const credentials = await getValidCredentials();
230
+ if (credentials) {
231
+ return {
232
+ authenticated: true,
233
+ message: `Authenticated as ${credentials.email}`,
234
+ };
235
+ }
236
+ // Need to authenticate
237
+ const result = await startDeviceFlow();
238
+ // Check if authentication was successful
239
+ const newCredentials = await getValidCredentials();
240
+ return {
241
+ authenticated: !!newCredentials,
242
+ message: result,
243
+ };
244
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * CMS Item Management Tools
3
+ *
4
+ * CRUD operations for managing items in CMS collections via the dashboard API.
5
+ */
6
+ /**
7
+ * Create a new item in a CMS collection
8
+ */
9
+ export declare function createCmsItem(params: {
10
+ projectId: string;
11
+ collectionSlug: string;
12
+ name: string;
13
+ slug?: string;
14
+ data: Record<string, unknown>;
15
+ publishedAt?: string;
16
+ }): Promise<string>;
17
+ /**
18
+ * List items in a CMS collection
19
+ */
20
+ export declare function listCmsItems(params: {
21
+ projectId: string;
22
+ collectionSlug: string;
23
+ limit?: number;
24
+ sort?: string;
25
+ order?: 'asc' | 'desc';
26
+ }): Promise<string>;
27
+ /**
28
+ * Get a single item by slug
29
+ */
30
+ export declare function getCmsItem(params: {
31
+ projectId: string;
32
+ collectionSlug: string;
33
+ itemSlug: string;
34
+ }): Promise<string>;
35
+ /**
36
+ * Update an existing item
37
+ */
38
+ export declare function updateCmsItem(params: {
39
+ projectId: string;
40
+ collectionSlug: string;
41
+ itemSlug: string;
42
+ name?: string;
43
+ data?: Record<string, unknown>;
44
+ publishedAt?: string | null;
45
+ }): Promise<string>;
46
+ /**
47
+ * Delete an item from a collection
48
+ * REQUIRES confirmDelete: true to execute
49
+ */
50
+ export declare function deleteCmsItem(params: {
51
+ projectId: string;
52
+ collectionSlug: string;
53
+ itemSlug: string;
54
+ confirmDelete: boolean;
55
+ }): Promise<string>;
56
+ //# sourceMappingURL=cms-items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-items.d.ts","sourceRoot":"","sources":["../../src/tools/cms-items.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqFH;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDlB;AAkBD;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ClB;AA4CD;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ClB;AAoBD;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ElB;AAkBD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwElB"}