diff --git a/config.js b/config.js
new file mode 100644
index 0000000..e3d79e1
--- /dev/null
+++ b/config.js
@@ -0,0 +1,5 @@
+config = {
+ prompt: 'user@browser $ ',
+ wallpaper: './src/img/background.jpg'
+}
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..1b2cb7f
--- /dev/null
+++ b/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+ Startpage
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/css/style.css b/src/css/style.css
new file mode 100644
index 0000000..eb32c86
--- /dev/null
+++ b/src/css/style.css
@@ -0,0 +1,50 @@
+@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap');
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Source Code Pro', monospace;
+ color: #e3e3e3;
+}
+
+#main {
+ width: 100%;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-size: cover;
+}
+
+#terminal {
+ width: 40%;
+ height: 60%;
+ overflow-y: scroll;
+ cursor: text;
+ padding: 1em;
+ border: #237e99 3px solid;
+ border-radius: 1em;
+ background-color: #252625d1;
+ backdrop-filter: blur(8px);
+}
+
+.line {
+ min-height: 1.5em;
+}
+
+.red {
+ color: #c22f2f;
+}
+
+#command-line input {
+ width: 70%;
+ background: none;
+ color: inherit;
+ font-family: inherit;
+ font-size: 1em;
+ border: none;
+}
+
+#command-line input:focus {
+ outline: none;
+}
diff --git a/src/img/background.jpg b/src/img/background.jpg
new file mode 100644
index 0000000..e33dcb2
Binary files /dev/null and b/src/img/background.jpg differ
diff --git a/src/js/commands.js b/src/js/commands.js
new file mode 100644
index 0000000..5303772
--- /dev/null
+++ b/src/js/commands.js
@@ -0,0 +1,49 @@
+const commands = {
+ go: (target) => {
+ if (target == '') {
+ _print('No target given!', color = 'red');
+ } else {
+ if (!target.match(/^https?:\/\/.+/g)) {
+ target = 'http://' + target;
+ }
+ window.open(target, "_self");
+ }
+ },
+ google: (query) => {
+ if (query == '') {
+ window.open("https://google.com/", "_self");
+ } else {
+ window.open("https://google.com/search?q=" + query, "_self");
+ }
+ },
+ reddit: (subreddit) => {
+ if (subreddit == '') {
+ window.open("https://reddit.com/", "_self");
+ } else {
+ window.open("https://reddit.com/r/" + subreddit, "_self");
+ }
+ },
+ print: (string) => {
+ _print(string);
+ },
+ clear: () => {
+ _clear();
+ },
+ date: () => {
+ _print('26/04/2022')
+ },
+ clock: () => {
+ const date = new Date();
+ const hours = date.getHours();
+ const minutes = date.getMinutes();
+ _print(hours + ':' + minutes);
+ },
+ show_commands: () => {
+ let availableCommands = Object.keys(commands);
+ let output = '';
+ availableCommands.forEach((cmd) => {
+ output += cmd + ' ';
+ });
+ _print(output);
+ }
+}
diff --git a/src/js/terminal.js b/src/js/terminal.js
new file mode 100644
index 0000000..f188843
--- /dev/null
+++ b/src/js/terminal.js
@@ -0,0 +1,25 @@
+const main = document.querySelector('#main');
+const terminal = document.querySelector('#terminal');
+const prompt = document.querySelector('#prompt');
+const commandInput = document.querySelector('#command-line input');
+
+commandInput.addEventListener('keypress', (event) => {
+ if (event.keyCode === 13) {
+ event.preventDefault();
+ rawEntry = commandInput.value;
+ _execute(rawEntry);
+ commandInput.value = '';
+ };
+});
+
+
+// Set prompt text
+prompt.innerText = config.prompt;
+
+// Set background
+main.style.backgroundImage = `url('${config.wallpaper}')`;
+
+// Set events
+terminal.addEventListener('click', focusToPrompt);
+window.addEventListener('load', focusToPrompt);
+
diff --git a/src/js/utils.js b/src/js/utils.js
new file mode 100644
index 0000000..0d838fa
--- /dev/null
+++ b/src/js/utils.js
@@ -0,0 +1,40 @@
+const focusToPrompt = () => {
+ commandInput.focus();
+}
+
+const parseEntry = (entry) => {
+ entry = entry.trim().replace(/\s\s+/g, ' ');
+ command = entry.split(' ')[0];
+ arg = entry.replace(command, '').trim();
+ return {command, arg};
+}
+
+const _print = (arg, color = null) => {
+ let line = document.createElement('div');
+ line.classList.add('line');
+ if (color == 'red') {
+ line.classList.add('red');
+ }
+ line.innerText += arg;
+ let commandInput = document.querySelector('#command-line');
+ commandInput.parentNode.insertBefore(line, commandInput);
+}
+
+const _clear = () => {
+ document.querySelectorAll('.line').forEach((elm) => {
+ elm.parentNode.removeChild(elm);
+ });
+}
+
+const _execute = (rawEntry) => {
+ let returns = null
+ _print(prompt.innerText + rawEntry);
+ parsed = parseEntry(rawEntry);
+ if (!(parsed.command in commands) && (parsed.command != '')) {
+ _print('Unknown command!', color = 'red');
+ } else {
+ returns = commands[parsed.command](parsed.arg);
+ }
+ return returns;
+}
+