├── .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 | Snap Photo
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 |
18 | Change Color
19 |
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 | Check Color
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 |
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 |
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 |
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 |
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 |
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 | Generate password
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 | Button
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 |
28 | Sort by Price
29 |
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 |
18 |
19 |
20 |
21 |
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 | Reload
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 |
Calculate
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 | calculate
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))
--------------------------------------------------------------------------------