├── js.png ├── .gitattributes ├── favicon.ico ├── .editorconfig ├── scripts ├── buttons.js ├── themeSetter.js ├── history.js ├── compare.js ├── eventListeners.js ├── fetchStats.js ├── getDetails.js └── functions.js ├── .github ├── ISSUE_TEMPLATE │ ├── FEATURE_REQUEST.yml │ └── BUG.yml └── pull_request_template.md ├── LICENSE ├── themes ├── default.css ├── metalic.css ├── galaxy.css ├── vibrant.css ├── nature.css ├── dracula.css ├── matrix.css └── sky.css ├── script.js ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md ├── index.html ├── style.css ├── config.js └── README.md /js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechSpiritSS/Terminal-Portfolio/HEAD/js.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechSpiritSS/Terminal-Portfolio/HEAD/favicon.ico -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | end_of_line = crlf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [*.{html,js,json,css}] 14 | indent_size = 4 15 | -------------------------------------------------------------------------------- /scripts/buttons.js: -------------------------------------------------------------------------------- 1 | //Buttons are set up in this file. 2 | 3 | function greenBtn() { 4 | const container = document.querySelector("#screenContainer"); 5 | container.classList.contains("maximized") 6 | ? container.classList.remove("maximized") 7 | : container.classList.add("maximized"); 8 | } 9 | 10 | function yellowBtn() { 11 | bodyContainer.classList.contains("minimized") 12 | ? bodyContainer.classList.remove("minimized") 13 | : bodyContainer.classList.add("minimized"); 14 | } 15 | 16 | function redBtn() { 17 | window.close(); 18 | } 19 | 20 | function themeBtn() { 21 | const dropdown = document.getElementsByClassName("theme-switches")[0]; 22 | const close = document.getElementsByClassName("close")[0]; 23 | dropdown.classList.toggle('hide'); 24 | close.classList.toggle('hide'); 25 | } 26 | 27 | export { 28 | greenBtn, 29 | yellowBtn, 30 | redBtn, 31 | themeBtn 32 | }; 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: File a feature request 3 | title: "[Req]: " 4 | labels: ["feature request"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this feature request! 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: feature 20 | attributes: 21 | label: Explain the proposed feature 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: use-case 26 | attributes: 27 | label: Explain the possible use cases for the feature 28 | validations: 29 | required: false 30 | - type: textarea 31 | id: other 32 | attributes: 33 | label: Any other details you would like to provide? 34 | validations: 35 | required: false 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Sidharth Sethi 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 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /scripts/themeSetter.js: -------------------------------------------------------------------------------- 1 | //Theme setter file. 2 | 3 | 4 | function setTheme(theme) { 5 | const chosenTheme = "./themes/" + theme + ".css"; 6 | document.getElementById("switcher-id").href = chosenTheme; 7 | 8 | localStorage.setItem("style", theme); 9 | if (theme === "default") { 10 | document.documentElement.setAttribute("data-theme", "default"); 11 | } else if (theme === "nature") { 12 | document.documentElement.setAttribute("data-theme", "nature"); 13 | } else if (theme === "metalic") { 14 | document.documentElement.setAttribute("data-theme", "metalic"); 15 | } else if (theme === "matrix") { 16 | document.documentElement.setAttribute("data-theme", "matrix"); 17 | } else if (theme === "sky") { 18 | document.documentElement.setAttribute("data-theme", "sky"); 19 | } else if (theme === "dracula") { 20 | document.documentElement.setAttribute("data-theme", "dracula"); 21 | } else if (theme === "vibrant") { 22 | document.documentElement.setAttribute("data-theme", "vibrant"); 23 | } else if (theme === "galaxy") { 24 | document.documentElement.setAttribute("data-theme", "galaxy"); 25 | } 26 | localStorage.setItem("style", theme); 27 | } 28 | 29 | export { 30 | //function exported 31 | setTheme 32 | } 33 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Fixes 4 | 5 | 6 | Fixes #[issue number] by @[issue author] 7 | 8 | 9 | ## Types of changes 10 | 11 | - [ ] Bug/Hot fix (non-breaking change which fixes an bug) 12 | - [ ] New feature (non-breaking change which adds a functionality/feature) 13 | - [ ] Refactoring Old Code ( non-breaking change replacing already existing code) 14 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 15 | 16 | 17 | ## Description 18 | 19 | 20 | 21 | ## Preview Link 22 | 23 | 25 | 26 | 27 | ## Checklist: 28 | 29 | 30 | - [ ] I have read the **CONTRIBUTING** guidelines in repository. 31 | - [ ] My pull request has a descriptive title and is attached to an existing issue. 32 | - [ ] I haven't repeated the code and it follows established code style of repository. 33 | - [ ] My branch is up-to-date with upstream branch. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: ["bug", "triage"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | - type: input 11 | id: contact 12 | attributes: 13 | label: Contact Details 14 | description: How can we get in touch with you if we need more info? 15 | placeholder: ex. email@example.com 16 | validations: 17 | required: false 18 | - type: textarea 19 | id: what-happened 20 | attributes: 21 | label: What happened? 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: expected-behavior 26 | attributes: 27 | label: What should have happened? 28 | validations: 29 | required: true 30 | - type: dropdown 31 | id: browsers 32 | attributes: 33 | label: What browsers are you seeing the problem on? 34 | multiple: true 35 | options: 36 | - Firefox 37 | - Chrome 38 | - Safari 39 | - Microsoft Edge 40 | - type: input 41 | id: version 42 | attributes: 43 | label: Version 44 | description: What version of the browser are you running? 45 | validations: 46 | required: false 47 | - type: textarea 48 | id: logs 49 | attributes: 50 | label: Relevant log output 51 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 52 | render: sh 53 | -------------------------------------------------------------------------------- /themes/default.css: -------------------------------------------------------------------------------- 1 | .container { 2 | border: 1px solid rgb(212, 12, 12); 3 | } 4 | 5 | .menu { 6 | background-color: #faa094ff; 7 | } 8 | 9 | .menu h1 { 10 | color: #000000; 11 | } 12 | 13 | #app { 14 | background-color: #ffdde2ff; 15 | } 16 | 17 | p { 18 | color: #000000; 19 | } 20 | 21 | .bottom-bar { 22 | background-color: #fc766aff; 23 | } 24 | 25 | .bottom-name { 26 | color: #000000; 27 | } 28 | 29 | h2 { 30 | color: #008c76ff; 31 | } 32 | 33 | p.code { 34 | color: #faea48; 35 | } 36 | 37 | span.text { 38 | color: #00ffc6; 39 | } 40 | 41 | p.path { 42 | color: #240a8e; 43 | } 44 | 45 | p.path span { 46 | color: #3ec70b; 47 | } 48 | 49 | p.path span+span { 50 | color: #3b44f6; 51 | } 52 | 53 | .success { 54 | color: #008c76ff; 55 | } 56 | 57 | .error { 58 | color: #c50000; 59 | } 60 | 61 | p.response { 62 | color: #37e2d5; 63 | } 64 | 65 | input { 66 | color: #ff8d29; 67 | } 68 | 69 | .icone { 70 | color: #008c76ff; 71 | } 72 | 73 | .icone.error { 74 | color: #ff1700; 75 | } 76 | 77 | .theme-switches { 78 | background-color: #faa094ff; 79 | } 80 | #switch8{ 81 | background-color: #A080FF; 82 | } 83 | #switch7{ 84 | background-color:#FF6600 ; 85 | 86 | } 87 | ::-webkit-scrollbar-track { 88 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 89 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 90 | background-color: #ffdde2ff; 91 | 92 | } 93 | 94 | ::-webkit-scrollbar { 95 | width: 8px; 96 | } 97 | 98 | ::-webkit-scrollbar-thumb { 99 | border-radius: 10px; 100 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 101 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 102 | background-color: #fc766aff; 103 | } -------------------------------------------------------------------------------- /scripts/history.js: -------------------------------------------------------------------------------- 1 | //imports 2 | import { createText, getInputValue } from "./functions.js"; 3 | //end imports 4 | export async function commandHistory(){ 5 | let record = JSON.parse(localStorage.getItem("history")) || []; 6 | if(record.length === 0){ 7 | await createText("No History Found!"); 8 | }else{ 9 | await createText("Previously used commands are: "); 10 | for(let i=0;i record.length) { 20 | await createText("No History Found for this id!"); 21 | } else { 22 | await createText(`Running command: ${record[id-1]}`); 23 | await getInputValue(record,false,record[id-1]); 24 | } 25 | } 26 | 27 | export function saveHistory(value){ 28 | let record = JSON.parse(localStorage.getItem("history")) || []; 29 | if(value.startsWith('history')) return; 30 | if(record.length > 9){ 31 | record.shift(); 32 | record.push(value); 33 | }else{ 34 | record.push(value); 35 | } 36 | localStorage.setItem("history", JSON.stringify(record)); 37 | } 38 | 39 | 40 | export async function clearHistory(){ 41 | let record = JSON.parse(localStorage.getItem("history")) || []; 42 | await createText("Clearing your history"); 43 | record = []; 44 | localStorage.setItem("history", JSON.stringify(record)); 45 | } 46 | 47 | export function popInvalidCommand(){ 48 | let record = JSON.parse(localStorage.getItem("history")) || []; 49 | record.pop(); 50 | localStorage.setItem("history", JSON.stringify(record)); 51 | } 52 | -------------------------------------------------------------------------------- /themes/metalic.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --back-color: #1d272a; 3 | --primary-color: #f9ffee; 4 | --header-back: #1a1d24; 5 | --header-text: #eee; 6 | } 7 | 8 | body { 9 | background-color: var(--back-color); 10 | color: var(--primary-color); 11 | } 12 | 13 | header { 14 | background-color: var(--header-back); 15 | color: var(--header-text); 16 | } 17 | 18 | .box img { 19 | border: 2px solid var(--primary-color); 20 | } 21 | 22 | .menu { 23 | /* top bar */ 24 | background-color: #3f545a; 25 | } 26 | 27 | .bottom-bar { 28 | background-color: #0e1314; 29 | } 30 | 31 | .menu h1 { 32 | color: #f9ffee; 33 | } 34 | 35 | .bottom-name, 36 | .bottom-bar { 37 | color: #727272; 38 | } 39 | 40 | p { 41 | color: #f9ffee; 42 | } 43 | 44 | #app { 45 | /* main content */ 46 | background-color: #1d272a; 47 | } 48 | 49 | p.path { 50 | /* username */ 51 | color: #7a9f81 !important; 52 | } 53 | 54 | #app p { 55 | /* main text */ 56 | color: #6e94ad; 57 | } 58 | 59 | p.path span { 60 | color: #ff8800; 61 | } 62 | 63 | p.path span+span { 64 | color: #937aba; 65 | } 66 | 67 | .icone { 68 | color: #6e94ad; 69 | } 70 | 71 | input { 72 | background-color: #; 73 | } 74 | 75 | .error { 76 | background-color: #; 77 | } 78 | 79 | .container { 80 | border: 1px solid #000000; 81 | } 82 | 83 | .close { 84 | border: 1px solid white; 85 | } 86 | 87 | .theme-switches { 88 | background-color: #3f545a; 89 | color: white; 90 | } 91 | #switch8{ 92 | background-color: #A080FF; 93 | } 94 | #switch7{ 95 | background-color:#FF6600 ; 96 | 97 | } 98 | ::-webkit-scrollbar-track { 99 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 100 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 101 | background-color: #1d272a; 102 | 103 | } 104 | 105 | ::-webkit-scrollbar { 106 | width: 8px; 107 | background-color: #555; 108 | } 109 | 110 | ::-webkit-scrollbar-thumb { 111 | border-radius: 10px; 112 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 113 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 114 | background-color: #ff8800; 115 | } -------------------------------------------------------------------------------- /themes/galaxy.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --back-color: #1d272a; 3 | --primary-color: #3c366b; 4 | --header-back: #5f718d; 5 | --header-text: #eee; 6 | } 7 | 8 | body { 9 | background-color: var(--back-color); 10 | color: var(--primary-color); 11 | } 12 | 13 | header { 14 | background-color: var(--header-back); 15 | color: var(--header-text); 16 | } 17 | 18 | .box img { 19 | border: 2px solid var(--primary-color); 20 | } 21 | 22 | .menu { /* top bar */ 23 | background-color: #efdfcf; 24 | } 25 | .code{ 26 | color:#A080FF !important; 27 | } 28 | .bottom-bar { 29 | background-color: #efdfcf; 30 | } 31 | 32 | .bottom-name, .menu h1, .bottom-bar { 33 | color: #585858; 34 | } 35 | 36 | p { 37 | color: #96905f; 38 | } 39 | 40 | h2 { 41 | color: #A080FF; 42 | } 43 | 44 | 45 | #app { /* main content */ 46 | background-color: black; 47 | } 48 | 49 | p.path { /* username */ 50 | color:#A080FF !important; 51 | 52 | } 53 | 54 | 55 | #app p { /* main text */ 56 | color: #D0D0FF; 57 | font-weight: 300; 58 | } 59 | 60 | p.path span { /* sudo */ 61 | color: #FFFFFF; 62 | } 63 | 64 | p.path span + span { /* directory */ 65 | color: #D0D0FF; 66 | font-weight: 25px !important; 67 | } 68 | 69 | .icone { 70 | color: #A080FF; 71 | } 72 | 73 | input { 74 | color:#D0D0FF; 75 | } 76 | 77 | .error { 78 | color: #ff1a8c; 79 | } 80 | 81 | .container { 82 | border: 1px solid #000000; 83 | } 84 | 85 | a { 86 | color: #A080FF; 87 | } 88 | 89 | .theme-switches { 90 | background-color: #FFFFFF; 91 | } 92 | #switch8{ 93 | background-color: #A080FF; 94 | } 95 | #switch7{ 96 | background-color:#FF6600 ; 97 | 98 | } 99 | ::-webkit-scrollbar-track { 100 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 101 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 102 | background-color: #000; 103 | 104 | } 105 | 106 | ::-webkit-scrollbar { 107 | width: 8px; 108 | } 109 | 110 | ::-webkit-scrollbar-thumb { 111 | border-radius: 10px; 112 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 113 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 114 | background-color: #A080FF; 115 | } -------------------------------------------------------------------------------- /themes/vibrant.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --back-color: #1d272a; 3 | --primary-color: #3c366b; 4 | --header-back: #5f718d; 5 | --header-text: #eee; 6 | } 7 | 8 | body { 9 | background-color: var(--back-color); 10 | color: var(--primary-color); 11 | } 12 | 13 | header { 14 | background-color: var(--header-back); 15 | color: var(--header-text); 16 | } 17 | 18 | .box img { 19 | border: 2px solid var(--primary-color); 20 | } 21 | 22 | .menu { /* top bar */ 23 | background-color: #efdfcf; 24 | } 25 | .code{ 26 | color:#FF6600 !important; 27 | } 28 | .bottom-bar { 29 | background-color: #efdfcf; 30 | } 31 | 32 | .bottom-name, .menu h1, .bottom-bar { 33 | color: #585858; 34 | } 35 | 36 | p { 37 | color: #96905f; 38 | } 39 | 40 | h2 { 41 | color: #81b6bc; 42 | } 43 | 44 | 45 | #app { /* main content */ 46 | background-color: black; 47 | } 48 | 49 | p.path { /* username */ 50 | color:#FF6600 !important; 51 | 52 | } 53 | 54 | 55 | #app p { /* main text */ 56 | color: #FFFFFF; 57 | font-weight: 300; 58 | } 59 | 60 | p.path span { /* sudo */ 61 | color: #FFFFFF; 62 | } 63 | 64 | p.path span + span { /* directory */ 65 | color: #FF6600; 66 | font-weight: 25px !important; 67 | } 68 | 69 | .icone { 70 | color: #FF6600; 71 | } 72 | 73 | input { 74 | color:#FFFFFF; 75 | } 76 | 77 | .error { 78 | color: #bfff00 ; 79 | } 80 | 81 | .container { 82 | border: 1px solid #000000; 83 | } 84 | 85 | a { 86 | color: #ff4d12; 87 | } 88 | 89 | .theme-switches { 90 | background-color: #FFFFFF; 91 | } 92 | #switch8{ 93 | background-color: #A080FF; 94 | } 95 | #switch7{ 96 | background-color:#FF6600 ; 97 | 98 | } 99 | ::-webkit-scrollbar-track { 100 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 101 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 102 | background-color: #000; 103 | 104 | } 105 | 106 | ::-webkit-scrollbar { 107 | width: 8px; 108 | } 109 | 110 | ::-webkit-scrollbar-thumb { 111 | border-radius: 10px; 112 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 113 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 114 | background-color: #FF6600; 115 | } -------------------------------------------------------------------------------- /themes/nature.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --back-color: #a18d70; 3 | --primary-color: #000000; 4 | --header-back: #5d5d5d; 5 | --header-text: #eee; 6 | } 7 | 8 | body { 9 | background-color: var(--back-color); 10 | color: var(--primary-color); 11 | } 12 | 13 | header { 14 | background-color: var(--header-back); 15 | color: var(--header-text); 16 | } 17 | 18 | .box img { 19 | border: 2px solid var(--primary-color); 20 | } 21 | 22 | .menu { 23 | /* top bar */ 24 | background-color: #4b4343; 25 | } 26 | 27 | .bottom-bar { 28 | background-color: #1e1a1a; 29 | } 30 | 31 | .bottom-name, 32 | .menu h1, 33 | .bottom-bar { 34 | color: #f9ffee; 35 | } 36 | 37 | p { 38 | color: #96905f; 39 | } 40 | 41 | h2, 42 | a { 43 | color: #71a46c; 44 | } 45 | 46 | 47 | #app { 48 | /* main content */ 49 | background-color: #292424; 50 | } 51 | 52 | p.path { 53 | /* username */ 54 | color: #c27d7b !important; 55 | } 56 | 57 | #app p { 58 | /* main text */ 59 | color: #96905f; 60 | } 61 | 62 | p.path span { 63 | /* sudo */ 64 | color: #e81050; 65 | } 66 | 67 | p.path span+span { 68 | /* directory */ 69 | color: #b680b1; 70 | } 71 | 72 | .icone { 73 | color: #96905f; 74 | } 75 | 76 | input { 77 | color: #8b8fc6; 78 | } 79 | 80 | .error { 81 | background-color: #; 82 | } 83 | 84 | .container { 85 | border: 1px solid #000000; 86 | } 87 | 88 | .theme-dropdown { 89 | color: white; 90 | } 91 | 92 | .close { 93 | border: 1px solid white; 94 | } 95 | 96 | .theme-switches { 97 | background-color: #4b4343; 98 | color: white; 99 | } 100 | #switch8{ 101 | background-color: #A080FF; 102 | } 103 | #switch7{ 104 | background-color:#FF6600 ; 105 | 106 | } 107 | ::-webkit-scrollbar-track { 108 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 109 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 110 | background-color: #292424; 111 | 112 | } 113 | 114 | ::-webkit-scrollbar { 115 | width: 8px; 116 | } 117 | 118 | ::-webkit-scrollbar-thumb { 119 | border-radius: 10px; 120 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 121 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 122 | background-color: #c27d7b; 123 | } -------------------------------------------------------------------------------- /themes/dracula.css: -------------------------------------------------------------------------------- 1 | /* Dracula theme for terminal - https://draculatheme.com */ 2 | @import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap'); 3 | 4 | :root { 5 | --back-color: #282a36; 6 | --primary-color: #f8f8f2; 7 | --header-back: #44475a; 8 | --header-text: #f8f8f2; 9 | } 10 | 11 | * { 12 | font-family: 'Fira Code', monospace; 13 | } 14 | 15 | body { 16 | background-color: #383a59; 17 | color: var(--primary-color); 18 | } 19 | 20 | header { 21 | background-color: var(--header-back); 22 | color: var(--header-text); 23 | } 24 | 25 | .box img { 26 | border: 2px solid var(--primary-color); 27 | } 28 | 29 | .menu { 30 | background-color: var(--header-back); 31 | } 32 | 33 | .bottom-bar { 34 | background-color: var(--header-back); 35 | } 36 | 37 | .bottom-name, 38 | .menu h1, 39 | .bottom-bar { 40 | color: var(--header-text); 41 | } 42 | 43 | p { 44 | color: var(--primary-color); 45 | } 46 | 47 | h2 { 48 | color: #8be9fd; 49 | } 50 | 51 | h3 { 52 | color: #6272a4; 53 | } 54 | 55 | #app { 56 | background-color: var(--back-color); 57 | } 58 | 59 | p.path { 60 | color: #ff79c6 !important; 61 | } 62 | 63 | #app p { 64 | color: #50fa7b; 65 | } 66 | 67 | p.path span { 68 | color: #ffb86c; 69 | } 70 | 71 | p.path span+span { 72 | color: #8be9fd; 73 | } 74 | 75 | .icone { 76 | color: #8be9fd; 77 | } 78 | 79 | input { 80 | border: none; 81 | background-color: #282a36; 82 | color: #f8f8f2; 83 | } 84 | 85 | .error { 86 | color: #ff5555; 87 | } 88 | 89 | .container { 90 | border: 1px solid #44475a; 91 | } 92 | 93 | a { 94 | color: #8be9fd; 95 | } 96 | 97 | .theme-switches { 98 | background-color: #44475a; 99 | } 100 | #switch8{ 101 | background-color: #A080FF; 102 | } 103 | #switch7{ 104 | background-color:#FF6600 ; 105 | 106 | } 107 | ::-webkit-scrollbar-track { 108 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 109 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 110 | background-color: #282a36; 111 | 112 | } 113 | 114 | ::-webkit-scrollbar { 115 | width: 8px; 116 | } 117 | 118 | ::-webkit-scrollbar-thumb { 119 | border-radius: 10px; 120 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 121 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 122 | background-color: #ff79c6; 123 | } -------------------------------------------------------------------------------- /themes/matrix.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=VT323&display=swap'); 2 | 3 | :root { 4 | --back-color: #1b1b1b; 5 | --primary-color: #702459; 6 | --header-back: #874f5e; 7 | --header-text: #eee; 8 | } 9 | 10 | body { 11 | background-color: var(--back-color); 12 | color: var(--primary-color); 13 | } 14 | 15 | header { 16 | background-color: var(--header-back); 17 | color: var(--header-text); 18 | } 19 | 20 | .box img { 21 | border: 2px solid var(--primary-color); 22 | } 23 | 24 | .menu { 25 | /* top bar */ 26 | background-color: black; 27 | } 28 | 29 | .bottom-bar { 30 | background-color: black; 31 | } 32 | 33 | .bottom-name, 34 | .menu h1, 35 | .bottom-bar { 36 | color: white; 37 | } 38 | 39 | p { 40 | color: #96905f; 41 | } 42 | 43 | h2 { 44 | color: lime; 45 | } 46 | 47 | 48 | #app { 49 | /* main content */ 50 | background-color: black; 51 | } 52 | 53 | p.path { 54 | /* username */ 55 | color: lime !important; 56 | } 57 | 58 | #app p { 59 | /* main text */ 60 | color: lime; 61 | } 62 | 63 | p.path span { 64 | /* sudo */ 65 | color: lime; 66 | } 67 | 68 | p.path span+span { 69 | /* directory */ 70 | color: lime; 71 | } 72 | 73 | .icone { 74 | color: lime; 75 | } 76 | 77 | input { 78 | color: lime; 79 | } 80 | 81 | .error { 82 | background-color: #; 83 | } 84 | 85 | .container { 86 | border: .5px solid rgb(47, 47, 47); 87 | } 88 | 89 | * { 90 | font-family: "VT323", monospace; 91 | } 92 | 93 | .theme-dropdown { 94 | color: rgb(232, 249, 131); 95 | } 96 | 97 | .close { 98 | border: 1px solid rgb(243, 255, 172); 99 | } 100 | 101 | .theme-switches { 102 | background-color: #000; 103 | color: white; 104 | } 105 | #switch8{ 106 | background-color: #A080FF; 107 | } 108 | #switch7{ 109 | background-color:#FF6600 ; 110 | 111 | } 112 | ::-webkit-scrollbar-track { 113 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 114 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 115 | background-color: black; 116 | } 117 | 118 | ::-webkit-scrollbar { 119 | width: 8px; 120 | background-color: #555; 121 | } 122 | 123 | ::-webkit-scrollbar-thumb { 124 | border-radius: 10px; 125 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 126 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 127 | background-color: lime; 128 | } -------------------------------------------------------------------------------- /scripts/compare.js: -------------------------------------------------------------------------------- 1 | /* 2 | Referenced from: 3 | https://github.com/aceakash/string-similarity 4 | https://www.tutorialspoint.com/levenshtein-distance-in-javascript 5 | */ 6 | 7 | import { commandsList } from "../script.js"; 8 | 9 | function compareTwoStrings(first, second) { 10 | first = first.replace(/\s+/g, '') 11 | second = second.replace(/\s+/g, '') 12 | 13 | if (first === second) return 1; // identical or empty 14 | if (first.length < 2 || second.length < 2) return 0; // if either is a 0-letter or 1-letter string 15 | 16 | let firstBigrams = new Map(); 17 | for (let i = 0; i < first.length - 1; i++) { 18 | const bigram = first.substring(i, i + 2); 19 | const count = firstBigrams.has(bigram) 20 | ? firstBigrams.get(bigram) + 1 21 | : 1; 22 | 23 | firstBigrams.set(bigram, count); 24 | }; 25 | 26 | let intersectionSize = 0; 27 | for (let i = 0; i < second.length - 1; i++) { 28 | const bigram = second.substring(i, i + 2); 29 | const count = firstBigrams.has(bigram) 30 | ? firstBigrams.get(bigram) 31 | : 0; 32 | 33 | if (count > 0) { 34 | firstBigrams.set(bigram, count - 1); 35 | intersectionSize++; 36 | } 37 | } 38 | 39 | return (2.0 * intersectionSize) / (first.length + second.length - 2); 40 | } 41 | 42 | function levenshteinDistance(str1 = '', str2 = '') { 43 | const track = Array(str2.length + 1).fill(null).map(() => 44 | Array(str1.length + 1).fill(null)); 45 | for (let i = 0; i <= str1.length; i += 1) { 46 | track[0][i] = i; 47 | } 48 | for (let j = 0; j <= str2.length; j += 1) { 49 | track[j][0] = j; 50 | } 51 | for (let j = 1; j <= str2.length; j += 1) { 52 | for (let i = 1; i <= str1.length; i += 1) { 53 | const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1; 54 | track[j][i] = Math.min( 55 | track[j][i - 1] + 1, // deletion 56 | track[j - 1][i] + 1, // insertion 57 | track[j - 1][i - 1] + indicator, // substitution 58 | ); 59 | } 60 | } 61 | return track[str2.length][str1.length]; 62 | }; 63 | 64 | export function suggestFurtherCommand(inputString) { 65 | let similarityList = []; 66 | for (let i = 0; i < commandsList.length; ++i) { 67 | similarityList.push([compareTwoStrings(inputString, commandsList[i]) - (levenshteinDistance(inputString, commandsList[i]) / 100), commandsList[i]]) 68 | } 69 | similarityList.sort((a, b) => a[0] - b[0]).reverse(); 70 | return similarityList[0][1]; 71 | } 72 | -------------------------------------------------------------------------------- /themes/sky.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --back-color: #3b88a7; /* Sky Blue */ 3 | --primary-color: #3b88a7; /* Peach Puff */ 4 | --header-back: #5f718d; /* Keep the same */ 5 | --header-text: #eee; /* Keep the same */ 6 | } 7 | 8 | body { 9 | background-color: var(--back-color); 10 | color: var(--primary-color); 11 | } 12 | 13 | header { 14 | background-color: var(--header-back); 15 | color: var(--header-text); 16 | } 17 | 18 | .box img { 19 | border: 2px solid var(--primary-color); 20 | } 21 | 22 | .menu { 23 | /* top bar */ 24 | background-color: #efdfcf; /* Keep the same */ 25 | } 26 | 27 | .bottom-bar { 28 | background-color: #efdfcf; /* Keep the same */ 29 | } 30 | 31 | .bottom-name, 32 | .menu h1, 33 | .bottom-bar { 34 | color: #585858; /* Keep the same */ 35 | } 36 | 37 | p { 38 | color: #96905f; /* Keep the same */ 39 | } 40 | 41 | h2 { 42 | color: #81b6bc; /* Keep the same */ 43 | } 44 | 45 | #app { 46 | /* main content */ 47 | background-color: #f5ebe1; /* Keep the same */ 48 | } 49 | 50 | p.path { 51 | /* username */ 52 | color: #8c4a79 !important; /* Keep the same */ 53 | } 54 | 55 | #app p { 56 | /* main text */ 57 | color: #1a8591; /* Keep the same */ 58 | } 59 | 60 | p.path span { 61 | /* sudo */ 62 | color: #b3534b; /* Keep the same */ 63 | } 64 | 65 | p.path span+span { 66 | /* directory */ 67 | color: #476238; /* Keep the same */ 68 | } 69 | 70 | .icone { 71 | color: #81b6bc; /* Keep the same */ 72 | } 73 | 74 | input { 75 | color: #81b6bc; /* Keep the same */ 76 | } 77 | 78 | .error { 79 | color: #ff1276; /* Keep the same */ 80 | } 81 | 82 | .container { 83 | border: 1px solid #000000; /* Keep the same */ 84 | } 85 | 86 | a { 87 | color: #ff4d12; /* Keep the same */ 88 | } 89 | 90 | .theme-switches { 91 | background-color: #efdfcf; /* Keep the same */ 92 | } 93 | #switch8{ 94 | background-color: #A080FF; /* Keep the same */ 95 | } 96 | #switch7{ 97 | background-color:#FF6600; /* Keep the same */ 98 | } 99 | ::-webkit-scrollbar-track { 100 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); /* Keep the same */ 101 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); /* Keep the same */ 102 | background-color: #f5ebe1; /* Keep the same */ 103 | } 104 | 105 | ::-webkit-scrollbar { 106 | width: 8px; /* Keep the same */ 107 | } 108 | 109 | ::-webkit-scrollbar-thumb { 110 | border-radius: 10px; /* Keep the same */ 111 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); /* Keep the same */ 112 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); /* Keep the same */ 113 | background-color: #1a8591; /* Keep the same */ 114 | } 115 | -------------------------------------------------------------------------------- /scripts/eventListeners.js: -------------------------------------------------------------------------------- 1 | //Event Listeners are defined in this file. These include events like - click, enter, UpArrow, etc 2 | 3 | //Imports done 4 | import { 5 | neofetch, 6 | removeNeoFetch, 7 | getInputValue, 8 | new_line, 9 | removeInput, 10 | trueValue, 11 | falseValue, 12 | createText, 13 | createCode, 14 | downloadFile 15 | } from "./functions.js"; 16 | import { commandsList } from "../script.js"; 17 | 18 | const app = document.querySelector("#app"); 19 | let delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 20 | let history = JSON.parse(localStorage.getItem("history")) || []; 21 | let count = history.length; 22 | 23 | //Event listeners added to app 24 | app.addEventListener("keydown", async function (event) { 25 | if (event.key === "Enter") { 26 | await delay(150); 27 | await getInputValue(history,true); 28 | // removeInput(); 29 | await delay(150); 30 | new_line(); 31 | count = history.length; 32 | } 33 | if (event.key === "ArrowUp") { 34 | if (count > 0) { 35 | await delay(0.005); 36 | const input = document.querySelector("input"); 37 | input.value = history[--count]; 38 | const end = input.value.length; 39 | input.setSelectionRange(end, end); 40 | } 41 | } 42 | if (event.key === "ArrowDown") { 43 | if (count < history.length - 1) { 44 | const input = document.querySelector("input"); 45 | input.value = history[++count]; 46 | } else { 47 | 48 | if (count === history.length - 1) { 49 | count++; 50 | } 51 | const input = document.querySelector("input"); 52 | input.value = ""; 53 | } 54 | } 55 | if (event.key === "Tab") { 56 | event.preventDefault(); 57 | const input = document.querySelector("input"); 58 | const toComplete = input.value; 59 | const completed = commandsList.find((command) => 60 | command.startsWith(toComplete) 61 | ); 62 | if (toComplete && completed) { 63 | // autocomplete if there was something typed in and it matches the start 64 | // of some command 65 | input.value = completed; 66 | } 67 | } 68 | if (event.ctrlKey) { 69 | if (event.key === "l" || event.key === "L") { 70 | document 71 | .querySelectorAll("p") 72 | .forEach((e) => e.parentNode.removeChild(e)); 73 | document 74 | .querySelectorAll("section") 75 | .forEach((e) => e.parentNode.removeChild(e)); 76 | removeInput(); 77 | await delay(150); 78 | new_line(); 79 | count = history.length; 80 | } 81 | } 82 | }); 83 | 84 | app.addEventListener("click", function () { 85 | const input = document.querySelector("input"); 86 | input.focus(); 87 | }); 88 | -------------------------------------------------------------------------------- /scripts/fetchStats.js: -------------------------------------------------------------------------------- 1 | //Statistics file. All fetchStats functions & variables are defined here & exported for use. 2 | 3 | import config from "../config.js"; 4 | 5 | //Stat variables 6 | let connections = 0; 7 | let githubStats = {}; 8 | let followers = 0, 9 | following = 0; 10 | let ranking = 0, 11 | totalSolved = 0, 12 | easySolved = 0, 13 | mediumSolved = 0, 14 | hardSolved = 0; 15 | 16 | //Stat functions 17 | async function fetchGithubSocialStats() { 18 | const githubLink = config.social.find((c) => c.title === "Github").link; 19 | const githubUsername = 20 | githubLink.split("/")[githubLink.split("/").length - 1]; 21 | const responseRaw = await fetch( 22 | `https://api.github.com/users/${githubUsername}` 23 | ); 24 | const response = await responseRaw.json(); 25 | followers = response.followers; 26 | following = response.following; 27 | } 28 | 29 | async function fetchLinkedInStats() { 30 | const Linkedinkink = config.social.find((c) => c.title === "LinkedIn").link; 31 | const LinkedinUsername = 32 | Linkedinkink.split("/")[Linkedinkink.split("/").length - 1]; 33 | const responseRaw = await fetch( 34 | `https://api.linkedin.com/v2/connections?q=viewer&projection=(paging)` 35 | ); 36 | const response = await responseRaw.json(); 37 | connections = response.connections; 38 | } 39 | 40 | async function fetchLeetCodeStats() { 41 | const leetcodelink = config.social.find((c) => c.title === "LeetCode").link; 42 | const leetcodeusername = 43 | leetcodelink.split("/")[leetcodelink.split("/").length - 1]; 44 | const responseRaw = await fetch( 45 | `https://leetcode-stats-api.herokuapp.com/${leetcodeusername}` 46 | ); 47 | const response = await responseRaw.json(); 48 | totalSolved = response.totalSolved; 49 | easySolved = response.easySolved; 50 | mediumSolved = response.mediumSolved; 51 | hardSolved = response.hardSolved; 52 | ranking = response.ranking; 53 | } 54 | 55 | async function fetchGithubStats() { 56 | try { 57 | const githubLink = config.social.find( 58 | (c) => c.title.toLowerCase() === "github" 59 | ).link; 60 | const githubUsername = 61 | githubLink.split("/")[githubLink.split("/").length - 1]; 62 | const responseRaw = await fetch( 63 | `https://api.github.com/users/${githubUsername}` 64 | ); 65 | const response = await responseRaw.json(); 66 | githubStats = { ...response, username: githubUsername }; 67 | } catch (error) { 68 | console.log(error); 69 | // handling the error 70 | githubStats = { 71 | username: githubUsername, 72 | bio: "_failed_to_fetch_", 73 | public_repos: "_failed_to_fetch_", 74 | public_gists: "_failed_to_fetch_", 75 | followers: "_failed_to_fetch_", 76 | following: "_failed_to_fetch_", 77 | }; 78 | } 79 | } 80 | 81 | export { 82 | //functions exported 83 | fetchGithubSocialStats, 84 | fetchLinkedInStats, 85 | fetchLeetCodeStats, 86 | fetchGithubStats, 87 | 88 | //variables exported 89 | connections, 90 | githubStats, 91 | followers, 92 | following, 93 | ranking, 94 | totalSolved, 95 | easySolved, 96 | mediumSolved, 97 | hardSolved, 98 | }; 99 | -------------------------------------------------------------------------------- /scripts/getDetails.js: -------------------------------------------------------------------------------- 1 | //Functions to fetch basic details are defined here. 2 | 3 | //Imports done 4 | import config from "../config.js"; 5 | 6 | let contributors = []; 7 | let userBlogs = []; 8 | let IpDetails = []; 9 | let userRepos = []; 10 | 11 | // functions defined 12 | const getContributors = async () => { 13 | try { 14 | const response = await fetch( 15 | "https://api.github.com/repos/TechSpiritSS/Terminal-Portfolio/contributors" 16 | ) 17 | .then((response) => response.json()) 18 | .then((data) => { 19 | data.forEach((user) => { 20 | const userDetails = { username: "", userProfile: "" }; 21 | userDetails.username = user.login; 22 | userDetails.userProfile = user.html_url; 23 | contributors.push(userDetails); 24 | }); 25 | }); 26 | } catch (error) { 27 | console.log(error); 28 | // handling the error 29 | contributors.push({ 30 | username: "__network_error __check internet connection", 31 | userProfile: " ", 32 | }); 33 | } 34 | }; 35 | 36 | const getBlogs = async () => { 37 | config.blogs.forEach(async (blog) => { 38 | try { 39 | const rssConverter = `https://api.rss2json.com/v1/api.json?rss_url=${blog.url}`; 40 | const response = await fetch(rssConverter); 41 | const data = await response.json(); 42 | userBlogs.push({ site: blog.site, items: data.items }); 43 | } catch (error) { 44 | console.log(error); 45 | // handling the error 46 | userBlogs.push({ 47 | site: blog.site, 48 | items: ["_failed_to_fetch_"], 49 | }); 50 | } 51 | }); 52 | }; 53 | 54 | const getIPDetails = async () => { 55 | try { 56 | const response = await fetch("https://ipapi.co/json") 57 | .then((response) => response.json()) 58 | .then((data) => { 59 | IpDetails.push(data); 60 | }); 61 | } catch (error) { 62 | console.log(error); 63 | // handling the error 64 | IpDetails.push({ 65 | ip: "__network_error", 66 | network: "__kindly check internet connection", 67 | city: "", 68 | region: "", 69 | org: "", 70 | postal: "", 71 | }); 72 | } 73 | }; 74 | 75 | const getRepo = async () => { 76 | try { 77 | const response = await fetch( 78 | "https://api.github.com/users/TechSpiritSS/repos" 79 | ) 80 | .then((response) => response.json()) 81 | .then((data) => { 82 | userRepos.push(data); 83 | }); 84 | } catch (error) { 85 | console.log(error); 86 | userRepos.push([ 87 | { 88 | name: "__network_error", 89 | description: "__kindly check internet connection", 90 | html_url: "", 91 | }, 92 | ]); 93 | } 94 | }; 95 | 96 | export { 97 | //functions exported 98 | getContributors, 99 | getBlogs, 100 | getIPDetails, 101 | getRepo, 102 | 103 | //variables exported 104 | contributors, 105 | userBlogs, 106 | IpDetails, 107 | userRepos, 108 | }; 109 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | //Main script file. All necessary script files are imported here 2 | 3 | import { greenBtn, yellowBtn, redBtn, themeBtn } from "./scripts/buttons.js"; 4 | import { 5 | fetchGithubSocialStats, fetchLinkedInStats, fetchLeetCodeStats, fetchGithubStats, 6 | connections, 7 | githubStats, 8 | followers, following, 9 | ranking, totalSolved, easySolved, mediumSolved, hardSolved, 10 | } from "./scripts/fetchStats.js"; 11 | 12 | import { getContributors, getBlogs, getIPDetails, getRepo, contributors, userBlogs, IpDetails, userRepos } from "./scripts/getDetails.js"; 13 | import { 14 | neofetch, 15 | removeNeoFetch, 16 | getInputValue, 17 | new_line, 18 | removeInput, 19 | trueValue, 20 | falseValue, 21 | createText, 22 | createCode, 23 | downloadFile, 24 | calc 25 | } from "./scripts/functions.js"; 26 | 27 | import { setTheme } from "./scripts/themeSetter.js"; 28 | 29 | export let commandsList = [ 30 | "help", 31 | "ls", 32 | "clear", 33 | "about", 34 | "social", 35 | "projects", 36 | "repos", 37 | "cheer", 38 | "ipconfig", 39 | "contributors", 40 | "neofetch", 41 | "download", 42 | "calc", 43 | "blog", 44 | "contact", 45 | "github", 46 | "experience", 47 | "skills", 48 | "history", 49 | "typing", 50 | "reset" 51 | ]; 52 | 53 | 54 | let delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 55 | 56 | const app = document.querySelector("#app"); 57 | const bodyContainer = document.querySelector("#bodyContainer"); 58 | 59 | const greenButton = document.querySelector("#greenButton"); 60 | greenButton.addEventListener("click", greenBtn); 61 | 62 | const yellowButton = document.querySelector("#yellowButton"); 63 | yellowButton.addEventListener("click", yellowBtn); 64 | 65 | const redButton = document.querySelector("#redButton"); 66 | redButton.addEventListener("click", redBtn); 67 | 68 | const themeButton = document.querySelector("#themeButton"); 69 | themeButton.addEventListener("click", themeBtn); 70 | 71 | //function to set up and start the terminal 72 | async function openTerminal() { 73 | await createText("Welcome to the Terminal"); 74 | await delay(500); 75 | await createText("Starting up..."); 76 | await delay(800); 77 | await createText("You can now interact with the Terminal"); 78 | await createCode("Type help", "for a list of commands"); 79 | await delay(500); 80 | new_line(); 81 | } 82 | 83 | //fetch statisticss from ./scripts/fetchStats.js 84 | fetchGithubSocialStats(); 85 | fetchLinkedInStats(); 86 | fetchLeetCodeStats(); 87 | fetchGithubStats(); 88 | 89 | //open the terminal 90 | openTerminal(); 91 | 92 | //get Details from ./scripts/getDetails.js 93 | getContributors(); 94 | // get the Blogs 95 | getBlogs(); 96 | // ip lookup --> https://ipapi.co/json 97 | getIPDetails(); 98 | // get user github repositories 99 | getRepo(); 100 | 101 | 102 | // Themes Switcher 103 | let switches = document.getElementsByClassName("main-switch"); 104 | let style = localStorage.getItem("style"); 105 | 106 | if (style == null) { 107 | setTheme("default"); 108 | } else { 109 | setTheme(style); 110 | } 111 | 112 | for (let i of switches) { 113 | i.addEventListener("click", function () { 114 | let theme = this.dataset.theme; 115 | setTheme(theme); 116 | }); 117 | } 118 | 119 | 120 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 🤝 2 | 3 |
4 | 5 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 6 |   7 | [![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)](https://github.com/Naereen/badges/) 8 | 9 | 10 | This documentation contains a set of guidelines to help you during the contribution process. 11 | We are happy to welcome all the contributions from anyone willing to improve/add new ideas to this project. 12 | Thank you for helping out and remember, **no contribution is too small.** 13 | Being an open source contributor doesn't just mean writing code, either. You can help out by writing documentation, tests, or even giving suggestions. 🏆 14 | 15 |
16 | 17 | ### 0 : Issues 18 | 19 | - Always check the [existing issues](https://github.com/TechSpiritSS/Terminal-Portfolio/issues) before creating your own issue.**Do not create an issue if it already exists.** 20 | - Only start working on an issue if it has been assigned to you. **Check assignees** 21 | - Every change in this project should/must have an associated issue. **Issue before PR** 22 | - Do not create multiple PRs for the same issue. **One PR per issue** 23 | - Assignee should make a PR in a time bound manner (possibly 1-2 weeks ) otherwise it maybe unassigned. 24 | - If a PR closes the issue link it to the issue. 25 | - If a change is requested, link the commit to the issue. 26 | 27 | 28 | 29 | ### 1 : Fork the Project 30 | 31 | - Fork this repository. This will create a local copy of this repository on your GitHub profile. 32 | Keep a reference to the original project in `upstream` remote. 33 | 34 | ```bash 35 | git clone https://github.com//Terminal-Portfolio.git 36 | cd Terminal-Portfolio 37 | git remote add upstream https://github.com/TechSpiritSS/Terminal-Portfolio.git 38 | ``` 39 | 40 | - If you have already forked the project, update your copy before working on it. 41 | 42 | ```bash 43 | git remote update 44 | git checkout main 45 | git rebase upstream/main 46 | ``` 47 | 48 | ### 2 : Branch 49 | 50 | Create a new branch after setting up the project locally before making any changes, so as to avoid merge conflicts while making PRs. 51 | Use the name of the branch to identify the issue you're addressing; Feature , Bug Fix or Enhancement. 52 | 53 | ```bash 54 | # It will create a new branch with name branch_name and switch to that branch 55 | git checkout -b branch_name 56 | ``` 57 | 58 | ### 3 : Work on the issue assigned 59 | 60 | - Work on the issue(s) assigned to you. 61 | - Add all the files/folders needed. 62 | - After you've made changes or made your contribution to the project, add changes to the branch you've just created: 63 | 64 | ```bash 65 | # To add all new files to branch branch_name 66 | git add . 67 | 68 | # To add only a few files to branch_name 69 | git add 70 | ``` 71 | 72 | ### 4 : Commit 73 | 74 | - To commit the changes you've made, give a descriptive message for the convenience of the reviewer: 75 | 76 | ```bash 77 | # This message get associated with all files you have changed 78 | git commit -m "message" 79 | ``` 80 | 81 | - **NOTE**: A PR should have only one commit. Multiple commits should be squashed. 82 | 83 | ### 5 : Work Remotely 84 | 85 | ```bash 86 | # To push your work to your remote repository 87 | git push -u origin branch_name 88 | ``` 89 | 90 | ### 6 : Pull Request 91 | 92 | - Go to your repository in the browser and click on compare and pull requests. 93 | Then add a title and description to your pull request that explains your contribution. 94 | 95 | 96 | ### 7 : Review 97 | 98 | - 🎉🌟Congratulations! Sit and relax, you've made your contribution to Terminal-Portfolio project. Wait until the PR is reviewed and incorporate changes suggested by the community. After which the PR can be successfully merged. 99 | 🎉🎊 100 | 101 | 102 | ### Note : Do not add images, rather 👇 103 | - You can do that by hosting all you images and screenshots to any images hosting sites such as [imgur](https://imgur.com/), [imgbb](https://imgbb.com/), [postimages](https://postimages.org/). 104 | - Then link your uploaded images to README files. 105 | 106 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Citizen Code of Conduct 2 | 3 | ## 1. Purpose 4 | 5 | A primary goal of Terminal Portfolio is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof). 6 | 7 | This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior. 8 | 9 | We invite all those who participate in Terminal Portfolio to help us create safe and positive experiences for everyone. 10 | 11 | ## 2. Open [Source/Culture/Tech] Citizenship 12 | 13 | A supplemental goal of this Code of Conduct is to increase open [source/culture/tech] citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community. 14 | 15 | Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society. 16 | 17 | If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know. 18 | 19 | ## 3. Expected Behavior 20 | 21 | The following behaviors are expected and requested of all community members: 22 | 23 | * Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community. 24 | * Exercise consideration and respect in your speech and actions. 25 | * Attempt collaboration before conflict. 26 | * Refrain from demeaning, discriminatory, or harassing behavior and speech. 27 | * Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. 28 | * Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations. 29 | 30 | ## 4. Unacceptable Behavior 31 | 32 | The following behaviors are considered harassment and are unacceptable within our community: 33 | 34 | * Violence, threats of violence or violent language directed against another person. 35 | * Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language. 36 | * Posting or displaying sexually explicit or violent material. 37 | * Posting or threatening to post other people's personally identifying information ("doxing"). 38 | * Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability. 39 | * Inappropriate photography or recording. 40 | * Inappropriate physical contact. You should have someone's consent before touching them. 41 | * Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances. 42 | * Deliberate intimidation, stalking or following (online or in person). 43 | * Advocating for, or encouraging, any of the above behavior. 44 | * Sustained disruption of community events, including talks and presentations. 45 | 46 | ## 5. Weapons Policy 47 | 48 | No weapons will be allowed at Terminal Portfolio events, community spaces, or in other spaces covered by the scope of this Code of Conduct. Weapons include but are not limited to guns, explosives (including fireworks), and large knives such as those used for hunting or display, as well as any other item used for the purpose of causing injury or harm to others. Anyone seen in possession of one of these items will be asked to leave immediately, and will only be allowed to return without the weapon. Community members are further expected to comply with all state and local laws on this matter. 49 | 50 | ## 6. Consequences of Unacceptable Behavior 51 | 52 | Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated. 53 | 54 | Anyone asked to stop unacceptable behavior is expected to comply immediately. 55 | 56 | If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event). 57 | 58 | ## 7. Reporting Guidelines 59 | 60 | If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. . 61 | 62 | Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress. 63 | 64 | ## 8. Addressing Grievances 65 | 66 | If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies. 67 | 68 | ## 9. Scope 69 | 70 | We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues--online and in-person--as well as in all one-on-one communications pertaining to community business. 71 | 72 | This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members. 73 | 74 | ## 10. Contact info 75 | 76 | ## 11. License and attribution 77 | 78 | The Citizen Code of Conduct is distributed by [Stumptown Syndicate](http://stumptownsyndicate.org) under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/). 79 | 80 | Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy). 81 | 82 | _Revision 2.3. Posted 6 March 2017._ 83 | 84 | _Revision 2.2. Posted 4 February 2016._ 85 | 86 | _Revision 2.1. Posted 23 June 2014._ 87 | 88 | _Revision 2.0, adopted by the [Stumptown Syndicate](http://stumptownsyndicate.org) board on 10 January 2013. Posted 17 March 2013._ 89 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Terminal 9 | 13 | 14 | 15 | 16 | 17 | 21 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 43 | 47 | 48 | 49 | 50 | 54 | 55 | 59 | 60 | 61 | Terminal 62 | 63 | 64 | 65 | 66 | 67 |
68 | 153 |
154 |
155 |
156 | © 157 | 160 | 164 | Sidharth Sethi 166 | 167 |
168 |
169 |
170 | 171 | 172 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@600&display=swap"); 2 | 3 | :root { 4 | --font-size: 1.3rem; 5 | --metalic: #6e94ad; 6 | --sky: #f5ebe1; 7 | --matrix: lime; 8 | --nature: #cda76e; 9 | --default: #fc766aff; 10 | --dracula: #ff79c6; 11 | } 12 | 13 | .key { 14 | color: purple; 15 | } 16 | 17 | .value { 18 | color: cyan; 19 | } 20 | 21 | .fetch-container { 22 | display: flex; 23 | flex-direction: row; 24 | justify-content: center; 25 | height: 500px; 26 | width: 100%; 27 | } 28 | 29 | .fetch-img-container { 30 | display: flex; 31 | justify-content: flex-end; 32 | height: 300px; 33 | width: 600px; 34 | } 35 | 36 | .fetch-img { 37 | margin-right: 50px; 38 | } 39 | 40 | .info { 41 | padding-top: 50px; 42 | height: 100%; 43 | width: 50%; 44 | } 45 | 46 | .theme-dropdown { 47 | display: flex; 48 | justify-content: center; 49 | align-items: center; 50 | padding: 1rem; 51 | font-size: larger; 52 | width: 10%; 53 | cursor: pointer; 54 | } 55 | 56 | .theme-switches { 57 | position: absolute; 58 | right: 4rem; 59 | top: 3.33rem; 60 | border-radius: 5px; 61 | box-shadow: 1px 1px 2px 2px rgb(97, 96, 96); 62 | color: #000000; 63 | padding: 10px; 64 | z-index: 100; 65 | margin-top: 10px; 66 | background-color: #fdcdc7; 67 | } 68 | 69 | @keyframes close-animation { 70 | 25% { 71 | border-left: 1px solid rgb(83, 252, 255); 72 | } 73 | 74 | 50% { 75 | border-top: 1px solid rgb(83, 252, 255); 76 | } 77 | 78 | 75% { 79 | border-right: 1px solid rgb(83, 252, 255); 80 | } 81 | 82 | 100% { 83 | border-bottom: 1px solid rgb(83, 252, 255); 84 | } 85 | } 86 | 87 | .close { 88 | margin-left: 1.5rem; 89 | font-size: large; 90 | font-weight: bold; 91 | font-family: "Arial Narrow", Arial, sans-serif; 92 | border: 1px solid black; 93 | padding: 4px 10px; 94 | border-radius: 5px; 95 | animation: close-animation 1s ease infinite; 96 | } 97 | 98 | 99 | .hide { 100 | display: none; 101 | } 102 | 103 | .theme-options { 104 | display: flex; 105 | justify-content: flex-start; 106 | align-items: center; 107 | cursor: pointer; 108 | } 109 | 110 | .theme-options:hover { 111 | border-color: #85899b; 112 | border-radius: 15px; 113 | font-size: large; 114 | box-shadow: 2px 3px 5px 1px rgb(0 0 0 / 57%); 115 | } 116 | 117 | .theme-options:hover .switch { 118 | transform: scale(1.1); 119 | transition: 0.3s ease-in-out; 120 | } 121 | 122 | .switch { 123 | border: 2px solid black; 124 | border-radius: 50px; 125 | height: 30px; 126 | width: 30px; 127 | margin: 10px; 128 | cursor: pointer; 129 | } 130 | 131 | #switch1 { 132 | background-color: var(--nature); 133 | } 134 | 135 | #switch2 { 136 | background-color: var(--metalic); 137 | } 138 | 139 | #switch3 { 140 | background-color: var(--matrix); 141 | } 142 | 143 | #switch4 { 144 | background-color: var(--sky); 145 | } 146 | 147 | #switch5 { 148 | background-color: var(--default); 149 | } 150 | 151 | #switch6 { 152 | background-color: var(--dracula); 153 | } 154 | 155 | * { 156 | margin: 0; 157 | padding: 0; 158 | box-sizing: border-box; 159 | font-family: "Source Code Pro", monospace; 160 | } 161 | 162 | ::-webkit-scrollbar-track { 163 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 164 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 165 | background-color: #f5f5f5; 166 | } 167 | 168 | ::-webkit-scrollbar { 169 | width: 12px; 170 | background-color: #555; 171 | } 172 | 173 | ::-webkit-scrollbar-thumb { 174 | border-radius: 10px; 175 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 176 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 177 | background-color: rgb(129, 129, 129); 178 | } 179 | 180 | .white { 181 | color: rgb(238, 238, 238); 182 | } 183 | 184 | .blue { 185 | color: #003cff; 186 | } 187 | 188 | a { 189 | text-decoration: none; 190 | color: #00b14a; 191 | } 192 | 193 | body { 194 | background-color: #222831; 195 | height: 100vh; 196 | display: flex; 197 | justify-content: center; 198 | } 199 | 200 | .container { 201 | display: flex; 202 | flex-direction: column; 203 | width: 100%; 204 | height: 100%; 205 | max-width: 95vw; 206 | max-height: 95vh; 207 | overflow: hidden; 208 | border-radius: 6px; 209 | border: 1px solid rgb(212, 12, 12); 210 | margin: 20px; 211 | cursor: text; 212 | } 213 | 214 | .maximized { 215 | max-width: 100vw; 216 | max-height: 100vh; 217 | margin: 0; 218 | } 219 | 220 | .minimized { 221 | height: 45px; 222 | } 223 | 224 | .menu { 225 | display: flex; 226 | align-items: center; 227 | text-align: center; 228 | justify-content: space-between; 229 | width: 100%; 230 | min-height: 45px; 231 | height: 45px; 232 | background-color: #faa094ff; 233 | padding: 0 6px; 234 | cursor: default; 235 | } 236 | 237 | .menu .button { 238 | display: flex; 239 | width: 20px; 240 | height: 20px; 241 | border-radius: 50%; 242 | margin-right: 8px; 243 | cursor: pointer; 244 | } 245 | 246 | .buttons-flex { 247 | display: flex; 248 | flex-direction: row; 249 | /* flex-grow: 1; */ 250 | flex-basis: 0; 251 | } 252 | 253 | @keyframes blinkanimation { 254 | from { 255 | width: 0px; 256 | } 257 | 258 | to { 259 | width: 200px; 260 | } 261 | } 262 | 263 | .blink { 264 | display: block; 265 | overflow: hidden; 266 | animation: blinkanimation 0.8s linear infinite; 267 | color: #3ec70b; 268 | margin-left: 10px; 269 | } 270 | 271 | @keyframes on-off { 272 | from { 273 | z-index: -1; 274 | } 275 | 276 | to { 277 | z-index: 1; 278 | } 279 | } 280 | 281 | .blink-dot { 282 | display: inline-block; 283 | position: relative; 284 | margin: auto; 285 | height: 12px; 286 | width: 12px; 287 | background-color: #00b14a; 288 | border-radius: 50%; 289 | ; 290 | animation: on-off 1s linear infinite; 291 | } 292 | 293 | .red { 294 | background-color: rgb(204, 20, 20); 295 | } 296 | 297 | .green { 298 | background-color: rgb(0, 170, 0); 299 | } 300 | 301 | .yellow { 302 | background-color: rgb(255, 255, 0); 303 | } 304 | 305 | div.title { 306 | flex: 1; 307 | text-align: center; 308 | } 309 | 310 | .menu h1 { 311 | font-size: 20px; 312 | color: #000000; 313 | } 314 | 315 | .theme-group { 316 | display: flex; 317 | flex-direction: column; 318 | /* align-items: center; */ 319 | margin: 10px; 320 | } 321 | 322 | .theme-group h3 { 323 | text-align: center; 324 | border-bottom: 2px dotted black; 325 | margin-bottom: 4px; 326 | } 327 | 328 | 329 | @media (max-width: 2990px) { 330 | .theme-switches{ 331 | right: 6rem; 332 | } 333 | } 334 | @media (max-width: 1300px) { 335 | .theme-dropdown{ 336 | width:14%; 337 | } 338 | .theme-switches{ 339 | right: 4rem; 340 | } 341 | } 342 | 343 | @media (max-width: 850px) { 344 | .theme-switches { 345 | right: 2.5rem; 346 | } 347 | .theme-dropdown{ 348 | width:24%; 349 | } 350 | } 351 | 352 | @media (max-width: 580px) { 353 | .theme-switches { 354 | right: 2.5rem; 355 | } 356 | body{ 357 | height: 90vh; 358 | } 359 | .theme-dropdown{ 360 | width:30%; 361 | } 362 | /* .close { 363 | margin-left: 5px; 364 | } */ 365 | } 366 | 367 | @media (max-width: 500px) { 368 | *{ 369 | font-size: 0.6em; 370 | } 371 | .buttons-flex { 372 | /* position: unset; */ 373 | display: flex; 374 | flex-direction: row; 375 | flex-basis: 0; 376 | } 377 | 378 | .fetch-img-container { 379 | justify-content: flex-start; 380 | } 381 | 382 | .fetch-container { 383 | flex-direction: column; 384 | height: 500px; 385 | width: 100%; 386 | margin-bottom: 20px; 387 | } 388 | 389 | .info { 390 | width: 100%; 391 | } 392 | 393 | .menu h1 { 394 | font-size: small; 395 | } 396 | .theme-dropdown{ 397 | font-size: 5em; 398 | width: 30%; 399 | } 400 | span{ 401 | font-size: small; 402 | } 403 | .title 404 | { 405 | font-size: 5em; 406 | } 407 | .theme-switches{ 408 | margin-top: 3.5rem; 409 | } 410 | } 411 | 412 | @media (max-width: 400px) { 413 | .menu h1 { 414 | display: none; 415 | } 416 | 417 | .info { 418 | height: 500px; 419 | } 420 | } 421 | 422 | #app { 423 | display: flex; 424 | flex-direction: column; 425 | width: 100%; 426 | height: 100%; 427 | overflow: auto; 428 | padding: 8px; 429 | background-color: #ffdde2ff; 430 | } 431 | 432 | p { 433 | font-size: var(--font-size); 434 | color: #000000; 435 | padding: 8px 0; 436 | } 437 | 438 | .bottom-bar { 439 | background-color: #fc766aff; 440 | font-size: larger; 441 | padding-top: 5px; 442 | padding-bottom: 5px; 443 | } 444 | 445 | .bottom-name { 446 | color: #000000; 447 | } 448 | 449 | h2 { 450 | font-size: var(--font-size); 451 | color: #008c76ff; 452 | } 453 | 454 | span.code { 455 | font-style: italic; 456 | color: #8e0a5b; 457 | margin-left: 8px; 458 | } 459 | 460 | span.text { 461 | margin-left: 16px; 462 | color: #00ffc6; 463 | } 464 | 465 | p.path { 466 | color: #240a8e; 467 | } 468 | 469 | p.path span { 470 | color: #3ec70b; 471 | } 472 | 473 | p.path span+span { 474 | color: #3b44f6; 475 | } 476 | 477 | .success { 478 | color: #008c76ff; 479 | } 480 | 481 | .error { 482 | color: #c50000; 483 | } 484 | 485 | p.response { 486 | color: #37e2d5; 487 | } 488 | 489 | input { 490 | border: none; 491 | background-color: unset; 492 | color: #ff8d29; 493 | width: 100%; 494 | font-size: var(--font-size); 495 | } 496 | 497 | input:focus { 498 | border: none; 499 | outline: none; 500 | box-shadow: none; 501 | background-color: unset; 502 | } 503 | 504 | .type { 505 | display: flex; 506 | align-items: center; 507 | padding: 8px 0; 508 | } 509 | 510 | .type2 { 511 | display: flex; 512 | align-items: center; 513 | padding: 8px 0; 514 | } 515 | 516 | .icone { 517 | color: #008c76ff; 518 | padding-right: 8px; 519 | } 520 | 521 | .icone.error { 522 | color: #ff1700; 523 | } 524 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | 2 | const config = { 3 | 4 | "help": [ 5 | { 6 | "title": "help", 7 | "description": "for a list of commands(add flags '-d' for commands description)", 8 | "info": ["help or ls command gives the list of commands","add '-d' flag for description of all commands also","write command after help to get info about that specific command like 'help typing'"] 9 | }, 10 | { 11 | "title": "clear", 12 | "description": "to clear the terminal", 13 | "info": ["clear or cls command clears the terminal"] 14 | }, 15 | { 16 | "title": "about", 17 | "description": "to learn more about me", 18 | "info": ["use about command to learn more about me"] 19 | }, 20 | { 21 | "title": "social", 22 | "description": "to see my social links (add flags '-l' for links and '-d' for detailed results)", 23 | "info": ["use social command to see my social links","add '-l' flag for links and '-d' flag for detailed results"] 24 | }, 25 | { 26 | "title": "projects", 27 | "description": "to see my projects", 28 | "info": ["use projects command to see my projects"] 29 | }, 30 | { 31 | "title": "blogs", 32 | "description": "to see my recent blogs", 33 | "info": ["use blogs command to see my recent blogs"] 34 | }, 35 | { 36 | "title": "contact", 37 | "description": "to enquire about my services", 38 | "info": ["use enquire command to enquire about my services"] 39 | }, 40 | { 41 | "title": "cheer", 42 | "description": "to appreciate my work", 43 | "info": ["use cheer command to appreciate my work"] 44 | }, 45 | { 46 | "title": "repos", 47 | "description": "to see my github repositories", 48 | "info": ["use repos command to see my github repositories"] 49 | }, 50 | { 51 | "title": "ipconfig", 52 | "description": "to see your IP details", 53 | "info": ["use ipconfig command to see your IP details"] 54 | }, 55 | { 56 | "title": "github", 57 | "description": "to see my github stats", 58 | "info": ["use github command to see my github stats"] 59 | }, 60 | { 61 | "title": "contributors", 62 | "description": "to see all the contributors", 63 | "info": ["use contributors command to see all the contributors"] 64 | }, 65 | { 66 | "title": "download", 67 | "description": "to download my pdf resume", 68 | "info": ["use download command to download my pdf resume"] 69 | }, 70 | { 71 | "title": "calc", 72 | "description": "to evaluate an expression, for eg: (2 + 3)", 73 | "info": ["use calc command to evaluate an expression","for eg: write 'calc 2+6*5/3'"] 74 | }, 75 | { 76 | "title": "experience", 77 | "description": "to see my work experience", 78 | "info": ["use experience command to see my work experience"] 79 | }, 80 | { 81 | "title": "history", 82 | "description": "shows the last 10 valid commands performed, use --clear flag to clear the history", 83 | "info": ["use history command to show your last 10 commands history","use --clear flag to clear the history","use history {id} command to run command of that id in your history"] 84 | }, 85 | { 86 | "title": "skills", 87 | "description": "to see my skills", 88 | "info": ["use skills command to see my skills"] 89 | }, 90 | { 91 | "title": "typing", 92 | "description": "shows typing animation status", 93 | "info": ["use typing command to see typing animation status","Turn typing animation on and off by adding -on or -off flags respectively","Also u can write a number(in ms) to set typing custom animation speed"] 94 | }, 95 | { 96 | "title": "reset", 97 | "description": "to reload site", 98 | "info": ["use reset command to to reload site"] 99 | } 100 | ], 101 | "terminal": { 102 | "user": "$Sidharth_Sethi", 103 | "host": "sudo", 104 | "path": "~/guest" 105 | }, 106 | "blogs": [ 107 | { 108 | "site": "Medium", 109 | "url": "https://medium.com/feed/@sidharth.sherry" 110 | } 111 | ], 112 | "cheer": { 113 | "responseArray": [ 114 | "Thank you! It makes my day😊😊😊", 115 | "It is great to hear that way!😁😁😁", 116 | "I would love to take credit😂😂😂", 117 | "That's so good to hear! I'm glad😍😍😍" 118 | ] 119 | }, 120 | "about": "🎓 Aspiring software engineer with strong foundation in computer science and engineering, gained through BE degree program and hands-on experience with various technologies. (Graduating July 2024) \n 🌇 Proficient in MERN stack, data structures and algorithms, SQL, and Google Cloud Platform. Demonstrated expertise in these technologies through successful projects and 300+ day badge on LeetCode. \n 📚 Active member of tech community, serving as lead for multiple organizations including GDSC, CodeChef Chapter, and Algoders Community. Contributed to growth and success of these organizations through leadership and technical skills. \n 💻 Constantly seeking opportunities to grow and improve skills, with long-term goal of becoming a software development engineer. As a Google Venkat Scholar, demonstrated commitment to excellence and potential to succeed in tech industry.", 121 | "social": [ 122 | { 123 | "title": "Github", 124 | "link": "https://github.com/techspiritss" 125 | }, 126 | { 127 | "title": "LinkedIn", 128 | "link": "https://www.linkedin.com/in/sidharthsethiss", 129 | "connections": "500+" 130 | }, 131 | { 132 | "title": "LeetCode", 133 | "link": "https://leetcode.com/techspiritss" 134 | }, 135 | { 136 | "title": "Codechef", 137 | "link": "https://www.codechef.com/users/techspiritss", 138 | "rating": "1670", 139 | "rank": "22,497" 140 | } 141 | ], 142 | "projects": [ 143 | { 144 | "title": "Mood Messenger", 145 | "link": "https://github.com/TechSpiritSS/Mood-Messenger", 146 | "description": "Mood Messenger is a real-time chat application built using Node.js, React.js, and Cloud SQL. It allows users to sign in with their Google account, initiate chats with other registered users based on their email, send messages, and view previous chats." 147 | }, 148 | { 149 | "title": "PregChat", 150 | "link": "https://github.com/TechSpiritSS/PregChat_Dialogflow", 151 | "description": "PregChat is a chatbot designed to help expecting mothers access important information about their pregnancy in a simple, accessible and interactive way. Our chatbot is powered by Dialogflow, a Google Cloud-based natural language processing platform. With PregChat, mothers can easily ask about their symptoms and receive information regarding medical emergencies, first aid, medications, and exercises. PregChat aims to provide support and education to mothers in need, ultimately improving the health outcomes for both mother and child." 152 | }, 153 | { 154 | "title": "S Movies", 155 | "link": "https://github.com/TechSpiritSS/S-Movies", 156 | "description": "This is a full fledged movie web app with profile and recommendations system. I am using ESLint configurations for clean code." 157 | }, 158 | { 159 | "title": "MyChabi", 160 | "link": "https://techspiritss.github.io/MyChabi/", 161 | "description": "MyChabi is a web application to help you out with your passwords" 162 | }, 163 | { 164 | "title": "Task C++", 165 | "link": "https://github.com/TechSpiritSS/Task-C-", 166 | "description": "A command-line based task management application" 167 | }, 168 | { 169 | "title": "Notes Insight", 170 | "link": "https://mohityadav0903.github.io/Notes-Insight", 171 | "description": "A note taking app for visually weak and elderly who aren't comfortable with Modern UI" 172 | }, 173 | { 174 | "title": "BigINT Library", 175 | "link": "https://github.com/TechSpiritSS/bigInt.git", 176 | "description": "This is my own C Library for BigINT made from scratch and it supports 2700 digits" 177 | }, 178 | { 179 | "title": "50 Days of Web", 180 | "link": "https://techspiritss.github.io/50-Days-50-Projects-Web-Dev/", 181 | "description": "50 Web Apps made over the period of 50 days for learning purpose" 182 | }, 183 | { 184 | "title": "Covid Vaccination Slot", 185 | "link": "https://github.com/TechSpiritSS/Covid-Vaccine", 186 | "description": "This Python Program informs about the available Covid vaccine slots at your pin code according to your age group" 187 | } 188 | ], 189 | "contact": { 190 | "email": "techspiritss@duck.com" 191 | }, 192 | "experience": [ 193 | { 194 | "title": "SDE Intern at Quaterstack Technologies", 195 | "description": "▪️ Improved performance and maintainability of client-team management application, Redwing, through refactoring of static code into dynamic function calls and reduction of team page code by 70%. \n ▪️ Identified and fixed drag event bug in Nodle Project that caused dramatic increase in CPU utilization (from 7% to 73% with a single mouse drag on flowchart area). \n ▪️ Resolved complex SVG scaling issue in Anatomy-Mapper Project, ensuring accuracy and reliability of visualization." 196 | }, 197 | { 198 | "title": "React Developer at EQ Soft Solutions", 199 | "description": "▪️ Acquired a strong foundation in ReactJS, including in-depth knowledge of key concepts such as routing, reducer, and Axios. \n ▪️ Demonstrated the ability to effectively apply ReactJS principles and techniques in projects and assignments. \n ▪️ Developed a solid understanding of the ReactJS ecosystem, including popular libraries and tools. \n ▪️ Demonstrated adaptability and a willingness to continuously learn and stay up-to-date with developments in the ReactJS field." 200 | } 201 | ], 202 | "skills": [ 203 | { 204 | "title": "Technical skills are: ", 205 | "description": "C++, C, MySQL, Linux, ReactJS, NodeJS, MongoDB, JSON, DSA, Google Cloud Platform, ExpressJS, VueJS, Redux, Material UI, Bootstrap, Tailwind" 206 | }, 207 | { 208 | "title": "Other Skills are:", 209 | "description": "Problem Solving, Team Leadership, Community Management, Team Building" 210 | } 211 | ], 212 | "neofetch": { 213 | "name": "Sidharth Sethi", 214 | "title": "MERN Developer", 215 | "skills": "Frontend, Backend, Cloud", 216 | "shell": "zsh", 217 | "languages": "Javascript, C++, HTML/CSS, SQL" 218 | }, 219 | } 220 | export default config 221 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | Typing SVG 5 |
6 | 7 | ![image](https://user-images.githubusercontent.com/76687985/210350014-65e73f81-4819-44ad-a182-3b8e7f584416.png) 8 | [see live here!](https://techspiritss.github.io/Terminal-Portfolio/) 9 | 10 | ### *Terminal Portfolio* 11 | 12 | ![Issues](https://img.shields.io/github/issues/TechSpiritSS/Terminal-Portfolio?color=brightgreen) 13 | ![Pull requests](https://img.shields.io/github/issues-pr/TechSpiritSS/Terminal-Portfolio) 14 | ![Forks](https://img.shields.io/github/forks/TechSpiritSS/Terminal-Portfolio) 15 | ![Stars](https://img.shields.io/github/stars/TechSpiritSS/Terminal-Portfolio) 16 | ![Licence](https://img.shields.io/github/license/TechSpiritSS/Terminal-Portfolio?color=orange) 17 | 18 | --- 19 | 20 | # Why Terminal Portfolio? 21 | 22 | ## Vision 23 | 24 | Terminal-Portfolio invites talented developers to create stunning, command-line themed portfolios to showcase their skills and work. Command-line interface is a powerful and efficient tool for developers, and this project aims to celebrate this through the creation of visually striking and intuitively designed web terminal. 25 | 26 | ## Status 27 | 28 | I am currently using this as my default Portfolio.:sparkles: 29 | 30 | ## Docs 31 | 32 | - [How to get started with Open Source](#how-to-get-started-with-open-source) 33 | - [Contributing](#contributing) 34 | - [Ground Rules](#ground-rules) 35 | - [Codebase](#codebase) 36 | - [Technologies](#technologies) 37 | 38 |

(back to top)

39 | 40 | ## Codebase 41 | 42 | ### Technologies 43 | 44 |

45 | 46 | HTML 47 | 48 | 49 | CSS 50 | 51 | 52 | JavaScript 53 | 54 |

55 | 56 | **Frontend HTML/CSS/JS**: Almost all of the code you'll touch in this codebase will be HTML, CSS or JavaScript. 57 | 58 | ## How to get started with Open Source 59 | Here's a quick run down on how to get started with open source, first of all let's know some basic terminologies: 60 | 61 | - Git: is a versioning system that let's you store your code and code history on your local computer preventing loses and allowing sharing of that code 62 | - Github: is a server that let's you store the history in a database 63 | - Open Source: A project is said to be open sourced if you can see the code on GitHub 64 | - Fork: This is a copy that you make of a project on GitHub, it gets added to your repositories 65 | - Repository: A project on GitHub is called a repository 66 | - Pull Request: This is a fix for an issue proposed to be done in a project, this consists of you editing a file in the project. 67 | - Issue: An issue is a change that should be done in a project, can be a bug, a new feature or a suggestion to a project 68 | - Branch: A branch is a new workspace derived from the default workspace(main or master), it allows you to work on something without affecting the original code 69 | 70 | Now you know some basic terms, let's get into how to get started with some resources to let you understand open source better: 71 | 72 | - [Crash Course to Git and Github](https://www.youtube.com/watch?v=apGV9Kg7ics) - Video 73 | - [A complete Guide to Open Source](https://www.youtube.com/watch?v=yzeVMecydCE) - Video 74 | - [Guide to Open Source](https://www.freecodecamp.org/news/how-to-contribute-to-open-source-projects-beginners-guide/) - Article 75 | 76 |

(back to top)

77 | 78 | ## Contributing 79 | 80 | - Take a look at the existing [Issues](https://github.com/TechSpiritSS/Terminal-Portfolio/issues) 81 | - Fork the Repo create a branch for any issue that you are working on and commit your work. 82 | - Create a ** [Pull Request](https://github.com/TechSpiritSS/Terminal-Portfolio/pulls), which will be promptly reviewed and given suggestions for improvements by the community. 83 | - Add screenshots or screen captures to your Pull Request to help us understand the effects of the changes that are included in your commits. 84 | 85 | ## How to make a Pull Request? 86 | 87 | 1. Start by forking the [**Terminal-Portfolio**](https://github.com/TechSpiritSS/Terminal-Portfolio) repository. Click on the symbol at the top right corner. 88 | 89 | 1. Clone your forked repository: 90 | 91 | ```bash 92 | git clone https://github.com//Terminal-Portfolio.git 93 | ``` 94 | 95 | 1. Navigate to the new project directory: 96 | 97 | ```bash 98 | cd Terminal-Portfolio 99 | ``` 100 | 101 | 1. Set upstream command: 102 | 103 | ```bash 104 | git remote add upstream https://github.com/TechSpiritSS/Terminal-Portfolio.git 105 | ``` 106 | 107 | 1. Create a new branch: 108 | 109 | ```bash 110 | git checkout -b YourBranchName 111 | ``` 112 | 113 | *or* 114 | 115 | ```bash 116 | git branch YourBranchName 117 | git switch YourBranchName 118 | ``` 119 | 120 | 1. Sync your fork or local repository with the origin repository: 121 | 122 | - In your forked repository click on "Fetch upstream" 123 | - Click "Fetch and merge". 124 | 125 | ### Alternatively, Git CLI way to Sync forked repository with origin repository: 126 | 127 | ```bash 128 | git fetch upstream 129 | ``` 130 | 131 | ```bash 132 | git merge upstream/main 133 | ``` 134 | 135 | ### [Github Docs](https://docs.github.com/en/github/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github) for Syncing 136 | 137 | 7. Make your changes to the source code. 138 | 139 | 8. Stage your changes and commit: 140 | 141 | ⚠️ **Make sure** not to commit `package.json` or `package-lock.json` file 142 | 143 | ⚠️ **Make sure** not to run the commands ```git add .``` or ```git add *```. Instead, stage your changes for each file/folder 144 | 145 | ```bash 146 | git add file/folder 147 | ``` 148 | 149 | ```bash 150 | git commit -m "" 151 | ``` 152 | 153 | 9. Push your local commits to the remote repository: 154 | 155 | ```bash 156 | git push origin YourBranchName 157 | ``` 158 | 159 | 10. Create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)! 160 | 161 |

(back to top)

162 | 163 | ## Alternatively to create a Pull Request using GitHub Desktop: 164 | 165 | 1. Open GitHub Desktop and log in to your GitHub account. 166 | 167 | 2. Make sure you are on the "Current Repository" view. If not, go to "File" and select "Add Local Repository" to add your repository. 168 | 169 | 3. In the "Current Repository" view, ensure you are on the branch that you want to submit a pull request for. If you're not on the correct branch, use the "Branch" menu to switch to the correct branch. 170 | 171 | 4. Once you're on the correct branch, make your changes and commit them to the branch. You can do this by clicking the "+" button in the upper-left corner of the GitHub Desktop window, making your changes, and then entering a commit message. 172 | 173 | 5. After you've made your changes and committed them, click the "Push origin" button in the top-right corner of the GitHub Desktop window. This will push your changes to the remote repository on GitHub. 174 | 175 | 6. Now, go to the GitHub website, navigate to your fork of the repository, and you should see a button to "Compare & pull request" between your fork and the original repository, click on it. 176 | 177 | 7. On the pull request page, you can review your changes and add any additional information, such as a title and a description, that you want to include with your pull request. 178 | 179 | 8. Once you're satisfied with your pull request, click the "Create pull request" button to submit it. 180 | 181 | **Note:** In order to create a pull request, you must have a fork of the original repository in your GitHub account and you must have made the changes in that forked repository. 182 | 183 | ## **Congratulations!** You've made your first contribution! 🙌🏼 184 | 185 | **We heartily welcome any and all contributions that match our engineering standards! :raised_hands:** 186 | 187 |

(back to top)

188 | 189 | ## Ground Rules 190 | 191 | #### Contributions and discussion guidelines 192 | 193 | All conversations and communities on Terminal Portfolio agree to GitHub's [Community Guidelines](https://help.github.com/en/github/site-policy/github-community-guidelines) and [Acceptable Use Policies](https://help.github.com/en/github/site-policy/github-acceptable-use-policies). This code of conduct also applies to all conversations that happen within our contributor community here on GitHub. We expect discussions in issues and pull requests to stay positive, productive, and respectful. **Remember**: There are real people on the other side of that screen:exclamation: 194 | 195 | #### Reporting a bug or discussing a feature idea 196 | 197 | If you found a technical bug on Terminal Portfolio or have ideas for features we should implement, the issue tracker is the best place to share your ideas. Make sure to follow the issue template and you should be golden! ([click here to open a new issue](https://github.com/TechSpiritSS/Terminal-Portfolio/issues/new)) 198 | 199 | #### Fixing a bug or implementing a new feature 200 | 201 | - If you find a bug on Terminal Portfolio and open a PR that fixes it. 202 | - If you want to implement a new feature, open an issue first to discuss what it'd look like . 203 | - If you want to contribute but are unsure to start, we have [a "good first issue" label](https://github.com/TechSpiritSS/Terminal-Portfolio/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) which is applied to newcomer-friendly issues. Take a look at [the full list of good first issues](https://github.com/TechSpiritSS/Terminal-Portfolio/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and pick something you like! 204 | - Want to fix a bug or implement an agreed-upon feature? Great, jump to the [local setup instructions](#first-time-setup)! 205 | 206 |

(back to top)

207 | 208 | ## Open Source Programs 209 | 210 | Hacktoberfest22-Dark 211 | 212 | 213 | 214 | SWOC S3 215 | 216 | 217 | ## Thanks to all Contributors 💪 218 | 219 | Thanks a lot for spending your time helping Terminal Portfolio grow. Thanks a lot! Keep rocking 🍻 220 | 221 | [![Contributors](https://contrib.rocks/image?repo=techspiritss/terminal-portfolio)](https://github.com/TechSpiritSS/Terminal-Portfolio/graphs/contributors) 222 | 223 | ## License 224 | 225 | ### MIT License, see the [LICENSE](./LICENSE) file 226 | 227 |

(back to top)

228 | -------------------------------------------------------------------------------- /scripts/functions.js: -------------------------------------------------------------------------------- 1 | //Functions file. All important functions are defined here. These are used for setup & operations 2 | 3 | //Imports done 4 | import config from "../config.js"; 5 | import { 6 | fetchGithubSocialStats, 7 | fetchLinkedInStats, 8 | fetchLeetCodeStats, 9 | fetchGithubStats, 10 | connections, 11 | githubStats, 12 | followers, 13 | following, 14 | ranking, 15 | totalSolved, 16 | easySolved, 17 | mediumSolved, 18 | hardSolved, 19 | } from "./fetchStats.js"; 20 | import { 21 | getContributors, 22 | getBlogs, 23 | getIPDetails, 24 | getRepo, 25 | contributors, 26 | userBlogs, 27 | IpDetails, 28 | userRepos, 29 | } from "./getDetails.js"; 30 | import { suggestFurtherCommand } from "./compare.js"; 31 | import { 32 | commandHistory, 33 | saveHistory, 34 | clearHistory, 35 | popInvalidCommand, 36 | runSpecificHistoryCmd, 37 | } from "./history.js"; 38 | 39 | const app = document.querySelector("#app"); 40 | let delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 41 | const resumeUrl = "https://drive.google.com/u/0/uc?id=1J8QGMreVTsC-K-d5bpKV1BVNXxrCUYQa&export=download"; 42 | 43 | //Defining the functions 44 | function neofetch() { 45 | // read data from data.json 46 | const data = config.neofetch; 47 | console.log(data); 48 | 49 | const container = document.createElement("div"); 50 | container.classList.add("fetch-container"); 51 | 52 | const fimg = document.createElement("div"); 53 | fimg.classList.add("fetch-img-container"); 54 | fimg.innerHTML = ""; 55 | 56 | const info = document.createElement("div"); 57 | info.classList.add("info"); 58 | container.appendChild(fimg); 59 | container.appendChild(info); 60 | 61 | for (const [key, value] of Object.entries(data)) { 62 | const p = document.createElement("p"); 63 | p.innerHTML = `${key}: ${value}`; 64 | info.appendChild(p); 65 | } 66 | 67 | app.appendChild(container); 68 | } 69 | 70 | 71 | function removeNeoFetch() { 72 | const element = document.querySelector(".fetch-container") 73 | if (element) element.remove(); 74 | } 75 | 76 | 77 | async function getInputValue(history, remove = false, cmd = undefined) { 78 | const val = cmd || document.querySelector("input").value.trim().toLowerCase(); 79 | saveHistory(val); 80 | const a = val.split(" "); 81 | const flag = a[1]; 82 | const value = a[0]; 83 | const flags = [...a]; 84 | 85 | flags.shift(); // removes the first element 86 | if (value.substring(0, 5) === "cheer") { 87 | value.substring(0, 5).toLowerCase(); 88 | } else { 89 | value.replace(/\s+/g, "").toLowerCase(); 90 | } 91 | 92 | history.push(cmd || document.querySelector("input").value); 93 | 94 | if (remove) removeInput(); 95 | 96 | switch (value) { 97 | case "help": 98 | case "ls": 99 | config.help.sort((a, b) => { 100 | return a.title.localeCompare(b.title); 101 | }); 102 | 103 | if (flag == '-d') { 104 | trueValue(val) 105 | for (let item of config.help) { 106 | await createText(`${item.title} :- ${item.description}`); 107 | } 108 | break; 109 | } 110 | 111 | if (flag) { 112 | trueValue(val); 113 | let isCmd = false; 114 | for (let x of config.help) { 115 | if (flag === x.title) { 116 | for (let i=0;i item.title); 133 | let titlesString = titles.join(', '); 134 | await createText(titlesString); 135 | await createText("type -d for more description") 136 | await createText("write help {command name} to know about specific command like 'help github'") 137 | break; 138 | 139 | case "neofetch": 140 | neofetch(); 141 | break; 142 | case "about": 143 | trueValue(value); 144 | await createText(config.about); 145 | break; 146 | 147 | case "reset": 148 | trueValue(value); 149 | location.reload(true); 150 | break; 151 | case "social": 152 | if (flag == "-l") { 153 | trueValue(val); 154 | config.social.forEach((item) => { 155 | createText(`${item.title} :- ${item.link} 156 | `, false); 157 | }); 158 | break; 159 | } else if (flag == "-d") { 160 | trueValue(val); 161 | config.social.forEach(async (item) => { 162 | createText(`${item.title} Link :- ${item.link} 163 | `, false); 164 | if (item.title == "Github") { 165 | createText(`Number of followers: ${followers}`); 166 | createText(`Number of following: ${following}`); 167 | } 168 | if (item.title == "LinkedIn") { 169 | createText(`Connections : 500+`); 170 | } 171 | if (item.title == "LeetCode") { 172 | createText(`Problems Solved: ${totalSolved}`); 173 | createText( 174 | `Distribution:- Easy:${easySolved} Medium:${mediumSolved} Hard:${hardSolved}` 175 | ); 176 | createText(`Ranking: ${ranking}`); 177 | } 178 | if (item.title == "Codechef") { 179 | createText(`Rank : ${item.rank}`); 180 | createText(`Rating : ${item.rating}`); 181 | } 182 | }); 183 | break; 184 | } 185 | trueValue(value); 186 | config.social.forEach((item) => { 187 | createText( 188 | `${item.title}`, false 189 | ); 190 | }); 191 | break; 192 | case "projects": 193 | trueValue(value); 194 | await createText("Projects:"); 195 | config.projects.forEach(async (item) => { 196 | await createText( 197 | `${item.title} - ${item.description}`, false 198 | ); 199 | }); 200 | break; 201 | case "blogs": 202 | trueValue(value); 203 | await createText("Recent Blogs:"); 204 | // Hashnode Feed URL: https://username.hashnode.dev/rss.xml 205 | // Dev.to Feed URL: https://dev.to/feed/username 206 | // Medium Feed URL: https://medium.com/feed/@username 207 | // TODO: Insert your Medium/Dev/Hashnode or any blog feed URL below 208 | userBlogs.forEach(async (blog) => { 209 | createText(`${blog.site}: `); 210 | blog.items.forEach((item, index) => { 211 | createText( 212 | `${index + 1}. ${item.title 213 | }`, false 214 | ); 215 | }); 216 | }); 217 | break; 218 | case "contributors": 219 | trueValue(value); 220 | contributors.forEach((user) => { 221 | createText( 222 | `- ${user.username}`, false 223 | ); 224 | }); 225 | await createText(`- Thanks to all the contributors 💖`); 226 | break; 227 | case "experience": 228 | trueValue(value); 229 | await createText("My Work Experience:"); 230 | config.experience.forEach((item) => { 231 | createText(`${item.title}`); 232 | createText(`${item.description} `); 233 | }); 234 | break; 235 | case "skills": 236 | trueValue(value); 237 | config.skills.forEach((item) => { 238 | createText(`${item.title}`); 239 | createText(`${item.description} `); 240 | }); 241 | break; 242 | case "ipconfig": 243 | trueValue(value); 244 | const IP = IpDetails[0]; 245 | await createText(`- Ipv6: ${IP.ip}`); 246 | await createText(`- network: ${IP.network}`); 247 | await createText(`- city: ${IP.city}`); 248 | await createText(`- network org: ${IP.org}`); 249 | await createText(`- region: ${IP.region}`); 250 | await createText(`- postal: ${IP.postal}`); 251 | break; 252 | case "repos": 253 | trueValue(value); 254 | userRepos[0].forEach((repo, index) => { 255 | createText( 256 | `- repo_${index} name: ${repo.name 257 | } | language: ${repo.language === null ? "no language" : repo.language 258 | }`, false 259 | ); 260 | createText( 261 | `_ description: ${repo.description === null 262 | ? "no description." 263 | : repo.description 264 | } ` 265 | ); 266 | }); 267 | break; 268 | case "download": 269 | trueValue(value); 270 | downloadFile(); 271 | break; 272 | case "clear": 273 | case "cls": 274 | document 275 | .querySelectorAll("p") 276 | .forEach((e) => e.parentNode.removeChild(e)); 277 | document 278 | .querySelectorAll("section") 279 | .forEach((e) => e.parentNode.removeChild(e)); 280 | removeNeoFetch(); 281 | removeInput(); 282 | await delay(150); 283 | break; 284 | case "contact": 285 | createText( 286 | `Hey! Would love to get in touch.
287 | My linkedin profile link: LinkedIn.
288 | Drop me a text at ${config.contact.email}`, false 289 | ); 290 | window.location.href = `mailto:${config.contact.email}`; 291 | // window.open(`mailto:${config.contact.email}`, "_blank"); 292 | break; 293 | case "sudo": 294 | trueValue(value); 295 | await createText("You are not authorized to use this command"); 296 | break; 297 | case "github": 298 | trueValue(value); 299 | await createText(`Github Username: ${githubStats.username}`); 300 | await createText(`Github Bio: ${githubStats.bio}`); 301 | await createText(`Number of repositories : ${githubStats.public_repos}`); 302 | await createText(`Number of gists: ${githubStats.public_gists}`); 303 | await createText(`Number of followers: ${githubStats.followers}`); 304 | await createText(`Number of following: ${githubStats.following}`); 305 | break; 306 | case "cd": 307 | trueValue(value); 308 | await createText("There's no directory in this path"); 309 | break; 310 | case "calc": 311 | calc(flags.join("")); 312 | break; 313 | case "history": 314 | if (flag === "--clear") { 315 | clearHistory(); 316 | } 317 | if (Number(flag)) { 318 | await runSpecificHistoryCmd(Number(flag)); 319 | } else { 320 | await commandHistory(); 321 | } 322 | break; 323 | case "typing": 324 | await typingCmd(flag); 325 | break; 326 | case "exit": 327 | window.close(); 328 | default: 329 | if (value.substring(0, 5) === "cheer") { 330 | trueValue(value); 331 | const reply = 332 | config.cheer.responseArray[ 333 | Math.floor( 334 | Math.random() * config.cheer.responseArray.length 335 | ) 336 | ]; 337 | await createText(reply); 338 | } else { 339 | falseValue(value); 340 | await createText(`${value} is not a valid command`); 341 | let commands = suggestFurtherCommand(value); 342 | await createText("Are you looking for this: " + commands); 343 | } 344 | } 345 | } 346 | 347 | function new_line() { 348 | const p = document.createElement("p"); 349 | const span = document.createElement("span"); 350 | const span2 = document.createElement("span"); 351 | p.setAttribute("class", "path"); 352 | p.textContent = config.terminal.user + " "; 353 | span.textContent = config.terminal.host + " "; 354 | span2.textContent = config.terminal.path + " "; 355 | p.appendChild(span); 356 | p.appendChild(span2); 357 | app.appendChild(p); 358 | const div = document.createElement("div"); 359 | div.setAttribute("class", "type"); 360 | const i = document.createElement("i"); 361 | i.setAttribute("class", "fas fa-angle-right icone"); 362 | const input = document.createElement("input"); 363 | div.appendChild(i); 364 | div.appendChild(input); 365 | app.appendChild(div); 366 | input.focus(); 367 | } 368 | 369 | function removeInput() { 370 | const div = document.querySelector(".type"); 371 | if (div) app.removeChild(div); 372 | } 373 | 374 | function trueValue(value) { 375 | const div = document.createElement("section"); 376 | div.setAttribute("class", "type2"); 377 | const i = document.createElement("i"); 378 | i.setAttribute("class", "fas fa-angle-right icone"); 379 | const msg = document.createElement("h2"); 380 | msg.textContent = `${value}`; 381 | div.appendChild(i); 382 | div.appendChild(msg); 383 | app.appendChild(div); 384 | } 385 | 386 | function falseValue(value) { 387 | const div = document.createElement("section"); 388 | div.setAttribute("class", "type2"); 389 | const i = document.createElement("i"); 390 | i.setAttribute("class", "fas fa-angle-right icone"); 391 | const msg = document.createElement("h2"); 392 | msg.setAttribute("class", "error"); 393 | msg.textContent = `${value}`; 394 | div.appendChild(i); 395 | div.appendChild(msg); 396 | app.appendChild(div); 397 | } 398 | 399 | async function createText(text, typingOn = true) { 400 | const p = document.createElement("p"); 401 | app.appendChild(p); 402 | p.scrollIntoView({ behavior: 'smooth' }); 403 | 404 | const typing = localStorage.getItem("typing"); 405 | 406 | if (!typingOn || (typing && typing === "off")) { 407 | p.innerHTML = text; 408 | return; 409 | } 410 | 411 | const typingSpeed = localStorage.getItem("typingSpeed") || 20; 412 | 413 | let index = 0; 414 | async function writeText() { 415 | while (index < text.length) { 416 | p.innerHTML += text[index++]; 417 | await new Promise((writeText) => setTimeout(writeText, typingSpeed)); 418 | } 419 | return; 420 | } 421 | 422 | await writeText(); 423 | 424 | } 425 | 426 | async function createCode(code, text, typingOn = true) { 427 | const p = document.createElement("p"); 428 | app.appendChild(p); 429 | 430 | const typing = localStorage.getItem("typing"); 431 | 432 | if (!typingOn || (typing && typing === "off")) { 433 | p.innerHTML = `${code} => ${text}`; 434 | return; 435 | } 436 | 437 | const typingSpeed = localStorage.getItem("typingSpeed") || 20; 438 | 439 | const span = document.createElement("span"); 440 | span.className = "code" 441 | p.appendChild(span); 442 | p.scrollIntoView({ behavior: 'smooth' }); 443 | let index = 0; 444 | async function writeCode() { 445 | while (index < code.length) { 446 | span.innerHTML += code[index++]; 447 | await new Promise((writeCode) => setTimeout(writeCode, typingSpeed)); 448 | } 449 | return; 450 | } 451 | await writeCode(); 452 | 453 | p.innerHTML += " " 454 | 455 | index = 0; 456 | async function writeText() { 457 | while (index < text.length) { 458 | p.innerHTML += text[index++]; 459 | await new Promise((writeText) => setTimeout(writeText, typingSpeed)); 460 | } 461 | return; 462 | } 463 | 464 | await writeText(); 465 | 466 | } 467 | 468 | function downloadFile() { 469 | let link = document.createElement("a"); 470 | link.href = resumeUrl; 471 | link.click(); 472 | const p = document.createElement("p"); 473 | p.innerHTML = "###############"; 474 | app.appendChild(p); 475 | setTimeout(() => { 476 | app.removeChild(p); 477 | }, 2500); 478 | document.body.removeChild(link); 479 | } 480 | 481 | async function calc(flag) { 482 | try { 483 | if (flag === "" || flag === " " || flag === undefined) { 484 | falseValue(flag); 485 | await createText("Please Enter a Valid Expression"); 486 | } else { 487 | trueValue(flag); 488 | function parse(str) { 489 | return Function(`'use strict'; return (${str})`)(); 490 | } 491 | await createText(flag + " = " + parse(flag)); 492 | } 493 | } catch (e) { 494 | falseValue(flag); 495 | await createText(flag + " is an Invalid Expression"); 496 | } 497 | } 498 | 499 | // all functions exported 500 | export { 501 | neofetch, 502 | removeNeoFetch, 503 | getInputValue, 504 | new_line, 505 | removeInput, 506 | trueValue, 507 | falseValue, 508 | createText, 509 | createCode, 510 | downloadFile, 511 | calc, 512 | }; 513 | 514 | const typingCmd = async (flag) => { 515 | const typing = localStorage.getItem("typing"); 516 | let typingSpeed = localStorage.getItem("typingSpeed"); 517 | 518 | if (flag == "-on") { 519 | localStorage.setItem("typing", "on"); 520 | createText("Typing animation is turned on"); 521 | } else if (flag == "-off") { 522 | localStorage.setItem("typing", "off"); 523 | createText("Typing animation is turned off"); 524 | } else if (Number(flag)) { 525 | localStorage.setItem("typingSpeed", Number(flag)); 526 | typingSpeed = localStorage.getItem("typingSpeed"); 527 | await createText(`Typing animation speed is set to ${typingSpeed ? typingSpeed : 20}ms`); 528 | } else { 529 | await createText(`Typing animation is currently ${typing ? typing : "on"} and speed is set to ${typingSpeed ? typingSpeed : 20}ms`); 530 | await createText("Turn typing animation on and off by adding -on or -off flags respectively"); 531 | await createText("Also u can write a number(in ms) to set typing custom animation speed"); 532 | } 533 | } --------------------------------------------------------------------------------