@duckmind/dm-darwin-x64 0.52.3 → 0.52.6
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/dm +0 -0
- package/extensions/.dm-extensions.json +6 -3
- package/extensions/greedysearch-dm/bin/gschrome.mjs +5 -7
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +2 -4
- package/extensions/greedysearch-dm/bin/launch.mjs +11 -5
- package/extensions/greedysearch-dm/bin/search.mjs +122 -120
- package/extensions/greedysearch-dm/extractors/consensus.mjs +43 -43
- package/extensions/greedysearch-dm/extractors/gemini.mjs +44 -44
- package/extensions/greedysearch-dm/extractors/logically.mjs +41 -41
- package/extensions/greedysearch-dm/index.js +18 -18
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +8 -9
- package/extensions/greedysearch-dm/src/search/chrome.mjs +25 -25
- package/extensions/greedysearch-dm/src/search/constants.mjs +8 -8
- package/extensions/greedysearch-dm/src/search/engines.mjs +9 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +49 -49
- package/extensions/greedysearch-dm/src/search/launcher-paths.mjs +3 -0
- package/extensions/greedysearch-dm/src/search/partial-output.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +1 -0
- package/extensions/greedysearch-dm/src/search/recovery.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +101 -101
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +10 -10
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +18 -18
- package/extensions/greedysearch-dm/src/tools/shared.js +9 -9
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{randomInt as
|
|
3
|
-
`)[0]?.slice(0,8);if(!
|
|
4
|
-
`)}return
|
|
2
|
+
import{randomInt as hg}from"node:crypto";import{spawn as og}from"node:child_process";import{dirname as Wg,join as Qg}from"node:path";import{fileURLToPath as Xg}from"node:url";import{basename as lg}from"node:path";function Zg(f=process.env,g=process.execPath){let u=f.GREEDY_SEARCH_NODE||f.NODE_BINARY||f.NODE;if(u?.trim())return u.trim();let n=lg(g||"").toLowerCase();if(n==="node"||n==="node.exe")return g;return"node"}var Jg=Wg(Xg(import.meta.url)),ig=Qg(Jg,"..","bin","cdp.mjs");function X(f,g=30000){return ff(f,null,g)}function ff(f,g=null,u=30000){return new Promise((n,$)=>{let w=og(Zg(),[ig,...f],{stdio:[g==null?"ignore":"pipe","pipe","pipe"]});if(g!=null)w.stdin.write(g),w.stdin.end();let o="",h="";w.stdout.on("data",(Q)=>o+=Q),w.stderr.on("data",(Q)=>h+=Q);let W=setTimeout(()=>{w.kill(),$(Error(`cdp timeout: ${f[0]}`))},u);w.on("close",(Q)=>{if(clearTimeout(W),Q===0)n(o.trim());else $(Error(h.trim()||`cdp exit ${Q}`))})})}async function qf(f){if(f)return f;let g=(await X(["list"])).split(`
|
|
3
|
+
`)[0]?.slice(0,8);if(!g)throw Error("No Chrome tabs found. Is Chrome running with --remote-debugging-port=9222?");let u=await X(["evalraw",g,"Target.createTarget",'{"url":"about:blank"}']),{targetId:n}=JSON.parse(u);await X(["list"]);let $=n.slice(0,8);try{await Vf($)}catch(w){process.stderr.write(`[getOrOpenTab] stealth injection failed: ${w.message}
|
|
4
|
+
`)}return $}async function Vf(f){await X(["evalraw",f,"Page.addScriptToEvaluateOnNewDocument",JSON.stringify({source:`
|
|
5
5
|
(function() {
|
|
6
6
|
// ── Runtime.enable / CDP detection masking ──────────────
|
|
7
7
|
try { delete window.__REBROWSER_RUNTIME_ENABLE; } catch(_) {}
|
|
@@ -209,10 +209,10 @@ import{randomInt as gf}from"node:crypto";import{spawn as of}from"node:child_proc
|
|
|
209
209
|
};
|
|
210
210
|
} catch(_) {}
|
|
211
211
|
})();
|
|
212
|
-
`})])}var
|
|
212
|
+
`})])}var gf={postNav:800,postNavSlow:1200,postClick:300,postType:300,inputPoll:400,copyPoll:600,afterVerify:1500};function D(f){let g=f*0.4,u=hg(-Math.floor(g),Math.floor(g)+1);return Math.max(50,Math.round(f+u))}async function G(f,g,u=15000,n=500){let $=String.raw`
|
|
213
213
|
new Promise((resolve) => {
|
|
214
214
|
const _deadline = Date.now() + ${u};
|
|
215
|
-
const _baseInterval = ${
|
|
215
|
+
const _baseInterval = ${n};
|
|
216
216
|
|
|
217
217
|
function _jitter(ms) {
|
|
218
218
|
return Math.max(50, ms + (Math.random() * ms * 0.4 - ms * 0.2));
|
|
@@ -220,7 +220,7 @@ import{randomInt as gf}from"node:crypto";import{spawn as of}from"node:child_proc
|
|
|
220
220
|
|
|
221
221
|
function _poll() {
|
|
222
222
|
try {
|
|
223
|
-
if (document.querySelector('${
|
|
223
|
+
if (document.querySelector('${g}')) { resolve(true); return; }
|
|
224
224
|
if (Date.now() < _deadline) { setTimeout(_poll, _jitter(_baseInterval)); }
|
|
225
225
|
else { resolve(false); }
|
|
226
226
|
} catch(_) { resolve(false); }
|
|
@@ -228,27 +228,27 @@ import{randomInt as gf}from"node:crypto";import{spawn as of}from"node:child_proc
|
|
|
228
228
|
|
|
229
229
|
_poll();
|
|
230
230
|
})
|
|
231
|
-
`;return await
|
|
232
|
-
`)}function
|
|
233
|
-
`)}process.stderr.write(`Error: ${
|
|
234
|
-
`),process.exit(1)}import{spawn as
|
|
235
|
-
[greedysearch] Available engines: ${Object.keys(
|
|
236
|
-
`);if(u.length>0)return u;process.stderr.write(`[greedysearch] Warning: no valid engines in ${
|
|
237
|
-
`)}}}catch{}return
|
|
238
|
-
`,"utf8")}catch{}}
|
|
239
|
-
[greedysearch] Available synthesizers: ${
|
|
240
|
-
[greedysearch] Falling back to default: ${
|
|
241
|
-
`)}}}catch{}return
|
|
242
|
-
${
|
|
243
|
-
`}function
|
|
244
|
-
|
|
245
|
-
`)[0],10):null}catch{return null}}
|
|
246
|
-
`);return
|
|
247
|
-
${
|
|
248
|
-
`);return}
|
|
249
|
-
`),await
|
|
250
|
-
`),await
|
|
251
|
-
`);let
|
|
231
|
+
`;return await X(["eval",f,$],u+5000)==="true"}async function Hf(f){let g=f.indexOf("--stdin");if(g===-1)return f;let u=await new Promise(($)=>{let w="";process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>w+=o),process.stdin.on("end",()=>$(w.trim()))}),n=[...f];return n[g]=u,n}function _f(f){let g=f.includes("--short"),u=f.filter((h)=>h!=="--short"),n=u.indexOf("--tab"),$=n===-1?null:u[n+1];if(n!==-1)u=u.filter((h,W)=>W!==n&&W!==n+1);let w=u.indexOf("--locale"),o=w===-1?null:u[w+1];if(w!==-1)u=u.filter((h,W)=>W!==w&&W!==w+1);return{query:u.join(" "),tabPrefix:$,short:g,locale:o}}function Nf(f,g){if(!f.length||f[0]==="--help")process.stderr.write(g),process.exit(1)}function Kf(f,g,u=300){if(!g||f.length<=u)return f;let n=f.slice(0,u),$=n.lastIndexOf(" ");return $>0?`${n.slice(0,$)}…`:`${n}…`}function Uf(f){process.stdout.write(`${JSON.stringify(f,null,2)}
|
|
232
|
+
`)}function i(f,g,u=null){if(!f||typeof f!=="object")return;let n=u?` (+${Date.now()-u}ms)`:"";if(f.lastStage=g,!Array.isArray(f.stages))f.stages=[];f.stages.push({stage:g,at:Date.now()});let $=f.engine||"extractor";console.error(`[${$}] stage: ${g}${n}`)}function uf({engine:f,mode:g="headless",clipboardEmpty:u=null,fallbackUsed:n=null,blockedBy:$=null,verificationResult:w=null,inputReady:o=null,durationMs:h=null,lastStage:W=null,stages:Q=null}={}){return{engine:f,mode:g,clipboardEmpty:u,fallbackUsed:n,blockedBy:$,verificationResult:w,inputReady:o,durationMs:h,lastStage:W,stages:Q}}function rf(f,g=null){if(g){let u=JSON.stringify({_envelope:g,error:f.message});process.stdout.write(`${u}
|
|
233
|
+
`)}process.stderr.write(`Error: ${f.message}
|
|
234
|
+
`),process.exit(1)}import{spawn as n0,execFileSync as Ff,execSync as $0}from"node:child_process";import{existsSync as s,readFileSync as d,renameSync as w0,unlinkSync as V,writeFileSync as e}from"node:fs";import Zf from"node:http";import{platform as af,tmpdir as h0}from"node:os";import{basename as bg}from"node:path";function xf(f=process.env,g=process.execPath){let u=f.GREEDY_SEARCH_NODE||f.NODE_BINARY||f.NODE;if(u?.trim())return u.trim();let n=bg(g||"").toLowerCase();if(n==="node"||n==="node.exe")return g;return"node"}import{existsSync as Af}from"node:fs";import{platform as Bg}from"node:os";import{join as U}from"node:path";function j(f){let g=Bg()==="win32",u=process.env.SystemRoot||"C:\\Windows",n={win32:{powershell:U(u,"System32","WindowsPowerShell","v1.0","powershell.exe"),powershell_ise:U(u,"System32","WindowsPowerShell","v1.0","powershell_ise.exe"),netstat:U(u,"System32","netstat.exe"),taskkill:U(u,"System32","taskkill.exe"),tasklist:U(u,"System32","tasklist.exe"),cmd:U(u,"System32","cmd.exe")},unix:{ps:"/usr/bin/ps",lsof:"/usr/bin/lsof",ss:"/usr/sbin/ss",grep:"/usr/bin/grep",kill:"/usr/bin/kill"}},$=g?n.win32:n.unix,w=f.toLowerCase();if($[w]&&Af($[w]))return $[w];if(g&&w==="netstat"){let o=U(u,"Sysnative","netstat.exe");if(Af(o))return o}return f}import{existsSync as S,mkdirSync as jg,readFileSync as Mf,writeFileSync as qg}from"node:fs";import{homedir as Vg}from"node:os";import{join as Of}from"node:path";import{tmpdir as F}from"node:os";function Hg(f,g=9222){let u=Number.parseInt(String(f??""),10);return Number.isInteger(u)&&u>1024&&u<65535?u:g}var Z=Hg(process.env.GREEDY_SEARCH_PORT,9222),_=(process.env.GREEDY_SEARCH_PROFILE_DIR||process.env.CDP_PROFILE_DIR||`${F().replaceAll("\\","/")}/greedysearch-chrome-profile`).replaceAll("\\","/"),O=`${_}/DevToolsActivePort`,_g=`${F().replaceAll("\\","/")}/cdp-pages.json`,r=process.env.GREEDY_SEARCH_MODE_FILE||`${F().replaceAll("\\","/")}/greedysearch-chrome-mode`,c0=`${F().replaceAll("\\","/")}/greedysearch-visible-recovery.jsonl`,$f=Of(Vg(),".dm"),q=Of($f,"greedyconfig"),wf=["perplexity","google","chatgpt"],hf="gemini";function Ng(){try{if(S(q)){let f=Mf(q,"utf8"),g=JSON.parse(f);if(Array.isArray(g.engines)&&g.engines.length>0&&g.engines.every((u)=>typeof u==="string")){let u=g.engines.filter(($)=>nf[$]),n=g.engines.filter(($)=>!nf[$]);if(n.length>0)process.stderr.write(`[greedysearch] Warning: ignoring unknown engine(s) in ${q}: ${n.join(", ")}
|
|
235
|
+
[greedysearch] Available engines: ${Object.keys(nf).join(", ")}
|
|
236
|
+
`);if(u.length>0)return u;process.stderr.write(`[greedysearch] Warning: no valid engines in ${q}, falling back to defaults: ${wf.join(", ")}
|
|
237
|
+
`)}}}catch{}return wf}function Kg(){try{if(!S($f))jg($f,{recursive:!0});if(!S(q))qg(q,JSON.stringify({engines:wf,synthesizer:hf},null,2)+`
|
|
238
|
+
`,"utf8")}catch{}}Kg();var kf=["gemini","chatgpt"];function Ug(){try{if(S(q)){let f=Mf(q,"utf8"),g=JSON.parse(f);if(typeof g.synthesizer==="string"){let u=g.synthesizer.toLowerCase();if(kf.includes(u))return u;process.stderr.write(`[greedysearch] Warning: unknown synthesizer "${g.synthesizer}" in ${q}
|
|
239
|
+
[greedysearch] Available synthesizers: ${kf.join(", ")}
|
|
240
|
+
[greedysearch] Falling back to default: ${hf}
|
|
241
|
+
`)}}}catch{}return hf}var nf={perplexity:"perplexity.mjs",p:"perplexity.mjs",bing:"bing-copilot.mjs",b:"bing-copilot.mjs",google:"google-ai.mjs",g:"google-ai.mjs",gemini:"gemini.mjs",gem:"gemini.mjs",chatgpt:"chatgpt.mjs",gpt:"chatgpt.mjs","semantic-scholar":"semantic-scholar.mjs",semanticscholar:"semantic-scholar.mjs",s2:"semantic-scholar.mjs",logically:"logically.mjs",log:"logically.mjs"},L0=Ng();var I0=Ug(),S0=Math.max(1,Number.parseInt(process.env.GREEDY_FETCH_CONCURRENCY||"5",10)||5);process.env.CDP_PROFILE_DIR=_;import{existsSync as a0,mkdirSync as rg,readFileSync as yf,renameSync as xg,unlinkSync as Ag,writeFileSync as Yf}from"node:fs";import kg from"node:http";import{platform as vf}from"node:os";import{dirname as Mg}from"node:path";var Df=[9222,9223],Og=/^(0|false|no|off)$/i;function zg(f){return[...new Set(f.filter(Boolean))]}function zf(f,g="explicit"){let u=new URL(f),n=u.protocol==="wss:"?"wss:":"ws:",$=u.port?Number.parseInt(u.port,10):n==="wss:"?443:80;return{source:g,wsUrl:`${n}//${u.host}${u.pathname}${u.search}`,host:u.hostname,port:$,path:`${u.pathname}${u.search}`,httpUrl:`http://${u.hostname}:${$}`}}function Gf(f=process.env){return![f.GREEDY_SEARCH_REUSE_EXISTING_BROWSER,f.DM_CUA_REUSE_EXISTING_BROWSER].some((g)=>g!==void 0&&Og.test(String(g)))}function of(f){let g=Number.parseInt(String(f??""),10);return Number.isInteger(g)&&g>0&&g<65536?g:null}function yg(f){if(!f)return null;let g=String(f).trim();if(!g)return null;let u=new URL(g.includes("://")?g:`http://${g}`),n=of(u.port)||(u.protocol==="https:"?443:80);return{host:u.hostname,port:n,source:`env:${g}`}}function Yg(f){if(!f)return[];return String(f).split(/[,\s]+/).map(of).filter(Boolean)}function vg({env:f=process.env,platformName:g=vf(),procVersionText:u=null}={}){if(g!=="linux")return!1;if(f.WSL_DISTRO_NAME||f.WSL_INTEROP)return!0;let n=u??(()=>{try{return yf("/proc/version","utf8")}catch{return""}})();return/microsoft|wsl/i.test(n)}function Dg({env:f=process.env,platformName:g=vf(),procVersionText:u=null,resolvConfText:n=null}={}){let $=["localhost","127.0.0.1"];if(vg({env:f,platformName:g,procVersionText:u})){let o=(n??(()=>{try{return yf("/etc/resolv.conf","utf8")}catch{return""}})()).match(/^\s*nameserver\s+([^\s#]+)/m);if(o)$.push(o[1]);$.push("host.docker.internal")}return zg($)}function Gg({env:f=process.env,hosts:g=Dg({env:f}),autoPorts:u=Df,excludePorts:n=[]}={}){let $=[];for(let W of["GREEDY_SEARCH_CDP_WS_URL","DM_CUA_CDP_WS_URL","CDP_WS_URL"])if(f[W])$.push({wsUrl:f[W],source:`env:${W}`});for(let W of["GREEDY_SEARCH_CDP_URL","DM_CUA_CDP_URL","CDP_URL"])try{let Q=yg(f[W]);if(Q)$.push(Q)}catch{}for(let W of["GREEDY_SEARCH_EXISTING_CDP_PORT","DM_CUA_EXISTING_CDP_PORT","GREEDY_SEARCH_CDP_PORT","DM_CUA_CDP_PORT"]){let Q=of(f[W]);if(!Q)continue;for(let l of g)$.push({host:l,port:Q,source:`env:${W}`})}let w=Yg(f.GREEDY_SEARCH_EXISTING_CDP_PORTS);for(let W of w)for(let Q of g)$.push({host:Q,port:W,source:"env:GREEDY_SEARCH_EXISTING_CDP_PORTS"});let o=new Set(n.filter(Boolean));if(Gf(f))for(let W of u){if(o.has(W))continue;for(let Q of g)$.push({host:Q,port:W,source:"auto"})}let h=new Set;return $.filter((W)=>{let Q=W.wsUrl||`${W.host}:${W.port}`;if(h.has(Q))return!1;return h.add(Q),!0})}async function tg(f,{timeoutMs:g=700}={}){if(f.wsUrl)return zf(f.wsUrl,f.source);let u=f.host||"localhost",n=f.port;if(!n)return null;let $=await new Promise((w)=>{let o=kg.get({host:u,port:n,path:"/json/version",timeout:g},(h)=>{let W="";h.setEncoding("utf8"),h.on("data",(Q)=>W+=Q),h.on("end",()=>w(h.statusCode===200?W:null))});o.on("error",()=>w(null)),o.setTimeout(g,()=>{o.destroy(),w(null)})});if(!$)return null;try{let w=JSON.parse($);if(!w.webSocketDebuggerUrl)return null;let o=zf(w.webSocketDebuggerUrl,f.source),h=o.path||new URL(w.webSocketDebuggerUrl).pathname;return{...o,host:u,port:n,httpUrl:`http://${u}:${n}`,wsUrl:`ws://${u}:${n}${h}`,path:h}}catch{return null}}async function Tg(f={}){for(let g of Gg(f)){let u=await tg(g,f);if(u)return u}return null}function Cg(f){if(!f)throw Error("missing CDP endpoint");let g=new URL(f.wsUrl);return`${g.host}
|
|
242
|
+
${g.pathname}${g.search}
|
|
243
|
+
`}function Rg(f,g){rg(Mg(f),{recursive:!0});let u=`${f}.tmp-${process.pid}`;Yf(u,Cg(g),"utf8");try{Ag(f)}catch{}xg(u,f)}async function tf({activePortFile:f,modeFile:g,env:u=process.env,excludePorts:n=[],autoPorts:$=Df}={}){if(!Gf(u))return null;let w=await Tg({env:u,excludePorts:n,autoPorts:$});if(!w)return null;if(Rg(f,w),g)Yf(g,"existing","utf8");return w}import{existsSync as mg}from"node:fs";import{dirname as Pg,join as z}from"node:path";function cg(f){let g=new Set;return f.filter((u)=>{if(!u||g.has(u))return!1;return g.add(u),!0})}function Lg({moduleDir:f,entrypoint:g=process.argv[1],env:u=process.env}={}){let n=g?Pg(g):null,$=u.GREEDY_SEARCH_EXTENSION_DIR?.trim()||null;return cg([$?z($,"bin","launch.mjs"):null,f?z(f,"launch.mjs"):null,f?z(f,"..","bin","launch.mjs"):null,f?z(f,"..","..","bin","launch.mjs"):null,n?z(n,"launch.mjs"):null,n?z(n,"..","bin","launch.mjs"):null])}function Tf({moduleDir:f,entrypoint:g=process.argv[1],env:u=process.env,exists:n=mg}={}){let $=Lg({moduleDir:f,entrypoint:g,env:u}),w=$.find((o)=>n(o));if(w)return w;throw Error(`GreedySearch launcher not found. Checked candidates:
|
|
244
|
+
${$.map((o)=>`- ${o}`).join(`
|
|
245
|
+
`)}`)}import{execFileSync as Ig}from"node:child_process";import{platform as Sg}from"node:os";function Fg(f,g){return Ig(j(f),g,{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5000})}function pg(f){let g=String(f||"").match(/\b(\d+)\b/);return g?Number.parseInt(g[1],10):null}function ag(f){return pg(f)}function Eg(f,g){for(let u of String(f||"").split(/\r?\n/)){if(!/\bLISTEN\b/i.test(u))continue;if(!u.trim().split(/\s+/).slice(0,6).some((w)=>w.endsWith(`:${g}`)))continue;let $=u.match(/\bpid=(\d+)\b/);if($)return Number.parseInt($[1],10)}return null}function eg(f,g){for(let u of String(f||"").split(/\r?\n/)){let n=u.trim().split(/\s+/);if(n.length<5||n[0].toUpperCase()!=="TCP")continue;if(!n.at(-2)?.toUpperCase().startsWith("LISTEN"))continue;if(!n[1].endsWith(`:${g}`))continue;let w=Number.parseInt(n.at(-1),10);if(Number.isInteger(w)&&w>0)return w}return null}function Wf(f,g,u){try{return f(g,u)}catch{return null}}function p(f,{platformName:g=Sg(),run:u=Fg}={}){if(g==="win32")return eg(Wf(u,"netstat",["-ano","-p","TCP"]),f);let n=Wf(u,"lsof",["-nP",`-iTCP:${f}`,"-sTCP:LISTEN","-t"]),$=ag(n);if($)return $;if(g!=="linux")return null;return Eg(Wf(u,"ss",["-ltnp"]),f)}import{execFileSync as Cf,execSync as Wu}from"node:child_process";import{existsSync as x,mkdirSync as sg,readFileSync as y,unlinkSync as k,writeFileSync as M}from"node:fs";import{platform as dg,tmpdir as cf}from"node:os";var R=cf().replaceAll("\\","/"),a=`${R}/greedysearch-chrome-metadata.json`,A=`${R}/greedysearch-chrome-launch.lock`,f0=15000,t=`${R}/greedysearch-chrome.pid`,T=`${R}/greedysearch-chrome-mode`,Y=`${R}/greedysearch-chrome-last-activity`;function C(f){if(!Number.isInteger(f)||f<=0)return!1;try{return process.kill(f,0),!0}catch{return!1}}function g0(f){if(!C(f))return null;try{if(dg()==="win32")return Cf(j("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${f}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return Cf(j("ps"),["-p",String(f),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Qf(f,g,u=Z){if(!f)return!1;let n=(o)=>String(o||"").replaceAll("\\","/").toLowerCase(),$=n(f),w=n(g);return $.includes(w)&&$.includes(`--remote-debugging-port=${u}`)&&!$.includes("--type=")}function Rf(f,g,u=Z){return Qf(g0(f),g,u)}function u0(f=Z){return p(f)}function m(){try{if(x(a)){let f=y(a,"utf8"),g=JSON.parse(f);if(g&&typeof g.tempDir==="string"&&typeof g.debugPort==="number")return{browserPid:Number.isInteger(g.browserPid)?g.browserPid:void 0,debugPort:g.debugPort,tempDir:g.tempDir,clientPids:Array.isArray(g.clientPids)?g.clientPids.filter((u)=>Number.isInteger(u)&&u>0):[],sessionMode:g.sessionMode==="visible"?"visible":"headless",lastActivity:Number.isFinite(g.lastActivity)?g.lastActivity:0,launchedAt:Number.isFinite(g.launchedAt)?g.launchedAt:0}}}catch{}try{if(!(x(t)||x(T)||x(Y)))return null;let g=x(t)?Number.parseInt(y(t,"utf8").trim(),10)||void 0:void 0,u=x(T)?y(T,"utf8").trim()==="visible"?"visible":"headless":"headless",n=x(Y)?Number.parseInt(y(Y,"utf8").trim(),10)||0:0;return{browserPid:g,debugPort:Z,tempDir:_,clientPids:g?[g]:[],sessionMode:u,lastActivity:n,launchedAt:0}}catch{return null}}function E(f){try{M(a,JSON.stringify({browserPid:f.browserPid,debugPort:f.debugPort,tempDir:f.tempDir,clientPids:[...new Set(f.clientPids.filter((g)=>g>0))],sessionMode:f.sessionMode,lastActivity:f.lastActivity,launchedAt:f.launchedAt},null,2),"utf8")}catch{}try{if(f.browserPid)M(t,String(f.browserPid),"utf8")}catch{}try{M(T,f.sessionMode,"utf8")}catch{}try{M(Y,String(f.lastActivity),"utf8")}catch{}}function mf(){try{k(a)}catch{}try{k(t)}catch{}try{k(T)}catch{}try{k(Y)}catch{}}function Lf(f){if(!f)return f;let g={...f,clientPids:[...new Set([...f.clientPids,process.pid].filter((u)=>C(u)||u===process.pid))]};return E(g),g}function Xf(f){let g=Date.now();try{if(f)E({...f,lastActivity:g});else M(Y,String(g),"utf8")}catch{}}var iu=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5;var Pf=!1;function If(){if(Pf)return;Pf=!0;let f=m();if(!f)return;if(f.browserPid){if(!C(f.browserPid)){mf();return}if(!Rf(f.browserPid,f.tempDir,f.debugPort))mf();else E({...f,clientPids:f.clientPids.filter(($)=>C($))})}let g=u0();if(g&&g!==f.browserPid)if(Rf(g,_,Z))E({browserPid:g,debugPort:Z,tempDir:_,clientPids:[g],sessionMode:f.sessionMode,lastActivity:Date.now(),launchedAt:Date.now()});else return}function Sf(){sg(cf(),{recursive:!0});try{let f=JSON.stringify({pid:process.pid,ts:Date.now()});return M(A,f,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{let g=y(A,"utf8");if(JSON.parse(g).pid===process.pid)k(A)}catch{}}}}catch(f){if(f?.code!=="EEXIST")return{acquired:!1,release:()=>{}}}try{let f=y(A,"utf8"),g=JSON.parse(f),u=Date.now()-(g.ts||0);if(!C(g.pid)||u>f0){try{k(A)}catch{}try{let $=JSON.stringify({pid:process.pid,ts:Date.now()});return M(A,$,{encoding:"utf8",flag:"wx"}),{acquired:!0,release:()=>{try{k(A)}catch{}}}}catch{return{acquired:!1,release:()=>{}}}}}catch{}return{acquired:!1,release:()=>{}}}var o0=import.meta.dirname||new URL(".",import.meta.url).pathname.replace(/^\/([A-Z]:)/,"$1"),Ef=h0().replaceAll("\\","/"),P=`${Ef}/greedysearch-chrome.pid`,c=`${Ef}/greedysearch-chrome-last-activity`,W0=Number.parseInt(process.env.GREEDY_SEARCH_IDLE_TIMEOUT_MINUTES||"5",10)||5,Q0=Number.parseInt(process.env.GREEDY_SEARCH_VISIBLE_IDLE_TIMEOUT_MINUTES||"60",10)||60;function X0(f,g=Z){let u=String(f||"").toLowerCase();if(!u.includes(`--remote-debugging-port=${g}`)||u.includes("--type="))return null;return u.includes("--headless")}function ef(){try{let f=Jf(),g=f?sf(f):null,u=X0(g);if(u!==null){try{e(r,u?"headless":"visible","utf8")}catch{}return u}}catch{}try{if(!s(r))return!0;return d(r,"utf8").trim()==="headless"}catch{return!0}}function l0(){try{e(c,String(Date.now()),"utf8")}catch{}try{let f=m();if(f)Xf(f)}catch{}}function sf(f){try{if(af()==="win32")return Ff(j("powershell"),["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId = ${f}").CommandLine`],{encoding:"utf8",windowsHide:!0,timeout:5000}).trim()||null;return Ff(j("ps"),["-p",String(f),"-o","command="],{encoding:"utf8",timeout:5000}).trim()||null}catch{return null}}function Jf(){return p(Z)}function df(){let f=[Jf()];if(s(P))f.push(Number.parseInt(d(P,"utf8").trim(),10)||null);for(let g of f){if(!g)continue;if(Qf(sf(g),_,Z))return g}return null}async function Z0(f=1500){let g=df();if(!g)return!1;try{let n=await new Promise((w,o)=>{let h=Zf.get(`http://localhost:${Z}/json/version`,(W)=>{let Q="";W.on("data",(l)=>Q+=l),W.on("end",()=>{try{w(JSON.parse(Q))}catch{o(Error("bad JSON"))}})});h.on("error",o),h.setTimeout(1000,()=>{h.destroy(),o(Error("timeout"))})}),$=new globalThis.WebSocket(n.webSocketDebuggerUrl);await new Promise((w)=>{$.onopen=()=>{$.send(JSON.stringify({id:1,method:"Browser.close"})),setTimeout(()=>{$.close(),w()},200)},$.onerror=()=>w(),setTimeout(w,1000)})}catch{}let u=Date.now()+f;while(Date.now()<u){let n=Jf();if(!n)return!0;if(n!==g)return!0;await new Promise(($)=>setTimeout($,150))}return J0()}function J0(){try{let f=df();if(!f)return!1;if(af()==="win32")$0(`${j("taskkill")} /F /PID ${f}`,{stdio:"ignore"});else process.kill(f,"SIGKILL");return!0}catch{return!1}}async function fg(){if(!await v(500)){try{V(P)}catch{}try{V(c)}catch{}try{V(r)}catch{}return!1}let g=await Z0(1500);try{V(P)}catch{}try{V(c)}catch{}try{V(r)}catch{}if(g)process.stderr.write(`[greedysearch] Killed Chrome on port ${Z}.
|
|
246
|
+
`);return g}var pf=fg;async function i0(){let g=ef()?W0:Q0;if(g<=0)return!1;if(!s(c))return l0(),!1;try{let u=Number.parseInt(d(c,"utf8").trim(),10);if(!u)return!1;if((Date.now()-u)/60000>=g)return fg()}catch{}return!1}function v(f=3000){return new Promise((g)=>{let u=Zf.get(`http://localhost:${Z}/json/version`,(n)=>{n.resume(),g(n.statusCode===200)});u.on("error",()=>g(!1)),u.setTimeout(f,()=>{u.destroy(),g(!1)})})}async function lf(){let f=`${O}.lock`,g=`${O}.tmp`,u=5000,n=1000,$=await new Promise((w)=>{let o=Date.now(),h=()=>{try{let W=JSON.stringify({pid:process.pid,ts:Date.now()});e(f,W,{encoding:"utf8",flag:"wx"}),w(!0)}catch(W){if(W?.code!=="EEXIST"){if(Date.now()-o<1000)setTimeout(h,50);else w(!1);return}try{let Q=d(f,"utf8").trim(),l=Q.startsWith("{")?JSON.parse(Q):{ts:Number(Q)},b=Number(l?.ts)||0;if(b>0&&Date.now()-b>5000)try{V(f)}catch{}if(Date.now()-o<1000)setTimeout(h,50);else w(!1)}catch{if(Date.now()-o<1000)setTimeout(h,50);else w(!1)}}};h()});try{let w=await new Promise((Q,l)=>{let b=Zf.get(`http://localhost:${Z}/json/version`,(N)=>{let K="";N.on("data",(H)=>K+=H),N.on("end",()=>Q(K))});b.on("error",l),b.setTimeout(3000,()=>{b.destroy(),l(Error("timeout"))})}),{webSocketDebuggerUrl:o}=JSON.parse(w),h=new URL(o),W=`${h.pathname}${h.search}`;if($){e(g,`localhost:${Z}
|
|
247
|
+
${W}`,"utf8");try{V(O)}catch{}w0(g,O)}}catch{}finally{if($)try{V(f)}catch{}}}async function gg(){let f=s(P)||!!m(),g=await tf({activePortFile:O,modeFile:r,excludePorts:f?[Z]:[]});if(g){process.stderr.write(`[greedysearch] Reusing existing browser CDP endpoint ${g.httpUrl} (${g.source}).
|
|
248
|
+
`);return}If();let u=await i0(),n=u?!1:await v();if(!n&&!u)await new Promise((h)=>setTimeout(h,500)),n=await v();let $=!1;if(n){let h=ef(),W=process.env.GREEDY_SEARCH_VISIBLE==="1";if(!W&&!h)process.stderr.write(`[greedysearch] Visible Chrome detected — switching to headless mode...
|
|
249
|
+
`),await pf(),await new Promise((Q)=>setTimeout(Q,1000)),$=!0;else if(W&&h)process.stderr.write(`[greedysearch] Headless Chrome detected — switching to visible mode...
|
|
250
|
+
`),await pf(),await new Promise((Q)=>setTimeout(Q,1000)),$=!0}if($?!1:await v()){await lf();try{let h=m();if(h)Xf(h),Lf(h)}catch{}return}let o=Sf();if(!o.acquired){let h=Date.now()+15000;while(Date.now()<h)if(await new Promise((W)=>setTimeout(W,250)),await v(1000)){await lf();return}throw Error(`Timed out waiting for another GreedySearch launcher on port ${Z}`)}try{if(await v(1000)){await lf();return}process.stderr.write(`GreedySearch Chrome not running on port ${Z} — auto-launching...
|
|
251
|
+
`);let W=[Tf({moduleDir:o0,entrypoint:process.argv[1]})];if(process.env.GREEDY_SEARCH_VISIBLE!=="1")W.push("--headless");await new Promise((Q,l)=>{n0(xf(),W,{stdio:["ignore",process.stderr,process.stderr]}).on("close",(N)=>N===0?Q():l(Error("launch.mjs failed")))})}finally{o.release()}}var b0=`
|
|
252
252
|
(function() {
|
|
253
253
|
// Google consent page (consent.google.com)
|
|
254
254
|
var g = document.querySelector('#L2AGLb, button[jsname="b3VHJd"], .tHlp8d');
|
|
@@ -265,10 +265,10 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
265
265
|
|
|
266
266
|
return null;
|
|
267
267
|
})()
|
|
268
|
-
`;async function
|
|
268
|
+
`;async function bf(f,g){let u=await g(["eval",f,b0]).catch(()=>null);if(u&&u!=="null")await new Promise((n)=>setTimeout(n,1500))}var B={input:'textarea[name="newMessage"]',submitButton:'button[aria-label="Submit search"]',answerContainer:'div[class*="prose"]',paperCard:'a[data-testid="search-result"]',exportButton:'button[aria-label="Export"]'};async function B0(f){return await X(["eval",f,`(() => {
|
|
269
269
|
const url = document.location.href || '';
|
|
270
270
|
return url.indexOf('/sign-up/') !== -1 || url.indexOf('redirect_url=') !== -1;
|
|
271
|
-
})()`]).catch(()=>"false")==="true"}async function
|
|
271
|
+
})()`]).catch(()=>"false")==="true"}async function ug(f){try{return JSON.parse(await X(["eval",f,`(() => {
|
|
272
272
|
const url = document.location.href || '';
|
|
273
273
|
const title = document.title || '';
|
|
274
274
|
const text = document.body?.innerText || '';
|
|
@@ -279,7 +279,7 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
279
279
|
text.includes('refresh_request_origin_azp_mismatch') ||
|
|
280
280
|
(text.includes('HTTP ERROR 405') && text.includes('This page isn'));
|
|
281
281
|
return JSON.stringify({ stale, url, title, text: text.slice(0, 500) });
|
|
282
|
-
})()`],5000))}catch{return{stale:!1,url:"",title:"",text:""}}}async function
|
|
282
|
+
})()`],5000))}catch{return{stale:!1,url:"",title:"",text:""}}}async function j0(f){for(let g of["https://consensus.app","https://clerk.consensus.app"])await X(["evalraw",f,"Storage.clearDataForOrigin",JSON.stringify({origin:g,storageTypes:"all"})]).catch((u)=>{console.error(`[consensus] Warning: failed to clear stale auth storage for ${g}: ${u.message}`)})}async function ng(f,g,u){let n=await ug(f);if(!n.stale)return!1;if(i(g,"auth-storage-reset",u),console.error(`[consensus] Detected stale Clerk/Consensus auth state (${n.title||n.url}) — clearing per-origin storage and retrying navigation`),g.fallbackUsed="clear-stale-consensus-auth",await j0(f),await X(["nav",f,"https://consensus.app/"],20000),await new Promise((w)=>setTimeout(w,900)),(await ug(f)).stale)throw g.blockedBy="signin",g.verificationResult="needs-human",Error("Consensus auth session is stale — visible Chrome is open. Please sign in again, then rerun the search.");return!0}async function q0(f,g){if(await X(["click",f,B.input]),await new Promise((n)=>setTimeout(n,D(200))),await ff(["type",f,"--stdin"],g),await new Promise((n)=>setTimeout(n,D(300))),await X(["eval",f,`(document.querySelector('${B.input}')?.value || '').length >= ${Math.floor(g.length*0.8)}`])!=="true")throw Error("Consensus input did not accept text — input verification failed")}async function V0(f){let u=await X(["eval",f,`(() => {
|
|
283
283
|
if (window.__pdiInstalled) return 'already';
|
|
284
284
|
window.__pdiInstalled = true;
|
|
285
285
|
const _origOpen = XMLHttpRequest.prototype.open;
|
|
@@ -312,8 +312,8 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
312
312
|
return _origSend.apply(this, arguments);
|
|
313
313
|
};
|
|
314
314
|
return 'installed';
|
|
315
|
-
})()`]);return u==="installed"||u==="already"}async function
|
|
316
|
-
const _deadline = Date.now() + ${
|
|
315
|
+
})()`]);return u==="installed"||u==="already"}async function H0(f,g=1e4){let u=`new Promise((resolve) => {
|
|
316
|
+
const _deadline = Date.now() + ${g};
|
|
317
317
|
function _check() {
|
|
318
318
|
const resps = window.__papersDetailsResps || [];
|
|
319
319
|
if (resps.length > 0) {
|
|
@@ -328,13 +328,13 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
_check();
|
|
331
|
-
})`,
|
|
331
|
+
})`,n=await X(["eval",f,u],g+5000);return JSON.parse(n)}async function _0(f,g=8){if(!await G(f,B.paperCard,20000,500).catch(()=>!1))return console.error("[consensus] Warning: no paper cards appeared within 20s — Load More will be skipped"),0;await new Promise(($)=>setTimeout($,800));let n=0;for(let $=0;$<g;$++){if(await X(["eval",f,`(() => {
|
|
332
332
|
const btns = Array.from(document.querySelectorAll('button'));
|
|
333
333
|
return btns.some(b => {
|
|
334
334
|
const t = (b.innerText || '').trim();
|
|
335
335
|
return /load more/i.test(t) || /more results/i.test(t) || /show more/i.test(t);
|
|
336
336
|
});
|
|
337
|
-
})()`])!=="true")break;await
|
|
337
|
+
})()`])!=="true")break;await X(["eval",f,`(() => {
|
|
338
338
|
const btns = Array.from(document.querySelectorAll('button'));
|
|
339
339
|
const btn = btns.find(b => {
|
|
340
340
|
const t = (b.innerText || '').trim();
|
|
@@ -342,20 +342,20 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
342
342
|
});
|
|
343
343
|
btn?.click();
|
|
344
344
|
return 'clicked';
|
|
345
|
-
})()`]),
|
|
346
|
-
const btn = document.querySelector('${
|
|
345
|
+
})()`]),n++,await new Promise((o)=>setTimeout(o,1500))}return n}async function N0(f){return await X(["eval",f,`(() => {
|
|
346
|
+
const btn = document.querySelector('${B.exportButton}');
|
|
347
347
|
if (!btn) return 'no-export';
|
|
348
348
|
btn.scrollIntoView({ block: 'center' });
|
|
349
349
|
btn.click();
|
|
350
350
|
return 'opened';
|
|
351
|
-
})()`]),await new Promise((u)=>setTimeout(u,600)),await
|
|
351
|
+
})()`]),await new Promise((u)=>setTimeout(u,600)),await X(["eval",f,`(() => {
|
|
352
352
|
const btn = Array.from(document.querySelectorAll('button'))
|
|
353
353
|
.find(b => /\\.CSV/.test((b.innerText || '').trim()));
|
|
354
354
|
if (!btn) return 'no-csv';
|
|
355
355
|
btn.click();
|
|
356
356
|
return 'clicked';
|
|
357
|
-
})()`])}function
|
|
358
|
-
const cards = Array.from(document.querySelectorAll('${
|
|
357
|
+
})()`])}function K0(f){let g=f?.paperDetailsListByPaperId||{},u=Object.keys(g),n=[];for(let $=0;$<u.length;$++){let w=g[u[$]]||{},o=w.url_slug||"",h=w.paper_id||w.hash_paper_id||u[$],W;if(o)W=`https://consensus.app/papers/${o}/${h}/`;else if(w.provider_url)W=w.provider_url;else if(w.doi)W=`https://doi.org/${w.doi}`;else W=`https://consensus.app/paper/${h}`;let Q=[],l=w.badges||{};if(l.study_type==="rct")Q.push("RCT");else if(l.study_type==="meta_analysis")Q.push("META-ANALYSIS");else if(l.study_type==="systematic_review")Q.push("SYSTEMATIC REVIEW");else if(l.study_type)Q.push(l.study_type.toUpperCase());if(l.rigorous_journal)Q.push("RIGOROUS JOURNAL");if(l.very_rigorous_journal)Q.push("VERY RIGOROUS JOURNAL");if(l.highly_cited_paper)Q.push("HIGHLY CITED");if(l.large_human_trial)Q.push("LARGE HUMAN TRIAL");if(w.is_retracted)Q.push("RETRACTED");if(w.open_access_pdf_url)Q.push("OPEN ACCESS");n.push({title:w.title||"",url:W,rank:$+1,authors:Array.isArray(w.authors)?w.authors:[],year:w.year||null,journal:w.journal||w.publisher_name||null,doi:w.doi||null,citation_count:w.citation_count||0,snippet:w.abstract_takeaway||"",tags:Q})}return n}async function $g(f){let g=`(() => {
|
|
358
|
+
const cards = Array.from(document.querySelectorAll('${B.paperCard}'));
|
|
359
359
|
const sources = [];
|
|
360
360
|
const seen = new Set();
|
|
361
361
|
for (const card of cards) {
|
|
@@ -377,8 +377,8 @@ ${r}`,"utf8");try{B(k)}catch{}af(f,k)}}catch{}finally{if(i)try{B(n)}catch{}}}asy
|
|
|
377
377
|
sources.push({ title, url, rank, snippet, tags });
|
|
378
378
|
}
|
|
379
379
|
return JSON.stringify(sources);
|
|
380
|
-
})()`,u=await
|
|
381
|
-
const prose = document.querySelector('${
|
|
380
|
+
})()`,u=await X(["eval",f,g],1e4);return JSON.parse(u)}async function U0(f){let g=`(() => {
|
|
381
|
+
const prose = document.querySelector('${B.answerContainer}');
|
|
382
382
|
return prose?.innerText?.trim() || '';
|
|
383
|
-
})()`;return await
|
|
384
|
-
`;async function
|
|
383
|
+
})()`;return await X(["eval",f,g],1e4)||""}var r0=`Usage: node extractors/consensus.mjs "<query>" [--tab <prefix>]
|
|
384
|
+
`;async function x0(){let f=await Hf(process.argv.slice(2));Nf(f,r0);let{query:g,tabPrefix:u,short:n}=_f(f),$=Date.now(),o={engine:"consensus",mode:process.env.GREEDY_SEARCH_VISIBLE==="1"?"visible":"headless",clipboardEmpty:null,fallbackUsed:null,blockedBy:null,verificationResult:null,inputReady:null};try{if(process.env.GREEDY_SEARCH_VISIBLE!=="1"&&process.env.GREEDY_SEARCH_ALWAYS_VISIBLE!=="1")process.env.GREEDY_SEARCH_HEADLESS="1";if(await gg(),!u)await X(["list"]);let h=await qf(u),W=await X(["eval",h,"document.location.href"]).catch(()=>""),Q=!1;try{let J=new URL(W).hostname.toLowerCase();Q=J==="consensus.app"||J.endsWith(".consensus.app")}catch{}if(!Q)i(o,"nav",$),await X(["nav",h,"https://consensus.app/"],20000),await new Promise((J)=>setTimeout(J,600));await ng(h,o,$),await bf(h,X),i(o,"input-wait",$);let l=await G(h,B.input,15000,400);if(o.inputReady=l,!l)if(await ng(h,o,$)){let L=await G(h,B.input,15000,400);if(o.inputReady=L,L)await bf(h,X);else throw Error("Consensus input not found after stale auth recovery — page may not have loaded or is in unexpected state")}else throw Error("Consensus input not found — page may not have loaded or is in unexpected state");if(await new Promise((J)=>setTimeout(J,D(gf.postClick))),i(o,"type-and-submit",$),await q0(h,g),await new Promise((J)=>setTimeout(J,D(gf.postType))),await X(["eval",h,`document.querySelector('${B.submitButton}')?.click()`]),await new Promise((J)=>setTimeout(J,2000)),await B0(h))throw o.blockedBy="signin",Error("Consensus requires sign-in — please sign in or create a free account in the visible browser window. Once signed in, cookies persist for future runs.");i(o,"answer-wait",$),await G(h,B.answerContainer,30000,500),await V0(h),i(o,"expand-refs",$);let b=await _0(h,8);if(b===0)console.error("[consensus] Note: 'Load more results' button not present (initial page has all references)");else console.error(`[consensus] Clicked 'Load more results' ${b} time(s) to expand references`);await new Promise((J)=>setTimeout(J,1500)),i(o,"csv-click",$);let N=await N0(h);if(N!=="clicked")console.error(`[consensus] Export → .CSV click did not register (${N}) — falling back to DOM`);i(o,"wait-csv-resp",$);let K=await H0(h,12000),H=[],Bf="dom";if(K.ok)H=K0(K.data),Bf="api-intercept",console.error(`[consensus] Captured /api/papers/details/ response with ${K.count} paper(s)`);else console.error(`[consensus] /api/papers/details/ response not captured (${K.reason}) — falling back to DOM cards`);i(o,"extract",$);let jf=await U0(h);if(!jf)throw Error("No answer extracted — Consensus may not have responded");if(H.length===0)H=await $g(h);else{let J=await $g(h),L=new Set(H.map((I)=>I.url));for(let I of J)if(!L.has(I.url))H.push(I)}let wg=await X(["eval",h,"document.location.href"]).catch(()=>"");o.durationMs=Date.now()-$,o.sourcePath=Bf,i(o,"done",$),Uf({query:g,url:wg,answer:Kf(jf,n),sources:H,_envelope:uf(o)})}catch(h){o.durationMs=Date.now()-$,rf(h,uf(o))}}x0();
|