celavii-mcp 0.2.2 → 0.2.4

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 CHANGED
@@ -130,6 +130,8 @@ import { z as z3 } from "zod";
130
130
  import { z as z2 } from "zod";
131
131
  var PLATFORMS = ["instagram", "tiktok", "youtube", "x"];
132
132
  var PlatformSchema = z2.enum(PLATFORMS);
133
+ var SEMANTIC_PLATFORMS = ["instagram", "tiktok", "x"];
134
+ var SemanticPlatformSchema = z2.enum(SEMANTIC_PLATFORMS);
133
135
 
134
136
  // src/tools/profiles.ts
135
137
  function registerProfileTools(server, client) {
@@ -856,7 +858,7 @@ function registerAnalyticsTools(server, client) {
856
858
  "get_youtube_channel_summary",
857
859
  {
858
860
  title: "Get YouTube Channel Summary",
859
- description: "Aggregate stats about a YouTube channel's commenter network \u2014 total comments collected, unique commenters, last collection time. Backed by api.get_channel_summary_yt_v1. Free.",
861
+ description: "Aggregate stats about a YouTube channel's commenter network \u2014 total comments collected, unique commenters, last collection time. Backed by api.get_channel_summary_yt_v1. Free. Response includes `data_status` (collected | channel_found_no_commenters | channel_not_found), `last_collected_at`, and `channel_id` (canonical yt:UCxxx) which can be passed directly to `scrape_youtube_commenters` to collect commenter data. The legacy `summary.out_*` fields are preserved for back-compat and will be removed in 0.3.0.",
860
862
  inputSchema: z6.object({
861
863
  seed: z6.string().describe("YouTube channel handle/username (with or without @)")
862
864
  })
@@ -875,7 +877,7 @@ function registerAnalyticsTools(server, client) {
875
877
  "get_youtube_bridge_creators",
876
878
  {
877
879
  title: "Get YouTube Bridge Creators",
878
- description: "Find YouTube channels whose commenters overlap with a seed channel \u2014 the YT-network analogue of audience overlap. Backed by api.get_bridge_creators_yt_v1. Free.",
880
+ description: 'Find YouTube channels whose commenters overlap with a seed channel \u2014 the YT-network analogue of audience overlap. Backed by api.get_bridge_creators_yt_v1. Free. Response includes `data_status` (collected | collected_no_bridges | no_commenter_data | channel_not_found) so callers can distinguish "no overlap" from "no data collected yet". If `no_commenter_data`, run `scrape_youtube_commenters` on the seed first.',
879
881
  inputSchema: z6.object({
880
882
  seed: z6.string().describe("Seed YouTube channel handle/username"),
881
883
  min_shared_commenters: z6.number().int().min(1).max(50).optional().describe("Minimum shared commenters (default 2)"),
@@ -927,24 +929,28 @@ function registerContentTools(server, client) {
927
929
  "search_content",
928
930
  {
929
931
  title: "Search Content",
930
- description: "Search posts across the creator database by keywords, hashtags, or mentions. Returns matching posts with engagement metrics and media. Costs 1 credit.",
932
+ description: "Full-text search across post captions on all 4 platforms (Instagram, TikTok, YouTube, X). Returns matching posts with engagement metrics. Use `platform` to filter to a single network. Use `verbose: false` to strip captions/hashtags from the response (helps when result captions are long \u2014 YouTube descriptions can run 2,000\u20135,000 chars). Costs 2 credits per call (was incorrectly documented as 1 credit through 0.2.3).",
931
933
  inputSchema: z7.object({
932
934
  query: z7.string().describe("Search query \u2014 matches post captions (required)"),
935
+ platform: PlatformSchema.optional().describe("Filter results to a single platform (default: all 4)"),
933
936
  author: z7.string().optional().describe("Filter by creator username"),
934
937
  min_engagement: z7.number().int().optional().describe("Minimum total engagement (likes + comments)"),
935
938
  since: z7.string().optional().describe("Only posts after this date (ISO 8601, e.g. 2025-01-01)"),
936
939
  sort: z7.enum(["relevance", "engagement", "date"]).optional().describe("Sort order (default: 'relevance')"),
937
- limit: z7.number().int().min(1).max(100).optional().describe("Results per page (default 25, max 100)")
940
+ limit: z7.number().int().min(1).max(100).optional().describe("Results per page (default 25, max 100)"),
941
+ verbose: z7.boolean().optional().describe("If false, strip caption + hashtags from response (default true; back-compat)")
938
942
  })
939
943
  },
940
944
  async (args) => {
941
945
  const params = new URLSearchParams();
942
946
  params.set("query", args.query);
947
+ if (args.platform) params.set("platform", args.platform);
943
948
  if (args.author) params.set("author", args.author);
944
949
  if (args.min_engagement !== void 0) params.set("min_engagement", String(args.min_engagement));
945
950
  if (args.since) params.set("since", args.since);
946
951
  if (args.sort) params.set("sort", args.sort);
947
952
  if (args.limit !== void 0) params.set("limit", String(args.limit));
953
+ if (args.verbose === false) params.set("verbose", "false");
948
954
  const result = await client.get(`/content/search?${params}`);
949
955
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
950
956
  }
@@ -953,16 +959,17 @@ function registerContentTools(server, client) {
953
959
  "semantic_search_content",
954
960
  {
955
961
  title: "Semantic Search Content",
956
- description: "Search posts using AI embeddings for semantic similarity. Finds conceptually related posts even without exact keyword matches. Combines full-text search with vector similarity for best results. Costs 1 credit.",
962
+ description: "Search posts using AI embeddings for semantic similarity (Instagram, TikTok, X only). Combines full-text search with vector similarity for best results. YouTube post embeddings are not yet populated \u2014 use `search_content` (FTS) for YouTube. Costs 1 credit.",
957
963
  inputSchema: z7.object({
958
964
  query: z7.string().describe("Search query \u2014 finds semantically similar posts"),
959
965
  author: z7.string().optional().describe("Filter by creator username"),
960
966
  min_engagement: z7.number().int().optional().describe("Minimum total engagement"),
961
967
  since: z7.string().optional().describe("Only posts after this date (ISO 8601)"),
962
- platform: PlatformSchema.optional().describe("Filter by platform"),
968
+ platform: SemanticPlatformSchema.optional().describe("Filter by platform (instagram | tiktok | x \u2014 YouTube embeddings pending)"),
963
969
  alpha: z7.number().min(0).max(1).optional().describe("Hybrid weight: 0=keyword only, 1=semantic only, 0.6=balanced (default)"),
964
970
  sort: z7.enum(["relevance", "engagement", "date"]).optional().describe("Sort order (default: 'relevance')"),
965
- limit: z7.number().int().min(1).max(100).optional().describe("Results per page (default 25, max 100)")
971
+ limit: z7.number().int().min(1).max(100).optional().describe("Results per page (default 25, max 100)"),
972
+ verbose: z7.boolean().optional().describe("If false, strip caption + hashtags from response (default true; back-compat)")
966
973
  })
967
974
  },
968
975
  async (args) => {
@@ -974,7 +981,8 @@ function registerContentTools(server, client) {
974
981
  platform: args.platform,
975
982
  alpha: args.alpha,
976
983
  sort: args.sort,
977
- limit: args.limit
984
+ limit: args.limit,
985
+ verbose: args.verbose
978
986
  });
979
987
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
980
988
  }
@@ -1744,9 +1752,10 @@ function registerScrapeTools(server, client) {
1744
1752
  "scrape_youtube_commenters",
1745
1753
  {
1746
1754
  title: "Scrape YouTube Commenters",
1747
- description: "YouTube does not expose subscriber lists \u2014 the closest network signal is the set of channels commenting on a creator's videos. Triggers a batched commenter fetch (channels.list + videos.list + per-video commentThreads.list). Returns a job ID. Costs 2 credits + YouTube Data API v3 quota usage.",
1755
+ description: "YouTube does not expose subscriber lists \u2014 the closest network signal is the set of channels commenting on a creator's videos. Triggers a batched commenter fetch (channels.list + videos.list + per-video commentThreads.list). Executes synchronously within the request (typically 5\u201330s depending on video_count \xD7 comments_per_video). The response contains the full result (total_comments, unique_commenters, etc.) AND a job_id for retrospective tracking \u2014 no polling needed. Results are stored in the network graph for use by get_youtube_bridge_creators and get_youtube_channel_summary. Costs 2 credits + YouTube Data API v3 quota usage.",
1748
1756
  inputSchema: z11.object({
1749
- profile_id: z11.string().describe("yt: prefixed channel ID (e.g. yt:UCxxxxx)"),
1757
+ channel: z11.string().optional().describe("Channel target \u2014 yt: prefixed ID (yt:UCxxx), @handle, or YouTube channel URL"),
1758
+ profile_id: z11.string().optional().describe("DEPRECATED alias for `channel`. Same accepted forms. Will be removed in 0.3.0."),
1750
1759
  video_count: z11.number().int().min(1).max(50).optional().describe("Videos to sample (default 5, max 50)"),
1751
1760
  comments_per_video: z11.number().int().min(1).max(500).optional().describe("Comments per video (default 100, max 500)"),
1752
1761
  dry_run: z11.boolean().optional().describe("If true, returns quota estimate without triggering")
@@ -1766,7 +1775,7 @@ function registerScrapeTools(server, client) {
1766
1775
  "scrape_youtube_hashtags",
1767
1776
  {
1768
1777
  title: "Scrape YouTube by Keyword",
1769
- description: "YouTube keyword/hashtag search via streamers/youtube-scraper. Each input becomes a search query. Returns a job ID. Costs 1 credit + processing.",
1778
+ description: "YouTube keyword/hashtag search via streamers/youtube-scraper (Apify-backed, NOT YouTube Data API v3). Each input becomes a search query. Returns a job_id immediately; results land asynchronously through the unified job system. Poll with `list_jobs` or `get_scrape_status` to track progress (typical run: 1\u20135 min depending on per_hashtag_limit). Costs 1 credit + Apify processing.",
1770
1779
  inputSchema: z11.object({
1771
1780
  hashtags: z11.array(z11.string()).min(1).max(10).describe("1\u201310 keyword queries (with or without #)"),
1772
1781
  per_hashtag_limit: z11.number().int().optional().describe("Max videos per query (default 5)"),
@@ -1790,7 +1799,7 @@ function registerScrapeTools(server, client) {
1790
1799
  "scrape_youtube_trending",
1791
1800
  {
1792
1801
  title: "Scrape YouTube Trending",
1793
- description: "Pull the YouTube trending feed via apidojo/youtube-scraper. Returns the most popular uploads in the requested timeframe. Costs 1 credit + processing.",
1802
+ description: "Pull the YouTube trending feed via apidojo/youtube-scraper (Apify-backed, NOT YouTube Data API v3). Returns a job_id immediately; results land asynchronously through the unified job system. Poll with `list_jobs` or `get_scrape_status` to track progress (typical run: 1\u20133 min depending on max_items). Returns the most popular uploads in the requested timeframe. Costs 1 credit + Apify processing.",
1794
1803
  inputSchema: z11.object({
1795
1804
  max_items: z11.number().int().min(1).max(200).optional().describe("Max trending videos (default 50, max 200)"),
1796
1805
  yt_include_shorts: z11.boolean().optional().describe("Include YouTube Shorts (default true)"),
@@ -1813,7 +1822,7 @@ function registerScrapeTools(server, client) {
1813
1822
  "scrape_youtube_videos",
1814
1823
  {
1815
1824
  title: "Collect YouTube Channel Videos",
1816
- description: "Collect a YouTube channel's recent videos via the YouTube Data API v3 (hybrid path \u2014 NOT Apify). Costs 2 credits + Data API v3 quota usage.",
1825
+ description: "Collect a YouTube channel's recent videos via the YouTube Data API v3 (NOT Apify). Executes synchronously within the request (typically 3\u201315s depending on videos_limit). The response contains the job_id + quota_consumed; results are written to `posts` and become queryable immediately. No polling needed for completion, but `get_scrape_status` works for retrospective tracking. Costs 2 credits + Data API v3 quota usage.",
1817
1826
  inputSchema: z11.object({
1818
1827
  target: z11.string().describe("Channel target \u2014 yt: prefixed ID, @handle, or YouTube channel URL"),
1819
1828
  videos_limit: z11.number().int().min(1).max(500).optional().describe("Max videos (default 50, max 500)"),
@@ -1933,9 +1942,19 @@ function registerJobsTools(server, client) {
1933
1942
  "list_jobs",
1934
1943
  {
1935
1944
  title: "List Jobs",
1936
- description: "List all jobs for the organization \u2014 enhancement, refinement, and scrape jobs. Returns a unified view sorted by most recent. Filter by type and/or status. Costs 0 credits.",
1945
+ description: "List all jobs for the organization \u2014 enhancement, refinement, and 7 scrape kinds. Returns a unified view sorted by most recent. Filter by type and/or status. Scrape kinds (added in 0.2.4): hashtag_scrape, location_scrape, video_scrape, commenter_scrape, url_scrape \u2014 alongside existing followers_scrape + following_scrape. Costs 0 credits.",
1937
1946
  inputSchema: z13.object({
1938
- type: z13.enum(["enhance", "refine", "followers_scrape", "following_scrape"]).optional().describe("Filter by job type (default: all)"),
1947
+ type: z13.enum([
1948
+ "enhance",
1949
+ "refine",
1950
+ "followers_scrape",
1951
+ "following_scrape",
1952
+ "hashtag_scrape",
1953
+ "location_scrape",
1954
+ "video_scrape",
1955
+ "commenter_scrape",
1956
+ "url_scrape"
1957
+ ]).optional().describe("Filter by job type (default: all)"),
1939
1958
  status: z13.string().optional().describe("Filter by status (e.g. 'completed', 'failed', 'processing', 'pending', 'queued')"),
1940
1959
  limit: z13.number().int().min(1).max(100).optional().describe("Results per page (default 25, max 100)"),
1941
1960
  cursor: z13.string().optional().describe("Pagination cursor")
@@ -2001,7 +2020,7 @@ function createServer(options) {
2001
2020
  // See tsup.config.ts. Fallback string is only used in `tsc --noEmit`
2002
2021
  // / direct ts-node runs; the published bundle always carries the
2003
2022
  // real value.
2004
- version: true ? "0.2.2" : "0.0.0-dev"
2023
+ version: true ? "0.2.4" : "0.0.0-dev"
2005
2024
  },
2006
2025
  {
2007
2026
  capabilities: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/client.ts","../src/tools/meta.ts","../src/tools/profiles.ts","../src/tools/_platform-schema.ts","../src/tools/campaigns.ts","../src/tools/lists.ts","../src/tools/analytics.ts","../src/tools/content.ts","../src/tools/manage.ts","../src/tools/knowledge.ts","../src/tools/enhance.ts","../src/tools/credit-guard.ts","../src/tools/scrape.ts","../src/tools/refine.ts","../src/tools/jobs.ts","../src/tools/_registry.ts"],"sourcesContent":["/**\n * Celavii MCP Server — stdio Entry Point\n *\n * Usage:\n * CELAVII_API_KEY=cvii_live_xxx npx celavii-mcp\n *\n * Or in MCP config:\n * {\n * \"mcpServers\": {\n * \"celavii\": {\n * \"command\": \"npx\",\n * \"args\": [\"-y\", \"celavii-mcp@latest\"],\n * \"env\": { \"CELAVII_API_KEY\": \"cvii_live_xxx\" }\n * }\n * }\n * }\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer, TOOL_GROUPS, type ToolGroup } from './server.js'\n\nfunction parseToolGroups(env: string | undefined): ToolGroup[] | undefined {\n if (!env) return undefined\n const requested = env.split(',').map((s) => s.trim().toLowerCase())\n const valid = requested.filter((g): g is ToolGroup =>\n (TOOL_GROUPS as readonly string[]).includes(g),\n )\n const invalid = requested.filter((g) => !(TOOL_GROUPS as readonly string[]).includes(g))\n if (invalid.length) {\n console.error(\n `Warning: Unknown tool groups ignored: ${invalid.join(', ')}\\n` +\n `Valid groups: ${TOOL_GROUPS.join(', ')}`,\n )\n }\n return valid.length > 0 ? valid : undefined\n}\n\nasync function main() {\n const apiKey = process.env.CELAVII_API_KEY\n if (!apiKey) {\n console.error(\n 'Error: CELAVII_API_KEY environment variable is required.\\n' +\n 'Get your API key at https://www.celavii.com/settings/api-keys\\n' +\n '\\nUsage:\\n' +\n ' CELAVII_API_KEY=cvii_live_xxx npx celavii-mcp\\n' +\n '\\nOptional: Load specific tool groups only:\\n' +\n ` CELAVII_TOOLS=profiles,analytics,campaigns\\n` +\n ` Available groups: ${TOOL_GROUPS.join(', ')}`,\n )\n process.exit(1)\n }\n\n const baseUrl = process.env.CELAVII_BASE_URL || undefined\n const tools = parseToolGroups(process.env.CELAVII_TOOLS)\n\n const server = createServer({ apiKey, baseUrl, tools })\n const transport = new StdioServerTransport()\n\n await server.connect(transport)\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err)\n process.exit(1)\n})\n","/**\n * Celavii MCP Server — Server Setup & Tool Registration (stdio entry)\n *\n * Creates an McpServer instance with the version baked in at build time\n * (see tsup.config.ts) and registers every tool group via the shared\n * registry at `tools/_registry.ts`.\n *\n * The remote endpoint at `src/app/api/mcp/[transport]/route.ts` (Vercel)\n * uses the same registry — there is no longer a duplicated tool list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { CelaviiClient, CelaviiApiError } from './client.js'\nimport { registerAllTools, TOOL_GROUPS, type ToolGroup } from './tools/_registry.js'\n\nexport { TOOL_GROUPS, type ToolGroup }\n\nexport interface CreateServerOptions {\n apiKey: string\n baseUrl?: string\n /** Tool groups to register. If omitted or empty, all groups are registered. */\n tools?: ToolGroup[]\n}\n\nexport function createServer(options: CreateServerOptions): McpServer {\n const { apiKey, baseUrl, tools } = options\n\n const server = new McpServer(\n {\n name: 'celavii',\n // Replaced at build time by tsup `define` from package.json#version.\n // See tsup.config.ts. Fallback string is only used in `tsc --noEmit`\n // / direct ts-node runs; the published bundle always carries the\n // real value.\n version:\n typeof __PACKAGE_VERSION__ !== 'undefined' ? __PACKAGE_VERSION__ : '0.0.0-dev',\n },\n {\n capabilities: {\n logging: {},\n },\n },\n )\n\n const client = new CelaviiClient(apiKey, baseUrl)\n\n registerAllTools(server, client, { groups: tools })\n\n return server\n}\n\nexport { CelaviiClient, CelaviiApiError }\n","/**\n * Celavii MCP Server — HTTP Client\n *\n * Thin wrapper around fetch that adds Bearer auth, error handling,\n * and structured error responses for MCP tool handlers.\n */\n\nconst DEFAULT_BASE_URL = 'https://www.celavii.com/api/v1'\n\nexport class CelaviiApiError extends Error {\n constructor(\n message: string,\n public code: string,\n public status: number,\n public retryAfter?: number,\n ) {\n super(message)\n this.name = 'CelaviiApiError'\n }\n}\n\nexport class CelaviiClient {\n private baseUrl: string\n private apiKey: string\n\n constructor(apiKey: string, baseUrl?: string) {\n this.apiKey = apiKey\n this.baseUrl = (baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, '')\n }\n\n private async request(path: string, init?: RequestInit): Promise<unknown> {\n const url = `${this.baseUrl}${path}`\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'celavii-mcp/0.1.0',\n ...init?.headers,\n },\n })\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n throw new CelaviiApiError(\n `HTTP ${res.status}: Failed to parse response`,\n 'INTERNAL_ERROR',\n res.status,\n )\n }\n\n if (!res.ok) {\n const err = json as { error?: { code?: string; message?: string; retry_after?: number } }\n const msg = err?.error?.message || `HTTP ${res.status}`\n const code = err?.error?.code || 'INTERNAL_ERROR'\n throw new CelaviiApiError(msg, code, res.status, err?.error?.retry_after)\n }\n\n return json\n }\n\n async get(path: string): Promise<unknown> {\n return this.request(path)\n }\n\n async post(path: string, body?: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'POST',\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n }\n\n async patch(path: string, body: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'PATCH',\n body: JSON.stringify(body),\n })\n }\n\n async put(path: string, body: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'PUT',\n body: JSON.stringify(body),\n })\n }\n\n async delete(path: string, body?: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'DELETE',\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n }\n}\n","/**\n * Meta tools — Account info and usage\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerMetaTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_account_info',\n {\n title: 'Get Account Info',\n description:\n 'Get information about the current API key, organization, and usage summary. ' +\n 'Useful to verify API key is working and see available scopes. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/me')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_usage',\n {\n title: 'Get Usage',\n description:\n 'Get credit usage and rate limit status for the current API key. ' +\n 'Shows total requests, credits used, daily breakdown, and rate limit info. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/usage')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_youtube_quota',\n {\n title: 'Get YouTube Data API v3 Quota',\n description:\n 'Returns the platform\\'s YouTube Data API v3 quota state. Returns BOTH raw units ' +\n '(cap, used, remaining, reset_seconds) AND a normalized \"operations remaining today\" ' +\n 'estimate per op-type — agents can pick the shape that suits their planning. ' +\n 'Note: quota is a global daily cap shared across all orgs on the same Google API key. Free.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/youtube/quota')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Profile tools — Search, details, affinities, posts, network, bulk\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerProfileTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'search_profiles',\n {\n title: 'Search Profiles',\n description:\n 'Search the Celavii creator database. Filter by query text, niche, location, gender, ' +\n 'follower count. Returns matching Instagram profiles with basic stats. ' +\n 'At least one filter is required. Costs 1 credit.',\n inputSchema: z.object({\n query: z.string().optional().describe('Search query — matches username, display name, or bio keywords'),\n niche: z.string().optional().describe(\"Filter by niche/topic (e.g. 'fitness', 'fashion', 'tech')\"),\n location: z.string().optional().describe(\"Filter by location (e.g. 'Miami', 'Los Angeles, California')\"),\n gender: z.enum(['male', 'female', 'non_binary', 'brand']).optional().describe('Filter by gender'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n has_contact: z.boolean().optional().describe('Only return profiles with email or phone'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor from a previous response'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.query) params.set('query', args.query)\n if (args.niche) params.set('niche', args.niche)\n if (args.location) params.set('location', args.location)\n if (args.gender) params.set('gender', args.gender)\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.has_contact) params.set('has_contact', 'true')\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/profiles/search?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'search_profiles_by_affinities',\n {\n title: 'Search Profiles by Affinities',\n description:\n 'Search creators by their AI-analyzed brand or topic affinities. ' +\n 'Find creators who have affinity for specific brands, interests, or topics. Costs 1 credit.',\n inputSchema: z.object({\n affinities: z.array(z.string()).describe(\"Affinity terms to search for (e.g. ['Nike', 'fitness', 'running'])\"),\n match_mode: z.enum(['any', 'all']).optional().describe(\"'any' = match any affinity, 'all' = must match all (default: 'any')\"),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor from a previous response'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('terms', args.affinities.join(','))\n if (args.match_mode) params.set('match_mode', args.match_mode)\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/profiles/search/affinities?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profiles_bulk',\n {\n title: 'Get Profiles Bulk',\n description:\n 'Get detailed information for multiple profiles at once by username or profile ID. ' +\n 'Up to 100 profiles per request. Costs 1 credit.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs (max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/bulk', { profiles: args.identifiers })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile',\n {\n title: 'Get Profile',\n description:\n 'Get detailed information about a single Instagram profile by username or profile ID. ' +\n 'Returns bio, stats, niche, location, job_status (enhance/refine/scrape progress), and more. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username (without @) or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_affinities',\n {\n title: 'Get Profile Affinities',\n description:\n 'Get AI-analyzed brand and topic affinities for a profile. ' +\n 'Shows what brands, interests, and topics a creator is associated with. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/affinities`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_posts',\n {\n title: 'Get Profile Posts',\n description:\n 'Get recent posts for a profile. Returns post content, engagement metrics, ' +\n 'media URLs, and hashtags. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of posts (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/posts${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_network',\n {\n title: 'Get Profile Network',\n description:\n 'Get the social network graph for a profile — mutual connections, ' +\n 'top followers, and following relationships. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/network`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_followers',\n {\n title: 'Get Profile Followers',\n description:\n 'Get the followers list for a profile. Only available if followers have been scraped. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of followers (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/followers${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_following',\n {\n title: 'Get Profile Following',\n description:\n 'Get the accounts a profile is following. Only available if following data has been scraped. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of following (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/following${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_social_links',\n {\n title: 'Get Profile Social Links',\n description:\n 'Get external social media links found in a profile bio (YouTube, TikTok, Twitter, etc.). Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/social-links`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_contact',\n {\n title: 'Get Profile Contact',\n description:\n 'Get contact information (email, phone) for a profile. ' +\n 'Requires the profiles:contact scope. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/contact`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ============================================================================\n // Semantic Search Tools (Phase 3 Embeddings)\n // ============================================================================\n\n server.registerTool(\n 'find_similar_profiles',\n {\n title: 'Find Similar Profiles',\n description:\n 'Find profiles semantically similar to a seed profile using AI embeddings. ' +\n 'Uses vector similarity to find creators with similar content, topics, and style. ' +\n 'More powerful than keyword matching — finds conceptually related profiles. Costs 1 credit.',\n inputSchema: z.object({\n profile_id: z.string().describe('Seed profile ID (e.g., ig:123456789) to find similar profiles for'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n platforms: z.array(PlatformSchema).optional().describe('Filter by platforms'),\n limit: z.number().int().min(1).max(100).optional().describe('Results to return (default 20, max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/search/similar', {\n profile_id: args.profile_id,\n min_followers: args.min_followers,\n max_followers: args.max_followers,\n platforms: args.platforms,\n limit: args.limit,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'find_similar_to_cohort',\n {\n title: 'Find Similar to Cohort',\n description:\n 'Find profiles similar to a GROUP of seed profiles. ' +\n 'Computes a centroid embedding from multiple profiles and finds similar creators. ' +\n 'Use case: \"Find creators like these 5 influencers I already work with\". Costs 1 credit.',\n inputSchema: z.object({\n profile_ids: z.array(z.string()).describe('Array of seed profile IDs (e.g., [\"ig:123\", \"ig:456\"])'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n platforms: z.array(PlatformSchema).optional().describe('Filter by platforms'),\n exclude_seeds: z.boolean().optional().describe('Exclude seed profiles from results (default true)'),\n limit: z.number().int().min(1).max(100).optional().describe('Results to return (default 20, max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/search/similar/cohort', {\n profile_ids: args.profile_ids,\n min_followers: args.min_followers,\n max_followers: args.max_followers,\n platforms: args.platforms,\n exclude_seeds: args.exclude_seeds,\n limit: args.limit,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Platform Schema — MCP-side mirror of `src/lib/api-keys/platform-schema.ts`.\n *\n * Duplicated rather than imported to keep the MCP package free of Next.js\n * coupling. The repo-root parity test\n * (`src/lib/api-keys/__tests__/platform-schema.test.ts`) asserts these two\n * files stay in sync — if you edit one, edit the other.\n */\n\nimport { z } from 'zod';\n\nexport const PLATFORMS = ['instagram', 'tiktok', 'youtube', 'x'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\nexport const PlatformSchema = z.enum(PLATFORMS);\n","/**\n * Campaign tools — List, metrics, creators, content\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerCampaignTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_campaigns',\n {\n title: 'List Campaigns',\n description:\n 'List all campaigns in the organization. Optionally filter by status. Costs 0 credits.',\n inputSchema: z.object({\n status: z.enum(['active', 'draft', 'completed', 'archived']).optional().describe('Filter by campaign status'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of campaigns (default 25, max 100)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const qs = params.toString()\n const result = await client.get(`/campaigns${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_metrics',\n {\n title: 'Get Campaign Metrics',\n description:\n 'Get performance metrics for a specific campaign — total creators, posts, ' +\n 'engagement, reach, and more. Costs 0 credits.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/metrics`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_creators',\n {\n title: 'Get Campaign Creators',\n description:\n 'Get the list of creators assigned to a campaign with their statuses and metrics. Costs 0 credits.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/creators${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_content',\n {\n title: 'Get Campaign Content',\n description:\n 'Get content (posts) associated with a campaign. Includes engagement data ' +\n 'and media. Costs 1 credit.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/content${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * List tools — CRUD + member management\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerListTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_lists',\n {\n title: 'List Lists',\n description: 'Get all creator lists in the organization. Costs 0 credits.',\n inputSchema: z.object({\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/lists${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_list',\n {\n title: 'Create List',\n description: 'Create a new creator list. Costs 1 credit.',\n inputSchema: z.object({\n name: z.string().describe('Name of the list'),\n description: z.string().optional().describe('Optional description'),\n }),\n },\n async (args) => {\n const result = await client.post('/lists', { name: args.name, description: args.description })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_list',\n {\n title: 'Get List',\n description: 'Get details for a specific list by ID. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/lists/${encodeURIComponent(args.list_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'update_list',\n {\n title: 'Update List',\n description: 'Update a list name or description. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n name: z.string().optional().describe('New name'),\n description: z.string().optional().describe('New description'),\n }),\n },\n async (args) => {\n const { list_id, ...body } = args\n const result = await client.patch(`/lists/${encodeURIComponent(list_id)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_list',\n {\n title: 'Delete List',\n description: 'Delete a list. This does not delete the creators in the list. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/lists/${encodeURIComponent(args.list_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_list_members',\n {\n title: 'Get List Members',\n description: 'Get the creator profiles in a list with optional filtering. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n limit: z.number().int().min(1).max(200).optional().describe('Results per page (default 25, max 200)'),\n offset: z.number().int().min(0).optional().describe('Number of results to skip (default 0). Use the offset from the previous response to paginate.'),\n min_followers: z.number().int().optional().describe('Minimum follower count filter'),\n max_followers: z.number().int().optional().describe('Maximum follower count filter'),\n added_after: z.string().optional().describe('Only profiles added after this date (ISO 8601, e.g. 2025-01-01)'),\n enhanced_after: z.string().optional().describe('Only profiles enhanced after this date (ISO 8601)'),\n platform: PlatformSchema.optional().describe('Filter by platform'),\n has_enhancement: z.boolean().optional().describe('Filter by completed enhancement (true = has, false = missing)'),\n has_refinement: z.boolean().optional().describe('Filter by completed refinement (true = has, false = missing)'),\n has_followers_scrape: z.boolean().optional().describe('Filter by completed followers scrape (true = has, false = missing)'),\n has_following_scrape: z.boolean().optional().describe('Filter by completed following scrape (true = has, false = missing)'),\n tags: z.array(z.string()).optional().describe('Filter by tags — profiles with ANY of these tags'),\n relationship_status: z.string().optional().describe(\"Filter by CRM status (e.g., 'shortlisted', 'outreached', 'negotiating', 'contracted')\"),\n has_notes: z.boolean().optional().describe('Filter by whether profile has notes (true = has notes, false = no notes)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.offset !== undefined) params.set('offset', String(args.offset))\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.added_after) params.set('added_after', args.added_after)\n if (args.enhanced_after) params.set('enhanced_after', args.enhanced_after)\n if (args.platform) params.set('platform', args.platform)\n if (args.has_enhancement !== undefined) params.set('has_enhancement', String(args.has_enhancement))\n if (args.has_refinement !== undefined) params.set('has_refinement', String(args.has_refinement))\n if (args.has_followers_scrape !== undefined) params.set('has_followers_scrape', String(args.has_followers_scrape))\n if (args.has_following_scrape !== undefined) params.set('has_following_scrape', String(args.has_following_scrape))\n if (args.tags && args.tags.length > 0) params.set('tags', args.tags.join(','))\n if (args.relationship_status) params.set('relationship_status', args.relationship_status)\n if (args.has_notes !== undefined) params.set('has_notes', String(args.has_notes))\n const qs = params.toString()\n const result = await client.get(`/lists/${encodeURIComponent(args.list_id)}/members${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'add_list_members',\n {\n title: 'Add List Members',\n description: 'Add creators to a list by username or profile ID. Costs 1 credit.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to add'),\n }),\n },\n async (args) => {\n const result = await client.post(\n `/lists/${encodeURIComponent(args.list_id)}/members`,\n { profiles: args.identifiers },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'remove_list_members',\n {\n title: 'Remove List Members',\n description: 'Remove creators from a list. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to remove'),\n }),\n },\n async (args) => {\n const result = await client.delete(\n `/lists/${encodeURIComponent(args.list_id)}/members`,\n { profiles: args.identifiers },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Analytics tools — Demographics, locations, niches, overlap, cohort\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\n/** Schema for endpoints that accept profile_ids + scope (demographics) */\nconst demographicsSchema = z.object({\n profile_ids: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n scope: z.enum(['global', 'org']).optional().describe(\"'global' (default, all profiles) or 'org' (managed only)\"),\n})\n\n/** Schema for endpoints that accept scope + limit only (locations, niches) */\nconst orgLevelSchema = z.object({\n scope: z.enum(['global', 'org']).optional().describe(\"'global' (default, all profiles) or 'org' (managed only)\"),\n limit: z.number().int().min(1).max(100).optional().describe('Max results (default 20, max 100)'),\n})\n\n/** Schema for profile source parameters used by overlap, shared-hashtags, cohort */\nconst profileSourceSchema = z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n})\n\n\nexport function registerAnalyticsTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_demographics',\n {\n title: 'Get Demographics',\n description:\n 'Get audience demographics breakdown (age, gender distribution). ' +\n 'Optionally pass profile_ids to analyze a subset, or scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: demographicsSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.profile_ids?.length) params.set('profile_ids', args.profile_ids.join(','))\n if (args.scope) params.set('scope', args.scope)\n const result = await client.get(`/analytics/demographics?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_locations',\n {\n title: 'Get Locations',\n description:\n 'Get location distribution — top cities and countries. ' +\n 'Use scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: orgLevelSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.scope) params.set('scope', args.scope)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/locations?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_niches',\n {\n title: 'Get Niches',\n description:\n 'Get niche/topic distribution across profiles. ' +\n 'Use scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: orgLevelSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.scope) params.set('scope', args.scope)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/niches?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_network_overlap',\n {\n title: 'Get Network Overlap',\n description:\n 'Get follower/following overlap between profiles. Shows shared connections. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profile_ids', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/network-overlap?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_shared_hashtags',\n {\n title: 'Get Shared Hashtags',\n description:\n 'Get hashtags shared across a set of profiles. Shows common themes and topics. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('usernames', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/shared-hashtags?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_hashtag_creators',\n {\n title: 'Get Hashtag Creators',\n description:\n 'Find creators who use specific hashtags. Useful for discovering creators by topic. Costs 1 credit.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).describe(\"Hashtags to search for (without #, e.g. ['fitness', 'gym'])\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('hashtags', args.hashtags.join(','))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/analytics/hashtag-creators?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_affinity_posts',\n {\n title: 'Get Affinity Posts',\n description:\n 'Get posts linked to a brand/topic affinity term. Searches globally across all profiles. Costs 1 credit.',\n inputSchema: z.object({\n affinity: z.string().describe('Affinity term to search for (e.g. \"photography\", \"Nike\", \"fitness\")'),\n affinity_type: z.enum(['all', 'topic', 'brand', 'location', 'category']).optional().describe(\"Filter by affinity type (default: 'all')\"),\n min_engagement: z.number().int().optional().describe('Minimum total engagement'),\n sort: z.enum(['engagement', 'date']).optional().describe(\"Sort order (default: 'engagement')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('affinity', args.affinity)\n if (args.affinity_type) params.set('affinity_type', args.affinity_type)\n if (args.min_engagement !== undefined) params.set('min_engagement', String(args.min_engagement))\n if (args.sort) params.set('sort', args.sort)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/affinity-posts?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'analyze_cohort',\n {\n title: 'Analyze Cohort',\n description:\n 'Run a full cohort analysis on a set of profiles. Includes demographics, affinities, ' +\n 'hashtag usage, and aggregate stats. Costs 2 credits.',\n inputSchema: z.object({\n profiles: z.array(z.string()).optional().describe('Array of usernames or profile IDs'),\n source: z.object({\n type: z.enum(['followers', 'following']).describe(\"Source type: 'followers' or 'following'\"),\n target: z.string().describe('Username or ig:ID of the seed profile'),\n limit: z.number().int().optional().describe('Max profiles to resolve from network (default 500, max 10000)'),\n }).optional().describe('Alternative: analyze followers/following of a profile'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n include: z.array(z.string()).optional().describe(\"Data to include: ['affinities', 'demographics', 'locations', 'niches', 'engagement_stats', 'hashtags', 'account_stats']\"),\n }),\n },\n async (args) => {\n const result = await client.post('/analytics/cohort', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_cohort_stats',\n {\n title: 'Get Cohort Stats',\n description:\n 'Get aggregate statistics for a cohort — average followers, engagement rate, etc. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profiles', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/cohort/stats?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'filter_cohort',\n {\n title: 'Filter Cohort',\n description:\n 'Filter a cohort of profiles by advanced criteria — follower range, engagement rate, ' +\n 'niche, location, affinities, and more. Costs 2 credits.',\n inputSchema: z.object({\n profiles: z.array(z.string()).optional().describe('Array of usernames or profile IDs to filter'),\n source: z.object({\n type: z.enum(['followers', 'following']).describe(\"Source type: 'followers' or 'following'\"),\n target: z.string().describe('Username or ig:ID of the seed profile'),\n limit: z.number().int().optional().describe('Max profiles to resolve from network (default 500, max 10000)'),\n }).optional().describe('Alternative: filter followers/following of a profile'),\n list_id: z.string().optional().describe('List UUID — filter all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — filter all creators in this campaign'),\n filters: z.record(z.string(), z.unknown()).optional().describe('Filter criteria (varies by field)'),\n }),\n },\n async (args) => {\n const result = await client.post('/analytics/cohort/filter', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_posting_times',\n {\n title: 'Get Posting Times',\n description:\n 'Get posting time patterns (day-of-week + hour heatmap), content format distribution, and sentiment analysis for a cohort. ' +\n 'Useful for finding optimal posting times. Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n platform: PlatformSchema.optional().describe(\"Platform to analyze (default: 'instagram')\"),\n days: z.number().int().min(1).max(365).optional().describe('Number of days to look back (default: 90)'),\n sample_max: z.number().int().min(1).max(50000).optional().describe('Max posts to sample (default: 5000)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profiles', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n if (args.platform) params.set('platform', args.platform)\n if (args.days !== undefined) params.set('days', String(args.days))\n if (args.sample_max !== undefined) params.set('sample_max', String(args.sample_max))\n // Call v1 analytics posting-times endpoint\n const result = await client.get(`/analytics/posting-times?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // YouTube analytics — Phase 3D (3 tools backed by api.*_yt_v1 RPCs)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'get_youtube_channel_summary',\n {\n title: 'Get YouTube Channel Summary',\n description:\n 'Aggregate stats about a YouTube channel\\'s commenter network — total comments collected, ' +\n 'unique commenters, last collection time. Backed by api.get_channel_summary_yt_v1. Free.',\n inputSchema: z.object({\n seed: z.string().describe('YouTube channel handle/username (with or without @)'),\n }),\n },\n async (args) => {\n try {\n const result = await client.get(`/youtube/channel-summary?seed=${encodeURIComponent(args.seed)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_youtube_bridge_creators',\n {\n title: 'Get YouTube Bridge Creators',\n description:\n 'Find YouTube channels whose commenters overlap with a seed channel — the YT-network ' +\n 'analogue of audience overlap. Backed by api.get_bridge_creators_yt_v1. Free.',\n inputSchema: z.object({\n seed: z.string().describe('Seed YouTube channel handle/username'),\n min_shared_commenters: z.number().int().min(1).max(50).optional().describe('Minimum shared commenters (default 2)'),\n limit: z.number().int().min(1).max(100).optional().describe('Max bridge creators to return (default 10)'),\n }),\n },\n async (args) => {\n try {\n const params = new URLSearchParams({ seed: args.seed })\n if (args.min_shared_commenters !== undefined) params.set('min_shared_commenters', String(args.min_shared_commenters))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/youtube/bridge-creators?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_youtube_graph_edges',\n {\n title: 'Get YouTube Commenter Graph Edges',\n description:\n 'Edge list for the commenter-overlap graph rooted at one or more seed channels — ' +\n 'suitable for network visualization. Provide seeds as usernames or yt: prefixed IDs. ' +\n 'Backed by api.get_graph_edges_yt_v1. Free.',\n inputSchema: z.object({\n seed_usernames: z.array(z.string()).optional().describe('YouTube channel usernames (one of seed_usernames OR seed_profile_ids required)'),\n seed_profile_ids: z.array(z.string()).optional().describe('yt: prefixed channel IDs'),\n max_nodes: z.number().int().min(10).max(5000).optional().describe('Max graph nodes (default 500)'),\n min_edge_weight: z.number().int().min(1).optional().describe('Minimum shared-commenter count to draw an edge (default 1)'),\n include_cross_creator: z.boolean().optional().describe('Include cross-creator edges (default true)'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/youtube/graph-edges', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n}\n","/**\n * Content tools — Post search\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerContentTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'search_content',\n {\n title: 'Search Content',\n description:\n 'Search posts across the creator database by keywords, hashtags, or mentions. ' +\n 'Returns matching posts with engagement metrics and media. Costs 1 credit.',\n inputSchema: z.object({\n query: z.string().describe('Search query — matches post captions (required)'),\n author: z.string().optional().describe('Filter by creator username'),\n min_engagement: z.number().int().optional().describe('Minimum total engagement (likes + comments)'),\n since: z.string().optional().describe('Only posts after this date (ISO 8601, e.g. 2025-01-01)'),\n sort: z.enum(['relevance', 'engagement', 'date']).optional().describe(\"Sort order (default: 'relevance')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('query', args.query)\n if (args.author) params.set('author', args.author)\n if (args.min_engagement !== undefined) params.set('min_engagement', String(args.min_engagement))\n if (args.since) params.set('since', args.since)\n if (args.sort) params.set('sort', args.sort)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/content/search?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ============================================================================\n // Semantic Content Search (Phase 3 Embeddings)\n // ============================================================================\n\n server.registerTool(\n 'semantic_search_content',\n {\n title: 'Semantic Search Content',\n description:\n 'Search posts using AI embeddings for semantic similarity. ' +\n 'Finds conceptually related posts even without exact keyword matches. ' +\n 'Combines full-text search with vector similarity for best results. Costs 1 credit.',\n inputSchema: z.object({\n query: z.string().describe('Search query — finds semantically similar posts'),\n author: z.string().optional().describe('Filter by creator username'),\n min_engagement: z.number().int().optional().describe('Minimum total engagement'),\n since: z.string().optional().describe('Only posts after this date (ISO 8601)'),\n platform: PlatformSchema.optional().describe('Filter by platform'),\n alpha: z.number().min(0).max(1).optional().describe('Hybrid weight: 0=keyword only, 1=semantic only, 0.6=balanced (default)'),\n sort: z.enum(['relevance', 'engagement', 'date']).optional().describe(\"Sort order (default: 'relevance')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/content/search/semantic', {\n query: args.query,\n author: args.author,\n min_engagement: args.min_engagement,\n since: args.since,\n platform: args.platform,\n alpha: args.alpha,\n sort: args.sort,\n limit: args.limit,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Manage tools — CRM operations\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerManageTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_managed_profiles',\n {\n title: 'Get Managed Profiles',\n description:\n 'Get all profiles in the CRM pipeline with their relationship statuses, ' +\n 'notes, and tags. Costs 0 credits.',\n inputSchema: z.object({\n status: z.string().optional().describe(\"Filter by relationship status (e.g. 'outreached', 'negotiating', 'contracted')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/manage/profiles${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_crm_summary',\n {\n title: 'Get CRM Summary',\n description:\n 'Get a summary of the CRM pipeline — counts by status, recent activity, etc. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/manage/summary')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_org_stats',\n {\n title: 'Get Organization Stats',\n description:\n 'Get aggregate statistics for the organization — total profiles, enhanced profiles, ' +\n 'scraped data, and more. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/manage/stats')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'upsert_relationship',\n {\n title: 'Upsert Relationship',\n description:\n 'Create or update a CRM relationship for a creator. Set status, notes, tags. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n status: z.string().optional().describe(\"Relationship status (e.g. 'identified', 'outreached', 'negotiating', 'contracted', 'active', 'paused')\"),\n notes: z.string().optional().describe('Free-text notes about the relationship'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n }),\n },\n async (args) => {\n const { identifier, ...body } = args\n const result = await client.patch(`/manage/profiles/${encodeURIComponent(identifier)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_relationship',\n {\n title: 'Delete Relationship',\n description:\n 'Remove a creator from the CRM pipeline. Does not delete the profile itself. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/manage/profiles/${encodeURIComponent(args.identifier)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'upsert_relationships_bulk',\n {\n title: 'Upsert Relationships Bulk',\n description:\n 'Bulk update notes, tags, or status for multiple CRM profiles in one call. ' +\n 'Creates relationships if they do not exist. Max 100 profiles per request. Costs 0 credits.',\n inputSchema: z.object({\n updates: z.array(z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n status: z.string().optional().describe(\"Relationship status (e.g. 'shortlisted', 'outreached', 'negotiating')\"),\n notes: z.string().optional().describe('Free-text notes about the relationship'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n })).min(1).max(100).describe('Array of profile updates (max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/manage/profiles/bulk', { updates: args.updates })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Knowledge tools — KB folders, entries, context search\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerKnowledgeTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_knowledge_folders',\n {\n title: 'List Knowledge Folders',\n description: 'List all knowledge base folders in the organization. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/knowledge/folders')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_knowledge_folder',\n {\n title: 'Create Knowledge Folder',\n description: 'Create a new knowledge base folder. Costs 0 credits.',\n inputSchema: z.object({\n name: z.string().describe('Folder name'),\n description: z.string().optional().describe('Optional description'),\n folder_type: z.enum(['general', 'brand', 'campaign', 'templates', 'research']).optional().describe(\"Folder type (default: 'general')\"),\n parent_folder_id: z.string().optional().describe('UUID of parent folder for nesting'),\n icon_name: z.string().optional().describe('Lucide icon name'),\n color: z.string().optional().describe('Hex color (e.g. #8b5cf6)'),\n }),\n },\n async (args) => {\n const result = await client.post('/knowledge/folders', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_folder_entries',\n {\n title: 'Get Folder Entries',\n description: 'Get all entries in a knowledge base folder. Costs 0 credits.',\n inputSchema: z.object({\n folder_id: z.string().describe('Folder UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/knowledge/folders/${encodeURIComponent(args.folder_id)}/entries${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_knowledge_entry',\n {\n title: 'Create Knowledge Entry',\n description: 'Create a new knowledge base entry in a folder. Costs 0 credits.',\n inputSchema: z.object({\n folder_id: z.string().describe('Folder UUID to add the entry to'),\n name: z.string().describe('Entry name'),\n content: z.string().optional().describe('Entry content (markdown supported)'),\n description: z.string().optional().describe('Short description'),\n source_url: z.string().optional().describe('Source URL reference'),\n }),\n },\n async (args) => {\n const result = await client.post('/knowledge/entries', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_knowledge_entry',\n {\n title: 'Get Knowledge Entry',\n description: 'Get a specific knowledge base entry by ID. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/knowledge/entries/${encodeURIComponent(args.entry_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'update_knowledge_entry',\n {\n title: 'Update Knowledge Entry',\n description: 'Update a knowledge base entry. At least one field required. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n name: z.string().optional().describe('New name'),\n content: z.string().optional().describe('New content'),\n description: z.string().optional().describe('New description'),\n summary: z.string().optional().describe('New summary'),\n folder_id: z.string().optional().describe('Move to a different folder (UUID)'),\n }),\n },\n async (args) => {\n const { entry_id, ...body } = args\n const result = await client.put(`/knowledge/entries/${encodeURIComponent(entry_id)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_knowledge_entry',\n {\n title: 'Delete Knowledge Entry',\n description: 'Delete a knowledge base entry. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/knowledge/entries/${encodeURIComponent(args.entry_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'search_knowledge',\n {\n title: 'Get Knowledge Context',\n description:\n 'Get aggregated brand context from the knowledge base, organized by folder type. ' +\n 'Returns entries for AI agent consumption. Filter by folder type to get specific context. Costs 0 credits.',\n inputSchema: z.object({\n folder_types: z.array(z.string()).optional().describe(\"Filter by folder types (e.g. ['brand', 'campaign', 'research'])\"),\n max_entries: z.number().int().min(1).max(100).optional().describe('Maximum entries to return (default 20, max 100)'),\n include_summaries: z.boolean().optional().describe('Include entry summaries (default true)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.folder_types?.length) params.set('folder_types', args.folder_types.join(','))\n if (args.max_entries !== undefined) params.set('max_entries', String(args.max_entries))\n if (args.include_summaries === false) params.set('include_summaries', 'false')\n const result = await client.get(`/knowledge/context?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Enhance tools — Profile enhancement triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { creditGuard } from './credit-guard'\n\nexport function registerEnhanceTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'enhance_profiles',\n {\n title: 'Enhance Profiles',\n description:\n 'Trigger AI enhancement for one or more profiles. Enhancement adds affinities, ' +\n 'demographics, niche analysis, and more. Returns a job ID — poll with ' +\n 'get_enhancement_status to check progress. Costs 1+ credits.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to enhance'),\n mode: z.enum(['basic', 'enhanced']).optional().describe(\"Enhancement mode: 'basic' (1 credit/profile) or 'enhanced' (2 credits/profile). Default: basic\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering enhancement'),\n auto_confirm: z.boolean().optional().describe('If true, auto-confirms the job without a separate confirm step'),\n authorize_overage: z.boolean().optional().describe('If true, allows proceeding even if credits are insufficient'),\n options: z.object({\n force: z.boolean().optional().describe('Re-enhance even if already enhanced'),\n }).optional().describe('Enhancement options'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { identifiers, options, confirmed, authorize_overage, ...rest } = args\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/enhance/profiles', { profiles: identifiers, ...rest, authorize_overage, dry_run: true }),\n `Enhance ${identifiers.length} profile${identifiers.length !== 1 ? 's' : ''}`,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/enhance/profiles', { profiles: identifiers, ...rest, authorize_overage })\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'enhance_bulk',\n {\n title: 'Enhance Bulk',\n description:\n 'Trigger bulk enhancement for a large set of profiles from a network source (followers/following) or search filters. ' +\n 'Returns a job ID. Costs 1+ credits.',\n inputSchema: z.object({\n source: z.object({\n type: z.enum(['followers', 'following', 'both', 'search']).describe(\"Source type: 'followers'/'following'/'both' (network) or 'search' (filter-based)\"),\n target: z.string().optional().describe('Username of the seed profile (required for followers/following/both)'),\n filters: z.object({\n query: z.string().optional().describe('Search query'),\n niche: z.string().optional().describe('Filter by niche'),\n location: z.string().optional().describe('Filter by location'),\n gender: z.enum(['male', 'female', 'non_binary', 'brand']).optional().describe('Filter by gender'),\n min_followers: z.number().int().optional().describe('Minimum followers'),\n max_followers: z.number().int().optional().describe('Maximum followers'),\n has_contact: z.boolean().optional().describe('Only profiles with contact info'),\n }).optional().describe('Search filters (required for search source)'),\n limit: z.number().int().optional().describe('Max profiles to resolve from source'),\n }).describe('Source specification for profiles to enhance'),\n mode: z.enum(['basic', 'enhanced']).optional().describe(\"Enhancement mode: 'basic' (1 credit) or 'enhanced' (2 credits). Default: basic\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering enhancement'),\n skip_already_enhanced: z.boolean().optional().describe('Skip profiles that are already enhanced'),\n auto_confirm: z.boolean().optional().describe('Auto-confirm the job without a separate confirm step'),\n authorize_overage: z.boolean().optional().describe('Allow proceeding even if credits are insufficient'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { confirmed, authorize_overage, ...rest } = args\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/enhance/bulk', { ...rest, authorize_overage, dry_run: true }),\n `Bulk enhance from ${rest.source.type} source`,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/enhance/bulk', { ...rest, authorize_overage })\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'confirm_enhancement',\n {\n title: 'Confirm Enhancement',\n description:\n 'Confirm and start a pending enhancement job. Some jobs require confirmation ' +\n 'before processing begins (e.g. large batches). Costs 0 credits (charged at creation).',\n inputSchema: z.object({\n job_id: z.string().describe('Enhancement job ID'),\n authorize_overage: z.boolean().optional().describe('Authorize credit overage if needed'),\n }),\n },\n async (args) => {\n const result = await client.post(\n `/enhance/${encodeURIComponent(args.job_id)}/confirm`,\n { authorize_overage: args.authorize_overage },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_enhancement_status',\n {\n title: 'Get Enhancement Status',\n description:\n 'Check the status of an enhancement job. Returns progress, completed count, ' +\n 'and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Enhancement job ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/enhance/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Credit Guard — Pre-execution cost check for expensive MCP tool calls.\n *\n * For operations estimated at ≥100 credits the guard performs a dry-run,\n * fetches the account's current usage, and returns a human-readable\n * confirmation prompt instead of executing the operation.\n *\n * The calling tool adds a `confirmed` boolean parameter. When `confirmed`\n * is true the guard is bypassed and the real request fires immediately.\n */\n\nimport type { CelaviiClient } from '../client.js'\n\nconst CREDIT_THRESHOLD = 100\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface UsageSnapshot {\n total_credits_used: number\n credits_today: number\n plan: string | null\n tier: string | null\n allow_overage: boolean\n}\n\nexport interface CreditGuardResult {\n /** true → proceed with execution */\n proceed: boolean\n /** If proceed is false, this is the confirmation message to show */\n message?: string\n /** Raw dry-run response (forwarded when proceed is true too) */\n dryRunData?: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function fetchUsage(client: CelaviiClient): Promise<UsageSnapshot> {\n try {\n const raw = (await client.get('/me')) as {\n data?: {\n usage?: { total_credits_used?: number; credits_today?: number }\n organization?: { plan?: string; allow_overage?: boolean }\n api_key?: { tier?: string }\n }\n }\n const d = raw?.data ?? (raw as Record<string, unknown>)\n const usage = (d as Record<string, unknown>)?.usage as Record<string, unknown> | undefined\n const org = (d as Record<string, unknown>)?.organization as Record<string, unknown> | undefined\n const key = (d as Record<string, unknown>)?.api_key as Record<string, unknown> | undefined\n return {\n total_credits_used: Number(usage?.total_credits_used ?? 0),\n credits_today: Number(usage?.credits_today ?? 0),\n plan: (org?.plan as string) ?? null,\n tier: (key?.tier as string) ?? null,\n allow_overage: Boolean(org?.allow_overage ?? false),\n }\n } catch {\n return { total_credits_used: 0, credits_today: 0, plan: null, tier: null, allow_overage: false }\n }\n}\n\nfunction formatConfirmation(\n action: string,\n estimatedCredits: number,\n usage: UsageSnapshot,\n dryRunData: unknown,\n): string {\n const lines: string[] = [\n '⚠️ Credit Authorization Required',\n '',\n `Action: ${action}`,\n `Estimated cost: ~${estimatedCredits} credits`,\n '',\n '── Current Account Usage ──',\n `Credits used today: ${usage.credits_today}`,\n `Total credits used: ${usage.total_credits_used}`,\n ...(usage.plan ? [`Plan: ${usage.plan}`] : []),\n ...(usage.tier ? [`API tier: ${usage.tier}`] : []),\n `Overage billing: ${usage.allow_overage ? 'enabled' : 'disabled'}`,\n '',\n '── Dry-Run Details ──',\n JSON.stringify(dryRunData, null, 2),\n '',\n 'To proceed, call this tool again with confirmed: true.',\n ]\n return lines.join('\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Guard\n// ---------------------------------------------------------------------------\n\n/**\n * Run the credit guard for a tool call that supports `dry_run`.\n *\n * @param client Celavii API client\n * @param confirmed Whether the user has already confirmed\n * @param dryRunFn A function that calls the API with dry_run: true and\n * returns the raw response. The guard will extract\n * `estimated_cost.credits` from `data` or from the root.\n * @param action Human-readable description of the operation\n */\nexport async function creditGuard(\n client: CelaviiClient,\n confirmed: boolean | undefined,\n dryRunFn: () => Promise<unknown>,\n action: string,\n): Promise<CreditGuardResult> {\n // Bypass when already confirmed\n if (confirmed) {\n return { proceed: true }\n }\n\n // Execute dry-run\n const dryResult = await dryRunFn()\n\n // Extract estimated credits from common response shapes\n const root = dryResult as Record<string, unknown>\n const data = (root?.data ?? root) as Record<string, unknown>\n const estCost = data?.estimated_cost as Record<string, unknown> | undefined\n const estimatedCredits = Number(estCost?.credits ?? data?.eligible ?? 0)\n\n // If below threshold, proceed without confirmation\n if (estimatedCredits < CREDIT_THRESHOLD) {\n return { proceed: true, dryRunData: dryResult }\n }\n\n // Above threshold → fetch usage and build confirmation prompt\n const usage = await fetchUsage(client)\n const message = formatConfirmation(action, estimatedCredits, usage, data)\n\n return { proceed: false, message, dryRunData: dryResult }\n}\n","/**\n * Scrape tools — Data collection triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerScrapeTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'scrape_followers',\n {\n title: 'Scrape Followers',\n description:\n 'Trigger a follower scrape for a profile. Collects the full follower list. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits.',\n inputSchema: z.object({\n username: z.string().describe('Instagram username to scrape followers for'),\n limit: z.number().int().optional().describe('Max followers to scrape (default: all)'),\n }),\n },\n async (args) => {\n try {\n const { limit, ...rest } = args\n const result = await client.post('/scrape/followers', { ...rest, ...(limit !== undefined && { max_results: limit }) })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_following',\n {\n title: 'Scrape Following',\n description:\n 'Trigger a following scrape for a profile. Collects who they follow. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits.',\n inputSchema: z.object({\n username: z.string().describe('Instagram username to scrape following for'),\n limit: z.number().int().optional().describe('Max following to scrape (default: all)'),\n }),\n },\n async (args) => {\n try {\n const { limit, ...rest } = args\n const result = await client.post('/scrape/following', { ...rest, ...(limit !== undefined && { max_results: limit }) })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_followers_bulk',\n {\n title: 'Bulk Scrape Followers',\n description:\n 'Trigger a follower scrape for multiple profiles in a single Apify run. ' +\n 'Much more efficient than calling scrape_followers repeatedly — uses 1 API call, ' +\n '1 DB connection, and 1 Apify run instead of N. Max 50 profiles per request. ' +\n 'Returns a single job ID — poll with get_scrape_status. Costs 2 credits + processing. ' +\n 'IMPORTANT: TikTok bulk scrapes limited to 10 profiles per request due to rate limiting.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional()\n .describe('Array of usernames to scrape followers for (max 50 for Instagram, max 10 for TikTok)'),\n profile_ids: z.array(z.string()).max(50).optional()\n .describe('Array of profile IDs (ig:XXX or tt:XXX) to scrape followers for (max 50 for Instagram, max 10 for TikTok)'),\n limit: z.number().int().optional()\n .describe('Max followers to scrape per profile (default: 10000)'),\n platform: PlatformSchema.optional()\n .describe('Platform override — auto-detected from profiles if not specified'),\n dry_run: z.boolean().optional()\n .describe('If true, returns cost estimate without triggering the scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.platform) body.platform = args.platform\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/followers/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_following_bulk',\n {\n title: 'Bulk Scrape Following',\n description:\n 'Trigger a following scrape for multiple profiles in a single Apify run. ' +\n 'Much more efficient than calling scrape_following repeatedly — uses 1 API call, ' +\n '1 DB connection, and 1 Apify run instead of N. Max 50 profiles per request. ' +\n 'Returns a single job ID — poll with get_scrape_status. Costs 2 credits + processing. ' +\n 'IMPORTANT: TikTok bulk scrapes limited to 10 profiles per request due to rate limiting.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional()\n .describe('Array of usernames to scrape following for (max 50 for Instagram, max 10 for TikTok)'),\n profile_ids: z.array(z.string()).max(50).optional()\n .describe('Array of profile IDs (ig:XXX or tt:XXX) to scrape following for (max 50 for Instagram, max 10 for TikTok)'),\n limit: z.number().int().optional()\n .describe('Max following to scrape per profile (default: 10000)'),\n platform: PlatformSchema.optional()\n .describe('Platform override — auto-detected from profiles if not specified'),\n dry_run: z.boolean().optional()\n .describe('If true, returns cost estimate without triggering the scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.platform) body.platform = args.platform\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/following/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_locations',\n {\n title: 'Scrape Locations',\n description:\n 'Scrape posts from a specific Instagram location/place. ' +\n 'Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n location_id: z.string().optional().describe('Instagram location ID'),\n location_name: z.string().optional().describe('Location name to search for'),\n limit: z.number().int().optional().describe('Max posts to scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.location_id) body.location_ids = [args.location_id]\n if (args.location_name) body.start_urls = [`https://www.instagram.com/explore/locations/${args.location_name}/`]\n if (args.limit !== undefined) body.max_items = args.limit\n const result = await client.post('/scrape/locations', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_hashtags',\n {\n title: 'Scrape Hashtags',\n description:\n 'Scrape posts from a specific hashtag. Collects recent posts using that hashtag. ' +\n 'Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n hashtag: z.string().describe('Hashtag to scrape (without #)'),\n limit: z.number().int().optional().describe('Max posts to scrape'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/hashtags', {\n hashtags: [args.hashtag],\n ...(args.limit !== undefined && { max_items: args.limit }),\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_urls',\n {\n title: 'Scrape URLs',\n description:\n 'Scrape specific Instagram post or reel URLs. Extracts engagement data, ' +\n 'comments, and media. Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n urls: z.array(z.string()).describe('Array of Instagram post/reel URLs'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/urls', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_scrape_status',\n {\n title: 'Get Scrape Status',\n description:\n 'Check the status of a scrape job. Returns progress and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Scrape job ID'),\n }),\n },\n async (args) => {\n try {\n const result = await client.get(`/scrape/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // X (Twitter) triggers — Phase 3B (5 tools)\n // Backed by /api/v1/scrape/x/* (Shape A subpaths)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'scrape_x_followers',\n {\n title: 'Scrape X Followers',\n description:\n 'Trigger an X (Twitter) follower scrape for a profile via apidojo/twitter-user-scraper. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits + processing.',\n inputSchema: z.object({\n username: z.string().optional().describe('X username (without @)'),\n profile_id: z.string().optional().describe('x: prefixed profile ID (e.g. x:elonmusk)'),\n limit: z.number().int().optional().describe('Max followers to scrape (default: 10000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.username) body.username = args.username\n if (args.profile_id) body.profile_id = args.profile_id\n if (args.limit !== undefined) body.max_results = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/followers', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_followers_bulk',\n {\n title: 'Bulk Scrape X Followers',\n description:\n 'Trigger X follower scrapes for up to 50 profiles in one request. Each profile gets ' +\n 'its own search row + queue job — independent retries. Costs 2 credits per profile.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional().describe('Array of X usernames (max 50)'),\n profile_ids: z.array(z.string()).max(50).optional().describe('Array of x: prefixed profile IDs (max 50)'),\n limit: z.number().int().optional().describe('Max followers per profile (default: 5000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/followers/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_following',\n {\n title: 'Scrape X Following',\n description:\n 'Trigger an X (Twitter) following scrape for a profile. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits + processing.',\n inputSchema: z.object({\n username: z.string().optional().describe('X username (without @)'),\n profile_id: z.string().optional().describe('x: prefixed profile ID'),\n limit: z.number().int().optional().describe('Max following to scrape (default: 10000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.username) body.username = args.username\n if (args.profile_id) body.profile_id = args.profile_id\n if (args.limit !== undefined) body.max_results = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/following', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_following_bulk',\n {\n title: 'Bulk Scrape X Following',\n description:\n 'Trigger X following scrapes for up to 50 profiles in one request. ' +\n 'Costs 2 credits per profile.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional().describe('Array of X usernames (max 50)'),\n profile_ids: z.array(z.string()).max(50).optional().describe('Array of x: prefixed profile IDs (max 50)'),\n limit: z.number().int().optional().describe('Max following per profile (default: 5000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/following/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_hashtags',\n {\n title: 'Scrape X Hashtags',\n description:\n 'Scrape recent X (Twitter) posts matching one or more hashtags via kaitoeasyapi tweet scraper. ' +\n 'Supports advanced filters (media-only, blue-verified, has-engagement) and sort order. ' +\n 'Returns a job ID. Costs 1 credit + processing.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).min(1).max(10).describe('1–10 hashtags (with or without #)'),\n max_items: z.number().int().optional().describe('Max tweets per hashtag (default 100)'),\n x_filters: z.object({\n media: z.boolean().optional().describe('Tweets with media only'),\n verified: z.boolean().optional().describe('Blue-verified accounts only'),\n engagement: z.boolean().optional().describe('Tweets with engagement only'),\n }).optional().describe('Advanced filters'),\n x_sort: z.enum(['Latest', 'Top']).optional().describe(\"Sort order (default 'Latest')\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/x/hashtags', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // YouTube triggers — Phase 3C (4 tools)\n // Backed by /api/v1/scrape/youtube/* (mix of runCollect + Data API v3)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'scrape_youtube_commenters',\n {\n title: 'Scrape YouTube Commenters',\n description:\n 'YouTube does not expose subscriber lists — the closest network signal is the set of ' +\n 'channels commenting on a creator\\'s videos. Triggers a batched commenter fetch ' +\n '(channels.list + videos.list + per-video commentThreads.list). Returns a job ID. ' +\n 'Costs 2 credits + YouTube Data API v3 quota usage.',\n inputSchema: z.object({\n profile_id: z.string().describe('yt: prefixed channel ID (e.g. yt:UCxxxxx)'),\n video_count: z.number().int().min(1).max(50).optional().describe('Videos to sample (default 5, max 50)'),\n comments_per_video: z.number().int().min(1).max(500).optional().describe('Comments per video (default 100, max 500)'),\n dry_run: z.boolean().optional().describe('If true, returns quota estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/commenters', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_hashtags',\n {\n title: 'Scrape YouTube by Keyword',\n description:\n 'YouTube keyword/hashtag search via streamers/youtube-scraper. Each input becomes a search query. ' +\n 'Returns a job ID. Costs 1 credit + processing.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).min(1).max(10).describe('1–10 keyword queries (with or without #)'),\n per_hashtag_limit: z.number().int().optional().describe('Max videos per query (default 5)'),\n yt_include_shorts: z.boolean().optional().describe('Include YouTube Shorts (default true)'),\n yt_duration: z.enum(['all', 'short', 'medium', 'long']).optional().describe(\"Duration filter (default 'all')\"),\n yt_upload_date: z.enum(['all', 'hour', 'today', 'week', 'month', 'year']).optional().describe(\"Upload date filter (default 'all')\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/hashtags', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_trending',\n {\n title: 'Scrape YouTube Trending',\n description:\n 'Pull the YouTube trending feed via apidojo/youtube-scraper. Returns the most popular ' +\n 'uploads in the requested timeframe. Costs 1 credit + processing.',\n inputSchema: z.object({\n max_items: z.number().int().min(1).max(200).optional().describe('Max trending videos (default 50, max 200)'),\n yt_include_shorts: z.boolean().optional().describe('Include YouTube Shorts (default true)'),\n yt_duration: z.enum(['all', 'short', 'medium', 'long']).optional().describe('Duration filter'),\n yt_upload_date: z.enum(['all', 'hour', 'today', 'week', 'month', 'year']).optional().describe('Upload date filter'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/trending', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_videos',\n {\n title: 'Collect YouTube Channel Videos',\n description:\n \"Collect a YouTube channel's recent videos via the YouTube Data API v3 (hybrid path — \" +\n 'NOT Apify). Costs 2 credits + Data API v3 quota usage.',\n inputSchema: z.object({\n target: z.string().describe('Channel target — yt: prefixed ID, @handle, or YouTube channel URL'),\n videos_limit: z.number().int().min(1).max(500).optional().describe('Max videos (default 50, max 500)'),\n search_name: z.string().optional().describe('Optional display name for the resulting search'),\n dry_run: z.boolean().optional().describe('If true, returns quota estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/videos', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n}\n","/**\n * Refine tools — AI refinement triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { creditGuard } from './credit-guard'\n\nexport function registerRefineTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'refine_profiles',\n {\n title: 'Refine Profiles',\n description:\n 'Trigger AI refinement for one or more profiles. Refinement uses AI to ' +\n 'improve and enrich profile data — better niche classification, bio analysis, ' +\n 'content themes, etc. Returns a job ID — poll with get_refinement_status. Costs 1+ credits.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to refine'),\n list_id: z.string().optional().describe('List UUID — refine all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — refine all creators in this campaign'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering refinement'),\n skip_already_refined: z.boolean().optional().describe('Skip profiles that have already been refined'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { identifiers, list_id, campaign_id, confirmed, ...rest } = args\n\n // Build request body based on input mode\n const bodyBase: Record<string, unknown> = { ...rest }\n if (identifiers && identifiers.length > 0) {\n bodyBase.profiles = identifiers\n } else if (list_id) {\n bodyBase.list_id = list_id\n } else if (campaign_id) {\n bodyBase.campaign_id = campaign_id\n } else {\n return { content: [{ type: 'text' as const, text: 'Error: Provide identifiers, list_id, or campaign_id' }] }\n }\n\n // Determine label for credit guard\n const label = list_id\n ? `Refine list ${list_id}`\n : campaign_id\n ? `Refine campaign ${campaign_id}`\n : `Refine ${identifiers?.length || 0} profile${(identifiers?.length || 0) !== 1 ? 's' : ''}`\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/refine/profiles', { ...bodyBase, dry_run: true }),\n label,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/refine/profiles', bodyBase)\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_refinement_status',\n {\n title: 'Get Refinement Status',\n description:\n 'Check the status of a refinement job. Returns progress and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Refinement job ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/refine/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Jobs tools — Job coverage and status tracking\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerJobsTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_job_coverage',\n {\n title: 'Get Job Coverage',\n description:\n 'Get aggregate job coverage stats for a list or campaign — shows how many profiles have been enhanced, refined, ' +\n 'or scraped (followers/following) and how many are pending or not started. ' +\n 'Provide a list_id or campaign_id. Optionally filter by job_type or platform. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().optional().describe('List UUID — get coverage for all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — get coverage for all creators in this campaign'),\n job_type: z.enum(['enhance', 'refine', 'followers_scrape', 'following_scrape']).optional()\n .describe(\"Filter to a single job type (default: all)\"),\n platform: PlatformSchema.optional()\n .describe(\"Filter by platform (default: all)\"),\n tags: z.array(z.string()).optional().describe('Filter by tags (reserved for future use)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n if (args.job_type) params.set('job_type', args.job_type)\n if (args.platform) params.set('platform', args.platform)\n if (args.tags?.length) params.set('tags', args.tags.join(','))\n const result = await client.get(`/jobs/coverage?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'list_jobs',\n {\n title: 'List Jobs',\n description:\n 'List all jobs for the organization — enhancement, refinement, and scrape jobs. ' +\n 'Returns a unified view sorted by most recent. Filter by type and/or status. Costs 0 credits.',\n inputSchema: z.object({\n type: z.enum(['enhance', 'refine', 'followers_scrape', 'following_scrape']).optional()\n .describe('Filter by job type (default: all)'),\n status: z.string().optional()\n .describe(\"Filter by status (e.g. 'completed', 'failed', 'processing', 'pending', 'queued')\"),\n limit: z.number().int().min(1).max(100).optional()\n .describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional()\n .describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.type) params.set('type', args.type)\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/jobs${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Tool registration registry — single source of truth.\n *\n * Both entry points register tools via this helper:\n * - stdio entry: packages/mcp/src/server.ts → createServer()\n * - remote entry: src/app/api/mcp/[transport]/route.ts → /api/mcp/mcp\n *\n * Before this module existed, both files had their own copy-pasted list\n * of `registerXxxTools(server, client)` calls, which drifted across\n * versions:\n * - 0.1.22 added `jobs` group → only stdio updated; remote was missing\n * `list_jobs` + `get_job_coverage` for two minor versions until v3.\n * - 0.2.0 added 13 YT/X tools → tool_count comments drifted \"61 tools\"\n * vs \"70 tools\" vs \"83 tools\" because two places had to be edited.\n *\n * Now there's one list. To add a tool group:\n * 1. Add the registrar function in `packages/mcp/src/tools/<group>.ts`\n * 2. Add the entry to `TOOL_GROUPS` and `REGISTRARS` below\n *\n * Both stdio and remote pick up the new group automatically — no second\n * edit, no drift possible.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nimport { registerMetaTools } from './meta.js'\nimport { registerProfileTools } from './profiles.js'\nimport { registerCampaignTools } from './campaigns.js'\nimport { registerListTools } from './lists.js'\nimport { registerAnalyticsTools } from './analytics.js'\nimport { registerContentTools } from './content.js'\nimport { registerManageTools } from './manage.js'\nimport { registerKnowledgeTools } from './knowledge.js'\nimport { registerEnhanceTools } from './enhance.js'\nimport { registerScrapeTools } from './scrape.js'\nimport { registerRefineTools } from './refine.js'\nimport { registerJobsTools } from './jobs.js'\n\n/**\n * Available tool groups, in canonical registration order.\n *\n * `meta` is always loaded (account info + usage); it sits outside this\n * list because the `CELAVII_TOOLS` env var filter never excludes it.\n */\nexport const TOOL_GROUPS = [\n 'profiles',\n 'campaigns',\n 'lists',\n 'analytics',\n 'content',\n 'manage',\n 'knowledge',\n 'enhance',\n 'scrape',\n 'refine',\n 'jobs',\n] as const\n\nexport type ToolGroup = (typeof TOOL_GROUPS)[number]\n\ntype Registrar = (server: McpServer, client: CelaviiClient) => void\n\n/**\n * Filterable registrars. Order is the canonical registration order, which\n * affects the order tools appear in `tools/list` responses (some clients\n * surface them in registration order in their tool picker).\n */\nconst REGISTRARS: Record<ToolGroup, Registrar> = {\n profiles: registerProfileTools,\n campaigns: registerCampaignTools,\n lists: registerListTools,\n analytics: registerAnalyticsTools,\n content: registerContentTools,\n manage: registerManageTools,\n knowledge: registerKnowledgeTools,\n enhance: registerEnhanceTools,\n scrape: registerScrapeTools,\n refine: registerRefineTools,\n jobs: registerJobsTools,\n}\n\nexport interface RegisterAllOptions {\n /**\n * Optional filter — only register tools in these groups. If omitted or\n * empty, every group is registered. `meta` is always registered\n * regardless.\n */\n groups?: ToolGroup[]\n}\n\n/**\n * Register every tool group on the given MCP server, optionally filtered\n * by `opts.groups`. `meta` is always registered.\n */\nexport function registerAllTools(\n server: McpServer,\n client: CelaviiClient,\n opts: RegisterAllOptions = {},\n): void {\n const enabled =\n opts.groups && opts.groups.length > 0 ? new Set(opts.groups) : null\n\n // Meta tools (account info, usage) are always registered, regardless of\n // the CELAVII_TOOLS filter.\n registerMetaTools(server, client)\n\n for (const group of TOOL_GROUPS) {\n if (!enabled || enabled.has(group)) {\n REGISTRARS[group](server, client)\n }\n }\n}\n"],"mappings":";;;AAkBA,SAAS,4BAA4B;;;ACPrC,SAAS,iBAAiB;;;ACJ1B,IAAM,mBAAmB;AAElB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACE,SACO,MACA,QACA,YACP;AACA,UAAM,OAAO;AAJN;AACA;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EAER,YAAY,QAAgB,SAAkB;AAC5C,SAAK,SAAS;AACd,SAAK,WAAW,WAAW,kBAAkB,QAAQ,OAAO,EAAE;AAAA,EAChE;AAAA,EAEA,MAAc,QAAQ,MAAc,MAAsC;AACxE,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAClC,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,GAAG;AAAA,MACH,SAAS;AAAA,QACP,eAAe,UAAU,KAAK,MAAM;AAAA,QACpC,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,IAAI,KAAK;AAAA,IACxB,QAAQ;AACN,YAAM,IAAI;AAAA,QACR,QAAQ,IAAI,MAAM;AAAA,QAClB;AAAA,QACA,IAAI;AAAA,MACN;AAAA,IACF;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM;AACZ,YAAM,MAAM,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM;AACrD,YAAM,OAAO,KAAK,OAAO,QAAQ;AACjC,YAAM,IAAI,gBAAgB,KAAK,MAAM,IAAI,QAAQ,KAAK,OAAO,WAAW;AAAA,IAC1E;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,MAAgC;AACxC,WAAO,KAAK,QAAQ,IAAI;AAAA,EAC1B;AAAA,EAEA,MAAM,KAAK,MAAc,MAAkC;AACzD,WAAO,KAAK,QAAQ,MAAM;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,MAAc,MAAiC;AACzD,WAAO,KAAK,QAAQ,MAAM;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,MAAc,MAAiC;AACvD,WAAO,KAAK,QAAQ,MAAM;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,MAAc,MAAkC;AAC3D,WAAO,KAAK,QAAQ,MAAM;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AAAA,EACH;AACF;;;AC1FA,SAAS,SAAS;AAIX,SAAS,kBAAkB,QAAmB,QAAuB;AAC1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,KAAK;AACrC,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,QAAQ;AACxC,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa,EAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,gBAAgB;AAChD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACnDA,SAAS,KAAAA,UAAS;;;ACKlB,SAAS,KAAAC,UAAS;AAEX,IAAM,YAAY,CAAC,aAAa,UAAU,WAAW,GAAG;AAIxD,IAAM,iBAAiBA,GAAE,KAAK,SAAS;;;ADNvC,SAAS,qBAAqB,QAAmB,QAAuB;AAC7E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaC,GAAE,OAAO;AAAA,QACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qEAAgE;AAAA,QACtG,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2DAA2D;AAAA,QACjG,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,QACvG,QAAQA,GAAE,KAAK,CAAC,QAAQ,UAAU,cAAc,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QAChG,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,aAAaA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,QACvF,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACrF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,UAAI,KAAK,SAAU,QAAO,IAAI,YAAY,KAAK,QAAQ;AACvD,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,MAAM;AACtD,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,SAAS,MAAM,OAAO,IAAI,oBAAoB,MAAM,EAAE;AAC5D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,oEAAoE;AAAA,QAC7G,YAAYA,GAAE,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,qEAAqE;AAAA,QAC5H,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACrF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,aAAO,IAAI,SAAS,KAAK,WAAW,KAAK,GAAG,CAAC;AAC7C,UAAI,KAAK,WAAY,QAAO,IAAI,cAAc,KAAK,UAAU;AAC7D,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,SAAS,MAAM,OAAO,IAAI,+BAA+B,MAAM,EAAE;AACvE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,6CAA6C;AAAA,MACzF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,kBAAkB,EAAE,UAAU,KAAK,YAAY,CAAC;AACjF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,8CAA8C;AAAA,MAChF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,EAAE;AAClF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,aAAa;AAC7F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,QAClE,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QACnG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,SAAS,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAC7G,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,UAAU;AAC1F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,QAClE,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACvG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,aAAa,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACjH,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,QAClE,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACvG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,aAAa,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACjH,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,eAAe;AAC/F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,mBAAmB,KAAK,UAAU,CAAC,UAAU;AAC1F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAMA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,mEAAmE;AAAA,QACnG,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,WAAWA,GAAE,MAAM,cAAc,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,QAC5E,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MACvG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B;AAAA,QAC3D,YAAY,KAAK;AAAA,QACjB,eAAe,KAAK;AAAA,QACpB,eAAe,KAAK;AAAA,QACpB,WAAW,KAAK;AAAA,QAChB,OAAO,KAAK;AAAA,MACd,CAAC;AACD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,wDAAwD;AAAA,QAClG,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QAC5E,WAAWA,GAAE,MAAM,cAAc,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,QAC5E,eAAeA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAClG,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MACvG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,mCAAmC;AAAA,QAClE,aAAa,KAAK;AAAA,QAClB,eAAe,KAAK;AAAA,QACpB,eAAe,KAAK;AAAA,QACpB,WAAW,KAAK;AAAA,QAChB,eAAe,KAAK;AAAA,QACpB,OAAO,KAAK;AAAA,MACd,CAAC;AACD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;AE5SA,SAAS,KAAAC,UAAS;AAIX,SAAS,sBAAsB,QAAmB,QAAuB;AAC9E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,QAAQA,GAAE,KAAK,CAAC,UAAU,SAAS,aAAa,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,QAC5G,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,MACzG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,aAAa,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACjE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,cAAc,mBAAmB,KAAK,WAAW,CAAC,UAAU;AAC5F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QAChD,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,cAAc,mBAAmB,KAAK,WAAW,CAAC,YAAY,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAClH,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,eAAe;AAAA,QAChD,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,cAAc,mBAAmB,KAAK,WAAW,CAAC,WAAW,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACjH,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACvFA,SAAS,KAAAC,UAAS;AAKX,SAAS,kBAAkB,QAAmB,QAAuB;AAC1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaC,GAAE,OAAO;AAAA,QACpB,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,SAAS,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAC7D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,MAAMA,GAAE,OAAO,EAAE,SAAS,kBAAkB;AAAA,QAC5C,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,UAAU,EAAE,MAAM,KAAK,MAAM,aAAa,KAAK,YAAY,CAAC;AAC7F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,UAAU,mBAAmB,KAAK,OAAO,CAAC,EAAE;AAC5E,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,QACxC,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,UAAU;AAAA,QAC/C,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,EAAE,SAAS,GAAG,KAAK,IAAI;AAC7B,YAAM,SAAS,MAAM,OAAO,MAAM,UAAU,mBAAmB,OAAO,CAAC,IAAI,IAAI;AAC/E,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,OAAO,UAAU,mBAAmB,KAAK,OAAO,CAAC,EAAE;AAC/E,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,QACxC,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,+FAA+F;AAAA,QACnJ,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QACnF,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QACnF,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iEAAiE;AAAA,QAC7G,gBAAgBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAClG,UAAU,eAAe,SAAS,EAAE,SAAS,oBAAoB;AAAA,QACjE,iBAAiBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,QAChH,gBAAgBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,QAC9G,sBAAsBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,QAC1H,sBAAsBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,QAC1H,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,uDAAkD;AAAA,QAChG,qBAAqBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uFAAuF;AAAA,QAC3I,WAAWA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0EAA0E;AAAA,MACvH,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,WAAW,OAAW,QAAO,IAAI,UAAU,OAAO,KAAK,MAAM,CAAC;AACvE,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,kBAAkB,OAAW,QAAO,IAAI,iBAAiB,OAAO,KAAK,aAAa,CAAC;AAC5F,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,UAAI,KAAK,eAAgB,QAAO,IAAI,kBAAkB,KAAK,cAAc;AACzE,UAAI,KAAK,SAAU,QAAO,IAAI,YAAY,KAAK,QAAQ;AACvD,UAAI,KAAK,oBAAoB,OAAW,QAAO,IAAI,mBAAmB,OAAO,KAAK,eAAe,CAAC;AAClG,UAAI,KAAK,mBAAmB,OAAW,QAAO,IAAI,kBAAkB,OAAO,KAAK,cAAc,CAAC;AAC/F,UAAI,KAAK,yBAAyB,OAAW,QAAO,IAAI,wBAAwB,OAAO,KAAK,oBAAoB,CAAC;AACjH,UAAI,KAAK,yBAAyB,OAAW,QAAO,IAAI,wBAAwB,OAAO,KAAK,oBAAoB,CAAC;AACjH,UAAI,KAAK,QAAQ,KAAK,KAAK,SAAS,EAAG,QAAO,IAAI,QAAQ,KAAK,KAAK,KAAK,GAAG,CAAC;AAC7E,UAAI,KAAK,oBAAqB,QAAO,IAAI,uBAAuB,KAAK,mBAAmB;AACxF,UAAI,KAAK,cAAc,OAAW,QAAO,IAAI,aAAa,OAAO,KAAK,SAAS,CAAC;AAChF,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,UAAU,mBAAmB,KAAK,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACzG,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,QACxC,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,0CAA0C;AAAA,MACtF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,UAAU,mBAAmB,KAAK,OAAO,CAAC;AAAA,QAC1C,EAAE,UAAU,KAAK,YAAY;AAAA,MAC/B;AACA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,OAAO,EAAE,SAAS,WAAW;AAAA,QACxC,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,6CAA6C;AAAA,MACzF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,UAAU,mBAAmB,KAAK,OAAO,CAAC;AAAA,QAC1C,EAAE,UAAU,KAAK,YAAY;AAAA,MAC/B;AACA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;AC5KA,SAAS,KAAAC,UAAS;AAMlB,IAAM,qBAAqBC,GAAE,OAAO;AAAA,EAClC,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EACnG,OAAOA,GAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,0DAA0D;AACjH,CAAC;AAGD,IAAM,iBAAiBA,GAAE,OAAO;AAAA,EAC9B,OAAOA,GAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,EAC/G,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mCAAmC;AACjG,CAAC;AAGD,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EACnC,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EACnG,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAA8C;AAAA,EACtF,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAAuD;AACrG,CAAC;AAGM,SAAS,uBAAuB,QAAmB,QAAuB;AAC/E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,aAAa,OAAQ,QAAO,IAAI,eAAe,KAAK,YAAY,KAAK,GAAG,CAAC;AAClF,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,YAAM,SAAS,MAAM,OAAO,IAAI,2BAA2B,MAAM,EAAE;AACnE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,YAAM,SAAS,MAAM,OAAO,IAAI,wBAAwB,MAAM,EAAE;AAChE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,YAAM,SAAS,MAAM,OAAO,IAAI,qBAAqB,MAAM,EAAE;AAC7D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,aAAa,OAAQ,QAAO,IAAI,eAAe,KAAK,YAAY,KAAK,GAAG,CAAC;AAClF,UAAI,KAAK,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACpD,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,YAAM,SAAS,MAAM,OAAO,IAAI,8BAA8B,MAAM,EAAE;AACtE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,aAAa,OAAQ,QAAO,IAAI,aAAa,KAAK,YAAY,KAAK,GAAG,CAAC;AAChF,UAAI,KAAK,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACpD,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,YAAM,SAAS,MAAM,OAAO,IAAI,8BAA8B,MAAM,EAAE;AACtE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,6DAA6D;AAAA,QACpG,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,aAAO,IAAI,YAAY,KAAK,SAAS,KAAK,GAAG,CAAC;AAC9C,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,SAAS,MAAM,OAAO,IAAI,+BAA+B,MAAM,EAAE;AACvE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,OAAO,EAAE,SAAS,qEAAqE;AAAA,QACnG,eAAeA,GAAE,KAAK,CAAC,OAAO,SAAS,SAAS,YAAY,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,QACvI,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,QAC/E,MAAMA,GAAE,KAAK,CAAC,cAAc,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,QAC7F,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACtG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,aAAO,IAAI,YAAY,KAAK,QAAQ;AACpC,UAAI,KAAK,cAAe,QAAO,IAAI,iBAAiB,KAAK,aAAa;AACtE,UAAI,KAAK,mBAAmB,OAAW,QAAO,IAAI,kBAAkB,OAAO,KAAK,cAAc,CAAC;AAC/F,UAAI,KAAK,KAAM,QAAO,IAAI,QAAQ,KAAK,IAAI;AAC3C,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,YAAM,SAAS,MAAM,OAAO,IAAI,6BAA6B,MAAM,EAAE;AACrE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,QACrF,QAAQA,GAAE,OAAO;AAAA,UACf,MAAMA,GAAE,KAAK,CAAC,aAAa,WAAW,CAAC,EAAE,SAAS,yCAAyC;AAAA,UAC3F,QAAQA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,UACnE,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,QAC7G,CAAC,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAAA,QAC9E,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAA8C;AAAA,QACtF,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAAuD;AAAA,QACnG,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yHAAyH;AAAA,MAC5K,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,qBAAqB,IAAI;AAC1D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,IACf;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,aAAa,OAAQ,QAAO,IAAI,YAAY,KAAK,YAAY,KAAK,GAAG,CAAC;AAC/E,UAAI,KAAK,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACpD,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,YAAM,SAAS,MAAM,OAAO,IAAI,2BAA2B,MAAM,EAAE;AACnE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,QAC/F,QAAQA,GAAE,OAAO;AAAA,UACf,MAAMA,GAAE,KAAK,CAAC,aAAa,WAAW,CAAC,EAAE,SAAS,yCAAyC;AAAA,UAC3F,QAAQA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,UACnE,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,QAC7G,CAAC,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,QAC7E,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kDAA6C;AAAA,QACrF,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2DAAsD;AAAA,QAClG,SAASA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MACpG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B,IAAI;AACjE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,aAAaA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,QACnG,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAA8C;AAAA,QACtF,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAAuD;AAAA,QACnG,UAAU,eAAe,SAAS,EAAE,SAAS,4CAA4C;AAAA,QACzF,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACtG,YAAYA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC1G,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,aAAa,OAAQ,QAAO,IAAI,YAAY,KAAK,YAAY,KAAK,GAAG,CAAC;AAC/E,UAAI,KAAK,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACpD,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,UAAI,KAAK,SAAU,QAAO,IAAI,YAAY,KAAK,QAAQ;AACvD,UAAI,KAAK,SAAS,OAAW,QAAO,IAAI,QAAQ,OAAO,KAAK,IAAI,CAAC;AACjE,UAAI,KAAK,eAAe,OAAW,QAAO,IAAI,cAAc,OAAO,KAAK,UAAU,CAAC;AAEnF,YAAM,SAAS,MAAM,OAAO,IAAI,4BAA4B,MAAM,EAAE;AACpE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAMA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,MAAMA,GAAE,OAAO,EAAE,SAAS,qDAAqD;AAAA,MACjF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,IAAI,iCAAiC,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAChG,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,MAAMA,GAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,QAChE,uBAAuBA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAClH,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MAC1G,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,KAAK,KAAK,CAAC;AACtD,YAAI,KAAK,0BAA0B,OAAW,QAAO,IAAI,yBAAyB,OAAO,KAAK,qBAAqB,CAAC;AACpH,YAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,cAAM,SAAS,MAAM,OAAO,IAAI,4BAA4B,MAAM,EAAE;AACpE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaA,GAAE,OAAO;AAAA,QACpB,gBAAgBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,QACxI,kBAAkBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,QACpF,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QACjG,iBAAiBA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,QACzH,uBAAuBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACrG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,wBAAwB,IAAI;AAC7D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACF;;;ACxVA,SAAS,KAAAC,UAAS;AAKX,SAAS,qBAAqB,QAAmB,QAAuB;AAC7E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaC,GAAE,OAAO;AAAA,QACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,sDAAiD;AAAA,QAC5E,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,QACnE,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,QAClG,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAAwD;AAAA,QAC9F,MAAMA,GAAE,KAAK,CAAC,aAAa,cAAc,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,QACzG,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACtG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,aAAO,IAAI,SAAS,KAAK,KAAK;AAC9B,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,UAAI,KAAK,mBAAmB,OAAW,QAAO,IAAI,kBAAkB,OAAO,KAAK,cAAc,CAAC;AAC/F,UAAI,KAAK,MAAO,QAAO,IAAI,SAAS,KAAK,KAAK;AAC9C,UAAI,KAAK,KAAM,QAAO,IAAI,QAAQ,KAAK,IAAI;AAC3C,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,YAAM,SAAS,MAAM,OAAO,IAAI,mBAAmB,MAAM,EAAE;AAC3D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAMA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaA,GAAE,OAAO;AAAA,QACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,sDAAiD;AAAA,QAC5E,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,QACnE,gBAAgBA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,QAC/E,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAC7E,UAAU,eAAe,SAAS,EAAE,SAAS,oBAAoB;AAAA,QACjE,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,wEAAwE;AAAA,QAC5H,MAAMA,GAAE,KAAK,CAAC,aAAa,cAAc,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,QACzG,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACtG,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B;AAAA,QAC3D,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,QACb,gBAAgB,KAAK;AAAA,QACrB,OAAO,KAAK;AAAA,QACZ,UAAU,KAAK;AAAA,QACf,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,MACd,CAAC;AACD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACxEA,SAAS,KAAAC,UAAS;AAIX,SAAS,oBAAoB,QAAmB,QAAuB;AAC5E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,QACvH,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACpG,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,mBAAmB,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACvE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,iBAAiB;AACjD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,eAAe;AAC/C,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,QAClE,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wGAAwG;AAAA,QAC/I,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QAC9E,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,MACzE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAChC,YAAM,SAAS,MAAM,OAAO,MAAM,oBAAoB,mBAAmB,UAAU,CAAC,IAAI,IAAI;AAC5F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,GAAE,OAAO;AAAA,QACpB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,OAAO,oBAAoB,mBAAmB,KAAK,UAAU,CAAC,EAAE;AAC5F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,SAASA,GAAE,MAAMA,GAAE,OAAO;AAAA,UACxB,YAAYA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,UAClE,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,UAC9G,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,UAC9E,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,QACzE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,oCAAoC;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,yBAAyB,EAAE,SAAS,KAAK,QAAQ,CAAC;AACnF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACnHA,SAAS,KAAAC,UAAS;AAIX,SAAS,uBAAuB,QAAmB,QAAuB;AAC/E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO,CAAC,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,IAAI,oBAAoB;AACpD,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,MAAMA,GAAE,OAAO,EAAE,SAAS,aAAa;AAAA,QACvC,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,QAClE,aAAaA,GAAE,KAAK,CAAC,WAAW,SAAS,YAAY,aAAa,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,QACrI,kBAAkBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,QACpF,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QAC5D,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MAClE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,sBAAsB,IAAI;AAC3D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,WAAWA,GAAE,OAAO,EAAE,SAAS,aAAa;AAAA,QAC5C,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QAC9E,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,sBAAsB,mBAAmB,KAAK,SAAS,CAAC,WAAW,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AACvH,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,WAAWA,GAAE,OAAO,EAAE,SAAS,iCAAiC;AAAA,QAChE,MAAMA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,QACtC,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,QAC5E,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,QAC/D,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,KAAK,sBAAsB,IAAI;AAC3D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,sBAAsB,mBAAmB,KAAK,QAAQ,CAAC,EAAE;AACzF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,QAC1C,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,UAAU;AAAA,QAC/C,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,QACrD,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,QAC7D,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,QACrD,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC/E,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,YAAM,SAAS,MAAM,OAAO,IAAI,sBAAsB,mBAAmB,QAAQ,CAAC,IAAI,IAAI;AAC1F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAaA,GAAE,OAAO;AAAA,QACpB,UAAUA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,OAAO,sBAAsB,mBAAmB,KAAK,QAAQ,CAAC,EAAE;AAC5F,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,GAAE,OAAO;AAAA,QACpB,cAAcA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,iEAAiE;AAAA,QACvH,aAAaA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,QACnH,mBAAmBA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MAC7F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,cAAc,OAAQ,QAAO,IAAI,gBAAgB,KAAK,aAAa,KAAK,GAAG,CAAC;AACrF,UAAI,KAAK,gBAAgB,OAAW,QAAO,IAAI,eAAe,OAAO,KAAK,WAAW,CAAC;AACtF,UAAI,KAAK,sBAAsB,MAAO,QAAO,IAAI,qBAAqB,OAAO;AAC7E,YAAM,SAAS,MAAM,OAAO,IAAI,sBAAsB,MAAM,EAAE;AAC9D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACvJA,SAAS,KAAAC,WAAS;;;ACSlB,IAAM,mBAAmB;AA2BzB,eAAe,WAAW,QAA+C;AACvE,MAAI;AACF,UAAM,MAAO,MAAM,OAAO,IAAI,KAAK;AAOnC,UAAM,IAAI,KAAK,QAAS;AACxB,UAAM,QAAS,GAA+B;AAC9C,UAAM,MAAO,GAA+B;AAC5C,UAAM,MAAO,GAA+B;AAC5C,WAAO;AAAA,MACL,oBAAoB,OAAO,OAAO,sBAAsB,CAAC;AAAA,MACzD,eAAe,OAAO,OAAO,iBAAiB,CAAC;AAAA,MAC/C,MAAO,KAAK,QAAmB;AAAA,MAC/B,MAAO,KAAK,QAAmB;AAAA,MAC/B,eAAe,QAAQ,KAAK,iBAAiB,KAAK;AAAA,IACpD;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,oBAAoB,GAAG,eAAe,GAAG,MAAM,MAAM,MAAM,MAAM,eAAe,MAAM;AAAA,EACjG;AACF;AAEA,SAAS,mBACP,QACA,kBACA,OACA,YACQ;AACR,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,oBAAoB,gBAAgB;AAAA,IACpC;AAAA,IACA;AAAA,IACA,uBAAuB,MAAM,aAAa;AAAA,IAC1C,uBAAuB,MAAM,kBAAkB;AAAA,IAC/C,GAAI,MAAM,OAAO,CAAC,SAAS,MAAM,IAAI,EAAE,IAAI,CAAC;AAAA,IAC5C,GAAI,MAAM,OAAO,CAAC,aAAa,MAAM,IAAI,EAAE,IAAI,CAAC;AAAA,IAChD,oBAAoB,MAAM,gBAAgB,YAAY,UAAU;AAAA,IAChE;AAAA,IACA;AAAA,IACA,KAAK,UAAU,YAAY,MAAM,CAAC;AAAA,IAClC;AAAA,IACA;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAgBA,eAAsB,YACpB,QACA,WACA,UACA,QAC4B;AAE5B,MAAI,WAAW;AACb,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAGA,QAAM,YAAY,MAAM,SAAS;AAGjC,QAAM,OAAO;AACb,QAAM,OAAQ,MAAM,QAAQ;AAC5B,QAAM,UAAU,MAAM;AACtB,QAAM,mBAAmB,OAAO,SAAS,WAAW,MAAM,YAAY,CAAC;AAGvE,MAAI,mBAAmB,kBAAkB;AACvC,WAAO,EAAE,SAAS,MAAM,YAAY,UAAU;AAAA,EAChD;AAGA,QAAM,QAAQ,MAAM,WAAW,MAAM;AACrC,QAAM,UAAU,mBAAmB,QAAQ,kBAAkB,OAAO,IAAI;AAExE,SAAO,EAAE,SAAS,OAAO,SAAS,YAAY,UAAU;AAC1D;;;AD/HO,SAAS,qBAAqB,QAAmB,QAAuB;AAC7E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaC,IAAE,OAAO;AAAA,QACpB,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,8CAA8C;AAAA,QACxF,MAAMA,IAAE,KAAK,CAAC,SAAS,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,gGAAgG;AAAA,QACxJ,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,QACxG,cAAcA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gEAAgE;AAAA,QAC9G,mBAAmBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,QAChH,SAASA,IAAE,OAAO;AAAA,UAChB,OAAOA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,QAC9E,CAAC,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,QAC5C,WAAWA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yEAAyE;AAAA,MACtH,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,EAAE,aAAa,SAAS,WAAW,mBAAmB,GAAG,KAAK,IAAI;AAGxE,cAAM,QAAQ,MAAM;AAAA,UAClB;AAAA,UACA;AAAA;AAAA,UACA,MAAM,OAAO,KAAK,qBAAqB,EAAE,UAAU,aAAa,GAAG,MAAM,mBAAmB,SAAS,KAAK,CAAC;AAAA,UAC3G,WAAW,YAAY,MAAM,WAAW,YAAY,WAAW,IAAI,MAAM,EAAE;AAAA,QAC7E;AAGA,YAAI,KAAK,SAAS;AAChB,gBAAM,OAAO,MAAM,aAAa,KAAK,UAAU,MAAM,YAAY,MAAM,CAAC,IAAI;AAC5E,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AAAA,QACtD;AAGA,YAAI,CAAC,MAAM,SAAS;AAClB,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,WAAW,wBAAwB,CAAC,EAAE;AAAA,QAChG;AAEA,cAAM,SAAS,MAAM,OAAO,KAAK,qBAAqB,EAAE,UAAU,aAAa,GAAG,MAAM,kBAAkB,CAAC;AAC3G,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MACvF,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO;AAAA,UACf,MAAMA,IAAE,KAAK,CAAC,aAAa,aAAa,QAAQ,QAAQ,CAAC,EAAE,SAAS,kFAAkF;AAAA,UACtJ,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sEAAsE;AAAA,UAC7G,SAASA,IAAE,OAAO;AAAA,YAChB,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,YACpD,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,YACvD,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,YAC7D,QAAQA,IAAE,KAAK,CAAC,QAAQ,UAAU,cAAc,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,YAChG,eAAeA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,YACvE,eAAeA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,YACvE,aAAaA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,UAChF,CAAC,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,UACpE,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,QACnF,CAAC,EAAE,SAAS,8CAA8C;AAAA,QAC1D,MAAMA,IAAE,KAAK,CAAC,SAAS,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,QACxI,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,QACxG,uBAAuBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,QAChG,cAAcA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,QACpG,mBAAmBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QACtG,WAAWA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yEAAyE;AAAA,MACtH,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,EAAE,WAAW,mBAAmB,GAAG,KAAK,IAAI;AAGlD,cAAM,QAAQ,MAAM;AAAA,UAClB;AAAA,UACA;AAAA;AAAA,UACA,MAAM,OAAO,KAAK,iBAAiB,EAAE,GAAG,MAAM,mBAAmB,SAAS,KAAK,CAAC;AAAA,UAChF,qBAAqB,KAAK,OAAO,IAAI;AAAA,QACvC;AAGA,YAAI,KAAK,SAAS;AAChB,gBAAM,OAAO,MAAM,aAAa,KAAK,UAAU,MAAM,YAAY,MAAM,CAAC,IAAI;AAC5E,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AAAA,QACtD;AAGA,YAAI,CAAC,MAAM,SAAS;AAClB,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,WAAW,wBAAwB,CAAC,EAAE;AAAA,QAChG;AAEA,cAAM,SAAS,MAAM,OAAO,KAAK,iBAAiB,EAAE,GAAG,MAAM,kBAAkB,CAAC;AAChF,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MACvF,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,QAChD,mBAAmBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MACzF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,YAAY,mBAAmB,KAAK,MAAM,CAAC;AAAA,QAC3C,EAAE,mBAAmB,KAAK,kBAAkB;AAAA,MAC9C;AACA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO,EAAE,SAAS,oBAAoB;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,YAAY,mBAAmB,KAAK,MAAM,CAAC,SAAS;AACpF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;AE7JA,SAAS,KAAAC,WAAS;AAKX,SAAS,oBAAoB,QAAmB,QAAuB;AAC5E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaC,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,OAAO,EAAE,SAAS,4CAA4C;AAAA,QAC1E,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACtF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,EAAE,OAAO,GAAG,KAAK,IAAI;AAC3B,cAAM,SAAS,MAAM,OAAO,KAAK,qBAAqB,EAAE,GAAG,MAAM,GAAI,UAAU,UAAa,EAAE,aAAa,MAAM,EAAG,CAAC;AACrH,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,OAAO,EAAE,SAAS,4CAA4C;AAAA,QAC1E,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACtF,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,EAAE,OAAO,GAAG,KAAK,IAAI;AAC3B,cAAM,SAAS,MAAM,OAAO,KAAK,qBAAqB,EAAE,GAAG,MAAM,GAAI,UAAU,UAAa,EAAE,aAAa,MAAM,EAAG,CAAC;AACrH,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAKF,aAAaA,IAAE,OAAO;AAAA,QACpB,WAAWA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAC7C,SAAS,sFAAsF;AAAA,QAClG,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAC/C,SAAS,2GAA2G;AAAA,QACvH,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAC9B,SAAS,sDAAsD;AAAA,QAClE,UAAU,eAAe,SAAS,EAC/B,SAAS,uEAAkE;AAAA,QAC9E,SAASA,IAAE,QAAQ,EAAE,SAAS,EAC3B,SAAS,8DAA8D;AAAA,MAC5E,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,UAAW,MAAK,YAAY,KAAK;AAC1C,YAAI,KAAK,YAAa,MAAK,cAAc,KAAK;AAC9C,YAAI,KAAK,UAAU,OAAW,MAAK,0BAA0B,KAAK;AAClE,YAAI,KAAK,SAAU,MAAK,WAAW,KAAK;AACxC,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,0BAA0B,IAAI;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAKF,aAAaA,IAAE,OAAO;AAAA,QACpB,WAAWA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAC7C,SAAS,sFAAsF;AAAA,QAClG,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAC/C,SAAS,2GAA2G;AAAA,QACvH,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAC9B,SAAS,sDAAsD;AAAA,QAClE,UAAU,eAAe,SAAS,EAC/B,SAAS,uEAAkE;AAAA,QAC9E,SAASA,IAAE,QAAQ,EAAE,SAAS,EAC3B,SAAS,8DAA8D;AAAA,MAC5E,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,UAAW,MAAK,YAAY,KAAK;AAC1C,YAAI,KAAK,YAAa,MAAK,cAAc,KAAK;AAC9C,YAAI,KAAK,UAAU,OAAW,MAAK,0BAA0B,KAAK;AAClE,YAAI,KAAK,SAAU,MAAK,WAAW,KAAK;AACxC,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,0BAA0B,IAAI;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,QACnE,eAAeA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,QAC3E,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,YAAa,MAAK,eAAe,CAAC,KAAK,WAAW;AAC3D,YAAI,KAAK,cAAe,MAAK,aAAa,CAAC,+CAA+C,KAAK,aAAa,GAAG;AAC/G,YAAI,KAAK,UAAU,OAAW,MAAK,YAAY,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,qBAAqB,IAAI;AAC1D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,SAASA,IAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,QAC5D,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,qBAAqB;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,oBAAoB;AAAA,UACnD,UAAU,CAAC,KAAK,OAAO;AAAA,UACvB,GAAI,KAAK,UAAU,UAAa,EAAE,WAAW,KAAK,MAAM;AAAA,QAC1D,CAAC;AACD,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,MAAMA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,mCAAmC;AAAA,MACxE,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,gBAAgB,IAAI;AACrD,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO,EAAE,SAAS,eAAe;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,IAAI,WAAW,mBAAmB,KAAK,MAAM,CAAC,SAAS;AACnF,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAOA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QACjE,YAAYA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,QACrF,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,QACtF,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,SAAU,MAAK,WAAW,KAAK;AACxC,YAAI,KAAK,WAAY,MAAK,aAAa,KAAK;AAC5C,YAAI,KAAK,UAAU,OAAW,MAAK,cAAc,KAAK;AACtD,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,uBAAuB,IAAI;AAC5D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,WAAWA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QAC1F,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACxG,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACvF,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,UAAW,MAAK,YAAY,KAAK;AAC1C,YAAI,KAAK,YAAa,MAAK,cAAc,KAAK;AAC9C,YAAI,KAAK,UAAU,OAAW,MAAK,0BAA0B,KAAK;AAClE,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B,IAAI;AACjE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QACjE,YAAYA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,QACnE,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,QACtF,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,SAAU,MAAK,WAAW,KAAK;AACxC,YAAI,KAAK,WAAY,MAAK,aAAa,KAAK;AAC5C,YAAI,KAAK,UAAU,OAAW,MAAK,cAAc,KAAK;AACtD,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,uBAAuB,IAAI;AAC5D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,WAAWA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QAC1F,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACxG,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACvF,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,OAAgC,CAAC;AACvC,YAAI,KAAK,UAAW,MAAK,YAAY,KAAK;AAC1C,YAAI,KAAK,YAAa,MAAK,cAAc,KAAK;AAC9C,YAAI,KAAK,UAAU,OAAW,MAAK,0BAA0B,KAAK;AAClE,YAAI,KAAK,YAAY,OAAW,MAAK,UAAU,KAAK;AACpD,cAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B,IAAI;AACjE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaA,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,wCAAmC;AAAA,QACzF,WAAWA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,QACtF,WAAWA,IAAE,OAAO;AAAA,UAClB,OAAOA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,UAC/D,UAAUA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,UACvE,YAAYA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,QAC3E,CAAC,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QACzC,QAAQA,IAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,QACrF,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,sBAAsB,IAAI;AAC3D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAOA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAaA,IAAE,OAAO;AAAA,QACpB,YAAYA,IAAE,OAAO,EAAE,SAAS,2CAA2C;AAAA,QAC3E,aAAaA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,QACvG,oBAAoBA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACpH,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,MAC/F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,8BAA8B,IAAI;AACnE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,UAAUA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,+CAA0C;AAAA,QAChG,mBAAmBA,IAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,QAC1F,mBAAmBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAC1F,aAAaA,IAAE,KAAK,CAAC,OAAO,SAAS,UAAU,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,QAC7G,gBAAgBA,IAAE,KAAK,CAAC,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,QAClI,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B,IAAI;AACjE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,WAAWA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QAC3G,mBAAmBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAC1F,aAAaA,IAAE,KAAK,CAAC,OAAO,SAAS,UAAU,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,QAC7F,gBAAgBA,IAAE,KAAK,CAAC,OAAO,QAAQ,SAAS,QAAQ,SAAS,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,QAClH,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC9F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,4BAA4B,IAAI;AACjE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO,EAAE,SAAS,wEAAmE;AAAA,QAC/F,cAAcA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,QACrG,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,QAC5F,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,MAC/F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,0BAA0B,IAAI;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MAC9E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACF;;;AChfA,SAAS,KAAAC,WAAS;AAKX,SAAS,oBAAoB,QAAmB,QAAuB;AAC5E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaC,IAAE,OAAO;AAAA,QACpB,aAAaA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,QAClG,SAASA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kDAA6C;AAAA,QACrF,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2DAAsD;AAAA,QAClG,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,QACvG,sBAAsBA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,QACpG,WAAWA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yEAAyE;AAAA,MACtH,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,UAAI;AACF,cAAM,EAAE,aAAa,SAAS,aAAa,WAAW,GAAG,KAAK,IAAI;AAGlE,cAAM,WAAoC,EAAE,GAAG,KAAK;AACpD,YAAI,eAAe,YAAY,SAAS,GAAG;AACzC,mBAAS,WAAW;AAAA,QACtB,WAAW,SAAS;AAClB,mBAAS,UAAU;AAAA,QACrB,WAAW,aAAa;AACtB,mBAAS,cAAc;AAAA,QACzB,OAAO;AACL,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sDAAsD,CAAC,EAAE;AAAA,QAC7G;AAGA,cAAM,QAAQ,UACV,eAAe,OAAO,KACtB,cACE,mBAAmB,WAAW,KAC9B,UAAU,aAAa,UAAU,CAAC,YAAY,aAAa,UAAU,OAAO,IAAI,MAAM,EAAE;AAG9F,cAAM,QAAQ,MAAM;AAAA,UAClB;AAAA,UACA;AAAA;AAAA,UACA,MAAM,OAAO,KAAK,oBAAoB,EAAE,GAAG,UAAU,SAAS,KAAK,CAAC;AAAA,UACpE;AAAA,QACF;AAGA,YAAI,KAAK,SAAS;AAChB,gBAAM,OAAO,MAAM,aAAa,KAAK,UAAU,MAAM,YAAY,MAAM,CAAC,IAAI;AAC5E,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AAAA,QACtD;AAGA,YAAI,CAAC,MAAM,SAAS;AAClB,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,WAAW,wBAAwB,CAAC,EAAE;AAAA,QAChG;AAEA,cAAM,SAAS,MAAM,OAAO,KAAK,oBAAoB,QAAQ;AAC7D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,MACvF,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAaA,IAAE,OAAO;AAAA,QACpB,QAAQA,IAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,MAAM,OAAO,IAAI,WAAW,mBAAmB,KAAK,MAAM,CAAC,SAAS;AACnF,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACzFA,SAAS,KAAAC,WAAS;AAKX,SAAS,kBAAkB,QAAmB,QAAuB;AAC1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAaC,IAAE,OAAO;AAAA,QACpB,SAASA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAAuD;AAAA,QAC/F,aAAaA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qEAAgE;AAAA,QAC5G,UAAUA,IAAE,KAAK,CAAC,WAAW,UAAU,oBAAoB,kBAAkB,CAAC,EAAE,SAAS,EACtF,SAAS,4CAA4C;AAAA,QACxD,UAAU,eAAe,SAAS,EAC/B,SAAS,mCAAmC;AAAA,QAC/C,MAAMA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,MAC1F,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACpD,UAAI,KAAK,YAAa,QAAO,IAAI,eAAe,KAAK,WAAW;AAChE,UAAI,KAAK,SAAU,QAAO,IAAI,YAAY,KAAK,QAAQ;AACvD,UAAI,KAAK,SAAU,QAAO,IAAI,YAAY,KAAK,QAAQ;AACvD,UAAI,KAAK,MAAM,OAAQ,QAAO,IAAI,QAAQ,KAAK,KAAK,KAAK,GAAG,CAAC;AAC7D,YAAM,SAAS,MAAM,OAAO,IAAI,kBAAkB,MAAM,EAAE;AAC1D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAaA,IAAE,OAAO;AAAA,QACpB,MAAMA,IAAE,KAAK,CAAC,WAAW,UAAU,oBAAoB,kBAAkB,CAAC,EAAE,SAAS,EAClF,SAAS,mCAAmC;AAAA,QAC/C,QAAQA,IAAE,OAAO,EAAE,SAAS,EACzB,SAAS,kFAAkF;AAAA,QAC9F,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAC9C,SAAS,wCAAwC;AAAA,QACpD,QAAQA,IAAE,OAAO,EAAE,SAAS,EACzB,SAAS,mBAAmB;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,KAAK,KAAM,QAAO,IAAI,QAAQ,KAAK,IAAI;AAC3C,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,UAAI,KAAK,UAAU,OAAW,QAAO,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,UAAI,KAAK,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AACjD,YAAM,KAAK,OAAO,SAAS;AAC3B,YAAM,SAAS,MAAM,OAAO,IAAI,QAAQ,KAAK,IAAI,EAAE,KAAK,EAAE,EAAE;AAC5D,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC9E;AAAA,EACF;AACF;;;ACxBO,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWA,IAAM,aAA2C;AAAA,EAC/C,UAAU;AAAA,EACV,WAAW;AAAA,EACX,OAAO;AAAA,EACP,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AACR;AAeO,SAAS,iBACd,QACA,QACA,OAA2B,CAAC,GACtB;AACN,QAAM,UACJ,KAAK,UAAU,KAAK,OAAO,SAAS,IAAI,IAAI,IAAI,KAAK,MAAM,IAAI;AAIjE,oBAAkB,QAAQ,MAAM;AAEhC,aAAW,SAAS,aAAa;AAC/B,QAAI,CAAC,WAAW,QAAQ,IAAI,KAAK,GAAG;AAClC,iBAAW,KAAK,EAAE,QAAQ,MAAM;AAAA,IAClC;AAAA,EACF;AACF;;;AhBxFO,SAAS,aAAa,SAAyC;AACpE,QAAM,EAAE,QAAQ,SAAS,MAAM,IAAI;AAEnC,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAKN,SACE,OAA6C,UAAsB;AAAA,IACvE;AAAA,IACA;AAAA,MACE,cAAc;AAAA,QACZ,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,IAAI,cAAc,QAAQ,OAAO;AAEhD,mBAAiB,QAAQ,QAAQ,EAAE,QAAQ,MAAM,CAAC;AAElD,SAAO;AACT;;;AD5BA,SAAS,gBAAgB,KAAkD;AACzE,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,YAAY,IAAI,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC;AAClE,QAAM,QAAQ,UAAU;AAAA,IAAO,CAAC,MAC7B,YAAkC,SAAS,CAAC;AAAA,EAC/C;AACA,QAAM,UAAU,UAAU,OAAO,CAAC,MAAM,CAAE,YAAkC,SAAS,CAAC,CAAC;AACvF,MAAI,QAAQ,QAAQ;AAClB,YAAQ;AAAA,MACN,yCAAyC,QAAQ,KAAK,IAAI,CAAC;AAAA,gBAC1C,YAAY,KAAK,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AACA,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAEA,eAAe,OAAO;AACpB,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAMuB,YAAY,KAAK,IAAI,CAAC;AAAA,IAC/C;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,QAAQ,IAAI,oBAAoB;AAChD,QAAM,QAAQ,gBAAgB,QAAQ,IAAI,aAAa;AAEvD,QAAM,SAAS,aAAa,EAAE,QAAQ,SAAS,MAAM,CAAC;AACtD,QAAM,YAAY,IAAI,qBAAqB;AAE3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,gBAAgB,GAAG;AACjC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/client.ts","../src/tools/meta.ts","../src/tools/profiles.ts","../src/tools/_platform-schema.ts","../src/tools/campaigns.ts","../src/tools/lists.ts","../src/tools/analytics.ts","../src/tools/content.ts","../src/tools/manage.ts","../src/tools/knowledge.ts","../src/tools/enhance.ts","../src/tools/credit-guard.ts","../src/tools/scrape.ts","../src/tools/refine.ts","../src/tools/jobs.ts","../src/tools/_registry.ts"],"sourcesContent":["/**\n * Celavii MCP Server — stdio Entry Point\n *\n * Usage:\n * CELAVII_API_KEY=cvii_live_xxx npx celavii-mcp\n *\n * Or in MCP config:\n * {\n * \"mcpServers\": {\n * \"celavii\": {\n * \"command\": \"npx\",\n * \"args\": [\"-y\", \"celavii-mcp@latest\"],\n * \"env\": { \"CELAVII_API_KEY\": \"cvii_live_xxx\" }\n * }\n * }\n * }\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer, TOOL_GROUPS, type ToolGroup } from './server.js'\n\nfunction parseToolGroups(env: string | undefined): ToolGroup[] | undefined {\n if (!env) return undefined\n const requested = env.split(',').map((s) => s.trim().toLowerCase())\n const valid = requested.filter((g): g is ToolGroup =>\n (TOOL_GROUPS as readonly string[]).includes(g),\n )\n const invalid = requested.filter((g) => !(TOOL_GROUPS as readonly string[]).includes(g))\n if (invalid.length) {\n console.error(\n `Warning: Unknown tool groups ignored: ${invalid.join(', ')}\\n` +\n `Valid groups: ${TOOL_GROUPS.join(', ')}`,\n )\n }\n return valid.length > 0 ? valid : undefined\n}\n\nasync function main() {\n const apiKey = process.env.CELAVII_API_KEY\n if (!apiKey) {\n console.error(\n 'Error: CELAVII_API_KEY environment variable is required.\\n' +\n 'Get your API key at https://www.celavii.com/settings/api-keys\\n' +\n '\\nUsage:\\n' +\n ' CELAVII_API_KEY=cvii_live_xxx npx celavii-mcp\\n' +\n '\\nOptional: Load specific tool groups only:\\n' +\n ` CELAVII_TOOLS=profiles,analytics,campaigns\\n` +\n ` Available groups: ${TOOL_GROUPS.join(', ')}`,\n )\n process.exit(1)\n }\n\n const baseUrl = process.env.CELAVII_BASE_URL || undefined\n const tools = parseToolGroups(process.env.CELAVII_TOOLS)\n\n const server = createServer({ apiKey, baseUrl, tools })\n const transport = new StdioServerTransport()\n\n await server.connect(transport)\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err)\n process.exit(1)\n})\n","/**\n * Celavii MCP Server — Server Setup & Tool Registration (stdio entry)\n *\n * Creates an McpServer instance with the version baked in at build time\n * (see tsup.config.ts) and registers every tool group via the shared\n * registry at `tools/_registry.ts`.\n *\n * The remote endpoint at `src/app/api/mcp/[transport]/route.ts` (Vercel)\n * uses the same registry — there is no longer a duplicated tool list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { CelaviiClient, CelaviiApiError } from './client.js'\nimport { registerAllTools, TOOL_GROUPS, type ToolGroup } from './tools/_registry.js'\n\nexport { TOOL_GROUPS, type ToolGroup }\n\nexport interface CreateServerOptions {\n apiKey: string\n baseUrl?: string\n /** Tool groups to register. If omitted or empty, all groups are registered. */\n tools?: ToolGroup[]\n}\n\nexport function createServer(options: CreateServerOptions): McpServer {\n const { apiKey, baseUrl, tools } = options\n\n const server = new McpServer(\n {\n name: 'celavii',\n // Replaced at build time by tsup `define` from package.json#version.\n // See tsup.config.ts. Fallback string is only used in `tsc --noEmit`\n // / direct ts-node runs; the published bundle always carries the\n // real value.\n version:\n typeof __PACKAGE_VERSION__ !== 'undefined' ? __PACKAGE_VERSION__ : '0.0.0-dev',\n },\n {\n capabilities: {\n logging: {},\n },\n },\n )\n\n const client = new CelaviiClient(apiKey, baseUrl)\n\n registerAllTools(server, client, { groups: tools })\n\n return server\n}\n\nexport { CelaviiClient, CelaviiApiError }\n","/**\n * Celavii MCP Server — HTTP Client\n *\n * Thin wrapper around fetch that adds Bearer auth, error handling,\n * and structured error responses for MCP tool handlers.\n */\n\nconst DEFAULT_BASE_URL = 'https://www.celavii.com/api/v1'\n\nexport class CelaviiApiError extends Error {\n constructor(\n message: string,\n public code: string,\n public status: number,\n public retryAfter?: number,\n ) {\n super(message)\n this.name = 'CelaviiApiError'\n }\n}\n\nexport class CelaviiClient {\n private baseUrl: string\n private apiKey: string\n\n constructor(apiKey: string, baseUrl?: string) {\n this.apiKey = apiKey\n this.baseUrl = (baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, '')\n }\n\n private async request(path: string, init?: RequestInit): Promise<unknown> {\n const url = `${this.baseUrl}${path}`\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'celavii-mcp/0.1.0',\n ...init?.headers,\n },\n })\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n throw new CelaviiApiError(\n `HTTP ${res.status}: Failed to parse response`,\n 'INTERNAL_ERROR',\n res.status,\n )\n }\n\n if (!res.ok) {\n const err = json as { error?: { code?: string; message?: string; retry_after?: number } }\n const msg = err?.error?.message || `HTTP ${res.status}`\n const code = err?.error?.code || 'INTERNAL_ERROR'\n throw new CelaviiApiError(msg, code, res.status, err?.error?.retry_after)\n }\n\n return json\n }\n\n async get(path: string): Promise<unknown> {\n return this.request(path)\n }\n\n async post(path: string, body?: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'POST',\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n }\n\n async patch(path: string, body: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'PATCH',\n body: JSON.stringify(body),\n })\n }\n\n async put(path: string, body: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'PUT',\n body: JSON.stringify(body),\n })\n }\n\n async delete(path: string, body?: unknown): Promise<unknown> {\n return this.request(path, {\n method: 'DELETE',\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n }\n}\n","/**\n * Meta tools — Account info and usage\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerMetaTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_account_info',\n {\n title: 'Get Account Info',\n description:\n 'Get information about the current API key, organization, and usage summary. ' +\n 'Useful to verify API key is working and see available scopes. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/me')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_usage',\n {\n title: 'Get Usage',\n description:\n 'Get credit usage and rate limit status for the current API key. ' +\n 'Shows total requests, credits used, daily breakdown, and rate limit info. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/usage')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_youtube_quota',\n {\n title: 'Get YouTube Data API v3 Quota',\n description:\n 'Returns the platform\\'s YouTube Data API v3 quota state. Returns BOTH raw units ' +\n '(cap, used, remaining, reset_seconds) AND a normalized \"operations remaining today\" ' +\n 'estimate per op-type — agents can pick the shape that suits their planning. ' +\n 'Note: quota is a global daily cap shared across all orgs on the same Google API key. Free.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/youtube/quota')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Profile tools — Search, details, affinities, posts, network, bulk\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerProfileTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'search_profiles',\n {\n title: 'Search Profiles',\n description:\n 'Search the Celavii creator database. Filter by query text, niche, location, gender, ' +\n 'follower count. Returns matching Instagram profiles with basic stats. ' +\n 'At least one filter is required. Costs 1 credit.',\n inputSchema: z.object({\n query: z.string().optional().describe('Search query — matches username, display name, or bio keywords'),\n niche: z.string().optional().describe(\"Filter by niche/topic (e.g. 'fitness', 'fashion', 'tech')\"),\n location: z.string().optional().describe(\"Filter by location (e.g. 'Miami', 'Los Angeles, California')\"),\n gender: z.enum(['male', 'female', 'non_binary', 'brand']).optional().describe('Filter by gender'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n has_contact: z.boolean().optional().describe('Only return profiles with email or phone'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor from a previous response'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.query) params.set('query', args.query)\n if (args.niche) params.set('niche', args.niche)\n if (args.location) params.set('location', args.location)\n if (args.gender) params.set('gender', args.gender)\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.has_contact) params.set('has_contact', 'true')\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/profiles/search?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'search_profiles_by_affinities',\n {\n title: 'Search Profiles by Affinities',\n description:\n 'Search creators by their AI-analyzed brand or topic affinities. ' +\n 'Find creators who have affinity for specific brands, interests, or topics. Costs 1 credit.',\n inputSchema: z.object({\n affinities: z.array(z.string()).describe(\"Affinity terms to search for (e.g. ['Nike', 'fitness', 'running'])\"),\n match_mode: z.enum(['any', 'all']).optional().describe(\"'any' = match any affinity, 'all' = must match all (default: 'any')\"),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor from a previous response'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('terms', args.affinities.join(','))\n if (args.match_mode) params.set('match_mode', args.match_mode)\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/profiles/search/affinities?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profiles_bulk',\n {\n title: 'Get Profiles Bulk',\n description:\n 'Get detailed information for multiple profiles at once by username or profile ID. ' +\n 'Up to 100 profiles per request. Costs 1 credit.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs (max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/bulk', { profiles: args.identifiers })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile',\n {\n title: 'Get Profile',\n description:\n 'Get detailed information about a single Instagram profile by username or profile ID. ' +\n 'Returns bio, stats, niche, location, job_status (enhance/refine/scrape progress), and more. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username (without @) or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_affinities',\n {\n title: 'Get Profile Affinities',\n description:\n 'Get AI-analyzed brand and topic affinities for a profile. ' +\n 'Shows what brands, interests, and topics a creator is associated with. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/affinities`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_posts',\n {\n title: 'Get Profile Posts',\n description:\n 'Get recent posts for a profile. Returns post content, engagement metrics, ' +\n 'media URLs, and hashtags. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of posts (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/posts${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_network',\n {\n title: 'Get Profile Network',\n description:\n 'Get the social network graph for a profile — mutual connections, ' +\n 'top followers, and following relationships. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/network`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_followers',\n {\n title: 'Get Profile Followers',\n description:\n 'Get the followers list for a profile. Only available if followers have been scraped. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of followers (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/followers${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_following',\n {\n title: 'Get Profile Following',\n description:\n 'Get the accounts a profile is following. Only available if following data has been scraped. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of following (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/following${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_social_links',\n {\n title: 'Get Profile Social Links',\n description:\n 'Get external social media links found in a profile bio (YouTube, TikTok, Twitter, etc.). Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/social-links`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_profile_contact',\n {\n title: 'Get Profile Contact',\n description:\n 'Get contact information (email, phone) for a profile. ' +\n 'Requires the profiles:contact scope. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/profiles/${encodeURIComponent(args.identifier)}/contact`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ============================================================================\n // Semantic Search Tools (Phase 3 Embeddings)\n // ============================================================================\n\n server.registerTool(\n 'find_similar_profiles',\n {\n title: 'Find Similar Profiles',\n description:\n 'Find profiles semantically similar to a seed profile using AI embeddings. ' +\n 'Uses vector similarity to find creators with similar content, topics, and style. ' +\n 'More powerful than keyword matching — finds conceptually related profiles. Costs 1 credit.',\n inputSchema: z.object({\n profile_id: z.string().describe('Seed profile ID (e.g., ig:123456789) to find similar profiles for'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n platforms: z.array(PlatformSchema).optional().describe('Filter by platforms'),\n limit: z.number().int().min(1).max(100).optional().describe('Results to return (default 20, max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/search/similar', {\n profile_id: args.profile_id,\n min_followers: args.min_followers,\n max_followers: args.max_followers,\n platforms: args.platforms,\n limit: args.limit,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'find_similar_to_cohort',\n {\n title: 'Find Similar to Cohort',\n description:\n 'Find profiles similar to a GROUP of seed profiles. ' +\n 'Computes a centroid embedding from multiple profiles and finds similar creators. ' +\n 'Use case: \"Find creators like these 5 influencers I already work with\". Costs 1 credit.',\n inputSchema: z.object({\n profile_ids: z.array(z.string()).describe('Array of seed profile IDs (e.g., [\"ig:123\", \"ig:456\"])'),\n min_followers: z.number().int().optional().describe('Minimum follower count'),\n max_followers: z.number().int().optional().describe('Maximum follower count'),\n platforms: z.array(PlatformSchema).optional().describe('Filter by platforms'),\n exclude_seeds: z.boolean().optional().describe('Exclude seed profiles from results (default true)'),\n limit: z.number().int().min(1).max(100).optional().describe('Results to return (default 20, max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/profiles/search/similar/cohort', {\n profile_ids: args.profile_ids,\n min_followers: args.min_followers,\n max_followers: args.max_followers,\n platforms: args.platforms,\n exclude_seeds: args.exclude_seeds,\n limit: args.limit,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Platform Schema — MCP-side mirror of `src/lib/api-keys/platform-schema.ts`.\n *\n * Duplicated rather than imported to keep the MCP package free of Next.js\n * coupling. The repo-root parity test\n * (`src/lib/api-keys/__tests__/platform-schema.test.ts`) asserts these two\n * files stay in sync — if you edit one, edit the other.\n */\n\nimport { z } from 'zod';\n\nexport const PLATFORMS = ['instagram', 'tiktok', 'youtube', 'x'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\nexport const PlatformSchema = z.enum(PLATFORMS);\n\n/**\n * Subset of platforms that have populated post embeddings (verified\n * 2026-05-13). YouTube post embeddings are not yet populated — semantic\n * search would silently return zero results, so we narrow the enum to\n * give agents the truth at schema time.\n *\n * When YT embeddings ship, replace this with `PlatformSchema`.\n */\nexport const SEMANTIC_PLATFORMS = ['instagram', 'tiktok', 'x'] as const;\nexport const SemanticPlatformSchema = z.enum(SEMANTIC_PLATFORMS);\n","/**\n * Campaign tools — List, metrics, creators, content\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerCampaignTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_campaigns',\n {\n title: 'List Campaigns',\n description:\n 'List all campaigns in the organization. Optionally filter by status. Costs 0 credits.',\n inputSchema: z.object({\n status: z.enum(['active', 'draft', 'completed', 'archived']).optional().describe('Filter by campaign status'),\n limit: z.number().int().min(1).max(100).optional().describe('Number of campaigns (default 25, max 100)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const qs = params.toString()\n const result = await client.get(`/campaigns${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_metrics',\n {\n title: 'Get Campaign Metrics',\n description:\n 'Get performance metrics for a specific campaign — total creators, posts, ' +\n 'engagement, reach, and more. Costs 0 credits.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/metrics`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_creators',\n {\n title: 'Get Campaign Creators',\n description:\n 'Get the list of creators assigned to a campaign with their statuses and metrics. Costs 0 credits.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/creators${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_campaign_content',\n {\n title: 'Get Campaign Content',\n description:\n 'Get content (posts) associated with a campaign. Includes engagement data ' +\n 'and media. Costs 1 credit.',\n inputSchema: z.object({\n campaign_id: z.string().describe('Campaign UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/campaigns/${encodeURIComponent(args.campaign_id)}/content${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * List tools — CRUD + member management\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerListTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_lists',\n {\n title: 'List Lists',\n description: 'Get all creator lists in the organization. Costs 0 credits.',\n inputSchema: z.object({\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/lists${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_list',\n {\n title: 'Create List',\n description: 'Create a new creator list. Costs 1 credit.',\n inputSchema: z.object({\n name: z.string().describe('Name of the list'),\n description: z.string().optional().describe('Optional description'),\n }),\n },\n async (args) => {\n const result = await client.post('/lists', { name: args.name, description: args.description })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_list',\n {\n title: 'Get List',\n description: 'Get details for a specific list by ID. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/lists/${encodeURIComponent(args.list_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'update_list',\n {\n title: 'Update List',\n description: 'Update a list name or description. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n name: z.string().optional().describe('New name'),\n description: z.string().optional().describe('New description'),\n }),\n },\n async (args) => {\n const { list_id, ...body } = args\n const result = await client.patch(`/lists/${encodeURIComponent(list_id)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_list',\n {\n title: 'Delete List',\n description: 'Delete a list. This does not delete the creators in the list. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/lists/${encodeURIComponent(args.list_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_list_members',\n {\n title: 'Get List Members',\n description: 'Get the creator profiles in a list with optional filtering. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n limit: z.number().int().min(1).max(200).optional().describe('Results per page (default 25, max 200)'),\n offset: z.number().int().min(0).optional().describe('Number of results to skip (default 0). Use the offset from the previous response to paginate.'),\n min_followers: z.number().int().optional().describe('Minimum follower count filter'),\n max_followers: z.number().int().optional().describe('Maximum follower count filter'),\n added_after: z.string().optional().describe('Only profiles added after this date (ISO 8601, e.g. 2025-01-01)'),\n enhanced_after: z.string().optional().describe('Only profiles enhanced after this date (ISO 8601)'),\n platform: PlatformSchema.optional().describe('Filter by platform'),\n has_enhancement: z.boolean().optional().describe('Filter by completed enhancement (true = has, false = missing)'),\n has_refinement: z.boolean().optional().describe('Filter by completed refinement (true = has, false = missing)'),\n has_followers_scrape: z.boolean().optional().describe('Filter by completed followers scrape (true = has, false = missing)'),\n has_following_scrape: z.boolean().optional().describe('Filter by completed following scrape (true = has, false = missing)'),\n tags: z.array(z.string()).optional().describe('Filter by tags — profiles with ANY of these tags'),\n relationship_status: z.string().optional().describe(\"Filter by CRM status (e.g., 'shortlisted', 'outreached', 'negotiating', 'contracted')\"),\n has_notes: z.boolean().optional().describe('Filter by whether profile has notes (true = has notes, false = no notes)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.offset !== undefined) params.set('offset', String(args.offset))\n if (args.min_followers !== undefined) params.set('min_followers', String(args.min_followers))\n if (args.max_followers !== undefined) params.set('max_followers', String(args.max_followers))\n if (args.added_after) params.set('added_after', args.added_after)\n if (args.enhanced_after) params.set('enhanced_after', args.enhanced_after)\n if (args.platform) params.set('platform', args.platform)\n if (args.has_enhancement !== undefined) params.set('has_enhancement', String(args.has_enhancement))\n if (args.has_refinement !== undefined) params.set('has_refinement', String(args.has_refinement))\n if (args.has_followers_scrape !== undefined) params.set('has_followers_scrape', String(args.has_followers_scrape))\n if (args.has_following_scrape !== undefined) params.set('has_following_scrape', String(args.has_following_scrape))\n if (args.tags && args.tags.length > 0) params.set('tags', args.tags.join(','))\n if (args.relationship_status) params.set('relationship_status', args.relationship_status)\n if (args.has_notes !== undefined) params.set('has_notes', String(args.has_notes))\n const qs = params.toString()\n const result = await client.get(`/lists/${encodeURIComponent(args.list_id)}/members${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'add_list_members',\n {\n title: 'Add List Members',\n description: 'Add creators to a list by username or profile ID. Costs 1 credit.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to add'),\n }),\n },\n async (args) => {\n const result = await client.post(\n `/lists/${encodeURIComponent(args.list_id)}/members`,\n { profiles: args.identifiers },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'remove_list_members',\n {\n title: 'Remove List Members',\n description: 'Remove creators from a list. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().describe('List UUID'),\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to remove'),\n }),\n },\n async (args) => {\n const result = await client.delete(\n `/lists/${encodeURIComponent(args.list_id)}/members`,\n { profiles: args.identifiers },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Analytics tools — Demographics, locations, niches, overlap, cohort\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\n/** Schema for endpoints that accept profile_ids + scope (demographics) */\nconst demographicsSchema = z.object({\n profile_ids: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n scope: z.enum(['global', 'org']).optional().describe(\"'global' (default, all profiles) or 'org' (managed only)\"),\n})\n\n/** Schema for endpoints that accept scope + limit only (locations, niches) */\nconst orgLevelSchema = z.object({\n scope: z.enum(['global', 'org']).optional().describe(\"'global' (default, all profiles) or 'org' (managed only)\"),\n limit: z.number().int().min(1).max(100).optional().describe('Max results (default 20, max 100)'),\n})\n\n/** Schema for profile source parameters used by overlap, shared-hashtags, cohort */\nconst profileSourceSchema = z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n})\n\n\nexport function registerAnalyticsTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_demographics',\n {\n title: 'Get Demographics',\n description:\n 'Get audience demographics breakdown (age, gender distribution). ' +\n 'Optionally pass profile_ids to analyze a subset, or scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: demographicsSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.profile_ids?.length) params.set('profile_ids', args.profile_ids.join(','))\n if (args.scope) params.set('scope', args.scope)\n const result = await client.get(`/analytics/demographics?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_locations',\n {\n title: 'Get Locations',\n description:\n 'Get location distribution — top cities and countries. ' +\n 'Use scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: orgLevelSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.scope) params.set('scope', args.scope)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/locations?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_niches',\n {\n title: 'Get Niches',\n description:\n 'Get niche/topic distribution across profiles. ' +\n 'Use scope=org for managed profiles only. Costs 1 credit.',\n inputSchema: orgLevelSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.scope) params.set('scope', args.scope)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/niches?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_network_overlap',\n {\n title: 'Get Network Overlap',\n description:\n 'Get follower/following overlap between profiles. Shows shared connections. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profile_ids', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/network-overlap?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_shared_hashtags',\n {\n title: 'Get Shared Hashtags',\n description:\n 'Get hashtags shared across a set of profiles. Shows common themes and topics. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('usernames', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/shared-hashtags?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_hashtag_creators',\n {\n title: 'Get Hashtag Creators',\n description:\n 'Find creators who use specific hashtags. Useful for discovering creators by topic. Costs 1 credit.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).describe(\"Hashtags to search for (without #, e.g. ['fitness', 'gym'])\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('hashtags', args.hashtags.join(','))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const result = await client.get(`/analytics/hashtag-creators?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_affinity_posts',\n {\n title: 'Get Affinity Posts',\n description:\n 'Get posts linked to a brand/topic affinity term. Searches globally across all profiles. Costs 1 credit.',\n inputSchema: z.object({\n affinity: z.string().describe('Affinity term to search for (e.g. \"photography\", \"Nike\", \"fitness\")'),\n affinity_type: z.enum(['all', 'topic', 'brand', 'location', 'category']).optional().describe(\"Filter by affinity type (default: 'all')\"),\n min_engagement: z.number().int().optional().describe('Minimum total engagement'),\n sort: z.enum(['engagement', 'date']).optional().describe(\"Sort order (default: 'engagement')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('affinity', args.affinity)\n if (args.affinity_type) params.set('affinity_type', args.affinity_type)\n if (args.min_engagement !== undefined) params.set('min_engagement', String(args.min_engagement))\n if (args.sort) params.set('sort', args.sort)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/analytics/affinity-posts?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'analyze_cohort',\n {\n title: 'Analyze Cohort',\n description:\n 'Run a full cohort analysis on a set of profiles. Includes demographics, affinities, ' +\n 'hashtag usage, and aggregate stats. Costs 2 credits.',\n inputSchema: z.object({\n profiles: z.array(z.string()).optional().describe('Array of usernames or profile IDs'),\n source: z.object({\n type: z.enum(['followers', 'following']).describe(\"Source type: 'followers' or 'following'\"),\n target: z.string().describe('Username or ig:ID of the seed profile'),\n limit: z.number().int().optional().describe('Max profiles to resolve from network (default 500, max 10000)'),\n }).optional().describe('Alternative: analyze followers/following of a profile'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n include: z.array(z.string()).optional().describe(\"Data to include: ['affinities', 'demographics', 'locations', 'niches', 'engagement_stats', 'hashtags', 'account_stats']\"),\n }),\n },\n async (args) => {\n const result = await client.post('/analytics/cohort', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_cohort_stats',\n {\n title: 'Get Cohort Stats',\n description:\n 'Get aggregate statistics for a cohort — average followers, engagement rate, etc. ' +\n 'Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: profileSourceSchema,\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profiles', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n const result = await client.get(`/analytics/cohort/stats?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'filter_cohort',\n {\n title: 'Filter Cohort',\n description:\n 'Filter a cohort of profiles by advanced criteria — follower range, engagement rate, ' +\n 'niche, location, affinities, and more. Costs 2 credits.',\n inputSchema: z.object({\n profiles: z.array(z.string()).optional().describe('Array of usernames or profile IDs to filter'),\n source: z.object({\n type: z.enum(['followers', 'following']).describe(\"Source type: 'followers' or 'following'\"),\n target: z.string().describe('Username or ig:ID of the seed profile'),\n limit: z.number().int().optional().describe('Max profiles to resolve from network (default 500, max 10000)'),\n }).optional().describe('Alternative: filter followers/following of a profile'),\n list_id: z.string().optional().describe('List UUID — filter all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — filter all creators in this campaign'),\n filters: z.record(z.string(), z.unknown()).optional().describe('Filter criteria (varies by field)'),\n }),\n },\n async (args) => {\n const result = await client.post('/analytics/cohort/filter', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_posting_times',\n {\n title: 'Get Posting Times',\n description:\n 'Get posting time patterns (day-of-week + hour heatmap), content format distribution, and sentiment analysis for a cohort. ' +\n 'Useful for finding optimal posting times. Provide identifiers, a list_id, or a campaign_id. Costs 1 credit.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to analyze'),\n list_id: z.string().optional().describe('List UUID — analyze all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — analyze all creators in this campaign'),\n platform: PlatformSchema.optional().describe(\"Platform to analyze (default: 'instagram')\"),\n days: z.number().int().min(1).max(365).optional().describe('Number of days to look back (default: 90)'),\n sample_max: z.number().int().min(1).max(50000).optional().describe('Max posts to sample (default: 5000)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.identifiers?.length) params.set('profiles', args.identifiers.join(','))\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n if (args.platform) params.set('platform', args.platform)\n if (args.days !== undefined) params.set('days', String(args.days))\n if (args.sample_max !== undefined) params.set('sample_max', String(args.sample_max))\n // Call v1 analytics posting-times endpoint\n const result = await client.get(`/analytics/posting-times?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // YouTube analytics — Phase 3D (3 tools backed by api.*_yt_v1 RPCs)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'get_youtube_channel_summary',\n {\n title: 'Get YouTube Channel Summary',\n description:\n 'Aggregate stats about a YouTube channel\\'s commenter network — total comments collected, ' +\n 'unique commenters, last collection time. Backed by api.get_channel_summary_yt_v1. Free. ' +\n 'Response includes `data_status` (collected | channel_found_no_commenters | channel_not_found), ' +\n '`last_collected_at`, and `channel_id` (canonical yt:UCxxx) which can be passed directly to ' +\n '`scrape_youtube_commenters` to collect commenter data. The legacy `summary.out_*` fields ' +\n 'are preserved for back-compat and will be removed in 0.3.0.',\n inputSchema: z.object({\n seed: z.string().describe('YouTube channel handle/username (with or without @)'),\n }),\n },\n async (args) => {\n try {\n const result = await client.get(`/youtube/channel-summary?seed=${encodeURIComponent(args.seed)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_youtube_bridge_creators',\n {\n title: 'Get YouTube Bridge Creators',\n description:\n 'Find YouTube channels whose commenters overlap with a seed channel — the YT-network ' +\n 'analogue of audience overlap. Backed by api.get_bridge_creators_yt_v1. Free. ' +\n 'Response includes `data_status` (collected | collected_no_bridges | no_commenter_data | ' +\n 'channel_not_found) so callers can distinguish \"no overlap\" from \"no data collected yet\". ' +\n 'If `no_commenter_data`, run `scrape_youtube_commenters` on the seed first.',\n inputSchema: z.object({\n seed: z.string().describe('Seed YouTube channel handle/username'),\n min_shared_commenters: z.number().int().min(1).max(50).optional().describe('Minimum shared commenters (default 2)'),\n limit: z.number().int().min(1).max(100).optional().describe('Max bridge creators to return (default 10)'),\n }),\n },\n async (args) => {\n try {\n const params = new URLSearchParams({ seed: args.seed })\n if (args.min_shared_commenters !== undefined) params.set('min_shared_commenters', String(args.min_shared_commenters))\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n const result = await client.get(`/youtube/bridge-creators?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_youtube_graph_edges',\n {\n title: 'Get YouTube Commenter Graph Edges',\n description:\n 'Edge list for the commenter-overlap graph rooted at one or more seed channels — ' +\n 'suitable for network visualization. Provide seeds as usernames or yt: prefixed IDs. ' +\n 'Backed by api.get_graph_edges_yt_v1. Free.',\n inputSchema: z.object({\n seed_usernames: z.array(z.string()).optional().describe('YouTube channel usernames (one of seed_usernames OR seed_profile_ids required)'),\n seed_profile_ids: z.array(z.string()).optional().describe('yt: prefixed channel IDs'),\n max_nodes: z.number().int().min(10).max(5000).optional().describe('Max graph nodes (default 500)'),\n min_edge_weight: z.number().int().min(1).optional().describe('Minimum shared-commenter count to draw an edge (default 1)'),\n include_cross_creator: z.boolean().optional().describe('Include cross-creator edges (default true)'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/youtube/graph-edges', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n}\n","/**\n * Content tools — Post search\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema, SemanticPlatformSchema } from './_platform-schema'\n\nexport function registerContentTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'search_content',\n {\n title: 'Search Content',\n description:\n 'Full-text search across post captions on all 4 platforms (Instagram, TikTok, YouTube, X). ' +\n 'Returns matching posts with engagement metrics. Use `platform` to filter to a single network. ' +\n 'Use `verbose: false` to strip captions/hashtags from the response (helps when result captions ' +\n 'are long — YouTube descriptions can run 2,000–5,000 chars). Costs 2 credits per call ' +\n '(was incorrectly documented as 1 credit through 0.2.3).',\n inputSchema: z.object({\n query: z.string().describe('Search query — matches post captions (required)'),\n platform: PlatformSchema.optional().describe('Filter results to a single platform (default: all 4)'),\n author: z.string().optional().describe('Filter by creator username'),\n min_engagement: z.number().int().optional().describe('Minimum total engagement (likes + comments)'),\n since: z.string().optional().describe('Only posts after this date (ISO 8601, e.g. 2025-01-01)'),\n sort: z.enum(['relevance', 'engagement', 'date']).optional().describe(\"Sort order (default: 'relevance')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n verbose: z.boolean().optional().describe('If false, strip caption + hashtags from response (default true; back-compat)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n params.set('query', args.query)\n if (args.platform) params.set('platform', args.platform)\n if (args.author) params.set('author', args.author)\n if (args.min_engagement !== undefined) params.set('min_engagement', String(args.min_engagement))\n if (args.since) params.set('since', args.since)\n if (args.sort) params.set('sort', args.sort)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.verbose === false) params.set('verbose', 'false')\n const result = await client.get(`/content/search?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n // ============================================================================\n // Semantic Content Search (Phase 3 Embeddings)\n // ============================================================================\n\n server.registerTool(\n 'semantic_search_content',\n {\n title: 'Semantic Search Content',\n description:\n 'Search posts using AI embeddings for semantic similarity (Instagram, TikTok, X only). ' +\n 'Combines full-text search with vector similarity for best results. ' +\n 'YouTube post embeddings are not yet populated — use `search_content` (FTS) for YouTube. ' +\n 'Costs 1 credit.',\n inputSchema: z.object({\n query: z.string().describe('Search query — finds semantically similar posts'),\n author: z.string().optional().describe('Filter by creator username'),\n min_engagement: z.number().int().optional().describe('Minimum total engagement'),\n since: z.string().optional().describe('Only posts after this date (ISO 8601)'),\n platform: SemanticPlatformSchema.optional().describe('Filter by platform (instagram | tiktok | x — YouTube embeddings pending)'),\n alpha: z.number().min(0).max(1).optional().describe('Hybrid weight: 0=keyword only, 1=semantic only, 0.6=balanced (default)'),\n sort: z.enum(['relevance', 'engagement', 'date']).optional().describe(\"Sort order (default: 'relevance')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n verbose: z.boolean().optional().describe('If false, strip caption + hashtags from response (default true; back-compat)'),\n }),\n },\n async (args) => {\n const result = await client.post('/content/search/semantic', {\n query: args.query,\n author: args.author,\n min_engagement: args.min_engagement,\n since: args.since,\n platform: args.platform,\n alpha: args.alpha,\n sort: args.sort,\n limit: args.limit,\n verbose: args.verbose,\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Manage tools — CRM operations\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerManageTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_managed_profiles',\n {\n title: 'Get Managed Profiles',\n description:\n 'Get all profiles in the CRM pipeline with their relationship statuses, ' +\n 'notes, and tags. Costs 0 credits.',\n inputSchema: z.object({\n status: z.string().optional().describe(\"Filter by relationship status (e.g. 'outreached', 'negotiating', 'contracted')\"),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/manage/profiles${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_crm_summary',\n {\n title: 'Get CRM Summary',\n description:\n 'Get a summary of the CRM pipeline — counts by status, recent activity, etc. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/manage/summary')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_org_stats',\n {\n title: 'Get Organization Stats',\n description:\n 'Get aggregate statistics for the organization — total profiles, enhanced profiles, ' +\n 'scraped data, and more. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/manage/stats')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'upsert_relationship',\n {\n title: 'Upsert Relationship',\n description:\n 'Create or update a CRM relationship for a creator. Set status, notes, tags. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n status: z.string().optional().describe(\"Relationship status (e.g. 'identified', 'outreached', 'negotiating', 'contracted', 'active', 'paused')\"),\n notes: z.string().optional().describe('Free-text notes about the relationship'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n }),\n },\n async (args) => {\n const { identifier, ...body } = args\n const result = await client.patch(`/manage/profiles/${encodeURIComponent(identifier)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_relationship',\n {\n title: 'Delete Relationship',\n description:\n 'Remove a creator from the CRM pipeline. Does not delete the profile itself. Costs 0 credits.',\n inputSchema: z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/manage/profiles/${encodeURIComponent(args.identifier)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'upsert_relationships_bulk',\n {\n title: 'Upsert Relationships Bulk',\n description:\n 'Bulk update notes, tags, or status for multiple CRM profiles in one call. ' +\n 'Creates relationships if they do not exist. Max 100 profiles per request. Costs 0 credits.',\n inputSchema: z.object({\n updates: z.array(z.object({\n identifier: z.string().describe('Instagram username or profile ID'),\n status: z.string().optional().describe(\"Relationship status (e.g. 'shortlisted', 'outreached', 'negotiating')\"),\n notes: z.string().optional().describe('Free-text notes about the relationship'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n })).min(1).max(100).describe('Array of profile updates (max 100)'),\n }),\n },\n async (args) => {\n const result = await client.post('/manage/profiles/bulk', { updates: args.updates })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Knowledge tools — KB folders, entries, context search\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\nexport function registerKnowledgeTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'list_knowledge_folders',\n {\n title: 'List Knowledge Folders',\n description: 'List all knowledge base folders in the organization. Costs 0 credits.',\n inputSchema: z.object({}),\n },\n async () => {\n const result = await client.get('/knowledge/folders')\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_knowledge_folder',\n {\n title: 'Create Knowledge Folder',\n description: 'Create a new knowledge base folder. Costs 0 credits.',\n inputSchema: z.object({\n name: z.string().describe('Folder name'),\n description: z.string().optional().describe('Optional description'),\n folder_type: z.enum(['general', 'brand', 'campaign', 'templates', 'research']).optional().describe(\"Folder type (default: 'general')\"),\n parent_folder_id: z.string().optional().describe('UUID of parent folder for nesting'),\n icon_name: z.string().optional().describe('Lucide icon name'),\n color: z.string().optional().describe('Hex color (e.g. #8b5cf6)'),\n }),\n },\n async (args) => {\n const result = await client.post('/knowledge/folders', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_folder_entries',\n {\n title: 'Get Folder Entries',\n description: 'Get all entries in a knowledge base folder. Costs 0 credits.',\n inputSchema: z.object({\n folder_id: z.string().describe('Folder UUID'),\n limit: z.number().int().min(1).max(100).optional().describe('Results per page'),\n cursor: z.string().optional().describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/knowledge/folders/${encodeURIComponent(args.folder_id)}/entries${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'create_knowledge_entry',\n {\n title: 'Create Knowledge Entry',\n description: 'Create a new knowledge base entry in a folder. Costs 0 credits.',\n inputSchema: z.object({\n folder_id: z.string().describe('Folder UUID to add the entry to'),\n name: z.string().describe('Entry name'),\n content: z.string().optional().describe('Entry content (markdown supported)'),\n description: z.string().optional().describe('Short description'),\n source_url: z.string().optional().describe('Source URL reference'),\n }),\n },\n async (args) => {\n const result = await client.post('/knowledge/entries', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_knowledge_entry',\n {\n title: 'Get Knowledge Entry',\n description: 'Get a specific knowledge base entry by ID. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/knowledge/entries/${encodeURIComponent(args.entry_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'update_knowledge_entry',\n {\n title: 'Update Knowledge Entry',\n description: 'Update a knowledge base entry. At least one field required. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n name: z.string().optional().describe('New name'),\n content: z.string().optional().describe('New content'),\n description: z.string().optional().describe('New description'),\n summary: z.string().optional().describe('New summary'),\n folder_id: z.string().optional().describe('Move to a different folder (UUID)'),\n }),\n },\n async (args) => {\n const { entry_id, ...body } = args\n const result = await client.put(`/knowledge/entries/${encodeURIComponent(entry_id)}`, body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'delete_knowledge_entry',\n {\n title: 'Delete Knowledge Entry',\n description: 'Delete a knowledge base entry. Costs 0 credits.',\n inputSchema: z.object({\n entry_id: z.string().describe('Entry UUID'),\n }),\n },\n async (args) => {\n const result = await client.delete(`/knowledge/entries/${encodeURIComponent(args.entry_id)}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'search_knowledge',\n {\n title: 'Get Knowledge Context',\n description:\n 'Get aggregated brand context from the knowledge base, organized by folder type. ' +\n 'Returns entries for AI agent consumption. Filter by folder type to get specific context. Costs 0 credits.',\n inputSchema: z.object({\n folder_types: z.array(z.string()).optional().describe(\"Filter by folder types (e.g. ['brand', 'campaign', 'research'])\"),\n max_entries: z.number().int().min(1).max(100).optional().describe('Maximum entries to return (default 20, max 100)'),\n include_summaries: z.boolean().optional().describe('Include entry summaries (default true)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.folder_types?.length) params.set('folder_types', args.folder_types.join(','))\n if (args.max_entries !== undefined) params.set('max_entries', String(args.max_entries))\n if (args.include_summaries === false) params.set('include_summaries', 'false')\n const result = await client.get(`/knowledge/context?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Enhance tools — Profile enhancement triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { creditGuard } from './credit-guard'\n\nexport function registerEnhanceTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'enhance_profiles',\n {\n title: 'Enhance Profiles',\n description:\n 'Trigger AI enhancement for one or more profiles. Enhancement adds affinities, ' +\n 'demographics, niche analysis, and more. Returns a job ID — poll with ' +\n 'get_enhancement_status to check progress. Costs 1+ credits.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).describe('Array of usernames or profile IDs to enhance'),\n mode: z.enum(['basic', 'enhanced']).optional().describe(\"Enhancement mode: 'basic' (1 credit/profile) or 'enhanced' (2 credits/profile). Default: basic\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering enhancement'),\n auto_confirm: z.boolean().optional().describe('If true, auto-confirms the job without a separate confirm step'),\n authorize_overage: z.boolean().optional().describe('If true, allows proceeding even if credits are insufficient'),\n options: z.object({\n force: z.boolean().optional().describe('Re-enhance even if already enhanced'),\n }).optional().describe('Enhancement options'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { identifiers, options, confirmed, authorize_overage, ...rest } = args\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/enhance/profiles', { profiles: identifiers, ...rest, authorize_overage, dry_run: true }),\n `Enhance ${identifiers.length} profile${identifiers.length !== 1 ? 's' : ''}`,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/enhance/profiles', { profiles: identifiers, ...rest, authorize_overage })\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'enhance_bulk',\n {\n title: 'Enhance Bulk',\n description:\n 'Trigger bulk enhancement for a large set of profiles from a network source (followers/following) or search filters. ' +\n 'Returns a job ID. Costs 1+ credits.',\n inputSchema: z.object({\n source: z.object({\n type: z.enum(['followers', 'following', 'both', 'search']).describe(\"Source type: 'followers'/'following'/'both' (network) or 'search' (filter-based)\"),\n target: z.string().optional().describe('Username of the seed profile (required for followers/following/both)'),\n filters: z.object({\n query: z.string().optional().describe('Search query'),\n niche: z.string().optional().describe('Filter by niche'),\n location: z.string().optional().describe('Filter by location'),\n gender: z.enum(['male', 'female', 'non_binary', 'brand']).optional().describe('Filter by gender'),\n min_followers: z.number().int().optional().describe('Minimum followers'),\n max_followers: z.number().int().optional().describe('Maximum followers'),\n has_contact: z.boolean().optional().describe('Only profiles with contact info'),\n }).optional().describe('Search filters (required for search source)'),\n limit: z.number().int().optional().describe('Max profiles to resolve from source'),\n }).describe('Source specification for profiles to enhance'),\n mode: z.enum(['basic', 'enhanced']).optional().describe(\"Enhancement mode: 'basic' (1 credit) or 'enhanced' (2 credits). Default: basic\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering enhancement'),\n skip_already_enhanced: z.boolean().optional().describe('Skip profiles that are already enhanced'),\n auto_confirm: z.boolean().optional().describe('Auto-confirm the job without a separate confirm step'),\n authorize_overage: z.boolean().optional().describe('Allow proceeding even if credits are insufficient'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { confirmed, authorize_overage, ...rest } = args\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/enhance/bulk', { ...rest, authorize_overage, dry_run: true }),\n `Bulk enhance from ${rest.source.type} source`,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/enhance/bulk', { ...rest, authorize_overage })\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'confirm_enhancement',\n {\n title: 'Confirm Enhancement',\n description:\n 'Confirm and start a pending enhancement job. Some jobs require confirmation ' +\n 'before processing begins (e.g. large batches). Costs 0 credits (charged at creation).',\n inputSchema: z.object({\n job_id: z.string().describe('Enhancement job ID'),\n authorize_overage: z.boolean().optional().describe('Authorize credit overage if needed'),\n }),\n },\n async (args) => {\n const result = await client.post(\n `/enhance/${encodeURIComponent(args.job_id)}/confirm`,\n { authorize_overage: args.authorize_overage },\n )\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'get_enhancement_status',\n {\n title: 'Get Enhancement Status',\n description:\n 'Check the status of an enhancement job. Returns progress, completed count, ' +\n 'and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Enhancement job ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/enhance/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Credit Guard — Pre-execution cost check for expensive MCP tool calls.\n *\n * For operations estimated at ≥100 credits the guard performs a dry-run,\n * fetches the account's current usage, and returns a human-readable\n * confirmation prompt instead of executing the operation.\n *\n * The calling tool adds a `confirmed` boolean parameter. When `confirmed`\n * is true the guard is bypassed and the real request fires immediately.\n */\n\nimport type { CelaviiClient } from '../client.js'\n\nconst CREDIT_THRESHOLD = 100\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface UsageSnapshot {\n total_credits_used: number\n credits_today: number\n plan: string | null\n tier: string | null\n allow_overage: boolean\n}\n\nexport interface CreditGuardResult {\n /** true → proceed with execution */\n proceed: boolean\n /** If proceed is false, this is the confirmation message to show */\n message?: string\n /** Raw dry-run response (forwarded when proceed is true too) */\n dryRunData?: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function fetchUsage(client: CelaviiClient): Promise<UsageSnapshot> {\n try {\n const raw = (await client.get('/me')) as {\n data?: {\n usage?: { total_credits_used?: number; credits_today?: number }\n organization?: { plan?: string; allow_overage?: boolean }\n api_key?: { tier?: string }\n }\n }\n const d = raw?.data ?? (raw as Record<string, unknown>)\n const usage = (d as Record<string, unknown>)?.usage as Record<string, unknown> | undefined\n const org = (d as Record<string, unknown>)?.organization as Record<string, unknown> | undefined\n const key = (d as Record<string, unknown>)?.api_key as Record<string, unknown> | undefined\n return {\n total_credits_used: Number(usage?.total_credits_used ?? 0),\n credits_today: Number(usage?.credits_today ?? 0),\n plan: (org?.plan as string) ?? null,\n tier: (key?.tier as string) ?? null,\n allow_overage: Boolean(org?.allow_overage ?? false),\n }\n } catch {\n return { total_credits_used: 0, credits_today: 0, plan: null, tier: null, allow_overage: false }\n }\n}\n\nfunction formatConfirmation(\n action: string,\n estimatedCredits: number,\n usage: UsageSnapshot,\n dryRunData: unknown,\n): string {\n const lines: string[] = [\n '⚠️ Credit Authorization Required',\n '',\n `Action: ${action}`,\n `Estimated cost: ~${estimatedCredits} credits`,\n '',\n '── Current Account Usage ──',\n `Credits used today: ${usage.credits_today}`,\n `Total credits used: ${usage.total_credits_used}`,\n ...(usage.plan ? [`Plan: ${usage.plan}`] : []),\n ...(usage.tier ? [`API tier: ${usage.tier}`] : []),\n `Overage billing: ${usage.allow_overage ? 'enabled' : 'disabled'}`,\n '',\n '── Dry-Run Details ──',\n JSON.stringify(dryRunData, null, 2),\n '',\n 'To proceed, call this tool again with confirmed: true.',\n ]\n return lines.join('\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Guard\n// ---------------------------------------------------------------------------\n\n/**\n * Run the credit guard for a tool call that supports `dry_run`.\n *\n * @param client Celavii API client\n * @param confirmed Whether the user has already confirmed\n * @param dryRunFn A function that calls the API with dry_run: true and\n * returns the raw response. The guard will extract\n * `estimated_cost.credits` from `data` or from the root.\n * @param action Human-readable description of the operation\n */\nexport async function creditGuard(\n client: CelaviiClient,\n confirmed: boolean | undefined,\n dryRunFn: () => Promise<unknown>,\n action: string,\n): Promise<CreditGuardResult> {\n // Bypass when already confirmed\n if (confirmed) {\n return { proceed: true }\n }\n\n // Execute dry-run\n const dryResult = await dryRunFn()\n\n // Extract estimated credits from common response shapes\n const root = dryResult as Record<string, unknown>\n const data = (root?.data ?? root) as Record<string, unknown>\n const estCost = data?.estimated_cost as Record<string, unknown> | undefined\n const estimatedCredits = Number(estCost?.credits ?? data?.eligible ?? 0)\n\n // If below threshold, proceed without confirmation\n if (estimatedCredits < CREDIT_THRESHOLD) {\n return { proceed: true, dryRunData: dryResult }\n }\n\n // Above threshold → fetch usage and build confirmation prompt\n const usage = await fetchUsage(client)\n const message = formatConfirmation(action, estimatedCredits, usage, data)\n\n return { proceed: false, message, dryRunData: dryResult }\n}\n","/**\n * Scrape tools — Data collection triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerScrapeTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'scrape_followers',\n {\n title: 'Scrape Followers',\n description:\n 'Trigger a follower scrape for a profile. Collects the full follower list. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits.',\n inputSchema: z.object({\n username: z.string().describe('Instagram username to scrape followers for'),\n limit: z.number().int().optional().describe('Max followers to scrape (default: all)'),\n }),\n },\n async (args) => {\n try {\n const { limit, ...rest } = args\n const result = await client.post('/scrape/followers', { ...rest, ...(limit !== undefined && { max_results: limit }) })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_following',\n {\n title: 'Scrape Following',\n description:\n 'Trigger a following scrape for a profile. Collects who they follow. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits.',\n inputSchema: z.object({\n username: z.string().describe('Instagram username to scrape following for'),\n limit: z.number().int().optional().describe('Max following to scrape (default: all)'),\n }),\n },\n async (args) => {\n try {\n const { limit, ...rest } = args\n const result = await client.post('/scrape/following', { ...rest, ...(limit !== undefined && { max_results: limit }) })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_followers_bulk',\n {\n title: 'Bulk Scrape Followers',\n description:\n 'Trigger a follower scrape for multiple profiles in a single Apify run. ' +\n 'Much more efficient than calling scrape_followers repeatedly — uses 1 API call, ' +\n '1 DB connection, and 1 Apify run instead of N. Max 50 profiles per request. ' +\n 'Returns a single job ID — poll with get_scrape_status. Costs 2 credits + processing. ' +\n 'IMPORTANT: TikTok bulk scrapes limited to 10 profiles per request due to rate limiting.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional()\n .describe('Array of usernames to scrape followers for (max 50 for Instagram, max 10 for TikTok)'),\n profile_ids: z.array(z.string()).max(50).optional()\n .describe('Array of profile IDs (ig:XXX or tt:XXX) to scrape followers for (max 50 for Instagram, max 10 for TikTok)'),\n limit: z.number().int().optional()\n .describe('Max followers to scrape per profile (default: 10000)'),\n platform: PlatformSchema.optional()\n .describe('Platform override — auto-detected from profiles if not specified'),\n dry_run: z.boolean().optional()\n .describe('If true, returns cost estimate without triggering the scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.platform) body.platform = args.platform\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/followers/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_following_bulk',\n {\n title: 'Bulk Scrape Following',\n description:\n 'Trigger a following scrape for multiple profiles in a single Apify run. ' +\n 'Much more efficient than calling scrape_following repeatedly — uses 1 API call, ' +\n '1 DB connection, and 1 Apify run instead of N. Max 50 profiles per request. ' +\n 'Returns a single job ID — poll with get_scrape_status. Costs 2 credits + processing. ' +\n 'IMPORTANT: TikTok bulk scrapes limited to 10 profiles per request due to rate limiting.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional()\n .describe('Array of usernames to scrape following for (max 50 for Instagram, max 10 for TikTok)'),\n profile_ids: z.array(z.string()).max(50).optional()\n .describe('Array of profile IDs (ig:XXX or tt:XXX) to scrape following for (max 50 for Instagram, max 10 for TikTok)'),\n limit: z.number().int().optional()\n .describe('Max following to scrape per profile (default: 10000)'),\n platform: PlatformSchema.optional()\n .describe('Platform override — auto-detected from profiles if not specified'),\n dry_run: z.boolean().optional()\n .describe('If true, returns cost estimate without triggering the scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.platform) body.platform = args.platform\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/following/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_locations',\n {\n title: 'Scrape Locations',\n description:\n 'Scrape posts from a specific Instagram location/place. ' +\n 'Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n location_id: z.string().optional().describe('Instagram location ID'),\n location_name: z.string().optional().describe('Location name to search for'),\n limit: z.number().int().optional().describe('Max posts to scrape'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.location_id) body.location_ids = [args.location_id]\n if (args.location_name) body.start_urls = [`https://www.instagram.com/explore/locations/${args.location_name}/`]\n if (args.limit !== undefined) body.max_items = args.limit\n const result = await client.post('/scrape/locations', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_hashtags',\n {\n title: 'Scrape Hashtags',\n description:\n 'Scrape posts from a specific hashtag. Collects recent posts using that hashtag. ' +\n 'Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n hashtag: z.string().describe('Hashtag to scrape (without #)'),\n limit: z.number().int().optional().describe('Max posts to scrape'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/hashtags', {\n hashtags: [args.hashtag],\n ...(args.limit !== undefined && { max_items: args.limit }),\n })\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_urls',\n {\n title: 'Scrape URLs',\n description:\n 'Scrape specific Instagram post or reel URLs. Extracts engagement data, ' +\n 'comments, and media. Returns a job ID. Costs 1 credit.',\n inputSchema: z.object({\n urls: z.array(z.string()).describe('Array of Instagram post/reel URLs'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/urls', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_scrape_status',\n {\n title: 'Get Scrape Status',\n description:\n 'Check the status of a scrape job. Returns progress and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Scrape job ID'),\n }),\n },\n async (args) => {\n try {\n const result = await client.get(`/scrape/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // X (Twitter) triggers — Phase 3B (5 tools)\n // Backed by /api/v1/scrape/x/* (Shape A subpaths)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'scrape_x_followers',\n {\n title: 'Scrape X Followers',\n description:\n 'Trigger an X (Twitter) follower scrape for a profile via apidojo/twitter-user-scraper. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits + processing.',\n inputSchema: z.object({\n username: z.string().optional().describe('X username (without @)'),\n profile_id: z.string().optional().describe('x: prefixed profile ID (e.g. x:elonmusk)'),\n limit: z.number().int().optional().describe('Max followers to scrape (default: 10000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.username) body.username = args.username\n if (args.profile_id) body.profile_id = args.profile_id\n if (args.limit !== undefined) body.max_results = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/followers', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_followers_bulk',\n {\n title: 'Bulk Scrape X Followers',\n description:\n 'Trigger X follower scrapes for up to 50 profiles in one request. Each profile gets ' +\n 'its own search row + queue job — independent retries. Costs 2 credits per profile.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional().describe('Array of X usernames (max 50)'),\n profile_ids: z.array(z.string()).max(50).optional().describe('Array of x: prefixed profile IDs (max 50)'),\n limit: z.number().int().optional().describe('Max followers per profile (default: 5000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/followers/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_following',\n {\n title: 'Scrape X Following',\n description:\n 'Trigger an X (Twitter) following scrape for a profile. ' +\n 'Returns a job ID — poll with get_scrape_status. Costs 2 credits + processing.',\n inputSchema: z.object({\n username: z.string().optional().describe('X username (without @)'),\n profile_id: z.string().optional().describe('x: prefixed profile ID'),\n limit: z.number().int().optional().describe('Max following to scrape (default: 10000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.username) body.username = args.username\n if (args.profile_id) body.profile_id = args.profile_id\n if (args.limit !== undefined) body.max_results = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/following', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_following_bulk',\n {\n title: 'Bulk Scrape X Following',\n description:\n 'Trigger X following scrapes for up to 50 profiles in one request. ' +\n 'Costs 2 credits per profile.',\n inputSchema: z.object({\n usernames: z.array(z.string()).max(50).optional().describe('Array of X usernames (max 50)'),\n profile_ids: z.array(z.string()).max(50).optional().describe('Array of x: prefixed profile IDs (max 50)'),\n limit: z.number().int().optional().describe('Max following per profile (default: 5000)'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const body: Record<string, unknown> = {}\n if (args.usernames) body.usernames = args.usernames\n if (args.profile_ids) body.profile_ids = args.profile_ids\n if (args.limit !== undefined) body.max_results_per_profile = args.limit\n if (args.dry_run !== undefined) body.dry_run = args.dry_run\n const result = await client.post('/scrape/x/following/bulk', body)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_x_hashtags',\n {\n title: 'Scrape X Hashtags',\n description:\n 'Scrape recent X (Twitter) posts matching one or more hashtags via kaitoeasyapi tweet scraper. ' +\n 'Supports advanced filters (media-only, blue-verified, has-engagement) and sort order. ' +\n 'Returns a job ID. Costs 1 credit + processing.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).min(1).max(10).describe('1–10 hashtags (with or without #)'),\n max_items: z.number().int().optional().describe('Max tweets per hashtag (default 100)'),\n x_filters: z.object({\n media: z.boolean().optional().describe('Tweets with media only'),\n verified: z.boolean().optional().describe('Blue-verified accounts only'),\n engagement: z.boolean().optional().describe('Tweets with engagement only'),\n }).optional().describe('Advanced filters'),\n x_sort: z.enum(['Latest', 'Top']).optional().describe(\"Sort order (default 'Latest')\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/x/hashtags', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n // ──────────────────────────────────────────────────────────────────────\n // YouTube triggers — Phase 3C (4 tools)\n // Backed by /api/v1/scrape/youtube/* (mix of runCollect + Data API v3)\n // ──────────────────────────────────────────────────────────────────────\n\n server.registerTool(\n 'scrape_youtube_commenters',\n {\n title: 'Scrape YouTube Commenters',\n description:\n 'YouTube does not expose subscriber lists — the closest network signal is the set of ' +\n 'channels commenting on a creator\\'s videos. Triggers a batched commenter fetch ' +\n '(channels.list + videos.list + per-video commentThreads.list). ' +\n 'Executes synchronously within the request (typically 5–30s depending on video_count × ' +\n 'comments_per_video). The response contains the full result (total_comments, unique_commenters, ' +\n 'etc.) AND a job_id for retrospective tracking — no polling needed. ' +\n 'Results are stored in the network graph for use by get_youtube_bridge_creators and ' +\n 'get_youtube_channel_summary. Costs 2 credits + YouTube Data API v3 quota usage.',\n inputSchema: z.object({\n channel: z.string().optional().describe('Channel target — yt: prefixed ID (yt:UCxxx), @handle, or YouTube channel URL'),\n profile_id: z.string().optional().describe('DEPRECATED alias for `channel`. Same accepted forms. Will be removed in 0.3.0.'),\n video_count: z.number().int().min(1).max(50).optional().describe('Videos to sample (default 5, max 50)'),\n comments_per_video: z.number().int().min(1).max(500).optional().describe('Comments per video (default 100, max 500)'),\n dry_run: z.boolean().optional().describe('If true, returns quota estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/commenters', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_hashtags',\n {\n title: 'Scrape YouTube by Keyword',\n description:\n 'YouTube keyword/hashtag search via streamers/youtube-scraper (Apify-backed, NOT YouTube Data API v3). ' +\n 'Each input becomes a search query. Returns a job_id immediately; results land asynchronously through ' +\n 'the unified job system. Poll with `list_jobs` or `get_scrape_status` to track progress (typical run: ' +\n '1–5 min depending on per_hashtag_limit). Costs 1 credit + Apify processing.',\n inputSchema: z.object({\n hashtags: z.array(z.string()).min(1).max(10).describe('1–10 keyword queries (with or without #)'),\n per_hashtag_limit: z.number().int().optional().describe('Max videos per query (default 5)'),\n yt_include_shorts: z.boolean().optional().describe('Include YouTube Shorts (default true)'),\n yt_duration: z.enum(['all', 'short', 'medium', 'long']).optional().describe(\"Duration filter (default 'all')\"),\n yt_upload_date: z.enum(['all', 'hour', 'today', 'week', 'month', 'year']).optional().describe(\"Upload date filter (default 'all')\"),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/hashtags', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_trending',\n {\n title: 'Scrape YouTube Trending',\n description:\n 'Pull the YouTube trending feed via apidojo/youtube-scraper (Apify-backed, NOT YouTube Data API v3). ' +\n 'Returns a job_id immediately; results land asynchronously through the unified job system. Poll with ' +\n '`list_jobs` or `get_scrape_status` to track progress (typical run: 1–3 min depending on max_items). ' +\n 'Returns the most popular uploads in the requested timeframe. Costs 1 credit + Apify processing.',\n inputSchema: z.object({\n max_items: z.number().int().min(1).max(200).optional().describe('Max trending videos (default 50, max 200)'),\n yt_include_shorts: z.boolean().optional().describe('Include YouTube Shorts (default true)'),\n yt_duration: z.enum(['all', 'short', 'medium', 'long']).optional().describe('Duration filter'),\n yt_upload_date: z.enum(['all', 'hour', 'today', 'week', 'month', 'year']).optional().describe('Upload date filter'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/trending', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'scrape_youtube_videos',\n {\n title: 'Collect YouTube Channel Videos',\n description:\n \"Collect a YouTube channel's recent videos via the YouTube Data API v3 (NOT Apify). \" +\n 'Executes synchronously within the request (typically 3–15s depending on videos_limit). The response ' +\n 'contains the job_id + quota_consumed; results are written to `posts` and become queryable immediately. ' +\n 'No polling needed for completion, but `get_scrape_status` works for retrospective tracking. ' +\n 'Costs 2 credits + Data API v3 quota usage.',\n inputSchema: z.object({\n target: z.string().describe('Channel target — yt: prefixed ID, @handle, or YouTube channel URL'),\n videos_limit: z.number().int().min(1).max(500).optional().describe('Max videos (default 50, max 500)'),\n search_name: z.string().optional().describe('Optional display name for the resulting search'),\n dry_run: z.boolean().optional().describe('If true, returns quota estimate without triggering'),\n }),\n },\n async (args) => {\n try {\n const result = await client.post('/scrape/youtube/videos', args)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text', text: `Error: ${message}` }] }\n }\n },\n )\n}\n","/**\n * Refine tools — AI refinement triggers + status\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { creditGuard } from './credit-guard'\n\nexport function registerRefineTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'refine_profiles',\n {\n title: 'Refine Profiles',\n description:\n 'Trigger AI refinement for one or more profiles. Refinement uses AI to ' +\n 'improve and enrich profile data — better niche classification, bio analysis, ' +\n 'content themes, etc. Returns a job ID — poll with get_refinement_status. Costs 1+ credits.',\n inputSchema: z.object({\n identifiers: z.array(z.string()).optional().describe('Array of usernames or profile IDs to refine'),\n list_id: z.string().optional().describe('List UUID — refine all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — refine all creators in this campaign'),\n dry_run: z.boolean().optional().describe('If true, returns cost estimate without triggering refinement'),\n skip_already_refined: z.boolean().optional().describe('Skip profiles that have already been refined'),\n confirmed: z.boolean().optional().describe('Set to true after reviewing the cost estimate to proceed with execution'),\n }),\n },\n async (args) => {\n try {\n const { identifiers, list_id, campaign_id, confirmed, ...rest } = args\n\n // Build request body based on input mode\n const bodyBase: Record<string, unknown> = { ...rest }\n if (identifiers && identifiers.length > 0) {\n bodyBase.profiles = identifiers\n } else if (list_id) {\n bodyBase.list_id = list_id\n } else if (campaign_id) {\n bodyBase.campaign_id = campaign_id\n } else {\n return { content: [{ type: 'text' as const, text: 'Error: Provide identifiers, list_id, or campaign_id' }] }\n }\n\n // Determine label for credit guard\n const label = list_id\n ? `Refine list ${list_id}`\n : campaign_id\n ? `Refine campaign ${campaign_id}`\n : `Refine ${identifiers?.length || 0} profile${(identifiers?.length || 0) !== 1 ? 's' : ''}`\n\n // Credit guard: dry-run first for 100+ credit operations\n const guard = await creditGuard(\n client,\n confirmed, // Only bypass when explicitly confirmed, NOT for dry_run\n () => client.post('/refine/profiles', { ...bodyBase, dry_run: true }),\n label,\n )\n\n // For dry_run, always return the dry-run data (guard executes the API call)\n if (rest.dry_run) {\n const text = guard.dryRunData ? JSON.stringify(guard.dryRunData, null, 2) : 'Dry-run failed - no data returned'\n return { content: [{ type: 'text' as const, text }] }\n }\n\n // For non-dry-run, check if confirmation is needed (≥100 credits)\n if (!guard.proceed) {\n return { content: [{ type: 'text' as const, text: guard.message || 'Confirmation required' }] }\n }\n\n const result = await client.post('/refine/profiles', bodyBase)\n return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { content: [{ type: 'text' as const, text: `Error: ${message}` }] }\n }\n },\n )\n\n server.registerTool(\n 'get_refinement_status',\n {\n title: 'Get Refinement Status',\n description:\n 'Check the status of a refinement job. Returns progress and results when done. Costs 0 credits.',\n inputSchema: z.object({\n job_id: z.string().describe('Refinement job ID'),\n }),\n },\n async (args) => {\n const result = await client.get(`/refine/${encodeURIComponent(args.job_id)}/status`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Jobs tools — Job coverage and status tracking\n */\n\nimport { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\nimport { PlatformSchema } from './_platform-schema'\n\nexport function registerJobsTools(server: McpServer, client: CelaviiClient) {\n server.registerTool(\n 'get_job_coverage',\n {\n title: 'Get Job Coverage',\n description:\n 'Get aggregate job coverage stats for a list or campaign — shows how many profiles have been enhanced, refined, ' +\n 'or scraped (followers/following) and how many are pending or not started. ' +\n 'Provide a list_id or campaign_id. Optionally filter by job_type or platform. Costs 0 credits.',\n inputSchema: z.object({\n list_id: z.string().optional().describe('List UUID — get coverage for all members of this list'),\n campaign_id: z.string().optional().describe('Campaign UUID — get coverage for all creators in this campaign'),\n job_type: z.enum(['enhance', 'refine', 'followers_scrape', 'following_scrape']).optional()\n .describe(\"Filter to a single job type (default: all)\"),\n platform: PlatformSchema.optional()\n .describe(\"Filter by platform (default: all)\"),\n tags: z.array(z.string()).optional().describe('Filter by tags (reserved for future use)'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.list_id) params.set('list_id', args.list_id)\n if (args.campaign_id) params.set('campaign_id', args.campaign_id)\n if (args.job_type) params.set('job_type', args.job_type)\n if (args.platform) params.set('platform', args.platform)\n if (args.tags?.length) params.set('tags', args.tags.join(','))\n const result = await client.get(`/jobs/coverage?${params}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n\n server.registerTool(\n 'list_jobs',\n {\n title: 'List Jobs',\n description:\n 'List all jobs for the organization — enhancement, refinement, and 7 scrape kinds. ' +\n 'Returns a unified view sorted by most recent. Filter by type and/or status. ' +\n 'Scrape kinds (added in 0.2.4): hashtag_scrape, location_scrape, video_scrape, ' +\n 'commenter_scrape, url_scrape — alongside existing followers_scrape + following_scrape. ' +\n 'Costs 0 credits.',\n inputSchema: z.object({\n type: z.enum([\n 'enhance',\n 'refine',\n 'followers_scrape',\n 'following_scrape',\n 'hashtag_scrape',\n 'location_scrape',\n 'video_scrape',\n 'commenter_scrape',\n 'url_scrape',\n ]).optional()\n .describe('Filter by job type (default: all)'),\n status: z.string().optional()\n .describe(\"Filter by status (e.g. 'completed', 'failed', 'processing', 'pending', 'queued')\"),\n limit: z.number().int().min(1).max(100).optional()\n .describe('Results per page (default 25, max 100)'),\n cursor: z.string().optional()\n .describe('Pagination cursor'),\n }),\n },\n async (args) => {\n const params = new URLSearchParams()\n if (args.type) params.set('type', args.type)\n if (args.status) params.set('status', args.status)\n if (args.limit !== undefined) params.set('limit', String(args.limit))\n if (args.cursor) params.set('cursor', args.cursor)\n const qs = params.toString()\n const result = await client.get(`/jobs${qs ? `?${qs}` : ''}`)\n return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }\n },\n )\n}\n","/**\n * Tool registration registry — single source of truth.\n *\n * Both entry points register tools via this helper:\n * - stdio entry: packages/mcp/src/server.ts → createServer()\n * - remote entry: src/app/api/mcp/[transport]/route.ts → /api/mcp/mcp\n *\n * Before this module existed, both files had their own copy-pasted list\n * of `registerXxxTools(server, client)` calls, which drifted across\n * versions:\n * - 0.1.22 added `jobs` group → only stdio updated; remote was missing\n * `list_jobs` + `get_job_coverage` for two minor versions until v3.\n * - 0.2.0 added 13 YT/X tools → tool_count comments drifted \"61 tools\"\n * vs \"70 tools\" vs \"83 tools\" because two places had to be edited.\n *\n * Now there's one list. To add a tool group:\n * 1. Add the registrar function in `packages/mcp/src/tools/<group>.ts`\n * 2. Add the entry to `TOOL_GROUPS` and `REGISTRARS` below\n *\n * Both stdio and remote pick up the new group automatically — no second\n * edit, no drift possible.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CelaviiClient } from '../client.js'\n\n// .js suffix intentionally omitted on these value imports.\n//\n// Turbopack (Next.js 16) on Vercel cannot resolve sibling .ts files via\n// the .js extension as a value import — the build fails with\n// \"Module not found: Can't resolve './meta.js'\". See Phase 5 finding\n// (commit 7d265895) where the same fix was applied to the\n// `_platform-schema.js` imports across the tool files.\n//\n// Type-only imports above (e.g. `import type { CelaviiClient } from\n// '../client.js'`) are erased before Turbopack's resolver runs and\n// don't trigger this issue.\n//\n// The npm package is unaffected because tsup is configured with\n// `splitting: false` — it bundles all imports inline into a single\n// dist/index.js regardless of extension.\nimport { registerMetaTools } from './meta'\nimport { registerProfileTools } from './profiles'\nimport { registerCampaignTools } from './campaigns'\nimport { registerListTools } from './lists'\nimport { registerAnalyticsTools } from './analytics'\nimport { registerContentTools } from './content'\nimport { registerManageTools } from './manage'\nimport { registerKnowledgeTools } from './knowledge'\nimport { registerEnhanceTools } from './enhance'\nimport { registerScrapeTools } from './scrape'\nimport { registerRefineTools } from './refine'\nimport { registerJobsTools } from './jobs'\n\n/**\n * Available tool groups, in canonical registration order.\n *\n * `meta` is always loaded (account info + usage); it sits outside this\n * list because the `CELAVII_TOOLS` env var filter never excludes it.\n */\nexport const TOOL_GROUPS = [\n 'profiles',\n 'campaigns',\n 'lists',\n 'analytics',\n 'content',\n 'manage',\n 'knowledge',\n 'enhance',\n 'scrape',\n 'refine',\n 'jobs',\n] as const\n\nexport type ToolGroup = (typeof TOOL_GROUPS)[number]\n\ntype Registrar = (server: McpServer, client: CelaviiClient) => void\n\n/**\n * Filterable registrars. Order is the canonical registration order, which\n * affects the order tools appear in `tools/list` responses (some clients\n * surface them in registration order in their tool picker).\n */\nconst REGISTRARS: Record<ToolGroup, Registrar> = {\n profiles: registerProfileTools,\n campaigns: registerCampaignTools,\n lists: registerListTools,\n analytics: registerAnalyticsTools,\n content: registerContentTools,\n manage: registerManageTools,\n knowledge: registerKnowledgeTools,\n enhance: registerEnhanceTools,\n scrape: registerScrapeTools,\n refine: registerRefineTools,\n jobs: registerJobsTools,\n}\n\nexport interface RegisterAllOptions {\n /**\n * Optional filter — only register tools in these groups. If omitted or\n * empty, every group is registered. `meta` is always registered\n * regardless.\n */\n groups?: ToolGroup[]\n}\n\n/**\n * Register every tool group on the given MCP server, optionally filtered\n * by `opts.groups`. `meta` is always registered.\n */\nexport function registerAllTools(\n server: McpServer,\n client: CelaviiClient,\n opts: RegisterAllOptions = {},\n): void {\n const enabled =\n opts.groups && opts.groups.length > 0 ? new Set(opts.groups) : null\n\n // Meta tools (account info, usage) are always registered, regardless of\n // the CELAVII_TOOLS filter.\n registerMetaTools(server, client)\n\n for (const group of TOOL_GROUPS) {\n if (!enabled || enabled.has(group)) {\n REGISTRARS[group](server, client)\n }\n }\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "celavii-mcp",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Celavii MCP Server — Connect your Celavii account to AI-powered IDEs and assistants",
5
5
  "author": "Celavii <engineering@celavii.com>",
6
6
  "license": "MIT",