@waniwani/relay 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +169 -2
- package/dist/index.d.ts +44 -0
- package/dist/index.js +1368 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/headers.ts","../src/settings.ts","../src/http.ts","../src/ingest.ts","../src/key.ts","../src/logic/decide.ts","../src/logic/agents.json","../src/logic/ip-ranges.generated.json","../src/match-key.ts","../src/version.ts","../src/wait-until.ts","../src/index.ts"],"sourcesContent":["export const HEADER_CAP: readonly string[] = [\n\t\"user-agent\",\n\t\"referer\",\n\t\"accept\",\n\t\"accept-language\",\n\t\"from\",\n\t\"signature-agent\",\n\t\"signature-input\",\n\t\"signature\",\n\t\"dpop\",\n\t\"sec-ch-ua\",\n\t\"sec-ch-ua-platform\",\n\t\"sec-ch-ua-mobile\",\n\t\"authorization\",\n];\n\nconst KNOWN_SCHEMES = new Map(\n\t[\n\t\t\"Basic\",\n\t\t\"Bearer\",\n\t\t\"Digest\",\n\t\t\"DPoP\",\n\t\t\"HOBA\",\n\t\t\"Mutual\",\n\t\t\"Negotiate\",\n\t\t\"NTLM\",\n\t\t\"OAuth\",\n\t\t\"PrivateToken\",\n\t\t\"SCRAM-SHA-1\",\n\t\t\"SCRAM-SHA-256\",\n\t\t\"vapid\",\n\t\t\"AWS4-HMAC-SHA256\",\n\t].map((scheme) => [scheme.toLowerCase(), scheme]),\n);\n\n/** The canonical name of a known Authorization scheme, kept only when a credential follows it. */\nexport function authorizationScheme(value: string): string | null {\n\tconst parts = value.trim().split(/\\s+/);\n\tif (parts.length < 2) {\n\t\treturn null;\n\t}\n\treturn KNOWN_SCHEMES.get((parts[0] ?? \"\").toLowerCase()) ?? null;\n}\n\nexport function readCappedHeaders(headers: Headers): Record<string, string> {\n\tconst out: Record<string, string> = {};\n\tfor (const name of HEADER_CAP) {\n\t\tconst value = headers.get(name);\n\t\tif (value === null) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (name === \"authorization\") {\n\t\t\tconst scheme = authorizationScheme(value);\n\t\t\tif (scheme !== null) {\n\t\t\t\tout[name] = scheme;\n\t\t\t}\n\t\t} else {\n\t\t\tout[name] = value;\n\t\t}\n\t}\n\treturn out;\n}\n\n/** Cloudflare appends the real IP to a client-sent `X-Forwarded-For`, so `CF-Connecting-IP` comes first. */\nexport function clientIp(headers: Headers): string | null {\n\tconst forwarded = headers.get(\"x-forwarded-for\");\n\tconst candidate =\n\t\theaders.get(\"cf-connecting-ip\") ??\n\t\t(forwarded !== null ? forwarded.split(\",\")[0] : headers.get(\"x-real-ip\"));\n\tconst ip = candidate?.trim().toLowerCase();\n\treturn ip ? ip : null;\n}\n","export const settings = {\n\tapiUrls: {\n\t\tus: \"https://app.waniwani.ai\",\n\t\teu: \"https://eu.app.waniwani.ai\",\n\t},\n\trequestTimeoutMs: 2000,\n\tretryDelayMs: 500,\n};\n","import { settings } from \"./settings\";\n\nexport type Outcome = { status: number } | { failure: \"timeout\" | \"network\" };\n\n/** One fetch bounded by the request timeout. Never rejects. */\nexport async function fetchWithTimeout(\n\turl: string,\n\tinit: RequestInit,\n): Promise<Outcome> {\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), settings.requestTimeoutMs);\n\ttry {\n\t\tconst response = await fetch(url, { ...init, signal: controller.signal });\n\t\tawait response.body?.cancel().catch(() => {});\n\t\treturn { status: response.status };\n\t} catch {\n\t\treturn { failure: controller.signal.aborted ? \"timeout\" : \"network\" };\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\nexport const delay = (ms: number) =>\n\tnew Promise<void>((resolve) => setTimeout(resolve, ms));\n","import { delay, fetchWithTimeout, type Outcome } from \"./http\";\nimport { settings } from \"./settings\";\n\nconst isSuccess = (outcome: Outcome) =>\n\t\"status\" in outcome && outcome.status >= 200 && outcome.status < 300;\n\nconst isRetryable = (outcome: Outcome) =>\n\t\"failure\" in outcome || outcome.status === 429 || outcome.status >= 500;\n\nconst describe = (outcome: Outcome) =>\n\t\"failure\" in outcome ? outcome.failure : `status ${outcome.status}`;\n\nconst post = (url: string, body: string) =>\n\tfetchWithTimeout(url, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"content-type\": \"application/json\" },\n\t\tbody,\n\t});\n\n/** Posts once, retries once on a timeout, network error, 429 or 5xx, and never rejects. */\nexport async function postEvent(url: string, body: string): Promise<boolean> {\n\tlet outcome = await post(url, body);\n\tif (!isSuccess(outcome) && isRetryable(outcome)) {\n\t\tawait delay(settings.retryDelayMs);\n\t\toutcome = await post(url, body);\n\t}\n\tif (isSuccess(outcome)) {\n\t\treturn true;\n\t}\n\tconsole.warn(\n\t\t`[@waniwani/relay] Could not record an agent visit (${describe(outcome)}). The event was dropped.`,\n\t);\n\treturn false;\n}\n","export type RelayKey = { ingestToken: string; orgKey: string };\n\nconst KEY = /^wwt_([A-Za-z0-9_-]+)\\.([A-Za-z0-9_-]+={0,2})$/;\n\nlet warnedMalformed = false;\n\nexport function readKey(explicit: string | undefined): RelayKey | null {\n\tconst raw = explicit ?? readEnv(\"WANIWANI_AGENT_TRAFFIC_KEY\");\n\tif (raw === undefined || raw.trim() === \"\") {\n\t\treturn null;\n\t}\n\tconst match = KEY.exec(raw.trim());\n\tif (!match?.[1] || !match[2]) {\n\t\tif (!warnedMalformed) {\n\t\t\twarnedMalformed = true;\n\t\t\tconsole.warn(\n\t\t\t\t\"[@waniwani/relay] WANIWANI_AGENT_TRAFFIC_KEY is malformed, so no agent visits are recorded. Copy the key again from the WaniWani setup screen.\",\n\t\t\t);\n\t\t}\n\t\treturn null;\n\t}\n\treturn { ingestToken: match[1], orgKey: match[2] };\n}\n\nfunction readEnv(name: string): string | undefined {\n\ttry {\n\t\treturn typeof process === \"undefined\" ? undefined : process.env[name];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n","import { BlockList } from \"node:net\";\nimport agents from \"./agents.json\";\nimport ranges from \"./ip-ranges.generated.json\";\n\nexport type DecideInput = {\n\theaders: Record<string, string>;\n\tip: string | null;\n};\n\nconst MAX_SCANNED_USER_AGENT = 1024;\nconst PREFIX = 3;\n\nconst tokensByPrefix = new Map<string, string[]>();\nfor (const token of agents.tokens) {\n\tconst key = token.slice(0, PREFIX);\n\tconst list = tokensByPrefix.get(key);\n\tif (list) {\n\t\tlist.push(token);\n\t} else {\n\t\ttokensByPrefix.set(key, [token]);\n\t}\n}\n\nconst agentRanges = new BlockList();\nconst addRanges = (cidrs: string[], type: \"ipv4\" | \"ipv6\") => {\n\tfor (const cidr of cidrs) {\n\t\tconst [address = \"\", prefix] = cidr.split(\"/\");\n\t\tagentRanges.addSubnet(address, Number(prefix), type);\n\t}\n};\nfor (const source of ranges.sources) {\n\taddRanges(source.ipv4, \"ipv4\");\n\taddRanges(source.ipv6, \"ipv6\");\n}\n\nexport const isAgentIp = (ip: string): boolean =>\n\tagentRanges.check(ip, ip.includes(\":\") ? \"ipv6\" : \"ipv4\");\n\nexport function hasAgentToken(userAgent: string): boolean {\n\tconst text = userAgent.slice(0, MAX_SCANNED_USER_AGENT).toLowerCase();\n\tfor (let i = 0; i + PREFIX <= text.length; i++) {\n\t\tconst candidates = tokensByPrefix.get(text.slice(i, i + PREFIX));\n\t\tif (candidates) {\n\t\t\tfor (const token of candidates) {\n\t\t\t\tif (text.startsWith(token, i)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function decide({ headers, ip }: DecideInput): boolean {\n\tconst userAgent = headers[\"user-agent\"];\n\treturn (\n\t\t(userAgent !== undefined && hasAgentToken(userAgent)) ||\n\t\theaders[\"signature-agent\"] !== undefined ||\n\t\theaders.dpop !== undefined ||\n\t\theaders.authorization?.toLowerCase() === \"dpop\" ||\n\t\t(ip !== null && isAgentIp(ip))\n\t);\n}\n","{\n\t\"source\": \"Hand copied from the WaniWani bot catalog (kinds training, search and fetcher). Each token is matched case-insensitively inside the User-Agent header.\",\n\t\"tokens\": [\n\t\t\"gptbot\",\n\t\t\"claudebot\",\n\t\t\"anthropic-ai\",\n\t\t\"googleother\",\n\t\t\"googleother-image\",\n\t\t\"googleother-video\",\n\t\t\"meta-externalagent\",\n\t\t\"facebookbot\",\n\t\t\"bytespider\",\n\t\t\"tiktokspider\",\n\t\t\"ccbot\",\n\t\t\"diffbot\",\n\t\t\"ai2bot\",\n\t\t\"ai2bot-dolma\",\n\t\t\"timpibot\",\n\t\t\"cohere-training-data-crawler\",\n\t\t\"mistralai-training\",\n\t\t\"deepseekbot\",\n\t\t\"erniebot\",\n\t\t\"qwenbot\",\n\t\t\"pangubot\",\n\t\t\"kimibot\",\n\t\t\"yandexadditional\",\n\t\t\"yandexadditionalbot\",\n\t\t\"brightbot\",\n\t\t\"reflectionbot\",\n\t\t\"agenttimes\",\n\t\t\"aihitbot\",\n\t\t\"awario\",\n\t\t\"chatglm-spider\",\n\t\t\"cotoyogi\",\n\t\t\"datenbank crawler\",\n\t\t\"echobot bot\",\n\t\t\"echoboxbot\",\n\t\t\"factset_spyderbot\",\n\t\t\"friendlycrawler\",\n\t\t\"icc-crawler\",\n\t\t\"imagesiftbot\",\n\t\t\"imagespider\",\n\t\t\"img2dataset\",\n\t\t\"isscyberriskcrawler\",\n\t\t\"kangaroo bot\",\n\t\t\"kunatocrawler\",\n\t\t\"laion-huggingface-processor\",\n\t\t\"laiondownloader\",\n\t\t\"mycentralaiscraperbot\",\n\t\t\"nagetbot\",\n\t\t\"netestate imprint crawler\",\n\t\t\"omgili\",\n\t\t\"omgilibot\",\n\t\t\"panscient\",\n\t\t\"poseidon research crawler\",\n\t\t\"sbintuitionsbot\",\n\t\t\"sidetrade indexer bot\",\n\t\t\"thinkbot\",\n\t\t\"velenpublicwebcrawler\",\n\t\t\"wardbot\",\n\t\t\"oai-searchbot\",\n\t\t\"oai-adsbot\",\n\t\t\"claude-searchbot\",\n\t\t\"perplexitybot\",\n\t\t\"applebot\",\n\t\t\"amazonbot\",\n\t\t\"amzn-searchbot\",\n\t\t\"amazon-kendra\",\n\t\t\"meta-webindexer\",\n\t\t\"mistralai-index\",\n\t\t\"kimi-searchbot\",\n\t\t\"azureai-searchbot\",\n\t\t\"petalbot\",\n\t\t\"youbot\",\n\t\t\"exabot\",\n\t\t\"exasearchbot\",\n\t\t\"keenablebot\",\n\t\t\"linkupbot\",\n\t\t\"seltzsitemapfetcher\",\n\t\t\"shapbot\",\n\t\t\"tavilybot\",\n\t\t\"bravebot\",\n\t\t\"cloudflare-autorag\",\n\t\t\"jackjillcareersbot\",\n\t\t\"addsearchbot\",\n\t\t\"aiwebindex\",\n\t\t\"andibot\",\n\t\t\"aranet-searchbot\",\n\t\t\"channel3bot\",\n\t\t\"iaskbot\",\n\t\t\"iaskspider\",\n\t\t\"querit-searchbot\",\n\t\t\"queritbot\",\n\t\t\"terracotta\",\n\t\t\"terra cotta\",\n\t\t\"zanistabot\",\n\t\t\"chatgpt-user\",\n\t\t\"chatgpt agent\",\n\t\t\"claude-user\",\n\t\t\"claude-web\",\n\t\t\"claude-code\",\n\t\t\"perplexity-user\",\n\t\t\"mistralai-user\",\n\t\t\"meta-externalfetcher\",\n\t\t\"google-cloudvertexbot\",\n\t\t\"cloudvertexbot\",\n\t\t\"google-firebase\",\n\t\t\"google-notebooklm\",\n\t\t\"notebooklm\",\n\t\t\"gemini-deep-research\",\n\t\t\"google-agent\",\n\t\t\"googleagent-mariner\",\n\t\t\"googleagent-urlcontext\",\n\t\t\"google-gemini-cli\",\n\t\t\"duckassistbot\",\n\t\t\"cohere-ai\",\n\t\t\"amzn-user\",\n\t\t\"amazonbuyforme\",\n\t\t\"amazon-qbusiness\",\n\t\t\"novaact\",\n\t\t\"bedrockbot\",\n\t\t\"diffbot-user\",\n\t\t\"ai2bot-deepresearcheval\",\n\t\t\"kimi-agent\",\n\t\t\"kimi-user\",\n\t\t\"manus-user\",\n\t\t\"kagi-fetcher\",\n\t\t\"phindbot\",\n\t\t\"tongyibot\",\n\t\t\"yiyanbot\",\n\t\t\"doubaobot\",\n\t\t\"shap-user\",\n\t\t\"firecrawlagent\",\n\t\t\"apifybot\",\n\t\t\"apifywebsitecontentcrawler\",\n\t\t\"cloudflarebrowserrenderingcrawler\",\n\t\t\"crawlspace\",\n\t\t\"mozilla-tabstack\",\n\t\t\"klaviyoaibot\",\n\t\t\"atlassian-bot\",\n\t\t\"semrushbot-ocob\",\n\t\t\"semrushbot-swa\",\n\t\t\"quillbot\",\n\t\t\"bigsur.ai\",\n\t\t\"geisthaus-pagefetcher\",\n\t\t\"poggio-citations\",\n\t\t\"qualifiedbot\",\n\t\t\"twinagent\",\n\t\t\"agentdatabot\",\n\t\t\"bixelbot\",\n\t\t\"buddybot\",\n\t\t\"cragcrawler\",\n\t\t\"crawl4ai\",\n\t\t\"henkbot\",\n\t\t\"lightpanda\",\n\t\t\"linerbot\",\n\t\t\"qodercli\",\n\t\t\"wrtnbot\"\n\t]\n}\n","{\n\t\"sources\": [\n\t\t{\n\t\t\t\"bot\": \"GPTBot\",\n\t\t\t\"url\": \"https://openai.com/gptbot.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"4.227.36.0/25\",\n\t\t\t\t\"20.125.66.80/28\",\n\t\t\t\t\"20.171.206.0/24\",\n\t\t\t\t\"20.171.207.0/24\",\n\t\t\t\t\"52.230.152.0/24\",\n\t\t\t\t\"74.7.175.128/25\",\n\t\t\t\t\"74.7.227.0/25\",\n\t\t\t\t\"74.7.227.128/25\",\n\t\t\t\t\"74.7.228.0/25\",\n\t\t\t\t\"74.7.230.0/25\",\n\t\t\t\t\"74.7.241.0/25\",\n\t\t\t\t\"74.7.241.128/25\",\n\t\t\t\t\"74.7.242.0/25\",\n\t\t\t\t\"74.7.243.128/25\",\n\t\t\t\t\"74.7.244.0/25\",\n\t\t\t\t\"132.196.86.0/24\",\n\t\t\t\t\"172.182.202.0/25\",\n\t\t\t\t\"172.182.207.0/25\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"OAI-SearchBot\",\n\t\t\t\"url\": \"https://openai.com/searchbot.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"4.227.36.0/25\",\n\t\t\t\t\"13.66.216.176/28\",\n\t\t\t\t\"20.14.99.96/28\",\n\t\t\t\t\"20.25.151.224/28\",\n\t\t\t\t\"20.42.10.176/28\",\n\t\t\t\t\"20.168.18.32/28\",\n\t\t\t\t\"20.169.6.224/28\",\n\t\t\t\t\"20.169.7.48/28\",\n\t\t\t\t\"20.169.77.0/25\",\n\t\t\t\t\"20.171.53.224/28\",\n\t\t\t\t\"20.171.123.64/28\",\n\t\t\t\t\"23.102.145.48/28\",\n\t\t\t\t\"40.67.175.0/25\",\n\t\t\t\t\"40.90.214.16/28\",\n\t\t\t\t\"51.8.102.0/24\",\n\t\t\t\t\"74.7.175.128/25\",\n\t\t\t\t\"74.7.228.0/25\",\n\t\t\t\t\"74.7.228.128/25\",\n\t\t\t\t\"74.7.229.0/25\",\n\t\t\t\t\"74.7.229.128/25\",\n\t\t\t\t\"74.7.230.0/25\",\n\t\t\t\t\"74.7.241.128/25\",\n\t\t\t\t\"74.7.242.128/25\",\n\t\t\t\t\"74.7.243.0/25\",\n\t\t\t\t\"74.7.244.0/25\",\n\t\t\t\t\"104.210.140.128/28\",\n\t\t\t\t\"135.234.64.0/24\",\n\t\t\t\t\"172.182.193.80/28\",\n\t\t\t\t\"172.182.193.224/28\",\n\t\t\t\t\"172.182.194.32/28\",\n\t\t\t\t\"172.182.194.144/28\",\n\t\t\t\t\"172.182.195.48/28\",\n\t\t\t\t\"172.182.209.208/28\",\n\t\t\t\t\"172.182.211.192/28\",\n\t\t\t\t\"172.182.213.192/28\",\n\t\t\t\t\"172.182.224.0/28\",\n\t\t\t\t\"172.203.190.80/28\",\n\t\t\t\t\"172.203.190.112/28\",\n\t\t\t\t\"172.203.190.128/28\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"ChatGPT-User\",\n\t\t\t\"url\": \"https://openai.com/chatgpt-user.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"4.151.71.176/28\",\n\t\t\t\t\"4.151.119.48/28\",\n\t\t\t\t\"4.189.118.208/28\",\n\t\t\t\t\"4.189.119.48/28\",\n\t\t\t\t\"4.197.22.112/28\",\n\t\t\t\t\"4.197.64.0/28\",\n\t\t\t\t\"4.197.64.16/28\",\n\t\t\t\t\"4.197.64.48/28\",\n\t\t\t\t\"4.197.64.64/28\",\n\t\t\t\t\"4.197.115.112/28\",\n\t\t\t\t\"4.201.232.64/28\",\n\t\t\t\t\"4.205.128.176/28\",\n\t\t\t\t\"4.218.24.64/28\",\n\t\t\t\t\"4.226.200.16/28\",\n\t\t\t\t\"4.226.226.32/28\",\n\t\t\t\t\"9.129.0.0/16\",\n\t\t\t\t\"9.160.34.144/28\",\n\t\t\t\t\"9.160.36.16/28\",\n\t\t\t\t\"9.160.96.16/28\",\n\t\t\t\t\"9.160.128.16/28\",\n\t\t\t\t\"9.160.128.64/28\",\n\t\t\t\t\"9.160.163.128/28\",\n\t\t\t\t\"9.163.101.48/28\",\n\t\t\t\t\"9.205.8.48/28\",\n\t\t\t\t\"9.205.8.64/28\",\n\t\t\t\t\"9.205.25.128/28\",\n\t\t\t\t\"9.205.30.128/28\",\n\t\t\t\t\"9.205.30.144/28\",\n\t\t\t\t\"9.205.30.176/28\",\n\t\t\t\t\"9.205.128.32/28\",\n\t\t\t\t\"9.205.128.48/28\",\n\t\t\t\t\"9.223.181.208/28\",\n\t\t\t\t\"9.234.96.192/28\",\n\t\t\t\t\"9.234.97.96/28\",\n\t\t\t\t\"13.65.138.112/28\",\n\t\t\t\t\"13.67.72.16/28\",\n\t\t\t\t\"13.71.2.208/28\",\n\t\t\t\t\"13.76.32.208/28\",\n\t\t\t\t\"13.76.116.80/28\",\n\t\t\t\t\"13.83.167.128/28\",\n\t\t\t\t\"13.83.237.176/28\",\n\t\t\t\t\"20.45.178.144/28\",\n\t\t\t\t\"20.55.229.144/28\",\n\t\t\t\t\"20.57.199.192/28\",\n\t\t\t\t\"20.63.180.96/28\",\n\t\t\t\t\"20.63.221.64/28\",\n\t\t\t\t\"20.78.130.48/28\",\n\t\t\t\t\"20.83.243.176/28\",\n\t\t\t\t\"20.98.18.80/28\",\n\t\t\t\t\"20.102.212.144/28\",\n\t\t\t\t\"20.113.211.112/28\",\n\t\t\t\t\"20.113.225.112/28\",\n\t\t\t\t\"20.125.112.224/28\",\n\t\t\t\t\"20.125.144.144/28\",\n\t\t\t\t\"20.161.75.208/28\",\n\t\t\t\t\"20.168.7.192/28\",\n\t\t\t\t\"20.169.73.32/28\",\n\t\t\t\t\"20.169.73.64/28\",\n\t\t\t\t\"20.169.78.48/28\",\n\t\t\t\t\"20.169.78.64/28\",\n\t\t\t\t\"20.169.78.128/28\",\n\t\t\t\t\"20.169.78.160/28\",\n\t\t\t\t\"20.169.78.192/28\",\n\t\t\t\t\"20.169.86.224/28\",\n\t\t\t\t\"20.169.86.240/28\",\n\t\t\t\t\"20.170.184.16/28\",\n\t\t\t\t\"20.170.184.32/28\",\n\t\t\t\t\"20.170.184.48/28\",\n\t\t\t\t\"20.170.184.64/28\",\n\t\t\t\t\"20.170.184.80/28\",\n\t\t\t\t\"20.172.29.32/28\",\n\t\t\t\t\"20.199.211.160/28\",\n\t\t\t\t\"20.199.242.0/28\",\n\t\t\t\t\"20.200.212.240/28\",\n\t\t\t\t\"20.206.101.192/28\",\n\t\t\t\t\"20.210.211.192/28\",\n\t\t\t\t\"20.212.62.208/28\",\n\t\t\t\t\"20.215.187.208/28\",\n\t\t\t\t\"20.215.219.128/28\",\n\t\t\t\t\"20.215.219.160/28\",\n\t\t\t\t\"20.215.219.208/28\",\n\t\t\t\t\"20.218.30.240/28\",\n\t\t\t\t\"20.219.71.192/28\",\n\t\t\t\t\"20.219.161.192/28\",\n\t\t\t\t\"20.219.184.96/28\",\n\t\t\t\t\"20.222.36.192/28\",\n\t\t\t\t\"20.227.140.32/28\",\n\t\t\t\t\"20.228.106.176/28\",\n\t\t\t\t\"20.235.87.224/28\",\n\t\t\t\t\"20.249.63.208/28\",\n\t\t\t\t\"20.250.6.128/28\",\n\t\t\t\t\"20.250.136.64/28\",\n\t\t\t\t\"20.254.201.208/28\",\n\t\t\t\t\"23.98.142.176/28\",\n\t\t\t\t\"23.98.186.64/28\",\n\t\t\t\t\"23.98.186.96/28\",\n\t\t\t\t\"23.98.186.176/28\",\n\t\t\t\t\"23.98.186.192/28\",\n\t\t\t\t\"23.101.217.176/28\",\n\t\t\t\t\"23.102.140.144/28\",\n\t\t\t\t\"23.102.141.32/28\",\n\t\t\t\t\"40.74.200.208/28\",\n\t\t\t\t\"40.81.67.96/28\",\n\t\t\t\t\"40.81.234.144/28\",\n\t\t\t\t\"40.84.221.208/28\",\n\t\t\t\t\"40.84.221.224/28\",\n\t\t\t\t\"40.116.73.208/28\",\n\t\t\t\t\"40.119.36.240/28\",\n\t\t\t\t\"40.124.161.0/28\",\n\t\t\t\t\"48.221.40.176/28\",\n\t\t\t\t\"48.221.184.80/28\",\n\t\t\t\t\"48.221.184.96/28\",\n\t\t\t\t\"51.8.155.48/28\",\n\t\t\t\t\"51.8.155.112/28\",\n\t\t\t\t\"51.57.0.96/28\",\n\t\t\t\t\"51.59.24.64/28\",\n\t\t\t\t\"51.59.24.80/28\",\n\t\t\t\t\"51.59.48.80/28\",\n\t\t\t\t\"51.116.2.80/28\",\n\t\t\t\t\"51.116.221.96/28\",\n\t\t\t\t\"52.148.129.32/28\",\n\t\t\t\t\"52.156.77.144/28\",\n\t\t\t\t\"52.159.227.32/28\",\n\t\t\t\t\"52.159.249.96/28\",\n\t\t\t\t\"52.161.49.96/28\",\n\t\t\t\t\"52.165.212.48/28\",\n\t\t\t\t\"52.172.129.160/28\",\n\t\t\t\t\"52.173.219.96/28\",\n\t\t\t\t\"52.173.219.112/28\",\n\t\t\t\t\"52.173.221.16/28\",\n\t\t\t\t\"52.173.221.176/28\",\n\t\t\t\t\"52.173.221.208/28\",\n\t\t\t\t\"52.173.234.16/28\",\n\t\t\t\t\"52.173.234.80/28\",\n\t\t\t\t\"52.183.217.240/28\",\n\t\t\t\t\"52.190.137.16/28\",\n\t\t\t\t\"52.190.137.144/28\",\n\t\t\t\t\"52.190.139.48/28\",\n\t\t\t\t\"52.190.142.64/28\",\n\t\t\t\t\"52.190.190.16/28\",\n\t\t\t\t\"52.190.251.112/28\",\n\t\t\t\t\"52.225.75.208/28\",\n\t\t\t\t\"52.231.30.48/28\",\n\t\t\t\t\"52.231.34.176/28\",\n\t\t\t\t\"52.231.39.144/28\",\n\t\t\t\t\"52.231.50.64/28\",\n\t\t\t\t\"52.236.94.144/28\",\n\t\t\t\t\"52.241.146.208/28\",\n\t\t\t\t\"52.242.132.224/28\",\n\t\t\t\t\"52.242.132.240/28\",\n\t\t\t\t\"52.255.109.80/28\",\n\t\t\t\t\"52.255.109.96/28\",\n\t\t\t\t\"52.255.109.144/28\",\n\t\t\t\t\"52.255.111.0/28\",\n\t\t\t\t\"52.255.111.80/28\",\n\t\t\t\t\"57.154.174.112/28\",\n\t\t\t\t\"57.154.175.0/28\",\n\t\t\t\t\"57.154.187.32/28\",\n\t\t\t\t\"68.154.28.96/28\",\n\t\t\t\t\"68.220.57.64/28\",\n\t\t\t\t\"70.153.32.16/28\",\n\t\t\t\t\"70.153.32.32/28\",\n\t\t\t\t\"70.153.87.224/28\",\n\t\t\t\t\"70.153.189.192/28\",\n\t\t\t\t\"70.156.152.96/28\",\n\t\t\t\t\"74.7.35.48/28\",\n\t\t\t\t\"74.7.35.112/28\",\n\t\t\t\t\"74.7.36.64/28\",\n\t\t\t\t\"74.7.36.80/28\",\n\t\t\t\t\"74.7.36.96/28\",\n\t\t\t\t\"74.161.200.96/28\",\n\t\t\t\t\"74.224.217.64/28\",\n\t\t\t\t\"74.226.253.160/28\",\n\t\t\t\t\"74.248.37.160/28\",\n\t\t\t\t\"85.211.128.16/28\",\n\t\t\t\t\"85.211.128.32/28\",\n\t\t\t\t\"104.208.184.192/28\",\n\t\t\t\t\"104.210.139.192/28\",\n\t\t\t\t\"104.210.139.224/28\",\n\t\t\t\t\"128.85.198.32/28\",\n\t\t\t\t\"132.196.82.48/28\",\n\t\t\t\t\"134.33.102.192/28\",\n\t\t\t\t\"134.138.52.16/28\",\n\t\t\t\t\"134.138.52.64/28\",\n\t\t\t\t\"134.138.52.96/28\",\n\t\t\t\t\"134.138.52.128/28\",\n\t\t\t\t\"134.138.57.64/28\",\n\t\t\t\t\"134.138.57.80/28\",\n\t\t\t\t\"134.138.57.176/28\",\n\t\t\t\t\"134.138.58.32/28\",\n\t\t\t\t\"134.149.233.80/28\",\n\t\t\t\t\"135.13.64.240/28\",\n\t\t\t\t\"135.116.136.160/28\",\n\t\t\t\t\"135.220.73.208/28\",\n\t\t\t\t\"135.220.73.240/28\",\n\t\t\t\t\"135.222.99.32/28\",\n\t\t\t\t\"135.237.131.208/28\",\n\t\t\t\t\"135.237.133.48/28\",\n\t\t\t\t\"137.135.191.176/28\",\n\t\t\t\t\"138.91.46.96/28\",\n\t\t\t\t\"145.132.136.96/28\",\n\t\t\t\t\"158.158.5.32/28\",\n\t\t\t\t\"168.63.252.240/28\",\n\t\t\t\t\"172.162.248.64/28\",\n\t\t\t\t\"172.170.1.80/28\",\n\t\t\t\t\"172.170.225.0/28\",\n\t\t\t\t\"172.170.241.80/28\",\n\t\t\t\t\"172.172.206.48/28\",\n\t\t\t\t\"172.175.152.224/28\",\n\t\t\t\t\"172.178.140.144/28\",\n\t\t\t\t\"172.178.141.112/28\",\n\t\t\t\t\"172.178.141.128/28\",\n\t\t\t\t\"172.183.143.224/28\",\n\t\t\t\t\"172.183.222.128/28\",\n\t\t\t\t\"172.192.112.208/28\",\n\t\t\t\t\"172.197.160.192/28\",\n\t\t\t\t\"172.197.203.16/28\",\n\t\t\t\t\"172.198.58.176/28\",\n\t\t\t\t\"172.198.78.192/28\",\n\t\t\t\t\"172.198.79.112/28\",\n\t\t\t\t\"172.198.161.128/28\",\n\t\t\t\t\"172.199.137.80/28\",\n\t\t\t\t\"172.204.28.224/28\",\n\t\t\t\t\"172.204.96.80/28\",\n\t\t\t\t\"172.205.189.192/28\",\n\t\t\t\t\"172.206.38.240/28\",\n\t\t\t\t\"172.207.1.32/28\",\n\t\t\t\t\"172.212.172.160/28\",\n\t\t\t\t\"172.215.215.32/28\",\n\t\t\t\t\"191.232.238.96/28\",\n\t\t\t\t\"191.233.197.0/28\",\n\t\t\t\t\"191.233.199.160/28\",\n\t\t\t\t\"191.234.167.144/28\",\n\t\t\t\t\"191.235.99.160/28\",\n\t\t\t\t\"191.237.249.64/28\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"PerplexityBot\",\n\t\t\t\"url\": \"https://www.perplexity.com/perplexitybot.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"3.222.232.239/32\",\n\t\t\t\t\"3.224.62.45/32\",\n\t\t\t\t\"18.97.1.228/32\",\n\t\t\t\t\"18.97.9.96/32\",\n\t\t\t\t\"18.97.9.97/32\",\n\t\t\t\t\"18.97.9.98/32\",\n\t\t\t\t\"18.97.9.99/32\",\n\t\t\t\t\"18.97.9.100/32\",\n\t\t\t\t\"18.97.9.101/32\",\n\t\t\t\t\"18.97.9.102/32\",\n\t\t\t\t\"18.97.9.103/32\",\n\t\t\t\t\"18.210.92.235/32\",\n\t\t\t\t\"107.20.236.150/32\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"Perplexity-User\",\n\t\t\t\"url\": \"https://www.perplexity.com/perplexity-user.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"18.97.43.80/32\",\n\t\t\t\t\"18.97.43.81/32\",\n\t\t\t\t\"18.97.43.82/32\",\n\t\t\t\t\"18.97.43.83/32\",\n\t\t\t\t\"18.97.43.84/32\",\n\t\t\t\t\"18.97.43.85/32\",\n\t\t\t\t\"18.97.43.86/32\",\n\t\t\t\t\"18.97.43.87/32\",\n\t\t\t\t\"34.193.163.52/32\",\n\t\t\t\t\"44.208.221.197/32\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"MistralAI-User\",\n\t\t\t\"url\": \"https://mistral.ai/mistralai-user-ips.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"20.240.160.1/32\",\n\t\t\t\t\"20.240.160.161/32\",\n\t\t\t\t\"20.240.194.83/32\",\n\t\t\t\t\"51.12.243.114/32\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"CCBot\",\n\t\t\t\"url\": \"https://index.commoncrawl.org/ccbot.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"3.41.188.32/29\",\n\t\t\t\t\"18.97.9.168/29\",\n\t\t\t\t\"18.97.14.80/29\",\n\t\t\t\t\"18.97.14.88/30\"\n\t\t\t],\n\t\t\t\"ipv6\": [\n\t\t\t\t\"2600:1f28:365:8000::/56\"\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"bot\": \"DuckAssistBot\",\n\t\t\t\"url\": \"https://duckduckgo.com/duckassistbot.json\",\n\t\t\t\"ipv4\": [\n\t\t\t\t\"4.144.148.23/32\",\n\t\t\t\t\"4.144.182.50/32\",\n\t\t\t\t\"4.144.227.142/32\",\n\t\t\t\t\"4.144.251.39/32\",\n\t\t\t\t\"4.149.142.7/32\",\n\t\t\t\t\"4.149.159.71/32\",\n\t\t\t\t\"4.149.159.102/32\",\n\t\t\t\t\"4.149.216.220/32\",\n\t\t\t\t\"4.150.142.218/32\",\n\t\t\t\t\"4.154.193.167/32\",\n\t\t\t\t\"4.156.30.123/32\",\n\t\t\t\t\"4.156.136.79/32\",\n\t\t\t\t\"4.156.154.107/32\",\n\t\t\t\t\"4.157.77.76/32\",\n\t\t\t\t\"4.172.49.103/32\",\n\t\t\t\t\"4.177.16.196/32\",\n\t\t\t\t\"4.182.10.198/32\",\n\t\t\t\t\"4.182.131.108/32\",\n\t\t\t\t\"4.195.133.120/32\",\n\t\t\t\t\"4.201.125.59/32\",\n\t\t\t\t\"4.201.141.71/32\",\n\t\t\t\t\"4.201.197.203/32\",\n\t\t\t\t\"4.201.206.133/32\",\n\t\t\t\t\"4.201.220.8/32\",\n\t\t\t\t\"4.207.220.92/32\",\n\t\t\t\t\"4.209.224.56/32\",\n\t\t\t\t\"4.213.46.14/32\",\n\t\t\t\t\"4.226.40.135/32\",\n\t\t\t\t\"4.228.76.163/32\",\n\t\t\t\t\"4.237.155.54/32\",\n\t\t\t\t\"4.237.244.80/32\",\n\t\t\t\t\"4.242.119.13/32\",\n\t\t\t\t\"4.246.10.252/32\",\n\t\t\t\t\"4.248.234.26/32\",\n\t\t\t\t\"4.249.216.104/32\",\n\t\t\t\t\"4.249.223.51/32\",\n\t\t\t\t\"4.249.238.11/32\",\n\t\t\t\t\"4.254.123.56/32\",\n\t\t\t\t\"4.255.35.121/32\",\n\t\t\t\t\"4.255.39.80/32\",\n\t\t\t\t\"13.86.35.212/32\",\n\t\t\t\t\"13.89.106.77/32\",\n\t\t\t\t\"13.90.178.139/32\",\n\t\t\t\t\"20.3.1.178/32\",\n\t\t\t\t\"20.3.60.212/32\",\n\t\t\t\t\"20.8.252.26/32\",\n\t\t\t\t\"20.9.114.242/32\",\n\t\t\t\t\"20.12.141.99/32\",\n\t\t\t\t\"20.12.249.123/32\",\n\t\t\t\t\"20.12.252.21/32\",\n\t\t\t\t\"20.13.44.19/32\",\n\t\t\t\t\"20.15.142.178/32\",\n\t\t\t\t\"20.23.88.231/32\",\n\t\t\t\t\"20.29.149.44/32\",\n\t\t\t\t\"20.29.154.56/32\",\n\t\t\t\t\"20.40.133.240/32\",\n\t\t\t\t\"20.40.147.172/32\",\n\t\t\t\t\"20.43.150.85/32\",\n\t\t\t\t\"20.43.150.93/32\",\n\t\t\t\t\"20.43.152.28/32\",\n\t\t\t\t\"20.43.172.120/32\",\n\t\t\t\t\"20.44.222.1/32\",\n\t\t\t\t\"20.49.129.236/32\",\n\t\t\t\t\"20.49.136.28/32\",\n\t\t\t\t\"20.50.48.159/32\",\n\t\t\t\t\"20.50.48.192/32\",\n\t\t\t\t\"20.50.49.0/32\",\n\t\t\t\t\"20.50.49.25/32\",\n\t\t\t\t\"20.50.49.40/32\",\n\t\t\t\t\"20.50.49.55/32\",\n\t\t\t\t\"20.50.49.237/32\",\n\t\t\t\t\"20.50.50.46/32\",\n\t\t\t\t\"20.50.50.118/32\",\n\t\t\t\t\"20.50.50.121/32\",\n\t\t\t\t\"20.50.50.123/32\",\n\t\t\t\t\"20.50.50.130/32\",\n\t\t\t\t\"20.50.50.134/32\",\n\t\t\t\t\"20.50.50.145/32\",\n\t\t\t\t\"20.50.50.146/32\",\n\t\t\t\t\"20.50.50.163/32\",\n\t\t\t\t\"20.50.168.91/32\",\n\t\t\t\t\"20.53.78.106/32\",\n\t\t\t\t\"20.53.78.123/32\",\n\t\t\t\t\"20.53.78.138/32\",\n\t\t\t\t\"20.53.78.144/32\",\n\t\t\t\t\"20.53.78.236/32\",\n\t\t\t\t\"20.53.91.2/32\",\n\t\t\t\t\"20.53.92.211/32\",\n\t\t\t\t\"20.53.134.160/32\",\n\t\t\t\t\"20.54.224.39/32\",\n\t\t\t\t\"20.56.197.58/32\",\n\t\t\t\t\"20.56.197.63/32\",\n\t\t\t\t\"20.59.0.65/32\",\n\t\t\t\t\"20.61.34.40/32\",\n\t\t\t\t\"20.61.142.192/32\",\n\t\t\t\t\"20.62.224.44/32\",\n\t\t\t\t\"20.64.185.45/32\",\n\t\t\t\t\"20.69.74.250/32\",\n\t\t\t\t\"20.69.129.205/32\",\n\t\t\t\t\"20.69.131.45/32\",\n\t\t\t\t\"20.69.138.149/32\",\n\t\t\t\t\"20.69.138.189/32\",\n\t\t\t\t\"20.69.144.137/32\",\n\t\t\t\t\"20.69.146.171/32\",\n\t\t\t\t\"20.69.147.21/32\",\n\t\t\t\t\"20.69.171.204/32\",\n\t\t\t\t\"20.71.12.143/32\",\n\t\t\t\t\"20.71.69.210/32\",\n\t\t\t\t\"20.72.197.110/32\",\n\t\t\t\t\"20.72.203.250/32\",\n\t\t\t\t\"20.72.218.29/32\",\n\t\t\t\t\"20.72.221.33/32\",\n\t\t\t\t\"20.72.221.45/32\",\n\t\t\t\t\"20.72.225.13/32\",\n\t\t\t\t\"20.72.242.93/32\",\n\t\t\t\t\"20.72.242.209/32\",\n\t\t\t\t\"20.73.132.240/32\",\n\t\t\t\t\"20.73.202.147/32\",\n\t\t\t\t\"20.75.144.152/32\",\n\t\t\t\t\"20.75.254.61/32\",\n\t\t\t\t\"20.77.146.108/32\",\n\t\t\t\t\"20.79.226.26/32\",\n\t\t\t\t\"20.79.238.198/32\",\n\t\t\t\t\"20.79.239.66/32\",\n\t\t\t\t\"20.80.114.203/32\",\n\t\t\t\t\"20.80.120.41/32\",\n\t\t\t\t\"20.80.129.80/32\",\n\t\t\t\t\"20.80.135.7/32\",\n\t\t\t\t\"20.80.156.88/32\",\n\t\t\t\t\"20.81.115.13/32\",\n\t\t\t\t\"20.82.24.207/32\",\n\t\t\t\t\"20.84.138.61/32\",\n\t\t\t\t\"20.84.219.45/32\",\n\t\t\t\t\"20.84.251.223/32\",\n\t\t\t\t\"20.85.138.75/32\",\n\t\t\t\t\"20.85.167.56/32\",\n\t\t\t\t\"20.85.187.146/32\",\n\t\t\t\t\"20.88.168.65/32\",\n\t\t\t\t\"20.93.28.24/32\",\n\t\t\t\t\"20.93.49.96/32\",\n\t\t\t\t\"20.99.154.113/32\",\n\t\t\t\t\"20.99.255.235/32\",\n\t\t\t\t\"20.100.136.36/32\",\n\t\t\t\t\"20.100.140.155/32\",\n\t\t\t\t\"20.101.17.173/32\",\n\t\t\t\t\"20.102.34.205/32\",\n\t\t\t\t\"20.109.129.162/32\",\n\t\t\t\t\"20.109.130.190/32\",\n\t\t\t\t\"20.109.241.18/32\",\n\t\t\t\t\"20.112.58.44/32\",\n\t\t\t\t\"20.113.3.121/32\",\n\t\t\t\t\"20.113.14.159/32\",\n\t\t\t\t\"20.115.181.187/32\",\n\t\t\t\t\"20.118.11.251/32\",\n\t\t\t\t\"20.119.127.146/32\",\n\t\t\t\t\"20.121.75.32/32\",\n\t\t\t\t\"20.166.171.150/32\",\n\t\t\t\t\"20.170.75.54/32\",\n\t\t\t\t\"20.175.232.228/32\",\n\t\t\t\t\"20.185.79.15/32\",\n\t\t\t\t\"20.185.79.47/32\",\n\t\t\t\t\"20.190.21.172/32\",\n\t\t\t\t\"20.191.44.16/32\",\n\t\t\t\t\"20.191.44.22/32\",\n\t\t\t\t\"20.191.44.119/32\",\n\t\t\t\t\"20.191.44.234/32\",\n\t\t\t\t\"20.191.45.212/32\",\n\t\t\t\t\"20.193.12.126/32\",\n\t\t\t\t\"20.193.24.10/32\",\n\t\t\t\t\"20.193.24.251/32\",\n\t\t\t\t\"20.193.25.197/32\",\n\t\t\t\t\"20.193.27.215/32\",\n\t\t\t\t\"20.193.45.113/32\",\n\t\t\t\t\"20.195.58.189/32\",\n\t\t\t\t\"20.195.108.47/32\",\n\t\t\t\t\"20.197.209.11/32\",\n\t\t\t\t\"20.197.209.27/32\",\n\t\t\t\t\"20.198.132.126/32\",\n\t\t\t\t\"20.198.152.208/32\",\n\t\t\t\t\"20.201.15.208/32\",\n\t\t\t\t\"20.204.228.200/32\",\n\t\t\t\t\"20.204.240.172/32\",\n\t\t\t\t\"20.204.241.148/32\",\n\t\t\t\t\"20.204.242.19/32\",\n\t\t\t\t\"20.204.242.101/32\",\n\t\t\t\t\"20.204.243.55/32\",\n\t\t\t\t\"20.204.246.81/32\",\n\t\t\t\t\"20.204.246.254/32\",\n\t\t\t\t\"20.207.72.11/32\",\n\t\t\t\t\"20.207.72.21/32\",\n\t\t\t\t\"20.207.72.110/32\",\n\t\t\t\t\"20.207.72.113/32\",\n\t\t\t\t\"20.207.97.190/32\",\n\t\t\t\t\"20.207.99.197/32\",\n\t\t\t\t\"20.207.107.181/32\",\n\t\t\t\t\"20.207.117.66/32\",\n\t\t\t\t\"20.212.90.107/32\",\n\t\t\t\t\"20.212.139.34/32\",\n\t\t\t\t\"20.216.200.223/32\",\n\t\t\t\t\"20.219.43.246/32\",\n\t\t\t\t\"20.219.45.67/32\",\n\t\t\t\t\"20.219.45.190/32\",\n\t\t\t\t\"20.221.10.115/32\",\n\t\t\t\t\"20.221.84.185/32\",\n\t\t\t\t\"20.226.133.105/32\",\n\t\t\t\t\"20.231.254.179/32\",\n\t\t\t\t\"20.232.51.46/32\",\n\t\t\t\t\"20.232.249.95/32\",\n\t\t\t\t\"20.236.40.93/32\",\n\t\t\t\t\"20.236.195.196/32\",\n\t\t\t\t\"20.236.198.192/32\",\n\t\t\t\t\"20.236.227.113/32\",\n\t\t\t\t\"20.236.233.23/32\",\n\t\t\t\t\"20.236.247.180/32\",\n\t\t\t\t\"20.237.1.51/32\",\n\t\t\t\t\"20.241.135.19/32\",\n\t\t\t\t\"20.241.147.151/32\",\n\t\t\t\t\"20.241.153.203/32\",\n\t\t\t\t\"20.241.164.5/32\",\n\t\t\t\t\"20.241.241.100/32\",\n\t\t\t\t\"20.242.133.53/32\",\n\t\t\t\t\"20.242.135.165/32\",\n\t\t\t\t\"20.242.211.139/32\",\n\t\t\t\t\"20.242.215.53/32\",\n\t\t\t\t\"20.242.237.240/32\",\n\t\t\t\t\"20.246.132.168/32\",\n\t\t\t\t\"20.246.225.34/32\",\n\t\t\t\t\"20.247.235.11/32\",\n\t\t\t\t\"20.250.51.113/32\",\n\t\t\t\t\"20.252.9.6/32\",\n\t\t\t\t\"20.252.16.193/32\",\n\t\t\t\t\"20.252.41.18/32\",\n\t\t\t\t\"20.252.63.162/32\",\n\t\t\t\t\"20.252.88.10/32\",\n\t\t\t\t\"20.253.59.76/32\",\n\t\t\t\t\"20.253.96.199/32\",\n\t\t\t\t\"20.253.114.51/32\",\n\t\t\t\t\"40.64.67.220/32\",\n\t\t\t\t\"40.64.78.45/32\",\n\t\t\t\t\"40.64.88.145/32\",\n\t\t\t\t\"40.64.105.247/32\",\n\t\t\t\t\"40.64.106.11/32\",\n\t\t\t\t\"40.64.106.152/32\",\n\t\t\t\t\"40.65.78.86/32\",\n\t\t\t\t\"40.76.162.17/32\",\n\t\t\t\t\"40.76.162.191/32\",\n\t\t\t\t\"40.76.162.208/32\",\n\t\t\t\t\"40.76.162.247/32\",\n\t\t\t\t\"40.76.163.7/32\",\n\t\t\t\t\"40.76.163.23/32\",\n\t\t\t\t\"40.76.173.151/32\",\n\t\t\t\t\"40.81.250.205/32\",\n\t\t\t\t\"40.82.218.203/32\",\n\t\t\t\t\"40.88.21.235/32\",\n\t\t\t\t\"40.88.195.62/32\",\n\t\t\t\t\"40.89.243.175/32\",\n\t\t\t\t\"40.114.182.45/32\",\n\t\t\t\t\"40.114.182.153/32\",\n\t\t\t\t\"40.114.182.172/32\",\n\t\t\t\t\"40.114.183.88/32\",\n\t\t\t\t\"40.114.183.196/32\",\n\t\t\t\t\"40.114.183.251/32\",\n\t\t\t\t\"40.119.232.50/32\",\n\t\t\t\t\"40.119.232.146/32\",\n\t\t\t\t\"40.119.232.215/32\",\n\t\t\t\t\"40.119.232.218/32\",\n\t\t\t\t\"40.119.232.251/32\",\n\t\t\t\t\"40.121.121.54/32\",\n\t\t\t\t\"40.127.154.196/32\",\n\t\t\t\t\"48.192.16.86/32\",\n\t\t\t\t\"48.192.74.178/32\",\n\t\t\t\t\"48.200.33.227/32\",\n\t\t\t\t\"48.202.155.200/32\",\n\t\t\t\t\"48.202.171.124/32\",\n\t\t\t\t\"48.204.32.87/32\",\n\t\t\t\t\"48.206.18.152/32\",\n\t\t\t\t\"48.217.23.236/32\",\n\t\t\t\t\"48.217.129.210/32\",\n\t\t\t\t\"48.217.212.89/32\",\n\t\t\t\t\"48.223.209.110/32\",\n\t\t\t\t\"51.8.31.28/32\",\n\t\t\t\t\"51.8.71.117/32\",\n\t\t\t\t\"51.8.253.152/32\",\n\t\t\t\t\"51.104.144.31/32\",\n\t\t\t\t\"51.104.146.225/32\",\n\t\t\t\t\"51.104.146.235/32\",\n\t\t\t\t\"51.104.160.167/32\",\n\t\t\t\t\"51.104.160.177/32\",\n\t\t\t\t\"51.104.161.32/32\",\n\t\t\t\t\"51.104.162.149/32\",\n\t\t\t\t\"51.104.163.250/32\",\n\t\t\t\t\"51.104.164.109/32\",\n\t\t\t\t\"51.104.164.147/32\",\n\t\t\t\t\"51.104.164.189/32\",\n\t\t\t\t\"51.104.164.215/32\",\n\t\t\t\t\"51.104.166.111/32\",\n\t\t\t\t\"51.104.167.19/32\",\n\t\t\t\t\"51.104.167.52/32\",\n\t\t\t\t\"51.104.167.54/32\",\n\t\t\t\t\"51.104.167.61/32\",\n\t\t\t\t\"51.104.167.71/32\",\n\t\t\t\t\"51.104.167.87/32\",\n\t\t\t\t\"51.104.167.88/32\",\n\t\t\t\t\"51.104.167.95/32\",\n\t\t\t\t\"51.104.167.96/32\",\n\t\t\t\t\"51.104.167.104/32\",\n\t\t\t\t\"51.104.167.110/32\",\n\t\t\t\t\"51.104.180.26/32\",\n\t\t\t\t\"51.104.180.47/32\",\n\t\t\t\t\"51.104.180.53/32\",\n\t\t\t\t\"51.107.40.209/32\",\n\t\t\t\t\"51.116.131.221/32\",\n\t\t\t\t\"51.120.48.122/32\",\n\t\t\t\t\"51.138.90.161/32\",\n\t\t\t\t\"51.138.90.206/32\",\n\t\t\t\t\"51.138.90.233/32\",\n\t\t\t\t\"51.143.114.45/32\",\n\t\t\t\t\"51.145.185.16/32\",\n\t\t\t\t\"52.142.24.149/32\",\n\t\t\t\t\"52.142.26.175/32\",\n\t\t\t\t\"52.143.95.162/32\",\n\t\t\t\t\"52.143.95.204/32\",\n\t\t\t\t\"52.143.241.111/32\",\n\t\t\t\t\"52.143.242.6/32\",\n\t\t\t\t\"52.143.243.117/32\",\n\t\t\t\t\"52.143.244.81/32\",\n\t\t\t\t\"52.143.247.235/32\",\n\t\t\t\t\"52.146.57.51/32\",\n\t\t\t\t\"52.146.58.236/32\",\n\t\t\t\t\"52.146.59.12/32\",\n\t\t\t\t\"52.146.59.154/32\",\n\t\t\t\t\"52.146.59.156/32\",\n\t\t\t\t\"52.146.63.80/32\",\n\t\t\t\t\"52.148.161.87/32\",\n\t\t\t\t\"52.148.165.38/32\",\n\t\t\t\t\"52.149.25.43/32\",\n\t\t\t\t\"52.149.28.18/32\",\n\t\t\t\t\"52.149.28.83/32\",\n\t\t\t\t\"52.149.30.45/32\",\n\t\t\t\t\"52.149.56.151/32\",\n\t\t\t\t\"52.149.58.27/32\",\n\t\t\t\t\"52.149.58.69/32\",\n\t\t\t\t\"52.149.58.139/32\",\n\t\t\t\t\"52.149.58.173/32\",\n\t\t\t\t\"52.149.60.38/32\",\n\t\t\t\t\"52.149.61.51/32\",\n\t\t\t\t\"52.154.60.82/32\",\n\t\t\t\t\"52.154.169.50/32\",\n\t\t\t\t\"52.154.169.200/32\",\n\t\t\t\t\"52.154.170.26/32\",\n\t\t\t\t\"52.154.170.28/32\",\n\t\t\t\t\"52.154.170.88/32\",\n\t\t\t\t\"52.154.170.96/32\",\n\t\t\t\t\"52.154.170.113/32\",\n\t\t\t\t\"52.154.170.117/32\",\n\t\t\t\t\"52.154.170.122/32\",\n\t\t\t\t\"52.154.170.209/32\",\n\t\t\t\t\"52.154.170.229/32\",\n\t\t\t\t\"52.154.170.243/32\",\n\t\t\t\t\"52.154.171.0/32\",\n\t\t\t\t\"52.154.171.44/32\",\n\t\t\t\t\"52.154.171.70/32\",\n\t\t\t\t\"52.154.171.87/32\",\n\t\t\t\t\"52.154.171.150/32\",\n\t\t\t\t\"52.154.171.196/32\",\n\t\t\t\t\"52.154.171.205/32\",\n\t\t\t\t\"52.154.171.235/32\",\n\t\t\t\t\"52.154.171.250/32\",\n\t\t\t\t\"52.154.172.2/32\",\n\t\t\t\t\"52.154.204.93/32\",\n\t\t\t\t\"52.185.93.208/32\",\n\t\t\t\t\"52.186.37.211/32\",\n\t\t\t\t\"52.188.89.106/32\",\n\t\t\t\t\"52.189.70.103/32\",\n\t\t\t\t\"52.190.37.160/32\",\n\t\t\t\t\"52.191.82.242/32\",\n\t\t\t\t\"52.191.222.158/32\",\n\t\t\t\t\"52.224.16.221/32\",\n\t\t\t\t\"52.224.16.229/32\",\n\t\t\t\t\"52.224.19.152/32\",\n\t\t\t\t\"52.224.20.174/32\",\n\t\t\t\t\"52.224.20.181/32\",\n\t\t\t\t\"52.224.20.186/32\",\n\t\t\t\t\"52.224.20.190/32\",\n\t\t\t\t\"52.224.20.193/32\",\n\t\t\t\t\"52.224.20.203/32\",\n\t\t\t\t\"52.224.20.204/32\",\n\t\t\t\t\"52.224.20.223/32\",\n\t\t\t\t\"52.224.20.227/32\",\n\t\t\t\t\"52.224.20.249/32\",\n\t\t\t\t\"52.224.21.4/32\",\n\t\t\t\t\"52.224.21.19/32\",\n\t\t\t\t\"52.224.21.20/32\",\n\t\t\t\t\"52.224.21.23/32\",\n\t\t\t\t\"52.224.21.27/32\",\n\t\t\t\t\"52.224.21.49/32\",\n\t\t\t\t\"52.224.21.51/32\",\n\t\t\t\t\"52.224.21.53/32\",\n\t\t\t\t\"52.224.21.55/32\",\n\t\t\t\t\"52.224.21.61/32\",\n\t\t\t\t\"52.224.147.21/32\",\n\t\t\t\t\"52.224.191.245/32\",\n\t\t\t\t\"52.242.224.168/32\",\n\t\t\t\t\"52.250.46.221/32\",\n\t\t\t\t\"57.151.44.140/32\",\n\t\t\t\t\"57.152.17.237/32\",\n\t\t\t\t\"57.152.62.107/32\",\n\t\t\t\t\"57.152.72.128/32\",\n\t\t\t\t\"57.155.18.44/32\",\n\t\t\t\t\"57.165.205.172/32\",\n\t\t\t\t\"57.167.88.38/32\",\n\t\t\t\t\"64.236.15.33/32\",\n\t\t\t\t\"64.236.93.100/32\",\n\t\t\t\t\"64.236.118.43/32\",\n\t\t\t\t\"68.219.152.220/32\",\n\t\t\t\t\"72.144.95.185/32\",\n\t\t\t\t\"74.163.169.106/32\",\n\t\t\t\t\"74.163.208.206/32\",\n\t\t\t\t\"74.179.200.126/32\",\n\t\t\t\t\"74.179.232.116/32\",\n\t\t\t\t\"74.242.194.48/32\",\n\t\t\t\t\"98.70.219.37/32\",\n\t\t\t\t\"104.43.54.127/32\",\n\t\t\t\t\"104.43.55.116/32\",\n\t\t\t\t\"104.43.55.117/32\",\n\t\t\t\t\"104.43.55.166/32\",\n\t\t\t\t\"104.43.55.167/32\",\n\t\t\t\t\"108.141.83.74/32\",\n\t\t\t\t\"128.203.82.154/32\",\n\t\t\t\t\"128.203.132.152/32\",\n\t\t\t\t\"128.203.181.79/32\",\n\t\t\t\t\"128.203.214.241/32\",\n\t\t\t\t\"128.203.236.110/32\",\n\t\t\t\t\"130.107.228.224/32\",\n\t\t\t\t\"131.145.39.118/32\",\n\t\t\t\t\"131.189.183.241/32\",\n\t\t\t\t\"132.164.209.198/32\",\n\t\t\t\t\"132.196.106.146/32\",\n\t\t\t\t\"132.220.1.71/32\",\n\t\t\t\t\"134.33.207.189/32\",\n\t\t\t\t\"135.171.251.169/32\",\n\t\t\t\t\"135.233.63.237/32\",\n\t\t\t\t\"135.234.221.112/32\",\n\t\t\t\t\"135.235.183.95/32\",\n\t\t\t\t\"172.168.12.93/32\",\n\t\t\t\t\"172.168.43.43/32\",\n\t\t\t\t\"172.168.51.216/32\",\n\t\t\t\t\"172.168.53.53/32\",\n\t\t\t\t\"172.168.81.217/32\",\n\t\t\t\t\"172.168.94.160/32\",\n\t\t\t\t\"172.168.115.250/32\",\n\t\t\t\t\"172.168.133.76/32\",\n\t\t\t\t\"172.168.137.102/32\",\n\t\t\t\t\"172.168.152.88/32\",\n\t\t\t\t\"172.168.173.230/32\",\n\t\t\t\t\"172.168.190.186/32\",\n\t\t\t\t\"172.168.227.120/32\",\n\t\t\t\t\"172.168.254.119/32\",\n\t\t\t\t\"172.169.7.33/32\",\n\t\t\t\t\"172.169.17.165/32\",\n\t\t\t\t\"172.169.28.184/32\",\n\t\t\t\t\"172.169.36.43/32\",\n\t\t\t\t\"172.169.53.208/32\",\n\t\t\t\t\"172.169.60.134/32\",\n\t\t\t\t\"172.169.93.148/32\",\n\t\t\t\t\"172.169.164.109/32\",\n\t\t\t\t\"172.169.177.131/32\",\n\t\t\t\t\"172.169.181.237/32\",\n\t\t\t\t\"172.171.37.221/32\",\n\t\t\t\t\"172.179.105.87/32\",\n\t\t\t\t\"172.179.128.118/32\",\n\t\t\t\t\"172.188.250.220/32\",\n\t\t\t\t\"172.189.40.18/32\",\n\t\t\t\t\"172.193.184.42/32\",\n\t\t\t\t\"172.193.197.146/32\",\n\t\t\t\t\"172.193.245.229/32\",\n\t\t\t\t\"172.194.141.49/32\",\n\t\t\t\t\"172.199.55.212/32\",\n\t\t\t\t\"172.210.111.68/32\",\n\t\t\t\t\"191.233.3.197/32\",\n\t\t\t\t\"191.233.3.202/32\",\n\t\t\t\t\"191.234.216.4/32\",\n\t\t\t\t\"191.234.216.178/32\",\n\t\t\t\t\"191.235.201.214/32\",\n\t\t\t\t\"191.235.202.38/32\",\n\t\t\t\t\"191.235.202.48/32\"\n\t\t\t],\n\t\t\t\"ipv6\": []\n\t\t}\n\t]\n}\n","const encoder = new TextEncoder();\nconst keys = new Map<string, Promise<CryptoKey>>();\n\nfunction importOrgKey(orgKey: string): Promise<CryptoKey> {\n\tlet key = keys.get(orgKey);\n\tif (!key) {\n\t\tkey = crypto.subtle.importKey(\n\t\t\t\"raw\",\n\t\t\tencoder.encode(orgKey),\n\t\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\t\tfalse,\n\t\t\t[\"sign\"],\n\t\t);\n\t\tkey.catch(() => keys.delete(orgKey));\n\t\tkeys.set(orgKey, key);\n\t}\n\treturn key;\n}\n\nconst toHex = (bytes: ArrayBuffer): string =>\n\tArray.from(new Uint8Array(bytes), (byte) =>\n\t\tbyte.toString(16).padStart(2, \"0\"),\n\t).join(\"\");\n\nexport async function deriveMatchKey(\n\torgKey: string,\n\tip: string,\n): Promise<string> {\n\tconst signature = await crypto.subtle.sign(\n\t\t\"HMAC\",\n\t\tawait importOrgKey(orgKey),\n\t\tencoder.encode(ip),\n\t);\n\treturn toHex(signature);\n}\n","declare const __RELAY_PACKAGE_VERSION__: string | undefined;\n\nexport const RELAY_VERSION: string =\n\ttypeof __RELAY_PACKAGE_VERSION__ === \"string\"\n\t\t? __RELAY_PACKAGE_VERSION__\n\t\t: \"0.0.0-dev\";\n","type WaitUntil = (promise: Promise<unknown>) => void;\ntype RequestContextStore = {\n\tget?: () => { waitUntil?: WaitUntil } | undefined;\n};\n\nconst REQUEST_CONTEXT = Symbol.for(\"@vercel/request-context\");\n\n/** The `waitUntil` that the Vercel runtime puts in the request context, the same one `@vercel/functions` reads. */\nexport function vercelWaitUntil(): WaitUntil | undefined {\n\tconst store: RequestContextStore | undefined = Reflect.get(\n\t\tglobalThis,\n\t\tREQUEST_CONTEXT,\n\t);\n\tconst context = store?.get?.();\n\treturn context?.waitUntil\n\t\t? (promise) => context.waitUntil?.(promise)\n\t\t: undefined;\n}\n","import { clientIp, readCappedHeaders } from \"./headers\";\nimport { postEvent } from \"./ingest\";\nimport { readKey } from \"./key\";\nimport { decide } from \"./logic\";\nimport { deriveMatchKey } from \"./match-key\";\nimport { settings } from \"./settings\";\nimport { RELAY_VERSION } from \"./version\";\nimport { vercelWaitUntil } from \"./wait-until\";\n\nexport type Region = keyof typeof settings.apiUrls;\n\nexport type RelayOptions = {\n\t/** The region of your WaniWani organization. Defaults to `\"us\"`. */\n\tregion?: Region;\n\t/** Overrides the host that `region` picks. */\n\tapiUrl?: string;\n\t/** Overrides `process.env.WANIWANI_AGENT_TRAFFIC_KEY`. */\n\tkey?: string;\n\t/** Keeps the background post alive after the response. Defaults to the `waitUntil` of the Vercel request context. */\n\twaitUntil?: (promise: Promise<unknown>) => void;\n\t/** Header names, and the fields `matchKey`, `userAgent` or `referer`, to leave out of every event. */\n\tomit?: Array<string>;\n};\n\nexport type AgentVisitRecord = {\n\toccurredAt: string;\n\tmethod: string;\n\thost: string;\n\tpath: string;\n\tuserAgent?: string;\n\treferer?: string;\n\theaders: Record<string, string>;\n\tmatchKey?: string;\n\tsourceEventId: string;\n\trelayVersion: string;\n};\n\n/** Tells whether a request comes from an AI agent. Reads headers only, makes no network call. */\nexport function isAgent(request: Request): boolean {\n\ttry {\n\t\tconst headers = readCappedHeaders(request.headers);\n\t\treturn decide({ headers, ip: clientIp(request.headers) });\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Posts one event for this request to WaniWani after the response.\n * Sends nothing when no key is set. Never throws and never touches the request.\n */\nexport function recordAgentVisit(\n\trequest: Request,\n\toptions: RelayOptions = {},\n): void {\n\ttry {\n\t\tconst key = readKey(options.key);\n\t\tif (!key) {\n\t\t\treturn;\n\t\t}\n\t\tconst apiUrl = resolveApiUrl(options);\n\t\tif (!apiUrl) {\n\t\t\treturn;\n\t\t}\n\t\tconst omitted = omitSet(options.omit);\n\t\tconst ip = clientIp(request.headers);\n\t\tconst capped = readCappedHeaders(request.headers);\n\n\t\tconst headers: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(capped)) {\n\t\t\tif (!omitted.has(name)) {\n\t\t\t\theaders[name] = value;\n\t\t\t}\n\t\t}\n\t\tconst url = new URL(request.url);\n\t\tconst record: AgentVisitRecord = {\n\t\t\toccurredAt: new Date().toISOString(),\n\t\t\tmethod: request.method,\n\t\t\thost: url.hostname,\n\t\t\tpath: url.pathname + url.search,\n\t\t\theaders,\n\t\t\tsourceEventId: crypto.randomUUID(),\n\t\t\trelayVersion: RELAY_VERSION,\n\t\t};\n\t\tif (capped[\"user-agent\"] !== undefined && !omitted.has(\"user-agent\")) {\n\t\t\trecord.userAgent = capped[\"user-agent\"];\n\t\t}\n\t\tif (capped.referer !== undefined && !omitted.has(\"referer\")) {\n\t\t\trecord.referer = capped.referer;\n\t\t}\n\n\t\tconst ingestUrl = `${apiUrl}/api/v2/agent-traffic/ingest/middleware/${key.ingestToken}`;\n\t\tconst withMatchKey = async () => {\n\t\t\tif (ip !== null && !omitted.has(\"matchkey\")) {\n\t\t\t\trecord.matchKey = await deriveMatchKey(key.orgKey, ip).catch(\n\t\t\t\t\t() => undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait postEvent(ingestUrl, JSON.stringify({ requests: [record] }));\n\t\t};\n\t\tschedule(withMatchKey(), options.waitUntil);\n\t} catch {}\n}\n\nlet warnedRegion = false;\n\nfunction resolveApiUrl(options: RelayOptions): string | null {\n\tif (options.apiUrl !== undefined) {\n\t\treturn options.apiUrl.replace(/\\/+$/, \"\");\n\t}\n\tconst region = options.region ?? \"us\";\n\tif (Object.hasOwn(settings.apiUrls, region)) {\n\t\treturn settings.apiUrls[region];\n\t}\n\tif (!warnedRegion) {\n\t\twarnedRegion = true;\n\t\tconsole.warn(\n\t\t\t`[@waniwani/relay] Unknown region ${JSON.stringify(region)}, so no agent visits are recorded. Use \"us\" or \"eu\".`,\n\t\t);\n\t}\n\treturn null;\n}\n\nfunction omitSet(omit: Array<string> | undefined): Set<string> {\n\tconst names = new Set((omit ?? []).map((name) => name.toLowerCase()));\n\tif (names.has(\"useragent\")) {\n\t\tnames.add(\"user-agent\");\n\t}\n\treturn names;\n}\n\nfunction schedule(\n\twork: Promise<unknown>,\n\twaitUntil: RelayOptions[\"waitUntil\"],\n) {\n\tconst settled = work.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t);\n\ttry {\n\t\t(waitUntil ?? vercelWaitUntil())?.(settled);\n\t} catch {}\n}\n"],"mappings":"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ACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;;;AC/JA;AAAA,EACC,SAAW;AAAA,IACV;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ,CAAC;AAAA,IACV;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,MACA,MAAQ;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,KAAO;AAAA,MACP,KAAO;AAAA,MACP,MAAQ;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAA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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,61 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@waniwani/relay",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Records AI agent visits to your website from your middleware and posts them to WaniWani. Open source, so your security team can read every line.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist/index.js",
|
|
18
|
+
"dist/index.js.map",
|
|
19
|
+
"dist/index.d.ts",
|
|
20
|
+
"NOTICE"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=24"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "rm -rf dist && bun run typecheck && bun run lint && tsup",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"lint": "biome check .",
|
|
30
|
+
"lint:fix": "biome check . --write",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"rules": "bun scripts/build-rules.ts",
|
|
33
|
+
"prepublishOnly": "bun run build",
|
|
34
|
+
"release:patch": "npm version patch && git push --follow-tags",
|
|
35
|
+
"release:minor": "npm version minor && git push --follow-tags"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@biomejs/biome": "^2.6.3",
|
|
39
|
+
"@types/node": "^24",
|
|
40
|
+
"tsup": "^9.0.0",
|
|
41
|
+
"typescript": "^5",
|
|
42
|
+
"vitest": "^5.0.5"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/WaniWani-AI/relay"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"ai-agents",
|
|
50
|
+
"bots",
|
|
51
|
+
"crawlers",
|
|
52
|
+
"vercel",
|
|
53
|
+
"middleware",
|
|
54
|
+
"nextjs",
|
|
55
|
+
"proxy",
|
|
56
|
+
"analytics",
|
|
57
|
+
"waniwani"
|
|
58
|
+
],
|
|
59
|
+
"author": "Waniwani",
|
|
60
|
+
"license": "Apache-2.0"
|
|
61
|
+
}
|