@disruptorganic/mcp-google-search-console 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 (108) hide show
  1. package/.env.example +141 -0
  2. package/LICENSE +21 -0
  3. package/README.md +0 -0
  4. package/dist/auth/index.d.ts +3 -0
  5. package/dist/auth/index.d.ts.map +1 -0
  6. package/dist/auth/index.js +2 -0
  7. package/dist/auth/index.js.map +1 -0
  8. package/dist/auth/oauth2.d.ts +31 -0
  9. package/dist/auth/oauth2.d.ts.map +1 -0
  10. package/dist/auth/oauth2.js +380 -0
  11. package/dist/auth/oauth2.js.map +1 -0
  12. package/dist/config/index.d.ts +36 -0
  13. package/dist/config/index.d.ts.map +1 -0
  14. package/dist/config/index.js +87 -0
  15. package/dist/config/index.js.map +1 -0
  16. package/dist/gsc/client.d.ts +72 -0
  17. package/dist/gsc/client.d.ts.map +1 -0
  18. package/dist/gsc/client.js +243 -0
  19. package/dist/gsc/client.js.map +1 -0
  20. package/dist/gsc/index.d.ts +3 -0
  21. package/dist/gsc/index.d.ts.map +1 -0
  22. package/dist/gsc/index.js +3 -0
  23. package/dist/gsc/index.js.map +1 -0
  24. package/dist/gsc/properties.d.ts +42 -0
  25. package/dist/gsc/properties.d.ts.map +1 -0
  26. package/dist/gsc/properties.js +393 -0
  27. package/dist/gsc/properties.js.map +1 -0
  28. package/dist/gsc/queries.d.ts +73 -0
  29. package/dist/gsc/queries.d.ts.map +1 -0
  30. package/dist/gsc/queries.js +390 -0
  31. package/dist/gsc/queries.js.map +1 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +186 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/tools/compare-date-ranges.d.ts +83 -0
  37. package/dist/tools/compare-date-ranges.d.ts.map +1 -0
  38. package/dist/tools/compare-date-ranges.js +462 -0
  39. package/dist/tools/compare-date-ranges.js.map +1 -0
  40. package/dist/tools/get-property-info.d.ts +30 -0
  41. package/dist/tools/get-property-info.d.ts.map +1 -0
  42. package/dist/tools/get-property-info.js +174 -0
  43. package/dist/tools/get-property-info.js.map +1 -0
  44. package/dist/tools/get-top-pages.d.ts +103 -0
  45. package/dist/tools/get-top-pages.d.ts.map +1 -0
  46. package/dist/tools/get-top-pages.js +254 -0
  47. package/dist/tools/get-top-pages.js.map +1 -0
  48. package/dist/tools/get-top-queries.d.ts +103 -0
  49. package/dist/tools/get-top-queries.d.ts.map +1 -0
  50. package/dist/tools/get-top-queries.js +254 -0
  51. package/dist/tools/get-top-queries.js.map +1 -0
  52. package/dist/tools/health-check.d.ts +12 -0
  53. package/dist/tools/health-check.d.ts.map +1 -0
  54. package/dist/tools/health-check.js +107 -0
  55. package/dist/tools/health-check.js.map +1 -0
  56. package/dist/tools/index.d.ts +1124 -0
  57. package/dist/tools/index.d.ts.map +1 -0
  58. package/dist/tools/index.js +70 -0
  59. package/dist/tools/index.js.map +1 -0
  60. package/dist/tools/list-properties.d.ts +50 -0
  61. package/dist/tools/list-properties.d.ts.map +1 -0
  62. package/dist/tools/list-properties.js +234 -0
  63. package/dist/tools/list-properties.js.map +1 -0
  64. package/dist/tools/query-advanced.d.ts +109 -0
  65. package/dist/tools/query-advanced.d.ts.map +1 -0
  66. package/dist/tools/query-advanced.js +378 -0
  67. package/dist/tools/query-advanced.js.map +1 -0
  68. package/dist/tools/query-by-keyword.d.ts +115 -0
  69. package/dist/tools/query-by-keyword.d.ts.map +1 -0
  70. package/dist/tools/query-by-keyword.js +339 -0
  71. package/dist/tools/query-by-keyword.js.map +1 -0
  72. package/dist/tools/query-by-url.d.ts +116 -0
  73. package/dist/tools/query-by-url.d.ts.map +1 -0
  74. package/dist/tools/query-by-url.js +366 -0
  75. package/dist/tools/query-by-url.js.map +1 -0
  76. package/dist/utils/cache.d.ts +22 -0
  77. package/dist/utils/cache.d.ts.map +1 -0
  78. package/dist/utils/cache.js +75 -0
  79. package/dist/utils/cache.js.map +1 -0
  80. package/dist/utils/index.d.ts +8 -0
  81. package/dist/utils/index.d.ts.map +1 -0
  82. package/dist/utils/index.js +8 -0
  83. package/dist/utils/index.js.map +1 -0
  84. package/dist/utils/logger.d.ts +4 -0
  85. package/dist/utils/logger.d.ts.map +1 -0
  86. package/dist/utils/logger.js +15 -0
  87. package/dist/utils/logger.js.map +1 -0
  88. package/dist/utils/metrics.d.ts +9 -0
  89. package/dist/utils/metrics.d.ts.map +1 -0
  90. package/dist/utils/metrics.js +54 -0
  91. package/dist/utils/metrics.js.map +1 -0
  92. package/dist/utils/rate-limiter.d.ts +24 -0
  93. package/dist/utils/rate-limiter.d.ts.map +1 -0
  94. package/dist/utils/rate-limiter.js +175 -0
  95. package/dist/utils/rate-limiter.js.map +1 -0
  96. package/dist/utils/token-estimator.d.ts +33 -0
  97. package/dist/utils/token-estimator.d.ts.map +1 -0
  98. package/dist/utils/token-estimator.js +226 -0
  99. package/dist/utils/token-estimator.js.map +1 -0
  100. package/dist/utils/types.d.ts +68 -0
  101. package/dist/utils/types.d.ts.map +1 -0
  102. package/dist/utils/types.js +13 -0
  103. package/dist/utils/types.js.map +1 -0
  104. package/dist/utils/validators.d.ts +579 -0
  105. package/dist/utils/validators.d.ts.map +1 -0
  106. package/dist/utils/validators.js +358 -0
  107. package/dist/utils/validators.js.map +1 -0
  108. package/package.json +73 -0
