mcp-scraper 0.35.1 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +9 -9
  2. package/dist/bin/api-server.cjs +25071 -19082
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/mcp-scraper-cli.cjs +51 -7
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +48 -5
  8. package/dist/bin/mcp-scraper-cli.js.map +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +2 -2
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +2 -2
  12. package/dist/bin/mcp-stdio-server.cjs +995 -222
  13. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-stdio-server.js +8 -8
  15. package/dist/bin/paa-harvest.cjs +125 -70
  16. package/dist/bin/paa-harvest.cjs.map +1 -1
  17. package/dist/bin/paa-harvest.js +4 -4
  18. package/dist/chunk-345BQXZH.js +712 -0
  19. package/dist/chunk-345BQXZH.js.map +1 -0
  20. package/dist/chunk-3LWYPAU5.js +7 -0
  21. package/dist/chunk-3LWYPAU5.js.map +1 -0
  22. package/dist/{chunk-M2S27J6Z.js → chunk-44HZLHDV.js} +10 -1
  23. package/dist/chunk-44HZLHDV.js.map +1 -0
  24. package/dist/{chunk-62DQAWPF.js → chunk-CSCD2HNS.js} +498 -43
  25. package/dist/chunk-CSCD2HNS.js.map +1 -0
  26. package/dist/{chunk-ZID3WQID.js → chunk-FQI5PFE7.js} +9 -71
  27. package/dist/chunk-FQI5PFE7.js.map +1 -0
  28. package/dist/{chunk-3HBPKR5G.js → chunk-FSAXLDB3.js} +3 -3
  29. package/dist/chunk-G3P3ZDB4.js +69 -0
  30. package/dist/chunk-G3P3ZDB4.js.map +1 -0
  31. package/dist/{chunk-YRGSEY5L.js → chunk-G7KAVJ3F.js} +2 -2
  32. package/dist/{chunk-YRGSEY5L.js.map → chunk-G7KAVJ3F.js.map} +1 -1
  33. package/dist/{chunk-NPMW5HUS.js → chunk-JK2FRDAP.js} +930 -244
  34. package/dist/chunk-JK2FRDAP.js.map +1 -0
  35. package/dist/{chunk-XVVNKASZ.js → chunk-LOPKN3YL.js} +118 -73
  36. package/dist/chunk-LOPKN3YL.js.map +1 -0
  37. package/dist/{chunk-4ZB3X6BQ.js → chunk-MA5JBAUZ.js} +16 -2
  38. package/dist/{chunk-4ZB3X6BQ.js.map → chunk-MA5JBAUZ.js.map} +1 -1
  39. package/dist/chunk-PUJFYJXB.js +684 -0
  40. package/dist/chunk-PUJFYJXB.js.map +1 -0
  41. package/dist/{chunk-BWXLTWF7.js → chunk-PWPUKR5U.js} +9 -5
  42. package/dist/chunk-PWPUKR5U.js.map +1 -0
  43. package/dist/chunk-Q35WZJJK.js +499 -0
  44. package/dist/chunk-Q35WZJJK.js.map +1 -0
  45. package/dist/chunk-QZXKQB7Y.js +414 -0
  46. package/dist/chunk-QZXKQB7Y.js.map +1 -0
  47. package/dist/{db-YAI5AQOI.js → db-N3YECFWR.js} +12 -2
  48. package/dist/{extract-bundle-ONWZVV55.js → extract-bundle-346R6MXD.js} +284 -98
  49. package/dist/extract-bundle-346R6MXD.js.map +1 -0
  50. package/dist/index.cjs +129 -70
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +11 -0
  53. package/dist/index.d.ts +11 -0
  54. package/dist/index.js +4 -4
  55. package/dist/location-data-repository-O2VII3ON.js +35 -0
  56. package/dist/{server-GKUTC73B.js → server-QKDDEBVQ.js} +7325 -3762
  57. package/dist/server-QKDDEBVQ.js.map +1 -0
  58. package/dist/site-extract-repository-I3VM6WXN.js +62 -0
  59. package/dist/site-extract-repository-I3VM6WXN.js.map +1 -0
  60. package/dist/{worker-645BZPEK.js → worker-TTFXPPDK.js} +7 -7
  61. package/docs/hosted-location-data.md +108 -0
  62. package/docs/mcp-tool-craft-lint.generated.md +6 -3
  63. package/docs/mcp-tool-manifest.generated.json +1447 -240
  64. package/docs/mcp-tool-quality-spec.md +1 -1
  65. package/docs/specs/connected-services-control-plane-decoupling-spec.md +1044 -0
  66. package/docs/specs/kernel-stealth-captcha-test-matrix.md +278 -0
  67. package/docs/specs/multimodal-image-memory-architecture-spec.md +1022 -0
  68. package/docs/specs/unified-credit-and-scheduled-execution-billing-spec.md +36 -27
  69. package/package.json +7 -6
  70. package/dist/chunk-62DQAWPF.js.map +0 -1
  71. package/dist/chunk-BWXLTWF7.js.map +0 -1
  72. package/dist/chunk-M2S27J6Z.js.map +0 -1
  73. package/dist/chunk-NPMW5HUS.js.map +0 -1
  74. package/dist/chunk-R7EETU7Z.js +0 -419
  75. package/dist/chunk-R7EETU7Z.js.map +0 -1
  76. package/dist/chunk-U44TPRST.js +0 -130
  77. package/dist/chunk-U44TPRST.js.map +0 -1
  78. package/dist/chunk-XVVNKASZ.js.map +0 -1
  79. package/dist/chunk-YR4LJ6AQ.js +0 -7
  80. package/dist/chunk-YR4LJ6AQ.js.map +0 -1
  81. package/dist/chunk-YV2FUEBX.js +0 -851
  82. package/dist/chunk-YV2FUEBX.js.map +0 -1
  83. package/dist/chunk-ZID3WQID.js.map +0 -1
  84. package/dist/extract-bundle-ONWZVV55.js.map +0 -1
  85. package/dist/server-GKUTC73B.js.map +0 -1
  86. package/dist/site-extract-repository-L6BHWVDU.js +0 -30
  87. /package/dist/{chunk-3HBPKR5G.js.map → chunk-FSAXLDB3.js.map} +0 -0
  88. /package/dist/{db-YAI5AQOI.js.map → db-N3YECFWR.js.map} +0 -0
  89. /package/dist/{site-extract-repository-L6BHWVDU.js.map → location-data-repository-O2VII3ON.js.map} +0 -0
  90. /package/dist/{worker-645BZPEK.js.map → worker-TTFXPPDK.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/url-utils.ts","../src/api/image-audit.ts","../src/api/seo-link-report.ts","../src/api/seo-issues.ts","../src/api/private-artifacts.ts"],"sourcesContent":["import { isIP } from 'node:net'\nimport { lookup } from 'node:dns/promises'\nimport ipaddr from 'ipaddr.js'\n\nfunction unbracketIpLiteral(value: string): string {\n return value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value\n}\n\nexport function isPrivateIpAddress(address: string): boolean {\n const normalized = unbracketIpLiteral(address)\n if (!isIP(normalized)) return false\n try {\n const parsed = ipaddr.parse(normalized)\n const isExtraNonGlobalIpv4 = (ipv4: InstanceType<typeof ipaddr.IPv4>): boolean => {\n const extraNonGlobal: Array<[string, number]> = [\n ['192.0.0.0', 24],\n ['192.0.2.0', 24],\n ['198.18.0.0', 15],\n ['198.51.100.0', 24],\n ['203.0.113.0', 24],\n ]\n return extraNonGlobal.some(([network, bits]) => ipv4.match(ipaddr.parse(network) as InstanceType<typeof ipaddr.IPv4>, bits))\n }\n if (parsed instanceof ipaddr.IPv6 && parsed.isIPv4MappedAddress()) {\n const mapped = parsed.toIPv4Address()\n return mapped.range() !== 'unicast' || isExtraNonGlobalIpv4(mapped)\n }\n if (parsed instanceof ipaddr.IPv4) {\n if (isExtraNonGlobalIpv4(parsed)) return true\n }\n // Despite the historical function name, outbound URL validation needs to\n // reject every non-global range: loopback/private/link-local plus CGNAT,\n // multicast, documentation, benchmark, reserved and unspecified space.\n return parsed.range() !== 'unicast'\n } catch { return true }\n}\n\nexport async function resolvesToPrivateAddress(hostname: string): Promise<boolean> {\n const host = unbracketIpLiteral(hostname.toLowerCase())\n if (host === 'localhost' || host.endsWith('.localhost') || host.endsWith('.local')) return true\n if (isPrivateIpAddress(host)) return true\n try {\n const addresses = await lookup(host, { all: true, verbatim: true })\n return addresses.length === 0 || addresses.some((entry) => isPrivateIpAddress(entry.address))\n } catch {\n // URL safety must fail closed when DNS cannot establish a public target.\n return true\n }\n}\n\nexport async function validatePublicHttpUrl(raw: string, opts: { field: string; requireHttps?: boolean }): Promise<{ parsed?: URL; error?: string }> {\n let parsed: URL\n try {\n parsed = new URL(raw.trim())\n } catch {\n return { error: `Invalid ${opts.field}` }\n }\n const allowedProtocols = opts.requireHttps ? ['https:'] : ['http:', 'https:']\n if (!allowedProtocols.includes(parsed.protocol)) {\n return { error: opts.requireHttps ? `${opts.field} must use https` : `${opts.field} must use http or https` }\n }\n if (await resolvesToPrivateAddress(parsed.hostname)) {\n return { error: `${opts.field} must resolve to a public internet host` }\n }\n return { parsed }\n}\n","import type { PageData } from './site-extractor.js'\nimport { validatePublicHttpUrl } from './url-utils.js'\n\nexport interface ImageRow {\n url: string\n status: number | null\n bytes: number | null\n size: string | null\n contentType: string | null\n format: string\n over100kb: boolean\n legacyFormat: boolean\n error?: string\n}\n\nexport interface ImageAuditSummary {\n unique: number\n sized: number\n totalBytes: number\n totalSize: string\n avgSize: string\n over100kb: number\n legacyFormat: number\n formatCounts: Record<string, number>\n sampleTruncated?: boolean\n sampleCap?: number\n}\n\nexport interface ImageAudit {\n rows: ImageRow[]\n summary: ImageAuditSummary\n}\n\nconst OVER_BYTES = 100 * 1024\nconst MODERN = new Set(['webp', 'avif', 'svg', 'svg+xml'])\n\nexport function formatBytes(n: number | null): string | null {\n if (n == null) return null\n if (n < 1024) return `${n} B`\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`\n return `${(n / (1024 * 1024)).toFixed(2)} MB`\n}\n\nconst decodeEntities = (u: string): string =>\n u.replace(/&amp;/g, '&').replace(/&#0?38;/g, '&').replace(/&#x26;/gi, '&').trim()\n\nconst dedupKey = (u: string): string => u.replace(/^https?:\\/\\//i, '//').replace(/\\/$/, '')\n\nconst formatOf = (ct: string | null, url: string): string => {\n if (ct) { const m = ct.split(';')[0].trim().toLowerCase(); if (m.startsWith('image/')) return m.replace('image/', '') }\n return (url.split('?')[0].match(/\\.([a-z0-9]+)$/i)?.[1] || 'unknown').toLowerCase()\n}\n\nfunction collectUrls(pages: PageData[]): string[] {\n const byKey = new Map<string, string>()\n for (const p of pages) for (const raw of (p.imageLinks || [])) {\n const u = decodeEntities(raw)\n if (!/^https?:\\/\\//i.test(u)) continue\n if (/[{}]|%7[bd]/i.test(u)) continue\n const k = dedupKey(u)\n const prev = byKey.get(k)\n if (!prev || (/^https:/i.test(u) && /^http:/i.test(prev))) byKey.set(k, u)\n }\n return [...byKey.values()]\n}\n\nasync function sizeAndType(url: string, timeoutMs: number): Promise<Omit<ImageRow, 'size' | 'format' | 'over100kb' | 'legacyFormat'>> {\n const ctrl = new AbortController()\n const t = setTimeout(() => ctrl.abort(), timeoutMs)\n const read = (res: Response) => ({\n len: res.headers.get('content-length'),\n cr: res.headers.get('content-range'),\n ct: res.headers.get('content-type'),\n status: res.status,\n })\n const safeFetch = async (method: 'HEAD' | 'GET'): Promise<Response> => {\n let target = url\n for (let redirects = 0; redirects <= 5; redirects++) {\n const checked = await validatePublicHttpUrl(target, { field: 'image URL' })\n if (checked.error || !checked.parsed) throw new Error(checked.error ?? 'Image URL was rejected')\n const response = await fetch(checked.parsed.href, {\n method,\n ...(method === 'GET' ? { headers: { Range: 'bytes=0-0' } } : {}),\n redirect: 'manual',\n signal: ctrl.signal,\n })\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location')\n if (!location) throw new Error(`HTTP ${response.status} redirect did not include Location`)\n target = new URL(location, checked.parsed.href).href\n continue\n }\n return response\n }\n throw new Error('Image request exceeded five redirects')\n }\n try {\n let bytes: number | null = null\n let ct: string | null = null\n let status: number | null = null\n try {\n const h = read(await safeFetch('HEAD'))\n status = h.status; ct = h.ct\n if (h.len) bytes = Number(h.len)\n } catch { /* fall through to ranged GET */ }\n if (bytes == null) {\n const g = await safeFetch('GET')\n const r = read(g)\n status = status ?? r.status; ct = ct ?? r.ct\n if (r.cr && r.cr.includes('/')) { const tail = r.cr.split('/')[1]; if (tail && tail !== '*') bytes = Number(tail) }\n else if (r.len) bytes = Number(r.len)\n try { await g.body?.cancel() } catch { /* ignore */ }\n }\n return { url, status, bytes: Number.isFinite(bytes as number) ? bytes : null, contentType: ct }\n } catch (e) {\n return { url, status: null, bytes: null, contentType: null, error: String((e as Error).message || e) }\n } finally {\n clearTimeout(t)\n }\n}\n\nasync function pool<T, R>(items: T[], n: number, fn: (item: T) => Promise<R>): Promise<R[]> {\n const out = new Array<R>(items.length)\n let i = 0\n await Promise.all(Array.from({ length: Math.min(n, items.length) }, async () => {\n while (i < items.length) { const idx = i++; out[idx] = await fn(items[idx]) }\n }))\n return out\n}\n\nexport async function auditImages(\n pages: PageData[],\n opts: { concurrency?: number; timeoutMs?: number; max?: number } = {},\n): Promise<ImageAudit> {\n return auditImageUrls(collectUrls(pages), opts)\n}\n\nexport async function auditImageUrls(\n inputUrls: string[],\n opts: { concurrency?: number; timeoutMs?: number; max?: number; sampleTruncated?: boolean } = {},\n): Promise<ImageAudit> {\n const concurrency = opts.concurrency ?? 12\n const timeoutMs = opts.timeoutMs ?? 12_000\n const max = opts.max ?? 5000\n const urls = collectUrls([{ imageLinks: inputUrls } as PageData]).slice(0, max)\n\n const heads = await pool(urls, concurrency, (u) => sizeAndType(u, timeoutMs))\n const rows: ImageRow[] = heads.map(r => {\n const format = formatOf(r.contentType, r.url)\n return {\n ...r,\n size: formatBytes(r.bytes),\n format,\n over100kb: r.bytes != null && r.bytes > OVER_BYTES,\n legacyFormat: format !== 'unknown' && !MODERN.has(format),\n }\n })\n\n const sized = rows.filter(r => r.bytes != null)\n const totalBytes = sized.reduce((a, r) => a + (r.bytes as number), 0)\n const formatCounts: Record<string, number> = {}\n for (const r of rows) formatCounts[r.format] = (formatCounts[r.format] || 0) + 1\n\n return {\n rows: rows.sort((a, b) => (b.bytes ?? 0) - (a.bytes ?? 0)),\n summary: {\n unique: rows.length,\n sized: sized.length,\n totalBytes,\n totalSize: formatBytes(totalBytes) ?? '0 B',\n avgSize: formatBytes(Math.round(totalBytes / (sized.length || 1))) ?? '0 B',\n over100kb: rows.filter(r => r.over100kb).length,\n legacyFormat: rows.filter(r => r.legacyFormat).length,\n formatCounts,\n ...(opts.sampleTruncated ? { sampleTruncated: true, sampleCap: max } : {}),\n },\n }\n}\n\nexport function renderImageSection(audit: ImageAudit): string {\n const s = audit.summary\n const fmt = Object.entries(s.formatCounts).sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k}:${v}`).join(' ')\n const heaviest = audit.rows.filter(r => r.over100kb).slice(0, 15)\n const lines = [\n `## Images`,\n `**${s.unique} unique images** · ${s.totalSize} total · ${s.avgSize} avg · ${s.over100kb} over 100 KB · ${s.legacyFormat} legacy format`,\n `Formats: ${fmt}`,\n ]\n if (heaviest.length) {\n lines.push('', '| Size | Format | URL |', '|------|--------|-----|')\n for (const r of heaviest) lines.push(`| ${r.size} | ${r.format} | ${r.url} |`)\n }\n return lines.join('\\n')\n}\n","import type { LinkEdge, PageLinkMetrics } from './seo-link-graph.js'\n\nexport interface ExtDomainRow { domain: string; links: number; nofollow: number; pages: number }\n\nexport interface LinkReportSummary {\n internal: {\n totalLinks: number\n pages: number\n orphans: number\n brokenInternal: number\n avgInlinks: number\n avgOutlinks: number\n distribution: { zero: number; oneToTwo: number; threeToTen: number; elevenPlus: number }\n topByInlinks: Array<{ url: string; inlinks: number; outlinksInternal: number; outlinksExternal: number }>\n }\n external: {\n totalLinks: number\n uniqueDomains: number\n topDomains: ExtDomainRow[]\n }\n}\n\nexport interface LinkReport {\n summary: LinkReportSummary\n externalDomains: ExtDomainRow[]\n}\n\nfunction registrableDomain(host: string): string {\n const h = host.replace(/^www\\./, '').toLowerCase()\n const parts = h.split('.')\n return parts.length <= 2 ? h : parts.slice(-2).join('.')\n}\n\nexport function buildLinkReport(edges: LinkEdge[], metrics: PageLinkMetrics[], siteUrl: string): LinkReport {\n let siteReg = ''\n try { siteReg = registrableDomain(new URL(siteUrl).hostname) } catch { siteReg = '' }\n const internalEdges = edges.filter(e => e.internal)\n const pages = metrics.length\n const orphans = metrics.filter(m => m.orphan).length\n const brokenInternal = internalEdges.filter(e => e.targetStatus != null && e.targetStatus >= 400).length\n const sumInlinks = metrics.reduce((a, m) => a + m.inlinks, 0)\n const sumOutlinks = metrics.reduce((a, m) => a + m.outlinksInternal + m.outlinksExternal, 0)\n\n const distribution = { zero: 0, oneToTwo: 0, threeToTen: 0, elevenPlus: 0 }\n for (const m of metrics) {\n if (m.inlinks === 0) distribution.zero++\n else if (m.inlinks <= 2) distribution.oneToTwo++\n else if (m.inlinks <= 10) distribution.threeToTen++\n else distribution.elevenPlus++\n }\n\n const topByInlinks = [...metrics].sort((a, b) => b.inlinks - a.inlinks).slice(0, 20)\n .map(m => ({ url: m.url, inlinks: m.inlinks, outlinksInternal: m.outlinksInternal, outlinksExternal: m.outlinksExternal }))\n\n const domMap = new Map<string, { links: number; nofollow: number; pages: Set<string> }>()\n let externalTotal = 0\n for (const e of edges) {\n let domain: string\n try { domain = registrableDomain(new URL(e.to).hostname) } catch { continue }\n if (!domain || domain === siteReg) continue\n externalTotal++\n const d = domMap.get(domain) ?? { links: 0, nofollow: 0, pages: new Set<string>() }\n d.links++\n if (e.nofollow) d.nofollow++\n d.pages.add(e.from)\n domMap.set(domain, d)\n }\n const externalDomains: ExtDomainRow[] = [...domMap.entries()]\n .map(([domain, d]) => ({ domain, links: d.links, nofollow: d.nofollow, pages: d.pages.size }))\n .sort((a, b) => b.links - a.links)\n\n const round = (n: number) => Math.round(n * 10) / 10\n return {\n summary: {\n internal: {\n totalLinks: internalEdges.length,\n pages, orphans, brokenInternal,\n avgInlinks: pages ? round(sumInlinks / pages) : 0,\n avgOutlinks: pages ? round(sumOutlinks / pages) : 0,\n distribution,\n topByInlinks,\n },\n external: {\n totalLinks: externalTotal,\n uniqueDomains: externalDomains.length,\n topDomains: externalDomains.slice(0, 20),\n },\n },\n externalDomains,\n }\n}\n\nexport function renderLinkReport(r: LinkReport): string {\n const s = r.summary\n const lines = [\n `## Link analysis`,\n `**Internal:** ${s.internal.totalLinks} links · ${s.internal.pages} pages · avg ${s.internal.avgInlinks} inlinks/page · ${s.internal.orphans} orphans · ${s.internal.brokenInternal} broken`,\n `**External:** ${s.external.totalLinks} links to ${s.external.uniqueDomains} domains`,\n ``,\n `### Inlink distribution`,\n `- 0 inlinks (orphans): ${s.internal.distribution.zero}`,\n `- 1–2: ${s.internal.distribution.oneToTwo}`,\n `- 3–10: ${s.internal.distribution.threeToTen}`,\n `- 11+: ${s.internal.distribution.elevenPlus}`,\n ``,\n `### Top 20 internal pages by inlinks`,\n `| inlinks | out (int/ext) | URL |`,\n `|---|---|---|`,\n ...s.internal.topByInlinks.map(p => `| ${p.inlinks} | ${p.outlinksInternal}/${p.outlinksExternal} | ${p.url} |`),\n ``,\n `### Top 20 external domains by links`,\n `| links | nofollow | from pages | domain |`,\n `|---|---|---|---|`,\n ...s.external.topDomains.map(d => `| ${d.links} | ${d.nofollow} | ${d.pages} | ${d.domain} |`),\n ]\n return lines.join('\\n')\n}\n","import type { PageData } from './site-extractor.js'\nimport type { PageLinkMetrics } from './seo-link-graph.js'\n\nexport interface IssueGroup { count: number; urls: string[] }\nexport type IssueReport = Record<string, IssueGroup>\n\nconst THIN_WORDS = 200\nconst TITLE_MAX = 60\nconst TITLE_PX_MAX = 561\nconst TITLE_MIN = 30\nconst META_MAX = 155\nconst META_MIN = 70\nconst H1_MAX = 70\nconst URL_MAX = 115\n\nfunction dupes<T>(pages: PageData[], key: (p: PageData) => T | null | undefined): string[] {\n const groups = new Map<string, string[]>()\n for (const p of pages) {\n const k = key(p)\n if (k === null || k === undefined || k === '') continue\n const ks = String(k)\n if (!groups.has(ks)) groups.set(ks, [])\n groups.get(ks)!.push(p.url)\n }\n return [...groups.values()].filter(g => g.length > 1).flat()\n}\n\nexport function computeIssues(pages: PageData[], metrics: Map<string, PageLinkMetrics>, precomputedBrokenLinkPages?: Set<string>): IssueReport {\n const group = (urls: string[]): IssueGroup => ({ count: urls.length, urls: urls.slice(0, 200) })\n const where = (fn: (p: PageData) => boolean) => pages.filter(fn).map(p => p.url)\n const extracted = (p: PageData) => p.extractionStatus !== 'failed'\n const ok = (p: PageData) => extracted(p) && p.status === 200\n const extractedUrls = new Set(pages.filter(extracted).map(page => page.url))\n const pathname = (u: string) => { try { return new URL(u).pathname } catch { return '' } }\n\n const report: IssueReport = {\n 'title.missing': group(where(p => ok(p) && !p.title)),\n 'title.duplicate': group(dupes(pages.filter(ok), p => p.title)),\n 'title.tooLong': group(where(p => (p.titleLength ?? 0) > TITLE_MAX || (p.titlePixels ?? 0) > TITLE_PX_MAX)),\n 'title.tooShort': group(where(p => p.title != null && (p.titleLength ?? 0) < TITLE_MIN)),\n 'title.sameAsH1': group(where(p => !!p.title && !!p.h1 && p.title.trim() === p.h1.trim())),\n 'meta.missing': group(where(p => ok(p) && !p.metaDescription)),\n 'meta.duplicate': group(dupes(pages.filter(ok), p => p.metaDescription)),\n 'meta.tooLong': group(where(p => (p.metaDescLength ?? 0) > META_MAX)),\n 'meta.tooShort': group(where(p => p.metaDescription != null && (p.metaDescLength ?? 0) < META_MIN)),\n 'h1.missing': group(where(p => ok(p) && !p.h1)),\n 'h1.multiple': group(where(p => !!p.h1_2)),\n 'h1.duplicate': group(dupes(pages.filter(ok), p => p.h1)),\n 'h1.tooLong': group(where(p => (p.h1?.length ?? 0) > H1_MAX)),\n 'h2.missing': group(where(p => ok(p) && p.h2Count === 0)),\n // A transport/extraction failure is not an SEO conclusion about the URL.\n // Keep it in a dedicated crawl bucket so empty records cannot become a\n // wall of false missing-title/H1/non-indexable findings.\n 'crawl.extractionFailed': group(where(p => !extracted(p))),\n 'indexability.nonIndexable': group(where(p => extracted(p) && !p.indexable)),\n 'indexability.noindex': group(where(p => p.indexabilityReason === 'noindex')),\n 'canonical.missing': group(where(p => ok(p) && !p.canonicalUrl)),\n 'canonical.canonicalised': group(where(p => p.indexabilityReason === 'canonicalised')),\n 'response.broken4xx': group(where(p => (p.status ?? 0) >= 400 && (p.status ?? 0) < 500)),\n 'response.error5xx': group(where(p => (p.status ?? 0) >= 500)),\n 'response.redirect3xx': group(where(p => (p.status ?? 0) >= 300 && (p.status ?? 0) < 400)),\n 'response.noResponse': group(where(p => p.status === null)),\n 'content.thin': group(where(p => ok(p) && p.wordCount > 0 && p.wordCount < THIN_WORDS)),\n 'content.exactDuplicate': group(dupes(pages.filter(p => ok(p) && p.contentHash), p => p.contentHash)),\n 'images.missingAlt': group(where(p => extracted(p) && p.imagesMissingAlt > 0)),\n 'schema.missing': group(where(p => ok(p) && p.schemaTypes.length === 0)),\n 'url.tooLong': group(where(p => p.url.length > URL_MAX)),\n 'url.uppercase': group(where(p => /[A-Z]/.test(pathname(p.url)))),\n 'url.underscores': group(where(p => pathname(p.url).includes('_'))),\n 'links.orphan': group([...metrics.values()].filter(m => m.orphan && extractedUrls.has(m.url)).map(m => m.url)),\n }\n\n let brokenLinkPages = precomputedBrokenLinkPages\n if (!brokenLinkPages) {\n const normUrl = (u: string) => { try { const x = new URL(u); x.hash = ''; return (x.origin + x.pathname).replace(/\\/+$/, '') + x.search } catch { return u.replace(/#.*$/, '').replace(/\\/+$/, '') } }\n const statusByUrl = new Map(pages.map(p => [normUrl(p.url), p.status]))\n brokenLinkPages = new Set<string>()\n for (const p of pages) {\n for (const l of p.outlinks ?? []) {\n if (!l.internal) continue\n const st = statusByUrl.get(normUrl(l.href))\n if (st != null && st >= 400) brokenLinkPages.add(p.url)\n }\n }\n }\n report['links.brokenInternal'] = group([...brokenLinkPages])\n\n return report\n}\n\nexport function renderIssueReport(siteUrl: string, pages: PageData[], report: IssueReport, metrics: Map<string, PageLinkMetrics>): string {\n const total = pages.length\n const successful = pages.filter(page => page.extractionStatus !== 'failed').length\n const failed = total - successful\n const sev = (key: string): string => (\n key.startsWith('response.broken') || key.startsWith('response.error') || key.startsWith('links.broken') ? '🔴'\n : key.startsWith('title.missing') || key.startsWith('h1.missing') || key.startsWith('indexability') || key.startsWith('canonical.missing') ? '🟠'\n : '🟡'\n )\n const rows = Object.entries(report)\n .filter(([, g]) => g.count > 0)\n .sort((a, b) => b[1].count - a[1].count)\n .map(([k, g]) => `| ${sev(k)} | \\`${k}\\` | ${g.count} | ${g.urls.slice(0, 3).join(' · ')}${g.urls.length > 3 ? ' …' : ''} |`)\n\n const depths = [...metrics.values()].map(m => m.crawlDepth).filter((d): d is number => d != null)\n const maxDepth = depths.length ? Math.max(...depths) : 0\n const extractedUrls = new Set(pages.filter(page => page.extractionStatus !== 'failed').map(page => page.url))\n const orphans = [...metrics.values()].filter(m => m.orphan && extractedUrls.has(m.url)).length\n const topLinked = [...metrics.values()].sort((a, b) => b.inlinks - a.inlinks).slice(0, 5)\n\n return [\n `# SEO Crawl Report: ${siteUrl}`,\n `**${total} pages attempted** · ${successful} extracted · ${failed} failed · max crawl depth ${maxDepth} · ${orphans} orphan page(s)`,\n `\\n## Issues\\n| | Issue | Count | Examples |\\n|---|-------|-------|----------|\\n${rows.join('\\n') || '| ✅ | none | 0 | — |'}`,\n `\\n## Most-linked pages\\n${topLinked.map(m => `- ${m.inlinks} inlinks · depth ${m.crawlDepth ?? '—'} · ${m.url}`).join('\\n')}`,\n `\\n_Thresholds: title ${TITLE_MAX}ch/${TITLE_PX_MAX}px, meta ${META_MAX}ch, H1 ${H1_MAX}ch, thin <${THIN_WORDS} words, URL ${URL_MAX}ch. Pixel widths are estimates._`,\n ].join('\\n')\n}\n","import { createHash } from 'node:crypto'\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { createWriteStream } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { Readable, Transform } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\n\nexport interface PrivateArtifactPolicy {\n prefix: string\n artifactTtlMs: number\n downloadTtlMs: number\n token?: string | null\n localBaseDir?: string\n hosted?: boolean\n}\n\nexport interface PrivateArtifactPointer {\n artifactId: string\n filename: string\n contentType: string\n bytes: number\n sha256: string\n expiresAt: string\n downloadUrl: string | null\n downloadUrlExpiresAt: string | null\n}\n\nexport interface PrivateArtifactWindow {\n text: string\n totalBytes: number\n nextOffset: number | null\n}\n\nfunction hostedByEnvironment(): boolean {\n return process.env.VERCEL === '1' || process.env.NODE_ENV === 'production'\n}\n\nfunction policyHosted(policy: PrivateArtifactPolicy): boolean {\n return policy.hosted ?? hostedByEnvironment()\n}\n\nfunction policyLocalBaseDir(policy: PrivateArtifactPolicy): string {\n return policy.localBaseDir?.trim()\n || process.env.MCP_SCRAPER_OUTPUT_DIR?.trim()\n || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction normalizedPrefix(prefix: string): string {\n const normalized = prefix.replace(/^\\/+/, '').replace(/\\/+$/, '')\n if (!normalized || normalized.includes('..') || !/^[a-zA-Z0-9/_-]+$/.test(normalized)) {\n throw new Error('private artifact prefix is invalid')\n }\n return `${normalized}/`\n}\n\nfunction requiredSafeSegment(value: string, field: string): string {\n const trimmed = value.trim()\n if (!/^[a-zA-Z0-9_-]{1,160}$/.test(trimmed)) {\n throw new Error(`${field} must contain only letters, numbers, underscores, or hyphens`)\n }\n return trimmed\n}\n\nfunction requiredSafeArtifactKey(value: string): string {\n const trimmed = value.trim()\n if (!/^[a-zA-Z0-9_.-]{1,200}$/.test(trimmed) || trimmed === '.' || trimmed === '..') {\n throw new Error('private artifact key is invalid')\n }\n return trimmed\n}\n\nfunction safeDownloadFilename(value: string): string {\n const normalized = value.trim().replace(/[^a-zA-Z0-9_.-]+/g, '-').replace(/^-+|-+$/g, '')\n return (normalized || 'artifact').slice(0, 160)\n}\n\nfunction createdAtMs(value: Date | string | number): number {\n const normalized = typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/.test(value)\n ? `${value.replace(' ', 'T')}Z`\n : value\n const timestamp = normalized instanceof Date\n ? normalized.getTime()\n : typeof normalized === 'number'\n ? normalized\n : new Date(normalized).getTime()\n if (!Number.isSafeInteger(timestamp) || timestamp <= 0) throw new Error('private artifact createdAt is invalid')\n return timestamp\n}\n\nfunction validatePolicy(policy: PrivateArtifactPolicy): Required<Pick<PrivateArtifactPolicy, 'prefix' | 'artifactTtlMs' | 'downloadTtlMs'>> {\n if (!Number.isSafeInteger(policy.artifactTtlMs) || policy.artifactTtlMs <= 0) {\n throw new Error('private artifact TTL must be a positive integer')\n }\n if (!Number.isSafeInteger(policy.downloadTtlMs) || policy.downloadTtlMs <= 0) {\n throw new Error('private artifact download TTL must be a positive integer')\n }\n return {\n prefix: normalizedPrefix(policy.prefix),\n artifactTtlMs: policy.artifactTtlMs,\n downloadTtlMs: policy.downloadTtlMs,\n }\n}\n\nfunction artifactTimestamp(artifactId: string, prefix: string): number | null {\n const normalized = normalizedPrefix(prefix)\n if (!artifactId.startsWith(normalized)) return null\n const filename = artifactId.split('/').at(-1) ?? ''\n const match = filename.match(/^(\\d{13})-/)\n if (!match) return null\n const timestamp = Number(match[1])\n return Number.isSafeInteger(timestamp) && timestamp > 0 ? timestamp : null\n}\n\nexport function privateArtifactOwnerId(artifactId: string, prefix: string): string | null {\n const normalized = normalizedPrefix(prefix)\n if (!artifactId.startsWith(normalized) || artifactId.includes('..')) return null\n const rest = artifactId.slice(normalized.length)\n const segments = rest.split('/')\n if (segments.length !== 2) return null\n try {\n return requiredSafeSegment(segments[0] ?? '', 'ownerId')\n } catch {\n return null\n }\n}\n\nexport function privateArtifactExpiresAt(artifactId: string, policy: PrivateArtifactPolicy): Date | null {\n const validated = validatePolicy(policy)\n if (privateArtifactOwnerId(artifactId, validated.prefix) === null) return null\n const timestamp = artifactTimestamp(artifactId, validated.prefix)\n return timestamp === null ? null : new Date(timestamp + validated.artifactTtlMs)\n}\n\nasync function signedDownloadUrl(pathname: string, expiresAt: Date, policy: PrivateArtifactPolicy): Promise<{\n url: string\n expiresAt: string\n} | null> {\n const token = policy.token?.trim()\n if (!token) return null\n const validUntil = Math.min(Date.now() + policy.downloadTtlMs, expiresAt.getTime())\n if (validUntil <= Date.now()) return null\n const { issueSignedToken, presignUrl } = await import('@vercel/blob')\n const signedToken = await issueSignedToken({\n token,\n pathname,\n operations: ['get'],\n validUntil,\n })\n const { presignedUrl } = await presignUrl(signedToken, {\n access: 'private',\n operation: 'get',\n pathname,\n validUntil,\n })\n return { url: presignedUrl, expiresAt: new Date(validUntil).toISOString() }\n}\n\nexport async function createPrivateArtifact(args: {\n policy: PrivateArtifactPolicy\n ownerId: string\n artifactKey: string\n createdAt: Date | string | number\n filename: string\n contentType: string\n content: string | Buffer\n}): Promise<PrivateArtifactPointer> {\n const policy = { ...args.policy, ...validatePolicy(args.policy) }\n const ownerId = requiredSafeSegment(args.ownerId, 'ownerId')\n const artifactKey = requiredSafeArtifactKey(args.artifactKey)\n const timestamp = createdAtMs(args.createdAt)\n const requestedPathname = `${policy.prefix}${ownerId}/${timestamp}-${artifactKey}`\n const body = Buffer.isBuffer(args.content) ? args.content : Buffer.from(args.content)\n const bytes = body.length\n const sha256 = createHash('sha256').update(body).digest('hex')\n const expiresAt = new Date(timestamp + policy.artifactTtlMs)\n const token = policy.token?.trim() || null\n\n let artifactId = requestedPathname\n if (token) {\n const { put } = await import('@vercel/blob')\n const stored = await put(requestedPathname, body, {\n access: 'private',\n token,\n contentType: args.contentType,\n addRandomSuffix: false,\n allowOverwrite: true,\n cacheControlMaxAge: 60,\n multipart: bytes > 100 * 1024 * 1024,\n })\n artifactId = stored.pathname\n } else {\n if (policyHosted(policy)) throw new Error('private_artifact_blob_not_configured')\n const path = join(policyLocalBaseDir(policy), 'blobs', requestedPathname)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, body)\n }\n\n const download = await signedDownloadUrl(artifactId, expiresAt, policy)\n return {\n artifactId,\n filename: safeDownloadFilename(args.filename),\n contentType: args.contentType,\n bytes,\n sha256,\n expiresAt: expiresAt.toISOString(),\n downloadUrl: download?.url ?? null,\n downloadUrlExpiresAt: download?.expiresAt ?? null,\n }\n}\n\nexport async function createPrivateArtifactFromStream(args: {\n policy: PrivateArtifactPolicy\n ownerId: string\n artifactKey: string\n createdAt: Date | string | number\n filename: string\n contentType: string\n content: Readable\n}): Promise<PrivateArtifactPointer> {\n const policy = { ...args.policy, ...validatePolicy(args.policy) }\n const ownerId = requiredSafeSegment(args.ownerId, 'ownerId')\n const artifactKey = requiredSafeArtifactKey(args.artifactKey)\n const timestamp = createdAtMs(args.createdAt)\n const requestedPathname = `${policy.prefix}${ownerId}/${timestamp}-${artifactKey}`\n const expiresAt = new Date(timestamp + policy.artifactTtlMs)\n const token = policy.token?.trim() || null\n const hash = createHash('sha256')\n let bytes = 0\n const meter = new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n bytes += chunk.length\n hash.update(chunk)\n callback(null, chunk)\n },\n })\n\n let artifactId = requestedPathname\n if (token) {\n const { put } = await import('@vercel/blob')\n const pumping = pipeline(args.content, meter)\n try {\n const stored = await put(requestedPathname, meter, {\n access: 'private',\n token,\n contentType: args.contentType,\n addRandomSuffix: false,\n allowOverwrite: true,\n cacheControlMaxAge: 60,\n multipart: true,\n })\n await pumping\n artifactId = stored.pathname\n } catch (error) {\n args.content.destroy(error instanceof Error ? error : new Error(String(error)))\n meter.destroy(error instanceof Error ? error : new Error(String(error)))\n await pumping.catch(() => undefined)\n throw error\n }\n } else {\n if (policyHosted(policy)) throw new Error('private_artifact_blob_not_configured')\n const path = join(policyLocalBaseDir(policy), 'blobs', requestedPathname)\n await mkdir(dirname(path), { recursive: true })\n await pipeline(args.content, meter, createWriteStream(path))\n }\n\n const sha256 = hash.digest('hex')\n const download = await signedDownloadUrl(artifactId, expiresAt, policy)\n return {\n artifactId,\n filename: safeDownloadFilename(args.filename),\n contentType: args.contentType,\n bytes,\n sha256,\n expiresAt: expiresAt.toISOString(),\n downloadUrl: download?.url ?? null,\n downloadUrlExpiresAt: download?.expiresAt ?? null,\n }\n}\n\nexport async function renewPrivateArtifactDownload(args: {\n policy: PrivateArtifactPolicy\n artifactId: string\n ownerId: string\n}): Promise<{ downloadUrl: string; downloadUrlExpiresAt: string; expiresAt: string } | null> {\n if (privateArtifactOwnerId(args.artifactId, args.policy.prefix) !== args.ownerId) return null\n const expiresAt = privateArtifactExpiresAt(args.artifactId, args.policy)\n if (!expiresAt || expiresAt.getTime() <= Date.now()) return null\n const download = await signedDownloadUrl(args.artifactId, expiresAt, args.policy)\n if (!download) return null\n return {\n downloadUrl: download.url,\n downloadUrlExpiresAt: download.expiresAt,\n expiresAt: expiresAt.toISOString(),\n }\n}\n\nasync function streamToBuffer(stream: ReadableStream<Uint8Array>): Promise<Buffer> {\n const reader = stream.getReader()\n const chunks: Buffer[] = []\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n if (value) chunks.push(Buffer.from(value))\n }\n } finally {\n reader.releaseLock()\n }\n return Buffer.concat(chunks)\n}\n\nexport async function readPrivateArtifactWindow(args: {\n policy: PrivateArtifactPolicy\n artifactId: string\n offset: number\n maxBytes: number\n}): Promise<PrivateArtifactWindow | null> {\n const expiresAt = privateArtifactExpiresAt(args.artifactId, args.policy)\n if (!expiresAt || expiresAt.getTime() <= Date.now()) return null\n if (!Number.isSafeInteger(args.offset) || args.offset < 0) throw new Error('private artifact offset is invalid')\n if (!Number.isSafeInteger(args.maxBytes) || args.maxBytes <= 0) throw new Error('private artifact maxBytes is invalid')\n\n const token = args.policy.token?.trim() || null\n let buffer: Buffer\n if (token) {\n const { get } = await import('@vercel/blob')\n const result = await get(args.artifactId, { access: 'private', token, useCache: false })\n if (!result || result.statusCode !== 200) return null\n buffer = await streamToBuffer(result.stream)\n } else {\n if (policyHosted(args.policy)) return null\n try {\n buffer = await readFile(join(policyLocalBaseDir(args.policy), 'blobs', args.artifactId))\n } catch {\n return null\n }\n }\n\n const totalBytes = buffer.length\n const end = Math.min(totalBytes, args.offset + args.maxBytes)\n return {\n text: buffer.subarray(args.offset, end).toString('utf8'),\n totalBytes,\n nextOffset: end < totalBytes ? end : null,\n }\n}\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,OAAO,YAAY;AAEnB,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AAC7E;AAEO,SAAS,mBAAmB,SAA0B;AAC3D,QAAM,aAAa,mBAAmB,OAAO;AAC7C,MAAI,CAAC,KAAK,UAAU,EAAG,QAAO;AAC9B,MAAI;AACF,UAAM,SAAS,OAAO,MAAM,UAAU;AACtC,UAAM,uBAAuB,CAAC,SAAoD;AAChF,YAAM,iBAA0C;AAAA,QAC9C,CAAC,aAAa,EAAE;AAAA,QAChB,CAAC,aAAa,EAAE;AAAA,QAChB,CAAC,cAAc,EAAE;AAAA,QACjB,CAAC,gBAAgB,EAAE;AAAA,QACnB,CAAC,eAAe,EAAE;AAAA,MACpB;AACA,aAAO,eAAe,KAAK,CAAC,CAAC,SAAS,IAAI,MAAM,KAAK,MAAM,OAAO,MAAM,OAAO,GAAuC,IAAI,CAAC;AAAA,IAC7H;AACA,QAAI,kBAAkB,OAAO,QAAQ,OAAO,oBAAoB,GAAG;AACjE,YAAM,SAAS,OAAO,cAAc;AACpC,aAAO,OAAO,MAAM,MAAM,aAAa,qBAAqB,MAAM;AAAA,IACpE;AACA,QAAI,kBAAkB,OAAO,MAAM;AACjC,UAAI,qBAAqB,MAAM,EAAG,QAAO;AAAA,IAC3C;AAIA,WAAO,OAAO,MAAM,MAAM;AAAA,EAC5B,QAAQ;AAAE,WAAO;AAAA,EAAK;AACxB;AAEA,eAAsB,yBAAyB,UAAoC;AACjF,QAAM,OAAO,mBAAmB,SAAS,YAAY,CAAC;AACtD,MAAI,SAAS,eAAe,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,QAAQ,EAAG,QAAO;AAC3F,MAAI,mBAAmB,IAAI,EAAG,QAAO;AACrC,MAAI;AACF,UAAM,YAAY,MAAM,OAAO,MAAM,EAAE,KAAK,MAAM,UAAU,KAAK,CAAC;AAClE,WAAO,UAAU,WAAW,KAAK,UAAU,KAAK,CAAC,UAAU,mBAAmB,MAAM,OAAO,CAAC;AAAA,EAC9F,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,sBAAsB,KAAa,MAA4F;AACnJ,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,IAAI,KAAK,CAAC;AAAA,EAC7B,QAAQ;AACN,WAAO,EAAE,OAAO,WAAW,KAAK,KAAK,GAAG;AAAA,EAC1C;AACA,QAAM,mBAAmB,KAAK,eAAe,CAAC,QAAQ,IAAI,CAAC,SAAS,QAAQ;AAC5E,MAAI,CAAC,iBAAiB,SAAS,OAAO,QAAQ,GAAG;AAC/C,WAAO,EAAE,OAAO,KAAK,eAAe,GAAG,KAAK,KAAK,oBAAoB,GAAG,KAAK,KAAK,0BAA0B;AAAA,EAC9G;AACA,MAAI,MAAM,yBAAyB,OAAO,QAAQ,GAAG;AACnD,WAAO,EAAE,OAAO,GAAG,KAAK,KAAK,0CAA0C;AAAA,EACzE;AACA,SAAO,EAAE,OAAO;AAClB;;;AChCA,IAAM,aAAa,MAAM;AACzB,IAAM,SAAS,oBAAI,IAAI,CAAC,QAAQ,QAAQ,OAAO,SAAS,CAAC;AAElD,SAAS,YAAY,GAAiC;AAC3D,MAAI,KAAK,KAAM,QAAO;AACtB,MAAI,IAAI,KAAM,QAAO,GAAG,CAAC;AACzB,MAAI,IAAI,OAAO,KAAM,QAAO,IAAI,IAAI,MAAM,QAAQ,CAAC,CAAC;AACpD,SAAO,IAAI,KAAK,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC1C;AAEA,IAAM,iBAAiB,CAAC,MACtB,EAAE,QAAQ,UAAU,GAAG,EAAE,QAAQ,YAAY,GAAG,EAAE,QAAQ,YAAY,GAAG,EAAE,KAAK;AAElF,IAAM,WAAW,CAAC,MAAsB,EAAE,QAAQ,iBAAiB,IAAI,EAAE,QAAQ,OAAO,EAAE;AAE1F,IAAM,WAAW,CAAC,IAAmB,QAAwB;AAC3D,MAAI,IAAI;AAAE,UAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY;AAAG,QAAI,EAAE,WAAW,QAAQ,EAAG,QAAO,EAAE,QAAQ,UAAU,EAAE;AAAA,EAAE;AACtH,UAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,iBAAiB,IAAI,CAAC,KAAK,WAAW,YAAY;AACpF;AAEA,SAAS,YAAY,OAA6B;AAChD,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,KAAK,MAAO,YAAW,OAAQ,EAAE,cAAc,CAAC,GAAI;AAC7D,UAAM,IAAI,eAAe,GAAG;AAC5B,QAAI,CAAC,gBAAgB,KAAK,CAAC,EAAG;AAC9B,QAAI,eAAe,KAAK,CAAC,EAAG;AAC5B,UAAM,IAAI,SAAS,CAAC;AACpB,UAAM,OAAO,MAAM,IAAI,CAAC;AACxB,QAAI,CAAC,QAAS,WAAW,KAAK,CAAC,KAAK,UAAU,KAAK,IAAI,EAAI,OAAM,IAAI,GAAG,CAAC;AAAA,EAC3E;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;AAEA,eAAe,YAAY,KAAa,WAA8F;AACpI,QAAM,OAAO,IAAI,gBAAgB;AACjC,QAAM,IAAI,WAAW,MAAM,KAAK,MAAM,GAAG,SAAS;AAClD,QAAM,OAAO,CAAC,SAAmB;AAAA,IAC/B,KAAK,IAAI,QAAQ,IAAI,gBAAgB;AAAA,IACrC,IAAI,IAAI,QAAQ,IAAI,eAAe;AAAA,IACnC,IAAI,IAAI,QAAQ,IAAI,cAAc;AAAA,IAClC,QAAQ,IAAI;AAAA,EACd;AACA,QAAM,YAAY,OAAO,WAA8C;AACrE,QAAI,SAAS;AACb,aAAS,YAAY,GAAG,aAAa,GAAG,aAAa;AACnD,YAAM,UAAU,MAAM,sBAAsB,QAAQ,EAAE,OAAO,YAAY,CAAC;AAC1E,UAAI,QAAQ,SAAS,CAAC,QAAQ,OAAQ,OAAM,IAAI,MAAM,QAAQ,SAAS,wBAAwB;AAC/F,YAAM,WAAW,MAAM,MAAM,QAAQ,OAAO,MAAM;AAAA,QAChD;AAAA,QACA,GAAI,WAAW,QAAQ,EAAE,SAAS,EAAE,OAAO,YAAY,EAAE,IAAI,CAAC;AAAA,QAC9D,UAAU;AAAA,QACV,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,UAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AACnD,cAAM,WAAW,SAAS,QAAQ,IAAI,UAAU;AAChD,YAAI,CAAC,SAAU,OAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,oCAAoC;AAC1F,iBAAS,IAAI,IAAI,UAAU,QAAQ,OAAO,IAAI,EAAE;AAChD;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,MAAI;AACF,QAAI,QAAuB;AAC3B,QAAI,KAAoB;AACxB,QAAI,SAAwB;AAC5B,QAAI;AACF,YAAM,IAAI,KAAK,MAAM,UAAU,MAAM,CAAC;AACtC,eAAS,EAAE;AAAQ,WAAK,EAAE;AAC1B,UAAI,EAAE,IAAK,SAAQ,OAAO,EAAE,GAAG;AAAA,IACjC,QAAQ;AAAA,IAAmC;AAC3C,QAAI,SAAS,MAAM;AACjB,YAAM,IAAI,MAAM,UAAU,KAAK;AAC/B,YAAM,IAAI,KAAK,CAAC;AAChB,eAAS,UAAU,EAAE;AAAQ,WAAK,MAAM,EAAE;AAC1C,UAAI,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,GAAG;AAAE,cAAM,OAAO,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC;AAAG,YAAI,QAAQ,SAAS,IAAK,SAAQ,OAAO,IAAI;AAAA,MAAE,WACzG,EAAE,IAAK,SAAQ,OAAO,EAAE,GAAG;AACpC,UAAI;AAAE,cAAM,EAAE,MAAM,OAAO;AAAA,MAAE,QAAQ;AAAA,MAAe;AAAA,IACtD;AACA,WAAO,EAAE,KAAK,QAAQ,OAAO,OAAO,SAAS,KAAe,IAAI,QAAQ,MAAM,aAAa,GAAG;AAAA,EAChG,SAAS,GAAG;AACV,WAAO,EAAE,KAAK,QAAQ,MAAM,OAAO,MAAM,aAAa,MAAM,OAAO,OAAQ,EAAY,WAAW,CAAC,EAAE;AAAA,EACvG,UAAE;AACA,iBAAa,CAAC;AAAA,EAChB;AACF;AAEA,eAAe,KAAW,OAAY,GAAW,IAA2C;AAC1F,QAAM,MAAM,IAAI,MAAS,MAAM,MAAM;AACrC,MAAI,IAAI;AACR,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,MAAM,EAAE,GAAG,YAAY;AAC9E,WAAO,IAAI,MAAM,QAAQ;AAAE,YAAM,MAAM;AAAK,UAAI,GAAG,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC;AAAA,IAAE;AAAA,EAC9E,CAAC,CAAC;AACF,SAAO;AACT;AAEA,eAAsB,YACpB,OACA,OAAmE,CAAC,GAC/C;AACrB,SAAO,eAAe,YAAY,KAAK,GAAG,IAAI;AAChD;AAEA,eAAsB,eACpB,WACA,OAA8F,CAAC,GAC1E;AACrB,QAAM,cAAc,KAAK,eAAe;AACxC,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,OAAO,YAAY,CAAC,EAAE,YAAY,UAAU,CAAa,CAAC,EAAE,MAAM,GAAG,GAAG;AAE9E,QAAM,QAAQ,MAAM,KAAK,MAAM,aAAa,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AAC5E,QAAM,OAAmB,MAAM,IAAI,OAAK;AACtC,UAAM,SAAS,SAAS,EAAE,aAAa,EAAE,GAAG;AAC5C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM,YAAY,EAAE,KAAK;AAAA,MACzB;AAAA,MACA,WAAW,EAAE,SAAS,QAAQ,EAAE,QAAQ;AAAA,MACxC,cAAc,WAAW,aAAa,CAAC,OAAO,IAAI,MAAM;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,KAAK,OAAO,OAAK,EAAE,SAAS,IAAI;AAC9C,QAAM,aAAa,MAAM,OAAO,CAAC,GAAG,MAAM,IAAK,EAAE,OAAkB,CAAC;AACpE,QAAM,eAAuC,CAAC;AAC9C,aAAW,KAAK,KAAM,cAAa,EAAE,MAAM,KAAK,aAAa,EAAE,MAAM,KAAK,KAAK;AAE/E,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,MAAM,EAAE,SAAS,EAAE;AAAA,IACzD,SAAS;AAAA,MACP,QAAQ,KAAK;AAAA,MACb,OAAO,MAAM;AAAA,MACb;AAAA,MACA,WAAW,YAAY,UAAU,KAAK;AAAA,MACtC,SAAS,YAAY,KAAK,MAAM,cAAc,MAAM,UAAU,EAAE,CAAC,KAAK;AAAA,MACtE,WAAW,KAAK,OAAO,OAAK,EAAE,SAAS,EAAE;AAAA,MACzC,cAAc,KAAK,OAAO,OAAK,EAAE,YAAY,EAAE;AAAA,MAC/C;AAAA,MACA,GAAI,KAAK,kBAAkB,EAAE,iBAAiB,MAAM,WAAW,IAAI,IAAI,CAAC;AAAA,IAC1E;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,OAA2B;AAC5D,QAAM,IAAI,MAAM;AAChB,QAAM,MAAM,OAAO,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI;AAC7G,QAAM,WAAW,MAAM,KAAK,OAAO,OAAK,EAAE,SAAS,EAAE,MAAM,GAAG,EAAE;AAChE,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,EAAE,MAAM,yBAAsB,EAAE,SAAS,eAAY,EAAE,OAAO,aAAU,EAAE,SAAS,qBAAkB,EAAE,YAAY;AAAA,IACxH,YAAY,GAAG;AAAA,EACjB;AACA,MAAI,SAAS,QAAQ;AACnB,UAAM,KAAK,IAAI,2BAA2B,yBAAyB;AACnE,eAAW,KAAK,SAAU,OAAM,KAAK,KAAK,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,EAAE,GAAG,IAAI;AAAA,EAC/E;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACtKA,SAAS,kBAAkB,MAAsB;AAC/C,QAAM,IAAI,KAAK,QAAQ,UAAU,EAAE,EAAE,YAAY;AACjD,QAAM,QAAQ,EAAE,MAAM,GAAG;AACzB,SAAO,MAAM,UAAU,IAAI,IAAI,MAAM,MAAM,EAAE,EAAE,KAAK,GAAG;AACzD;AAEO,SAAS,gBAAgB,OAAmB,SAA4B,SAA6B;AAC1G,MAAI,UAAU;AACd,MAAI;AAAE,cAAU,kBAAkB,IAAI,IAAI,OAAO,EAAE,QAAQ;AAAA,EAAE,QAAQ;AAAE,cAAU;AAAA,EAAG;AACpF,QAAM,gBAAgB,MAAM,OAAO,OAAK,EAAE,QAAQ;AAClD,QAAM,QAAQ,QAAQ;AACtB,QAAM,UAAU,QAAQ,OAAO,OAAK,EAAE,MAAM,EAAE;AAC9C,QAAM,iBAAiB,cAAc,OAAO,OAAK,EAAE,gBAAgB,QAAQ,EAAE,gBAAgB,GAAG,EAAE;AAClG,QAAM,aAAa,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,CAAC;AAC5D,QAAM,cAAc,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,mBAAmB,EAAE,kBAAkB,CAAC;AAE3F,QAAM,eAAe,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,EAAE;AAC1E,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,YAAY,EAAG,cAAa;AAAA,aACzB,EAAE,WAAW,EAAG,cAAa;AAAA,aAC7B,EAAE,WAAW,GAAI,cAAa;AAAA,QAClC,cAAa;AAAA,EACpB;AAEA,QAAM,eAAe,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,EAChF,IAAI,QAAM,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,SAAS,kBAAkB,EAAE,kBAAkB,kBAAkB,EAAE,iBAAiB,EAAE;AAE5H,QAAM,SAAS,oBAAI,IAAqE;AACxF,MAAI,gBAAgB;AACpB,aAAW,KAAK,OAAO;AACrB,QAAI;AACJ,QAAI;AAAE,eAAS,kBAAkB,IAAI,IAAI,EAAE,EAAE,EAAE,QAAQ;AAAA,IAAE,QAAQ;AAAE;AAAA,IAAS;AAC5E,QAAI,CAAC,UAAU,WAAW,QAAS;AACnC;AACA,UAAM,IAAI,OAAO,IAAI,MAAM,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,oBAAI,IAAY,EAAE;AAClF,MAAE;AACF,QAAI,EAAE,SAAU,GAAE;AAClB,MAAE,MAAM,IAAI,EAAE,IAAI;AAClB,WAAO,IAAI,QAAQ,CAAC;AAAA,EACtB;AACA,QAAM,kBAAkC,CAAC,GAAG,OAAO,QAAQ,CAAC,EACzD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,OAAO,EAAE,OAAO,UAAU,EAAE,UAAU,OAAO,EAAE,MAAM,KAAK,EAAE,EAC5F,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAEnC,QAAM,QAAQ,CAAC,MAAc,KAAK,MAAM,IAAI,EAAE,IAAI;AAClD,SAAO;AAAA,IACL,SAAS;AAAA,MACP,UAAU;AAAA,QACR,YAAY,cAAc;AAAA,QAC1B;AAAA,QAAO;AAAA,QAAS;AAAA,QAChB,YAAY,QAAQ,MAAM,aAAa,KAAK,IAAI;AAAA,QAChD,aAAa,QAAQ,MAAM,cAAc,KAAK,IAAI;AAAA,QAClD;AAAA,QACA;AAAA,MACF;AAAA,MACA,UAAU;AAAA,QACR,YAAY;AAAA,QACZ,eAAe,gBAAgB;AAAA,QAC/B,YAAY,gBAAgB,MAAM,GAAG,EAAE;AAAA,MACzC;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,iBAAiB,GAAuB;AACtD,QAAM,IAAI,EAAE;AACZ,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,iBAAiB,EAAE,SAAS,UAAU,eAAY,EAAE,SAAS,KAAK,mBAAgB,EAAE,SAAS,UAAU,sBAAmB,EAAE,SAAS,OAAO,iBAAc,EAAE,SAAS,cAAc;AAAA,IACnL,iBAAiB,EAAE,SAAS,UAAU,aAAa,EAAE,SAAS,aAAa;AAAA,IAC3E;AAAA,IACA;AAAA,IACA,0BAA0B,EAAE,SAAS,aAAa,IAAI;AAAA,IACtD,eAAU,EAAE,SAAS,aAAa,QAAQ;AAAA,IAC1C,gBAAW,EAAE,SAAS,aAAa,UAAU;AAAA,IAC7C,UAAU,EAAE,SAAS,aAAa,UAAU;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,EAAE,SAAS,aAAa,IAAI,OAAK,KAAK,EAAE,OAAO,MAAM,EAAE,gBAAgB,IAAI,EAAE,gBAAgB,MAAM,EAAE,GAAG,IAAI;AAAA,IAC/G;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,EAAE,SAAS,WAAW,IAAI,OAAK,KAAK,EAAE,KAAK,MAAM,EAAE,QAAQ,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,IAAI;AAAA,EAC/F;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC9GA,IAAM,aAAa;AACnB,IAAM,YAAY;AAClB,IAAM,eAAe;AACrB,IAAM,YAAY;AAClB,IAAM,WAAW;AACjB,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,UAAU;AAEhB,SAAS,MAAS,OAAmB,KAAsD;AACzF,QAAM,SAAS,oBAAI,IAAsB;AACzC,aAAW,KAAK,OAAO;AACrB,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,MAAM,QAAQ,MAAM,UAAa,MAAM,GAAI;AAC/C,UAAM,KAAK,OAAO,CAAC;AACnB,QAAI,CAAC,OAAO,IAAI,EAAE,EAAG,QAAO,IAAI,IAAI,CAAC,CAAC;AACtC,WAAO,IAAI,EAAE,EAAG,KAAK,EAAE,GAAG;AAAA,EAC5B;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC,EAAE,KAAK;AAC7D;AAEO,SAAS,cAAc,OAAmB,SAAuC,4BAAuD;AAC7I,QAAM,QAAQ,CAAC,UAAgC,EAAE,OAAO,KAAK,QAAQ,MAAM,KAAK,MAAM,GAAG,GAAG,EAAE;AAC9F,QAAM,QAAQ,CAAC,OAAiC,MAAM,OAAO,EAAE,EAAE,IAAI,OAAK,EAAE,GAAG;AAC/E,QAAM,YAAY,CAAC,MAAgB,EAAE,qBAAqB;AAC1D,QAAM,KAAK,CAAC,MAAgB,UAAU,CAAC,KAAK,EAAE,WAAW;AACzD,QAAM,gBAAgB,IAAI,IAAI,MAAM,OAAO,SAAS,EAAE,IAAI,UAAQ,KAAK,GAAG,CAAC;AAC3E,QAAM,WAAW,CAAC,MAAc;AAAE,QAAI;AAAE,aAAO,IAAI,IAAI,CAAC,EAAE;AAAA,IAAS,QAAQ;AAAE,aAAO;AAAA,IAAG;AAAA,EAAE;AAEzF,QAAM,SAAsB;AAAA,IAC1B,iBAAiB,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;AAAA,IACpD,mBAAmB,MAAM,MAAM,MAAM,OAAO,EAAE,GAAG,OAAK,EAAE,KAAK,CAAC;AAAA,IAC9D,iBAAiB,MAAM,MAAM,QAAM,EAAE,eAAe,KAAK,cAAc,EAAE,eAAe,KAAK,YAAY,CAAC;AAAA,IAC1G,kBAAkB,MAAM,MAAM,OAAK,EAAE,SAAS,SAAS,EAAE,eAAe,KAAK,SAAS,CAAC;AAAA,IACvF,kBAAkB,MAAM,MAAM,OAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;AAAA,IACzF,gBAAgB,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;AAAA,IAC7D,kBAAkB,MAAM,MAAM,MAAM,OAAO,EAAE,GAAG,OAAK,EAAE,eAAe,CAAC;AAAA,IACvE,gBAAgB,MAAM,MAAM,QAAM,EAAE,kBAAkB,KAAK,QAAQ,CAAC;AAAA,IACpE,iBAAiB,MAAM,MAAM,OAAK,EAAE,mBAAmB,SAAS,EAAE,kBAAkB,KAAK,QAAQ,CAAC;AAAA,IAClG,cAAc,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AAAA,IAC9C,eAAe,MAAM,MAAM,OAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,IACzC,gBAAgB,MAAM,MAAM,MAAM,OAAO,EAAE,GAAG,OAAK,EAAE,EAAE,CAAC;AAAA,IACxD,cAAc,MAAM,MAAM,QAAM,EAAE,IAAI,UAAU,KAAK,MAAM,CAAC;AAAA,IAC5D,cAAc,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,IAIxD,0BAA0B,MAAM,MAAM,OAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAAA,IACzD,6BAA6B,MAAM,MAAM,OAAK,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;AAAA,IAC3E,wBAAwB,MAAM,MAAM,OAAK,EAAE,uBAAuB,SAAS,CAAC;AAAA,IAC5E,qBAAqB,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;AAAA,IAC/D,2BAA2B,MAAM,MAAM,OAAK,EAAE,uBAAuB,eAAe,CAAC;AAAA,IACrF,sBAAsB,MAAM,MAAM,QAAM,EAAE,UAAU,MAAM,QAAQ,EAAE,UAAU,KAAK,GAAG,CAAC;AAAA,IACvF,qBAAqB,MAAM,MAAM,QAAM,EAAE,UAAU,MAAM,GAAG,CAAC;AAAA,IAC7D,wBAAwB,MAAM,MAAM,QAAM,EAAE,UAAU,MAAM,QAAQ,EAAE,UAAU,KAAK,GAAG,CAAC;AAAA,IACzF,uBAAuB,MAAM,MAAM,OAAK,EAAE,WAAW,IAAI,CAAC;AAAA,IAC1D,gBAAgB,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,EAAE,YAAY,UAAU,CAAC;AAAA,IACtF,0BAA0B,MAAM,MAAM,MAAM,OAAO,OAAK,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAK,EAAE,WAAW,CAAC;AAAA,IACpG,qBAAqB,MAAM,MAAM,OAAK,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;AAAA,IAC7E,kBAAkB,MAAM,MAAM,OAAK,GAAG,CAAC,KAAK,EAAE,YAAY,WAAW,CAAC,CAAC;AAAA,IACvE,eAAe,MAAM,MAAM,OAAK,EAAE,IAAI,SAAS,OAAO,CAAC;AAAA,IACvD,iBAAiB,MAAM,MAAM,OAAK,QAAQ,KAAK,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;AAAA,IAChE,mBAAmB,MAAM,MAAM,OAAK,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC;AAAA,IAClE,gBAAgB,MAAM,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,UAAU,cAAc,IAAI,EAAE,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,GAAG,CAAC;AAAA,EAC/G;AAEA,MAAI,kBAAkB;AACtB,MAAI,CAAC,iBAAiB;AACpB,UAAM,UAAU,CAAC,MAAc;AAAE,UAAI;AAAE,cAAM,IAAI,IAAI,IAAI,CAAC;AAAG,UAAE,OAAO;AAAI,gBAAQ,EAAE,SAAS,EAAE,UAAU,QAAQ,QAAQ,EAAE,IAAI,EAAE;AAAA,MAAO,QAAQ;AAAE,eAAO,EAAE,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAAA,MAAE;AAAA,IAAE;AACrM,UAAM,cAAc,IAAI,IAAI,MAAM,IAAI,OAAK,CAAC,QAAQ,EAAE,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC;AACtE,sBAAkB,oBAAI,IAAY;AAClC,eAAW,KAAK,OAAO;AACrB,iBAAW,KAAK,EAAE,YAAY,CAAC,GAAG;AAChC,YAAI,CAAC,EAAE,SAAU;AACjB,cAAM,KAAK,YAAY,IAAI,QAAQ,EAAE,IAAI,CAAC;AAC1C,YAAI,MAAM,QAAQ,MAAM,IAAK,iBAAgB,IAAI,EAAE,GAAG;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACA,SAAO,sBAAsB,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC;AAE3D,SAAO;AACT;AAEO,SAAS,kBAAkB,SAAiB,OAAmB,QAAqB,SAA+C;AACxI,QAAM,QAAQ,MAAM;AACpB,QAAM,aAAa,MAAM,OAAO,UAAQ,KAAK,qBAAqB,QAAQ,EAAE;AAC5E,QAAM,SAAS,QAAQ;AACvB,QAAM,MAAM,CAAC,QACX,IAAI,WAAW,iBAAiB,KAAK,IAAI,WAAW,gBAAgB,KAAK,IAAI,WAAW,cAAc,IAAI,cACxG,IAAI,WAAW,eAAe,KAAK,IAAI,WAAW,YAAY,KAAK,IAAI,WAAW,cAAc,KAAK,IAAI,WAAW,mBAAmB,IAAI,cAC3I;AAEJ,QAAM,OAAO,OAAO,QAAQ,MAAM,EAC/B,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EACtC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK,QAAK,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,YAAO,EAAE,IAAI;AAE9H,QAAM,SAAS,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,IAAI,OAAK,EAAE,UAAU,EAAE,OAAO,CAAC,MAAmB,KAAK,IAAI;AAChG,QAAM,WAAW,OAAO,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;AACvD,QAAM,gBAAgB,IAAI,IAAI,MAAM,OAAO,UAAQ,KAAK,qBAAqB,QAAQ,EAAE,IAAI,UAAQ,KAAK,GAAG,CAAC;AAC5G,QAAM,UAAU,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,OAAO,OAAK,EAAE,UAAU,cAAc,IAAI,EAAE,GAAG,CAAC,EAAE;AACxF,QAAM,YAAY,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC;AAExF,SAAO;AAAA,IACL,uBAAuB,OAAO;AAAA,IAC9B,KAAK,KAAK,2BAAwB,UAAU,mBAAgB,MAAM,gCAA6B,QAAQ,SAAM,OAAO;AAAA,IACpH;AAAA;AAAA;AAAA;AAAA,EAAkF,KAAK,KAAK,IAAI,KAAK,gCAAsB;AAAA,IAC3H;AAAA;AAAA,EAA2B,UAAU,IAAI,OAAK,KAAK,EAAE,OAAO,uBAAoB,EAAE,cAAc,QAAG,SAAM,EAAE,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5H;AAAA,qBAAwB,SAAS,MAAM,YAAY,YAAY,QAAQ,UAAU,MAAM,aAAa,UAAU,eAAe,OAAO;AAAA,EACtI,EAAE,KAAK,IAAI;AACb;;;ACrHA,SAAS,kBAAkB;AAC3B,SAAS,OAAO,UAAU,iBAAiB;AAC3C,SAAS,yBAAyB;AAClC,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;AAC9B,SAAmB,iBAAiB;AACpC,SAAS,gBAAgB;AA4BzB,SAAS,sBAA+B;AACtC,SAAO,QAAQ,IAAI,WAAW,OAAO,QAAQ,IAAI,aAAa;AAChE;AAEA,SAAS,aAAa,QAAwC;AAC5D,SAAO,OAAO,UAAU,oBAAoB;AAC9C;AAEA,SAAS,mBAAmB,QAAuC;AACjE,SAAO,OAAO,cAAc,KAAK,KAC5B,QAAQ,IAAI,wBAAwB,KAAK,KACzC,KAAK,QAAQ,GAAG,aAAa,aAAa;AACjD;AAEA,SAAS,iBAAiB,QAAwB;AAChD,QAAM,aAAa,OAAO,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAChE,MAAI,CAAC,cAAc,WAAW,SAAS,IAAI,KAAK,CAAC,oBAAoB,KAAK,UAAU,GAAG;AACrF,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AACA,SAAO,GAAG,UAAU;AACtB;AAEA,SAAS,oBAAoB,OAAe,OAAuB;AACjE,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,yBAAyB,KAAK,OAAO,GAAG;AAC3C,UAAM,IAAI,MAAM,GAAG,KAAK,8DAA8D;AAAA,EACxF;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,OAAuB;AACtD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,0BAA0B,KAAK,OAAO,KAAK,YAAY,OAAO,YAAY,MAAM;AACnF,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,OAAuB;AACnD,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,qBAAqB,GAAG,EAAE,QAAQ,YAAY,EAAE;AACxF,UAAQ,cAAc,YAAY,MAAM,GAAG,GAAG;AAChD;AAEA,SAAS,YAAY,OAAuC;AAC1D,QAAM,aAAa,OAAO,UAAU,YAAY,wCAAwC,KAAK,KAAK,IAC9F,GAAG,MAAM,QAAQ,KAAK,GAAG,CAAC,MAC1B;AACJ,QAAM,YAAY,sBAAsB,OACpC,WAAW,QAAQ,IACnB,OAAO,eAAe,WACpB,aACA,IAAI,KAAK,UAAU,EAAE,QAAQ;AACnC,MAAI,CAAC,OAAO,cAAc,SAAS,KAAK,aAAa,EAAG,OAAM,IAAI,MAAM,uCAAuC;AAC/G,SAAO;AACT;AAEA,SAAS,eAAe,QAAoH;AAC1I,MAAI,CAAC,OAAO,cAAc,OAAO,aAAa,KAAK,OAAO,iBAAiB,GAAG;AAC5E,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,MAAI,CAAC,OAAO,cAAc,OAAO,aAAa,KAAK,OAAO,iBAAiB,GAAG;AAC5E,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,SAAO;AAAA,IACL,QAAQ,iBAAiB,OAAO,MAAM;AAAA,IACtC,eAAe,OAAO;AAAA,IACtB,eAAe,OAAO;AAAA,EACxB;AACF;AAEA,SAAS,kBAAkB,YAAoB,QAA+B;AAC5E,QAAM,aAAa,iBAAiB,MAAM;AAC1C,MAAI,CAAC,WAAW,WAAW,UAAU,EAAG,QAAO;AAC/C,QAAM,WAAW,WAAW,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK;AACjD,QAAM,QAAQ,SAAS,MAAM,YAAY;AACzC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,OAAO,MAAM,CAAC,CAAC;AACjC,SAAO,OAAO,cAAc,SAAS,KAAK,YAAY,IAAI,YAAY;AACxE;AAEO,SAAS,uBAAuB,YAAoB,QAA+B;AACxF,QAAM,aAAa,iBAAiB,MAAM;AAC1C,MAAI,CAAC,WAAW,WAAW,UAAU,KAAK,WAAW,SAAS,IAAI,EAAG,QAAO;AAC5E,QAAM,OAAO,WAAW,MAAM,WAAW,MAAM;AAC/C,QAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,MAAI;AACF,WAAO,oBAAoB,SAAS,CAAC,KAAK,IAAI,SAAS;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,yBAAyB,YAAoB,QAA4C;AACvG,QAAM,YAAY,eAAe,MAAM;AACvC,MAAI,uBAAuB,YAAY,UAAU,MAAM,MAAM,KAAM,QAAO;AAC1E,QAAM,YAAY,kBAAkB,YAAY,UAAU,MAAM;AAChE,SAAO,cAAc,OAAO,OAAO,IAAI,KAAK,YAAY,UAAU,aAAa;AACjF;AAEA,eAAe,kBAAkB,UAAkB,WAAiB,QAG1D;AACR,QAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,KAAK,IAAI,KAAK,IAAI,IAAI,OAAO,eAAe,UAAU,QAAQ,CAAC;AAClF,MAAI,cAAc,KAAK,IAAI,EAAG,QAAO;AACrC,QAAM,EAAE,kBAAkB,WAAW,IAAI,MAAM,OAAO,cAAc;AACpE,QAAM,cAAc,MAAM,iBAAiB;AAAA,IACzC;AAAA,IACA;AAAA,IACA,YAAY,CAAC,KAAK;AAAA,IAClB;AAAA,EACF,CAAC;AACD,QAAM,EAAE,aAAa,IAAI,MAAM,WAAW,aAAa;AAAA,IACrD,QAAQ;AAAA,IACR,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACF,CAAC;AACD,SAAO,EAAE,KAAK,cAAc,WAAW,IAAI,KAAK,UAAU,EAAE,YAAY,EAAE;AAC5E;AAEA,eAAsB,sBAAsB,MAQR;AAClC,QAAM,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,eAAe,KAAK,MAAM,EAAE;AAChE,QAAM,UAAU,oBAAoB,KAAK,SAAS,SAAS;AAC3D,QAAM,cAAc,wBAAwB,KAAK,WAAW;AAC5D,QAAM,YAAY,YAAY,KAAK,SAAS;AAC5C,QAAM,oBAAoB,GAAG,OAAO,MAAM,GAAG,OAAO,IAAI,SAAS,IAAI,WAAW;AAChF,QAAM,OAAO,OAAO,SAAS,KAAK,OAAO,IAAI,KAAK,UAAU,OAAO,KAAK,KAAK,OAAO;AACpF,QAAM,QAAQ,KAAK;AACnB,QAAM,SAAS,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AAC7D,QAAM,YAAY,IAAI,KAAK,YAAY,OAAO,aAAa;AAC3D,QAAM,QAAQ,OAAO,OAAO,KAAK,KAAK;AAEtC,MAAI,aAAa;AACjB,MAAI,OAAO;AACT,UAAM,EAAE,IAAI,IAAI,MAAM,OAAO,cAAc;AAC3C,UAAM,SAAS,MAAM,IAAI,mBAAmB,MAAM;AAAA,MAChD,QAAQ;AAAA,MACR;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,MACpB,WAAW,QAAQ,MAAM,OAAO;AAAA,IAClC,CAAC;AACD,iBAAa,OAAO;AAAA,EACtB,OAAO;AACL,QAAI,aAAa,MAAM,EAAG,OAAM,IAAI,MAAM,sCAAsC;AAChF,UAAM,OAAO,KAAK,mBAAmB,MAAM,GAAG,SAAS,iBAAiB;AACxE,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,UAAU,MAAM,IAAI;AAAA,EAC5B;AAEA,QAAM,WAAW,MAAM,kBAAkB,YAAY,WAAW,MAAM;AACtE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,qBAAqB,KAAK,QAAQ;AAAA,IAC5C,aAAa,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW,UAAU,YAAY;AAAA,IACjC,aAAa,UAAU,OAAO;AAAA,IAC9B,sBAAsB,UAAU,aAAa;AAAA,EAC/C;AACF;AAEA,eAAsB,gCAAgC,MAQlB;AAClC,QAAM,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,eAAe,KAAK,MAAM,EAAE;AAChE,QAAM,UAAU,oBAAoB,KAAK,SAAS,SAAS;AAC3D,QAAM,cAAc,wBAAwB,KAAK,WAAW;AAC5D,QAAM,YAAY,YAAY,KAAK,SAAS;AAC5C,QAAM,oBAAoB,GAAG,OAAO,MAAM,GAAG,OAAO,IAAI,SAAS,IAAI,WAAW;AAChF,QAAM,YAAY,IAAI,KAAK,YAAY,OAAO,aAAa;AAC3D,QAAM,QAAQ,OAAO,OAAO,KAAK,KAAK;AACtC,QAAM,OAAO,WAAW,QAAQ;AAChC,MAAI,QAAQ;AACZ,QAAM,QAAQ,IAAI,UAAU;AAAA,IAC1B,UAAU,OAAe,WAAW,UAAU;AAC5C,eAAS,MAAM;AACf,WAAK,OAAO,KAAK;AACjB,eAAS,MAAM,KAAK;AAAA,IACtB;AAAA,EACF,CAAC;AAED,MAAI,aAAa;AACjB,MAAI,OAAO;AACT,UAAM,EAAE,IAAI,IAAI,MAAM,OAAO,cAAc;AAC3C,UAAM,UAAU,SAAS,KAAK,SAAS,KAAK;AAC5C,QAAI;AACF,YAAM,SAAS,MAAM,IAAI,mBAAmB,OAAO;AAAA,QACjD,QAAQ;AAAA,QACR;AAAA,QACA,aAAa,KAAK;AAAA,QAClB,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,WAAW;AAAA,MACb,CAAC;AACD,YAAM;AACN,mBAAa,OAAO;AAAA,IACtB,SAAS,OAAO;AACd,WAAK,QAAQ,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAC9E,YAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AACvE,YAAM,QAAQ,MAAM,MAAM,MAAS;AACnC,YAAM;AAAA,IACR;AAAA,EACF,OAAO;AACL,QAAI,aAAa,MAAM,EAAG,OAAM,IAAI,MAAM,sCAAsC;AAChF,UAAM,OAAO,KAAK,mBAAmB,MAAM,GAAG,SAAS,iBAAiB;AACxE,UAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,SAAS,KAAK,SAAS,OAAO,kBAAkB,IAAI,CAAC;AAAA,EAC7D;AAEA,QAAM,SAAS,KAAK,OAAO,KAAK;AAChC,QAAM,WAAW,MAAM,kBAAkB,YAAY,WAAW,MAAM;AACtE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,qBAAqB,KAAK,QAAQ;AAAA,IAC5C,aAAa,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW,UAAU,YAAY;AAAA,IACjC,aAAa,UAAU,OAAO;AAAA,IAC9B,sBAAsB,UAAU,aAAa;AAAA,EAC/C;AACF;AAEA,eAAsB,6BAA6B,MAI0C;AAC3F,MAAI,uBAAuB,KAAK,YAAY,KAAK,OAAO,MAAM,MAAM,KAAK,QAAS,QAAO;AACzF,QAAM,YAAY,yBAAyB,KAAK,YAAY,KAAK,MAAM;AACvE,MAAI,CAAC,aAAa,UAAU,QAAQ,KAAK,KAAK,IAAI,EAAG,QAAO;AAC5D,QAAM,WAAW,MAAM,kBAAkB,KAAK,YAAY,WAAW,KAAK,MAAM;AAChF,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;AAAA,IACL,aAAa,SAAS;AAAA,IACtB,sBAAsB,SAAS;AAAA,IAC/B,WAAW,UAAU,YAAY;AAAA,EACnC;AACF;AAEA,eAAe,eAAe,QAAqD;AACjF,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAmB,CAAC;AAC1B,MAAI;AACF,eAAS;AACP,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,UAAI,MAAO,QAAO,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,IAC3C;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACA,SAAO,OAAO,OAAO,MAAM;AAC7B;AAEA,eAAsB,0BAA0B,MAKN;AACxC,QAAM,YAAY,yBAAyB,KAAK,YAAY,KAAK,MAAM;AACvE,MAAI,CAAC,aAAa,UAAU,QAAQ,KAAK,KAAK,IAAI,EAAG,QAAO;AAC5D,MAAI,CAAC,OAAO,cAAc,KAAK,MAAM,KAAK,KAAK,SAAS,EAAG,OAAM,IAAI,MAAM,oCAAoC;AAC/G,MAAI,CAAC,OAAO,cAAc,KAAK,QAAQ,KAAK,KAAK,YAAY,EAAG,OAAM,IAAI,MAAM,sCAAsC;AAEtH,QAAM,QAAQ,KAAK,OAAO,OAAO,KAAK,KAAK;AAC3C,MAAI;AACJ,MAAI,OAAO;AACT,UAAM,EAAE,IAAI,IAAI,MAAM,OAAO,cAAc;AAC3C,UAAM,SAAS,MAAM,IAAI,KAAK,YAAY,EAAE,QAAQ,WAAW,OAAO,UAAU,MAAM,CAAC;AACvF,QAAI,CAAC,UAAU,OAAO,eAAe,IAAK,QAAO;AACjD,aAAS,MAAM,eAAe,OAAO,MAAM;AAAA,EAC7C,OAAO;AACL,QAAI,aAAa,KAAK,MAAM,EAAG,QAAO;AACtC,QAAI;AACF,eAAS,MAAM,SAAS,KAAK,mBAAmB,KAAK,MAAM,GAAG,SAAS,KAAK,UAAU,CAAC;AAAA,IACzF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,aAAa,OAAO;AAC1B,QAAM,MAAM,KAAK,IAAI,YAAY,KAAK,SAAS,KAAK,QAAQ;AAC5D,SAAO;AAAA,IACL,MAAM,OAAO,SAAS,KAAK,QAAQ,GAAG,EAAE,SAAS,MAAM;AAAA,IACvD;AAAA,IACA,YAAY,MAAM,aAAa,MAAM;AAAA,EACvC;AACF;","names":[]}
@@ -0,0 +1,7 @@
1
+ // src/version.ts
2
+ var PACKAGE_VERSION = "0.37.0";
3
+
4
+ export {
5
+ PACKAGE_VERSION
6
+ };
7
+ //# sourceMappingURL=chunk-3LWYPAU5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.37.0'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
@@ -19,6 +19,14 @@ var ExtractionError = class extends Error {
19
19
  cause;
20
20
  name = "ExtractionError";
21
21
  };
22
+ var MapsSearchIncompletePageError = class extends Error {
23
+ constructor(pageState) {
24
+ super(`Google Maps search did not reach a complete result state (${pageState})`);
25
+ this.pageState = pageState;
26
+ }
27
+ pageState;
28
+ name = "MapsSearchIncompletePageError";
29
+ };
22
30
  var RequestAbortedError = class extends Error {
23
31
  name = "RequestAbortedError";
24
32
  constructor(message = "Request aborted before harvest completed") {
@@ -37,7 +45,8 @@ export {
37
45
  sanitizeVendorName,
38
46
  CaptchaError,
39
47
  ExtractionError,
48
+ MapsSearchIncompletePageError,
40
49
  RequestAbortedError,
41
50
  LocationMismatchError
42
51
  };
43
- //# sourceMappingURL=chunk-M2S27J6Z.js.map
52
+ //# sourceMappingURL=chunk-44HZLHDV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["export const RECAPTCHA_INSTRUCTIONS = 'Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.'\n\nexport function sanitizeVendorName(message: string): string {\n return message\n .replace(/kernel\\.sh\\s+sessions?/gi, 'sessions')\n .replace(/kernel\\.sh\\s+session/gi, 'this session')\n .replace(/kernel\\.sh/gi, 'the service')\n .replace(/kernel\\s+sessions?/gi, 'sessions')\n .replace(/kernel\\s+session/gi, 'this session')\n .replace(/\\bkernel\\b/gi, 'the service')\n .replace(/ +/g, ' ')\n .trim()\n}\n\nexport class CaptchaError extends Error {\n readonly name = 'CaptchaError'\n constructor(public readonly instructions: string) {\n super(`CAPTCHA detected. ${instructions}`)\n }\n}\n\nexport class ExtractionError extends Error {\n readonly name = 'ExtractionError'\n constructor(message: string, public readonly cause?: unknown) {\n super(message)\n }\n}\n\n/**\n * Google Maps sometimes finishes navigation without rendering either result\n * cards or its explicit no-results message. Treating that page as a genuine\n * empty search loses data, so callers should retry it with a fresh browser (and\n * a fresh proxy when location rotation is enabled).\n */\nexport class MapsSearchIncompletePageError extends Error {\n readonly name = 'MapsSearchIncompletePageError'\n\n constructor(public readonly pageState: string) {\n super(`Google Maps search did not reach a complete result state (${pageState})`)\n }\n}\n\nexport class RequestAbortedError extends Error {\n readonly name = 'RequestAbortedError'\n constructor(message = 'Request aborted before harvest completed') {\n super(message)\n }\n}\n\nexport class LocationMismatchError extends Error {\n readonly name = 'LocationMismatchError'\n constructor(message = 'Google returned results for a different location than requested') {\n super(message)\n }\n}\n"],"mappings":";AAAO,IAAM,yBAAyB;AAE/B,SAAS,mBAAmB,SAAyB;AAC1D,SAAO,QACJ,QAAQ,4BAA4B,UAAU,EAC9C,QAAQ,0BAA0B,cAAc,EAChD,QAAQ,gBAAgB,aAAa,EACrC,QAAQ,wBAAwB,UAAU,EAC1C,QAAQ,sBAAsB,cAAc,EAC5C,QAAQ,gBAAgB,aAAa,EACrC,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EAEtC,YAA4B,cAAsB;AAChD,UAAM,qBAAqB,YAAY,EAAE;AADf;AAAA,EAE5B;AAAA,EAF4B;AAAA,EADnB,OAAO;AAIlB;AAEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAEzC,YAAY,SAAiC,OAAiB;AAC5D,UAAM,OAAO;AAD8B;AAAA,EAE7C;AAAA,EAF6C;AAAA,EADpC,OAAO;AAIlB;AAQO,IAAM,gCAAN,cAA4C,MAAM;AAAA,EAGvD,YAA4B,WAAmB;AAC7C,UAAM,6DAA6D,SAAS,GAAG;AADrD;AAAA,EAE5B;AAAA,EAF4B;AAAA,EAFnB,OAAO;AAKlB;AAEO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EACpC,OAAO;AAAA,EAChB,YAAY,UAAU,4CAA4C;AAChE,UAAM,OAAO;AAAA,EACf;AACF;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACtC,OAAO;AAAA,EAChB,YAAY,UAAU,mEAAmE;AACvF,UAAM,OAAO;AAAA,EACf;AACF;","names":[]}