typescript-virtual-container 1.3.1 → 1.3.2

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 (59) hide show
  1. package/README.md +61 -1
  2. package/builds/self-standalone.js +481 -0
  3. package/builds/self-standalone.js.map +7 -0
  4. package/{standalone-wo-sftp.js → builds/standalone-wo-sftp.js} +137 -137
  5. package/{standalone-wo-sftp.js.map → builds/standalone-wo-sftp.js.map} +4 -4
  6. package/{standalone.js → builds/standalone.js} +176 -176
  7. package/{standalone.js.map → builds/standalone.js.map} +4 -4
  8. package/builds/web-full-api.min.js +13 -0
  9. package/builds/web-full-api.min.js.map +7 -0
  10. package/builds/web-iife.min.js +13 -0
  11. package/builds/web-iife.min.js.map +7 -0
  12. package/builds/web.min.js +13 -0
  13. package/builds/web.min.js.map +7 -0
  14. package/dist/SSHMimic/loginBanner.d.ts +7 -0
  15. package/dist/SSHMimic/loginBanner.d.ts.map +1 -0
  16. package/dist/SSHMimic/loginBanner.js +22 -0
  17. package/dist/VirtualShell/index.d.ts +21 -1
  18. package/dist/VirtualShell/index.d.ts.map +1 -1
  19. package/dist/VirtualShell/index.js +34 -2
  20. package/dist/VirtualShell/shell.d.ts.map +1 -1
  21. package/dist/VirtualShell/shell.js +2 -17
  22. package/dist/self-standalone.d.ts +2 -0
  23. package/dist/self-standalone.d.ts.map +1 -0
  24. package/dist/self-standalone.js +147 -0
  25. package/dist/web-api.d.ts +26 -0
  26. package/dist/web-api.d.ts.map +1 -0
  27. package/dist/web-api.js +46 -0
  28. package/dist/web-full.d.ts +4 -0
  29. package/dist/web-full.d.ts.map +1 -0
  30. package/dist/web-full.js +8 -0
  31. package/dist/web.d.ts +108 -0
  32. package/dist/web.d.ts.map +1 -0
  33. package/dist/web.js +773 -0
  34. package/examples/README.md +81 -3
  35. package/examples/app-iife.js +58 -0
  36. package/examples/app.js +28 -0
  37. package/examples/index-cf.html +27 -0
  38. package/examples/index.html +27 -0
  39. package/examples/server.js +55 -0
  40. package/examples/web-iife.min.js +13 -0
  41. package/examples/web.min.js +13 -0
  42. package/package.json +10 -3
  43. package/polyfills/node:child_process/index.js +2 -0
  44. package/polyfills/node:crypto/index.js +7 -0
  45. package/polyfills/node:events/index.js +9 -0
  46. package/polyfills/node:fs/index.js +8 -0
  47. package/polyfills/node:fs/promises.js +4 -0
  48. package/polyfills/node:os/index.js +9 -0
  49. package/polyfills/node:path/index.js +14 -0
  50. package/polyfills/node:vm/index.js +7 -0
  51. package/polyfills/node:zlib/index.js +3 -0
  52. package/src/SSHMimic/loginBanner.ts +36 -0
  53. package/src/VirtualShell/index.ts +60 -2
  54. package/src/VirtualShell/shell.ts +3 -31
  55. package/src/self-standalone.ts +183 -0
  56. package/src/web-api.ts +62 -0
  57. package/src/web-full.ts +11 -0
  58. package/src/web.ts +930 -0
  59. package/tests/web.test.ts +182 -0
