thebird 1.2.79 → 1.2.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.github/workflows/publish.yml +9 -1
  2. package/CHANGELOG.md +217 -0
  3. package/CLAUDE.md +16 -0
  4. package/docs/agent-chat.js +7 -4
  5. package/docs/app.js +14 -11
  6. package/docs/defaults.json +1 -1
  7. package/docs/index.html +23 -6
  8. package/docs/kilo-http-stream.js +24 -0
  9. package/docs/node-builtins.js +24 -0
  10. package/docs/preview/index.html +32 -0
  11. package/docs/preview-sw-client.js +37 -6
  12. package/docs/preview-sw.js +55 -51
  13. package/docs/shell-awk.js +113 -0
  14. package/docs/shell-builtins-extra.js +121 -0
  15. package/docs/shell-builtins-text.js +109 -0
  16. package/docs/shell-builtins-util.js +112 -0
  17. package/docs/shell-builtins.js +183 -0
  18. package/docs/shell-bun.js +45 -0
  19. package/docs/shell-control.js +132 -0
  20. package/docs/shell-deno.js +54 -0
  21. package/docs/shell-exec.js +85 -0
  22. package/docs/shell-expand.js +164 -0
  23. package/docs/shell-fd.js +86 -0
  24. package/docs/shell-jobs.js +86 -0
  25. package/docs/shell-node-advanced.js +86 -0
  26. package/docs/shell-node-brotli.js +22 -0
  27. package/docs/shell-node-busnet.js +90 -0
  28. package/docs/shell-node-cipher.js +61 -0
  29. package/docs/shell-node-cluster.js +33 -0
  30. package/docs/shell-node-coreutils.js +36 -0
  31. package/docs/shell-node-crypto.js +137 -0
  32. package/docs/shell-node-dns.js +41 -0
  33. package/docs/shell-node-extras.js +148 -0
  34. package/docs/shell-node-firefox.js +95 -0
  35. package/docs/shell-node-git.js +60 -0
  36. package/docs/shell-node-inspector.js +39 -0
  37. package/docs/shell-node-io.js +131 -0
  38. package/docs/shell-node-ipc.js +15 -0
  39. package/docs/shell-node-keyobject.js +60 -0
  40. package/docs/shell-node-modules.js +157 -0
  41. package/docs/shell-node-native.js +31 -0
  42. package/docs/shell-node-net.js +71 -0
  43. package/docs/shell-node-observe.js +80 -0
  44. package/docs/shell-node-opfs.js +54 -0
  45. package/docs/shell-node-procfs.js +42 -0
  46. package/docs/shell-node-profiler.js +50 -0
  47. package/docs/shell-node-registry.js +24 -0
  48. package/docs/shell-node-resolve.js +147 -0
  49. package/docs/shell-node-runtime.js +83 -0
  50. package/docs/shell-node-srcmap.js +52 -0
  51. package/docs/shell-node-stdlib.js +103 -0
  52. package/docs/shell-node-streams.js +66 -0
  53. package/docs/shell-node-tar.js +47 -0
  54. package/docs/shell-node-testrunner.js +35 -0
  55. package/docs/shell-node-util-extras.js +66 -0
  56. package/docs/shell-node.js +175 -169
  57. package/docs/shell-npm.js +173 -0
  58. package/docs/shell-parser.js +122 -0
  59. package/docs/shell-pm-layout.js +62 -0
  60. package/docs/shell-pm.js +39 -0
  61. package/docs/shell-posix.js +70 -0
  62. package/docs/shell-procsub.js +65 -0
  63. package/docs/shell-readline.js +59 -4
  64. package/docs/shell-runtime.js +37 -0
  65. package/docs/shell-sed.js +83 -0
  66. package/docs/shell-signals.js +54 -0
  67. package/docs/shell-sw-jobs.js +76 -0
  68. package/docs/shell-ts.js +30 -0
  69. package/docs/shell.js +161 -152
  70. package/docs/terminal.js +9 -11
  71. package/docs/todo.html +211 -0
  72. package/package.json +1 -1
  73. package/server.js +43 -4
  74. package/start-kilo.js +17 -0
  75. package/test.js +199 -0
  76. package/.codeinsight +0 -73
  77. package/docs/acp-stream.js +0 -102
  78. package/docs/coi-serviceworker.js +0 -2
