one-search-mcp 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,38 +1,86 @@
1
1
  # 🚀 OneSearch MCP Server: Web Search & Crawl & Scraper & Extract
2
2
 
3
- A Model Context Protocol (MCP) server implementation that integrates with Searxng/Tavily/DuckDuckGo/Bing for web search, local browser search, and scraping capabilities with Firecrawl.
3
+ A Model Context Protocol (MCP) server implementation that integrates with Searxng/Tavily/DuckDuckGo/Bing for web search, local browser search, and scraping capabilities with agent-browser.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - Web Search, scrape, crawl and extract content from websites.
8
- - Support multiple search engines and web scrapers: **SearXNG**, **Firecrawl**, **Tavily**, **DuckDuckGo**, **Bing**, etc.
8
+ - Support multiple search engines and web scrapers: **SearXNG**, **Tavily**, **DuckDuckGo**, **Bing**, etc.
9
9
  - **Local web search** (browser search), support multiple search engines: **Bing**, **Google**, **Baidu**, **Sogou**, etc.
10
- - Use `puppeteer-core` to scrape content from websites.
11
- - You should have a local browser installed, such as `Chromium`, `Google Chrome`, `Google Chrome Canary`, etc.
12
- - Free, no keys required.
13
- - **Enabled tools:** `one_search`, `one_scrape`, `one_map`
14
- - Support for self-hosted: SearXNG, Firecrawl, etc. (see [Deploy](./deploy/README.md))
10
+ - Use `agent-browser` for browser automation.
11
+ - Free, no API keys required.
12
+ - **Enabled tools:** `one_search`, `one_scrape`, `one_map`, `one_extract`
15
13
 
16
- ## Installation
14
+ ## Migration from v1.0.10 and Earlier
15
+
16
+ **Breaking Changes in v1.0.11:**
17
+
18
+ - **Firecrawl Removed**: The Firecrawl integration has been removed in favor of `agent-browser`, which provides similar functionality without requiring external API services.
19
+ - **New Browser Requirement**: You must install Chromium browser (see Prerequisites section).
20
+ - **Environment Variables**: `FIRECRAWL_API_URL` and `FIRECRAWL_API_KEY` are no longer used.
21
+
22
+ **What Changed:**
23
+
24
+ - `one_scrape` and `one_map` now use `agent-browser` instead of Firecrawl
25
+ - `one_extract` tool is now fully implemented for structured data extraction from multiple URLs
26
+ - All browser-based operations are now handled locally, providing better privacy and no API costs
27
+
28
+ **Migration Steps:**
29
+
30
+ 1. Install Chromium browser (see Prerequisites)
31
+ 2. Remove `FIRECRAWL_API_URL` and `FIRECRAWL_API_KEY` from your environment variables
32
+ 3. Update to the latest version: `npm install -g one-search-mcp@latest`
33
+
34
+ ## Prerequisites
17
35
 
18
- ### Installing via Smithery
36
+ **Browser Requirement**: This server uses `agent-browser` for web scraping and local search, which requires a Chromium-based browser.
19
37
 
20
- To install OneSearch for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@yokingma/one-search):
38
+ **Good News**: The server will automatically detect and use browsers already installed on your system:
39
+
40
+ - ✅ Google Chrome
41
+ - ✅ Microsoft Edge
42
+ - ✅ Chromium
43
+ - ✅ Google Chrome Canary
44
+
45
+ **If you don't have any of these browsers installed**, you can:
21
46
 
22
47
  ```bash
23
- npx -y @smithery/cli install @yokingma/one-search --client claude
48
+ # Option 1: Install Google Chrome (Recommended)
49
+ # Download from: https://www.google.com/chrome/
50
+
51
+ # Option 2: Install Microsoft Edge
52
+ # Download from: https://www.microsoft.com/edge
53
+
54
+ # Option 3: Install Chromium via agent-browser
55
+ npx agent-browser install
56
+
57
+ # Option 4: Install Chromium directly
58
+ # Download from: https://www.chromium.org/getting-involved/download-chromium/
59
+ ```
60
+
61
+ ## Installation
62
+
63
+ ### Using Claude Code CLI (Recommended)
64
+
65
+ ```bash
66
+ # Add to Claude Code with default settings (local search)
67
+ claude mcp add one-search-mcp -- npx -y one-search-mcp
68
+
69
+ # Add with custom search provider (e.g., SearXNG)
70
+ claude mcp add -e SEARCH_PROVIDER=searxng -e SEARCH_API_URL=http://127.0.0.1:8080 one-search-mcp -- npx -y one-search-mcp
71
+
72
+ # Add with Tavily API
73
+ claude mcp add -e SEARCH_PROVIDER=tavily -e SEARCH_API_KEY=your_api_key one-search-mcp -- npx -y one-search-mcp
24
74
  ```
25
75
 
26
76
  ### Manual Installation
27
77
 
28
- ```shell
29
- # Manually install (Optional)
78
+ ```bash
79
+ # Install globally (Optional)
30
80
  npm install -g one-search-mcp
31
- ```
32
81
 
33
- ```shell
34
- # using npx
35
- env SEARCH_API_URL=http://127.0.0.1:8080 FIRECRAWL_API_URL=http://127.0.0.1:3002 npx -y one-search-mcp
82
+ # Or run directly with npx
83
+ npx -y one-search-mcp
36
84
  ```
37
85
 
38
86
  ## Environment Variables
@@ -48,14 +96,14 @@ env SEARCH_API_URL=http://127.0.0.1:8080 FIRECRAWL_API_URL=http://127.0.0.1:3002
48
96
  export type SearchProvider = 'searxng' | 'duckduckgo' | 'bing' | 'tavily' | 'local';
49
97
  ```
50
98
 
51
- **Firecrawl:**
99
+ ## Configuration for Other MCP Clients
52
100
 
53
- - FIRECRAWL_API_URL (Optional): The URL of the Firecrawl API, required for `firecrawl`.
54
- - FIRECRAWL_API_KEY (Optional): The API key for the Firecrawl API, required for `firecrawl` if using cloud service.
101
+ ### Claude Desktop
55
102
 
56
- ## Running on Cursor
103
+ Add to your Claude Desktop configuration file:
57
104
 
58
- Your `mcp.json` file will look like this:
105
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
106
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
59
107
 
60
108
  ```json
61
109
  {
@@ -64,20 +112,16 @@ Your `mcp.json` file will look like this:
64
112
  "command": "npx",
65
113
  "args": ["-y", "one-search-mcp"],
66
114
  "env": {
67
- "SEARCH_PROVIDER": "searxng",
68
- "SEARCH_API_URL": "http://127.0.0.1:8080",
69
- "SEARCH_API_KEY": "YOUR_API_KEY",
70
- "FIRECRAWL_API_URL": "http://127.0.0.1:3002",
71
- "FIRECRAWL_API_KEY": "YOUR_API_KEY"
115
+ "SEARCH_PROVIDER": "local"
72
116
  }
73
117
  }
74
118
  }
75
119
  }
76
120
  ```
77
121
 
78
- ## Running on Windsurf
122
+ ### Cursor
79
123
 
80
- Add this to your `./codeium/windsurf/model_config.json` file:
124
+ Add to your `mcp.json` file:
81
125
 
82
126
  ```json
83
127
  {
@@ -86,24 +130,78 @@ Add this to your `./codeium/windsurf/model_config.json` file:
86
130
  "command": "npx",
87
131
  "args": ["-y", "one-search-mcp"],
88
132
  "env": {
89
- "SEARCH_PROVIDER": "searxng",
90
- "SEARCH_API_URL": "http://127.0.0.1:8080",
91
- "SEARCH_API_KEY": "YOUR_API_KEY",
92
- "FIRECRAWL_API_URL": "http://127.0.0.1:3002",
93
- "FIRECRAWL_API_KEY": "YOUR_API_KEY"
133
+ "SEARCH_PROVIDER": "local"
94
134
  }
95
135
  }
96
136
  }
97
137
  }
98
138
  ```
99
139
 
100
- ## Self-host
140
+ ### Windsurf
101
141
 
