├── .gitignore ├── .vscode └── settings.json ├── CircuitBreaker ├── CircuitBreaker-configurable.js ├── CircuitBreaker-manual-overrides.js ├── CircuitBreaker-with-fallback.js ├── CircuitBreaker.js └── README.md ├── LICENSE ├── RGB-to-hex └── rbg-to-hex.js ├── accordion ├── index.html ├── script.js └── style.css ├── acsci-to-binary └── atob.js ├── advanced-obj └── main.js ├── arrays-methods ├── array-from.js ├── async 2.js ├── async.js ├── concat.js ├── copies.js ├── copyWithin.js ├── destructuring.js ├── entries.js ├── filter-hasNext.js ├── filter-numbers.js ├── filter-objects.js ├── find-indexes.js ├── find.js ├── flat.js ├── for-of-in.js ├── for.js ├── forEach.js ├── map.js ├── mother.js ├── push.js ├── reduce-to-array.js ├── reduce-to-object.js ├── reduce-to-value.js ├── shift.js ├── slice.js ├── some-every.js ├── sort.js └── splice.js ├── async-array-loops └── app.js ├── binary-search-algorithm └── main.js ├── calculate-mouse-pos └── mouse-position.js ├── camera-access ├── camera.html └── camera.js ├── challenges └── string-challenges.js ├── change-bg-color ├── index.html └── script.js ├── color-methods ├── eyeDropper.js └── index.html ├── console └── log.js ├── count-of-lines ├── count-of-lines.js └── test.js ├── create-custom-element ├── index.html └── script.js ├── d3-parliment ├── d3-parliament-chart.js └── d3-parliament-chart.min.js ├── date-methods ├── date.js └── format-date.js ├── decimal-to-binary └── decimal-to-binary.js ├── email-validation ├── index.html └── script.js ├── equations └── liner-aquation.js ├── fetch-api └── chaining-promises.js ├── flat-flatmap └── flat.js ├── generators ├── generate-otp │ └── generate-opt.js └── id-generator.js ├── graph-traversal ├── breadth-first-search.js ├── dfs.js └── graph.js ├── guess-number └── main.js ├── hash-train └── hash.js ├── html-to-text └── html-to-text.js ├── js-algorithms ├── bubble-sort │ └── bubble-sort.js ├── selection-sort │ └── main.js └── sort │ └── sort.js ├── js-clock ├── index.html └── script.js ├── js-tricks ├── async.js ├── calculateDaysBetweenDates.js ├── clone-object.js ├── download-file.js ├── functions.js ├── get-ip.js ├── promis.js ├── string-search.js ├── uid.js └── using-switch.js ├── letter-to-UpperCase └── main.js ├── local-storage └── save-localStorage-to-file.js ├── matrix-bg ├── index.html └── scripts.js ├── mobile-phone-methods ├── orientation.js ├── phone-vibration.js └── screen-wake.js ├── mouse-methods └── onOutsideClick.js ├── onclick └── index.html ├── oneLineCodes ├── 20OneLinesPro.js └── script.js ├── package-lock.json ├── palindrome └── checkPalindrome.js ├── password-validator ├── index.html ├── script.js └── style.css ├── photo-uploader ├── index.html └── scripts.js ├── pwd-generator ├── index.html └── script.js ├── quiz └── quizq.js ├── react └── index.html ├── readme.md ├── recaptcha └── recaptcha.js ├── recursive-factorial └── rf.js ├── reduce-method └── index.js ├── regex-pattern ├── validate-email.js └── validate-phone-number.js ├── rxjs ├── index.html └── index.js ├── search └── search.js ├── short-code-snippets └── app.js ├── snake-game ├── draw.js ├── fruit.js ├── index.html └── snake.js ├── sololearn └── js-course │ ├── currency-convertor.js │ └── snail.js ├── sort-by-js ├── index.html └── script.js ├── speed-typing ├── index.html ├── scripts.js └── styles.css ├── string-methods ├── byte-to-size.js └── limit-with-substring.js ├── text-to-img-server ├── text-to-img.md └── txt-to-img.js ├── textColor ├── index.html ├── script.js └── style.css ├── tip-calculator ├── index.html ├── scripts.js └── styles.css ├── touch-events ├── app.js └── index.html ├── ts ├── app.js ├── export-to-file.ts ├── get-ip.ts ├── index.ts └── string-code-extract.ts ├── url-snippets └── get-url-parts.js ├── useblackbox.io └── test.js ├── useful-Snippets ├── capitalize-string.js ├── clear-all-cookies.js ├── copy-to-clipboard.js ├── dynamic-get-all-el.js ├── generate-random-hex.js ├── reverse-string.js └── scroll-to-top.js ├── vanilla-web-components ├── counter.js └── index.html ├── web-worker ├── index.html ├── index.js └── worker.js ├── why-people-hate-js └── resons.js └── ᛉ-algorithms ├── bubble-sort-search.js └── recursive-factorial.js /.gitignore: -------------------------------------------------------------------------------- 1 | config.json 2 | .env 3 | /.idea 4 | /.vscode 5 | /sounds/** 6 | !/sounds/putmusichere.mp3 7 | /dist 8 | 9 | # Logs 10 | logs 11 | *.log 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | 28 | # nyc test coverage 29 | .nyc_output 30 | 31 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 32 | .grunt 33 | 34 | # Bower dependency directory (https://bower.io/) 35 | bower_components 36 | 37 | # node-waf configuration 38 | .lock-wscript 39 | 40 | # Compiled binary addons (https://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directories 44 | node_modules/ 45 | jspm_packages/ 46 | 47 | # TypeScript v1 declaration files 48 | typings/ 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # Temp ignore 66 | config.json 67 | # General 68 | .DS_Store 69 | .AppleDouble 70 | .LSOverride 71 | __MACOSX 72 | 73 | # Icon must end with two \r 74 | Icon 75 | 76 | # Thumbnails 77 | ._* 78 | 79 | # Files that might appear in the root of a volume 80 | .DocumentRevisions-V100 81 | .fseventsd 82 | .Spotlight-V100 83 | .TemporaryItems 84 | .Trashes 85 | .VolumeIcon.icns 86 | .com.apple.timemachine.donotpresent 87 | 88 | # Directories potentially created on remote AFP share 89 | .AppleDB 90 | .AppleDesktop 91 | Network Trash Folder 92 | Temporary Items 93 | .apdisk -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501, 3 | "workbench.colorCustomizations": { 4 | "statusBar.background": "#ffee00", 5 | "statusBar.foreground": "#ff0000", 6 | "statusBar.border": "#ffee00" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CircuitBreaker/CircuitBreaker-configurable.js: -------------------------------------------------------------------------------- 1 | class CircuitBreaker { 2 | constructor(request, options = {}) { 3 | const defaults = { 4 | failureThreshold: 3, 5 | successThreshold: 2, 6 | timeout: 6000 7 | } 8 | Object.assign(this, defaults, options, { 9 | request, 10 | state: "CLOSED", 11 | failureCount: 0, 12 | successCount: 0, 13 | nextAttempt: Date.now() 14 | }) 15 | } 16 | 17 | async fire() { 18 | if (this.state === "OPEN") { 19 | if (this.nextAttempt <= Date.now()) { 20 | this.state = "HALF" 21 | } else { 22 | throw new Error("Breaker is OPEN") 23 | } 24 | } 25 | try { 26 | const response = await this.request() 27 | return this.success(response) 28 | } catch (err) { 29 | return this.fail(err) 30 | } 31 | } 32 | 33 | success(response) { 34 | if (this.state === "HALF") { 35 | this.successCount++ 36 | if (this.successCount > this.successThreshold) { 37 | this.successCount = 0 38 | this.state = "CLOSED" 39 | } 40 | } 41 | this.failureCount = 0 42 | 43 | this.status("Success") 44 | return response 45 | } 46 | 47 | fail(err) { 48 | this.failureCount++ 49 | if (this.failureCount >= this.failureThreshold) { 50 | this.state = "OPEN" 51 | this.nextAttempt = Date.now() + this.timeout 52 | } 53 | this.status("Failure") 54 | return err 55 | } 56 | 57 | status(action) { 58 | console.table({ 59 | Action: action, 60 | Timestamp: Date.now(), 61 | Successes: this.successCount, 62 | Failures: this.failureCount, 63 | "Next State": this.state 64 | }) 65 | } 66 | } 67 | 68 | module.exports = CircuitBreaker -------------------------------------------------------------------------------- /CircuitBreaker/CircuitBreaker-manual-overrides.js: -------------------------------------------------------------------------------- 1 | class CircuitBreaker { 2 | constructor(request, options = {}) { 3 | const defaults = { 4 | failureThreshold: 3, 5 | successThreshold: 2, 6 | timeout: 6000 7 | } 8 | Object.assign(this, defaults, options, { 9 | request, 10 | state: "CLOSED", 11 | failureCount: 0, 12 | successCount: 0, 13 | nextAttempt: Date.now() 14 | }) 15 | } 16 | 17 | async fire() { 18 | if (this.state === "OPEN") { 19 | if (this.nextAttempt <= Date.now()) { 20 | this.state = "HALF" 21 | } else { 22 | throw new Error("Breaker is OPEN") 23 | } 24 | } 25 | try { 26 | const response = await this.request() 27 | return this.success(response) 28 | } catch (err) { 29 | return this.fail(err) 30 | } 31 | } 32 | 33 | success(response) { 34 | if (this.state === "HALF") { 35 | this.successCount++ 36 | if (this.successCount > this.successThreshold) { 37 | this.close() 38 | } 39 | } 40 | this.failureCount = 0 41 | 42 | this.status("Success") 43 | return response 44 | } 45 | 46 | fail(err) { 47 | this.failureCount++ 48 | if (this.failureCount >= this.failureThreshold) { 49 | this.open() 50 | } 51 | this.status("Failure") 52 | return err 53 | } 54 | 55 | open() { 56 | this.state = "OPEN" 57 | this.nextAttempt = Date.now() + this.timeout 58 | } 59 | close() { 60 | this.successCount = 0 61 | this.failureCount = 0 62 | this.state = "CLOSED" 63 | } 64 | half() { 65 | this.state = "HALF" 66 | } 67 | 68 | status(action) { 69 | console.table({ 70 | Action: action, 71 | Timestamp: Date.now(), 72 | Successes: this.successCount, 73 | Failures: this.failureCount, 74 | "Next State": this.state 75 | }) 76 | } 77 | } 78 | module.exports = CircuitBreaker -------------------------------------------------------------------------------- /CircuitBreaker/CircuitBreaker-with-fallback.js: -------------------------------------------------------------------------------- 1 | class CircuitBreaker { 2 | constructor(request, options = {}) { 3 | const defaults = { 4 | failureThreshold: 3, 5 | successThreshold: 2, 6 | timeout: 6000, 7 | fallback: null 8 | } 9 | Object.assign(this, defaults, options, { 10 | request, 11 | state: "CLOSED", 12 | failureCount: 0, 13 | successCount: 0, 14 | nextAttempt: Date.now() 15 | }) 16 | } 17 | 18 | async fire() { 19 | if (this.state === "OPEN") { 20 | if (this.nextAttempt <= Date.now()) { 21 | this.state = "HALF" 22 | } else { 23 | if (this.fallback) { 24 | return this.tryFallback() 25 | } 26 | throw new Error("Breaker is OPEN") 27 | } 28 | } 29 | try { 30 | const response = await this.request() 31 | return this.success(response) 32 | } catch (err) { 33 | return this.fail(err) 34 | } 35 | } 36 | 37 | success(response) { 38 | if (this.state === "HALF") { 39 | this.successCount++ 40 | if (this.successCount > this.successThreshold) { 41 | this.successCount = 0 42 | this.state = "CLOSED" 43 | } 44 | } 45 | this.failureCount = 0 46 | 47 | this.status("Success") 48 | return response 49 | } 50 | 51 | fail(err) { 52 | this.failureCount++ 53 | if (this.failureCount >= this.failureThreshold) { 54 | this.open() 55 | } 56 | this.status("Failure") 57 | if (this.fallback) return this.tryFallback() 58 | return err 59 | } 60 | 61 | open() { 62 | this.state = "OPEN" 63 | this.nextAttempt = Date.now() + this.timeout 64 | } 65 | close() { 66 | this.successCount = 0 67 | this.failureCount = 0 68 | this.state = "CLOSED" 69 | } 70 | half() { 71 | this.state = "HALF" 72 | } 73 | 74 | async tryFallback() { 75 | console.log("Attempting fallback request") 76 | try { 77 | const response = await this.fallback() 78 | return response 79 | } catch (err) { 80 | return err 81 | } 82 | } 83 | 84 | status(action) { 85 | console.table({ 86 | Action: action, 87 | Timestamp: Date.now(), 88 | Successes: this.successCount, 89 | Failures: this.failureCount, 90 | "Next State": this.state 91 | }) 92 | } 93 | } 94 | 95 | module.exports = CircuitBreaker 96 | -------------------------------------------------------------------------------- /CircuitBreaker/CircuitBreaker.js: -------------------------------------------------------------------------------- 1 | class CircuitBreaker { 2 | constructor(request) { 3 | this.request = request 4 | this.state = "CLOSED" 5 | this.failureThreshold = 3 6 | this.failureCount = 0 7 | this.successThreshold = 2 8 | this.successCount = 0 9 | this.timeout = 6000 10 | this.nextAttempt = Date.now() 11 | } 12 | 13 | async fire() { 14 | if (this.state === "OPEN") { 15 | if (this.nextAttempt <= Date.now()) { 16 | this.state = "HALF" 17 | } else { 18 | throw new Error("Breaker is OPEN") 19 | } 20 | } 21 | try { 22 | const response = await this.request() 23 | return this.success(response) 24 | } catch (err) { 25 | return this.fail(err) 26 | } 27 | } 28 | 29 | success(response) { 30 | if (this.state === "HALF") { 31 | this.successCount++ 32 | if (this.successCount > this.successThreshold) { 33 | this.successCount = 0 34 | this.state = "CLOSED" 35 | } 36 | } 37 | this.failureCount = 0 38 | 39 | this.status("Success") 40 | return response 41 | } 42 | 43 | fail(err) { 44 | this.failureCount++ 45 | if (this.failureCount >= this.failureThreshold) { 46 | this.state = "OPEN" 47 | this.nextAttempt = Date.now() + this.timeout 48 | } 49 | this.status("Failure") 50 | return err 51 | } 52 | 53 | status(action) { 54 | console.table({ 55 | Action: action, 56 | Timestamp: Date.now(), 57 | Successes: this.successCount, 58 | Failures: this.failureCount, 59 | "Next State": this.state 60 | }) 61 | } 62 | } 63 | 64 | module.exports = CircuitBreaker 65 | -------------------------------------------------------------------------------- /CircuitBreaker/README.md: -------------------------------------------------------------------------------- 1 | # Circuit Breakers 2 | 3 | The following examples are for [Building a Circuit Breaker in Node.js](https://bearer.sh/blog/build-a-circuit-breaker-in-node-js-part-2) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehsanghaffar/javascript-playground/985dd2bbe6f40cd58c8616d9464f6dd9122ce3d3/LICENSE -------------------------------------------------------------------------------- /RGB-to-hex/rbg-to-hex.js: -------------------------------------------------------------------------------- 1 | 2 | // function for convert RGB to Hex code 3 | const rgbToHex = (r, g, b) => 4 | "#" + ((1 << 24) + (r << 16) + (g << 8) + b) 5 | .toString(16).slice(1); 6 | 7 | 8 | // example 9 | const example = rgbToHex(255, 0, 0) 10 | 11 | // test 12 | // console.log(example) 13 | -------------------------------------------------------------------------------- /accordion/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Accordion with javascript 7 | 8 | 9 | 10 |
11 |

12 | Accordion tabs with javascript 13 |

14 | 15 |
16 |
17 |

Tab 1 Title

18 |
19 |
20 |

21 | Tab 1 text is here. 22 | Tab 1 text is here. 23 |

24 |
25 |
26 | 27 |
28 |
29 |

Tab 2 Title

30 |
31 |
32 |

33 | Tab 2 text is here. 34 | Js project with Ehsanghaffarii 35 |

36 |
37 |
38 | 39 |
40 |
41 |

Tab 3 Title

42 |
43 |
44 |

45 | tab 3 content is here. 46 | Accordion with javascript by Ehsanghaffarii 47 |

48 |
49 |
50 |
51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /accordion/script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * create accordion with js 3 | * @param {string} selector 4 | * @param {string} openTab 5 | * @param {string} closeTab 6 | * @return {object} 7 | * @author: Ehsan Ghaffar 8 | */ 9 | const tabs = document.querySelectorAll(".tab"); 10 | 11 | const openTab = (tab) => { 12 | const content = tab.childNodes[3]; 13 | const contentHeight = content.scrollHeight; 14 | content.style.height = contentHeight + "px"; 15 | }; 16 | 17 | /** 18 | * 19 | * @param tabs 20 | * @param openTab 21 | * @param closeTab 22 | * @return {object} 23 | */ 24 | const closeTab = (tabs, openTab) => { 25 | tabs.forEach((tab) => { 26 | if (tab !== openTab) { 27 | const content = tab.childNodes[3]; 28 | content.style.height = 0; 29 | } 30 | }); 31 | }; 32 | 33 | /** 34 | * @param {string} selector 35 | * @param {string} openTab 36 | * @param {string} closeTab 37 | * @return {object} 38 | */ 39 | tabs.forEach((tab) => { 40 | tab.addEventListener("click", () => { 41 | openTab(tab); 42 | closeTab(tabs, tab); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /accordion/style.css: -------------------------------------------------------------------------------- 1 | 2 | /* General styles */ 3 | * { 4 | padding: 0; 5 | margin: 0; 6 | } 7 | body { 8 | font-family: 'Roboto', sans-serif; 9 | background: #ffffff; 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | min-height: 100vh; 14 | font-size: 14px; 15 | position: relative; 16 | } 17 | .mb-5 { 18 | margin-bottom: 2rem !important; 19 | } 20 | /* Accordion */ 21 | .accordion { 22 | max-width: 400px; 23 | } 24 | .tab-heading { 25 | background: #092e3d; 26 | padding: 10px; 27 | border-radius: 3px; 28 | font-size: 0.6em; 29 | color: #fff; 30 | cursor: pointer; 31 | } 32 | .tab-heading h2 { 33 | pointer-events: none; 34 | } 35 | .tab-content { 36 | background: #f3f3f3; 37 | overflow-y: hidden; 38 | height: 0; 39 | transition: 0.5s ease; 40 | } 41 | .tab-content p { 42 | margin: 20px; 43 | } 44 | -------------------------------------------------------------------------------- /acsci-to-binary/atob.js: -------------------------------------------------------------------------------- 1 | // ASCII to Binary converter 2 | var asci = 3 | "eJyt0k1ugzAQBeCrIHcbAgTMT3YNKZeoqmpiBrAKDLIdpVGVu5dUXVgyS3vjkRfv0zz5/YfJlh2DeBcwKWheRzYYs+hjFLVgQCi407wXNEVygh7132sodXhBuBrZXceoRf1laAkvim4alY7IDOu1X+aerbGCRlLP3H7NYo9d8E8mPkkxKJrQIV+yQ8mbzFIPPtWJNEjhqlVS8tfKUlOfaicVdvTtsgXP0rfUYjOf7IxGC1g2Sk55UZV2ydyni22PnyP2IO4uHcfn5JxYdO71Iy+owEXrOo4TGy187+uaOa+znFtm6dOUG2LTnKq0sMTKp6ihAyW3un0e9vj4BfcriOY="; 4 | 5 | var toBinaryMethod = atob(asci); 6 | 7 | var toBinary = toBinaryMethod.split("").map((x) => { 8 | return x.charCodeAt(0); 9 | }); 10 | 11 | console.log(toBinary); 12 | 13 | // result 14 | // [ 15 | // 120, 156, 173, 210, 77, 110, 131, 48, 16, 5, 224, 171, 16 | // 32, 119, 27, 2, 4, 204, 79, 118, 13, 41, 151, 168, 17 | // 170, 106, 98, 6, 176, 10, 12, 178, 29, 165, 81, 149, 18 | // 187, 151, 84, 93, 88, 50, 75, 123, 227, 145, 23, 239, 19 | // 211, 60, 249, 253, 135, 201, 150, 29, 131, 120, 23, 48, 20 | // 41, 104, 94, 71, 54, 24, 179, 232, 99, 20, 181, 96, 21 | // 64, 40, 184, 211, 188, 23, 52, 69, 114, 130, 30, 245, 22 | // 223, 107, 40, 117, 120, 65, 184, 26, 217, 93, 199, 168, 23 | // 69, 253, 101, 104, 24 | // ... 157 more items 25 | // ] 26 | -------------------------------------------------------------------------------- /advanced-obj/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * advanced object examples 3 | * @param {string} model 4 | * @param {string} mobile 5 | * @return {object} 6 | * @author Ehsan Ghaffar 7 | */ 8 | 9 | // This keyword 10 | const robot = { 11 | model: "B-4MI", 12 | mobile: true, 13 | greeting() { 14 | console.log(`I'm model ${this.model}, how may I be of service?`); 15 | }, 16 | }; 17 | 18 | // Arrow function DONT return THIS keyword 19 | const massProdRobot = (model, mobile) => { 20 | return { 21 | model, 22 | mobile, 23 | greeting() { 24 | console.log(`I'm model ${this.model}, how may I be of service?`); 25 | }, 26 | }; 27 | }; 28 | 29 | const shinyNewRobot = massProdRobot("TrayHax", true); 30 | 31 | // Private methods 32 | const chargingStation = { 33 | _name: "Electrons-R-Us", 34 | _robotCapacity: 120, 35 | _active: true, 36 | _chargingRooms: ["Low N Slow", "Middle of the Road", "In and Output"], 37 | // setter method 38 | set robotCapacity(newCapacity) { 39 | if (typeof newCapacity === "number") { 40 | this._robotCapacity = newCapacity; 41 | } else { 42 | console.log(`Change ${newCapacity} to a number.`); 43 | } 44 | }, 45 | get robotCapacity() { 46 | return this._robotCapacity; 47 | }, 48 | }; 49 | 50 | /// Another example of setter and getter methods 51 | const robot = { 52 | _model: "1E78V2", 53 | _energyLevel: 100, 54 | _numOfSensors: 15, 55 | get numOfSensors() { 56 | if (typeof this._numOfSensors === "number") { 57 | return this._numOfSensors; 58 | } else { 59 | return "Sensors are currently down."; 60 | } 61 | }, 62 | 63 | set numOfSensors(num) { 64 | if (typeof num === "number" && num >= 0) { 65 | this._numOfSensors = num; 66 | } else { 67 | console.log("Pass in a number that is greater than or equal to 0"); 68 | } 69 | }, 70 | }; 71 | robot.numOfSensors = 100; 72 | console.log(robot.numOfSensors); 73 | 74 | // factory function example 75 | const robotFactory = (model, mobile) => { 76 | return { 77 | model: model, 78 | mobile: mobile, 79 | beep() { 80 | console.log("Beep Boop"); 81 | }, 82 | }; 83 | }; 84 | 85 | const tinCan = robotFactory("P-500", true); 86 | 87 | tinCan.beep(); 88 | 89 | // Destructured Assignment 90 | const robot = { 91 | model: "1E78V2", 92 | energyLevel: 100, 93 | functionality: { 94 | beep() { 95 | console.log("Beep Boop"); 96 | }, 97 | fireLaser() { 98 | console.log("Pew Pew"); 99 | }, 100 | }, 101 | }; 102 | 103 | const { functionality } = robot; // we can access to robot.functionality 104 | 105 | functionality.beep(); 106 | 107 | // Built-in Object Methods 108 | const robot = { 109 | model: "SAL-1000", 110 | mobile: true, 111 | sentient: false, 112 | armor: "Steel-plated", 113 | energyLevel: 75, 114 | }; 115 | 116 | // What is missing in the following method call? 117 | const robotKeys = Object.keys(robot); 118 | 119 | console.log(robotKeys); 120 | 121 | // Declare robotEntries below this line: 122 | const robotEntries = Object.entries(robot); 123 | 124 | console.log(robotEntries); 125 | 126 | // Declare newRobot without change robot 127 | const newRobot = Object.assign( 128 | { laserBlaster: true, voiceRecognition: true }, 129 | robot 130 | ); 131 | console.log(newRobot); 132 | -------------------------------------------------------------------------------- /arrays-methods/array-from.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | Array.from(numbers); 4 | Array.from(numbers, (v) => v * 10); 5 | -------------------------------------------------------------------------------- /arrays-methods/async 2.js: -------------------------------------------------------------------------------- 1 | function getById(id) { 2 | return new Promise((resolve) => { 3 | setTimeout(() => { 4 | console.log(`Got ${id}`); 5 | resolve(id); 6 | }, 1000); 7 | }); 8 | } 9 | 10 | const ids = [10, 20, 30]; 11 | 12 | ids.reduce(async (promise, id) => { 13 | await promise; 14 | return getById(id); 15 | }, Promise.resolve()); 16 | -------------------------------------------------------------------------------- /arrays-methods/async.js: -------------------------------------------------------------------------------- 1 | function getById(id) { 2 | return new Promise((resolve) => { 3 | setTimeout(() => { 4 | console.log(`Got ${id}`); 5 | resolve(id); 6 | }, 1000); 7 | }); 8 | } 9 | 10 | (async function () { 11 | const ids = [10, 20, 30]; 12 | // for (const id of ids) { 13 | // await getById(id); 14 | // } 15 | ids.forEach(async (id) => { 16 | await getById(id); 17 | }); 18 | })(); 19 | -------------------------------------------------------------------------------- /arrays-methods/concat.js: -------------------------------------------------------------------------------- 1 | const first = [10, 20]; 2 | const second = [30, 40, 50]; 3 | 4 | first.concat(second); 5 | 6 | first.concat(second).map((v) => v * 10); 7 | 8 | [...first, ...second].map((v) => v * 10); 9 | -------------------------------------------------------------------------------- /arrays-methods/copies.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | numbers; 3 | const copyOfNumbers = [...numbers]; 4 | copyOfNumbers; 5 | copyOfNumbers[0] = 100; 6 | copyOfNumbers; 7 | numbers; 8 | 9 | const people = [{ name: "John" }, { name: "Jane" }]; 10 | people; 11 | const copyOfPeople = [...people]; 12 | copyOfPeople; 13 | copyOfPeople[0].name = "Jack"; 14 | copyOfPeople; 15 | people; 16 | -------------------------------------------------------------------------------- /arrays-methods/copyWithin.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | 3 | numbers.copyWithin(2, 0); 4 | numbers; 5 | -------------------------------------------------------------------------------- /arrays-methods/destructuring.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | // const first = numbers[0]; 3 | // const second = numbers[1]; 4 | const [first, second, third, ...rest] = numbers; 5 | first; 6 | second; 7 | third; 8 | rest; 9 | -------------------------------------------------------------------------------- /arrays-methods/entries.js: -------------------------------------------------------------------------------- 1 | const values = [10, 20, 30, 40, 50]; 2 | 3 | values.entries(); 4 | for (const value of values.values()) { 5 | console.log(value); 6 | } 7 | 8 | const customers = { 9 | Jack: 12, 10 | Jim: 15, 11 | Sally: 18, 12 | }; 13 | 14 | function sum(objOrArray) { 15 | return Object.values(objOrArray).reduce((sum, value) => sum + value, 0); 16 | } 17 | 18 | sum(values); 19 | sum(customers); 20 | -------------------------------------------------------------------------------- /arrays-methods/filter-hasNext.js: -------------------------------------------------------------------------------- 1 | const numbers = [9, 10, 11, 13, 14, 15]; 2 | 3 | const hasNext = numbers.filter((v, _, a) => a.includes(v + 1)); 4 | hasNext; 5 | -------------------------------------------------------------------------------- /arrays-methods/filter-numbers.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, -20, 30, -40, 50]; 2 | 3 | const allPositive = numbers.filter((v) => v > 0); 4 | allPositive; 5 | const allNegatives = numbers.filter((v) => v < 0); 6 | allNegatives; 7 | 8 | const positiveUnder50 = numbers.filter((v) => v > 0).filter((v) => v < 50); 9 | positiveUnder50; 10 | -------------------------------------------------------------------------------- /arrays-methods/filter-objects.js: -------------------------------------------------------------------------------- 1 | const people = [{ name: "John" }, { name: "Ann" }]; 2 | 3 | const jPeople = people.filter(({ name }) => name.startsWith("J")); 4 | jPeople; 5 | jPeople[0].name = "Jack"; 6 | jPeople; 7 | people; 8 | -------------------------------------------------------------------------------- /arrays-methods/find-indexes.js: -------------------------------------------------------------------------------- 1 | const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"]; 2 | 3 | console.log(names.indexOf("Alice")); 4 | console.log(names.indexOf("Alice", 1)); 5 | console.log(names.indexOf("Sally")); 6 | 7 | console.log(names.lastIndexOf("Alice")); 8 | 9 | console.log(names.findIndex((name) => name === "Bruce")); 10 | -------------------------------------------------------------------------------- /arrays-methods/find.js: -------------------------------------------------------------------------------- 1 | const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"]; 2 | 3 | console.log(names.find((value) => value === "Alice")); 4 | 5 | const people = [{ name: "John" }, { name: "Jane" }]; 6 | const person = people.find((p) => p.name === "Jane"); 7 | person; 8 | person.name = "Sally"; 9 | person; 10 | people; 11 | -------------------------------------------------------------------------------- /arrays-methods/flat.js: -------------------------------------------------------------------------------- 1 | const numbers = [ 2 | [10, 20, 30], 3 | [40, 50, 60], 4 | [70, 80, 90], 5 | ]; 6 | numbers.flat(); 7 | 8 | const deepNumbers = [[[[10, 20, 30]]], [[[40, 50, 60]]], [[[70, 80, 90]]]]; 9 | deepNumbers.flat(); 10 | deepNumbers.flat(2); 11 | deepNumbers.flat(Infinity); 12 | 13 | const values = [10, 20, 30, 40, 50]; 14 | 15 | values.map((v, i) => [v, i]); 16 | values.flatMap((v, i) => [v, i]); 17 | -------------------------------------------------------------------------------- /arrays-methods/for-of-in.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | for (const index in numbers) { 4 | console.log(index); 5 | console.log(numbers[index]); 6 | } 7 | 8 | for (const value of numbers) { 9 | if (value > 20) { 10 | break; 11 | } 12 | console.log(value); 13 | } 14 | -------------------------------------------------------------------------------- /arrays-methods/for.js: -------------------------------------------------------------------------------- 1 | // good 2 | const arrayOfNumbers = []; 3 | for (let value = 10; value <= 50; value += 10) { 4 | arrayOfNumbers.push(value); 5 | } 6 | 7 | // bad 8 | for (let index = 0; index < arrayOfNumbers.length; index++) { 9 | console.log(arrayOfNumbers[index]); 10 | } 11 | -------------------------------------------------------------------------------- /arrays-methods/forEach.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | numbers.forEach((value, index) => { 4 | console.log(value); 5 | console.log(index); 6 | }); 7 | -------------------------------------------------------------------------------- /arrays-methods/map.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | const numbersTimes10 = numbers.map((v) => v * 10); 4 | numbersTimes10; 5 | 6 | const numbersTimes10Obj = numbers.map((v) => ({ value: v * 10 })); 7 | numbersTimes10Obj; 8 | 9 | const numbersWithNegatives = [-10, 20, 30, -40, -50]; 10 | const positveBy10 = numbersWithNegatives 11 | .filter((v) => v > 0) 12 | .map((v) => v * 10); 13 | positveBy10; 14 | 15 | const people = [ 16 | { first: "Jane", last: "Smith", address: { city: "Oakland" } }, 17 | { first: "Sally", last: "Joe", address: { city: "Foster City" } }, 18 | ]; 19 | 20 | const cheapClone = (obj) => JSON.parse(JSON.stringify(obj)); 21 | 22 | const fullNames = people.map((p) => 23 | cheapClone({ 24 | ...p, 25 | fullName: `${p.first} ${p.last}`, 26 | }) 27 | ); 28 | console.log(fullNames); 29 | fullNames[0].first = "Penny"; 30 | fullNames[0].address.city = "San Jose"; 31 | fullNames; 32 | people; 33 | -------------------------------------------------------------------------------- /arrays-methods/mother.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | 3 | // Includes 4 | numbers.reduce((includes, value) => (includes ? includes : value === 3), false); 5 | numbers.reduce( 6 | (includes, value) => (includes ? includes : value === 10), 7 | false 8 | ); 9 | 10 | // Slice 11 | numbers.reduce( 12 | (arr, value, index) => (index > 0 && index < 4 ? [...arr, value] : arr), 13 | [] 14 | ); 15 | 16 | // Map 17 | numbers.reduce((arr, value) => [...arr, value * 100], []); 18 | -------------------------------------------------------------------------------- /arrays-methods/push.js: -------------------------------------------------------------------------------- 1 | const original = [1, 2, 3, 4, 5]; 2 | 3 | const originalRef = original; 4 | originalRef === original; 5 | 6 | original; 7 | original.pop(); 8 | original; 9 | original.push(5); 10 | original; 11 | 12 | originalRef === original; 13 | 14 | let aNumber = 5; 15 | const stateManagerCopy = aNumber; 16 | stateManagerCopy === aNumber; 17 | aNumber = 6; 18 | stateManagerCopy === aNumber; 19 | 20 | const unchanging = [1, 2, 3, 4, 5]; 21 | // pop 22 | const popped = unchanging.slice(-1)[0]; 23 | const rest = unchanging.slice(0, -1); 24 | // push 25 | const aNewArray = [...unchanging, 6]; 26 | -------------------------------------------------------------------------------- /arrays-methods/reduce-to-array.js: -------------------------------------------------------------------------------- 1 | const numbers = [1, 2, 3, 4, 5]; 2 | 3 | let arr = []; 4 | for (const number of numbers) { 5 | arr = [number, ...arr]; 6 | } 7 | arr; 8 | 9 | numbers.reduce((arr, number) => [...arr, number], []); 10 | 11 | numbers.reduceRight((arr, number) => [...arr, number], []); 12 | 13 | const groups = [ 14 | [3, 2], 15 | [2, 5], 16 | [3, 7], 17 | ]; 18 | 19 | // [2,2,2,5,5,7,7,7] 20 | 21 | groups.reduce((arr, [count, value]) => { 22 | for (let index = 0; index < count; index++) { 23 | arr.push(value); 24 | } 25 | return arr; 26 | }, []); 27 | 28 | []; 29 | Array(3); 30 | Array(3).fill(2); 31 | 32 | groups.reduce( 33 | (arr, [count, value]) => [...arr, ...Array(count).fill(value)], 34 | [] 35 | ); 36 | -------------------------------------------------------------------------------- /arrays-methods/reduce-to-object.js: -------------------------------------------------------------------------------- 1 | const numbers = [12, 15, 12, 2, 6, 6, 2, 12]; 2 | 3 | const lookup = {}; 4 | for (const number of numbers) { 5 | lookup[number] = (lookup[number] ?? 0) + 1; 6 | } 7 | lookup; 8 | 9 | numbers.reduce( 10 | (lookup, value) => ({ 11 | ...lookup, 12 | [value]: (lookup[value] ?? 0) + 1, 13 | }), 14 | {} 15 | ); 16 | 17 | numbers.reduce( 18 | ({ min, max }, value) => ({ 19 | min: Math.min(min, value), 20 | max: Math.max(max, value), 21 | }), 22 | { 23 | min: Infinity, 24 | max: -Infinity, 25 | } 26 | ); 27 | -------------------------------------------------------------------------------- /arrays-methods/reduce-to-value.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | let sum = 0; 4 | for (const value of numbers) { 5 | sum += value; 6 | } 7 | sum; 8 | 9 | numbers.reduce((sum, value) => { 10 | sum += value; 11 | return sum; 12 | }, 0); 13 | 14 | numbers.reduce((sum, value) => sum + value, 0); 15 | 16 | numbers.reduce((avg, value, _, arr) => avg + value / arr.length, 0); 17 | 18 | const names = ["LG", "Mimi", "Sadie", "Ripley"]; 19 | 20 | const str = names.reduce( 21 | (str, name, index) => str + (index > 0 ? ", " : "") + name, 22 | "" 23 | ); 24 | str; 25 | 26 | names.join(", "); 27 | -------------------------------------------------------------------------------- /arrays-methods/shift.js: -------------------------------------------------------------------------------- 1 | const original = [1, 2, 3, 4, 5]; 2 | 3 | original; 4 | original.shift(); 5 | original; 6 | original.unshift(1); 7 | original; 8 | 9 | const unchanging = [1, 2, 3, 4, 5]; 10 | // shift 11 | const [value, ...rest] = unchanging; 12 | console.log("value", value, "rest", rest) 13 | value; 14 | rest; 15 | // unshift 16 | const newArray = [0, ...unchanging]; 17 | newArray; 18 | unchanging; 19 | -------------------------------------------------------------------------------- /arrays-methods/slice.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, 20, 30, 40, 50]; 2 | 3 | const middleThree = numbers.filter((_, i) => i > 0 && i < 4); 4 | middleThree; 5 | 6 | const easierMiddleThree = numbers.slice(1, 4); 7 | easierMiddleThree; 8 | 9 | numbers.slice(); 10 | numbers.slice(1); 11 | numbers.slice(-1); 12 | numbers.slice(-2); 13 | -------------------------------------------------------------------------------- /arrays-methods/some-every.js: -------------------------------------------------------------------------------- 1 | const numbers = [10, -20, 30, -40, 50]; 2 | 3 | console.log(numbers.includes(10)); 4 | 5 | console.log(numbers.some((num) => num > 0)); 6 | console.log(numbers.every((num) => num > 0)); 7 | -------------------------------------------------------------------------------- /arrays-methods/sort.js: -------------------------------------------------------------------------------- 1 | const numbers = [2, 6, 3, 4, 1, 5]; 2 | numbers.sort(); 3 | 4 | const names = ["Jack", "Jill", "Jane", "John", "Jim"]; 5 | names.sort(); 6 | 7 | const people = [ 8 | { id: 6, name: "Jack" }, 9 | { id: 1, name: "Sam" }, 10 | { id: 3, name: "Sally" }, 11 | ]; 12 | people.sort((a, b) => a.id - b.id); 13 | people; 14 | 15 | const unchanging = [2, 6, 3, 4, 1, 5]; 16 | const newNumbers = [...unchanging].sort(); 17 | unchanging; 18 | 19 | numbers; 20 | numbers.reverse(); 21 | numbers; 22 | 23 | unchanging; 24 | [...unchanging].sort().reverse(); 25 | unchanging; 26 | -------------------------------------------------------------------------------- /arrays-methods/splice.js: -------------------------------------------------------------------------------- 1 | const values = [1, 2, 4, 5, 6]; 2 | 3 | values; 4 | values.splice(2, 0, 3); 5 | values; 6 | values.splice(2, 1); 7 | values; 8 | 9 | const unchanging = [1, 2, 4, 5, 6]; 10 | const copy = [...unchanging]; 11 | copy.splice(2, 0, 3); 12 | copy; 13 | unchanging; 14 | -------------------------------------------------------------------------------- /async-array-loops/app.js: -------------------------------------------------------------------------------- 1 | const asyncUppercase = (item) => 2 | new Promise((resolve) => 3 | setTimeout( 4 | () => resolve(item.toUpperCase()), 5 | Math.floor(Math.random() * 1000) 6 | ) 7 | ); 8 | 9 | const uppercaseItems = async () => { 10 | const items = ["a", "b", "c"]; 11 | await items.forEach(async (item) => { 12 | const uppercaseItem = await asyncUppercase(item); 13 | console.log(uppercaseItem); 14 | }); 15 | 16 | console.log("Items processed"); 17 | }; 18 | 19 | uppercaseItems(); 20 | // LOGS: ''Items processed', 'B', 'A', 'C' 21 | -------------------------------------------------------------------------------- /binary-search-algorithm/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Binary search assumes the array (or any other data structure) you are searching in is ordered. 3 | * @param {object} list 4 | * @param {string} item 5 | * @returns {number} 6 | * @author: Ehsan Ghaffar 7 | */ 8 | 9 | const binarySearch = (list, item) => { 10 | let low = 0; 11 | let high = list.length - 1; 12 | 13 | while (low <= high) { 14 | const mid = Math.floor((low + high) / 2); 15 | const guess = list[mid]; 16 | 17 | if (guess === item) { 18 | return mid; 19 | } 20 | 21 | if (guess > item) { 22 | high = mid - 1; 23 | } else { 24 | low = mid + 1; 25 | } 26 | } 27 | return null; // if not found 28 | }; 29 | 30 | // test 31 | console.log(binarySearch([1, 2, 3, 4, 5], 5)); 32 | -------------------------------------------------------------------------------- /calculate-mouse-pos/mouse-position.js: -------------------------------------------------------------------------------- 1 | const ele = document.getElementById("mouse-position"); 2 | 3 | ele.addEventListener("mousedown", function (e) { 4 | // Get the target 5 | const target = e.target; 6 | 7 | // Get the bounding rectangle of target 8 | const rect = target.getBoundingClientRect(); 9 | 10 | // Mouse position 11 | const x = e.clientX - rect.left; 12 | const y = e.clientY - rect.top; 13 | }); 14 | -------------------------------------------------------------------------------- /camera-access/camera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | camera demo 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /camera-access/camera.js: -------------------------------------------------------------------------------- 1 | // Grab elements, create settings, etc. 2 | var video = document.getElementById('video'); 3 | 4 | // Get access to the camera! 5 | if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { 6 | // Not adding `{ audio: true }` since we only want video now 7 | navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) { 8 | video.src = window.URL.createObjectURL(stream); 9 | video.srcObject = stream; 10 | video.play(); 11 | }); 12 | } 13 | 14 | // Legacy code below: getUserMedia 15 | else if(navigator.getUserMedia) { // Standard 16 | navigator.getUserMedia({ video: true }, function(stream) { 17 | video.src = stream; 18 | video.play(); 19 | }, errBack); 20 | } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed 21 | navigator.webkitGetUserMedia({ video: true }, function(stream){ 22 | video.src = window.webkitURL.createObjectURL(stream); 23 | video.play(); 24 | }, errBack); 25 | } else if(navigator.mozGetUserMedia) { // Mozilla-prefixed 26 | navigator.mozGetUserMedia({ video: true }, function(stream){ 27 | video.srcObject = stream; 28 | video.play(); 29 | }, errBack); 30 | } 31 | 32 | 33 | // Elements for taking the snapshot 34 | var canvas = document.getElementById('canvas'); 35 | var context = canvas.getContext('2d'); 36 | var video = document.getElementById('video'); 37 | 38 | // Trigger photo take 39 | document.getElementById("snap").addEventListener("click", function() { 40 | context.drawImage(video, 0, 0, 640, 480); 41 | }); -------------------------------------------------------------------------------- /challenges/string-challenges.js: -------------------------------------------------------------------------------- 1 | // The input string containing a series of words 2 | const str = "Whiskey Hotel Four Tango Dash Alpha Romeo Three Dash Yankee Oscar Uniform Dash Sierra One November Kilo India November Golf Dash Four Bravo Zero Uniform Seven"; 3 | 4 | // Split the string into an array of words using a space as the separator 5 | const words = str.split(' '); 6 | 7 | // Define a dictionary (object) for special word replacements 8 | const specials = { 9 | One: 1, 10 | Two: 2, 11 | Three: 3, 12 | Four: 4, 13 | Five: 5, 14 | Six: 6, 15 | Seven: 7, 16 | Eight: 8, 17 | Nine: 9, 18 | Zero: 0, 19 | Dash: '-', 20 | }; 21 | 22 | // Loop through each word in the array 23 | for (const word of words) { 24 | // Check if the word exists in the dictionary, if yes, use its value as replacement 25 | // Otherwise, use the first character of the word as a default replacement 26 | const replacement = specials[word] !== undefined ? specials[word] : word[0]; 27 | 28 | // Print the result to the browser console or developer tools console 29 | console.log(replacement); 30 | } 31 | -------------------------------------------------------------------------------- /change-bg-color/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Change background color 7 | 13 | 14 | 15 |
16 |

Change background color with javascript

17 | 20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /change-bg-color/script.js: -------------------------------------------------------------------------------- 1 | // change background color with js 2 | 3 | const body = document.body; 4 | const btn = document.getElementById('changeBtn'); 5 | 6 | const colors = ['red', 'yellow', 'green', 'blue']; 7 | 8 | body.style.backgroundColor = 'red'; 9 | 10 | const changeBg = () => { 11 | 12 | body.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)] 13 | } 14 | 15 | btn.addEventListener('click', changeBg); -------------------------------------------------------------------------------- /color-methods/eyeDropper.js: -------------------------------------------------------------------------------- 1 | const colorDiv = document.getElementById("color") 2 | const colorCode = document.getElementById("colorCode") 3 | 4 | function eyeDropperHandler() { 5 | const eyeDropper = new EyeDropper(); 6 | eyeDropper.open().then((res) => { 7 | console.log(res) 8 | colorDiv.style.background = res.sRGBHex 9 | colorCode.innerText = res.sRGBHex 10 | }) 11 | } -------------------------------------------------------------------------------- /color-methods/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | رنگ انتخاب شده 11 | 12 |
13 | 14 | -------------------------------------------------------------------------------- /console/log.js: -------------------------------------------------------------------------------- 1 | let foo = 2, 2 | bar = 4, 3 | loggedIn = false; 4 | 5 | console.log({ foo, bar }); 6 | 7 | // condition 8 | // verbose 💩 9 | if (loggedIn) { 10 | console.error("user is logged in assertion failed"); 11 | } 12 | 13 | // much better 😍 14 | console.assert(loggedIn, "user is logged in"); 15 | 16 | // Timer in console 17 | console.time(); 18 | // do stuff 19 | console.timeLog("did stuff"); 20 | // do more stuff 21 | console.timeLog("did more stuff"); 22 | console.timeEnd(); 23 | 24 | // add custom style to console 25 | console.log("%c YOUR_MESSAGE", "YOUR_CSS"); -------------------------------------------------------------------------------- /count-of-lines/count-of-lines.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | function countFileLines(filePath) { 4 | return new Promise((resolve, reject) => { 5 | let lineCount = 0; 6 | // eslint-disable-next-line no-undef 7 | fs.createReadStream(filePath) 8 | .on("data", (buffer) => { 9 | let idx = -1; 10 | lineCount--; // Because the loop will run once for idx=-1 11 | do { 12 | idx = buffer.indexOf(10, idx + 1); 13 | lineCount++; 14 | } while (idx !== -1); 15 | }) 16 | .on("end", () => { 17 | console.log(`${filePath} has ${lineCount} lines`); 18 | resolve(lineCount); 19 | }) 20 | .on("error", reject); 21 | }); 22 | } 23 | 24 | countFileLines("test.js"); 25 | -------------------------------------------------------------------------------- /count-of-lines/test.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const cors = require("cors"); 3 | const http = require("http"); 4 | process.env.DEBUG = "*"; 5 | const app = express(); 6 | const bodyParser = require("body-parser"); 7 | 8 | app.use(bodyParser.urlencoded({ extended: true })); 9 | app.use(cors()); 10 | app.use(bodyParser.json()); 11 | const server = http.createServer(app); 12 | const singleRoutes = require("./routes/single-routes"); 13 | 14 | app.get("/", (req, res) => { 15 | res.send("Hello World!"); 16 | }); 17 | 18 | app.use(singleRoutes); 19 | 20 | server.listen(4000, () => { 21 | console.log("Server running at http://localhost:4000/"); 22 | }); 23 | -------------------------------------------------------------------------------- /create-custom-element/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /create-custom-element/script.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // create DOM custom Element 4 | class CustomEl extends HTMLElement { 5 | connectedCallback() { 6 | this.innerHTML = 'custom element is created' 7 | } 8 | } 9 | customElements.define('custom-el', CustomEl) 10 | 11 | -------------------------------------------------------------------------------- /d3-parliment/d3-parliament-chart.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 | typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {})); 5 | }(this, (function (exports) { 'use strict'; 6 | 7 | /** 8 | * Generate the points and angle for a single section of the parliament 9 | * 10 | * @param seats - number of seats in this section 11 | * @param startRad - start radians of this section 12 | * @param endRad - end radians of this section 13 | * @param seatRadius - radius of the seats 14 | * @param rowHeight - height of the row 15 | * @param graphicHeight - height of the graphic 16 | * @param sectionGap - The gap between sections 17 | * @returns {[]} 18 | */ 19 | const generatePartial = ({ 20 | seats, startRad, endRad, seatRadius, rowHeight, graphicHeight, sectionGap, 21 | }) => { 22 | // Calculate the radius of the graph, because we don't want the poitns to extend 23 | // beyond the width of the graphic 24 | const graphRadius = graphicHeight - seatRadius; 25 | 26 | // Final Array 27 | let points = []; 28 | 29 | // Which row we are currently drawing 30 | let currentRow = 0; 31 | 32 | // Create all the points 33 | while (points.length < seats) { 34 | // The radius of the row we are currently drawing 35 | const currentRowRadius = graphRadius - (rowHeight * currentRow); 36 | 37 | // We need to also justify for the gap of the section, which radians value varies per row 38 | const currentRowGapRad = Math.atan((seatRadius + (sectionGap / 2)) / currentRowRadius); 39 | const currentRowStartRad = startRad + currentRowGapRad; 40 | const currentRowEndRad = endRad - currentRowGapRad; 41 | 42 | // If our data doesn't fit inside the row or the graph, we just stop 43 | if (currentRowEndRad <= currentRowStartRad || currentRowRadius <= 0) break; 44 | 45 | // Find the minimum size step given the radius 46 | const currRadStep = Math.atan((2.5 * (seatRadius)) / currentRowRadius); 47 | 48 | // Find how many seats are in this row 49 | const rowSeats = Math.min( 50 | Math.floor((currentRowEndRad - currentRowStartRad) / currRadStep), 51 | seats - points.length - 1, 52 | ); 53 | 54 | // Get adjusted step size so that things are justified evenly 55 | // edge case if there is only one seat in this row 56 | const roundedRadStep = rowSeats 57 | ? (currentRowEndRad - currentRowStartRad) / rowSeats 58 | : 0; 59 | 60 | // Add all the seats in this row 61 | for (let currSeat = 0; currSeat <= rowSeats; currSeat += 1) { 62 | // Get the current angle of the seat we are drawing 63 | const currentAngle = rowSeats 64 | ? (currSeat * roundedRadStep + currentRowStartRad) 65 | // edge case if there is only one seat in this row, we put it in the middle 66 | : ((currentRowStartRad + currentRowEndRad) / 2); 67 | 68 | // convert the angle to x y coordinates 69 | points = points.concat([{ 70 | x: Math.cos(currentAngle) 71 | * (graphRadius - (rowHeight * currentRow)) 72 | + graphicHeight, 73 | // flip the y coordinates 74 | y: graphicHeight - (Math.sin(currentAngle) 75 | * (graphRadius - (rowHeight * currentRow)) 76 | + seatRadius) 77 | // Add seatRadius and any sectionGap / 4 so that we vertically center 78 | + seatRadius + (sectionGap / 4), 79 | angle: currentAngle, 80 | }]); 81 | } 82 | currentRow += 1; 83 | } 84 | return points; 85 | }; 86 | 87 | /** 88 | * Generates the list of all points and their x and y positions 89 | * 90 | * @param totalPoints - total number of points we want to draw 91 | * @param sections - total number of sections we want to draw 92 | * @param sectionGap - gap between sections 93 | * @param seatRadius - radius of each seat 94 | * @param rowHeight - height of each row 95 | * @param graphicWidth - width of the entire graphic 96 | * @returns {this} 97 | */ 98 | var getParliamentPoints = (totalPoints, { sections, sectionGap, seatRadius, rowHeight }, graphicWidth) => { 99 | // Calculate the graphic height 100 | const graphicHeight = graphicWidth / 2; 101 | 102 | // Get the number of final sections 103 | const finalSections = Math.min(totalPoints, sections); 104 | 105 | // Angle step per section in radians 106 | const radStep = Math.PI / finalSections; 107 | 108 | // Divide the seats evenly among the sections, while also calculating 109 | // the start radians and end radians. 110 | const sectionObjs = Array(finalSections) 111 | // First evenly divide the seats into each section 112 | .fill({ seats: Math.floor(totalPoints / finalSections) }) 113 | // add the start and end radians 114 | .map((a, i) => ({ ...a, startRad: i * radStep, endRad: (i + 1) * radStep })); 115 | 116 | // There are leftover seats that we need to fit into sections 117 | // Calculate how many there are 118 | let leftoverSeats = totalPoints % finalSections; 119 | 120 | // If leftover seats is 0, we can skip this entire section 121 | if (leftoverSeats !== 0) { 122 | // We want to add the leftover seats to the center section first, then move outward 123 | // We do this by separating the sections into two arrays, left and right 124 | const right = Array(finalSections).fill(null).map((c, i) => i); 125 | const left = right.splice(0, Math.floor(finalSections / 2)).reverse(); 126 | 127 | // Add the seats 128 | while (leftoverSeats > 0) { 129 | // Whichever array is longer, we pop from that array and add to that section first 130 | if (left.length >= right.length) sectionObjs[left.shift()].seats += 1; 131 | else sectionObjs[right.shift()].seats += 1; 132 | 133 | // decrement leftoverSeats by one 134 | leftoverSeats -= 1; 135 | } 136 | } 137 | 138 | // Call the section partial generation tool for each section 139 | return sectionObjs.map((s) => generatePartial({ 140 | ...s, seatRadius, rowHeight, graphicHeight, sectionGap, 141 | })) 142 | // flatten the array 143 | .reduce((acc, val) => [...acc, ...val], []) 144 | // sort by angle 145 | .sort((a, b) => b.angle - a.angle) 146 | // remove angle from returned dataset 147 | .map((r) => { 148 | const { angle, ...rest } = r; 149 | return rest; 150 | }); 151 | }; 152 | 153 | const debugColor = '#1abc9c'; 154 | 155 | /** 156 | * Draw Debugging circle and section guides. 157 | */ 158 | var debugGuides = (selection, graphicWidth, options, totalSeats) => { 159 | const sections = Math.min(totalSeats, options.sections); 160 | 161 | // Create a container for our debug lines 162 | const g = selection.append('g') 163 | .attr('class', 'debug') 164 | .attr('transform', `translate(0, ${options.sectionGap / 4})`); 165 | 166 | // The radius of the semicircle 167 | const radius = graphicWidth / 2; 168 | 169 | // Semicircle frame 170 | g.append('path') 171 | .attr('d', `M${graphicWidth},${radius} a1,1 0 0,0 -${graphicWidth},0 m 0 -${options.sectionGap / 2} l ${graphicWidth} 0`) 172 | .attr('stroke', debugColor) 173 | .attr('stroke-width', 2) 174 | .attr('stroke-dasharray', '5 5') 175 | .attr('fill', 'none'); 176 | 177 | // Section borders 178 | const radStep = Math.PI / sections; 179 | for (let i = 1; i < sections; i += 1) { 180 | const radAngle = radStep * i; 181 | 182 | // If the section gap is 0 we only need to draw one line 183 | if (options.sectionGap <= 0) { 184 | g.append('line') 185 | .attr('x1', radius).attr('y1', radius) 186 | .attr('x2', (Math.cos(radAngle) * radius) + radius) 187 | .attr('y2', radius - (Math.sin(radAngle) * radius)) 188 | .attr('stroke', debugColor) 189 | .attr('stroke-width', 2) 190 | .attr('stroke-dasharray', '5 5'); 191 | } else { 192 | // Calculate the offset and draw two lines. 193 | const offsetX = Math.sin(radAngle) * (options.sectionGap / 2); 194 | const offsetY = Math.cos(radAngle) * (options.sectionGap / 2); 195 | 196 | g.append('line') 197 | .attr('x1', radius - offsetX) 198 | .attr('y1', radius - offsetY) 199 | .attr('x2', ((Math.cos(radAngle) * radius) + radius) - offsetX) 200 | .attr('y2', (radius - (Math.sin(radAngle) * radius)) - offsetY) 201 | .attr('stroke', debugColor) 202 | .attr('stroke-width', 2) 203 | .attr('stroke-dasharray', '5 5'); 204 | 205 | g.append('line') 206 | .attr('x1', radius + offsetX) 207 | .attr('y1', radius + offsetY) 208 | .attr('x2', ((Math.cos(radAngle) * radius) + radius) + offsetX) 209 | .attr('y2', (radius - (Math.sin(radAngle) * radius)) + offsetY) 210 | .attr('stroke', debugColor) 211 | .attr('stroke-width', 2) 212 | .attr('stroke-dasharray', '5 5'); 213 | } 214 | } 215 | }; 216 | 217 | /** 218 | * ___ ____ ___ _ _ _ ___ _ _ 219 | * | \__ / | _ \__ _ _ _| (_)__ _ _ __ ___ _ _| |_ / __| |_ __ _ _ _| |_ 220 | * | |) |_ \ | _/ _` | '_| | / _` | ' \/ -_) ' \ _| | (__| ' \/ _` | '_| _| 221 | * |___/___/ |_| \__,_|_| |_|_\__,_|_|_|_\___|_||_\__| \___|_||_\__,_|_| \__| 222 | * 223 | * A d3 plugin for making semi-circle parliament charts. 224 | */ 225 | 226 | var parliamentChart = (data = [], width = 0) => { 227 | // Dimensions of the graphic 228 | let graphicWidth = parseFloat(width); 229 | 230 | // clean out any x and y values provided in data objects. 231 | let rawData = data.map(({ x, y, ...restProps }) => restProps); 232 | 233 | // visual options 234 | const options = { 235 | sections: 4, // Number of sections to divide the half circle into 236 | sectionGap: 60, // The gap of the aisle between sections 237 | seatRadius: 12, // The radius of each seat 238 | rowHeight: 42, // The height of each row 239 | }; 240 | 241 | // Whether we should draw the debug lines or not 242 | let debug = false; 243 | 244 | // ////////////////////////////////////////////////////////////////////////// 245 | // Selection call 246 | // 247 | // This function gets called on instances such as: 248 | // d3.select('g').call(parliamentChart()) 249 | const parliamentChart = (selection) => { 250 | if (graphicWidth === 0) { 251 | // Sets the graphicWidth based on our selected container 252 | graphicWidth = selection.node().getBoundingClientRect().width; 253 | } 254 | 255 | // Get the processed data (filter for entries that have x and y locations) 256 | const processedData = parliamentChart.data().filter((r) => r.x && r.y); 257 | 258 | // Remove existing chart 259 | selection.select('g.parliament-chart').remove(); 260 | 261 | // Add new chart 262 | const innerSelection = selection 263 | .append('g') 264 | .attr('class', 'parliament-chart'); 265 | 266 | // First remove any existing debug lines 267 | innerSelection.select('g.debug').remove(); 268 | 269 | // Append debug lines 270 | if (debug) debugGuides(innerSelection, graphicWidth, options, processedData.length); 271 | 272 | return innerSelection 273 | .selectAll('circle') 274 | .data(processedData) 275 | .enter() 276 | .insert('circle') 277 | .attr('cx', (d) => d.x) 278 | .attr('cy', (d) => d.y) 279 | .attr('r', options.seatRadius) 280 | .attr('fill', (d) => d.color || '#AAA'); 281 | }; 282 | 283 | // ////////////////////////////////////////////////////////////////////////// 284 | // Getters and Setters 285 | 286 | // Sets the width and the height of the graphic 287 | parliamentChart.width = (w) => { 288 | // eslint-disable-next-line no-restricted-globals 289 | if (!isNaN(w)) { 290 | // parse the width 291 | graphicWidth = parseFloat(w); 292 | } 293 | return parliamentChart; 294 | }; 295 | 296 | // Create getters and setters for sections, sectionGap, seatRadius, and rowHeight 297 | Object.keys(options) 298 | .forEach((attr) => { 299 | parliamentChart[attr] = (s) => { 300 | // eslint-disable-next-line no-restricted-globals 301 | if (!isNaN(s)) { 302 | options[attr] = parseInt(s, 10); 303 | return parliamentChart; 304 | } 305 | return options[attr]; 306 | }; 307 | }); 308 | 309 | // enable / disable debug mode 310 | parliamentChart.debug = (b) => { 311 | debug = !!b; 312 | return parliamentChart; 313 | }; 314 | 315 | // ////////////////////////////////////////////////////////////////////////// 316 | // Data Processing 317 | // 318 | // Gets the data processed data with x and y coordinates or sets 319 | // the raw data. 320 | parliamentChart.data = (d) => { 321 | // If an argument with new data is provided 322 | if (d) { 323 | // clean out any x and y values provided in data objects. 324 | rawData = d.map(({ x, y, ...restProps }) => restProps); 325 | return parliamentChart; 326 | } 327 | 328 | // If width is not set, don't calculate this instance 329 | if (graphicWidth <= 0 || rawData.length <= 0) return rawData; 330 | 331 | // Check if we have already run this instance 332 | if (rawData.every((r) => r.x && r.y)) return rawData; 333 | 334 | // The number of points we need to fit 335 | const totalPoints = rawData.length; 336 | 337 | // The locations of all the points 338 | const locations = getParliamentPoints(totalPoints, options, graphicWidth); 339 | 340 | // Add locations to the rawData object 341 | locations.forEach((coords, i) => rawData[i] = ({ ...rawData[i], ...coords })); 342 | 343 | // return the data 344 | return rawData; 345 | }; 346 | 347 | // Instead of passing in an array of every single point, we pass in an array of objects 348 | // that each have a key `seats` that specifies the number of seats. This function can only 349 | // set, not get. 350 | parliamentChart.aggregatedData = (d) => { 351 | rawData = d.reduce((acc, val) => { 352 | const { seats = 0, x, y, ...restProps } = val; 353 | return [...acc, ...Array(seats).fill(restProps)]; 354 | }, []); 355 | 356 | return parliamentChart; 357 | }; 358 | 359 | return parliamentChart; 360 | }; 361 | 362 | exports.parliamentChart = parliamentChart; 363 | 364 | Object.defineProperty(exports, '__esModule', { value: true }); 365 | 366 | }))); 367 | -------------------------------------------------------------------------------- /d3-parliment/d3-parliament-chart.min.js: -------------------------------------------------------------------------------- 1 | !function(t,a){"object"==typeof exports&&"undefined"!=typeof module?a(exports):"function"==typeof define&&define.amd?define(["exports"],a):a((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,function(t){"use strict";const p=({seats:t,startRad:a,endRad:e,seatRadius:r,rowHeight:s,graphicHeight:n,sectionGap:o})=>{var i=n-r;let l=[],c=0;for(;l.length{let f=parseFloat(a),e=t.map(({x:t,y:a,...e})=>e);const g={sections:4,sectionGap:60,seatRadius:12,rowHeight:42};let u=!1;const y=t=>{0===f&&(f=t.node().getBoundingClientRect().width);var a=y.data().filter(t=>t.x&&t.y);t.select("g.parliament-chart").remove();const e=t.append("g").attr("class","parliament-chart");if(e.select("g.debug").remove(),u){var t=e,r=f,s=g,n=a.length,o=Math.min(n,s.sections);const p=t.append("g").attr("class","debug").attr("transform",`translate(0, ${s.sectionGap/4})`);var i=r/2,l=(p.append("path").attr("d",`M${r},${i} a1,1 0 0,0 -${r},0 m 0 -${s.sectionGap/2} l ${r} 0`).attr("stroke",M).attr("stroke-width",2).attr("stroke-dasharray","5 5").attr("fill","none"),Math.PI/o);for(let t=1;tt.x).attr("cy",t=>t.y).attr("r",g.seatRadius).attr("fill",t=>t.color||"#AAA")};return y.width=t=>(isNaN(t)||(f=parseFloat(t)),y),Object.keys(g).forEach(a=>{y[a]=t=>isNaN(t)?g[a]:(g[a]=parseInt(t,10),y)}),y.debug=t=>(u=!!t,y),y.data=t=>{if(t)return e=t.map(({x:t,y:a,...e})=>e),y;if(f<=0||e.length<=0)return e;if(e.every(t=>t.x&&t.y))return e;const a=((t,{sections:a,sectionGap:e,seatRadius:r,rowHeight:s},n)=>{const o=n/2;n=Math.min(t,a);const i=Math.PI/n,l=Array(n).fill({seats:Math.floor(t/n)}).map((t,a)=>({...t,startRad:a*i,endRad:(a+1)*i}));let c=t%n;if(0!==c){const h=Array(n).fill(null).map((t,a)=>a),d=h.splice(0,Math.floor(n/2)).reverse();for(;0=h.length?l[d.shift()].seats+=1:l[h.shift()].seats+=1,--c}return l.map(t=>p({...t,seatRadius:r,rowHeight:s,graphicHeight:o,sectionGap:e})).reduce((t,a)=>[...t,...a],[]).sort((t,a)=>a.angle-t.angle).map(t=>{const{angle:a,...e}=t;return e})})(e.length,g,f);return a.forEach((t,a)=>e[a]={...e[a],...t}),e},y.aggregatedData=t=>(e=t.reduce((t,a)=>{const{seats:e=0,x:r,y:s,...n}=a;return[...t,...Array(e).fill(n)]},[]),y),y},Object.defineProperty(t,"__esModule",{value:!0})}); -------------------------------------------------------------------------------- /date-methods/date.js: -------------------------------------------------------------------------------- 1 | // You can create a date object using the new Date() constructor 2 | const timeNow = new Date(); 3 | console.log(timeNow); // shows current date and time 4 | 5 | 6 | // new Date(milliseconds) creates a new date object by adding the milliseconds to the zero time 7 | const time1 = new Date(0); 8 | 9 | // epoch time 10 | console.log(time1); // Thu Jan 01 1970 05:30:00 11 | 12 | // 100000000000 milliseconds after the epoch time 13 | const time2 = new Date(100000000000) 14 | console.log(time2); // Sat Mar 03 1973 15:16:40 15 | 16 | // You can create a date object by passing ISO date formats. 17 | const date = new Date("2020-07-01"); // ISO Date(International Standard) 18 | 19 | // the result date will be according to UTC 20 | console.log(date); // Wed Jul 01 2020 05:45:00 GMT+0545 21 | 22 | // You can also pass only the year and month or only the year. 23 | const date = new Date("2020-07"); 24 | console.log(date); // Wed Jul 01 2020 05:45:00 GMT+0545 25 | 26 | const date1 = new Date("2020"); 27 | console.log(date1); // Wed Jul 01 2020 05:45:00 GMT+0545 28 | 29 | // You can also pass specific time to ISO dates. 30 | const date = new Date("2020-07-01T12:00:00Z"); 31 | console.log(date); // Wed Jul 01 2020 17:45:00 GMT+0545 32 | 33 | 34 | 35 | 36 | // 37 | new Date().toDateString(); // e.g. "Fri Nov 11 2016" 38 | 39 | new Date().toISOString(); // e.g. "2016-11-21T08:00:00.000Z" 40 | 41 | new Date().toJSON(); // e.g. "2016-11-21T08:00:00.000Z" 42 | 43 | new Date().toLocaleDateString(); // e.g. "21/11/2016" 44 | 45 | new Date().toLocaleString(); // e.g. "21/11/2016, 08:00:00 AM" 46 | 47 | new Date().toLocaleTimeString(); // e.g. "08:00:00 AM" 48 | 49 | new Date().toString(); // e.g. "Fri Nov 21 2016 08:00:00 GMT+0100 (W. Europe Standard Time)" 50 | 51 | new Date().toISOString().slice(0,10); //return YYYY-MM-DD 52 | 53 | // Specifying the locale for standard functions: 54 | 55 | toLocaleDateString([locales[, options]]) 56 | toLocaleTimeString([locales[, options]]) 57 | toLocaleString([locales[, options]]) 58 | //e.g. toLocaleDateString('ko-KR'); 59 | // toLocaleString('en-GB', { month: 'short' }) 60 | // toLocaleString('en-GB', { month: 'long' }) 61 | // toLocaleString('en-GB', { hour12: true })); 62 | -------------------------------------------------------------------------------- /date-methods/format-date.js: -------------------------------------------------------------------------------- 1 | export function formatDate(timeBySeconds: number) { 2 | let time = new Date(timeBySeconds); 3 | return ( 4 | time.getFullYear() + 5 | '-' + 6 | (time.getMonth() + 1) + 7 | '-' + 8 | time.getDate() + 9 | ' ' + 10 | time.getHours() + 11 | ':' + 12 | time.getMinutes() + 13 | ':' + 14 | time.getSeconds() 15 | ); 16 | } 17 | 18 | export function formatDateByString(date: Date, fmt: string) { 19 | let o = { 20 | 'M+': date.getMonth() + 1, //月份 21 | 'd+': date.getDate(), //日 22 | 'h+': date.getHours(), //小时 23 | 'm+': date.getMinutes(), //分 24 | 's+': date.getSeconds(), //秒 25 | 'q+': Math.floor((date.getMonth() + 3) / 3), //季度 26 | 'S': date.getMilliseconds(), //毫秒 27 | }; 28 | if (/(y+)/.test(fmt)) { 29 | fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); 30 | } 31 | for (var k in o) { 32 | if (new RegExp('(' + k + ')').test(fmt)) { 33 | fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)); 34 | } 35 | } 36 | return fmt; 37 | } 38 | -------------------------------------------------------------------------------- /decimal-to-binary/decimal-to-binary.js: -------------------------------------------------------------------------------- 1 | // Example 1 2 | // program to convert decimal to binary 3 | function convertToBinary(x) { 4 | let bin = 0; 5 | let rem, 6 | i = 1, 7 | step = 1; 8 | while (x != 0) { 9 | rem = x % 2; 10 | console.log( 11 | `Step ${step++}: ${x}/2, Remainder = ${rem}, Quotient = ${parseInt( 12 | x / 2 13 | )}` 14 | ); 15 | x = parseInt(x / 2); 16 | bin = bin + rem * i; 17 | i = i * 10; 18 | } 19 | console.log(`Binary: ${bin}`); 20 | } 21 | 22 | // take input 23 | // let number = prompt("Enter a decimal number: "); 24 | // convertToBinary(number); 25 | 26 | // Example 2 27 | // program to convert decimal to binary 28 | 29 | // take input 30 | const number = parseInt(prompt("Enter a decimal number: ")); 31 | 32 | // convert to binary 33 | const result = number.toString(2); 34 | 35 | console.log("Binary:" + " " + result); 36 | // Output 37 | // Enter a decimal number: 9 38 | // Binary: 1001 39 | -------------------------------------------------------------------------------- /email-validation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Form Validation 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
Name
EMail
Zip Code
Country 31 | 37 |
46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /email-validation/script.js: -------------------------------------------------------------------------------- 1 | function validate() 2 | { 3 | 4 | if( document.myForm.Name.value == "" ) 5 | { 6 | alert( "Please provide your name!" ); 7 | document.myForm.Name.focus() ; 8 | return false; 9 | } 10 | 11 | if( document.myForm.EMail.value == "" ) 12 | { 13 | alert( "Please provide your Email!" ); 14 | document.myForm.EMail.focus() ; 15 | return false; 16 | } 17 | 18 | if( document.myForm.Zip.value == "" || 19 | isNaN( document.myForm.Zip.value ) || 20 | document.myForm.Zip.value.length != 5 ) 21 | { 22 | alert( "Please provide a zip in the format #####." ); 23 | document.myForm.Zip.focus() ; 24 | return false; 25 | } 26 | 27 | if( document.myForm.Country.value == "-1" ) 28 | { 29 | alert( "Please provide your country!" ); 30 | return false; 31 | } 32 | return( true ); 33 | } 34 | 35 | // email validation 36 | function validateEmail() 37 | { 38 | var emailID = document.myForm.EMail.value; 39 | atpos = emailID.indexOf("@"); 40 | dotpos = emailID.lastIndexOf("."); 41 | 42 | if (atpos < 1 || ( dotpos - atpos < 2 )) 43 | { 44 | alert("Please enter correct email ID") 45 | document.myForm.EMail.focus() ; 46 | return false; 47 | } 48 | return( true ); 49 | } 50 | -------------------------------------------------------------------------------- /equations/liner-aquation.js: -------------------------------------------------------------------------------- 1 | // quera 44 2 | function linerEquation(a, b) { 3 | let liner = -b / a; 4 | let result; 5 | if (liner > 0) { 6 | result = `unique`; 7 | } else if (liner == -Infinity) { 8 | result = `infinite`; 9 | } else { 10 | result = `invalid`; 11 | } 12 | return result; 13 | } 14 | -------------------------------------------------------------------------------- /fetch-api/chaining-promises.js: -------------------------------------------------------------------------------- 1 | // Define the base URL for GitHub user API requests. 2 | const URL = "https://api.github.com/users/"; 3 | 4 | // Define a function to load JSON data from a given URL. 5 | const loadJson = (url) => { 6 | // Make a fetch request to the given URL. 7 | return fetch(url) 8 | // Wait for the response to be received. 9 | .then(response => response.json()) 10 | }; 11 | 12 | // Define a function to load a GitHub user's data from the API. 13 | const loadGithubUser = (name) => { 14 | // Return the result of loading JSON data from the following URL: 15 | // `https://api.github.com/users/`. 16 | return loadJson(`${URL}${name}`); 17 | }; 18 | 19 | // Define a function to show a GitHub user's avatar image. 20 | const showAvatar = (githubUser) => { 21 | // Return a promise that resolves after 3 seconds. 22 | // The resolved value will be the given GitHub user object. 23 | return new Promise((resolve, reject) => { 24 | setTimeout(() => { 25 | resolve(githubUser); 26 | }, 3000); 27 | }); 28 | }; 29 | 30 | // Load JSON data for the user with the login name `ehsanghaffar`. 31 | loadJson('https://api.github.com/users/ehsanghaffar') 32 | // Wait for the response to be received and parsed. 33 | .then(user => { 34 | // Load JSON data for the user's avatar image. 35 | return loadGithubUser(user.login); 36 | }) 37 | // Wait for the avatar image data to be received and parsed. 38 | .then(data => { 39 | // Show the avatar image. 40 | return showAvatar(data); 41 | }) 42 | // Wait for the avatar image to be shown. 43 | .then(githubUser => { 44 | // Log the user's name. 45 | console.log(githubUser.name); 46 | }); 47 | 48 | 49 | /** 50 | * Better Approach 51 | */ 52 | 53 | // Define an async function to load JSON data from a given URL. 54 | const loadJson = async (url) => { 55 | // Make an async fetch request to the given URL. 56 | const response = await fetch(url); 57 | 58 | // If the response is not successful, throw an error. 59 | if (!response.ok) { 60 | throw new Error(`HTTP error! status: ${response.status}`); 61 | } 62 | 63 | // Return the parsed JSON data. 64 | return response.json(); 65 | }; 66 | 67 | // Define an async function to load a GitHub user's data from the API. 68 | const loadGithubUser = async (name) => { 69 | // Return the result of loading JSON data from the following URL: 70 | // `https://api.github.com/users/`. 71 | const url = `${URL}${name}`; 72 | const userData = await loadJson(url); 73 | return userData; 74 | }; 75 | 76 | // Define a function to show a GitHub user's avatar image. 77 | const showAvatar = (githubUser) => { 78 | // Return a promise that resolves after 3 seconds. 79 | // The resolved value will be the given GitHub user object. 80 | return new Promise((resolve) => { 81 | setTimeout(() => { 82 | resolve(githubUser); 83 | }, 3000); 84 | }); 85 | }; 86 | 87 | // Start an async function to load JSON data for the user with the login name `ehsanghaffar`. 88 | (async () => { 89 | // Try to load the JSON data. 90 | try { 91 | const response = await loadJson("https://api.github.com/users/ehsanghaffar"); 92 | 93 | // Load the user's avatar image data. 94 | const user = await loadGithubUser(response.login); 95 | 96 | // Show the avatar image. 97 | const githubUser = await showAvatar(user); 98 | 99 | // Log the user's name. 100 | console.log(githubUser.name); 101 | } catch (error) { 102 | // Log the error message. 103 | console.error(`Error: ${error.message}`); 104 | } 105 | })(); -------------------------------------------------------------------------------- /flat-flatmap/flat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ES2019 version new methods for Array.prototype.flatMap 3 | * @param {Function} callback 4 | * @param {Object} thisArg 5 | * @returns {Array} 6 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap 7 | * @see https://tc39.es/ecma262/#sec-array.prototype.flatmap 8 | * @description 9 | * This method is like Array.prototype.map except that the callback is invoked with three arguments: 10 | * the value, the index, and the array. 11 | */ 12 | 13 | // Syntax: 14 | // Arrow function 15 | flatMap((currentValue) => { 16 | /* ... */ 17 | }); 18 | flatMap((currentValue, index) => { 19 | /* ... */ 20 | }); 21 | flatMap((currentValue, index, array) => { 22 | /* ... */ 23 | }); 24 | 25 | // Callback function 26 | flatMap(callbackFn); 27 | flatMap(callbackFn, thisArg); 28 | 29 | // Inline callback function 30 | flatMap(function (currentValue) { 31 | /* ... */ 32 | }); 33 | flatMap(function (currentValue, index) { 34 | /* ... */ 35 | }); 36 | flatMap(function (currentValue, index, array) { 37 | /* ... */ 38 | }); 39 | flatMap(function (currentValue, index, array) { 40 | /* ... */ 41 | }, thisArg); 42 | 43 | // Example of map() and flatMap() 44 | let arr1 = [1, 2, 3, 4]; 45 | 46 | arr1.map((x) => [x * 2]); 47 | // [[2], [4], [6], [8]] 48 | 49 | arr1.flatMap((x) => [x * 2]); 50 | // [2, 4, 6, 8] 51 | 52 | // only one level is flattened 53 | arr1.flatMap((x) => [[x * 2]]); 54 | // [[2], [4], [6], [8]] 55 | 56 | 57 | / Let's say we want to remove all the negative numbers 58 | // and split the odd numbers into an even number and a 1 59 | let a = [5, 4, -3, 20, 17, -33, -4, 18] 60 | // |\ \ x | | \ x x | 61 | // [4,1, 4, 20, 16, 1, 18] 62 | 63 | a.flatMap( (n) => 64 | (n < 0) ? [] : 65 | (n % 2 == 0) ? [n] : 66 | [n-1, 1] 67 | ) 68 | 69 | // expected output: [4, 1, 4, 20, 16, 1, 18] -------------------------------------------------------------------------------- /generators/generate-otp/generate-opt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generate OTP 3 | * @generator 4 | * @requires Math.random Math.floor 5 | * @returns {number} OTP 6 | * @example 7 | * generateOTP(); // => "435897" 8 | */ 9 | 10 | const generateOTP = () => { 11 | let otp = ""; 12 | for (let i = 0; i < 6; i++) { 13 | otp += Math.floor(Math.random() * 10); 14 | } 15 | return otp; 16 | }; 17 | 18 | console.log(generateOTP()); 19 | -------------------------------------------------------------------------------- /generators/id-generator.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const randomId = () => { 4 | return Math.round(Math.random() * 36 ** 8).toString(36) 5 | } 6 | 7 | 8 | // Typescript syntax 9 | export const randomId = (): string => { 10 | return Math.round(Math.random() * 36 ** 8).toString(36) 11 | } 12 | -------------------------------------------------------------------------------- /graph-traversal/breadth-first-search.js: -------------------------------------------------------------------------------- 1 | function bfs(start) { 2 | 3 | const visited = new Set(); 4 | 5 | const queue = [start]; 6 | 7 | 8 | while (queue.length > 0) { 9 | 10 | const airport = queue.shift(); // mutates the queue 11 | 12 | const destinations = adjacencyList.get(airport); 13 | 14 | 15 | for (const destination of destinations) { 16 | 17 | if (destination === 'BKK') { 18 | console.log(`BFS found Bangkok!`) 19 | } 20 | 21 | if (!visited.has(destination)) { 22 | visited.add(destination); 23 | queue.push(destination); 24 | } 25 | 26 | } 27 | 28 | } 29 | 30 | } 31 | 32 | bfs('PHX') 33 | -------------------------------------------------------------------------------- /graph-traversal/dfs.js: -------------------------------------------------------------------------------- 1 | function dfs(start, visited = new Set()) { 2 | 3 | console.log(start) 4 | 5 | visited.add(start); 6 | 7 | const destinations = adjacencyList.get(start); 8 | 9 | for (const destination of destinations) { 10 | 11 | if (destination === 'BKK') { 12 | console.log(`DFS found Bangkok`) 13 | return; 14 | } 15 | 16 | if (!visited.has(destination)) { 17 | dfs(destination, visited); 18 | } 19 | 20 | } 21 | 22 | } 23 | 24 | dfs('PHX') -------------------------------------------------------------------------------- /graph-traversal/graph.js: -------------------------------------------------------------------------------- 1 | // DATA 2 | const airports = 'PHX BKK OKC JFK LAX MEX EZE HEL LOS LAP LIM'.split(' '); 3 | 4 | const routes = [ 5 | ['PHX', 'LAX'], 6 | ['PHX', 'JFK'], 7 | ['JFK', 'OKC'], 8 | ['JFK', 'HEL'], 9 | ['JFK', 'LOS'], 10 | ['MEX', 'LAX'], 11 | ['MEX', 'BKK'], 12 | ['MEX', 'LIM'], 13 | ['MEX', 'EZE'], 14 | ['LIM', 'BKK'], 15 | ]; 16 | 17 | 18 | // The graph 19 | const adjacencyList = new Map(); 20 | 21 | // Add node 22 | function addNode(airport) { 23 | adjacencyList.set(airport, []); 24 | } 25 | 26 | // Add edge, undirected 27 | function addEdge(origin, destination) { 28 | adjacencyList.get(origin).push(destination); 29 | adjacencyList.get(destination).push(origin); 30 | } 31 | 32 | // Create the Graph 33 | airports.forEach(addNode); 34 | routes.forEach(route => addEdge(...route)) 35 | -------------------------------------------------------------------------------- /guess-number/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * programm to guess a number 3 | * @method guessNumber() 4 | * @param {number} number - the number to guess 5 | * @param {number} guess - the number to guess 6 | * @return {boolean} true if the number is guessed, false otherwise 7 | * @author: Ehsan Ghaffar 8 | */ 9 | function guessNumber() { 10 | // generate a random number from 1 to 10 11 | const random = Math.floor(Math.random() * 10) + 1; 12 | 13 | // take input from the user 14 | let number = parseInt(prompt("Guess a number from 1 to 10:")); 15 | 16 | // take the input until the guess is correct 17 | while (number !== random) { 18 | number = parseInt(prompt("Guess a number from 1 to 10:")); 19 | } 20 | 21 | // check if the guess is correct 22 | if (number == random) { 23 | console.log("You guessed the correct number."); 24 | } 25 | } 26 | 27 | // Call the function 28 | guessNumber(); 29 | -------------------------------------------------------------------------------- /hash-train/hash.js: -------------------------------------------------------------------------------- 1 | var a = 'ehsan'; 2 | 3 | var chark = a.split(''); 4 | 5 | 6 | const letter = (l) => chark.forEach(c => { 7 | l = c.toUpperCase() 8 | }); 9 | 10 | console.log(letter(l)) 11 | -------------------------------------------------------------------------------- /html-to-text/html-to-text.js: -------------------------------------------------------------------------------- 1 | 2 | const html2text = (html) => { 3 | var tag = document.createElement('div'); 4 | tag.innerHTML = html; 5 | 6 | return tag.innerText; 7 | } 8 | 9 | // Convert Any copied text to plain text in TinyMCE 10 | paste_preprocess: function(plugin, args) { 11 | var tag = document.createElement('div'); 12 | tag.innerHTML = args.content; 13 | args.content = tag.innerText; 14 | } 15 | 16 | // Convert Any copied text to plain text in TinyMCE (Keep

tag only) 17 | paste_preprocess: function(plugin, args) { 18 | var pWithStyle = args.content.replace(/<[^p](?:.|\n)*?>/gm, ''); 19 | args.content = pWithStyle.replace(/\sstyle=\"(.*?)\"/gm, ''); 20 | } -------------------------------------------------------------------------------- /js-algorithms/bubble-sort/bubble-sort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JavaScript implementation of bubble sort algorithm 3 | * @param {Array} arr - array of numbers 4 | * @returns {Array} - sorted array 5 | * @author: Ehsan Ghaffar 6 | */ 7 | const bubbleSort = (originalArray) => { 8 | let swapped = false; 9 | 10 | const a = [...originalArray]; 11 | 12 | for (let i = 1; i < a.length - 1; i++) { 13 | swapped = false; 14 | 15 | for (let j = 0; j < a.length - i; j++) { 16 | if (a[j + 1] < a[j]) { 17 | [a[j], a[j + 1]] = [a[j + 1], a[j]]; 18 | swapped = true; 19 | } 20 | } 21 | 22 | if (!swapped) { 23 | return a; 24 | } 25 | } 26 | 27 | return a; 28 | }; 29 | 30 | console.log(bubbleSort([2, 1, 6])); 31 | -------------------------------------------------------------------------------- /js-algorithms/selection-sort/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JavaScript Algorithms and Data Structures Projects: Selection Sort 3 | * @author Ehsan Ghaffar 4 | */ 5 | 6 | // Sorts an array of numbers, using the selection sort algorithm. 7 | 8 | // Use the spread operator (...) to clone the original array, arr. 9 | // Use a for loop to iterate over elements in the array. 10 | // Use Array.prototype.slice() and Array.prototype.reduce() to find the index of the minimum element in the subarray to the right of the current index. Perform a swap, if necessary. 11 | 12 | const selectionSort = (arr) => { 13 | const a = [...arr]; 14 | for (let i = 0; i < a.length; i++) { 15 | const min = a 16 | .slice(i + 1) 17 | .reduce((acc, val, j) => (val < a[acc] ? j + i + 1 : acc), i); 18 | if (min !== i) [a[i], a[min]] = [a[min], a[i]]; 19 | } 20 | return a; 21 | }; 22 | 23 | selectionSort([5, 1, 4, 2, 3]); // [1, 2, 3, 4, 5] 24 | -------------------------------------------------------------------------------- /js-algorithms/sort/sort.js: -------------------------------------------------------------------------------- 1 | // this is sorting algorithms 2 | -------------------------------------------------------------------------------- /js-clock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Javascript Simple Clock 7 | 12 | 13 | 14 | 15 |

16 |
17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /js-clock/script.js: -------------------------------------------------------------------------------- 1 | 2 | const showClock = () => { 3 | // get dom-element with id 4 | const clock = document.getElementById('clock'); 5 | // use js Date() 6 | let NowDate = new Date(); 7 | 8 | // initial hours & minutes & seconds from date 9 | let h = NowDate.getHours(); 10 | let m = NowDate.getMinutes(); 11 | let s = NowDate.getSeconds(); 12 | 13 | // add rules to clock with if segments 14 | // use short hand if else 15 | m = m < 10 ? `0${m}` : m; 16 | s = s < 10 ? `0${s}` : s; 17 | 18 | // add to clock element 19 | clock.innerText = `${h}:${m}:${s}`; 20 | 21 | setTimeout(showClock, 1000); 22 | } 23 | showClock() -------------------------------------------------------------------------------- /js-tricks/async.js: -------------------------------------------------------------------------------- 1 | function doubleAfter2Seconds(x) { 2 | return new Promise((resolve) => { 3 | console.log(`Execute ${x}`); 4 | setTimeout(() => { 5 | resolve(x * 2); 6 | }, 2000); 7 | }); 8 | } 9 | 10 | async function addAsync(x) { 11 | const a = await doubleAfter2Seconds(10); 12 | const b = await doubleAfter2Seconds(20); 13 | const c = await doubleAfter2Seconds(30); 14 | return x + a + b + c; 15 | } 16 | 17 | addAsync(10).then((sum) => { 18 | console.log(`Finally ${sum}`); 19 | }); 20 | -------------------------------------------------------------------------------- /js-tricks/calculateDaysBetweenDates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {*} firstDate 4 | * @param {*} secondDate 5 | * @returns {number} 6 | */ 7 | const calculateDaysBetweenDates = (firstDate, secondDate) => { 8 | const oneDay = 24 * 60 * 60 * 1000; 9 | const firstDateMs = firstDate.getTime(); 10 | const secondDateMs = secondDate.getTime(); 11 | const differenceMs = Math.abs(firstDateMs - secondDateMs); 12 | return Math.round(differenceMs / oneDay); 13 | }; 14 | -------------------------------------------------------------------------------- /js-tricks/clone-object.js: -------------------------------------------------------------------------------- 1 | /** 2 | * program to clone the object in JS 3 | * @author Ehsan Ghaffar 4 | * @example 1 5 | */ 6 | // declaring object 7 | const person = { 8 | name: "John", 9 | age: 21, 10 | }; 11 | 12 | // cloning the object 13 | const clonePerson = Object.assign({}, person); 14 | 15 | console.log(clonePerson); 16 | 17 | // changing the value of clonePerson 18 | clonePerson.name = "Peter"; 19 | 20 | console.log(clonePerson.name); 21 | console.log(person.name); 22 | 23 | /** 24 | * @example 2 25 | */ 26 | // declaring object 27 | const person = { 28 | name: "John", 29 | age: 21, 30 | }; 31 | 32 | // cloning the object 33 | const clonePerson = { ...person }; 34 | 35 | console.log(clonePerson); 36 | 37 | // changing the value of clonePerson 38 | clonePerson.name = "Peter"; 39 | 40 | console.log(clonePerson.name); 41 | console.log(person.name); 42 | 43 | /** 44 | * @example 3 45 | * @param {object} obj 46 | */ 47 | // declaring object 48 | const person = { 49 | name: "John", 50 | age: 21, 51 | }; 52 | 53 | // cloning the object 54 | const clonePerson = JSON.parse(JSON.stringify(person)); 55 | 56 | console.log(clonePerson); 57 | 58 | // changing the value of clonePerson 59 | clonePerson.name = "Peter"; 60 | 61 | console.log(clonePerson.name); 62 | console.log(person.name); 63 | -------------------------------------------------------------------------------- /js-tricks/download-file.js: -------------------------------------------------------------------------------- 1 | 2 | // Dynamically Creating a Download Link 3 | const download = (data, filename) => { 4 | const data = JSON.stringify(data) 5 | const link = document.createElement('a') 6 | 7 | link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data)) 8 | link.setAttribute('download', filename || 'data.json') 9 | link.style.display = 'none' 10 | 11 | document.body.appendChild(link) 12 | 13 | link.click() 14 | 15 | document.body.removeChild(link) 16 | } 17 | 18 | // Later call it like so: 19 | download({ name: 'John Doe', email: 'john@doe.com', phone: '+1 234 567' }) 20 | 21 | // Calling with a custom file name 22 | download({ name: 'John Doe' }, 'user.json') 23 | 24 | 25 | 26 | // Creating the download functionality for downloading blobs 27 | const download = async (url, filename) => { 28 | const data = await fetch(url) 29 | const blob = await data.blob() 30 | const objectUrl = URL.createObjectURL(blob) 31 | 32 | const link = document.createElement('a') 33 | 34 | link.setAttribute('href', objectUrl) 35 | link.setAttribute('download', filename) 36 | link.style.display = 'none' 37 | 38 | document.body.appendChild(link) 39 | 40 | link.click() 41 | 42 | document.body.removeChild(link) 43 | } 44 | 45 | // Later call it with an URL and filename like so: 46 | download('https://unpkg.com/react@18/umd/react.production.min.js', 'react.js') -------------------------------------------------------------------------------- /js-tricks/functions.js: -------------------------------------------------------------------------------- 1 | 2 | console.log(makeBread(2)) // Call still works here 3 | 4 | // function Declarations 5 | function makeBread(qty) { 6 | return '🍞'.repeat(qty) 7 | } 8 | 9 | 10 | // function expressions 11 | const makeBeer = function (qty) { 12 | return '🍺'.repeat(qty); 13 | } 14 | 15 | const a = makeBeer(2) 16 | console.log(a) 17 | 18 | 19 | // Arrow function 20 | const makeWine = (qty) => '🍷'.repeat(qty); 21 | 22 | /* 23 | * Structure parameters in a function: 24 | * Positional 25 | * Named 26 | * Rest params 27 | */ 28 | 29 | // Positional 30 | function makeBreakfast(main, side, drink) { 31 | console.log(arguments) 32 | return `Breakfast is ${main}, ${side}, and ${drink}.`; 33 | } 34 | 35 | // Named 36 | function makeLunch(opts) { 37 | const { main, side, drink } = opts; 38 | console.log(opts) 39 | return `Lunch is ${main}, ${side}, and ${drink}.`; 40 | } 41 | 42 | // Rest params 43 | function makeDinner(main, ...args) { 44 | console.log(main, args) 45 | return `Dinner includes ${main} and ${args.join('')}.`; 46 | } 47 | 48 | 49 | makeBreakfast('🥞', '🥓', '🥛', '\n'); 50 | 51 | makeLunch({ main: '🥙', side: '🍟', drink: '🥤' }); 52 | 53 | makeDinner('🍜', '🥘', '🍙', '🥠', '🍑'); 54 | 55 | 56 | 57 | // Impure & Pure functions 58 | 59 | // Impure 60 | let global = 0; 61 | const impure = () => { 62 | global++; 63 | return global ** 2; 64 | } 65 | 66 | // Pure 67 | const pure = (x) => x ** 2; 68 | 69 | 70 | /* High Order Function 71 | * A higher order function is created by combining (or composing) multiple 72 | * functions together by passing (1) functions as arguments or (2) returning functions. 73 | * There are many built-in JS functions that use HOF, for example setTimeout and Array.map. 74 | */ 75 | 76 | // Anonymous 77 | setTimeout(() => console.log('hello!'), 2000); 78 | 79 | // Named 80 | const log = () => console.log('hello'); 81 | setTimeout(log, 2000); 82 | 83 | 84 | // Array Map 85 | [1, 2, 3, 4].map(v => v ** 2); 86 | 87 | 88 | // Recursive Function 89 | const fs = require('fs'); 90 | const { join } = require('path'); 91 | 92 | const traverse = (dir) => { 93 | 94 | const subfolders = fs.statSync(dir).isDirectory() 95 | && fs.readdirSync(dir); 96 | 97 | if (subfolders) { 98 | 99 | console.log('👟👟👟 Traversing ', dir); 100 | 101 | subfolders.forEach(path => { 102 | const fullPath = join(dir, path); 103 | 104 | traverse(fullPath); 105 | 106 | 107 | }); 108 | } 109 | 110 | } 111 | 112 | traverse(process.cwd()); -------------------------------------------------------------------------------- /js-tricks/get-ip.js: -------------------------------------------------------------------------------- 1 | const fetch = (...args) => 2 | import("node-fetch").then(({ default: fetch }) => fetch(...args)); 3 | 4 | let baseUrl = "https://geolocation-db.com/"; 5 | 6 | // get my ip address and information 7 | async function getIp(address) { 8 | let response = await fetch(baseUrl + address); 9 | const data = await response.json(); 10 | console.log(data); 11 | } 12 | getIp("json"); 13 | 14 | // get ip address information 15 | const getIpInfo = async (ip) => { 16 | const prefix = "jsonp/"; 17 | const url = `${baseUrl}${prefix}${ip}`; 18 | const res = await fetch(url) 19 | .then((data) => console.log("simplest possible fetch", data)) 20 | .catch((err) => console.log(err)); 21 | }; 22 | 23 | testIp = "82.196.6.158"; 24 | getIpInfo(testIp); 25 | -------------------------------------------------------------------------------- /js-tricks/promis.js: -------------------------------------------------------------------------------- 1 | var a = 1; 2 | var one = 1; 3 | 4 | var promise = new Promise((resolve, reject) => { 5 | if (a === one) { 6 | resolve(); 7 | } else { 8 | reject(); 9 | } 10 | }) 11 | .then(() => { 12 | console.log("Thats right"); 13 | }) 14 | .catch((err) => { 15 | console.log(err + "Not right"); 16 | }); 17 | -------------------------------------------------------------------------------- /js-tricks/string-search.js: -------------------------------------------------------------------------------- 1 | // JS string search 2 | const simple = "My id is @ehsanghaffar" 3 | 4 | const index = simple.search("@ehsanghaffar") 5 | 6 | console.log(index) // 9 7 | 8 | const secondIndex = simple.search("Developer") 9 | 10 | console.log(secondIndex) // -1 -------------------------------------------------------------------------------- /js-tricks/uid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * create uid without any packahge or library in JavaScript 3 | * @returns {number} - unique id 4 | * @author: Ehsan Ghaffar 5 | */ 6 | const uid = () => { 7 | const firstSection = Date.now().toString(36); 8 | const secondSection = Math.random().toString(36).substring(2); 9 | return firstSection.concat(secondSection); 10 | }; 11 | 12 | console.log(uid()); 13 | -------------------------------------------------------------------------------- /js-tricks/using-switch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * using switch statements in JavaScript is a good way to avoid repetition 3 | * @author: Ehsan Ghaffar 4 | */ 5 | 6 | /** 7 | * example of using if statements in JavaScript 8 | */ 9 | 10 | if (animal.toLowerCase() === "cat") { 11 | return "Kitten"; 12 | } else if (animal.toLowerCase() == "cattle") { 13 | return "Calf"; 14 | } else if (animal.toLowerCase() === "cheetah") { 15 | return "Cub"; 16 | } else if (animal.toLowerCase() === "dog") { 17 | return "Pup"; 18 | } else { 19 | return "I don't know that"; 20 | } 21 | 22 | /** 23 | * example of using switch statements in JavaScript 24 | * @param {string} animal - animal name 25 | * @returns {string} - animal name 26 | */ 27 | switch (animal.toLowerCase()) { 28 | case "cat": 29 | return "Kitten"; 30 | case "cattle": 31 | return "Calf"; 32 | case "cheetah": 33 | return "Cub"; 34 | case "dog": 35 | return "Pup"; 36 | default: 37 | return "I don't know that"; 38 | } 39 | Th; 40 | -------------------------------------------------------------------------------- /letter-to-UpperCase/main.js: -------------------------------------------------------------------------------- 1 | // program to convert first letter of a string to uppercase 2 | 3 | function capitalizeFirstletter(str) { 4 | 5 | // converting first letter to uppercase 6 | const capitalized = str.charAt(0).toUpperCase() + str.slice(1); 7 | 8 | return capitalized; 9 | 10 | } 11 | 12 | // take input letter from user 13 | const string = prompt('Enter a String:'); // Enter a string: javaScript 14 | 15 | const result = capitalizeFirstletter(string); 16 | 17 | console.log(result) // JavaScript -------------------------------------------------------------------------------- /local-storage/save-localStorage-to-file.js: -------------------------------------------------------------------------------- 1 | // How to save local storage data to a file. 2 | 3 | function saveLocalstorageToFile(fileName) { 4 | 5 | // dump local storage to string 6 | var a = {}; 7 | for (var i = 0; i < localStorage.length; i++) { 8 | var k = localStorage.key(i); 9 | var v = localStorage.getItem(k); 10 | a[k] = v; 11 | } 12 | 13 | // save it as blog. 14 | var textToSave = JSON.stringify(a) 15 | var textToSaveAsBlob = new Blob([textToSave], { 16 | type: "text/plain" 17 | }); 18 | var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob); 19 | 20 | // auto download 21 | var downloadLink = document.createElement("a"); 22 | downloadLink.download = fileName; 23 | downloadLink.innerHTML = "Download File"; 24 | downloadLink.href = textToSaveAsURL; 25 | downloadLink.onclick = function () { 26 | document.body.removeChild(event.target); 27 | }; 28 | downloadLink.style.display = "none"; 29 | document.body.appendChild(downloadLink); 30 | downloadLink.click(); 31 | 32 | } -------------------------------------------------------------------------------- /matrix-bg/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | i'm alive 6 | 7 | 8 | 20 | 26 | 27 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /matrix-bg/scripts.js: -------------------------------------------------------------------------------- 1 | 2 | const canvas = document.getElementById("canvas"); 3 | const c = canvas.getContext("2d"); 4 | 5 | const fontHeight = 14; 6 | const fontFamily = "Meiryo, monospace"; 7 | 8 | const numbers = "0123456789"; 9 | const operators = "#+-\\/|="; 10 | const katakana = 11 | "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲ"; 12 | const hiragana = 13 | "あいうえおかきくけこがぎぐげごさしすせそざじずぜぞtたちつてとだぢづでどなにぬねのはひふへほばびぶべぼぱぴぷぺぽまみむめもやゆよらりるれろわゐゑをんㅬㅭㆊㆆㆅㆃㅧㅬㅄㅃㄱ"; 14 | const persian = "ضشظصسطثیزقبرفلذغادعتئهنخمحگچپو"; 15 | const alphabet = numbers + operators + katakana + hiragana + persian; 16 | 17 | const spawnInterval = 500; 18 | const density = 0.7; 19 | 20 | const glitchInterval = 500; 21 | const glitchAmount = 0.01; 22 | 23 | const moveScale = 0.012; 24 | 25 | const speedBase = 1.0; 26 | const speedDeviation = 0.4; 27 | const streaks = 1.9; 28 | 29 | const brightRatio = 0.1; 30 | 31 | const randomGlyph = () => { 32 | return { 33 | glyph: alphabet[Math.floor(Math.random() * alphabet.length)], 34 | flipped: Math.random() < 0.5, 35 | bright: Math.random() < brightRatio, 36 | }; 37 | }; 38 | 39 | const makeUniverse = (size) => { 40 | out = []; 41 | for (let i = 0; i < size; i++) { 42 | out.push(randomGlyph()); 43 | } 44 | return out; 45 | }; 46 | const universe = makeUniverse(1000); 47 | 48 | let w; 49 | let h; 50 | 51 | let charHeight; 52 | let colWidth; 53 | let colsPerLine; 54 | let charsOnCol; 55 | 56 | const setCanvasExtents = () => { 57 | w = document.body.clientWidth; 58 | h = document.body.clientHeight; 59 | canvas.width = w; 60 | canvas.height = h; 61 | 62 | // need to recalculate font properties when canvas is resized 63 | c.font = fontHeight + "px " + fontFamily; 64 | c.textBaseline = "top"; 65 | const charSize = c.measureText("ネ"); 66 | 67 | colWidth = charSize.width * 1.15; 68 | charHeight = fontHeight * 1.15; 69 | 70 | charsOnCol = Math.ceil(h / charHeight); 71 | if (charsOnCol <= 0) { 72 | charsOnCol = 1; 73 | } 74 | colsPerLine = Math.ceil(w / colWidth); 75 | if (colsPerLine <= 0) { 76 | colsPerLine = 1; 77 | } 78 | }; 79 | 80 | setCanvasExtents(); 81 | 82 | window.onresize = () => { 83 | setCanvasExtents(); 84 | }; 85 | 86 | const makeTrail = (col, maxSpeed = null, headAt = null) => { 87 | let speed = 88 | speedBase + (Math.random() * speedDeviation * 2 - speedDeviation); 89 | 90 | if (maxSpeed > 0 && speed > maxSpeed) { 91 | speed = maxSpeed; 92 | } 93 | 94 | if (headAt == null) { 95 | headAt = -Math.floor(Math.random() * 2 * charsOnCol); 96 | } 97 | 98 | return { 99 | col: col, 100 | universeAt: Math.floor(Math.random() * universe.length), 101 | headAt: headAt, 102 | speed: speed, 103 | length: Math.floor(Math.random() * streaks * charsOnCol) + 8, 104 | }; 105 | }; 106 | 107 | const trails = []; 108 | 109 | const clear = () => { 110 | c.fillStyle = "black"; 111 | c.fillRect(0, 0, canvas.width, canvas.height); 112 | }; 113 | 114 | const rgb = "#008000"; 115 | const rgbBright = "#20E020"; 116 | const rgbHead = ["#F0FFF0", "#D0F0D0", "#80C080", "#40B040"]; 117 | const rgbTail = ["#000500", "#003000", "#005000", "#007000"]; 118 | 119 | const drawTrail = (trail) => { 120 | const head = Math.round(trail.headAt); 121 | 122 | // trail has yet to enter screen from above 123 | if (head < 0) return; 124 | 125 | const x = trail.col * colWidth; 126 | let y = head * charHeight + charHeight * 0.35; 127 | 128 | for (let i = 0; i < trail.length; i++, y -= charHeight) { 129 | // went up beyond top screen edge? 130 | if (y < 0) break; 131 | // went down beyond bottom screen edge? 132 | if (y > h) continue; 133 | 134 | const idx = (trail.universeAt + head - i) % universe.length; 135 | const item = universe[idx]; 136 | 137 | if (i < rgbHead.length) { 138 | c.fillStyle = rgbHead[i]; 139 | } else if (trail.length - i - 1 < rgbTail.length) { 140 | c.fillStyle = rgbTail[trail.length - i - 1]; 141 | } else { 142 | if (item.bright) { 143 | c.fillStyle = rgbBright; 144 | } else { 145 | c.fillStyle = rgb; 146 | } 147 | } 148 | 149 | if (item.flipped) { 150 | c.setTransform(-1, 0, 0, 1, 0, 0); 151 | c.fillText(item.glyph, -x - colWidth, y); 152 | c.setTransform(1, 0, 0, 1, 0, 0); 153 | } else { 154 | c.fillText(item.glyph, x, y); 155 | } 156 | } 157 | }; 158 | 159 | const moveTrails = (distance) => { 160 | const trailsToRemove = []; 161 | 162 | const count = trails.length; 163 | for (let i = 0; i < count; i++) { 164 | const trail = trails[i]; 165 | trail.headAt += trail.speed * distance; 166 | 167 | const tip = trail.headAt - trail.length; 168 | // if the trail went far enough down to be invisible, mark it for removal 169 | if (tip * charHeight > h) { 170 | trailsToRemove.push(i); 171 | } 172 | } 173 | 174 | // remove trails that went entirely beyond screen bottom edge 175 | while (trailsToRemove.length > 0) { 176 | trails.splice(trailsToRemove.pop(), 1); 177 | } 178 | }; 179 | 180 | const spawnTrails = () => { 181 | // find topmost trail on each column 182 | const topTrailPerCol = []; 183 | for (let i = 0; i < trails.length; i++) { 184 | const trail = trails[i]; 185 | const trailTop = trail.headAt - trail.length; 186 | const top = topTrailPerCol[trail.col]; 187 | if (!top || top.headAt - top.length > trailTop) { 188 | topTrailPerCol[trail.col] = trail; 189 | } 190 | } 191 | 192 | // spawn new trails 193 | for (let i = 0; i < colsPerLine; i++) { 194 | let spawnProbability = 0.0; 195 | let maxSpeed = null; 196 | let headAt = null; 197 | 198 | if (!topTrailPerCol[i]) { 199 | // column has no trail at all 200 | // we'll try and add one 201 | // this most commonly happens at the beginning of the animation 202 | // when few trails have spawned yet 203 | spawnProbability = 1.0; 204 | } else { 205 | // column has a trail 206 | const topTrail = topTrailPerCol[i]; 207 | const tip = Math.round(topTrail.headAt) - topTrail.length; 208 | if (tip > 0) { 209 | // if trail's top tip is on screen 210 | // we might spawn another one 211 | // probability rises the further down the tip is 212 | const emptySpaceRatio = tip / charsOnCol; 213 | spawnProbability = emptySpaceRatio; 214 | // heuristic limiting speed of new trail chasint the existing one 215 | // we don't want the chasing trail to catch up 216 | maxSpeed = topTrail.speed * (1 + emptySpaceRatio); 217 | // we'll spawn the follow up at the top of the screen 218 | headAt = 0; 219 | } 220 | } 221 | 222 | // scale the probabilities by density 223 | const effectiveP = spawnProbability * density; 224 | 225 | // spawn? 226 | const p = Math.random(); 227 | 228 | if (p < effectiveP) { 229 | trails.push(makeTrail(i, maxSpeed, headAt)); 230 | } 231 | } 232 | }; 233 | 234 | const glitchUniverse = (count) => { 235 | for (let i = 0; i < count; i++) { 236 | const idx = Math.floor(Math.random() * universe.length); 237 | universe[idx] = randomGlyph(); 238 | } 239 | }; 240 | 241 | let prevTime; 242 | let glitchCollect = 0; 243 | let spawnCollect = 0; 244 | 245 | const init = (time) => { 246 | prevTime = time; 247 | requestAnimationFrame(tick); 248 | }; 249 | 250 | const tick = (time) => { 251 | let elapsed = time - prevTime; 252 | prevTime = time; 253 | 254 | moveTrails(elapsed * moveScale); 255 | 256 | spawnCollect += elapsed; 257 | while (spawnCollect > spawnInterval) { 258 | spawnCollect -= spawnInterval; 259 | spawnTrails(); 260 | } 261 | 262 | glitchCollect += elapsed; 263 | while (glitchCollect > glitchInterval) { 264 | glitchCollect -= glitchInterval; 265 | glitchUniverse(Math.floor(universe.length * glitchAmount)); 266 | } 267 | 268 | clear(); 269 | 270 | const count = trails.length; 271 | for (var i = 0; i < count; i++) { 272 | const trail = trails[i]; 273 | drawTrail(trail); 274 | } 275 | 276 | requestAnimationFrame(tick); 277 | }; 278 | 279 | requestAnimationFrame(init); -------------------------------------------------------------------------------- /mobile-phone-methods/orientation.js: -------------------------------------------------------------------------------- 1 | // get orientation of device 2 | 3 | function getOrientationDevice() { 4 | const isPortrait = screen.orientation.type.startsWith('portrait') 5 | return isPortrait ? 'portrait' : 'landscape' 6 | } -------------------------------------------------------------------------------- /mobile-phone-methods/phone-vibration.js: -------------------------------------------------------------------------------- 1 | const vibratePhone = () => { 2 | if (navigator.vibrate) { 3 | navigator.vibrate(1000) 4 | } else { 5 | console.log("Vibration not supported") 6 | } 7 | } -------------------------------------------------------------------------------- /mobile-phone-methods/screen-wake.js: -------------------------------------------------------------------------------- 1 | // Stop screen lock 2 | 3 | let wakeLock = null 4 | 5 | async function play() { 6 | // -- 7 | wakeLock = await navigator.wakeLock.request('screen') 8 | } 9 | 10 | async function pause() { 11 | await wakeLock.release() 12 | } -------------------------------------------------------------------------------- /mouse-methods/onOutsideClick.js: -------------------------------------------------------------------------------- 1 | // Import the necessary libraries 2 | import { useRef } from 'react'; 3 | import { isEqual } from 'lodash'; 4 | import { useEffect, useRef } from 'react'; 5 | 6 | // Define a custom hook, useDeepCompareMemoize, that takes a value as an argument 7 | // and returns a memoized version of the value that only updates if the new 8 | // value is not equal to the existing one. 9 | const useDeepCompareMemoize = value => { 10 | // Initialize a reference to the value using useRef. 11 | const valueRef = useRef(); 12 | 13 | // If the new value is not equal to the current one, update the reference with the new value. 14 | if (!isEqual(value, valueRef.current)) { 15 | valueRef.current = value; 16 | } 17 | 18 | // Return the memoized value. 19 | return valueRef.current; 20 | }; 21 | 22 | // Define another custom hook, useOnOutsideClick, that listens for mouse clicks outside 23 | // of a given element and calls a callback function when a click occurs outside of it. 24 | // The hook takes in multiple arguments including the elements to be ignored during the 25 | // check, whether or not the listener is currently active, the callback function to call 26 | // on outside clicks, and the element that the listener should be attached to. 27 | const useOnOutsideClick = ( 28 | $ignoredElementRefs, 29 | isListening, 30 | onOutsideClick, 31 | $listeningElementRef, 32 | ) => { 33 | // Initialize a reference to the mouse-down target using useRef. 34 | const $mouseDownTargetRef = useRef(); 35 | 36 | // Memoize the list of ignored element references using the useDeepCompareMemoize hook. 37 | const $ignoredElementRefsMemoized = useDeepCompareMemoize([$ignoredElementRefs].flat()); 38 | 39 | // Use the useEffect hook to add event listeners for mouse down and up events. 40 | // This hook also handles removing these listeners when the component unmounts. 41 | useEffect(() => { 42 | // Define a function that sets the mouse-down target reference to the current event target. 43 | const handleMouseDown = event => { 44 | $mouseDownTargetRef.current = event.target; 45 | }; 46 | 47 | // Define a function that checks if the mouse up event occurred outside of the listening element 48 | // and all ignored elements, and calls the onOutsideClick callback if it did. 49 | const handleMouseUp = event => { 50 | const isAnyIgnoredElementAncestorOfTarget = $ignoredElementRefsMemoized.some( 51 | $elementRef => 52 | $elementRef.current.contains($mouseDownTargetRef.current) || 53 | $elementRef.current.contains(event.target), 54 | ); 55 | if (event.button === 0 && !isAnyIgnoredElementAncestorOfTarget) { 56 | onOutsideClick(); 57 | } 58 | }; 59 | 60 | // Get the element to attach the listener to by either using the provided ref or defaulting to document. 61 | const $listeningElement = ($listeningElementRef || {}).current || document; 62 | 63 | // If the listener is currently active, add listeners for mouse down and up events. 64 | if (isListening) { 65 | $listeningElement.addEventListener('mousedown', handleMouseDown); 66 | $listeningElement.addEventListener('mouseup', handleMouseUp); 67 | } 68 | 69 | // Return a cleanup function that removes the listeners when the component unmounts. 70 | return () => { 71 | $listeningElement.removeEventListener('mousedown', handleMouseDown); 72 | $listeningElement.removeEventListener('mouseup', handleMouseUp); 73 | }; 74 | }, [$ignoredElementRefsMemoized, $listeningElementRef, isListening, onOutsideClick]); 75 | }; 76 | 77 | // Export the useOnOutsideClick hook as the default export. 78 | export default useOnOutsideClick; -------------------------------------------------------------------------------- /onclick/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 |
13 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /oneLineCodes/20OneLinesPro.js: -------------------------------------------------------------------------------- 1 | /* Get a random boolean */ 2 | const getRandomNumber = () => Math.random() >= 0.5 3 | console.log(getRandomNumber()) 4 | 5 | 6 | /* Check if the date is Weekend */ 7 | const isWeekend = (date) => [0, 6].indexOf(date.getDay()) !== -1; 8 | 9 | console.log(isWeekend(new Date(2021, 4, 14))); 10 | // false (Friday) 11 | console.log(isWeekend(new Date(2021, 4, 15))); 12 | // true (Saturday) 13 | 14 | 15 | /* Check if a number is even or odd */ 16 | const isEven = (num) => num % 2 === 0; 17 | 18 | console.log(isEven(5)); 19 | // false 20 | console.log(isEven(4)); 21 | // true 22 | 23 | 24 | /* Get the unique values in an array */ 25 | const uniqueArr = (arr) => [...new Set(arr)]; 26 | 27 | console.log(uniqueArr([1, 2, 3, 1, 2, 3, 4, 5])); 28 | // [1, 2, 3, 4, 5] 29 | 30 | 31 | /* Check if a variable is an array */ 32 | const isArray = (arr) => Array.isArray(arr); 33 | 34 | console.log(isArray([1, 2, 3])); 35 | // true 36 | console.log(isArray({ name: 'Ovi' })); 37 | // false 38 | console.log(isArray('Hello World')); 39 | // false 40 | 41 | 42 | /* Generate a random number between two numbers */ 43 | const randomBetweenTwoNumber = (min, max) => Math.floor(Math.random() * (max - min + 1) + min); 44 | 45 | console.log(randomBetweenTwoNumber(1, 50)); 46 | 47 | 48 | /* Generate a random string (unique id?) */ 49 | const randomString = () => Math.random().toString(36).slice(2); 50 | 51 | console.log(randomString()); 52 | 53 | 54 | /* Scroll to the top of the page */ 55 | const scrollToTop = () => window.scrollTo(0, 0); 56 | 57 | scrollToTop(); 58 | 59 | 60 | /* Calculate number of days between two dates */ 61 | const daysDiff = (date, date2) => Math.ceil(Math.abs(date - date2) / 86400000); 62 | 63 | console.log(daysDiff(new Date('2021-05-10'), new Date('2021-11-25'))); 64 | 65 | 66 | /* Copy text to clipboard */ 67 | const copyTextToClipboard = async (text) => { 68 | await navigator.clipboard.writeText(text); 69 | }; 70 | 71 | 72 | /* Different ways of merging multiple arrays */ 73 | // Merge without remove the duplications 74 | const merge = (a, b) => a.concat(b); 75 | // Or 76 | const merge = (a, b) => [...a, ...b]; 77 | 78 | // Merge with remove the duplications 79 | const merge = [...new Set(a.concat(b))]; 80 | // Or 81 | const merge = [...new Set([...a, ...b])]; 82 | 83 | 84 | /* Truncate string at the end */ 85 | const truncateString = (string, length) => { 86 | return string.length < length ? string : `${string.slice(0, length - 3)}...`; 87 | }; 88 | 89 | console.log( 90 | truncateString('Hi, I should be truncated because I am too loooong!', 36), 91 | ); 92 | // Hi, I should be truncated because... 93 | 94 | 95 | /* Truncate string from the middle */ 96 | const truncateStringMiddle = (string, length, start, end) => { 97 | return `${string.slice(0, start)}...${string.slice(string.length - end)}`; 98 | }; 99 | 100 | console.log( 101 | truncateStringMiddle( 102 | 'A long story goes here but then eventually ends!', // string 103 | 25, // total size needed 104 | 13, // chars to keep from start 105 | 17, // chars to keep from end 106 | ), 107 | ); 108 | // A long story ... eventually ends! 109 | 110 | 111 | /* Capitalizing a string */ 112 | const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1); 113 | 114 | console.log(capitalize('hello world')); 115 | // Hello world 116 | 117 | 118 | /* Check if the user is on an Apple device */ 119 | const isAppleDevice = () => /Mac|iPod|iPhone|iPad/.test(navigator.platform); 120 | 121 | console.log(isAppleDevice); 122 | // true/false 123 | -------------------------------------------------------------------------------- /oneLineCodes/script.js: -------------------------------------------------------------------------------- 1 | 2 | // 1 - Check if an array is empty // 3 | // arr is an array 4 | const isEmpty = arr => !Array.isArray(arr) || arr.length === 0; 5 | // uses example 6 | isEmpty([]) // true 7 | isEmpty([1, 2, 3]) // false 8 | 9 | // 2 - Convert an array of string to number // 10 | const toNumber = arr => arr.map(Number); 11 | // example 12 | console.log(toNumber(['1', '2', '3'])); 13 | 14 | // 3 - Create an empty function 15 | const noop = () => {}; 16 | 17 | // 4 - Check if the code is running in node js 18 | const isNode = typeof process !== 'undefined' && process.versions !== null && process.versions.node !== null; 19 | 20 | // 5 - Check if the code is running in the browser 21 | const isBrowser = typeof window === 'object' && typeof document === 'object'; 22 | 23 | // 6 - Redirect the page to https if it is in http 24 | const redirectHttps = () => (location.protocol === 'https') ? {} : location.replace(`https://${location.split('//')[1]}`); 25 | 26 | // 7 - Convert a string to url slug 27 | const slugify = string => string.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]+/g, ''); 28 | 29 | // Example 30 | slugify('Chapter One: Once upon a time...'); // 'chapter-one-once-upon-a-time' 31 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-beginner-pr", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "js-beginner-pr", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "node-fetch": "^2.6.7" 13 | } 14 | }, 15 | "node_modules/node-fetch": { 16 | "version": "2.6.7", 17 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", 18 | "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", 19 | "dependencies": { 20 | "whatwg-url": "^5.0.0" 21 | }, 22 | "engines": { 23 | "node": "4.x || >=6.0.0" 24 | }, 25 | "peerDependencies": { 26 | "encoding": "^0.1.0" 27 | }, 28 | "peerDependenciesMeta": { 29 | "encoding": { 30 | "optional": true 31 | } 32 | } 33 | }, 34 | "node_modules/tr46": { 35 | "version": "0.0.3", 36 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 37 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" 38 | }, 39 | "node_modules/webidl-conversions": { 40 | "version": "3.0.1", 41 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 42 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" 43 | }, 44 | "node_modules/whatwg-url": { 45 | "version": "5.0.0", 46 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 47 | "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", 48 | "dependencies": { 49 | "tr46": "~0.0.3", 50 | "webidl-conversions": "^3.0.0" 51 | } 52 | } 53 | }, 54 | "dependencies": { 55 | "node-fetch": { 56 | "version": "2.6.7", 57 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", 58 | "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", 59 | "requires": { 60 | "whatwg-url": "^5.0.0" 61 | } 62 | }, 63 | "tr46": { 64 | "version": "0.0.3", 65 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 66 | "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" 67 | }, 68 | "webidl-conversions": { 69 | "version": "3.0.1", 70 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 71 | "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" 72 | }, 73 | "whatwg-url": { 74 | "version": "5.0.0", 75 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 76 | "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", 77 | "requires": { 78 | "tr46": "~0.0.3", 79 | "webidl-conversions": "^3.0.0" 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /palindrome/checkPalindrome.js: -------------------------------------------------------------------------------- 1 | // program to check if the string is palindrome or not 2 | 3 | function checkPalindrome(str) { 4 | 5 | // convert string to an array 6 | const arrayValues = string.split(''); 7 | 8 | // reverse the array values 9 | const reverseArrayValues = arrayValues.reverse(); 10 | 11 | // convert array to string 12 | const reverseString = reverseArrayValues.join(''); 13 | 14 | if(string == reverseString) { 15 | console.log('It is a palindrome'); 16 | } 17 | else { 18 | console.log('It is not a palindrome'); 19 | } 20 | } 21 | 22 | //take input 23 | const string = prompt('Enter a string: '); 24 | 25 | checkPalindrome(string); 26 | -------------------------------------------------------------------------------- /password-validator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Password validation 7 | 8 | 9 | 10 |
11 | 12 |

13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /password-validator/script.js: -------------------------------------------------------------------------------- 1 | const input = document.querySelector('.password-input'); 2 | const error = document.querySelector('.error-message'); 3 | const timeout = null; 4 | 5 | const showError = message => { 6 | error.style.color = '#C91E1E'; 7 | error.style.display = 'block'; 8 | error.innerHTML = message; 9 | }; 10 | 11 | const showPass = message => { 12 | error.style.color = '#119822'; 13 | error.innerHTML = message; 14 | }; 15 | 16 | const validatePassword = password => { 17 | const lowerCaseRegex = new RegExp('^(?=.*[a-z])'); 18 | const upperCaseRegex = new RegExp('^(?=.*[A-Z])'); 19 | const specialCharacterRegex = new RegExp('^(?=.*[!@#$%^&*])'); 20 | const numericRegex = new RegExp('^(?=.*[0-9])'); 21 | 22 | if (password.length < 6) { 23 | showError('Your password must be least 6 characters long.'); 24 | } else if (!lowerCaseRegex.test(password)) { 25 | showError('Your password must include at least one lowercase character.'); 26 | } else if (!upperCaseRegex.test(password)) { 27 | showError('Your password must include at least one uppercase character.'); 28 | } else if (!specialCharacterRegex.test(password)) { 29 | showError('Your password must include at least one special character.'); 30 | } else if (!numericRegex.test(password)) { 31 | showError('Your password must include at least one number.'); 32 | } else { 33 | showPass('Strong password!'); 34 | } 35 | }; 36 | 37 | input.addEventListener('keyup', e => { 38 | const password = e.target.value; 39 | // Wait until typing stopped and then validate the password 40 | clearTimeout(timeout); 41 | timeout = setTimeout(() => validatePassword(password), 400); 42 | }); 43 | -------------------------------------------------------------------------------- /password-validator/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | body { 6 | background: #ffffff; 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | min-height: 100vh; 11 | font-family: "Roboto", sans-serif; 12 | font-size: 14px; 13 | } 14 | .form { 15 | position: relative; 16 | width: 250px; 17 | overflow: hidden; 18 | z-index: 10; 19 | } 20 | .password-input { 21 | width: 100%; 22 | border: 0; 23 | border-radius: 3px; 24 | font-size: 1.2em; 25 | background: #2d2a3d; 26 | outline: 0; 27 | box-sizing: border-box; 28 | padding: 10px 40px 10px 10px; 29 | color: #fff; 30 | } 31 | .password-input::placeholder { 32 | color: #b3b3b3; 33 | font-weight: 300; 34 | } 35 | .error-message { 36 | font-size: 1em; 37 | display: none; 38 | color: red; 39 | padding-left: 2px; 40 | animation: 0.2s ease-in-out fadeIn forwards; 41 | } 42 | @keyframes fadeIn { 43 | from { 44 | margin-top: 16px; 45 | opacity: 0; 46 | } 47 | to { 48 | margin-top: 8px; 49 | opacity: 1; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /photo-uploader/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Image uploader 9 | 10 | 11 |
12 | 13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /photo-uploader/scripts.js: -------------------------------------------------------------------------------- 1 | // Get the form element 2 | var form = document.getElementById("upload-form"); 3 | 4 | // Handle form submission 5 | form.addEventListener("submit", function (event) { 6 | event.preventDefault(); 7 | 8 | // Get the selected file 9 | var file = document.getElementById("image-file").files[0]; 10 | 11 | // Create a new FormData object 12 | var formData = new FormData(); 13 | 14 | // Add the file to the FormData object 15 | formData.append("image", file); 16 | 17 | // Add any additional data to the FormData object 18 | formData.append("user", "John Doe"); 19 | 20 | // Send the request 21 | var xhr = new XMLHttpRequest(); 22 | xhr.open("POST", "/api/upload"); 23 | xhr.send(formData); 24 | 25 | // Handle the response 26 | xhr.onload = function () { 27 | if (xhr.status === 200) { 28 | alert("Image uploaded successfully"); 29 | } else { 30 | alert("An error occurred"); 31 | } 32 | }; 33 | }); 34 | 35 | function showPreview(event) { 36 | if (event.target.files.length > 0) { 37 | var src = URL.createObjectURL(event.target.files[0]); 38 | var preview = document.getElementById("file-ip-1-preview"); 39 | preview.src = src; 40 | preview.style.display = "block"; 41 | } 42 | } -------------------------------------------------------------------------------- /pwd-generator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /pwd-generator/script.js: -------------------------------------------------------------------------------- 1 | 2 | // get element from dom 3 | const pwd = document.getElementById('pwd'); 4 | 5 | // create function for generate password 6 | 7 | const pwdGen = () => { 8 | // use created varible from dom element 9 | pwd.innerText = 10 | // use Math.random() method to generate random password string 11 | Math.random().toString(36).slice(2) + // use toString() method 12 | Math.random().toString(36) 13 | .toUpperCase().slice(2) 14 | } 15 | -------------------------------------------------------------------------------- /quiz/quizq.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Quiz Question Javascript Part 1 3 | */ 4 | 5 | var a = (1, 5 - 1) * 2; // returns 8 6 | 7 | var b = (1, 2, 3); // returns 3 8 | // explanation: 9 | // comma operator (,) evaluates the each of the operands from left to right and returns the last one. 10 | -------------------------------------------------------------------------------- /react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # JavaScript Code Collection 2 | 3 | A comprehensive collection of JavaScript code snippets, algorithms, and mini-projects for learning and reference purposes. 4 | 5 | ## 🚀 Overview 6 | 7 | This repository serves as a learning resource and reference guide for JavaScript developers, containing various implementations of: 8 | 9 | - Data Structures & Algorithms 10 | - JavaScript Methods & Features 11 | - UI Components & Interactions 12 | - Utility Functions 13 | - Web APIs & Browser Features 14 | - Programming Challenges 15 | 16 | ## 📂 Project Structure 17 | 18 | The repository is organized into multiple directories, each focusing on specific concepts or features: 19 | 20 | ### Algorithms & Data Structures 21 | 22 | - `js-algorithms/` - Common algorithmic implementations 23 | - `binary-search-algorithm/` - Binary search implementation 24 | - `graph-traversal/` - Graph traversal algorithms 25 | - `recursive-factorial/` - Factorial calculation using recursion 26 | 27 | ### JavaScript Features & Methods 28 | 29 | - `arrays-methods/` - Array manipulation examples 30 | - `string-methods/` - String manipulation utilities 31 | - `date-methods/` - Date handling examples 32 | - `reduce-method/` - Examples of Array.reduce() 33 | - `generators/` - JavaScript Generator functions 34 | - `flat-flatmap/` - Array flattening methods 35 | 36 | ### Browser APIs & Web Features 37 | 38 | - `web-worker/` - Web Workers implementation 39 | - `fetch-api/` - Fetch API examples 40 | - `local-storage/` - Local Storage usage 41 | - `camera-access/` - Browser camera API 42 | - `touch-events/` - Touch interaction handling 43 | - `mouse-methods/` - Mouse event handling 44 | 45 | ### UI Components & Projects 46 | 47 | - `snake-game/` - Classic Snake game implementation 48 | - `quiz/` - Interactive quiz application 49 | - `accordion/` - Accordion component 50 | - `matrix-bg/` - Matrix-style background effect 51 | - `speed-typing/` - Typing speed test game 52 | - `pwd-generator/` - Password generator tool 53 | 54 | ### Utility Functions 55 | 56 | - `RGB-to-hex/` - Color format conversion 57 | - `decimal-to-binary/` - Number system conversion 58 | - `email-validation/` - Email validation utilities 59 | - `password-validator/` - Password validation 60 | - `text-to-img-server/` - Text to image conversion 61 | 62 | ### React & Modern Web 63 | 64 | - `react/` - React.js examples 65 | - `vanilla-web-components/` - Web Components 66 | - `rxjs/` - RxJS examples 67 | - `d3-parliment/` - D3.js visualization 68 | 69 | ## 🛠️ Getting Started 70 | 71 | 1. Clone the repository: 72 | 73 | ```bash 74 | git clone https://github.com/[username]/js-beginner-pr.git 75 | ``` 76 | 77 | 2. Navigate to any project directory: 78 | 79 | ```bash 80 | cd [project-directory] 81 | ``` 82 | 83 | 3. Most projects can be run directly in the browser by opening the HTML file, while some may require a local server or additional setup (check individual project directories for specific instructions). 84 | 85 | ## 📚 Learning Resources 86 | 87 | Each directory contains specific examples and implementations that can be used as: 88 | 89 | - Reference for implementing common JavaScript patterns 90 | - Learning material for JavaScript concepts 91 | - Code snippets for common programming challenges 92 | - Examples of browser API usage 93 | 94 | ## 🤝 Contributing 95 | 96 | Contributions are welcome! Feel free to: 97 | 98 | - Add new examples 99 | - Improve existing implementations 100 | - Fix bugs 101 | - Add documentation 102 | - Suggest new features 103 | 104 | ## 📄 License 105 | 106 | This project is licensed under the terms of the LICENSE file included in the repository. 107 | 108 | ## 🔗 Additional Resources 109 | 110 | - Check individual project directories for specific documentation 111 | - Explore the `challenges/` directory for programming exercises 112 | - Visit `useful-Snippets/` for commonly used code snippets 113 | -------------------------------------------------------------------------------- /recaptcha/recaptcha.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Google reCAPTCHA client side API. 3 | * @param {string} siteKey Site key. 4 | * @author: Ehsan Ghaffarii 5 | */ 6 | 7 | const apiKey = ""; 8 | 9 | function checkRecaptcha() { 10 | var response = grecaptcha.getResponse(); 11 | if (response.length == 0) { 12 | //reCaptcha not verified 13 | alert("no pass"); 14 | } else { 15 | //reCaptch verified 16 | alert("pass"); 17 | } 18 | } 19 | 20 | // implement on the backend 21 | function backend_API_challenge() { 22 | var response = grecaptcha.getResponse(); 23 | $.ajax({ 24 | type: "POST", 25 | url: "https://www.google.com/recaptcha/api/siteverify", 26 | data: { 27 | secret: apiKey, 28 | response: response, 29 | remoteip: "localhost", 30 | }, 31 | contentType: "application/x-www-form-urlencoded", 32 | success: function (data) { 33 | console.log(data); 34 | }, 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /recursive-factorial/rf.js: -------------------------------------------------------------------------------- 1 | // program to find the factorial of a number 2 | function factorial(x) { 3 | // if number is 0 4 | if (x == 0) { 5 | return 1; 6 | } 7 | 8 | // if number is positive 9 | else { 10 | return x * factorial(x - 1); 11 | } 12 | } 13 | 14 | // take input from the user 15 | const num = prompt("Enter a positive number: "); 16 | 17 | // calling factorial() if num is positive 18 | if (num >= 0) { 19 | const result = factorial(num); 20 | console.log(`The factorial of ${num} is ${result}`); 21 | } else { 22 | console.log("Enter a positive number."); 23 | } 24 | -------------------------------------------------------------------------------- /reduce-method/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Examples of using reduce method 3 | * @param {Array} arr 4 | * @author @ehsanghaffarii 5 | * @since 2022-04-20 6 | * @prototype arr.reduce(callback, initialValue) 7 | * @callback function (accumulator, currentValue, index, array) {} 8 | */ 9 | 10 | /** 11 | * reduce method has two arguments 12 | * 1.callback function 13 | * 2.initial value 14 | */ 15 | 16 | /** 17 | * reduce method used for summing all the elements of an array 18 | * @param {Array} arr - array of number - [1, 2, 3, 4, 5]; 19 | * @returns {Number} // 15 20 | * @since 2022-04-20 21 | */ 22 | const sum = (arr) => { 23 | const result = arr.reduce((acc, curr) => { 24 | return acc + curr; 25 | }, 0); 26 | return result; 27 | }; 28 | 29 | /** 30 | * reduce method used for multiplying all the elements of an array 31 | * @param {Array} arr - array of number - [1, 2, 3, 4, 5]; 32 | * @returns {Number} // 120 33 | * @since 2022-04-20 34 | */ 35 | const multiply = (arr) => { 36 | const result = arr.reduce((acc, curr) => { 37 | return acc * curr; 38 | }, 1); 39 | return result; 40 | }; 41 | 42 | /** 43 | * reduce method used for finding the longest string in an array 44 | * @param {Array} arr - array of string - ["Ali", "Hassan", "Ehsan", "Hafiz", "Mohammad"]; 45 | * @returns {String} - "Mohammad" 46 | * @since 2022-04-20 47 | */ 48 | const longestString = (arr) => { 49 | const result = arr.reduce((acc, curr) => { 50 | if (acc.length > curr.length) { 51 | return acc; 52 | } 53 | return curr; 54 | }, ""); 55 | return result; 56 | }; 57 | 58 | /** 59 | * reduce method used for flattening an array 60 | * @param {Array} arr - array of array - [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; 61 | * @returns {Array} - [1, 2, 3, 4, 5, 6, 7, 8, 9] 62 | * @since 2022-04-20 63 | */ 64 | const flatten = (arr) => { 65 | const result = arr.reduce((acc, curr) => { 66 | return acc.concat(curr); 67 | }, []); 68 | return result; 69 | }; 70 | 71 | /** 72 | * reduce method used for calculate the array length 73 | * @param {Array} arr - [1, 2, 3, 4, 5] || ["Ali", "Hassan", "Ehsan", "Hafiz", "Mohammad"] || ... 74 | * @returns {Any} - 75 | * @since 2022-04-20 76 | */ 77 | var len = arr.reduce((total, curr) => { 78 | return total + curr.length; 79 | }, 0); 80 | 81 | 82 | /** 83 | * reduce method used for finding how meny times a word is repeated in a string 84 | * @param {String} str - "Ali Hassan Ehsan Hafiz Mohammad" 85 | * @returns {Object} - {Ali: 1, Hassan: 1, Ehsan: 1, Hafiz: 1, Mohammad: 1} 86 | * @since 2022-04-20 87 | */ 88 | var repeat = char.reduce((total, curr) => { 89 | if (!item in total) { 90 | total[item] = 1; 91 | } 92 | total[item]++; 93 | 94 | return total; 95 | } 96 | 97 | /** 98 | * reduce method used for duble the elements of an array 99 | * @param {Array} arr - [1, 2, 3, 4, 5] 100 | * @returns {Array} - [2, 4, 6, 8, 10] 101 | * @since 2022-04-20 102 | * NOTE: for duble the elements of an array, we can use map method 103 | */ 104 | var doubled = arr.reduce((output, item, index) => { 105 | output[index] = item * 2; 106 | return output; 107 | },[]) 108 | 109 | -------------------------------------------------------------------------------- /regex-pattern/validate-email.js: -------------------------------------------------------------------------------- 1 | function validateEmail(email) { 2 | if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) { 3 | return true; 4 | } 5 | return false; 6 | } 7 | 8 | console.log(validateEmail("eghg.com")) -------------------------------------------------------------------------------- /regex-pattern/validate-phone-number.js: -------------------------------------------------------------------------------- 1 | 2 | // program to validate the phone number with regex pattern 3 | 4 | function validatePhone(num) { 5 | // regex pattern for phone number 6 | const re = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/g; 7 | // check if the phone number is valid 8 | let result = num.match(re); 9 | if (result) { 10 | console.log(`The number is valid: ${num}`); 11 | } 12 | else { 13 | let num = prompt('Enter number in XXX-XXX-XXXX format:'); 14 | validatePhone(num); 15 | } 16 | } 17 | 18 | // take input 19 | let number = prompt('Enter a number XXX-XXX-XXXX'); 20 | 21 | validatePhone(number); -------------------------------------------------------------------------------- /rxjs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | RxJS 8 | 20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /rxjs/index.js: -------------------------------------------------------------------------------- 1 | // import { fromEvent, interval } from "rxjs"; 2 | // import { map, take } from "rxjs/operators"; 3 | 4 | let fromEvent = rxjs.fromEvent; 5 | 6 | fromEvent(document, "click") 7 | .pipe( 8 | rxjs.operators.map((e) => e.clientX), 9 | rxjs.operators.filter((x) => x > 200) 10 | ) 11 | .subscribe(() => { 12 | let x = Math.random() * window.innerWidth; 13 | let y = Math.random() * window.innerHeight; 14 | let r = Math.random() * 100; 15 | let color = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${ 16 | Math.random() * 255 17 | })`; 18 | let circle = document.createElement("div"); 19 | circle.style.width = circle.style.height = `${r}px`; 20 | circle.style.backgroundColor = color; 21 | circle.style.position = "absolute"; 22 | circle.style.left = `${x}px`; 23 | circle.style.top = `${y}px`; 24 | document.body.appendChild(circle); 25 | }); 26 | -------------------------------------------------------------------------------- /search/search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Search for an item in an array of objects 3 | * @param {array} ItemsList - array of objects 4 | * @param {string} search - search term 5 | * @returns {array} - array of objects 6 | * @example 7 | * findItem([{name: 'toy', price: '$10'}, {name: 'toy', price: '$10'}], 'toy'); 8 | * // [{name: 'toy', price: '$10'}, {name: 'toy', price: '$10'}] 9 | * @author Ehsan Ghaffar 10 | * @since 2022-02-26 11 | */ 12 | 13 | const items = [ 14 | { id: "1", title: "planes", tags: ["Airbus", "Bouing", "F15"] }, 15 | { id: "2", title: "cars", tags: ["Toyota", "Ford", "Nissan"] }, 16 | ]; 17 | 18 | const findItem = (ItemsList = [], search = "") => { 19 | let list = []; 20 | function createList() { 21 | items.forEach(function (word) { 22 | let i; 23 | list[word] = i; 24 | }); 25 | } 26 | function searchWord(term) { 27 | if (term in list) { 28 | console.log(term + " is found at " + list[term]); 29 | } 30 | } 31 | createList(); 32 | searchWord("toy"); 33 | }; 34 | 35 | findItem(items, "Toyota"); 36 | console.log(items); 37 | -------------------------------------------------------------------------------- /short-code-snippets/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * here some examples of short code 3 | * for more programming examples check out the github: https://github.com/ehsanghaffarii 4 | */ 5 | 6 | // for loop regular example 7 | array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 8 | 9 | for (var i = 0; i < array.length; i++) { 10 | console.log(i); 11 | } 12 | // now with short code ⬇️ 13 | for (let value of array) { 14 | console.log(value); 15 | } 16 | 17 | // return example in regular way 18 | dummyMultiply = (value) => { 19 | w; 20 | return value * value; 21 | }; 22 | // now with short code ⬇️ 23 | dummyMultiply = (value) => value * value; 24 | // or 25 | dummyMultiply = (value) => { 26 | value * value; 27 | }; 28 | 29 | // example of default parameters 30 | function volume(length, width, height = 1) { 31 | if (height === undefined) { 32 | height = 1; 33 | } 34 | if (width === undefined) { 35 | width = 1; 36 | } 37 | return length * width * height; 38 | } 39 | // now with short code ⬇️ 40 | volume = (length, width, height = 1) => length * width * height; 41 | 42 | // example of use destructuring 43 | const name = employee.name; 44 | const age = employee.age; 45 | 46 | // now with short code ⬇️ 47 | const { name, age } = employee; 48 | 49 | // example of regular function 50 | function setFullName(firstName, lastName) { 51 | return function () { 52 | return "Hello I'm" + firstName + " " + lastName; 53 | }; 54 | } 55 | // now with short code with arrow function & template literal ⬇️ 56 | const setFullName = (firstName, lastName) => { 57 | () => `Hello I'm ${firstName} ${lastName}`; 58 | }; 59 | -------------------------------------------------------------------------------- /snake-game/draw.js: -------------------------------------------------------------------------------- 1 | const canvas = document.querySelector(".canvas"); 2 | const ctx = canvas.getContext("2d"); 3 | const scale = 10; 4 | const rows = canvas.height / scale; 5 | const columns = canvas.width / scale; 6 | var snake; 7 | 8 | (function setup() { 9 | snake = new Snake(); 10 | fruit = new Fruit(); 11 | fruit.pickLocation(); 12 | 13 | window.setInterval(() => { 14 | ctx.clearRect(0, 0, canvas.width, canvas.height); 15 | fruit.draw(); 16 | snake.update(); 17 | snake.draw(); 18 | 19 | if (snake.eat(fruit)) { 20 | fruit.pickLocation(); 21 | } 22 | 23 | snake.checkCollision(); 24 | document.querySelector(".score").innerText = snake.total; 25 | }, 250); 26 | })(); 27 | 28 | window.addEventListener("keydown", (evt) => { 29 | const direction = evt.key.replace("Arrow", ""); 30 | snake.changeDirection(direction); 31 | }); 32 | -------------------------------------------------------------------------------- /snake-game/fruit.js: -------------------------------------------------------------------------------- 1 | function Fruit() { 2 | this.x; 3 | this.y; 4 | 5 | this.pickLocation = function () { 6 | this.x = (Math.floor(Math.random() * columns - 1) + 1) * scale; 7 | this.y = (Math.floor(Math.random() * rows - 1) + 1) * scale; 8 | }; 9 | 10 | this.draw = function () { 11 | ctx.fillStyle = "#4cafab"; 12 | ctx.fillRect(this.x, this.y, scale, scale); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /snake-game/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Snake Game Vanilla Javascript 5 | 11 | 12 | 13 | 19 | 20 |

21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /snake-game/snake.js: -------------------------------------------------------------------------------- 1 | function Snake() { 2 | this.x = 0; 3 | this.y = 0; 4 | this.xSpeed = scale * 1; 5 | this.ySpeed = 0; 6 | this.total = 0; 7 | this.tail = []; 8 | 9 | this.draw = function () { 10 | ctx.fillStyle = "#FFFFFF"; 11 | for (let i = 0; i < this.tail.length; i++) { 12 | ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale); 13 | } 14 | 15 | ctx.fillRect(this.x, this.y, scale, scale); 16 | }; 17 | 18 | this.update = function () { 19 | for (let i = 0; i < this.tail.length - 1; i++) { 20 | this.tail[i] = this.tail[i + 1]; 21 | } 22 | 23 | this.tail[this.total - 1] = { x: this.x, y: this.y }; 24 | 25 | this.x += this.xSpeed; 26 | this.y += this.ySpeed; 27 | 28 | if (this.x > canvas.width) { 29 | this.x = 0; 30 | } 31 | 32 | if (this.y > canvas.height) { 33 | this.y = 0; 34 | } 35 | 36 | if (this.x < 0) { 37 | this.x = canvas.width; 38 | } 39 | 40 | if (this.y < 0) { 41 | this.y = canvas.height; 42 | } 43 | }; 44 | 45 | this.changeDirection = function (direction) { 46 | switch (direction) { 47 | case "Up": 48 | this.xSpeed = 0; 49 | this.ySpeed = -scale * 1; 50 | break; 51 | case "Down": 52 | this.xSpeed = 0; 53 | this.ySpeed = scale * 1; 54 | break; 55 | case "Left": 56 | this.xSpeed = -scale * 1; 57 | this.ySpeed = 0; 58 | break; 59 | case "Right": 60 | this.xSpeed = scale * 1; 61 | this.ySpeed = 0; 62 | break; 63 | } 64 | }; 65 | 66 | this.eat = function (fruit) { 67 | if (this.x === fruit.x && this.y === fruit.y) { 68 | this.total++; 69 | return true; 70 | } 71 | 72 | return false; 73 | }; 74 | 75 | this.checkCollision = function () { 76 | for (var i = 0; i < this.tail.length; i++) { 77 | if (this.x === this.tail[i].x && this.y === this.tail[i].y) { 78 | this.total = 0; 79 | this.tail = []; 80 | } 81 | } 82 | }; 83 | } 84 | -------------------------------------------------------------------------------- /sololearn/js-course/currency-convertor.js: -------------------------------------------------------------------------------- 1 | // You are making a currency converter app. 2 | // Create a function called convert, which takes two parameters: the amount to convert, and the rate, and returns the resulting amount. 3 | // The code to take the parameters as input and call the function is already present in the Playground. 4 | // Create the function to make the code work. 5 | 6 | // function main() { 7 | // var amount = 100; 8 | // var rate = 1.1; 9 | 10 | // function convert(am, ra) { 11 | // let result = am * ra; 12 | // return parseInt(result); 13 | // } 14 | 15 | // console.log(convert(amount, rate)); 16 | // } 17 | 18 | // main(); 19 | 20 | function contact(name, number) { 21 | this.name = name; 22 | this.number = number; 23 | 24 | this.print = function () { 25 | console.log(`${this.name} ${this.number}`); 26 | }; 27 | } 28 | 29 | var a = new contact("David", 12345); 30 | var b = new contact("Amy", 987654321); 31 | // a.print(); 32 | // b.print(); 33 | 34 | function main() { 35 | var increase = 9; 36 | var prices = [98.99, 15.2, 20, 1026]; 37 | //your code goes here 38 | let res = []; 39 | prices.forEach((i) => { 40 | i = i + increase; 41 | res.push(i); 42 | }); 43 | 44 | console.log(res); 45 | } 46 | 47 | // main(); 48 | 49 | class Add { 50 | constructor(...words) { 51 | this.words = words; 52 | } 53 | //your code goes here 54 | print() { 55 | let res = ""; 56 | this.words.forEach((i) => { 57 | res += "$" + i; 58 | }); 59 | console.log(res + "$"); 60 | } 61 | } 62 | 63 | var x = new Add("hehe", "hoho", "haha", "hihi", "huhu"); 64 | var y = new Add("this", "is", "awesome"); 65 | var z = new Add( 66 | "lorem", 67 | "ipsum", 68 | "dolor", 69 | "sit", 70 | "amet", 71 | "consectetur", 72 | "adipiscing", 73 | "elit" 74 | ); 75 | x.print(); 76 | y.print(); 77 | z.print(); 78 | -------------------------------------------------------------------------------- /sololearn/js-course/snail.js: -------------------------------------------------------------------------------- 1 | // The snail in the wall 2 | // 3 | // The snail climbs up 7 feet each day and slips back 2 feet each night. 4 | // How many days will it take the snail to get out of a well with the given depth? 5 | 6 | // Sample Input: 7 | // 31 8 | 9 | // Sample Output: 10 | // 6 11 | 12 | // Explanation: Let's break down the distance the snail covers each day: 13 | // Day 1: 7-2=5 14 | // Day 2: 5+7-2=10 15 | // Day 3: 10+7-2=15 16 | // Day 4: 15+7-2=20 17 | // Day 5: 20+7-2=25 18 | // Day 6: 25+7=32 19 | // So, on Day 6 the snail will reach 32 feet and get out of the well at day, without slipping back that night. 20 | function main() { 21 | var depth = parseInt(128, 10); 22 | var days = 0; 23 | var up = 7; 24 | var down = 2; 25 | var distance = 0; 26 | while (distance < depth - down) { 27 | distance += up; 28 | distance -= down; 29 | days++; 30 | console.log(distance, days); 31 | } 32 | console.log(days); 33 | } 34 | 35 | main(); 36 | -------------------------------------------------------------------------------- /sort-by-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sort by price with JavaScript 7 | 13 | 14 | 21 |
22 |

Top smartphones

23 |
    24 | 30 |
    31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /sort-by-js/script.js: -------------------------------------------------------------------------------- 1 | // Products list 2 | const products = [ 3 | { 4 | name: 'Samsung Galaxy S10', 5 | price: '599.99' 6 | }, 7 | { 8 | name: 'Huawei P30 Pro', 9 | price: '490.76' 10 | }, 11 | { 12 | name: 'Iphone 11 Pro', 13 | price: '1043.98' 14 | }, 15 | { 16 | name: 'OnePlus 7T Pro', 17 | price: '697.80' 18 | } 19 | ]; 20 | // Generate
  • for each product 21 | function generateHTML() { 22 | const ul = document.querySelector('.list-group'); 23 | ul.innerHTML = ''; 24 | products.forEach(product => { 25 | const li = document.createElement('li'); 26 | li.classList.add('list-group-item'); 27 | 28 | const name = document.createTextNode(product.name); 29 | li.appendChild(name); 30 | 31 | const span = document.createElement('span'); 32 | span.classList.add('float-right'); 33 | const price = document.createTextNode('£' + product.price); 34 | span.appendChild(price); 35 | 36 | li.appendChild(span); 37 | ul.appendChild(li); 38 | }); 39 | } 40 | 41 | window.addEventListener('load', generateHTML); 42 | const button = document.querySelector('.sort-btn'); 43 | button.addEventListener('click', () => { 44 | products.sort((a, b) => a.price - b.price); 45 | generateHTML(); 46 | }); 47 | -------------------------------------------------------------------------------- /speed-typing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | Speed Typing Test 15 | 16 | 17 | 20 | 21 |
    22 |
    23 |
    24 | 25 | 30 |
    31 |
    32 |
    33 | 34 |
    35 |

    👩‍💻 Speed Typing Test 👨‍💻

    36 | Type the following: 37 | 38 |

    39 | 40 | 47 | 48 |

    Time left: 10s

    49 | 50 |

    Score: 0

    51 | 52 |
    53 |
    54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /speed-typing/scripts.js: -------------------------------------------------------------------------------- 1 | const word = document.getElementById("word"); 2 | const text = document.getElementById("text"); 3 | const scoreEl = document.getElementById("score"); 4 | const timeEl = document.getElementById("time"); 5 | const endgameEl = document.getElementById("end-game-container"); 6 | const settingsBtn = document.getElementById("settings-btn"); 7 | const settings = document.getElementById("settings"); 8 | const settingsForm = document.getElementById("settings-form"); 9 | const difficultySelect = document.getElementById("difficulty"); 10 | 11 | const words = [ 12 | "sigh", 13 | "tense", 14 | "airplane", 15 | "ball", 16 | "pies", 17 | "juice", 18 | "warlike", 19 | "bad", 20 | "north", 21 | "dependent", 22 | "steer", 23 | "silver", 24 | "highfalutin", 25 | "superficial", 26 | "quince", 27 | "eight", 28 | "feeble", 29 | "admit", 30 | "drag", 31 | "loving", 32 | ]; 33 | 34 | // Init word 35 | let randomWord; 36 | 37 | // Init score 38 | let score = 0; 39 | 40 | // Init time 41 | let time = 10; 42 | 43 | // Set difficulty to value in ls or medium 44 | let difficulty = 45 | localStorage.getItem("difficulty") !== null 46 | ? localStorage.getItem("difficulty") 47 | : "medium"; 48 | 49 | // Set difficulty select value 50 | difficultySelect.value = 51 | localStorage.getItem("difficulty") !== null 52 | ? localStorage.getItem("difficulty") 53 | : "medium"; 54 | 55 | // Focus on text on start 56 | text.focus(); 57 | 58 | // Start counting down 59 | const timeInterval = setInterval(updateTime, 1000); 60 | 61 | // Generate random word from array 62 | function getRandomWord() { 63 | return words[Math.floor(Math.random() * words.length)]; 64 | } 65 | 66 | // Add word to DOM 67 | function addWordToDOM() { 68 | randomWord = getRandomWord(); 69 | word.innerHTML = randomWord; 70 | } 71 | 72 | // Update score 73 | function updateScore() { 74 | score++; 75 | scoreEl.innerHTML = score; 76 | } 77 | 78 | // Update time 79 | function updateTime() { 80 | time--; 81 | timeEl.innerHTML = time + "s"; 82 | 83 | if (time === 0) { 84 | clearInterval(timeInterval); 85 | // end game 86 | gameOver(); 87 | } 88 | } 89 | 90 | // Game over, show end screen 91 | function gameOver() { 92 | endgameEl.innerHTML = ` 93 |

    Time ran out

    94 |

    Your final score is ${score}

    95 | 96 | `; 97 | 98 | endgameEl.style.display = "flex"; 99 | } 100 | 101 | addWordToDOM(); 102 | 103 | // Event listeners 104 | 105 | // Typing 106 | text.addEventListener("input", (e) => { 107 | const insertedText = e.target.value; 108 | 109 | if (insertedText === randomWord) { 110 | addWordToDOM(); 111 | updateScore(); 112 | 113 | // Clear 114 | e.target.value = ""; 115 | 116 | if (difficulty === "hard") { 117 | time += 2; 118 | } else if (difficulty === "medium") { 119 | time += 3; 120 | } else { 121 | time += 5; 122 | } 123 | 124 | updateTime(); 125 | } 126 | }); 127 | 128 | // Settings btn click event 129 | settingsBtn.addEventListener("click", () => settings.classList.toggle("hide")); 130 | 131 | // Settings select 132 | settingsForm.addEventListener("change", (e) => { 133 | difficulty = e.target.value; 134 | localStorage.setItem("difficulty", difficulty); 135 | }); 136 | -------------------------------------------------------------------------------- /speed-typing/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background-color: #2c3e50; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | min-height: 100vh; 11 | margin: 0; 12 | font-family: Verdana, Geneva, Tahoma, sans-serif; 13 | } 14 | 15 | button { 16 | cursor: pointer; 17 | font-size: 14px; 18 | border-radius: 4px; 19 | padding: 5px 15px; 20 | } 21 | 22 | select { 23 | width: 200px; 24 | padding: 5px; 25 | appearance: none; 26 | -webkit-appearance: none; 27 | -moz-appearance: none; 28 | border-radius: 0; 29 | background-color: #a7c5e3; 30 | } 31 | 32 | select:focus, 33 | button:focus { 34 | outline: 0; 35 | } 36 | 37 | .settings-btn { 38 | position: absolute; 39 | bottom: 30px; 40 | left: 30px; 41 | } 42 | 43 | .settings { 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | width: 100%; 48 | background-color: rgba(0, 0, 0, 0.3); 49 | height: 70px; 50 | color: #fff; 51 | display: flex; 52 | align-items: center; 53 | justify-content: center; 54 | transform: translateY(0); 55 | transition: transform 0.3s ease-in-out; 56 | } 57 | 58 | .settings.hide { 59 | transform: translateY(-100%); 60 | } 61 | 62 | .container { 63 | background-color: #34495e; 64 | padding: 20px; 65 | border-radius: 4px; 66 | box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3); 67 | color: #fff; 68 | position: relative; 69 | text-align: center; 70 | width: 500px; 71 | } 72 | 73 | h2 { 74 | background-color: rgba(0, 0, 0, 0.3); 75 | padding: 8px; 76 | border-radius: 4px; 77 | margin: 0 0 40px; 78 | } 79 | 80 | h1 { 81 | margin: 0; 82 | } 83 | 84 | input { 85 | border: 0; 86 | border-radius: 4px; 87 | font-size: 14px; 88 | width: 300px; 89 | padding: 12px 20px; 90 | margin-top: 10px; 91 | } 92 | 93 | .score-container { 94 | position: absolute; 95 | top: 60px; 96 | right: 20px; 97 | } 98 | 99 | .time-container { 100 | position: absolute; 101 | top: 60px; 102 | left: 20px; 103 | } 104 | 105 | .end-game-container { 106 | background-color: inherit; 107 | display: none; 108 | align-items: center; 109 | justify-content: center; 110 | flex-direction: column; 111 | position: absolute; 112 | top: 0; 113 | left: 0; 114 | width: 100%; 115 | height: 100%; 116 | z-index: 1; 117 | } 118 | -------------------------------------------------------------------------------- /string-methods/byte-to-size.js: -------------------------------------------------------------------------------- 1 | const bytesToSize = (bytes: number, decimals: number = 2) => { 2 | if (bytes === 0) return '0 Bytes'; 3 | const k = 1024; 4 | const dm = decimals < 0 ? 0 : decimals; 5 | const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; 6 | const i = Math.floor(Math.log(bytes) / Math.log(k)); 7 | 8 | return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; 9 | }; 10 | export default bytesToSize; 11 | -------------------------------------------------------------------------------- /string-methods/limit-with-substring.js: -------------------------------------------------------------------------------- 1 | export function subString(str: string, limit: number): string { 2 | const len = str.length 3 | if (len > limit) { 4 | return str.substring(0, limit) + '...' 5 | } 6 | return str 7 | } 8 | -------------------------------------------------------------------------------- /text-to-img-server/text-to-img.md: -------------------------------------------------------------------------------- 1 | # Server Setup 2 | 3 | First, make sure to sign up for an OpenAI account and create an API key. Then store the API key in a file named .env. If it’s included in your .gitignore, this file will be ignored by Git so that you don’t accidentally share your API key with the world. 4 | 5 | ```js 6 | touch server.js 7 | 8 | npm i dotenv express cors openai 9 | node server.js 10 | ``` 11 | -------------------------------------------------------------------------------- /text-to-img-server/txt-to-img.js: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | dotenv.config(); 3 | 4 | import { Configuration, OpenAIApi } from 'openai'; 5 | 6 | const configuration = new Configuration({ 7 | apiKey: process.env.OPENAI, 8 | }); 9 | 10 | const openai = new OpenAIApi(configuration); 11 | 12 | import express from 'express'; 13 | import cors from 'cors'; 14 | 15 | const app = express(); 16 | app.use(cors()); 17 | app.use(express.json()); 18 | 19 | app.post('/dream', async (req, res) => { 20 | const prompt = req.body.prompt; 21 | 22 | const aiResponse = await openai.createImage({ 23 | prompt, 24 | n: 1, 25 | size: '1024x1024', 26 | }); 27 | 28 | const image = aiResponse.data.data[0].url; 29 | res.send({ image }); 30 | }); 31 | 32 | app.listen(8080, () => console.log('make art on http://localhost:8080/dream')); 33 | -------------------------------------------------------------------------------- /textColor/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Text Color if 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 | 13 |

    جاوااسکریپت

    14 |

    طراحی

    15 | 16 |

    وردپرس

    17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /textColor/script.js: -------------------------------------------------------------------------------- 1 | // const categoryElement = document.querySelector('h2'); 2 | 3 | // const categoryElementValue = categoryElement.textContent; 4 | 5 | const jsName = 'جاوااسکریپت' 6 | const designName = 'طراحی' 7 | const wpName = 'وردپرس' 8 | 9 | // const categoryChange = () => 10 | // categoryElementValue === jsName 11 | // ? categoryElementValue 12 | // : null; 13 | 14 | // categoryElementValue === wpName 15 | // ? categoryElement.classList.add('wpCss') : null; 16 | 17 | // categoryChange() 18 | 19 | 20 | 21 | const categoryColor = () => { 22 | 23 | const el2 = document.getElementsByTagName('h2'); 24 | 25 | 26 | } 27 | 28 | categoryColor() 29 | 30 | -------------------------------------------------------------------------------- /textColor/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | 5 | .body-class { 6 | background: #aaaaaa; 7 | } 8 | 9 | h2 { 10 | text-align: center; 11 | font-size: 2rem; 12 | } 13 | 14 | .jsCss { 15 | color: rgb(251, 255, 0); 16 | } 17 | 18 | .designCss { 19 | color: chocolate; 20 | } 21 | 22 | .wpCss { 23 | color: rgb(18, 90, 245); 24 | } 25 | -------------------------------------------------------------------------------- /tip-calculator/index.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Tip Calculator

    3 | 4 | 5 | 7 |
    8 |
    9 | -------------------------------------------------------------------------------- /tip-calculator/scripts.js: -------------------------------------------------------------------------------- 1 | let result = document.getElementById("result"); 2 | let resultInfo = ` 3 |
    Tip :
    4 |
    Total :
    5 |
    Each Person Pay :
    6 | ` 7 | result.innerHTML = resultInfo 8 | 9 | function calculateTip() { 10 | let bill = Number(document.getElementById("totalBill").value); 11 | let numOfPerson = Number(document.getElementById("numOfPerson").value); 12 | 13 | let tip = bill * .15; 14 | let totalBill = bill + tip; 15 | let perPersonPay = totalBill / numOfPerson 16 | 17 | result.innerHTML = ` 18 |
    Tip : ${tip}
    19 |
    Total : ${totalBill}
    20 |
    Each Person Pay : ${perPersonPay}
    21 | ` 22 | } 23 | 24 | -------------------------------------------------------------------------------- /tip-calculator/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "Poppins", sans-serif; 6 | } 7 | 8 | body { 9 | display: flex; 10 | justify-content: center; 11 | align-items: center; 12 | } 13 | 14 | .calculator { 15 | margin-top: 7rem; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | } 20 | 21 | .calculator input { 22 | margin: 16px 0; 23 | height: 40px; 24 | width: 20rem; 25 | padding: 10px; 26 | } 27 | 28 | .calculateBtn { 29 | font-size: 16px; 30 | padding: 6px 25px; 31 | width: 100%; 32 | background: #22d3ee; 33 | border: none; 34 | border-radius: 4px; 35 | color: white; 36 | cursor: pointer; 37 | } 38 | 39 | .result { 40 | width: 100%; 41 | min-height: 100px; 42 | border: 1px solid gainsboro; 43 | box-shadow: -3px 4px 11px 0px rgba(0, 0, 0, 0.41); 44 | margin-top: 20px; 45 | padding: 20px; 46 | } 47 | -------------------------------------------------------------------------------- /touch-events/app.js: -------------------------------------------------------------------------------- 1 | function update(event) { 2 | console.log(event.type, event.target); 3 | for (let dot; (dot = document.querySelector("dot")); ) { 4 | dot.remove(); 5 | } 6 | for (let i = 0; i < event.touches.length; i++) { 7 | let { pageX, pageY } = event.touches[i]; 8 | let dot = document.createElement("dot"); 9 | dot.style.left = pageX - 50 + "px"; 10 | dot.style.top = pageY - 50 + "px"; 11 | document.body.appendChild(dot); 12 | } 13 | } 14 | window.addEventListener("touchstart", update); 15 | window.addEventListener("touchmove", update); 16 | window.addEventListener("touchend", update); 17 | -------------------------------------------------------------------------------- /touch-events/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Touch Events 8 | 9 | 19 | 20 | 21 |

    Touch this page

    22 | 23 | 24 | -------------------------------------------------------------------------------- /ts/app.js: -------------------------------------------------------------------------------- 1 | const logger = (a: Number) => { 2 | if (typeof a === "string") { 3 | return console.log("type Error"); 4 | } 5 | return console.log(a); 6 | }; 7 | 8 | logger("sdas"); 9 | -------------------------------------------------------------------------------- /ts/export-to-file.ts: -------------------------------------------------------------------------------- 1 | const exportToFile = (data: string, filename: string) => { 2 | const blob = new Blob([data], { type: 'text/plain' }); 3 | const url = URL.createObjectURL(blob); 4 | const link = document.createElement('a'); 5 | 6 | link.setAttribute('href', url); 7 | link.setAttribute('download', filename); 8 | link.click(); 9 | 10 | URL.revokeObjectURL(url); 11 | }; 12 | 13 | export { exportToFile }; -------------------------------------------------------------------------------- /ts/get-ip.ts: -------------------------------------------------------------------------------- 1 | // get user ip in next.js 2 | import { headers } from "next/headers"; 3 | 4 | export function getUserIP() { 5 | const forwardedFor = headers().get("x-forwarded-for"); 6 | const realIp = headers().get("x-real-ip"); 7 | 8 | if (forwardedFor) { 9 | return forwardedFor.split(",")[0].trim(); 10 | } 11 | if (realIp) { 12 | return realIp.trim(); 13 | } 14 | 15 | return null; 16 | } -------------------------------------------------------------------------------- /ts/index.ts: -------------------------------------------------------------------------------- 1 | // const logger = (a: string) => { 2 | // return console.log(a) 3 | // } 4 | 5 | // logger(2) -------------------------------------------------------------------------------- /ts/string-code-extract.ts: -------------------------------------------------------------------------------- 1 | export type CodeMessage = { 2 | language: string; 3 | code: string; 4 | }; 5 | 6 | function removeCode(str: string) { 7 | let i = 0; 8 | const regexToRmCode = /```[\s\S]*?```/g; 9 | return str.replace(regexToRmCode, `some-code`).split("some-code"); 10 | } 11 | 12 | function getCodesFromString(str: string) { 13 | const regexToRmContent = /```(\w+)\n([\s\S]+?)```/g; 14 | let match; 15 | const codes: CodeMessage[] = []; 16 | while ((match = regexToRmContent.exec(str)) !== null) { 17 | const language = match[1]; 18 | const code = match[2]; 19 | codes.push({ 20 | language, 21 | code, 22 | }); 23 | } 24 | return codes; 25 | } 26 | 27 | export function parseCode(str: string) { 28 | return { 29 | withoutCodeArr: removeCode(str), 30 | codesArr: getCodesFromString(str), 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /url-snippets/get-url-parts.js: -------------------------------------------------------------------------------- 1 | 2 | var urlRegex = /([a-z]{1,2}tps?):\/\/((?:(?!(?:\/|#|\?|&)).)+)(?:(\/(?:(?:(?:(?!(?:#|\?|&)).)+\/))?))?(?:((?:(?!(?:\.|$|\?|#)).)+))?(?:(\.(?:(?!(?:\?|$|#)).)+))?(?:(\?(?:(?!(?:$|#)).)+))?(?:(#.+))?/; 3 | 4 | var getUrlParts = function getUrlParts(url) { 5 | var found = url.match(urlRegex); 6 | console.log("reg", found) 7 | try { 8 | var _found = _slicedToArray(found, 8), 9 | fullUrl = _found[0], 10 | protocol = _found[1], 11 | domain = _found[2], 12 | path = _found[3], 13 | endFilename = _found[4], 14 | endFileExtension = _found[5], 15 | query = _found[6], 16 | hash = _found[7]; 17 | 18 | return { 19 | fullUrl: fullUrl, 20 | protocol: protocol, 21 | domain: domain, 22 | path: path, 23 | endFilename: endFilename, 24 | endFileExtension: endFileExtension, 25 | query: query, 26 | hash: hash 27 | }; 28 | } catch (e) { 29 | throw new Error("Could not find url parts from ".concat(url, ".")); 30 | } 31 | }; 32 | 33 | const testUrl = getUrlParts('https://google.com/bio?dsdas=dsd&defs2=cdcs#nea') 34 | console.log("t", testUrl) -------------------------------------------------------------------------------- /useblackbox.io/test.js: -------------------------------------------------------------------------------- 1 | // ask question like below 2 | 3 | //define middleware in nodejs? 4 | // express 5 | var app = express(); 6 | // middleware 7 | var stack = middleware(); 8 | 9 | // express 10 | app.use(express.static(..)); 11 | // middleware 12 | stack.use(function(data, next) { 13 | next(); 14 | }); 15 | 16 | // express, you need to do nothing 17 | // middleware 18 | stack.handle(someData); 19 | 20 | var middleware = require("../src/middleware.js"); 21 | 22 | var stack = middleware(function(data, next) { 23 | data.foo = data.data*2; 24 | next(); 25 | }, function(data, next) { 26 | setTimeout(function() { 27 | data.async = true; 28 | next(); 29 | }, 100) 30 | }, function(data) { 31 | console.log(data); 32 | }); 33 | 34 | stack.handle({ 35 | "data": 42 36 | }) 37 | 38 | 39 | // middleware 40 | 41 | var stack = middleware(function(req, res, next) { 42 | users.getAll(function(err, users) { 43 | if (err) next(err); 44 | req.users = users; 45 | next(); 46 | }); 47 | }, function(req, res, next) { 48 | posts.getAll(function(err, posts) { 49 | if (err) next(err); 50 | req.posts = posts; 51 | next(); 52 | }) 53 | }, function(req, res, next) { 54 | req.posts.forEach(function(post) { 55 | post.user = req.users[post.userId]; 56 | }); 57 | 58 | res.render("blog/posts", { 59 | "posts": req.posts 60 | }); 61 | }); 62 | 63 | var app = express.createServer(); 64 | 65 | app.get("/posts", function(req, res) { 66 | stack.handle(req, res); 67 | }); 68 | 69 | // express 70 | 71 | var app = express.createServer(); 72 | 73 | app.get("/posts", [ 74 | function(req, res, next) { 75 | users.getAll(function(err, users) { 76 | if (err) next(err); 77 | req.users = users; 78 | next(); 79 | }); 80 | }, function(req, res, next) { 81 | posts.getAll(function(err, posts) { 82 | if (err) next(err); 83 | req.posts = posts; 84 | next(); 85 | }) 86 | }, function(req, res, next) { 87 | req.posts.forEach(function(post) { 88 | post.user = req.users[post.userId]; 89 | }); 90 | 91 | res.render("blog/posts", { 92 | "posts": req.posts 93 | }); 94 | } 95 | ], function(req, res) { 96 | stack.handle(req, res); 97 | }); -------------------------------------------------------------------------------- /useful-Snippets/capitalize-string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalise a string 3 | */ 4 | 5 | const capitalizeString = (str) => { 6 | let capStr = str.replace(/\w\S*/g, (txt) => 7 | txt.replace(/^\w/, (chr) => chr.toUpperCase()) 8 | ); 9 | return capStr; 10 | }; 11 | 12 | console.log(capitalizeString("hello world")); 13 | -------------------------------------------------------------------------------- /useful-Snippets/clear-all-cookies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Clear browser all cookies 3 | */ 4 | 5 | const clearAllCookies = () => { 6 | document.cookie.split(";").forEach(function (c) { 7 | document.cookie = c 8 | .replace(/^ +/, "") 9 | .replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /useful-Snippets/copy-to-clipboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copy to clipboard 3 | */ 4 | 5 | const copy = (text) => navigator.clipboard.writeText(text); 6 | 7 | copy("Hello World!"); 8 | -------------------------------------------------------------------------------- /useful-Snippets/dynamic-get-all-el.js: -------------------------------------------------------------------------------- 1 | 2 | let s = '' 3 | document.querySelectorAll('[id]').forEach(el => { 4 | let {id} = el 5 | let name = id.replace(/-(.)/g, (_, c) => c.toUpperCase()) 6 | s += `const $${name} = document.getElementById('${id}')\n` 7 | }) 8 | console.log(s) 9 | 10 | 11 | let $refs = {} 12 | document.querySelectorAll('[id]').forEach($el => { 13 | let key = $el.id.replace(/-(.)/g, (_, s) => s.toUpperCase()) 14 | $refs[key] = $el 15 | }) 16 | 17 | console.log($refs) -------------------------------------------------------------------------------- /useful-Snippets/generate-random-hex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gernerate a random hex color 3 | */ 4 | 5 | const hexColor = () => 6 | "#" + 7 | Math.floor(Math.random() * 0xffffff) 8 | .toString(16) 9 | .padEnd(6, "0"); 10 | 11 | console.log(hexColor()); 12 | -------------------------------------------------------------------------------- /useful-Snippets/reverse-string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Reverse a string 3 | */ 4 | 5 | // Method 1 6 | function reverseString(str) { 7 | return str.split("").reverse().join(""); 8 | } 9 | console.log(reverseString("hello")); 10 | 11 | // Method 2 12 | function reverse(s) { 13 | var o = ""; 14 | for (var i = s.length - 1; i >= 0; i--) o += s[i]; 15 | return o; 16 | } 17 | 18 | console.log(reverse("Hello")); 19 | -------------------------------------------------------------------------------- /useful-Snippets/scroll-to-top.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Scroll to top 3 | */ 4 | const toTop = () => window.scrollTo(0, 0); 5 | -------------------------------------------------------------------------------- /vanilla-web-components/counter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Vanilla Web Components Counter 3 | * @class MyCounter 4 | * @extends {HTMLElement} 5 | * @author Ehsan Ghaffar 6 | * @version 1.0.0 7 | */ 8 | 9 | class MyCounter extends HTMLElement { 10 | constructor() { 11 | super(); 12 | this.shadow = this.attachShadow({ mode: "open" }); 13 | } 14 | 15 | get count() { 16 | return this.getAttribute("count"); 17 | } 18 | 19 | set count(val) { 20 | this.setAttribute("count", val); 21 | } 22 | 23 | static get observedAttributes() { 24 | return ["count"]; 25 | } 26 | 27 | attributesChangedCallback(attrName, oldVal, newVal) { 28 | if (attrName === "count") { 29 | this.render(); 30 | let btn = this.shadow.querySelector("#btn"); 31 | btn.addEventListener("click", this.inc.bind(this)); 32 | } 33 | } 34 | 35 | inc() { 36 | this.count++; 37 | } 38 | 39 | connectedCallback() { 40 | this.render(); 41 | let btn = this.shadow.querySelector("#btn"); 42 | btn.addEventListener("click", this.inc.bind(this)); 43 | } 44 | 45 | render() { 46 | this.shadow.innerHTML = ` 47 |

    Counter

    48 |

    Count: ${this.count}

    49 | 50 | `; 51 | } 52 | } 53 | 54 | customElements.define("my-counter", MyCounter); 55 | -------------------------------------------------------------------------------- /vanilla-web-components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vanilla Web Component 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web-worker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Web Worker 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web-worker/index.js: -------------------------------------------------------------------------------- 1 | // create a web worker 2 | // function startWorker() { 3 | // const worker = new Worker('worker.js'); 4 | // worker.postMessage('Hello World'); 5 | // worker.onmessage = function(event) { 6 | // console.log('Worker said: ' + event.data); 7 | // }; 8 | 9 | // worker.postMessage("Start the calculation"); 10 | // } 11 | 12 | // startWorker(); 13 | 14 | 15 | // create process large dataser 16 | function processLargeDataset(dataset) { 17 | const numberOfWorkers = 4; 18 | const chunkSize = Math.ceil(dataset.length / numberOfWorkers); 19 | const workers = []; 20 | let processedData = []; 21 | 22 | for (let i = 0; i < numberOfWorkers; i++) { 23 | const worker = new Worker('worker.js'); 24 | worker.onmessage = function(event) { 25 | processedData.push(...event.data); 26 | if (processedData.length === dataset.length) { 27 | console.log('Processed data: ', processedData); 28 | } 29 | } 30 | 31 | const start = i * chunkSize; 32 | const end = start + chunkSize; 33 | worker.postMessage(dataset.slice(start, end)); 34 | workers.push(worker); 35 | } 36 | 37 | } 38 | 39 | const largeDataset = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`); 40 | processLargeDataset(largeDataset); 41 | -------------------------------------------------------------------------------- /web-worker/worker.js: -------------------------------------------------------------------------------- 1 | // onmessage = function(event) { 2 | // if (event.data === 'Start the calculation') { 3 | // postMessage('Worker started the calculation'); 4 | // } 5 | // let result = 0; 6 | // for (let i = 0; i < 1000000000; i++) { 7 | // result += i; 8 | // } 9 | // postMessage('Result: ' + result); 10 | // } 11 | 12 | onmessage = function(event) { 13 | const chunk = event.data; 14 | const proccesChunk = chunk.map(item => item.toUpperCase()); 15 | postMessage(proccesChunk); 16 | } -------------------------------------------------------------------------------- /why-people-hate-js/resons.js: -------------------------------------------------------------------------------- 1 | for (var i = 0; i < 10; i++) { 2 | setTimeout(() => { 3 | console.log(i) 4 | }, 1000); 5 | } -------------------------------------------------------------------------------- /ᛉ-algorithms/bubble-sort-search.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * The function bubbleSearch is defined with two parameters: arr (the input array) 4 | * and target (the value to search for). 5 | */ 6 | function bubbleSearch(arr, target) { 7 | /** 8 | * Three variables are initialized: maxIndex (the maximum index of the array), 9 | * end (the end index for the bubble sort algorithm), and swapped 10 | * (a flag to indicate if any swaps were made during the bubble sort). 11 | */ 12 | var maxIndex = arr.length - 1; 13 | var end = maxIndex; 14 | var swapped = true; 15 | /** 16 | * A while loop is used to perform the bubble sort. 17 | * The loop continues as long as swapped is true 18 | * (i.e., there were swaps made during the previous iteration). 19 | * Inside the loop, a for loop is used to compare adjacent elements 20 | * in the array and swap them if necessary 21 | * (i.e., if the current element is greater than the next element). 22 | * If a swap is made, swapped is set to true to indicate that the 23 | * loop should continue. 24 | */ 25 | while (swapped) { 26 | swapped = false; 27 | for (var i = 0; i < end; i++) { 28 | if (arr[i] > arr[i+1]) { 29 | // Swap elements 30 | var temp = arr[i]; 31 | arr[i] = arr[i+1]; 32 | arr[i+1] = temp; 33 | 34 | swapped = true; 35 | } 36 | } 37 | end--; 38 | } 39 | 40 | /** 41 | * After the bubble sort is complete, 42 | * a binary search is performed to find the index of the target 43 | * value in the sorted array. A while loop is used to continue 44 | * the search as long as start is less than or equal to maxIndex. 45 | * Inside the loop, the middle index is calculated using the formula 46 | * Math.floor((start + maxIndex) / 2). If the middle element is equal 47 | * to the target, the function returns the index of the middle element. 48 | * If the middle element is less than the target, the search continues 49 | * in the right half of the array (by setting start to mid + 1). 50 | * If the middle element is greater than the target, the search continues 51 | * in the left half of the array (by setting maxIndex to mid - 1). 52 | */ 53 | var start = 0; 54 | while (start <= maxIndex) { 55 | var mid = Math.floor((start + maxIndex) / 2); 56 | if (arr[mid] === target) { 57 | return mid; 58 | } else if (arr[mid] < target) { 59 | start = mid + 1; 60 | } else { 61 | maxIndex = mid - 1; 62 | } 63 | } 64 | 65 | // Target not found 66 | return -1; 67 | } 68 | 69 | 70 | // Test 71 | 72 | let myArray = [12, 10, 3, 7, 4]; 73 | 74 | console.log(bubbleSearch(myArray, 10)) 75 | -------------------------------------------------------------------------------- /ᛉ-algorithms/recursive-factorial.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * This recursive function takes in a number num and returns its factorial. 4 | * The base case is when num is equal to 0, in which case the function returns 1. 5 | * The recursive case multiplies num by the result of the function called with num - 1 as the argument. 6 | * This continues recursively until the base case is reached. 7 | */ 8 | 9 | function factorial(num) { 10 | if (num === 0) { // base case 11 | return 1; 12 | } else { 13 | return num * factorial(num - 1); // recursive case 14 | } 15 | } 16 | 17 | console.log(factorial(4)) --------------------------------------------------------------------------------