├── .github └── workflows │ └── claude.yml ├── .gitignore ├── .stignore ├── LICENSE ├── README.md ├── config ├── commands.js ├── fs.js ├── help.js ├── jobs.js ├── portfolio.js └── team.js ├── css ├── bootstrap.css └── styles.css ├── favicon.png ├── images ├── adept.jpg ├── allspice.jpg ├── aperture.jpg ├── aperturedata.jpg ├── apolloshield.jpg ├── avidan.png ├── ben.png ├── breakpoint.jpg ├── cady.jpg ├── cape.jpg ├── chargelab.jpg ├── chrissy.png ├── cloudastructure.jpg ├── coral.jpg ├── creator.jpg ├── crux.jpg ├── daily.jpg ├── determinate.jpg ├── dusty.jpg ├── esper.jpg ├── fudge.jpg ├── genalpha.jpg ├── geo │ ├── avidan2.jpg │ ├── banana.gif │ ├── ben2.jpg │ ├── chrissy2.jpg │ ├── construction.gif │ ├── counter.gif │ ├── counter2.gif │ ├── divider.gif │ ├── divider1.gif │ ├── divider2.gif │ ├── divider3.gif │ ├── divider4.gif │ ├── emily2.jpg │ ├── flames.gif │ ├── geocities.jpg │ ├── hacker.gif │ ├── ie_logo.gif │ ├── kane2.jpg │ ├── laelah2.jpg │ ├── lee2.jpg │ ├── mchammer.gif │ ├── microfab.gif │ ├── new.gif │ ├── new2.gif │ ├── notepad.gif │ ├── ns_logo.gif │ ├── progress.gif │ ├── rainbow.gif │ ├── share.png │ ├── stars.gif │ ├── underconstruction.gif │ └── zodi2.jpg ├── hash.jpg ├── hunch.jpg ├── iasql.jpg ├── illoca.jpg ├── instance.jpg ├── instrumental.jpg ├── integrated.jpg ├── kane.png ├── kayhan.jpg ├── kodra.jpg ├── laelah.png ├── latent.jpg ├── lee.png ├── logo.png ├── loom.jpg ├── mashgin.jpg ├── meroxa.jpg ├── mimeo.jpg ├── nautilus.jpg ├── nordsense.jpg ├── ntopology.jpg ├── nullify.jpg ├── og-image.png ├── okteto.jpg ├── oma_fertility.jpg ├── particle.jpg ├── patterns.jpg ├── plethora.jpg ├── privacy_dynamics.jpg ├── prynt.jpg ├── quilter.jpg ├── radical.jpg ├── righthook.jpg ├── rootvc-square.png ├── ruby.jpg ├── seam.jpg ├── seismic.jpg ├── sensable.jpg ├── shaper.jpg ├── sixwheel.jpg ├── skycatch.jpg ├── stellar.jpg ├── sublayer.jpg ├── subtrace.jpg ├── superconductive.jpg ├── supertokens.jpg ├── thread.jpg ├── thruwave.jpg ├── topologic.jpg ├── tortuga.jpg ├── trieve.jpg ├── trucklabs.jpg ├── versatile.jpg ├── wildtype.jpg ├── zed.jpg └── zodi.png ├── index.html ├── js ├── aalib.js.map ├── ascii-art.js ├── comcastify.js ├── geo.js ├── terminal-ext.js ├── terminal.js ├── xterm-addon-fit.js.map ├── xterm-addon-web-links.js.map └── xterm.js.map ├── package-lock.json ├── package.json └── welcome.htm /.github/workflows/claude.yml: -------------------------------------------------------------------------------- 1 | name: Claude PR Assistant 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | pull_request_review_comment: 7 | types: [created] 8 | issues: 9 | types: [opened, assigned] 10 | pull_request_review: 11 | types: [submitted] 12 | 13 | jobs: 14 | claude-code-action: 15 | if: | 16 | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || 17 | (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || 18 | (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || 19 | (github.event_name == 'issues' && contains(github.event.issue.body, '@claude')) 20 | runs-on: ubuntu-latest 21 | permissions: 22 | contents: read 23 | pull-requests: read 24 | issues: read 25 | id-token: write 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v4 29 | with: 30 | fetch-depth: 1 31 | 32 | - name: Run Claude PR Action 33 | uses: anthropics/claude-code-action@beta 34 | with: 35 | anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} 36 | timeout_minutes: "60" 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # for build 2 | css/xterm.css 3 | js/xterm*.js* 4 | js/aalib.js* 5 | 6 | images/*Zone.Identifier 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | lerna-debug.log* 15 | 16 | # Diagnostic reports (https://nodejs.org/api/report.html) 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | *.lcov 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (https://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | jspm_packages/ 50 | 51 | # TypeScript v1 declaration files 52 | typings/ 53 | 54 | # TypeScript cache 55 | *.tsbuildinfo 56 | 57 | # Optional npm cache directory 58 | .npm 59 | 60 | # Optional eslint cache 61 | .eslintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variables file 79 | .env 80 | .env.test 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | 85 | # Next.js build output 86 | .next 87 | 88 | # Nuxt.js build / generate output 89 | .nuxt 90 | dist 91 | 92 | # Gatsby files 93 | .cache/ 94 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 95 | # https://nextjs.org/blog/next-9-1#public-directory-support 96 | # public 97 | 98 | # vuepress build output 99 | .vuepress/dist 100 | 101 | # Serverless directories 102 | .serverless/ 103 | 104 | # FuseBox cache 105 | .fusebox/ 106 | 107 | # DynamoDB Local files 108 | .dynamodb/ 109 | 110 | # TernJS port file 111 | .tern-port 112 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 113 | 114 | # dependencies 115 | /node_modules 116 | /.pnp 117 | .pnp.js 118 | 119 | # testing 120 | /coverage 121 | 122 | # production 123 | /build 124 | 125 | # misc 126 | .DS_Store 127 | .env.local 128 | .env.development.local 129 | .env.test.local 130 | .env.production.local 131 | 132 | npm-debug.log* 133 | yarn-debug.log* 134 | yarn-error.log* 135 | 136 | .vscode/settings.json 137 | 138 | # Local Netlify folder 139 | .netlify 140 | 141 | .DS_Store 142 | **/.DS_Store 143 | -------------------------------------------------------------------------------- /.stignore: -------------------------------------------------------------------------------- 1 | .git 2 | # Runtime data 3 | pids 4 | *.pid 5 | *.seed 6 | *.pid.lock 7 | 8 | # Directory for instrumented libs generated by jscoverage/JSCover 9 | lib-cov 10 | 11 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 12 | .grunt 13 | 14 | # Bower dependency directory (https://bower.io/) 15 | bower_components 16 | 17 | # node-waf configuration 18 | .lock-wscript 19 | 20 | # Compiled binary addons (https://nodejs.org/api/addons.html) 21 | build/Release 22 | 23 | # Dependency directories 24 | node_modules 25 | jspm_packages 26 | 27 | # Optional npm cache directory 28 | .npm 29 | 30 | # Optional eslint cache 31 | .eslintcache 32 | 33 | # Optional REPL history 34 | .node_repl_history 35 | 36 | # Output of 'npm pack' 37 | *.tgz 38 | 39 | # Yarn Integrity file 40 | .yarn-integrity 41 | 42 | # parcel-bundler cache (https://parceljs.org/) 43 | .cache 44 | 45 | # next.js build output 46 | .next 47 | 48 | # nuxt.js build output 49 | .nuxt 50 | 51 | # vuepress build output 52 | .vuepress/dist 53 | 54 | # Serverless directories 55 | .serverless 56 | 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License With Custom Attribution Condition 2 | 3 | Copyright (c) 2025 Root Ventures 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | > You must give Root Ventures a shoutout on at least one (1) of: LinkedIn, X, 13 | podcast interview, television news interview, your next Annual General Meeting, 14 | or OnlyFans. 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cli-website 2 | Who needs a website when you have a terminal. 3 | 4 | [![Netlify Status](https://api.netlify.com/api/v1/badges/f3bfb854-9bc6-40a7-8d4c-2cccd3850764/deploy-status)](https://app.netlify.com/sites/rootvc-cli-website/deploys) 5 | 6 | ## Basic Commands 7 | - help: list all commands 8 | - whois root: learn about us 9 | - whois [partner]: learn about a partner 10 | - tldr: list all portfolio companies 11 | - tldr: [company_name]": learn about a portfolio company 12 | - email: reach out to us 13 | - twitter: twitter accounts 14 | - instagram: instagram account 15 | - git: this repo 16 | - github: all repos 17 | - test: do not use 18 | - other: try your favorite linux commands 19 | 20 | ## Advanced Commands 21 | - alias 22 | - cat 23 | - cd 24 | - chmod 25 | - chown 26 | - clear 27 | - cp 28 | - curl 29 | - df 30 | - echo 31 | - emacs 32 | - exit 33 | - fdisk 34 | - find 35 | - finger 36 | - free 37 | - ftp 38 | - grep 39 | - groups 40 | - gzip 41 | - head 42 | - history 43 | - kill 44 | - less 45 | - ls 46 | - man (alias: woman) 47 | - mkdir 48 | - more 49 | - mv 50 | - nano 51 | - open 52 | - passwd 53 | - pico 54 | - pine 55 | - ps 56 | - pwd 57 | - quit 58 | - rm 59 | - say 60 | - sftp 61 | - ssh 62 | - stop 63 | - su 64 | - sudo 65 | - tail 66 | - top 67 | - touch 68 | - uname 69 | - vi 70 | - vim 71 | - zsh 72 | 73 | Missing a favorite one? Make a PR! 74 | 75 | ## Portfolio CLIs 76 | Future project: get the Hello Worlds working for every portfolio company with a CLI or npm/pypi/cargo package 77 | - esper 78 | - great_expectations (alias: ge) 79 | - meroxa 80 | - okteto 81 | - particle 82 | - privacy_dynamics (alias: privacy) 83 | - zed 84 | 85 | Live at: [https://root.vc](https://root.vc). 86 | 87 | Special thanks to [Jerry Neumann](https://www.linkedin.com/in/jerryneumann/) at [Neu Venture Capital](https://neuvc.com/) for the inspiration for this website concept. 88 | 89 | Thanks to the team at [divshot](https://www.divshot.com) for the awesome and hilarious [Geocities Bootstrap Theme](https://github.com/divshot/geo-bootstrap). 90 | 91 | _aut viam inveniam aut faciam_ 92 | -------------------------------------------------------------------------------- /config/commands.js: -------------------------------------------------------------------------------- 1 | const whoisRoot = "Root Ventures is a San Francisco-based deep tech seed fund. As engineers ourselves, we specialize in leading initial funding for founders tackling new technical opportunities. Our initial investments typically range from $2-3M. With a selective few new deals a year and 2/3 of our funds in reserve, we are committed to being a long-term partner. Try %whois% and one of avidan, kane, chrissy, lee, ben, zodi, or laelah to learn more about our team."; 2 | const timeUnit = 1000; // useful for development, set to 10 to run faster, set to 1000 for production 3 | let killed = false; 4 | 5 | const commands = { 6 | help: function() { 7 | const maxCmdLength = Math.max(...Object.keys(help).map(x => x.length)); 8 | Object.entries(help).forEach(function(kv) { 9 | const cmd = kv[0]; 10 | const desc = kv[1]; 11 | if (term.cols >= 80) { 12 | const rightPad = maxCmdLength - cmd.length + 2; 13 | const sep = " ".repeat(rightPad); 14 | term.stylePrint(`${cmd}${sep}${desc}`); 15 | } else { 16 | if (cmd != 'help') { // skip second leading newline 17 | term.writeln(""); 18 | } 19 | term.stylePrint(cmd); 20 | term.stylePrint(desc); 21 | } 22 | }) 23 | }, 24 | 25 | whois: function(args) { 26 | const name = args[0]; 27 | const people = Object.keys(team); 28 | 29 | if (!name) { 30 | term.stylePrint("%whois%: Learn about the firm, or a partner - usage:\r\n"); 31 | term.stylePrint("%whois% root"); 32 | for (p of people) { 33 | term.stylePrint(`%whois% ${p}`); 34 | } 35 | } else if (name == "root") { 36 | const description = whoisRoot; 37 | term.printArt("rootvc-square"); 38 | term.stylePrint(description); 39 | } else if (Object.keys(team).includes(name)) { 40 | const person = team[name]; 41 | term.printArt(name); 42 | term.stylePrint(`\r\n${person["name"]}, ${person["title"]} - ${name}@root.vc`); 43 | term.stylePrint(`${person["linkedin"]}\r\n`); 44 | term.stylePrint(person["description"]); 45 | } else { 46 | term.stylePrint(`User ${name || ''} not found. Try:\r\n`); 47 | term.stylePrint("%whois% root"); 48 | for (p of people) { 49 | term.stylePrint(`%whois% ${p}`); 50 | } 51 | } 52 | }, 53 | 54 | tldr: function(args) { 55 | const name = (args[0] || ""); 56 | if (!name) { 57 | const companies = Object.keys(portfolio); 58 | term.stylePrint("%tldr%: Learn about a portfolio company - usage:\r\n"); 59 | for (c of companies.sort()) { 60 | const data = portfolio[c]; 61 | const tabs = c.length > 10 ? "\t" : "\t\t"; 62 | const sep = term.cols >= 76 ? tabs : "\r\n"; 63 | term.stylePrint(`%tldr% ${c}${sep}${data["url"]}`); 64 | if (term.cols < 76 && c != companies[companies.length - 1]) { 65 | term.writeln(""); 66 | } 67 | } 68 | } else if (!portfolio[name]) { 69 | term.stylePrint(`Portfolio company ${name} not found. Should we talk to them? Email us: hello@root.vc`); 70 | } else { 71 | const company = portfolio[name]; 72 | term.cols >= 60 ? term.printArt(name) : term.writeln(""); 73 | term.stylePrint(company["name"]); 74 | term.stylePrint(company["url"]); 75 | if (company["memo"]) { 76 | term.stylePrint(`Investment Memo: ${company["memo"]}`); 77 | } 78 | term.stylePrint(""); 79 | term.stylePrint(company["description"]); 80 | if (company["demo"]) { 81 | term.stylePrint(`Try it with command: %${name}%`); 82 | } 83 | } 84 | }, 85 | 86 | git: function() { 87 | term.displayURL("https://github.com/rootvc/cli-website"); 88 | }, 89 | 90 | agm: function() { 91 | term.openURL("http://annualmeeting.root.vc"); 92 | }, 93 | 94 | test: function() { 95 | term.openURL("https://i.imgur.com/Q2Unw.gif"); 96 | }, 97 | 98 | email: function() { 99 | term.command("pine"); 100 | }, 101 | 102 | github: function() { 103 | term.displayURL("https://github.com/rootvc"); 104 | }, 105 | 106 | twitter: function() { 107 | term.displayURL("https://twitter.com/rootvc"); 108 | term.displayURL("https://twitter.com/machinepix"); 109 | }, 110 | 111 | instagram: function() { 112 | term.displayURL("https://instagram.com/machinepix/"); 113 | }, 114 | 115 | insta: function() { 116 | term.command("instagram"); 117 | }, 118 | 119 | other: function() { 120 | term.stylePrint("Yeah, I didn't literally mean %other%. I mean try some Linux commands"); 121 | }, 122 | 123 | echo: function(args) { 124 | const message = args.join(" "); 125 | term.stylePrint(message); 126 | }, 127 | 128 | say: function(args) { 129 | const message = args.join(" "); 130 | term.stylePrint(`(Robot voice): ${message}`); 131 | }, 132 | 133 | pwd: function() { 134 | term.stylePrint("/" + term.cwd.replaceAll("~", `home/${term.user}`)); 135 | }, 136 | 137 | ls: function() { 138 | term.stylePrint(_filesHere().join(" ")); 139 | }, 140 | 141 | // I am so, so sorry for this code. 142 | cd: function(args) { 143 | let dir = args[0] || "~"; 144 | if (dir != "/") { 145 | // strip trailing slash 146 | dir = dir.replace(/\/$/, ""); 147 | } 148 | 149 | switch (dir) { 150 | case "~": 151 | term.cwd = "~"; 152 | break; 153 | case "..": 154 | if (term.cwd == "~") { 155 | term.command("cd /home"); 156 | } else if (["home", "bin"].includes(term.cwd)) { 157 | term.command("cd /"); 158 | } 159 | break; 160 | case "../..": 161 | case "../../..": 162 | case "../../../..": 163 | case "/": 164 | term.cwd = "/"; 165 | break; 166 | case "home": 167 | if (term.cwd == "/") { 168 | term.command("cd /home"); 169 | } else { 170 | term.stylePrint(`You do not have permission to access this directory`); 171 | } 172 | break; 173 | case "/home": 174 | term.cwd = "home"; 175 | break; 176 | case "guest": 177 | case "root": 178 | if (term.cwd == "home") { 179 | if (term.user == dir) { 180 | term.command("cd ~"); 181 | } else { 182 | term.stylePrint(`You do not have permission to access this directory`); 183 | } 184 | } else { 185 | term.stylePrint(`No such directory: ${dir}`); 186 | } 187 | break; 188 | case "../home/avidan": 189 | case "../home/kane": 190 | case "../home/chrissy": 191 | case "../home/lee": 192 | case "../home/zodi": 193 | case "../home/ben": 194 | case "../home/laelah": 195 | if (term.cwd == "~" || term.cwd == "bin") { 196 | term.command(`cd ${dir.split("/")[2]}`); 197 | } else { 198 | term.stylePrint(`No such directory: ${dir}`); 199 | } 200 | break; 201 | case "/home/avidan": 202 | case "/home/kane": 203 | case "/home/chrissy": 204 | case "/home/lee": 205 | case "/home/zodi": 206 | case "/home/ben": 207 | case "/home/laelah": 208 | case "avidan": 209 | case "kane": 210 | case "chrissy": 211 | case "lee": 212 | case "zodi": 213 | case "ben": 214 | case "laelah": 215 | term.stylePrint(`You do not have permission to access this directory`); 216 | break; 217 | case "/bin": 218 | term.cwd = "bin"; 219 | break; 220 | case "bin": 221 | if (term.cwd == "/") { 222 | term.cwd = "bin"; 223 | } else { 224 | term.stylePrint(`No such directory: ${dir}`); 225 | } 226 | break; 227 | case ".": 228 | break; 229 | default: 230 | term.stylePrint(`No such directory: ${dir}`); 231 | break; 232 | } 233 | }, 234 | 235 | zsh: function() { 236 | term.init(term.user); 237 | }, 238 | 239 | cat: function(args) { 240 | const filename = args[0]; 241 | 242 | if (_filesHere().includes(filename)) { 243 | term.writeln(getFileContents(filename)); 244 | } else { 245 | term.stylePrint(`No such file: ${filename}`); 246 | } 247 | if (filename == "id_rsa") { 248 | term.openURL("https://i.imgur.com/Q2Unw.gif"); 249 | } 250 | }, 251 | 252 | grep: function(args) { 253 | const q = args[0]; 254 | const filename = args[1]; 255 | 256 | if (filename == "id_rsa") { 257 | term.openURL("https://i.imgur.com/Q2Unw.gif"); 258 | } 259 | 260 | if (!q || !filename) { 261 | term.stylePrint("usage: %grep% [pattern] [filename]"); 262 | return; 263 | } 264 | 265 | if (_filesHere().includes(filename)) { 266 | var file = getFileContents(filename); 267 | const matches = file.matchAll(q); 268 | for (match of matches) { 269 | file = file.replaceAll(match[0], colorText(match[0], "files")); 270 | } 271 | term.writeln(file); 272 | } else { 273 | term.stylePrint(`No such file or directory: ${filename}`); 274 | } 275 | }, 276 | 277 | finger: function(args) { 278 | const user = args[0]; 279 | 280 | switch (user) { 281 | case 'guest': 282 | term.stylePrint("Login: guest Name: Guest"); 283 | term.stylePrint("Directory: /home/guest Shell: /bin/zsh"); 284 | break; 285 | case 'root': 286 | term.stylePrint("Login: root Name: That's Us!"); 287 | term.stylePrint("Directory: /home/root Shell: /bin/zsh"); 288 | break; 289 | case 'avidan': 290 | case 'kane': 291 | case 'chrissy': 292 | case 'lee': 293 | case 'zodi': 294 | case 'ben': 295 | case 'laelah': 296 | term.stylePrint(`Login: ${user} Name: ${team[user]["name"]}`); 297 | term.stylePrint(`Directory: /home/${user} Shell: /bin/zsh`); 298 | break; 299 | default: 300 | term.stylePrint(user ? `%finger%: ${user}: no such user` : "usage: %finger% [user]"); 301 | break; 302 | } 303 | }, 304 | 305 | groups: function(args) { 306 | const user = args[0]; 307 | 308 | switch (user) { 309 | case 'guest': 310 | term.stylePrint("guest lps founders engineers investors"); 311 | break; 312 | case 'root': 313 | term.stylePrint("wheel investors engineers deep tech firms"); 314 | break; 315 | case 'avidan': 316 | term.stylePrint("wheel investors engineers managingpartner handypersons tinkers agtech foodtech foodies coffeesnobs"); 317 | break; 318 | case 'kane': 319 | term.stylePrint("wheel investors engineers partners tinkerers cad motorcyclists gearheads machinepix sportshooters gamers"); 320 | break; 321 | case 'chrissy': 322 | term.stylePrint("wheel investors engineers partners electrical manufacturing ecad wearables healthtech gearheads automotive sportshooters"); 323 | break; 324 | case 'lee': 325 | term.stylePrint("wheel investors engineers partners software devtools data ai+ml gamers winesnobs"); 326 | break; 327 | case 'zodi': 328 | term.stylePrint("wheel investors engineers investors ai+ml simulation terraforming maine"); 329 | break; 330 | case 'ben': 331 | term.stylePrint("wheel operations photography ironman racecars canyoneering"); 332 | break; 333 | case 'laelah': 334 | term.stylePrint("wheel admin operations miracleworkers gamers"); 335 | break; 336 | default: 337 | term.stylePrint(user ? `%groups%: ${user}: no such user` : "usage: %groups% [user]"); 338 | break; 339 | } 340 | }, 341 | 342 | gzip: function() { 343 | term.stylePrint("What are you going to do with a zip file on a fake terminal, seriously?"); 344 | }, 345 | 346 | free: function() { 347 | term.stylePrint("Honestly, our memory isn't what it used to be."); 348 | }, 349 | 350 | tail: function(args) { 351 | term.command(`cat ${args.join(" ")}`); 352 | }, 353 | 354 | less: function(args) { 355 | term.command(`cat ${args.join(" ")}`); 356 | }, 357 | 358 | head: function(args) { 359 | term.command(`cat ${args.join(" ")}`); 360 | }, 361 | 362 | open: function(args) { 363 | if (!args.length) { 364 | term.stylePrint("%open%: open a file - usage:\r\n"); 365 | term.stylePrint("%open% test.htm"); 366 | } else if (args[0].split(".")[0] == "test" && args[0].split(".")[1] == "htm") { 367 | term.openURL("https://i.imgur.com/Q2Unw.gif"); 368 | } else if (args[0].split(".")[1] == "htm") { 369 | term.openURL(`./${args[0]}`, false); 370 | } else if (args.join(" ") == "the pod bay doors") { 371 | term.stylePrint("I'm sorry Dave, I'm afraid I can't do that."); 372 | } else { 373 | term.command(`cat ${args.join(" ")}`); 374 | } 375 | }, 376 | 377 | more: function(args) { 378 | term.command(`cat ${args.join(" ")}`); 379 | }, 380 | 381 | emacs: function() { 382 | term.stylePrint("%emacs% not installed. try: %vi%"); 383 | }, 384 | 385 | vim: function() { 386 | term.stylePrint("%vim% not installed. try: %emacs%"); 387 | }, 388 | 389 | vi: function() { 390 | term.stylePrint("%vi% not installed. try: %emacs%"); 391 | }, 392 | 393 | pico: function() { 394 | term.stylePrint("%pico% not installed. try: %vi% or %emacs%"); 395 | }, 396 | 397 | nano: function() { 398 | term.stylePrint("%nano% not installed. try: %vi% or %emacs%"); 399 | }, 400 | 401 | pine: function() { 402 | term.openURL("mailto:hello@root.vc"); 403 | }, 404 | 405 | curl: function(args) { 406 | term.stylePrint(`Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource ${args[0]}. Use a real terminal.`); 407 | }, 408 | 409 | ftp: function(args) { 410 | term.command(`curl ${args.join(" ")}`); 411 | }, 412 | 413 | ssh: function(args) { 414 | term.command(`curl ${args.join(" ")}`); 415 | }, 416 | 417 | sftp: function(args) { 418 | term.command(`curl ${args.join(" ")}`); 419 | }, 420 | 421 | scp: function(args) { 422 | term.stylePrint(`████████████ Request Blocked: The ███████████ Policy disallows reading the ██████ resource ${args[0]}.`); 423 | }, 424 | 425 | rm: function() { 426 | term.stylePrint("I'm sorry Dave, I'm afraid I can't do that."); 427 | }, 428 | 429 | mkdir: function() { 430 | term.stylePrint("Come on, don't mess with our immaculate file system."); 431 | }, 432 | 433 | alias: function() { 434 | term.stylePrint("Just call me HAL."); 435 | }, 436 | 437 | df: function() { 438 | term.stylePrint("Nice try. Just get a Dropbox."); 439 | }, 440 | 441 | kill: function(args) { 442 | if (args && args.slice(-1) == 337) { 443 | killed = true; 444 | term.stylePrint("Root Ventures crypto miner disabled."); 445 | } else { 446 | term.stylePrint("You can't kill me!"); 447 | } 448 | }, 449 | 450 | killall: function(args) { 451 | term.command(`kill ${args.join(" ")}`); 452 | }, 453 | 454 | locate: function() { 455 | term.stylePrint("Root Ventures"); 456 | term.stylePrint("2670 Harrison St"); 457 | term.stylePrint("San Francisco, CA 94110"); 458 | }, 459 | 460 | history: function() { 461 | term.history.forEach((element, index) => { 462 | term.stylePrint(`${1000 + index} ${element}`); 463 | }) 464 | }, 465 | 466 | find: function(args) { 467 | const file = args[0]; 468 | if (Object.keys(_FILES).includes(file)) { 469 | term.stylePrint(_FULL_PATHS[file]); 470 | } else { 471 | term.stylePrint(`%find%: ${file}: No such file or directory`); 472 | } 473 | }, 474 | 475 | fdisk: function() { 476 | term.command("rm"); 477 | }, 478 | 479 | chown: function() { 480 | term.stylePrint("You do not have permission to %chown%"); 481 | }, 482 | 483 | chmod: function() { 484 | term.stylePrint("You do not have permission to %chmod%"); 485 | }, 486 | 487 | mv: function(args) { 488 | const src = args[0]; 489 | 490 | if (_filesHere().includes(src)) { 491 | term.stylePrint(`You do not have permission to move file ${src}`); 492 | } else { 493 | term.stylePrint(`%mv%: ${src}: No such file or directory`); 494 | } 495 | }, 496 | 497 | cp: function(args) { 498 | const src = args[0]; 499 | 500 | if (_filesHere().includes(src)) { 501 | term.stylePrint(`You do not have permission to copy file ${src}`); 502 | } else { 503 | term.stylePrint(`%cp%: ${src}: No such file or directory`); 504 | } 505 | }, 506 | 507 | touch: function() { 508 | term.stylePrint("You can't %touch% this"); 509 | }, 510 | 511 | sudo: function(args) { 512 | if (term.user == "root") { 513 | term.command(args.join(" ")); 514 | } 515 | else { 516 | term.stylePrint(`${colorText(term.user, "user")} is not in the sudoers file. This incident will be reported`); 517 | } 518 | }, 519 | 520 | su: function(args) { 521 | user = args[0] || "root"; 522 | 523 | if (user == "root" || user == "guest") { 524 | term.user = user; 525 | term.command("cd ~"); 526 | } else { 527 | term.stylePrint("su: Sorry"); 528 | } 529 | }, 530 | 531 | quit: function() { 532 | term.command("exit"); 533 | }, 534 | 535 | stop: function() { 536 | term.command("exit"); 537 | }, 538 | 539 | whoami: function() { 540 | term.stylePrint(term.user); 541 | }, 542 | 543 | passwd: function() { 544 | term.stylePrint("Wow. Maybe don't enter your password into a sketchy web-based term.command prompt?"); 545 | }, 546 | 547 | man: function(args) { 548 | term.command(`tldr ${args}`); 549 | }, 550 | 551 | woman: function(args) { 552 | term.command(`tldr ${args}`); 553 | }, 554 | 555 | ping: function() { 556 | term.stylePrint("pong"); 557 | }, 558 | 559 | ps: function() { 560 | term.stylePrint("PID TTY TIME CMD"); 561 | term.stylePrint("424 ttys00 0:00.33 %-zsh%"); 562 | term.stylePrint("158 ttys01 0:09.70 %/bin/npm start%"); 563 | term.stylePrint("767 ttys02 0:00.02 %/bin/sh%"); 564 | if (!killed) { 565 | term.stylePrint("337 ttys03 0:13.37 %/bin/cgminer -o pwn.d%"); 566 | } 567 | }, 568 | 569 | uname: function(args) { 570 | switch (args[0]) { 571 | case "-a": 572 | term.stylePrint("RootPC rootpc 0.0.1 RootPC Kernel Version 0.0.1 root:xnu-31415.926.5~3/RELEASE_X86_64 x86_64"); 573 | break; 574 | case "-mrs": 575 | term.stylePrint("RootPC 0.0.1 x86_64"); 576 | break; 577 | default: 578 | term.stylePrint("RootPC"); 579 | } 580 | }, 581 | 582 | top: function() { 583 | term.command("ps"); 584 | }, 585 | 586 | exit: function() { 587 | term.command("open welcome.htm"); 588 | }, 589 | 590 | clear: function() { 591 | term.init(); 592 | }, 593 | 594 | zed: function() { 595 | term.stylePrint("Coming soon! ;)"); 596 | }, 597 | 598 | ge: function() { 599 | term.command("great_expectations"); 600 | }, 601 | 602 | great_expectations: function() { 603 | term.command("superconductive"); 604 | }, 605 | 606 | privacy: function() { 607 | term.command("privacy_dynamics"); 608 | }, 609 | 610 | eval: function(args) { 611 | term.stylePrint("please instead build a webstore with macros. in the meantime, the result is: " + eval(args.join(" "))); 612 | }, 613 | 614 | jobs: function() { 615 | term.stylePrint(`[1] Running investor &`); 616 | term.stylePrint("\r\nUse %fg% [id] to see details of a job.") 617 | term.stylePrint("Yes, we know that's not exactly how %jobs% works in Unix, but close enough."); 618 | }, 619 | 620 | bg: function(args) { 621 | term.stylePrint(`Sorry. If you want to background one of these jobs, you'll need to help us fill it. Try %fg% ${args} instead.`); 622 | }, 623 | 624 | fg: function(args) { 625 | const job = jobs[args]; 626 | 627 | if (job) { 628 | job.map(line => term.stylePrint(line)); 629 | term.stylePrint(`\r\n%apply% ${args} to apply!`); 630 | } else { 631 | term.stylePrint(`job id ${args} not found.`); 632 | } 633 | }, 634 | 635 | apply: function(args) { 636 | if (args == 1) { 637 | term.stylePrint("If you think you'd enjoy working here, apply by hitting the following endpoint:"); 638 | term.stylePrint("\r\nhttps://hooks.attio.com/w/1d456d59-a7ac-4211-ac1d-fac612f7f491/5fc14931-0124-4121-b281-1dbfb64dceb2\r\n"); 639 | term.stylePrint(`with a ${colorText("POST", "command")} request containing a json object with 4 keys (use a real terminal):`); 640 | term.stylePrint(`\r\n{`); 641 | term.stylePrint(`\t${colorText("name", "command")}: [your name]`); 642 | term.stylePrint(`\t${colorText("email", "command")}: [your email]`); 643 | term.stylePrint(`\t${colorText("linkedin", "command")}: [your linkedin profile url]`); 644 | term.stylePrint(`\t${colorText("notes", "command")}: [(optional) anything else you'd like to share?]`); 645 | term.stylePrint(`}`); 646 | } else if (!args || args == "") { 647 | term.stylePrint("Please provide a job id. Use %jobs% to list all current jobs."); 648 | } else { 649 | term.stylePrint(`Job id ${args[0]} not found. Use %jobs% to list all current jobs.`) 650 | } 651 | } 652 | } 653 | 654 | // Add commands for company demos 655 | for (kv of Object.entries(portfolio)) { 656 | const key = kv[0]; 657 | const val = kv[1]; 658 | 659 | if (val["demo"]) { 660 | commands[key] = () => term.displayURL(val["demo"]); 661 | } 662 | } 663 | 664 | function _filesHere() { 665 | return _DIRS[term.cwd].filter((e) => e != 'README.md' || term.user == "root"); 666 | } 667 | -------------------------------------------------------------------------------- /config/fs.js: -------------------------------------------------------------------------------- 1 | const _LOCAL_FILES = { 2 | "id_rsa": "Nice try!", 3 | }; 4 | 5 | const _REMOTE_FILES = { 6 | "README.md": "https://raw.githubusercontent.com/rootvc/cli-website/main/README.md", 7 | "welcome.htm": "https://raw.githubusercontent.com/rootvc/cli-website/main/welcome.htm", 8 | }; 9 | 10 | const _FILES = { 11 | ..._LOCAL_FILES, 12 | ..._REMOTE_FILES, 13 | } 14 | 15 | const _DIRS = { 16 | "~": ["id_rsa", "welcome.htm", "README.md"], 17 | "bin": ["zsh"], 18 | "home": Object.keys(team).concat("guest", "root").sort(), 19 | "/": ["bin", "home"], 20 | }; 21 | 22 | let _FULL_PATHS = {}; 23 | for (const [key, values] of Object.entries(_DIRS)) { 24 | for (const value of values) { 25 | switch (key) { 26 | case "~": 27 | _FULL_PATHS[value] = `${key}/${value}`; 28 | break; 29 | case "/": 30 | _FULL_PATHS[value] = `/${value}`; 31 | break; 32 | default: 33 | _FULL_PATHS[value] = `/${key}/${value}`; 34 | } 35 | } 36 | } 37 | 38 | function preloadFiles() { 39 | for (kv of Object.entries(_REMOTE_FILES)) { 40 | _loadFile(kv[0]); 41 | } 42 | 43 | for (kv of Object.entries(_LOCAL_FILES)) { 44 | _insertFileToDOM(kv[0], kv[1]); 45 | } 46 | } 47 | 48 | function _loadFile(name) { 49 | fetch(_REMOTE_FILES[name]) 50 | .then(response => response.text()) 51 | .then((body) => _insertFileToDOM(name, body)); 52 | } 53 | 54 | function _insertFileToDOM(name, txt) { 55 | const parentDiv = document.getElementById("files-all"); 56 | div = document.createElement("div"); 57 | div.id = name; 58 | div.innerText = txt; 59 | parentDiv.appendChild(div); 60 | } 61 | 62 | function getFileContents(filename) { 63 | console.log(filename); 64 | const div = document.getElementById(filename); 65 | return div.innerHTML 66 | .replaceAll("
", "\r\n") 67 | .replaceAll(">", ">") 68 | .replaceAll("<", "<"); 69 | } 70 | -------------------------------------------------------------------------------- /config/help.js: -------------------------------------------------------------------------------- 1 | const help = { 2 | "%help%": "list all commands (you're looking at it)", 3 | "%whois%": "list all partners", 4 | "%whois% [partner]": "learn about a partner", 5 | "%whois% root": "learn about us", 6 | "%tldr%": "list all portfolio companies", 7 | "%tldr% [company_name]": "learn about a portfolio company", 8 | "%email%": "reach out to us", 9 | "%twitter%": "twitter accounts", 10 | "%instagram%": "instagram account", 11 | "%git%": "this repo", 12 | "%github%": "all repos", 13 | "%locate%": "physical address", 14 | "%jobs%": "check out our job openings", 15 | "%test%": "do not use", 16 | "%other%": "try your fav commands (e.g. %ls%, %groups%, %su%)" 17 | }; 18 | -------------------------------------------------------------------------------- /config/jobs.js: -------------------------------------------------------------------------------- 1 | // NOTE: Right now, when you change these, you need to also change the listing of jobs by id in commands.js 2 | 3 | const jobs = { 4 | 1: [ 5 | "We're hiring an Investor!", 6 | 7 | "\r\nRoot Ventures is a $325M Seed VC based in San Francisco. We invest in technical teams at the earliest stages, focusing on founders building products at the frontier of technology and founders building the tools to make it all possible.", 8 | "\r\nYour role will include identifying & analyzing potential investment opportunities, assisting with due diligence, performing market research & competitive analysis, and strengthening our network through hosting & attending events. We're a team of engineers and tinkerers, so you'll even be helping us with our constant office improvement projects.", 9 | 10 | "\r\nAbout the job:", 11 | "We operate at the intersection between hard technologies & business. We obsess about the latest technological advancements, and how they will change entire industries and humanity. This is not an engineering job. This is not a strategy consulting job. It’s definitely not an investment banking job. We work in a strange place in between. As a member of the Root investment team, you’ll get to spend time thinking about technical challenges and their industry implications at very deep levels", 12 | 13 | "\r\nAbout you:", 14 | " * Excellent attention to detail.", 15 | " * Thrives in an unstructured work environment; independent and self-motivated. Someone that defaults to action and finds unexpected opportunities to help.", 16 | " * Creativity: where should we be looking for opportunities that few others are?", 17 | " * Strong existing ties to the tech or startup community is a plus.", 18 | " * Personally passionate about technology; tinkerers and hobbyists like the rest of us.", 19 | " * Techno-optimist: we’re all here because we believe in human greatness and technology’s role in realizing it.", 20 | 21 | "\r\nJob qualifications:", 22 | " * Strong communication and analytical skills.", 23 | " * At least 3-5 years of work experience in VC, startup operations, engineering, or finance.", 24 | " * Based or able to relocate to the San Francisco Bay Area. We are an in-office team.", 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /config/portfolio.js: -------------------------------------------------------------------------------- 1 | const portfolio = { 2 | esper: { 3 | name: "Esper", 4 | url: "https://esper.io", 5 | description: 6 | "Esper is devops for devices, allowing teams to seamlessly build and manage enterprise hardware.", 7 | memo: null, 8 | demo: "https://esper.io/signup", 9 | }, 10 | 11 | meroxa: { 12 | name: "Meroxa", 13 | url: "https://meroxa.com", 14 | description: 15 | "Meroxa is a platform for software engineers to build mature, scalable data engineering infrastructure with a single command.", 16 | memo: "https://github.com/rootvc/investment-memos/blob/main/meroxa.md", 17 | demo: "https://meroxa.com/#data-warehouse", 18 | }, 19 | 20 | particle: { 21 | name: "Particle", 22 | url: "https://particle.io", 23 | description: 24 | "Particle is the largest professional IoT development platform.", 25 | demo: "https://docs.particle.io/", 26 | }, 27 | 28 | daily: { 29 | name: "Daily", 30 | url: "https://daily.co", 31 | description: 32 | "Daily makes it easier for developers to add video to websites and apps.", 33 | demo: "https://docs.daily.co/docs/introduction-1", 34 | }, 35 | 36 | hash: { 37 | name: "HASH", 38 | url: "https://hash.ai", 39 | description: 40 | "HASH is an open-source, self-building database that grows and maintains a typed graph of entities on your behalf.", 41 | demo: "https://app.hash.ai/", 42 | }, 43 | 44 | superconductive: { 45 | name: "Superconductive", 46 | url: "https://superconductive.ai", 47 | description: 48 | "Superconductive is a SaaS platform for verifying and enforcing data integrity at every stage of the lifecycle of data in an organization.", 49 | demo: "https://docs.greatexpectations.io/en/latest/guides/tutorials/quick_start.html#tutorials-quick-start", 50 | }, 51 | 52 | okteto: { 53 | name: "Okteto", 54 | url: "https://okteto.com", 55 | description: "Okteto is the best emphemeral environment for developers.", 56 | demo: "https://okteto.com/docs/getting-started/index.html", 57 | }, 58 | 59 | privacy_dynamics: { 60 | name: "Privacy Dynamics", 61 | url: "https://privacydynamics.io", 62 | description: 63 | "Privacy Dynamics ensures your customers' data privacy without slowing down your team.", 64 | demo: "https://privacydynamics.io/demo/contact", 65 | }, 66 | 67 | nautilus: { 68 | name: "Nautilus Labs", 69 | url: "https://nautiluslabs.com", 70 | description: 71 | "Nautilus Labs allows maritime fleets to optimize shipping routes and energy costs in real time.", 72 | }, 73 | 74 | ntopology: { 75 | name: "nTopology", 76 | url: "https://ntopology.com", 77 | description: "nTopology is the future of mechanical engineering software.", 78 | }, 79 | 80 | tortuga: { 81 | name: "Tortuga AgTech", 82 | url: "https://tortugaagtech.com", 83 | description: "Tortuga automates agriculture for high value produce.", 84 | }, 85 | 86 | instrumental: { 87 | name: "Instrumental", 88 | url: "https://instrumental.com", 89 | description: 90 | "Instrumental generates real time insights for mass manufacturing.", 91 | }, 92 | 93 | stellar: { 94 | name: "Stellar Pizza", 95 | url: "https://eatstellarpizza.com", 96 | description: 97 | "Stellar Pizza is building the future of automated food production.", 98 | }, 99 | 100 | versatile: { 101 | name: "Versatile", 102 | url: "https://versatile.ai", 103 | description: 104 | "Versatile is an onsite construction data provider for accelerating schedules.", 105 | }, 106 | 107 | dusty: { 108 | name: "Dusty Robotics", 109 | url: "https://dustyrobotics.com", 110 | description: 111 | "Dusty Robotics automates layout in complex construction projects.", 112 | }, 113 | 114 | thruwave: { 115 | name: "ThruWave", 116 | url: "https://thruwave.com", 117 | description: 118 | "Thruwave increases the efficiency and transparency of high volume logistics operations.", 119 | }, 120 | 121 | seismic: { 122 | name: "Seismic", 123 | url: "https://myseismic.com", 124 | description: 125 | "Seismic augments strength and safety for workers through soft robotics.", 126 | }, 127 | 128 | seam: { 129 | name: "Seam", 130 | url: "https://getseam.com", 131 | description: "Seam provides an API for managing building systems.", 132 | }, 133 | 134 | chargelab: { 135 | name: "ChargeLab", 136 | url: "https://chargelab.co", 137 | description: 138 | "ChargeLab builds API- and software-defined EV charging networks.", 139 | }, 140 | 141 | wildtype: { 142 | name: "Wildtype Foods", 143 | url: "https://wildtypefoods.com", 144 | description: 145 | "Wildtype creates organic, clean, high-quality, animal-free meat.", 146 | }, 147 | 148 | nordsense: { 149 | name: "Nordsense", 150 | url: "https://nordsense.com", 151 | description: 152 | "Nordsense optimizes pickup routes for waste management fleets.", 153 | }, 154 | 155 | trucklabs: { 156 | name: "TruckLabs", 157 | url: "https://trucklabs.com", 158 | description: 159 | "Trucklabs reduces fuel costs and increases profit margins for long haul trucking fleets.", 160 | }, 161 | 162 | sensable: { 163 | name: "Sensable", 164 | url: "https://getsensable.com", 165 | description: 166 | "Sensable generates real-time industrial engineering insights.", 167 | }, 168 | 169 | crux: { 170 | name: "Crux", 171 | url: "https://cruxocm.com", 172 | description: "Crux automates critical energy infrastructure.", 173 | }, 174 | 175 | iasql: { 176 | name: "IaSQL", 177 | url: "https://iasql.com", 178 | description: 179 | "IaSQL is the next evolution of infrastructure management, allowing you to manage your infra in a database instead of stateless config files.", 180 | }, 181 | 182 | mashgin: { 183 | name: "Mashgin", 184 | url: "https://mashgin.com", 185 | description: "Mashgin automates self-checkout.", 186 | }, 187 | 188 | creator: { 189 | name: "Creator", 190 | url: "https://creator.rest", 191 | description: "Creator builds fully autonomous hamburger robots.", 192 | }, 193 | 194 | apolloshield: { 195 | name: "ApolloShield", 196 | url: "https://apolloshield.com", 197 | description: 198 | "ApolloShield safeguards airspace from autonomous and remote piloted aircraft.", 199 | }, 200 | 201 | skycatch: { 202 | name: "Skycatch", 203 | url: "https://skycatch.com", 204 | description: 205 | "Skycatch provides high resolution 3D mapping and modeling of high-value infrastructure.", 206 | }, 207 | 208 | shaper: { 209 | name: "Shaper", 210 | url: "https://shapertools.com", 211 | description: 212 | "Shaper Tools makes the Origin, a handheld, auto-correcting CNC.", 213 | }, 214 | 215 | cape: { 216 | name: "Cape", 217 | url: "https://capenetworks.com", 218 | description: 219 | "Cape Networks allows IT professionals to monitor, text, and repair enterprise networks remotely.", 220 | }, 221 | 222 | righthook: { 223 | name: "Righthook", 224 | url: "https://righthook.io", 225 | description: 226 | "Righthook reduces the time and cost required to develop autonomous vehicles.", 227 | }, 228 | 229 | sixwheel: { 230 | name: "SixWheel", 231 | url: "https://sixwheel.com", 232 | description: 233 | "SixWheel brings autonomy and electrification to long haul trucking operations.", 234 | }, 235 | 236 | radical: { 237 | name: "Radical", 238 | url: "https://radicalsemiconductor.com", 239 | description: 240 | "Radical Semiconductor provides hardware security down to the individual IC.", 241 | }, 242 | 243 | zed: { 244 | name: "Zed", 245 | url: "https://zed.dev", 246 | description: 247 | "Zed is a fully-native desktop code editor focused on high performance, clean design, and real-time collaboration.", 248 | }, 249 | 250 | kayhan: { 251 | name: "Kayhan", 252 | url: "https://kayhan.space", 253 | description: 254 | "Kayhan’s spaceflight operations platform allows satellite operators to focus on their core mission.", 255 | }, 256 | 257 | allspice: { 258 | name: "AllSpice", 259 | url: "https://allspice.io", 260 | description: "Collaboration and testing platform for hardware teams.", 261 | }, 262 | 263 | quilter: { 264 | name: "Quilter", 265 | url: "https://quilter.ai", 266 | description: "Automated design tools for electrical engineers.", 267 | }, 268 | 269 | adept: { 270 | name: "Adept", 271 | url: "https://adept.ai", 272 | description: "Useful general intelligence.", 273 | }, 274 | 275 | aperture: { 276 | name: "Aperture Data", 277 | url: "https://aperturedata.io", 278 | description: 279 | "Aperture manage images and videos with a database purpose-built for data science and machine learning.", 280 | }, 281 | 282 | supertokens: { 283 | name: "SuperTokens", 284 | url: "https://supertokens.io", 285 | description: 286 | "SuperTokens is the best Open Source solution for user authentication.", 287 | }, 288 | 289 | fudge: { 290 | name: "Fudge", 291 | url: "https://fudge.ai", 292 | description: 293 | "Fudge is the best way to speed up your website to improve conversion rates and increase revenue.", 294 | }, 295 | 296 | kodra: { 297 | name: "Kodra", 298 | url: "https://kodra.ai", 299 | description: "Fast dataset curation for machine learning.", 300 | }, 301 | 302 | topologic: { 303 | name: "Topologic", 304 | url: "https://topologic.io", 305 | description: "Design and automation software for textile manufacturing.", 306 | }, 307 | 308 | ruby: { 309 | name: "Ruby Robotics", 310 | url: "https://ruby-robotics.com", 311 | description: 312 | "Robotics and AI to autonomously prepare, image, and assess tissue during biopsy procedures.", 313 | }, 314 | 315 | instance: { 316 | name: "Instance", 317 | url: "https://instance.bio", 318 | description: "Instance is the fastest way to synthesize DNA.", 319 | }, 320 | 321 | cady: { 322 | name: "CADY Solutions", 323 | url: "https://cadysolutions.com", 324 | description: "CADY automates the electrical schematic analysis process.", 325 | }, 326 | 327 | sublayer: { 328 | name: "Sublayer", 329 | url: "https://sublayer.com", 330 | description: "Sublayer is AI-assisted coding that works the way you do.", 331 | }, 332 | 333 | nullify: { 334 | name: "Nullify", 335 | url: "https://nullify.ai", 336 | description: 337 | "Nullify performs product security tasks alongside your developers.", 338 | }, 339 | 340 | trieve: { 341 | name: "Trieve", 342 | url: "https://trieve.ai", 343 | description: 344 | "Trieve provides infrastructure for building AI search into your applications.", 345 | }, 346 | 347 | genalpha: { 348 | name: "GenAlpha", 349 | url: "https://www.generation-alpha-transistor.com/", 350 | description: 351 | "GenAlpha is an AI copilot for analog and mixed-signal chip design.", 352 | }, 353 | 354 | breakpoint: { 355 | name: "Breakpoint AI", 356 | url: "https://setbreakpoint.com", 357 | description: 358 | "Breakpoint uses AI to detect failures in computer vision models and re-trains them to prevent future issues.", 359 | }, 360 | 361 | determinate: { 362 | name: "Determinate Systems", 363 | url: "https://determinate.systems", 364 | description: 365 | "Determinate provides enterprise-grade solutions for Nix package management.", 366 | }, 367 | 368 | genalpha: { 369 | name: "Gen Alpha", 370 | url: "https://www.generation-alpha-transistor.com", 371 | description: 372 | "Gen Alpha builds AI copilots for analog and mixed-signal chip design to streamline workflows.", 373 | }, 374 | 375 | hunch: { 376 | name: "Hunch", 377 | url: "https://hunchdata.com", 378 | description: 379 | "Hunch provides collaborative data exploration and visualization tools for non-technical users.", 380 | }, 381 | 382 | illoca: { 383 | name: "Illoca", 384 | url: "https://illoca.com", 385 | description: 386 | "Illoca accelerates commercial architecture workflows with generative AI for AEC software.", 387 | }, 388 | 389 | integrated: { 390 | name: "Integrated Biosciences", 391 | url: "https://integratebio.co", 392 | description: 393 | "Integrated uses optogenetics and ML to discover drugs for neurodegenerative and age-related diseases.", 394 | }, 395 | 396 | latent: { 397 | name: "Latent Technology", 398 | url: "https://latent-technology.com", 399 | description: 400 | "Latent helps animators and game developers create life-like 3D assets with AI-powered tools.", 401 | }, 402 | 403 | patterns: { 404 | name: "Patterns", 405 | url: "https://patterns.app", 406 | description: 407 | "Patterns provides tools and infrastructure for developing modern AI applications efficiently.", 408 | }, 409 | 410 | subtrace: { 411 | name: "Subtrace", 412 | url: "https://subtrace.dev", 413 | description: 414 | "Subtrace automatically tracks all HTTP requests coming in and going out of your production backend.", 415 | }, 416 | }; 417 | -------------------------------------------------------------------------------- /config/team.js: -------------------------------------------------------------------------------- 1 | const team = { 2 | avidan: { 3 | name: "Avidan Ross", 4 | title: "Managing Partner", 5 | description: 6 | "Avidan is the Founding Partner of Root Ventures. Previously, he designed industrial robotics for Food Network's kitchens and was CTO of CIM Group, where he focused on industrial investing, and worked as an embedded application developer at Excite@Home. Avidan has a BA in Computer Science from Columbia University.", 7 | linkedin: "https://www.linkedin.com/in/avidanross/", 8 | }, 9 | kane: { 10 | name: "Kane Hsieh", 11 | title: "Partner", 12 | description: 13 | "Before joining Root Ventures, Kane was founder and Head of Product at Brilliant Bicycle Co. He has also worked as an early-stage investor at RRE Ventures, a software engineer at Romotive, and a Project Manager at Microsoft. Kane has an AB in Computer Science from Harvard.", 14 | linkedin: "https://www.linkedin.com/in/kanehsieh/", 15 | }, 16 | chrissy: { 17 | name: "Chrissy Meyer", 18 | title: "Partner", 19 | description: 20 | "Chrissy has spent the past decade developing and shipping hardware as an engineering manager at Apple and Square. She was a founding team member at Pearl Automation, a vehicle technology startup. Chrissy has an MS in Electrical Engineering from Stanford and a BSEE from Rose-Hulman.", 21 | linkedin: "https://www.linkedin.com/in/chrissymeyer/", 22 | }, 23 | lee: { 24 | name: "Lee Edwards", 25 | title: "Partner", 26 | description: 27 | "Lee was most recently CTO at Teespring. Previously, Lee was a mechanical engineer at iRobot, a software engineer at Pivotal Labs, Lead Engineer at SideTour (acquired by Groupon in 2013), and engineering manager for GrouponLive. He graduated from Olin College of Engineering with a degree in Systems Engineering.", 28 | linkedin: "https://www.linkedin.com/in/leeredwards/", 29 | }, 30 | zodi: { 31 | name: "Zodi Chalat", 32 | title: "Associate", 33 | description: 34 | "Zodi began his career as an engineer working on ML infrastructure at Netflix before moving into venture investing. He previously studied CS and comparative literature at Yale.", 35 | linkedin: "https://linkedin.com/in/zodi", 36 | }, 37 | ben: { 38 | name: "Ben Lovell", 39 | title: "Head of Operations", 40 | description: 41 | "Ben worked at a16z, Menlo Ventures, and FT Partners to build operational automation and data pipelines. He also cofounded an adtech startup for rideshare companies. Ben graduated with a BA from Stanford University.", 42 | linkedin: "https://www.linkedin.com/in/lovellb/", 43 | }, 44 | laelah: { 45 | name: "Laelah Reino", 46 | title: "Operations Manager", 47 | description: 48 | "Laelah has spent over 15 years in marketing for films, consumer products, and subscription-based services. Laelah Reino has a BA in Business Administration with a Marketing concentration from Drexel University.", 49 | linkedin: "https://www.linkedin.com/in/laelah-reino-78b6a51/", 50 | }, 51 | }; 52 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Abel|Source+Code+Pro&display=swap); 2 | 3 | body, html { 4 | height: 100%; 5 | overflow: hidden; 6 | } 7 | 8 | body { 9 | background-color: #2c2c2c; 10 | font-family: "Abel"; 11 | margin: 0; 12 | } 13 | 14 | .terminal { 15 | height: 100%; 16 | padding: 24px; 17 | } 18 | 19 | #terminal { 20 | height: 100%; 21 | } 22 | 23 | :root { 24 | --brand-bg-color: #2c2c2c; 25 | --brand-txt-color: #fff; 26 | --brand-link-color: #fff; 27 | } -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/favicon.png -------------------------------------------------------------------------------- /images/adept.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/adept.jpg -------------------------------------------------------------------------------- /images/allspice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/allspice.jpg -------------------------------------------------------------------------------- /images/aperture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/aperture.jpg -------------------------------------------------------------------------------- /images/aperturedata.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/aperturedata.jpg -------------------------------------------------------------------------------- /images/apolloshield.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/apolloshield.jpg -------------------------------------------------------------------------------- /images/avidan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/avidan.png -------------------------------------------------------------------------------- /images/ben.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/ben.png -------------------------------------------------------------------------------- /images/breakpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/breakpoint.jpg -------------------------------------------------------------------------------- /images/cady.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/cady.jpg -------------------------------------------------------------------------------- /images/cape.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/cape.jpg -------------------------------------------------------------------------------- /images/chargelab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/chargelab.jpg -------------------------------------------------------------------------------- /images/chrissy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/chrissy.png -------------------------------------------------------------------------------- /images/cloudastructure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/cloudastructure.jpg -------------------------------------------------------------------------------- /images/coral.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/coral.jpg -------------------------------------------------------------------------------- /images/creator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/creator.jpg -------------------------------------------------------------------------------- /images/crux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/crux.jpg -------------------------------------------------------------------------------- /images/daily.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/daily.jpg -------------------------------------------------------------------------------- /images/determinate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/determinate.jpg -------------------------------------------------------------------------------- /images/dusty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/dusty.jpg -------------------------------------------------------------------------------- /images/esper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/esper.jpg -------------------------------------------------------------------------------- /images/fudge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/fudge.jpg -------------------------------------------------------------------------------- /images/genalpha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/genalpha.jpg -------------------------------------------------------------------------------- /images/geo/avidan2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/avidan2.jpg -------------------------------------------------------------------------------- /images/geo/banana.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/banana.gif -------------------------------------------------------------------------------- /images/geo/ben2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/ben2.jpg -------------------------------------------------------------------------------- /images/geo/chrissy2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/chrissy2.jpg -------------------------------------------------------------------------------- /images/geo/construction.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/construction.gif -------------------------------------------------------------------------------- /images/geo/counter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/counter.gif -------------------------------------------------------------------------------- /images/geo/counter2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/counter2.gif -------------------------------------------------------------------------------- /images/geo/divider.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/divider.gif -------------------------------------------------------------------------------- /images/geo/divider1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/divider1.gif -------------------------------------------------------------------------------- /images/geo/divider2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/divider2.gif -------------------------------------------------------------------------------- /images/geo/divider3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/divider3.gif -------------------------------------------------------------------------------- /images/geo/divider4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/divider4.gif -------------------------------------------------------------------------------- /images/geo/emily2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/emily2.jpg -------------------------------------------------------------------------------- /images/geo/flames.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/flames.gif -------------------------------------------------------------------------------- /images/geo/geocities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/geocities.jpg -------------------------------------------------------------------------------- /images/geo/hacker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/hacker.gif -------------------------------------------------------------------------------- /images/geo/ie_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/ie_logo.gif -------------------------------------------------------------------------------- /images/geo/kane2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/kane2.jpg -------------------------------------------------------------------------------- /images/geo/laelah2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/laelah2.jpg -------------------------------------------------------------------------------- /images/geo/lee2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/lee2.jpg -------------------------------------------------------------------------------- /images/geo/mchammer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/mchammer.gif -------------------------------------------------------------------------------- /images/geo/microfab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/microfab.gif -------------------------------------------------------------------------------- /images/geo/new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/new.gif -------------------------------------------------------------------------------- /images/geo/new2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/new2.gif -------------------------------------------------------------------------------- /images/geo/notepad.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/notepad.gif -------------------------------------------------------------------------------- /images/geo/ns_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/ns_logo.gif -------------------------------------------------------------------------------- /images/geo/progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/progress.gif -------------------------------------------------------------------------------- /images/geo/rainbow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/rainbow.gif -------------------------------------------------------------------------------- /images/geo/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/share.png -------------------------------------------------------------------------------- /images/geo/stars.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/stars.gif -------------------------------------------------------------------------------- /images/geo/underconstruction.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/underconstruction.gif -------------------------------------------------------------------------------- /images/geo/zodi2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/geo/zodi2.jpg -------------------------------------------------------------------------------- /images/hash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/hash.jpg -------------------------------------------------------------------------------- /images/hunch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/hunch.jpg -------------------------------------------------------------------------------- /images/iasql.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/iasql.jpg -------------------------------------------------------------------------------- /images/illoca.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/illoca.jpg -------------------------------------------------------------------------------- /images/instance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/instance.jpg -------------------------------------------------------------------------------- /images/instrumental.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/instrumental.jpg -------------------------------------------------------------------------------- /images/integrated.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/integrated.jpg -------------------------------------------------------------------------------- /images/kane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/kane.png -------------------------------------------------------------------------------- /images/kayhan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/kayhan.jpg -------------------------------------------------------------------------------- /images/kodra.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/kodra.jpg -------------------------------------------------------------------------------- /images/laelah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/laelah.png -------------------------------------------------------------------------------- /images/latent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/latent.jpg -------------------------------------------------------------------------------- /images/lee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/lee.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/logo.png -------------------------------------------------------------------------------- /images/loom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/loom.jpg -------------------------------------------------------------------------------- /images/mashgin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/mashgin.jpg -------------------------------------------------------------------------------- /images/meroxa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/meroxa.jpg -------------------------------------------------------------------------------- /images/mimeo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/mimeo.jpg -------------------------------------------------------------------------------- /images/nautilus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/nautilus.jpg -------------------------------------------------------------------------------- /images/nordsense.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/nordsense.jpg -------------------------------------------------------------------------------- /images/ntopology.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/ntopology.jpg -------------------------------------------------------------------------------- /images/nullify.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/nullify.jpg -------------------------------------------------------------------------------- /images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/og-image.png -------------------------------------------------------------------------------- /images/okteto.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/okteto.jpg -------------------------------------------------------------------------------- /images/oma_fertility.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/oma_fertility.jpg -------------------------------------------------------------------------------- /images/particle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/particle.jpg -------------------------------------------------------------------------------- /images/patterns.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/patterns.jpg -------------------------------------------------------------------------------- /images/plethora.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/plethora.jpg -------------------------------------------------------------------------------- /images/privacy_dynamics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/privacy_dynamics.jpg -------------------------------------------------------------------------------- /images/prynt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/prynt.jpg -------------------------------------------------------------------------------- /images/quilter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/quilter.jpg -------------------------------------------------------------------------------- /images/radical.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/radical.jpg -------------------------------------------------------------------------------- /images/righthook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/righthook.jpg -------------------------------------------------------------------------------- /images/rootvc-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/rootvc-square.png -------------------------------------------------------------------------------- /images/ruby.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/ruby.jpg -------------------------------------------------------------------------------- /images/seam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/seam.jpg -------------------------------------------------------------------------------- /images/seismic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/seismic.jpg -------------------------------------------------------------------------------- /images/sensable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/sensable.jpg -------------------------------------------------------------------------------- /images/shaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/shaper.jpg -------------------------------------------------------------------------------- /images/sixwheel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/sixwheel.jpg -------------------------------------------------------------------------------- /images/skycatch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/skycatch.jpg -------------------------------------------------------------------------------- /images/stellar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/stellar.jpg -------------------------------------------------------------------------------- /images/sublayer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/sublayer.jpg -------------------------------------------------------------------------------- /images/subtrace.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/subtrace.jpg -------------------------------------------------------------------------------- /images/superconductive.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/superconductive.jpg -------------------------------------------------------------------------------- /images/supertokens.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/supertokens.jpg -------------------------------------------------------------------------------- /images/thread.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/thread.jpg -------------------------------------------------------------------------------- /images/thruwave.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/thruwave.jpg -------------------------------------------------------------------------------- /images/topologic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/topologic.jpg -------------------------------------------------------------------------------- /images/tortuga.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/tortuga.jpg -------------------------------------------------------------------------------- /images/trieve.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/trieve.jpg -------------------------------------------------------------------------------- /images/trucklabs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/trucklabs.jpg -------------------------------------------------------------------------------- /images/versatile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/versatile.jpg -------------------------------------------------------------------------------- /images/wildtype.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/wildtype.jpg -------------------------------------------------------------------------------- /images/zed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/zed.jpg -------------------------------------------------------------------------------- /images/zodi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rootvc/cli-website/85fbcbba6c4e01f79005b76be5b8c512ec939635/images/zodi.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Root Ventures 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |

Root Ventures | Seeding bold engineers

65 |

Seed stage venture capital firm investing in deep tech. San Francisco, CA

66 | 67 | 68 | 70 | 71 | 72 | 73 |
74 | 85 | 86 | -------------------------------------------------------------------------------- /js/aalib.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"aalib.js","sourceRoot":""} -------------------------------------------------------------------------------- /js/ascii-art.js: -------------------------------------------------------------------------------- 1 | const LOGO_TYPE = 2 | ` _____ 3 | | __ \\ _ 4 | | |__) |___ ___ | |_ 5 | | _ // _ \\ / _ \\| __| 6 | | | \\ | (_) | (_) | |_ 7 | |_| \\_\\___/ \\___/_\\__| 8 | __ __ _ 9 | \\ \\ / /__ _ __ | |_ _ _ _ __ ___ ___ 10 | \\ \\/ / _ | '_ \\| __| | | | '__/ _ / __| 11 | \\ | __| | | | |_| |_| | | | __\\__ \\ 12 | \\/ \\___|_| |_|\\__|\\__,_|_| \\___|___/ 13 | 14 | `.replaceAll("\n", "\r\n"); 15 | 16 | function preloadASCIIArt() { 17 | const companies = Object.keys(portfolio); 18 | for (c of companies) { 19 | _loadArt(c, 0.5, 1.0, 'jpg', false); 20 | } 21 | 22 | _loadArt("rootvc-square", 1.0, term.cols >= 60 ? 0.5 : 1.0, 'png', false); 23 | const people = Object.keys(team); 24 | for (p of people) { 25 | _loadArt(p, 1.0, term.cols >= 60 ? 0.5 : 1.0, 'png', true); 26 | } 27 | } 28 | 29 | // TODO: Here is where we should insert alternatives to ASCII as text 30 | function _loadArt(id, ratio, scale, ext, inverse, callback) { 31 | const NICE_CHARSET = aalib.charset.SIMPLE_CHARSET + " "; 32 | const parentDiv = document.getElementById("aa-all"); 33 | const width = Math.floor(term.cols * scale); 34 | const height = Math.floor(width / 2 * ratio); 35 | var filename = `/images/${id}.${ext}`; 36 | 37 | var div = document.getElementById(id); 38 | 39 | if (!div) { 40 | div = document.createElement("div"); 41 | div.id = id; 42 | parentDiv.appendChild(div); 43 | } 44 | 45 | if (term.cols >= 40) { 46 | var aa = aalib.read.image.fromURL(filename) 47 | .map(aalib.aa({ width: width, height: height })); 48 | if (inverse) { aa = aa.map(aalib.filter.inverse()); } 49 | aa.map(aalib.render.html({ 50 | el: div, 51 | charset: NICE_CHARSET, 52 | })) 53 | .subscribe(callback); 54 | } else { 55 | div.innerText = `[ Photo: ${document.location.href}images/${id}.${ext} ]`; 56 | } 57 | } 58 | 59 | function getArt(id) { 60 | const div = document.getElementById(id); 61 | return div.innerText.replaceAll("\n", "\n\r"); 62 | } -------------------------------------------------------------------------------- /js/comcastify.js: -------------------------------------------------------------------------------- 1 | var comcastifyjs = (function () { 2 | 3 | // setup slowload modifier callback, structure avoids some annoying timer/closure problems 4 | var slowloadModiferCallback = function (slowloadDiv, args) { 5 | return function () { 6 | (function (slowloadDiv, args) { 7 | // calculate new height for box based on args 8 | var img = slowloadDiv.slothifyData.img; 9 | var newTopClip = slowloadDiv.slothifyData.imageTopClip + args.loadIncrement; 10 | if (args.randomPause === 0.0 || Math.random() > args.randomPause) { 11 | slowloadDiv.style.width = img.offsetWidth + 'px'; 12 | slowloadDiv.style.height = img.offsetHeight + 'px'; 13 | slowloadDiv.style.top = img.offsetTop + 'px'; 14 | slowloadDiv.style.left = img.offsetLeft + 'px'; 15 | 16 | // update slowload div 17 | slowloadDiv.style.clip = 'rect(' + newTopClip + 'px auto auto auto)'; 18 | 19 | // check stopping conditions 20 | var maxImageHeight = img.height * args.loadMaxPercent; 21 | } 22 | 23 | if (!img.complete) { 24 | setTimeout(slowloadModiferCallback(slowloadDiv, args), args.loadSpeed); 25 | } else if (typeof img.naturalHeight !== "undefined" && img.naturalWidth === 0) { 26 | setTimeout(slowloadModiferCallback(slowloadDiv, args), args.loadSpeed); 27 | } else if (!maxImageHeight || maxImageHeight === 0 || newTopClip < maxImageHeight) { 28 | // create new update timeout 29 | slowloadDiv.slothifyData.imageTopClip = newTopClip; 30 | setTimeout(slowloadModiferCallback(slowloadDiv, args), args.loadSpeed); 31 | } 32 | })(slowloadDiv, args); 33 | }; 34 | }; 35 | 36 | var prepare = function () { 37 | // hide images so image doesn't show up before box 38 | var imgs = document.getElementsByTagName('img'); 39 | for(var i = 0; i < imgs.length; i++) { 40 | var img = imgs[i]; 41 | img.style.visibility = 'hidden'; 42 | } 43 | }; 44 | 45 | var slowImages = function (args) { 46 | return function () { 47 | 48 | var params = { 49 | elements: args.elements || document.getElementsByTagName('img'), // elements affected 50 | boxColor: args.boxColor || '#000000', // color of box overlay 51 | loadMaxPercent: args.loadMaxPercent || 0.0, // max percentage to load images 52 | loadSpeed: args.loadSpeed || 300, // how often in ms to pass 53 | randLoadIncrement: args.randLoadIncrement || false, // true to randomize load increment 54 | loadIncrement: args.loadIncrement || 1, // pixels to load per pass 55 | randomPause: args.randomPause || 0.0 // probability of skipping a pass 56 | }; 57 | 58 | // make 'em load slow 59 | for(var i = 0; i < params.elements.length; i++) { 60 | // get some things we need 61 | var img = params.elements[i], 62 | parent = img.parentNode, 63 | slowload = document.createElement('DIV'); 64 | 65 | // set up initial state of box 66 | slowload.style.backgroundColor = params.boxColor; 67 | slowload.style.width = img.offsetWidth + 'px'; 68 | slowload.style.height = img.offsetHeight + 'px'; 69 | slowload.style.position = 'absolute'; 70 | slowload.style.top = img.offsetTop + 'px'; 71 | slowload.style.left = img.offsetLeft + 'px'; 72 | slowload.style.clip = 'rect(0 auto auto auto)'; 73 | 74 | // remember what the max height should be for later calculation 75 | slowload.slothifyData = { 76 | img: img, 77 | imageTopClip: 0, 78 | maxImageHeight: img.height * params.loadMaxPercent 79 | }; 80 | 81 | // put box over image 82 | parent.appendChild(slowload); 83 | 84 | // show image again 85 | img.style.visibility = 'visible'; 86 | 87 | if (params.loadMaxPercent > 0.0) { 88 | 89 | // allow for some changing of params per image 90 | var modParamPerImg = Object.create(params); 91 | if(modParamPerImg.randLoadIncrement) { 92 | // randomize load increment 93 | modParamPerImg.loadIncrement = Math.floor((Math.random() * 20) + 1); 94 | } 95 | 96 | // slowload using timeout since this is nicer to the browser :) 97 | setTimeout(slowloadModiferCallback(slowload, modParamPerImg), params.loadSpeed); 98 | } 99 | } 100 | } 101 | }; 102 | 103 | return { 104 | letsPrepareTheseImages: prepare, 105 | fixMyImagesLoadingSoFast: slowImages 106 | }; 107 | 108 | })(); -------------------------------------------------------------------------------- /js/geo.js: -------------------------------------------------------------------------------- 1 | function buildGeoPage() { 2 | console.log("Building geocities page"); 3 | 4 | const whois = document.getElementById("whois"); 5 | whois.innerHTML = whoisRoot.split(" Try")[0]; 6 | 7 | const portfolioTable = document.getElementById("portfolio"); 8 | const sortedPortfolioKeys = Object.keys(portfolio).sort((a, b) => 9 | portfolio[a].name.localeCompare(portfolio[b].name) 10 | ); 11 | for (const p of sortedPortfolioKeys) { 12 | const row = portfolioTable.insertRow(-1); 13 | const logoCell = row.insertCell(); 14 | const descriptionCell = row.insertCell(); 15 | const urlCell = row.insertCell(); 16 | 17 | logoCell.setAttribute("class", "portfolio-photo"); 18 | descriptionCell.setAttribute("class", "portfolio-description"); 19 | 20 | // of company logo 21 | const logoImgTag = document.createElement("img"); 22 | logoImgTag.setAttribute("src", `images/${p}.jpg`); 23 | logoImgTag.setAttribute("alt", `${portfolio[p].name}`); 24 | 25 | if (portfolio[p].url != "(inactive)") { 26 | // add logo w company link to table 27 | const logoLinkImgTag = document.createElement("a"); 28 | logoLinkImgTag.setAttribute("href", portfolio[p].url); 29 | logoLinkImgTag.setAttribute("target", `_blank`); 30 | logoLinkImgTag.setAttribute("alt", `${portfolio[p].name}`); 31 | logoLinkImgTag.appendChild(logoImgTag); 32 | logoCell.appendChild(logoLinkImgTag); 33 | 34 | // add company URL to table 35 | const urlATag = document.createElement("a"); 36 | urlATag.setAttribute("href", portfolio[p].url); 37 | urlATag.setAttribute("alt", `${portfolio[p].name}`); 38 | urlATag.setAttribute("target", "_blank"); 39 | urlATag.innerHTML = portfolio[p].url; 40 | urlCell.appendChild(urlATag); 41 | } else { 42 | // inactive company doesn't have links 43 | logoCell.appendChild(logoImgTag); 44 | 45 | urlCell.innerHTML = portfolio[p].url; 46 | } 47 | 48 | // add company description to table 49 | descriptionCell.innerHTML = portfolio[p].description; 50 | } 51 | 52 | const teamTable = document.getElementById("team"); 53 | for (t in team) { 54 | const row = teamTable.insertRow(-1); 55 | const photoCell = row.insertCell(); 56 | const nameCell = row.insertCell(); 57 | const titleCell = row.insertCell(); 58 | const descriptionCell = row.insertCell(); 59 | 60 | photoCell.setAttribute("class", "team-photo"); 61 | descriptionCell.setAttribute("class", "team-description"); 62 | 63 | const photoImgTag = document.createElement("img"); 64 | photoImgTag.setAttribute("src", `images/geo/${t}2.jpg`); 65 | photoImgTag.setAttribute("alt", `${team[t].name}`); 66 | photoCell.appendChild(photoImgTag); 67 | 68 | const linkedinATag = document.createElement("a"); 69 | linkedinATag.setAttribute("href", team[t].linkedin); 70 | linkedinATag.setAttribute("alt", `${team[t].name}`); 71 | linkedinATag.innerHTML = team[t].name; 72 | nameCell.appendChild(linkedinATag); 73 | 74 | titleCell.innerHTML = team[t].title; 75 | descriptionCell.innerHTML = team[t].description 76 | .replaceAll("\n\r", "
") 77 | .replaceAll("\t", "    "); 78 | } 79 | 80 | comcastifyjs.letsPrepareTheseImages(); 81 | comcastifyjs.fixMyImagesLoadingSoFast({ 82 | boxColor: "#000000", 83 | loadMaxPercent: 1.0, 84 | loadSpeed: 800, 85 | loadIncrement: 5, 86 | })(); 87 | } 88 | -------------------------------------------------------------------------------- /js/terminal-ext.js: -------------------------------------------------------------------------------- 1 | // TODO: make this a proper addon 2 | 3 | extend = (term) => { 4 | term.currentLine = ""; 5 | term.user = "guest"; 6 | term.host = "rootpc"; 7 | term.cwd = "~"; 8 | term.sep = ":"; 9 | term._promptChar = "$"; 10 | term.history = []; 11 | term.historyCursor = -1; 12 | term.pos = () => term._core.buffer.x - term._promptRawText().length - 1; 13 | term._promptRawText = () => 14 | `${term.user}${term.sep}${term.host} ${term.cwd} $`; 15 | term.deepLink = window.location.hash.replace("#", "").split("-").join(" "); 16 | 17 | term.promptText = () => { 18 | var text = term 19 | ._promptRawText() 20 | .replace(term.user, colorText(term.user, "user")) 21 | .replace(term.sep, colorText(term.sep, "")) 22 | .replace(term.host, colorText(term.host, "")) 23 | .replace(term.cwd, colorText(term.cwd, "hyperlink")) 24 | .replace(term._promptChar, colorText(term._promptChar, "prompt")); 25 | return text; 26 | }; 27 | 28 | term.timer = (ms) => new Promise((res) => setTimeout(res, ms)); 29 | 30 | term.dottedPrint = async (phrase, n, newline = true) => { 31 | term.write(phrase); 32 | 33 | for (let i = 0; i < n; i++) { 34 | await term.delayPrint(".", 1000); 35 | } 36 | if (newline) { 37 | term.write("\r\n"); 38 | } 39 | }; 40 | 41 | term.progressBar = async (t, msg) => { 42 | var r; 43 | 44 | if (msg) { 45 | term.write(msg); 46 | } 47 | term.write("\r\n["); 48 | 49 | for (let i = 0; i < term.cols / 2; i = i + 1) { 50 | r = Math.round((Math.random() * t) / 20); 51 | t = t - r; 52 | await term.delayPrint("█", r); 53 | } 54 | term.write("]\r\n"); 55 | }; 56 | 57 | term.delayPrint = async (str, t) => { 58 | await term.timer(t); 59 | term.write(str); 60 | }; 61 | 62 | term.delayStylePrint = async (str, t, wrap) => { 63 | await term.timer(t); 64 | term.stylePrint(str, wrap); 65 | }; 66 | 67 | term.prompt = (prefix = "\r\n", suffix = " ") => { 68 | term.write(`${prefix}${term.promptText()}${suffix}`); 69 | }; 70 | 71 | term.clearCurrentLine = (goToEndofHistory = false) => { 72 | term.write("\x1b[2K\r"); 73 | term.prompt("", " "); 74 | term.currentLine = ""; 75 | if (goToEndofHistory) { 76 | term.historyCursor = -1; 77 | term.scrollToBottom(); 78 | } 79 | }; 80 | 81 | term.setCurrentLine = (newLine, preserveCursor = false) => { 82 | const length = term.currentLine.length; 83 | term.clearCurrentLine(); 84 | term.currentLine = newLine; 85 | term.write(newLine); 86 | if (preserveCursor) { 87 | term.write("\x1b[D".repeat(length - term.pos())); 88 | } 89 | }; 90 | 91 | term.stylePrint = (text, wrap = true) => { 92 | // Hyperlinks 93 | const urlRegex = 94 | /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,24}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g; 95 | const urlMatches = text.matchAll(urlRegex); 96 | let allowWrapping = true; 97 | for (match of urlMatches) { 98 | allowWrapping = match[0].length < 76; 99 | text = text.replace(match[0], colorText(match[0], "hyperlink")); 100 | } 101 | 102 | // Text Wrap 103 | if (allowWrapping && wrap) { 104 | text = _wordWrap(text, Math.min(term.cols, 76)); 105 | } 106 | 107 | // Commands 108 | const cmds = Object.keys(commands); 109 | for (cmd of cmds) { 110 | const cmdMatches = text.matchAll(`%${cmd}%`); 111 | for (match of cmdMatches) { 112 | text = text.replace(match[0], colorText(cmd, "command")); 113 | } 114 | } 115 | 116 | term.writeln(text); 117 | }; 118 | 119 | term.printArt = (id) => { 120 | if (term.cols >= 40) { 121 | term.writeln(`\r\n${getArt(id)}\r\n`); 122 | } 123 | }; 124 | 125 | term.printLogoType = () => { 126 | term.writeln(term.cols >= 40 ? LOGO_TYPE : "[Root Ventures]\r\n"); 127 | }; 128 | 129 | term.openURL = (url, newWindow = true) => { 130 | term.stylePrint(`Opening ${url}`); 131 | if (term._initialized) { 132 | console.log(newWindow); 133 | if (newWindow) { 134 | window.open(url, "_blank"); 135 | } else { 136 | window.location.href = url; 137 | } 138 | } 139 | }; 140 | 141 | term.displayURL = (url) => { 142 | term.stylePrint(colorText(url, "hyperlink")); 143 | }; 144 | 145 | term.command = (line) => { 146 | const parts = line.split(/\s+/); 147 | const cmd = parts[0].toLowerCase(); 148 | const args = parts.slice(1, parts.length); 149 | const fn = commands[cmd]; 150 | if (typeof fn === "undefined") { 151 | term.stylePrint(`Command not found: ${cmd}. Try 'help' to get started.`); 152 | } else { 153 | return fn(args); 154 | } 155 | }; 156 | 157 | term.resizeListener = () => { 158 | term._initialized = false; 159 | term.init(term.user, true); 160 | term.runDeepLink(); 161 | for (c of term.history) { 162 | term.prompt("\r\n", ` ${c}\r\n`); 163 | term.command(c); 164 | } 165 | term.prompt(); 166 | term.scrollToBottom(); 167 | term._initialized = true; 168 | }; 169 | 170 | term.init = (user = "guest", preserveHistory = false) => { 171 | fitAddon.fit(); 172 | preloadASCIIArt(); 173 | preloadFiles(); 174 | term.reset(); 175 | term.printLogoType(); 176 | term.stylePrint( 177 | "Welcome to the Root Ventures terminal. Technical seed investors.", 178 | ); 179 | term.stylePrint( 180 | `Type ${colorText("help", "command")} to get started. Or type ${colorText("exit", "command")} for web version.`, 181 | false, 182 | ); 183 | term.stylePrint( 184 | `\r\nOpen jobs detected. Type ${colorText("jobs", "command")} for more info.`, 185 | false, 186 | ); 187 | 188 | term.user = user; 189 | if (!preserveHistory) { 190 | term.history = []; 191 | } 192 | term.focus(); 193 | }; 194 | 195 | term.runDeepLink = () => { 196 | if (term.deepLink != "") { 197 | term.command(term.deepLink); 198 | } 199 | }; 200 | }; 201 | 202 | // https://stackoverflow.com/questions/14484787/wrap-text-in-javascript 203 | // TODO: This doesn't work well at detecting newline 204 | function _wordWrap(str, maxWidth) { 205 | var newLineStr = "\r\n"; 206 | done = false; 207 | res = ""; 208 | while (str.length > maxWidth) { 209 | found = false; 210 | // Inserts new line at first whitespace of the line 211 | for (i = maxWidth - 1; i >= 0; i--) { 212 | if (_testWhite(str.charAt(i))) { 213 | res = res + [str.slice(0, i), newLineStr].join(""); 214 | str = str.slice(i + 1); 215 | found = true; 216 | break; 217 | } 218 | } 219 | // Inserts new line at maxWidth position, the word is too long to wrap 220 | if (!found) { 221 | res += [str.slice(0, maxWidth), newLineStr].join(""); 222 | str = str.slice(maxWidth); 223 | } 224 | } 225 | return res + str; 226 | } 227 | 228 | function _testWhite(x) { 229 | var white = new RegExp(/^\s$/); 230 | return white.test(x.charAt(0)); 231 | } 232 | -------------------------------------------------------------------------------- /js/terminal.js: -------------------------------------------------------------------------------- 1 | function runRootTerminal(term) { 2 | if (term._initialized) { 3 | return; 4 | } 5 | 6 | term.init(); 7 | term._initialized = true; 8 | term.locked = false; 9 | 10 | window.onload = (_) => { 11 | term.prompt(); 12 | term.runDeepLink(); 13 | 14 | window.addEventListener("resize", term.resizeListener); 15 | 16 | term.onData(e => { 17 | if (term._initialized && !term.locked) { 18 | switch (e) { 19 | case '\r': // Enter 20 | var exitStatus; 21 | term.currentLine = term.currentLine.trim(); 22 | const tokens = term.currentLine.split(" "); 23 | const cmd = tokens.shift(); 24 | const args = tokens.join(" "); 25 | 26 | term.writeln(""); 27 | 28 | if (term.currentLine.length > 0) { 29 | term.history.push(term.currentLine); 30 | exitStatus = term.command(term.currentLine); 31 | 32 | window.dataLayer = window.dataLayer || []; 33 | window.dataLayer.push({ 34 | "event": "commandSent", 35 | "command": cmd, 36 | "args": args, 37 | }); 38 | } 39 | 40 | if (exitStatus != 1) { 41 | term.prompt(); 42 | term.clearCurrentLine(true); 43 | } 44 | break; 45 | case '\u0001': // Ctrl+A 46 | term.write('\x1b[D'.repeat(term.pos())); 47 | break; 48 | case '\u0005': // Ctrl+E 49 | if (term.pos() < term.currentLine.length) { 50 | term.write('\x1b[C'.repeat(term.currentLine.length - term.pos())); 51 | } 52 | break; 53 | case '\u0003': // Ctrl+C 54 | term.prompt(); 55 | term.clearCurrentLine(true); 56 | break; 57 | case '\u0008': // Ctrl+H 58 | case '\u007F': // Backspace (DEL) 59 | // Do not delete the prompt 60 | if (term.pos() > 0) { 61 | const newLine = term.currentLine.slice(0, term.pos() - 1) + term.currentLine.slice(term.pos()); 62 | term.setCurrentLine(newLine, true) 63 | } 64 | break; 65 | case '\033[A': // up 66 | var h = [...term.history].reverse(); 67 | if (term.historyCursor < h.length - 1) { 68 | term.historyCursor += 1; 69 | term.setCurrentLine(h[term.historyCursor], false); 70 | } 71 | break; 72 | case '\033[B': // down 73 | var h = [...term.history].reverse(); 74 | if (term.historyCursor > 0) { 75 | term.historyCursor -= 1; 76 | term.setCurrentLine(h[term.historyCursor], false); 77 | } else { 78 | term.clearCurrentLine(true); 79 | } 80 | break; 81 | case '\033[C': // right 82 | if (term.pos() < term.currentLine.length) { 83 | term.write('\x1b[C'); 84 | } 85 | break; 86 | case '\033[D': // left 87 | if (term.pos() > 0) { 88 | term.write('\x1b[D'); 89 | } 90 | break; 91 | case '\t': // tab 92 | cmd = term.currentLine.split(" ")[0]; 93 | const rest = term.currentLine.slice(cmd.length).trim(); 94 | const autocompleteCmds = Object.keys(commands).filter((c) => c.startsWith(cmd)); 95 | var autocompleteArgs; 96 | 97 | // detect what to autocomplete 98 | if (autocompleteCmds && autocompleteCmds.length > 1) { 99 | const oldLine = term.currentLine; 100 | term.stylePrint(`\r\n${autocompleteCmds.sort().join(" ")}`); 101 | term.prompt(); 102 | term.setCurrentLine(oldLine); 103 | } else if (["cat", "tail", "less", "head", "open", "mv", "cp", "chown", "chmod"].includes(cmd)) { 104 | autocompleteArgs = _filesHere().filter((f) => f.startsWith(rest)); 105 | } else if (["whois", "finger", "groups"].includes(cmd)) { 106 | autocompleteArgs = Object.keys(team).filter((f) => f.startsWith(rest)); 107 | } else if (["man", "woman", "tldr"].includes(cmd)) { 108 | autocompleteArgs = Object.keys(portfolio).filter((f) => f.startsWith(rest)); 109 | } else if (["cd"].includes(cmd)) { 110 | autocompleteArgs = _filesHere().filter((dir) => dir.startsWith(rest) && !_DIRS[term.cwd].includes(dir)); 111 | } 112 | 113 | // do the autocompleting 114 | if (autocompleteArgs && autocompleteArgs.length > 1) { 115 | const oldLine = term.currentLine; 116 | term.writeln(`\r\n${autocompleteArgs.join(" ")}`); 117 | term.prompt(); 118 | term.setCurrentLine(oldLine); 119 | } else if (commands[cmd] && autocompleteArgs && autocompleteArgs.length > 0) { 120 | term.setCurrentLine(`${cmd} ${autocompleteArgs[0]}`); 121 | } else if (commands[cmd] && autocompleteArgs && autocompleteArgs.length == 0) { 122 | term.setCurrentLine(`${cmd} ${rest}`); 123 | } else if (autocompleteCmds && autocompleteCmds.length == 1) { 124 | term.setCurrentLine(`${autocompleteCmds[0]} `); 125 | } 126 | break; 127 | default: // Print all other characters 128 | const newLine = `${term.currentLine.slice(0, term.pos())}${e}${term.currentLine.slice(term.pos())}`; 129 | term.setCurrentLine(newLine, true); 130 | break; 131 | } 132 | term.scrollToBottom(); 133 | } 134 | }); 135 | }; 136 | 137 | } 138 | 139 | function colorText(text, color) { 140 | const colors = { 141 | "command": "\x1b[1;35m", 142 | "hyperlink": "\x1b[1;34m", 143 | "user": "\x1b[1;33m", 144 | "prompt": "\x1b[1;32m", 145 | "bold": "\x1b[1;37m" 146 | } 147 | return `${colors[color] || ""}${text}\x1b[0;38m`; 148 | } 149 | -------------------------------------------------------------------------------- /js/xterm-addon-fit.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://FitAddon/webpack/universalModuleDefinition","webpack://FitAddon/./src/FitAddon.ts","webpack://FitAddon/webpack/bootstrap","webpack://FitAddon/webpack/startup"],"names":["root","factory","exports","module","define","amd","self","activate","terminal","this","_terminal","dispose","fit","dims","proposeDimensions","core","_core","rows","cols","_renderService","clear","resize","element","parentElement","dimensions","actualCellWidth","actualCellHeight","parentElementStyle","window","getComputedStyle","parentElementHeight","parseInt","getPropertyValue","parentElementWidth","Math","max","elementStyle","availableHeight","availableWidth","viewport","scrollBarWidth","floor","FitAddon","__webpack_module_cache__","__webpack_require__","moduleId","__webpack_modules__"],"mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAkB,SAAID,IAEtBD,EAAe,SAAIC,IARrB,CASGK,MAAM,WACT,M,yGCSA,IAGA,aAGE,cA4DF,OA1DS,YAAAC,SAAP,SAAgBC,GACdC,KAAKC,UAAYF,GAGZ,YAAAG,QAAP,aAEO,YAAAC,IAAP,WACE,IAAMC,EAAOJ,KAAKK,oBAClB,GAAKD,GAASJ,KAAKC,UAAnB,CAKA,IAAMK,EAAQN,KAAKC,UAAkBM,MAGjCP,KAAKC,UAAUO,OAASJ,EAAKI,MAAQR,KAAKC,UAAUQ,OAASL,EAAKK,OACpEH,EAAKI,eAAeC,QACpBX,KAAKC,UAAUW,OAAOR,EAAKK,KAAML,EAAKI,SAInC,YAAAH,kBAAP,WACE,GAAKL,KAAKC,WAILD,KAAKC,UAAUY,SAAYb,KAAKC,UAAUY,QAAQC,cAAvD,CAKA,IAAMR,EAAQN,KAAKC,UAAkBM,MAErC,GAAuD,IAAnDD,EAAKI,eAAeK,WAAWC,iBAA6E,IAApDV,EAAKI,eAAeK,WAAWE,iBAA3F,CAIA,IAAMC,EAAqBC,OAAOC,iBAAiBpB,KAAKC,UAAUY,QAAQC,eACpEO,EAAsBC,SAASJ,EAAmBK,iBAAiB,WACnEC,EAAqBC,KAAKC,IAAI,EAAGJ,SAASJ,EAAmBK,iBAAiB,WAC9EI,EAAeR,OAAOC,iBAAiBpB,KAAKC,UAAUY,SAStDe,EAAkBP,GAPjBC,SAASK,EAAaJ,iBAAiB,gBACpCD,SAASK,EAAaJ,iBAAiB,oBAO3CM,EAAiBL,GANdF,SAASK,EAAaJ,iBAAiB,kBACxCD,SAASK,EAAaJ,iBAAiB,kBAKiBjB,EAAKwB,SAASC,eAK9E,MAJiB,CACftB,KAAMgB,KAAKC,IA7DI,EA6DcD,KAAKO,MAAMH,EAAiBvB,EAAKI,eAAeK,WAAWC,kBACxFR,KAAMiB,KAAKC,IA7DI,EA6DcD,KAAKO,MAAMJ,EAAkBtB,EAAKI,eAAeK,WAAWE,uBAI/F,EA/DA,GAAa,EAAAgB,aCrBTC,EAA2B,GCE/B,ODCA,SAASC,EAAoBC,GAE5B,GAAGF,EAAyBE,GAC3B,OAAOF,EAAyBE,GAAU3C,QAG3C,IAAIC,EAASwC,EAAyBE,GAAY,CAGjD3C,QAAS,IAOV,OAHA4C,EAAoBD,GAAU1C,EAAQA,EAAOD,QAAS0C,GAG/CzC,EAAOD,QCjBR0C,CAAoB,M","file":"xterm-addon-fit.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"FitAddon\"] = factory();\n\telse\n\t\troot[\"FitAddon\"] = factory();\n})(self, function() {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal, ITerminalAddon } from 'xterm';\n\ninterface ITerminalDimensions {\n /**\n * The number of rows in the terminal.\n */\n rows: number;\n\n /**\n * The number of columns in the terminal.\n */\n cols: number;\n}\n\nconst MINIMUM_COLS = 2;\nconst MINIMUM_ROWS = 1;\n\nexport class FitAddon implements ITerminalAddon {\n private _terminal: Terminal | undefined;\n\n constructor() {}\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n public dispose(): void {}\n\n public fit(): void {\n const dims = this.proposeDimensions();\n if (!dims || !this._terminal) {\n return;\n }\n\n // TODO: Remove reliance on private API\n const core = (this._terminal as any)._core;\n\n // Force a full render\n if (this._terminal.rows !== dims.rows || this._terminal.cols !== dims.cols) {\n core._renderService.clear();\n this._terminal.resize(dims.cols, dims.rows);\n }\n }\n\n public proposeDimensions(): ITerminalDimensions | undefined {\n if (!this._terminal) {\n return undefined;\n }\n\n if (!this._terminal.element || !this._terminal.element.parentElement) {\n return undefined;\n }\n\n // TODO: Remove reliance on private API\n const core = (this._terminal as any)._core;\n\n if (core._renderService.dimensions.actualCellWidth === 0 || core._renderService.dimensions.actualCellHeight === 0) {\n return undefined;\n }\n\n const parentElementStyle = window.getComputedStyle(this._terminal.element.parentElement);\n const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));\n const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));\n const elementStyle = window.getComputedStyle(this._terminal.element);\n const elementPadding = {\n top: parseInt(elementStyle.getPropertyValue('padding-top')),\n bottom: parseInt(elementStyle.getPropertyValue('padding-bottom')),\n right: parseInt(elementStyle.getPropertyValue('padding-right')),\n left: parseInt(elementStyle.getPropertyValue('padding-left'))\n };\n const elementPaddingVer = elementPadding.top + elementPadding.bottom;\n const elementPaddingHor = elementPadding.right + elementPadding.left;\n const availableHeight = parentElementHeight - elementPaddingVer;\n const availableWidth = parentElementWidth - elementPaddingHor - core.viewport.scrollBarWidth;\n const geometry = {\n cols: Math.max(MINIMUM_COLS, Math.floor(availableWidth / core._renderService.dimensions.actualCellWidth)),\n rows: Math.max(MINIMUM_ROWS, Math.floor(availableHeight / core._renderService.dimensions.actualCellHeight))\n };\n return geometry;\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// module exports must be returned from runtime so entry inlining is disabled\n// startup\n// Load entry module and return exports\nreturn __webpack_require__(775);\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /js/xterm-addon-web-links.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://WebLinksAddon/webpack/universalModuleDefinition","webpack://WebLinksAddon/webpack/bootstrap","webpack://WebLinksAddon/./src/WebLinksAddon.ts","webpack://WebLinksAddon/./src/WebLinkProvider.ts"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","strictUrlRegex","RegExp","start","handleLink","event","uri","newWindow","open","opener","location","href","console","warn","_handler","_options","_useLinkProvider","this","matchIndex","activate","terminal","_terminal","_linkProvider","registerLinkProvider","WebLinkProvider","_linkMatcherId","registerLinkMatcher","dispose","undefined","deregisterLinkMatcher","WebLinksAddon","_regex","provideLinks","y","callback","LinkComputer","computeLink","regex","handler","match","rex","source","flags","_translateBufferLineToStringWithWrap","line","startLineIndex","stringIndex","result","exec","text","log","indexOf","lastIndex","length","endX","endY","cols","range","x","end","push","lineIndex","trimRight","lineWrapsToNext","prevLinesToWrap","lineString","buffer","active","getLine","isWrapped","nextLine","translateToString","substring"],"mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAuB,cAAID,IAE3BD,EAAoB,cAAIC,IAR1B,CASGK,QAAQ,WACX,O,YCTE,IAAIC,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUP,QAGnC,IAAIC,EAASI,EAAiBE,GAAY,CACzCC,EAAGD,EACHE,GAAG,EACHT,QAAS,IAUV,OANAU,EAAQH,GAAUI,KAAKV,EAAOD,QAASC,EAAQA,EAAOD,QAASM,GAG/DL,EAAOQ,GAAI,EAGJR,EAAOD,QA0Df,OArDAM,EAAoBM,EAAIF,EAGxBJ,EAAoBO,EAAIR,EAGxBC,EAAoBQ,EAAI,SAASd,EAASe,EAAMC,GAC3CV,EAAoBW,EAAEjB,EAASe,IAClCG,OAAOC,eAAenB,EAASe,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEV,EAAoBgB,EAAI,SAAStB,GACX,oBAAXuB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAenB,EAASuB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAenB,EAAS,aAAc,CAAEyB,OAAO,KAQvDnB,EAAoBoB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQnB,EAAoBmB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFAxB,EAAoBgB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOnB,EAAoBQ,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRvB,EAAoB2B,EAAI,SAAShC,GAChC,IAAIe,EAASf,GAAUA,EAAO2B,WAC7B,WAAwB,OAAO3B,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAK,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRV,EAAoBW,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG7B,EAAoBgC,EAAI,GAIjBhC,EAAoBA,EAAoBiC,EAAI,G,uGC5ErD,WAoBMC,EAAiB,IAAIC,OAAOC,+SAElC,SAASC,EAAWC,EAAmBC,GACrC,IAAMC,EAAY1C,OAAO2C,OACrBD,GACFA,EAAUE,OAAS,KACnBF,EAAUG,SAASC,KAAOL,GAE1BM,QAAQC,KAAK,uDAIjB,iBAKE,WACUC,EACAC,EACAC,QAFA,IAAAF,MAAA,QACA,IAAAC,MAAA,SACA,IAAAC,OAAA,GAFA,KAAAF,WACA,KAAAC,WACA,KAAAC,mBAERC,KAAKF,SAASG,WAAa,EAqB/B,OAlBS,YAAAC,SAAP,SAAgBC,GACdH,KAAKI,UAAYD,EAEbH,KAAKD,kBAAoB,yBAA0BC,KAAKI,UAC1DJ,KAAKK,cAAgBL,KAAKI,UAAUE,qBAAqB,IAAI,EAAAC,gBAAgBP,KAAKI,UAAWpB,EAAgBgB,KAAKH,WAGlHG,KAAKQ,eAAkBR,KAAKI,UAAuBK,oBAAoBzB,EAAgBgB,KAAKH,SAAUG,KAAKF,WAIxG,YAAAY,QAAP,W,WAC8BC,IAAxBX,KAAKQ,qBAAmDG,IAAnBX,KAAKI,WAC5CJ,KAAKI,UAAUQ,sBAAsBZ,KAAKQ,gBAG1B,QAAlB,EAAAR,KAAKK,qBAAa,SAAEK,WAExB,EA/BA,GAAa,EAAAG,iB,sHC/Bb,iBAEE,WACmBT,EACAU,EACAjB,GAFA,KAAAO,YACA,KAAAU,SACA,KAAAjB,WAQrB,OAHS,YAAAkB,aAAP,SAAoBC,EAAWC,GAC7BA,EAASC,EAAaC,YAAYH,EAAGhB,KAAKc,OAAQd,KAAKI,UAAWJ,KAAKH,YAE3E,EAbA,GAAa,EAAAU,kBAeb,+BA8FA,OA7FgB,EAAAY,YAAd,SAA0BH,EAAWI,EAAejB,EAAoBkB,GAStE,IARA,IAIIC,EAJEC,EAAM,IAAItC,OAAOmC,EAAMI,QAASJ,EAAMK,OAAS,IAAM,KAErD,EAAyBP,EAAaQ,qCAAqCV,EAAI,GAAG,EAAOb,GAAxFwB,EAAI,KAAEC,EAAc,KAGvBC,GAAe,EACbC,EAAkB,GAEY,QAA5BR,EAAQC,EAAIQ,KAAKJ,KAAiB,CACxC,IAAMK,EAAOV,EAAM,GACnB,IAAKU,EAAM,CAGTrC,QAAQsC,IAAI,gDACZ,MASF,GAFAJ,EAAcF,EAAKO,QAAQF,EAAMH,EAAc,GAC/CN,EAAIY,UAAYN,EAAcG,EAAKI,OAC/BP,EAAc,EAEhB,MAMF,IAHA,IAAIQ,EAAOR,EAAcG,EAAKI,OAC1BE,EAAOV,EAAiB,EAErBS,EAAOlC,EAASoC,MACrBF,GAAQlC,EAASoC,KACjBD,IAGF,IAAME,EAAQ,CACZtD,MAAO,CACLuD,EAAGZ,EAAc,EACjBb,EAAGY,EAAiB,GAEtBc,IAAK,CACHD,EAAGJ,EACHrB,EAAGsB,IAIPR,EAAOa,KAAK,CAAEH,MAAK,EAAER,KAAI,EAAE9B,SAAUmB,IAGvC,OAAOS,GASM,EAAAJ,qCAAf,SAAoDkB,EAAmBC,EAAoB1C,GACzF,IACI2C,EACAC,EAFAC,EAAa,GAIjB,EAAG,CAED,KADMrB,EAAOxB,EAAS8C,OAAOC,OAAOC,QAAQP,IAE1C,MAGEjB,EAAKyB,WACPR,IAGFG,EAAkBpB,EAAKyB,gBAChBL,GAET,IAAMnB,EAAiBgB,EAEvB,EAAG,CACD,IAEMjB,EAFA0B,EAAWlD,EAAS8C,OAAOC,OAAOC,QAAQP,EAAY,GAG5D,GAFAE,IAAkBO,GAAWA,EAASD,YAChCzB,EAAOxB,EAAS8C,OAAOC,OAAOC,QAAQP,IAE1C,MAEFI,GAAcrB,EAAK2B,mBAAmBR,GAAmBD,GAAWU,UAAU,EAAGpD,EAASoC,MAC1FK,UACOE,GAET,MAAO,CAACE,EAAYpB,IAExB,EA9FA,GAAa,EAAAV","file":"xterm-addon-web-links.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"WebLinksAddon\"] = factory();\n\telse\n\t\troot[\"WebLinksAddon\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Terminal, ILinkMatcherOptions, ITerminalAddon, IDisposable } from 'xterm';\nimport { WebLinkProvider } from './WebLinkProvider';\n\nconst protocolClause = '(https?:\\\\/\\\\/)';\nconst domainCharacterSet = '[\\\\da-z\\\\.-]+';\nconst negatedDomainCharacterSet = '[^\\\\da-z\\\\.-]+';\nconst domainBodyClause = '(' + domainCharacterSet + ')';\nconst tldClause = '([a-z\\\\.]{2,6})';\nconst ipClause = '((\\\\d{1,3}\\\\.){3}\\\\d{1,3})';\nconst localHostClause = '(localhost)';\nconst portClause = '(:\\\\d{1,5})';\nconst hostClause = '((' + domainBodyClause + '\\\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';\nconst pathCharacterSet = '(\\\\/[\\\\/\\\\w\\\\.\\\\-%~:+@]*)*([^:\"\\'\\\\s])';\nconst pathClause = '(' + pathCharacterSet + ')?';\nconst queryStringHashFragmentCharacterSet = '[0-9\\\\w\\\\[\\\\]\\\\(\\\\)\\\\/\\\\?\\\\!#@$%&\\'*+,:;~\\\\=\\\\.\\\\-]*';\nconst queryStringClause = '(\\\\?' + queryStringHashFragmentCharacterSet + ')?';\nconst hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';\nconst negatedPathCharacterSet = '[^\\\\/\\\\w\\\\.\\\\-%]+';\nconst bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;\nconst start = '(?:^|' + negatedDomainCharacterSet + ')(';\nconst end = ')($|' + negatedPathCharacterSet + ')';\nconst strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);\n\nfunction handleLink(event: MouseEvent, uri: string): void {\n const newWindow = window.open();\n if (newWindow) {\n newWindow.opener = null;\n newWindow.location.href = uri;\n } else {\n console.warn('Opening link blocked as opener could not be cleared');\n }\n}\n\nexport class WebLinksAddon implements ITerminalAddon {\n private _linkMatcherId: number | undefined;\n private _terminal: Terminal | undefined;\n private _linkProvider: IDisposable | undefined;\n\n constructor(\n private _handler: (event: MouseEvent, uri: string) => void = handleLink,\n private _options: ILinkMatcherOptions = {},\n private _useLinkProvider: boolean = false\n ) {\n this._options.matchIndex = 1;\n }\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n\n if (this._useLinkProvider && 'registerLinkProvider' in this._terminal) {\n this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, strictUrlRegex, this._handler));\n } else {\n // TODO: This should be removed eventually\n this._linkMatcherId = (this._terminal as Terminal).registerLinkMatcher(strictUrlRegex, this._handler, this._options);\n }\n }\n\n public dispose(): void {\n if (this._linkMatcherId !== undefined && this._terminal !== undefined) {\n this._terminal.deregisterLinkMatcher(this._linkMatcherId);\n }\n\n this._linkProvider?.dispose();\n }\n}\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ILinkProvider, IBufferCellPosition, ILink, Terminal } from 'xterm';\n\nexport class WebLinkProvider implements ILinkProvider {\n\n constructor(\n private readonly _terminal: Terminal,\n private readonly _regex: RegExp,\n private readonly _handler: (event: MouseEvent, uri: string) => void\n ) {\n\n }\n\n public provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void {\n callback(LinkComputer.computeLink(y, this._regex, this._terminal, this._handler));\n }\n}\n\nexport class LinkComputer {\n public static computeLink(y: number, regex: RegExp, terminal: Terminal, handler: (event: MouseEvent, uri: string) => void): ILink[] {\n const rex = new RegExp(regex.source, (regex.flags || '') + 'g');\n\n const [line, startLineIndex] = LinkComputer._translateBufferLineToStringWithWrap(y - 1, false, terminal);\n\n let match;\n let stringIndex = -1;\n const result: ILink[] = [];\n\n while ((match = rex.exec(line)) !== null) {\n const text = match[1];\n if (!text) {\n // something matched but does not comply with the given matchIndex\n // since this is most likely a bug the regex itself we simply do nothing here\n console.log('match found without corresponding matchIndex');\n break;\n }\n\n // Get index, match.index is for the outer match which includes negated chars\n // therefore we cannot use match.index directly, instead we search the position\n // of the match group in text again\n // also correct regex and string search offsets for the next loop run\n stringIndex = line.indexOf(text, stringIndex + 1);\n rex.lastIndex = stringIndex + text.length;\n if (stringIndex < 0) {\n // invalid stringIndex (should not have happened)\n break;\n }\n\n let endX = stringIndex + text.length;\n let endY = startLineIndex + 1;\n\n while (endX > terminal.cols) {\n endX -= terminal.cols;\n endY++;\n }\n\n const range = {\n start: {\n x: stringIndex + 1,\n y: startLineIndex + 1\n },\n end: {\n x: endX,\n y: endY\n }\n };\n\n result.push({ range, text, activate: handler });\n }\n\n return result;\n }\n\n /**\n * Gets the entire line for the buffer line\n * @param line The line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param terminal The terminal\n */\n private static _translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean, terminal: Terminal): [string, number] {\n let lineString = '';\n let lineWrapsToNext: boolean;\n let prevLinesToWrap: boolean;\n\n do {\n const line = terminal.buffer.active.getLine(lineIndex);\n if (!line) {\n break;\n }\n\n if (line.isWrapped) {\n lineIndex--;\n }\n\n prevLinesToWrap = line.isWrapped;\n } while (prevLinesToWrap);\n\n const startLineIndex = lineIndex;\n\n do {\n const nextLine = terminal.buffer.active.getLine(lineIndex + 1);\n lineWrapsToNext = nextLine ? nextLine.isWrapped : false;\n const line = terminal.buffer.active.getLine(lineIndex);\n if (!line) {\n break;\n }\n lineString += line.translateToString(!lineWrapsToNext && trimRight).substring(0, terminal.cols);\n lineIndex++;\n } while (lineWrapsToNext);\n\n return [lineString, startLineIndex];\n }\n}\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rootvc-cli-website", 3 | "version": "0.1.0", 4 | "description": "Root Ventures' awesome website", 5 | "dependencies": { 6 | "aalib.js": "^2.0.0", 7 | "ai": "^3.0.18", 8 | "netlify-cli": "^6.14.7", 9 | "xterm": "^4.10.0", 10 | "xterm-addon-fit": "^0.5.0", 11 | "xterm-addon-web-links": "^0.4.0" 12 | }, 13 | "license": "MIT", 14 | "repository": { 15 | "type": "git", 16 | "url": "git@github.com:rootvc/cli-website.git" 17 | }, 18 | "scripts": { 19 | "build": "npm install && mkdir -p ./css && cp node_modules/xterm/css/*.css ./css && mkdir -p ./js && cp node_modules/xterm*/lib/*.js* ./js && cp node_modules/aalib.js/dist/aalib.js* ./js", 20 | "start": "netlify dev" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /welcome.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Root Ventures 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 41 | 42 | 43 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 97 | 98 | 99 |

100 | 101 | 102 | 103 |

104 | 105 |

106 | < Back 107 |

108 | 109 |


110 | 111 |
112 | 113 | 114 |

115 | R 116 | o 117 | o 118 | t 119 |   120 | V 121 | e 122 | n 123 | t 124 | u 125 | r 126 | e 127 | s 128 |

129 |

Seeding bold engineers

130 |

131 | 132 | Seed stage venture capital firm investing in hard tech. 133 | 134 |

135 |

136 | San Francisco, CA 137 | 138 |

139 | 145 |
146 | 147 |
148 | 149 |

About Us

150 |

151 | 152 |
153 |
154 | 155 |
156 |
157 | 158 |
159 |

160 | 161 | Portfolio 162 | 163 |

164 |
170 |
171 | 172 |
173 |    174 |    175 | 176 |
177 | 178 |
179 |

Team

180 |
186 |
187 | 188 |
189 |
190 | 191 |
192 |

193 | 194 | 220 | 221 |
222 | 223 |
224 | 225 |

226 | 227 | 230 | 231 | 232 | 240 | 241 | 242 | 243 | --------------------------------------------------------------------------------