@heyseo/mcp-server 0.1.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.
- package/README.md +284 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +258 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +22 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +267 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +38 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +247 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/tools/comparison.d.ts +159 -0
- package/dist/tools/comparison.d.ts.map +1 -0
- package/dist/tools/comparison.js +482 -0
- package/dist/tools/comparison.js.map +1 -0
- package/dist/tools/ga4.d.ts +182 -0
- package/dist/tools/ga4.d.ts.map +1 -0
- package/dist/tools/ga4.js +429 -0
- package/dist/tools/ga4.js.map +1 -0
- package/dist/tools/gsc.d.ts +194 -0
- package/dist/tools/gsc.d.ts.map +1 -0
- package/dist/tools/gsc.js +348 -0
- package/dist/tools/gsc.js.map +1 -0
- package/dist/tools/index.d.ts +392 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +59 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/pagespeed.d.ts +88 -0
- package/dist/tools/pagespeed.d.ts.map +1 -0
- package/dist/tools/pagespeed.js +285 -0
- package/dist/tools/pagespeed.js.map +1 -0
- package/dist/tools/tasks.d.ts +71 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +116 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/types.d.ts +151 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api-client.d.ts +69 -0
- package/dist/utils/api-client.d.ts.map +1 -0
- package/dist/utils/api-client.js +202 -0
- package/dist/utils/api-client.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comparison and Opportunities Tools
|
|
3
|
+
* Tools for comparing time periods and finding SEO opportunities
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { HeySeoApiClient } from '../utils/api-client.js';
|
|
7
|
+
export declare const comparePeriodSchema: z.ZodObject<{
|
|
8
|
+
siteId: z.ZodString;
|
|
9
|
+
period1Start: z.ZodString;
|
|
10
|
+
period1End: z.ZodString;
|
|
11
|
+
period2Start: z.ZodString;
|
|
12
|
+
period2End: z.ZodString;
|
|
13
|
+
includeGA4: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
siteId: string;
|
|
16
|
+
period1Start: string;
|
|
17
|
+
period1End: string;
|
|
18
|
+
period2Start: string;
|
|
19
|
+
period2End: string;
|
|
20
|
+
includeGA4: boolean;
|
|
21
|
+
}, {
|
|
22
|
+
siteId: string;
|
|
23
|
+
period1Start: string;
|
|
24
|
+
period1End: string;
|
|
25
|
+
period2Start: string;
|
|
26
|
+
period2End: string;
|
|
27
|
+
includeGA4?: boolean | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
export type ComparePeriodInput = z.infer<typeof comparePeriodSchema>;
|
|
30
|
+
export declare const findOpportunitiesSchema: z.ZodObject<{
|
|
31
|
+
siteId: z.ZodString;
|
|
32
|
+
type: z.ZodDefault<z.ZodOptional<z.ZodEnum<["keyword", "page", "technical", "content", "all"]>>>;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
siteId: string;
|
|
35
|
+
type: "page" | "keyword" | "technical" | "content" | "all";
|
|
36
|
+
}, {
|
|
37
|
+
siteId: string;
|
|
38
|
+
type?: "page" | "keyword" | "technical" | "content" | "all" | undefined;
|
|
39
|
+
}>;
|
|
40
|
+
export type FindOpportunitiesInput = z.infer<typeof findOpportunitiesSchema>;
|
|
41
|
+
export declare const weekOverWeekSchema: z.ZodObject<{
|
|
42
|
+
siteId: z.ZodString;
|
|
43
|
+
weeksBack: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
siteId: string;
|
|
46
|
+
weeksBack: number;
|
|
47
|
+
}, {
|
|
48
|
+
siteId: string;
|
|
49
|
+
weeksBack?: number | undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export type WeekOverWeekInput = z.infer<typeof weekOverWeekSchema>;
|
|
52
|
+
/**
|
|
53
|
+
* Execute period comparison tool
|
|
54
|
+
*/
|
|
55
|
+
export declare function executeComparePeriod(client: HeySeoApiClient, input: ComparePeriodInput): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Execute find opportunities tool
|
|
58
|
+
*/
|
|
59
|
+
export declare function executeFindOpportunities(client: HeySeoApiClient, input: FindOpportunitiesInput): Promise<string>;
|
|
60
|
+
/**
|
|
61
|
+
* Execute week-over-week comparison
|
|
62
|
+
*/
|
|
63
|
+
export declare function executeWeekOverWeek(client: HeySeoApiClient, input: WeekOverWeekInput): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Comparison tool definitions for MCP
|
|
66
|
+
*/
|
|
67
|
+
export declare const comparisonTools: ({
|
|
68
|
+
name: string;
|
|
69
|
+
description: string;
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: string;
|
|
72
|
+
properties: {
|
|
73
|
+
siteId: {
|
|
74
|
+
type: string;
|
|
75
|
+
description: string;
|
|
76
|
+
};
|
|
77
|
+
period1Start: {
|
|
78
|
+
type: string;
|
|
79
|
+
pattern: string;
|
|
80
|
+
description: string;
|
|
81
|
+
};
|
|
82
|
+
period1End: {
|
|
83
|
+
type: string;
|
|
84
|
+
pattern: string;
|
|
85
|
+
description: string;
|
|
86
|
+
};
|
|
87
|
+
period2Start: {
|
|
88
|
+
type: string;
|
|
89
|
+
pattern: string;
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
period2End: {
|
|
93
|
+
type: string;
|
|
94
|
+
pattern: string;
|
|
95
|
+
description: string;
|
|
96
|
+
};
|
|
97
|
+
includeGA4: {
|
|
98
|
+
type: string;
|
|
99
|
+
default: boolean;
|
|
100
|
+
description: string;
|
|
101
|
+
};
|
|
102
|
+
weeksBack?: undefined;
|
|
103
|
+
type?: undefined;
|
|
104
|
+
};
|
|
105
|
+
required: string[];
|
|
106
|
+
};
|
|
107
|
+
} | {
|
|
108
|
+
name: string;
|
|
109
|
+
description: string;
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: string;
|
|
112
|
+
properties: {
|
|
113
|
+
siteId: {
|
|
114
|
+
type: string;
|
|
115
|
+
description: string;
|
|
116
|
+
};
|
|
117
|
+
weeksBack: {
|
|
118
|
+
type: string;
|
|
119
|
+
minimum: number;
|
|
120
|
+
maximum: number;
|
|
121
|
+
default: number;
|
|
122
|
+
description: string;
|
|
123
|
+
};
|
|
124
|
+
period1Start?: undefined;
|
|
125
|
+
period1End?: undefined;
|
|
126
|
+
period2Start?: undefined;
|
|
127
|
+
period2End?: undefined;
|
|
128
|
+
includeGA4?: undefined;
|
|
129
|
+
type?: undefined;
|
|
130
|
+
};
|
|
131
|
+
required: string[];
|
|
132
|
+
};
|
|
133
|
+
} | {
|
|
134
|
+
name: string;
|
|
135
|
+
description: string;
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: string;
|
|
138
|
+
properties: {
|
|
139
|
+
siteId: {
|
|
140
|
+
type: string;
|
|
141
|
+
description: string;
|
|
142
|
+
};
|
|
143
|
+
type: {
|
|
144
|
+
type: string;
|
|
145
|
+
enum: string[];
|
|
146
|
+
default: string;
|
|
147
|
+
description: string;
|
|
148
|
+
};
|
|
149
|
+
period1Start?: undefined;
|
|
150
|
+
period1End?: undefined;
|
|
151
|
+
period2Start?: undefined;
|
|
152
|
+
period2End?: undefined;
|
|
153
|
+
includeGA4?: undefined;
|
|
154
|
+
weeksBack?: undefined;
|
|
155
|
+
};
|
|
156
|
+
required: string[];
|
|
157
|
+
};
|
|
158
|
+
})[];
|
|
159
|
+
//# sourceMappingURL=comparison.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparison.d.ts","sourceRoot":"","sources":["../../src/tools/comparison.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;EAuB9B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAGrE,eAAO,MAAM,uBAAuB;;;;;;;;;EAOlC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAG7E,eAAO,MAAM,kBAAkB;;;;;;;;;EAS7B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAyCnE;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,CA6IjB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAwKjB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoG3B,CAAC"}
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comparison and Opportunities Tools
|
|
3
|
+
* Tools for comparing time periods and finding SEO opportunities
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
// Schema for period comparison tool
|
|
7
|
+
export const comparePeriodSchema = z.object({
|
|
8
|
+
siteId: z.string().describe('The ID of the site to compare'),
|
|
9
|
+
period1Start: z
|
|
10
|
+
.string()
|
|
11
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
12
|
+
.describe('First period start date (YYYY-MM-DD)'),
|
|
13
|
+
period1End: z
|
|
14
|
+
.string()
|
|
15
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
16
|
+
.describe('First period end date (YYYY-MM-DD)'),
|
|
17
|
+
period2Start: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
20
|
+
.describe('Second period start date (YYYY-MM-DD)'),
|
|
21
|
+
period2End: z
|
|
22
|
+
.string()
|
|
23
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
24
|
+
.describe('Second period end date (YYYY-MM-DD)'),
|
|
25
|
+
includeGA4: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.optional()
|
|
28
|
+
.default(true)
|
|
29
|
+
.describe('Include GA4 metrics in comparison'),
|
|
30
|
+
});
|
|
31
|
+
// Schema for opportunities tool
|
|
32
|
+
export const findOpportunitiesSchema = z.object({
|
|
33
|
+
siteId: z.string().describe('The ID of the site to analyze'),
|
|
34
|
+
type: z
|
|
35
|
+
.enum(['keyword', 'page', 'technical', 'content', 'all'])
|
|
36
|
+
.optional()
|
|
37
|
+
.default('all')
|
|
38
|
+
.describe('Type of opportunities to find'),
|
|
39
|
+
});
|
|
40
|
+
// Schema for week-over-week comparison
|
|
41
|
+
export const weekOverWeekSchema = z.object({
|
|
42
|
+
siteId: z.string().describe('The ID of the site to compare'),
|
|
43
|
+
weeksBack: z
|
|
44
|
+
.number()
|
|
45
|
+
.min(1)
|
|
46
|
+
.max(12)
|
|
47
|
+
.optional()
|
|
48
|
+
.default(1)
|
|
49
|
+
.describe('Number of weeks to compare against (default: last week)'),
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Calculate percentage change
|
|
53
|
+
*/
|
|
54
|
+
function calculateChange(current, previous) {
|
|
55
|
+
const absolute = current - previous;
|
|
56
|
+
const percentage = previous !== 0 ? ((current - previous) / previous) * 100 : 0;
|
|
57
|
+
let trend;
|
|
58
|
+
if (Math.abs(percentage) < 1) {
|
|
59
|
+
trend = 'stable';
|
|
60
|
+
}
|
|
61
|
+
else if (percentage > 0) {
|
|
62
|
+
trend = 'up';
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
trend = 'down';
|
|
66
|
+
}
|
|
67
|
+
return { absolute, percentage, trend };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get trend emoji
|
|
71
|
+
*/
|
|
72
|
+
function getTrendEmoji(trend, metric) {
|
|
73
|
+
// For position, down is good (lower number = better rank)
|
|
74
|
+
if (metric === 'position') {
|
|
75
|
+
if (trend === 'down')
|
|
76
|
+
return '✅ ↓';
|
|
77
|
+
if (trend === 'up')
|
|
78
|
+
return '⚠️ ↑';
|
|
79
|
+
return '➡️';
|
|
80
|
+
}
|
|
81
|
+
// For other metrics, up is good
|
|
82
|
+
if (trend === 'up')
|
|
83
|
+
return '✅ ↑';
|
|
84
|
+
if (trend === 'down')
|
|
85
|
+
return '⚠️ ↓';
|
|
86
|
+
return '➡️';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Execute period comparison tool
|
|
90
|
+
*/
|
|
91
|
+
export async function executeComparePeriod(client, input) {
|
|
92
|
+
try {
|
|
93
|
+
// Fetch GSC data for both periods
|
|
94
|
+
const [gsc1, gsc2] = await Promise.all([
|
|
95
|
+
client.queryGSC({
|
|
96
|
+
siteId: input.siteId,
|
|
97
|
+
startDate: input.period1Start,
|
|
98
|
+
endDate: input.period1End,
|
|
99
|
+
dimensions: [],
|
|
100
|
+
rowLimit: 1,
|
|
101
|
+
}),
|
|
102
|
+
client.queryGSC({
|
|
103
|
+
siteId: input.siteId,
|
|
104
|
+
startDate: input.period2Start,
|
|
105
|
+
endDate: input.period2End,
|
|
106
|
+
dimensions: [],
|
|
107
|
+
rowLimit: 1,
|
|
108
|
+
}),
|
|
109
|
+
]);
|
|
110
|
+
// Extract metrics
|
|
111
|
+
const metrics1 = gsc1.rows[0] || { clicks: 0, impressions: 0, ctr: 0, position: 0 };
|
|
112
|
+
const metrics2 = gsc2.rows[0] || { clicks: 0, impressions: 0, ctr: 0, position: 0 };
|
|
113
|
+
// Calculate changes
|
|
114
|
+
const changes = {
|
|
115
|
+
clicks: calculateChange(metrics2.clicks, metrics1.clicks),
|
|
116
|
+
impressions: calculateChange(metrics2.impressions, metrics1.impressions),
|
|
117
|
+
ctr: calculateChange(metrics2.ctr * 100, metrics1.ctr * 100),
|
|
118
|
+
position: calculateChange(metrics2.position, metrics1.position),
|
|
119
|
+
};
|
|
120
|
+
// Format comparison
|
|
121
|
+
const comparison = {
|
|
122
|
+
clicks: {
|
|
123
|
+
period1: metrics1.clicks,
|
|
124
|
+
period2: metrics2.clicks,
|
|
125
|
+
change: `${changes.clicks.percentage >= 0 ? '+' : ''}${changes.clicks.percentage.toFixed(1)}%`,
|
|
126
|
+
trend: getTrendEmoji(changes.clicks.trend, 'clicks'),
|
|
127
|
+
},
|
|
128
|
+
impressions: {
|
|
129
|
+
period1: metrics1.impressions,
|
|
130
|
+
period2: metrics2.impressions,
|
|
131
|
+
change: `${changes.impressions.percentage >= 0 ? '+' : ''}${changes.impressions.percentage.toFixed(1)}%`,
|
|
132
|
+
trend: getTrendEmoji(changes.impressions.trend, 'impressions'),
|
|
133
|
+
},
|
|
134
|
+
ctr: {
|
|
135
|
+
period1: `${(metrics1.ctr * 100).toFixed(2)}%`,
|
|
136
|
+
period2: `${(metrics2.ctr * 100).toFixed(2)}%`,
|
|
137
|
+
change: `${changes.ctr.absolute >= 0 ? '+' : ''}${changes.ctr.absolute.toFixed(2)}pp`,
|
|
138
|
+
trend: getTrendEmoji(changes.ctr.trend, 'ctr'),
|
|
139
|
+
},
|
|
140
|
+
position: {
|
|
141
|
+
period1: metrics1.position.toFixed(1),
|
|
142
|
+
period2: metrics2.position.toFixed(1),
|
|
143
|
+
change: `${changes.position.absolute >= 0 ? '+' : ''}${changes.position.absolute.toFixed(1)}`,
|
|
144
|
+
trend: getTrendEmoji(changes.position.trend, 'position'),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
// Determine overall health
|
|
148
|
+
const positiveChanges = [
|
|
149
|
+
changes.clicks.trend === 'up',
|
|
150
|
+
changes.impressions.trend === 'up',
|
|
151
|
+
changes.ctr.trend === 'up',
|
|
152
|
+
changes.position.trend === 'down', // Lower position is better
|
|
153
|
+
].filter(Boolean).length;
|
|
154
|
+
let overallHealth;
|
|
155
|
+
if (positiveChanges >= 3) {
|
|
156
|
+
overallHealth = '🟢 Strong improvement';
|
|
157
|
+
}
|
|
158
|
+
else if (positiveChanges >= 2) {
|
|
159
|
+
overallHealth = '🟡 Mixed results';
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
overallHealth = '🔴 Needs attention';
|
|
163
|
+
}
|
|
164
|
+
// Find top gainers and losers (by query)
|
|
165
|
+
const [queries1, queries2] = await Promise.all([
|
|
166
|
+
client.queryGSC({
|
|
167
|
+
siteId: input.siteId,
|
|
168
|
+
startDate: input.period1Start,
|
|
169
|
+
endDate: input.period1End,
|
|
170
|
+
dimensions: ['query'],
|
|
171
|
+
rowLimit: 100,
|
|
172
|
+
}),
|
|
173
|
+
client.queryGSC({
|
|
174
|
+
siteId: input.siteId,
|
|
175
|
+
startDate: input.period2Start,
|
|
176
|
+
endDate: input.period2End,
|
|
177
|
+
dimensions: ['query'],
|
|
178
|
+
rowLimit: 100,
|
|
179
|
+
}),
|
|
180
|
+
]);
|
|
181
|
+
// Create maps for comparison
|
|
182
|
+
const queries1Map = new Map(queries1.rows.map((r) => [r.keys[0], r]));
|
|
183
|
+
const queries2Map = new Map(queries2.rows.map((r) => [r.keys[0], r]));
|
|
184
|
+
// Find changes
|
|
185
|
+
const queryChanges = [];
|
|
186
|
+
queries2Map.forEach((row, query) => {
|
|
187
|
+
const prev = queries1Map.get(query);
|
|
188
|
+
const prevClicks = prev?.clicks || 0;
|
|
189
|
+
const clickChange = row.clicks - prevClicks;
|
|
190
|
+
const clickChangePct = prevClicks > 0 ? (clickChange / prevClicks) * 100 : 100;
|
|
191
|
+
queryChanges.push({ query, clickChange, clickChangePct });
|
|
192
|
+
});
|
|
193
|
+
// Sort to find top gainers and losers
|
|
194
|
+
const sortedByChange = [...queryChanges].sort((a, b) => b.clickChange - a.clickChange);
|
|
195
|
+
const topGainers = sortedByChange.slice(0, 5).filter((q) => q.clickChange > 0);
|
|
196
|
+
const topLosers = sortedByChange.slice(-5).reverse().filter((q) => q.clickChange < 0);
|
|
197
|
+
return JSON.stringify({
|
|
198
|
+
success: true,
|
|
199
|
+
periods: {
|
|
200
|
+
period1: { start: input.period1Start, end: input.period1End },
|
|
201
|
+
period2: { start: input.period2Start, end: input.period2End },
|
|
202
|
+
},
|
|
203
|
+
overallHealth,
|
|
204
|
+
comparison,
|
|
205
|
+
topGainers: topGainers.map((q) => ({
|
|
206
|
+
query: q.query,
|
|
207
|
+
change: `+${q.clickChange} clicks (+${q.clickChangePct.toFixed(0)}%)`,
|
|
208
|
+
})),
|
|
209
|
+
topLosers: topLosers.map((q) => ({
|
|
210
|
+
query: q.query,
|
|
211
|
+
change: `${q.clickChange} clicks (${q.clickChangePct.toFixed(0)}%)`,
|
|
212
|
+
})),
|
|
213
|
+
}, null, 2);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
return JSON.stringify({
|
|
217
|
+
success: false,
|
|
218
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Execute find opportunities tool
|
|
224
|
+
*/
|
|
225
|
+
export async function executeFindOpportunities(client, input) {
|
|
226
|
+
try {
|
|
227
|
+
// If API supports opportunities endpoint
|
|
228
|
+
if (input.type !== 'all') {
|
|
229
|
+
const opportunities = await client.getOpportunities(input.siteId, input.type);
|
|
230
|
+
return JSON.stringify({ success: true, opportunities }, null, 2);
|
|
231
|
+
}
|
|
232
|
+
// Otherwise, analyze data to find opportunities
|
|
233
|
+
const endDate = new Date().toISOString().split('T')[0];
|
|
234
|
+
const startDate = new Date(Date.now() - 28 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
235
|
+
// Get keyword and page data
|
|
236
|
+
const [keywords, pages] = await Promise.all([
|
|
237
|
+
client.queryGSC({
|
|
238
|
+
siteId: input.siteId,
|
|
239
|
+
startDate,
|
|
240
|
+
endDate,
|
|
241
|
+
dimensions: ['query'],
|
|
242
|
+
rowLimit: 500,
|
|
243
|
+
}),
|
|
244
|
+
client.queryGSC({
|
|
245
|
+
siteId: input.siteId,
|
|
246
|
+
startDate,
|
|
247
|
+
endDate,
|
|
248
|
+
dimensions: ['page'],
|
|
249
|
+
rowLimit: 200,
|
|
250
|
+
}),
|
|
251
|
+
]);
|
|
252
|
+
const opportunities = [];
|
|
253
|
+
// Keyword opportunities: High impressions, low CTR, positions 5-20
|
|
254
|
+
const lowHangingKeywords = keywords.rows.filter((row) => row.impressions >= 100 &&
|
|
255
|
+
row.ctr < 0.03 && // Less than 3% CTR
|
|
256
|
+
row.position >= 5 &&
|
|
257
|
+
row.position <= 20);
|
|
258
|
+
if (lowHangingKeywords.length > 0) {
|
|
259
|
+
const topLowHanging = lowHangingKeywords
|
|
260
|
+
.sort((a, b) => b.impressions - a.impressions)
|
|
261
|
+
.slice(0, 5);
|
|
262
|
+
opportunities.push({
|
|
263
|
+
type: 'keyword',
|
|
264
|
+
priority: 'high',
|
|
265
|
+
title: 'Low-hanging fruit keywords',
|
|
266
|
+
description: `Found ${lowHangingKeywords.length} keywords ranking on page 1-2 with low CTR. Improving titles/descriptions could boost clicks.`,
|
|
267
|
+
impact: `Potential ${Math.round(lowHangingKeywords.reduce((sum, k) => sum + k.impressions * 0.03, 0))} additional monthly clicks`,
|
|
268
|
+
effort: 'low',
|
|
269
|
+
data: {
|
|
270
|
+
keywords: topLowHanging.map((k) => ({
|
|
271
|
+
keyword: k.keys[0],
|
|
272
|
+
position: k.position.toFixed(1),
|
|
273
|
+
impressions: k.impressions,
|
|
274
|
+
currentCtr: `${(k.ctr * 100).toFixed(2)}%`,
|
|
275
|
+
})),
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// Keyword opportunities: Position 11-20 (page 2)
|
|
280
|
+
const almostPage1 = keywords.rows.filter((row) => row.position >= 11 && row.position <= 20 && row.impressions >= 50);
|
|
281
|
+
if (almostPage1.length > 0) {
|
|
282
|
+
const topAlmost = almostPage1.sort((a, b) => b.impressions - a.impressions).slice(0, 5);
|
|
283
|
+
opportunities.push({
|
|
284
|
+
type: 'keyword',
|
|
285
|
+
priority: 'medium',
|
|
286
|
+
title: 'Keywords almost on page 1',
|
|
287
|
+
description: `Found ${almostPage1.length} keywords on page 2 that could reach page 1 with optimization.`,
|
|
288
|
+
impact: 'Page 1 rankings typically see 10x more clicks',
|
|
289
|
+
effort: 'medium',
|
|
290
|
+
data: {
|
|
291
|
+
keywords: topAlmost.map((k) => ({
|
|
292
|
+
keyword: k.keys[0],
|
|
293
|
+
position: k.position.toFixed(1),
|
|
294
|
+
impressions: k.impressions,
|
|
295
|
+
})),
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
// Page opportunities: High impressions but low clicks
|
|
300
|
+
const underperformingPages = pages.rows.filter((row) => row.impressions >= 500 && row.ctr < 0.02);
|
|
301
|
+
if (underperformingPages.length > 0) {
|
|
302
|
+
const topUnderperforming = underperformingPages
|
|
303
|
+
.sort((a, b) => b.impressions - a.impressions)
|
|
304
|
+
.slice(0, 5);
|
|
305
|
+
opportunities.push({
|
|
306
|
+
type: 'page',
|
|
307
|
+
priority: 'high',
|
|
308
|
+
title: 'Underperforming pages with high visibility',
|
|
309
|
+
description: `Found ${underperformingPages.length} pages with good impressions but poor CTR. Review titles and meta descriptions.`,
|
|
310
|
+
impact: 'Doubling CTR would significantly increase organic traffic',
|
|
311
|
+
effort: 'low',
|
|
312
|
+
data: {
|
|
313
|
+
pages: topUnderperforming.map((p) => ({
|
|
314
|
+
page: p.keys[0],
|
|
315
|
+
impressions: p.impressions,
|
|
316
|
+
clicks: p.clicks,
|
|
317
|
+
ctr: `${(p.ctr * 100).toFixed(2)}%`,
|
|
318
|
+
})),
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
// Content opportunities: Pages with declining impressions potential
|
|
323
|
+
const thinContent = pages.rows.filter((row) => row.impressions >= 100 && row.impressions < 1000 && row.position > 10);
|
|
324
|
+
if (thinContent.length > 0) {
|
|
325
|
+
opportunities.push({
|
|
326
|
+
type: 'content',
|
|
327
|
+
priority: 'medium',
|
|
328
|
+
title: 'Content expansion opportunities',
|
|
329
|
+
description: `Found ${thinContent.length} pages with moderate visibility that could benefit from content expansion.`,
|
|
330
|
+
impact: 'Longer, comprehensive content often ranks better',
|
|
331
|
+
effort: 'high',
|
|
332
|
+
data: {
|
|
333
|
+
pagesCount: thinContent.length,
|
|
334
|
+
samplePages: thinContent.slice(0, 3).map((p) => p.keys[0]),
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
// Sort by priority
|
|
339
|
+
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
340
|
+
opportunities.sort((a, b) => (priorityOrder[a.priority] || 2) -
|
|
341
|
+
(priorityOrder[b.priority] || 2));
|
|
342
|
+
return JSON.stringify({
|
|
343
|
+
success: true,
|
|
344
|
+
totalOpportunities: opportunities.length,
|
|
345
|
+
opportunities,
|
|
346
|
+
}, null, 2);
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
return JSON.stringify({
|
|
350
|
+
success: false,
|
|
351
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Execute week-over-week comparison
|
|
357
|
+
*/
|
|
358
|
+
export async function executeWeekOverWeek(client, input) {
|
|
359
|
+
// Calculate date ranges
|
|
360
|
+
const now = new Date();
|
|
361
|
+
const thisWeekEnd = new Date(now);
|
|
362
|
+
thisWeekEnd.setDate(now.getDate() - now.getDay()); // Last Sunday
|
|
363
|
+
const thisWeekStart = new Date(thisWeekEnd);
|
|
364
|
+
thisWeekStart.setDate(thisWeekEnd.getDate() - 6); // Monday before
|
|
365
|
+
const prevWeekEnd = new Date(thisWeekStart);
|
|
366
|
+
prevWeekEnd.setDate(thisWeekStart.getDate() - 1 - (input.weeksBack - 1) * 7);
|
|
367
|
+
const prevWeekStart = new Date(prevWeekEnd);
|
|
368
|
+
prevWeekStart.setDate(prevWeekEnd.getDate() - 6);
|
|
369
|
+
return executeComparePeriod(client, {
|
|
370
|
+
siteId: input.siteId,
|
|
371
|
+
period1Start: prevWeekStart.toISOString().split('T')[0],
|
|
372
|
+
period1End: prevWeekEnd.toISOString().split('T')[0],
|
|
373
|
+
period2Start: thisWeekStart.toISOString().split('T')[0],
|
|
374
|
+
period2End: thisWeekEnd.toISOString().split('T')[0],
|
|
375
|
+
includeGA4: true,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Comparison tool definitions for MCP
|
|
380
|
+
*/
|
|
381
|
+
export const comparisonTools = [
|
|
382
|
+
{
|
|
383
|
+
name: 'heyseo_compare_periods',
|
|
384
|
+
description: `Compare SEO metrics between two time periods.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
- Side-by-side comparison of clicks, impressions, CTR, and position
|
|
388
|
+
- Percentage changes with trend indicators
|
|
389
|
+
- Overall health assessment
|
|
390
|
+
- Top gaining and losing keywords
|
|
391
|
+
|
|
392
|
+
Useful for tracking progress, identifying trends, and measuring campaign impact.`,
|
|
393
|
+
inputSchema: {
|
|
394
|
+
type: 'object',
|
|
395
|
+
properties: {
|
|
396
|
+
siteId: {
|
|
397
|
+
type: 'string',
|
|
398
|
+
description: 'The ID of the site to compare',
|
|
399
|
+
},
|
|
400
|
+
period1Start: {
|
|
401
|
+
type: 'string',
|
|
402
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
|
|
403
|
+
description: 'First period start date (baseline)',
|
|
404
|
+
},
|
|
405
|
+
period1End: {
|
|
406
|
+
type: 'string',
|
|
407
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
|
|
408
|
+
description: 'First period end date',
|
|
409
|
+
},
|
|
410
|
+
period2Start: {
|
|
411
|
+
type: 'string',
|
|
412
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
|
|
413
|
+
description: 'Second period start date (comparison)',
|
|
414
|
+
},
|
|
415
|
+
period2End: {
|
|
416
|
+
type: 'string',
|
|
417
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
|
|
418
|
+
description: 'Second period end date',
|
|
419
|
+
},
|
|
420
|
+
includeGA4: {
|
|
421
|
+
type: 'boolean',
|
|
422
|
+
default: true,
|
|
423
|
+
description: 'Include GA4 metrics in comparison',
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
required: ['siteId', 'period1Start', 'period1End', 'period2Start', 'period2End'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
name: 'heyseo_week_over_week',
|
|
431
|
+
description: `Quick week-over-week performance comparison.
|
|
432
|
+
|
|
433
|
+
Compares the most recent complete week against a previous week.
|
|
434
|
+
Returns the same detailed comparison as heyseo_compare_periods.`,
|
|
435
|
+
inputSchema: {
|
|
436
|
+
type: 'object',
|
|
437
|
+
properties: {
|
|
438
|
+
siteId: {
|
|
439
|
+
type: 'string',
|
|
440
|
+
description: 'The ID of the site to compare',
|
|
441
|
+
},
|
|
442
|
+
weeksBack: {
|
|
443
|
+
type: 'number',
|
|
444
|
+
minimum: 1,
|
|
445
|
+
maximum: 12,
|
|
446
|
+
default: 1,
|
|
447
|
+
description: 'Number of weeks back to compare (1 = last week)',
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
required: ['siteId'],
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: 'heyseo_find_opportunities',
|
|
455
|
+
description: `Find SEO optimization opportunities for a site.
|
|
456
|
+
|
|
457
|
+
Analyzes your data to identify actionable opportunities:
|
|
458
|
+
- Keyword opportunities: Low-hanging fruit, almost page 1
|
|
459
|
+
- Page opportunities: High impressions with low CTR
|
|
460
|
+
- Content opportunities: Pages that could benefit from expansion
|
|
461
|
+
- Technical opportunities: Performance issues
|
|
462
|
+
|
|
463
|
+
Each opportunity includes priority, estimated impact, and required effort.`,
|
|
464
|
+
inputSchema: {
|
|
465
|
+
type: 'object',
|
|
466
|
+
properties: {
|
|
467
|
+
siteId: {
|
|
468
|
+
type: 'string',
|
|
469
|
+
description: 'The ID of the site to analyze',
|
|
470
|
+
},
|
|
471
|
+
type: {
|
|
472
|
+
type: 'string',
|
|
473
|
+
enum: ['keyword', 'page', 'technical', 'content', 'all'],
|
|
474
|
+
default: 'all',
|
|
475
|
+
description: 'Type of opportunities to find',
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
required: ['siteId'],
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
];
|
|
482
|
+
//# sourceMappingURL=comparison.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparison.js","sourceRoot":"","sources":["../../src/tools/comparison.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,oCAAoC;AACpC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC5D,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,CAAC;SAC5B,QAAQ,CAAC,sCAAsC,CAAC;IACnD,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,CAAC;SAC5B,QAAQ,CAAC,oCAAoC,CAAC;IACjD,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,CAAC;SAC5B,QAAQ,CAAC,uCAAuC,CAAC;IACpD,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,CAAC;SAC5B,QAAQ,CAAC,qCAAqC,CAAC;IAClD,UAAU,EAAE,CAAC;SACV,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,mCAAmC,CAAC;CACjD,CAAC,CAAC;AAIH,gCAAgC;AAChC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC5D,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;SACxD,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,+BAA+B,CAAC;CAC7C,CAAC,CAAC;AAIH,uCAAuC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC5D,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,QAAQ,EAAE;SACV,OAAO,CAAC,CAAC,CAAC;SACV,QAAQ,CAAC,yDAAyD,CAAC;CACvE,CAAC,CAAC;AAIH;;GAEG;AACH,SAAS,eAAe,CACtB,OAAe,EACf,QAAgB;IAEhB,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,MAAM,UAAU,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhF,IAAI,KAA+B,CAAC;IACpC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,GAAG,QAAQ,CAAC;IACnB,CAAC;SAAM,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,GAAG,IAAI,CAAC;IACf,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,MAAc;IAClD,0DAA0D;IAC1D,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,IAAI,KAAK,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QACnC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gCAAgC;IAChC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAuB,EACvB,KAAyB;IAEzB,IAAI,CAAC;QACH,kCAAkC;QAClC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACrC,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS,EAAE,KAAK,CAAC,YAAY;gBAC7B,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE,CAAC;aACZ,CAAC;YACF,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS,EAAE,KAAK,CAAC,YAAY;gBAC7B,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE,CAAC;aACZ,CAAC;SACH,CAAC,CAAC;QAEH,kBAAkB;QAClB,MAAM,QAAQ,GAAe,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAChG,MAAM,QAAQ,GAAe,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAEhG,oBAAoB;QACpB,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;YACzD,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC;YACxE,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,EAAE,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;YAC5D,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;SAChE,CAAC;QAEF,oBAAoB;QACpB,MAAM,UAAU,GAAG;YACjB,MAAM,EAAE;gBACN,OAAO,EAAE,QAAQ,CAAC,MAAM;gBACxB,OAAO,EAAE,QAAQ,CAAC,MAAM;gBACxB,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gBAC9F,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;aACrD;YACD,WAAW,EAAE;gBACX,OAAO,EAAE,QAAQ,CAAC,WAAW;gBAC7B,OAAO,EAAE,QAAQ,CAAC,WAAW;gBAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gBACxG,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC;aAC/D;YACD,GAAG,EAAE;gBACH,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gBAC9C,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gBAC9C,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;gBACrF,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;aAC/C;YACD,QAAQ,EAAE;gBACR,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrC,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;gBAC7F,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;aACzD;SACF,CAAC;QAEF,2BAA2B;QAC3B,MAAM,eAAe,GAAG;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI;YAC7B,OAAO,CAAC,WAAW,CAAC,KAAK,KAAK,IAAI;YAClC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI;YAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM,EAAE,2BAA2B;SAC/D,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAEzB,IAAI,aAAqB,CAAC;QAC1B,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;YACzB,aAAa,GAAG,uBAAuB,CAAC;QAC1C,CAAC;aAAM,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;YAChC,aAAa,GAAG,kBAAkB,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,oBAAoB,CAAC;QACvC,CAAC;QAED,yCAAyC;QACzC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS,EAAE,KAAK,CAAC,YAAY;gBAC7B,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,UAAU,EAAE,CAAC,OAAO,CAAC;gBACrB,QAAQ,EAAE,GAAG;aACd,CAAC;YACF,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS,EAAE,KAAK,CAAC,YAAY;gBAC7B,OAAO,EAAE,KAAK,CAAC,UAAU;gBACzB,UAAU,EAAE,CAAC,OAAO,CAAC;gBACrB,QAAQ,EAAE,GAAG;aACd,CAAC;SACH,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtE,eAAe;QACf,MAAM,YAAY,GAA0E,EAAE,CAAC;QAC/F,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC;YACrC,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC;YAC5C,MAAM,cAAc,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/E,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,sCAAsC;QACtC,MAAM,cAAc,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;QACvF,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAEtF,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACP,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE;gBAC7D,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE;aAC9D;YACD,aAAa;YACb,UAAU;YACV,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjC,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,IAAI,CAAC,CAAC,WAAW,aAAa,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;aACtE,CAAC,CAAC;YACH,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,YAAY,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;aACpE,CAAC,CAAC;SACJ,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAuB,EACvB,KAA6B;IAE7B,IAAI,CAAC;QACH,yCAAyC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9E,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,gDAAgD;QAChD,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9F,4BAA4B;QAC5B,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1C,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS;gBACT,OAAO;gBACP,UAAU,EAAE,CAAC,OAAO,CAAC;gBACrB,QAAQ,EAAE,GAAG;aACd,CAAC;YACF,MAAM,CAAC,QAAQ,CAAC;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS;gBACT,OAAO;gBACP,UAAU,EAAE,CAAC,MAAM,CAAC;gBACpB,QAAQ,EAAE,GAAG;aACd,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,aAAa,GAQd,EAAE,CAAC;QAER,mEAAmE;QACnE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAC7C,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,WAAW,IAAI,GAAG;YACtB,GAAG,CAAC,GAAG,GAAG,IAAI,IAAI,mBAAmB;YACrC,GAAG,CAAC,QAAQ,IAAI,CAAC;YACjB,GAAG,CAAC,QAAQ,IAAI,EAAE,CACrB,CAAC;QAEF,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG,kBAAkB;iBACrC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;iBAC7C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEf,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,4BAA4B;gBACnC,WAAW,EAAE,SAAS,kBAAkB,CAAC,MAAM,+FAA+F;gBAC9I,MAAM,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,4BAA4B;gBACjI,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE;oBACJ,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAClC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;wBAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC/B,WAAW,EAAE,CAAC,CAAC,WAAW;wBAC1B,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;qBAC3C,CAAC,CAAC;iBACJ;aACF,CAAC,CAAC;QACL,CAAC;QAED,iDAAiD;QACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CACtC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,CAC3E,CAAC;QAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAExF,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,2BAA2B;gBAClC,WAAW,EAAE,SAAS,WAAW,CAAC,MAAM,gEAAgE;gBACxG,MAAM,EAAE,+CAA+C;gBACvD,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE;oBACJ,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC9B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;wBAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC/B,WAAW,EAAE,CAAC,CAAC,WAAW;qBAC3B,CAAC,CAAC;iBACJ;aACF,CAAC,CAAC;QACL,CAAC;QAED,sDAAsD;QACtD,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAC5C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,IAAI,CAClD,CAAC;QAEF,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,kBAAkB,GAAG,oBAAoB;iBAC5C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;iBAC7C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEf,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,4CAA4C;gBACnD,WAAW,EAAE,SAAS,oBAAoB,CAAC,MAAM,iFAAiF;gBAClI,MAAM,EAAE,2DAA2D;gBACnE,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE;oBACJ,KAAK,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACpC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;wBACf,WAAW,EAAE,CAAC,CAAC,WAAW;wBAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;wBAChB,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;qBACpC,CAAC,CAAC;iBACJ;aACF,CAAC,CAAC;QACL,CAAC;QAED,oEAAoE;QACpE,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,QAAQ,GAAG,EAAE,CAC/E,CAAC;QAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,iCAAiC;gBACxC,WAAW,EAAE,SAAS,WAAW,CAAC,MAAM,4EAA4E;gBACpH,MAAM,EAAE,kDAAkD;gBAC1D,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE;oBACJ,UAAU,EAAE,WAAW,CAAC,MAAM;oBAC9B,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;iBAC3D;aACF,CAAC,CAAC;QACL,CAAC;QAED,mBAAmB;QACnB,MAAM,aAAa,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QACrD,aAAa,CAAC,IAAI,CAChB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,aAAa,CAAC,CAAC,CAAC,QAAsC,CAAC,IAAI,CAAC,CAAC;YAC9D,CAAC,aAAa,CAAC,CAAC,CAAC,QAAsC,CAAC,IAAI,CAAC,CAAC,CACjE,CAAC;QAEF,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,OAAO,EAAE,IAAI;YACb,kBAAkB,EAAE,aAAa,CAAC,MAAM;YACxC,aAAa;SACd,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAuB,EACvB,KAAwB;IAExB,wBAAwB;IACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,cAAc;IAEjE,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5C,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB;IAElE,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7E,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5C,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjD,OAAO,oBAAoB,CAAC,MAAM,EAAE;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,YAAY,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvD,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnD,YAAY,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvD,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnD,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE;;;;;;;;iFAQgE;QAC7E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+BAA+B;iBAC7C;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,wBAAwB;oBACjC,WAAW,EAAE,oCAAoC;iBAClD;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,wBAAwB;oBACjC,WAAW,EAAE,uBAAuB;iBACrC;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,wBAAwB;oBACjC,WAAW,EAAE,uCAAuC;iBACrD;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,wBAAwB;oBACjC,WAAW,EAAE,wBAAwB;iBACtC;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,IAAI;oBACb,WAAW,EAAE,mCAAmC;iBACjD;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;SACjF;KACF;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE;;;gEAG+C;QAC5D,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+BAA+B;iBAC7C;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,CAAC;oBACV,WAAW,EAAE,iDAAiD;iBAC/D;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE;;;;;;;;2EAQ0D;QACvE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,+BAA+B;iBAC7C;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC;oBACxD,OAAO,EAAE,KAAK;oBACd,WAAW,EAAE,+BAA+B;iBAC7C;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;CACF,CAAC"}
|