@@ -0,0 +1,481 @@
1
+ import{basename as Ti}from"node:path";import{stdin as Oi,stdout as Lt}from"node:process";import{createInterface as zi}from"node:readline";var Fe={name:"adduser",description:"Add a new user",category:"users",params:["<username> <password>"],run:async({authUser:r,shell:t,args:e})=>{if(r!=="root")return{stderr:"adduser: permission denied",exitCode:1};let[n,i]=e;return!n||!i?{stderr:"adduser: usage: adduser <username> <password>",exitCode:1}:(await t.users.addUser(n,i),{stdout:`adduser: user '${n}' created`,exitCode:0})}};function Ne(r){return Array.isArray(r)?r:[r]}function zt(r,t){if(r===t)return{matched:!0,inlineValue:null};let e=`${t}=`;return r.startsWith(e)?{matched:!0,inlineValue:r.slice(e.length)}:{matched:!1,inlineValue:null}}function ds(r,t={}){let e=new Set(t.flags??[]),n=new Set(t.flagsWithValue??[]),i=[],s=!1;for(let o=0;o<r.length;o+=1){let a=r[o];if(s){i.push(a);continue}if(a==="--"){s=!0;continue}let l=!1;for(let c of e){let{matched:u}=zt(a,c);if(u){l=!0;break}}if(!l){for(let c of n){let u=zt(a,c);if(u.matched){l=!0,u.inlineValue===null&&o+1<r.length&&(o+=1);break}}l||i.push(a)}}return i}function h(r,t){let e=Ne(t);for(let n of r)for(let i of e)if(zt(n,i).matched)return!0;return!1}function rt(r,t){let e=Ne(t);for(let n=0;n<r.length;n+=1){let i=r[n];for(let s of e){let o=zt(i,s);if(!o.matched)continue;if(o.inlineValue!==null)return o.inlineValue;let a=r[n+1];return a!==void 0&&a!=="--"?a:!0}}}function it(r,t,e={}){return ds(r,e)[t]}function et(r,t={}){let e=new Set,n=new Map,i=[],s=new Set(t.flags??[]),o=new Set(t.flagsWithValue??[]),a=!1;for(let l=0;l<r.length;l+=1){let c=r[l];if(a){i.push(c);continue}if(c==="--"){a=!0;continue}if(s.has(c)){e.add(c);continue}if(o.has(c)){let d=r[l+1];d&&!d.startsWith("-")?(n.set(c,d),l+=1):n.set(c,"");continue}let u=Array.from(o).find(d=>c.startsWith(`${d}=`));if(u){n.set(u,c.slice(u.length+1));continue}i.push(c)}return{flags:e,flagsWithValues:n,positionals:i}}var Ie={name:"alias",description:"Define or display aliases",category:"shell",params:["[name[=value] ...]"],run:({args:r,env:t})=>{if(!t)return{exitCode:0};if(r.length===0)return{stdout:Object.entries(t.vars).filter(([i])=>i.startsWith("__alias_")).map(([i,s])=>`alias ${i.slice(8)}='${s}'`).join(`
2
+ `)||"",exitCode:0};let e=[];for(let n of r){let i=n.indexOf("=");if(i===-1){let s=t.vars[`__alias_${n}`];if(s)e.push(`alias ${n}='${s}'`);else return{stderr:`alias: ${n}: not found`,exitCode:1}}else{let s=n.slice(0,i),o=n.slice(i+1).replace(/^['"]|['"]$/g,"");t.vars[`__alias_${s}`]=o}}return{stdout:e.join(`
3
+ `)||void 0,exitCode:0}}},Ve={name:"unalias",description:"Remove alias definitions",category:"shell",params:["<name...> | -a"],run:({args:r,env:t})=>{if(!t)return{exitCode:0};if(h(r,["-a"])){for(let e of Object.keys(t.vars))e.startsWith("__alias_")&&delete t.vars[e];return{exitCode:0}}for(let e of r)delete t.vars[`__alias_${e}`];return{exitCode:0}}};import*as lt from"node:path";var ms=["/virtual-env-js/.auth"];function S(r,t){return!t||t.trim()===""?r:t.startsWith("/")?lt.posix.normalize(t):lt.posix.normalize(lt.posix.join(r,t))}function ps(r){let t=r.startsWith("/")?lt.posix.normalize(r):lt.posix.normalize(`/${r}`);return ms.some(e=>t===e||t.startsWith(`${e}/`))}function N(r,t,e){if(r!=="root"&&ps(t))throw new Error(`${e}: permission denied: ${t}`)}function Re(r){let e=(r.split("?")[0]?.split("#")[0]??r).split("/").filter(Boolean).pop();return e&&e.length>0?e:"index.html"}function fs(r,t){let e=Array.from({length:r.length+1},()=>Array(t.length+1).fill(0));for(let n=0;n<=r.length;n+=1)e[n][0]=n;for(let n=0;n<=t.length;n+=1)e[0][n]=n;for(let n=1;n<=r.length;n+=1)for(let i=1;i<=t.length;i+=1){let s=r[n-1]===t[i-1]?0:1;e[n][i]=Math.min(e[n-1][i]+1,e[n][i-1]+1,e[n-1][i-1]+s)}return e[r.length][t.length]}function De(r,t,e){let n=S(t,e);if(r.exists(n))return n;let i=lt.posix.dirname(n),s=lt.posix.basename(n),o=r.list(i),a=o.filter(c=>c.toLowerCase()===s.toLowerCase());if(a.length===1)return lt.posix.join(i,a[0]);let l=o.filter(c=>fs(c.toLowerCase(),s.toLowerCase())<=1);return l.length===1?lt.posix.join(i,l[0]):n}function _e(r,t,e){return t.map(n=>{let i=S(r,n);return e(i).type==="directory"?`${n}/`:n}).join(" ")}function vt(r){return r.packageManager}var Le={name:"apt",aliases:["apt-get"],description:"Package manager",category:"package",params:["<install|remove|update|upgrade|search|show|list> [pkg...]"],run:({args:r,shell:t,authUser:e})=>{let n=vt(t);if(!n)return{stderr:"apt: package manager not initialised",exitCode:1};let i=r[0]?.toLowerCase(),s=r.slice(1),o=h(s,["-q","--quiet","-qq"]),a=h(s,["--purge"]),l=s.filter(u=>!u.startsWith("-"));if(["install","remove","purge","upgrade","update"].includes(i??"")&&e!=="root")return{stderr:`E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
4
+ E: Unable to acquire the dpkg frontend lock, are you root?`,exitCode:100};switch(i){case"install":{if(l.length===0)return{stderr:"apt: no packages specified",exitCode:1};let{output:u,exitCode:d}=n.install(l,{quiet:o});return{stdout:u||void 0,exitCode:d}}case"remove":case"purge":{if(l.length===0)return{stderr:"apt: no packages specified",exitCode:1};let{output:u,exitCode:d}=n.remove(l,{purge:i==="purge"||a,quiet:o});return{stdout:u||void 0,exitCode:d}}case"update":return{stdout:["Hit:1 fortune://packages.fortune.local aurora InRelease","Hit:2 fortune://security.fortune.local aurora-security InRelease","Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","All packages are up to date."].join(`
5
+ `),exitCode:0};case"upgrade":return{stdout:["Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","Calculating upgrade... Done","0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."].join(`
6
+ `),exitCode:0};case"search":{let u=l[0];if(!u)return{stderr:"apt: search requires a term",exitCode:1};let d=n.search(u);return d.length===0?{stdout:`Sorting... Done
7
+ Full Text Search... Done
8
+ (no results)`,exitCode:0}:{stdout:`Sorting... Done
9
+ Full Text Search... Done
10
+ ${d.map(f=>`${f.name}/${f.section??"misc"} ${f.version} amd64
11
+ ${f.shortDesc??f.description}`).join(`
12
+ `)}`,exitCode:0}}case"show":{let u=l[0];if(!u)return{stderr:"apt: show requires a package name",exitCode:1};let d=n.show(u);return d?{stdout:d,exitCode:0}:{stderr:`N: Unable to locate package ${u}`,exitCode:100}}case"list":{if(h(s,["--installed"])){let f=n.listInstalled();return f.length===0?{stdout:`Listing... Done
13
+ (no packages installed)`,exitCode:0}:{stdout:`Listing... Done
14
+ ${f.map(g=>`${g.name}/${g.section} ${g.version} ${g.architecture} [installed]`).join(`
15
+ `)}`,exitCode:0}}return{stdout:`Listing... Done
16
+ ${n.listAvailable().map(f=>`${f.name}/${f.section??"misc"} ${f.version} amd64`).join(`
17
+ `)}`,exitCode:0}}default:return{stdout:["Usage: apt [options] command","","Commands:"," install <pkg...> Install packages"," remove <pkg...> Remove packages"," purge <pkg...> Remove packages and config files"," update Refresh package index"," upgrade Upgrade all packages"," search <term> Search in package descriptions"," show <pkg> Show package details"," list [--installed] List packages"].join(`
18
+ `),exitCode:0}}}},Te={name:"apt-cache",description:"Query the package cache",category:"package",params:["<search|show|policy> [pkg]"],run:({args:r,shell:t})=>{let e=vt(t);if(!e)return{stderr:"apt-cache: package manager not initialised",exitCode:1};let n=r[0]?.toLowerCase(),i=r[1];switch(n){case"search":return i?{stdout:e.search(i).map(o=>`${o.name} - ${o.shortDesc??o.description}`).join(`
19
+ `)||"(no results)",exitCode:0}:{stderr:"Need a search term",exitCode:1};case"show":{if(!i)return{stderr:"Need a package name",exitCode:1};let s=e.show(i);return s?{stdout:s,exitCode:0}:{stderr:`N: Unable to locate package ${i}`,exitCode:100}}case"policy":{if(!i)return{stderr:"Need a package name",exitCode:1};let s=e.findInRegistry(i);if(!s)return{stderr:`N: Unable to locate package ${i}`,exitCode:100};let o=e.isInstalled(i);return{stdout:[`${i}:`,` Installed: ${o?s.version:"(none)"}`,` Candidate: ${s.version}`," Version table:",` ${s.version} 500`," 500 fortune://packages.fortune.local aurora/main amd64 Packages"].join(`
20
+ `),exitCode:0}}default:return{stderr:`apt-cache: unknown command '${n??""}'`,exitCode:1}}}};var Oe={name:"awk",description:"Pattern scanning and processing language (minimal)",category:"text",params:["[-F <sep>] '<program>' [file]"],run:({args:r,stdin:t})=>{let e=rt(r,["-F"])??" ",n=r.find(l=>!l.startsWith("-")&&l!==e);if(!n)return{stderr:"awk: no program",exitCode:1};let i=n.match(/^\{?\s*print\s+([^}]+)\s*\}?$/);if(!i)return{stderr:`awk: unsupported program: ${n}`,exitCode:1};let s=i[1].split(/\s*,\s*/).map(l=>l.trim());return{stdout:(t??"").split(`
21
+ `).filter(Boolean).map(l=>{let c=l.split(e===" "?/\s+/:e);return s.map(u=>{if(u==="$0")return l;let d=parseInt(u.replace("$",""),10);return Number.isNaN(d)?u.replace(/"/g,""):c[d-1]??""}).join(e===" "?" ":e)}).join(`
22
+ `),exitCode:0}}};var ze={name:"base64",description:"Encode/decode base64",category:"text",params:["[-d] [file]"],run:({args:r,stdin:t})=>{let e=h(r,["-d","--decode"]),n=t??"";if(e)try{return{stdout:Buffer.from(n.trim(),"base64").toString("utf8"),exitCode:0}}catch{return{stderr:"base64: invalid input",exitCode:1}}return{stdout:Buffer.from(n).toString("base64"),exitCode:0}}};var Be={name:"cat",description:"Concatenate and print files",category:"files",params:["[-n] [-b] <file...>"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=h(n,["-n","--number"]),o=h(n,["-b","--number-nonblank"]),a=n.filter(m=>!m.startsWith("-"));if(a.length===0&&i!==void 0)return{stdout:i,exitCode:0};if(a.length===0)return{stderr:"cat: missing file operand",exitCode:1};let l=[];for(let m of a){let f=De(t.vfs,e,m);N(r,f,"cat"),l.push(t.vfs.readFile(f))}let c=l.join("");if(!s&&!o)return{stdout:c,exitCode:0};let u=1;return{stdout:c.split(`
23
+ `).map(m=>o&&m.trim()===""?m:`${String(u++).padStart(6)} ${m}`).join(`
24
+ `),exitCode:0}}};var Ue={name:"cd",description:"Change directory",category:"navigation",params:["[path]"],run:({authUser:r,shell:t,cwd:e,args:n,mode:i})=>{let s=S(e,n[0]??"/virtual-env-js");return N(r,s,"cd"),t.vfs.stat(s).type!=="directory"?{stderr:`cd: not a directory: ${s}`,exitCode:1}:i==="exec"?{exitCode:0}:{nextCwd:s,exitCode:0}}};function hs(r,t){let e=/^([ugoa]*)([+\-=])([rwx]*)$/,n=t.split(","),i=r;for(let s of n){let o=s.trim().match(e);if(!o)return null;let[,a="a",l,c=""]=o,u=a===""||a==="a"?["u","g","o"]:a.split(""),d={u:{r:256,w:128,x:64},g:{r:32,w:16,x:8},o:{r:4,w:2,x:1}};for(let m of u)for(let f of c.split("")){let x=d[m]?.[f];if(x!==void 0){if(l==="+")i|=x;else if(l==="-")i&=~x;else if(l==="="){let g=Object.values(d[m]??{}).reduce((y,$)=>y|$,0);i=i&~g|x}}}}return i}var je={name:"chmod",description:"Change file permissions",category:"files",params:["<mode> <file>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let[i,s]=n;if(!i||!s)return{stderr:"chmod: missing operand",exitCode:1};let o=S(e,s);try{if(N(r,o,"chmod"),!t.vfs.exists(o))return{stderr:`chmod: ${s}: No such file or directory`,exitCode:1};let a,l=parseInt(i,8);if(!Number.isNaN(l)&&/^[0-7]+$/.test(i))a=l;else{let c=t.vfs.stat(o).mode,u=hs(c,i);if(u===null)return{stderr:`chmod: invalid mode: ${i}`,exitCode:1};a=u}return t.vfs.chmod(o,a),{exitCode:0}}catch(a){return{stderr:`chmod: ${a instanceof Error?a.message:String(a)}`,exitCode:1}}}};var We={name:"clear",description:"Clear the terminal screen",category:"shell",params:[],run:()=>({clearScreen:!0,stdout:"",exitCode:0})};var He={name:"cp",description:"Copy files or directories",category:"files",params:["[-r] <source> <dest>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=h(n,["-r","-R","--recursive"]),s=n.filter(u=>!u.startsWith("-")),[o,a]=s;if(!o||!a)return{stderr:"cp: missing operand",exitCode:1};let l=S(e,o),c=S(e,a);try{if(N(r,l,"cp"),N(r,c,"cp"),!t.vfs.exists(l))return{stderr:`cp: ${o}: No such file or directory`,exitCode:1};if(t.vfs.stat(l).type==="directory"){if(!i)return{stderr:`cp: ${o}: is a directory (use -r)`,exitCode:1};let d=(f,x)=>{t.vfs.mkdir(x,493);for(let g of t.vfs.list(f)){let y=`${f}/${g}`,$=`${x}/${g}`;if(t.vfs.stat(y).type==="directory")d(y,$);else{let k=t.vfs.readFileRaw(y);t.writeFileAsUser(r,$,k)}}},m=t.vfs.exists(c)&&t.vfs.stat(c).type==="directory"?`${c}/${o.split("/").pop()}`:c;d(l,m)}else{let d=t.vfs.exists(c)&&t.vfs.stat(c).type==="directory"?`${c}/${o.split("/").pop()}`:c,m=t.vfs.readFileRaw(l);t.writeFileAsUser(r,d,m)}return{exitCode:0}}catch(u){return{stderr:`cp: ${u instanceof Error?u.message:String(u)}`,exitCode:1}}}};var qe={name:"curl",description:"Transfer data from or to a server (pure fetch)",category:"network",params:["[options] <url>"],run:async({authUser:r,cwd:t,args:e,shell:n})=>{let{flagsWithValues:i,positionals:s}=et(e,{flagsWithValue:["-o","--output","-X","--request","-d","--data","-H","--header","-u","--user"]});if(h(e,["--help","-h"]))return{stdout:["Usage: curl [options] <url>"," -o, --output <file> Write to file"," -X, --request <method> HTTP method"," -d, --data <data> POST data"," -H, --header <hdr> Extra header"," -s, --silent Silent mode"," -I, --head Fetch headers only"," -L, --location Follow redirects"," -v, --verbose Verbose"].join(`
25
+ `),exitCode:0};let o=s[0];if(!o)return{stderr:"curl: no URL specified",exitCode:1};let a=i.get("-o")??i.get("--output")??null,l=(i.get("-X")??i.get("--request")??"GET").toUpperCase(),c=i.get("-d")??i.get("--data")??null,u=i.get("-H")??i.get("--header")??null,d=h(e,["-s","--silent"]),m=h(e,["-I","--head"]),f=h(e,["-L","--location"]),x=h(e,["-v","--verbose"]),g={"User-Agent":"curl/7.88.1"};if(u){let D=u.indexOf(":");D!==-1&&(g[u.slice(0,D).trim()]=u.slice(D+1).trim())}let y=c&&l==="GET"?"POST":l,$={method:y,headers:g,redirect:f?"follow":"manual"};c&&(g["Content-Type"]??="application/x-www-form-urlencoded",$.body=c);let V=[];x&&(V.push(`* Trying ${o}...`,"* Connected"),V.push(`> ${y} / HTTP/1.1`,`> Host: ${new URL(o).host}`));let k;try{k=await fetch(o,$)}catch(D){return{stderr:`curl: (6) Could not resolve host: ${D instanceof Error?D.message:String(D)}`,exitCode:6}}if(x&&V.push(`< HTTP/1.1 ${k.status} ${k.statusText}`),m){let D=[`HTTP/1.1 ${k.status} ${k.statusText}`];for(let[tt,w]of k.headers.entries())D.push(`${tt}: ${w}`);return{stdout:`${D.join(`\r
26
+ `)}\r
27
+ `,exitCode:0}}let R;try{R=await k.text()}catch{return{stderr:"curl: failed to read response body",exitCode:1}}if(a){let D=S(t,a);return N(r,D,"curl"),n.writeFileAsUser(r,D,R),d||V.push(` % Total % Received
28
+ 100 ${R.length} 100 ${R.length}`),{stderr:V.join(`
29
+ `)||void 0,exitCode:k.ok?0:22}}return{stdout:R,stderr:V.length>0?V.join(`
30
+ `):void 0,exitCode:k.ok?0:22}}};var Ke={name:"cut",description:"Remove sections from lines",category:"text",params:["-d <delim> -f <fields> [file]"],run:({args:r,stdin:t})=>{let e=rt(r,["-d"])??" ",i=(rt(r,["-f"])??"1").split(",").map(a=>{let[l,c]=a.split("-").map(Number);return c!==void 0?{from:(l??1)-1,to:c-1}:{from:(l??1)-1,to:(l??1)-1}});return{stdout:(t??"").split(`
31
+ `).map(a=>{let l=a.split(e),c=[];for(let u of i)for(let d=u.from;d<=Math.min(u.to,l.length-1);d++)c.push(l[d]??"");return c.join(e)}).join(`
32
+ `),exitCode:0}}};var Ge={name:"date",description:"Print current date and time",category:"system",params:["[+format]"],run:({args:r})=>{let t=new Date,e=r[0];return e?.startsWith("+")?{stdout:e.slice(1).replace("%Y",String(t.getFullYear())).replace("%m",String(t.getMonth()+1).padStart(2,"0")).replace("%d",String(t.getDate()).padStart(2,"0")).replace("%H",String(t.getHours()).padStart(2,"0")).replace("%M",String(t.getMinutes()).padStart(2,"0")).replace("%S",String(t.getSeconds()).padStart(2,"0")).replace("%s",String(Math.floor(t.getTime()/1e3))),exitCode:0}:{stdout:t.toString(),exitCode:0}}};var Ze={name:"declare",aliases:["local","typeset"],description:"Declare variables and give them attributes",category:"shell",params:["[-i] [-r] [-x] [-a] [name[=value]...]"],run:({args:r,env:t})=>{if(!t)return{exitCode:0};let e=h(r,["-i"]),n=h(r,["-r"]),i=h(r,["-x"]);if(r.filter(a=>!a.startsWith("-")).length===0)return{stdout:Object.entries(t.vars).map(([l,c])=>`declare -- ${l}="${c}"`).join(`
33
+ `),exitCode:0};let o=r.filter(a=>!a.startsWith("-"));for(let a of o){let l=a.indexOf("=");if(l===-1)a in t.vars||(t.vars[a]="");else{let c=a.slice(0,l),u=a.slice(l+1);if(e){let d=parseInt(u,10);u=Number.isNaN(d)?"0":String(d)}t.vars[c]=u}}return{exitCode:0}}};var Je={name:"deluser",description:"Delete a user",category:"users",params:["<username>"],run:async({authUser:r,args:t,shell:e})=>{if(r!=="root")return{stderr:"deluser: permission denied",exitCode:1};let[n]=t;return n?(await e.users.deleteUser(n),{stdout:`deluser: user '${n}' deleted`,exitCode:0}):{stderr:"deluser: usage: deluser <username>",exitCode:1}}};var Ye={name:"df",description:"Report filesystem disk space usage",category:"system",params:["[-h]"],run:({shell:r})=>{let e=(r.vfs.getUsageBytes()/1024).toFixed(0),n="1048576",i=String(Number(n)-Number(e)),s=Math.round(Number(e)/Number(n)*100),o="Filesystem 1K-blocks Used Available Use% Mounted on",a=`virtual-fs ${n.padStart(9)} ${e.padStart(7)} ${i.padStart(9)} ${s}% /`;return{stdout:`${o}
34
+ ${a}`,exitCode:0}}};var Qe={name:"diff",description:"Compare files line by line",category:"text",params:["<file1> <file2>"],run:({shell:r,cwd:t,args:e})=>{let[n,i]=e;if(!n||!i)return{stderr:"diff: missing operand",exitCode:1};let s=S(t,n),o=S(t,i),a,l;try{a=r.vfs.readFile(s).split(`
35
+ `)}catch{return{stderr:`diff: ${n}: No such file or directory`,exitCode:2}}try{l=r.vfs.readFile(o).split(`
36
+ `)}catch{return{stderr:`diff: ${i}: No such file or directory`,exitCode:2}}let c=[],u=Math.max(a.length,l.length);for(let d=0;d<u;d++){let m=a[d],f=l[d];m!==f&&(m!==void 0&&c.push(`< ${m}`),f!==void 0&&c.push(`> ${f}`))}return{stdout:c.join(`
37
+ `),exitCode:c.length>0?1:0}}};var Xe={name:"dpkg",description:"Debian package manager low-level tool",category:"package",params:["[-l] [-s pkg] [-L pkg] [-i pkg] [--remove pkg]"],run:({args:r,authUser:t,shell:e})=>{let n=vt(e);if(!n)return{stderr:"dpkg: package manager not initialised",exitCode:1};let i=h(r,["-l","--list"]),s=h(r,["-s","--status"]),o=h(r,["-L","--listfiles"]),a=h(r,["-r","--remove"]),l=h(r,["-P","--purge"]),{positionals:c}=et(r,{flags:["-l","--list","-s","--status","-L","--listfiles","-r","--remove","-P","--purge"]});if(i){let u=n.listInstalled();if(u.length===0)return{stdout:["Desired=Unknown/Install/Remove/Purge/Hold","|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend","|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)","||/ Name Version Architecture Description","+++-==============-===============-============-========================================","(no packages installed)"].join(`
38
+ `),exitCode:0};let d=["Desired=Unknown/Install/Remove/Purge/Hold","|Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend","|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)","||/ Name Version Architecture Description","+++-==============-===============-============-========================================"],m=u.map(f=>{let x=f.name.padEnd(14).slice(0,14),g=f.version.padEnd(15).slice(0,15),y=f.architecture.padEnd(12).slice(0,12),$=(f.description||"").slice(0,40);return`ii ${x} ${g} ${y} ${$}`});return{stdout:[...d,...m].join(`
39
+ `),exitCode:0}}if(s){let u=c[0];if(!u)return{stderr:"dpkg: -s needs a package name",exitCode:1};let d=n.show(u);return d?{stdout:d,exitCode:0}:{stderr:`dpkg-query: package '${u}' is not installed and no information is available`,exitCode:1}}if(o){let u=c[0];if(!u)return{stderr:"dpkg: -L needs a package name",exitCode:1};let d=n.listInstalled().find(m=>m.name===u);return d?d.files.length===0?{stdout:"/.keep",exitCode:0}:{stdout:d.files.join(`
40
+ `),exitCode:0}:{stderr:`dpkg-query: package '${u}' is not installed`,exitCode:1}}if(a||l){if(t!=="root")return{stderr:"dpkg: error: requested operation requires superuser privilege",exitCode:2};if(c.length===0)return{stderr:"dpkg: error: need an action option",exitCode:2};let{output:u,exitCode:d}=n.remove(c,{purge:l});return{stdout:u||void 0,exitCode:d}}return{stdout:["Usage: dpkg [<option>...] <command>","","Commands:"," -l, --list List packages matching given pattern"," -s, --status <pkg>... Report status of specified package"," -L, --listfiles <pkg>... List files owned by package"," -r, --remove <pkg>... Remove <pkg> but leave its configuration"," -P, --purge <pkg>... Remove <pkg> and its configuration"].join(`
41
+ `),exitCode:0}}},tr={name:"dpkg-query",description:"Show information about installed packages",category:"package",params:["-W [pkg] | -l [pattern]"],run:({args:r,shell:t})=>{let e=vt(t);if(!e)return{stderr:"dpkg-query: package manager not initialised",exitCode:1};let n=h(r,["-l"]),i=h(r,["-W","--show"]),{positionals:s}=et(r,{flags:["-l","-W","--show"]});if(n||i){let o=e.listInstalled(),a=s[0],l=a?o.filter(u=>u.name.includes(a)):o;return i?{stdout:l.map(u=>`${u.name} ${u.version}`).join(`
42
+ `),exitCode:0}:{stdout:l.map(u=>{let d=u.name.padEnd(14).slice(0,14),m=u.version.padEnd(15).slice(0,15);return`ii ${d} ${m} amd64 ${(u.description||"").slice(0,40)}`}).join(`
43
+ `)||"(no packages match)",exitCode:0}}return{stderr:"dpkg-query: need a flag (-l, -W)",exitCode:1}}};var er={name:"du",description:"Estimate file space usage",category:"system",params:["[-h] [-s] [path]"],run:({shell:r,cwd:t,args:e})=>{let n=h(e,["-h"]),i=h(e,["-s"]),s=e.find(u=>!u.startsWith("-"))??".",o=S(t,s),a=u=>n?`${(u/1024).toFixed(1)}K`:String(Math.ceil(u/1024));if(!r.vfs.exists(o))return{stderr:`du: ${s}: No such file or directory`,exitCode:1};if(i||r.vfs.stat(o).type==="file")return{stdout:`${a(r.vfs.getUsageBytes(o))} ${s}`,exitCode:0};let l=[],c=(u,d)=>{let m=0;for(let f of r.vfs.list(u)){let x=`${u}/${f}`,g=`${d}/${f}`,y=r.vfs.stat(x);y.type==="directory"?m+=c(x,g):(m+=y.size,i||l.push(`${a(y.size)} ${g}`))}return l.push(`${a(m)} ${d}`),m};return c(o,s),{stdout:l.join(`
44
+ `),exitCode:0}}};function gs(r,t){let e=r.replace(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g,(n,i)=>{let s=t[i];return s!==void 0&&s!==""?s:"0"});if(!/^[\d\s+\-*/%()^!&|<>=,. ]+$/.test(e))return NaN;try{let n=Function(`"use strict"; return (${e.replace(/\*\*/g,"**")});`)();return typeof n=="number"?Math.trunc(n):NaN}catch{return NaN}}function ys(r,t){let e=[],n=0;for(;n<r.length;){let i=r.indexOf("'",n);if(i===-1){e.push(t(r.slice(n)));break}e.push(t(r.slice(n,i)));let s=r.indexOf("'",i+1);if(s===-1){e.push(r.slice(i));break}e.push(r.slice(i,s+1)),n=s+1}return e.join("")}function ae(r,t,e=0,n){let i=n??t.HOME??"/home/user";return ys(r,s=>{let o=s;return o=o.replace(/(^|[\s:])~(\/|$)/g,(a,l,c)=>`${l}${i}${c}`),o=o.replace(/\$\?/g,String(e)),o=o.replace(/\$\$/g,"1"),o=o.replace(/\$#/g,"0"),o=o.replace(/\$\(\(([^)]+(?:\([^)]*\)[^)]*)*)\)\)/g,(a,l)=>{let c=gs(l,t);return Number.isNaN(c)?"0":String(c)}),o=o.replace(/\$\{#([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,l)=>String((t[l]??"").length)),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):-([^}]*)\}/g,(a,l,c)=>t[l]!==void 0&&t[l]!==""?t[l]:c),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):=([^}]*)\}/g,(a,l,c)=>((t[l]===void 0||t[l]==="")&&(t[l]=c),t[l])),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*):\+([^}]*)\}/g,(a,l,c)=>t[l]!==void 0&&t[l]!==""?c:""),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,l)=>t[l]??""),o=o.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g,(a,l)=>t[l]??""),o})}async function Bt(r,t,e,n){if(r.includes("$(")){let i="",s=!1,o=0;for(;o<r.length;){let a=r[o];if(a==="'"&&!s){s=!0,i+=a,o++;continue}if(a==="'"&&s){s=!1,i+=a,o++;continue}if(!s&&a==="$"&&r[o+1]==="("){if(r[o+2]==="("){i+=a,o++;continue}let l=0,c=o+1;for(;c<r.length;){if(r[c]==="(")l++;else if(r[c]===")"&&(l--,l===0))break;c++}let u=r.slice(o+2,c).trim(),d=(await n(u)).replace(/\n$/,"");i+=d,o=c+1;continue}i+=a,o++}r=i}return ae(r,t,e)}function Ss(r){return r.replace(/\\n/g,`
45
+ `).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\a/g,"\x07").replace(/\\b/g,"\b").replace(/\\f/g,"\f").replace(/\\v/g,"\v").replace(/\\0(\d{1,3})/g,(t,e)=>String.fromCharCode(parseInt(e,8)))}var rr={name:"echo",description:"Display text",category:"shell",params:["[-n] [-e] [text...]"],run:({args:r,stdin:t,env:e})=>{let{flags:n,positionals:i}=et(r,{flags:["-n","-e","-E"]}),s=n.has("-n"),o=n.has("-e"),a=i.length>0?i.join(" "):t??"",l=ae(a,e?.vars??{},e?.lastExitCode??0),c=o?Ss(l):l;return{stdout:s?c:`${c}
46
+ `,exitCode:0}}};var nr={name:"env",description:"Print environment variables",category:"shell",params:[],run:({env:r,authUser:t})=>{let e={...r.vars,USER:t,HOME:`/home/${t}`};return{stdout:Object.entries(e).map(([n,i])=>`${n}=${i}`).join(`
47
+ `),exitCode:0}}};var sr={name:"exit",aliases:["bye"],description:"Exit the shell session",category:"shell",params:["[code]"],run:({args:r})=>({closeSession:!0,exitCode:parseInt(r[0]??"0",10)||0})};var ir={name:"export",description:"Set shell environment variable",category:"shell",params:["[VAR=value]"],run:({args:r,env:t})=>{if(r.length===0)return{stdout:Object.entries(t.vars).map(([n,i])=>`declare -x ${n}="${i}"`).join(`
48
+ `),exitCode:0};for(let e of r)if(e.includes("=")){let n=e.indexOf("="),i=e.slice(0,n),s=e.slice(n+1);t.vars[i]=s}return{exitCode:0}}};var or={name:"find",description:"Search for files",category:"files",params:["[path] [-name <pattern>] [-type f|d]"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=rt(n,["-name"]),s=rt(n,["-type"]),a=n.filter(m=>!m.startsWith("-")&&m!==i&&m!==s)[0]??".",l=S(e,a);try{if(N(r,l,"find"),!t.vfs.exists(l))return{stderr:`find: ${a}: No such file or directory`,exitCode:1}}catch(m){return{stderr:`find: ${m instanceof Error?m.message:String(m)}`,exitCode:1}}let c=i?new RegExp(`^${i.replace(/\./g,"\\.").replace(/\*/g,".*").replace(/\?/g,".")}$`):null,u=[],d=(m,f)=>{let x=t.vfs.stat(m),g=!s||s==="f"&&x.type==="file"||s==="d"&&x.type==="directory",y=!c||c.test(m.split("/").pop()??"");if(g&&y&&u.push(f),x.type==="directory")for(let $ of t.vfs.list(m)){let V=`${m}/${$}`,k=`${f}/${$}`;d(V,k)}};return d(l,a),{stdout:u.join(`
49
+ `),exitCode:0}}};import*as Ut from"node:os";var ar={name:"free",description:"Display amount of free and used memory",category:"system",params:["[-h] [-m] [-g]"],run:({args:r})=>{let t=h(r,["-h","--human"]),e=h(r,["-m"]),n=h(r,["-g"]),i=Ut.totalmem(),s=Ut.freemem(),o=i-s,a=Math.floor(i*.02),l=Math.floor(i*.05),c=Math.floor(s*.95),u=Math.floor(i*.5),d=g=>t?g>=1024*1024*1024?`${(g/(1024*1024*1024)).toFixed(1)}G`:g>=1024*1024?`${(g/(1024*1024)).toFixed(1)}M`:`${(g/1024).toFixed(1)}K`:String(Math.floor(n?g/(1024*1024*1024):e?g/(1024*1024):g/1024)),m=" total used free shared buff/cache available",f=`Mem: ${d(i).padStart(12)} ${d(o).padStart(11)} ${d(s).padStart(11)} ${d(a).padStart(11)} ${d(l).padStart(11)} ${d(c).padStart(11)}`,x=`Swap: ${d(u).padStart(12)} ${d(0).padStart(11)} ${d(u).padStart(11)}`;return{stdout:[m,f,x].join(`
50
+ `),exitCode:0}}};var lr={name:"grep",description:"Search text patterns",category:"text",params:["[-i] [-v] [-n] [-r] <pattern> [file...]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let{flags:s,positionals:o}=et(n,{flags:["-i","-v","-n","-r"]}),a=s.has("-i"),l=s.has("-v"),c=s.has("-n"),u=s.has("-r"),d=o[0],m=o.slice(1);if(!d)return{stderr:"grep: no pattern specified",exitCode:1};let f;try{let $=a?"mi":"m";f=new RegExp(d,$)}catch{return{stderr:`grep: invalid regex: ${d}`,exitCode:1}}let x=($,V="")=>{let k=$.split(`
51
+ `),R=[];for(let D=0;D<k.length;D++){let tt=k[D]??"",w=f.test(tt);if(l?!w:w){let T=c?`${D+1}:`:"";R.push(`${V}${T}${tt}`)}}return R},g=$=>{if(!t.vfs.exists($))return[];if(t.vfs.stat($).type==="file")return[$];if(!u)return[];let k=[],R=D=>{for(let tt of t.vfs.list(D)){let w=`${D}/${tt}`;t.vfs.stat(w).type==="file"?k.push(w):R(w)}};return R($),k},y=[];if(m.length===0){if(!i)return{stdout:"",exitCode:1};y.push(...x(i))}else{let $=m.flatMap(V=>{let k=S(e,V);return g(k).map(R=>({file:V,path:R}))});for(let{file:V,path:k}of $)try{N(r,k,"grep");let R=t.vfs.readFile(k),D=$.length>1?`${V}:`:"";y.push(...x(R,D))}catch{return{stderr:`grep: ${V}: No such file or directory`,exitCode:1}}}return{stdout:y.length>0?y.join(`
52
+ `):"",exitCode:y.length>0?0:1}}};var cr={name:"groups",description:"Print group memberships",category:"system",params:["[user]"],run:({authUser:r,shell:t,args:e})=>{let n=e[0]??r;return{stdout:t.users.isSudoer(n)?`${n} sudo root`:n,exitCode:0}}};var ur={name:"gzip",description:"Compress files",category:"archive",params:["<file>"],run:({shell:r,cwd:t,args:e})=>{let n=e[0];if(!n)return{stderr:"gzip: no file specified",exitCode:1};let i=S(t,n);try{return r.vfs.compressFile(i),{exitCode:0}}catch{return{stderr:`gzip: ${n}: No such file or directory`,exitCode:1}}}},dr={name:"gunzip",description:"Decompress files",category:"archive",params:["<file>"],aliases:["zcat"],run:({shell:r,cwd:t,args:e})=>{let n=e[0];if(!n)return{stderr:"gunzip: no file specified",exitCode:1};let i=S(t,n);try{return r.vfs.decompressFile(i),{exitCode:0}}catch{return{stderr:`gunzip: ${n}: No such file or directory`,exitCode:1}}}};var mr={name:"head",description:"Output first lines",category:"text",params:["[-n <lines>] [file...]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=rt(n,["-n"]),o=typeof s=="string"?parseInt(s,10):10,a=n.filter(u=>!u.startsWith("-")&&u!==s),l=u=>u.split(`
53
+ `).slice(0,o).join(`
54
+ `);if(a.length===0)return{stdout:l(i??""),exitCode:0};let c=[];for(let u of a){let d=S(e,u);try{N(r,d,"head"),c.push(l(t.vfs.readFile(d)))}catch{return{stderr:`head: ${u}: No such file or directory`,exitCode:1}}}return{stdout:c.join(`
55
+ `),exitCode:0}}};var pr=["navigation","files","text","archive","system","package","network","shell","users","misc"],hr={navigation:"Navigation",files:"Files & Filesystem",text:"Text Processing",archive:"Archive & Compression",system:"System",package:"Package Management",network:"Network",shell:"Shell & Scripting",users:"Users & Permissions",misc:"Miscellaneous"},gr="\x1B[1m",ct="\x1B[0m",xs="\x1B[36m",bs="\x1B[33m",At="\x1B[2m",ws="\x1B[32m";function fr(r,t){return r.length>=t?r:r+" ".repeat(t-r.length)}function vs(r){let t=r.aliases?.length?` ${At}(${r.aliases.join(", ")})${ct}`:"";return` ${xs}${fr(r.name,16)}${ct}${t}${fr("",(r.aliases?.length,0))} ${r.description??""}`}function Cs(r){let t={};for(let s of r){let o=s.category??"misc";t[o]||(t[o]=[]),t[o].push(s)}let e=[`${gr}Available commands${ct}`,`${At}Type 'help <command>' for detailed usage.${ct}`,""],n=[...pr.filter(s=>t[s]),...Object.keys(t).filter(s=>!pr.includes(s)).sort()];for(let s of n){let o=t[s];if(!o?.length)continue;e.push(`${bs}${hr[s]??s}${ct}`);let a=[...o].sort((l,c)=>l.name.localeCompare(c.name));for(let l of a)e.push(vs(l));e.push("")}let i=r.length;return e.push(`${At}${i} commands available.${ct}`),e.join(`
56
+ `)}function $s(r){let t=[];if(t.push(`${gr}${r.name}${ct} \u2014 ${r.description??"no description"}`),r.aliases?.length&&t.push(`${At}Aliases: ${r.aliases.join(", ")}${ct}`),t.push(""),t.push(`${ws}Usage:${ct}`),r.params.length)for(let n of r.params)t.push(` ${r.name} ${n}`);else t.push(` ${r.name}`);let e=hr[r.category??"misc"]??r.category??"misc";return t.push(""),t.push(`${At}Category: ${e}${ct}`),t.join(`
57
+ `)}function yr(r){return{name:"help",description:"List all commands, or show usage for a specific command",category:"shell",params:["[command]"],run:({args:t})=>{let e=le();if(t[0]){let n=t[0].toLowerCase(),i=e.find(s=>s.name===n||s.aliases?.includes(n));return i?{stdout:$s(i),exitCode:0}:{stderr:`help: no help entry for '${t[0]}'`,exitCode:1}}return{stdout:Cs(e),exitCode:0}}}}var Sr={name:"history",description:"Display command history",category:"shell",params:["[n]"],run:({args:r,shell:t})=>{let e="/virtual-env-js/.bash_history";if(!t.vfs.exists(e))return{stdout:"",exitCode:0};let i=t.vfs.readFile(e).split(`
58
+ `).filter(Boolean),s=r[0],o=s?parseInt(s,10):null,a=o&&!Number.isNaN(o)?i.slice(-o):i,l=i.length-a.length+1;return{stdout:a.map((u,d)=>`${String(l+d).padStart(5)} ${u}`).join(`
59
+ `),exitCode:0}}};var xr={name:"hostname",description:"Print hostname",category:"system",params:[],run:({hostname:r})=>({stdout:r,exitCode:0})};var br={name:"htop",description:"System monitor",category:"system",params:[],run:({mode:r})=>r==="exec"?{stderr:"htop: interactive terminal required",exitCode:1}:{openHtop:!0,exitCode:0}};var wr={name:"id",description:"Print user identity",category:"system",params:["[user]"],run:({authUser:r,shell:t,args:e})=>{let n=e[0]??r,i=n==="root"?0:1e3,s=i,a=t.users.isSudoer(n)?`${s}(${n}),0(root)`:`${s}(${n})`;return{stdout:`uid=${i}(${n}) gid=${s}(${n}) groups=${a}`,exitCode:0}}};var vr={name:"kill",description:"Send signal to process",category:"system",params:["[-9] <pid>"],run:({args:r})=>r.find(e=>!e.startsWith("-"))?{stdout:"",exitCode:0}:{stderr:"kill: no pid specified",exitCode:1}};var Cr={name:"ln",description:"Create links",category:"files",params:["[-s] <target> <link_name>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=h(n,["-s","--symbolic"]),s=n.filter(u=>!u.startsWith("-")),[o,a]=s;if(!o||!a)return{stderr:"ln: missing operand",exitCode:1};let l=S(e,a),c=i?o:S(e,o);try{if(N(r,l,"ln"),i)t.vfs.symlink(c,l);else{let u=S(e,o);if(N(r,u,"ln"),!t.vfs.exists(u))return{stderr:`ln: ${o}: No such file or directory`,exitCode:1};let d=t.vfs.readFile(u);t.writeFileAsUser(r,l,d)}return{exitCode:0}}catch(u){return{stderr:`ln: ${u instanceof Error?u.message:String(u)}`,exitCode:1}}}};function Ps(r,t){let e=t?"d":"-",i=[[256,"r"],[128,"w"],[64,"x"],[32,"r"],[16,"w"],[8,"x"],[4,"r"],[2,"w"],[1,"x"]].map(([s,o])=>r&s?o:"-").join("");return`${e}${i}`}function ks(r){return r.toISOString().replace("T"," ").slice(0,16)}var $r={name:"ls",description:"List directory contents",category:"navigation",params:["[-la] [path]"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=h(n,["-l","--long"]),s=h(n,["-a","--all"]),o=it(n,0,{flags:["-l","--long","-a","--all","-la","-al"]}),a=S(e,o??e);N(r,a,"ls");let l=t.vfs.list(a).filter(u=>s||!u.startsWith("."));return{stdout:i?l.map(u=>{let d=S(a,u),m=t.vfs.stat(d),f=m.type==="file"?m.size:m.childrenCount;return`${Ps(m.mode,m.type==="directory")} 1 ${f} ${ks(m.updatedAt)} ${u}${m.type==="directory"?"/":""}`}).join(`
60
+ `):_e(a,l,u=>t.vfs.stat(u)),exitCode:0}}};var Pr={name:"lsb_release",description:"Print distribution-specific information",category:"system",params:["[-a] [-i] [-d] [-r] [-c]"],run:({args:r,shell:t})=>{let e=t.properties?.os??"Fortune GNU/Linux x64",n="aurora",i="1.0";try{let d=t.vfs.readFile("/etc/os-release");for(let m of d.split(`
61
+ `))m.startsWith("PRETTY_NAME=")&&(e=m.slice(12).replace(/^"|"$/g,"").trim()),m.startsWith("VERSION_CODENAME=")&&(n=m.slice(17).trim()),m.startsWith("VERSION_ID=")&&(i=m.slice(11).replace(/^"|"$/g,"").trim())}catch{}let s=h(r,["-a","--all"]),o=h(r,["-i","--id"]),a=h(r,["-d","--description"]),l=h(r,["-r","--release"]),c=h(r,["-c","--codename"]);if(s||r.length===0)return{stdout:["Distributor ID: Fortune",`Description: ${e}`,`Release: ${i}`,`Codename: ${n}`].join(`
62
+ `),exitCode:0};let u=[];return o&&u.push("Distributor ID: Fortune"),a&&u.push(`Description: ${e}`),l&&u.push(`Release: ${i}`),c&&u.push(`Codename: ${n}`),{stdout:u.join(`
63
+ `),exitCode:0}}};var Ms={ls:`LS(1) User Commands LS(1)
64
+
65
+ NAME
66
+ ls - list directory contents
67
+
68
+ SYNOPSIS
69
+ ls [OPTION]... [FILE]...
70
+
71
+ DESCRIPTION
72
+ List information about the FILEs (the current directory by default).
73
+
74
+ OPTIONS
75
+ -l use a long listing format
76
+ -a do not ignore entries starting with .
77
+ -h with -l, print human readable sizes
78
+ -r reverse order while sorting
79
+ -t sort by modification time
80
+
81
+ AUTHOR
82
+ Written by Richard M. Stallman and David MacKenzie.`,cat:`CAT(1) User Commands CAT(1)
83
+
84
+ NAME
85
+ cat - concatenate files and print on the standard output
86
+
87
+ SYNOPSIS
88
+ cat [OPTION]... [FILE]...
89
+
90
+ DESCRIPTION
91
+ Concatenate FILE(s) to standard output.
92
+
93
+ OPTIONS
94
+ -n, --number number all output lines
95
+ -b, --number-nonblank number nonempty output lines`,grep:`GREP(1) User Commands GREP(1)
96
+
97
+ NAME
98
+ grep, egrep, fgrep - print lines that match patterns
99
+
100
+ SYNOPSIS
101
+ grep [OPTION]... PATTERNS [FILE]...
102
+
103
+ OPTIONS
104
+ -i, --ignore-case ignore case distinctions in patterns and data
105
+ -v, --invert-match select non-matching lines
106
+ -n, --line-number print line number with output lines
107
+ -r, --recursive read all files under each directory, recursively`,apt:`APT(8) APT APT(8)
108
+
109
+ NAME
110
+ apt - command-line interface
111
+
112
+ SYNOPSIS
113
+ apt [options] command
114
+
115
+ DESCRIPTION
116
+ apt provides a high-level commandline interface for the package
117
+ management system.
118
+
119
+ COMMANDS
120
+ install pkg... Install packages
121
+ remove pkg... Remove packages
122
+ update Download package information
123
+ upgrade Upgrade installed packages
124
+ search term Search in package descriptions
125
+ show pkg Show package information
126
+ list List packages`,ssh:`SSH(1) OpenSSH SSH(1)
127
+
128
+ NAME
129
+ ssh - OpenSSH remote login client
130
+
131
+ SYNOPSIS
132
+ ssh [-p port] [user@]hostname [command]
133
+
134
+ DESCRIPTION
135
+ ssh (SSH client) is a program for logging into a remote machine and
136
+ for executing commands on a remote machine.`,curl:`CURL(1) User Commands CURL(1)
137
+
138
+ NAME
139
+ curl - transfer a URL
140
+
141
+ SYNOPSIS
142
+ curl [options / URLs]
143
+
144
+ DESCRIPTION
145
+ curl is a tool for transferring data with URL syntax.
146
+
147
+ OPTIONS
148
+ -o, --output <file> Write output to <file>
149
+ -X, --request <method> Specify request method
150
+ -d, --data <data> HTTP POST data
151
+ -H, --header <header> Pass custom header
152
+ -s, --silent Silent mode
153
+ -I, --head Show document info only
154
+ -L, --location Follow redirects
155
+ -v, --verbose Make the operation more talkative`,chmod:`CHMOD(1) User Commands CHMOD(1)
156
+
157
+ NAME
158
+ chmod - change file mode bits
159
+
160
+ SYNOPSIS
161
+ chmod [OPTION]... MODE[,MODE]... FILE...
162
+ chmod [OPTION]... OCTAL-MODE FILE...
163
+
164
+ DESCRIPTION
165
+ Change the file mode bits of each given file according to MODE.
166
+
167
+ EXAMPLES
168
+ chmod 755 script.sh rwxr-xr-x
169
+ chmod 644 file.txt rw-r--r--
170
+ chmod +x script.sh add execute permission`,tar:`TAR(1) GNU tar Manual TAR(1)
171
+
172
+ NAME
173
+ tar - an archiving utility
174
+
175
+ SYNOPSIS
176
+ tar [OPTION...] [FILE]...
177
+
178
+ DESCRIPTION
179
+ tar saves many files together into a single tape or disk archive,
180
+ and can restore individual files from the archive.
181
+
182
+ OPTIONS
183
+ -c, --create create a new archive
184
+ -x, --extract extract files from an archive
185
+ -z, --gzip filter the archive through gzip
186
+ -f, --file=ARCHIVE use archive file or device ARCHIVE
187
+ -v, --verbose verbosely list files processed
188
+ -t, --list list the contents of an archive`},kr={name:"man",description:"Interface to the system reference manuals",category:"shell",params:["<command>"],run:({args:r,shell:t})=>{let e=r[0];if(!e)return{stderr:"What manual page do you want?",exitCode:1};let n=`/usr/share/man/man1/${e}.1`;if(t.vfs.exists(n))return{stdout:t.vfs.readFile(n),exitCode:0};let i=Ms[e.toLowerCase()];return i?{stdout:i,exitCode:0}:{stderr:`No manual entry for ${e}`,exitCode:16}}};var Mr={name:"mkdir",description:"Make directories",category:"files",params:["<dir>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{if(n.length===0)return{stderr:"mkdir: missing operand",exitCode:1};for(let i=0;i<n.length;i++){let s=it(n,i);if(!s)return{stderr:"mkdir: missing operand",exitCode:1};let o=S(e,s);N(r,o,"mkdir"),t.vfs.mkdir(o)}return{exitCode:0}}};var Er={name:"mv",description:"Move or rename files",category:"files",params:["<source> <dest>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=n.filter(c=>!c.startsWith("-")),[s,o]=i;if(!s||!o)return{stderr:"mv: missing operand",exitCode:1};let a=S(e,s),l=S(e,o);try{if(N(r,a,"mv"),N(r,l,"mv"),!t.vfs.exists(a))return{stderr:`mv: ${s}: No such file or directory`,exitCode:1};let c=t.vfs.exists(l)&&t.vfs.stat(l).type==="directory"?`${l}/${s.split("/").pop()}`:l;return t.vfs.move(a,c),{exitCode:0}}catch(c){return{stderr:`mv: ${c instanceof Error?c.message:String(c)}`,exitCode:1}}}};import*as Ar from"node:path";var Fr={name:"nano",description:"Text editor",category:"files",params:["<file>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=n[0];if(!i)return{stderr:"nano: missing file operand",exitCode:1};let s=S(e,i);N(r,s,"nano");let o=t.vfs.exists(s)?t.vfs.readFile(s):"",a=Ar.posix.basename(s)||"buffer",l=`/tmp/sshmimic-nano-${Date.now()}-${a}.tmp`;return{openEditor:{targetPath:s,tempPath:l,initialContent:o},exitCode:0}}};import{existsSync as Lr,readdirSync as Es,readFileSync as ce}from"node:fs";import*as Q from"node:os";import*as Tr from"node:path";function As(r){let t=Math.max(1,Math.floor(r/60)),e=Math.floor(t/1440),n=Math.floor(t%1440/60),i=t%60,s=[];return e>0&&s.push(`${e} day${e>1?"s":""}`),n>0&&s.push(`${n} hour${n>1?"s":""}`),(i>0||s.length===0)&&s.push(`${i} min${i>1?"s":""}`),s.join(", ")}function Nr(r){return`\x1B[${r}m \x1B[0m`}function Fs(){let r=[40,41,42,43,44,45,46,47].map(Nr).join(""),t=[100,101,102,103,104,105,106,107].map(Nr).join("");return[r,t]}function Ir(r,t,e){if(r.trim().length===0)return r;let n={r:255,g:255,b:255},i={r:168,g:85,b:247},s=e<=1?0:t/(e-1),o=Math.round(n.r+(i.r-n.r)*s),a=Math.round(n.g+(i.g-n.g)*s),l=Math.round(n.b+(i.b-n.b)*s);return`\x1B[38;2;${o};${a};${l}m${r}\x1B[0m`}function Ns(r){if(r.trim().length===0)return r;let t=r.indexOf(":");if(t===-1)return r.includes("@")?Vr(r):r;let e=r.substring(0,t+1),n=r.substring(t+1);return Vr(e)+n}function Vr(r){let t=new RegExp("\x1B\\[[\\d;]*m","g"),e=r.replace(t,"");if(e.trim().length===0)return r;let n={r:255,g:255,b:255},i={r:168,g:85,b:247},s="";for(let o=0;o<e.length;o+=1){let a=e.length<=1?0:o/(e.length-1),l=Math.round(n.r+(i.r-n.r)*a),c=Math.round(n.g+(i.g-n.g)*a),u=Math.round(n.b+(i.b-n.b)*a);s+=`\x1B[38;2;${l};${c};${u}m${e[o]}\x1B[0m`}return s}function Rr(r){return Math.max(0,Math.round(r/(1024*1024)))}function Dr(){try{let r=ce("/etc/os-release","utf8");for(let t of r.split(`
189
+ `)){if(!t.startsWith("PRETTY_NAME="))continue;return t.slice(12).trim().replace(/^"|"$/g,"")}}catch{return}}function _r(r){try{let t=ce(r,"utf8").split(`
190
+ `)[0]?.trim();return!t||t.length===0?void 0:t}catch{return}}function Is(r){let t=_r("/sys/devices/virtual/dmi/id/sys_vendor"),e=_r("/sys/devices/virtual/dmi/id/product_name");return t&&e?`${t} ${e}`:e||r}function Vs(){let r=["/var/lib/dpkg/status","/usr/local/var/lib/dpkg/status"];for(let t of r)if(Lr(t))try{return ce(t,"utf8").match(/^Package:\s+/gm)?.length??0}catch{}}function Rs(){let r=["/snap","/var/lib/snapd/snaps"];for(let t of r)if(Lr(t))try{return Es(t,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}}function Ds(){let r=Vs(),t=Rs();return r!==void 0&&t!==void 0?`${r} (dpkg), ${t} (snap)`:r!==void 0?`${r} (dpkg)`:t!==void 0?`${t} (snap)`:"n/a"}function _s(){let r=Q.cpus();if(r.length===0)return"unknown";let t=r[0];if(!t)return"unknown";let e=(t.speed/1e3).toFixed(2);return`${t.model} (${r.length}) @ ${e}GHz`}function Ls(r){return!r||r.trim().length===0?"unknown":Tr.posix.basename(r.trim())}function Ts(r){let t=Q.totalmem(),e=Q.freemem(),n=Math.max(0,t-e),i=r.shellProps,s=process.uptime();return r.uptimeSeconds===void 0&&(r.uptimeSeconds=Math.round(s)),{user:r.user,host:r.host,osName:i?.os??r.osName??`${Dr()??Q.type()} ${Q.arch()}`,kernel:i?.kernel??r.kernel??Q.release(),uptimeSeconds:r.uptimeSeconds??Q.uptime(),packages:r.packages??Ds(),shell:Ls(r.shell),shellProps:r.shellProps??{kernel:r.kernel??Q.release(),os:r.osName??`${Dr()??Q.type()} ${Q.arch()}`,arch:Q.arch()},resolution:r.resolution??"n/a (ssh)",terminal:r.terminal??"unknown",cpu:r.cpu??_s(),gpu:r.gpu??"n/a",memoryUsedMiB:r.memoryUsedMiB??Rr(n),memoryTotalMiB:r.memoryTotalMiB??Rr(t)}}function Or(r){let t=Ts(r),e=As(t.uptimeSeconds),n=Fs(),i=[" .. .:. "," .::.. .. .. ",". .... ... .. ",": .... .:. .. ",": .:.:........:. .. ",": .. ",". : ",". : ",".. : "," :. .. "," .. .. "," :-. :: "," .:. :. "," ..: ... "," ..: :.. "," :... :...."," .. ...."," . .. "," .:. .: "," :. .. "," ::. .. ","..... ..:... ","...:. .. ",".:...:. ::. .. "," ... ..:::::.. ..:::::::.. "],s=[`${t.user}@${t.host}`,"-------------------------",`OS: ${t.osName}`,`Host: ${Is(t.host)}`,`Kernel: ${t.kernel}`,`Uptime: ${e}`,`Packages: ${t.packages}`,`Shell: ${t.shell}`,`Resolution: ${t.resolution}`,`Terminal: ${t.terminal}`,`CPU: ${t.cpu}`,`GPU: ${t.gpu}`,`Memory: ${t.memoryUsedMiB}MiB / ${t.memoryTotalMiB}MiB`,"",n[0],n[1]],o=Math.max(i.length,s.length),a=[];for(let l=0;l<o;l+=1){let c=i[l]??"",u=s[l]??"";if(u.length>0){let d=Ir(c.padEnd(31," "),l,i.length),m=Ns(u);a.push(`${d} ${m}`);continue}a.push(Ir(c,l,i.length))}return a.join(`
191
+ `)}var ue={PATH:"/usr/local/bin:/usr/bin:/bin",HOME:"/home/user",SHELL:"/bin/sh",TERM:"xterm-256color",USER:"user"};function zr(r){return ue.USER=r,ue.HOME=`/home/${r}`,{...ue}}var Br={name:"set",description:"Display or set shell variables",category:"shell",params:["[VAR=value]"],run:({args:r,env:t})=>{if(r.length===0)return{stdout:Object.entries(t.vars).map(([n,i])=>`${n}=${i}`).join(`
192
+ `),exitCode:0};for(let e of r)if(e.includes("=")){let n=e.indexOf("=");t.vars[e.slice(0,n)]=e.slice(n+1)}return{exitCode:0}}};var Ur={name:"neofetch",description:"System info display",category:"system",params:["[--off]"],run:({args:r,authUser:t,hostname:e,shell:n})=>{let i=zr(t);return h(r,"--help")?{stdout:"Usage: neofetch [--off]",exitCode:0}:h(r,"--off")?{stdout:`${t}@${e}`,exitCode:0}:{stdout:Or({user:t,host:e,shell:i.SHELL,shellProps:n.properties,terminal:i.TERM,uptimeSeconds:Math.floor((Date.now()-n.startTime)/1e3),packages:`${n.packageManager?.installedCount()??0} (dpkg)`}),exitCode:0}}};import jr from"node:vm";var jt="v18.19.0",Wr={node:jt,npm:"9.2.0",v8:"10.2.154.26-node.22"};function Os(r,t){let e={version:jt,versions:Wr,platform:"linux",arch:"x64",env:{NODE_ENV:"production",HOME:"/root",PATH:"/usr/local/bin:/usr/bin:/bin"},argv:["node"],stdout:{write:s=>(r.push(s),!0)},stderr:{write:s=>(t.push(s),!0)},exit:(s=0)=>{throw new Wt(s)},cwd:()=>"/root",hrtime:()=>[0,0]},n={log:(...s)=>r.push(s.map(ut).join(" ")),error:(...s)=>t.push(s.map(ut).join(" ")),warn:(...s)=>t.push(s.map(ut).join(" ")),info:(...s)=>r.push(s.map(ut).join(" ")),dir:s=>r.push(ut(s))},i=s=>{switch(s){case"path":return{join:(...o)=>o.join("/").replace(/\/+/g,"/"),resolve:(...o)=>`/${o.join("/").replace(/^\/+/,"")}`,dirname:o=>o.split("/").slice(0,-1).join("/")||"/",basename:o=>o.split("/").pop()??"",extname:o=>{let a=o.split("/").pop()??"",l=a.lastIndexOf(".");return l>0?a.slice(l):""},sep:"/",delimiter:":"};case"os":return{platform:()=>"linux",arch:()=>"x64",type:()=>"Linux",hostname:()=>"fortune-vm",homedir:()=>"/root",tmpdir:()=>"/tmp",EOL:`
193
+ `};case"util":return{format:(...o)=>o.map(ut).join(" "),inspect:o=>ut(o)};case"fs":case"fs/promises":throw new Error(`Cannot require '${s}': filesystem access not available in virtual runtime`);case"child_process":case"net":case"http":case"https":throw new Error(`Cannot require '${s}': not available in virtual runtime`);default:throw new Error(`Cannot find module '${s}'`)}};return i.resolve=s=>{throw new Error(`Cannot resolve '${s}'`)},i.cache={},i.extensions={},jr.createContext({console:n,process:e,require:i,Math,JSON,Object,Array,String,Number,Boolean,Symbol,Date,RegExp,Error,TypeError,RangeError,SyntaxError,Promise,Map,Set,WeakMap,WeakSet,parseInt,parseFloat,isNaN,isFinite,encodeURIComponent,decodeURIComponent,encodeURI,decodeURI,setTimeout:()=>{},clearTimeout:()=>{},setInterval:()=>{},clearInterval:()=>{},queueMicrotask:()=>{},globalThis:void 0,undefined:void 0,Infinity:1/0,NaN:NaN})}var Wt=class{constructor(t){this.code=t}code};function ut(r){if(r===null)return"null";if(r===void 0)return"undefined";if(typeof r=="string")return r;if(typeof r=="function")return`[Function: ${r.name||"(anonymous)"}]`;if(Array.isArray(r))return`[ ${r.map(ut).join(", ")} ]`;if(r instanceof Error)return`${r.name}: ${r.message}`;if(typeof r=="object")try{return`{ ${Object.entries(r).map(([e,n])=>`${e}: ${ut(n)}`).join(", ")} }`}catch{return"[Object]"}return String(r)}function Ht(r){let t=[],e=[],n=Os(t,e),i=0;try{let s=jr.runInContext(r,n,{timeout:5e3});s!==void 0&&t.length===0&&t.push(ut(s))}catch(s){s instanceof Wt?i=s.code:s instanceof Error?(e.push(`${s.name}: ${s.message}`),i=1):(e.push(String(s)),i=1)}return{stdout:t.length?`${t.join(`
194
+ `)}
195
+ `:"",stderr:e.length?`${e.join(`
196
+ `)}
197
+ `:"",exitCode:i}}function zs(r){let t=r.trim();return!t.includes(`
198
+ `)&&!t.startsWith("const ")&&!t.startsWith("let ")&&!t.startsWith("var ")&&!t.startsWith("function ")&&!t.startsWith("class ")&&!t.startsWith("if ")&&!t.startsWith("for ")&&!t.startsWith("while ")&&!t.startsWith("import ")&&!t.startsWith("//")?Ht(t):Ht(`(async () => { ${r} })()`)}var Hr={name:"node",description:"JavaScript runtime (virtual)",category:"system",params:["[--version] [-e <expr>] [-p <expr>] [file]"],run:({args:r,shell:t,cwd:e})=>{if(!t.packageManager.isInstalled("nodejs"))return{stderr:`bash: node: command not found
199
+ Hint: install it with: apt install nodejs
200
+ `,exitCode:127};if(h(r,["--version","-v"]))return{stdout:`${jt}
201
+ `,exitCode:0};if(h(r,["--versions"]))return{stdout:`${JSON.stringify(Wr,null,2)}
202
+ `,exitCode:0};let n=r.findIndex(o=>o==="-e"||o==="--eval");if(n!==-1){let o=r[n+1];if(!o)return{stderr:`node: -e requires an argument
203
+ `,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=Ht(o);return{stdout:a||void 0,stderr:l||void 0,exitCode:c}}let i=r.findIndex(o=>o==="-p"||o==="--print");if(i!==-1){let o=r[i+1];if(!o)return{stderr:`node: -p requires an argument
204
+ `,exitCode:1};let{stdout:a,stderr:l,exitCode:c}=Ht(o);return{stdout:a||(c===0?`
205
+ `:void 0),stderr:l||void 0,exitCode:c}}let s=r.find(o=>!o.startsWith("-"));if(s){let o=S(e,s);if(!t.vfs.exists(o))return{stderr:`node: cannot open file '${s}': No such file or directory
206
+ `,exitCode:1};let a=t.vfs.readFile(o),{stdout:l,stderr:c,exitCode:u}=zs(a);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}return{stdout:[`Welcome to Node.js ${jt}.`,'Type ".exit" to exit the REPL.',"> "].join(`
207
+ `),exitCode:0}}};var qt="9.2.0",Bs="18.19.0",qr={name:"npm",description:"Node.js package manager (virtual)",category:"system",params:["<command> [args]"],run:({args:r,shell:t})=>{if(!t.packageManager.isInstalled("npm"))return{stderr:`bash: npm: command not found
208
+ Hint: install it with: apt install npm
209
+ `,exitCode:127};if(h(r,["--version","-v"]))return{stdout:`${qt}
210
+ `,exitCode:0};let e=r[0]?.toLowerCase();switch(e){case"version":case"-version":return{stdout:`{ npm: '${qt}', node: '${Bs}', v8: '10.2.154.26' }
211
+ `,exitCode:0};case"install":case"i":case"add":return{stderr:`npm warn: package installation is not available in the virtual runtime.
212
+ npm warn: This environment simulates npm CLI behaviour only.
213
+ `,exitCode:1};case"run":case"exec":case"x":return{stderr:`npm error: script execution is not available in the virtual runtime.
214
+ `,exitCode:1};case"init":return{stdout:`Wrote to /home/user/package.json
215
+ `,exitCode:0};case"list":case"ls":return{stdout:`${e==="ls"||e==="list"?"virtual-env@1.0.0":""}
216
+ \u2514\u2500\u2500 (empty)
217
+ `,exitCode:0};case"help":case void 0:return{stdout:`${[`npm ${qt}`,"","Usage: npm <command>","","Commands:"," install (not available in virtual runtime)"," run (not available in virtual runtime)"," exec (not available in virtual runtime)"," list List installed packages"," version Print versions"," --version Print npm version"].join(`
218
+ `)}
219
+ `,exitCode:0};default:return{stderr:`npm error: unknown command: ${e}
220
+ `,exitCode:1}}}},Kr={name:"npx",description:"Node.js package runner (virtual)",category:"system",params:["<package> [args]"],run:({args:r,shell:t})=>t.packageManager.isInstalled("npm")?h(r,["--version"])?{stdout:`${qt}
221
+ `,exitCode:0}:{stderr:`npx: package execution is not available in the virtual runtime.
222
+ `,exitCode:1}:{stderr:`bash: npx: command not found
223
+ Hint: install it with: apt install npm
224
+ `,exitCode:127}};var Gr={name:"passwd",description:"Change user password",category:"users",params:["<username> <password>"],run:async({authUser:r,args:t,shell:e})=>{let[n,i]=t;return!n||!i?{stderr:"passwd: usage: passwd <username> <password>",exitCode:1}:r!=="root"&&r!==n?{stderr:"passwd: permission denied",exitCode:1}:(await e.users.setPassword(n,i),{stdout:`passwd: password updated for '${n}'`,exitCode:0})}};var Zr={name:"ping",description:"Send ICMP ECHO_REQUEST (mock)",category:"network",params:["[-c <count>] <host>"],run:({args:r})=>{let{flagsWithValues:t,positionals:e}=et(r,{flagsWithValue:["-c","-i","-W"]}),n=e[0]??"localhost",i=t.get("-c"),s=i?Math.max(1,parseInt(i,10)||4):4,o=[`PING ${n}: 56 data bytes`];for(let a=0;a<s;a++){let l=(Math.random()*10+1).toFixed(3);o.push(`64 bytes from ${n}: icmp_seq=${a} ttl=64 time=${l} ms`)}return o.push(`--- ${n} ping statistics ---`),o.push(`${s} packets transmitted, ${s} received, 0% packet loss`),{stdout:o.join(`
225
+ `),exitCode:0}}};function Us(r,t){let e=0,n="",i=0;for(;i<r.length;){if(r[i]==="\\"&&i+1<r.length)switch(r[i+1]){case"n":n+=`
226
+ `,i+=2;continue;case"t":n+=" ",i+=2;continue;case"r":n+="\r",i+=2;continue;case"\\":n+="\\",i+=2;continue;case"a":n+="\x07",i+=2;continue;case"b":n+="\b",i+=2;continue;case"f":n+="\f",i+=2;continue;case"v":n+="\v",i+=2;continue;default:n+=r[i],i++;continue}if(r[i]==="%"&&i+1<r.length){let s=i+1;for(r[s]==="-"&&s++;s<r.length&&/\d/.test(r[s]);)s++;if(r[s]===".")for(s++;s<r.length&&/\d/.test(r[s]);)s++;let o=r[s],a=t[e++]??"";switch(o){case"s":n+=a;break;case"d":case"i":n+=String(parseInt(a,10)||0);break;case"f":n+=String(parseFloat(a)||0);break;case"o":n+=(parseInt(a,10)||0).toString(8);break;case"x":n+=(parseInt(a,10)||0).toString(16);break;case"X":n+=(parseInt(a,10)||0).toString(16).toUpperCase();break;case"%":n+="%",e--;break;default:n+=r[i],i++;continue}i=s+1;continue}n+=r[i],i++}return n}var Jr={name:"printf",description:"Format and print data",category:"shell",params:["<format> [args...]"],run:({args:r})=>{let t=r[0];return t?{stdout:Us(t,r.slice(1)),exitCode:0}:{stderr:"printf: missing format string",exitCode:1}}};var Yr={name:"ps",description:"Report process status",category:"system",params:["[-a] [-u] [-x] [aux]"],run:({authUser:r,shell:t,args:e})=>{let n=t.users.listActiveSessions(),i=h(e,["-u"])||e.includes("u")||e.includes("aux")||e.includes("au"),s=h(e,["-a","-x"])||e.includes("a")||e.includes("aux");if(i){let u=["USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND"],d=1e3;for(let m of n){let f=m.username.padEnd(10).slice(0,10),x=(Math.random()*.5).toFixed(1),g=Math.floor(Math.random()*2e4+5e3),y=Math.floor(Math.random()*5e3+1e3);u.push(`${f} ${String(d).padStart(6)} 0.0 ${x.padStart(4)} ${String(g).padStart(6)} ${String(y).padStart(5)} ${m.tty.padEnd(8)} Ss 00:00 0:00 bash`),d++}return u.push(`root ${String(d).padStart(6)} 0.0 0.0 0 0 ? S 00:00 0:00 ps`),{stdout:u.join(`
227
+ `),exitCode:0}}let a=[" PID TTY TIME CMD"],l=1e3;for(let c of n)!s&&c.username!==r||(a.push(`${String(l).padStart(5)} ${c.tty.padEnd(12)} 00:00:00 ${c.username===r?"bash":`bash (${c.username})`}`),l++);return a.push(`${String(l).padStart(5)} pts/0 00:00:00 ps`),{stdout:a.join(`
228
+ `),exitCode:0}}};var Qr={name:"pwd",description:"Print working directory",category:"navigation",params:[],run:({cwd:r})=>({stdout:r,exitCode:0})};var js="Python 3.11.2";var Kt="3.11.2 (default, Mar 13 2023, 12:18:29) [GCC 12.2.0]",p={__pytype__:"none"};function j(r=[]){return{__pytype__:"dict",data:new Map(r)}}function de(r,t,e=1){return{__pytype__:"range",start:r,stop:t,step:e}}function B(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="dict"}function $t(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="range"}function dt(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="func"}function me(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="class"}function Ft(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="instance"}function gt(r){return!!r&&typeof r=="object"&&!Array.isArray(r)&&r.__pytype__==="none"}function G(r){return r===null||gt(r)?"None":r===!0?"True":r===!1?"False":typeof r=="number"?Number.isInteger(r)?String(r):r.toPrecision(12).replace(/\.?0+$/,""):typeof r=="string"?`'${r.replace(/'/g,"\\'")}'`:Array.isArray(r)?`[${r.map(G).join(", ")}]`:B(r)?`{${[...r.data.entries()].map(([t,e])=>`'${t}': ${G(e)}`).join(", ")}}`:$t(r)?`range(${r.start}, ${r.stop}${r.step!==1?`, ${r.step}`:""})`:dt(r)?`<function ${r.name} at 0x...>`:me(r)?`<class '${r.name}'>`:Ft(r)?`<${r.cls.name} object at 0x...>`:String(r)}function M(r){return r===null||gt(r)?"None":r===!0?"True":r===!1?"False":typeof r=="number"?Number.isInteger(r)?String(r):r.toPrecision(12).replace(/\.?0+$/,""):typeof r=="string"?r:Array.isArray(r)?`[${r.map(G).join(", ")}]`:B(r)?`{${[...r.data.entries()].map(([t,e])=>`'${t}': ${G(e)}`).join(", ")}}`:$t(r)?`range(${r.start}, ${r.stop}${r.step!==1?`, ${r.step}`:""})`:G(r)}function nt(r){return r===null||gt(r)?!1:typeof r=="boolean"?r:typeof r=="number"?r!==0:typeof r=="string"||Array.isArray(r)?r.length>0:B(r)?r.data.size>0:$t(r)?tn(r)>0:!0}function tn(r){if(r.step===0)return 0;let t=Math.ceil((r.stop-r.start)/r.step);return Math.max(0,t)}function Ws(r){let t=[];for(let e=r.start;(r.step>0?e<r.stop:e>r.stop)&&(t.push(e),!(t.length>1e4));e+=r.step);return t}function K(r){if(Array.isArray(r))return r;if(typeof r=="string")return[...r];if($t(r))return Ws(r);if(B(r))return[...r.data.keys()];throw new U("TypeError",`'${St(r)}' object is not iterable`)}function St(r){return r===null||gt(r)?"NoneType":typeof r=="boolean"?"bool":typeof r=="number"?Number.isInteger(r)?"int":"float":typeof r=="string"?"str":Array.isArray(r)?"list":B(r)?"dict":$t(r)?"range":dt(r)?"function":me(r)?"type":Ft(r)?r.cls.name:"object"}var U=class{constructor(t,e){this.type=t;this.message=e}type;message;toString(){return`${this.type}: ${this.message}`}},Ct=class{constructor(t){this.value=t}value},Nt=class{},It=class{},Vt=class{constructor(t){this.code=t}code};function Hs(r){let t=new Map,e=j([["sep","/"],["linesep",`
229
+ `],["curdir","."],["pardir",".."]]);return e.__methods__={getcwd:()=>r,getenv:n=>typeof n=="string"?process.env[n]??p:p,path:j([["join",p],["exists",p],["dirname",p],["basename",p]]),listdir:()=>[]},t.set("__builtins__",p),t.set("__name__","__main__"),t.set("__cwd__",r),t}function qs(r){let t=j([["sep","/"],["curdir","."]]),e=j([["sep","/"],["linesep",`
230
+ `],["name","posix"]]);return e._cwd=r,t._cwd=r,e.path=t,e}function Ks(){return j([["version",Kt],["version_info",j([["major",3],["minor",11],["micro",2]].map(([r,t])=>[r,t]))],["platform","linux"],["executable","/usr/bin/python3"],["prefix","/usr"],["path",["/usr/lib/python3.11","/usr/lib/python3.11/lib-dynload"]],["argv",[""]],["maxsize",9007199254740991]])}function Gs(){return j([["pi",Math.PI],["e",Math.E],["tau",Math.PI*2],["inf",1/0],["nan",NaN],["sqrt",p],["floor",p],["ceil",p],["log",p],["pow",p],["sin",p],["cos",p],["tan",p],["fabs",p],["factorial",p]])}function Zs(){return j([["dumps",p],["loads",p]])}function Js(){return j([["match",p],["search",p],["findall",p],["sub",p],["split",p],["compile",p]])}var Xr={os:qs,sys:()=>Ks(),math:()=>Gs(),json:()=>Zs(),re:()=>Js(),random:()=>j([["random",p],["randint",p],["choice",p],["shuffle",p]]),time:()=>j([["time",p],["sleep",p],["ctime",p]]),datetime:()=>j([["datetime",p],["date",p],["timedelta",p]]),collections:()=>j([["Counter",p],["defaultdict",p],["OrderedDict",p]]),itertools:()=>j([["chain",p],["product",p],["combinations",p],["permutations",p]]),functools:()=>j([["reduce",p],["partial",p],["lru_cache",p]]),string:()=>j([["ascii_letters","abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"],["digits","0123456789"],["punctuation","!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"]])},Gt=class{constructor(t){this.cwd=t}cwd;output=[];stderr=[];modules=new Map;getOutput(){return this.output.join(`
231
+ `)+(this.output.length?`
232
+ `:"")}getStderr(){return this.stderr.join(`
233
+ `)+(this.stderr.length?`
234
+ `:"")}splitArgs(t){let e=[],n=0,i="",s=!1,o="";for(let a=0;a<t.length;a++){let l=t[a];s?(i+=l,l===o&&t[a-1]!=="\\"&&(s=!1)):l==='"'||l==="'"?(s=!0,o=l,i+=l):"([{".includes(l)?(n++,i+=l):")]}".includes(l)?(n--,i+=l):l===","&&n===0?(e.push(i.trim()),i=""):i+=l}return i.trim()&&e.push(i.trim()),e}pyEval(t,e){if(t=t.trim(),!t||t==="None")return p;if(t==="True")return!0;if(t==="False")return!1;if(t==="...")return p;if(/^-?\d+$/.test(t))return parseInt(t,10);if(/^-?\d+\.\d*$/.test(t))return parseFloat(t);if(/^0x[0-9a-fA-F]+$/.test(t))return parseInt(t,16);if(/^0o[0-7]+$/.test(t))return parseInt(t.slice(2),8);if(/^('''[\s\S]*'''|"""[\s\S]*""")$/.test(t))return t.slice(3,-3);if(/^(['"])(.*)\1$/s.test(t))return t.slice(1,-1).replace(/\\n/g,`
235
+ `).replace(/\\t/g," ").replace(/\\r/g,"\r").replace(/\\\\/g,"\\").replace(/\\'/g,"'").replace(/\\"/g,'"');let n=t.match(/^f(['"])([\s\S]*)\1$/);if(n){let c=n[2];return c=c.replace(/\{([^{}]+)\}/g,(u,d)=>{try{return M(this.pyEval(d.trim(),e))}catch{return`{${d}}`}}),c}let i=t.match(/^b(['"])(.*)\1$/s);if(i)return i[2];if(t.startsWith("[")&&t.endsWith("]")){let c=t.slice(1,-1).trim();if(!c)return[];let u=c.match(/^(.+?)\s+for\s+(\w+)\s+in\s+(.+?)(?:\s+if\s+(.+))?$/);if(u){let[,d,m,f,x]=u,g=K(this.pyEval(f.trim(),e)),y=[];for(let $ of g){let V=new Map(e);V.set(m,$),!(x&&!nt(this.pyEval(x,V)))&&y.push(this.pyEval(d.trim(),V))}return y}return this.splitArgs(c).map(d=>this.pyEval(d,e))}if(t.startsWith("(")&&t.endsWith(")")){let c=t.slice(1,-1).trim();if(!c)return[];let u=this.splitArgs(c);return u.length===1&&!c.endsWith(",")?this.pyEval(u[0],e):u.map(d=>this.pyEval(d,e))}if(t.startsWith("{")&&t.endsWith("}")){let c=t.slice(1,-1).trim();if(!c)return j();let u=j();for(let d of this.splitArgs(c)){let m=d.indexOf(":");if(m===-1)continue;let f=M(this.pyEval(d.slice(0,m).trim(),e)),x=this.pyEval(d.slice(m+1).trim(),e);u.data.set(f,x)}return u}let s=t.match(/^not\s+(.+)$/);if(s)return!nt(this.pyEval(s[1],e));let o=[["or"],["and"],["in","not in","is not","is","==","!=","<=",">=","<",">"],["+","-"],["**"],["*","//","/","%"]];for(let c of o){let u=this.tryBinaryOp(t,c,e);if(u!==void 0)return u}if(t.startsWith("-")){let c=this.pyEval(t.slice(1),e);if(typeof c=="number")return-c}if(process.env.PY_DEBUG&&console.error("eval:",JSON.stringify(t)),t.endsWith("]")&&!t.startsWith("[")){let c=this.findMatchingBracket(t,"[");if(c!==-1){let u=this.pyEval(t.slice(0,c),e),d=t.slice(c+1,-1);return this.subscript(u,d,e)}}let a=t.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*\(([\s\S]*)\)$/);if(a){let[,c,u]=a,d=(u?.trim()?this.splitArgs(u):[]).map(m=>this.pyEval(m,e));return this.callBuiltin(c,d,e)}let l=this.findDotAccess(t);if(l){let{objExpr:c,attr:u,callPart:d}=l,m=this.pyEval(c,e);if(d!==void 0){let f=d.slice(1,-1),x=f.trim()?this.splitArgs(f).map(g=>this.pyEval(g,e)):[];return this.callMethod(m,u,x,e)}return this.getAttr(m,u,e)}if(/^[A-Za-z_][A-Za-z0-9_]*$/.test(t)){if(e.has(t))return e.get(t);throw new U("NameError",`name '${t}' is not defined`)}if(/^[A-Za-z_][A-Za-z0-9_.]+$/.test(t)){let c=t.split("."),u=e.get(c[0])??(()=>{throw new U("NameError",`name '${c[0]}' is not defined`)})();for(let d of c.slice(1))u=this.getAttr(u,d,e);return u}return p}findMatchingBracket(t,e){let n=e==="["?"]":e==="("?")":"}",i=0;for(let s=t.length-1;s>=0;s--)if(t[s]===n&&i++,t[s]===e&&(i--,i===0))return s;return-1}findDotAccess(t){let e=0,n=!1,i="";for(let s=t.length-1;s>0;s--){let o=t[s];if(n){o===i&&t[s-1]!=="\\"&&(n=!1);continue}if(o==='"'||o==="'"){n=!0,i=o;continue}if(")]}".includes(o)){e++;continue}if("([{".includes(o)){e--;continue}if(e!==0||o!==".")continue;let a=t.slice(0,s).trim(),c=t.slice(s+1).match(/^(\w+)(\([\s\S]*\))?$/);if(c&&!/^-?\d+$/.test(a))return{objExpr:a,attr:c[1],callPart:c[2]}}return null}tryBinaryOp(t,e,n){let i=0,s=!1,o="";for(let a=t.length-1;a>=0;a--){let l=t[a];if(s){l===o&&t[a-1]!=="\\"&&(s=!1);continue}if(l==='"'||l==="'"){s=!0,o=l;continue}if(")]}".includes(l)){i++;continue}if("([{".includes(l)){i--;continue}if(i===0){for(let c of e)if(t.slice(a,a+c.length)===c){if(c==="*"&&(t[a+1]==="*"||t[a-1]==="*"))continue;let u=t[a-1],d=t[a+c.length];if(/^[a-z]/.test(c)&&(u&&/\w/.test(u)||d&&/\w/.test(d)))continue;let f=t.slice(0,a).trim(),x=t.slice(a+c.length).trim();if(!f||!x)continue;return this.applyBinaryOp(c,f,x,n)}}}}applyBinaryOp(t,e,n,i){if(t==="and"){let a=this.pyEval(e,i);return nt(a)?this.pyEval(n,i):a}if(t==="or"){let a=this.pyEval(e,i);return nt(a)?a:this.pyEval(n,i)}let s=this.pyEval(e,i),o=this.pyEval(n,i);switch(t){case"+":return typeof s=="string"&&typeof o=="string"?s+o:Array.isArray(s)&&Array.isArray(o)?[...s,...o]:s+o;case"-":return s-o;case"*":if(typeof s=="string"&&typeof o=="number")return s.repeat(o);if(Array.isArray(s)&&typeof o=="number"){let a=[];for(let l=0;l<o;l++)a.push(...s);return a}return s*o;case"/":{if(o===0)throw new U("ZeroDivisionError","division by zero");return s/o}case"//":{if(o===0)throw new U("ZeroDivisionError","integer division or modulo by zero");return Math.floor(s/o)}case"%":{if(typeof s=="string")return this.pyStringFormat(s,Array.isArray(o)?o:[o]);if(o===0)throw new U("ZeroDivisionError","integer division or modulo by zero");return s%o}case"**":return s**o;case"==":return G(s)===G(o)||s===o;case"!=":return G(s)!==G(o)&&s!==o;case"<":return s<o;case"<=":return s<=o;case">":return s>o;case">=":return s>=o;case"in":return this.pyIn(o,s);case"not in":return!this.pyIn(o,s);case"is":return s===o||gt(s)&&gt(o);case"is not":return!(s===o||gt(s)&&gt(o))}return p}pyIn(t,e){return typeof t=="string"?typeof e=="string"&&t.includes(e):Array.isArray(t)?t.some(n=>G(n)===G(e)):B(t)?t.data.has(M(e)):!1}subscript(t,e,n){if(e.includes(":")){let s=e.split(":").map(l=>l.trim()),o=s[0]?this.pyEval(s[0],n):void 0,a=s[1]?this.pyEval(s[1],n):void 0;return typeof t=="string"||Array.isArray(t)?t.slice(o,a):p}let i=this.pyEval(e,n);if(Array.isArray(t)){let s=i;return s<0&&(s=t.length+s),t[s]??p}if(typeof t=="string"){let s=i;return s<0&&(s=t.length+s),t[s]??p}if(B(t))return t.data.get(M(i))??p;throw new U("TypeError",`'${St(t)}' is not subscriptable`)}getAttr(t,e,n){return B(t)?t.data.has(e)?t.data.get(e):e==="path"&&t.path?t.path:p:Ft(t)?t.attrs.get(e)??p:typeof t=="string"?{__class__:{__pytype__:"class",name:"str"}}[e]??p:p}callMethod(t,e,n,i){if(typeof t=="string")switch(e){case"upper":return t.toUpperCase();case"lower":return t.toLowerCase();case"strip":return(n[0]?t.replace(new RegExp(`[${n[0]}]+`,"g"),""):t).trim();case"lstrip":return t.trimStart();case"rstrip":return t.trimEnd();case"split":return t.split(typeof n[0]=="string"?n[0]:/\s+/).filter((s,o)=>o>0||s!=="");case"splitlines":return t.split(`
236
+ `);case"join":return K(n[0]??[]).map(M).join(t);case"replace":return t.replaceAll(M(n[0]??""),M(n[1]??""));case"startswith":return t.startsWith(M(n[0]??""));case"endswith":return t.endsWith(M(n[0]??""));case"find":return t.indexOf(M(n[0]??""));case"index":{let s=t.indexOf(M(n[0]??""));if(s===-1)throw new U("ValueError","substring not found");return s}case"count":return t.split(M(n[0]??"")).length-1;case"format":return this.pyStringFormat(t,n);case"encode":return t;case"decode":return t;case"isdigit":return/^\d+$/.test(t);case"isalpha":return/^[a-zA-Z]+$/.test(t);case"isalnum":return/^[a-zA-Z0-9]+$/.test(t);case"isspace":return/^\s+$/.test(t);case"isupper":return t===t.toUpperCase()&&t!==t.toLowerCase();case"islower":return t===t.toLowerCase()&&t!==t.toUpperCase();case"center":{let s=n[0]??0,o=M(n[1]??" ");return t.padStart(Math.floor((s+t.length)/2),o).padEnd(s,o)}case"ljust":return t.padEnd(n[0]??0,M(n[1]??" "));case"rjust":return t.padStart(n[0]??0,M(n[1]??" "));case"zfill":return t.padStart(n[0]??0,"0");case"title":return t.replace(/\b\w/g,s=>s.toUpperCase());case"capitalize":return t[0]?.toUpperCase()+t.slice(1).toLowerCase();case"swapcase":return[...t].map(s=>s===s.toUpperCase()?s.toLowerCase():s.toUpperCase()).join("")}if(Array.isArray(t))switch(e){case"append":return t.push(n[0]??p),p;case"extend":for(let s of K(n[0]??[]))t.push(s);return p;case"insert":return t.splice(n[0]??0,0,n[1]??p),p;case"pop":{let s=n[0]!==void 0?n[0]:-1,o=s<0?t.length+s:s;return t.splice(o,1)[0]??p}case"remove":{let s=t.findIndex(o=>G(o)===G(n[0]??p));return s!==-1&&t.splice(s,1),p}case"index":{let s=t.findIndex(o=>G(o)===G(n[0]??p));if(s===-1)throw new U("ValueError","is not in list");return s}case"count":return t.filter(s=>G(s)===G(n[0]??p)).length;case"sort":return t.sort((s,o)=>typeof s=="number"&&typeof o=="number"?s-o:M(s).localeCompare(M(o))),p;case"reverse":return t.reverse(),p;case"copy":return[...t];case"clear":return t.splice(0),p}if(B(t))switch(e){case"keys":return[...t.data.keys()];case"values":return[...t.data.values()];case"items":return[...t.data.entries()].map(([s,o])=>[s,o]);case"get":return t.data.get(M(n[0]??""))??n[1]??p;case"update":{if(B(n[0]??p))for(let[s,o]of n[0].data)t.data.set(s,o);return p}case"pop":{let s=M(n[0]??""),o=t.data.get(s)??n[1]??p;return t.data.delete(s),o}case"clear":return t.data.clear(),p;case"copy":return j([...t.data.entries()]);case"setdefault":{let s=M(n[0]??"");return t.data.has(s)||t.data.set(s,n[1]??p),t.data.get(s)??p}}if(B(t)&&t.data.has("name")&&t.data.get("name")==="posix")switch(e){case"getcwd":return this.cwd;case"getenv":return typeof n[0]=="string"?process.env[n[0]]??n[1]??p:p;case"listdir":return[];case"path":return t}if(B(t))switch(e){case"join":return n.map(M).join("/").replace(/\/+/g,"/");case"exists":return!1;case"dirname":return M(n[0]??"").split("/").slice(0,-1).join("/")||"/";case"basename":return M(n[0]??"").split("/").pop()??"";case"abspath":return M(n[0]??"");case"splitext":{let s=M(n[0]??""),o=s.lastIndexOf(".");return o>0?[s.slice(0,o),s.slice(o)]:[s,""]}case"isfile":return!1;case"isdir":return!1}if(B(t)&&t.data.has("version")&&t.data.get("version")===Kt&&e==="exit")throw new Vt(n[0]??0);if(B(t)){let s={sqrt:Math.sqrt,floor:Math.floor,ceil:Math.ceil,fabs:Math.abs,log:Math.log,log2:Math.log2,log10:Math.log10,sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,atan2:Math.atan2,pow:Math.pow,exp:Math.exp,hypot:Math.hypot};if(e in s){let o=s[e];return o(...n.map(a=>a))}if(e==="factorial"){let o=n[0]??0,a=1;for(;o>1;)a*=o--;return a}if(e==="gcd"){let o=Math.abs(n[0]??0),a=Math.abs(n[1]??0);for(;a;)[o,a]=[a,o%a];return o}}if(B(t)){if(e==="dumps"){let s=B(n[1]??p)?n[1]:void 0,o=s?s.data.get("indent"):void 0;return JSON.stringify(this.pyToJs(n[0]??p),null,o)}if(e==="loads")return this.jsToPy(JSON.parse(M(n[0]??"")))}if(Ft(t)){let s=t.attrs.get(e)??t.cls.methods.get(e)??p;if(dt(s)){let o=new Map(s.closure);return o.set("self",t),s.params.slice(1).forEach((a,l)=>o.set(a,n[l]??p)),this.execBlock(s.body,o)}}throw new U("AttributeError",`'${St(t)}' object has no attribute '${e}'`)}pyStringFormat(t,e){let n=0;return t.replace(/%([diouxXeEfFgGcrs%])/g,(i,s)=>{if(s==="%")return"%";let o=e[n++];switch(s){case"d":case"i":return String(Math.trunc(o));case"f":return o.toFixed(6);case"s":return M(o??p);case"r":return G(o??p);default:return String(o)}})}pyToJs(t){return gt(t)?null:B(t)?Object.fromEntries([...t.data.entries()].map(([e,n])=>[e,this.pyToJs(n)])):Array.isArray(t)?t.map(e=>this.pyToJs(e)):t}jsToPy(t){return t==null?p:typeof t=="boolean"||typeof t=="number"||typeof t=="string"?t:Array.isArray(t)?t.map(e=>this.jsToPy(e)):typeof t=="object"?j(Object.entries(t).map(([e,n])=>[e,this.jsToPy(n)])):p}callBuiltin(t,e,n){if(n.has(t)){let i=n.get(t)??p;return dt(i)?this.callFunc(i,e,n):me(i)?this.instantiate(i,e,n):i}switch(t){case"print":return this.output.push(e.map(M).join(" ")+`
237
+ `.replace(/\\n/g,"")),p;case"input":return this.output.push(M(e[0]??"")),"";case"int":{if(e.length===0)return 0;let i=e[1]??10,s=parseInt(M(e[0]??0),i);return Number.isNaN(s)?(()=>{throw new U("ValueError","invalid literal for int()")})():s}case"float":{if(e.length===0)return 0;let i=parseFloat(M(e[0]??0));return Number.isNaN(i)?(()=>{throw new U("ValueError","could not convert to float")})():i}case"str":return e.length===0?"":M(e[0]??p);case"bool":return e.length===0?!1:nt(e[0]??p);case"list":return e.length===0?[]:K(e[0]??[]);case"tuple":return e.length===0?[]:K(e[0]??[]);case"set":return e.length===0?[]:[...new Set(K(e[0]??[]).map(G))].map(i=>K(e[0]??[]).find(o=>G(o)===i)??p);case"dict":return e.length===0?j():B(e[0]??p)?e[0]:j();case"bytes":return typeof e[0]=="string"?e[0]:M(e[0]??"");case"bytearray":return e.length===0?"":M(e[0]??"");case"type":return e.length===1?`<class '${St(e[0]??p)}'>`:p;case"isinstance":return St(e[0]??p)===M(e[1]??"");case"issubclass":return!1;case"callable":return dt(e[0]??p);case"hasattr":return B(e[0]??p)?e[0].data.has(M(e[1]??"")):!1;case"getattr":return B(e[0]??p)?e[0].data.get(M(e[1]??""))??e[2]??p:e[2]??p;case"setattr":return B(e[0]??p)&&e[0].data.set(M(e[1]??""),e[2]??p),p;case"len":{let i=e[0]??p;if(typeof i=="string"||Array.isArray(i))return i.length;if(B(i))return i.data.size;if($t(i))return tn(i);throw new U("TypeError",`object of type '${St(i)}' has no len()`)}case"range":return e.length===1?de(0,e[0]):e.length===2?de(e[0],e[1]):de(e[0],e[1],e[2]);case"enumerate":{let i=e[1]??0;return K(e[0]??[]).map((s,o)=>[o+i,s])}case"zip":{let i=e.map(K),s=Math.min(...i.map(o=>o.length));return Array.from({length:s},(o,a)=>i.map(l=>l[a]??p))}case"map":{let i=e[0]??p;return K(e[1]??[]).map(s=>dt(i)?this.callFunc(i,[s],n):p)}case"filter":{let i=e[0]??p;return K(e[1]??[]).filter(s=>dt(i)?nt(this.callFunc(i,[s],n)):nt(s))}case"reduce":{let i=e[0]??p,s=K(e[1]??[]);if(s.length===0)return e[2]??p;let o=e[2]!==void 0?e[2]:s[0];for(let a of e[2]!==void 0?s:s.slice(1))o=dt(i)?this.callFunc(i,[o,a],n):p;return o}case"sorted":{let i=[...K(e[0]??[])],s=e[1]??p,o=B(s)?s.data.get("key")??p:s;return i.sort((a,l)=>{let c=dt(o)?this.callFunc(o,[a],n):a,u=dt(o)?this.callFunc(o,[l],n):l;return typeof c=="number"&&typeof u=="number"?c-u:M(c).localeCompare(M(u))}),i}case"reversed":return[...K(e[0]??[])].reverse();case"any":return K(e[0]??[]).some(nt);case"all":return K(e[0]??[]).every(nt);case"sum":return K(e[0]??[]).reduce((i,s)=>i+s,e[1]??0);case"max":return(e.length===1?K(e[0]??[]):e).reduce((s,o)=>s>=o?s:o);case"min":return(e.length===1?K(e[0]??[]):e).reduce((s,o)=>s<=o?s:o);case"abs":return Math.abs(e[0]??0);case"round":return e[1]!==void 0?parseFloat(e[0].toFixed(e[1])):Math.round(e[0]??0);case"divmod":{let i=e[0],s=e[1];return[Math.floor(i/s),i%s]}case"pow":return e[0]**e[1];case"hex":return`0x${e[0].toString(16)}`;case"oct":return`0o${e[0].toString(8)}`;case"bin":return`0b${e[0].toString(2)}`;case"ord":return M(e[0]??"").charCodeAt(0);case"chr":return String.fromCharCode(e[0]??0);case"id":return Math.floor(Math.random()*4294967295);case"hash":return typeof e[0]=="number"?e[0]:M(e[0]??"").split("").reduce((i,s)=>i*31+s.charCodeAt(0)|0,0);case"open":throw new U("PermissionError","open() not available in virtual runtime");case"repr":return G(e[0]??p);case"iter":return e[0]??p;case"next":return Array.isArray(e[0])&&e[0].length>0?e[0].shift():e[1]??(()=>{throw new U("StopIteration","")})();case"vars":return j([...n.entries()].map(([i,s])=>[i,s]));case"globals":return j([...n.entries()].map(([i,s])=>[i,s]));case"locals":return j([...n.entries()].map(([i,s])=>[i,s]));case"dir":{if(e.length===0)return[...n.keys()];let i=e[0]??p;return typeof i=="string"?["upper","lower","strip","split","join","replace","find","format","encode","startswith","endswith","count","isdigit","isalpha","title","capitalize"]:Array.isArray(i)?["append","extend","insert","pop","remove","index","count","sort","reverse","copy","clear"]:B(i)?["keys","values","items","get","update","pop","clear","copy","setdefault"]:[]}case"Exception":case"ValueError":case"TypeError":case"KeyError":case"IndexError":case"AttributeError":case"NameError":case"RuntimeError":case"StopIteration":case"NotImplementedError":case"OSError":case"IOError":throw new U(t,M(e[0]??""));case"exec":return this.execScript(M(e[0]??""),n),p;case"eval":return this.pyEval(M(e[0]??""),n);default:throw new U("NameError",`name '${t}' is not defined`)}}callFunc(t,e,n){let i=new Map(t.closure);t.params.forEach((s,o)=>{if(s.startsWith("*")){i.set(s.slice(1),e.slice(o));return}i.set(s,e[o]??p)});try{return this.execBlock(t.body,i)}catch(s){if(s instanceof Ct)return s.value;throw s}}instantiate(t,e,n){let i={__pytype__:"instance",cls:t,attrs:new Map};return t.methods.get("__init__")&&this.callMethod(i,"__init__",e,n),i}execScript(t,e){let n=t.split(`
238
+ `);this.execLines(n,0,e)}execLines(t,e,n){let i=e;for(;i<t.length;){let s=t[i];if(!s.trim()||s.trim().startsWith("#")){i++;continue}i=this.execStatement(t,i,n)}return i}execBlock(t,e){try{this.execLines(t,0,e)}catch(n){if(n instanceof Ct)return n.value;throw n}return p}getIndent(t){let e=0;for(let n of t)if(n===" ")e++;else if(n===" ")e+=4;else break;return e}collectBlock(t,e,n){let i=[];for(let s=e;s<t.length;s++){let o=t[s];if(!o.trim()){i.push("");continue}if(this.getIndent(o)<=n)break;i.push(o.slice(n+4))}return i}execStatement(t,e,n){let i=t[e],s=i.trim(),o=this.getIndent(i);if(s==="pass")return e+1;if(s==="break")throw new Nt;if(s==="continue")throw new It;let a=s.match(/^return(?:\s+(.+))?$/);if(a)throw new Ct(a[1]?this.pyEval(a[1],n):p);let l=s.match(/^raise(?:\s+(.+))?$/);if(l){if(l[1]){let w=this.pyEval(l[1],n);throw new U(typeof w=="string"?w:St(w),M(w))}throw new U("RuntimeError","")}let c=s.match(/^assert\s+(.+?)(?:,\s*(.+))?$/);if(c){if(!nt(this.pyEval(c[1],n)))throw new U("AssertionError",c[2]?M(this.pyEval(c[2],n)):"");return e+1}let u=s.match(/^del\s+(.+)$/);if(u)return n.delete(u[1].trim()),e+1;let d=s.match(/^import\s+(\w+)(?:\s+as\s+(\w+))?$/);if(d){let[,w,E]=d,T=Xr[w];if(T){let b=T(this.cwd);this.modules.set(w,b),n.set(E??w,b)}return e+1}let m=s.match(/^from\s+(\w+)\s+import\s+(.+)$/);if(m){let[,w,E]=m,T=Xr[w];if(T){let b=T(this.cwd);if(E?.trim()==="*")for(let[P,I]of b.data)n.set(P,I);else for(let P of E.split(",").map(I=>I.trim()))n.set(P,b.data.get(P)??p)}return e+1}let f=s.match(/^def\s+(\w+)\s*\(([^)]*)\)\s*:$/);if(f){let[,w,E]=f,T=E.split(",").map(I=>I.trim()).filter(Boolean),b=this.collectBlock(t,e+1,o),P={__pytype__:"func",name:w,params:T,body:b,closure:new Map(n)};return n.set(w,P),e+1+b.length}let x=s.match(/^class\s+(\w+)(?:\(([^)]*)\))?\s*:$/);if(x){let[,w,E]=x,T=E?E.split(",").map(H=>H.trim()):[],b=this.collectBlock(t,e+1,o),P={__pytype__:"class",name:w,methods:new Map,bases:T},I=0;for(;I<b.length;){let z=b[I].trim().match(/^def\s+(\w+)\s*\(([^)]*)\)\s*:$/);if(z){let[,q,ft]=z,ot=ft.split(",").map(C=>C.trim()).filter(Boolean),ht=this.collectBlock(b,I+1,0);P.methods.set(q,{__pytype__:"func",name:q,params:ot,body:ht,closure:new Map(n)}),I+=1+ht.length}else I++}return n.set(w,P),e+1+b.length}if(s.startsWith("if ")&&s.endsWith(":")){let w=s.slice(3,-1).trim(),E=this.collectBlock(t,e+1,o),T=E.length+1;if(nt(this.pyEval(w,n))){this.execBlock(E,new Map(n).also?.(I=>{for(let[H,z]of n)I.set(H,z)})??n),this.runBlockInScope(E,n);let P=e+1+E.length;for(;P<t.length;){let I=t[P].trim();if(this.getIndent(t[P])<o||!I.startsWith("elif")&&!I.startsWith("else"))break;let H=this.collectBlock(t,P+1,o);P+=1+H.length}return P}let b=e+1+E.length;for(;b<t.length;){let P=t[b],I=P.trim();if(this.getIndent(P)!==o)break;let H=I.match(/^elif\s+(.+):$/);if(H){let z=this.collectBlock(t,b+1,o);if(nt(this.pyEval(H[1],n))){for(this.runBlockInScope(z,n),b+=1+z.length;b<t.length;){let q=t[b].trim();if(this.getIndent(t[b])!==o||!q.startsWith("elif")&&!q.startsWith("else"))break;let ft=this.collectBlock(t,b+1,o);b+=1+ft.length}return b}b+=1+z.length;continue}if(I==="else:"){let z=this.collectBlock(t,b+1,o);return this.runBlockInScope(z,n),b+1+z.length}break}return b}let g=s.match(/^for\s+(.+?)\s+in\s+(.+?)\s*:$/);if(g){let[,w,E]=g,T=K(this.pyEval(E.trim(),n)),b=this.collectBlock(t,e+1,o),P=[],I=e+1+b.length;I<t.length&&t[I]?.trim()==="else:"&&(P=this.collectBlock(t,I+1,o),I+=1+P.length);let H=!1;for(let z of T){if(w.includes(",")){let q=w.split(",").map(ot=>ot.trim()),ft=Array.isArray(z)?z:[z];q.forEach((ot,ht)=>n.set(ot,ft[ht]??p))}else n.set(w.trim(),z);try{this.runBlockInScope(b,n)}catch(q){if(q instanceof Nt){H=!0;break}if(q instanceof It)continue;throw q}}return!H&&P.length&&this.runBlockInScope(P,n),I}let y=s.match(/^while\s+(.+?)\s*:$/);if(y){let w=y[1],E=this.collectBlock(t,e+1,o),T=0;for(;nt(this.pyEval(w,n))&&T++<1e5;)try{this.runBlockInScope(E,n)}catch(b){if(b instanceof Nt)break;if(b instanceof It)continue;throw b}return e+1+E.length}if(s==="try:"){let w=this.collectBlock(t,e+1,o),E=e+1+w.length,T=[],b=[],P=[];for(;E<t.length;){let H=t[E],z=H.trim();if(this.getIndent(H)!==o)break;if(z.startsWith("except")){let q=z.match(/^except(?:\s+(\w+)(?:\s+as\s+(\w+))?)?\s*:$/),ft=q?.[1]??null,ot=q?.[2],ht=this.collectBlock(t,E+1,o);T.push({exc:ft,body:ht}),ot&&n.set(ot,""),E+=1+ht.length}else if(z==="else:")P=this.collectBlock(t,E+1,o),E+=1+P.length;else if(z==="finally:")b=this.collectBlock(t,E+1,o),E+=1+b.length;else break}let I=null;try{this.runBlockInScope(w,n),P.length&&this.runBlockInScope(P,n)}catch(H){if(H instanceof U){I=H;let z=!1;for(let q of T)if(q.exc===null||q.exc===H.type||q.exc==="Exception"){this.runBlockInScope(q.body,n),z=!0;break}if(!z)throw H}else throw H}finally{b.length&&this.runBlockInScope(b,n)}return E}let $=s.match(/^with\s+(.+?)\s+as\s+(\w+)\s*:$/);if($){let w=this.collectBlock(t,e+1,o);return n.set($[2],p),this.runBlockInScope(w,n),e+1+w.length}let V=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*(\+=|-=|\*=|\/\/=|\/=|%=|\*\*=|&=|\|=)\s*(.+)$/);if(V){let[,w,E,T]=V,b=n.get(w)??0,P=this.pyEval(T,n),I;switch(E){case"+=":I=typeof b=="string"?b+M(P):b+P;break;case"-=":I=b-P;break;case"*=":I=b*P;break;case"/=":I=b/P;break;case"//=":I=Math.floor(b/P);break;case"%=":I=b%P;break;case"**=":I=b**P;break;default:I=P}return n.set(w,I),e+1}let k=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\[(.+)\]\s*=\s*(.+)$/);if(k){let[,w,E,T]=k,b=n.get(w)??p,P=this.pyEval(T,n)??p,I=this.pyEval(E,n)??p;return Array.isArray(b)?b[I]=P:B(b)&&b.data.set(M(I),P),e+1}let R=s.match(/^([A-Za-z_][A-Za-z0-9_.]+)\s*=\s*(.+)$/);if(R){let w=R[1].lastIndexOf(".");if(w!==-1){let E=R[1].slice(0,w),T=R[1].slice(w+1),b=this.pyEval(R[2],n),P=this.pyEval(E,n);return B(P)?P.data.set(T,b):Ft(P)&&P.attrs.set(T,b),e+1}}let D=s.match(/^([A-Za-z_][A-Za-z0-9_,\s]*),\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.+)$/);if(D){let w=this.pyEval(D[3],n),E=s.split("=")[0].split(",").map(b=>b.trim()),T=K(w);return E.forEach((b,P)=>n.set(b,T[P]??p)),e+1}let tt=s.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*(?::[^=]+)?\s*=\s*(.+)$/);if(tt){let[,w,E]=tt;return n.set(w,this.pyEval(E,n)),e+1}try{this.pyEval(s,n)}catch(w){if(w instanceof U||w instanceof Vt)throw w}return e+1}runBlockInScope(t,e){this.execLines(t,0,e)}run(t){let e=Hs(this.cwd);try{this.execScript(t,e)}catch(n){return n instanceof Vt?{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:n.code}:n instanceof U?(this.stderr.push(n.toString()),{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:1}):n instanceof Ct?{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:0}:(this.stderr.push(`RuntimeError: ${n}`),{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:1})}return{stdout:this.getOutput(),stderr:this.getStderr(),exitCode:0}}},en={name:"python3",aliases:["python"],description:"Python 3 interpreter (virtual)",category:"system",params:["[--version] [-c <code>] [-V] [file]"],run:({args:r,shell:t,cwd:e})=>{if(!t.packageManager.isInstalled("python3"))return{stderr:`bash: python3: command not found
239
+ Hint: install it with: apt install python3
240
+ `,exitCode:127};if(h(r,["--version","-V"]))return{stdout:`${js}
241
+ `,exitCode:0};if(h(r,["--version-full"]))return{stdout:`${Kt}
242
+ `,exitCode:0};let n=r.indexOf("-c");if(n!==-1){let s=r[n+1];if(!s)return{stderr:`python3: -c requires a code argument
243
+ `,exitCode:1};let o=s.replace(/\\n/g,`
244
+ `).replace(/\\t/g," "),a=new Gt(e),{stdout:l,stderr:c,exitCode:u}=a.run(o);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}let i=r.find(s=>!s.startsWith("-"));if(i){let s=S(e,i);if(!t.vfs.exists(s))return{stderr:`python3: can't open file '${i}': [Errno 2] No such file or directory
245
+ `,exitCode:2};let o=t.vfs.readFile(s),a=new Gt(e),{stdout:l,stderr:c,exitCode:u}=a.run(o);return{stdout:l||void 0,stderr:c||void 0,exitCode:u}}return{stdout:`${Kt}
246
+ Type "help", "copyright", "credits" or "license" for more information.
247
+ >>> `,exitCode:0}}};var rn={name:"read",description:"Read a line from stdin into variables",category:"shell",params:["[-r] [-p prompt] <var...>"],run:({args:r,stdin:t,env:e})=>{let n=r.indexOf("-p"),i=r.filter((a,l)=>a!=="-r"&&a!=="-p"&&r[l-1]!=="-p"),s=(t??"").split(`
248
+ `)[0]??"",o=h(r,["-r"])?s:s.replace(/\\(?:\r?\n|.)/g,a=>a[1]===`
249
+ `||a[1]==="\r"?"":a[1]);if(!e)return{exitCode:0};if(i.length===0)e.vars.REPLY=o;else if(i.length===1)e.vars[i[0]]=o;else{let a=o.split(/\s+/);for(let l=0;l<i.length;l++)e.vars[i[l]]=l<i.length-1?a[l]??"":a.slice(l).join(" ")}return{exitCode:0}}};var nn={name:"rm",description:"Remove files or directories",category:"files",params:["[-r|-rf] <path>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{if(n.length===0)return{stderr:"rm: missing operand",exitCode:1};let i=h(n,["-r","-rf","-fr"]),s=[];for(let o=0;;o+=1){let a=it(n,o,{flags:["-r","-rf","-fr"]});if(!a)break;s.push(a)}if(s.length===0)return{stderr:"rm: missing operand",exitCode:1};for(let o of s){let a=S(e,o);N(r,a,"rm"),t.vfs.remove(a,{recursive:i})}return{exitCode:0}}};var sn={name:"sed",description:"Stream editor for filtering and transforming text",category:"text",params:["-e <expr> [file]","s/pattern/replace/[g]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=h(n,["-i"]),o=rt(n,["-e"])??n.find(y=>!y.startsWith("-")),a=n.filter(y=>!y.startsWith("-")&&y!==o).pop();if(!o)return{stderr:"sed: no expression",exitCode:1};let l=i??"";if(a){let y=S(e,a);try{l=t.vfs.readFile(y)}catch{return{stderr:`sed: ${a}: No such file or directory`,exitCode:1}}}let c=o.match(/^s([^a-zA-Z0-9])(.+?)\1(.*?)\1([gi]*)$/);if(!c)return{stderr:`sed: unrecognized command: ${o}`,exitCode:1};let[,,u,d,m]=c,f=(m??"").includes("i")?"gi":(m??"").includes("g")?"g":"",x;try{x=new RegExp(u,f||"")}catch{return{stderr:`sed: invalid regex: ${u}`,exitCode:1}}let g=((m??"").includes("g")||f.includes("g"),l.replace(x,d??""));if(s&&a){let y=S(e,a);return t.writeFileAsUser(r,y,g),{exitCode:0}}return{stdout:g,exitCode:0}}};async function fe(r,t,e,n){return Bt(r,t,e,i=>Z(i,n.authUser,n.hostname,n.mode,n.cwd,n.shell,void 0,n.env).then(s=>s.stdout??""))}function xt(r){let t=[],e=0;for(;e<r.length;){let n=r[e].trim();if(!n||n.startsWith("#")){e++;continue}if(n.startsWith("if ")||n==="if"){let i=n.replace(/^if\s+/,"").replace(/;\s*then\s*$/,"").trim(),s=[],o=[],a=[],l="then",c="";for(e++;e<r.length&&r[e]?.trim()!=="fi";){let u=r[e].trim();u.startsWith("elif ")?(l="elif",c=u.replace(/^elif\s+/,"").replace(/;\s*then\s*$/,"").trim(),o.push({cond:c,body:[]})):u==="else"?l="else":u!=="then"&&(l==="then"?s.push(u):l==="elif"&&o.length>0?o[o.length-1].body.push(u):a.push(u)),e++}t.push({type:"if",cond:i,then_:s,elif:o,else_:a})}else if(n.startsWith("for ")){let i=n.match(/^for\s+(\w+)\s+in\s+(.+?)(?:\s*;\s*do)?$/);if(i){let s=[];for(e++;e<r.length&&r[e]?.trim()!=="done";){let o=r[e].trim().replace(/^do\s+/,"");o&&o!=="do"&&s.push(o),e++}t.push({type:"for",var:i[1],list:i[2],body:s})}else t.push({type:"cmd",line:n})}else if(n.startsWith("while ")){let i=n.replace(/^while\s+/,"").replace(/;\s*do\s*$/,"").trim(),s=[];for(e++;e<r.length&&r[e]?.trim()!=="done";){let o=r[e].trim().replace(/^do\s+/,"");o&&o!=="do"&&s.push(o),e++}t.push({type:"while",cond:i,body:s})}else t.push({type:"cmd",line:n});e++}return t}async function pe(r,t){let e=await fe(r,t.env.vars,t.env.lastExitCode,t),n=e.match(/^\[?\s*(.+?)\s*\]?$/);if(n){let s=n[1],o=s.match(/^-([fdeznr])\s+(.+)$/);if(o){let[,c,u]=o,d=S(t.cwd,u);if(c==="f")return t.shell.vfs.exists(d)&&t.shell.vfs.stat(d).type==="file";if(c==="d")return t.shell.vfs.exists(d)&&t.shell.vfs.stat(d).type==="directory";if(c==="e")return t.shell.vfs.exists(d);if(c==="z")return(u??"").length===0;if(c==="n")return(u??"").length>0}let a=s.match(/^"?([^"]*)"?\s*(==|!=|=|<|>)\s*"?([^"]*)"?$/);if(a){let[,c,u,d]=a;if(u==="=="||u==="=")return c===d;if(u==="!=")return c!==d}let l=s.match(/^(\S+)\s+(-eq|-ne|-lt|-le|-gt|-ge)\s+(\S+)$/);if(l){let[,c,u,d]=l,m=Number(c),f=Number(d);if(u==="-eq")return m===f;if(u==="-ne")return m!==f;if(u==="-lt")return m<f;if(u==="-le")return m<=f;if(u==="-gt")return m>f;if(u==="-ge")return m>=f}}return((await Z(e,t.authUser,t.hostname,t.mode,t.cwd,t.shell,void 0,t.env)).exitCode??0)===0}async function bt(r,t){let e={exitCode:0},n="";for(let i of r)if(i.type==="cmd"){let s=await fe(i.line,t.env.vars,t.env.lastExitCode,t),o=/^([A-Za-z_][A-Za-z0-9_]*)=(.*)/,a=s.trim().split(/\s+/);if(a.length>0&&o.test(a[0])&&a.every(u=>o.test(u))){for(let u of a){let d=u.match(o);t.env.vars[d[1]]=d[2]}t.env.lastExitCode=0;continue}let l=await Z(s,t.authUser,t.hostname,t.mode,t.cwd,t.shell,void 0,t.env);if(t.env.lastExitCode=l.exitCode??0,l.stdout&&(n+=`${l.stdout}
250
+ `),l.stderr)return{...l,stdout:n.trim()};e=l}else if(i.type==="if"){let s=!1;if(await pe(i.cond,t)){let o=await bt(xt(i.then_),t);o.stdout&&(n+=`${o.stdout}
251
+ `),s=!0}else{for(let o of i.elif)if(await pe(o.cond,t)){let a=await bt(xt(o.body),t);a.stdout&&(n+=`${a.stdout}
252
+ `),s=!0;break}if(!s&&i.else_.length>0){let o=await bt(xt(i.else_),t);o.stdout&&(n+=`${o.stdout}
253
+ `)}}}else if(i.type==="for"){let o=(await fe(i.list,t.env.vars,t.env.lastExitCode,t)).trim().split(/\s+/);for(let a of o){t.env.vars[i.var]=a;let l=await bt(xt(i.body),t);if(l.stdout&&(n+=`${l.stdout}
254
+ `),l.closeSession)return l}}else if(i.type==="while"){let s=0;for(;s<1e3&&await pe(i.cond,t);){let o=await bt(xt(i.body),t);if(o.stdout&&(n+=`${o.stdout}
255
+ `),o.closeSession)return o;s++}}return{...e,stdout:n.trim()||e.stdout}}var on={name:"sh",aliases:["bash"],description:"Execute shell script or command",category:"shell",params:["-c <script>","[<file>]"],run:async r=>{let{args:t,shell:e,cwd:n}=r;if(h(t,"-c")){let s=t[t.indexOf("-c")+1]??"";if(!s)return{stderr:"sh: -c requires a script",exitCode:1};let o=s.split(/[;\n]/).map(l=>l.trim()).filter(l=>l&&!l.startsWith("#")),a=xt(o);return bt(a,r)}let i=t[0];if(i){let s=S(n,i);if(!e.vfs.exists(s))return{stderr:`sh: ${i}: No such file or directory`,exitCode:1};let a=e.vfs.readFile(s).split(`
256
+ `).map(c=>c.trim()).filter(c=>c&&!c.startsWith("#")),l=xt(a);return bt(l,r)}return{stderr:"sh: invalid usage. Use: sh -c 'cmd' or sh <file>",exitCode:1}}};var an={name:"shift",description:"Shift positional parameters",category:"shell",params:["[n]"],run:({args:r,env:t})=>{if(!t)return{exitCode:0};let e=parseInt(r[0]??"1",10)||1,n=t.vars.__argv?.split("\0").filter(Boolean)??[];t.vars.__argv=n.slice(e).join("\0");let i=n.slice(e);for(let s=1;s<=9;s++)t.vars[String(s)]=i[s-1]??"";return{exitCode:0}}},ln={name:"trap",description:"Trap signals and events",category:"shell",params:["[action] [signal...]"],run:({args:r,env:t})=>{if(!t||r.length===0)return{exitCode:0};let e=r[0]??"",n=r.slice(1);for(let i of n)t.vars[`__trap_${i.toUpperCase()}`]=e;return{exitCode:0}}},cn={name:"return",description:"Return from a shell function",category:"shell",params:["[n]"],run:({args:r,env:t})=>{let e=parseInt(r[0]??"0",10);return t&&(t.lastExitCode=e),{exitCode:e}}};var un={name:"sleep",description:"Delay execution",category:"system",params:["<seconds>"],run:async({args:r})=>{let t=parseFloat(r[0]??"1");return Number.isNaN(t)||t<0?{stderr:"sleep: invalid time",exitCode:1}:(await new Promise(e=>setTimeout(e,t*1e3)),{exitCode:0})}};var dn={name:"sort",description:"Sort lines of text",category:"text",params:["[-r] [-n] [-u] [-k <col>] [file...]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=h(n,["-r"]),o=h(n,["-n"]),a=h(n,["-u"]),l=n.filter(x=>!x.startsWith("-")),d=[...(l.length>0?l.map(x=>{try{return N(r,S(e,x),"sort"),t.vfs.readFile(S(e,x))}catch{return""}}).join(`
257
+ `):i??"").split(`
258
+ `).filter(Boolean)].sort((x,g)=>o?Number(x)-Number(g):x.localeCompare(g)),m=s?d.reverse():d;return{stdout:(a?[...new Set(m)]:m).join(`
259
+ `),exitCode:0}}};var mn={name:"source",aliases:["."],description:"Execute commands from a file in the current shell environment",category:"shell",params:["<file> [args...]"],run:async({args:r,authUser:t,hostname:e,cwd:n,shell:i,env:s})=>{let o=r[0];if(!o)return{stderr:"source: missing filename",exitCode:1};let a=S(n,o);if(!i.vfs.exists(a))return{stderr:`source: ${o}: No such file or directory`,exitCode:1};let l=i.vfs.readFile(a),c=0;for(let u of l.split(`
260
+ `)){let d=u.trim();if(!d||d.startsWith("#"))continue;let m=await Z(d,t,e,"shell",n,i,void 0,s);if(c=m.exitCode??0,m.closeSession||m.switchUser)return m}return{exitCode:c}}};var pn={name:"su",description:"Switch user",category:"users",params:["- <username>"],run:({authUser:r,shell:t,args:e})=>{let n=t.users,i=it(e,0,{flags:["-"]});return i?!n.isSudoer(r)&&r!=="root"?{stderr:"su: permission denied",exitCode:1}:!n.verifyPassword(i,it(e,1)??"")&&r!=="root"?{stderr:"su: authentication failure",exitCode:1}:{switchUser:i,nextCwd:`/home/${i}`,exitCode:0}:{stderr:"su: missing username",exitCode:1}}};function Ys(r){let{flags:t,flagsWithValues:e,positionals:n}=et(r,{flags:["-i","-S"],flagsWithValue:["-u","--user"]}),i=t.has("-i"),s=e.get("-u")||e.get("--user")||"root",o=n.length>0?n.join(" "):null;return{targetUser:s,loginShell:i,commandLine:o}}var fn={name:"sudo",description:"Execute as superuser",category:"users",params:["<command...>"],run:async({authUser:r,hostname:t,mode:e,cwd:n,shell:i,args:s})=>{let{targetUser:o,loginShell:a,commandLine:l}=Ys(s);if(r!=="root"&&!i.users.isSudoer(r))return{stderr:"sudo: permission denied",exitCode:1};let c=o||"root",u=`[sudo] password for ${r}: `;return r==="root"?!l&&a?{switchUser:c,nextCwd:`/home/${c}`,exitCode:0}:l?Z(l,c,t,e,a?`/home/${c}`:n,i):{stderr:"sudo: missing command",exitCode:1}:{sudoChallenge:{username:r,targetUser:c,commandLine:l,loginShell:a,prompt:u},exitCode:0}}};var hn={name:"tail",description:"Output last lines",category:"text",params:["[-n <lines>] [file...]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=rt(n,["-n"]),o=typeof s=="string"?parseInt(s,10):10,a=n.filter(u=>!u.startsWith("-")&&u!==s),l=u=>{let d=u.split(`
261
+ `);return d.slice(Math.max(0,d.length-o)).join(`
262
+ `)};if(a.length===0)return{stdout:l(i??""),exitCode:0};let c=[];for(let u of a){let d=S(e,u);try{N(r,d,"tail"),c.push(l(t.vfs.readFile(d)))}catch{return{stderr:`tail: ${u}: No such file or directory`,exitCode:1}}}return{stdout:c.join(`
263
+ `),exitCode:0}}};var gn={name:"tar",description:"Archive utility",category:"archive",params:["[-czf|-xzf|-tf] <archive> [files...]"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=h(n,["-c"]),s=h(n,["-x"]),o=h(n,["-t"]),a=n.findIndex(u=>u.includes("f")),l=a!==-1?n[a+1]:n.find(u=>u.endsWith(".tar")||u.endsWith(".tar.gz")||u.endsWith(".tgz"));if(!l)return{stderr:"tar: no archive specified",exitCode:1};let c=S(e,l);if(i){let u=n.filter(m=>!m.startsWith("-")&&m!==l),d={};for(let m of u){let f=S(e,m);try{if(t.vfs.stat(f).type==="file")d[m]=t.vfs.readFile(f);else{let g=(y,$)=>{for(let V of t.vfs.list(y)){let k=`${y}/${V}`,R=`${$}/${V}`;t.vfs.stat(k).type==="file"?d[R]=t.vfs.readFile(k):g(k,R)}};g(f,m)}}catch{return{stderr:`tar: ${m}: No such file or directory`,exitCode:1}}}return t.writeFileAsUser(r,c,JSON.stringify(d)),{exitCode:0}}if(o||s){let u;try{u=JSON.parse(t.vfs.readFile(c))}catch{return{stderr:`tar: ${l}: cannot open archive`,exitCode:1}}if(o)return{stdout:Object.keys(u).join(`
264
+ `),exitCode:0};for(let[d,m]of Object.entries(u))t.writeFileAsUser(r,S(e,d),m);return{exitCode:0}}return{stderr:"tar: must specify -c, -x, or -t",exitCode:1}}};var yn={name:"tee",description:"Read stdin, write to stdout and files",category:"text",params:["[-a] <file...>"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=h(n,["-a"]),o=n.filter(l=>!l.startsWith("-")),a=i??"";for(let l of o){let c=S(e,l);if(s){let u=(()=>{try{return t.vfs.readFile(c)}catch{return""}})();t.writeFileAsUser(r,c,u+a)}else t.writeFileAsUser(r,c,a)}return{stdout:a,exitCode:0}}};function Pt(r,t,e){if(r[r.length-1]==="]"&&(r=r.slice(0,-1)),r[0]==="["&&(r=r.slice(1)),r.length===0)return!1;if(r[0]==="!")return!Pt(r.slice(1),t,e);let n=r.indexOf("-a");if(n!==-1)return Pt(r.slice(0,n),t,e)&&Pt(r.slice(n+1),t,e);let i=r.indexOf("-o");if(i!==-1)return Pt(r.slice(0,i),t,e)||Pt(r.slice(i+1),t,e);if(r.length===2){let[s,o=""]=r,l=(c=>c.startsWith("/")?c:`${e}/${c}`.replace(/\/+/g,"/"))(o);switch(s){case"-e":return t.vfs.exists(l);case"-f":return t.vfs.exists(l)&&t.vfs.stat(l).type==="file";case"-d":return t.vfs.exists(l)&&t.vfs.stat(l).type==="directory";case"-r":return t.vfs.exists(l);case"-w":return t.vfs.exists(l);case"-x":return t.vfs.exists(l)&&!!(t.vfs.stat(l).mode&73);case"-s":return t.vfs.exists(l)&&t.vfs.stat(l).type==="file"&&t.vfs.stat(l).size>0;case"-z":return o.length===0;case"-n":return o.length>0;case"-L":return t.vfs.isSymlink(l)}}if(r.length===3){let[s="",o,a=""]=r,l=Number(s),c=Number(a);switch(o){case"=":case"==":return s===a;case"!=":return s!==a;case"<":return s<a;case">":return s>a;case"-eq":return l===c;case"-ne":return l!==c;case"-lt":return l<c;case"-le":return l<=c;case"-gt":return l>c;case"-ge":return l>=c}}return r.length===1?(r[0]??"").length>0:!1}var Sn={name:"test",aliases:["["],description:"Evaluate conditional expression",category:"shell",params:["<expression>"],run:({args:r,shell:t,cwd:e})=>{try{return{exitCode:Pt([...r],t,e)?0:1}}catch{return{stderr:"test: malformed expression",exitCode:2}}}};var xn={name:"touch",description:"Create or update files",category:"files",params:["<file>"],run:({authUser:r,shell:t,cwd:e,args:n})=>{if(n.length===0)return{stderr:"touch: missing file operand",exitCode:1};for(let i of n){let s=S(e,i);N(r,s,"touch"),t.vfs.exists(s)||t.writeFileAsUser(r,s,"")}return{exitCode:0}}};var bn={name:"tr",description:"Translate or delete characters",category:"text",params:["[-d] <set1> [set2]"],run:({args:r,stdin:t})=>{let e=h(r,["-d"]),n=r.filter(a=>!a.startsWith("-")),i=n[0]??"",s=n[1]??"",o=t??"";if(e)for(let a of i)o=o.split(a).join("");else if(s)for(let a=0;a<i.length;a++)o=o.split(i[a]).join(s[a]??s[s.length-1]??"");return{stdout:o,exitCode:0}}};var wn={name:"tree",description:"Display directory tree",category:"navigation",params:["[path]"],run:({authUser:r,shell:t,cwd:e,args:n})=>{let i=S(e,it(n,0)??e);return N(r,i,"tree"),{stdout:t.vfs.tree(i),exitCode:0}}};var vn={name:"true",description:"Return success exit code",category:"shell",params:[],run:()=>({exitCode:0})},Cn={name:"false",description:"Return failure exit code",category:"shell",params:[],run:()=>({exitCode:1})};var $n={name:"type",description:"Describe how a command would be interpreted",category:"shell",params:["<command...>"],run:({args:r,shell:t,env:e})=>{if(r.length===0)return{stderr:"type: missing argument",exitCode:1};let n=(e?.vars?.PATH??"/usr/local/bin:/usr/bin:/bin").split(":"),i=[],s=0;for(let o of r){if(mt(o)){i.push(`${o} is a shell builtin`);continue}let a=!1;for(let l of n){let c=`${l}/${o}`;if(t.vfs.exists(c)){i.push(`${o} is ${c}`),a=!0;break}}a||(i.push(`${o}: not found`),s=1)}return{stdout:i.join(`
265
+ `),exitCode:s}}};var Pn={name:"uname",description:"Print system information",category:"system",params:["[-a] [-s] [-r] [-m]"],run:({shell:r,args:t})=>{let e=h(t,["-a"]),n="Linux",i=r.properties?.kernel??"5.15.0",s=r.properties?.arch??"x86_64",o=r.hostname;return e?{stdout:`${n} ${o} ${i} #1 SMP ${s} GNU/Linux`,exitCode:0}:h(t,["-r"])?{stdout:i,exitCode:0}:h(t,["-m"])?{stdout:s,exitCode:0}:{stdout:n,exitCode:0}}};var kn={name:"uniq",description:"Report or filter out repeated lines",category:"text",params:["[-c] [-d] [-u] [file]"],run:({args:r,stdin:t})=>{let e=h(r,["-c"]),n=h(r,["-d"]),i=h(r,["-u"]),s=(t??"").split(`
266
+ `),o=[],a=0;for(;a<s.length;){let l=a;for(;l<s.length&&s[l]===s[a];)l++;let c=l-a,u=s[a];if(n&&c===1){a=l;continue}if(i&&c>1){a=l;continue}o.push(e?`${String(c).padStart(4)} ${u}`:u),a=l}return{stdout:o.join(`
267
+ `),exitCode:0}}};var Mn={name:"unset",description:"Remove shell variable",category:"shell",params:["<VAR>"],run:({args:r,env:t})=>{for(let e of r)delete t.vars[e];return{exitCode:0}}};var En={name:"uptime",description:"Tell how long the system has been running",category:"system",params:["[-p] [-s]"],run:({args:r,shell:t})=>{let e=h(r,["-p"]),n=h(r,["-s"]),i=Math.floor((Date.now()-t.startTime)/1e3),s=Math.floor(i/86400),o=Math.floor(i%86400/3600),a=Math.floor(i%3600/60);if(n)return{stdout:new Date(t.startTime).toISOString().slice(0,19).replace("T"," "),exitCode:0};if(e){let m=[];return s>0&&m.push(`${s} day${s>1?"s":""}`),o>0&&m.push(`${o} hour${o>1?"s":""}`),m.push(`${a} minute${a!==1?"s":""}`),{stdout:`up ${m.join(", ")}`,exitCode:0}}let l=new Date().toTimeString().slice(0,8),c=s>0?`${s} day${s>1?"s":""}, ${String(o).padStart(2)}:${String(a).padStart(2,"0")}`:`${String(o).padStart(2)}:${String(a).padStart(2,"0")}`,u=t.users.listActiveSessions().length,d=(Math.random()*.5).toFixed(2);return{stdout:` ${l} up ${c}, ${u} user${u!==1?"s":""}, load average: ${d}, ${d}, ${d}`,exitCode:0}}};var An={name:"wc",description:"Count words/lines/bytes",category:"text",params:["[-l] [-w] [-c] [file...]"],run:({authUser:r,shell:t,cwd:e,args:n,stdin:i})=>{let s=h(n,["-l"]),o=h(n,["-w"]),a=h(n,["-c"]),l=!s&&!o&&!a,c=n.filter(m=>!m.startsWith("-")),u=(m,f)=>{let x=m.split(`
268
+ `).length-(m.endsWith(`
269
+ `)?1:0),g=m.trim().split(/\s+/).filter(Boolean).length,y=Buffer.byteLength(m,"utf8"),$=[];return(l||s)&&$.push(String(x).padStart(7)),(l||o)&&$.push(String(g).padStart(7)),(l||a)&&$.push(String(y).padStart(7)),f&&$.push(` ${f}`),$.join("")};if(c.length===0)return{stdout:u(i??"",""),exitCode:0};let d=[];for(let m of c){let f=S(e,m);try{N(r,f,"wc");let x=t.vfs.readFile(f);d.push(u(x,m))}catch{return{stderr:`wc: ${m}: No such file or directory`,exitCode:1}}}return{stdout:d.join(`
270
+ `),exitCode:0}}};var Fn={name:"wget",description:"File downloader (pure fetch)",category:"network",params:["[options] <url>"],run:async({authUser:r,cwd:t,args:e,shell:n})=>{let{flagsWithValues:i,positionals:s}=et(e,{flagsWithValue:["-O","--output-document","-o","--output-file","-P","--directory-prefix","--tries","--timeout"]});if(h(e,["-h","--help"]))return{stdout:["Usage: wget [option]... [URL]..."," -O, --output-document=FILE Write to FILE ('-' for stdout)"," -P, --directory-prefix=DIR Save files in DIR"," -q, --quiet Quiet mode"," -v, --verbose Verbose output (default)"," -c, --continue Continue partial download"," --tries=N Retry N times"," --timeout=N Timeout in seconds"].join(`
271
+ `),exitCode:0};if(h(e,["-V","--version"]))return{stdout:"GNU Wget 1.21.3 (virtual) built on Fortune GNU/Linux.",exitCode:0};let o=s[0];if(!o)return{stderr:`wget: missing URL
272
+ Usage: wget [OPTION]... [URL]...`,exitCode:1};let a=i.get("-O")??i.get("--output-document")??null,l=i.get("-P")??i.get("--directory-prefix")??null,c=h(e,["-q","--quiet"]),u=a==="-"?null:a??Re(o),d=u?S(t,l?`${l}/${u}`:u):null;d&&N(r,d,"wget");let m=[];c||(m.push(`--${new Date().toISOString()}-- ${o}`),m.push(`Resolving ${new URL(o).host}...`),m.push(`Connecting to ${new URL(o).host}...`));let f;try{f=await fetch(o,{headers:{"User-Agent":"Wget/1.21.3 (Fortune GNU/Linux)"}})}catch(g){let y=g instanceof Error?g.message:String(g);return m.push(`wget: unable to resolve host: ${y}`),{stderr:m.join(`
273
+ `),exitCode:4}}if(!f.ok)return m.push(`ERROR ${f.status}: ${f.statusText}`),{stderr:m.join(`
274
+ `),exitCode:8};let x;try{x=await f.text()}catch{return{stderr:"wget: failed to read response",exitCode:1}}if(!c){let g=f.headers.get("content-type")??"application/octet-stream";m.push(`HTTP request sent, awaiting response... ${f.status} ${f.statusText}`),m.push(`Length: ${x.length} [${g}]`)}return a==="-"?{stdout:x,stderr:m.join(`
275
+ `)||void 0,exitCode:0}:d?(n.writeFileAsUser(r,d,x),c||m.push(`Saving to: '${d}'
276
+ ${d} 100%[==================>] ${x.length} B`),{stderr:m.join(`
277
+ `)||void 0,exitCode:0}):{stdout:x,exitCode:0}}};var Nn={name:"which",description:"Locate a command in PATH",category:"shell",params:["<command...>"],run:({args:r,shell:t,env:e})=>{if(r.length===0)return{stderr:"which: missing argument",exitCode:1};let n=(e?.vars?.PATH??"/usr/local/bin:/usr/bin:/bin").split(":"),i=[],s=!1;for(let o of r){let a=!1;for(let l of n){let c=`${l}/${o}`;if(t.vfs.exists(c)&&t.vfs.stat(c).type==="file"){i.push(c),a=!0;break}}a||(s=!0)}return i.length===0?{exitCode:1}:{stdout:i.join(`
278
+ `),exitCode:s?1:0}}};function Zt(r){let t=r.toLocaleString("en-US",{weekday:"short"}),e=r.toLocaleString("en-US",{month:"short"}),n=r.getDate().toString().padStart(2,"0"),i=r.getHours().toString().padStart(2,"0"),s=r.getMinutes().toString().padStart(2,"0"),o=r.getSeconds().toString().padStart(2,"0"),a=r.getFullYear();return`${t} ${e} ${n} ${i}:${s}:${o} ${a}`}var In={name:"who",description:"Show active sessions",category:"system",params:[],run:({shell:r})=>({stdout:r.users.listActiveSessions().map(e=>{let n=new Date(e.startedAt),i=Number.isNaN(n.getTime())?e.startedAt:Zt(n);return`${e.username} ${e.tty} ${i} (${e.remoteAddress||"unknown"})`}).join(`
279
+ `),exitCode:0})};var Vn={name:"whoami",description:"Print current user",category:"system",params:[],run:({authUser:r})=>({stdout:r,exitCode:0})};var Rn={name:"xargs",description:"Build and execute command lines from stdin",category:"text",params:["[command] [args...]"],run:async({authUser:r,hostname:t,mode:e,cwd:n,args:i,stdin:s,shell:o,env:a})=>{let l=i[0]??"echo",c=i.slice(1),u=(s??"").trim().split(/\s+/).filter(Boolean);if(u.length===0)return{exitCode:0};let d=[l,...c,...u].join(" ");return Z(d,r,t,e,n,o,void 0,a)}};var Qs=[Qr,Ue,$r,wn,Be,xn,nn,Mr,He,Er,Cr,je,or,lr,sn,Oe,dn,kn,An,mr,hn,Ke,bn,yn,Rn,Qe,gn,ur,dr,ze,Vn,In,xr,wr,cr,Pn,Yr,vr,Ye,er,Ge,un,Zr,rr,nr,ir,Br,Mn,on,We,sr,Fr,br,qe,Fn,Fe,Gr,Je,fn,pn,Ur,Le,Te,Xe,tr,Nn,$n,kr,Ie,Ve,Sn,mn,Sr,Jr,rn,Ze,an,ln,cn,vn,Cn,qr,Kr,Hr,en,En,ar,Pr],Dn=[],Rt=new Map,Jt=null,Xs=yr(()=>ge().map(r=>r.name));function he(){Rt.clear();for(let r of ge()){Rt.set(r.name,r);for(let t of r.aliases??[])Rt.set(t,r)}Jt=Array.from(Rt.keys()).sort()}function ge(){return[...Qs,...Dn,Xs]}function ye(r){let t={...r,name:r.name.trim().toLowerCase(),aliases:r.aliases?.map(n=>n.trim().toLowerCase())};if([t.name,...t.aliases??[]].some(n=>n.length===0||/\s/.test(n)))throw new Error("Command names must be non-empty and contain no spaces");Dn.push(t),he()}function Se(r,t,e){return{name:r,params:t,run:e}}function xe(){return Jt||he(),Jt}function le(){return ge()}function mt(r){return Jt||he(),Rt.get(r.toLowerCase())}async function _n(r,t,e,n,i,s,o){let a={exitCode:0},l=0;for(;l<r.length;){let c=r[l];if(a=await ti(c.pipeline,t,e,n,i,s,o),o.lastExitCode=a.exitCode??0,a.closeSession||a.switchUser)return a;let u=c.op;if(!(!u||u===";")){if(u==="&&"){if((a.exitCode??0)!==0)for(;l<r.length&&r[l]?.op==="&&";)l++}else if(u==="||"&&(a.exitCode??0)===0)for(;l<r.length&&r[l]?.op==="||";)l++}l++}return a}async function ti(r,t,e,n,i,s,o){if(!r.isValid)return{stderr:r.error||"Syntax error",exitCode:1};if(r.commands.length===0)return{exitCode:0};let a=o??{vars:{},lastExitCode:0};return r.commands.length===1?ei(r.commands[0],t,e,n,i,s,a):ri(r.commands,t,e,n,i,s,a)}async function ei(r,t,e,n,i,s,o){let a;if(r.inputFile){let c=S(i,r.inputFile);try{a=s.vfs.readFile(c)}catch{return{stderr:`${r.inputFile}: No such file or directory`,exitCode:1}}}let l=await Yt(r.name,r.args,t,e,n,i,s,a,o);if(r.outputFile){let c=S(i,r.outputFile),u=l.stdout||"";try{if(r.appendOutput){let d=(()=>{try{return s.vfs.readFile(c)}catch{return""}})();s.writeFileAsUser(t,c,d+u)}else s.writeFileAsUser(t,c,u);return{...l,stdout:""}}catch{return{...l,stderr:`Failed to write to ${r.outputFile}`,exitCode:1}}}return l}async function ri(r,t,e,n,i,s,o){let a="",l=0;for(let c=0;c<r.length;c++){let u=r[c];if(c===0&&u.inputFile){let m=S(i,u.inputFile);try{a=s.vfs.readFile(m)}catch{return{stderr:`${u.inputFile}: No such file or directory`,exitCode:1}}}let d=await Yt(u.name,u.args,t,e,n,i,s,a,o);if(l=d.exitCode??0,c===r.length-1&&u.outputFile){let m=S(i,u.outputFile),f=d.stdout||"";try{if(u.appendOutput){let x=(()=>{try{return s.vfs.readFile(m)}catch{return""}})();s.writeFileAsUser(t,m,x+f)}else s.writeFileAsUser(t,m,f);a=""}catch{return{stderr:`Failed to write to ${u.outputFile}`,exitCode:1}}}else a=d.stdout||"";if(d.stderr&&l!==0)return{stderr:d.stderr,exitCode:l};if(d.closeSession||d.switchUser)return d}return{stdout:a,exitCode:l}}function Ln(r){let t=r.trim();if(!t)return{statements:[],isValid:!0};try{return{statements:ni(t),isValid:!0}}catch(e){return{statements:[],isValid:!1,error:e.message}}}function ni(r){let t=si(r),e=[];for(let n of t){let s={pipeline:{commands:ii(n.text.trim()),isValid:!0}};n.op&&(s.op=n.op),e.push(s)}return e}function si(r){let t=[],e="",n=0,i=!1,s="",o=0,a=l=>{e.trim()&&t.push({text:e,op:l}),e=""};for(;o<r.length;){let l=r[o],c=r.slice(o,o+2);if((l==='"'||l==="'")&&!i){i=!0,s=l,e+=l,o++;continue}if(i&&l===s){i=!1,e+=l,o++;continue}if(i){e+=l,o++;continue}if(l==="("){n++,e+=l,o++;continue}if(l===")"){n--,e+=l,o++;continue}if(n>0){e+=l,o++;continue}if(c==="&&"){a("&&"),o+=2;continue}if(c==="||"){a("||"),o+=2;continue}if(l===";"){a(";"),o++;continue}e+=l,o++}return a(),t}function ii(r){return oi(r).map(ai)}function oi(r){let t=[],e="",n=!1,i="";for(let o=0;o<r.length;o++){let a=r[o];if((a==='"'||a==="'")&&!n){n=!0,i=a,e+=a;continue}if(n&&a===i){n=!1,e+=a;continue}if(n){e+=a;continue}if(a==="|"&&r[o+1]!=="|"){if(!e.trim())throw new Error("Syntax error near unexpected token '|'");t.push(e.trim()),e=""}else e+=a}let s=e.trim();if(!s&&t.length>0)throw new Error("Syntax error near unexpected token '|'");return s&&t.push(s),t}function ai(r){let t=li(r);if(t.length===0)return{name:"",args:[]};let e=[],n,i,s=!1,o=0;for(;o<t.length;){let l=t[o];if(l==="<"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after <");n=t[o],o++}else if(l===">>"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after >>");i=t[o],s=!0,o++}else if(l===">"){if(o++,o>=t.length)throw new Error("Syntax error: expected filename after >");i=t[o],s=!1,o++}else e.push(l),o++}return{name:(e[0]??"").toLowerCase(),args:e.slice(1),inputFile:n,outputFile:i,appendOutput:s}}function li(r){let t=[],e="",n=!1,i="",s=0;for(;s<r.length;){let o=r[s],a=r[s+1];if((o==='"'||o==="'")&&!n){n=!0,i=o,s++;continue}if(n&&o===i){n=!1,i="",s++;continue}if(n){e+=o,s++;continue}if(o===" "){e&&(t.push(e),e=""),s++;continue}if((o===">"||o==="<")&&!n){e&&(t.push(e),e=""),o===">"&&a===">"?(t.push(">>"),s+=2):(t.push(o),s++);continue}e+=o,s++}return e&&t.push(e),t}function Tn(r){let t=[],e="",n=!1,i="",s=0;for(;s<r.length;){let o=r[s],a=r[s+1];if((o==='"'||o==="'")&&!n){n=!0,i=o,s++;continue}if(n&&o===i){n=!1,i="",s++;continue}if(n){e+=o,s++;continue}if(o===" "){e&&(t.push(e),e=""),s++;continue}if((o===">"||o==="<")&&!n){e&&(t.push(e),e=""),o===">"&&a===">"?(t.push(">>"),s+=2):(t.push(o),s++);continue}e+=o,s++}return e&&t.push(e),t}function kt(r,t){return{vars:{PATH:"/usr/local/bin:/usr/bin:/bin",HOME:`/home/${r}`,USER:r,LOGNAME:r,SHELL:"/bin/sh",TERM:"xterm-256color",HOSTNAME:t,PS1:"\\u@\\h:\\w\\$ "},lastExitCode:0}}function On(r,t,e,n){if(r.startsWith("/")){if(!e.vfs.exists(r))return null;try{let s=e.vfs.stat(r);return s.type!=="file"||!(s.mode&73)||(r.startsWith("/sbin/")||r.startsWith("/usr/sbin/"))&&n!=="root"?null:r}catch{return null}}let i=(t.vars.PATH??"/usr/local/bin:/usr/bin:/bin").split(":");for(let s of i){if((s==="/sbin"||s==="/usr/sbin")&&n!=="root")continue;let o=`${s}/${r}`;if(e.vfs.exists(o))try{let a=e.vfs.stat(o);if(a.type!=="file"||!(a.mode&73))continue;return o}catch{}}return null}async function Yt(r,t,e,n,i,s,o,a,l){let c=l.vars[`__alias_${r}`];if(c)return Z(`${c} ${t.join(" ")}`,e,n,i,s,o,a,l);let u=mt(r);if(!u){let d=On(r,l,o,e);if(d){let m=o.vfs.readFile(d),f=m.match(/exec\s+builtin\s+(\S+)/);if(f){let g=mt(f[1]);if(g)return await g.run({authUser:e,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:[r,...t].join(" "),mode:i,args:t,stdin:a,cwd:s,shell:o,env:l})}let x=mt("sh");if(x)return await x.run({authUser:e,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:`sh -c ${JSON.stringify(m)}`,mode:i,args:["-c",m,"--",...t],stdin:a,cwd:s,shell:o,env:l})}return{stderr:`${r}: command not found`,exitCode:127}}try{return await u.run({authUser:e,hostname:n,activeSessions:o.users.listActiveSessions(),rawInput:[r,...t].join(" "),mode:i,args:t,stdin:a,cwd:s,shell:o,env:l})}catch(d){return{stderr:d instanceof Error?d.message:"Command failed",exitCode:1}}}async function Z(r,t,e,n,i,s,o,a){let l=r.trim();if(l.length===0)return{exitCode:0};let c=a??kt(t,e),d=Tn(l)[0]?.toLowerCase()??"",m=c.vars[`__alias_${d}`],f=m?l.replace(d,m):l;if(/(?<![|&])[|](?![|])/.test(f)||f.includes(">")||f.includes("<")||f.includes("&&")||f.includes("||")||f.includes(";")){let R=Ln(f);if(!R.isValid)return{stderr:R.error||"Syntax error",exitCode:1};try{return await _n(R.statements,t,e,n,i,s,c)}catch(D){return{stderr:D instanceof Error?D.message:"Execution failed",exitCode:1}}}let g=await Bt(f,c.vars,c.lastExitCode,R=>Z(R,t,e,n,i,s,void 0,c).then(D=>D.stdout??"")),y=Tn(g.trim()),$=y[0]?.toLowerCase()??"",V=y.slice(1),k=mt($);if(!k){let R=On($,c,s,t);if(R){let D=s.vfs.readFile(R),tt=D.match(/exec\s+builtin\s+(\S+)/);if(tt){let E=tt[1],T=mt(E);if(T)return await T.run({authUser:t,hostname:e,activeSessions:s.users.listActiveSessions(),rawInput:[$,...V].join(" "),mode:n,args:V,stdin:o,cwd:i,shell:s,env:c})}let w=mt("sh");if(w)return await w.run({authUser:t,hostname:e,activeSessions:s.users.listActiveSessions(),rawInput:`sh -c ${JSON.stringify(D)}`,mode:n,args:["-c",D,"--",...V],stdin:o,cwd:i,shell:s,env:c})}return{stderr:`${$}: command not found`,exitCode:127}}try{return await k.run({authUser:t,hostname:e,activeSessions:s.users.listActiveSessions(),rawInput:g,mode:n,args:V,stdin:o,cwd:i,shell:s,env:c})}catch(R){return{stderr:R instanceof Error?R.message:"Command failed",exitCode:1}}}function Qt(r,t,e){let n=[`Linux ${r} ${t.kernel} ${t.arch}`,"","The programs included with the Fortune GNU/Linux system are free software;","the exact distribution terms for each program are described in the","individual files in /usr/share/doc/*/copyright.","","Fortune GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent","permitted by applicable law."];if(e){let i=new Date(e.at),s=Number.isNaN(i.getTime())?e.at:Zt(i);n.push(`Last login: ${s} from ${e.from||"unknown"}`)}return n.push(""),`${n.map(i=>`${i}\r
280
+ `).join("")}`}function Xt(r,t,e){let n=r==="root",i=n?"\x1B[31;1m":"\x1B[35;1m",s="\x1B[37;1m",o="\x1B[34;1m",a="\x1B[0m";return`${s}[${i}${r}${s}@${o}${t}${a} ${e}${s}]${a}${n?"#":"$"} `}import{EventEmitter as Ri}from"node:events";import*as Mt from"node:os";function v(r,t,e=493){r.exists(t)||r.mkdir(t,e)}function O(r,t,e,n=420){r.exists(t)||r.writeFile(t,e,{mode:n})}function ci(r,t,e){v(r,"/etc"),O(r,"/etc/os-release",`${['NAME="Fortune GNU/Linux"',`PRETTY_NAME="${e.os}"`,"ID=fortune","ID_LIKE=debian",'HOME_URL="https://github.com/itsrealfortune/typescript-virtual-container"',"VERSION_CODENAME=aurora",'VERSION_ID="1.0"'].join(`
281
+ `)}
282
+ `),O(r,"/etc/debian_version",`12.0
283
+ `),O(r,"/etc/hostname",`${t}
284
+ `),O(r,"/etc/shells",`/bin/sh
285
+ /bin/bash
286
+ /usr/bin/bash
287
+ `),O(r,"/etc/profile",`${["export PATH=/usr/local/bin:/usr/bin:/bin","export PS1='\\u@\\h:\\w\\$ '"].join(`
288
+ `)}
289
+ `),O(r,"/etc/issue",`Fortune GNU/Linux 1.0 \\n \\l
290
+ `),O(r,"/etc/motd",["",`Welcome to ${e.os}`,`Kernel: ${e.kernel}`,""].join(`
291
+ `)),v(r,"/etc/apt"),v(r,"/etc/apt/sources.list.d"),O(r,"/etc/apt/sources.list",`${["# Fortune GNU/Linux package sources","deb [virtual] fortune://packages.fortune.local aurora main contrib","deb [virtual] fortune://security.fortune.local aurora-security main"].join(`
292
+ `)}
293
+ `),v(r,"/etc/network"),O(r,"/etc/network/interfaces",`${["auto lo","iface lo inet loopback","","auto eth0","iface eth0 inet dhcp"].join(`
294
+ `)}
295
+ `),O(r,"/etc/resolv.conf",`nameserver 1.1.1.1
296
+ nameserver 8.8.8.8
297
+ `),O(r,"/etc/hosts",`${["127.0.0.1 localhost",`127.0.1.1 ${t}`,"::1 localhost ip6-localhost ip6-loopback"].join(`
298
+ `)}
299
+ `),v(r,"/etc/cron.d"),v(r,"/etc/init.d"),v(r,"/etc/systemd"),v(r,"/etc/systemd/system")}function be(r,t){let e=t.listUsers(),n=["root:x:0:0:root:/root:/bin/bash","daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin","www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin","nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin"],i=1e3;for(let a of e)a!=="root"&&(n.push(`${a}:x:${i}:${i}::/home/${a}:/bin/bash`),i++);r.writeFile("/etc/passwd",`${n.join(`
300
+ `)}
301
+ `);let s=["root:x:0:","daemon:x:1:",`sudo:x:27:${e.filter(a=>t.isSudoer(a)).join(",")}`,`users:x:100:${e.filter(a=>a!=="root").join(",")}`,"nogroup:x:65534:"];r.writeFile("/etc/group",`${s.join(`
302
+ `)}
303
+ `);let o=["root:*:19000:0:99999:7:::","daemon:*:19000:0:99999:7:::"];for(let a of e)a!=="root"&&o.push(`${a}:!:19000:0:99999:7:::`);r.writeFile("/etc/shadow",`${o.join(`
304
+ `)}
305
+ `,{mode:416})}function zn(r){let t=r.match(/(\d+)$/);return 1e3+(t?.[1]?parseInt(t[1],10):0)}function Bn(r,t,e,n,i,s,o){let a=`/proc/${t}`;v(r,a),v(r,`${a}/fd`),v(r,`${a}/fdinfo`);let l=Math.floor((Date.now()-new Date(s).getTime())/1e3);r.writeFile(`${a}/cmdline`,`${i.replace(/\s+/g,"\0")}\0`),r.writeFile(`${a}/comm`,i.split(/\s+/)[0]??"bash"),r.writeFile(`${a}/status`,`${[`Name: ${i.split(/\s+/)[0]??"bash"}`,"State: S (sleeping)",`Pid: ${t}`,"PPid: 1","Uid: 0 0 0 0","Gid: 0 0 0 0","VmRSS: 4096 kB","VmSize: 16384 kB","Threads: 1"].join(`
306
+ `)}
307
+ `),r.writeFile(`${a}/stat`,`${t} (${i.split(/\s+/)[0]??"bash"}) S 1 ${t} ${t} 0 -1 4194304 0 0 0 0 ${l} 0 0 0 20 0 1 0 0 16384 4096 0
308
+ `),r.writeFile(`${a}/environ`,`${Object.entries(o).map(([c,u])=>`${c}=${u}`).join("\0")}\0`),r.writeFile(`${a}/cwd`,`/home/${e}\0`),r.writeFile(`${a}/exe`,"/bin/bash\0"),r.writeFile(`${a}/fd/0`,""),r.writeFile(`${a}/fd/1`,""),r.writeFile(`${a}/fd/2`,"")}function te(r,t,e,n,i){v(r,"/proc");let s=Math.floor((Date.now()-n)/1e3);r.writeFile("/proc/uptime",`${s}.00 ${Math.floor(s*.9)}.00
309
+ `);let o=Math.floor(Mt.totalmem()/1024),a=Math.floor(Mt.freemem()/1024),l=Math.floor(a*.95);r.writeFile("/proc/meminfo",`${[`MemTotal: ${String(o).padStart(10)} kB`,`MemFree: ${String(a).padStart(10)} kB`,`MemAvailable: ${String(l).padStart(10)} kB`,`Buffers: ${String(Math.floor(o*.02)).padStart(10)} kB`,`Cached: ${String(Math.floor(o*.15)).padStart(10)} kB`,`SwapTotal: ${String(Math.floor(o*.5)).padStart(10)} kB`,`SwapFree: ${String(Math.floor(o*.5)).padStart(10)} kB`].join(`
310
+ `)}
311
+ `);let c=Mt.cpus(),u=[];for(let y=0;y<c.length;y++){let $=c[y];if(!$)continue;let V=$.speed.toFixed(3);u.push(`processor : ${y}`,`model name : ${$.model}`,`cpu MHz : ${V}`,"cache size : 8192 KB","")}r.writeFile("/proc/cpuinfo",`${u.join(`
312
+ `)}
313
+ `),r.writeFile("/proc/version",`Linux version ${t.kernel} (fortune@build) (gcc version 12.2.0) #1 SMP
314
+ `),r.writeFile("/proc/hostname",`${e}
315
+ `);let d=(Math.random()*.5).toFixed(2),m=1+(i?.length??0);r.writeFile("/proc/loadavg",`${d} ${d} ${d} ${m}/${m} 1
316
+ `),v(r,"/proc/net"),O(r,"/proc/net/dev",`${["Inter-| Receive | Transmit"," face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed"," lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"," eth0: 131072 1024 0 0 0 0 0 0 65536 512 0 0 0 0 0 0"].join(`
317
+ `)}
318
+ `),Bn(r,1,"root","pts/0","/sbin/init",new Date(n).toISOString(),{});let f=i??[];for(let y of f){let $=zn(y.tty);Bn(r,$,y.username,y.tty,"bash",y.startedAt,{USER:y.username,HOME:`/home/${y.username}`,TERM:"xterm-256color",SHELL:"/bin/bash"})}let x=f.length>0?zn(f[f.length-1].tty):1;if(r.exists("/proc/self"))try{r.remove("/proc/self")}catch{}let g=`/proc/${x}`;if(r.exists(g)){v(r,"/proc/self"),v(r,"/proc/self/fd");for(let y of r.list(g)){let $=`${g}/${y}`,V=`/proc/self/${y}`;try{r.stat($).type==="file"&&r.writeFile(V,r.readFile($))}catch{}}r.writeFile("/proc/self/status",r.exists(`${g}/status`)?r.readFile(`${g}/status`):"")}else v(r,"/proc/self"),r.writeFile("/proc/self/cmdline","bash\0"),r.writeFile("/proc/self/comm","bash"),r.writeFile("/proc/self/status",`Name: bash
319
+ State: S (sleeping)
320
+ Pid: 1
321
+ PPid: 0
322
+ `),r.writeFile("/proc/self/environ",""),r.writeFile("/proc/self/cwd","/root\0"),r.writeFile("/proc/self/exe","/bin/bash\0")}function ui(r,t){v(r,"/sys"),v(r,"/sys/devices"),v(r,"/sys/devices/virtual"),v(r,"/sys/devices/virtual/dmi"),v(r,"/sys/devices/virtual/dmi/id"),O(r,"/sys/devices/virtual/dmi/id/sys_vendor",`Fortune Systems
323
+ `),O(r,"/sys/devices/virtual/dmi/id/product_name",`VirtualContainer v1
324
+ `),O(r,"/sys/devices/virtual/dmi/id/board_name",`fortune-board
325
+ `),v(r,"/sys/class"),v(r,"/sys/class/net"),v(r,"/sys/kernel"),O(r,"/sys/kernel/hostname",`fortune-vm
326
+ `),O(r,"/sys/kernel/osrelease",`${t.kernel}
327
+ `),O(r,"/sys/kernel/ostype",`Linux
328
+ `)}function di(r){v(r,"/dev"),O(r,"/dev/null","",438),O(r,"/dev/zero","",438),O(r,"/dev/random","",292),O(r,"/dev/urandom","",292),v(r,"/dev/pts"),v(r,"/dev/shm")}function mi(r){v(r,"/usr"),v(r,"/usr/bin"),v(r,"/usr/sbin"),v(r,"/usr/local"),v(r,"/usr/local/bin"),v(r,"/usr/local/lib"),v(r,"/usr/local/share"),v(r,"/usr/share"),v(r,"/usr/share/doc"),v(r,"/usr/share/man"),v(r,"/usr/share/man/man1"),v(r,"/usr/lib");let t=["sh","bash","ls","cat","echo","grep","find","sort","head","tail","cut","tr","sed","awk","wc","tee","tar","gzip","gunzip","touch","mkdir","rm","mv","cp","chmod","ln","pwd","env","date","sleep","id","whoami","hostname","uname","ps","kill","df","du","curl","wget","nano","diff","uniq","xargs","base64"];for(let e of t)O(r,`/usr/bin/${e}`,`#!/bin/sh
329
+ exec builtin ${e} "$@"
330
+ `,493);O(r,"/usr/bin/lsb_release",`#!/bin/sh
331
+ exec lsb_release "$@"
332
+ `,493)}function pi(r){v(r,"/var"),v(r,"/var/log"),v(r,"/var/tmp"),v(r,"/var/run"),v(r,"/var/cache"),v(r,"/var/cache/apt"),v(r,"/var/cache/apt/archives"),v(r,"/var/lib"),v(r,"/var/lib/apt"),v(r,"/var/lib/apt/lists"),v(r,"/var/lib/dpkg"),v(r,"/var/lib/dpkg/info"),O(r,"/var/lib/dpkg/status",""),O(r,"/var/lib/dpkg/available",""),O(r,"/var/log/syslog",`${new Date().toUTCString()} fortune kernel: Virtual container started
333
+ `),O(r,"/var/log/auth.log",""),O(r,"/var/log/dpkg.log",""),O(r,"/var/log/apt/history.log",""),O(r,"/var/log/apt/term.log","")}function fi(r){r.exists("/bin")||r.symlink("/usr/bin","/bin"),r.exists("/sbin")||r.symlink("/usr/sbin","/sbin"),r.exists("/lib")||v(r,"/lib"),r.exists("/lib64")||v(r,"/lib64")}function hi(r){v(r,"/tmp",1023)}function gi(r){v(r,"/root",448),O(r,"/root/.bashrc",`${["# root .bashrc","export PS1='\\[\\033[0;31m\\]\\u@\\h\\[\\033[0m\\]:\\[\\033[0;34m\\]\\w\\[\\033[0m\\]# '","export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","alias ll='ls -la'","alias la='ls -A'"].join(`
334
+ `)}
335
+ `),O(r,"/root/.profile",`[ -f ~/.bashrc ] && . ~/.bashrc
336
+ `),r.exists("/home/root")||r.symlink("/root","/home/root")}function yi(r){v(r,"/opt"),v(r,"/srv"),v(r,"/mnt"),v(r,"/media")}function Un(r,t,e,n,i){ci(r,e,n),ui(r,n),di(r),mi(r),pi(r),fi(r),hi(r),gi(r),yi(r),te(r,n,e,i,[]),be(r,t)}function jn(r){return r==="1"||r==="true"}function Wn(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Si(){return jn(process.env.DEV_MODE)||jn(process.env.RENDER_PERF)}function ee(r){let t=Si();if(!t)return{enabled:t,mark:()=>{},done:()=>{}};let e=Wn(),n=s=>{let o=Wn()-e;console.log(`[perf][${r}] ${s}: ${o.toFixed(1)}ms`)};return{enabled:t,mark:n,done:(s="done")=>{n(s)}}}import{EventEmitter as wi}from"node:events";import*as yt from"node:fs";import*as pt from"node:path";import{gunzipSync as $e,gzipSync as Qn}from"node:zlib";var Ce=Buffer.from([86,70,83,33]),xi=1,Hn=1,qn=2,we=class{chunks=[];write(t){this.chunks.push(t)}writeUint8(t){let e=Buffer.allocUnsafe(1);e.writeUInt8(t,0),this.chunks.push(e)}writeUint16(t){let e=Buffer.allocUnsafe(2);e.writeUInt16LE(t,0),this.chunks.push(e)}writeUint32(t){let e=Buffer.allocUnsafe(4);e.writeUInt32LE(t,0),this.chunks.push(e)}writeFloat64(t){let e=Buffer.allocUnsafe(8);e.writeDoubleBE(t,0),this.chunks.push(e)}writeString(t){let e=Buffer.from(t,"utf8");this.writeUint16(e.length),this.chunks.push(e)}writeBytes(t){this.writeUint32(t.length),this.chunks.push(t)}toBuffer(){return Buffer.concat(this.chunks)}};function Kn(r,t){if(t.type==="file"){let e=t;r.writeUint8(Hn),r.writeString(e.name),r.writeUint32(e.mode),r.writeFloat64(e.createdAt.getTime()),r.writeFloat64(e.updatedAt.getTime()),r.writeUint8(e.compressed?1:0),r.writeBytes(e.content)}else{let e=t;r.writeUint8(qn),r.writeString(e.name),r.writeUint32(e.mode),r.writeFloat64(e.createdAt.getTime()),r.writeFloat64(e.updatedAt.getTime());let n=Array.from(e.children.values());r.writeUint32(n.length);for(let i of n)Kn(r,i)}}function Gn(r){let t=new we;return t.write(Ce),t.writeUint8(xi),Kn(t,r),t.toBuffer()}var ve=class{constructor(t){this.buf=t}buf;pos=0;readUint8(){return this.buf.readUInt8(this.pos++)}readUint16(){let t=this.buf.readUInt16LE(this.pos);return this.pos+=2,t}readUint32(){let t=this.buf.readUInt32LE(this.pos);return this.pos+=4,t}readFloat64(){let t=this.buf.readDoubleBE(this.pos);return this.pos+=8,t}readString(){let t=this.readUint16(),e=this.buf.toString("utf8",this.pos,this.pos+t);return this.pos+=t,e}readBytes(){let t=this.readUint32(),e=this.buf.slice(this.pos,this.pos+t);return this.pos+=t,e}remaining(){return this.buf.length-this.pos}};function Zn(r){let t=r.readUint8(),e=r.readString(),n=r.readUint32(),i=new Date(r.readFloat64()),s=new Date(r.readFloat64());if(t===Hn){let o=r.readUint8()===1,a=r.readBytes();return{type:"file",name:e,mode:n,createdAt:i,updatedAt:s,compressed:o,content:a}}if(t===qn){let o=r.readUint32(),a=new Map;for(let l=0;l<o;l++){let c=Zn(r);a.set(c.name,c)}return{type:"directory",name:e,mode:n,createdAt:i,updatedAt:s,children:a}}throw new Error(`[VFS binary] Unknown node type: 0x${t.toString(16)}`)}function Jn(r){if(r.length<5)throw new Error("[VFS binary] Buffer too short");if(!r.slice(0,4).equals(Ce))throw new Error("[VFS binary] Invalid magic \u2014 not a VFS binary snapshot");let e=new ve(r);for(let i=0;i<5;i++)e.readUint8();let n=Zn(e);if(n.type!=="directory")throw new Error("[VFS binary] Root node must be a directory");return n}function Yn(r){return r.length>=4&&r.slice(0,4).equals(Ce)}import*as re from"node:path";function W(r){if(!r||r.trim()==="")return"/";let t=re.posix.normalize(r.startsWith("/")?r:`/${r}`);return t===""?"/":t}function bi(r){return r.split("/").filter(Boolean)}function X(r,t){let e=W(t);if(e==="/")return r;let n=bi(e),i=r;for(let s of n){if(i.type!=="directory")throw new Error(`Path '${e}' does not exist.`);let o=i.children.get(s);if(!o)throw new Error(`Path '${e}' does not exist.`);i=o}return i}function Et(r,t,e,n){let i=W(t);if(i==="/")throw new Error("Root path has no parent directory.");let s=re.posix.dirname(i),o=re.posix.basename(i);if(!o)throw new Error(`Invalid path '${t}'.`);e&&n(s);let a=X(r,s);if(a.type!=="directory")throw new Error(`Parent path '${s}' is not a directory.`);return{parent:a,name:o}}var Pe=class r extends wi{root;mode;snapshotFile;constructor(t={}){if(super(),this.mode=t.mode??"memory",this.mode==="fs"){if(!t.snapshotPath)throw new Error('VirtualFileSystem: "snapshotPath" is required when mode is "fs".');this.snapshotFile=pt.resolve(t.snapshotPath,"vfs-snapshot.vfsb")}else this.snapshotFile=null;this.root=this.makeDir("",493)}makeDir(t,e){let n=new Date;return{type:"directory",name:t,mode:e,createdAt:n,updatedAt:n,children:new Map}}makeFile(t,e,n,i){let s=new Date;return{type:"file",name:t,content:e,mode:n,compressed:i,createdAt:s,updatedAt:s}}mkdirRecursive(t,e){let n=W(t);if(n==="/")return;let i=n.split("/").filter(Boolean),s=this.root,o="";for(let a of i){o+=`/${a}`;let l=s.children.get(a);if(!l)l=this.makeDir(a,e),s.children.set(a,l),this.emit("dir:create",{path:o,mode:e});else if(l.type!=="directory")throw new Error(`Cannot create directory '${o}': path is a file.`);s=l}}async restoreMirror(){if(!(this.mode!=="fs"||!this.snapshotFile)&&yt.existsSync(this.snapshotFile))try{let t=yt.readFileSync(this.snapshotFile);if(Yn(t))this.root=Jn(t);else{let e=JSON.parse(t.toString("utf8"));this.root=this.deserializeDir(e.root,""),console.info("[VirtualFileSystem] Migrating legacy JSON snapshot to binary format.")}this.emit("snapshot:restore",{path:this.snapshotFile})}catch(t){console.warn(`[VirtualFileSystem] Could not restore snapshot from ${this.snapshotFile}:`,t instanceof Error?t.message:String(t))}}async flushMirror(){if(this.mode!=="fs"||!this.snapshotFile){this.emit("mirror:flush");return}let t=pt.dirname(this.snapshotFile);yt.mkdirSync(t,{recursive:!0});let e=Gn(this.root);yt.writeFileSync(this.snapshotFile,e),this.emit("mirror:flush",{path:this.snapshotFile})}getMode(){return this.mode}getSnapshotPath(){return this.snapshotFile}mkdir(t,e=493){let n=W(t),i=(()=>{try{return X(this.root,n)}catch{return null}})();if(i&&i.type!=="directory")throw new Error(`Cannot create directory '${n}': path is a file.`);this.mkdirRecursive(n,e)}writeFile(t,e,n={}){let i=W(t),{parent:s,name:o}=Et(this.root,i,!0,m=>this.mkdirRecursive(m,493)),a=s.children.get(o);if(a?.type==="directory")throw new Error(`Cannot write file '${i}': path is a directory.`);let l=Buffer.isBuffer(e)?e:Buffer.from(e,"utf8"),c=n.compress??!1,u=c?Qn(l):l,d=n.mode??420;if(a){let m=a;m.content=u,m.compressed=c,m.mode=d,m.updatedAt=new Date}else s.children.set(o,this.makeFile(o,u,d,c));this.emit("file:write",{path:i,size:u.length})}readFile(t){let e=W(t),n=X(this.root,e);if(n.type!=="file")throw new Error(`Cannot read '${t}': not a file.`);let i=n,s=i.compressed?$e(i.content):i.content;return this.emit("file:read",{path:e,size:s.length}),s.toString("utf8")}readFileRaw(t){let e=W(t),n=X(this.root,e);if(n.type!=="file")throw new Error(`Cannot read '${t}': not a file.`);let i=n,s=i.compressed?$e(i.content):i.content;return this.emit("file:read",{path:e,size:s.length}),s}exists(t){try{return X(this.root,W(t)),!0}catch{return!1}}chmod(t,e){X(this.root,W(t)).mode=e}stat(t){let e=W(t),n=X(this.root,e),i=e==="/"?"":pt.posix.basename(e);if(n.type==="file"){let o=n;return{type:"file",name:i,path:e,mode:o.mode,createdAt:o.createdAt,updatedAt:o.updatedAt,compressed:o.compressed,size:o.content.length}}let s=n;return{type:"directory",name:i,path:e,mode:s.mode,createdAt:s.createdAt,updatedAt:s.updatedAt,childrenCount:s.children.size}}list(t="/"){let e=W(t),n=X(this.root,e);if(n.type!=="directory")throw new Error(`Cannot list '${t}': not a directory.`);return Array.from(n.children.keys()).sort()}tree(t="/"){let e=W(t),n=X(this.root,e);if(n.type!=="directory")throw new Error(`Cannot render tree for '${t}': not a directory.`);let i=t==="/"?"/":pt.posix.basename(e);return this.renderTreeLines(n,i)}renderTreeLines(t,e){let n=[e],i=Array.from(t.children.keys()).sort();for(let s=0;s<i.length;s++){let o=i[s],a=t.children.get(o),l=s===i.length-1,c=l?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",u=l?" ":"\u2502 ";if(n.push(`${c}${o}`),a.type==="directory"){let d=this.renderTreeLines(a,"").split(`
337
+ `).slice(1).map(m=>`${u}${m}`);n.push(...d)}}return n.join(`
338
+ `)}getUsageBytes(t="/"){return this.computeUsage(X(this.root,W(t)))}computeUsage(t){if(t.type==="file")return t.content.length;let e=0;for(let n of t.children.values())e+=this.computeUsage(n);return e}compressFile(t){let e=X(this.root,W(t));if(e.type!=="file")throw new Error(`Cannot compress '${t}': not a file.`);let n=e;n.compressed||(n.content=Qn(n.content),n.compressed=!0,n.updatedAt=new Date)}decompressFile(t){let e=X(this.root,W(t));if(e.type!=="file")throw new Error(`Cannot decompress '${t}': not a file.`);let n=e;n.compressed&&(n.content=$e(n.content),n.compressed=!1,n.updatedAt=new Date)}symlink(t,e){let n=W(e),i=t.startsWith("/")?W(t):t,{parent:s,name:o}=Et(this.root,n,!0,l=>this.mkdirRecursive(l,493)),a={type:"file",name:o,content:Buffer.from(i,"utf8"),mode:41471,compressed:!1,createdAt:new Date,updatedAt:new Date};s.children.set(o,a),this.emit("symlink:create",{link:n,target:i})}isSymlink(t){try{let e=X(this.root,W(t));return e.type==="file"&&e.mode===41471}catch{return!1}}resolveSymlink(t,e=8){let n=W(t);for(let i=0;i<e;i++){try{let s=X(this.root,n);if(s.type==="file"&&s.mode===41471){let o=s.content.toString("utf8");n=o.startsWith("/")?o:W(pt.posix.join(pt.posix.dirname(n),o));continue}}catch{break}return n}throw new Error(`Too many levels of symbolic links: ${t}`)}remove(t,e={}){let n=W(t);if(n==="/")throw new Error("Cannot remove root directory.");let i=X(this.root,n);if(i.type==="directory"){let a=i;if(!e.recursive&&a.children.size>0)throw new Error(`Directory '${n}' is not empty. Use recursive option.`)}let{parent:s,name:o}=Et(this.root,n,!1,()=>{});s.children.delete(o),this.emit("node:remove",{path:n})}move(t,e){let n=W(t),i=W(e);if(n==="/"||i==="/")throw new Error("Cannot move root directory.");let s=X(this.root,n);if(this.exists(i))throw new Error(`Destination '${i}' already exists.`);this.mkdirRecursive(pt.posix.dirname(i),493);let{parent:o,name:a}=Et(this.root,i,!1,()=>{}),{parent:l,name:c}=Et(this.root,n,!1,()=>{});l.children.delete(c),s.name=a,o.children.set(a,s)}toSnapshot(){return{root:this.serializeDir(this.root)}}serializeDir(t){let e=[];for(let n of t.children.values())e.push(n.type==="file"?this.serializeFile(n):this.serializeDir(n));return{type:"directory",name:t.name,mode:t.mode,createdAt:t.createdAt.toISOString(),updatedAt:t.updatedAt.toISOString(),children:e}}serializeFile(t){return{type:"file",name:t.name,mode:t.mode,createdAt:t.createdAt.toISOString(),updatedAt:t.updatedAt.toISOString(),compressed:t.compressed,contentBase64:t.content.toString("base64")}}static fromSnapshot(t){let e=new r;return e.root=e.deserializeDir(t.root,""),e}importSnapshot(t){this.root=this.deserializeDir(t.root,""),this.emit("snapshot:import")}deserializeDir(t,e){let n={type:"directory",name:e,mode:t.mode,createdAt:new Date(t.createdAt),updatedAt:new Date(t.updatedAt),children:new Map};for(let i of t.children)if(i.type==="file"){let s=i;n.children.set(s.name,{type:"file",name:s.name,mode:s.mode,createdAt:new Date(s.createdAt),updatedAt:new Date(s.updatedAt),compressed:s.compressed,content:Buffer.from(s.contentBase64,"base64")})}else{let s=this.deserializeDir(i,i.name);n.children.set(i.name,s)}return n}},Xn=Pe;var ke=[{name:"vim",version:"2:9.0.1378-2",section:"editors",description:"Vi IMproved - enhanced vi editor",shortDesc:"Vi IMproved",installedSizeKb:3812,files:[{path:"/usr/bin/vim",content:`#!/bin/sh
339
+ echo 'vim: use nano for editing in this environment'
340
+ `,mode:493},{path:"/usr/bin/vi",content:`#!/bin/sh
341
+ exec vim "$@"
342
+ `,mode:493},{path:"/usr/share/doc/vim/README",content:`Vim editor \u2014 virtual package.
343
+ `}]},{name:"git",version:"1:2.39.2-1",section:"vcs",description:"Fast, scalable, distributed revision control system",shortDesc:"fast distributed version control system",installedSizeKb:11240,files:[{path:"/usr/bin/git",content:`#!/bin/sh
344
+ echo 'git: virtual stub \u2014 no host access'
345
+ `,mode:493},{path:"/usr/share/doc/git/README.Debian",content:`Git virtual package for Fortune GNU/Linux.
346
+ `}]},{name:"python3",version:"3.11.2-1+b1",section:"python",description:"Interactive high-level object-oriented language (version 3)",shortDesc:"interactive high-level object-oriented language",installedSizeKb:512,depends:["python3-minimal"],files:[{path:"/usr/bin/python3",content:`#!/bin/sh
347
+ echo 'Python 3.11.2 (virtual)'
348
+ `,mode:493},{path:"/usr/bin/python3.11",content:`#!/bin/sh
349
+ exec python3 "$@"
350
+ `,mode:493},{path:"/usr/lib/python3.11/.keep",content:""}]},{name:"python3-minimal",version:"3.11.2-1+b1",section:"python",description:"Minimal subset of the Python language (version 3)",shortDesc:"minimal subset of Python language",installedSizeKb:196,files:[{path:"/usr/lib/python3-minimal/.keep",content:""}]},{name:"nodejs",version:"18.19.0+dfsg-6",section:"javascript",description:"Evented I/O for V8 javascript - runtime executable",shortDesc:"Node.js JavaScript runtime",installedSizeKb:15360,files:[{path:"/usr/bin/node",content:`#!/bin/sh
351
+ echo 'node v18.19.0 (virtual)'
352
+ `,mode:493},{path:"/usr/bin/nodejs",content:`#!/bin/sh
353
+ exec node "$@"
354
+ `,mode:493},{path:"/usr/share/doc/nodejs/README",content:`Node.js virtual package.
355
+ `}]},{name:"npm",version:"9.2.0~ds1-2",section:"javascript",description:"package manager for Node.js",shortDesc:"package manager for Node.js",installedSizeKb:9814,depends:["nodejs"],files:[{path:"/usr/bin/npm",content:`#!/bin/sh
356
+ exec builtin npm "$@"
357
+ `,mode:493},{path:"/usr/bin/npx",content:`#!/bin/sh
358
+ exec builtin npx "$@"
359
+ `,mode:493}]},{name:"curl",version:"7.88.1-10+deb12u5",section:"web",description:"command line tool for transferring data with URL syntax",shortDesc:"command line tool for transferring data",installedSizeKb:368,files:[{path:"/usr/bin/curl",content:`#!/bin/sh
360
+ exec builtin curl "$@"
361
+ `,mode:493}]},{name:"wget",version:"1.21.3-1+b2",section:"web",description:"Retrieves files from the web",shortDesc:"retrieves files from the web",installedSizeKb:952,files:[{path:"/usr/bin/wget",content:`#!/bin/sh
362
+ exec builtin wget "$@"
363
+ `,mode:493}]},{name:"htop",version:"3.2.2-2",section:"utils",description:"interactive processes viewer",shortDesc:"interactive process viewer",installedSizeKb:412,files:[{path:"/usr/bin/htop",content:`#!/bin/sh
364
+ exec builtin htop
365
+ `,mode:493}]},{name:"openssh-client",version:"1:9.2p1-2+deb12u2",section:"net",description:"Secure Shell (SSH) client",shortDesc:"secure shell (SSH) client",installedSizeKb:4540,files:[{path:"/usr/bin/ssh",content:`#!/bin/sh
366
+ echo 'ssh: virtual stub'
367
+ `,mode:493},{path:"/usr/bin/ssh-keygen",content:`#!/bin/sh
368
+ echo 'ssh-keygen: virtual stub'
369
+ `,mode:493},{path:"/etc/ssh/ssh_config",content:`Host *
370
+ StrictHostKeyChecking ask
371
+ `}]},{name:"openssh-server",version:"1:9.2p1-2+deb12u2",section:"net",description:"Secure Shell server (sshd)",shortDesc:"secure shell server",installedSizeKb:1732,depends:["openssh-client"],files:[{path:"/usr/sbin/sshd",content:`#!/bin/sh
372
+ echo 'sshd: virtual \u2014 server already running'
373
+ `,mode:493},{path:"/etc/ssh/sshd_config",content:`Port 22
374
+ PermitRootLogin yes
375
+ PasswordAuthentication yes
376
+ `}]},{name:"net-tools",version:"2.10-0.1",section:"net",description:"NET-3 networking toolkit (ifconfig, netstat, route)",shortDesc:"networking toolkit",installedSizeKb:988,files:[{path:"/usr/bin/ifconfig",content:`#!/bin/sh
377
+ echo 'eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500'
378
+ echo ' inet 10.0.0.2 netmask 255.255.255.0 broadcast 10.0.0.255'
379
+ echo ' ether 02:42:0a:00:00:02 txqueuelen 0 (Ethernet)'
380
+ `,mode:493},{path:"/usr/bin/netstat",content:`#!/bin/sh
381
+ echo 'Active Internet connections (only servers)'
382
+ echo 'Proto Recv-Q Send-Q Local Address Foreign Address State'
383
+ `,mode:493},{path:"/usr/bin/route",content:`#!/bin/sh
384
+ echo 'Kernel IP routing table'
385
+ echo 'Destination Gateway Genmask Flags Metric Ref Use Iface'
386
+ echo '0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0'
387
+ `,mode:493}]},{name:"iputils-ping",version:"3:20221126-1",section:"net",description:"Tools to test the reachability of network hosts",shortDesc:"test reachability of network hosts",installedSizeKb:164,files:[{path:"/usr/bin/ping",content:`#!/bin/sh
388
+ exec builtin ping "$@"
389
+ `,mode:493}]},{name:"jq",version:"1.6-2.1",section:"utils",description:"Lightweight and flexible command-line JSON processor",shortDesc:"command-line JSON processor",installedSizeKb:296,files:[{path:"/usr/bin/jq",content:`#!/bin/sh
390
+ echo 'jq: virtual stub \u2014 pipe JSON here'
391
+ `,mode:493}]},{name:"build-essential",version:"12.9",section:"devel",description:"Informational list of build-essential packages",shortDesc:"build-essential meta-package",installedSizeKb:12,depends:["gcc","g++","make"],files:[{path:"/usr/share/doc/build-essential/README",content:`Build-essential virtual meta-package.
392
+ `}]},{name:"gcc",version:"4:12.2.0-3",section:"devel",description:"GNU C compiler",shortDesc:"GNU C compiler",installedSizeKb:24448,files:[{path:"/usr/bin/gcc",content:`#!/bin/sh
393
+ echo 'gcc (Fortune GNU/Linux) 12.2.0 (virtual)'
394
+ `,mode:493},{path:"/usr/bin/gcc-12",content:`#!/bin/sh
395
+ exec gcc "$@"
396
+ `,mode:493}]},{name:"g++",version:"4:12.2.0-3",section:"devel",description:"GNU C++ compiler",shortDesc:"GNU C++ compiler",installedSizeKb:1024,depends:["gcc"],files:[{path:"/usr/bin/g++",content:`#!/bin/sh
397
+ echo 'g++ (Fortune GNU/Linux) 12.2.0 (virtual)'
398
+ `,mode:493}]},{name:"make",version:"4.3-4.1",section:"devel",description:"Utility for directing compilation",shortDesc:"build utility",installedSizeKb:504,files:[{path:"/usr/bin/make",content:`#!/bin/sh
399
+ echo 'make: *** No targets specified and no makefile found. Stop.'
400
+ exit 2
401
+ `,mode:493}]},{name:"less",version:"590-2",section:"text",description:"Pager program similar to more",shortDesc:"pager program",installedSizeKb:328,files:[{path:"/usr/bin/less",content:`#!/bin/sh
402
+ cat "$@"
403
+ `,mode:493}]},{name:"unzip",version:"6.0-28",section:"utils",description:"De-archiver for .zip files",shortDesc:"de-archiver for .zip files",installedSizeKb:464,files:[{path:"/usr/bin/unzip",content:`#!/bin/sh
404
+ echo 'unzip: virtual stub'
405
+ `,mode:493}]},{name:"rsync",version:"3.2.7-1",section:"net",description:"Fast, versatile, remote (and local) file-copying tool",shortDesc:"fast remote file copy program",installedSizeKb:716,files:[{path:"/usr/bin/rsync",content:`#!/bin/sh
406
+ echo 'rsync: virtual stub'
407
+ `,mode:493}]},{name:"tmux",version:"3.3a-3",section:"utils",description:"Terminal multiplexer",shortDesc:"terminal multiplexer",installedSizeKb:812,files:[{path:"/usr/bin/tmux",content:`#!/bin/sh
408
+ echo 'tmux: terminal multiplexer (virtual stub)'
409
+ `,mode:493}]},{name:"tree",version:"2.1.0-1",section:"utils",description:"Displays an indented directory tree, in color",shortDesc:"list files in tree format",installedSizeKb:108,files:[{path:"/usr/bin/tree",content:`#!/bin/sh
410
+ exec builtin tree "$@"
411
+ `,mode:493}]},{name:"ca-certificates",version:"20230311",section:"misc",description:"Common CA certificates",shortDesc:"common CA certificates",installedSizeKb:388,files:[{path:"/etc/ssl/certs/.keep",content:""},{path:"/etc/ssl/private/.keep",content:""},{path:"/usr/share/ca-certificates/.keep",content:""}],onInstall:r=>{r.exists("/etc/ssl")||r.mkdir("/etc/ssl",493),r.exists("/etc/ssl/certs")||r.mkdir("/etc/ssl/certs",493)}},{name:"locales",version:"2.36-9+deb12u3",section:"localization",description:"GNU C Library: National Language (locale) data",shortDesc:"locale data",installedSizeKb:16484,files:[{path:"/etc/locale.gen",content:`en_US.UTF-8 UTF-8
412
+ `},{path:"/etc/default/locale",content:`LANG=en_US.UTF-8
413
+ LANGUAGE=en_US:en
414
+ `}]},{name:"sudo",version:"1.9.13p3-1+deb12u1",section:"admin",description:"Provide limited super user privileges to specific users",shortDesc:"super user privilege execution",installedSizeKb:2304,files:[{path:"/usr/bin/sudo",content:`#!/bin/sh
415
+ exec builtin sudo "$@"
416
+ `,mode:493},{path:"/etc/sudoers",content:`root ALL=(ALL:ALL) ALL
417
+ %sudo ALL=(ALL:ALL) ALL
418
+ `}]},{name:"systemd",version:"252.22-1~deb12u1",section:"admin",description:"System and service manager",shortDesc:"system and service manager",installedSizeKb:26624,files:[{path:"/usr/bin/systemctl",content:`#!/bin/sh
419
+ echo 'systemd is not running in this virtual container.'
420
+ exit 1
421
+ `,mode:493},{path:"/usr/bin/journalctl",content:`#!/bin/sh
422
+ echo 'journalctl: virtual stub'
423
+ `,mode:493}]}],ne=class{constructor(t,e){this.vfs=t;this.users=e}vfs;users;installed=new Map;registryPath="/var/lib/dpkg/status";logPath="/var/log/dpkg.log";aptLogPath="/var/log/apt/history.log";load(){if(!this.vfs.exists(this.registryPath))return;let t=this.vfs.readFile(this.registryPath);if(!t.trim())return;let e=t.split(/\n\n+/);for(let n of e){if(!n.trim())continue;let i=this.parseFields(n),s=i.Package;s&&this.installed.set(s,{name:s,version:i.Version??"unknown",architecture:i.Architecture??"amd64",maintainer:i.Maintainer??"Fortune Maintainers",description:i.Description??"",section:i.Section??"misc",installedSizeKb:Number(i["Installed-Size"]??0),installedAt:i["X-Installed-At"]??new Date().toISOString(),files:(i["X-Files"]??"").split("|").filter(Boolean)})}}persist(){let t=[];for(let e of this.installed.values())t.push([`Package: ${e.name}`,"Status: install ok installed","Priority: optional",`Section: ${e.section}`,`Installed-Size: ${e.installedSizeKb}`,`Maintainer: ${e.maintainer}`,`Architecture: ${e.architecture}`,`Version: ${e.version}`,`Description: ${e.description}`,`X-Installed-At: ${e.installedAt}`,`X-Files: ${e.files.join("|")}`].join(`
424
+ `));this.vfs.writeFile(this.registryPath,`${t.join(`
425
+
426
+ `)}
427
+ `)}parseFields(t){let e={};for(let n of t.split(`
428
+ `)){let i=n.indexOf(": ");i!==-1&&(e[n.slice(0,i)]=n.slice(i+2))}return e}log(t){let n=`${new Date().toISOString().replace("T"," ").slice(0,19)} ${t}
429
+ `,i=this.vfs.exists(this.logPath)?this.vfs.readFile(this.logPath):"";this.vfs.writeFile(this.logPath,i+n)}aptLog(t,e){let n=new Date().toISOString(),i=this.vfs.exists(this.aptLogPath)?this.vfs.readFile(this.aptLogPath):"",s=[`Start-Date: ${n}`,`Commandline: apt-get ${t} ${e.join(" ")}`,`${t==="install"?"Install":"Remove"}: ${e.join(", ")}`,`End-Date: ${n}`,""].join(`
430
+ `);this.vfs.writeFile(this.aptLogPath,i+s)}findInRegistry(t){return ke.find(e=>e.name.toLowerCase()===t.toLowerCase())}listAvailable(){return[...ke].sort((t,e)=>t.name.localeCompare(e.name))}listInstalled(){return[...this.installed.values()].sort((t,e)=>t.name.localeCompare(e.name))}isInstalled(t){return this.installed.has(t.toLowerCase())}installedCount(){return this.installed.size}install(t,e={}){let n=[],i=[],s=[],o=(l,c=new Set)=>{if(c.has(l)||(c.add(l),this.isInstalled(l)))return;let u=this.findInRegistry(l);if(!u){s.push(l);return}for(let d of u.depends??[])o(d,c);i.find(d=>d.name===u.name)||i.push(u)};for(let l of t)o(l);if(s.length>0)return{output:`E: Unable to locate package ${s.join(", ")}`,exitCode:100};if(i.length===0)return{output:t.map(l=>`${l} is already the newest version.`).join(`
431
+ `),exitCode:0};let a=i.reduce((l,c)=>l+(c.installedSizeKb??0),0);e.quiet||n.push("Reading package lists... Done","Building dependency tree... Done","Reading state information... Done","The following NEW packages will be installed:",` ${i.map(l=>l.name).join(" ")}`,`0 upgraded, ${i.length} newly installed, 0 to remove and 0 not upgraded.`,`Need to get 0 B/${a} kB of archives.`,`After this operation, ${a} kB of additional disk space will be used.`,"");for(let l of i){e.quiet||(n.push(`Selecting previously unselected package ${l.name}.`),n.push("(Reading database ... 12345 files and directories currently installed.)"),n.push(`Preparing to unpack .../archives/${l.name}_${l.version}_amd64.deb ...`),n.push(`Unpacking ${l.name} (${l.version}) ...`));for(let u of l.files??[]){let d=u.path.slice(0,u.path.lastIndexOf("/"));d&&!this.vfs.exists(d)&&this.vfs.mkdir(d,493),this.vfs.writeFile(u.path,u.content,{mode:u.mode??420})}l.onInstall?.(this.vfs,this.users),e.quiet||n.push(`Setting up ${l.name} (${l.version}) ...`);let c=new Date().toISOString();this.installed.set(l.name,{name:l.name,version:l.version,architecture:l.architecture??"amd64",maintainer:l.maintainer??"Fortune Maintainers <pkg@fortune.local>",description:l.description,section:l.section??"misc",installedSizeKb:l.installedSizeKb??0,installedAt:c,files:(l.files??[]).map(u=>u.path)}),this.log(`install ${l.name} ${l.version}`)}return this.aptLog("install",i.map(l=>l.name)),this.persist(),e.quiet||n.push("Processing triggers for man-db (2.11.2-2) ..."),{output:n.join(`
432
+ `),exitCode:0}}remove(t,e={}){let n=[],i=[];for(let s of t){let o=this.installed.get(s.toLowerCase());o?i.push(o):n.push(`Package '${s}' is not installed, so not removed`)}if(i.length===0)return{output:n.join(`
433
+ `)||"Nothing to remove.",exitCode:0};e.quiet||n.push("Reading package lists... Done","Building dependency tree... Done","The following packages will be REMOVED:",` ${i.map(s=>s.name).join(" ")}`,`0 upgraded, 0 newly installed, ${i.length} to remove and 0 not upgraded.`);for(let s of i){e.quiet||n.push(`Removing ${s.name} (${s.version}) ...`);for(let a of s.files)if(!(!e.purge&&(a.startsWith("/etc/")||a.endsWith(".conf"))))try{this.vfs.exists(a)&&this.vfs.remove(a)}catch{}this.findInRegistry(s.name)?.onRemove?.(this.vfs),this.installed.delete(s.name),this.log(`remove ${s.name} ${s.version}`)}return this.aptLog("remove",i.map(s=>s.name)),this.persist(),{output:n.join(`
434
+ `),exitCode:0}}search(t){let e=t.toLowerCase();return ke.filter(n=>n.name.includes(e)||n.description.toLowerCase().includes(e)||(n.shortDesc??"").toLowerCase().includes(e)).sort((n,i)=>n.name.localeCompare(i.name))}show(t){let e=this.findInRegistry(t);if(!e)return null;let n=this.installed.get(t);return[`Package: ${e.name}`,`Version: ${e.version}`,`Architecture: ${e.architecture??"amd64"}`,`Maintainer: ${e.maintainer??"Fortune Maintainers <pkg@fortune.local>"}`,`Installed-Size: ${e.installedSizeKb??0}`,`Depends: ${(e.depends??[]).join(", ")||"(none)"}`,`Section: ${e.section??"misc"}`,"Priority: optional",`Description: ${e.description}`,`Status: ${n?"install ok installed":"install ok not-installed"}`].join(`
435
+ `)}};import{createHash as vi,randomBytes as Ci,randomUUID as $i,scryptSync as Pi}from"node:crypto";import{EventEmitter as ki}from"node:events";import*as es from"node:path";function Mi(){let r=process.env.SSH_MIMIC_FAST_PASSWORD_HASH;return!!r&&!["0","false","no","off"].includes(r.toLowerCase())}var J=ee("VirtualUserManager"),se=class r extends ki{constructor(e,n=!0){super();this.vfs=e;this.autoSudoForNewUsers=n;J.mark("constructor")}vfs;autoSudoForNewUsers;static recordCache=new Map;static fastPasswordHash=Mi();usersPath="/virtual-env-js/.auth/htpasswd";sudoersPath="/virtual-env-js/.auth/sudoers";quotasPath="/virtual-env-js/.auth/quotas";authDirPath="/virtual-env-js/.auth";users=new Map;sudoers=new Set;quotas=new Map;activeSessions=new Map;nextTty=0;async initialize(){J.mark("initialize"),this.loadFromVfs(),this.loadSudoersFromVfs(),this.loadQuotasFromVfs();let e=!1;this.users.has("root")||(this.users.set("root",this.createRecord("root","")),e=!0),this.sudoers.add("root"),e&&await this.persist(),this.emit("initialized")}async setQuotaBytes(e,n){if(J.mark("setQuotaBytes"),this.validateUsername(e),!this.users.has(e))throw new Error(`quota: user '${e}' does not exist`);if(!Number.isFinite(n)||n<0)throw new Error("quota: maxBytes must be a non-negative number");this.quotas.set(e,Math.floor(n)),await this.persist()}async clearQuota(e){J.mark("clearQuota"),this.validateUsername(e),this.quotas.delete(e),await this.persist()}getQuotaBytes(e){return J.mark("getQuotaBytes"),this.quotas.get(e)??null}getUsageBytes(e){J.mark("getUsageBytes");let n=`/home/${e}`;return this.vfs.exists(n)?this.vfs.getUsageBytes(n):0}assertWriteWithinQuota(e,n,i){J.mark("assertWriteWithinQuota");let s=this.quotas.get(e);if(s===void 0)return;let o=ts(n),a=ts(`/home/${e}`);if(!(o===a||o.startsWith(`${a}/`)))return;let c=this.getUsageBytes(e),u=0;if(this.vfs.exists(o)){let f=this.vfs.stat(o);f.type==="file"&&(u=f.size)}let d=Buffer.isBuffer(i)?i.length:Buffer.byteLength(i,"utf8"),m=c-u+d;if(m>s)throw new Error(`quota exceeded for '${e}': ${m}/${s} bytes`)}verifyPassword(e,n){J.mark("verifyPassword");let i=this.users.get(e);return i?this.hashPassword(n)===i.passwordHash:!1}async addUser(e,n){if(J.mark("addUser"),this.validateUsername(e),this.validatePassword(n),this.users.has(e))return;this.users.set(e,this.createRecord(e,n)),this.autoSudoForNewUsers&&this.sudoers.add(e);let i=`/home/${e}`;this.vfs.exists(i)||(this.vfs.mkdir(i,493),this.vfs.writeFile(`${i}/README.txt`,`Welcome to the virtual environment, ${e}`)),await this.persist(),this.emit("user:add",{username:e})}getPasswordHash(e){J.mark("getPasswordHash");let n=this.users.get(e);return n?n.passwordHash:null}async setPassword(e,n){if(J.mark("setPassword"),this.validateUsername(e),this.validatePassword(n),!this.users.has(e))throw new Error(`passwd: user '${e}' does not exist`);this.users.set(e,this.createRecord(e,n)),await this.persist()}async deleteUser(e){if(J.mark("deleteUser"),this.validateUsername(e),e==="root")throw new Error("deluser: cannot delete root");if(!this.users.delete(e))throw new Error(`deluser: user '${e}' does not exist`);this.sudoers.delete(e),this.emit("user:delete",{username:e}),await this.persist()}isSudoer(e){return J.mark("isSudoer"),this.sudoers.has(e)}async addSudoer(e){if(J.mark("addSudoer"),this.validateUsername(e),!this.users.has(e))throw new Error(`sudoers: user '${e}' does not exist`);this.sudoers.add(e),await this.persist()}async removeSudoer(e){if(J.mark("removeSudoer"),this.validateUsername(e),e==="root")throw new Error("sudoers: cannot remove root");this.sudoers.delete(e),await this.persist()}registerSession(e,n){J.mark("registerSession");let i={id:$i(),username:e,tty:`pts/${this.nextTty++}`,remoteAddress:n,startedAt:new Date().toISOString()};return this.activeSessions.set(i.id,i),this.emit("session:register",{sessionId:i.id,username:e,remoteAddress:n}),i}unregisterSession(e){if(J.mark("unregisterSession"),!e)return;let n=this.activeSessions.get(e);this.activeSessions.delete(e),n&&this.emit("session:unregister",{sessionId:e,username:n.username}),this.activeSessions.delete(e)}updateSession(e,n,i){if(J.mark("updateSession"),!e)return;let s=this.activeSessions.get(e);s&&this.activeSessions.set(e,{...s,username:n,remoteAddress:i})}listActiveSessions(){return J.mark("listActiveSessions"),Array.from(this.activeSessions.values()).sort((e,n)=>e.startedAt.localeCompare(n.startedAt))}listUsers(){return Array.from(this.users.keys()).sort()}loadFromVfs(){if(this.users.clear(),!this.vfs.exists(this.usersPath))return;let e=this.vfs.readFile(this.usersPath);for(let n of e.split(`
436
+ `)){let i=n.trim();if(i.length===0)continue;let s=i.split(":");if(s.length<3)continue;let[o,a,l]=s;!o||!a||!l||this.users.set(o,{username:o,salt:a,passwordHash:l})}}loadSudoersFromVfs(){if(this.sudoers.clear(),!this.vfs.exists(this.sudoersPath))return;let e=this.vfs.readFile(this.sudoersPath);for(let n of e.split(`
437
+ `)){let i=n.trim();i.length>0&&this.sudoers.add(i)}}loadQuotasFromVfs(){if(this.quotas.clear(),!this.vfs.exists(this.quotasPath))return;let e=this.vfs.readFile(this.quotasPath);for(let n of e.split(`
438
+ `)){let i=n.trim();if(i.length===0)continue;let[s,o]=i.split(":"),a=Number.parseInt(o??"",10);!s||!Number.isFinite(a)||a<0||this.quotas.set(s,a)}}async persist(){this.vfs.exists(this.authDirPath)||this.vfs.mkdir(this.authDirPath,448);let e=Array.from(this.users.values()).sort((o,a)=>o.username.localeCompare(a.username)).map(o=>[o.username,o.salt,o.passwordHash].join(":")).join(`
439
+ `),n=Array.from(this.sudoers.values()).sort().join(`
440
+ `),i=Array.from(this.quotas.entries()).sort(([o],[a])=>o.localeCompare(a)).map(([o,a])=>`${o}:${a}`).join(`
441
+ `),s=!1;s=this.writeIfChanged(this.usersPath,e.length>0?`${e}
442
+ `:"",384)||s,s=this.writeIfChanged(this.sudoersPath,n.length>0?`${n}
443
+ `:"",384)||s,s=this.writeIfChanged(this.quotasPath,i.length>0?`${i}
444
+ `:"",384)||s,s&&await this.vfs.flushMirror()}writeIfChanged(e,n,i){return this.vfs.exists(e)&&this.vfs.readFile(e)===n?(this.vfs.chmod(e,i),!1):(this.vfs.writeFile(e,n,{mode:i}),!0)}createRecord(e,n){let i=`${e}:${n}`,s=r.recordCache.get(i);if(s)return s;let o=Ci(16).toString("hex"),a={username:e,salt:o,passwordHash:this.hashPassword(n)};return r.recordCache.set(i,a),a}hasPassword(e){if(J.mark("hasPassword"),this.getPasswordHash(e)===this.hashPassword(""))return!1;let n=this.users.get(e);return!!n&&!!n.passwordHash}hashPassword(e){return r.fastPasswordHash?vi("sha256").update(`${e}`).digest("hex"):Pi(e,"",32).toString("hex")}validateUsername(e){if(!e||e.trim()==="")throw new Error("invalid username");if(!/^[a-z_][a-z0-9_-]{0,31}$/i.test(e))throw new Error("invalid username")}validatePassword(e){if(!e||e.trim()==="")throw new Error("invalid password")}authorizedKeys=new Map;addAuthorizedKey(e,n,i){J.mark("addAuthorizedKey");let s=this.authorizedKeys.get(e)??[];s.push({algo:n,data:i}),this.authorizedKeys.set(e,s),this.emit("key:add",{username:e,algo:n})}removeAuthorizedKeys(e){this.authorizedKeys.delete(e),this.emit("key:remove",{username:e})}getAuthorizedKeys(e){return this.authorizedKeys.get(e)??[]}};function ts(r){let t=es.posix.normalize(r);return t.startsWith("/")?t:`/${t}`}import{readFile as Fi,unlink as Ni,writeFile as Ii}from"node:fs/promises";import*as Ee from"node:path";import{spawn as Ai}from"node:child_process";import{readFile as Ei}from"node:fs/promises";import*as ie from"node:path";function Me(r){return`'${r.replace(/'/g,"'\\''")}'`}function Dt(r){return r.replace(/\r\n/g,`
445
+ `).replace(/\r/g,`
446
+ `).replace(/\n/g,`\r
447
+ `)}function rs(r,t){let e=Number.isFinite(t.cols)&&t.cols>0?Math.floor(t.cols):80,n=Number.isFinite(t.rows)&&t.rows>0?Math.floor(t.rows):24;return`stty cols ${e} rows ${n} 2>/dev/null; ${r}`}function ns(r,t){return!t||t.trim()===""||t==="."?r:t.startsWith("/")?ie.posix.normalize(t):ie.posix.normalize(ie.posix.join(r,t))}async function ss(r){try{let e=(await Ei(`/proc/${r}/task/${r}/children`,"utf8")).trim().split(/\s+/).filter(Boolean).map(i=>Number.parseInt(i,10)).filter(i=>Number.isInteger(i)&&i>0),n=await Promise.all(e.map(i=>ss(i)));return[...e,...n.flat()]}catch{return[]}}async function is(r=process.pid){let t=await ss(r),e=Array.from(new Set(t)).sort((n,i)=>n-i);return e.length===0?null:e.join(",")}function os(r,t,e){let n=rs(r,t),i=Ai("script",["-qfec",n,"/dev/null"],{stdio:["pipe","pipe","pipe"],env:{...process.env,TERM:process.env.TERM??"xterm-256color"}});return i.stdout.on("data",s=>{e.write(s.toString("utf8"))}),i.stderr.on("data",s=>{e.write(s.toString("utf8"))}),i}function as(r,t,e){return os(`nano -- ${Me(r)}`,t,e)}function ls(r,t,e){return os(`htop -p ${Me(r)}`,t,e)}function cs(r,t,e,n,i,s="unknown",o={cols:80,rows:24},a){let l="",c=0,u=Vi(a.vfs),d=null,m="",f=`/home/${e}`,x=kt(e,n),g=null,y=null,$=()=>{let C=`/home/${e}`,A=f===C?"~":Ee.posix.basename(f)||"/";return Xt(e,n,A)},V=Array.from(new Set(xe())).sort();console.log(`[${i}] Shell started for user '${e}' at ${s}`),(async()=>{let C=`/home/${e}/.bashrc`;if(a.vfs.exists(C))try{let A=a.vfs.readFile(C);for(let _ of A.split(`
448
+ `)){let F=_.trim();!F||F.startsWith("#")||await Z(F,e,n,"shell",f,a,void 0,x)}}catch{}})();function k(){let C=$();t.write(`\r${C}${l}\x1B[K`);let A=l.length-c;A>0&&t.write(`\x1B[${A}D`)}function R(){t.write("\r\x1B[K")}function D(C){y={...C,buffer:""},R(),t.write(C.prompt)}async function tt(C){if(!y)return;let A=y;if(y=null,!C){t.write(`\r
449
+ Sorry, try again.\r
450
+ `),k();return}if(!A.commandLine){e=A.targetUser,f=`/home/${e}`,a.users.updateSession(i,e,s),t.write(`\r
451
+ `),k();return}let _=A.loginShell?`/home/${A.targetUser}`:f,F=await Promise.resolve(Z(A.commandLine,A.targetUser,n,"shell",_,a));if(t.write(`\r
452
+ `),F.openEditor){await E(F.openEditor.targetPath,F.openEditor.initialContent,F.openEditor.tempPath);return}if(F.openHtop){await T();return}F.clearScreen&&t.write("\x1B[2J\x1B[H"),F.stdout&&t.write(`${Dt(F.stdout)}\r
453
+ `),F.stderr&&t.write(`${Dt(F.stderr)}\r
454
+ `),F.switchUser?(e=F.switchUser,f=F.nextCwd??`/home/${e}`,a.users.updateSession(i,e,s)):F.nextCwd&&(f=F.nextCwd),await a.vfs.flushMirror(),k()}async function w(){if(!g)return;let C=g;if(C.kind==="nano"){try{let A=await Fi(C.tempPath,"utf8");a.writeFileAsUser(e,C.targetPath,A),await a.vfs.flushMirror()}catch{}await Ni(C.tempPath).catch(()=>{})}g=null,l="",c=0,t.write(`\r
455
+ `),k()}async function E(C,A,_){a.vfs.exists(C)&&await Ii(_,A,"utf8");let F=as(_,o,t);F.on("error",Y=>{t.write(`nano: ${Y.message}\r
456
+ `),w()}),F.on("close",()=>{w()}),g={kind:"nano",targetPath:C,tempPath:_,process:F}}async function T(){let C=await is();if(!C){t.write(`htop: no child_process processes to display\r
457
+ `);return}let A=ls(C,o,t);A.on("error",_=>{t.write(`htop: ${_.message}\r
458
+ `),w()}),A.on("close",()=>{w()}),g={kind:"htop",targetPath:"",tempPath:"",process:A}}function b(C){l=C,c=l.length,k()}function P(C){l=`${l.slice(0,c)}${C}${l.slice(c)}`,c+=C.length,k()}function I(C,A){let _=A;for(;_>0&&!/\s/.test(C[_-1]);)_-=1;let F=A;for(;F<C.length&&!/\s/.test(C[F]);)F+=1;return{start:_,end:F}}function H(C){let A=C.lastIndexOf("/"),_=A>=0?C.slice(0,A+1):"",F=A>=0?C.slice(A+1):C,Y=ns(f,_||".");try{return a.vfs.list(Y).filter(L=>!L.startsWith(".")).filter(L=>L.startsWith(F)).map(L=>{let at=Ee.posix.join(Y,L),Ot=a.vfs.stat(at).type==="directory"?"/":"";return`${_}${L}${Ot}`}).sort()}catch{return[]}}function z(){let{start:C,end:A}=I(l,c),_=l.slice(C,c);if(_.length===0)return;let Y=l.slice(0,C).trim().length===0?V.filter(wt=>wt.startsWith(_)):[],L=H(_),at=Array.from(new Set([...Y,...L])).sort();if(at.length!==0){if(at.length===1){let wt=at[0],Ot=wt.endsWith("/")?"":" ";l=`${l.slice(0,C)}${wt}${Ot}${l.slice(A)}`,c=C+wt.length+Ot.length,k();return}t.write(`\r
459
+ `),t.write(`${at.join(" ")}\r
460
+ `),k()}}function q(C){if(C.length===0)return;u.push(C),u.length>500&&(u=u.slice(u.length-500));let A=u.length>0?`${u.join(`
461
+ `)}
462
+ `:"";a.vfs.writeFile("/virtual-env-js/.bash_history",A)}function ft(){let C=`/virtual-env-js/.lastlog/${e}.json`;if(!a.vfs.exists(C))return null;try{return JSON.parse(a.vfs.readFile(C))}catch{return null}}function ot(C){let A="/virtual-env-js/.lastlog";a.vfs.exists(A)||a.vfs.mkdir(A,448);let _=`${A}/${e}.json`;a.vfs.writeFile(_,JSON.stringify({at:C,from:s}))}function ht(){let C=ft(),A=new Date().toISOString();t.write(Qt(n,r,C)),ot(A)}ht(),k(),t.on("data",async C=>{if(g){g.process.stdin.write(C);return}if(y){let _=C.toString("utf8");for(let F=0;F<_.length;F+=1){let Y=_[F];if(Y===""){y=null,t.write(`^C\r
463
+ `),k();return}if(Y==="\x7F"||Y==="\b"){y.buffer=y.buffer.slice(0,-1);continue}if(Y==="\r"||Y===`
464
+ `){let L=y.buffer;y.buffer="";let at=a.users.verifyPassword(y.username,L);await tt(at);return}Y>=" "&&(y.buffer+=Y)}return}let A=C.toString("utf8");for(let _=0;_<A.length;_+=1){let F=A[_];if(F===""){l="",c=0,d=null,m="",t.write(`bye\r
465
+ `),q("bye"),await a.vfs.flushMirror(),t.write(`logout\r
466
+ `),t.exit(0),t.end();return}if(F===" "){z();continue}if(F==="\x1B"){let Y=A[_+1],L=A[_+2],at=A[_+3];if(Y==="["&&L){if(L==="A"){_+=2,u.length>0&&(d===null?(m=l,d=u.length-1):d>0&&(d-=1),b(u[d]??""));continue}if(L==="B"){_+=2,d!==null&&(d<u.length-1?(d+=1,b(u[d]??"")):(d=null,b(m)));continue}if(L==="C"){_+=2,c<l.length&&(c+=1,t.write("\x1B[C"));continue}if(L==="D"){_+=2,c>0&&(c-=1,t.write("\x1B[D"));continue}if(L==="3"&&at==="~"){_+=3,c<l.length&&(l=`${l.slice(0,c)}${l.slice(c+1)}`,k());continue}}}if(F===""){l="",c=0,d=null,m="",t.write(`^C\r
467
+ `),k();continue}if(F==="\r"||F===`
468
+ `){let Y=l.trim();if(l="",c=0,d=null,m="",t.write(`\r
469
+ `),Y.length>0){let L=await Promise.resolve(Z(Y,e,n,"shell",f,a,void 0,x));if(q(Y),L.openEditor){await E(L.openEditor.targetPath,L.openEditor.initialContent,L.openEditor.tempPath);return}if(L.openHtop){await T();return}if(L.sudoChallenge){D(L.sudoChallenge);return}if(L.clearScreen&&t.write("\x1B[2J\x1B[H"),L.stdout&&t.write(`${Dt(L.stdout)}\r
470
+ `),L.stderr&&t.write(`${Dt(L.stderr)}\r
471
+ `),L.closeSession){t.write(`logout\r
472
+ `),t.exit(L.exitCode??0),t.end();return}L.nextCwd&&(f=L.nextCwd),L.switchUser&&(e=L.switchUser,f=L.nextCwd??`/home/${e}`,a.users.updateSession(i,e,s),l="",c=0),await a.vfs.flushMirror()}k();continue}if(F==="\x7F"||F==="\b"){c>0&&(l=`${l.slice(0,c-1)}${l.slice(c)}`,c-=1,k());continue}P(F)}}),t.on("close",()=>{g&&(g.process.kill("SIGTERM"),g=null)})}function Vi(r){let t="/virtual-env-js/.bash_history";return r.exists(t)?r.readFile(t).split(`
473
+ `).map(n=>n.trim()).filter(n=>n.length>0):(r.writeFile(t,""),[])}function Di(r){return typeof r=="object"&&r!==null&&"vfsInstance"in r&&us(r.vfsInstance)}function us(r){if(typeof r!="object"||r===null)return!1;let t=r;return typeof t.restoreMirror=="function"&&typeof t.flushMirror=="function"&&typeof t.writeFile=="function"&&typeof t.readFile=="function"&&typeof t.mkdir=="function"&&typeof t.exists=="function"&&typeof t.stat=="function"&&typeof t.list=="function"&&typeof t.remove=="function"&&typeof t.copy=="function"&&typeof t.move=="function"&&typeof t.touch=="function"}var _i={kernel:"1.0.0+itsrealfortune+1-amd64",os:"Fortune GNU/Linux x64",arch:"x86_64"},_t=ee("VirtualShell");function Li(){let r=process.env.SSH_MIMIC_AUTO_SUDO_NEW_USERS;return r?!["0","false","no","off"].includes(r.toLowerCase()):!0}var oe=class extends Ri{vfs;users;packageManager;hostname;properties;startTime;initialized;constructor(t,e,n){super(),_t.mark("constructor"),this.hostname=t,this.properties=e||_i,this.startTime=Date.now(),us(n)?this.vfs=n:Di(n)?this.vfs=n.vfsInstance:this.vfs=new Xn(n??{}),this.users=new se(this.vfs,Li()),this.packageManager=new ne(this.vfs,this.users);let i=this.vfs,s=this.users,o=this.packageManager,a=this.properties,l=this.hostname,c=this.startTime;this.initialized=(async()=>{await i.restoreMirror(),await s.initialize(),Un(i,s,l,a,c),o.load(),this.emit("initialized")})()}async ensureInitialized(){_t.mark("ensureInitialized"),await this.initialized}addCommand(t,e,n){let i=t.trim().toLowerCase();if(i.length===0||/\s/.test(i))throw new Error("Command name must be non-empty and contain no spaces");ye(Se(i,e,n))}executeCommand(t,e,n){_t.mark("executeCommand"),Z(t,e,this.hostname,"shell",n,this),this.emit("command",{command:t,user:e,cwd:n})}startInteractiveSession(t,e,n,i,s){_t.mark("startInteractiveSession"),this.emit("session:start",{user:e,sessionId:n,remoteAddress:i}),cs(this.properties,t,e,this.hostname,n,i,s,this),this.refreshProcSessions()}refreshProcFs(){te(this.vfs,this.properties,this.hostname,this.startTime,this.users.listActiveSessions())}refreshProcSessions(){te(this.vfs,this.properties,this.hostname,this.startTime,this.users.listActiveSessions())}syncPasswd(){be(this.vfs,this.users)}getVfs(){return this?.vfs??null}getUsers(){return this?.users??null}getHostname(){return this?.hostname}writeFileAsUser(t,e,n){_t.mark("writeFileAsUser"),this.users.assertWriteWithinQuota(t,e,n),this.vfs.writeFile(e,n)}};var Tt=process.env.SSH_MIMIC_HOSTNAME??"typescript-vm",Ae=process.argv.slice(2);function Bi(){for(let r=0;r<Ae.length;r+=1){let t=Ae[r];if(t==="--user"){let e=Ae[r+1];if(!e||e.startsWith("--"))throw new Error("self-standalone: --user requires a value");return e}if(t?.startsWith("--user="))return t.slice(7)||"root"}return"root"}var Ui=Bi(),st=new oe(Tt,void 0,{mode:"fs",snapshotPath:".vfs"});function ji(r){let t=`/virtual-env-js/.lastlog/${r}.json`;if(!st.vfs.exists(t))return null;try{return JSON.parse(st.vfs.readFile(t))}catch{return null}}function Wi(r,t){return new Promise(e=>{r.question(t,e)})}function Hi(r,t){let e="/virtual-env-js/.lastlog";st.vfs.exists(e)||st.vfs.mkdir(e,448),st.vfs.writeFile(`/virtual-env-js/.lastlog/${r}.json`,JSON.stringify({at:new Date().toISOString(),from:t}))}st.addCommand("demo",[],()=>({stdout:"This is a demo command. It does nothing useful.",exitCode:0}));async function qi(){let r=zi({input:Oi,output:Lt,terminal:!0});await st.ensureInitialized();let t=Ui.trim()||"root";st.users.getPasswordHash(t)!==null||(process.stderr.write(`self-standalone: user '${t}' does not exist
474
+ `),process.exit(1));let n=kt(t,Tt),i=t,s=`/home/${i}`;n.vars.PWD=s;let o="localhost";if(process.env.USER!=="root"&&st.users.hasPassword(i)){let c=await Wi(r,`Password for ${i}: `);st.users.verifyPassword(i,c)||(process.stderr.write(`self-standalone: authentication failed
475
+ `),process.exit(1))}let a=()=>{let c=s===`/home/${i}`?"~":Ti(s)||"/";return Xt(i,Tt,c)},l=()=>{r.setPrompt(a()),r.prompt()};for(r.on("SIGINT",()=>{Lt.write(`^C
476
+ `),r.write("",{ctrl:!0,name:"u"}),l()}),r.on("close",()=>{console.log(""),process.exit(0)}),Lt.write(Qt(Tt,st.properties,ji(i))),Hi(i,o),l();;){let c=await new Promise(d=>{r.once("line",m=>d(m))});r.pause();let u=await Z(c,i,Tt,"shell",s,st,void 0,n);u.stdout&&Lt.write(u.stdout.endsWith(`
477
+ `)?u.stdout:`${u.stdout}
478
+ `),u.stderr&&process.stderr.write(u.stderr.endsWith(`
479
+ `)?u.stderr:`${u.stderr}
480
+ `),u.clearScreen&&Lt.write("\x1B[2J\x1B[H"),u.switchUser?(i=u.switchUser,s=u.nextCwd??`/home/${i}`,n.vars.USER=i,n.vars.LOGNAME=i,n.vars.HOME=`/home/${i}`,n.vars.PWD=s):u.nextCwd&&(s=u.nextCwd,n.vars.PWD=s),u.closeSession&&(r.close(),process.exit(u.exitCode??0)),l(),r.resume()}}qi().catch(r=>{console.error("Failed to start readline SSH emulation:",r),process.exit(1)});process.on("uncaughtException",r=>{console.log("Oh my god, something terrible happened: ",r)});process.on("unhandledRejection",(r,t)=>{console.log(" Oh Lord! We forgot to handle a promise rejection here: ",t),console.log(" The error was: ",r)});
481
+ //# sourceMappingURL=self-standalone.js.map