@@ -0,0 +1,254 @@
1
+ import { listProperties, matchProperty, generatePropertyMatchError } from '../gsc/properties.js';
2
+ import { executeTopNQuery } from '../gsc/queries.js';
3
+ import { getTopQueriesParamsSchema } from '../utils/validators.js';
4
+ import { logger } from '../utils/logger.js';
5
+ export const getTopQueriesTool = {
6
+ name: 'get_top_queries',
7
+ description: 'Quickly retrieves top performing search queries for a property. Returns the most impactful keywords sorted by clicks, impressions, CTR, or position. Ideal for quick insights into what drives traffic. Supports filtering by minimum thresholds (e.g., min 100 clicks), position ranges (e.g., positions 1-10), and date ranges. No chunking needed - results fit within token limits. IMPORTANT: Use list_properties first to get the correct property identifier.',
8
+ inputSchema: {
9
+ type: 'object',
10
+ properties: {
11
+ property: {
12
+ type: 'string',
13
+ description: 'Property identifier from list_properties (e.g., "sc-domain:example.com")',
14
+ },
15
+ startDate: {
16
+ type: 'string',
17
+ description: 'Start date in ISO 8601 format (YYYY-MM-DD)',
18
+ pattern: '^\\d{4}-\\d{2}-\\d{2}$',
19
+ },
20
+ endDate: {
21
+ type: 'string',
22
+ description: 'End date in ISO 8601 format (YYYY-MM-DD)',
23
+ pattern: '^\\d{4}-\\d{2}-\\d{2}$',
24
+ },
25
+ limit: {
26
+ type: 'number',
27
+ description: 'Number of top queries to return (1-1000, default: 20)',
28
+ minimum: 1,
29
+ maximum: 1000,
30
+ default: 20,
31
+ },
32
+ sortBy: {
33
+ type: 'string',
34
+ enum: ['clicks', 'impressions', 'ctr', 'position'],
35
+ description: 'Metric to sort by (default: clicks)',
36
+ default: 'clicks',
37
+ },
38
+ sortOrder: {
39
+ type: 'string',
40
+ enum: ['asc', 'desc'],
41
+ description: 'Sort order (default: desc)',
42
+ default: 'desc',
43
+ },
44
+ searchType: {
45
+ type: 'string',
46
+ enum: ['web', 'image', 'video', 'news', 'discover', 'googleNews'],
47
+ description: 'Search type filter (default: web)',
48
+ default: 'web',
49
+ },
50
+ minClicks: {
51
+ type: 'number',
52
+ description: 'Minimum clicks threshold (optional)',
53
+ minimum: 0,
54
+ },
55
+ minImpressions: {
56
+ type: 'number',
57
+ description: 'Minimum impressions threshold (optional)',
58
+ minimum: 0,
59
+ },
60
+ positionRange: {
61
+ type: 'object',
62
+ properties: {
63
+ min: {
64
+ type: 'number',
65
+ description: 'Minimum position (e.g., 1)',
66
+ minimum: 1,
67
+ },
68
+ max: {
69
+ type: 'number',
70
+ description: 'Maximum position (e.g., 10)',
71
+ minimum: 1,
72
+ },
73
+ },
74
+ required: ['min', 'max'],
75
+ description: 'Filter by position range (optional)',
76
+ },
77
+ deviceType: {
78
+ type: 'string',
79
+ enum: ['desktop', 'mobile', 'tablet'],
80
+ description: 'Filter by device type (optional)',
81
+ },
82
+ country: {
83
+ type: 'string',
84
+ description: '3-letter country code (e.g., "usa", "gbr") (optional)',
85
+ pattern: '^[a-z]{3}$',
86
+ },
87
+ },
88
+ required: ['property', 'startDate', 'endDate'],
89
+ },
90
+ };
91
+ export async function handleGetTopQueries(params, client) {
92
+ try {
93
+ logger.info('Handling get_top_queries request', {
94
+ propertyInput: params.property,
95
+ limit: params.limit || 20,
96
+ sortBy: params.sortBy || 'clicks',
97
+ dateRange: params.startDate && params.endDate ? `${params.startDate} to ${params.endDate}` : 'not provided',
98
+ });
99
+ const validationResult = getTopQueriesParamsSchema.safeParse(params);
100
+ if (!validationResult.success) {
101
+ const errorMessages = validationResult.error.issues.map(issue => {
102
+ const path = issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';
103
+ return `${path}${issue.message}`;
104
+ }).join('; ');
105
+ logger.error('Input validation failed', {
106
+ errors: errorMessages,
107
+ params,
108
+ });
109
+ return {
110
+ content: [{
111
+ type: 'text',
112
+ text: JSON.stringify({
113
+ error: 'Input validation failed',
114
+ details: errorMessages,
115
+ }, null, 2),
116
+ }],
117
+ isError: true,
118
+ };
119
+ }
120
+ const validated = validationResult.data;
121
+ const { property, startDate, endDate, limit = 20, sortBy = 'clicks', sortOrder = 'desc', searchType = 'web', minClicks, minImpressions, positionRange, deviceType, country, } = validated;
122
+ logger.debug('Fetching available properties');
123
+ const availableProperties = await listProperties(client);
124
+ if (availableProperties.length === 0) {
125
+ logger.warn('No properties found for this account');
126
+ return {
127
+ content: [{
128
+ type: 'text',
129
+ text: JSON.stringify({
130
+ error: 'No properties found',
131
+ details: 'No Google Search Console properties are accessible with this account. Please verify your account has access to at least one property.',
132
+ }, null, 2),
133
+ }],
134
+ isError: true,
135
+ };
136
+ }
137
+ const matchResult = matchProperty(property, availableProperties);
138
+ if (!matchResult.matched) {
139
+ const errorMessage = generatePropertyMatchError(matchResult, availableProperties);
140
+ logger.error('Property matching failed', {
141
+ searchInput: property,
142
+ matchType: matchResult.matchType,
143
+ alternativeCount: matchResult.alternatives?.length || 0,
144
+ });
145
+ return {
146
+ content: [{
147
+ type: 'text',
148
+ text: JSON.stringify({
149
+ error: 'Property not found or ambiguous',
150
+ details: errorMessage,
151
+ }, null, 2),
152
+ }],
153
+ isError: true,
154
+ };
155
+ }
156
+ const matchedProperty = matchResult.matched;
157
+ logger.info('Property matched successfully', {
158
+ searchInput: property,
159
+ matched: matchedProperty.propertyUrl,
160
+ matchType: matchResult.matchType,
161
+ });
162
+ logger.info('Executing top queries query', {
163
+ property: matchedProperty.propertyUrl,
164
+ limit,
165
+ dateRange: `${startDate} to ${endDate}`,
166
+ });
167
+ const results = await executeTopNQuery(client, matchedProperty.propertyUrl, startDate, endDate, 'query', {
168
+ limit,
169
+ sortBy: sortBy,
170
+ sortOrder: sortOrder,
171
+ searchType,
172
+ minClicks,
173
+ minImpressions,
174
+ positionRange,
175
+ deviceType,
176
+ country,
177
+ });
178
+ const topQueries = results.map((row) => ({
179
+ query: row.keys[0] || '',
180
+ clicks: row.clicks,
181
+ impressions: row.impressions,
182
+ ctr: row.ctr,
183
+ position: row.position,
184
+ }));
185
+ const filters = {};
186
+ if (minClicks !== undefined)
187
+ filters.minClicks = minClicks;
188
+ if (minImpressions !== undefined)
189
+ filters.minImpressions = minImpressions;
190
+ if (positionRange)
191
+ filters.positionRange = positionRange;
192
+ if (deviceType)
193
+ filters.deviceType = deviceType;
194
+ if (country)
195
+ filters.country = country;
196
+ const responseObject = {
197
+ property: matchedProperty.propertyUrl,
198
+ topQueries,
199
+ totalQueries: topQueries.length,
200
+ ...(Object.keys(filters).length > 0 && { filters }),
201
+ sortBy,
202
+ sortOrder,
203
+ searchType,
204
+ dateRange: {
205
+ start: startDate,
206
+ end: endDate,
207
+ },
208
+ };
209
+ logger.info('Get top queries completed successfully', {
210
+ property: matchedProperty.propertyUrl,
211
+ queriesReturned: topQueries.length,
212
+ limit,
213
+ });
214
+ return {
215
+ content: [{
216
+ type: 'text',
217
+ text: JSON.stringify(responseObject, null, 2),
218
+ }],
219
+ };
220
+ }
221
+ catch (error) {
222
+ const errorMessage = error instanceof Error ? error.message : String(error);
223
+ const errorStack = error instanceof Error ? error.stack : undefined;
224
+ logger.error('Get top queries handler failed', {
225
+ error: errorMessage,
226
+ stack: errorStack,
227
+ params,
228
+ });
229
+ let userFriendlyMessage = errorMessage;
230
+ if (errorMessage.includes('permission') || errorMessage.includes('Permission')) {
231
+ userFriendlyMessage = `Permission denied for property ${params.property}. Use list_properties to see accessible properties.`;
232
+ }
233
+ else if (errorMessage.includes('not found') || errorMessage.includes('Not Found')) {
234
+ userFriendlyMessage = `Property ${params.property} not found. Use list_properties to get valid property identifiers.`;
235
+ }
236
+ else if (errorMessage.includes('date') || errorMessage.includes('Date')) {
237
+ userFriendlyMessage = `Invalid date range. ${errorMessage}`;
238
+ }
239
+ else if (errorMessage.includes('rate limit') || errorMessage.includes('Rate limit')) {
240
+ userFriendlyMessage = 'Rate limit exceeded. Please wait a moment and try again.';
241
+ }
242
+ return {
243
+ content: [{
244
+ type: 'text',
245
+ text: JSON.stringify({
246
+ error: 'Get top queries execution failed',
247
+ details: userFriendlyMessage,
248
+ }, null, 2),
249
+ }],
250
+ isError: true,
251
+ };
252
+ }
253
+ }
254
+ //# sourceMappingURL=get-top-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-top-queries.js","sourceRoot":"","sources":["../../src/tools/get-top-queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ import { GSCClient } from '../gsc/client.js';
3
+ export interface ToolResponse {
4
+ content: Array<{
5
+ type: 'text';
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }
10
+ export declare const healthCheckTool: Tool;
11
+ export declare function handleHealthCheck(_params: any, client: GSCClient): Promise<ToolResponse>;
12
+ //# sourceMappingURL=health-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAS7C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAKD,eAAO,MAAM,eAAe,EAAE,IAS7B,CAAC;AASF,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,YAAY,CAAC,CA6GvB"}
@@ -0,0 +1,107 @@
1
+ import { getToolStats } from './index.js';
2
+ import { propertyCache } from '../utils/cache.js';
3
+ import { logger } from '../utils/logger.js';
4
+ import { config, getEnvironment } from '../config/index.js';
5
+ export const healthCheckTool = {
6
+ name: 'health_check',
7
+ description: 'Check MCP server health and status. Returns authentication status, rate limiter statistics, cache statistics, tool availability, and system information. Useful for monitoring and debugging.',
8
+ inputSchema: {
9
+ type: 'object',
10
+ properties: {},
11
+ required: [],
12
+ },
13
+ };
14
+ export async function handleHealthCheck(_params, client) {
15
+ try {
16
+ logger.debug('Health check requested');
17
+ const rateLimitStatus = client.getRateLimitStatus();
18
+ const cacheStats = propertyCache.getStats();
19
+ const toolStats = getToolStats();
20
+ let authenticationStatus = 'authenticated';
21
+ let authenticationError;
22
+ try {
23
+ const isValid = await client.validateConnection();
24
+ if (!isValid) {
25
+ authenticationStatus = 'error';
26
+ authenticationError = 'Connection validation failed';
27
+ }
28
+ }
29
+ catch (error) {
30
+ authenticationStatus = 'error';
31
+ authenticationError =
32
+ error instanceof Error ? error.message : String(error);
33
+ }
34
+ const health = {
35
+ status: authenticationStatus === 'authenticated' ? 'healthy' : 'degraded',
36
+ timestamp: new Date().toISOString(),
37
+ server: {
38
+ name: 'google-search-console-mcp',
39
+ version: '1.0.0',
40
+ uptime: process.uptime(),
41
+ nodeVersion: process.version,
42
+ platform: process.platform,
43
+ environment: getEnvironment(),
44
+ },
45
+ authentication: {
46
+ status: authenticationStatus,
47
+ error: authenticationError,
48
+ tokenPath: config.tokenPath,
49
+ },
50
+ rateLimiter: {
51
+ ...rateLimitStatus,
52
+ description: 'Token bucket rate limiter (18 queries/second, 1,080/minute)',
53
+ },
54
+ cache: {
55
+ ...cacheStats,
56
+ description: 'Property list cache (24-hour TTL)',
57
+ },
58
+ tools: {
59
+ total: toolStats.total,
60
+ available: toolStats.names,
61
+ details: toolStats.tools.map((t) => ({
62
+ name: t.name,
63
+ requiredParams: t.requiredParams,
64
+ optionalParams: t.optionalParams,
65
+ })),
66
+ },
67
+ memory: {
68
+ heapUsed: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
69
+ heapTotal: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
70
+ rss: Math.round(process.memoryUsage().rss / 1024 / 1024),
71
+ unit: 'MB',
72
+ },
73
+ };
74
+ logger.info('Health check completed', {
75
+ status: health.status,
76
+ authStatus: health.authentication.status,
77
+ });
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: JSON.stringify(health, null, 2),
83
+ },
84
+ ],
85
+ };
86
+ }
87
+ catch (error) {
88
+ const errorMessage = error instanceof Error ? error.message : String(error);
89
+ logger.error('Health check failed', {
90
+ error: errorMessage,
91
+ });
92
+ return {
93
+ content: [
94
+ {
95
+ type: 'text',
96
+ text: JSON.stringify({
97
+ status: 'error',
98
+ timestamp: new Date().toISOString(),
99
+ error: errorMessage,
100
+ }, null, 2),
101
+ },
102
+ ],
103
+ isError: true,
104
+ };
105
+ }
106
+ }
107
+ //# sourceMappingURL=health-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAa5D,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,+LAA+L;IACjM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;KACb;CACF,CAAC;AASF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAY,EACZ,MAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAGvC,MAAM,eAAe,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAGpD,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC;QAG5C,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QAGjC,IAAI,oBAAoB,GAA8B,eAAe,CAAC;QACtE,IAAI,mBAAuC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAClD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,oBAAoB,GAAG,OAAO,CAAC;gBAC/B,mBAAmB,GAAG,8BAA8B,CAAC;YACvD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oBAAoB,GAAG,OAAO,CAAC;YAC/B,mBAAmB;gBACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;QAGD,MAAM,MAAM,GAAG;YACb,MAAM,EAAE,oBAAoB,KAAK,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;YACzE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE;gBACN,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;gBACxB,WAAW,EAAE,OAAO,CAAC,OAAO;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,WAAW,EAAE,cAAc,EAAE;aAC9B;YACD,cAAc,EAAE;gBACd,MAAM,EAAE,oBAAoB;gBAC5B,KAAK,EAAE,mBAAmB;gBAC1B,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B;YACD,WAAW,EAAE;gBACX,GAAG,eAAe;gBAClB,WAAW,EAAE,6DAA6D;aAC3E;YACD,KAAK,EAAE;gBACL,GAAG,UAAU;gBACb,WAAW,EAAE,mCAAmC;aACjD;YACD,KAAK,EAAE;gBACL,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,SAAS,EAAE,SAAS,CAAC,KAAK;gBAC1B,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnC,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,cAAc,EAAE,CAAC,CAAC,cAAc;oBAChC,cAAc,EAAE,CAAC,CAAC,cAAc;iBACjC,CAAC,CAAC;aACJ;YACD,MAAM,EAAE;gBACN,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;gBAClE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;gBACpE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;gBACxD,IAAI,EAAE,IAAI;aACX;SACF,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;YACpC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM;SACzC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE5E,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;YAClC,KAAK,EAAE,YAAY;SACpB,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,MAAM,EAAE,OAAO;wBACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACnC,KAAK,EAAE,YAAY;qBACpB,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}