@@ -0,0 +1,61 @@
1
+ const ALG_MAP={
2
+ 'aes-128-gcm':{name:'AES-GCM',length:128},'aes-192-gcm':{name:'AES-GCM',length:192},'aes-256-gcm':{name:'AES-GCM',length:256},
3
+ 'aes-128-cbc':{name:'AES-CBC',length:128},'aes-192-cbc':{name:'AES-CBC',length:192},'aes-256-cbc':{name:'AES-CBC',length:256},
4
+ 'aes-128-ctr':{name:'AES-CTR',length:128},'aes-256-ctr':{name:'AES-CTR',length:256},
5
+ };
6
+ const toBytes=d=>typeof d==='string'?new TextEncoder().encode(d):d instanceof Uint8Array?d:new Uint8Array(d);
7
+ const concat=list=>{const t=list.reduce((s,c)=>s+c.length,0);const out=new Uint8Array(t);let o=0;for(const c of list){out.set(c,o);o+=c.length;}return out;};
8
+
9
+ async function importKey(alg,keyBytes,usages){
10
+ return crypto.subtle.importKey('raw',keyBytes,{name:alg.name,length:alg.length},false,usages);
11
+ }
12
+
13
+ function makeCipher(alg,keyBytes,iv,decrypt=false){
14
+ const spec=ALG_MAP[alg];
15
+ if(!spec)throw new Error(`cipher algorithm not supported: ${alg}`);
16
+ const chunks=[];let authTag=null;let aad=null;let final=null;
17
+ const usage=decrypt?['decrypt']:['encrypt'];
18
+ return {
19
+ update(data,inputEnc,outputEnc){const bytes=inputEnc?Buffer.from(data,inputEnc):toBytes(data);chunks.push(bytes);return Buffer.alloc(0);},
20
+ async final(enc){const input=concat(chunks);const key=await importKey(spec,toBytes(keyBytes),usage);const params={name:spec.name,iv:toBytes(iv)};if(spec.name==='AES-GCM'&&aad)params.additionalData=aad;if(decrypt&&spec.name==='AES-GCM'&&authTag){const full=concat([input,authTag]);const out=new Uint8Array(await crypto.subtle.decrypt(params,key,full));return enc?Buffer.from(out).toString(enc):Buffer.from(out);}const op=decrypt?crypto.subtle.decrypt.bind(crypto.subtle):crypto.subtle.encrypt.bind(crypto.subtle);const out=new Uint8Array(await op(params,key,input));if(!decrypt&&spec.name==='AES-GCM'){authTag=out.slice(-16);const ct=out.slice(0,-16);final=Buffer.from(ct);return enc?final.toString(enc):final;}return enc?Buffer.from(out).toString(enc):Buffer.from(out);},
21
+ setAAD(d){aad=toBytes(d);return this;},
22
+ setAuthTag(t){authTag=toBytes(t);return this;},
23
+ getAuthTag(){return authTag?Buffer.from(authTag):null;},
24
+ setAutoPadding(){return this;},
25
+ };
26
+ }
27
+
28
+ export function extendCrypto(cryptoMod,Buf){
29
+ globalThis.Buffer=globalThis.Buffer||Buf;
30
+ cryptoMod.createCipheriv=(alg,key,iv)=>makeCipher(alg.toLowerCase(),key,iv,false);
31
+ cryptoMod.createDecipheriv=(alg,key,iv)=>makeCipher(alg.toLowerCase(),key,iv,true);
32
+ cryptoMod.createCipher=()=>{throw new Error('crypto.createCipher: deprecated and unsafe — use createCipheriv');};
33
+ cryptoMod.createDecipher=()=>{throw new Error('crypto.createDecipher: deprecated — use createDecipheriv');};
34
+ cryptoMod.generateKeyPair=(type,opts,cb)=>{cryptoMod.generateKeyPairAsync?.(type,opts).then(r=>cb(null,r.publicKey,r.privateKey),cb);};
35
+ cryptoMod.generateKeyPairSync=()=>{throw new Error('crypto.generateKeyPairSync: synchronous keypair generation not available in browser — use generateKeyPair (async)');};
36
+ cryptoMod.generateKeyPairAsync=async(type,opts={})=>{const algMap={rsa:{name:'RSASSA-PKCS1-v1_5',modulusLength:opts.modulusLength||2048,publicExponent:new Uint8Array([1,0,1]),hash:'SHA-256'},ec:{name:'ECDSA',namedCurve:opts.namedCurve||'P-256'}};const alg=algMap[type];if(!alg)throw new Error(`unsupported key type: ${type}`);const kp=await crypto.subtle.generateKey(alg,true,type==='rsa'?['sign','verify']:['sign','verify']);const pub=new Uint8Array(await crypto.subtle.exportKey('spki',kp.publicKey));const priv=new Uint8Array(await crypto.subtle.exportKey('pkcs8',kp.privateKey));const pem=(b,label)=>`-----BEGIN ${label}-----\n${btoa(String.fromCharCode(...b)).match(/.{1,64}/g).join('\n')}\n-----END ${label}-----\n`;return {publicKey:pem(pub,'PUBLIC KEY'),privateKey:pem(priv,'PRIVATE KEY')};};
37
+ const pemToBytes=pem=>{const m=pem.match(/-----BEGIN [^-]+-----([\s\S]+?)-----END/);if(!m)throw new Error('invalid PEM');return Uint8Array.from(atob(m[1].replace(/\s/g,'')),c=>c.charCodeAt(0));};
38
+ const hashFromAlg=a=>{const u=a.toUpperCase();if(u.includes('SHA512')||u.includes('SHA-512'))return'SHA-512';if(u.includes('SHA384')||u.includes('SHA-384'))return'SHA-384';if(u.includes('SHA1')||u.includes('SHA-1'))return'SHA-1';return'SHA-256';};
39
+ const isEcBytes=bytes=>{const s=String.fromCharCode(...bytes.slice(0,Math.min(bytes.length,80)));return s.includes('\x2A\x86\x48\xCE\x3D\x02\x01');};
40
+ const importForSign=async(pem,hash)=>{const bytes=pemToBytes(pem);const ec=isEcBytes(bytes);const params=ec?{name:'ECDSA',namedCurve:'P-256'}:{name:'RSASSA-PKCS1-v1_5',hash};const k=await crypto.subtle.importKey('pkcs8',bytes,params,false,['sign']);return{key:k,alg:ec?{name:'ECDSA',hash}:{name:'RSASSA-PKCS1-v1_5'}};};
41
+ const importForVerify=async(pem,hash)=>{const bytes=pemToBytes(pem);const ec=isEcBytes(bytes);const params=ec?{name:'ECDSA',namedCurve:'P-256'}:{name:'RSASSA-PKCS1-v1_5',hash};const k=await crypto.subtle.importKey('spki',bytes,params,false,['verify']);return{key:k,alg:ec?{name:'ECDSA',hash}:{name:'RSASSA-PKCS1-v1_5'}};};
42
+ cryptoMod.signAsync=async(alg,data,keyPem)=>{const pem=typeof keyPem==='string'?keyPem:keyPem.key;const {key,alg:a}=await importForSign(pem,hashFromAlg(alg));const sig=await crypto.subtle.sign(a,key,toBytes(data));return Buf.from(new Uint8Array(sig));};
43
+ cryptoMod.verifyAsync=async(alg,data,keyPem,sig)=>{const pem=typeof keyPem==='string'?keyPem:keyPem.key;const {key,alg:a}=await importForVerify(pem,hashFromAlg(alg));return crypto.subtle.verify(a,key,toBytes(sig),toBytes(data));};
44
+ cryptoMod.hkdf=(digest,ikm,salt,info,keylen,cb)=>{cryptoMod.hkdfAsync(digest,ikm,salt,info,keylen).then(r=>cb(null,r),cb);};
45
+ cryptoMod.hkdfSync=()=>{throw new Error('crypto.hkdfSync: use async hkdf in browser (webcrypto is async-only)');};
46
+ cryptoMod.hkdfAsync=async(digest,ikm,salt,info,keylen)=>{const hash=hashFromAlg(digest);const k=await crypto.subtle.importKey('raw',toBytes(ikm),'HKDF',false,['deriveBits']);const bits=await crypto.subtle.deriveBits({name:'HKDF',hash,salt:toBytes(salt),info:toBytes(info)},k,keylen*8);return Buf.from(new Uint8Array(bits));};
47
+ cryptoMod.createECDH=curve=>{const nc=curve==='prime256v1'?'P-256':curve==='secp384r1'?'P-384':curve==='secp521r1'?'P-521':curve;let kp=null;return{generateKeys:async()=>{kp=await crypto.subtle.generateKey({name:'ECDH',namedCurve:nc},true,['deriveBits']);const pub=await crypto.subtle.exportKey('raw',kp.publicKey);return Buf.from(new Uint8Array(pub));},getPublicKey:async()=>{if(!kp)throw new Error('generateKeys first');const pub=await crypto.subtle.exportKey('raw',kp.publicKey);return Buf.from(new Uint8Array(pub));},computeSecret:async otherPub=>{if(!kp)throw new Error('generateKeys first');const other=await crypto.subtle.importKey('raw',toBytes(otherPub),{name:'ECDH',namedCurve:nc},false,[]);const bits=await crypto.subtle.deriveBits({name:'ECDH',public:other},kp.privateKey,256);return Buf.from(new Uint8Array(bits));}};};
48
+ cryptoMod.createDiffieHellman=()=>{throw new Error('crypto.createDiffieHellman: classic modp DH not supported — use createECDH(\'prime256v1\')');};
49
+ cryptoMod.sign=(alg,data,key,cb)=>{if(cb)cryptoMod.signAsync(alg,data,key).then(r=>cb(null,r),cb);else return cryptoMod.signAsync(alg,data,key);};
50
+ cryptoMod.verify=(alg,data,key,sig,cb)=>{if(cb)cryptoMod.verifyAsync(alg,data,key,sig).then(r=>cb(null,r),cb);else return cryptoMod.verifyAsync(alg,data,key,sig);};
51
+ cryptoMod.createSign=alg=>{const parts=[];return{update(d){parts.push(toBytes(d));return this;},async sign(key,enc){const data=concat(parts);const sig=await cryptoMod.signAsync(alg,data,key);return enc?sig.toString(enc):sig;}};};
52
+ cryptoMod.createVerify=alg=>{const parts=[];return{update(d){parts.push(toBytes(d));return this;},async verify(key,sig,enc){const data=concat(parts);const sigBytes=typeof sig==='string'?Buf.from(sig,enc):sig;return cryptoMod.verifyAsync(alg,data,key,sigBytes);}};};
53
+ cryptoMod.getCiphers=()=>Object.keys(ALG_MAP);
54
+ cryptoMod.getHashes=()=>['sha1','sha256','sha512','md5'];
55
+ cryptoMod.getCurves=()=>['P-256','P-384','P-521'];
56
+ cryptoMod.timingSafeEqual=(a,b)=>{if(a.length!==b.length)return false;let r=0;for(let i=0;i<a.length;i++)r|=a[i]^b[i];return r===0;};
57
+ cryptoMod.diffieHellman=()=>{throw new Error('crypto.diffieHellman: use webcrypto ECDH')};
58
+ cryptoMod.scrypt=(pw,salt,len,opts,cb)=>{if(typeof opts==='function'){cb=opts;opts={};}queueMicrotask(()=>{try{const k=cryptoMod.pbkdf2Sync(pw,salt,16384,len,'sha256');cb(null,Buf.from(k));}catch(e){cb(e);}});};
59
+ cryptoMod.scryptSync=(pw,salt,len)=>Buf.from(cryptoMod.pbkdf2Sync(pw,salt,16384,len,'sha256'));
60
+ return cryptoMod;
61
+ }
@@ -0,0 +1,33 @@
1
+ const CHANNEL='plugkit-cluster';
2
+ const isWorkerUrl=()=>typeof location!=='undefined'&&location.hash==='#cluster-worker';
3
+
4
+ export function makeCluster(){
5
+ if(typeof BroadcastChannel==='undefined')return null;
6
+ const bc=new BroadcastChannel(CHANNEL);
7
+ const workers=new Map();let nextId=1;
8
+ const isMaster=!isWorkerUrl();
9
+ const handlers={message:[],exit:[],online:[],listening:[],disconnect:[]};
10
+ const onBC=e=>{const{from,to,type,data,id}=e.data||{};if(isMaster){if(to==='master'){const w=workers.get(from);if(!w)return;if(type==='ready'){w.state='online';for(const f of handlers.online)f(w);for(const f of w._h.online||[])f();}if(type==='message'){for(const f of handlers.message)f(w,data);for(const f of w._h.message||[])f(data);}if(type==='exit'){w.state='dead';for(const f of handlers.exit)f(w,data?.code||0);for(const f of w._h.exit||[])f(data?.code||0);workers.delete(from);}}}else{if(to==='worker'||to==='all'){if(type==='message')for(const f of workerHandlers.message)f(data);}}};
11
+ bc.addEventListener('message',onBC);
12
+ const workerHandlers={message:[]};
13
+ const cluster={
14
+ isMaster,
15
+ isPrimary:isMaster,
16
+ isWorker:!isMaster,
17
+ workers:{},
18
+ SCHED_RR:1,SCHED_NONE:0,
19
+ schedulingPolicy:1,
20
+ settings:{},
21
+ setupMaster:opts=>Object.assign(cluster.settings,opts||{}),
22
+ setupPrimary:opts=>Object.assign(cluster.settings,opts||{}),
23
+ fork(env){if(!isMaster)throw new Error('cluster.fork: only master can fork');const id=nextId++;const w={id,state:'starting',_h:{},process:{pid:id,send:(msg)=>{bc.postMessage({from:'master',to:id,type:'message',data:msg});return true;},kill:()=>{bc.postMessage({from:'master',to:id,type:'kill'});}},send(msg){return this.process.send(msg);},on(ev,fn){(this._h[ev]=this._h[ev]||[]).push(fn);return this;},disconnect(){bc.postMessage({from:'master',to:id,type:'disconnect'});},kill(){this.process.kill();}};workers.set(id,w);cluster.workers[id]=w;const url=(cluster.settings.exec||location.href.split('#')[0])+'#cluster-worker';try{window.open(url,'_blank','noopener');}catch{}return w;},
24
+ disconnect(cb){for(const w of workers.values())w.disconnect();cb&&cb();},
25
+ on(ev,fn){(handlers[ev]=handlers[ev]||[]).push(fn);return cluster;},
26
+ worker:isMaster?null:{id:0,process:{send:msg=>{bc.postMessage({from:0,to:'master',type:'message',data:msg});return true;},on(ev,fn){if(ev==='message')workerHandlers.message.push(fn);}}},
27
+ _bc:bc,
28
+ _workerSend:msg=>bc.postMessage({from:0,to:'master',type:'message',data:msg}),
29
+ _workerReady:()=>bc.postMessage({from:0,to:'master',type:'ready'}),
30
+ };
31
+ if(!isMaster)queueMicrotask(()=>cluster._workerReady());
32
+ return cluster;
33
+ }
@@ -0,0 +1,36 @@
1
+ export function makeCoreutils(ctx,procFs){
2
+ const term=ctx.term;
3
+ const out=s=>term.write(s+'\r\n');
4
+ return{
5
+ uname:args=>{const flags=args.join('');const info={kernel:'Linux',node:'thebird',release:'6.0.0-browser',version:'#1 SMP',machine:'x86_64',os:'thebird'};if(flags.includes('a'))out(`${info.kernel} ${info.node} ${info.release} ${info.version} ${info.machine} ${info.os}`);else if(flags.includes('r'))out(info.release);else if(flags.includes('n'))out(info.node);else if(flags.includes('m'))out(info.machine);else if(flags.includes('s'))out(info.kernel);else if(flags.includes('o'))out(info.os);else out(info.kernel);return 0;},
6
+ whoami:()=>{out(ctx.env.USER||'root');return 0;},
7
+ hostname:args=>{if(args[0]){ctx.env.HOSTNAME=args[0];return 0;}out(ctx.env.HOSTNAME||'thebird');return 0;},
8
+ id:args=>{out('uid=0(root) gid=0(root) groups=0(root)');return 0;},
9
+ df:args=>{const used=performance.memory?.usedJSHeapSize||5e8;const total=performance.memory?.jsHeapSizeLimit||2e9;out('Filesystem 1K-blocks Used Available Use% Mounted on');out(`idbfs ${(total/1024)|0} ${(used/1024)|0} ${((total-used)/1024)|0} ${((used/total)*100)|0}% /`);return 0;},
10
+ free:args=>{const m=performance.memory||{totalJSHeapSize:1e9,usedJSHeapSize:5e8,jsHeapSizeLimit:2e9};const kb=n=>(n/1024)|0;out(' total used free shared buff/cache available');out(`Mem: ${kb(m.jsHeapSizeLimit).toString().padStart(11)} ${kb(m.usedJSHeapSize).toString().padStart(11)} ${kb(m.jsHeapSizeLimit-m.usedJSHeapSize).toString().padStart(11)} 0 0 ${kb(m.jsHeapSizeLimit-m.usedJSHeapSize).toString().padStart(11)}`);out('Swap: 0 0 0');return 0;},
11
+ uptime:args=>{const sec=(performance.now()/1000)|0;const h=(sec/3600)|0,m=((sec%3600)/60)|0;out(`${new Date().toTimeString().slice(0,8)} up ${h}:${String(m).padStart(2,'0')}, 1 user, load average: 0.00, 0.00, 0.00`);return 0;},
12
+ ps:args=>{out(' PID TTY TIME CMD');out(' 1 pts/0 00:00:00 sh');out(' 2 pts/0 00:00:00 ps');return 0;},
13
+ nproc:args=>{out(String(navigator?.hardwareConcurrency||1));return 0;},
14
+ arch:()=>{out('x86_64');return 0;},
15
+ yes:args=>{const s=args.length?args.join(' '):'y';for(let i=0;i<1000;i++)out(s);return 0;},
16
+ true:()=>0,
17
+ false:()=>1,
18
+ sleep:args=>new Promise(r=>setTimeout(()=>r(0),(parseFloat(args[0])||0)*1000)),
19
+ seq:args=>{const[first,...rest]=args.map(Number);const last=rest.length?rest[rest.length-1]:first;const step=rest.length===2?rest[0]:1;const start=rest.length?first:1;for(let i=start;step>0?i<=last:i>=last;i+=step)out(String(i));return 0;},
20
+ tac:args=>{if(args[0]){const c=ctx.readFile?.(args[0])||'';out(c.split('\n').reverse().join('\n'));}return 0;},
21
+ rev:args=>{if(args[0]){const c=ctx.readFile?.(args[0])||'';for(const line of c.split('\n'))out([...line].reverse().join(''));}return 0;},
22
+ nl:args=>{if(args[0]){const c=ctx.readFile?.(args[0])||'';c.split('\n').forEach((line,i)=>out(` ${i+1}\t${line}`));}return 0;},
23
+ fold:args=>{const w=args.includes('-w')?parseInt(args[args.indexOf('-w')+1])||80:80;const text=args.filter(a=>!a.startsWith('-'))[0];if(text){const c=ctx.readFile?.(text)||'';for(const line of c.split('\n'))for(let i=0;i<line.length;i+=w)out(line.slice(i,i+w));}return 0;},
24
+ tr:args=>{return 0;},
25
+ od:args=>{if(args[0]){const c=ctx.readFile?.(args[0])||'';const b=typeof c==='string'?new TextEncoder().encode(c):c;for(let i=0;i<b.length;i+=16){const hex=[...b.slice(i,i+16)].map(x=>x.toString(16).padStart(2,'0')).join(' ');out(i.toString(8).padStart(7,'0')+' '+hex);}}return 0;},
26
+ xxd:args=>{if(args[0]){const c=ctx.readFile?.(args[0])||'';const b=typeof c==='string'?new TextEncoder().encode(c):c;for(let i=0;i<b.length;i+=16){const row=b.slice(i,i+16);const hex=[...row].map(x=>x.toString(16).padStart(2,'0')).join(' ').padEnd(47);const asc=[...row].map(x=>x>=0x20&&x<0x7f?String.fromCharCode(x):'.').join('');out(i.toString(16).padStart(8,'0')+': '+hex+' '+asc);}}return 0;},
27
+ dirname:args=>{out((args[0]||'').replace(/\/[^/]*$/,'')||'.');return 0;},
28
+ basename:args=>{const p=args[0]||'';const ext=args[1]||'';let b=p.split('/').pop()||'';if(ext&&b.endsWith(ext))b=b.slice(0,-ext.length);out(b);return 0;},
29
+ pwd:()=>{out(ctx.cwd||'/');return 0;},
30
+ groups:()=>{out('root');return 0;},
31
+ logname:()=>{out('root');return 0;},
32
+ tty:()=>{out('/dev/pts/0');return 0;},
33
+ stty:()=>0,
34
+ locale:()=>{out('LANG=C\nLC_ALL=\n');return 0;},
35
+ };
36
+ }
@@ -0,0 +1,137 @@
1
+ const K256 = new Uint32Array([0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2]);
2
+ const rotr32 = (x, n) => (x >>> n) | (x << (32 - n));
3
+
4
+ function padMsg(msg, blockSize, lenBytes, little = false) {
5
+ const bitLen = msg.length * 8;
6
+ const padLen = ((msg.length + lenBytes + 1 + blockSize - 1) & ~(blockSize - 1));
7
+ const p = new Uint8Array(padLen); p.set(msg); p[msg.length] = 0x80;
8
+ const v = new DataView(p.buffer);
9
+ if (little) { v.setUint32(padLen - 8, bitLen >>> 0, true); v.setUint32(padLen - 4, Math.floor(bitLen / 0x100000000), true); }
10
+ else { v.setUint32(padLen - 4, bitLen >>> 0); v.setUint32(padLen - 8, Math.floor(bitLen / 0x100000000)); }
11
+ return p;
12
+ }
13
+
14
+ export function sha1(msg) {
15
+ const p = padMsg(msg, 64, 8); const v = new DataView(p.buffer);
16
+ let h0 = 0x67452301, h1 = 0xefcdab89, h2 = 0x98badcfe, h3 = 0x10325476, h4 = 0xc3d2e1f0;
17
+ const W = new Uint32Array(80);
18
+ for (let i = 0; i < p.length; i += 64) {
19
+ for (let j = 0; j < 16; j++) W[j] = v.getUint32(i + j * 4);
20
+ for (let j = 16; j < 80; j++) W[j] = rotr32(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 31);
21
+ let a = h0, b = h1, c = h2, d = h3, e = h4;
22
+ for (let j = 0; j < 80; j++) {
23
+ const f = j < 20 ? (b & c) | (~b & d) : j < 40 ? b ^ c ^ d : j < 60 ? (b & c) | (b & d) | (c & d) : b ^ c ^ d;
24
+ const k = j < 20 ? 0x5a827999 : j < 40 ? 0x6ed9eba1 : j < 60 ? 0x8f1bbcdc : 0xca62c1d6;
25
+ const t = (rotr32(a, 27) + f + e + k + W[j]) >>> 0;
26
+ e = d; d = c; c = rotr32(b, 2); b = a; a = t;
27
+ }
28
+ h0 = (h0 + a) >>> 0; h1 = (h1 + b) >>> 0; h2 = (h2 + c) >>> 0; h3 = (h3 + d) >>> 0; h4 = (h4 + e) >>> 0;
29
+ }
30
+ const out = new Uint8Array(20); const ov = new DataView(out.buffer);
31
+ ov.setUint32(0, h0); ov.setUint32(4, h1); ov.setUint32(8, h2); ov.setUint32(12, h3); ov.setUint32(16, h4);
32
+ return out;
33
+ }
34
+
35
+ export function sha256(msg) {
36
+ const p = padMsg(msg, 64, 8); const v = new DataView(p.buffer);
37
+ const H = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
38
+ const W = new Uint32Array(64);
39
+ for (let i = 0; i < p.length; i += 64) {
40
+ for (let j = 0; j < 16; j++) W[j] = v.getUint32(i + j * 4);
41
+ for (let j = 16; j < 64; j++) { const s0 = rotr32(W[j-15], 7) ^ rotr32(W[j-15], 18) ^ (W[j-15] >>> 3); const s1 = rotr32(W[j-2], 17) ^ rotr32(W[j-2], 19) ^ (W[j-2] >>> 10); W[j] = (W[j-16] + s0 + W[j-7] + s1) >>> 0; }
42
+ let [a, b, c, d, e, f, g, h] = H;
43
+ for (let j = 0; j < 64; j++) { const S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25); const ch = (e & f) ^ (~e & g); const t1 = (h + S1 + ch + K256[j] + W[j]) >>> 0; const S0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22); const mj = (a & b) ^ (a & c) ^ (b & c); const t2 = (S0 + mj) >>> 0; h = g; g = f; f = e; e = (d + t1) >>> 0; d = c; c = b; b = a; a = (t1 + t2) >>> 0; }
44
+ H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h;
45
+ }
46
+ const out = new Uint8Array(32);
47
+ for (let i = 0; i < 8; i++) new DataView(out.buffer).setUint32(i * 4, H[i]);
48
+ return out;
49
+ }
50
+
51
+ export function md5(msg) {
52
+ const p = padMsg(msg, 64, 8, true); const v = new DataView(p.buffer);
53
+ let a0 = 0x67452301, b0 = 0xefcdab89, c0 = 0x98badcfe, d0 = 0x10325476;
54
+ const s = [7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21];
55
+ const K = new Uint32Array([0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391]);
56
+ for (let i = 0; i < p.length; i += 64) {
57
+ const M = new Uint32Array(16); for (let j = 0; j < 16; j++) M[j] = v.getUint32(i + j * 4, true);
58
+ let A = a0, B = b0, C = c0, D = d0;
59
+ for (let j = 0; j < 64; j++) { let F, g; if (j < 16) { F = (B & C) | (~B & D); g = j; } else if (j < 32) { F = (D & B) | (~D & C); g = (5 * j + 1) % 16; } else if (j < 48) { F = B ^ C ^ D; g = (3 * j + 5) % 16; } else { F = C ^ (B | ~D); g = (7 * j) % 16; }
60
+ F = (F + A + K[j] + M[g]) >>> 0; A = D; D = C; C = B; B = (B + (((F << s[j]) | (F >>> (32 - s[j]))) >>> 0)) >>> 0;
61
+ }
62
+ a0 = (a0 + A) >>> 0; b0 = (b0 + B) >>> 0; c0 = (c0 + C) >>> 0; d0 = (d0 + D) >>> 0;
63
+ }
64
+ const out = new Uint8Array(16); const ov = new DataView(out.buffer);
65
+ ov.setUint32(0, a0, true); ov.setUint32(4, b0, true); ov.setUint32(8, c0, true); ov.setUint32(12, d0, true);
66
+ return out;
67
+ }
68
+
69
+ const K512 = [0x428a2f98d728ae22n,0x7137449123ef65cdn,0xb5c0fbcfec4d3b2fn,0xe9b5dba58189dbbcn,0x3956c25bf348b538n,0x59f111f1b605d019n,0x923f82a4af194f9bn,0xab1c5ed5da6d8118n,0xd807aa98a3030242n,0x12835b0145706fben,0x243185be4ee4b28cn,0x550c7dc3d5ffb4e2n,0x72be5d74f27b896fn,0x80deb1fe3b1696b1n,0x9bdc06a725c71235n,0xc19bf174cf692694n,0xe49b69c19ef14ad2n,0xefbe4786384f25e3n,0x0fc19dc68b8cd5b5n,0x240ca1cc77ac9c65n,0x2de92c6f592b0275n,0x4a7484aa6ea6e483n,0x5cb0a9dcbd41fbd4n,0x76f988da831153b5n,0x983e5152ee66dfabn,0xa831c66d2db43210n,0xb00327c898fb213fn,0xbf597fc7beef0ee4n,0xc6e00bf33da88fc2n,0xd5a79147930aa725n,0x06ca6351e003826fn,0x142929670a0e6e70n,0x27b70a8546d22ffcn,0x2e1b21385c26c926n,0x4d2c6dfc5ac42aedn,0x53380d139d95b3dfn,0x650a73548baf63den,0x766a0abb3c77b2a8n,0x81c2c92e47edaee6n,0x92722c851482353bn,0xa2bfe8a14cf10364n,0xa81a664bbc423001n,0xc24b8b70d0f89791n,0xc76c51a30654be30n,0xd192e819d6ef5218n,0xd69906245565a910n,0xf40e35855771202an,0x106aa07032bbd1b8n,0x19a4c116b8d2d0c8n,0x1e376c085141ab53n,0x2748774cdf8eeb99n,0x34b0bcb5e19b48a8n,0x391c0cb3c5c95a63n,0x4ed8aa4ae3418acbn,0x5b9cca4f7763e373n,0x682e6ff3d6b2b8a3n,0x748f82ee5defb2fcn,0x78a5636f43172f60n,0x84c87814a1f0ab72n,0x8cc702081a6439ecn,0x90befffa23631e28n,0xa4506cebde82bde9n,0xbef9a3f7b2c67915n,0xc67178f2e372532bn,0xca273eceea26619cn,0xd186b8c721c0c207n,0xeada7dd6cde0eb1en,0xf57d4f7fee6ed178n,0x06f067aa72176fban,0x0a637dc5a2c898a6n,0x113f9804bef90daen,0x1b710b35131c471bn,0x28db77f523047d84n,0x32caab7b40c72493n,0x3c9ebe0a15c9bebcn,0x431d67c49c100d4cn,0x4cc5d4becb3e42b6n,0x597f299cfc657e2an,0x5fcb6fab3ad6faecn,0x6c44198c4a475817n];
70
+ const MASK64 = 0xffffffffffffffffn;
71
+ const rotr64 = (x, n) => (((x >> BigInt(n)) | (x << BigInt(64 - n))) & MASK64);
72
+
73
+ export function sha512(msg) {
74
+ const p = padMsg(msg, 128, 16); const v = new DataView(p.buffer);
75
+ const H = [0x6a09e667f3bcc908n, 0xbb67ae8584caa73bn, 0x3c6ef372fe94f82bn, 0xa54ff53a5f1d36f1n, 0x510e527fade682d1n, 0x9b05688c2b3e6c1fn, 0x1f83d9abfb41bd6bn, 0x5be0cd19137e2179n];
76
+ const W = new Array(80);
77
+ for (let i = 0; i < p.length; i += 128) {
78
+ for (let j = 0; j < 16; j++) W[j] = (BigInt(v.getUint32(i + j * 8)) << 32n) | BigInt(v.getUint32(i + j * 8 + 4));
79
+ for (let j = 16; j < 80; j++) { const s0 = rotr64(W[j-15], 1) ^ rotr64(W[j-15], 8) ^ (W[j-15] >> 7n); const s1 = rotr64(W[j-2], 19) ^ rotr64(W[j-2], 61) ^ (W[j-2] >> 6n); W[j] = (W[j-16] + s0 + W[j-7] + s1) & MASK64; }
80
+ let [a, b, c, d, e, f, g, h] = H;
81
+ for (let j = 0; j < 80; j++) { const S1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41); const ch = (e & f) ^ (~e & MASK64 & g); const t1 = (h + S1 + ch + K512[j] + W[j]) & MASK64; const S0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39); const mj = (a & b) ^ (a & c) ^ (b & c); const t2 = (S0 + mj) & MASK64; h = g; g = f; f = e; e = (d + t1) & MASK64; d = c; c = b; b = a; a = (t1 + t2) & MASK64; }
82
+ H[0] = (H[0] + a) & MASK64; H[1] = (H[1] + b) & MASK64; H[2] = (H[2] + c) & MASK64; H[3] = (H[3] + d) & MASK64; H[4] = (H[4] + e) & MASK64; H[5] = (H[5] + f) & MASK64; H[6] = (H[6] + g) & MASK64; H[7] = (H[7] + h) & MASK64;
83
+ }
84
+ const out = new Uint8Array(64); const ov = new DataView(out.buffer);
85
+ for (let i = 0; i < 8; i++) { ov.setUint32(i * 8, Number(H[i] >> 32n)); ov.setUint32(i * 8 + 4, Number(H[i] & 0xffffffffn)); }
86
+ return out;
87
+ }
88
+
89
+ function concat(a, b) { const o = new Uint8Array(a.length + b.length); o.set(a); o.set(b, a.length); return o; }
90
+ function toBytes(d) { return typeof d === 'string' ? new TextEncoder().encode(d) : d; }
91
+
92
+ const HASH_IMPLS = { sha1: { fn: sha1, size: 64, len: 20 }, sha256: { fn: sha256, size: 64, len: 32 }, sha512: { fn: sha512, size: 128, len: 64 }, md5: { fn: md5, size: 64, len: 16 } };
93
+
94
+ export function createHash(alg) {
95
+ const a = alg.toLowerCase();
96
+ const spec = HASH_IMPLS[a];
97
+ if (!spec) throw new Error('hash algorithm not supported: ' + a);
98
+ const chunks = [];
99
+ return {
100
+ update(data) { chunks.push(toBytes(data)); return this; },
101
+ digest(enc) { const total = chunks.reduce((s, c) => s + c.length, 0); const buf = new Uint8Array(total); let off = 0; for (const c of chunks) { buf.set(c, off); off += c.length; } const out = spec.fn(buf); if (enc === 'hex') return [...out].map(b => b.toString(16).padStart(2, '0')).join(''); if (enc === 'base64') return btoa(String.fromCharCode(...out)); return out; },
102
+ };
103
+ }
104
+
105
+ export function createHmac(alg, key) {
106
+ const spec = HASH_IMPLS[alg.toLowerCase()];
107
+ if (!spec) throw new Error('hmac algorithm not supported: ' + alg);
108
+ let k = toBytes(key);
109
+ if (k.length > spec.size) k = spec.fn(k);
110
+ if (k.length < spec.size) { const pad = new Uint8Array(spec.size); pad.set(k); k = pad; }
111
+ const ipad = new Uint8Array(spec.size), opad = new Uint8Array(spec.size);
112
+ for (let i = 0; i < spec.size; i++) { ipad[i] = k[i] ^ 0x36; opad[i] = k[i] ^ 0x5c; }
113
+ const chunks = [];
114
+ return {
115
+ update(data) { chunks.push(toBytes(data)); return this; },
116
+ digest(enc) { const total = chunks.reduce((s, c) => s + c.length, 0); const buf = new Uint8Array(total); let off = 0; for (const c of chunks) { buf.set(c, off); off += c.length; } const inner = spec.fn(concat(ipad, buf)); const out = spec.fn(concat(opad, inner)); if (enc === 'hex') return [...out].map(b => b.toString(16).padStart(2, '0')).join(''); if (enc === 'base64') return btoa(String.fromCharCode(...out)); return out; },
117
+ };
118
+ }
119
+
120
+ export function pbkdf2Sync(password, salt, iterations, keylen, digest) {
121
+ const spec = HASH_IMPLS[digest.toLowerCase()];
122
+ if (!spec) throw new Error('pbkdf2 digest not supported: ' + digest);
123
+ const hLen = spec.len;
124
+ const saltB = toBytes(salt);
125
+ const blocks = Math.ceil(keylen / hLen);
126
+ const out = new Uint8Array(blocks * hLen);
127
+ for (let i = 1; i <= blocks; i++) {
128
+ const block = new Uint8Array(saltB.length + 4); block.set(saltB); const dv = new DataView(block.buffer); dv.setUint32(saltB.length, i);
129
+ let U = createHmac(digest, password).update(block).digest();
130
+ let T = new Uint8Array(U);
131
+ for (let j = 1; j < iterations; j++) { U = createHmac(digest, password).update(U).digest(); for (let k = 0; k < hLen; k++) T[k] ^= U[k]; }
132
+ out.set(T, (i - 1) * hLen);
133
+ }
134
+ return out.slice(0, keylen);
135
+ }
136
+
137
+ export function randomBytes(n) { const out = new Uint8Array(n); (globalThis.crypto || { getRandomValues: a => { for (let i = 0; i < a.length; i++) a[i] = Math.random() * 256 | 0; return a; } }).getRandomValues(out); return out; }
@@ -0,0 +1,41 @@
1
+ const DOH='https://cloudflare-dns.com/dns-query';
2
+ const DOH_FALLBACK='https://dns.google/resolve';
3
+
4
+ async function query(name,type='A'){
5
+ const TYPES={A:1,AAAA:28,MX:15,TXT:16,NS:2,CNAME:5,SOA:6,PTR:12,SRV:33};
6
+ const t=TYPES[type]||1;
7
+ try{
8
+ const r=await fetch(`${DOH}?name=${encodeURIComponent(name)}&type=${t}`,{headers:{accept:'application/dns-json'}});
9
+ const j=await r.json();
10
+ return j.Answer||[];
11
+ }catch{
12
+ const r=await fetch(`${DOH_FALLBACK}?name=${encodeURIComponent(name)}&type=${t}`);
13
+ const j=await r.json();
14
+ return j.Answer||[];
15
+ }
16
+ }
17
+
18
+ export function makeDns(){
19
+ const extract=(answers,want)=>answers.filter(a=>a.type===want).map(a=>a.data.replace(/^"|"$/g,''));
20
+ return{
21
+ promises:{
22
+ async resolve(name,type='A'){const a=await query(name,type);return extract(a,{A:1,AAAA:28,CNAME:5,NS:2,TXT:16,MX:15,PTR:12,SRV:33,SOA:6}[type]);},
23
+ async resolve4(name){return this.resolve(name,'A');},
24
+ async resolve6(name){return this.resolve(name,'AAAA');},
25
+ async resolveMx(name){const a=await query(name,'MX');return extract(a,15).map(s=>{const[priority,exchange]=s.split(' ');return{priority:+priority,exchange};});},
26
+ async resolveTxt(name){const a=await query(name,'TXT');return extract(a,16).map(s=>[s]);},
27
+ async resolveCname(name){return this.resolve(name,'CNAME');},
28
+ async resolveNs(name){return this.resolve(name,'NS');},
29
+ async resolveSrv(name){const a=await query(name,'SRV');return extract(a,33).map(s=>{const[priority,weight,port,name]=s.split(' ');return{priority:+priority,weight:+weight,port:+port,name};});},
30
+ async reverse(ip){const rev=ip.includes(':')?ip:ip.split('.').reverse().join('.')+'.in-addr.arpa';const a=await query(rev,'PTR');return extract(a,12);},
31
+ async lookup(hostname,opts={}){if(hostname==='localhost')return{address:'127.0.0.1',family:4};const t=opts.family===6?'AAAA':'A';const results=await query(hostname,t);if(!results.length)throw Object.assign(new Error('getaddrinfo ENOTFOUND '+hostname),{code:'ENOTFOUND',hostname});return{address:results[0].data,family:opts.family===6?6:4};},
32
+ async lookupService(ip,port){return{hostname:ip,service:String(port)};},
33
+ getServers(){return['1.1.1.1','8.8.8.8'];},
34
+ setServers(){},
35
+ },
36
+ get resolve(){const p=this.promises;return(name,type,cb)=>{if(typeof type==='function'){cb=type;type='A';}p.resolve(name,type).then(r=>cb(null,r),cb);};},
37
+ lookup:(h,o,cb)=>{if(typeof o==='function'){cb=o;o={};}query(h,o.family===6?'AAAA':'A').then(a=>a.length?cb(null,a[0].data,o.family===6?6:4):cb(Object.assign(new Error('ENOTFOUND'),{code:'ENOTFOUND'})),cb);},
38
+ ADDRCONFIG:0x20,V4MAPPED:0x8,ALL:0x10,
39
+ NODATA:'ENODATA',FORMERR:'EFORMERR',SERVFAIL:'ESERVFAIL',NOTFOUND:'ENOTFOUND',
40
+ };
41
+ }
@@ -0,0 +1,148 @@
1
+ export function extendBuffer(Buf) {
2
+ const proto = Buf.prototype;
3
+ proto.readBigUInt64BE = function(o=0){return (BigInt(this.readUInt32BE(o))<<32n)|BigInt(this.readUInt32BE(o+4));};
4
+ proto.readBigUInt64LE = function(o=0){return (BigInt(this.readUInt32LE(o)))|(BigInt(this.readUInt32LE(o+4))<<32n);};
5
+ proto.readUInt32LE = function(o=0){return (this[o]|(this[o+1]<<8)|(this[o+2]<<16)|(this[o+3]*0x1000000))>>>0;};
6
+ proto.readDoubleBE = function(o=0){return new DataView(this.buffer,this.byteOffset+o,8).getFloat64(0,false);};
7
+ proto.readDoubleLE = function(o=0){return new DataView(this.buffer,this.byteOffset+o,8).getFloat64(0,true);};
8
+ proto.readFloatBE = function(o=0){return new DataView(this.buffer,this.byteOffset+o,4).getFloat32(0,false);};
9
+ proto.readFloatLE = function(o=0){return new DataView(this.buffer,this.byteOffset+o,4).getFloat32(0,true);};
10
+ proto.writeUInt16BE = function(v,o=0){this[o]=(v>>8)&0xff;this[o+1]=v&0xff;return o+2;};
11
+ proto.writeUInt16LE = function(v,o=0){this[o]=v&0xff;this[o+1]=(v>>8)&0xff;return o+2;};
12
+ proto.writeUInt32BE = function(v,o=0){this[o]=(v>>>24)&0xff;this[o+1]=(v>>>16)&0xff;this[o+2]=(v>>>8)&0xff;this[o+3]=v&0xff;return o+4;};
13
+ proto.swap16 = function(){for(let i=0;i<this.length;i+=2){const t=this[i];this[i]=this[i+1];this[i+1]=t;}return this;};
14
+ proto.swap32 = function(){for(let i=0;i<this.length;i+=4){[this[i],this[i+3]]=[this[i+3],this[i]];[this[i+1],this[i+2]]=[this[i+2],this[i+1]];}return this;};
15
+ proto.swap64 = function(){for(let i=0;i<this.length;i+=8){for(let j=0;j<4;j++){const t=this[i+j];this[i+j]=this[i+7-j];this[i+7-j]=t;}}return this;};
16
+ Buf.copyBytesFrom = (view,off=0,len)=>Buf.from(view.buffer,view.byteOffset+off,len??view.byteLength-off);
17
+ return Buf;
18
+ }
19
+
20
+ const WIN = /^[A-Za-z]:[\\/]/;
21
+ function win32Mod(){
22
+ const sep='\\';
23
+ const norm=p=>{const abs=WIN.test(p);const parts=[];for(const s of p.replace(/\//g,'\\').split('\\')){if(s==='..')parts.pop();else if(s&&s!=='.')parts.push(s);}return (abs?p.slice(0,3):'')+parts.slice(abs?1:0).join('\\');};
24
+ return {sep,delimiter:';',normalize:norm,join:(...a)=>norm(a.join('\\')),resolve:(...a)=>{let r='';for(const p of a)r=WIN.test(p)?p:r+'\\'+p;return norm(r);},dirname:p=>{const i=p.replace(/\//g,'\\').lastIndexOf('\\');return i<=0?'.':p.slice(0,i);},basename:(p,ext)=>{const b=p.replace(/\//g,'\\').split('\\').pop()||'';return ext&&b.endsWith(ext)?b.slice(0,-ext.length):b;},extname:p=>{const b=p.split(/[\\/]/).pop()||'';const i=b.lastIndexOf('.');return i>0?b.slice(i):'';},isAbsolute:p=>WIN.test(p)||p.startsWith('\\'),relative:(f,t)=>t.replace(f+'\\',''),parse:p=>({root:WIN.test(p)?p.slice(0,3):'',dir:p.slice(0,p.lastIndexOf('\\'))||'',base:p.split('\\').pop()||'',ext:'',name:''})};
25
+ }
26
+ export function extendPath(posix){
27
+ posix.delimiter=':';
28
+ posix.posix=posix;
29
+ posix.win32=win32Mod();
30
+ return posix;
31
+ }
32
+
33
+ export function createUrlExt(){
34
+ const pathToFileURL=p=>{const u=new URL('file://');u.pathname=p.startsWith('/')?p:'/'+p;return u;};
35
+ const fileURLToPath=u=>{const url=typeof u==='string'?new URL(u):u;if(url.protocol!=='file:')throw new TypeError('only file: supported');return decodeURIComponent(url.pathname);};
36
+ return {URL,URLSearchParams,parse:s=>{const u=new URL(s);return{protocol:u.protocol,host:u.host,hostname:u.hostname,port:u.port,pathname:u.pathname,search:u.search,query:u.search.slice(1),hash:u.hash,href:u.href};},format:o=>{if(o instanceof URL)return o.href;const u=new URL('http://x');for(const[k,v]of Object.entries(o)){try{u[k]=v;}catch{}}return u.href;},resolve:(f,t)=>new URL(t,f).href,pathToFileURL,fileURLToPath,domainToASCII:s=>s,domainToUnicode:s=>s};
37
+ }
38
+
39
+ export function makeStringDecoder(){
40
+ class StringDecoder{
41
+ constructor(enc='utf8'){this.encoding=enc;this._td=new TextDecoder(enc==='utf8'?'utf-8':enc,{fatal:false});this._buf=null;}
42
+ write(b){return this._td.decode(b,{stream:true});}
43
+ end(b){return this._td.decode(b||new Uint8Array(0),{stream:false});}
44
+ }
45
+ return {StringDecoder};
46
+ }
47
+
48
+ export function makeReadline(term,proc){
49
+ return {
50
+ createInterface:({input,output,prompt='> ',terminal:useTerm}={})=>{
51
+ const handlers={line:[],close:[],history:[]};
52
+ const useXterm=useTerm!==false&&term&&(!input||input===proc?.stdin);
53
+ let buf='';
54
+ const rl={
55
+ on:(ev,fn)=>{(handlers[ev]=handlers[ev]||[]).push(fn);return rl;},
56
+ once:(ev,fn)=>rl.on(ev,(...a)=>{rl.off(ev,fn);fn(...a);}),
57
+ off:(ev,fn)=>{handlers[ev]=(handlers[ev]||[]).filter(f=>f!==fn);return rl;},
58
+ write:s=>(output||term)?.write?.(s),
59
+ prompt:()=>(output||term)?.write?.(prompt),
60
+ question:(q,cb)=>{(output||term)?.write?.(q);return new Promise(resolve=>{const handler=l=>{rl.off('line',handler);resolve(l);cb?.(l);};handlers.line.push(handler);});},
61
+ close:()=>{for(const h of handlers.close)h();},
62
+ setPrompt:p=>{prompt=p;},
63
+ pause:()=>rl,resume:()=>rl,
64
+ [Symbol.asyncIterator](){return{next(){return new Promise(r=>{handlers.line.push(function on(l){handlers.line=handlers.line.filter(f=>f!==on);r({value:l,done:false});});});}};}
65
+ };
66
+ if(useXterm){
67
+ const sink=d=>{if(d==='\r'||d==='\n'){const l=buf;buf='';term.write('\r\n');for(const h of handlers.line)h(l);}else if(d==='\x7f'){if(buf.length){buf=buf.slice(0,-1);term.write('\b \b');}}else if(d>=' '){buf+=d;term.write(d);}};
68
+ if(proc?.stdin?.on)proc.stdin.on('data',sink);
69
+ }else if(input?._onLine)input._onLine(l=>{for(const h of handlers.line)h(l);});
70
+ return rl;
71
+ },
72
+ cursorTo:(s,x,y)=>{if(s?.write)s.write(`\x1b[${(y||0)+1};${(x||0)+1}H`);},
73
+ clearLine:s=>s?.write?.('\x1b[2K'),
74
+ clearScreenDown:s=>s?.write?.('\x1b[J'),
75
+ moveCursor:(s,dx,dy)=>{if(s?.write){if(dx>0)s.write(`\x1b[${dx}C`);else if(dx<0)s.write(`\x1b[${-dx}D`);if(dy>0)s.write(`\x1b[${dy}B`);else if(dy<0)s.write(`\x1b[${-dy}A`);}},
76
+ emitKeypressEvents:(stream,rl)=>{if(!stream?.on)return;stream.on('data',d=>{const name=d==='\r'?'return':d==='\x1b[A'?'up':d==='\x1b[B'?'down':d==='\x7f'?'backspace':d.length===1?d:'';stream.emit?.('keypress',d,{name,ctrl:false,meta:false,shift:false,sequence:d});});},
77
+ };
78
+ }
79
+
80
+ export function makeTimersMod(){
81
+ return {setTimeout,setInterval,setImmediate:fn=>setTimeout(fn,0),clearTimeout,clearInterval,clearImmediate:clearTimeout,promises:{setTimeout:ms=>new Promise(r=>setTimeout(r,ms)),setImmediate:()=>Promise.resolve(),setInterval:async function*(ms){while(1){await new Promise(r=>setTimeout(r,ms));yield;}}}};
82
+ }
83
+
84
+ export function makePerfHooks(){
85
+ return {performance:globalThis.performance,PerformanceObserver:class{observe(){}disconnect(){}},monitorEventLoopDelay:()=>({enable(){},disable(){},reset(){},min:0,max:0,mean:0,stddev:0,percentile:()=>0}),constants:{NODE_PERFORMANCE_GC_MAJOR:2}};
86
+ }
87
+
88
+ export function makeV8Mod(){
89
+ return {getHeapStatistics:()=>({total_heap_size:20000000,used_heap_size:10000000,heap_size_limit:2000000000,total_available_size:1990000000}),getHeapSpaceStatistics:()=>[],serialize:o=>new TextEncoder().encode(JSON.stringify(o)),deserialize:b=>JSON.parse(new TextDecoder().decode(b)),cachedDataVersionTag:()=>0,setFlagsFromString:()=>{}};
90
+ }
91
+
92
+ export function makeAsyncHooks(){
93
+ return {createHook:()=>({enable(){return this;},disable(){return this;}}),executionAsyncId:()=>1,triggerAsyncId:()=>0,executionAsyncResource:()=>({}),AsyncLocalStorage:class{constructor(){this._s=null;}run(s,fn,...a){const p=this._s;this._s=s;try{return fn(...a);}finally{this._s=p;}}getStore(){return this._s;}enterWith(s){this._s=s;}disable(){this._s=null;}exit(fn,...a){const p=this._s;this._s=null;try{return fn(...a);}finally{this._s=p;}}},AsyncResource:class{constructor(){}runInAsyncScope(fn,t,...a){return fn.apply(t,a);}}};
94
+ }
95
+
96
+ export function makeStubs(ctx){
97
+ const stub=name=>({__stub:name,toString:()=>`[${name} stub]`});
98
+ return {
99
+ inspector:{open:()=>{},close:()=>{},url:()=>undefined,waitForDebugger:()=>{},Session:class{connect(){}post(){}}},
100
+ cluster:{isPrimary:true,isMaster:true,isWorker:false,workers:{},fork:()=>{throw new Error('cluster.fork: not supported in browser')},on:()=>{},emit:()=>{}},
101
+ sea:{isSea:()=>false,getAsset:()=>{throw new Error('sea.getAsset: no SEA blob')},getRawAsset:()=>{throw new Error('sea.getRawAsset: no SEA blob')}},
102
+ test_runner:{test:(n,fn)=>Promise.resolve(fn?.()),describe:(n,fn)=>fn?.(),it:(n,fn)=>Promise.resolve(fn?.()),before:fn=>fn?.(),after:fn=>fn?.(),beforeEach:()=>{},afterEach:()=>{},run:()=>({})},
103
+ readline_promises:{createInterface:()=>({close(){},question:q=>Promise.resolve('')})},
104
+ punycode:{encode:s=>s,decode:s=>s,toASCII:s=>s,toUnicode:s=>s,ucs2:{encode:a=>String.fromCodePoint(...a),decode:s=>[...s].map(c=>c.codePointAt(0))}},
105
+ tty:{isatty:()=>true,ReadStream:class{isTTY=true;},WriteStream:class{isTTY=true;columns=80;rows=24;}},
106
+ domain:{create:()=>({run:fn=>fn(),add(){},remove(){},dispose(){},on(){},emit(){}})},
107
+ diagnostics_channel:{channel:name=>({hasSubscribers:false,publish(){},subscribe(){},unsubscribe(){}}),hasSubscribers:()=>false},
108
+ string_decoder:makeStringDecoder(),
109
+ tls:{connect:()=>{throw new Error('tls.connect: use fetch() for HTTPS in browser');},createServer:()=>{throw new Error('tls.createServer: not supported in browser');},DEFAULT_CIPHERS:'',DEFAULT_MIN_VERSION:'TLSv1.2',DEFAULT_MAX_VERSION:'TLSv1.3'},
110
+ };
111
+ }
112
+
113
+ export function makeErrorCodes(){
114
+ const codes={ERR_MODULE_NOT_FOUND:'Cannot find module',ERR_INVALID_ARG_TYPE:'Invalid argument type',ERR_INVALID_ARG_VALUE:'Invalid argument value',ERR_OUT_OF_RANGE:'Value out of range',ERR_UNHANDLED_ERROR:'Unhandled error',ERR_ASSERTION:'Assertion failed',ERR_UNSUPPORTED_DIR_IMPORT:'Directory import not supported',ERR_PACKAGE_PATH_NOT_EXPORTED:'Package path not exported',ERR_REQUIRE_ESM:'Cannot require() ESM module',ERR_UNKNOWN_FILE_EXTENSION:'Unknown file extension',ERR_UNKNOWN_BUILTIN_MODULE:'Unknown builtin module',ERR_INVALID_URL:'Invalid URL',ERR_STREAM_DESTROYED:'Stream destroyed',ERR_STREAM_WRITE_AFTER_END:'Write after end',ERR_STREAM_PREMATURE_CLOSE:'Premature close'};
115
+ const make=(code,msg)=>{const e=new Error(msg||codes[code]);e.code=code;return e;};
116
+ return {codes,make};
117
+ }
118
+
119
+ export function extendProcessExtras(proc,ctx){
120
+ proc.stdout.columns=80;proc.stdout.rows=24;proc.stdout.isTTY=true;proc.stdout.getColorDepth=()=>8;proc.stdout.hasColors=()=>true;
121
+ proc.stderr.columns=80;proc.stderr.rows=24;proc.stderr.isTTY=true;
122
+ proc.stdin.isTTY=true;
123
+ proc.resourceUsage=()=>({userCPUTime:0,systemCPUTime:0,maxRSS:50000,sharedMemorySize:0,unsharedDataSize:0,unsharedStackSize:0,minorPageFault:0,majorPageFault:0,swappedOut:0,fsRead:0,fsWrite:0,ipcSent:0,ipcReceived:0,signalsCount:0,voluntaryContextSwitches:0,involuntaryContextSwitches:0});
124
+ proc.binding=name=>{throw new Error(`process.binding('${name}'): internal bindings not available`);};
125
+ proc.allowedNodeEnvironmentFlags=new Set(['--experimental-vm-modules','--no-warnings','--loader','--import','--require','-r','--enable-source-maps','--inspect','--inspect-brk','--trace-warnings','--unhandled-rejections','--preserve-symlinks','--no-deprecation','--throw-deprecation']);
126
+ const nodeOpts=(ctx.env.NODE_OPTIONS||'').split(/\s+/).filter(Boolean);
127
+ proc.execArgv=nodeOpts;
128
+ proc.sourceMapsEnabled=nodeOpts.includes('--enable-source-maps');
129
+ proc.features={inspector:false,debug:false,uv:false,ipv6:true,tls_alpn:false,tls_sni:false,tls_ocsp:false,tls:false,cached_builtins:true};
130
+ proc.report={getReport:()=>({}),writeReport:()=>'report.json'};
131
+ proc.availableMemory=()=>1073741824;
132
+ proc.constrainedMemory=()=>0;
133
+ proc.loadEnvFile=p=>{};
134
+ proc.noDeprecation=false;proc.throwDeprecation=false;proc.traceDeprecation=false;
135
+ proc.sourceMapsEnabled=false;
136
+ proc.channel=undefined;proc.connected=false;
137
+ const sigH={};
138
+ const origOn=proc.on?.bind(proc);
139
+ proc.on=(ev,fn)=>{if(['SIGINT','SIGTERM','SIGHUP','exit','beforeExit','uncaughtException','unhandledRejection','warning','message'].includes(ev)){(sigH[ev]=sigH[ev]||[]).push(fn);}origOn?.(ev,fn);return proc;};
140
+ proc._emitSignal=(ev,...a)=>{for(const h of sigH[ev]||[])h(...a);};
141
+ proc.kill=()=>true;
142
+ return proc;
143
+ }
144
+
145
+ export function makeStreamConsumers(){
146
+ const toArr=async it=>{const a=[];for await(const c of it)a.push(c);return a;};
147
+ return {text:async s=>{const a=await toArr(s);return a.map(c=>typeof c==='string'?c:new TextDecoder().decode(c)).join('');},json:async s=>JSON.parse(await (await import('./shell-node-extras.js')).makeStreamConsumers().text(s)),arrayBuffer:async s=>{const a=await toArr(s);const b=Buffer.concat(a.map(c=>c instanceof Uint8Array?c:new TextEncoder().encode(c)));return b.buffer;},buffer:async s=>{const a=await toArr(s);return Buffer.concat(a.map(c=>c instanceof Uint8Array?c:new TextEncoder().encode(c)));}};
148
+ }
@@ -0,0 +1,95 @@
1
+ export function detectBrowser(){
2
+ const ua=(typeof navigator!=='undefined'?navigator.userAgent:'')||'';
3
+ const vendor=/Firefox\//.test(ua)?'firefox':/Edg\//.test(ua)?'edge':/Chrome\//.test(ua)?'chromium':/Safari\//.test(ua)?'webkit':'unknown';
4
+ const m=ua.match(/(Firefox|Chrome|Edg|Safari|Version)\/([\d.]+)/);
5
+ const version=m?m[2]:'0';
6
+ const g=globalThis;
7
+ const caps={
8
+ opfs:!!(g.navigator?.storage?.getDirectory),
9
+ sharedArrayBuffer:typeof SharedArrayBuffer!=='undefined'&&g.crossOriginIsolated===true,
10
+ performanceMemory:!!(g.performance?.memory),
11
+ compressionStream:typeof g.CompressionStream!=='undefined',
12
+ webTransport:typeof g.WebTransport!=='undefined',
13
+ webRTCDataChannel:typeof g.RTCPeerConnection!=='undefined',
14
+ webCodecs:typeof g.VideoEncoder!=='undefined',
15
+ storageBuckets:!!(g.navigator?.storageBuckets),
16
+ fileSystemObserver:typeof g.FileSystemObserver!=='undefined',
17
+ measureMemory:typeof g.performance?.measureUserAgentSpecificMemory==='function',
18
+ broadcastChannel:typeof g.BroadcastChannel!=='undefined',
19
+ };
20
+ return{vendor,version,ua,capabilities:caps};
21
+ }
22
+
23
+ export function registerPolyfill(reg,name,backing,reason){
24
+ reg.polyfills=reg.polyfills||{};
25
+ reg.polyfills[name]={active:true,backing,reason,activatedAt:Date.now()};
26
+ }
27
+
28
+ export function makeCompressionStreamZlib(streamMod,Buf){
29
+ if(typeof CompressionStream==='undefined')return null;
30
+ const mk=(name,Ctor)=>()=>{const t=new Ctor(name);const reader=t.readable.getReader();const writer=t.writable.getWriter();const out=new streamMod.Transform({transform(c,e,cb){writer.write(c instanceof Uint8Array?c:new TextEncoder().encode(String(c))).then(()=>cb(),cb);},flush(cb){writer.close().then(async()=>{for(;;){const{value,done}=await reader.read();if(done)break;out.push(Buf.from(value));}cb();},cb);}});return out;};
31
+ return{
32
+ createGzip:mk('gzip',CompressionStream),
33
+ createGunzip:mk('gzip',DecompressionStream),
34
+ createDeflate:mk('deflate',CompressionStream),
35
+ createInflate:mk('deflate',DecompressionStream),
36
+ createDeflateRaw:mk('deflate-raw',CompressionStream),
37
+ createInflateRaw:mk('deflate-raw',DecompressionStream),
38
+ };
39
+ }
40
+
41
+ export function makeWebCodecs(){
42
+ const g=globalThis;
43
+ if(typeof g.VideoEncoder==='undefined')return null;
44
+ return{VideoEncoder:g.VideoEncoder,VideoDecoder:g.VideoDecoder,AudioEncoder:g.AudioEncoder,AudioDecoder:g.AudioDecoder,ImageDecoder:g.ImageDecoder,EncodedVideoChunk:g.EncodedVideoChunk,EncodedAudioChunk:g.EncodedAudioChunk,VideoFrame:g.VideoFrame,AudioData:g.AudioData};
45
+ }
46
+
47
+ export function makeWebPush(){
48
+ return{
49
+ async subscribe(applicationServerKey,opts={}){
50
+ if(!navigator.serviceWorker)throw new Error('web-push: serviceWorker not available');
51
+ const reg=await navigator.serviceWorker.ready;
52
+ return reg.pushManager.subscribe({userVisibleOnly:opts.userVisibleOnly!==false,applicationServerKey});
53
+ },
54
+ async getSubscription(){
55
+ const reg=await navigator.serviceWorker?.ready;
56
+ return reg?reg.pushManager.getSubscription():null;
57
+ },
58
+ async unsubscribe(){
59
+ const sub=await this.getSubscription();
60
+ return sub?sub.unsubscribe():false;
61
+ }
62
+ };
63
+ }
64
+
65
+ export function makeStorageHelpers(){
66
+ const g=globalThis;
67
+ return{
68
+ async estimate(){if(!g.navigator?.storage?.estimate)return{usage:0,quota:0,usageDetails:{}};return g.navigator.storage.estimate();},
69
+ async persist(){if(!g.navigator?.storage?.persist)return false;return g.navigator.storage.persist();},
70
+ async persisted(){if(!g.navigator?.storage?.persisted)return false;return g.navigator.storage.persisted();},
71
+ buckets:g.navigator?.storageBuckets||null,
72
+ };
73
+ }
74
+
75
+ export function makeFsObserver(getSnap,fsWatchers){
76
+ const g=globalThis;
77
+ if(typeof g.FileSystemObserver==='undefined')return null;
78
+ return async (opfsRoot)=>{
79
+ const obs=new g.FileSystemObserver(records=>{
80
+ for(const r of records){
81
+ const path=r.relativePathComponents.join('/');
82
+ for(const w of fsWatchers)if(path===w.path||(w.recursive&&path.startsWith(w.path+'/')))for(const h of w.handlers.change)h(r.type,path.split('/').pop());
83
+ }
84
+ });
85
+ if(opfsRoot)await obs.observe(opfsRoot,{recursive:true});
86
+ return obs;
87
+ };
88
+ }
89
+
90
+ export function wrapWorkerForFirefox(opts={}){
91
+ const ua=typeof navigator!=='undefined'?navigator.userAgent:'';
92
+ const isOldFirefox=/Firefox\/(\d+)/.test(ua)&&parseInt(ua.match(/Firefox\/(\d+)/)[1])<128;
93
+ if(!isOldFirefox||opts.type!=='module')return opts;
94
+ return{...opts,type:'classic'};
95
+ }