@mgsoftwarebv/mcp-server-bridge 2.7.0 ā 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +74 -19
- package/dist/index.js.map +1 -1
- package/package.json +47 -47
package/dist/index.js
CHANGED
|
@@ -14,6 +14,10 @@ if (!apiKey) {
|
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
16
|
var supabase = createClient(supabaseUrl, supabaseKey);
|
|
17
|
+
async function getAccessibleTeamIds(teamId) {
|
|
18
|
+
const { data: accessibleTeams } = await supabase.from("teams").select("id").or(`id.eq.${teamId},parent_team_id.eq.${teamId}`);
|
|
19
|
+
return accessibleTeams?.map((t) => t.id) || [teamId];
|
|
20
|
+
}
|
|
17
21
|
async function validateApiKey(key) {
|
|
18
22
|
if (!key.startsWith("mid_") || key.length !== 68) {
|
|
19
23
|
console.error("\u{1F511} Invalid API key format");
|
|
@@ -404,6 +408,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
404
408
|
switch (name) {
|
|
405
409
|
case "get-tickets": {
|
|
406
410
|
const { status, priority, projectId, customerId, q, pageSize = 20 } = args2;
|
|
411
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
407
412
|
let query = supabase.from("tickets").select(`
|
|
408
413
|
id,
|
|
409
414
|
ticket_number,
|
|
@@ -417,7 +422,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
417
422
|
customer_id,
|
|
418
423
|
projects:project_id(id, name),
|
|
419
424
|
customers:customer_id(id, name)
|
|
420
|
-
`).
|
|
425
|
+
`).in("team_id", teamIds).limit(Math.min(pageSize, 100));
|
|
421
426
|
if (status) query = query.eq("status", status);
|
|
422
427
|
if (priority) query = query.eq("priority", priority);
|
|
423
428
|
if (projectId) query = query.eq("project_id", projectId);
|
|
@@ -443,14 +448,19 @@ ${ticket.projects?.name ? `Project: ${ticket.projects.name}
|
|
|
443
448
|
}
|
|
444
449
|
case "get-ticket-by-id": {
|
|
445
450
|
const { id } = args2;
|
|
446
|
-
const { data, error } = await supabase.from("tickets").select(`
|
|
451
|
+
const { data: ticketData, error } = await supabase.from("tickets").select(`
|
|
447
452
|
*,
|
|
448
453
|
projects:project_id(id, name),
|
|
449
454
|
customers:customer_id(id, name),
|
|
450
455
|
assignee:assignee_id(id, full_name, email),
|
|
451
456
|
requester:requester_id(id, full_name, email)
|
|
452
|
-
`).eq("id", id).
|
|
457
|
+
`).eq("id", id).single();
|
|
453
458
|
if (error) throw error;
|
|
459
|
+
const { data: teamAccess } = await supabase.from("teams").select("id").or(`id.eq.${ticketData.team_id},parent_team_id.eq.${authContext.teamId}`).eq("id", ticketData.team_id).single();
|
|
460
|
+
if (!teamAccess && ticketData.team_id !== authContext.teamId) {
|
|
461
|
+
throw new Error("Access denied: You do not have permission to view this ticket");
|
|
462
|
+
}
|
|
463
|
+
const data = ticketData;
|
|
454
464
|
const { data: attachments, error: attachmentsError } = await supabase.from("ticket_attachments").select(`
|
|
455
465
|
id,
|
|
456
466
|
file_name,
|
|
@@ -459,7 +469,7 @@ ${ticket.projects?.name ? `Project: ${ticket.projects.name}
|
|
|
459
469
|
storage_key,
|
|
460
470
|
created_at,
|
|
461
471
|
users:user_id(id, full_name)
|
|
462
|
-
`).eq("ticket_id", id).
|
|
472
|
+
`).eq("ticket_id", id).order("created_at", { ascending: true });
|
|
463
473
|
if (attachmentsError) {
|
|
464
474
|
console.error("Error fetching attachments:", attachmentsError);
|
|
465
475
|
}
|
|
@@ -483,7 +493,7 @@ ${ticket.projects?.name ? `Project: ${ticket.projects.name}
|
|
|
483
493
|
mime_type,
|
|
484
494
|
storage_key,
|
|
485
495
|
created_at
|
|
486
|
-
`).in("comment_id", commentIds)
|
|
496
|
+
`).in("comment_id", commentIds);
|
|
487
497
|
if (commAttachmentsError) {
|
|
488
498
|
console.error("Error fetching comment attachments:", commAttachmentsError);
|
|
489
499
|
} else {
|
|
@@ -592,7 +602,8 @@ Type: ${type}
|
|
|
592
602
|
}
|
|
593
603
|
case "get-customers": {
|
|
594
604
|
const { q, pageSize = 20 } = args2;
|
|
595
|
-
|
|
605
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
606
|
+
let query = supabase.from("customers").select("id, name, email, website, created_at").in("team_id", teamIds).limit(Math.min(pageSize, 100));
|
|
596
607
|
if (q) query = query.or(`name.ilike.%${q}%,email.ilike.%${q}%`);
|
|
597
608
|
const { data, error } = await query.order("name");
|
|
598
609
|
if (error) throw error;
|
|
@@ -635,6 +646,7 @@ ${email ? `Email: ${email}
|
|
|
635
646
|
}
|
|
636
647
|
case "get-projects": {
|
|
637
648
|
const { customerId, q, pageSize = 20 } = args2;
|
|
649
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
638
650
|
let query = supabase.from("projects").select(`
|
|
639
651
|
id,
|
|
640
652
|
name,
|
|
@@ -643,7 +655,7 @@ ${email ? `Email: ${email}
|
|
|
643
655
|
status,
|
|
644
656
|
created_at,
|
|
645
657
|
customers:customer_id(id, name)
|
|
646
|
-
`).
|
|
658
|
+
`).in("team_id", teamIds).limit(Math.min(pageSize, 100));
|
|
647
659
|
if (customerId) query = query.eq("customer_id", customerId);
|
|
648
660
|
if (q) query = query.ilike("name", `%${q}%`);
|
|
649
661
|
const { data, error } = await query.order("name");
|
|
@@ -703,6 +715,33 @@ ${description ? `Description: ${description}
|
|
|
703
715
|
// Start actively tracking time
|
|
704
716
|
}).select("id, ticket_id, cursor_session_id, created_at").single();
|
|
705
717
|
if (error) throw error;
|
|
718
|
+
const { data: ticketData } = await supabase.from("tickets").select("project_id, title, ticket_number, description").eq("id", ticketId).single();
|
|
719
|
+
const draftStartTime = sessionStartTime;
|
|
720
|
+
const draftEndTime = new Date(sessionStartTime.getTime() + aiTimeEstimateMinutes * 60 * 1e3);
|
|
721
|
+
const eventTitle = ticketData?.title || "Development Work";
|
|
722
|
+
const eventDescription = ticketData?.description ? `${ticketData.ticket_number}: ${ticketData.description.substring(0, 200)}${ticketData.description.length > 200 ? "..." : ""}` : `Work on ticket ${ticketData?.ticket_number || ticketId}`;
|
|
723
|
+
const { data: draftEvent, error: draftError } = await supabase.from("agenda_events").insert({
|
|
724
|
+
team_id: authContext.teamId,
|
|
725
|
+
user_id: authContext.userId,
|
|
726
|
+
title: eventTitle,
|
|
727
|
+
description: eventDescription,
|
|
728
|
+
start_time: draftStartTime.toISOString(),
|
|
729
|
+
end_time: draftEndTime.toISOString(),
|
|
730
|
+
project_id: ticketData?.project_id || null,
|
|
731
|
+
ticket_id: ticketId,
|
|
732
|
+
// Link to ticket
|
|
733
|
+
type: "work",
|
|
734
|
+
status: "draft",
|
|
735
|
+
// Mark as draft for approval
|
|
736
|
+
all_day: false,
|
|
737
|
+
is_tracked: true,
|
|
738
|
+
// Mark as tracked time
|
|
739
|
+
tracked_duration: aiTimeEstimateMinutes * 60
|
|
740
|
+
// Store estimate in seconds
|
|
741
|
+
}).select("id").single();
|
|
742
|
+
if (draftError) {
|
|
743
|
+
console.error("\u26A0\uFE0F Failed to create draft agenda event:", draftError);
|
|
744
|
+
}
|
|
706
745
|
await supabase.from("ai_time_logs").insert({
|
|
707
746
|
ai_session_id: sessionData.id,
|
|
708
747
|
activity_type: "thinking",
|
|
@@ -724,7 +763,12 @@ ${complexityScore ? `\u{1F3AF} Complexity: ${complexityScore}/10
|
|
|
724
763
|
` : ""}\u23F1\uFE0F **Automatic Time Tracking Started**
|
|
725
764
|
${cursorSessionId ? `\u{1F517} Cursor Session: ${cursorSessionId}
|
|
726
765
|
` : ""}\u{1F4C5} Started: ${sessionStartTime.toLocaleString()}
|
|
727
|
-
|
|
766
|
+
${draftEvent ? `\u{1F4C6} **Draft Agenda Event Created** (needs approval)
|
|
767
|
+
\u2022 Title: "${eventTitle}"
|
|
768
|
+
\u2022 Time: ${draftStartTime.toLocaleTimeString()} - ${draftEndTime.toLocaleTimeString()} (${aiTimeEstimateMinutes}min)
|
|
769
|
+
\u2022 Ticket: ${ticketData?.ticket_number || "N/A"}
|
|
770
|
+
\u2022 Status: DRAFT
|
|
771
|
+
` : ""}
|
|
728
772
|
\u2705 Session initialized - ready for development with smart context!`
|
|
729
773
|
}]
|
|
730
774
|
};
|
|
@@ -732,7 +776,8 @@ ${cursorSessionId ? `\u{1F517} Cursor Session: ${cursorSessionId}
|
|
|
732
776
|
case "track-manual-follow-up": {
|
|
733
777
|
const { aiSessionId, originalPrompt, aiResponse, developerFollowUp, followUpReason, outcome = "success", timeSpentMinutes } = args2;
|
|
734
778
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
735
|
-
const
|
|
779
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
780
|
+
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select("id, status, created_at, ai_time_estimate_minutes").in("team_id", teamIds);
|
|
736
781
|
if (sessionError) {
|
|
737
782
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
738
783
|
}
|
|
@@ -797,6 +842,7 @@ ${timeSpentMinutes ? `\u23F1\uFE0F Time spent: ${timeSpentMinutes} minutes
|
|
|
797
842
|
case "get-session-context": {
|
|
798
843
|
const { aiSessionId, includeTicketData = true, includeTodoProgress = true, includeFollowUpHistory = false } = args2;
|
|
799
844
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
845
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
800
846
|
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select(`
|
|
801
847
|
id,
|
|
802
848
|
ticket_id,
|
|
@@ -806,7 +852,7 @@ ${timeSpentMinutes ? `\u23F1\uFE0F Time spent: ${timeSpentMinutes} minutes
|
|
|
806
852
|
complexity_score,
|
|
807
853
|
created_at,
|
|
808
854
|
cursor_session_id
|
|
809
|
-
`).
|
|
855
|
+
`).in("team_id", teamIds);
|
|
810
856
|
if (sessionError) {
|
|
811
857
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
812
858
|
}
|
|
@@ -857,7 +903,8 @@ ${context.ticketData ? `Ticket: ${context.ticketData.ticket_number} - ${context.
|
|
|
857
903
|
case "sync-session-todos": {
|
|
858
904
|
const { aiSessionId, todos, replaceAll = true } = args2;
|
|
859
905
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
860
|
-
const
|
|
906
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
907
|
+
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select("id").in("team_id", teamIds);
|
|
861
908
|
if (sessionError) {
|
|
862
909
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
863
910
|
}
|
|
@@ -900,7 +947,8 @@ ${replaceAll ? "" : "\u2795 Added to existing todo list\n"}
|
|
|
900
947
|
case "add-follow-up-todos": {
|
|
901
948
|
const { aiSessionId, newTodos, followUpReason } = args2;
|
|
902
949
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
903
|
-
const
|
|
950
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
951
|
+
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select("id").in("team_id", teamIds);
|
|
904
952
|
if (sessionError) {
|
|
905
953
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
906
954
|
}
|
|
@@ -937,7 +985,8 @@ ${followUpReason ? `Reason: ${followUpReason}
|
|
|
937
985
|
case "update-session-status": {
|
|
938
986
|
const { aiSessionId, status, actualTimeMinutes, completionNotes } = args2;
|
|
939
987
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
940
|
-
const
|
|
988
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
989
|
+
const { data: allSessions, error: findError } = await supabase.from("ai_sessions").select("id").in("team_id", teamIds);
|
|
941
990
|
if (findError) {
|
|
942
991
|
throw new Error(`Database error: ${findError.message}`);
|
|
943
992
|
}
|
|
@@ -968,6 +1017,7 @@ ${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes
|
|
|
968
1017
|
case "get-completion-context": {
|
|
969
1018
|
const { aiSessionId, includeFollowUps = true, includeTimeMetrics = true, includeTodos = true } = args2;
|
|
970
1019
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
1020
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
971
1021
|
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select(`
|
|
972
1022
|
id,
|
|
973
1023
|
ticket_id,
|
|
@@ -978,7 +1028,7 @@ ${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes
|
|
|
978
1028
|
completed_at,
|
|
979
1029
|
status,
|
|
980
1030
|
complexity_score
|
|
981
|
-
`).
|
|
1031
|
+
`).in("team_id", teamIds);
|
|
982
1032
|
if (sessionError) {
|
|
983
1033
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
984
1034
|
}
|
|
@@ -1046,7 +1096,8 @@ ${JSON.stringify(contextData, null, 2)}\`\`\``
|
|
|
1046
1096
|
case "save-customer-response": {
|
|
1047
1097
|
const { aiSessionId, customerResponse, responseType = "completion" } = args2;
|
|
1048
1098
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
1049
|
-
const
|
|
1099
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
1100
|
+
const { data: allSessions, error: sessionError } = await supabase.from("ai_sessions").select("id").in("team_id", teamIds);
|
|
1050
1101
|
if (sessionError) {
|
|
1051
1102
|
throw new Error(`Database error: ${sessionError.message}`);
|
|
1052
1103
|
}
|
|
@@ -1084,7 +1135,8 @@ ${customerResponse.substring(0, 200)}${customerResponse.length > 200 ? "..." : "
|
|
|
1084
1135
|
case "complete-ai-session": {
|
|
1085
1136
|
const { aiSessionId, workCompleted, technicalSummary, efficiencyNotes } = args2;
|
|
1086
1137
|
const sessionUuid = aiSessionId.replace("ai-sess-", "");
|
|
1087
|
-
const
|
|
1138
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
1139
|
+
const { data: allSessions, error: getSessionError } = await supabase.from("ai_sessions").select("id, ticket_id, ai_time_estimate_minutes, created_at").in("team_id", teamIds);
|
|
1088
1140
|
if (getSessionError) {
|
|
1089
1141
|
throw new Error(`Database error: ${getSessionError.message}`);
|
|
1090
1142
|
}
|
|
@@ -1194,6 +1246,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1194
1246
|
try {
|
|
1195
1247
|
switch (uri) {
|
|
1196
1248
|
case "tickets://recent": {
|
|
1249
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
1197
1250
|
const { data, error } = await supabase.from("tickets").select(`
|
|
1198
1251
|
id,
|
|
1199
1252
|
ticket_number,
|
|
@@ -1201,7 +1254,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1201
1254
|
status,
|
|
1202
1255
|
priority,
|
|
1203
1256
|
created_at
|
|
1204
|
-
`).
|
|
1257
|
+
`).in("team_id", teamIds).order("created_at", { ascending: false }).limit(20);
|
|
1205
1258
|
if (error) throw error;
|
|
1206
1259
|
return {
|
|
1207
1260
|
contents: [{
|
|
@@ -1212,7 +1265,8 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1212
1265
|
};
|
|
1213
1266
|
}
|
|
1214
1267
|
case "customers://all": {
|
|
1215
|
-
const
|
|
1268
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
1269
|
+
const { data, error } = await supabase.from("customers").select("id, name, email, website, created_at").in("team_id", teamIds).order("name").limit(50);
|
|
1216
1270
|
if (error) throw error;
|
|
1217
1271
|
return {
|
|
1218
1272
|
contents: [{
|
|
@@ -1223,6 +1277,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1223
1277
|
};
|
|
1224
1278
|
}
|
|
1225
1279
|
case "projects://active": {
|
|
1280
|
+
const teamIds = await getAccessibleTeamIds(authContext.teamId);
|
|
1226
1281
|
const { data, error } = await supabase.from("projects").select(`
|
|
1227
1282
|
id,
|
|
1228
1283
|
name,
|
|
@@ -1230,7 +1285,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
1230
1285
|
status,
|
|
1231
1286
|
created_at,
|
|
1232
1287
|
customers:customer_id(id, name)
|
|
1233
|
-
`).
|
|
1288
|
+
`).in("team_id", teamIds).eq("status", "active").order("name").limit(50);
|
|
1234
1289
|
if (error) throw error;
|
|
1235
1290
|
return {
|
|
1236
1291
|
contents: [{
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["args","name"],"mappings":";;;;;;;AASA,IAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACjC,IAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,KAAO,IAAI,UAAA,CAAW,YAAY,CAAC,CAAA,EAAG,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,QAAQ,GAAA,CAAI,kBAAA;AAE5F,IAAM,cAAc,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,KAAO,GAAA,CAAI,WAAW,iBAAiB,CAAC,CAAA,EAAG,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IACnF,OAAA,CAAQ,IAAI,YAAA,IACZ,0CAAA;AAEF,IAAM,cAAc,IAAA,CAAK,IAAA,CAAK,CAAA,GAAA,KAAO,GAAA,CAAI,WAAW,iBAAiB,CAAC,CAAA,EAAG,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IACnF,OAAA,CAAQ,IAAI,yBAAA,IACZ,6NAAA;AAEF,IAAI,CAAC,MAAA,EAAQ;AACX,EAAA,OAAA,CAAQ,MAAM,mGAA8F,CAAA;AAC5G,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB;AAQA,IAAM,QAAA,GAAW,YAAA,CAAa,WAAA,EAAa,WAAW,CAAA;AAYtD,eAAe,eAAe,GAAA,EAA0C;AACtE,EAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,IAAK,GAAA,CAAI,WAAW,EAAA,EAAI;AAChD,IAAA,OAAA,CAAQ,MAAM,kCAA2B,CAAA;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AAEF,IAAA,MAAM,OAAA,GAAU,WAAW,QAAQ,CAAA,CAAE,OAAO,GAAG,CAAA,CAAE,OAAO,KAAK,CAAA;AAC7D,IAAA,OAAA,CAAQ,MAAM,CAAA,mCAAA,EAA+B,OAAA,CAAQ,UAAU,CAAA,EAAG,EAAE,CAAC,CAAA,GAAA,CAAK,CAAA;AAG1E,IAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAM,GAAI,MAAM,QAAA,CACvC,IAAA,CAAK,UAAU,CAAA,CACf,OAAO,4CAA4C,CAAA,CACnD,GAAG,UAAA,EAAY,OAAO,EACtB,MAAA,EAAO;AAEV,IAAA,IAAI,KAAA,IAAS,CAAC,UAAA,EAAY;AACxB,MAAA,OAAA,CAAQ,KAAA,CAAM,sCAAA,EAAmC,KAAA,EAAO,OAAO,CAAA;AAC/D,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,SACH,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,EAAE,YAAA,EAAA,iBAAc,IAAI,IAAA,EAAK,EAAE,aAAY,EAAG,EACjD,EAAA,CAAG,IAAA,EAAM,WAAW,EAAE,CAAA;AAEzB,IAAA,OAAA,CAAQ,MAAM,CAAA,kCAAA,EAAgC,UAAA,CAAW,OAAO,CAAA,SAAA,EAAY,UAAA,CAAW,OAAO,CAAA,CAAE,CAAA;AAEhG,IAAA,OAAO;AAAA,MACL,QAAQ,UAAA,CAAW,OAAA;AAAA,MACnB,QAAQ,UAAA,CAAW,OAAA;AAAA,MACnB,MAAA,EAAQ,UAAA,CAAW,MAAA,IAAU;AAAC,KAChC;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAgC,KAAK,CAAA;AACnD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAGA,IAAI,WAAA,GAAkC,IAAA;AAGtC,SAAS,YAAY,QAAA,EAA2B;AAC9C,EAAA,OAAO,QAAA,CAAS,UAAA,CAAW,QAAQ,CAAA,IAC5B,CAAC,YAAA,EAAc,WAAA,EAAa,WAAA,EAAa,WAAA,EAAa,YAAY,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA;AAC9F;AAGA,eAAe,sBAAsB,UAAA,EAA4C;AAC/E,EAAA,IAAI;AAEF,IAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,UAAS,GAAI,MAAM,QAAA,CAAS,OAAA,CACvD,IAAA,CAAK,OAAO,CAAA,CACZ,eAAA,CAAgB,YAAY,IAAI,CAAA;AAEnC,IAAA,IAAI,QAAA,IAAY,CAAC,OAAA,EAAS,SAAA,EAAW;AACnC,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,UAAU,CAAA,CAAA,CAAA,EAAK,QAAQ,CAAA;AACxE,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA;AAC9C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,UAAU,CAAA,EAAA,EAAK,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AACzE,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,EAAY;AAC/C,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,CAAK,WAAW,CAAA;AACtC,IAAA,OAAO,MAAA,CAAO,SAAS,QAAQ,CAAA;AAAA,EACjC,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,UAAU,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAGA,IAAM,SAAS,IAAI,MAAA;AAAA,EACjB;AAAA,IACE,IAAA,EAAM,uBAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,YAAA,EAAc;AAAA,MACZ,OAAO,EAAC;AAAA,MACR,WAAW;AAAC;AACd;AAEJ,CAAA;AAGA,IAAM,KAAA,GAAQ;AAAA,EACZ;AAAA,IACE,IAAA,EAAM,aAAA;AAAA,IACN,WAAA,EAAa,6FAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,MAAA,EAAQ,aAAA,EAAe,QAAA,EAAU,UAAA,EAAY,QAAA,EAAU,SAAS,CAAA,EAAE;AAAA,QACnG,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,KAAA,EAAO,QAAA,EAAU,MAAA,EAAQ,UAAU,CAAA,EAAE;AAAA,QACxE,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC5B,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC7B,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,uCAAA,EAAwC;AAAA,QAC1E,UAAU,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,EAAA,EAAI,SAAS,GAAA;AAAI,OACxD;AAAA,MACA,UAAU;AAAC;AACb,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,kBAAA;AAAA,IACN,WAAA,EAAa,0OAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,EAAA,EAAI,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,WAAA;AAAY,OACjD;AAAA,MACA,QAAA,EAAU,CAAC,IAAI;AAAA;AACjB,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,eAAA;AAAA,IACN,WAAA,EAAa,qBAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,cAAA,EAAe;AAAA,QACrD,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,CAAC,MAAA,EAAQ,aAAA,EAAe,QAAA,EAAU,UAAA,EAAY,QAAA,EAAU,SAAS,CAAA,EAAG,SAAS,MAAA,EAAO;AAAA,QACpH,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,KAAA,EAAO,QAAA,EAAU,MAAA,EAAQ,UAAU,CAAA,EAAG,OAAA,EAAS,QAAA,EAAS;AAAA,QAC3F,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,CAAC,MAAA,EAAQ,KAAA,EAAO,SAAA,EAAW,SAAA,EAAW,UAAA,EAAY,aAAa,CAAA,EAAG,SAAS,MAAA,EAAO;AAAA,QAChH,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC5B,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA;AAAS,OAC/B;AAAA,MACA,QAAA,EAAU,CAAC,OAAO;AAAA;AACpB,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,eAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,yCAAA,EAA0C;AAAA,QAC5E,UAAU,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,EAAA,EAAI,SAAS,GAAA;AAAI,OACxD;AAAA,MACA,UAAU;AAAC;AACb,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,iBAAA;AAAA,IACN,WAAA,EAAa,uBAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,eAAA,EAAgB;AAAA,QACrD,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACxB,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA;AAAS,OAC5B;AAAA,MACA,QAAA,EAAU,CAAC,MAAM;AAAA;AACnB,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,cAAA;AAAA,IACN,WAAA,EAAa,sCAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,uBAAA,EAAwB;AAAA,QACnE,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,+BAAA,EAAgC;AAAA,QAClE,UAAU,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,EAAA,EAAI,SAAS,GAAA;AAAI,OACxD;AAAA,MACA,UAAU;AAAC;AACb,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,gBAAA;AAAA,IACN,WAAA,EAAa,sBAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,IAAA,EAAM,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,cAAA,EAAe;AAAA,QACpD,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC7B,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,QAAA,EAAU,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA,EAAG,OAAA,EAAS,QAAA;AAAS,OACrG;AAAA,MACA,QAAA,EAAU,CAAC,MAAM;AAAA;AACnB,GACF;AAAA;AAAA,EAEA;AAAA,IACE,IAAA,EAAM,wBAAA;AAAA,IACN,WAAA,EAAa,kGAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC3B,SAAA,EAAW,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,mBAAA,EAAoB;AAAA,QAC9D,eAAA,EAAiB,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,2BAAA,EAA4B;AAAA,QAC5E,eAAA,EAAiB;AAAA,UACf,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,UACxB,WAAA,EAAa;AAAA,SACf;AAAA,QACA,qBAAA,EAAuB;AAAA,UACrB,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,eAAA,EAAiB;AAAA,UACf,IAAA,EAAM,QAAA;AAAA,UACN,OAAA,EAAS,CAAA;AAAA,UACT,OAAA,EAAS,EAAA;AAAA,UACT,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA,QAAA,EAAU,CAAC,UAAA,EAAY,uBAAuB;AAAA;AAChD,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,wBAAA;AAAA,IACN,WAAA,EAAa,4CAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,cAAA,EAAgB,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACjC,UAAA,EAAY,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC7B,iBAAA,EAAmB,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACpC,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,QAAA;AAAA,UACN,IAAA,EAAM,CAAC,mBAAA,EAAqB,gBAAA,EAAkB,uBAAuB,eAAe;AAAA,SACtF;AAAA,QACA,OAAA,EAAS;AAAA,UACP,IAAA,EAAM,QAAA;AAAA,UACN,IAAA,EAAM,CAAC,SAAA,EAAW,iBAAA,EAAmB,cAAc,CAAA;AAAA,UACnD,OAAA,EAAS;AAAA,SACX;AAAA,QACA,gBAAA,EAAkB,EAAE,IAAA,EAAM,QAAA;AAAS,OACrC;AAAA,MACA,UAAU,CAAC,aAAA,EAAe,gBAAA,EAAkB,YAAA,EAAc,qBAAqB,gBAAgB;AAAA;AACjG,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,qBAAA;AAAA,IACN,WAAA,EAAa,sDAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,iBAAA,EAAmB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QACpD,mBAAA,EAAqB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QACtD,sBAAA,EAAwB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,KAAA;AAAM,OAC5D;AAAA,MACA,QAAA,EAAU,CAAC,aAAa;AAAA;AAC1B,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,oBAAA;AAAA,IACN,WAAA,EAAa,2EAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,QAAA;AAAA,YACN,UAAA,EAAY;AAAA,cACV,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,wCAAA,EAAyC;AAAA,cAChF,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,cAC1B,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,SAAA,EAAW,aAAA,EAAe,WAAA,EAAa,WAAW,CAAA,EAAE;AAAA,cACrF,gBAAA,EAAkB,EAAE,IAAA,EAAM,QAAA;AAAS,aACrC;AAAA,YACA,QAAA,EAAU,CAAC,SAAA,EAAW,QAAQ;AAAA;AAChC,SACF;AAAA,QACA,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,SAAA;AAAA,UACN,OAAA,EAAS,IAAA;AAAA,UACT,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA,QAAA,EAAU,CAAC,aAAA,EAAe,OAAO;AAAA;AACnC,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,qBAAA;AAAA,IACN,WAAA,EAAa,gEAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,QAAA,EAAU;AAAA,UACR,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,QAAA;AAAA,YACN,UAAA,EAAY;AAAA,cACV,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,cAC1B,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,CAAC,SAAA,EAAW,aAAa,CAAA,EAAG,OAAA,EAAS,SAAA,EAAU;AAAA,cAC/E,gBAAA,EAAkB,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,cACnC,eAAA,EAAiB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA;AAAK,aACpD;AAAA,YACA,QAAA,EAAU,CAAC,SAAS;AAAA;AACtB,SACF;AAAA,QACA,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA,QAAA,EAAU,CAAC,aAAA,EAAe,UAAU;AAAA;AACtC,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,uBAAA;AAAA,IACN,WAAA,EAAa,8CAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,MAAM,CAAC,SAAA,EAAW,aAAA,EAAe,QAAA,EAAU,aAAa,QAAQ;AAAA,SAClE;AAAA,QACA,iBAAA,EAAmB,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QACpC,eAAA,EAAiB,EAAE,IAAA,EAAM,QAAA;AAAS,OACpC;AAAA,MACA,QAAA,EAAU,CAAC,aAAA,EAAe,QAAQ;AAAA;AACpC,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,wBAAA;AAAA,IACN,WAAA,EAAa,oEAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,gBAAA,EAAkB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QACnD,kBAAA,EAAoB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AAAA,QACrD,YAAA,EAAc,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA;AAAK,OACjD;AAAA,MACA,QAAA,EAAU,CAAC,aAAa;AAAA;AAC1B,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,wBAAA;AAAA,IACN,WAAA,EAAa,+CAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,gBAAA,EAAkB,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,0CAAA,EAA2C;AAAA,QAC5F,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,QAAA;AAAA,UACN,IAAA,EAAM,CAAC,YAAA,EAAc,iBAAA,EAAmB,qBAAqB,CAAA;AAAA,UAC7D,OAAA,EAAS;AAAA;AACX,OACF;AAAA,MACA,QAAA,EAAU,CAAC,aAAA,EAAe,kBAAkB;AAAA;AAC9C,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,qBAAA;AAAA,IACN,WAAA,EAAa,uEAAA;AAAA,IACb,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,QAC9B,aAAA,EAAe;AAAA,UACb,IAAA,EAAM,OAAA;AAAA,UACN,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AAAA,UACxB,WAAA,EAAa;AAAA,SACf;AAAA,QACA,gBAAA,EAAkB;AAAA,UAChB,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,eAAA,EAAiB,EAAE,IAAA,EAAM,QAAA;AAAS,OACpC;AAAA,MACA,QAAA,EAAU,CAAC,aAAA,EAAe,eAAe;AAAA;AAC3C;AAEJ,CAAA;AAGA,IAAM,SAAA,GAAY;AAAA,EAChB;AAAA,IACE,GAAA,EAAK,kBAAA;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,WAAA,EAAa,+BAAA;AAAA,IACb,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,GAAA,EAAK,iBAAA;AAAA,IACL,IAAA,EAAM,eAAA;AAAA,IACN,WAAA,EAAa,6BAAA;AAAA,IACb,QAAA,EAAU;AAAA,GACZ;AAAA,EACA;AAAA,IACE,GAAA,EAAK,mBAAA;AAAA,IACL,IAAA,EAAM,iBAAA;AAAA,IACN,WAAA,EAAa,2BAAA;AAAA,IACb,QAAA,EAAU;AAAA;AAEd,CAAA;AAGA,MAAA,CAAO,iBAAA,CAAkB,wBAAwB,YAAY;AAC3D,EAAA,OAAO,EAAE,OAAO,KAAA,EAAM;AACxB,CAAC,CAAA;AAGD,MAAA,CAAO,iBAAA,CAAkB,4BAA4B,YAAY;AAC/D,EAAA,OAAO,EAAE,WAAW,SAAA,EAAU;AAChC,CAAC,CAAA;AAGD,MAAA,CAAO,iBAAA,CAAkB,qBAAA,EAAuB,OAAO,OAAA,KAAY;AACjE,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,wDAAwD;AAAA,KAC1F;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAWA,KAAAA,KAAS,OAAA,CAAQ,MAAA;AAC1C,EAAA,OAAA,CAAQ,MAAM,CAAA,iCAAA,EAAwB,IAAI,CAAA,UAAA,EAAa,WAAA,CAAY,MAAM,CAAA,CAAE,CAAA;AAE3E,EAAA,IAAI;AACF,IAAA,QAAQ,IAAA;AAAM,MACZ,KAAK,aAAA,EAAe;AAClB,QAAA,MAAM,EAAE,QAAQ,QAAA,EAAU,SAAA,EAAW,YAAY,CAAA,EAAG,QAAA,GAAW,IAAG,GAAIA,KAAAA;AAEtE,QAAA,IAAI,KAAA,GAAQ,QAAA,CACT,IAAA,CAAK,SAAS,EACd,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAaP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,GAAG,CAAC,CAAA;AAEhC,QAAA,IAAI,MAAA,EAAQ,KAAA,GAAQ,KAAA,CAAM,EAAA,CAAG,UAAU,MAAM,CAAA;AAC7C,QAAA,IAAI,QAAA,EAAU,KAAA,GAAQ,KAAA,CAAM,EAAA,CAAG,YAAY,QAAQ,CAAA;AACnD,QAAA,IAAI,SAAA,EAAW,KAAA,GAAQ,KAAA,CAAM,EAAA,CAAG,cAAc,SAAS,CAAA;AACvD,QAAA,IAAI,UAAA,EAAY,KAAA,GAAQ,KAAA,CAAM,EAAA,CAAG,eAAe,UAAU,CAAA;AAC1D,QAAA,IAAI,CAAA,UAAW,KAAA,CAAM,EAAA,CAAG,gBAAgB,CAAC,CAAA,qBAAA,EAAwB,CAAC,CAAA,CAAA,CAAG,CAAA;AAErE,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,KAAA,CAAM,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,KAAA,EAAO,CAAA;AAE5E,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,MAAA,EAAS,IAAA,EAAM,MAAA,IAAU,CAAC,CAAA;;AAAA,EAAgB,IAAA,EAAM,GAAA;AAAA,cAAI,YACxD,CAAA,EAAA,EAAK,MAAA,CAAO,aAAa,CAAA,IAAA,EAAO,OAAO,KAAK;AAAA,QAAA,EACjC,MAAA,CAAO,MAAM,CAAA,aAAA,EAAgB,MAAA,CAAO,QAAQ;AAAA,EACnD,OAAO,QAAA,EAAkB,IAAA,GAAO,CAAA,SAAA,EAAa,MAAA,CAAO,SAAiB,IAAI;AAAA,CAAA,GAAO,EAAE,GAClF,MAAA,CAAO,SAAA,EAAmB,OAAO,CAAA,UAAA,EAAc,MAAA,CAAO,UAAkB,IAAI;AAAA,CAAA,GAAO,EAAE,YAC7E,IAAI,IAAA,CAAK,OAAO,UAAU,CAAA,CAAE,oBAAoB;AAAA;AAAA,aAC9D,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,mBAAmB,CAAA;AAAA,WACpC;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,kBAAA,EAAoB;AACvB,QAAA,MAAM,EAAE,IAAG,GAAIA,KAAAA;AAGf,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,SAAS,CAAA,CACd,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAMP,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,EAAE,CAAA,CACX,GAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAGjB,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,gBAAA,EAAiB,GAAI,MAAM,QAAA,CAC1D,IAAA,CAAK,oBAAoB,CAAA,CACzB,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAQP,CAAA,CACA,EAAA,CAAG,WAAA,EAAa,EAAE,EAClB,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,EAChC,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,MAAM,CAAA;AAE1C,QAAA,IAAI,gBAAA,EAAkB;AACpB,UAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,gBAAgB,CAAA;AAAA,QAC/D;AAGA,QAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,aAAA,EAAc,GAAI,MAAM,QAAA,CACpD,IAAA,CAAK,iBAAiB,CAAA,CACtB,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAKP,CAAA,CACA,EAAA,CAAG,WAAA,EAAa,EAAE,CAAA,CAClB,MAAM,YAAA,EAAc,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAE1C,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,OAAA,CAAQ,KAAA,CAAM,4BAA4B,aAAa,CAAA;AAAA,QACzD;AAGA,QAAA,MAAM,aAAa,QAAA,EAAU,GAAA,CAAI,OAAK,CAAA,CAAE,EAAE,KAAK,EAAC;AAChD,QAAA,IAAI,qBAA4B,EAAC;AAEjC,QAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,UAAA,MAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,KAAA,EAAO,oBAAA,EAAqB,GAAI,MAAM,QAAA,CAClE,IAAA,CAAK,4BAA4B,CAAA,CACjC,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAAA,CAQP,CAAA,CACA,GAAG,YAAA,EAAc,UAAU,EAC3B,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,UAAA,IAAI,oBAAA,EAAsB;AACxB,YAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,oBAAoB,CAAA;AAAA,UAC3E,CAAA,MAAO;AACL,YAAA,kBAAA,GAAqB,mBAAmB,EAAC;AAAA,UAC3C;AAAA,QACF;AAGA,QAAA,MAAM,UAAiB,CAAC;AAAA,UACtB,IAAA,EAAM,MAAA;AAAA,UACN,IAAA,EAAM,CAAA;;AAAA,EAAA,EACK,IAAA,CAAK,aAAa,CAAA,IAAA,EAAO,IAAA,CAAK,KAAK;AAAA,QAAA,EAC7B,KAAK,MAAM;AAAA,UAAA,EACT,KAAK,QAAQ;AAAA,MAAA,EACjB,KAAK,IAAI;AAAA,EACf,IAAA,CAAK,WAAA,GAAc,CAAA,aAAA,EAAgB,IAAA,CAAK,WAAW;AAAA,CAAA,GAAO,EAAE,GAC3D,IAAA,CAAK,QAAA,EAAkB,OAAO,CAAA,SAAA,EAAa,IAAA,CAAK,SAAiB,IAAI;AAAA,CAAA,GAAO,EAAE,GAC9E,IAAA,CAAK,SAAA,EAAmB,OAAO,CAAA,UAAA,EAAc,IAAA,CAAK,UAAkB,IAAI;AAAA,CAAA,GAAO,EAAE,GAClF,IAAA,CAAK,QAAA,EAAU,YAAY,CAAA,UAAA,EAAa,IAAA,CAAK,SAAS,SAAS;AAAA,CAAA,GAAO,EAAE,CAAA,WAAA,EAC7D,IAAA,CAAK,SAAA,EAAW,aAAa,SAAS;AAAA,SAAA,EACxC,IAAI,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA,CAAE,oBAAoB;AAAA,EACvD,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI;AAAA,uBAAA,EAAqB,YAAY,MAAM;AAAA,CAAA,GAAO,EAAE,GACxF,QAAA,IAAY,QAAA,CAAS,SAAS,CAAA,GAAI,CAAA,oBAAA,EAAgB,SAAS,MAAM;AAAA,CAAA,GAAO,EAAE,CAAA;AAAA,SACpF,CAAA;AAGD,QAAA,IAAI,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,EAAG;AACzC,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qBAAA,EAAiB,WAAA,CAAY,MAAM,CAAA,sBAAA,CAAwB,CAAA;AAEzE,UAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AACpC,YAAA,IAAI,WAAA,CAAY,UAAA,CAAW,SAAS,CAAA,EAAG;AACrC,cAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,oCAAA,EAA2B,UAAA,CAAW,SAAS,CAAA,CAAE,CAAA;AAC/D,cAAA,MAAM,UAAA,GAAa,MAAM,qBAAA,CAAsB,UAAA,CAAW,WAAW,CAAA;AAErE,cAAA,IAAI,UAAA,EAAY;AACd,gBAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,kBACX,IAAA,EAAM,OAAA;AAAA,kBACN,IAAA,EAAM,UAAA;AAAA,kBACN,UAAU,UAAA,CAAW;AAAA,iBACtB,CAAA;AAGD,gBAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,kBACX,IAAA,EAAM,MAAA;AAAA,kBACN,IAAA,EAAM;AAAA,iCAAA,EAA+B,UAAA,CAAW,SAAS,CAAA,EAAA,EAAK,IAAA,CAAK,MAAM,UAAA,CAAW,SAAA,GAAY,IAAI,CAAC,CAAA,gBAAA,EAAoB,WAAW,KAAA,EAAe,SAAA,IAAa,SAAS,CAAA,IAAA,EAAO,IAAI,KAAK,UAAA,CAAW,UAAU,CAAA,CAAE,kBAAA,EAAoB,CAAA;AAAA;AAAA,iBACrO,CAAA;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,QAAA,IAAI,kBAAA,CAAmB,SAAS,CAAA,EAAG;AACjC,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qBAAA,EAAiB,kBAAA,CAAmB,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAEjF,UAAA,KAAA,MAAW,cAAc,kBAAA,EAAoB;AAC3C,YAAA,IAAI,WAAA,CAAY,UAAA,CAAW,SAAS,CAAA,EAAG;AACrC,cAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,4CAAA,EAAmC,UAAA,CAAW,SAAS,CAAA,CAAE,CAAA;AACvE,cAAA,MAAM,UAAA,GAAa,MAAM,qBAAA,CAAsB,UAAA,CAAW,WAAW,CAAA;AAErE,cAAA,IAAI,UAAA,EAAY;AAEd,gBAAA,MAAM,UAAU,QAAA,EAAU,IAAA,CAAK,OAAK,CAAA,CAAE,EAAA,KAAO,WAAW,UAAU,CAAA;AAElE,gBAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,kBACX,IAAA,EAAM,OAAA;AAAA,kBACN,IAAA,EAAM,UAAA;AAAA,kBACN,UAAU,UAAA,CAAW;AAAA,iBACtB,CAAA;AAGD,gBAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,kBACX,IAAA,EAAM,MAAA;AAAA,kBACN,IAAA,EAAM;AAAA,oCAAA,EAAmC,OAAA,EAAS,OAAe,SAAA,IAAa,SAAS,OAAO,IAAI,IAAA,CAAK,WAAW,UAAU,CAAA,CAAE,oBAAoB,CAAA,EAAA,EAAK,WAAW,SAAS,CAAA,EAAA,EAAK,KAAK,KAAA,CAAM,UAAA,CAAW,SAAA,GAAY,IAAI,CAAC,CAAA;AAAA,CAAA,IAChN,OAAA,EAAS,OAAA,GAAU,CAAA,eAAA,EAAkB,OAAA,CAAQ,QAAQ,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,GAAG,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,GAAA,GAAM,QAAQ,EAAE,CAAA;AAAA,CAAA,GAAQ,EAAA;AAAA,iBAClI,CAAA;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,6BAAA,EAA2B,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,OAAO,CAAA,CAAE,MAAM,CAAA,OAAA,CAAS,CAAA;AAEhG,QAAA,OAAO,EAAE,OAAA,EAAQ;AAAA,MACnB;AAAA,MAEA,KAAK,eAAA,EAAiB;AACpB,QAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAa,MAAA,GAAS,MAAA,EAAQ,QAAA,GAAW,QAAA,EAAU,IAAA,GAAO,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAW,GAAIA,KAAAA;AAG3G,QAAA,MAAM,IAAA,GAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACpC,QAAA,MAAM,EAAE,OAAM,GAAI,MAAM,SACrB,IAAA,CAAK,SAAS,EACd,MAAA,CAAO,GAAA,EAAK,EAAE,KAAA,EAAO,OAAA,EAAS,MAAM,IAAA,EAAM,EAC1C,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,MAAM,YAAA,GAAe,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,MAAA,CAAA,CAAQ,KAAA,IAAS,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAEzE,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,SAAS,CAAA,CACd,MAAA,CAAO;AAAA,UACN,SAAS,WAAA,CAAY,MAAA;AAAA,UACrB,aAAA,EAAe,YAAA;AAAA,UACf,KAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA;AAAA,UACA,YAAY,SAAA,IAAa,IAAA;AAAA,UACzB,aAAa,UAAA,IAAc,IAAA;AAAA,UAC3B,cAAc,WAAA,CAAY;AAAA,SAC3B,CAAA,CACA,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,iBAAA,EACoB,YAAY,CAAA;AAAA,OAAA,EACtB,KAAK;AAAA,QAAA,EACJ,MAAM;AAAA,UAAA,EACJ,QAAQ;AAAA,MAAA,EACZ,IAAI;AAAA;AAAA,WACpB;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,eAAA,EAAiB;AACpB,QAAA,MAAM,EAAE,CAAA,EAAG,QAAA,GAAW,EAAA,EAAG,GAAIA,KAAAA;AAE7B,QAAA,IAAI,QAAQ,QAAA,CACT,IAAA,CAAK,WAAW,CAAA,CAChB,MAAA,CAAO,sCAAsC,CAAA,CAC7C,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,KAAA,CAAM,KAAK,GAAA,CAAI,QAAA,EAAU,GAAG,CAAC,CAAA;AAEhC,QAAA,IAAI,CAAA,UAAW,KAAA,CAAM,EAAA,CAAG,eAAe,CAAC,CAAA,eAAA,EAAkB,CAAC,CAAA,CAAA,CAAG,CAAA;AAE9D,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,KAAU,MAAM,KAAA,CAAM,MAAM,MAAM,CAAA;AAEhD,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,MAAA,EAAS,IAAA,EAAM,MAAA,IAAU,CAAC,CAAA;;AAAA,EAAkB,IAAA,EAAM,GAAA;AAAA,cAAI,CAAA,QAAA,KAC1D,CAAA,EAAA,EAAK,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,QAAA,CAAS,KAAA,GAAQ,CAAA,OAAA,EAAU,QAAA,CAAS,KAAK;AAAA,CAAA,GAAO,EAAE,CAAA,EAClD,QAAA,CAAS,OAAA,GAAU,CAAA,SAAA,EAAY,SAAS,OAAO;AAAA,CAAA,GAAO,EAAE,YAC/C,IAAI,IAAA,CAAK,SAAS,UAAU,CAAA,CAAE,oBAAoB;AAAA;AAAA,aAChE,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,qBAAqB,CAAA;AAAA,WACtC;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,iBAAA,EAAmB;AACtB,QAAA,MAAM,EAAE,IAAA,EAAAC,KAAAA,EAAM,KAAA,EAAO,SAAQ,GAAID,KAAAA;AAEjC,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,WAAW,CAAA,CAChB,MAAA,CAAO;AAAA,UACN,SAAS,WAAA,CAAY,MAAA;AAAA,UACrB,IAAA,EAAAC,KAAAA;AAAA,UACA,OAAO,KAAA,IAAS,IAAA;AAAA,UAChB,SAAS,OAAA,IAAW,IAAA;AAAA,UACpB,SAAS,WAAA,CAAY;AAAA,SACtB,CAAA,CACA,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,MAAA,EACSA,KAAI;AAAA,EACV,KAAA,GAAQ,UAAU,KAAK;AAAA,CAAA,GAAO,EAAE,CAAA,EAChC,OAAA,GAAU,CAAA,SAAA,EAAY,OAAO;AAAA,CAAA,GAAO,EAAE,CAAA;AAAA,WAChD;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,cAAA,EAAgB;AACnB,QAAA,MAAM,EAAE,UAAA,EAAY,CAAA,EAAG,QAAA,GAAW,IAAG,GAAID,KAAAA;AAEzC,QAAA,IAAI,KAAA,GAAQ,QAAA,CACT,IAAA,CAAK,UAAU,EACf,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAQP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,GAAG,CAAC,CAAA;AAEhC,QAAA,IAAI,UAAA,EAAY,KAAA,GAAQ,KAAA,CAAM,EAAA,CAAG,eAAe,UAAU,CAAA;AAC1D,QAAA,IAAI,GAAG,KAAA,GAAQ,KAAA,CAAM,MAAM,MAAA,EAAQ,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAE3C,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,KAAU,MAAM,KAAA,CAAM,MAAM,MAAM,CAAA;AAEhD,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,MAAA,EAAS,IAAA,EAAM,MAAA,IAAU,CAAC,CAAA;;AAAA,EAAiB,IAAA,EAAM,GAAA;AAAA,cAAI,CAAA,OAAA,KACzD,CAAA,EAAA,EAAK,OAAA,CAAQ,IAAI,CAAA;AAAA,QAAA,EACN,QAAQ,MAAM;AAAA,EACtB,OAAA,CAAQ,WAAA,GAAc,CAAA,aAAA,EAAgB,OAAA,CAAQ,WAAW;AAAA,CAAA,GAAO,EAAE,GACjE,OAAA,CAAQ,SAAA,EAAmB,OAAO,CAAA,UAAA,EAAc,OAAA,CAAQ,UAAkB,IAAI;AAAA,CAAA,GAAO,EAAE,YAC/E,IAAI,IAAA,CAAK,QAAQ,UAAU,CAAA,CAAE,oBAAoB;AAAA;AAAA,aAC/D,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,oBAAoB,CAAA;AAAA,WACrC;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,gBAAA,EAAkB;AACrB,QAAA,MAAM,EAAE,IAAA,EAAAC,KAAAA,EAAM,aAAa,UAAA,EAAY,MAAA,GAAS,UAAS,GAAID,KAAAA;AAE7D,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO;AAAA,UACN,SAAS,WAAA,CAAY,MAAA;AAAA,UACrB,IAAA,EAAAC,KAAAA;AAAA,UACA,aAAa,WAAA,IAAe,IAAA;AAAA,UAC5B,aAAa,UAAA,IAAc,IAAA;AAAA,UAC3B,MAAA;AAAA,UACA,SAAS,WAAA,CAAY;AAAA,SACtB,CAAA,CACA,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,MAAA,EACSA,KAAI;AAAA,QAAA,EACF,MAAM;AAAA,EACd,WAAA,GAAc,gBAAgB,WAAW;AAAA,CAAA,GAAO,EAAE,CAAA;AAAA,WAC5D;AAAA,SACH;AAAA,MACF;AAAA;AAAA,MAGA,KAAK,wBAAA,EAA0B;AAC7B,QAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,iBAAiB,eAAA,EAAiB,qBAAA,EAAuB,iBAAgB,GAAID,KAAAA;AAG1G,QAAA,MAAM,gBAAA,uBAAuB,IAAA,EAAK;AAClC,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAM,GAAI,MAAM,QAAA,CACxC,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA,UACN,SAAA,EAAW,QAAA;AAAA,UACX,kBAAkB,WAAA,CAAY,MAAA;AAAA,UAC9B,SAAS,WAAA,CAAY,MAAA;AAAA,UACrB,mBAAmB,eAAA,IAAmB,IAAA;AAAA,UACtC,wBAAA,EAA0B,qBAAA;AAAA;AAAA,UAC1B,kBAAkB,eAAA,IAAmB,IAAA;AAAA,UACrC,MAAA,EAAQ;AAAA;AAAA,SACT,CAAA,CACA,MAAA,CAAO,8CAA8C,EACrD,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAGjB,QAAA,MAAM,QAAA,CACH,IAAA,CAAK,cAAc,CAAA,CACnB,MAAA,CAAO;AAAA,UACN,eAAe,WAAA,CAAY,EAAA;AAAA,UAC3B,aAAA,EAAe,UAAA;AAAA,UACf,WAAA,EAAa,kDAAA;AAAA,UACb,gBAAA,EAAkB,CAAA;AAAA,UAClB,kBAAA,EAAoB,CAAA;AAAA,UACpB,SAAA,EAAW;AAAA,SACZ,CAAA;AAGH,QAAA,MAAM,YAAY,CAAA,QAAA,EAAW,WAAA,CAAY,GAAG,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAE3D,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,wBAAA,EACoB,SAAS,CAAA;AAAA,kBAAA,EACf,QAAQ;AAAA,4BAAA,EACD,qBAAqB,CAAA;AAAA,EACvC,eAAA,GAAkB,yBAAkB,eAAe,CAAA;AAAA,CAAA,GAAU,EAAE,CAAA;AAAA,EAE/D,eAAA,GAAkB,6BAAsB,eAAe;AAAA,CAAA,GAAO,EAAE,CAAA,mBAAA,EACpD,gBAAA,CAAiB,cAAA,EAAgB;;AAAA,sEAAA;AAAA,WAEvD;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,wBAAA,EAA0B;AAC7B,QAAA,MAAM,EAAE,aAAa,cAAA,EAAgB,UAAA,EAAY,mBAAmB,cAAA,EAAgB,OAAA,GAAU,SAAA,EAAW,gBAAA,EAAiB,GAAIA,KAAAA;AAG9H,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAItD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,KAAiB,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,kDAAkD,EACzD,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAC9E,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAEA,QAAA,MAAM,YAAA,uBAAmB,IAAA,EAAK;AAG9B,QAAA,MAAM,QAAA,CACH,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA,UACN,MAAA,EAAQ;AAAA;AAAA;AAAA,SAET,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,QAAQ,EAAE,CAAA;AAGtB,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,mBAAmB,CAAA,CACxB,MAAA,CAAO;AAAA,UACN,eAAe,OAAA,CAAQ,EAAA;AAAA,UACvB,cAAc,WAAA,CAAY,MAAA;AAAA,UAC1B,SAAS,WAAA,CAAY,MAAA;AAAA,UACrB,eAAA,EAAiB,cAAA;AAAA,UACjB,WAAA,EAAa,UAAA;AAAA,UACb,gBAAA,EAAkB,iBAAA;AAAA,UAClB,gBAAA,EAAkB,cAAA;AAAA,UAClB,OAAA;AAAA,UACA,oBAAoB,gBAAA,IAAoB,IAAA;AAAA,UACxC,aAAa,OAAA,KAAY,SAAA,GAAA,qBAAgB,IAAA,EAAK,EAAE,aAAY,GAAI;AAAA,SACjE,CAAA,CACA,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAGjB,QAAA,MAAM,QAAA,CACH,IAAA,CAAK,cAAc,CAAA,CACnB,MAAA,CAAO;AAAA,UACN,eAAe,OAAA,CAAQ,EAAA;AAAA,UACvB,aAAA,EAAe,WAAA;AAAA;AAAA,UACf,WAAA,EAAa,cAAc,cAAA,CAAe,OAAA,CAAQ,KAAK,GAAG,CAAC,MAAM,OAAO,CAAA,CAAA;AAAA,UACxE,gBAAA,EAAA,CAAmB,oBAAoB,CAAA,IAAK,EAAA;AAAA,UAC5C,oBAAoB,OAAA,KAAY,SAAA,GAAY,CAAA,GAAI,OAAA,KAAY,oBAAoB,CAAA,GAAI,CAAA;AAAA,UACpF,SAAA,EAAW;AAAA,SACZ,CAAA;AAGH,QAAA,MAAM,gBAAA,GAAmB,IAAI,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AACpD,QAAA,MAAM,mBAAA,GAAsB,KAAK,KAAA,CAAA,CAAO,YAAA,CAAa,SAAQ,GAAI,gBAAA,CAAiB,OAAA,EAAQ,IAAK,GAAK,CAAA;AACpG,QAAA,MAAM,gBAAA,GAAmB,QAAQ,wBAAA,IAA4B,EAAA;AAC7D,QAAA,MAAM,iBAAA,GAAoB,mBAAA,GAAsB,CAAA,GAAK,mBAAA,GAAsB,gBAAA,GAAoB,CAAA;AAG/F,QAAA,MAAM,QAAA,CACH,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA,UACN,gBAAA,EAAkB,iBAAA,CAAkB,OAAA,CAAQ,CAAC,CAAA;AAAA,UAC7C,mBAAA,EAAqB;AAAA,SACtB,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,QAAQ,EAAE,CAAA;AAEtB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,mBAAA,EACe,WAAW,CAAA;AAAA,kBAAA,EACZ,cAAA,CAAe,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAC;AAAA,gBAAA,EAChC,OAAO;AAAA,EAClB,gBAAA,GAAmB,4BAAkB,gBAAgB,CAAA;AAAA,CAAA,GAAe,EAAE,CAAA;AAAA,sBAAA,EAErD,mBAAmB,CAAA;AAAA,qBAAA,EACpB,gBAAgB,CAAA;AAAA,sBAAA,EACf,iBAAA,GAAoB,CAAA,GAAI,YAAA,GAAQ,iBAAA,GAAoB,GAAA,GAAM,eAAA,GAAQ,eAAK,CAAA,EAAA,CAAI,iBAAA,GAAoB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;;AAAA,4DAAA;AAAA,WAEzI;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,qBAAA,EAAuB;AAC1B,QAAA,MAAM,EAAE,aAAa,iBAAA,GAAoB,IAAA,EAAM,sBAAsB,IAAA,EAAM,sBAAA,GAAyB,OAAM,GAAIA,KAAAA;AAG9G,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGtD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa,GAAI,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CASP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAE9E,QAAA,IAAI,YAAA,IAAgB,CAAC,OAAA,EAAS;AAC5B,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,WAAW,CAAA,CAAE,CAAA;AAAA,QACrD;AAEA,QAAA,IAAI,OAAA,GAAe;AAAA,UACjB,SAAA,EAAW,WAAA;AAAA,UACX,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,cAAc,OAAA,CAAQ,wBAAA;AAAA,UACtB,YAAY,OAAA,CAAQ,mBAAA;AAAA,UACpB,YAAY,OAAA,CAAQ,gBAAA;AAAA,UACpB,WAAW,OAAA,CAAQ;AAAA,SACrB;AAGA,QAAA,IAAI,iBAAA,EAAmB;AACrB,UAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,MAAM,SAC5B,IAAA,CAAK,SAAS,CAAA,CACd,MAAA,CAAO,+DAA+D,CAAA,CACtE,EAAA,CAAG,MAAM,OAAA,CAAQ,SAAS,EAC1B,MAAA,EAAO;AAEV,UAAA,OAAA,CAAQ,UAAA,GAAa,MAAA;AAAA,QACvB;AAGA,QAAA,IAAI,mBAAA,EAAqB;AACvB,UAAA,MAAM,EAAE,IAAA,EAAM,KAAA,KAAU,MAAM,QAAA,CAC3B,KAAK,UAAU,CAAA,CACf,MAAA,CAAO,wDAAwD,EAC/D,EAAA,CAAG,eAAA,EAAiB,QAAQ,EAAE,CAAA,CAC9B,MAAM,gBAAgB,CAAA;AAEzB,UAAA,OAAA,CAAQ,KAAA,GAAQ,SAAS,EAAC;AAC1B,UAAA,OAAA,CAAQ,YAAA,GAAe;AAAA,YACrB,KAAA,EAAO,OAAO,MAAA,IAAU,CAAA;AAAA,YACxB,SAAA,EAAW,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,MAAA,KAAW,WAAW,EAAE,MAAA,IAAU,CAAA;AAAA,YAClE,UAAA,EAAY,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,MAAA,KAAW,aAAa,EAAE,MAAA,IAAU;AAAA,WACvE;AAAA,QACF;AAGA,QAAA,IAAI,sBAAA,EAAwB;AAC1B,UAAA,MAAM,EAAE,IAAA,EAAM,SAAA,KAAc,MAAM,QAAA,CAC/B,KAAK,mBAAmB,CAAA,CACxB,MAAA,CAAO,2DAA2D,EAClE,EAAA,CAAG,eAAA,EAAiB,QAAQ,EAAE,CAAA,CAC9B,MAAM,YAAY,CAAA;AAErB,UAAA,OAAA,CAAQ,eAAA,GAAkB,aAAa,EAAC;AAAA,QAC1C;AAEA,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,SAAA,EACY,WAAW;AAAA,QAAA,EACZ,QAAQ,MAAM;AAAA,EACtB,OAAA,CAAQ,aAAa,CAAA,QAAA,EAAW,OAAA,CAAQ,WAAW,aAAa,CAAA,GAAA,EAAM,OAAA,CAAQ,UAAA,CAAW,KAAK;AAAA,CAAA,GAAO,EAAE,CAAA,EACvG,OAAA,CAAQ,YAAA,GAAe,CAAA,eAAA,EAAkB,OAAA,CAAQ,YAAA,CAAa,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,YAAA,CAAa,KAAK,CAAA;AAAA,CAAA,GAAiB,EAAE,CAAA,EACxH,OAAA,CAAQ,kBAAkB,CAAA,YAAA,EAAe,OAAA,CAAQ,gBAAgB,MAAM;AAAA,CAAA,GAAO,EAAE;AAAA,2DAAA;AAAA,WAE1F;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,oBAAA,EAAsB;AACzB,QAAA,MAAM,EAAE,WAAA,EAAa,KAAA,EAAO,UAAA,GAAa,MAAK,GAAIA,KAAAA;AAGlD,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGtD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,KAAiB,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,IAAI,EACX,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAC9E,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAGA,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,MAAM,QAAA,CACH,KAAK,UAAU,CAAA,CACf,QAAO,CACP,EAAA,CAAG,eAAA,EAAiB,OAAA,CAAQ,EAAE,CAAA;AAAA,QACnC;AAEA,QAAA,IAAI,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAE7B,UAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,UAAA,IAAI,CAAC,UAAA,EAAY;AACf,YAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAQ,GAAI,MAAM,QAAA,CAC7B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,gBAAgB,CAAA,CACvB,EAAA,CAAG,eAAA,EAAiB,OAAA,CAAQ,EAAE,CAAA,CAC9B,KAAA,CAAM,gBAAA,EAAkB,EAAE,SAAA,EAAW,KAAA,EAAO,CAAA,CAC5C,KAAA,CAAM,CAAC,CAAA,CACP,MAAA,EAAO;AACV,YAAA,aAAA,GAAA,CAAiB,OAAA,EAAS,kBAAkB,CAAA,IAAK,CAAA;AAAA,UACnD;AAEA,UAAA,MAAM,WAAA,GAAc,KAAA,CAAM,GAAA,CAAI,CAAC,MAAW,KAAA,MAAmB;AAAA,YAC3D,eAAe,OAAA,CAAQ,EAAA;AAAA,YACvB,SAAS,IAAA,CAAK,OAAA;AAAA,YACd,QAAQ,IAAA,CAAK,MAAA;AAAA,YACb,cAAA,EAAgB,KAAK,MAAA,IAAU,IAAA;AAAA,YAC/B,iBAAA,EAAmB,KAAK,gBAAA,IAAoB,IAAA;AAAA,YAC5C,gBAAgB,aAAA,GAAgB;AAAA,WAClC,CAAE,CAAA;AAEF,UAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAY,GAAI,MAAM,SAClC,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,WAAW,CAAA;AAErB,UAAA,IAAI,aAAa,MAAM,WAAA;AAAA,QACzB;AAEA,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA,eAAA,EAAa,UAAA,GAAa,QAAA,GAAW,OAAO,CAAA;;AAAA,SAAA,EAChC,WAAW;AAAA,EACpB,aAAa,QAAA,GAAW,OAAO,CAAA,CAAA,EAAI,KAAA,EAAO,UAAU,CAAC,CAAA;AAAA,EACrD,UAAA,GAAa,KAAK,sCAAiC;AAAA,gEAAA;AAAA,WAE7D;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,qBAAA,EAAuB;AAC1B,QAAA,MAAM,EAAE,WAAA,EAAa,QAAA,EAAU,cAAA,EAAe,GAAIA,KAAAA;AAGlD,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGtD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,KAAiB,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,IAAI,EACX,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAC9E,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAEA,QAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAEnC,UAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAQ,GAAI,MAAM,QAAA,CAC7B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,gBAAgB,CAAA,CACvB,EAAA,CAAG,eAAA,EAAiB,OAAA,CAAQ,EAAE,CAAA,CAC9B,KAAA,CAAM,gBAAA,EAAkB,EAAE,SAAA,EAAW,KAAA,EAAO,CAAA,CAC5C,KAAA,CAAM,CAAC,CAAA,CACP,MAAA,EAAO;AACV,UAAA,MAAM,aAAA,GAAA,CAAiB,OAAA,EAAS,cAAA,IAAkB,CAAA,IAAK,CAAA;AAEvD,UAAA,MAAM,WAAA,GAAc,QAAA,CAAS,GAAA,CAAI,CAAC,MAAW,KAAA,MAAmB;AAAA,YAC9D,eAAe,OAAA,CAAQ,EAAA;AAAA,YACvB,OAAA,EAAS,CAAA,YAAA,EAAe,IAAA,CAAK,OAAO,CAAA,CAAA;AAAA,YACpC,MAAA,EAAQ,KAAK,MAAA,IAAU,SAAA;AAAA,YACvB,iBAAA,EAAmB,KAAK,gBAAA,IAAoB,IAAA;AAAA,YAC5C,gBAAgB,aAAA,GAAgB;AAAA,WAClC,CAAE,CAAA;AAEF,UAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAY,GAAI,MAAM,SAClC,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,WAAW,CAAA;AAErB,UAAA,IAAI,aAAa,MAAM,WAAA;AAAA,QACzB;AAEA,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,SAAA,EACY,WAAW;AAAA,MAAA,EACd,QAAA,EAAU,UAAU,CAAC,CAAA;AAAA,EAC3B,cAAA,GAAiB,WAAW,cAAc;AAAA,CAAA,GAAO,EAAE;AAAA,8DAAA;AAAA,WAE7D;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,uBAAA,EAAyB;AAC5B,QAAA,MAAM,EAAE,WAAA,EAAa,MAAA,EAAQ,iBAAA,EAAmB,iBAAgB,GAAIA,KAAAA;AAGpE,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAItD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,SAAA,KAAc,MAAM,QAAA,CACnD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,IAAI,EACX,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,SAAA,CAAU,OAAO,CAAA,CAAE,CAAA;AAAA,QACxD;AAEA,QAAA,MAAM,YAAA,GAAe,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AACnF,QAAA,IAAI,CAAC,YAAA,EAAc;AACjB,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAGA,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA,UACN,MAAA;AAAA,UACA,qBAAqB,iBAAA,IAAqB,IAAA;AAAA,UAC1C,cAAc,MAAA,KAAW,WAAA,GAAA,qBAAkB,IAAA,EAAK,EAAE,aAAY,GAAI;AAAA,SACnE,EACA,EAAA,CAAG,IAAA,EAAM,aAAa,EAAE,CAAA,CACxB,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,SAAA,EACY,WAAW;AAAA,QAAA,EACZ,MAAM;AAAA,EACd,iBAAA,GAAoB,gBAAgB,iBAAiB,CAAA;AAAA,CAAA,GAAe,EAAE,CAAA,EACtE,MAAA,KAAW,WAAA,GAAc,CAAA;AAAA,CAAA,GAAwC,EAAE,CAAA,EACnE,eAAA,GAAkB,CAAA,OAAA,EAAU,eAAe;AAAA,CAAA,GAAO,EAAE,CAAA;AAAA,WAC9D;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,wBAAA,EAA0B;AAC7B,QAAA,MAAM,EAAE,aAAa,gBAAA,GAAmB,IAAA,EAAM,qBAAqB,IAAA,EAAM,YAAA,GAAe,MAAK,GAAIA,KAAAA;AAGjG,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAItD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa,GAAI,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAUP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAC9E,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAGA,QAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAO,WAAA,EAAY,GAAI,MAAM,QAAA,CAChD,IAAA,CAAK,SAAS,CAAA,CACd,MAAA,CAAO,mDAAmD,CAAA,CAC1D,EAAA,CAAG,MAAM,OAAA,CAAQ,SAAS,EAC1B,MAAA,EAAO;AAEV,QAAA,IAAI,WAAA,IAAe,CAAC,MAAA,EAAQ;AAC1B,UAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,QAChD;AAEA,QAAA,IAAI,WAAA,GAAmB;AAAA,UACrB,OAAA,EAAS;AAAA,YACP,EAAA,EAAI,WAAA;AAAA,YACJ,QAAQ,OAAA,CAAQ,MAAA;AAAA,YAChB,YAAY,OAAA,CAAQ,gBAAA;AAAA,YACpB,WAAW,OAAA,CAAQ,UAAA;AAAA,YACnB,aAAa,OAAA,CAAQ;AAAA,WACvB;AAAA,UACA,MAAA,EAAQ;AAAA,YACN,QAAQ,MAAA,CAAO,aAAA;AAAA,YACf,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,aAAa,MAAA,CAAO,WAAA;AAAA,YACpB,MAAM,MAAA,CAAO,IAAA;AAAA,YACb,UAAU,MAAA,CAAO;AAAA;AACnB,SACF;AAGA,QAAA,IAAI,kBAAA,EAAoB;AACtB,UAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,wBAAA,IAA4B,OAAA,CAAQ,mBAAA,GAC1D,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,CAAQ,wBAAA,GAA2B,OAAA,CAAQ,mBAAmB,CAAA,GAC1E,IAAA;AAEJ,UAAA,WAAA,CAAY,WAAA,GAAc;AAAA,YACxB,kBAAkB,OAAA,CAAQ,wBAAA;AAAA,YAC1B,eAAe,OAAA,CAAQ,mBAAA;AAAA,YACvB,SAAA;AAAA,YACA,YAAY,OAAA,CAAQ,gBAAA;AAAA,YACpB,eAAA,EAAiB,QAAQ,YAAA,IAAgB,OAAA,CAAQ,aAC7C,IAAA,CAAK,KAAA,CAAA,CAAO,IAAI,IAAA,CAAK,OAAA,CAAQ,YAAY,EAAE,OAAA,EAAQ,GAAI,IAAI,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,EAAQ,IAAK,GAAK,CAAA,GACtG;AAAA,WACN;AAAA,QACF;AAGA,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO,kEAAkE,EACzE,EAAA,CAAG,eAAA,EAAiB,QAAQ,EAAE,CAAA,CAC9B,MAAM,YAAA,EAAc,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAE1C,UAAA,WAAA,CAAY,KAAA,GAAQ,SAAS,EAAC;AAAA,QAChC;AAGA,QAAA,IAAI,gBAAA,EAAkB;AACpB,UAAA,MAAM,EAAE,MAAM,SAAA,EAAU,GAAI,MAAM,QAAA,CAC/B,IAAA,CAAK,mBAAmB,CAAA,CACxB,MAAA,CAAO,2DAA2D,EAClE,EAAA,CAAG,eAAA,EAAiB,QAAQ,EAAE,CAAA,CAC9B,MAAM,YAAA,EAAc,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAE1C,UAAA,WAAA,CAAY,SAAA,GAAY,aAAa,EAAC;AAAA,QACxC;AAEA,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,sBAAA,EACkB,MAAA,CAAO,aAAa,CAAA,GAAA,EAAM,MAAA,CAAO,KAAK;AAAA,uBAAA,EACrC,WAAW,CAAA,EAAA,EAAK,OAAA,CAAQ,MAAM,CAAA;AAAA,uBAAA,EACjC,QAAQ,mBAAA,IAAuB,KAAK,CAAA,CAAA,EAAI,OAAA,CAAQ,4BAA4B,KAAK,CAAA;AAAA,qBAAA,EAChF,WAAA,CAAY,KAAA,EAAO,MAAA,CAAO,CAAC,MAAW,CAAA,CAAE,MAAA,KAAW,WAAW,CAAA,CAAE,UAAU,CAAC,CAAA,CAAA,EAAI,WAAA,CAAY,KAAA,EAAO,UAAU,CAAC,CAAA;AAAA,0BAAA,EACxG,WAAA,CAAY,SAAA,EAAW,MAAA,IAAU,CAAC;;AAAA;;AAAA;AAAA;AAAA,EAEtB,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,EAAM,CAAC,CAAC,CAAA,MAAA;AAAA,WAC7E;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,wBAAA,EAA0B;AAC7B,QAAA,MAAM,EAAE,WAAA,EAAa,gBAAA,EAAkB,YAAA,GAAe,cAAa,GAAIA,KAAAA;AAGvE,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGtD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,KAAiB,MAAM,QAAA,CACtD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,IAAI,EACX,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAA,CAAa,OAAO,CAAA,CAAE,CAAA;AAAA,QAC3D;AAGA,QAAA,MAAM,OAAA,GAAU,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AAC9E,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAGA,QAAA,MAAM,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,aAAA,EAAc,GAAI,MAAM,QAAA,CACxD,IAAA,CAAK,cAAc,CAAA,CACnB,MAAA,CAAO;AAAA,UACN,eAAe,OAAA,CAAQ,EAAA;AAAA,UACvB,aAAA,EAAe,YAAA;AAAA,UACf,OAAA,EAAS,gBAAA;AAAA,UACT,qBAAA,EAAuB,IAAA;AAAA,UACvB,iBAAA,EAAmB;AAAA;AAAA,SACpB,CAAA,CACA,MAAA,EAAO,CACP,MAAA,EAAO;AAEV,QAAA,IAAI,eAAe,MAAM,aAAA;AAEzB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,CAAA;;AAAA,mBAAA,EACe,WAAW;AAAA,yBAAA,EACL,YAAY;AAAA,kBAAA,EACnB,iBAAiB,MAAM,CAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA,EAGZ,gBAAA,CAAiB,SAAA,CAAU,CAAA,EAAG,GAAG,CAAC,GAAG,gBAAA,CAAiB,MAAA,GAAS,GAAA,GAAM,KAAA,GAAQ,EAAE,CAAA,MAAA;AAAA,WAC/G;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,qBAAA,EAAuB;AAC1B,QAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,gBAAA,EAAkB,iBAAgB,GAAIA,KAAAA;AAG1E,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAGtD,QAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,eAAA,KAAoB,MAAM,QAAA,CACzD,IAAA,CAAK,aAAa,EAClB,MAAA,CAAO,qDAAqD,EAC5D,EAAA,CAAG,SAAA,EAAW,YAAY,MAAM,CAAA;AAEnC,QAAA,IAAI,eAAA,EAAiB;AACnB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,eAAA,CAAgB,OAAO,CAAA,CAAE,CAAA;AAAA,QAC9D;AAGA,QAAA,MAAM,eAAA,GAAkB,WAAA,EAAa,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,QAAA,EAAS,CAAE,UAAA,CAAW,WAAW,CAAC,CAAA;AACtF,QAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,UAAA,MAAM,IAAI,MAAM,CAAA,mBAAA,EAAsB,WAAW,cAAc,WAAA,EAAa,MAAA,IAAU,CAAC,CAAA,UAAA,CAAY,CAAA;AAAA,QACrG;AAGA,QAAA,MAAM,cAAA,uBAAqB,IAAA,EAAK;AAChC,QAAA,MAAM,gBAAA,GAAmB,IAAI,IAAA,CAAK,eAAA,CAAgB,UAAU,CAAA;AAC5D,QAAA,MAAM,gBAAA,GAAmB,KAAK,KAAA,CAAA,CAAO,cAAA,CAAe,SAAQ,GAAI,gBAAA,CAAiB,OAAA,EAAQ,IAAK,GAAK,CAAA;AAGnG,QAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,YAAA,EAAa,GAAI,MAAM,QAAA,CAClD,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO;AAAA,UACN,MAAA,EAAQ,WAAA;AAAA,UACR,mBAAA,EAAqB,gBAAA;AAAA,UACrB,YAAA,EAAc,eAAe,WAAA,EAAY;AAAA,UACzC,gBAAA,EAAkB;AAAA;AAAA,SACnB,CAAA,CACA,EAAA,CAAG,IAAA,EAAM,eAAA,CAAgB,EAAE,CAAA,CAC3B,MAAA,CAAO,qDAAqD,CAAA,CAC5D,MAAA,EAAO;AAEV,QAAA,IAAI,YAAA,IAAgB,CAAC,OAAA,EAAS;AAC5B,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,WAAW,CAAA,CAAE,CAAA;AAAA,QAC5D;AAGA,QAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,wBAAA,GAC3B,gBAAA,GAAmB,QAAQ,wBAAA,GAC5B,CAAA;AAGJ,QAAA,MAAM,SACH,IAAA,CAAK,aAAa,CAAA,CAClB,MAAA,CAAO,EAAE,gBAAA,EAAkB,eAAA,CAAgB,OAAA,CAAQ,CAAC,GAAG,CAAA,CACvD,EAAA,CAAG,IAAA,EAAM,QAAQ,EAAE,CAAA;AAGtB,QAAA,MAAM,kBAAkB,IAAA,CAAK,KAAA;AAAA,UAAA,CAC1B,cAAA,CAAe,SAAQ,GAAI,IAAI,KAAK,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,EAAQ,IAAK;AAAA,SACxE;AAGA,QAAA,MAAM,cAAc,CAAA,UAAA,EAAa,aAAA,CAAc,MAAM,CAAA,kBAAA,EAAqB,aAAA,CAAc,MAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,cAAc,MAAA,GAAS,CAAA,GAAI,cAAc,EAAE,CAAA,CAAA,CAAA;AAE5J,QAAA,IAAI,YAAA,GAAe,CAAA;;AAAA,CAAA;AACnB,QAAA,YAAA,IAAgB,sBAAe,WAAW;AAAA,CAAA;AAC1C,QAAA,YAAA,IAAgB,CAAA;AAAA,CAAA;AAChB,QAAA,YAAA,IAAgB,CAAA,2BAAA,EAAyB,cAAc,MAAM;AAAA,CAAA;AAC7D,QAAA,YAAA,IAAgB,yBAAoB,gBAAgB,CAAA;AAAA,CAAA;AACpD,QAAA,YAAA,IAAgB,CAAA,0BAAA,EAAwB,OAAA,CAAQ,wBAAA,IAA4B,KAAK,CAAA;AAAA,CAAA;AACjF,QAAA,YAAA,IAAgB,CAAA,sBAAA,EAAoB,eAAA,GAAkB,CAAA,GAAI,WAAA,GAAO,eAAA,GAAkB,GAAA,GAAM,cAAA,GAAO,cAAI,CAAA,CAAA,EAAA,CAAK,eAAA,GAAkB,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,CAAA;AAC1I,QAAA,YAAA,IAAgB,+BAA0B,eAAe,CAAA;;AAAA,CAAA;AAEzD,QAAA,YAAA,IAAgB,CAAA;AAAA,CAAA;AAChB,QAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,IAAA,EAAc,KAAA,KAAkB;AACrD,UAAA,YAAA,IAAgB,CAAA,EAAG,KAAA,GAAQ,CAAC,CAAA,EAAA,EAAK,IAAI;AAAA,CAAA;AAAA,QACvC,CAAC,CAAA;AACD,QAAA,YAAA,IAAgB;AAAA,CAAA;AAEhB,QAAA,IAAI,gBAAA,EAAkB;AACpB,UAAA,YAAA,IAAgB,CAAA;AAAA,EAA8B,gBAAgB;;AAAA,CAAA;AAAA,QAChE;AAEA,QAAA,IAAI,eAAA,EAAiB;AACnB,UAAA,YAAA,IAAgB,CAAA;AAAA,EAA6B,eAAe;;AAAA,CAAA;AAAA,QAC9D;AAGA,QAAA,YAAA,IAAgB,CAAA;AAAA,CAAA;AAChB,QAAA,YAAA,IAAgB,CAAA;AAAA,CAAA;AAChB,QAAA,YAAA,IAAgB,CAAA;AAAA,CAAA;AAChB,QAAA,YAAA,IAAgB,CAAA;;AAAA,CAAA;AAEhB,QAAA,YAAA,IAAgB,CAAA,4CAAA,CAAA;AAEhB,QAAA,OAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM;AAAA,WACP;AAAA,SACH;AAAA,MACF;AAAA,MAEA;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,cAAA,EAAiB,IAAI,CAAA,CAAE,CAAA;AAAA;AAC3C,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,gCAA2B,KAAK,CAAA;AAC9C,IAAA,OAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,IAAA,EAAM,MAAA;AAAA,QACN,IAAA,EAAM,mBAAmB,IAAI,CAAA,EAAA,EAAK,iBAAiB,KAAA,GAAQ,KAAA,CAAM,UAAU,eAAe,CAAA;AAAA,OAC3F;AAAA,KACH;AAAA,EACF;AACF,CAAC,CAAA;AAGD,MAAA,CAAO,iBAAA,CAAkB,yBAAA,EAA2B,OAAO,OAAA,KAAY;AACrE,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,GAAA,EAAK,QAAQ,MAAA,CAAO,GAAA;AAAA,QACpB,QAAA,EAAU,YAAA;AAAA,QACV,IAAA,EAAM;AAAA,OACP;AAAA,KACH;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,EAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,4BAAA,EAAwB,GAAG,CAAA,CAAE,CAAA;AAE3C,EAAA,IAAI;AACF,IAAA,QAAQ,GAAA;AAAK,MACX,KAAK,kBAAA,EAAoB;AACvB,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,SAAS,CAAA,CACd,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAOP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,KAAA,CAAM,YAAA,EAAc,EAAE,SAAA,EAAW,KAAA,EAAO,CAAA,CACxC,MAAM,EAAE,CAAA;AAEX,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,UAAU,CAAC;AAAA,YACT,GAAA;AAAA,YACA,QAAA,EAAU,kBAAA;AAAA,YACV,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,MAAM,CAAC;AAAA,WACnC;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,iBAAA,EAAmB;AACtB,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,WAAW,CAAA,CAChB,MAAA,CAAO,sCAAsC,CAAA,CAC7C,EAAA,CAAG,WAAW,WAAA,CAAY,MAAM,EAChC,KAAA,CAAM,MAAM,CAAA,CACZ,KAAA,CAAM,EAAE,CAAA;AAEX,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,UAAU,CAAC;AAAA,YACT,GAAA;AAAA,YACA,QAAA,EAAU,kBAAA;AAAA,YACV,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,MAAM,CAAC;AAAA,WACnC;AAAA,SACH;AAAA,MACF;AAAA,MAEA,KAAK,mBAAA,EAAqB;AACxB,QAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,QAAA,CAC3B,IAAA,CAAK,UAAU,CAAA,CACf,MAAA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,CAOP,CAAA,CACA,EAAA,CAAG,SAAA,EAAW,WAAA,CAAY,MAAM,CAAA,CAChC,EAAA,CAAG,QAAA,EAAU,QAAQ,CAAA,CACrB,KAAA,CAAM,MAAM,CAAA,CACZ,MAAM,EAAE,CAAA;AAEX,QAAA,IAAI,OAAO,MAAM,KAAA;AAEjB,QAAA,OAAO;AAAA,UACL,UAAU,CAAC;AAAA,YACT,GAAA;AAAA,YACA,QAAA,EAAU,kBAAA;AAAA,YACV,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,MAAM,CAAC;AAAA,WACnC;AAAA,SACH;AAAA,MACF;AAAA,MAEA;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,GAAG,CAAA,CAAE,CAAA;AAAA;AAC9C,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA0B,KAAK,CAAA;AAC7C,IAAA,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,GAAA;AAAA,QACA,QAAA,EAAU,YAAA;AAAA,QACV,IAAA,EAAM,iBAAiB,GAAG,CAAA,EAAA,EAAK,iBAAiB,KAAA,GAAQ,KAAA,CAAM,UAAU,eAAe,CAAA;AAAA,OACxF;AAAA,KACH;AAAA,EACF;AACF,CAAC,CAAA;AAGD,eAAe,IAAA,GAAO;AACpB,EAAA,OAAA,CAAQ,MAAM,oDAA6C,CAAA;AAC3D,EAAA,OAAA,CAAQ,MAAM,CAAA,mBAAA,EAAe,MAAA,EAAQ,UAAU,CAAA,EAAG,EAAE,CAAC,CAAA,GAAA,CAAK,CAAA;AAG1D,EAAA,WAAA,GAAc,MAAM,eAAe,MAAO,CAAA;AAC1C,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAA,CAAQ,MAAM,wEAAmE,CAAA;AACjF,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,OAAA,CAAQ,MAAM,CAAA,6BAAA,EAA2B,WAAA,CAAY,MAAM,CAAA,SAAA,EAAY,WAAA,CAAY,MAAM,CAAA,CAAE,CAAA;AAC3F,EAAA,OAAA,CAAQ,MAAM,CAAA,4BAAA,EAAwB,WAAA,CAAY,OAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AACrE,EAAA,OAAA,CAAQ,MAAM,mDAA4C,CAAA;AAE1D,EAAA,MAAM,SAAA,GAAY,IAAI,oBAAA,EAAqB;AAC3C,EAAA,MAAM,MAAA,CAAO,QAAQ,SAAS,CAAA;AAChC;AAGA,OAAA,CAAQ,EAAA,CAAG,UAAU,YAAY;AAC/B,EAAA,OAAA,CAAQ,MAAM,8CAAuC,CAAA;AACrD,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,OAAA,CAAQ,EAAA,CAAG,WAAW,YAAY;AAChC,EAAA,OAAA,CAAQ,MAAM,8CAAuC,CAAA;AACrD,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA;AAGD,IAAA,EAAK,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AACtB,EAAA,OAAA,CAAQ,KAAA,CAAM,0BAAmB,KAAK,CAAA;AACtC,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA","file":"index.js","sourcesContent":["#!/usr/bin/env node\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { createClient } from '@supabase/supabase-js';\nimport { createHash } from 'crypto';\n\n// Parse command line arguments and environment\nconst args = process.argv.slice(2);\nconst apiKey = args.find(arg => arg.startsWith('--api-key='))?.split('=')[1] || process.env.MG_TICKETS_API_KEY;\n// Default to MG Software's Supabase for SaaS customers\nconst supabaseUrl = args.find(arg => arg.startsWith('--supabase-url='))?.split('=')[1] || \n process.env.SUPABASE_URL || \n 'https://cvjdbczxyczjnatuolsk.supabase.co';\n\nconst supabaseKey = args.find(arg => arg.startsWith('--supabase-key='))?.split('=')[1] || \n process.env.SUPABASE_SERVICE_ROLE_KEY || \n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN2amRiY3p4eWN6am5hdHVvbHNrIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc1NjE0NzcyNCwiZXhwIjoyMDcxNzIzNzI0fQ.LljuNdCZXDcSIVTeIVOSNsvGNBfWsIM1QIswBJmGXKE';\n\nif (!apiKey) {\n console.error('ā API key is required. Use --api-key=your_key or set MG_TICKETS_API_KEY environment variable');\n process.exit(1);\n}\n\n// Supabase credentials validation (optional with defaults)\nif (!supabaseUrl || !supabaseKey) {\n console.error('ā Supabase credentials missing. Using defaults for MG Software SaaS.');\n}\n\n// Initialize Supabase client with service role\nconst supabase = createClient(supabaseUrl, supabaseKey);\n\ninterface AuthContext {\n userId: string;\n teamId: string;\n scopes: string[];\n}\n\n// Smart time estimation and codebase analysis is now handled by Cursor AI\n// MCP bridge focuses on data storage and session management only\n\n// API Key validation - direct database access\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\n if (!key.startsWith('mid_') || key.length !== 68) {\n console.error('š Invalid API key format');\n return null;\n }\n\n try {\n // Hash the API key\n const keyHash = createHash('sha256').update(key).digest('hex');\n console.error(`š Validating API key hash: ${keyHash.substring(0, 16)}...`);\n \n // Query database for API key\n const { data: apiKeyData, error } = await supabase\n .from('api_keys')\n .select('id, user_id, team_id, scopes, last_used_at')\n .eq('key_hash', keyHash)\n .single();\n\n if (error || !apiKeyData) {\n console.error('ā API key not found or invalid:', error?.message);\n return null;\n }\n\n // Update last used timestamp\n await supabase\n .from('api_keys')\n .update({ last_used_at: new Date().toISOString() })\n .eq('id', apiKeyData.id);\n\n console.error(`ā
API key validated for user ${apiKeyData.user_id} in team ${apiKeyData.team_id}`);\n \n return {\n userId: apiKeyData.user_id,\n teamId: apiKeyData.team_id,\n scopes: apiKeyData.scopes || []\n };\n } catch (error) {\n console.error('š„ API key validation error:', error);\n return null;\n }\n}\n\n// Validate auth context once at startup\nlet authContext: AuthContext | null = null;\n\n// Helper function to check if a file is an image\nfunction isImageFile(mimeType: string): boolean {\n return mimeType.startsWith('image/') && \n ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'].includes(mimeType);\n}\n\n// Helper function to download and convert image to base64\nasync function downloadImageAsBase64(storageKey: string): Promise<string | null> {\n try {\n // Get signed URL for the file (1 hour expiry)\n const { data: urlData, error: urlError } = await supabase.storage\n .from('vault')\n .createSignedUrl(storageKey, 3600);\n \n if (urlError || !urlData?.signedUrl) {\n console.error(`Failed to create signed URL for ${storageKey}:`, urlError);\n return null;\n }\n \n // Download the file\n const response = await fetch(urlData.signedUrl);\n if (!response.ok) {\n console.error(`Failed to download file ${storageKey}: ${response.status}`);\n return null;\n }\n \n // Convert to base64\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n return buffer.toString('base64');\n } catch (error) {\n console.error(`Error downloading image ${storageKey}:`, error);\n return null;\n }\n}\n\n// MCP Server setup\nconst server = new Server(\n {\n name: 'mg-tickets-mcp-bridge',\n version: '2.0.0',\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n }\n);\n\n// Available tools definition\nconst TOOLS = [\n {\n name: 'get-tickets',\n description: 'Get tickets with optional filtering by status, priority, project, customer, or search query',\n inputSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'] },\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\n projectId: { type: 'string' },\n customerId: { type: 'string' },\n q: { type: 'string', description: 'Search query for title or description' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'get-ticket-by-id',\n description: 'Get a specific ticket by its ID, including all attachments, comments, and images. Images from ticket attachments and comment attachments are automatically downloaded and returned as base64-encoded content that can be analyzed by AI.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Ticket ID' }\n },\n required: ['id']\n }\n },\n {\n name: 'create-ticket',\n description: 'Create a new ticket',\n inputSchema: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Ticket title' },\n description: { type: 'string' },\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'], default: 'open' },\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },\n type: { type: 'string', enum: ['task', 'bug', 'feature', 'support', 'question', 'improvement'], default: 'task' },\n projectId: { type: 'string' },\n customerId: { type: 'string' }\n },\n required: ['title']\n }\n },\n {\n name: 'get-customers',\n description: 'Get customers with optional search',\n inputSchema: {\n type: 'object',\n properties: {\n q: { type: 'string', description: 'Search query for customer name or email' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'create-customer',\n description: 'Create a new customer',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Customer name' },\n email: { type: 'string' },\n website: { type: 'string' }\n },\n required: ['name']\n }\n },\n {\n name: 'get-projects',\n description: 'Get projects with optional filtering',\n inputSchema: {\n type: 'object',\n properties: {\n customerId: { type: 'string', description: 'Filter by customer ID' },\n q: { type: 'string', description: 'Search query for project name' },\n pageSize: { type: 'number', default: 20, maximum: 100 }\n },\n required: []\n }\n },\n {\n name: 'create-project',\n description: 'Create a new project',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Project name' },\n description: { type: 'string' },\n customerId: { type: 'string' },\n status: { type: 'string', enum: ['active', 'on_hold', 'completed', 'cancelled'], default: 'active' }\n },\n required: ['name']\n }\n },\n // === NEW AI SESSION TOOLS ===\n {\n name: 'start-ai-session-smart',\n description: 'Start a new AI development session with automatic tracking (time estimate provided by Cursor AI)',\n inputSchema: {\n type: 'object',\n properties: {\n ticketId: { type: 'string' },\n ticketUrl: { type: 'string', description: 'URL to the ticket' },\n cursorSessionId: { type: 'string', description: 'Cursor session identifier' },\n codebaseContext: { \n type: 'array', \n items: { type: 'string' },\n description: 'Relevant files for complexity analysis'\n },\n aiTimeEstimateMinutes: { \n type: 'number', \n description: 'AI estimate in minutes without AI assistance' \n },\n complexityScore: {\n type: 'number',\n minimum: 1,\n maximum: 10,\n description: 'Estimated complexity from 1-10'\n }\n },\n required: ['ticketId', 'aiTimeEstimateMinutes']\n }\n },\n {\n name: 'track-manual-follow-up',\n description: 'Track manual follow-up prompt by developer',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n originalPrompt: { type: 'string' },\n aiResponse: { type: 'string' },\n developerFollowUp: { type: 'string' },\n followUpReason: { \n type: 'string', \n enum: ['incomplete_result', 'wrong_approach', 'needs_clarification', 'error_in_code']\n },\n outcome: {\n type: 'string',\n enum: ['success', 'partial_success', 'still_failed'],\n default: 'success'\n },\n timeSpentMinutes: { type: 'number' }\n },\n required: ['aiSessionId', 'originalPrompt', 'aiResponse', 'developerFollowUp', 'followUpReason']\n }\n },\n {\n name: 'get-session-context',\n description: 'Get current session context for follow-up continuity',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n includeTicketData: { type: 'boolean', default: true },\n includeTodoProgress: { type: 'boolean', default: true },\n includeFollowUpHistory: { type: 'boolean', default: false }\n },\n required: ['aiSessionId']\n }\n },\n {\n name: 'sync-session-todos',\n description: 'Synchronize todo list with AI session (replace existing) or add new todos',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n todos: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n todoId: { type: 'string', description: 'Optional external todo ID for tracking' },\n content: { type: 'string' },\n status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'] },\n estimatedMinutes: { type: 'number' }\n },\n required: ['content', 'status']\n }\n },\n replaceAll: { \n type: 'boolean', \n default: true, \n description: 'If true, replace all existing todos. If false, add new todos to existing ones' \n }\n },\n required: ['aiSessionId', 'todos']\n }\n },\n {\n name: 'add-follow-up-todos',\n description: 'Add new todos from follow-up (without replacing existing ones)',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n newTodos: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n status: { type: 'string', enum: ['pending', 'in_progress'], default: 'pending' },\n estimatedMinutes: { type: 'number' },\n addedInFollowUp: { type: 'boolean', default: true }\n },\n required: ['content']\n }\n },\n followUpReason: { \n type: 'string', \n description: 'Why were these todos added in follow-up' \n }\n },\n required: ['aiSessionId', 'newTodos']\n }\n },\n {\n name: 'update-session-status',\n description: 'Update AI session status and completion info',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n status: {\n type: 'string',\n enum: ['started', 'in_progress', 'paused', 'completed', 'failed']\n },\n actualTimeMinutes: { type: 'number' },\n completionNotes: { type: 'string' }\n },\n required: ['aiSessionId', 'status']\n }\n },\n {\n name: 'get-completion-context',\n description: 'Get all context needed for Cursor AI to generate customer response',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n includeFollowUps: { type: 'boolean', default: true },\n includeTimeMetrics: { type: 'boolean', default: true },\n includeTodos: { type: 'boolean', default: true }\n },\n required: ['aiSessionId']\n }\n },\n {\n name: 'save-customer-response',\n description: 'Save customer response generated by Cursor AI',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n customerResponse: { type: 'string', description: 'Customer response generated by Cursor AI' },\n responseType: { \n type: 'string', \n enum: ['completion', 'progress_update', 'needs_clarification'],\n default: 'completion'\n }\n },\n required: ['aiSessionId', 'customerResponse']\n }\n },\n {\n name: 'complete-ai-session',\n description: 'Complete AI session with work summary - time calculated automatically',\n inputSchema: {\n type: 'object',\n properties: {\n aiSessionId: { type: 'string' },\n workCompleted: {\n type: 'array',\n items: { type: 'string' },\n description: 'List of completed tasks/todos in English'\n },\n technicalSummary: {\n type: 'string',\n description: 'Technical summary of work done in English'\n },\n efficiencyNotes: { type: 'string' }\n },\n required: ['aiSessionId', 'workCompleted']\n }\n }\n];\n\n// Available resources\nconst RESOURCES = [\n {\n uri: 'tickets://recent',\n name: 'Recent Tickets',\n description: 'Most recently created tickets',\n mimeType: 'application/json'\n },\n {\n uri: 'customers://all',\n name: 'All Customers', \n description: 'Complete customer directory',\n mimeType: 'application/json'\n },\n {\n uri: 'projects://active',\n name: 'Active Projects',\n description: 'Currently active projects',\n mimeType: 'application/json'\n }\n];\n\n// List tools handler\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n});\n\n// List resources handler\nserver.setRequestHandler(ListResourcesRequestSchema, async () => {\n return { resources: RESOURCES };\n});\n\n// Tool execution handler\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (!authContext) {\n return {\n content: [{ type: 'text', text: 'Error: Not authenticated. API key validation failed.' }],\n };\n }\n\n const { name, arguments: args } = request.params;\n console.error(`š ļø Executing tool: ${name} for team ${authContext.teamId}`);\n \n try {\n switch (name) {\n case 'get-tickets': {\n const { status, priority, projectId, customerId, q, pageSize = 20 } = args as any;\n \n let query = supabase\n .from('tickets')\n .select(`\n id,\n ticket_number,\n title,\n description,\n status,\n priority,\n type,\n created_at,\n project_id,\n customer_id,\n projects:project_id(id, name),\n customers:customer_id(id, name)\n `)\n .eq('team_id', authContext.teamId)\n .limit(Math.min(pageSize, 100));\n \n if (status) query = query.eq('status', status);\n if (priority) query = query.eq('priority', priority);\n if (projectId) query = query.eq('project_id', projectId);\n if (customerId) query = query.eq('customer_id', customerId);\n if (q) query = query.or(`title.ilike.%${q}%,description.ilike.%${q}%`);\n \n const { data, error } = await query.order('created_at', { ascending: false });\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} tickets:\\n\\n${data?.map(ticket => \n `**${ticket.ticket_number}**: ${ticket.title}\\n` +\n `Status: ${ticket.status} | Priority: ${ticket.priority}\\n` +\n `${(ticket.projects as any)?.name ? `Project: ${(ticket.projects as any).name}\\n` : ''}` +\n `${(ticket.customers as any)?.name ? `Customer: ${(ticket.customers as any).name}\\n` : ''}` +\n `Created: ${new Date(ticket.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No tickets found.'}`\n }]\n };\n }\n \n case 'get-ticket-by-id': {\n const { id } = args as any;\n \n // Get ticket data\n const { data, error } = await supabase\n .from('tickets')\n .select(`\n *,\n projects:project_id(id, name),\n customers:customer_id(id, name),\n assignee:assignee_id(id, full_name, email),\n requester:requester_id(id, full_name, email)\n `)\n .eq('id', id)\n .eq('team_id', authContext.teamId)\n .single();\n \n if (error) throw error;\n \n // Get ticket attachments\n const { data: attachments, error: attachmentsError } = await supabase\n .from('ticket_attachments')\n .select(`\n id,\n file_name,\n file_size,\n mime_type,\n storage_key,\n created_at,\n users:user_id(id, full_name)\n `)\n .eq('ticket_id', id)\n .eq('team_id', authContext.teamId)\n .order('created_at', { ascending: true });\n \n if (attachmentsError) {\n console.error('Error fetching attachments:', attachmentsError);\n }\n \n // Get ticket comments\n const { data: comments, error: commentsError } = await supabase\n .from('ticket_comments')\n .select(`\n id,\n content,\n created_at,\n users:user_id(id, full_name)\n `)\n .eq('ticket_id', id)\n .order('created_at', { ascending: true });\n \n if (commentsError) {\n console.error('Error fetching comments:', commentsError);\n }\n \n // Get comment attachments\n const commentIds = comments?.map(c => c.id) || [];\n let commentAttachments: any[] = [];\n \n if (commentIds.length > 0) {\n const { data: commAttachments, error: commAttachmentsError } = await supabase\n .from('ticket_comment_attachments')\n .select(`\n id,\n comment_id,\n file_name,\n file_size,\n mime_type,\n storage_key,\n created_at\n `)\n .in('comment_id', commentIds)\n .eq('team_id', authContext.teamId);\n \n if (commAttachmentsError) {\n console.error('Error fetching comment attachments:', commAttachmentsError);\n } else {\n commentAttachments = commAttachments || [];\n }\n }\n \n // Build content array starting with text\n const content: any[] = [{\n type: 'text',\n text: `**Ticket Details:**\\n\\n` +\n `**${data.ticket_number}**: ${data.title}\\n` +\n `Status: ${data.status}\\n` +\n `Priority: ${data.priority}\\n` +\n `Type: ${data.type}\\n` +\n `${data.description ? `Description: ${data.description}\\n` : ''}` +\n `${(data.projects as any)?.name ? `Project: ${(data.projects as any).name}\\n` : ''}` +\n `${(data.customers as any)?.name ? `Customer: ${(data.customers as any).name}\\n` : ''}` +\n `${data.assignee?.full_name ? `Assignee: ${data.assignee.full_name}\\n` : ''}` +\n `Requester: ${data.requester?.full_name || 'Unknown'}\\n` +\n `Created: ${new Date(data.created_at).toLocaleDateString()}\\n` +\n `${attachments && attachments.length > 0 ? `\\nš Attachments: ${attachments.length}\\n` : ''}` +\n `${comments && comments.length > 0 ? `š¬ Comments: ${comments.length}\\n` : ''}`\n }];\n \n // Process ticket attachments - download images\n if (attachments && attachments.length > 0) {\n console.error(`š Processing ${attachments.length} ticket attachments...`);\n \n for (const attachment of attachments) {\n if (isImageFile(attachment.mime_type)) {\n console.error(`š¼ļø Downloading image: ${attachment.file_name}`);\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\n \n if (base64Data) {\n content.push({\n type: 'image',\n data: base64Data,\n mimeType: attachment.mime_type\n });\n \n // Add text context about the image\n content.push({\n type: 'text',\n text: `\\nšø **Image from ticket**: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB, uploaded by ${(attachment.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()})\\n`\n });\n }\n }\n }\n }\n \n // Process comment attachments - download images\n if (commentAttachments.length > 0) {\n console.error(`š Processing ${commentAttachments.length} comment attachments...`);\n \n for (const attachment of commentAttachments) {\n if (isImageFile(attachment.mime_type)) {\n console.error(`š¼ļø Downloading comment image: ${attachment.file_name}`);\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\n \n if (base64Data) {\n // Find the comment this attachment belongs to\n const comment = comments?.find(c => c.id === attachment.comment_id);\n \n content.push({\n type: 'image',\n data: base64Data,\n mimeType: attachment.mime_type\n });\n \n // Add text context about the image\n content.push({\n type: 'text',\n text: `\\nšø **Image from comment** by ${(comment?.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()}: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB)\\n` +\n (comment?.content ? `Comment text: \"${comment.content.substring(0, 100)}${comment.content.length > 100 ? '...' : ''}\"\\n` : '')\n });\n }\n }\n }\n }\n \n console.error(`ā
Returning ticket with ${content.filter(c => c.type === 'image').length} images`);\n \n return { content };\n }\n \n case 'create-ticket': {\n const { title, description, status = 'open', priority = 'medium', type = 'task', projectId, customerId } = args as any;\n \n // Generate ticket number\n const year = new Date().getFullYear();\n const { count } = await supabase\n .from('tickets')\n .select('*', { count: 'exact', head: true })\n .eq('team_id', authContext.teamId);\n \n const ticketNumber = `${year}-${String((count || 0) + 1).padStart(3, '0')}`;\n \n const { data, error } = await supabase\n .from('tickets')\n .insert({\n team_id: authContext.teamId,\n ticket_number: ticketNumber,\n title,\n description,\n status,\n priority,\n type,\n project_id: projectId || null,\n customer_id: customerId || null,\n requester_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `ā
**Ticket Created Successfully!**\\n\\n` +\n `Ticket Number: **${ticketNumber}**\\n` +\n `Title: ${title}\\n` +\n `Status: ${status}\\n` +\n `Priority: ${priority}\\n` +\n `Type: ${type}\\n`\n }]\n };\n }\n \n case 'get-customers': {\n const { q, pageSize = 20 } = args as any;\n \n let query = supabase\n .from('customers')\n .select('id, name, email, website, created_at')\n .eq('team_id', authContext.teamId)\n .limit(Math.min(pageSize, 100));\n \n if (q) query = query.or(`name.ilike.%${q}%,email.ilike.%${q}%`);\n \n const { data, error } = await query.order('name');\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} customers:\\n\\n${data?.map(customer => \n `**${customer.name}**\\n` +\n `${customer.email ? `Email: ${customer.email}\\n` : ''}` +\n `${customer.website ? `Website: ${customer.website}\\n` : ''}` +\n `Created: ${new Date(customer.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No customers found.'}`\n }]\n };\n }\n \n case 'create-customer': {\n const { name, email, website } = args as any;\n \n const { data, error } = await supabase\n .from('customers')\n .insert({\n team_id: authContext.teamId,\n name,\n email: email || null,\n website: website || null,\n user_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `ā
**Customer Created Successfully!**\\n\\n` +\n `Name: ${name}\\n` +\n `${email ? `Email: ${email}\\n` : ''}` +\n `${website ? `Website: ${website}\\n` : ''}`\n }]\n };\n }\n \n case 'get-projects': {\n const { customerId, q, pageSize = 20 } = args as any;\n \n let query = supabase\n .from('projects')\n .select(`\n id,\n name,\n description,\n customer_id,\n status,\n created_at,\n customers:customer_id(id, name)\n `)\n .eq('team_id', authContext.teamId)\n .limit(Math.min(pageSize, 100));\n \n if (customerId) query = query.eq('customer_id', customerId);\n if (q) query = query.ilike('name', `%${q}%`);\n \n const { data, error } = await query.order('name');\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `Found ${data?.length || 0} projects:\\n\\n${data?.map(project => \n `**${project.name}**\\n` +\n `Status: ${project.status}\\n` +\n `${project.description ? `Description: ${project.description}\\n` : ''}` +\n `${(project.customers as any)?.name ? `Customer: ${(project.customers as any).name}\\n` : ''}` +\n `Created: ${new Date(project.created_at).toLocaleDateString()}\\n`\n ).join('\\n') || 'No projects found.'}`\n }]\n };\n }\n \n case 'create-project': {\n const { name, description, customerId, status = 'active' } = args as any;\n \n const { data, error } = await supabase\n .from('projects')\n .insert({\n team_id: authContext.teamId,\n name,\n description: description || null,\n customer_id: customerId || null,\n status,\n user_id: authContext.userId\n })\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `ā
**Project Created Successfully!**\\n\\n` +\n `Name: ${name}\\n` +\n `Status: ${status}\\n` +\n `${description ? `Description: ${description}\\n` : ''}`\n }]\n };\n }\n \n // === AI SESSION TOOLS ===\n case 'start-ai-session-smart': {\n const { ticketId, ticketUrl, cursorSessionId, codebaseContext, aiTimeEstimateMinutes, complexityScore } = args as any;\n \n // Store the time estimate as provided by Cursor AI (already smart-adjusted)\n const sessionStartTime = new Date();\n const { data: sessionData, error } = await supabase\n .from('ai_sessions')\n .insert({\n ticket_id: ticketId,\n provider_user_id: authContext.userId,\n team_id: authContext.teamId,\n cursor_session_id: cursorSessionId || null,\n ai_time_estimate_minutes: aiTimeEstimateMinutes, // Use Cursor's smart estimate\n complexity_score: complexityScore || null,\n status: 'in_progress' // Start actively tracking time\n })\n .select('id, ticket_id, cursor_session_id, created_at')\n .single();\n \n if (error) throw error;\n \n // START TIME TRACKING: Log session start\n await supabase\n .from('ai_time_logs')\n .insert({\n ai_session_id: sessionData.id,\n activity_type: 'thinking',\n description: 'AI session started - analysis and planning phase',\n duration_seconds: 0,\n productivity_score: 8,\n logged_at: sessionStartTime\n });\n \n // Generate a readable session ID for UI\n const sessionId = `ai-sess-${sessionData.id.substring(0, 8)}`;\n \n return {\n content: [{\n type: 'text',\n text: `š **AI Session Started Successfully!**\\n\\n` +\n `š Session ID: **${sessionId}**\\n` +\n `š« Ticket: ${ticketId}\\n` +\n `ā±ļø Time Estimate: ${aiTimeEstimateMinutes} minutes\\n` +\n `${complexityScore ? `šÆ Complexity: ${complexityScore}/10\\n` : ''}` +\n `ā±ļø **Automatic Time Tracking Started**\\n` +\n `${cursorSessionId ? `š Cursor Session: ${cursorSessionId}\\n` : ''}` +\n `š
Started: ${sessionStartTime.toLocaleString()}\\n\\n` +\n `ā
Session initialized - ready for development with smart context!`\n }]\n };\n }\n \n case 'track-manual-follow-up': {\n const { aiSessionId, originalPrompt, aiResponse, developerFollowUp, followUpReason, outcome = 'success', timeSpentMinutes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the full session ID and current session data\n // Find the session - get all sessions for this team and filter in JS\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id, status, created_at, ai_time_estimate_minutes')\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n const followUpTime = new Date();\n \n // RESTART SESSION: Set status back to in_progress for continued tracking\n await supabase\n .from('ai_sessions')\n .update({\n status: 'in_progress', // Restart active tracking\n // Don't update completed_at - session continues\n })\n .eq('id', session.id);\n \n // LOG FOLLOW-UP: Track the manual follow-up interaction\n const { data, error } = await supabase\n .from('manual_follow_ups')\n .insert({\n ai_session_id: session.id,\n developer_id: authContext.userId,\n team_id: authContext.teamId,\n original_prompt: originalPrompt,\n ai_response: aiResponse,\n follow_up_prompt: developerFollowUp,\n follow_up_reason: followUpReason,\n outcome: outcome,\n time_spent_minutes: timeSpentMinutes || null,\n resolved_at: outcome === 'success' ? new Date().toISOString() : null\n })\n .select()\n .single();\n \n if (error) throw error;\n \n // RESTART TIME TRACKING: Log follow-up activity start\n await supabase\n .from('ai_time_logs')\n .insert({\n ai_session_id: session.id,\n activity_type: 'debugging', // Follow-ups are typically debugging/fixing\n description: `Follow-up: ${followUpReason.replace('_', ' ')} - ${outcome}`,\n duration_seconds: (timeSpentMinutes || 0) * 60,\n productivity_score: outcome === 'success' ? 9 : outcome === 'partial_success' ? 6 : 4,\n logged_at: followUpTime\n });\n \n // CALCULATE CURRENT EFFICIENCY: Compare time spent vs estimated\n const sessionStartTime = new Date(session.created_at);\n const totalMinutesElapsed = Math.round((followUpTime.getTime() - sessionStartTime.getTime()) / 60000);\n const estimatedMinutes = session.ai_time_estimate_minutes || 60;\n const currentEfficiency = totalMinutesElapsed > 0 ? (totalMinutesElapsed / estimatedMinutes) : 1;\n \n // UPDATE EFFICIENCY TRACKING: Update running efficiency score\n await supabase\n .from('ai_sessions')\n .update({\n efficiency_score: currentEfficiency.toFixed(2),\n actual_time_minutes: totalMinutesElapsed\n })\n .eq('id', session.id);\n \n return {\n content: [{\n type: 'text',\n text: `š **Follow-up Tracked & Session Restarted!**\\n\\n` +\n `š Session: ${aiSessionId} (back to active)\\n` +\n `š Reason: ${followUpReason.replace('_', ' ')}\\n` +\n `ā
Outcome: ${outcome}\\n` +\n `${timeSpentMinutes ? `ā±ļø Time spent: ${timeSpentMinutes} minutes\\n` : ''}` +\n `š **Current Progress:**\\n` +\n ` ⢠Total time: ${totalMinutesElapsed} minutes\\n` +\n ` ⢠Estimated: ${estimatedMinutes} minutes\\n` +\n ` ⢠Efficiency: ${currentEfficiency < 1 ? 'š ' : currentEfficiency > 1.5 ? 'ā ļø ' : 'ā±ļø '}${(currentEfficiency * 100).toFixed(0)}%\\n` +\n `\\nā” **Time tracking resumed** - continue with confidence!`\n }]\n };\n }\n \n case 'get-session-context': {\n const { aiSessionId, includeTicketData = true, includeTodoProgress = true, includeFollowUpHistory = false } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session data with related info - find by JavaScript filtering\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select(`\n id,\n ticket_id,\n status,\n ai_time_estimate_minutes,\n actual_time_minutes,\n complexity_score,\n created_at,\n cursor_session_id\n `)\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n \n if (sessionError || !session) {\n throw new Error(`Session not found: ${aiSessionId}`);\n }\n \n let context: any = {\n sessionId: aiSessionId,\n status: session.status,\n timeEstimate: session.ai_time_estimate_minutes,\n actualTime: session.actual_time_minutes,\n complexity: session.complexity_score,\n createdAt: session.created_at\n };\n \n // Include ticket data if requested\n if (includeTicketData) {\n const { data: ticket } = await supabase\n .from('tickets')\n .select('id, ticket_number, title, description, status, priority, type')\n .eq('id', session.ticket_id)\n .single();\n \n context.ticketData = ticket;\n }\n \n // Include todo progress if requested\n if (includeTodoProgress) {\n const { data: todos } = await supabase\n .from('ai_todos')\n .select('id, content, status, estimated_minutes, actual_minutes')\n .eq('ai_session_id', session.id)\n .order('sequence_order');\n \n context.todos = todos || [];\n context.todoProgress = {\n total: todos?.length || 0,\n completed: todos?.filter(t => t.status === 'completed').length || 0,\n inProgress: todos?.filter(t => t.status === 'in_progress').length || 0\n };\n }\n \n // Include follow-up history if requested\n if (includeFollowUpHistory) {\n const { data: followUps } = await supabase\n .from('manual_follow_ups')\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\n .eq('ai_session_id', session.id)\n .order('created_at');\n \n context.followUpHistory = followUps || [];\n }\n \n return {\n content: [{\n type: 'text',\n text: `šÆ **Session Context Retrieved**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Status: ${session.status}\\n` +\n `${context.ticketData ? `Ticket: ${context.ticketData.ticket_number} - ${context.ticketData.title}\\n` : ''}` +\n `${context.todoProgress ? `Todo Progress: ${context.todoProgress.completed}/${context.todoProgress.total} completed\\n` : ''}` +\n `${context.followUpHistory ? `Follow-ups: ${context.followUpHistory.length}\\n` : ''}` +\n `\\nš Full context preserved for seamless continuation!`\n }]\n };\n }\n \n case 'sync-session-todos': {\n const { aiSessionId, todos, replaceAll = true } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the session - get all sessions for this team and filter in JS\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // If replacing all, clear existing todos first\n if (replaceAll) {\n await supabase\n .from('ai_todos')\n .delete()\n .eq('ai_session_id', session.id);\n }\n \n if (todos && todos.length > 0) {\n // Get current max sequence order if adding to existing\n let startSequence = 0;\n if (!replaceAll) {\n const { data: maxTodo } = await supabase\n .from('ai_todos')\n .select('sequence_order')\n .eq('ai_session_id', session.id)\n .order('sequence_order', { ascending: false })\n .limit(1)\n .single();\n startSequence = (maxTodo?.sequence_order || 0) + 1;\n }\n \n const todoInserts = todos.map((todo: any, index: number) => ({\n ai_session_id: session.id,\n content: todo.content,\n status: todo.status,\n cursor_todo_id: todo.todoId || null,\n estimated_minutes: todo.estimatedMinutes || null,\n sequence_order: startSequence + index\n }));\n \n const { error: insertError } = await supabase\n .from('ai_todos')\n .insert(todoInserts);\n \n if (insertError) throw insertError;\n }\n \n return {\n content: [{\n type: 'text',\n text: `ā
**Todos ${replaceAll ? 'Synced' : 'Added'} Successfully!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `${replaceAll ? 'Synced' : 'Added'} ${todos?.length || 0} todos\\n` +\n `${replaceAll ? '' : 'ā Added to existing todo list\\n'}` +\n `\\nš Todo list updated and tracked for progress monitoring!`\n }]\n };\n }\n \n case 'add-follow-up-todos': {\n const { aiSessionId, newTodos, followUpReason } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find the session - get all sessions for this team and filter in JS\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n if (newTodos && newTodos.length > 0) {\n // Get current max sequence order\n const { data: maxTodo } = await supabase\n .from('ai_todos')\n .select('sequence_order')\n .eq('ai_session_id', session.id)\n .order('sequence_order', { ascending: false })\n .limit(1)\n .single();\n const startSequence = (maxTodo?.sequence_order || 0) + 1;\n \n const todoInserts = newTodos.map((todo: any, index: number) => ({\n ai_session_id: session.id,\n content: `[Follow-up] ${todo.content}`,\n status: todo.status || 'pending',\n estimated_minutes: todo.estimatedMinutes || null,\n sequence_order: startSequence + index\n }));\n \n const { error: insertError } = await supabase\n .from('ai_todos')\n .insert(todoInserts);\n \n if (insertError) throw insertError;\n }\n \n return {\n content: [{\n type: 'text',\n text: `ā
**Follow-up Todos Added Successfully!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Added ${newTodos?.length || 0} new todos from follow-up\\n` +\n `${followUpReason ? `Reason: ${followUpReason}\\n` : ''}` +\n `\\nš New tasks identified and added to existing workflow!`\n }]\n };\n }\n \n case 'update-session-status': {\n const { aiSessionId, status, actualTimeMinutes, completionNotes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Find and update the session\n // First find the session\n const { data: allSessions, error: findError } = await supabase\n .from('ai_sessions')\n .select('id')\n .eq('team_id', authContext.teamId);\n \n if (findError) {\n throw new Error(`Database error: ${findError.message}`);\n }\n \n const foundSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!foundSession) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Now update the found session\n const { data, error } = await supabase\n .from('ai_sessions')\n .update({\n status: status,\n actual_time_minutes: actualTimeMinutes || null,\n completed_at: status === 'completed' ? new Date().toISOString() : null\n })\n .eq('id', foundSession.id)\n .select()\n .single();\n \n if (error) throw error;\n \n return {\n content: [{\n type: 'text',\n text: `šÆ **Session Status Updated!**\\n\\n` +\n `Session: ${aiSessionId}\\n` +\n `Status: ${status}\\n` +\n `${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes\\n` : ''}` +\n `${status === 'completed' ? `ā
Session completed successfully!\\n` : ''}` +\n `${completionNotes ? `Notes: ${completionNotes}\\n` : ''}`\n }]\n };\n }\n \n case 'get-completion-context': {\n const { aiSessionId, includeFollowUps = true, includeTimeMetrics = true, includeTodos = true } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session data with ticket info\n // Get comprehensive session context - find by JavaScript filtering\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select(`\n id,\n ticket_id,\n ai_time_estimate_minutes,\n actual_time_minutes,\n efficiency_score,\n created_at,\n completed_at,\n status,\n complexity_score\n `)\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Get ticket data\n const { data: ticket, error: ticketError } = await supabase\n .from('tickets')\n .select('ticket_number, title, description, type, priority')\n .eq('id', session.ticket_id)\n .single();\n \n if (ticketError || !ticket) {\n throw new Error('Ticket not found for session');\n }\n \n let contextData: any = {\n session: {\n id: aiSessionId,\n status: session.status,\n complexity: session.complexity_score,\n createdAt: session.created_at,\n completedAt: session.completed_at\n },\n ticket: {\n number: ticket.ticket_number,\n title: ticket.title,\n description: ticket.description,\n type: ticket.type,\n priority: ticket.priority\n }\n };\n \n // Add time metrics if requested\n if (includeTimeMetrics) {\n const timeSaved = session.ai_time_estimate_minutes && session.actual_time_minutes \n ? Math.max(0, session.ai_time_estimate_minutes - session.actual_time_minutes)\n : null;\n \n contextData.timeMetrics = {\n estimatedMinutes: session.ai_time_estimate_minutes,\n actualMinutes: session.actual_time_minutes,\n timeSaved: timeSaved,\n efficiency: session.efficiency_score,\n sessionDuration: session.completed_at && session.created_at \n ? Math.round((new Date(session.completed_at).getTime() - new Date(session.created_at).getTime()) / 60000)\n : null\n };\n }\n \n // Add todos if requested\n if (includeTodos) {\n const { data: todos } = await supabase\n .from('ai_todos')\n .select('content, status, estimated_minutes, actual_minutes, completed_at')\n .eq('ai_session_id', session.id)\n .order('created_at', { ascending: true });\n \n contextData.todos = todos || [];\n }\n \n // Add follow-ups if requested\n if (includeFollowUps) {\n const { data: followUps } = await supabase\n .from('manual_follow_ups')\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\n .eq('ai_session_id', session.id)\n .order('created_at', { ascending: true });\n \n contextData.followUps = followUps || [];\n }\n \n return {\n content: [{\n type: 'text',\n text: `š **Completion Context Retrieved!**\\n\\n` +\n `š« **Ticket:** ${ticket.ticket_number} - ${ticket.title}\\n` +\n `š **Session:** ${aiSessionId} (${session.status})\\n` +\n `ā±ļø **Time:** ${session.actual_time_minutes || 'N/A'}/${session.ai_time_estimate_minutes || 'N/A'} minutes\\n` +\n `š **Todos:** ${contextData.todos?.filter((t: any) => t.status === 'completed').length || 0}/${contextData.todos?.length || 0} completed\\n` +\n `š **Follow-ups:** ${contextData.followUps?.length || 0}\\n\\n` +\n `ā
**Full context ready for Cursor AI to generate customer response!**\\n\\n` +\n `**Context Data:**\\n\\`\\`\\`json\\n${JSON.stringify(contextData, null, 2)}\\`\\`\\``\n }]\n };\n }\n \n case 'save-customer-response': {\n const { aiSessionId, customerResponse, responseType = 'completion' } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session to validate it exists - find by JavaScript filtering\n const { data: allSessions, error: sessionError } = await supabase\n .from('ai_sessions')\n .select('id')\n .eq('team_id', authContext.teamId);\n \n if (sessionError) {\n throw new Error(`Database error: ${sessionError.message}`);\n }\n \n // Find session with matching prefix\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!session) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n \n // Save the response in database\n const { data: responseData, error: responseError } = await supabase\n .from('ai_responses')\n .insert({\n ai_session_id: session.id,\n response_type: responseType,\n content: customerResponse,\n is_ready_for_customer: true,\n provider_approved: false // Needs manual approval\n })\n .select()\n .single();\n \n if (responseError) throw responseError;\n \n return {\n content: [{\n type: 'text',\n text: `š¾ **Customer Response Saved!**\\n\\n` +\n `š Session: ${aiSessionId}\\n` +\n `š Response Type: ${responseType}\\n` +\n `š Length: ${customerResponse.length} characters\\n\\n` +\n `ā
**Response ready for provider approval**\\n` +\n `š Provider can review in AI tab before sending to customer\\n\\n` +\n `**Preview:**\\n\\`\\`\\`\\n${customerResponse.substring(0, 200)}${customerResponse.length > 200 ? '...' : ''}\\`\\`\\``\n }]\n };\n }\n \n case 'complete-ai-session': {\n const { aiSessionId, workCompleted, technicalSummary, efficiencyNotes } = args as any;\n \n // Extract actual session UUID from readable ID\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\n \n // Get session to calculate actual time spent - find by JavaScript filtering\n const { data: allSessions, error: getSessionError } = await supabase\n .from('ai_sessions')\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\n .eq('team_id', authContext.teamId);\n \n if (getSessionError) {\n throw new Error(`Database error: ${getSessionError.message}`);\n }\n \n // Find session with matching prefix\n const existingSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\n if (!existingSession) {\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\n }\n\n // Calculate actual time spent automatically\n const completionTime = new Date();\n const sessionStartTime = new Date(existingSession.created_at);\n const timeSpentMinutes = Math.round((completionTime.getTime() - sessionStartTime.getTime()) / 60000);\n \n // Update session to completed with calculated time\n const { data: session, error: sessionError } = await supabase\n .from('ai_sessions')\n .update({\n status: 'completed',\n actual_time_minutes: timeSpentMinutes,\n completed_at: completionTime.toISOString(),\n efficiency_score: null // Will be calculated\n })\n .eq('id', existingSession.id)\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\n .single();\n \n if (sessionError || !session) {\n throw new Error(`Failed to update session: ${aiSessionId}`);\n }\n \n // Calculate efficiency score\n const efficiencyScore = session.ai_time_estimate_minutes \n ? (timeSpentMinutes / session.ai_time_estimate_minutes)\n : 1.0;\n \n // Update efficiency score\n await supabase\n .from('ai_sessions')\n .update({ efficiency_score: efficiencyScore.toFixed(2) })\n .eq('id', session.id);\n \n // Get session duration\n const sessionDuration = Math.round(\n (completionTime.getTime() - new Date(session.created_at).getTime()) / 60000\n );\n \n // Create work summary\n const workSummary = `Completed ${workCompleted.length} tasks including: ${workCompleted.slice(0, 3).join(', ')}${workCompleted.length > 3 ? ' and more' : ''}.`;\n \n let responseText = `š **AI Session Completed Successfully!**\\n\\n`;\n responseText += `š Session: ${aiSessionId}\\n`;\n responseText += `š **Performance Summary:**\\n`;\n responseText += ` ⢠Tasks Completed: ${workCompleted.length}\\n`;\n responseText += ` ⢠Time Spent: ${timeSpentMinutes} minutes\\n`;\n responseText += ` ⢠Estimated Time: ${session.ai_time_estimate_minutes || 'N/A'} minutes\\n`;\n responseText += ` ⢠Efficiency: ${efficiencyScore < 1 ? 'š' : efficiencyScore > 1.5 ? 'ā ļø' : 'ā±ļø'} ${(efficiencyScore * 100).toFixed(0)}%\\n`;\n responseText += ` ⢠Session Duration: ${sessionDuration} minutes\\n\\n`;\n \n responseText += `ā
**Work Completed:**\\n`;\n workCompleted.forEach((task: string, index: number) => {\n responseText += `${index + 1}. ${task}\\n`;\n });\n responseText += `\\n`;\n \n if (technicalSummary) {\n responseText += `š§ **Technical Summary:**\\n${technicalSummary}\\n\\n`;\n }\n \n if (efficiencyNotes) {\n responseText += `š **Efficiency Notes:**\\n${efficiencyNotes}\\n\\n`;\n }\n \n // Provide context for Cursor AI to generate customer response\n responseText += `š **Context for Customer Response:**\\n`;\n responseText += ` ⢠Use \"get-completion-context\" to retrieve full context\\n`;\n responseText += ` ⢠Generate customer-friendly response based on completed work\\n`;\n responseText += ` ⢠Focus on business value and customer benefits\\n\\n`;\n \n responseText += `šÆ **Session archived successfully!**`;\n \n return {\n content: [{\n type: 'text',\n text: responseText\n }]\n };\n }\n \n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n \n } catch (error) {\n console.error(`ā Tool execution error:`, error);\n return {\n content: [{\n type: 'text',\n text: `Error executing ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`\n }]\n };\n }\n});\n\n// Resource read handler\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n if (!authContext) {\n return {\n contents: [{\n uri: request.params.uri,\n mimeType: 'text/plain',\n text: 'Error: Not authenticated. API key validation failed.'\n }]\n };\n }\n\n const { uri } = request.params;\n console.error(`š Reading resource: ${uri}`);\n \n try {\n switch (uri) {\n case 'tickets://recent': {\n const { data, error } = await supabase\n .from('tickets')\n .select(`\n id,\n ticket_number,\n title,\n status,\n priority,\n created_at\n `)\n .eq('team_id', authContext.teamId)\n .order('created_at', { ascending: false })\n .limit(20);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n case 'customers://all': {\n const { data, error } = await supabase\n .from('customers')\n .select('id, name, email, website, created_at')\n .eq('team_id', authContext.teamId)\n .order('name')\n .limit(50);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n case 'projects://active': {\n const { data, error } = await supabase\n .from('projects')\n .select(`\n id,\n name,\n description,\n status,\n created_at,\n customers:customer_id(id, name)\n `)\n .eq('team_id', authContext.teamId)\n .eq('status', 'active')\n .order('name')\n .limit(50);\n \n if (error) throw error;\n \n return {\n contents: [{\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(data, null, 2)\n }]\n };\n }\n \n default:\n throw new Error(`Unknown resource: ${uri}`);\n }\n \n } catch (error) {\n console.error(`ā Resource read error:`, error);\n return {\n contents: [{\n uri,\n mimeType: 'text/plain',\n text: `Error reading ${uri}: ${error instanceof Error ? error.message : 'Unknown error'}`\n }]\n };\n }\n});\n\n// Main function\nasync function main() {\n console.error('š Starting MG Tickets MCP Bridge Server...');\n console.error(`š API Key: ${apiKey?.substring(0, 10)}...`);\n \n // Validate API key\n authContext = await validateApiKey(apiKey!);\n if (!authContext) {\n console.error('ā API key validation failed. Please check your key and try again.');\n process.exit(1);\n }\n \n console.error(`ā
Authenticated as user ${authContext.userId} in team ${authContext.teamId}`);\n console.error(`š Available scopes: ${authContext.scopes.join(', ')}`);\n console.error('š” MCP Bridge Server ready for connections');\n \n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\n// Handle graceful shutdown\nprocess.on('SIGINT', async () => {\n console.error('š Shutting down MCP Bridge Server...');\n process.exit(0);\n});\n\nprocess.on('SIGTERM', async () => {\n console.error('š Shutting down MCP Bridge Server...');\n process.exit(0);\n});\n\n// Start the server\nmain().catch((error) => {\n console.error('š„ Fatal error:', error);\n process.exit(1);\n});"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["args","name"],"mappings":"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","file":"index.js","sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';\r\nimport { createClient } from '@supabase/supabase-js';\r\nimport { createHash } from 'crypto';\r\n\r\n// Parse command line arguments and environment\r\nconst args = process.argv.slice(2);\r\nconst apiKey = args.find(arg => arg.startsWith('--api-key='))?.split('=')[1] || process.env.MG_TICKETS_API_KEY;\r\n// Default to MG Software's Supabase for SaaS customers\r\nconst supabaseUrl = args.find(arg => arg.startsWith('--supabase-url='))?.split('=')[1] || \r\n process.env.SUPABASE_URL || \r\n 'https://cvjdbczxyczjnatuolsk.supabase.co';\r\n\r\nconst supabaseKey = args.find(arg => arg.startsWith('--supabase-key='))?.split('=')[1] || \r\n process.env.SUPABASE_SERVICE_ROLE_KEY || \r\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImN2amRiY3p4eWN6am5hdHVvbHNrIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc1NjE0NzcyNCwiZXhwIjoyMDcxNzIzNzI0fQ.LljuNdCZXDcSIVTeIVOSNsvGNBfWsIM1QIswBJmGXKE';\r\n\r\nif (!apiKey) {\r\n console.error('ā API key is required. Use --api-key=your_key or set MG_TICKETS_API_KEY environment variable');\r\n process.exit(1);\r\n}\r\n\r\n// Supabase credentials validation (optional with defaults)\r\nif (!supabaseUrl || !supabaseKey) {\r\n console.error('ā Supabase credentials missing. Using defaults for MG Software SaaS.');\r\n}\r\n\r\n// Initialize Supabase client with service role\r\nconst supabase = createClient(supabaseUrl, supabaseKey);\r\n\r\ninterface AuthContext {\r\n userId: string;\r\n teamId: string;\r\n scopes: string[];\r\n}\r\n\r\n// Smart time estimation and codebase analysis is now handled by Cursor AI\r\n// MCP bridge focuses on data storage and session management only\r\n\r\n// Helper function to get accessible team IDs (own team + child teams)\r\nasync function getAccessibleTeamIds(teamId: string): Promise<string[]> {\r\n const { data: accessibleTeams } = await supabase\r\n .from('teams')\r\n .select('id')\r\n .or(`id.eq.${teamId},parent_team_id.eq.${teamId}`);\r\n \r\n return accessibleTeams?.map(t => t.id) || [teamId];\r\n}\r\n\r\n// API Key validation - direct database access\r\nasync function validateApiKey(key: string): Promise<AuthContext | null> {\r\n if (!key.startsWith('mid_') || key.length !== 68) {\r\n console.error('š Invalid API key format');\r\n return null;\r\n }\r\n\r\n try {\r\n // Hash the API key\r\n const keyHash = createHash('sha256').update(key).digest('hex');\r\n console.error(`š Validating API key hash: ${keyHash.substring(0, 16)}...`);\r\n \r\n // Query database for API key\r\n const { data: apiKeyData, error } = await supabase\r\n .from('api_keys')\r\n .select('id, user_id, team_id, scopes, last_used_at')\r\n .eq('key_hash', keyHash)\r\n .single();\r\n\r\n if (error || !apiKeyData) {\r\n console.error('ā API key not found or invalid:', error?.message);\r\n return null;\r\n }\r\n\r\n // Update last used timestamp\r\n await supabase\r\n .from('api_keys')\r\n .update({ last_used_at: new Date().toISOString() })\r\n .eq('id', apiKeyData.id);\r\n\r\n console.error(`ā
API key validated for user ${apiKeyData.user_id} in team ${apiKeyData.team_id}`);\r\n \r\n return {\r\n userId: apiKeyData.user_id,\r\n teamId: apiKeyData.team_id,\r\n scopes: apiKeyData.scopes || []\r\n };\r\n } catch (error) {\r\n console.error('š„ API key validation error:', error);\r\n return null;\r\n }\r\n}\r\n\r\n// Validate auth context once at startup\r\nlet authContext: AuthContext | null = null;\r\n\r\n// Helper function to check if a file is an image\r\nfunction isImageFile(mimeType: string): boolean {\r\n return mimeType.startsWith('image/') && \r\n ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'].includes(mimeType);\r\n}\r\n\r\n// Helper function to download and convert image to base64\r\nasync function downloadImageAsBase64(storageKey: string): Promise<string | null> {\r\n try {\r\n // Get signed URL for the file (1 hour expiry)\r\n const { data: urlData, error: urlError } = await supabase.storage\r\n .from('vault')\r\n .createSignedUrl(storageKey, 3600);\r\n \r\n if (urlError || !urlData?.signedUrl) {\r\n console.error(`Failed to create signed URL for ${storageKey}:`, urlError);\r\n return null;\r\n }\r\n \r\n // Download the file\r\n const response = await fetch(urlData.signedUrl);\r\n if (!response.ok) {\r\n console.error(`Failed to download file ${storageKey}: ${response.status}`);\r\n return null;\r\n }\r\n \r\n // Convert to base64\r\n const arrayBuffer = await response.arrayBuffer();\r\n const buffer = Buffer.from(arrayBuffer);\r\n return buffer.toString('base64');\r\n } catch (error) {\r\n console.error(`Error downloading image ${storageKey}:`, error);\r\n return null;\r\n }\r\n}\r\n\r\n// MCP Server setup\r\nconst server = new Server(\r\n {\r\n name: 'mg-tickets-mcp-bridge',\r\n version: '2.0.0',\r\n },\r\n {\r\n capabilities: {\r\n tools: {},\r\n resources: {},\r\n },\r\n }\r\n);\r\n\r\n// Available tools definition\r\nconst TOOLS = [\r\n {\r\n name: 'get-tickets',\r\n description: 'Get tickets with optional filtering by status, priority, project, customer, or search query',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'] },\r\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\r\n projectId: { type: 'string' },\r\n customerId: { type: 'string' },\r\n q: { type: 'string', description: 'Search query for title or description' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'get-ticket-by-id',\r\n description: 'Get a specific ticket by its ID, including all attachments, comments, and images. Images from ticket attachments and comment attachments are automatically downloaded and returned as base64-encoded content that can be analyzed by AI.',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n id: { type: 'string', description: 'Ticket ID' }\r\n },\r\n required: ['id']\r\n }\r\n },\r\n {\r\n name: 'create-ticket',\r\n description: 'Create a new ticket',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n title: { type: 'string', description: 'Ticket title' },\r\n description: { type: 'string' },\r\n status: { type: 'string', enum: ['open', 'in_progress', 'review', 'resolved', 'closed', 'backlog'], default: 'open' },\r\n priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' },\r\n type: { type: 'string', enum: ['task', 'bug', 'feature', 'support', 'question', 'improvement'], default: 'task' },\r\n projectId: { type: 'string' },\r\n customerId: { type: 'string' }\r\n },\r\n required: ['title']\r\n }\r\n },\r\n {\r\n name: 'get-customers',\r\n description: 'Get customers with optional search',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n q: { type: 'string', description: 'Search query for customer name or email' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'create-customer',\r\n description: 'Create a new customer',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n name: { type: 'string', description: 'Customer name' },\r\n email: { type: 'string' },\r\n website: { type: 'string' }\r\n },\r\n required: ['name']\r\n }\r\n },\r\n {\r\n name: 'get-projects',\r\n description: 'Get projects with optional filtering',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n customerId: { type: 'string', description: 'Filter by customer ID' },\r\n q: { type: 'string', description: 'Search query for project name' },\r\n pageSize: { type: 'number', default: 20, maximum: 100 }\r\n },\r\n required: []\r\n }\r\n },\r\n {\r\n name: 'create-project',\r\n description: 'Create a new project',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n name: { type: 'string', description: 'Project name' },\r\n description: { type: 'string' },\r\n customerId: { type: 'string' },\r\n status: { type: 'string', enum: ['active', 'on_hold', 'completed', 'cancelled'], default: 'active' }\r\n },\r\n required: ['name']\r\n }\r\n },\r\n // === NEW AI SESSION TOOLS ===\r\n {\r\n name: 'start-ai-session-smart',\r\n description: 'Start a new AI development session with automatic tracking (time estimate provided by Cursor AI)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n ticketId: { type: 'string' },\r\n ticketUrl: { type: 'string', description: 'URL to the ticket' },\r\n cursorSessionId: { type: 'string', description: 'Cursor session identifier' },\r\n codebaseContext: { \r\n type: 'array', \r\n items: { type: 'string' },\r\n description: 'Relevant files for complexity analysis'\r\n },\r\n aiTimeEstimateMinutes: { \r\n type: 'number', \r\n description: 'AI estimate in minutes without AI assistance' \r\n },\r\n complexityScore: {\r\n type: 'number',\r\n minimum: 1,\r\n maximum: 10,\r\n description: 'Estimated complexity from 1-10'\r\n }\r\n },\r\n required: ['ticketId', 'aiTimeEstimateMinutes']\r\n }\r\n },\r\n {\r\n name: 'track-manual-follow-up',\r\n description: 'Track manual follow-up prompt by developer',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n originalPrompt: { type: 'string' },\r\n aiResponse: { type: 'string' },\r\n developerFollowUp: { type: 'string' },\r\n followUpReason: { \r\n type: 'string', \r\n enum: ['incomplete_result', 'wrong_approach', 'needs_clarification', 'error_in_code']\r\n },\r\n outcome: {\r\n type: 'string',\r\n enum: ['success', 'partial_success', 'still_failed'],\r\n default: 'success'\r\n },\r\n timeSpentMinutes: { type: 'number' }\r\n },\r\n required: ['aiSessionId', 'originalPrompt', 'aiResponse', 'developerFollowUp', 'followUpReason']\r\n }\r\n },\r\n {\r\n name: 'get-session-context',\r\n description: 'Get current session context for follow-up continuity',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n includeTicketData: { type: 'boolean', default: true },\r\n includeTodoProgress: { type: 'boolean', default: true },\r\n includeFollowUpHistory: { type: 'boolean', default: false }\r\n },\r\n required: ['aiSessionId']\r\n }\r\n },\r\n {\r\n name: 'sync-session-todos',\r\n description: 'Synchronize todo list with AI session (replace existing) or add new todos',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n todos: {\r\n type: 'array',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n todoId: { type: 'string', description: 'Optional external todo ID for tracking' },\r\n content: { type: 'string' },\r\n status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'cancelled'] },\r\n estimatedMinutes: { type: 'number' }\r\n },\r\n required: ['content', 'status']\r\n }\r\n },\r\n replaceAll: { \r\n type: 'boolean', \r\n default: true, \r\n description: 'If true, replace all existing todos. If false, add new todos to existing ones' \r\n }\r\n },\r\n required: ['aiSessionId', 'todos']\r\n }\r\n },\r\n {\r\n name: 'add-follow-up-todos',\r\n description: 'Add new todos from follow-up (without replacing existing ones)',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n newTodos: {\r\n type: 'array',\r\n items: {\r\n type: 'object',\r\n properties: {\r\n content: { type: 'string' },\r\n status: { type: 'string', enum: ['pending', 'in_progress'], default: 'pending' },\r\n estimatedMinutes: { type: 'number' },\r\n addedInFollowUp: { type: 'boolean', default: true }\r\n },\r\n required: ['content']\r\n }\r\n },\r\n followUpReason: { \r\n type: 'string', \r\n description: 'Why were these todos added in follow-up' \r\n }\r\n },\r\n required: ['aiSessionId', 'newTodos']\r\n }\r\n },\r\n {\r\n name: 'update-session-status',\r\n description: 'Update AI session status and completion info',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n status: {\r\n type: 'string',\r\n enum: ['started', 'in_progress', 'paused', 'completed', 'failed']\r\n },\r\n actualTimeMinutes: { type: 'number' },\r\n completionNotes: { type: 'string' }\r\n },\r\n required: ['aiSessionId', 'status']\r\n }\r\n },\r\n {\r\n name: 'get-completion-context',\r\n description: 'Get all context needed for Cursor AI to generate customer response',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n includeFollowUps: { type: 'boolean', default: true },\r\n includeTimeMetrics: { type: 'boolean', default: true },\r\n includeTodos: { type: 'boolean', default: true }\r\n },\r\n required: ['aiSessionId']\r\n }\r\n },\r\n {\r\n name: 'save-customer-response',\r\n description: 'Save customer response generated by Cursor AI',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n customerResponse: { type: 'string', description: 'Customer response generated by Cursor AI' },\r\n responseType: { \r\n type: 'string', \r\n enum: ['completion', 'progress_update', 'needs_clarification'],\r\n default: 'completion'\r\n }\r\n },\r\n required: ['aiSessionId', 'customerResponse']\r\n }\r\n },\r\n {\r\n name: 'complete-ai-session',\r\n description: 'Complete AI session with work summary - time calculated automatically',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n aiSessionId: { type: 'string' },\r\n workCompleted: {\r\n type: 'array',\r\n items: { type: 'string' },\r\n description: 'List of completed tasks/todos in English'\r\n },\r\n technicalSummary: {\r\n type: 'string',\r\n description: 'Technical summary of work done in English'\r\n },\r\n efficiencyNotes: { type: 'string' }\r\n },\r\n required: ['aiSessionId', 'workCompleted']\r\n }\r\n }\r\n];\r\n\r\n// Available resources\r\nconst RESOURCES = [\r\n {\r\n uri: 'tickets://recent',\r\n name: 'Recent Tickets',\r\n description: 'Most recently created tickets',\r\n mimeType: 'application/json'\r\n },\r\n {\r\n uri: 'customers://all',\r\n name: 'All Customers', \r\n description: 'Complete customer directory',\r\n mimeType: 'application/json'\r\n },\r\n {\r\n uri: 'projects://active',\r\n name: 'Active Projects',\r\n description: 'Currently active projects',\r\n mimeType: 'application/json'\r\n }\r\n];\r\n\r\n// List tools handler\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return { tools: TOOLS };\r\n});\r\n\r\n// List resources handler\r\nserver.setRequestHandler(ListResourcesRequestSchema, async () => {\r\n return { resources: RESOURCES };\r\n});\r\n\r\n// Tool execution handler\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n if (!authContext) {\r\n return {\r\n content: [{ type: 'text', text: 'Error: Not authenticated. API key validation failed.' }],\r\n };\r\n }\r\n\r\n const { name, arguments: args } = request.params;\r\n console.error(`š ļø Executing tool: ${name} for team ${authContext.teamId}`);\r\n \r\n try {\r\n switch (name) {\r\n case 'get-tickets': {\r\n const { status, priority, projectId, customerId, q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('tickets')\r\n .select(`\r\n id,\r\n ticket_number,\r\n title,\r\n description,\r\n status,\r\n priority,\r\n type,\r\n created_at,\r\n project_id,\r\n customer_id,\r\n projects:project_id(id, name),\r\n customers:customer_id(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (status) query = query.eq('status', status);\r\n if (priority) query = query.eq('priority', priority);\r\n if (projectId) query = query.eq('project_id', projectId);\r\n if (customerId) query = query.eq('customer_id', customerId);\r\n if (q) query = query.or(`title.ilike.%${q}%,description.ilike.%${q}%`);\r\n \r\n const { data, error } = await query.order('created_at', { ascending: false });\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} tickets:\\n\\n${data?.map(ticket => \r\n `**${ticket.ticket_number}**: ${ticket.title}\\n` +\r\n `Status: ${ticket.status} | Priority: ${ticket.priority}\\n` +\r\n `${(ticket.projects as any)?.name ? `Project: ${(ticket.projects as any).name}\\n` : ''}` +\r\n `${(ticket.customers as any)?.name ? `Customer: ${(ticket.customers as any).name}\\n` : ''}` +\r\n `Created: ${new Date(ticket.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No tickets found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-ticket-by-id': {\r\n const { id } = args as any;\r\n \r\n // Get ticket data - include tickets from provider's team AND child customer teams\r\n const { data: ticketData, error } = await supabase\r\n .from('tickets')\r\n .select(`\r\n *,\r\n projects:project_id(id, name),\r\n customers:customer_id(id, name),\r\n assignee:assignee_id(id, full_name, email),\r\n requester:requester_id(id, full_name, email)\r\n `)\r\n .eq('id', id)\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // Check if user has access to this ticket (own team or child team)\r\n const { data: teamAccess } = await supabase\r\n .from('teams')\r\n .select('id')\r\n .or(`id.eq.${ticketData.team_id},parent_team_id.eq.${authContext.teamId}`)\r\n .eq('id', ticketData.team_id)\r\n .single();\r\n \r\n if (!teamAccess && ticketData.team_id !== authContext.teamId) {\r\n throw new Error('Access denied: You do not have permission to view this ticket');\r\n }\r\n \r\n const data = ticketData;\r\n \r\n // Get ticket attachments (no team filter needed - already validated ticket access)\r\n const { data: attachments, error: attachmentsError } = await supabase\r\n .from('ticket_attachments')\r\n .select(`\r\n id,\r\n file_name,\r\n file_size,\r\n mime_type,\r\n storage_key,\r\n created_at,\r\n users:user_id(id, full_name)\r\n `)\r\n .eq('ticket_id', id)\r\n .order('created_at', { ascending: true });\r\n \r\n if (attachmentsError) {\r\n console.error('Error fetching attachments:', attachmentsError);\r\n }\r\n \r\n // Get ticket comments\r\n const { data: comments, error: commentsError } = await supabase\r\n .from('ticket_comments')\r\n .select(`\r\n id,\r\n content,\r\n created_at,\r\n users:user_id(id, full_name)\r\n `)\r\n .eq('ticket_id', id)\r\n .order('created_at', { ascending: true });\r\n \r\n if (commentsError) {\r\n console.error('Error fetching comments:', commentsError);\r\n }\r\n \r\n // Get comment attachments (no team filter needed - already validated ticket access)\r\n const commentIds = comments?.map(c => c.id) || [];\r\n let commentAttachments: any[] = [];\r\n \r\n if (commentIds.length > 0) {\r\n const { data: commAttachments, error: commAttachmentsError } = await supabase\r\n .from('ticket_comment_attachments')\r\n .select(`\r\n id,\r\n comment_id,\r\n file_name,\r\n file_size,\r\n mime_type,\r\n storage_key,\r\n created_at\r\n `)\r\n .in('comment_id', commentIds);\r\n \r\n if (commAttachmentsError) {\r\n console.error('Error fetching comment attachments:', commAttachmentsError);\r\n } else {\r\n commentAttachments = commAttachments || [];\r\n }\r\n }\r\n \r\n // Build content array starting with text\r\n const content: any[] = [{\r\n type: 'text',\r\n text: `**Ticket Details:**\\n\\n` +\r\n `**${data.ticket_number}**: ${data.title}\\n` +\r\n `Status: ${data.status}\\n` +\r\n `Priority: ${data.priority}\\n` +\r\n `Type: ${data.type}\\n` +\r\n `${data.description ? `Description: ${data.description}\\n` : ''}` +\r\n `${(data.projects as any)?.name ? `Project: ${(data.projects as any).name}\\n` : ''}` +\r\n `${(data.customers as any)?.name ? `Customer: ${(data.customers as any).name}\\n` : ''}` +\r\n `${data.assignee?.full_name ? `Assignee: ${data.assignee.full_name}\\n` : ''}` +\r\n `Requester: ${data.requester?.full_name || 'Unknown'}\\n` +\r\n `Created: ${new Date(data.created_at).toLocaleDateString()}\\n` +\r\n `${attachments && attachments.length > 0 ? `\\nš Attachments: ${attachments.length}\\n` : ''}` +\r\n `${comments && comments.length > 0 ? `š¬ Comments: ${comments.length}\\n` : ''}`\r\n }];\r\n \r\n // Process ticket attachments - download images\r\n if (attachments && attachments.length > 0) {\r\n console.error(`š Processing ${attachments.length} ticket attachments...`);\r\n \r\n for (const attachment of attachments) {\r\n if (isImageFile(attachment.mime_type)) {\r\n console.error(`š¼ļø Downloading image: ${attachment.file_name}`);\r\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\r\n \r\n if (base64Data) {\r\n content.push({\r\n type: 'image',\r\n data: base64Data,\r\n mimeType: attachment.mime_type\r\n });\r\n \r\n // Add text context about the image\r\n content.push({\r\n type: 'text',\r\n text: `\\nšø **Image from ticket**: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB, uploaded by ${(attachment.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()})\\n`\r\n });\r\n }\r\n }\r\n }\r\n }\r\n \r\n // Process comment attachments - download images\r\n if (commentAttachments.length > 0) {\r\n console.error(`š Processing ${commentAttachments.length} comment attachments...`);\r\n \r\n for (const attachment of commentAttachments) {\r\n if (isImageFile(attachment.mime_type)) {\r\n console.error(`š¼ļø Downloading comment image: ${attachment.file_name}`);\r\n const base64Data = await downloadImageAsBase64(attachment.storage_key);\r\n \r\n if (base64Data) {\r\n // Find the comment this attachment belongs to\r\n const comment = comments?.find(c => c.id === attachment.comment_id);\r\n \r\n content.push({\r\n type: 'image',\r\n data: base64Data,\r\n mimeType: attachment.mime_type\r\n });\r\n \r\n // Add text context about the image\r\n content.push({\r\n type: 'text',\r\n text: `\\nšø **Image from comment** by ${(comment?.users as any)?.full_name || 'Unknown'} on ${new Date(attachment.created_at).toLocaleDateString()}: ${attachment.file_name} (${Math.round(attachment.file_size / 1024)}KB)\\n` +\r\n (comment?.content ? `Comment text: \"${comment.content.substring(0, 100)}${comment.content.length > 100 ? '...' : ''}\"\\n` : '')\r\n });\r\n }\r\n }\r\n }\r\n }\r\n \r\n console.error(`ā
Returning ticket with ${content.filter(c => c.type === 'image').length} images`);\r\n \r\n return { content };\r\n }\r\n \r\n case 'create-ticket': {\r\n const { title, description, status = 'open', priority = 'medium', type = 'task', projectId, customerId } = args as any;\r\n \r\n // Generate ticket number\r\n const year = new Date().getFullYear();\r\n const { count } = await supabase\r\n .from('tickets')\r\n .select('*', { count: 'exact', head: true })\r\n .eq('team_id', authContext.teamId);\r\n \r\n const ticketNumber = `${year}-${String((count || 0) + 1).padStart(3, '0')}`;\r\n \r\n const { data, error } = await supabase\r\n .from('tickets')\r\n .insert({\r\n team_id: authContext.teamId,\r\n ticket_number: ticketNumber,\r\n title,\r\n description,\r\n status,\r\n priority,\r\n type,\r\n project_id: projectId || null,\r\n customer_id: customerId || null,\r\n requester_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `ā
**Ticket Created Successfully!**\\n\\n` +\r\n `Ticket Number: **${ticketNumber}**\\n` +\r\n `Title: ${title}\\n` +\r\n `Status: ${status}\\n` +\r\n `Priority: ${priority}\\n` +\r\n `Type: ${type}\\n`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-customers': {\r\n const { q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('customers')\r\n .select('id, name, email, website, created_at')\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (q) query = query.or(`name.ilike.%${q}%,email.ilike.%${q}%`);\r\n \r\n const { data, error } = await query.order('name');\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} customers:\\n\\n${data?.map(customer => \r\n `**${customer.name}**\\n` +\r\n `${customer.email ? `Email: ${customer.email}\\n` : ''}` +\r\n `${customer.website ? `Website: ${customer.website}\\n` : ''}` +\r\n `Created: ${new Date(customer.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No customers found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'create-customer': {\r\n const { name, email, website } = args as any;\r\n \r\n const { data, error } = await supabase\r\n .from('customers')\r\n .insert({\r\n team_id: authContext.teamId,\r\n name,\r\n email: email || null,\r\n website: website || null,\r\n user_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `ā
**Customer Created Successfully!**\\n\\n` +\r\n `Name: ${name}\\n` +\r\n `${email ? `Email: ${email}\\n` : ''}` +\r\n `${website ? `Website: ${website}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-projects': {\r\n const { customerId, q, pageSize = 20 } = args as any;\r\n \r\n // Get all accessible team IDs (own team + child teams)\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n \r\n let query = supabase\r\n .from('projects')\r\n .select(`\r\n id,\r\n name,\r\n description,\r\n customer_id,\r\n status,\r\n created_at,\r\n customers:customer_id(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .limit(Math.min(pageSize, 100));\r\n \r\n if (customerId) query = query.eq('customer_id', customerId);\r\n if (q) query = query.ilike('name', `%${q}%`);\r\n \r\n const { data, error } = await query.order('name');\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Found ${data?.length || 0} projects:\\n\\n${data?.map(project => \r\n `**${project.name}**\\n` +\r\n `Status: ${project.status}\\n` +\r\n `${project.description ? `Description: ${project.description}\\n` : ''}` +\r\n `${(project.customers as any)?.name ? `Customer: ${(project.customers as any).name}\\n` : ''}` +\r\n `Created: ${new Date(project.created_at).toLocaleDateString()}\\n`\r\n ).join('\\n') || 'No projects found.'}`\r\n }]\r\n };\r\n }\r\n \r\n case 'create-project': {\r\n const { name, description, customerId, status = 'active' } = args as any;\r\n \r\n const { data, error } = await supabase\r\n .from('projects')\r\n .insert({\r\n team_id: authContext.teamId,\r\n name,\r\n description: description || null,\r\n customer_id: customerId || null,\r\n status,\r\n user_id: authContext.userId\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `ā
**Project Created Successfully!**\\n\\n` +\r\n `Name: ${name}\\n` +\r\n `Status: ${status}\\n` +\r\n `${description ? `Description: ${description}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n // === AI SESSION TOOLS ===\r\n case 'start-ai-session-smart': {\r\n const { ticketId, ticketUrl, cursorSessionId, codebaseContext, aiTimeEstimateMinutes, complexityScore } = args as any;\r\n \r\n // Store the time estimate as provided by Cursor AI (already smart-adjusted)\r\n const sessionStartTime = new Date();\r\n const { data: sessionData, error } = await supabase\r\n .from('ai_sessions')\r\n .insert({\r\n ticket_id: ticketId,\r\n provider_user_id: authContext.userId,\r\n team_id: authContext.teamId,\r\n cursor_session_id: cursorSessionId || null,\r\n ai_time_estimate_minutes: aiTimeEstimateMinutes, // Use Cursor's smart estimate\r\n complexity_score: complexityScore || null,\r\n status: 'in_progress' // Start actively tracking time\r\n })\r\n .select('id, ticket_id, cursor_session_id, created_at')\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // Get ticket details to extract project_id and ticket_number for draft event\r\n const { data: ticketData } = await supabase\r\n .from('tickets')\r\n .select('project_id, title, ticket_number, description')\r\n .eq('id', ticketId)\r\n .single();\r\n \r\n // CREATE DRAFT AGENDA EVENT: Automatically block time for this ticket work\r\n // Start time = now (when session starts)\r\n // End time = now + estimated minutes\r\n const draftStartTime = sessionStartTime;\r\n const draftEndTime = new Date(sessionStartTime.getTime() + aiTimeEstimateMinutes * 60 * 1000);\r\n \r\n // Create customer-friendly title and description (no AI jargon)\r\n const eventTitle = ticketData?.title || 'Development Work';\r\n const eventDescription = ticketData?.description \r\n ? `${ticketData.ticket_number}: ${ticketData.description.substring(0, 200)}${ticketData.description.length > 200 ? '...' : ''}`\r\n : `Work on ticket ${ticketData?.ticket_number || ticketId}`;\r\n \r\n const { data: draftEvent, error: draftError } = await supabase\r\n .from('agenda_events')\r\n .insert({\r\n team_id: authContext.teamId,\r\n user_id: authContext.userId,\r\n title: eventTitle,\r\n description: eventDescription,\r\n start_time: draftStartTime.toISOString(),\r\n end_time: draftEndTime.toISOString(),\r\n project_id: ticketData?.project_id || null,\r\n ticket_id: ticketId, // Link to ticket\r\n type: 'work',\r\n status: 'draft', // Mark as draft for approval\r\n all_day: false,\r\n is_tracked: true, // Mark as tracked time\r\n tracked_duration: aiTimeEstimateMinutes * 60 // Store estimate in seconds\r\n })\r\n .select('id')\r\n .single();\r\n \r\n if (draftError) {\r\n console.error('ā ļø Failed to create draft agenda event:', draftError);\r\n // Don't fail the session creation if draft event fails\r\n }\r\n \r\n // START TIME TRACKING: Log session start\r\n await supabase\r\n .from('ai_time_logs')\r\n .insert({\r\n ai_session_id: sessionData.id,\r\n activity_type: 'thinking',\r\n description: 'AI session started - analysis and planning phase',\r\n duration_seconds: 0,\r\n productivity_score: 8,\r\n logged_at: sessionStartTime\r\n });\r\n \r\n // Generate a readable session ID for UI\r\n const sessionId = `ai-sess-${sessionData.id.substring(0, 8)}`;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `š **AI Session Started Successfully!**\\n\\n` +\r\n `š Session ID: **${sessionId}**\\n` +\r\n `š« Ticket: ${ticketId}\\n` +\r\n `ā±ļø Time Estimate: ${aiTimeEstimateMinutes} minutes\\n` +\r\n `${complexityScore ? `šÆ Complexity: ${complexityScore}/10\\n` : ''}` +\r\n `ā±ļø **Automatic Time Tracking Started**\\n` +\r\n `${cursorSessionId ? `š Cursor Session: ${cursorSessionId}\\n` : ''}` +\r\n `š
Started: ${sessionStartTime.toLocaleString()}\\n` +\r\n `${draftEvent ? `š **Draft Agenda Event Created** (needs approval)\\n ⢠Title: \"${eventTitle}\"\\n ⢠Time: ${draftStartTime.toLocaleTimeString()} - ${draftEndTime.toLocaleTimeString()} (${aiTimeEstimateMinutes}min)\\n ⢠Ticket: ${ticketData?.ticket_number || 'N/A'}\\n ⢠Status: DRAFT\\n` : ''}` +\r\n `\\nā
Session initialized - ready for development with smart context!`\r\n }]\r\n };\r\n }\r\n \r\n case 'track-manual-follow-up': {\r\n const { aiSessionId, originalPrompt, aiResponse, developerFollowUp, followUpReason, outcome = 'success', timeSpentMinutes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the full session ID and current session data\r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id, status, created_at, ai_time_estimate_minutes')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n const followUpTime = new Date();\r\n \r\n // RESTART SESSION: Set status back to in_progress for continued tracking\r\n await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: 'in_progress', // Restart active tracking\r\n // Don't update completed_at - session continues\r\n })\r\n .eq('id', session.id);\r\n \r\n // LOG FOLLOW-UP: Track the manual follow-up interaction\r\n const { data, error } = await supabase\r\n .from('manual_follow_ups')\r\n .insert({\r\n ai_session_id: session.id,\r\n developer_id: authContext.userId,\r\n team_id: authContext.teamId,\r\n original_prompt: originalPrompt,\r\n ai_response: aiResponse,\r\n follow_up_prompt: developerFollowUp,\r\n follow_up_reason: followUpReason,\r\n outcome: outcome,\r\n time_spent_minutes: timeSpentMinutes || null,\r\n resolved_at: outcome === 'success' ? new Date().toISOString() : null\r\n })\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n // RESTART TIME TRACKING: Log follow-up activity start\r\n await supabase\r\n .from('ai_time_logs')\r\n .insert({\r\n ai_session_id: session.id,\r\n activity_type: 'debugging', // Follow-ups are typically debugging/fixing\r\n description: `Follow-up: ${followUpReason.replace('_', ' ')} - ${outcome}`,\r\n duration_seconds: (timeSpentMinutes || 0) * 60,\r\n productivity_score: outcome === 'success' ? 9 : outcome === 'partial_success' ? 6 : 4,\r\n logged_at: followUpTime\r\n });\r\n \r\n // CALCULATE CURRENT EFFICIENCY: Compare time spent vs estimated\r\n const sessionStartTime = new Date(session.created_at);\r\n const totalMinutesElapsed = Math.round((followUpTime.getTime() - sessionStartTime.getTime()) / 60000);\r\n const estimatedMinutes = session.ai_time_estimate_minutes || 60;\r\n const currentEfficiency = totalMinutesElapsed > 0 ? (totalMinutesElapsed / estimatedMinutes) : 1;\r\n \r\n // UPDATE EFFICIENCY TRACKING: Update running efficiency score\r\n await supabase\r\n .from('ai_sessions')\r\n .update({\r\n efficiency_score: currentEfficiency.toFixed(2),\r\n actual_time_minutes: totalMinutesElapsed\r\n })\r\n .eq('id', session.id);\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `š **Follow-up Tracked & Session Restarted!**\\n\\n` +\r\n `š Session: ${aiSessionId} (back to active)\\n` +\r\n `š Reason: ${followUpReason.replace('_', ' ')}\\n` +\r\n `ā
Outcome: ${outcome}\\n` +\r\n `${timeSpentMinutes ? `ā±ļø Time spent: ${timeSpentMinutes} minutes\\n` : ''}` +\r\n `š **Current Progress:**\\n` +\r\n ` ⢠Total time: ${totalMinutesElapsed} minutes\\n` +\r\n ` ⢠Estimated: ${estimatedMinutes} minutes\\n` +\r\n ` ⢠Efficiency: ${currentEfficiency < 1 ? 'š ' : currentEfficiency > 1.5 ? 'ā ļø ' : 'ā±ļø '}${(currentEfficiency * 100).toFixed(0)}%\\n` +\r\n `\\nā” **Time tracking resumed** - continue with confidence!`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-session-context': {\r\n const { aiSessionId, includeTicketData = true, includeTodoProgress = true, includeFollowUpHistory = false } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session data with related info - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select(`\r\n id,\r\n ticket_id,\r\n status,\r\n ai_time_estimate_minutes,\r\n actual_time_minutes,\r\n complexity_score,\r\n created_at,\r\n cursor_session_id\r\n `)\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n \r\n if (sessionError || !session) {\r\n throw new Error(`Session not found: ${aiSessionId}`);\r\n }\r\n \r\n let context: any = {\r\n sessionId: aiSessionId,\r\n status: session.status,\r\n timeEstimate: session.ai_time_estimate_minutes,\r\n actualTime: session.actual_time_minutes,\r\n complexity: session.complexity_score,\r\n createdAt: session.created_at\r\n };\r\n \r\n // Include ticket data if requested\r\n if (includeTicketData) {\r\n const { data: ticket } = await supabase\r\n .from('tickets')\r\n .select('id, ticket_number, title, description, status, priority, type')\r\n .eq('id', session.ticket_id)\r\n .single();\r\n \r\n context.ticketData = ticket;\r\n }\r\n \r\n // Include todo progress if requested\r\n if (includeTodoProgress) {\r\n const { data: todos } = await supabase\r\n .from('ai_todos')\r\n .select('id, content, status, estimated_minutes, actual_minutes')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order');\r\n \r\n context.todos = todos || [];\r\n context.todoProgress = {\r\n total: todos?.length || 0,\r\n completed: todos?.filter(t => t.status === 'completed').length || 0,\r\n inProgress: todos?.filter(t => t.status === 'in_progress').length || 0\r\n };\r\n }\r\n \r\n // Include follow-up history if requested\r\n if (includeFollowUpHistory) {\r\n const { data: followUps } = await supabase\r\n .from('manual_follow_ups')\r\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at');\r\n \r\n context.followUpHistory = followUps || [];\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šÆ **Session Context Retrieved**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Status: ${session.status}\\n` +\r\n `${context.ticketData ? `Ticket: ${context.ticketData.ticket_number} - ${context.ticketData.title}\\n` : ''}` +\r\n `${context.todoProgress ? `Todo Progress: ${context.todoProgress.completed}/${context.todoProgress.total} completed\\n` : ''}` +\r\n `${context.followUpHistory ? `Follow-ups: ${context.followUpHistory.length}\\n` : ''}` +\r\n `\\nš Full context preserved for seamless continuation!`\r\n }]\r\n };\r\n }\r\n \r\n case 'sync-session-todos': {\r\n const { aiSessionId, todos, replaceAll = true } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // If replacing all, clear existing todos first\r\n if (replaceAll) {\r\n await supabase\r\n .from('ai_todos')\r\n .delete()\r\n .eq('ai_session_id', session.id);\r\n }\r\n \r\n if (todos && todos.length > 0) {\r\n // Get current max sequence order if adding to existing\r\n let startSequence = 0;\r\n if (!replaceAll) {\r\n const { data: maxTodo } = await supabase\r\n .from('ai_todos')\r\n .select('sequence_order')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order', { ascending: false })\r\n .limit(1)\r\n .single();\r\n startSequence = (maxTodo?.sequence_order || 0) + 1;\r\n }\r\n \r\n const todoInserts = todos.map((todo: any, index: number) => ({\r\n ai_session_id: session.id,\r\n content: todo.content,\r\n status: todo.status,\r\n cursor_todo_id: todo.todoId || null,\r\n estimated_minutes: todo.estimatedMinutes || null,\r\n sequence_order: startSequence + index\r\n }));\r\n \r\n const { error: insertError } = await supabase\r\n .from('ai_todos')\r\n .insert(todoInserts);\r\n \r\n if (insertError) throw insertError;\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `ā
**Todos ${replaceAll ? 'Synced' : 'Added'} Successfully!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `${replaceAll ? 'Synced' : 'Added'} ${todos?.length || 0} todos\\n` +\r\n `${replaceAll ? '' : 'ā Added to existing todo list\\n'}` +\r\n `\\nš Todo list updated and tracked for progress monitoring!`\r\n }]\r\n };\r\n }\r\n \r\n case 'add-follow-up-todos': {\r\n const { aiSessionId, newTodos, followUpReason } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find the session - get all sessions for accessible teams and filter in JS\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n if (newTodos && newTodos.length > 0) {\r\n // Get current max sequence order\r\n const { data: maxTodo } = await supabase\r\n .from('ai_todos')\r\n .select('sequence_order')\r\n .eq('ai_session_id', session.id)\r\n .order('sequence_order', { ascending: false })\r\n .limit(1)\r\n .single();\r\n const startSequence = (maxTodo?.sequence_order || 0) + 1;\r\n \r\n const todoInserts = newTodos.map((todo: any, index: number) => ({\r\n ai_session_id: session.id,\r\n content: `[Follow-up] ${todo.content}`,\r\n status: todo.status || 'pending',\r\n estimated_minutes: todo.estimatedMinutes || null,\r\n sequence_order: startSequence + index\r\n }));\r\n \r\n const { error: insertError } = await supabase\r\n .from('ai_todos')\r\n .insert(todoInserts);\r\n \r\n if (insertError) throw insertError;\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `ā
**Follow-up Todos Added Successfully!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Added ${newTodos?.length || 0} new todos from follow-up\\n` +\r\n `${followUpReason ? `Reason: ${followUpReason}\\n` : ''}` +\r\n `\\nš New tasks identified and added to existing workflow!`\r\n }]\r\n };\r\n }\r\n \r\n case 'update-session-status': {\r\n const { aiSessionId, status, actualTimeMinutes, completionNotes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Find and update the session\r\n // First find the session\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: findError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (findError) {\r\n throw new Error(`Database error: ${findError.message}`);\r\n }\r\n \r\n const foundSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!foundSession) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Now update the found session\r\n const { data, error } = await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: status,\r\n actual_time_minutes: actualTimeMinutes || null,\r\n completed_at: status === 'completed' ? new Date().toISOString() : null\r\n })\r\n .eq('id', foundSession.id)\r\n .select()\r\n .single();\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `šÆ **Session Status Updated!**\\n\\n` +\r\n `Session: ${aiSessionId}\\n` +\r\n `Status: ${status}\\n` +\r\n `${actualTimeMinutes ? `Actual Time: ${actualTimeMinutes} minutes\\n` : ''}` +\r\n `${status === 'completed' ? `ā
Session completed successfully!\\n` : ''}` +\r\n `${completionNotes ? `Notes: ${completionNotes}\\n` : ''}`\r\n }]\r\n };\r\n }\r\n \r\n case 'get-completion-context': {\r\n const { aiSessionId, includeFollowUps = true, includeTimeMetrics = true, includeTodos = true } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session data with ticket info\r\n // Get comprehensive session context - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select(`\r\n id,\r\n ticket_id,\r\n ai_time_estimate_minutes,\r\n actual_time_minutes,\r\n efficiency_score,\r\n created_at,\r\n completed_at,\r\n status,\r\n complexity_score\r\n `)\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Get ticket data\r\n const { data: ticket, error: ticketError } = await supabase\r\n .from('tickets')\r\n .select('ticket_number, title, description, type, priority')\r\n .eq('id', session.ticket_id)\r\n .single();\r\n \r\n if (ticketError || !ticket) {\r\n throw new Error('Ticket not found for session');\r\n }\r\n \r\n let contextData: any = {\r\n session: {\r\n id: aiSessionId,\r\n status: session.status,\r\n complexity: session.complexity_score,\r\n createdAt: session.created_at,\r\n completedAt: session.completed_at\r\n },\r\n ticket: {\r\n number: ticket.ticket_number,\r\n title: ticket.title,\r\n description: ticket.description,\r\n type: ticket.type,\r\n priority: ticket.priority\r\n }\r\n };\r\n \r\n // Add time metrics if requested\r\n if (includeTimeMetrics) {\r\n const timeSaved = session.ai_time_estimate_minutes && session.actual_time_minutes \r\n ? Math.max(0, session.ai_time_estimate_minutes - session.actual_time_minutes)\r\n : null;\r\n \r\n contextData.timeMetrics = {\r\n estimatedMinutes: session.ai_time_estimate_minutes,\r\n actualMinutes: session.actual_time_minutes,\r\n timeSaved: timeSaved,\r\n efficiency: session.efficiency_score,\r\n sessionDuration: session.completed_at && session.created_at \r\n ? Math.round((new Date(session.completed_at).getTime() - new Date(session.created_at).getTime()) / 60000)\r\n : null\r\n };\r\n }\r\n \r\n // Add todos if requested\r\n if (includeTodos) {\r\n const { data: todos } = await supabase\r\n .from('ai_todos')\r\n .select('content, status, estimated_minutes, actual_minutes, completed_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at', { ascending: true });\r\n \r\n contextData.todos = todos || [];\r\n }\r\n \r\n // Add follow-ups if requested\r\n if (includeFollowUps) {\r\n const { data: followUps } = await supabase\r\n .from('manual_follow_ups')\r\n .select('follow_up_reason, outcome, time_spent_minutes, created_at')\r\n .eq('ai_session_id', session.id)\r\n .order('created_at', { ascending: true });\r\n \r\n contextData.followUps = followUps || [];\r\n }\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `š **Completion Context Retrieved!**\\n\\n` +\r\n `š« **Ticket:** ${ticket.ticket_number} - ${ticket.title}\\n` +\r\n `š **Session:** ${aiSessionId} (${session.status})\\n` +\r\n `ā±ļø **Time:** ${session.actual_time_minutes || 'N/A'}/${session.ai_time_estimate_minutes || 'N/A'} minutes\\n` +\r\n `š **Todos:** ${contextData.todos?.filter((t: any) => t.status === 'completed').length || 0}/${contextData.todos?.length || 0} completed\\n` +\r\n `š **Follow-ups:** ${contextData.followUps?.length || 0}\\n\\n` +\r\n `ā
**Full context ready for Cursor AI to generate customer response!**\\n\\n` +\r\n `**Context Data:**\\n\\`\\`\\`json\\n${JSON.stringify(contextData, null, 2)}\\`\\`\\``\r\n }]\r\n };\r\n }\r\n \r\n case 'save-customer-response': {\r\n const { aiSessionId, customerResponse, responseType = 'completion' } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session to validate it exists - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id')\r\n .in('team_id', teamIds);\r\n \r\n if (sessionError) {\r\n throw new Error(`Database error: ${sessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const session = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!session) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n \r\n // Save the response in database\r\n const { data: responseData, error: responseError } = await supabase\r\n .from('ai_responses')\r\n .insert({\r\n ai_session_id: session.id,\r\n response_type: responseType,\r\n content: customerResponse,\r\n is_ready_for_customer: true,\r\n provider_approved: false // Needs manual approval\r\n })\r\n .select()\r\n .single();\r\n \r\n if (responseError) throw responseError;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `š¾ **Customer Response Saved!**\\n\\n` +\r\n `š Session: ${aiSessionId}\\n` +\r\n `š Response Type: ${responseType}\\n` +\r\n `š Length: ${customerResponse.length} characters\\n\\n` +\r\n `ā
**Response ready for provider approval**\\n` +\r\n `š Provider can review in AI tab before sending to customer\\n\\n` +\r\n `**Preview:**\\n\\`\\`\\`\\n${customerResponse.substring(0, 200)}${customerResponse.length > 200 ? '...' : ''}\\`\\`\\``\r\n }]\r\n };\r\n }\r\n \r\n case 'complete-ai-session': {\r\n const { aiSessionId, workCompleted, technicalSummary, efficiencyNotes } = args as any;\r\n \r\n // Extract actual session UUID from readable ID\r\n const sessionUuid = aiSessionId.replace('ai-sess-', '');\r\n \r\n // Get session to calculate actual time spent - find by JavaScript filtering\r\n const teamIds = await getAccessibleTeamIds(authContext.teamId);\r\n const { data: allSessions, error: getSessionError } = await supabase\r\n .from('ai_sessions')\r\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\r\n .in('team_id', teamIds);\r\n \r\n if (getSessionError) {\r\n throw new Error(`Database error: ${getSessionError.message}`);\r\n }\r\n \r\n // Find session with matching prefix\r\n const existingSession = allSessions?.find(s => s.id.toString().startsWith(sessionUuid));\r\n if (!existingSession) {\r\n throw new Error(`Session not found: ${aiSessionId} (searched ${allSessions?.length || 0} sessions)`);\r\n }\r\n\r\n // Calculate actual time spent automatically\r\n const completionTime = new Date();\r\n const sessionStartTime = new Date(existingSession.created_at);\r\n const timeSpentMinutes = Math.round((completionTime.getTime() - sessionStartTime.getTime()) / 60000);\r\n \r\n // Update session to completed with calculated time\r\n const { data: session, error: sessionError } = await supabase\r\n .from('ai_sessions')\r\n .update({\r\n status: 'completed',\r\n actual_time_minutes: timeSpentMinutes,\r\n completed_at: completionTime.toISOString(),\r\n efficiency_score: null // Will be calculated\r\n })\r\n .eq('id', existingSession.id)\r\n .select('id, ticket_id, ai_time_estimate_minutes, created_at')\r\n .single();\r\n \r\n if (sessionError || !session) {\r\n throw new Error(`Failed to update session: ${aiSessionId}`);\r\n }\r\n \r\n // Calculate efficiency score\r\n const efficiencyScore = session.ai_time_estimate_minutes \r\n ? (timeSpentMinutes / session.ai_time_estimate_minutes)\r\n : 1.0;\r\n \r\n // Update efficiency score\r\n await supabase\r\n .from('ai_sessions')\r\n .update({ efficiency_score: efficiencyScore.toFixed(2) })\r\n .eq('id', session.id);\r\n \r\n // Get session duration\r\n const sessionDuration = Math.round(\r\n (completionTime.getTime() - new Date(session.created_at).getTime()) / 60000\r\n );\r\n \r\n // Create work summary\r\n const workSummary = `Completed ${workCompleted.length} tasks including: ${workCompleted.slice(0, 3).join(', ')}${workCompleted.length > 3 ? ' and more' : ''}.`;\r\n \r\n let responseText = `š **AI Session Completed Successfully!**\\n\\n`;\r\n responseText += `š Session: ${aiSessionId}\\n`;\r\n responseText += `š **Performance Summary:**\\n`;\r\n responseText += ` ⢠Tasks Completed: ${workCompleted.length}\\n`;\r\n responseText += ` ⢠Time Spent: ${timeSpentMinutes} minutes\\n`;\r\n responseText += ` ⢠Estimated Time: ${session.ai_time_estimate_minutes || 'N/A'} minutes\\n`;\r\n responseText += ` ⢠Efficiency: ${efficiencyScore < 1 ? 'š' : efficiencyScore > 1.5 ? 'ā ļø' : 'ā±ļø'} ${(efficiencyScore * 100).toFixed(0)}%\\n`;\r\n responseText += ` ⢠Session Duration: ${sessionDuration} minutes\\n\\n`;\r\n \r\n responseText += `ā
**Work Completed:**\\n`;\r\n workCompleted.forEach((task: string, index: number) => {\r\n responseText += `${index + 1}. ${task}\\n`;\r\n });\r\n responseText += `\\n`;\r\n \r\n if (technicalSummary) {\r\n responseText += `š§ **Technical Summary:**\\n${technicalSummary}\\n\\n`;\r\n }\r\n \r\n if (efficiencyNotes) {\r\n responseText += `š **Efficiency Notes:**\\n${efficiencyNotes}\\n\\n`;\r\n }\r\n \r\n // Provide context for Cursor AI to generate customer response\r\n responseText += `š **Context for Customer Response:**\\n`;\r\n responseText += ` ⢠Use \"get-completion-context\" to retrieve full context\\n`;\r\n responseText += ` ⢠Generate customer-friendly response based on completed work\\n`;\r\n responseText += ` ⢠Focus on business value and customer benefits\\n\\n`;\r\n \r\n responseText += `šÆ **Session archived successfully!**`;\r\n \r\n return {\r\n content: [{\r\n type: 'text',\r\n text: responseText\r\n }]\r\n };\r\n }\r\n \r\n default:\r\n throw new Error(`Unknown tool: ${name}`);\r\n }\r\n \r\n } catch (error) {\r\n console.error(`ā Tool execution error:`, error);\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Error executing ${name}: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n }]\r\n };\r\n }\r\n});\r\n\r\n// Resource read handler\r\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n if (!authContext) {\r\n return {\r\n contents: [{\r\n uri: request.params.uri,\r\n mimeType: 'text/plain',\r\n text: 'Error: Not authenticated. API key validation failed.'\r\n }]\r\n };\r\n }\r\n\r\n const { uri } = request.params;\r\n console.error(`š Reading resource: ${uri}`);\r\n \r\n try {\r\n switch (uri) {\r\n case 'tickets://recent': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('tickets')\r\n .select(`\r\n id,\r\n ticket_number,\r\n title,\r\n status,\r\n priority,\r\n created_at\r\n `)\r\n .in('team_id', teamIds)\r\n .order('created_at', { ascending: false })\r\n .limit(20);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n case 'customers://all': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('customers')\r\n .select('id, name, email, website, created_at')\r\n .in('team_id', teamIds)\r\n .order('name')\r\n .limit(50);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n case 'projects://active': {\r\n const teamIds = await getAccessibleTeamIds(authContext!.teamId);\r\n const { data, error } = await supabase\r\n .from('projects')\r\n .select(`\r\n id,\r\n name,\r\n description,\r\n status,\r\n created_at,\r\n customers:customer_id(id, name)\r\n `)\r\n .in('team_id', teamIds)\r\n .eq('status', 'active')\r\n .order('name')\r\n .limit(50);\r\n \r\n if (error) throw error;\r\n \r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'application/json',\r\n text: JSON.stringify(data, null, 2)\r\n }]\r\n };\r\n }\r\n \r\n default:\r\n throw new Error(`Unknown resource: ${uri}`);\r\n }\r\n \r\n } catch (error) {\r\n console.error(`ā Resource read error:`, error);\r\n return {\r\n contents: [{\r\n uri,\r\n mimeType: 'text/plain',\r\n text: `Error reading ${uri}: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n }]\r\n };\r\n }\r\n});\r\n\r\n// Main function\r\nasync function main() {\r\n console.error('š Starting MG Tickets MCP Bridge Server...');\r\n console.error(`š API Key: ${apiKey?.substring(0, 10)}...`);\r\n \r\n // Validate API key\r\n authContext = await validateApiKey(apiKey!);\r\n if (!authContext) {\r\n console.error('ā API key validation failed. Please check your key and try again.');\r\n process.exit(1);\r\n }\r\n \r\n console.error(`ā
Authenticated as user ${authContext.userId} in team ${authContext.teamId}`);\r\n console.error(`š Available scopes: ${authContext.scopes.join(', ')}`);\r\n console.error('š” MCP Bridge Server ready for connections');\r\n \r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n}\r\n\r\n// Handle graceful shutdown\r\nprocess.on('SIGINT', async () => {\r\n console.error('š Shutting down MCP Bridge Server...');\r\n process.exit(0);\r\n});\r\n\r\nprocess.on('SIGTERM', async () => {\r\n console.error('š Shutting down MCP Bridge Server...');\r\n process.exit(0);\r\n});\r\n\r\n// Start the server\r\nmain().catch((error) => {\r\n console.error('š„ Fatal error:', error);\r\n process.exit(1);\r\n});"]}
|
package/package.json
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mgsoftwarebv/mcp-server-bridge",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "MCP Server bridge for MG Tickets - connects Cursor to HTTP MCP server with image support",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"mg-tickets-mcp": "dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsup",
|
|
12
|
-
"dev": "tsup --watch",
|
|
13
|
-
"start": "node dist/index.js",
|
|
14
|
-
"typecheck": "tsc --noEmit"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"mcp",
|
|
18
|
-
"tickets",
|
|
19
|
-
"bridge",
|
|
20
|
-
"cursor",
|
|
21
|
-
"mg-software"
|
|
22
|
-
],
|
|
23
|
-
"author": "MG Software B.V.",
|
|
24
|
-
"license": "MIT",
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
27
|
-
"@supabase/supabase-js": "^2.50.0",
|
|
28
|
-
"crypto": "^1.0.1"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@types/node": "^20.0.0",
|
|
32
|
-
"tsup": "^8.0.0",
|
|
33
|
-
"typescript": "^5.0.0"
|
|
34
|
-
},
|
|
35
|
-
"files": [
|
|
36
|
-
"dist",
|
|
37
|
-
"README.md"
|
|
38
|
-
],
|
|
39
|
-
"repository": {
|
|
40
|
-
"type": "git",
|
|
41
|
-
"url": "git+https://github.com/mgsoftwarebv/tickets-v2.git"
|
|
42
|
-
},
|
|
43
|
-
"publishConfig": {
|
|
44
|
-
"access": "public",
|
|
45
|
-
"registry": "https://registry.npmjs.org/"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mgsoftwarebv/mcp-server-bridge",
|
|
3
|
+
"version": "2.8.0",
|
|
4
|
+
"description": "MCP Server bridge for MG Tickets - connects Cursor to HTTP MCP server with image support",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mg-tickets-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup",
|
|
12
|
+
"dev": "tsup --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"typecheck": "tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"tickets",
|
|
19
|
+
"bridge",
|
|
20
|
+
"cursor",
|
|
21
|
+
"mg-software"
|
|
22
|
+
],
|
|
23
|
+
"author": "MG Software B.V.",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
27
|
+
"@supabase/supabase-js": "^2.50.0",
|
|
28
|
+
"crypto": "^1.0.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.0.0",
|
|
32
|
+
"tsup": "^8.0.0",
|
|
33
|
+
"typescript": "^5.0.0"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/mgsoftwarebv/tickets-v2.git"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"registry": "https://registry.npmjs.org/"
|
|
46
|
+
}
|
|
47
|
+
}
|