102
- Local deployment of SearXNG and Firecrawl, please refer to [Deploy](./deploy/README.md)
142
+ Add to your `./codeium/windsurf/model_config.json` file:
143
+
144
+ ```json
145
+ {
146
+ "mcpServers": {
147
+ "one-search-mcp": {
148
+ "command": "npx",
149
+ "args": ["-y", "one-search-mcp"],
150
+ "env": {
151
+ "SEARCH_PROVIDER": "local"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ ## Self-hosting SearXNG (Optional)
159
+
160
+ If you want to use SearXNG as your search provider, you can deploy it locally using Docker:
161
+
162
+ **Prerequisites:**
163
+
164
+ - Docker installed and running (version 20.10.0 or higher)
165
+ - At least 4GB of RAM available
166
+
167
+ **Quick Start:**
168
+
169
+ ```bash
170
+ # Clone SearXNG Docker repository
171
+ git clone https://github.com/searxng/searxng-docker.git
172
+ cd searxng-docker
173
+
174
+ # Start SearXNG
175
+ docker compose up -d
176
+ ```
177
+
178
+ After deployment, SearXNG will be available at `http://127.0.0.1:8080` by default.
179
+
180
+ **Configure OneSearch to use SearXNG:**
181
+
182
+ ```bash
183
+ # Set environment variables
184
+ export SEARCH_PROVIDER=searxng
185
+ export SEARCH_API_URL=http://127.0.0.1:8080
186
+ ```
187
+
188
+ For more details, see the [official SearXNG Docker documentation](https://github.com/searxng/searxng-docker).
103
189
 
104
190
  ## Troubleshooting
105
191
 
106
- - [ReferenceError]: __name is not defined: This is because Puppeteer has problems with `tsx`, [esbuild#1031](https://github.com/evanw/esbuild/issues/1031)
192
+ ### Browser not found error
193
+
194
+ If you see an error like "Browser not found", the server couldn't detect any installed Chromium-based browser. Please install one of the following:
195
+
196
+ - **Google Chrome**: <https://www.google.com/chrome/>
197
+ - **Microsoft Edge**: <https://www.microsoft.com/edge>
198
+ - **Chromium**: <https://www.chromium.org/getting-involved/download-chromium/>
199
+
200
+ Or install via agent-browser:
201
+
202
+ ```bash
203
+ npx agent-browser install
204
+ ```
107
205
 
108
206
  ## License
109
207
 
package/dist/index.cjs CHANGED
@@ -1,16 +1,39 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Ae=Object.create;var U=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var Pe=Object.getPrototypeOf,Ce=Object.prototype.hasOwnProperty;var q=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Le(t))!Ce.call(i,n)&&n!==e&&U(i,n,{get:()=>t[n],enumerable:!(r=xe(t,n))||r.enumerable});return i};var m=(i,t,e)=>(e=i!=null?Ae(Pe(i)):{},q(t||!i||!i.__esModule?U(e,"default",{value:i,enumerable:!0}):e,i)),Re=i=>q(U({},"__esModule",{value:!0}),i);var Ze={};module.exports=Re(Ze);var be=require("@modelcontextprotocol/sdk/server/index.js"),D=require("@modelcontextprotocol/sdk/types.js"),we=require("@modelcontextprotocol/sdk/server/stdio.js");async function H(i){let{query:t,limit:e=10,safeSearch:r=0,page:n=1,apiUrl:a="https://api.bing.microsoft.com/v7.0/search",apiKey:o,language:s}=i,u=["Off","Moderate","Strict"];if(!o)throw new Error("Bing API key is required");let h={q:t,count:e,offset:(n-1)*e,mkt:s,safeSearch:u[r]};try{let c=new URLSearchParams;Object.entries(h).forEach(([d,_])=>{_!==void 0&&c.set(d,_.toString())});let g=await fetch(`${a}?${c}`,{method:"GET",headers:{"Content-Type":"application/json","Ocp-Apim-Subscription-Key":o}});if(!g.ok)throw new Error(`Bing search error: ${g.status} ${g.statusText}`);return{results:(await g.json()).webPages?.value?.map(d=>({title:d.name,snippet:d.snippet,url:d.url,source:d.siteName,thumbnailUrl:d.thumbnailUrl,language:d.language,image:null,video:null,engine:"bing"}))??[],success:!0}}catch(c){let g=c instanceof Error?c.message:"Bing search error.";throw process.stdout.write(g),c}}var N=m(require("duck-duck-scrape"),1),j=m(require("async-retry"),1);async function W(i){try{let{query:t,timeout:e=1e4,safeSearch:r=N.SafeSearchType.OFF,retry:n={retries:3},...a}=i,o=await(0,j.default)(()=>N.search(t,{...a,safeSearch:r},{response_timeout:e}),n);return{results:(o?{noResults:o.noResults,vqd:o.vqd,results:o.results}:{noResults:!0,vqd:"",results:[]}).results.map(u=>({title:u.title,snippet:u.description,url:u.url,source:u.hostname,image:null,video:null,engine:"duckduckgo"})),success:!0}}catch(t){let e=t instanceof Error?t.message:"DuckDuckGo search error.";throw process.stdout.write(e),t}}var V=m(require("url"),1);async function X(i){try{let{query:t,page:e=1,limit:r=10,categories:n="general",engines:a="all",safeSearch:o=0,format:s="json",language:u="auto",timeRange:h="",timeout:c=1e4,apiKey:g,apiUrl:l}=i;if(!l)throw new Error("SearxNG API URL is required");let p=new AbortController,b=setTimeout(()=>p.abort(),Number(c)),d={q:t,pageno:e,categories:n,format:s,safesearch:o,language:u,engines:a,time_range:h},_=`${l}/search`,B=V.default.format({query:d}),k={"Content-Type":"application/json"};g&&(k.Authorization=`Bearer ${g}`);let ve=await fetch(`${_}${B}`,{method:"POST",headers:k,signal:p.signal});clearTimeout(b);let G=await ve.json();return G.results?{results:G.results.slice(0,r).map(y=>{let Te=y.img_src?{thumbnail:y.thumbnail_src,src:y.img_src}:null,Ne=y.iframe_src?{thumbnail:y.thumbnail_src,src:y.iframe_src}:null;return{title:y.title,snippet:y.content,url:y.url,source:y.source,image:Te,video:Ne,engine:y.engine}}),success:!0}:{results:[],success:!1}}catch(t){let e=t instanceof Error?t.message:"Searxng search error.";throw process.stdout.write(e),t}}var K=require("@tavily/core");async function Y(i){let{query:t,limit:e=10,categories:r="general",timeRange:n,apiKey:a}=i;if(!a)throw new Error("Tavily API key is required");try{let o=(0,K.tavily)({apiKey:a}),s={topic:r,timeRange:n,maxResults:e};return{results:(await o.search(t,s)).results.map(c=>({title:c.title,url:c.url,snippet:c.content,engine:"tavily"})),success:!0}}catch(o){let s=o instanceof Error?o.message:"Tavily search error.";throw process.stdout.write(s),o}}var Oe=require("puppeteer-core");var S=m(require("fs"),1),M=m(require("path"),1),z=m(require("os"),1),J=require("@agent-infra/logger"),A=class{logger;constructor(t){this.logger=t??J.defaultLogger}get browsers(){let t=z.homedir(),e=process.env.LOCALAPPDATA;return[{name:"Chromium",executable:{win32:"C:\\Program Files\\Chromium\\Application\\chrome.exe",darwin:"/Applications/Chromium.app/Contents/MacOS/Chromium",linux:"/usr/bin/chromium"},userDataDir:{win32:`${e}\\Chromium\\User Data`,darwin:`${t}/Library/Application Support/Chromium`,linux:`${t}/.config/chromium`}},{name:"Google Chrome",executable:{win32:"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",darwin:"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",linux:"/usr/bin/google-chrome"},userDataDir:{win32:`${e}\\Google\\Chrome\\User Data`,darwin:`${t}/Library/Application Support/Google/Chrome`,linux:`${t}/.config/google-chrome`}},{name:"Google Chrome Canary",executable:{win32:"C:\\Program Files\\Google\\Chrome Canary\\Application\\chrome.exe",darwin:"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",linux:"/usr/bin/google-chrome-canary"},userDataDir:{win32:`${e}\\Google\\Chrome Canary\\User Data`,darwin:`${t}/Library/Application Support/Google/Chrome Canary`,linux:`${t}/.config/google-chrome-canary`}}]}findBrowser(t){let e=process.platform;if(this.logger.info("Finding browser on platform:",e),e!=="darwin"&&e!=="win32"&&e!=="linux"){let a=new Error(`Unsupported platform: ${e}`);throw this.logger.error(a.message),a}let r=t?this.browsers.find(a=>a.name===t&&S.existsSync(a.executable[e])):this.browsers.find(a=>S.existsSync(a.executable[e]));if(this.logger.log("browser",r),!r){let a=t?new Error(`Cannot find browser: ${t}`):new Error("Cannot find a supported browser on your system. Please install Chrome, Edge, or Brave.");throw this.logger.error(a.message),a}let n={executable:r.executable[e],userDataDir:r.userDataDir[e]};return this.logger.success(`Found browser: ${r.name}`),this.logger.info("Browser details:",n),n}getBrowserProfiles(t){let e=this.findBrowser(t);try{let n=JSON.parse(S.readFileSync(M.join(e.userDataDir,"Local State"),"utf8")).profile.info_cache;return Object.entries(n).map(([a,o])=>({displayName:o.name,path:M.join(e.userDataDir,a)}))}catch{return[]}}findChrome(){try{let{executable:t}=this.findBrowser("Google Chrome");return t}catch{return null}}};var Q=require("@agent-infra/logger"),E=class{browser=null;logger;activePage=null;constructor(t){this.logger=t?.logger??Q.defaultLogger,this.logger.info("Browser Options:",t)}getBrowser(){if(!this.browser)throw new Error("Browser not launched");return this.browser}async setupPageListener(){this.browser&&this.browser.on("targetcreated",async t=>{let e=await t.page();e&&(this.logger.info("New page created:",await e.url()),this.activePage=e,e.once("close",()=>{this.activePage===e&&(this.activePage=null)}),e.once("error",()=>{this.activePage===e&&(this.activePage=null)}))})}async close(){this.logger.info("Closing browser");try{await this.browser?.close(),this.browser=null,this.logger.success("Browser closed successfully")}catch(t){throw this.logger.error("Failed to close browser:",t),t}}async evaluateOnNewPage(t){let{url:e,pageFunction:r,pageFunctionParams:n,beforePageLoad:a,afterPageLoad:o,beforeSendResult:s,waitForOptions:u}=t,h=await this.browser.newPage();try{await a?.(h),await h.goto(e,{waitUntil:"networkidle2",...u}),await o?.(h);let c=await h.evaluateHandle(()=>window),g=await h.evaluate(r,c,...n);return await s?.(h,g),await c.dispose(),await h.close(),g}catch(c){throw await h.close(),c}}async createPage(){if(!this.browser)throw this.logger.error("No active browser"),new Error("Browser not launched");return await this.browser.newPage()}async getActivePage(){if(!this.browser)throw new Error("Browser not launched");if(this.activePage)try{return await this.activePage.evaluate(()=>document.readyState),this.activePage}catch(e){this.logger.warn("Active page no longer available:",e),this.activePage=null}let t=await this.browser.pages();if(t.length===0)return this.activePage=await this.createPage(),this.activePage;for(let e=t.length-1;e>=0;e--){let r=t[e];try{return await r.evaluate(()=>document.readyState),this.activePage=r,r}catch{continue}}throw new Error("No active page found")}};var Z=m(require("puppeteer-core"),1);var x=class extends E{browserFinder=new A;async launch(t={}){this.logger.info("Launching browser with options:",t);let e=t?.executablePath||this.browserFinder.findBrowser().executable;this.logger.info("Using executable path:",e);let r=t?.defaultViewport?.width??1280,n=t?.defaultViewport?.height??800,a={executablePath:e,headless:t?.headless??!1,defaultViewport:{width:r,height:n},args:["--no-sandbox","--mute-audio","--disable-gpu","--disable-http2","--disable-blink-features=AutomationControlled","--disable-infobars","--disable-background-timer-throttling","--disable-popup-blocking","--disable-backgrounding-occluded-windows","--disable-renderer-backgrounding","--disable-window-activation","--disable-focus-on-load","--no-default-browser-check","--disable-web-security","--disable-features=IsolateOrigins,site-per-process","--disable-site-isolation-trials",`--window-size=${r},${n+90}`,t?.proxy?`--proxy-server=${t.proxy}`:"",t?.profilePath?`--profile-directory=${t.profilePath}`:""].filter(Boolean),ignoreDefaultArgs:["--enable-automation"],timeout:t.timeout??0,downloadBehavior:{policy:"deny"}};this.logger.info("Launch options:",a);try{this.browser=await Z.launch(a),await this.setupPageListener(),this.logger.success("Browser launched successfully")}catch(o){throw this.logger.error("Failed to launch browser:",o),o}}};var Ie=m(require("puppeteer-core"),1);var ee='function q(t,e){if(e&&e.documentElement)t=e,e=arguments[2];else if(!t||!t.documentElement)throw new Error("First argument to Readability constructor should be a document object.");if(e=e||{},this._doc=t,this._docJSDOMParser=this._doc.firstChild.__JSDOMParser__,this._articleTitle=null,this._articleByline=null,this._articleDir=null,this._articleSiteName=null,this._attempts=[],this._debug=!!e.debug,this._maxElemsToParse=e.maxElemsToParse||this.DEFAULT_MAX_ELEMS_TO_PARSE,this._nbTopCandidates=e.nbTopCandidates||this.DEFAULT_N_TOP_CANDIDATES,this._charThreshold=e.charThreshold||this.DEFAULT_CHAR_THRESHOLD,this._classesToPreserve=this.CLASSES_TO_PRESERVE.concat(e.classesToPreserve||[]),this._keepClasses=!!e.keepClasses,this._serializer=e.serializer||function(i){return i.innerHTML},this._disableJSONLD=!!e.disableJSONLD,this._allowedVideoRegex=e.allowedVideoRegex||this.REGEXPS.videos,this._flags=this.FLAG_STRIP_UNLIKELYS|this.FLAG_WEIGHT_CLASSES|this.FLAG_CLEAN_CONDITIONALLY,this._debug){let i=function(r){if(r.nodeType==r.TEXT_NODE)return`${r.nodeName} ("${r.textContent}")`;let l=Array.from(r.attributes||[],function(a){return`${a.name}="${a.value}"`}).join(" ");return`<${r.localName} ${l}>`};this.log=function(){if(typeof console!="undefined"){let l=Array.from(arguments,a=>a&&a.nodeType==this.ELEMENT_NODE?i(a):a);l.unshift("Reader: (Readability)"),console.log.apply(console,l)}else if(typeof dump!="undefined"){var r=Array.prototype.map.call(arguments,function(l){return l&&l.nodeName?i(l):l}).join(" ");dump("Reader: (Readability) "+r+`\n`)}}}else this.log=function(){}}q.prototype={FLAG_STRIP_UNLIKELYS:1,FLAG_WEIGHT_CLASSES:2,FLAG_CLEAN_CONDITIONALLY:4,ELEMENT_NODE:1,TEXT_NODE:3,DEFAULT_MAX_ELEMS_TO_PARSE:0,DEFAULT_N_TOP_CANDIDATES:5,DEFAULT_TAGS_TO_SCORE:"section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","),DEFAULT_CHAR_THRESHOLD:500,REGEXPS:{unlikelyCandidates:/-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,okMaybeItsACandidate:/and|article|body|column|content|main|shadow/i,positive:/article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,negative:/-ad-|hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,extraneous:/print|archive|comment|discuss|e[\\-]?mail|share|reply|all|login|sign|single|utility/i,byline:/byline|author|dateline|writtenby|p-author/i,replaceFonts:/<(\\/?)font[^>]*>/gi,normalize:/\\s{2,}/g,videos:/\\/\\/(www\\.)?((dailymotion|youtube|youtube-nocookie|player\\.vimeo|v\\.qq)\\.com|(archive|upload\\.wikimedia)\\.org|player\\.twitch\\.tv)/i,shareElements:/(\\b|_)(share|sharedaddy)(\\b|_)/i,nextLink:/(next|weiter|continue|>([^\\|]|$)|\xBB([^\\|]|$))/i,prevLink:/(prev|earl|old|new|<|\xAB)/i,tokenize:/\\W+/g,whitespace:/^\\s*$/,hasContent:/\\S$/,hashUrl:/^#.+/,srcsetUrl:/(\\S+)(\\s+[\\d.]+[xw])?(\\s*(?:,|$))/g,b64DataUrl:/^data:\\s*([^\\s;,]+)\\s*;\\s*base64\\s*,/i,commas:/\\u002C|\\u060C|\\uFE50|\\uFE10|\\uFE11|\\u2E41|\\u2E34|\\u2E32|\\uFF0C/g,jsonLdArticleTypes:/^Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|AskPublicNewsArticle|BackgroundNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|SatiricalArticle|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference$/},UNLIKELY_ROLES:["menu","menubar","complementary","navigation","alert","alertdialog","dialog"],DIV_TO_P_ELEMS:new Set(["BLOCKQUOTE","DL","DIV","IMG","OL","P","PRE","TABLE","UL"]),ALTER_TO_DIV_EXCEPTIONS:["DIV","ARTICLE","SECTION","P"],PRESENTATIONAL_ATTRIBUTES:["align","background","bgcolor","border","cellpadding","cellspacing","frame","hspace","rules","style","valign","vspace"],DEPRECATED_SIZE_ATTRIBUTE_ELEMS:["TABLE","TH","TD","HR","PRE"],PHRASING_ELEMS:["ABBR","AUDIO","B","BDO","BR","BUTTON","CITE","CODE","DATA","DATALIST","DFN","EM","EMBED","I","IMG","INPUT","KBD","LABEL","MARK","MATH","METER","NOSCRIPT","OBJECT","OUTPUT","PROGRESS","Q","RUBY","SAMP","SCRIPT","SELECT","SMALL","SPAN","STRONG","SUB","SUP","TEXTAREA","TIME","VAR","WBR"],CLASSES_TO_PRESERVE:["page"],HTML_ESCAPE_MAP:{lt:"<",gt:">",amp:"&",quot:\'"\',apos:"\'"},_postProcessContent:function(t){this._fixRelativeUris(t),this._simplifyNestedElements(t),this._keepClasses||this._cleanClasses(t)},_removeNodes:function(t,e){if(this._docJSDOMParser&&t._isLiveNodeList)throw new Error("Do not pass live node lists to _removeNodes");for(var i=t.length-1;i>=0;i--){var r=t[i],l=r.parentNode;l&&(!e||e.call(this,r,i,t))&&l.removeChild(r)}},_replaceNodeTags:function(t,e){if(this._docJSDOMParser&&t._isLiveNodeList)throw new Error("Do not pass live node lists to _replaceNodeTags");for(let i of t)this._setNodeTag(i,e)},_forEachNode:function(t,e){Array.prototype.forEach.call(t,e,this)},_findNode:function(t,e){return Array.prototype.find.call(t,e,this)},_someNode:function(t,e){return Array.prototype.some.call(t,e,this)},_everyNode:function(t,e){return Array.prototype.every.call(t,e,this)},_concatNodeLists:function(){var t=Array.prototype.slice,e=t.call(arguments),i=e.map(function(r){return t.call(r)});return Array.prototype.concat.apply([],i)},_getAllNodesWithTag:function(t,e){return t.querySelectorAll?t.querySelectorAll(e.join(",")):[].concat.apply([],e.map(function(i){var r=t.getElementsByTagName(i);return Array.isArray(r)?r:Array.from(r)}))},_cleanClasses:function(t){var e=this._classesToPreserve,i=(t.getAttribute("class")||"").split(/\\s+/).filter(function(r){return e.indexOf(r)!=-1}).join(" ");for(i?t.setAttribute("class",i):t.removeAttribute("class"),t=t.firstElementChild;t;t=t.nextElementSibling)this._cleanClasses(t)},_fixRelativeUris:function(t){var e=this._doc.baseURI,i=this._doc.documentURI;function r(s){if(e==i&&s.charAt(0)=="#")return s;try{return new URL(s,e).href}catch(h){}return s}var l=this._getAllNodesWithTag(t,["a"]);this._forEachNode(l,function(s){var h=s.getAttribute("href");if(h)if(h.indexOf("javascript:")===0)if(s.childNodes.length===1&&s.childNodes[0].nodeType===this.TEXT_NODE){var c=this._doc.createTextNode(s.textContent);s.parentNode.replaceChild(c,s)}else{for(var n=this._doc.createElement("span");s.firstChild;)n.appendChild(s.firstChild);s.parentNode.replaceChild(n,s)}else s.setAttribute("href",r(h))});var a=this._getAllNodesWithTag(t,["img","picture","figure","video","audio","source"]);this._forEachNode(a,function(s){var h=s.getAttribute("src"),c=s.getAttribute("poster"),n=s.getAttribute("srcset");if(h&&s.setAttribute("src",r(h)),c&&s.setAttribute("poster",r(c)),n){var u=n.replace(this.REGEXPS.srcsetUrl,function(m,b,N,v){return r(b)+(N||"")+v});s.setAttribute("srcset",u)}})},_simplifyNestedElements:function(t){for(var e=t;e;){if(e.parentNode&&["DIV","SECTION"].includes(e.tagName)&&!(e.id&&e.id.startsWith("readability"))){if(this._isElementWithoutContent(e)){e=this._removeAndGetNext(e);continue}else if(this._hasSingleTagInsideElement(e,"DIV")||this._hasSingleTagInsideElement(e,"SECTION")){for(var i=e.children[0],r=0;r<e.attributes.length;r++)i.setAttribute(e.attributes[r].name,e.attributes[r].value);e.parentNode.replaceChild(i,e),e=i;continue}}e=this._getNextNode(e)}},_getArticleTitle:function(){var t=this._doc,e="",i="";try{e=i=t.title.trim(),typeof e!="string"&&(e=i=this._getInnerText(t.getElementsByTagName("title")[0]))}catch(u){}var r=!1;function l(u){return u.split(/\\s+/).length}if(/ [\\|\\-\\\\\\/>\xBB] /.test(e))r=/ [\\\\\\/>\xBB] /.test(e),e=i.replace(/(.*)[\\|\\-\\\\\\/>\xBB] .*/gi,"$1"),l(e)<3&&(e=i.replace(/[^\\|\\-\\\\\\/>\xBB]*[\\|\\-\\\\\\/>\xBB](.*)/gi,"$1"));else if(e.indexOf(": ")!==-1){var a=this._concatNodeLists(t.getElementsByTagName("h1"),t.getElementsByTagName("h2")),s=e.trim(),h=this._someNode(a,function(u){return u.textContent.trim()===s});h||(e=i.substring(i.lastIndexOf(":")+1),l(e)<3?e=i.substring(i.indexOf(":")+1):l(i.substr(0,i.indexOf(":")))>5&&(e=i))}else if(e.length>150||e.length<15){var c=t.getElementsByTagName("h1");c.length===1&&(e=this._getInnerText(c[0]))}e=e.trim().replace(this.REGEXPS.normalize," ");var n=l(e);return n<=4&&(!r||n!=l(i.replace(/[\\|\\-\\\\\\/>\xBB]+/g,""))-1)&&(e=i),e},_prepDocument:function(){var t=this._doc;this._removeNodes(this._getAllNodesWithTag(t,["style"])),t.body&&this._replaceBrs(t.body),this._replaceNodeTags(this._getAllNodesWithTag(t,["font"]),"SPAN")},_nextNode:function(t){for(var e=t;e&&e.nodeType!=this.ELEMENT_NODE&&this.REGEXPS.whitespace.test(e.textContent);)e=e.nextSibling;return e},_replaceBrs:function(t){this._forEachNode(this._getAllNodesWithTag(t,["br"]),function(e){for(var i=e.nextSibling,r=!1;(i=this._nextNode(i))&&i.tagName=="BR";){r=!0;var l=i.nextSibling;i.parentNode.removeChild(i),i=l}if(r){var a=this._doc.createElement("p");for(e.parentNode.replaceChild(a,e),i=a.nextSibling;i;){if(i.tagName=="BR"){var s=this._nextNode(i.nextSibling);if(s&&s.tagName=="BR")break}if(!this._isPhrasingContent(i))break;var h=i.nextSibling;a.appendChild(i),i=h}for(;a.lastChild&&this._isWhitespace(a.lastChild);)a.removeChild(a.lastChild);a.parentNode.tagName==="P"&&this._setNodeTag(a.parentNode,"DIV")}})},_setNodeTag:function(t,e){if(this.log("_setNodeTag",t,e),this._docJSDOMParser)return t.localName=e.toLowerCase(),t.tagName=e.toUpperCase(),t;for(var i=t.ownerDocument.createElement(e);t.firstChild;)i.appendChild(t.firstChild);t.parentNode.replaceChild(i,t),t.readability&&(i.readability=t.readability);for(var r=0;r<t.attributes.length;r++)try{i.setAttribute(t.attributes[r].name,t.attributes[r].value)}catch(l){}return i},_prepArticle:function(t){this._cleanStyles(t),this._markDataTables(t),this._fixLazyImages(t),this._cleanConditionally(t,"form"),this._cleanConditionally(t,"fieldset"),this._clean(t,"object"),this._clean(t,"embed"),this._clean(t,"footer"),this._clean(t,"link"),this._clean(t,"aside");var e=this.DEFAULT_CHAR_THRESHOLD;this._forEachNode(t.children,function(i){this._cleanMatchedNodes(i,function(r,l){return this.REGEXPS.shareElements.test(l)&&r.textContent.length<e})}),this._clean(t,"iframe"),this._clean(t,"input"),this._clean(t,"textarea"),this._clean(t,"select"),this._clean(t,"button"),this._cleanHeaders(t),this._cleanConditionally(t,"table"),this._cleanConditionally(t,"ul"),this._cleanConditionally(t,"div"),this._replaceNodeTags(this._getAllNodesWithTag(t,["h1"]),"h2"),this._removeNodes(this._getAllNodesWithTag(t,["p"]),function(i){var r=i.getElementsByTagName("img").length,l=i.getElementsByTagName("embed").length,a=i.getElementsByTagName("object").length,s=i.getElementsByTagName("iframe").length,h=r+l+a+s;return h===0&&!this._getInnerText(i,!1)}),this._forEachNode(this._getAllNodesWithTag(t,["br"]),function(i){var r=this._nextNode(i.nextSibling);r&&r.tagName=="P"&&i.parentNode.removeChild(i)}),this._forEachNode(this._getAllNodesWithTag(t,["table"]),function(i){var r=this._hasSingleTagInsideElement(i,"TBODY")?i.firstElementChild:i;if(this._hasSingleTagInsideElement(r,"TR")){var l=r.firstElementChild;if(this._hasSingleTagInsideElement(l,"TD")){var a=l.firstElementChild;a=this._setNodeTag(a,this._everyNode(a.childNodes,this._isPhrasingContent)?"P":"DIV"),i.parentNode.replaceChild(a,i)}}})},_initializeNode:function(t){switch(t.readability={contentScore:0},t.tagName){case"DIV":t.readability.contentScore+=5;break;case"PRE":case"TD":case"BLOCKQUOTE":t.readability.contentScore+=3;break;case"ADDRESS":case"OL":case"UL":case"DL":case"DD":case"DT":case"LI":case"FORM":t.readability.contentScore-=3;break;case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":case"TH":t.readability.contentScore-=5;break}t.readability.contentScore+=this._getClassWeight(t)},_removeAndGetNext:function(t){var e=this._getNextNode(t,!0);return t.parentNode.removeChild(t),e},_getNextNode:function(t,e){if(!e&&t.firstElementChild)return t.firstElementChild;if(t.nextElementSibling)return t.nextElementSibling;do t=t.parentNode;while(t&&!t.nextElementSibling);return t&&t.nextElementSibling},_textSimilarity:function(t,e){var i=t.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean),r=e.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean);if(!i.length||!r.length)return 0;var l=r.filter(s=>!i.includes(s)),a=l.join(" ").length/r.join(" ").length;return 1-a},_checkByline:function(t,e){if(this._articleByline)return!1;if(t.getAttribute!==void 0)var i=t.getAttribute("rel"),r=t.getAttribute("itemprop");return(i==="author"||r&&r.indexOf("author")!==-1||this.REGEXPS.byline.test(e))&&this._isValidByline(t.textContent)?(this._articleByline=t.textContent.trim(),!0):!1},_getNodeAncestors:function(t,e){e=e||0;for(var i=0,r=[];t.parentNode&&(r.push(t.parentNode),!(e&&++i===e));)t=t.parentNode;return r},_grabArticle:function(t){this.log("**** grabArticle ****");var e=this._doc,i=t!==null;if(t=t||this._doc.body,!t)return this.log("No body found in document. Abort."),null;for(var r=t.innerHTML;;){this.log("Starting grabArticle loop");var l=this._flagIsActive(this.FLAG_STRIP_UNLIKELYS),a=[],s=this._doc.documentElement;let J=!0;for(;s;){s.tagName==="HTML"&&(this._articleLang=s.getAttribute("lang"));var h=s.className+" "+s.id;if(!this._isProbablyVisible(s)){this.log("Removing hidden node - "+h),s=this._removeAndGetNext(s);continue}if(s.getAttribute("aria-modal")=="true"&&s.getAttribute("role")=="dialog"){s=this._removeAndGetNext(s);continue}if(this._checkByline(s,h)){s=this._removeAndGetNext(s);continue}if(J&&this._headerDuplicatesTitle(s)){this.log("Removing header: ",s.textContent.trim(),this._articleTitle.trim()),J=!1,s=this._removeAndGetNext(s);continue}if(l){if(this.REGEXPS.unlikelyCandidates.test(h)&&!this.REGEXPS.okMaybeItsACandidate.test(h)&&!this._hasAncestorTag(s,"table")&&!this._hasAncestorTag(s,"code")&&s.tagName!=="BODY"&&s.tagName!=="A"){this.log("Removing unlikely candidate - "+h),s=this._removeAndGetNext(s);continue}if(this.UNLIKELY_ROLES.includes(s.getAttribute("role"))){this.log("Removing content with role "+s.getAttribute("role")+" - "+h),s=this._removeAndGetNext(s);continue}}if((s.tagName==="DIV"||s.tagName==="SECTION"||s.tagName==="HEADER"||s.tagName==="H1"||s.tagName==="H2"||s.tagName==="H3"||s.tagName==="H4"||s.tagName==="H5"||s.tagName==="H6")&&this._isElementWithoutContent(s)){s=this._removeAndGetNext(s);continue}if(this.DEFAULT_TAGS_TO_SCORE.indexOf(s.tagName)!==-1&&a.push(s),s.tagName==="DIV"){for(var c=null,n=s.firstChild;n;){var u=n.nextSibling;if(this._isPhrasingContent(n))c!==null?c.appendChild(n):this._isWhitespace(n)||(c=e.createElement("p"),s.replaceChild(c,n),c.appendChild(n));else if(c!==null){for(;c.lastChild&&this._isWhitespace(c.lastChild);)c.removeChild(c.lastChild);c=null}n=u}if(this._hasSingleTagInsideElement(s,"P")&&this._getLinkDensity(s)<.25){var m=s.children[0];s.parentNode.replaceChild(m,s),s=m,a.push(s)}else this._hasChildBlockElement(s)||(s=this._setNodeTag(s,"P"),a.push(s))}s=this._getNextNode(s)}var b=[];this._forEachNode(a,function(A){if(!(!A.parentNode||typeof A.parentNode.tagName=="undefined")){var T=this._getInnerText(A);if(!(T.length<25)){var K=this._getNodeAncestors(A,5);if(K.length!==0){var C=0;C+=1,C+=T.split(this.REGEXPS.commas).length,C+=Math.min(Math.floor(T.length/100),3),this._forEachNode(K,function(S,F){if(!(!S.tagName||!S.parentNode||typeof S.parentNode.tagName=="undefined")){if(typeof S.readability=="undefined"&&(this._initializeNode(S),b.push(S)),F===0)var X=1;else F===1?X=2:X=F*3;S.readability.contentScore+=C/X}})}}}});for(var N=[],v=0,y=b.length;v<y;v+=1){var E=b[v],d=E.readability.contentScore*(1-this._getLinkDensity(E));E.readability.contentScore=d,this.log("Candidate:",E,"with score "+d);for(var p=0;p<this._nbTopCandidates;p++){var x=N[p];if(!x||d>x.readability.contentScore){N.splice(p,0,E),N.length>this._nbTopCandidates&&N.pop();break}}}var o=N[0]||null,L=!1,g;if(o===null||o.tagName==="BODY"){for(o=e.createElement("DIV"),L=!0;t.firstChild;)this.log("Moving child out:",t.firstChild),o.appendChild(t.firstChild);t.appendChild(o),this._initializeNode(o)}else if(o){for(var I=[],P=1;P<N.length;P++)N[P].readability.contentScore/o.readability.contentScore>=.75&&I.push(this._getNodeAncestors(N[P]));var O=3;if(I.length>=O)for(g=o.parentNode;g.tagName!=="BODY";){for(var G=0,H=0;H<I.length&&G<O;H++)G+=Number(I[H].includes(g));if(G>=O){o=g;break}g=g.parentNode}o.readability||this._initializeNode(o),g=o.parentNode;for(var M=o.readability.contentScore,Q=M/3;g.tagName!=="BODY";){if(!g.readability){g=g.parentNode;continue}var V=g.readability.contentScore;if(V<Q)break;if(V>M){o=g;break}M=g.readability.contentScore,g=g.parentNode}for(g=o.parentNode;g.tagName!="BODY"&&g.children.length==1;)o=g,g=o.parentNode;o.readability||this._initializeNode(o)}var _=e.createElement("DIV");i&&(_.id="readability-content");var Z=Math.max(10,o.readability.contentScore*.2);g=o.parentNode;for(var U=g.children,w=0,j=U.length;w<j;w++){var f=U[w],R=!1;if(this.log("Looking at sibling node:",f,f.readability?"with score "+f.readability.contentScore:""),this.log("Sibling has score",f.readability?f.readability.contentScore:"Unknown"),f===o)R=!0;else{var $=0;if(f.className===o.className&&o.className!==""&&($+=o.readability.contentScore*.2),f.readability&&f.readability.contentScore+$>=Z)R=!0;else if(f.nodeName==="P"){var Y=this._getLinkDensity(f),z=this._getInnerText(f),k=z.length;(k>80&&Y<.25||k<80&&k>0&&Y===0&&z.search(/\\.( |$)/)!==-1)&&(R=!0)}}R&&(this.log("Appending node:",f),this.ALTER_TO_DIV_EXCEPTIONS.indexOf(f.nodeName)===-1&&(this.log("Altering sibling:",f,"to div."),f=this._setNodeTag(f,"DIV")),_.appendChild(f),U=g.children,w-=1,j-=1)}if(this._debug&&this.log("Article content pre-prep: "+_.innerHTML),this._prepArticle(_),this._debug&&this.log("Article content post-prep: "+_.innerHTML),L)o.id="readability-page-1",o.className="page";else{var B=e.createElement("DIV");for(B.id="readability-page-1",B.className="page";_.firstChild;)B.appendChild(_.firstChild);_.appendChild(B)}this._debug&&this.log("Article content after paging: "+_.innerHTML);var W=!0,D=this._getInnerText(_,!0).length;if(D<this._charThreshold)if(W=!1,t.innerHTML=r,this._flagIsActive(this.FLAG_STRIP_UNLIKELYS))this._removeFlag(this.FLAG_STRIP_UNLIKELYS),this._attempts.push({articleContent:_,textLength:D});else if(this._flagIsActive(this.FLAG_WEIGHT_CLASSES))this._removeFlag(this.FLAG_WEIGHT_CLASSES),this._attempts.push({articleContent:_,textLength:D});else if(this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY))this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY),this._attempts.push({articleContent:_,textLength:D});else{if(this._attempts.push({articleContent:_,textLength:D}),this._attempts.sort(function(A,T){return T.textLength-A.textLength}),!this._attempts[0].textLength)return null;_=this._attempts[0].articleContent,W=!0}if(W){var tt=[g,o].concat(this._getNodeAncestors(g));return this._someNode(tt,function(A){if(!A.tagName)return!1;var T=A.getAttribute("dir");return T?(this._articleDir=T,!0):!1}),_}}},_isValidByline:function(t){return typeof t=="string"||t instanceof String?(t=t.trim(),t.length>0&&t.length<100):!1},_unescapeHtmlEntities:function(t){if(!t)return t;var e=this.HTML_ESCAPE_MAP;return t.replace(/&(quot|amp|apos|lt|gt);/g,function(i,r){return e[r]}).replace(/&#(?:x([0-9a-z]{1,4})|([0-9]{1,4}));/gi,function(i,r,l){var a=parseInt(r||l,r?16:10);return String.fromCharCode(a)})},_getJSONLD:function(t){var e=this._getAllNodesWithTag(t,["script"]),i;return this._forEachNode(e,function(r){if(!i&&r.getAttribute("type")==="application/ld+json")try{var l=r.textContent.replace(/^\\s*<!\\[CDATA\\[|\\]\\]>\\s*$/g,""),a=JSON.parse(l);if(!a["@context"]||!a["@context"].match(/^https?\\:\\/\\/schema\\.org$/)||(!a["@type"]&&Array.isArray(a["@graph"])&&(a=a["@graph"].find(function(n){return(n["@type"]||"").match(this.REGEXPS.jsonLdArticleTypes)})),!a||!a["@type"]||!a["@type"].match(this.REGEXPS.jsonLdArticleTypes)))return;if(i={},typeof a.name=="string"&&typeof a.headline=="string"&&a.name!==a.headline){var s=this._getArticleTitle(),h=this._textSimilarity(a.name,s)>.75,c=this._textSimilarity(a.headline,s)>.75;c&&!h?i.title=a.headline:i.title=a.name}else typeof a.name=="string"?i.title=a.name.trim():typeof a.headline=="string"&&(i.title=a.headline.trim());a.author&&(typeof a.author.name=="string"?i.byline=a.author.name.trim():Array.isArray(a.author)&&a.author[0]&&typeof a.author[0].name=="string"&&(i.byline=a.author.filter(function(n){return n&&typeof n.name=="string"}).map(function(n){return n.name.trim()}).join(", "))),typeof a.description=="string"&&(i.excerpt=a.description.trim()),a.publisher&&typeof a.publisher.name=="string"&&(i.siteName=a.publisher.name.trim()),typeof a.datePublished=="string"&&(i.datePublished=a.datePublished.trim());return}catch(n){this.log(n.message)}}),i||{}},_getArticleMetadata:function(t){var e={},i={},r=this._doc.getElementsByTagName("meta"),l=/\\s*(article|dc|dcterm|og|twitter)\\s*:\\s*(author|creator|description|published_time|title|site_name)\\s*/gi,a=/^\\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\\s*[\\.:]\\s*)?(author|creator|description|title|site_name)\\s*$/i;return this._forEachNode(r,function(s){var h=s.getAttribute("name"),c=s.getAttribute("property"),n=s.getAttribute("content");if(n){var u=null,m=null;c&&(u=c.match(l),u&&(m=u[0].toLowerCase().replace(/\\s/g,""),i[m]=n.trim())),!u&&h&&a.test(h)&&(m=h,n&&(m=m.toLowerCase().replace(/\\s/g,"").replace(/\\./g,":"),i[m]=n.trim()))}}),e.title=t.title||i["dc:title"]||i["dcterm:title"]||i["og:title"]||i["weibo:article:title"]||i["weibo:webpage:title"]||i.title||i["twitter:title"],e.title||(e.title=this._getArticleTitle()),e.byline=t.byline||i["dc:creator"]||i["dcterm:creator"]||i.author,e.excerpt=t.excerpt||i["dc:description"]||i["dcterm:description"]||i["og:description"]||i["weibo:article:description"]||i["weibo:webpage:description"]||i.description||i["twitter:description"],e.siteName=t.siteName||i["og:site_name"],e.publishedTime=t.datePublished||i["article:published_time"]||null,e.title=this._unescapeHtmlEntities(e.title),e.byline=this._unescapeHtmlEntities(e.byline),e.excerpt=this._unescapeHtmlEntities(e.excerpt),e.siteName=this._unescapeHtmlEntities(e.siteName),e.publishedTime=this._unescapeHtmlEntities(e.publishedTime),e},_isSingleImage:function(t){return t.tagName==="IMG"?!0:t.children.length!==1||t.textContent.trim()!==""?!1:this._isSingleImage(t.children[0])},_unwrapNoscriptImages:function(t){var e=Array.from(t.getElementsByTagName("img"));this._forEachNode(e,function(r){for(var l=0;l<r.attributes.length;l++){var a=r.attributes[l];switch(a.name){case"src":case"srcset":case"data-src":case"data-srcset":return}if(/\\.(jpg|jpeg|png|webp)/i.test(a.value))return}r.parentNode.removeChild(r)});var i=Array.from(t.getElementsByTagName("noscript"));this._forEachNode(i,function(r){var l=t.createElement("div");if(l.innerHTML=r.innerHTML,!!this._isSingleImage(l)){var a=r.previousElementSibling;if(a&&this._isSingleImage(a)){var s=a;s.tagName!=="IMG"&&(s=a.getElementsByTagName("img")[0]);for(var h=l.getElementsByTagName("img")[0],c=0;c<s.attributes.length;c++){var n=s.attributes[c];if(n.value!==""&&(n.name==="src"||n.name==="srcset"||/\\.(jpg|jpeg|png|webp)/i.test(n.value))){if(h.getAttribute(n.name)===n.value)continue;var u=n.name;h.hasAttribute(u)&&(u="data-old-"+u),h.setAttribute(u,n.value)}}r.parentNode.replaceChild(l.firstElementChild,a)}}})},_removeScripts:function(t){this._removeNodes(this._getAllNodesWithTag(t,["script","noscript"]))},_hasSingleTagInsideElement:function(t,e){return t.children.length!=1||t.children[0].tagName!==e?!1:!this._someNode(t.childNodes,function(i){return i.nodeType===this.TEXT_NODE&&this.REGEXPS.hasContent.test(i.textContent)})},_isElementWithoutContent:function(t){return t.nodeType===this.ELEMENT_NODE&&t.textContent.trim().length==0&&(t.children.length==0||t.children.length==t.getElementsByTagName("br").length+t.getElementsByTagName("hr").length)},_hasChildBlockElement:function(t){return this._someNode(t.childNodes,function(e){return this.DIV_TO_P_ELEMS.has(e.tagName)||this._hasChildBlockElement(e)})},_isPhrasingContent:function(t){return t.nodeType===this.TEXT_NODE||this.PHRASING_ELEMS.indexOf(t.tagName)!==-1||(t.tagName==="A"||t.tagName==="DEL"||t.tagName==="INS")&&this._everyNode(t.childNodes,this._isPhrasingContent)},_isWhitespace:function(t){return t.nodeType===this.TEXT_NODE&&t.textContent.trim().length===0||t.nodeType===this.ELEMENT_NODE&&t.tagName==="BR"},_getInnerText:function(t,e){e=typeof e=="undefined"?!0:e;var i=t.textContent.trim();return e?i.replace(this.REGEXPS.normalize," "):i},_getCharCount:function(t,e){return e=e||",",this._getInnerText(t).split(e).length-1},_cleanStyles:function(t){if(!(!t||t.tagName.toLowerCase()==="svg")){for(var e=0;e<this.PRESENTATIONAL_ATTRIBUTES.length;e++)t.removeAttribute(this.PRESENTATIONAL_ATTRIBUTES[e]);this.DEPRECATED_SIZE_ATTRIBUTE_ELEMS.indexOf(t.tagName)!==-1&&(t.removeAttribute("width"),t.removeAttribute("height"));for(var i=t.firstElementChild;i!==null;)this._cleanStyles(i),i=i.nextElementSibling}},_getLinkDensity:function(t){var e=this._getInnerText(t).length;if(e===0)return 0;var i=0;return this._forEachNode(t.getElementsByTagName("a"),function(r){var l=r.getAttribute("href"),a=l&&this.REGEXPS.hashUrl.test(l)?.3:1;i+=this._getInnerText(r).length*a}),i/e},_getClassWeight:function(t){if(!this._flagIsActive(this.FLAG_WEIGHT_CLASSES))return 0;var e=0;return typeof t.className=="string"&&t.className!==""&&(this.REGEXPS.negative.test(t.className)&&(e-=25),this.REGEXPS.positive.test(t.className)&&(e+=25)),typeof t.id=="string"&&t.id!==""&&(this.REGEXPS.negative.test(t.id)&&(e-=25),this.REGEXPS.positive.test(t.id)&&(e+=25)),e},_clean:function(t,e){var i=["object","embed","iframe"].indexOf(e)!==-1;this._removeNodes(this._getAllNodesWithTag(t,[e]),function(r){if(i){for(var l=0;l<r.attributes.length;l++)if(this._allowedVideoRegex.test(r.attributes[l].value))return!1;if(r.tagName==="object"&&this._allowedVideoRegex.test(r.innerHTML))return!1}return!0})},_hasAncestorTag:function(t,e,i,r){i=i||3,e=e.toUpperCase();for(var l=0;t.parentNode;){if(i>0&&l>i)return!1;if(t.parentNode.tagName===e&&(!r||r(t.parentNode)))return!0;t=t.parentNode,l++}return!1},_getRowAndColumnCount:function(t){for(var e=0,i=0,r=t.getElementsByTagName("tr"),l=0;l<r.length;l++){var a=r[l].getAttribute("rowspan")||0;a&&(a=parseInt(a,10)),e+=a||1;for(var s=0,h=r[l].getElementsByTagName("td"),c=0;c<h.length;c++){var n=h[c].getAttribute("colspan")||0;n&&(n=parseInt(n,10)),s+=n||1}i=Math.max(i,s)}return{rows:e,columns:i}},_markDataTables:function(t){for(var e=t.getElementsByTagName("table"),i=0;i<e.length;i++){var r=e[i],l=r.getAttribute("role");if(l=="presentation"){r._readabilityDataTable=!1;continue}var a=r.getAttribute("datatable");if(a=="0"){r._readabilityDataTable=!1;continue}var s=r.getAttribute("summary");if(s){r._readabilityDataTable=!0;continue}var h=r.getElementsByTagName("caption")[0];if(h&&h.childNodes.length>0){r._readabilityDataTable=!0;continue}var c=["col","colgroup","tfoot","thead","th"],n=function(m){return!!r.getElementsByTagName(m)[0]};if(c.some(n)){this.log("Data table because found data-y descendant"),r._readabilityDataTable=!0;continue}if(r.getElementsByTagName("table")[0]){r._readabilityDataTable=!1;continue}var u=this._getRowAndColumnCount(r);if(u.rows>=10||u.columns>4){r._readabilityDataTable=!0;continue}r._readabilityDataTable=u.rows*u.columns>10}},_fixLazyImages:function(t){this._forEachNode(this._getAllNodesWithTag(t,["img","picture","figure"]),function(e){if(e.src&&this.REGEXPS.b64DataUrl.test(e.src)){var i=this.REGEXPS.b64DataUrl.exec(e.src);if(i[1]==="image/svg+xml")return;for(var r=!1,l=0;l<e.attributes.length;l++){var a=e.attributes[l];if(a.name!=="src"&&/\\.(jpg|jpeg|png|webp)/i.test(a.value)){r=!0;break}}if(r){var s=e.src.search(/base64\\s*/i)+7,h=e.src.length-s;h<133&&e.removeAttribute("src")}}if(!((e.src||e.srcset&&e.srcset!="null")&&e.className.toLowerCase().indexOf("lazy")===-1)){for(var c=0;c<e.attributes.length;c++)if(a=e.attributes[c],!(a.name==="src"||a.name==="srcset"||a.name==="alt")){var n=null;if(/\\.(jpg|jpeg|png|webp)\\s+\\d/.test(a.value)?n="srcset":/^\\s*\\S+\\.(jpg|jpeg|png|webp)\\S*\\s*$/.test(a.value)&&(n="src"),n){if(e.tagName==="IMG"||e.tagName==="PICTURE")e.setAttribute(n,a.value);else if(e.tagName==="FIGURE"&&!this._getAllNodesWithTag(e,["img","picture"]).length){var u=this._doc.createElement("img");u.setAttribute(n,a.value),e.appendChild(u)}}}}})},_getTextDensity:function(t,e){var i=this._getInnerText(t,!0).length;if(i===0)return 0;var r=0,l=this._getAllNodesWithTag(t,e);return this._forEachNode(l,a=>r+=this._getInnerText(a,!0).length),r/i},_cleanConditionally:function(t,e){this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)&&this._removeNodes(this._getAllNodesWithTag(t,[e]),function(i){var r=function(g){return g._readabilityDataTable},l=e==="ul"||e==="ol";if(!l){var a=0,s=this._getAllNodesWithTag(i,["ul","ol"]);this._forEachNode(s,g=>a+=this._getInnerText(g).length),l=a/this._getInnerText(i).length>.9}if(e==="table"&&r(i)||this._hasAncestorTag(i,"table",-1,r)||this._hasAncestorTag(i,"code"))return!1;var h=this._getClassWeight(i);this.log("Cleaning Conditionally",i);var c=0;if(h+c<0)return!0;if(this._getCharCount(i,",")<10){for(var n=i.getElementsByTagName("p").length,u=i.getElementsByTagName("img").length,m=i.getElementsByTagName("li").length-100,b=i.getElementsByTagName("input").length,N=this._getTextDensity(i,["h1","h2","h3","h4","h5","h6"]),v=0,y=this._getAllNodesWithTag(i,["object","embed","iframe"]),E=0;E<y.length;E++){for(var d=0;d<y[E].attributes.length;d++)if(this._allowedVideoRegex.test(y[E].attributes[d].value))return!1;if(y[E].tagName==="object"&&this._allowedVideoRegex.test(y[E].innerHTML))return!1;v++}var p=this._getLinkDensity(i),x=this._getInnerText(i).length,o=u>1&&n/u<.5&&!this._hasAncestorTag(i,"figure")||!l&&m>n||b>Math.floor(n/3)||!l&&N<.9&&x<25&&(u===0||u>2)&&!this._hasAncestorTag(i,"figure")||!l&&h<25&&p>.2||h>=25&&p>.5||v===1&&x<75||v>1;if(l&&o){for(var L=0;L<i.children.length;L++)if(i.children[L].children.length>1)return o;let g=i.getElementsByTagName("li").length;if(u==g)return!1}return o}return!1})},_cleanMatchedNodes:function(t,e){for(var i=this._getNextNode(t,!0),r=this._getNextNode(t);r&&r!=i;)e.call(this,r,r.className+" "+r.id)?r=this._removeAndGetNext(r):r=this._getNextNode(r)},_cleanHeaders:function(t){let e=this._getAllNodesWithTag(t,["h1","h2"]);this._removeNodes(e,function(i){let r=this._getClassWeight(i)<0;return r&&this.log("Removing header with low class weight:",i),r})},_headerDuplicatesTitle:function(t){if(t.tagName!="H1"&&t.tagName!="H2")return!1;var e=this._getInnerText(t,!1);return this.log("Evaluating similarity of header:",e,this._articleTitle),this._textSimilarity(this._articleTitle,e)>.75},_flagIsActive:function(t){return(this._flags&t)>0},_removeFlag:function(t){this._flags=this._flags&~t},_isProbablyVisible:function(t){return(!t.style||t.style.display!="none")&&(!t.style||t.style.visibility!="hidden")&&!t.hasAttribute("hidden")&&(!t.hasAttribute("aria-hidden")||t.getAttribute("aria-hidden")!="true"||t.className&&t.className.indexOf&&t.className.indexOf("fallback-image")!==-1)},parse:function(){if(this._maxElemsToParse>0){var t=this._doc.getElementsByTagName("*").length;if(t>this._maxElemsToParse)throw new Error("Aborting parsing document; "+t+" elements found")}this._unwrapNoscriptImages(this._doc);var e=this._disableJSONLD?{}:this._getJSONLD(this._doc);this._removeScripts(this._doc),this._prepDocument();var i=this._getArticleMetadata(e);this._articleTitle=i.title;var r=this._grabArticle();if(!r)return null;if(this.log("Grabbed: "+r.innerHTML),this._postProcessContent(r),!i.excerpt){var l=r.getElementsByTagName("p");l.length>0&&(i.excerpt=l[0].textContent.trim())}var a=r.textContent;return{title:this._articleTitle,byline:i.byline||this._articleByline,dir:this._articleDir,lang:this._articleLang,content:this._serializer(r),textContent:a,length:a.length,excerpt:i.excerpt,siteName:i.siteName||this._articleSiteName,publishedTime:i.publishedTime}}};typeof module=="object"&&(module.exports=q);\n';var le=require("@agent-infra/logger");var te=m(require("turndown"),1),re=require("turndown-plugin-gfm"),ie=require("@agent-infra/logger"),ne=m(require("user-agents"),1),De=i=>{try{return new URL(i)}catch{return null}},se=i=>{let t=De(i);if(!t)return!0;let{hostname:e}=t;return["reddit.com","www.reddit.com","x.com","twitter.com","www.twitter.com","youtube.com","www.youtube.com"].includes(e)};async function Be(i){let t=new ne.default({deviceCategory:"desktop"}).toString();await i.setBypassCSP(!0),await i.setUserAgent(t),await i.evaluate(()=>{Object.defineProperty(navigator,"webdriver",{get:()=>{}}),Object.defineProperty(navigator,"languages",{get:()=>["en-US","en"]}),Object.defineProperty(navigator,"plugins",{get:()=>[{},{},{},{},{}]}),Object.defineProperty(navigator,"headless",{get:()=>!1});let e=window.navigator.permissions.query;window.navigator.permissions.query=r=>r.name==="notifications"?Promise.resolve({state:Notification.permission}):e(r)})}async function $(i){await Be(i),await i.setRequestInterception(!0),i.on("request",t=>t.resourceType()!=="document"?t.abort():t.isNavigationRequest()?t.continue():t.abort())}function ae(i,t){let e=new Function("module",`${t}
3
- return module.exports`)({}),r=i.document;r.querySelectorAll("script,noscript,style,link,svg,img,video,iframe,canvas,.reflist").forEach(s=>s.remove());let n=new e(r).parse(),a=n?.content||"",o=r.title;return{content:a,title:n?.title||o}}function oe(i,t={}){if(!i)return"";try{let{codeBlockStyle:e="fenced",headingStyle:r="atx",emDelimiter:n="*",strongDelimiter:a="**",gfmExtension:o=!0}=t,s=new te.default({codeBlockStyle:e,headingStyle:r,emDelimiter:n,strongDelimiter:a});return o&&s.use(re.gfm),s.turndown(i)}catch(e){return ie.defaultLogger.error("Error converting HTML to Markdown:",e),i}}var L=class{queue=[];concurrency;running=0;results=[];constructor(t=1){this.concurrency=t}add(t){return new Promise((e,r)=>{this.queue.push(async()=>{try{let n=await t();return e(n),n}catch(n){throw r(n),n}}),this.run()})}async run(){if(this.running>=this.concurrency||this.queue.length===0)return;this.running++;let t=this.queue.shift();try{let e=await t();this.results.push(e)}catch{}finally{this.running--,this.run()}}async waitAll(){for(;this.running>0||this.queue.length>0;)await new Promise(t=>setTimeout(t,100));return this.results}};var v=class{getSearchUrl(t,e){return`https://www.bing.com/search?${new URLSearchParams({q:`${e.excludeDomains&&e.excludeDomains.length>0?`${e.excludeDomains.map(n=>`-site:${n}`).join(" ")} `:""}${t}`,count:`${e.count||10}`}).toString()}`}extractSearchResults(t){let e=[],r=t.document,n=o=>{try{return new URL(o),!0}catch{return!1}},a=o=>{let s=o.cloneNode(!0);return s.querySelectorAll("h2").forEach(l=>l.remove()),s.querySelectorAll(".b_attribution").forEach(l=>l.remove()),s.querySelectorAll("script, style").forEach(l=>l.remove()),Array.from(s.querySelectorAll("*")).filter(l=>l.textContent?.trim()).map(l=>l.textContent?.trim()).filter(Boolean).reduce((l,p)=>(l.some(b=>b.includes(p)||p.includes(b))||l.push(p),l),[]).join(" ").trim().replace(/\s+/g," ")};try{r.querySelectorAll(".b_algo").forEach(s=>{let u=s.querySelector("h2"),c=s.querySelector("h2 a")?.getAttribute("href"),g=a(s);if(!c||!n(c))return;let l={title:u?.textContent||"",snippet:g,url:c,content:""};!l.title||!l.url||e.push(l)})}catch(o){throw console.error("Error extracting search results from Bing:",o),o}return e}async waitForSearchResults(t,e){await t.waitForSelector("#b_results",{timeout:e??1e4})}};var P=class{getSearchUrl(t,e){let r=e.excludeDomains&&e.excludeDomains.length>0?e.excludeDomains.map(a=>`-site:${a}`).join(" "):"";return`https://www.baidu.com/s?${new URLSearchParams({wd:r?`${r} ${t}`:t,rn:`${e.count||10}`}).toString()}`}extractSearchResults(t){let e=[],r=t.document;try{r.querySelectorAll(".result").forEach(a=>{let o=a.querySelector(".t a"),s=o?.getAttribute("href"),u=a.querySelector(".c-span-last .content-right_2s-H4");if(!s)return;let h={title:o?.textContent||"",url:s,snippet:u?.textContent||"",content:""};!h.title||!h.url||e.push(h)})}catch(n){console.error("Error extracting search results from Baidu:",n)}return e}async waitForSearchResults(t,e){await t.waitForSelector("#page",{timeout:e??1e4})}};var C=class{getSearchUrl(t,e){let{count:r=10,excludeDomains:n=[]}=e,a=n&&n.length>0?n.map(s=>`-site:${s}`).join(" "):"";return`https://www.sogou.com/web?${new URLSearchParams({query:`${a?`${a} `:""}${t}`,num:`${r}`}).toString()}`}extractSearchResults(t){let e=[],r=t.document,n=s=>{try{return new URL(s),!0}catch{return!1}},a="https://www.sogou.com",o={results:".results .vrwrap",resultTitle:".vr-title",resultLink:".vr-title > a",resultSnippet:[".star-wiki",".fz-mid",".attribute-centent"],resultSnippetExcluded:[".text-lightgray",".zan-box",".tag-website"],related:"#main .vrwrap.middle-better-hintBox .hint-mid"};try{r.querySelectorAll(o.results).forEach(u=>{let h=u.querySelector(o.resultTitle),c=u.querySelector(o.resultLink)?.getAttribute("href"),l=o.resultSnippet.map(b=>{let d=u.cloneNode(!0);return o.resultSnippetExcluded.forEach(B=>{d.querySelector(B)?.remove()}),d.querySelector(b)?.textContent?.trim()||""}).filter(Boolean).join(" ").replace(/\s+/g," ").trim();if(c?.includes("http")||(c=`${a}${c}`),!c?.trim()||!n(c))return;let p={title:h?.textContent?.trim()||"",url:c,snippet:l,content:""};!p.title||!p.url||e.push(p)})}catch(s){let u=s instanceof Error?s.message:String(s);throw console.error("Error extracting search results from Sogou:",u),s}return e}async waitForSearchResults(t,e){await t.waitForSelector("#pagebar_container",{timeout:e??1e4})}};var R=class{getSearchUrl(t,e){let r=new URLSearchParams({q:`${e.excludeDomains&&e.excludeDomains.length>0?`${e.excludeDomains.map(n=>`-site:${n}`).join(" ")} `:""}${t}`,num:`${e.count||10}`});return r.set("udm","14"),`https://www.google.com/search?${r.toString()}`}extractSearchResults(t){let e=[],r=t.document,n=o=>{try{return new URL(o),!0}catch{return!1}},a=o=>{let s=o.cloneNode(!0);return s.querySelectorAll("h3").forEach(l=>l.remove()),s.querySelectorAll("cite").forEach(l=>l.remove()),s.querySelectorAll("script, style").forEach(l=>l.remove()),Array.from(s.querySelectorAll("*")).filter(l=>l.textContent?.trim()).map(l=>l.textContent?.trim()).filter(Boolean).reduce((l,p)=>(l.some(b=>b.includes(p)||p.includes(b))||l.push(p),l),[]).join(" ").trim().replace(/\s+/g," ")};try{r.querySelectorAll(".tF2Cxc").forEach(s=>{let u=s.querySelector("h3"),c=s.querySelector("a")?.getAttribute("href"),g=a(s.parentElement||s);if(!c||!n(c))return;let l={title:u?.textContent||"",url:c,snippet:g,content:""};!l.title||!l.url||e.push(l)})}catch(o){console.error(o)}return e}async waitForSearchResults(t,e){await t.waitForSelector("#search",{timeout:e??1e4})}};function F(i){switch(i){case"bing":return new v;case"baidu":return new P;case"sogou":return new C;case"google":return new R;default:return new v}}var O=class{constructor(t={}){this.config=t;this.logger=t?.logger??le.defaultLogger,this.browser=t.browser??new x({logger:this.logger}),this.defaultEngine=t.defaultEngine??"bing"}logger;browser;isBrowserOpen=!1;defaultEngine;async perform(t){this.logger.info("Starting search with options:",t);let e=Array.isArray(t.query)?t.query:[t.query],r=t.excludeDomains||[],n=t.count&&Math.max(3,Math.floor(t.count/e.length)),a=t.engine||this.defaultEngine;try{this.isBrowserOpen?this.logger.info("Using existing browser instance"):(this.logger.info("Launching browser"),await this.browser.launch(this.config.browserOptions),this.isBrowserOpen=!0);let o=new L(t.concurrency||15),s=new Set,u=await Promise.all(e.map(h=>this.search(this.browser,{query:h,count:n,queue:o,visitedUrls:s,excludeDomains:r,truncate:t.truncate,needVisitedUrls:t.needVisitedUrls,engine:a})));return this.logger.success("Search completed successfully"),u.flat()}catch(o){return this.logger.error("Search failed:",o),[]}finally{!t.keepBrowserOpen&&this.isBrowserOpen&&await this.closeBrowser()}}async closeBrowser(){this.isBrowserOpen&&(this.logger.info("Closing browser"),await this.browser.close(),this.isBrowserOpen=!1)}async search(t,e){let r=F(e.engine),n=r.getSearchUrl(e.query,{count:e.count,excludeDomains:e.excludeDomains});this.logger.info(`Searching with ${e.engine} engine: ${n}`);let a=await t.evaluateOnNewPage({url:n,waitForOptions:{waitUntil:"networkidle2"},pageFunction:r.extractSearchResults,pageFunctionParams:[],beforePageLoad:async s=>{await $(s)},afterPageLoad:async s=>{r.waitForSearchResults&&await r.waitForSearchResults(s,1e4)}});return this.logger.info(`Fetched ${a?.length??0} links`),a=a?.filter(s=>e.visitedUrls.has(s.url)?!1:(e.visitedUrls.add(s.url),!se(s.url)))||[],a.length?(await Promise.allSettled(e.needVisitedUrls?a.map(s=>e.queue.add(()=>this.visitLink(this.browser,s))):a)).map(s=>s.status==="rejected"||!s.value?null:{...s.value,content:e.truncate?s.value.content.slice(0,e.truncate):s.value.content}).filter(s=>s!==null):(this.logger.info("No valid links found"),[])}async visitLink(t,e){try{this.logger.info("Visiting link:",e.url);let r=await t.evaluateOnNewPage({url:e.url,pageFunction:ae,pageFunctionParams:[ee],beforePageLoad:async n=>{await $(n)}});if(r){let n=oe(r.content);return{...r,url:e.url,content:n,snippet:e.snippet}}}catch(r){this.logger.error("Failed to visit link:",r)}}};var ue=require("@agent-infra/logger"),ce=new ue.ConsoleLogger("[LocalSearch]");async function he(i){let{query:t,limit:e=10}=i,{engines:r="all"}=i,n=new O({logger:ce,browserOptions:{headless:!0}});r==="all"&&(r="bing,google,baidu,sogou");try{let a=r.split(",");if(a.length===0)throw new Error("engines is required");let o=[];for(let s of a){let u=await n.perform({query:t,count:e,engine:s,needVisitedUrls:!1});if(u.length>0){o.push(...u);break}}return ce.info(`Found ${o.length} results for ${t}`,o),{results:o,success:!0}}catch(a){let o=a instanceof Error?a.message:"Local search error.";throw process.stdout.write(o),a}finally{await n.closeBrowser()}}var ge={name:"one_search",description:"Search and retrieve content from web pages. Returns SERP results by default (url, title, description).",inputSchema:{type:"object",properties:{query:{type:"string",description:"Search query string"},limit:{type:"number",description:"Maximum number of results to return (default: 10)"},language:{type:"string",description:"Language code for search results (default: auto)"},categories:{type:"string",enum:["general","news","images","videos","it","science","map","music","files","social_media"],description:"Categories to search for (default: general)"},timeRange:{type:"string",description:"Time range for search results (default: all)",enum:["all","day","week","month","year"]}},required:["query"]}},pe={name:"one_map",description:"Discover URLs from a starting point. Can use both sitemap.xml and HTML link discovery.",inputSchema:{type:"object",properties:{url:{type:"string",description:"Starting URL for URL discovery"},search:{type:"string",description:"Optional search term to filter URLs"},ignoreSitemap:{type:"boolean",description:"Skip sitemap.xml discovery and only use HTML links"},sitemapOnly:{type:"boolean",description:"Only use sitemap.xml for discovery, ignore HTML links"},includeSubdomains:{type:"boolean",description:"Include URLs from subdomains in results"},limit:{type:"number",description:"Maximum number of URLs to return"}},required:["url"]}},de={name:"one_scrape",description:"Scrape a single webpage with advanced options for content extraction. Supports various formats including markdown, HTML, and screenshots. Can execute custom actions like clicking or scrolling before scraping.",inputSchema:{type:"object",properties:{url:{type:"string",description:"The URL to scrape"},formats:{type:"array",items:{type:"string",enum:["markdown","html","rawHtml","screenshot","links","screenshot@fullPage","extract"]},description:"Content formats to extract (default: ['markdown'])"},onlyMainContent:{type:"boolean",description:"Extract only the main content, filtering out navigation, footers, etc."},includeTags:{type:"array",items:{type:"string"},description:"HTML tags to specifically include in extraction"},excludeTags:{type:"array",items:{type:"string"},description:"HTML tags to exclude from extraction"},waitFor:{type:"number",description:"Time in milliseconds to wait for dynamic content to load"},timeout:{type:"number",description:"Maximum time in milliseconds to wait for the page to load"},actions:{type:"array",items:{type:"object",properties:{type:{type:"string",enum:["wait","click","screenshot","write","press","scroll","scrape","executeJavascript"],description:"Type of action to perform"},selector:{type:"string",description:"CSS selector for the target element"},milliseconds:{type:"number",description:"Time to wait in milliseconds (for wait action)"},text:{type:"string",description:"Text to write (for write action)"},key:{type:"string",description:"Key to press (for press action)"},direction:{type:"string",enum:["up","down"],description:"Scroll direction"},script:{type:"string",description:"JavaScript code to execute"},fullPage:{type:"boolean",description:"Take full page screenshot"}},required:["type"]},description:"List of actions to perform before scraping"},extract:{type:"object",properties:{schema:{type:"object",description:"Schema for structured data extraction"},systemPrompt:{type:"string",description:"System prompt for LLM extraction"},prompt:{type:"string",description:"User prompt for LLM extraction"}},description:"Configuration for structured data extraction"},mobile:{type:"boolean",description:"Use mobile viewport"},skipTlsVerification:{type:"boolean",description:"Skip TLS certificate verification"},removeBase64Images:{type:"boolean",description:"Remove base64 encoded images from output"},location:{type:"object",properties:{country:{type:"string",description:"Country code for geolocation"},languages:{type:"array",items:{type:"string"},description:"Language codes for content"}},description:"Location settings for scraping"}},required:["url"]}},me={name:"one_extract",description:"Extract structured information from web pages using LLM. Supports both cloud AI and self-hosted LLM extraction.",inputSchema:{type:"object",properties:{urls:{type:"array",items:{type:"string"},description:"List of URLs to extract information from"},prompt:{type:"string",description:"Prompt for the LLM extraction"},systemPrompt:{type:"string",description:"System prompt for LLM extraction"},schema:{type:"object",description:"JSON schema for structured data extraction"},allowExternalLinks:{type:"boolean",description:"Allow extraction from external links"},enableWebSearch:{type:"boolean",description:"Enable web search for additional context"},includeSubdomains:{type:"boolean",description:"Include subdomains in extraction"}},required:["urls"]}};var _e=m(require("@mendable/firecrawl-js"),1),Se=m(require("@dotenvx/dotenvx"),1),I=require("duck-duck-scrape");Se.default.config();var ke=process.env.SEARCH_API_URL,T=process.env.SEARCH_API_KEY,fe=process.env.SEARCH_PROVIDER??"local",Ue=process.env.SAFE_SEARCH??0,Me=process.env.LIMIT??10,$e=process.env.CATEGORIES??"general",Fe=process.env.ENGINES??"all",Ge=process.env.FORMAT??"json",qe=process.env.LANGUAGE??"auto",He=process.env.TIME_RANGE??"",je=process.env.TIMEOUT??1e4,We=process.env.FIRECRAWL_API_KEY,ye=process.env.FIRECRAWL_API_URL,Ee=new _e.default({apiKey:We??"",...ye?{apiUrl:ye}:{}}),f=new be.Server({name:"one-search-mcp",version:"0.0.1"},{capabilities:{tools:{},logging:{}}}),w={limit:Number(Me),categories:$e,format:Ge,safesearch:Ue,language:qe,engines:Fe,time_range:He,timeout:je};f.setRequestHandler(D.ListToolsRequestSchema,async()=>({tools:[ge,me,de,pe]}));f.setRequestHandler(D.CallToolRequestSchema,async i=>{let t=Date.now();try{let{name:e,arguments:r}=i.params;if(!r)throw new Error("No arguments provided");switch(f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Received request for tool: [${e}]`}),e){case"one_search":{if(!Ye(r))throw new Error(`Invalid arguments for tool: [${e}]`);try{let{results:n,success:a}=await Ve({...r,apiKey:T??"",apiUrl:ke});if(!a)throw new Error("Failed to search");return{content:[{type:"text",text:n.map(s=>`Title: ${s.title}
2
+ "use strict";var fe=Object.create;var D=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var be=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var j=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Se(e))!ye.call(o,s)&&s!==t&&D(o,s,{get:()=>e[s],enumerable:!(r=we(e,s))||r.enumerable});return o};var d=(o,e,t)=>(t=o!=null?fe(be(o)):{},j(e||!o||!o.__esModule?D(t,"default",{value:o,enumerable:!0}):t,o)),xe=o=>j(D({},"__esModule",{value:!0}),o);var Fe={};module.exports=xe(Fe);var le=require("@modelcontextprotocol/sdk/server/mcp.js"),ue=require("@modelcontextprotocol/sdk/server/stdio.js");async function N(o){let{query:e,limit:t=10,safeSearch:r=0,page:s=1,apiUrl:i="https://api.bing.microsoft.com/v7.0/search",apiKey:a,language:p}=o,c=["Off","Moderate","Strict"];if(!a)throw new Error("Bing API key is required");let u={q:e,count:t,offset:(s-1)*t,mkt:p,safeSearch:c[r]};try{let l=new URLSearchParams;Object.entries(u).forEach(([h,C])=>{C!==void 0&&l.set(h,C.toString())});let g=await fetch(`${i}?${l}`,{method:"GET",headers:{"Content-Type":"application/json","Ocp-Apim-Subscription-Key":a}});if(!g.ok)throw new Error(`Bing search error: ${g.status} ${g.statusText}`);return{results:(await g.json()).webPages?.value?.map(h=>({title:h.name,snippet:h.snippet,url:h.url,source:h.siteName,thumbnailUrl:h.thumbnailUrl,language:h.language,image:null,video:null,engine:"bing"}))??[],success:!0}}catch(l){let g=l instanceof Error?l.message:"Bing search error.";throw process.stdout.write(g),l}}var A=d(require("duck-duck-scrape"),1),W=d(require("async-retry"),1);async function K(o){try{let{query:e,timeout:t=1e4,safeSearch:r=A.SafeSearchType.OFF,retry:s={retries:3},...i}=o,a=await(0,W.default)(()=>A.search(e,{...i,safeSearch:r},{response_timeout:t}),s);return{results:(a?{noResults:a.noResults,vqd:a.vqd,results:a.results}:{noResults:!0,vqd:"",results:[]}).results.map(c=>({title:c.title,snippet:c.description,url:c.url,source:c.hostname,image:null,video:null,engine:"duckduckgo"})),success:!0}}catch(e){let t=e instanceof Error?e.message:"DuckDuckGo search error.";throw process.stdout.write(t),e}}var V=d(require("url"),1);async function z(o){try{let{query:e,page:t=1,limit:r=10,categories:s="general",engines:i="all",safeSearch:a=0,format:p="json",language:c="auto",timeRange:u="",timeout:l=1e4,apiKey:g,apiUrl:S}=o;if(!S)throw new Error("SearxNG API URL is required");let _=new AbortController,G=setTimeout(()=>_.abort(),Number(l)),h={q:e,pageno:t,categories:s,format:p,safesearch:a,language:c,engines:i,time_range:u},C=`${S}/search`,ge=V.default.format({query:h}),B={"Content-Type":"application/json"};g&&(B.Authorization=`Bearer ${g}`);let me=await fetch(`${C}${ge}`,{method:"POST",headers:B,signal:_.signal});clearTimeout(G);let H=await me.json();return H.results?{results:H.results.slice(0,r).map(m=>{let he=m.img_src?{thumbnail:m.thumbnail_src,src:m.img_src}:null,de=m.iframe_src?{thumbnail:m.thumbnail_src,src:m.iframe_src}:null;return{title:m.title,snippet:m.content,url:m.url,source:m.source,image:he,video:de,engine:m.engine}}),success:!0}:{results:[],success:!1}}catch(e){let t=e instanceof Error?e.message:"Searxng search error.";throw process.stdout.write(t),e}}var J=require("@tavily/core");async function Y(o){let{query:e,limit:t=10,categories:r="general",timeRange:s,apiKey:i}=o;if(!i)throw new Error("Tavily API key is required");try{let a=(0,J.tavily)({apiKey:i}),p={topic:r,timeRange:s,maxResults:t};return{results:(await a.search(e,p)).results.map(l=>({title:l.title,url:l.url,snippet:l.content,engine:"tavily"})),success:!0}}catch(a){let p=a instanceof Error?a.message:"Tavily search error.";throw process.stdout.write(p),a}}var Z=require("agent-browser/dist/browser.js"),ee=d(require("turndown"),1),te=require("turndown-plugin-gfm"),R=d(require("cheerio"),1);var v=d(require("fs"),1),F=d(require("path"),1),X=d(require("os"),1);var Q=d(require("pino"),1),x=class{logger;constructor(e){this.logger=(0,Q.default)({name:e||"one-search-mcp",level:process.env.LOG_LEVEL||"info",transport:process.env.NODE_ENV==="development"?{target:"pino-pretty",options:{colorize:!0,translateTime:"SYS:standard",ignore:"pid,hostname"}}:void 0},process.stderr)}logWithLevel(e,t,...r){r.length>0?this.logger[e]({data:r},t):this.logger[e](t)}info(e,...t){this.logWithLevel("info",e,...t)}error(e,...t){this.logWithLevel("error",e,...t)}success(e,...t){t.length>0?this.logger.info({level:"success",data:t},e):this.logger.info({level:"success"},e)}warn(e,...t){this.logWithLevel("warn",e,...t)}log(e,...t){this.logWithLevel("info",e,...t)}},P=new x;var $=class{logger;constructor(e){this.logger=e??P}get browsers(){let e=X.homedir(),t=process.env.LOCALAPPDATA;return[{name:"Chromium",executable:{win32:"C:\\Program Files\\Chromium\\Application\\chrome.exe",darwin:"/Applications/Chromium.app/Contents/MacOS/Chromium",linux:"/usr/bin/chromium"},userDataDir:{win32:`${t}\\Chromium\\User Data`,darwin:`${e}/Library/Application Support/Chromium`,linux:`${e}/.config/chromium`}},{name:"Google Chrome",executable:{win32:"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",darwin:"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",linux:"/usr/bin/google-chrome"},userDataDir:{win32:`${t}\\Google\\Chrome\\User Data`,darwin:`${e}/Library/Application Support/Google/Chrome`,linux:`${e}/.config/google-chrome`}},{name:"Google Chrome Canary",executable:{win32:"C:\\Program Files\\Google\\Chrome Canary\\Application\\chrome.exe",darwin:"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",linux:"/usr/bin/google-chrome-canary"},userDataDir:{win32:`${t}\\Google\\Chrome Canary\\User Data`,darwin:`${e}/Library/Application Support/Google/Chrome Canary`,linux:`${e}/.config/google-chrome-canary`}},{name:"Microsoft Edge",executable:{win32:"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",darwin:"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",linux:"/usr/bin/microsoft-edge"},userDataDir:{win32:`${t}\\Microsoft\\Edge\\User Data`,darwin:`${e}/Library/Application Support/Microsoft Edge`,linux:`${e}/.config/microsoft-edge`}}]}findBrowser(e){let t=process.platform;if(this.logger.info("Finding browser on platform:",t),t!=="darwin"&&t!=="win32"&&t!=="linux"){let i=new Error(`Unsupported platform: ${t}`);throw this.logger.error(i.message),i}let r=e?this.browsers.find(i=>i.name===e&&v.existsSync(i.executable[t])):this.browsers.find(i=>v.existsSync(i.executable[t]));if(this.logger.log("browser",r),!r){let i=e?new Error(`Cannot find browser: ${e}`):new Error("Cannot find a supported browser on your system. Please install Chrome, Chromium, Edge, or Brave.");throw this.logger.error(i.message),i}let s={executable:r.executable[t],userDataDir:r.userDataDir[t]};return this.logger.success(`Found browser: ${r.name}`),this.logger.info("Browser details:",s),s}getBrowserProfiles(e){let t=this.findBrowser(e);try{let s=JSON.parse(v.readFileSync(F.join(t.userDataDir,"Local State"),"utf8")).profile.info_cache;return Object.entries(s).map(([i,a])=>({displayName:a.name,path:F.join(t.userDataDir,i)}))}catch{return[]}}findChrome(){try{let{executable:e}=this.findBrowser("Google Chrome");return e}catch{return null}}};var k={DEFAULT_WAIT_MS:2e3,SEARCH_WAIT_MS:3e3,DEFAULT_TIMEOUT:3e4,DEFAULT_HEADLESS:!0},q=["bing","google","baidu","sogou"];var w=class{constructor(e={}){this.options=e;this.browser=new Z.BrowserManager;try{let t=new $,{executable:r}=t.findBrowser();this.browserPath=r}catch{this.browserPath=void 0}this.turndown=new ee.default({headingStyle:"atx",codeBlockStyle:"fenced"}),this.turndown.use(te.gfm)}browser;turndown;browserPath;async ensureLaunched(){if(!this.browser.isLaunched())try{await this.browser.launch({id:`session-${Date.now()}`,action:"launch",headless:this.options.headless??!0,executablePath:this.browserPath})}catch(e){let t=e instanceof Error?e.message:String(e);throw t.includes("Executable")||t.includes("browser")?new Error(`Browser not found. Please install one of the following:
3
+ - Google Chrome: https://www.google.com/chrome/
4
+ - Microsoft Edge: https://www.microsoft.com/edge
5
+ - Chromium: https://www.chromium.org/getting-involved/download-chromium/
6
+ Or install via Playwright:
7
+ npx playwright install chromium
8
+ Original error: ${t}`):e}}async getPage(){return await this.ensureLaunched(),this.browser.getPage()}async navigate(e){await(await this.getPage()).goto(e,{waitUntil:"domcontentloaded",timeout:this.options.timeout})}async getHtml(){return await(await this.getPage()).content()}async getText(){return await(await this.getPage()).evaluate(()=>document.body.innerText)}async screenshot(){return`data:image/png;base64,${(await(await this.getPage()).screenshot({type:"png",fullPage:!1})).toString("base64")}`}async wait(e){await new Promise(t=>setTimeout(t,e))}async close(){this.browser.isLaunched()&&await this.browser.close()}async scrapeUrl(e,t={}){try{await this.navigate(e),t.waitFor?await this.wait(t.waitFor):await this.wait(k.DEFAULT_WAIT_MS);let r={success:!0},s=t.formats||["markdown"],i=await this.getHtml();return s.includes("markdown")&&(r.markdown=this.turndown.turndown(i)),(s.includes("html")||s.includes("rawHtml"))&&(r.html=i,r.rawHtml=i),s.includes("links")&&(r.links=this.extractLinks(i,e)),(s.includes("screenshot")||s.includes("screenshot@fullPage"))&&(r.screenshot=await this.screenshot()),r}catch(r){return{success:!1,error:r instanceof Error?r.message:String(r)}}}async mapUrl(e,t={}){try{await this.navigate(e),await this.wait(k.DEFAULT_WAIT_MS);let r=await this.getHtml(),s=this.extractLinks(r,e);if(t.search&&(s=s.filter(i=>i.toLowerCase().includes(t.search.toLowerCase()))),!t.includeSubdomains){let i=new URL(e).hostname;s=s.filter(a=>{try{return new URL(a).hostname===i}catch{return!1}})}return t.limit&&(s=s.slice(0,t.limit)),{success:!0,links:s}}catch(r){return{success:!1,error:r instanceof Error?r.message:String(r)}}}async search(e){let{query:t,engine:r,limit:s=10}=e,i=this.getSearchUrl(r,t);await this.navigate(i),await this.wait(k.SEARCH_WAIT_MS);let a=await this.getHtml();return this.extractSearchResults(r,a).slice(0,s)}getSearchUrl(e,t){let r=encodeURIComponent(t);switch(e){case"google":return`https://www.google.com/search?q=${r}`;case"bing":return`https://www.bing.com/search?q=${r}`;case"baidu":return`https://www.baidu.com/s?wd=${r}`;case"sogou":return`https://www.sogou.com/web?query=${r}`;default:throw new Error(`Unsupported search engine: ${e}`)}}extractSearchResults(e,t){try{switch(e){case"google":return this.extractGoogleResults(t);case"bing":return this.extractBingResults(t);case"baidu":return this.extractBaiduResults(t);case"sogou":return this.extractSogouResults(t);default:return[]}}catch(r){let s=r instanceof Error?r.message:String(r);return P.warn(`Failed to extract ${e} search results: ${s}`),[]}}extractGoogleResults(e){let t=R.load(e),r=[];return t("div.g").each((s,i)=>{let a=t(i),p=a.find("a[href]").first(),c=a.find("h3").first(),u=a.find("div.VwiC3b, div[data-sncf]").first(),l=p.attr("href"),g=c.text().trim(),S=u.text().trim();l&&g&&!l.startsWith("/search")&&r.push({title:g,url:l,snippet:S})}),r}extractBingResults(e){let t=R.load(e),r=[];return t("li.b_algo").each((s,i)=>{let a=t(i),p=a.find("h2 a").first(),c=a.find("p, div.b_caption p").first(),u=p.attr("href"),l=p.text().trim(),g=c.text().trim();u&&l&&r.push({title:l,url:u,snippet:g})}),r}extractBaiduResults(e){let t=R.load(e),r=[];return t("div.result").each((s,i)=>{let a=t(i),p=a.find("h3 a").first(),c=a.find('div.c-abstract, div[class*="abstract"]').first(),u=p.attr("href"),l=p.text().trim(),g=c.text().trim();u&&l&&r.push({title:l,url:u,snippet:g})}),r}extractSogouResults(e){let t=R.load(e),r=[];return t("div.vrwrap").each((s,i)=>{let a=t(i),p=a.find("h3 a").first(),c=a.find('p.str-text, p[class*="text"]').first(),u=p.attr("href"),l=p.text().trim(),g=c.text().trim();u&&l&&r.push({title:l,url:u,snippet:g})}),r}extractLinks(e,t){let r=/<a[^>]+href=["']([^"']+)["']/gi,s=[],i;for(;(i=r.exec(e))!==null;)try{let a=new URL(i[1],t).href;s.includes(a)||s.push(a)}catch{}return s}};var b=new x("[LocalSearch]");function re(o){return q.includes(o)}function ve(o,e){return{title:o.title,snippet:o.snippet,url:o.url,markdown:o.content,engine:e}}async function se(o){let{query:e,limit:t=10}=o,{engines:r="all"}=o;r==="all"&&(r="bing,google,baidu,sogou");let s=r.split(",").map(c=>c.trim()).filter(Boolean);if(s.length===0)throw new Error("engines is required");let i=s.filter(re),a=s.filter(c=>!re(c));if(a.length>0&&b.warn(`Invalid search engines ignored: ${a.join(", ")}`),i.length===0)throw new Error(`No valid search engines provided. Valid engines: ${q.join(", ")}`);let p=new w({headless:!0,timeout:3e4});try{let c=[];for(let u of i)try{b.info(`Searching with engine: ${u}`);let l=await p.search({query:e,engine:u,limit:t});if(l.length>0){let g=l.map(S=>ve(S,u));c.push(...g),b.info(`Found ${l.length} results from ${u}`);break}}catch(l){b.error(`Failed to search with ${u}:`,l)}return b.info(`Total results found: ${c.length}`),{results:c,success:!0}}catch(c){let u=c instanceof Error?c.message:"Local search error.";throw b.error(u,c),c}finally{await p.close()}}var n=require("zod/v3"),ne=n.z.object({query:n.z.string().describe("Search query string"),limit:n.z.number().optional().describe("Maximum number of results to return (default: 10)"),language:n.z.string().optional().describe("Language code for search results (default: auto)"),categories:n.z.enum(["general","news","images","videos","it","science","map","music","files","social_media"]).optional().describe("Categories to search for (default: general)"),timeRange:n.z.enum(["all","day","week","month","year"]).optional().describe("Time range for search results (default: all)")}),oe=n.z.object({url:n.z.string().describe("Starting URL for URL discovery"),search:n.z.string().optional().describe("Optional search term to filter URLs"),ignoreSitemap:n.z.boolean().optional().describe("Skip sitemap.xml discovery and only use HTML links"),sitemapOnly:n.z.boolean().optional().describe("Only use sitemap.xml for discovery, ignore HTML links"),includeSubdomains:n.z.boolean().optional().describe("Include URLs from subdomains in results"),limit:n.z.number().optional().describe("Maximum number of URLs to return")}),Re=n.z.discriminatedUnion("type",[n.z.object({type:n.z.literal("wait"),milliseconds:n.z.number().describe("Time to wait in milliseconds")}),n.z.object({type:n.z.literal("click"),selector:n.z.string().describe("CSS selector for the target element")}),n.z.object({type:n.z.literal("screenshot"),fullPage:n.z.boolean().optional().describe("Take full page screenshot")}),n.z.object({type:n.z.literal("write"),selector:n.z.string().describe("CSS selector for the target element"),text:n.z.string().describe("Text to write")}),n.z.object({type:n.z.literal("press"),key:n.z.string().describe("Key to press")}),n.z.object({type:n.z.literal("scroll"),direction:n.z.enum(["up","down"]).describe("Scroll direction")}),n.z.object({type:n.z.literal("scrape")}),n.z.object({type:n.z.literal("executeJavascript"),script:n.z.string().describe("JavaScript code to execute")})]),ie=n.z.object({url:n.z.string().describe("The URL to scrape"),formats:n.z.array(n.z.enum(["markdown","html","rawHtml","screenshot","links","screenshot@fullPage","extract"])).optional().describe("Content formats to extract (default: ['markdown'])"),onlyMainContent:n.z.boolean().optional().describe("Extract only the main content, filtering out navigation, footers, etc."),includeTags:n.z.array(n.z.string()).optional().describe("HTML tags to specifically include in extraction"),excludeTags:n.z.array(n.z.string()).optional().describe("HTML tags to exclude from extraction"),waitFor:n.z.number().optional().describe("Time in milliseconds to wait for dynamic content to load"),timeout:n.z.number().optional().describe("Maximum time in milliseconds to wait for the page to load"),actions:n.z.array(Re).optional().describe("List of actions to perform before scraping"),extract:n.z.object({schema:n.z.record(n.z.any()).optional().describe("Schema for structured data extraction"),systemPrompt:n.z.string().optional().describe("System prompt for LLM extraction"),prompt:n.z.string().optional().describe("User prompt for LLM extraction")}).optional().describe("Configuration for structured data extraction"),mobile:n.z.boolean().optional().describe("Use mobile viewport"),skipTlsVerification:n.z.boolean().optional().describe("Skip TLS certificate verification"),removeBase64Images:n.z.boolean().optional().describe("Remove base64 encoded images from output"),location:n.z.object({country:n.z.string().optional().describe("Country code for geolocation"),languages:n.z.array(n.z.string()).optional().describe("Language codes for content")}).optional().describe("Location settings for scraping")}),ae=n.z.object({urls:n.z.array(n.z.string()).describe("List of URLs to extract information from"),prompt:n.z.string().optional().describe("Prompt for the LLM extraction"),systemPrompt:n.z.string().optional().describe("System prompt for LLM extraction"),schema:n.z.record(n.z.any()).optional().describe("JSON schema for structured data extraction"),allowExternalLinks:n.z.boolean().optional().describe("Allow extraction from external links"),enableWebSearch:n.z.boolean().optional().describe("Enable web search for additional context"),includeSubdomains:n.z.boolean().optional().describe("Include subdomains in extraction")});var E={name:"one_search",description:"Search and retrieve content from web pages. Returns SERP results by default (url, title, description).",schema:ne},L={name:"one_map",description:"Discover URLs from a starting point. Can use both sitemap.xml and HTML link discovery.",schema:oe},I={name:"one_scrape",description:"Scrape a single webpage with advanced options for content extraction. Supports various formats including markdown, HTML, and screenshots. Can execute custom actions like clicking or scrolling before scraping.",schema:ie},T={name:"one_extract",description:"Extract structured information from web pages using LLM. Supports both cloud AI and self-hosted LLM extraction.",schema:ae};var pe=d(require("@dotenvx/dotenvx"),1),M=require("duck-duck-scrape");pe.default.config({quiet:!0});var Ee=process.env.SEARCH_API_URL,O=process.env.SEARCH_API_KEY,ce=process.env.SEARCH_PROVIDER??"local",Le=process.env.SAFE_SEARCH??0,Ie=process.env.LIMIT??10,Te=process.env.CATEGORIES??"general",Oe=process.env.ENGINES??"all",Ce=process.env.FORMAT??"json",Ae=process.env.LANGUAGE??"auto",Pe=process.env.TIME_RANGE??"",$e=process.env.TIMEOUT??1e4,f=new le.McpServer({name:"one-search-mcp",version:"1.1.0"},{capabilities:{tools:{},logging:{}}}),y={limit:Number(Ie),categories:Te,format:Ce,safesearch:Le,language:Ae,engines:Oe,time_range:Pe,timeout:$e};function U(o,e){return async t=>{let r=Date.now();try{await f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Request started for tool: [${o}]`});let s=await e(t);return await f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Request completed in ${Date.now()-r}ms`}),s}catch(s){return await f.sendLoggingMessage({level:"error",data:`[${new Date().toISOString()}] Error in ${o}: ${s}`}),{content:[{type:"text",text:s instanceof Error?s.message:String(s)}],isError:!0}}}}f.registerTool(E.name,{description:E.description,inputSchema:E.schema},U(E.name,async o=>{let{results:e,success:t}=await ke({...o,apiKey:O??"",apiUrl:Ee});if(!t)throw new Error("Failed to search");return{content:[{type:"text",text:e.map(s=>`Title: ${s.title}
4
9
  URL: ${s.url}
5
10
  Description: ${s.snippet}
6
11
  ${s.markdown?`Content: ${s.markdown}`:""}`).join(`
7
12
 
8
- `)}],results:n,success:a}}catch(n){return f.sendLoggingMessage({level:"error",data:`[${new Date().toISOString()}] Error searching: ${n}`}),{success:!1,content:[{type:"text",text:n instanceof Error?n.message:"Unknown error"}]}}}case"one_scrape":{if(!ze(r))throw new Error(`Invalid arguments for tool: [${e}]`);try{let n=Date.now();f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Scraping started for url: [${r.url}]`});let{url:a,...o}=r,{content:s,success:u,result:h}=await Xe(a,o);return f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Scraping completed in ${Date.now()-n}ms`}),{content:s,result:h,success:u}}catch(n){return f.sendLoggingMessage({level:"error",data:`[${new Date().toISOString()}] Error scraping: ${n}`}),{success:!1,content:[{type:"text",text:n instanceof Error?n.message:"Unknown error"}]}}}case"one_map":{if(!Je(r))throw new Error(`Invalid arguments for tool: [${e}]`);try{let{content:n,success:a,result:o}=await Ke(r.url,r);return{content:n,result:o,success:a}}catch(n){return f.sendLoggingMessage({level:"error",data:`[${new Date().toISOString()}] Error mapping: ${n}`}),{success:!1,content:[{type:"text",text:n instanceof Error?n.message:String(n)}]}}}default:throw new Error(`Unknown tool: ${e}`)}}catch(e){let r=e instanceof Error?e.message:String(e);return f.sendLoggingMessage({level:"error",data:{message:`[${new Date().toISOString()}] Error processing request: ${r}`,tool:i.params.name,arguments:i.params.arguments,timestamp:new Date().toISOString(),duration:Date.now()-t}}),{success:!1,content:[{type:"text",text:r}]}}finally{f.sendLoggingMessage({level:"info",data:`[${new Date().toISOString()}] Request completed in ${Date.now()-t}ms`})}});async function Ve(i){switch(fe){case"searxng":{let t={...w,...i,apiKey:T},{categories:e,language:r}=w;return e&&(t.categories=e),r&&(t.language=r),await X(t)}case"tavily":return await Y({...w,...i,apiKey:T});case"bing":return await H({...w,...i,apiKey:T});case"duckduckgo":{let t=i.safeSearch??0,e=[I.SafeSearchType.STRICT,I.SafeSearchType.MODERATE,I.SafeSearchType.OFF];return await W({...w,...i,apiKey:T,safeSearch:e[t]})}case"local":return await he({...w,...i});default:throw new Error(`Unsupported search provider: ${fe}`)}}async function Xe(i,t){let e=await Ee.scrapeUrl(i,{...t});if(!e.success)throw new Error(`Failed to scrape: ${e.error}`);let r=[];return e.markdown&&r.push(e.markdown),e.rawHtml&&r.push(e.rawHtml),e.links&&r.push(e.links.join(`
9
- `)),e.screenshot&&r.push(e.screenshot),e.html&&r.push(e.html),e.extract&&r.push(e.extract),{content:[{type:"text",text:r.join(`
13
+ `)}]}}));f.registerTool(I.name,{description:I.description,inputSchema:I.schema},U(I.name,async o=>{let{url:e,...t}=o,{content:r}=await Me(e,t);return{content:r}}));f.registerTool(L.name,{description:L.description,inputSchema:L.schema},U(L.name,async o=>{let{content:e}=await Ue(o.url,o);return{content:e}}));f.registerTool(T.name,{description:T.description,inputSchema:T.schema},U(T.name,async o=>{let{content:e}=await _e(o);return{content:e}}));async function ke(o){switch(ce){case"searxng":{let e={...y,...o,apiKey:O},{categories:t,language:r}=y;return t&&(e.categories=t),r&&(e.language=r),await z(e)}case"tavily":return await Y({...y,...o,apiKey:O});case"bing":return await N({...y,...o,apiKey:O});case"duckduckgo":{let e=o.safeSearch??0,t=[M.SafeSearchType.STRICT,M.SafeSearchType.MODERATE,M.SafeSearchType.OFF];return await K({...y,...o,apiKey:O,safeSearch:t[e]})}case"local":return await se({...y,...o});default:throw new Error(`Unsupported search provider: ${ce}`)}}async function Me(o,e){let t=new w({headless:!0,timeout:3e4});try{let r=await t.scrapeUrl(o,e);if(!r.success)throw new Error(`Failed to scrape: ${r.error}`);let s=[];return r.markdown&&s.push(r.markdown),r.rawHtml&&s.push(r.rawHtml),r.links&&s.push(r.links.join(`
14
+ `)),r.screenshot&&s.push(r.screenshot),r.html&&s.push(r.html),{content:[{type:"text",text:s.join(`
10
15
 
11
- `)||"No content found"}],result:e,success:!0}}async function Ke(i,t){let e=await Ee.mapUrl(i,{...t});if("error"in e)throw new Error(`Failed to map: ${e.error}`);if(!e.links)throw new Error(`No links found from: ${i}`);return{content:[{type:"text",text:e.links.join(`
12
- `).trim()}],result:e.links,success:!0}}function Ye(i){return typeof i=="object"&&i!==null&&"query"in i&&typeof i.query=="string"}function ze(i){return typeof i=="object"&&i!==null&&"url"in i&&typeof i.url=="string"}function Je(i){return typeof i=="object"&&i!==null&&"url"in i&&typeof i.url=="string"}async function Qe(){try{process.stdout.write(`Starting OneSearch MCP server...
13
- `);let i=new we.StdioServerTransport;await f.connect(i),f.sendLoggingMessage({level:"info",data:"OneSearch MCP server started"})}catch(i){let t=i instanceof Error?i.message:String(i);process.stderr.write(`Error starting server: ${t}
14
- `),process.exit(1)}}Qe().catch(i=>{let t=i instanceof Error?i.message:String(i);process.stderr.write(`Error running server: ${t}
16
+ `)||"No content found"}],result:r,success:!0}}finally{await t.close()}}async function Ue(o,e){let t=new w({headless:!0,timeout:3e4});try{let r=await t.mapUrl(o,e);if(!r.success)throw new Error(`Failed to map: ${r.error}`);if(!r.links)throw new Error(`No links found from: ${o}`);return{content:[{type:"text",text:r.links.join(`
17
+ `).trim()}],result:r.links,success:!0}}finally{await t.close()}}async function _e(o){let{urls:e,prompt:t,systemPrompt:r,schema:s}=o,i=new w({headless:!0,timeout:3e4});try{let a=[];for(let c of e)try{let u=await i.scrapeUrl(c,{formats:["markdown"],onlyMainContent:!0});u.success&&u.markdown?a.push(`## Content from ${c}
18
+
19
+ ${u.markdown}`):a.push(`## Failed to extract from ${c}
20
+
21
+ Error: ${u.error||"Unknown error"}`)}catch(u){let l=u instanceof Error?u.message:String(u);a.push(`## Failed to extract from ${c}
22
+
23
+ Error: ${l}`)}let p=a.join(`
24
+
25
+ ---
26
+
27
+ `);if(t||r||s){let c=[];r&&c.push(`System Instructions: ${r}`),t&&c.push(`Extraction Task: ${t}`),s&&c.push(`Expected Schema:
28
+ ${JSON.stringify(s,null,2)}`),p=`${c.join(`
29
+
30
+ `)}
31
+
32
+ ---
33
+
34
+ Extracted Content:
35
+
36
+ ${p}`}return{content:[{type:"text",text:p}]}}finally{await i.close()}}async function De(){try{let o=new ue.StdioServerTransport;await f.connect(o),await f.sendLoggingMessage({level:"info",data:"OneSearch MCP server started"})}catch(o){let e=o instanceof Error?o.message:String(o);process.stderr.write(`Error starting server: ${e}
37
+ `),process.exit(1)}}De().catch(o=>{let e=o instanceof Error?o.message:String(o);process.stderr.write(`Error running server: ${e}
15
38
  `),process.exit(1)});
16
39
  //# sourceMappingURL=index.cjs.map