commit 6383b52083efe5725c5944451c8132f015826a95
Author: bckelley <>
Date: Thu Oct 31 15:14:36 2024 -0500
init commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e072899
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.env
+bckelleyResume.docx
+app.js
+package*
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..8f2dd59
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,12 @@
+# Terminal Portfolio
+
+A simple Express.js application for a terminal portfolio.
+
+## Installation
+
+Clone the repository and run:
+
+```bash
+npm install
+npm start
+```
diff --git a/src/css/style.css b/src/css/style.css
new file mode 100644
index 0000000..ff9f464
--- /dev/null
+++ b/src/css/style.css
@@ -0,0 +1,131 @@
+body {
+ margin: 0;
+ padding: 15px 20px;
+ min-height: 99%;
+ width: 100%;
+ min-width: 550px;
+ color: #519975;
+ background: #211D1B;
+ font-family: cursor, monospace;
+ overflow-x: hidden;
+}
+::selection {
+ color: #211830;
+ background-color: #519975;
+}
+::-moz-selection {
+ color: #211830;
+ background-color: #519975;
+}
+textarea {
+ left: -1000px;
+ position: absolute;
+}
+b {
+ font-weight: bold;
+ text-decoration: underline;
+}
+/* Cursor Start */
+.cursor {
+ font-size: 12px;
+ color: #73ABAD;
+ background-color: #73ABAD;
+ position: relative;
+ opacity: 1;
+ height: 1.5em;
+ width: 10px;
+ max-width: 10px;
+ transform: translateY(4px);
+ overflow: hidden;
+ text-indent: -5px;
+ display: inline-block;
+ text-decoration: blink;
+ animation: blinker 1s linear infinite;
+}
+@keyframes blinker {
+ 50% {
+ opacity: 0;
+ }
+}
+#command {
+ cursor: text;
+ height: 50px;
+ color: #73ABAD;
+}
+#liner {
+ line-height: 1.3em;
+ margin-top: -2px;
+ animation: show 0.5s ease forwards;
+ animation-delay: 1.2s;
+ opacity: 0;
+}
+#liner::before {
+ color: #519975;
+ content: "visitor@bckelley.com:~$";
+}
+#liner.password::before {
+ content: "Password:";
+}
+@keyframes show {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+/* Cursor End */
+p {
+ display: block;
+ line-height: 1.3em;
+ margin: 0;
+ overflow: hidden;
+ white-space: nowrap;
+ margin: 0;
+ letter-spacing: 0.05em;
+ animation: typing 0.5s steps(30, end);
+}
+.no-animation {
+ animation: typing 0 steps(30, end);
+}
+.margin {
+ margin-left: 20px;
+}
+@keyframes typing {
+ from {
+ width: 0;
+ }
+ to {
+ width: 100%;
+ }
+}
+.index {
+ color: #DCDCCC;
+}
+.color2 {
+ color: #B89076;
+}
+.command {
+ color: #73ABAD;
+ text-shadow: 0 0 5px #73ABAD;
+}
+.error {
+ color: #B89076;
+}
+.white {
+ color: #fff;
+}
+.inherit,
+a {
+ color: #9C8394;
+}
+a {
+ text-decoration: inherit;
+}
+a:hover {
+ background: #73ABAD;
+ color: #211830;
+}
+a:focus {
+ outline: 0;
+}
\ No newline at end of file
diff --git a/src/html/favicon.ico b/src/html/favicon.ico
new file mode 100644
index 0000000..b62d3cf
Binary files /dev/null and b/src/html/favicon.ico differ
diff --git a/src/html/index.html b/src/html/index.html
new file mode 100644
index 0000000..68f74d2
--- /dev/null
+++ b/src/html/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+ bckelley | Terminal
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/js/caret.js b/src/js/caret.js
new file mode 100644
index 0000000..c5112b2
--- /dev/null
+++ b/src/js/caret.js
@@ -0,0 +1,38 @@
+function $(elid) {
+ return document.getElementById(elid);
+ }
+
+var cursor;
+window.onload = init;
+
+function init() {
+ cursor = $("cursor");
+ cursor.style.left = "0px";
+}
+
+function nl2br(txt) {
+ return txt.replace(/\n/g, '');
+}
+
+function typeIt(from, e) {
+ e = e || window.event;
+ var w = $("typer");
+ var tw = from.value;
+ if (!pw){
+ w.innerHTML = nl2br(tw);
+ }
+}
+
+function moveIt(count, e) {
+ e = e || window.event;
+ var keycode = e.keyCode || e.which;
+ if (keycode == 37 && parseInt(cursor.style.left) >= (0 - ((count - 1) * 10))) {
+ cursor.style.left = parseInt(cursor.style.left) - 10 + "px";
+ } else if (keycode == 39 && (parseInt(cursor.style.left) + 10) <= 0) {
+ cursor.style.left = parseInt(cursor.style.left) + 10 + "px";
+ }
+}
+
+function alert(txt) {
+ console.log(txt);
+}
\ No newline at end of file
diff --git a/src/js/commands.js b/src/js/commands.js
new file mode 100644
index 0000000..c3a048a
--- /dev/null
+++ b/src/js/commands.js
@@ -0,0 +1,101 @@
+var youtube = "";
+var twitter = "";
+var instagram = "";
+var threads = "";
+var github = "https://github.com/bckelley/";
+var linkedin = "https://www.linkedin.com/in/bckelley2/";
+var password = "phpRulez";
+var email = 'mailto:admin@bradonckelley.me';
+
+whois = [
+ "
",
+ "Hey! My name is Bradon 👋 and I am a back-end developer with a passion for PHP and technology.",
+ "I have 12 of experience and have worked on projects like my SimplePHPDB which can read about on github.",
+ "You can connect with me on linkedin or check out my work on github",
+ "
"
+];
+
+whoami = [
+ "
",
+ "The paradox of “Who am I?” is a labyrinth with no map, yet we tirelessly",
+ "explore its winding paths. Each step reveals a new facet of ourselves, a",
+ "reflection in the ever-shifting mirror of experience. And so, the journey",
+ "becomes the answer, the quest for self-discovery a tapestry woven from the",
+ "threads of existence.",
+ "
"
+];
+
+social = [
+ "
",
+ (youtube !== "") ? 'youtube youtube/' + "" : '',
+ (twitter !== "") ? 'twitter twitter/' + '' : '',
+ (linkedin !== "") ? 'linkedin linkedin/bckelley' + "" : '',
+ (instagram !== "") ? 'instagram instagram/' + '' : '',
+ (threads !== "") ? 'threads threads/' + '' : '',
+ (github !== "") ? 'github github/bckelley' + "" : '',
+ "
"
+];
+
+secret = [
+ "
",
+ "sudo We trust you have received the usual lecture from the local",
+ " System Administrator. It usually boils down to these three things: ",
+ " #1) Respect the privacy of others. ",
+ " #2) Think before you type. ",
+ " #3) With great power comes great responsibility. ",
+ "
"
+];
+
+projects = [
+ "
",
+ "Still curating... most projects are offline, on GitHub, or confidential.",
+ (github !== "") ? '[ github/todo-list ]: github/bckelley/todo-list' + "" : '',
+ (github !== "") ? '[ github/RouteEaseMVC ]: github/bckelley/TouteEaseMVC' + "" : '',
+ (github !== "") ? '[ github/SimplePHPDB ]: github/bckelley/SimplePHPDB' + "" : '',
+// (github !== "") ? '[ github/ ]: github/bckelley/' + "" : '',
+ "
"
+];
+
+help = [
+ "
",
+ 'whois Who is bckelley?',
+ 'whoami Who are you?',
+ (youtube !== "")?'video View YouTube videos': '',
+ 'social Display social networks',
+ 'secret Find the password',
+ 'projects View coding projects',
+ 'history View command history',
+ 'help You obviously already know what this does',
+ 'email Do not email me',
+ 'clear Clear terminal',
+ 'banner Display the header',
+ "
",
+];
+
+license = [
+ '
',
+ 'bckelley Terminal Portfolio by bckelley is licensed under
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International 



'
+];
+
+
+banner = [
+ 'Bradon Kelley (BK) Not A Corporation. All rights reserved.',
+ ' ',
+ ' ,dPYb, ,dPYb, ,dPYb, ,dPYb, ',
+ ' IP\'`Yb IP\'`Yb IP\'`Yb IP\'`Yb ',
+ ' I8 8I I8 8I I8 8I I8 8I ',
+ ' I8 8\' I8 8bgg, I8 8\' I8 8\' ',
+ ' I8 dP ,gggg, I8 dP" "8 ,ggg, I8 dP I8 dP ,ggg, gg gg ',
+ ' I8dP 88gg dP" "Yb I8d8bggP" i8" "8i I8dP I8dP i8" "8i I8 8I ',
+ ' I8P 8I i8\' I8P\' "Yb, I8, ,8I I8P I8P I8, ,8I I8, ,8I ',
+ ' ,d8b, ,8I ,d8,_ _,d8 `Yb, `YbadP\' ,d8b,_ ,d8b,_ `YbadP\' ,d8b, ,d8I ',
+ ' 8P\'"Y88P"\' P""Y8888PP88P Y8888P"Y8888P\'"Y888P\'"Y88888P"Y888P""Y88P"888 ',
+ ' ,d8I\' ',
+ ' ,dP\'8I ',
+ ' ,8" 8I ',
+ ' I8 8I ',
+ ' `8, ,8I ',
+ ' `Y8P\' ',
+ 'Welcome to my interactive web terminal.',
+ 'For a list of available commands, type \'help\'.',
+];
\ No newline at end of file
diff --git a/src/js/main.js b/src/js/main.js
new file mode 100644
index 0000000..e10514a
--- /dev/null
+++ b/src/js/main.js
@@ -0,0 +1,193 @@
+var before = document.getElementById("before");
+var liner = document.getElementById("liner");
+var command = document.getElementById("typer");
+var textarea = document.getElementById("texter");
+var terminal = document.getElementById("terminal");
+
+var git = 0;
+var pw = false;
+let pwd = false;
+var commands = [];
+
+setTimeout(function() {
+ loopLines(banner, "", 80);
+ textarea.focus();
+}, 100);
+
+window.addEventListener("keyup", enterKey);
+
+console.log(
+ "%cYou hacked my password!😠",
+ "color: #04ff00; font-weight: bold; font-size: 24px;"
+);
+console.log("%cPassword: '" + password + "' - I wonder what it does?🤔", "color: grey");
+
+//init
+textarea.value = "";
+command.innerHTML = textarea.value;
+
+function enterKey(e) {
+ if (e.keyCode == 181) {
+ document.location.reload(true);
+ }
+ if (pw) {
+ let et = "*";
+ let w = textarea.value.length;
+ command.innerHTML = et.repeat(w);
+ if (textarea.value === password) {
+ pwd = true;
+ }
+ if (pwd && e.keyCode == 13) {
+ loopLines(secret, "color2 margin", 120);
+ command.innerHTML = "";
+ textarea.value = "";
+ pwd = false;
+ pw = false;
+ liner.classList.remove("password");
+ } else if (e.keyCode == 13) {
+ addLine("Wrong password", "error", 0);
+ command.innerHTML = "";
+ textarea.value = "";
+ pw = false;
+ liner.classList.remove("password");
+ }
+ } else {
+ if (e.keyCode == 13) {
+ commands.push(command.innerHTML);
+ git = commands.length;
+ addLine("visitor@bckelley.com:~$ " + command.innerHTML, "no-animation", 0);
+ commander(command.innerHTML.toLowerCase());
+ command.innerHTML = "";
+ textarea.value = "";
+ }
+ if (e.keyCode == 38 && git != 0) {
+ git -= 1;
+ textarea.value = commands[git];
+ command.innerHTML = textarea.value;
+ }
+ if (e.keyCode == 40 && git != commands.length) {
+ git += 1;
+ if (commands[git] === undefined) {
+ textarea.value = "";
+ } else {
+ textarea.value = commands[git];
+ }
+ command.innerHTML = textarea.value;
+ }
+ }
+}
+
+function commander(cmd) {
+ switch (cmd.toLowerCase()) {
+ case "help":
+ loopLines(help, "color2 margin", 80);
+ break;
+ case "whois":
+ loopLines(whois, "color2 margin", 80);
+ break;
+ case "whoami":
+ loopLines(whoami, "color2 margin", 80);
+ break;
+ case "video":
+ addLine("Opening YouTube...", "color2", 80);
+ newTab(youtube);
+ break;
+ case "sudo":
+ addLine("Oh no, you're not admin...", "color2", 80);
+ setTimeout(function() {
+ window.open('https://youtu.be/uRGljemfwUE?si=V-SJLK5v-Dj9FIE3');
+ }, 1000);
+ break;
+ case "social":
+ loopLines(social, "color2 margin", 80);
+ break;
+ case "secret":
+ liner.classList.add("password");
+ pw = true;
+ break;
+ case "projects":
+ loopLines(projects, "color2 margin", 80);
+ break;
+ case "password":
+ addLine(" Lol! You're joking, right? You\'re gonna have to try harder than that!😂", "error", 100);
+ break;
+ case "history":
+ addLine("
", "", 0);
+ loopLines(commands, "color2", 80);
+ addLine("
", "command", 80 * commands.length + 50);
+ break;
+ case "email":
+ addLine(`Opening ${email}...`, "color2", 80);
+ newTab(email);
+ break;
+ case "clear":
+ setTimeout(function() {
+ terminal.innerHTML = '';
+ before = document.getElementById("before");
+ }, 1);
+ break;
+ case "banner":
+ loopLines(banner, "", 80);
+ break;
+ // socials
+ case "youtube":
+ addLine("Opening YouTube...", "color2", 80);
+ newTab(youtube);
+ break;
+ case "twitter":
+ addLine("Opening Twitter...", "color2", 0);
+ newTab(twitter);
+ break;
+ case "linkedin":
+ addLine("Opening LinkedIn...", "color2", 0);
+ newTab(linkedin);
+ break;
+ case "instagram":
+ addLine("Opening Instagram...", "color2", 0);
+ newTab(instagram);
+ break;
+ case "github":
+ addLine("Opening GitHub...", "color2", 0);
+ newTab(github);
+ break;
+ case "license":
+ loopLines(license, "", 80);
+ break;
+ default:
+ addLine("Command not found. For a list of commands, type 'help'.", "error", 100);
+ break;
+ }
+}
+
+function newTab(link) {
+ setTimeout(function() {
+ window.open(link, "_blank");
+ }, 500);
+}
+
+function addLine(text, style, time) {
+ var t = "";
+ for (let i = 0; i < text.length; i++) {
+ if (text.charAt(i) == " " && text.charAt(i + 1) == " ") {
+ t += " ";
+ i++;
+ } else {
+ t += text.charAt(i);
+ }
+ }
+ setTimeout(function() {
+ var next = document.createElement("p");
+ next.innerHTML = t;
+ next.className = style;
+
+ before.parentNode.insertBefore(next, before);
+
+ window.scrollTo(0, document.body.offsetHeight);
+ }, time);
+}
+
+function loopLines(name, style, time) {
+ name.forEach(function(item, index) {
+ addLine(item, style, index * time);
+ });
+}