Repository: FaridaNelson/se_project_spots
Pull request #1: First attempt Project 9
Author: login: FaridaNelson
Created: 2025-05-22T06:56:06Z | Merged: 2025-05-30T01:00:10Z



Diff:
diff --git a/package-lock.json b/package-lock.json
index 0a7a7a9..81c548e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,10 +16,11 @@
         "copy-webpack-plugin": "^13.0.0",
         "css-loader": "6.7.1",
         "cssnano": "5.1.12",
+        "gh-pages": "^6.3.0",
         "html-webpack-plugin": "5.5.0",
         "mini-css-extract-plugin": "2.6.1",
         "postcss-loader": "7.0.1",
-        "webpack": "5.76.0",
+        "webpack": "^5.99.9",
         "webpack-cli": "4.10.0",
         "webpack-dev-server": "4.9.3"
       }
@@ -1788,6 +1789,44 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/@trysound/sax": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@@ -1863,9 +1902,9 @@
       }
     },
     "node_modules/@types/estree": {
-      "version": "0.0.51",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
-      "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+      "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
       "dev": true,
       "license": "MIT"
     },
@@ -2066,73 +2105,73 @@
       }
     },
     "node_modules/@webassemblyjs/ast": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
-      "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+      "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/helper-numbers": "1.11.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+        "@webassemblyjs/helper-numbers": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
       }
     },
     "node_modules/@webassemblyjs/floating-point-hex-parser": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
-      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+      "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webassemblyjs/helper-api-error": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
-      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+      "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webassemblyjs/helper-buffer": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
-      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+      "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webassemblyjs/helper-numbers": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
-      "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+      "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/floating-point-hex-parser": "1.11.1",
-        "@webassemblyjs/helper-api-error": "1.11.1",
+        "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+        "@webassemblyjs/helper-api-error": "1.13.2",
         "@xtuc/long": "4.2.2"
       }
     },
     "node_modules/@webassemblyjs/helper-wasm-bytecode": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
-      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+      "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webassemblyjs/helper-wasm-section": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
-      "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+      "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/helper-buffer": "1.11.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
-        "@webassemblyjs/wasm-gen": "1.11.1"
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/wasm-gen": "1.14.1"
       }
     },
     "node_modules/@webassemblyjs/ieee754": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
-      "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+      "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2140,9 +2179,9 @@
       }
     },
     "node_modules/@webassemblyjs/leb128": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
-      "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+      "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
       "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
@@ -2150,79 +2189,79 @@
       }
     },
     "node_modules/@webassemblyjs/utf8": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
-      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+      "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webassemblyjs/wasm-edit": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
-      "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+      "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/helper-buffer": "1.11.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
-        "@webassemblyjs/helper-wasm-section": "1.11.1",
-        "@webassemblyjs/wasm-gen": "1.11.1",
-        "@webassemblyjs/wasm-opt": "1.11.1",
-        "@webassemblyjs/wasm-parser": "1.11.1",
-        "@webassemblyjs/wast-printer": "1.11.1"
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/helper-wasm-section": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-opt": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1",
+        "@webassemblyjs/wast-printer": "1.14.1"
       }
     },
     "node_modules/@webassemblyjs/wasm-gen": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
-      "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+      "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
-        "@webassemblyjs/ieee754": "1.11.1",
-        "@webassemblyjs/leb128": "1.11.1",
-        "@webassemblyjs/utf8": "1.11.1"
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
       }
     },
     "node_modules/@webassemblyjs/wasm-opt": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
-      "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+      "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/helper-buffer": "1.11.1",
-        "@webassemblyjs/wasm-gen": "1.11.1",
-        "@webassemblyjs/wasm-parser": "1.11.1"
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1"
       }
     },
     "node_modules/@webassemblyjs/wasm-parser": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
-      "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+      "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/helper-api-error": "1.11.1",
-        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
-        "@webassemblyjs/ieee754": "1.11.1",
-        "@webassemblyjs/leb128": "1.11.1",
-        "@webassemblyjs/utf8": "1.11.1"
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-api-error": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
       }
     },
     "node_modules/@webassemblyjs/wast-printer": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
-      "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+      "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webassemblyjs/ast": "1.11.1",
+        "@webassemblyjs/ast": "1.14.1",
         "@xtuc/long": "4.2.2"
       }
     },
@@ -2316,17 +2355,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/acorn-import-assertions": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
-      "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
-      "deprecated": "package has been renamed to acorn-import-attributes",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "acorn": "^8"
-      }
-    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2463,6 +2491,13 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/autoprefixer": {
       "version": "10.4.7",
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
@@ -3045,36 +3080,6 @@
         "webpack": "^5.1.0"
       }
     },
-    "node_modules/copy-webpack-plugin/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
     "node_modules/copy-webpack-plugin/node_modules/glob-parent": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -3088,33 +3093,6 @@
         "node": ">=10.13.0"
       }
     },
-    "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/core-js": {
       "version": "3.23.5",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.5.tgz",
@@ -3475,6 +3453,19 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/dns-packet": {
       "version": "5.6.1",
       "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -3597,6 +3588,13 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/email-addresses": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz",
+      "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
@@ -3685,9 +3683,9 @@
       }
     },
     "node_modules/es-module-lexer": {
-      "version": "0.9.3",
-      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
-      "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+      "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
       "dev": true,
       "license": "MIT"
     },
@@ -3721,6 +3719,16 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
     "node_modules/eslint-scope": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -3883,6 +3891,23 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-glob": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.8"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
     "node_modules/fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -3917,6 +3942,16 @@
         "node": ">= 4.9.1"
       }
     },
+    "node_modules/fastq": {
+      "version": "1.19.1",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+      "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
     "node_modules/faye-websocket": {
       "version": "0.11.4",
       "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
@@ -3930,6 +3965,34 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/filename-reserved-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+      "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/filenamify": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
+      "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "filename-reserved-regex": "^2.0.0",
+        "strip-outer": "^1.0.1",
+        "trim-repeated": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/fill-range": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4059,6 +4122,21 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/fs-extra": {
+      "version": "11.3.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+      "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=14.14"
+      }
+    },
     "node_modules/fs-monkey": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz",
@@ -4160,6 +4238,70 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/gh-pages": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz",
+      "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "async": "^3.2.4",
+        "commander": "^13.0.0",
+        "email-addresses": "^5.0.0",
+        "filenamify": "^4.3.0",
+        "find-cache-dir": "^3.3.1",
+        "fs-extra": "^11.1.1",
+        "globby": "^11.1.0"
+      },
+      "bin": {
+        "gh-pages": "bin/gh-pages.js",
+        "gh-pages-clean": "bin/gh-pages-clean.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/gh-pages/node_modules/array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/gh-pages/node_modules/commander": {
+      "version": "13.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+      "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/gh-pages/node_modules/globby": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.2.9",
+        "ignore": "^5.2.0",
+        "merge2": "^1.4.1",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/glob": {
       "version": "7.2.3",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -4558,6 +4700,16 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/ignore": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
     "node_modules/import-fresh": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -4903,6 +5055,19 @@
         "node": ">=6"
       }
     },
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
     "node_modules/kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -5099,6 +5264,16 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
     "node_modules/methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -5189,63 +5364,6 @@
         "webpack": "^5.0.0"
       }
     },
-    "node_modules/mini-css-extract-plugin/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
-    "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -6466,9 +6584,30 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/randombytes": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
       "dev": true,
       "license": "MIT",
@@ -6709,6 +6848,17 @@
         "node": ">= 4"
       }
     },
+    "node_modules/reusify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -6726,6 +6876,30 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -6755,15 +6929,16 @@
       "license": "MIT"
     },
     "node_modules/schema-utils": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
-      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
+      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@types/json-schema": "^7.0.8",
-        "ajv": "^6.12.5",
-        "ajv-keywords": "^3.5.2"
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
       },
       "engines": {
         "node": ">= 10.13.0"
@@ -6773,6 +6948,43 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/schema-utils/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/schema-utils/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/schema-utils/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -7067,6 +7279,16 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/sockjs": {
       "version": "0.3.24",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -7243,6 +7465,19 @@
         "node": ">=6"
       }
     },
+    "node_modules/strip-outer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/stylehacks": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
@@ -7399,63 +7634,6 @@
         }
       }
     },
-    "node_modules/terser-webpack-plugin/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
-    "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/thunky": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
@@ -7531,6 +7709,19 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/trim-repeated": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+      "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "escape-string-regexp": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/tslib": {
       "version": "2.8.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -7603,6 +7794,16 @@
         "node": ">=4"
       }
     },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
     "node_modules/unpipe": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -7723,35 +7924,35 @@
       }
     },
     "node_modules/webpack": {
-      "version": "5.76.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz",
-      "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==",
+      "version": "5.99.9",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz",
+      "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@types/eslint-scope": "^3.7.3",
-        "@types/estree": "^0.0.51",
-        "@webassemblyjs/ast": "1.11.1",
-        "@webassemblyjs/wasm-edit": "1.11.1",
-        "@webassemblyjs/wasm-parser": "1.11.1",
-        "acorn": "^8.7.1",
-        "acorn-import-assertions": "^1.7.6",
-        "browserslist": "^4.14.5",
+        "@types/eslint-scope": "^3.7.7",
+        "@types/estree": "^1.0.6",
+        "@types/json-schema": "^7.0.15",
+        "@webassemblyjs/ast": "^1.14.1",
+        "@webassemblyjs/wasm-edit": "^1.14.1",
+        "@webassemblyjs/wasm-parser": "^1.14.1",
+        "acorn": "^8.14.0",
+        "browserslist": "^4.24.0",
         "chrome-trace-event": "^1.0.2",
-        "enhanced-resolve": "^5.10.0",
-        "es-module-lexer": "^0.9.0",
+        "enhanced-resolve": "^5.17.1",
+        "es-module-lexer": "^1.2.1",
         "eslint-scope": "5.1.1",
         "events": "^3.2.0",
         "glob-to-regexp": "^0.4.1",
-        "graceful-fs": "^4.2.9",
+        "graceful-fs": "^4.2.11",
         "json-parse-even-better-errors": "^2.3.1",
         "loader-runner": "^4.2.0",
         "mime-types": "^2.1.27",
         "neo-async": "^2.6.2",
-        "schema-utils": "^3.1.0",
+        "schema-utils": "^4.3.2",
         "tapable": "^2.1.1",
-        "terser-webpack-plugin": "^5.1.3",
-        "watchpack": "^2.4.0",
+        "terser-webpack-plugin": "^5.3.11",
+        "watchpack": "^2.4.1",
         "webpack-sources": "^3.2.3"
       },
       "bin": {
@@ -7852,63 +8053,6 @@
         "webpack": "^4.0.0 || ^5.0.0"
       }
     },
-    "node_modules/webpack-dev-middleware/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
-    "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/webpack-dev-server": {
       "version": "4.9.3",
       "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz",
@@ -7965,63 +8109,6 @@
         }
       }
     },
-    "node_modules/webpack-dev-server/node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/webpack-dev-server/node_modules/ajv-keywords": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
-      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3"
-      },
-      "peerDependencies": {
-        "ajv": "^8.8.2"
-      }
-    },
-    "node_modules/webpack-dev-server/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/webpack-dev-server/node_modules/schema-utils": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
-      "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/json-schema": "^7.0.9",
-        "ajv": "^8.9.0",
-        "ajv-formats": "^2.1.1",
-        "ajv-keywords": "^5.1.0"
-      },
-      "engines": {
-        "node": ">= 10.13.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/webpack-merge": {
       "version": "5.10.0",
       "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
diff --git a/package.json b/package.json
index 8ef88db..91f0ee6 100644
--- a/package.json
+++ b/package.json
@@ -8,16 +8,19 @@
     "copy-webpack-plugin": "^13.0.0",
     "css-loader": "6.7.1",
     "cssnano": "5.1.12",
+    "gh-pages": "^6.3.0",
     "html-webpack-plugin": "5.5.0",
     "mini-css-extract-plugin": "2.6.1",
     "postcss-loader": "7.0.1",
-    "webpack": "5.76.0",
+    "webpack": "^5.99.9",
     "webpack-cli": "4.10.0",
     "webpack-dev-server": "4.9.3"
   },
   "scripts": {
     "build": "webpack --mode production",
-    "dev": "webpack serve --mode development"
+    "dev": "webpack serve --mode development",
+    "predeploy": "npm run build",
+    "deploy": "gh-pages -d dist"
   },
   "dependencies": {
     "core-js": "3.23.5"
diff --git a/src/blocks/modal.css b/src/blocks/modal.css
index e8e0493..1472815 100644
--- a/src/blocks/modal.css
+++ b/src/blocks/modal.css
@@ -41,6 +41,11 @@
   width: auto;
 }
 
+.modal__container.modal__container_delete_card {
+  width: 630px;
+  padding: 32px 20px;
+}
+
 .modal__image {
   max-width: 80vw;
   max-height: 80vh;
@@ -64,6 +69,13 @@
   cursor: pointer;
 }
 
+.modal__close-button_delete_card {
+  position: relative;
+  background-image: url(../images/x-wht.svg);
+  right: -350px;
+  color: #fff;
+}
+
 .modal__close-button:hover {
   opacity: 1;
   cursor: pointer;
@@ -101,14 +113,21 @@
   color: #212121;
 }
 
+.modal__title.modal__title_delete_card {
+  font-size: 24px;
+  justify-self: center;
+}
+
 .modal__label {
   display: flex;
   flex-direction: column;
+  font-family: Poppins, Arial, Helvetica, sans-serif;
   gap: 8px;
   margin-bottom: 32px;
   color: rgba(33, 33, 33, 0.7);
   font-weight: 500;
   line-height: 17.6px;
+  font-size: 16px;
 }
 
 .modal__input {
@@ -123,6 +142,12 @@
   cursor: pointer;
 }
 
+.modal__form.modal__form_delete_card {
+  display: flex;
+  justify-content: center;
+  gap: 20px;
+}
+
 .modal__form input.modal__input_type_error {
   border: 1px solid rgba(255, 0, 0, 0.6);
 }
@@ -151,6 +176,8 @@
 
 .modal__submit-button {
   border: none;
+  font-family: Poppins, Arial, Helvetica, sans-serif;
+  font-size: 16px;
   width: 156px;
   padding: 18px;
   border-radius: 8px;
@@ -158,6 +185,16 @@
   background-color: #212121;
 }
 
+.modal__submit-button_delete_card {
+  background-color: #ff6565;
+  color: #212121;
+}
+
+.modal__submit-button.modal__submit-button_delete_card:hover {
+  background-color: #ff3333;
+  opacity: 1;
+}
+
 .modal__submit-button_disabled {
   opacity: 0.5;
   cursor: not-allowed;
@@ -169,6 +206,31 @@
   cursor: pointer;
 }
 
+.modal__cancel-button {
+  border: 1px solid #212121;
+  font-family: Poppins, Arial, Helvetica, sans-serif;
+  font-size: 16px;
+  width: 156px;
+  padding: 18px;
+  border-radius: 8px;
+  color: #212121;
+  background-color: transparent;
+}
+
+.modal__cancel-button:hover {
+  background-color: #212121;
+  color: #fff;
+  cursor: pointer;
+}
+
+@media screen and (max-width: 750px) {
+  .modal__close-button.modal__close-button_delete_card {
+    top: -16px;
+    right: -300px;
+    z-index: 10;
+  }
+}
+
 @media screen and (max-width: 627px) {
   .modal {
     padding: 0 10px;
@@ -189,6 +251,24 @@
     line-height: 20px;
   }
 
+  .modal__title.modal__title_delete_card {
+    font-size: 20px;
+    text-align: center;
+    line-height: 120%;
+  }
+
+  .modal__form.modal__form_delete_card {
+    flex-direction: column;
+    justify-content: center;
+    gap: 12px;
+    align-items: center;
+  }
+
+  .modal__container.modal__container_delete_card {
+    width: 300px;
+    padding: 12px;
+  }
+
   .modal__close-button {
     top: 12px;
     right: 12px;
@@ -202,6 +282,12 @@
     padding: 0;
   }
 
+  .modal__close-button.modal__close-button_delete_card {
+    top: -16px;
+    right: -140px;
+    z-index: 10;
+  }
+
   .modal__label {
     margin-bottom: 24px;
   }
@@ -213,6 +299,14 @@
   .modal__submit-button {
     width: 100%;
   }
+
+  .modal__submit-button.modal__submit-button_delete_card {
+    width: 156px;
+  }
+
+  .modal__cancel-button {
+    width: 156px;
+  }
 }
 
 @media screen and (max-width: 363px) {
diff --git a/src/blocks/profile.css b/src/blocks/profile.css
index 84bd132..81c39dc 100644
--- a/src/blocks/profile.css
+++ b/src/blocks/profile.css
@@ -4,8 +4,46 @@
   border-bottom: 1px rgba(33, 33, 33, 0.4) solid;
 }
 
-.profile__avatar {
+.profile__avatar-container {
+  position: relative;
   margin-right: 20px;
+}
+
+.profile__avatar-btn {
+  position: absolute;
+  width: 190px;
+  height: 190px;
+  display: flex;
+  align-items: flex-end;
+  justify-content: center;
+  visibility: hidden;
+  padding: 0;
+  border: none;
+}
+
+.profile__avatar-container:hover .profile__avatar-btn {
+  visibility: visible;
+  background-color: rgba(0, 0, 0, 0.5);
+  border-radius: 8px;
+  cursor: pointer;
+}
+
+.profile__avatar-btn::after {
+  content: "Edit Avatar";
+  padding-bottom: 12px;
+  padding-left: 8px;
+  color: #ffffff;
+  font-size: 16px;
+  font-weight: 500;
+  opacity: 1;
+}
+
+.profile__pencil-icon {
+  padding-bottom: 14px;
+  opacity: 1;
+}
+
+.profile__avatar {
   border-radius: 8px;
   height: 190px;
   width: 190px;
@@ -119,12 +157,52 @@
     padding-top: 20px;
   }
 
+  .profile__avatar-container {
+    margin: 0 0 12px;
+    width: 80px;
+    height: 80px;
+  }
+
   .profile__avatar {
     margin: 0 0 12px;
     height: 80px;
     width: 80px;
   }
 
+  .profile__pencil-icon {
+    width: 18px;
+    height: 18px;
+    object-fit: contain;
+    opacity: 1;
+    padding: 0 0 0 15px;
+  }
+
+  .profile__avatar-btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 40px;
+    height: 40px;
+    visibility: hidden;
+    border-radius: 6px;
+    padding: 6px;
+    gap: 8px;
+    top: 52px;
+    left: 52px;
+    right: 4px;
+    bottom: 4px;
+    width: auto;
+    height: auto;
+  }
+
+  .profile__avatar-btn:hover {
+    visibility: visible;
+  }
+
+  .profile__avatar-btn::after {
+    content: "";
+  }
+
   .profile__title {
     font-size: 20px;
     margin: 0 0 6px;
diff --git a/src/images/pensil-wht.svg b/src/images/pensil-wht.svg
new file mode 100644
index 0000000..874c3b8
--- /dev/null
+++ b/src/images/pensil-wht.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="13.0679" y="4.87506" width="11.6506" height="3.21396" transform="rotate(135 13.0679 4.87506)" fill="white"/>
+<path d="M14.204 1.4662C14.8316 2.09377 14.8316 3.11125 14.204 3.73881L13.6359 4.30697L11.3633 2.03436L11.9314 1.4662C12.559 0.83864 13.5765 0.83864 14.204 1.4662Z" fill="white"/>
+<path d="M1.54045 13.4837L2.55698 10.8408L4.82959 13.1134L2.18661 14.1299C1.78224 14.2854 1.38492 13.8881 1.54045 13.4837Z" fill="white"/>
+</svg>
diff --git a/src/images/x-wht.svg b/src/images/x-wht.svg
new file mode 100644
index 0000000..02e29f2
--- /dev/null
+++ b/src/images/x-wht.svg
@@ -0,0 +1,4 @@
+<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.48535 24.4854L24.4854 8.48535" stroke="white" stroke-width="2" stroke-linecap="round"/>
+<path d="M24.4854 24.4854L8.48535 8.48535" stroke="white" stroke-width="2" stroke-linecap="round"/>
+</svg>
diff --git a/src/index.html b/src/index.html
index ad6e812..7894fbc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -15,7 +15,12 @@
       </header>
       <main class="content">
         <section class="profile page__section">
-          <img class="profile__avatar" alt="Picture of Bessie Coleman" />
+          <div class="profile__avatar-container">
+            <button class="profile__avatar-btn">
+              <img class="profile__pencil-icon" alt="Edit Pencil Icon" />
+            </button>
+            <img class="profile__avatar" alt="Picture of Bessie Coleman" />
+          </div>
           <div class="profile__column">
             <h1 class="profile__title">Bessie Coleman</h1>
             <p class="profile__description">Civil Aviator</p>
@@ -147,5 +152,57 @@ <h2 class="modal__title">New post</h2>
         <p class="modal__caption"></p>
       </div>
     </div>
+
+    <div class="modal" id="avatar-modal">
+      <div class="modal__container">
+        <button
+          type="button"
+          class="modal__close-button"
+          aria-label="Close form"
+        ></button>
+        <h2 class="modal__title">Edit profile avatar</h2>
+        <form name="edit-avatar-form" class="modal__form" novalidate>
+          <label for="profile-avatar-input" class="modal__label">
+            Profile picture
+            <input
+              type="url"
+              id="profile-avatar-input"
+              class="modal__input"
+              placeholder="Upload Your Avatar"
+              name="avatar"
+              required
+            />
+            <span id="profile-avatar-input-error" class="modal__error"></span>
+          </label>
+          <button type="submit" class="modal__submit-button">Save</button>
+        </form>
+      </div>
+    </div>
+
+    <div class="modal" id="delete-modal">
+      <button
+        type="button"
+        class="modal__close-button modal__close-button_delete_card"
+        aria-label="Close form"
+      ></button>
+      <div class="modal__container modal__container_delete_card">
+        <h2 class="modal__title modal__title_delete_card">
+          Are you sure you want to delete this image?
+        </h2>
+        <form
+          id="delete-form"
+          class="modal__form modal__form_delete_card"
+          novalidate
+        >
+          <button
+            type="submit"
+            class="modal__submit-button modal__submit-button_delete_card"
+          >
+            Delete
+          </button>
+          <button type="button" class="modal__cancel-button">Cancel</button>
+        </form>
+      </div>
+    </div>
   </body>
 </html>
diff --git a/src/index.js b/src/index.js
index 0977a4e..cc6e88d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,46 +4,60 @@ import "./vendor/normalize.css";
 import "./vendor/fonts.css";
 import logo from "./images/logo.svg";
 import avatar from "./images/avatar.jpg";
+import pencilIcon from "./images/pensil-wht.svg";
 import {
   resetValidation,
   disableButton,
   settings,
 } from "./scripts/validation.js";
+import { setButtonText } from "./utils/helpers.js";
+import Api from "./utils/Api.js";
 
 document.querySelector(".header__logo").src = logo;
 document.querySelector(".profile__avatar").src = avatar;
+document.querySelector(".profile__pencil-icon").src = pencilIcon;
 
-const initialCards = [
-  {
-    name: "New York Library",
-    link: "https://images.unsplash.com/photo-1737923336697-621a80820522?q=80&w=2862&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
-  },
-  {
-    name: "A Beach in the Phillipines",
-    link: "https://images.unsplash.com/photo-1586768798120-95597acaa6e3?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
-  },
-  {
-    name: "A Landscape In Canada",
-    link: "https://images.unsplash.com/photo-1738936339590-ea1fc8bd9732?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
-  },
-  {
-    name: "Pfeiffer Beach",
-    link: "https://images.unsplash.com/photo-1739057736231-3577bfc1a1b9?q=80&w=2825&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
-  },
-  {
-    name: "Idyllic Alpine Waterscape",
-    link: "https://images.unsplash.com/photo-1738599778390-af77d7cf10e6?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
-  },
-  {
-    name: "Oia sunset in Santorini, Greece",
-    link: "https://images.unsplash.com/photo-1569581464548-66d245ae5ca5?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+// const initialCards = [
+//   {
+//     name: "New York Library",
+//     link: "https://images.unsplash.com/photo-1737923336697-621a80820522?q=80&w=2862&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+//   {
+//     name: "A Beach in the Phillipines",
+//     link: "https://images.unsplash.com/photo-1586768798120-95597acaa6e3?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+//   {
+//     name: "A Landscape In Canada",
+//     link: "https://images.unsplash.com/photo-1738936339590-ea1fc8bd9732?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+//   {
+//     name: "Pfeiffer Beach",
+//     link: "https://images.unsplash.com/photo-1739057736231-3577bfc1a1b9?q=80&w=2825&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+//   {
+//     name: "Idyllic Alpine Waterscape",
+//     link: "https://images.unsplash.com/photo-1738599778390-af77d7cf10e6?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+//   {
+//     name: "Oia sunset in Santorini, Greece",
+//     link: "https://images.unsplash.com/photo-1569581464548-66d245ae5ca5?q=80&w=2787&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+//   },
+// ];
+
+const api = new Api({
+  baseUrl: "https://around-api.en.tripleten-services.com/v1",
+  headers: {
+    authorization: "3afa45a9-62de-49c7-b3d5-fa0d981aed53",
+    "Content-Type": "application/json",
   },
-];
+});
 
 document.addEventListener("DOMContentLoaded", function () {
   //Profile elements
   const profileEditButton = document.querySelector(".profile__edit-button");
   const profileAddButton = document.querySelector(".profile__add-button");
+
+  const avatarModalButton = document.querySelector(".profile__avatar-btn");
   const profileName = document.querySelector(".profile__title");
   const profileDescription = document.querySelector(".profile__description");
 
@@ -71,10 +85,64 @@ document.addEventListener("DOMContentLoaded", function () {
   const previewModalImage = previewModal.querySelector(".modal__image");
   const previewModalCaption = previewModal.querySelector(".modal__caption");
 
+  //Avatar modal elements
+  const avatarModal = document.querySelector("#avatar-modal");
+  const avatarFormElement = avatarModal.querySelector(".modal__form");
+  const avatarLinkInput = avatarModal.querySelector("#profile-avatar-input");
+
+  //Delete modal elements
+  const deleteModal = document.querySelector("#delete-modal");
+  const deleteForm = deleteModal.querySelector(".modal__form");
+
+  const cancelButton = deleteModal?.querySelector(".modal__cancel-button");
+  if (cancelButton) {
+    cancelButton.addEventListener("click", () => closeModal(deleteModal));
+  }
+
   //Card related elements
   const cardTemplate = document.querySelector("#card-template");
   const cardsList = document.querySelector(".cards__list");
 
+  let selectedCard;
+  let selectedCardId;
+
+  api
+    .getAppInfo()
+    .then(([cards, userInfo]) => {
+      api.userId = userInfo._id;
+
+      profileName.textContent = userInfo.name;
+      profileDescription.textContent = userInfo.about;
+
+      document.querySelector(".profile__avatar").src = userInfo.avatar;
+      cards.reverse().forEach((card) => {
+        const cardElement = getCardElement(card);
+        cardsList.prepend(cardElement);
+      });
+    })
+    .catch((err) => {
+      console.error(err);
+    });
+
+  function handleLike(evt, id) {
+    const cardLikeButton = evt.currentTarget;
+    const isLiked = cardLikeButton.classList.contains(
+      "card__like-button_liked"
+    );
+    api
+      .changeLikeStatus(id, isLiked)
+      .then((updatedCard) => {
+        if (updatedCard.isLiked === true) {
+          cardLikeButton.classList.add("card__like-button_liked");
+        } else {
+          cardLikeButton.classList.remove("card__like-button_liked");
+        }
+      })
+      .catch((err) => {
+        console.error("Error toggling like status:", err);
+      });
+  }
+
   function getCardElement(data) {
     const cardElement = cardTemplate.content
       .querySelector(".card")
@@ -85,13 +153,17 @@ document.addEventListener("DOMContentLoaded", function () {
     const cardLikeButton = cardElement.querySelector(".card__like-button");
     const cardDeleteButton = cardElement.querySelector(".card__delete-button");
 
+    if (data.isLiked === true) {
+      cardLikeButton.classList.add("card__like-button_liked");
+    }
+
     cardNameElement.textContent = data.name;
     cardImage.src = data.link;
     cardImage.alt = `Image of ${data.name}`;
 
-    cardLikeButton.addEventListener("click", () => {
-      cardLikeButton.classList.toggle("card__like-button_liked");
-    });
+    cardLikeButton.addEventListener("click", (evt) =>
+      handleLike(evt, data._id)
+    );
 
     cardImage.addEventListener("click", () => {
       openModal(previewModal);
@@ -101,16 +173,12 @@ document.addEventListener("DOMContentLoaded", function () {
     });
 
     cardDeleteButton.addEventListener("click", () => {
-      deleteCard(cardElement);
+      handleDeleteCard(cardElement, data._id);
     });
 
     return cardElement;
   }
 
-  function deleteCard(card) {
-    card.remove();
-  }
-
   function openModal(modal) {
     modal.classList.add("modal_opened");
     document.addEventListener("keydown", closeOnEscape);
@@ -140,23 +208,96 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+
+    api
+      .editUserInfo({
+        name: modalProfileName.value,
+        about: modalProfileDescription.value,
+      })
+      .then((data) => {
+        profileName.textContent = data.name;
+        profileDescription.textContent = data.about;
+        closeModal(editProfileModal);
+      })
+      .catch(console.error)
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleDeleteCard(cardElement, cardId) {
+    selectedCard = cardElement;
+    selectedCardId = cardId;
+    openModal(deleteModal);
+  }
+
+  function handleDeleteSubmit(evt) {
+    evt.preventDefault();
+
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true, "Deleting...", "Delete");
+    api
+      .deleteCard(selectedCardId)
+      .then(() => {
+        selectedCard.remove();
+        closeModal(deleteModal);
+      })
+      .catch((err) => {
+        console.error(err);
+      })
+      .finally(() => {
+        setButtonText(submitBtn, false, "Deleting...", "Delete");
+      });
   }
 
   function handleCardFormSubmit(evt) {
     evt.preventDefault();
-    const inputValues = {
-      name: cardCaptionInput.value,
-      link: cardLinkInput.value,
-    };
-    const cardElement = getCardElement(inputValues);
-    cardsList.prepend(cardElement);
-
-    cardFormElement.reset();
-    disableButton(cardSubmitButton, settings);
-    closeModal(cardModal);
+
+    const name = cardCaptionInput.value;
+    const link = cardLinkInput.value;
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+    api
+      .addNewCard({ name, link })
+      .then((cardData) => {
+        if (cardData.isLiked === undefined) {
+          cardData.isLiked = false;
+        }
+        const newCardElement = getCardElement(cardData);
+        cardsList.prepend(newCardElement);
+
+        cardFormElement.reset();
+        disableButton(cardSubmitButton, settings);
+        closeModal(cardModal);
+      })
+      .catch((err) => {
+        console.error("Error adding new card;", err);
+      })
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleAvatarSubmit(evt) {
+    evt.preventDefault();
+    const avatar = avatarLinkInput.value;
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+    api
+      .editAvatarInfo(avatar)
+      .then((data) => {
+        document.querySelector(".profile__avatar").src = data.avatar;
+        avatarFormElement.reset();
+        disableButton(submitBtn, settings);
+        closeModal(avatarModal);
+      })
+      .catch(console.error)
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
   }
 
   profileEditButton.addEventListener("click", () => {
@@ -174,6 +315,11 @@ document.addEventListener("DOMContentLoaded", function () {
     openModal(cardModal);
   });
 
+  avatarModalButton.addEventListener("click", () => {
+    openModal(avatarModal);
+  });
+  avatarFormElement.addEventListener("submit", handleAvatarSubmit);
+
   closeButtons.forEach((button) => {
     const popup = button.closest(".modal");
     button.addEventListener("click", () => closeModal(popup));
@@ -182,8 +328,5 @@ document.addEventListener("DOMContentLoaded", function () {
   profileForm.addEventListener("submit", handleModalFormSubmit);
   cardFormElement.addEventListener("submit", handleCardFormSubmit);
 
-  initialCards.forEach((card) => {
-    const cardElement = getCardElement(card);
-    cardsList.prepend(cardElement);
-  });
+  deleteForm.addEventListener("submit", handleDeleteSubmit);
 });
diff --git a/src/utils/Api.js b/src/utils/Api.js
new file mode 100644
index 0000000..096c7d7
--- /dev/null
+++ b/src/utils/Api.js
@@ -0,0 +1,73 @@
+class Api {
+  constructor({ baseUrl, headers }) {
+    this._baseUrl = baseUrl;
+    this._headers = headers;
+  }
+
+  _checkResponse(res) {
+    return res.ok ? res.json() : Promise.reject(`Error: ${res.status}`);
+  }
+  getAppInfo() {
+    return Promise.all([this.getInitialCards(), this.getUserInfo()]);
+  }
+
+  getUserInfo() {
+    return fetch(`${this._baseUrl}/users/me`, {
+      headers: this._headers,
+    }).then(this._checkResponse);
+  }
+
+  getInitialCards() {
+    return fetch(`${this._baseUrl}/cards`, {
+      headers: this._headers,
+    }).then(this._checkResponse);
+  }
+
+  addNewCard({ name, link }) {
+    return fetch(`${this._baseUrl}/cards`, {
+      method: "POST",
+      headers: this._headers,
+      body: JSON.stringify({
+        name,
+        link,
+      }),
+    }).then(this._checkResponse);
+  }
+
+  editUserInfo({ name, about }) {
+    return fetch(`${this._baseUrl}/users/me`, {
+      method: "PATCH",
+      headers: this._headers,
+      body: JSON.stringify({
+        name,
+        about,
+      }),
+    }).then(this._checkResponse);
+  }
+
+  editAvatarInfo(avatar) {
+    return fetch(`${this._baseUrl}/users/me/avatar`, {
+      method: "PATCH",
+      headers: this._headers,
+      body: JSON.stringify({
+        avatar,
+      }),
+    }).then(this._checkResponse);
+  }
+
+  deleteCard(id) {
+    return fetch(`${this._baseUrl}/cards/${id}`, {
+      method: "DELETE",
+      headers: this._headers,
+    }).then(this._checkResponse);
+  }
+
+  changeLikeStatus(id, isLiked) {
+    return fetch(`${this._baseUrl}/cards/${id}/likes`, {
+      method: isLiked ? "DELETE" : "PUT",
+      headers: this._headers,
+    }).then(this._checkResponse);
+  }
+}
+
+export default Api;
diff --git a/src/utils/helpers.js b/src/utils/helpers.js
new file mode 100644
index 0000000..8281277
--- /dev/null
+++ b/src/utils/helpers.js
@@ -0,0 +1,12 @@
+export function setButtonText(
+  btn,
+  isLoading,
+  loadingText = "Saving...",
+  defaultText = "Save"
+) {
+  if (isLoading) {
+    btn.textContent = loadingText;
+  } else {
+    btn.textContent = defaultText;
+  }
+}
diff --git a/webpack.config.js b/webpack.config.js
index de9df51..ec6aeb2 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -30,7 +30,7 @@ module.exports = {
       {
         test: /\.js$/,
         loader: "babel-loader",
-        exclude: /node_modules/,
+        exclude: "/node_modules/",
       },
       {
         test: /\.css$/,
@@ -39,15 +39,14 @@ module.exports = {
           {
             loader: "css-loader",
             options: {
-              // Add an options object
               importLoaders: 1,
             },
           },
-          "postcss-loader", // Add the postcss loader
+          "postcss-loader",
         ],
       },
       {
-        test: /\.(png|svg|jpg|jpeg|gif|woff(2)?|eot|ttf|otf)$/,
+        test: /\.(png|svg|jpg|jpeg|webp|gif|woff(2)?|eot|ttf|otf)$/,
         type: "asset/resource",
       },
     ],
@@ -55,10 +54,6 @@ module.exports = {
   plugins: [
     new HtmlWebpackPlugin({
       template: "./src/index.html",
-      favicon: "./src/favicon.ico",
-    }),
-    new CopyWebpackPlugin({
-      patterns: [{ from: "src/favicon.ico", to: "favicon.ico" }],
     }),
     new CleanWebpackPlugin(),
     new MiniCssExtractPlugin(),


Reviews:
user: login: sebasLTripleTen
body: **↓ Please, expand the general comment ↓**

Dear Farida,

Unfortunately, I am unable to complete the review at this time because **some part** of the task **hasn't been implemented**:

- The `webpack.config.js` file contains errors.
- The `Api` class is incomplete, methods for creating, deleting, liking, and unliking cards are missing.
- You need to upload the link to the pull request, not the repository.

If you need any assistance in the meantime, our dedicated tutors are available to support you. Please don’t hesitate to reach out to them for guidance.

If your code is correct locally on your computer, then check if you have **pushed** all the changes to github. I can see those changes only if they are in your branch

state: CHANGES_REQUESTED
author_association: NONE
submitted_at: 2025-05-22T21:18:52Z
user: login: gennady-bars
body: (**Please, expand the general comment ↓**)

Dear Farida, 

Unfortunately, I am unable to complete the review at this time because **some part** of the task **hasn't been implemented**:

* There is an error in the console https://snipboard.io/LEYx9z.jpg 
* Some remarks haven't been corrected, starting from here https://github.com/FaridaNelson/se_project_spots/pull/1#discussion_r2103391159 
* Likes don't work
* All my new cards disappear when I reload the page. Please, send them correctly to the server


If you need any assistance in the meantime, our dedicated tutors are available to support you. Please don’t hesitate to reach out to them for guidance.

If your code is correct locally on your computer, then check if you have **pushed** all the changes to `github`. I can see those changes only if they are in your branch


state: COMMENTED
author_association: NONE
submitted_at: 2025-05-27T13:57:31Z
user: login: sebasLTripleTen
body: Hello, Farida!

Thank you for submitting your project. It's clear that a lot of work has been put into this project.

**Parts I really liked in your project:**

- Well-structured and clean code
- The code for closing the modal windows is executed in the right place
- You've created the class instance and used their methods correctly
- All required classes and methods are implemented
- Good job catching possible errors at the end of server requests.

There are few things that need to be corrected in your project. They're mostly minor issues that are easy to fix.

- All comments left in the code, along with the ones below:
  - According to the task, you need to change the text of the submit button (`Saving…` or `Deleting...`) while waiting for the server response. The user should see it.
  - The code that checks the server response should be refactored to avoid repetition.
  - After submitting the Avatar form you need to reset it and disable the submit button.
  - Inputs meant to receive links should have their `type` attribute set to `url` to enable proper validation.

There are also some comments for improvement marked as **"Could be improved"**. They don’t mean that you’ve done anything wrong, but they’re things we wanted to point out that can help you further develop your skills.

**Reminder:** For the project to be accepted, you must fix all **"Needs correcting"** comments. **"Could be improved"** comments are optional, so you can implement them if you choose.

It's fantastic to see how far you've come with this project. Even though there are areas for improvement, your hard work and dedication are evident. Remember that each step forward is progress. If you need help with any part of the feedback, our tutors are available to support you. Keep pushing forward and continue your impressive journey!
state: CHANGES_REQUESTED
author_association: NONE
submitted_at: 2025-05-27T21:57:13Z
user: login: ernesto-av-triple-ten
body: Hi Farida Nelson, 

You've made a lot of progress!

Let's make these small improvements to strengthen your project even more:

- Please, use the `setButtonText()` consistently
- Let's reset the appropriate form when submitting the avatar form 
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-29T21:36:34Z

Review comments:
diff_hunk: @@ -0,0 +1,53 @@
+class Api {
+  constructor({ baseUrl, headers }) {
+    this._baseUrl = baseUrl;
+    this._headers = headers;
+  }
+
+  getAppInfo() {
+    return Promise.all([this.getInitialCards(), this.getUserInfo()]);
+  }
+
+  getInitialCards() {
+    return fetch(`${this._baseUrl}/cards`, {
+      headers: this._headers,
+    }).then((res) =>
path: src/utils/Api.js
user: login: sebasLTripleTen
body: To **avoid repeating response-checking logic** across multiple API requests, you can define a reusable method called `_checkResponse`. This method should handle checking whether the server response is successful (`res.ok`) and process or reject it accordingly:

```js
_checkResponse(res) {
   return res.ok ? res.json() : Promise.reject(`Error: ${res.status}`);
}
```

Once defined, you can simplify your API calls by using:

```js
.then(this._checkResponse)
```

Note: Make sure to pass a reference to the method (i.e., without parentheses), not the result of calling it. This ensures that the function is only executed when the .then() block is triggered.

created_at: 2025-05-22T20:59:43Z
author_association: NONE
diff_hunk: @@ -0,0 +1,53 @@
+class Api {
+  constructor({ baseUrl, headers }) {
+    this._baseUrl = baseUrl;
+    this._headers = headers;
+  }
+
+  getAppInfo() {
+    return Promise.all([this.getInitialCards(), this.getUserInfo()]);
+  }
+
+  getInitialCards() {
+    return fetch(`${this._baseUrl}/cards`, {
+      headers: this._headers,
+    }).then((res) =>
+      res.ok ? res.json() : Promise.reject(`Error: ${res.status}`)
+    );
+  }
+
path: src/utils/Api.js
user: login: sebasLTripleTen
body: **COULD BE IMPROVED**

To avoid repeating the same fetch-and-check pattern in every request, consider creating a dedicated method that handles both fetching and response checking:

```js
_request(url, options) {
  return fetch(url, options).then(this._checkResponse);
}
```

You can then replace direct fetch calls with this._request(...) throughout your class. This keeps your code cleaner and easier to maintain.

created_at: 2025-05-22T20:59:59Z
author_association: NONE
path: webpack.config.js
user: login: sebasLTripleTen
body: This file contains errors that prevent the project from running. Please update it as follows:

```js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "main.js",
    publicPath: "",
  },

  mode: "development",
  devtool: "inline-source-map",
  stats: "errors-only",
  devServer: {
    static: path.resolve(__dirname, "./dist"),
    compress: true,
    port: 8080,
    open: true,
    liveReload: true,
    hot: false,
  },
  target: ["web", "es5"],
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: "/node_modules/",
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
            },
          },
          "postcss-loader",
        ],
      },
      {
        test: /\.(png|svg|jpg|jpeg|webp|gif|woff(2)?|eot|ttf|otf)$/,
        type: "asset/resource",
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin(),
  ],
};
```

You can see the full list of configuration files here: https://tripleten.com/trainer/web/lesson/738717e1-c8e0-4c9f-9089-a87edb616a21/?from=program
created_at: 2025-05-22T21:14:18Z
author_association: NONE
diff_hunk: @@ -0,0 +1,53 @@
+class Api {
path: src/utils/Api.js
user: login: sebasLTripleTen
body: The Api class is incomplete—methods for creating, deleting, liking, and unliking cards are missing.
created_at: 2025-05-22T21:16:05Z
author_association: NONE
diff_hunk: @@ -147,5 +152,56 @@ <h2 class="modal__title">New post</h2>
         <p class="modal__caption"></p>
       </div>
     </div>
+
+    <div class="modal" id="avatar-modal">
+      <div class="modal__container">
+        <button
+          type="button"
+          class="modal__close-button"
+          aria-label="Close form"
+        ></button>
+        <h2 class="modal__title">Edit profile avatar</h2>
+        <form name="edit-avatar-form" class="modal__form" novalidate>
+          <label for="profile-avatar-input" class="modal__label">
+            Profile picture
+            <input
path: src/index.html
user: login: sebasLTripleTen
body: Since this input is meant to receive image links, you should set its `type` attribute to `url` to enable proper validation.
created_at: 2025-05-27T21:24:02Z
author_association: NONE
diff_hunk: @@ -4,8 +4,45 @@
   border-bottom: 1px rgba(33, 33, 33, 0.4) solid;
 }
 
-.profile__avatar {
+.profile__avatar-container {
+  position: relative;
   margin-right: 20px;
+}
+
+.profile__avatar-btn {
+  position: absolute;
+  width: 190px;
+  height: 190px;
+  display: flex;
+  align-items: flex-end;
+  justify-content: center;
+  visibility: hidden;
+  padding: 0;
+  border: none;
+}
+
+.profile__avatar-container:hover .profile__avatar-btn {
path: src/blocks/profile.css
user: login: sebasLTripleTen
body: Since this is an interactive element, you should add cursor: pointer to visually indicate that it's clickable.
created_at: 2025-05-27T21:26:48Z
author_association: NONE
diff_hunk: @@ -66,15 +78,75 @@ document.addEventListener("DOMContentLoaded", function () {
   const cardSubmitButton = cardModal.querySelector(".modal__submit-button");
   const cardLinkInput = cardModal.querySelector("#add-card-link-input");
   const cardCaptionInput = cardModal.querySelector("#add-card-caption-input");
+  const cardLikeButton = document.querySelector(".card__like-button");
 
   const previewModal = document.querySelector("#preview-modal");
   const previewModalImage = previewModal.querySelector(".modal__image");
   const previewModalCaption = previewModal.querySelector(".modal__caption");
 
+  //Avatar modal elements
+  const avatarModal = document.querySelector("#avatar-modal");
+  const avatarFormElement = avatarModal.querySelector(".modal__form");
+  const avatarSubmitButton = avatarModal.querySelector(".modal__submit-button");
+  const avatarLinkInput = avatarModal.querySelector("#profile-avatar-input");
+
+  //Delete modal elements
+  const deleteModal = document.querySelector("#delete-modal");
+  const deleteForm = deleteModal.querySelector(".modal__form");
+
+  const cancelButton = deleteModal?.querySelector(".modal__cancel-button");
+  if (cancelButton) {
+    cancelButton.addEventListener("click", () => closeModal(deleteModal));
+  }
+
   //Card related elements
   const cardTemplate = document.querySelector("#card-template");
   const cardsList = document.querySelector(".cards__list");
 
+  let selectedCard;
+  let selectedCardId;
+
+  api
+    .getAppInfo()
+    .then(([cards, userInfo]) => {
+      api.userId = userInfo._id;
+
+      profileName.textContent = userInfo.name;
+      profileDescription.textContent = userInfo.about;
+
+      document.querySelector(".profile__avatar").src = userInfo.avatar;
+      cards.reverse().forEach((card) => {
+        const cardElement = getCardElement(card);
+        cardsList.prepend(cardElement);
+      });
+    })
+    .catch((err) => {
+      console.error(err);
+    });
+
+  function handleLike(evt, id) {
+    const cardLikeButton = evt.currentTarget;
+    const isLiked = cardLikeButton.classList.contains(
+      "card__like-button_liked"
+    );
+    api
+      .changeLikeStatus(id, isLiked)
+      .then((updatedCard) => {
+        console.log("API response:", updatedCard);
+
+        if (updatedCard.isLiked === true) {
+          cardLikeButton.classList.add("card__like-button_liked");
+        } else {
+          cardLikeButton.classList.remove("card__like-button_liked");
+        }
+        console.log("Button class list:", cardLikeButton.classList);
path: src/index.js
user: login: sebasLTripleTen
body: **COULD BE IMPROVED**

`console.log()` calls should be removed to keep your code clean.
created_at: 2025-05-27T21:33:48Z
author_association: NONE
diff_hunk: @@ -140,23 +212,72 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+    api
path: src/index.js
user: login: sebasLTripleTen
body: According to the task requirements, the submit button text should update while waiting for the server response. You should change the text when the request starts, and then revert it to the default inside a `finally` block.

- For the delete confirmation modal, change the button text to `"Deleting..."`
- For the other forms, change it to `"Saving..."`

This provides a better user experience by indicating that an action is in progress.
created_at: 2025-05-27T21:42:43Z
author_association: NONE
diff_hunk: @@ -140,23 +212,72 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+    api
+      .editUserInfo({
+        name: modalProfileName.value,
+        about: modalProfileDescription.value,
+      })
+      .then((data) => {
+        profileName.textContent = data.name;
+        profileDescription.textContent = data.about;
+        closeModal(editProfileModal);
+      })
+      .catch(console.error);
+  }
+
+  function handleDeleteCard(cardElement, cardId) {
+    selectedCard = cardElement;
+    selectedCardId = cardId;
+    openModal(deleteModal);
+  }
+
+  function handleDeleteSubmit(evt) {
+    evt.preventDefault();
+    api
+      .deleteCard(selectedCardId)
+      .then(() => {
+        selectedCard.remove();
+        closeModal(deleteModal);
+      })
+      .catch((err) => {
+        console.error(err);
+      });
   }
 
   function handleCardFormSubmit(evt) {
     evt.preventDefault();
-    const inputValues = {
-      name: cardCaptionInput.value,
-      link: cardLinkInput.value,
-    };
-    const cardElement = getCardElement(inputValues);
-    cardsList.prepend(cardElement);
-
-    cardFormElement.reset();
-    disableButton(cardSubmitButton, settings);
-    closeModal(cardModal);
+
+    const name = cardCaptionInput.value;
+    const link = cardLinkInput.value;
+
+    api
+      .addNewCard({ name, link })
+      .then((cardData) => {
+        if (cardData.isLiked === undefined) {
+          cardData.isLiked = false;
+        }
+        const newCardElement = getCardElement(cardData);
+        cardsList.prepend(newCardElement);
+
+        cardFormElement.reset();
+        disableButton(cardSubmitButton, settings);
+        closeModal(cardModal);
+      })
+      .catch((err) => {
+        console.error("Error adding new card;", err);
+      });
+  }
+
+  function handleAvatarSubmit(evt) {
+    evt.preventDefault();
+    const avatar = avatarLinkInput.value;
+    api
+      .editAvatarInfo(avatar)
+      .then((data) => {
path: src/index.js
user: login: sebasLTripleTen
body: After submitting the form, you need to reset it and disable the submit button.
created_at: 2025-05-27T21:46:24Z
author_association: NONE
diff_hunk: @@ -0,0 +1,53 @@
+class Api {
+  constructor({ baseUrl, headers }) {
+    this._baseUrl = baseUrl;
+    this._headers = headers;
+  }
+
+  getAppInfo() {
+    return Promise.all([this.getInitialCards(), this.getUserInfo()]);
+  }
+
+  getInitialCards() {
+    return fetch(`${this._baseUrl}/cards`, {
+      headers: this._headers,
+    }).then((res) =>
path: src/utils/Api.js
user: login: sebasLTripleTen
body: **This correction hasn't been implemented**

> To **avoid repeating response-checking logic** across multiple API requests, you can define a reusable method called `_checkResponse`. This method should handle checking whether the server response is successful (`res.ok`) and process or reject it accordingly:
> 
> ```js
> _checkResponse(res) {
>    return res.ok ? res.json() : Promise.reject(`Error: ${res.status}`);
> }
> ```
> 
> Once defined, you can simplify your API calls by using:
> 
> ```js
> .then(this._checkResponse)
> ```
> 
> Note: Make sure to pass a reference to the method (i.e., without parentheses), not the result of calling it. This ensures that the function is only executed when the .then() block is triggered.


created_at: 2025-05-27T21:49:40Z
author_association: NONE
diff_hunk: @@ -140,23 +210,96 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+
+    api
+      .editUserInfo({
+        name: modalProfileName.value,
+        about: modalProfileDescription.value,
+      })
+      .then((data) => {
+        profileName.textContent = data.name;
+        profileDescription.textContent = data.about;
+        closeModal(editProfileModal);
+      })
+      .catch(console.error)
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleDeleteCard(cardElement, cardId) {
+    selectedCard = cardElement;
+    selectedCardId = cardId;
+    openModal(deleteModal);
+  }
+
+  function handleDeleteSubmit(evt) {
+    evt.preventDefault();
+
+    const submitBtn = evt.submitter;
+    submitBtn.textContent = "Deleting...";
+    api
+      .deleteCard(selectedCardId)
+      .then(() => {
+        selectedCard.remove();
+        closeModal(deleteModal);
+      })
+      .catch((err) => {
+        console.error(err);
+      })
+      .finally(() => {
+        submitBtn.textContent = "Delete";
+      });
   }
 
   function handleCardFormSubmit(evt) {
     evt.preventDefault();
-    const inputValues = {
-      name: cardCaptionInput.value,
-      link: cardLinkInput.value,
-    };
-    const cardElement = getCardElement(inputValues);
-    cardsList.prepend(cardElement);
-
-    cardFormElement.reset();
-    disableButton(cardSubmitButton, settings);
-    closeModal(cardModal);
+
+    const name = cardCaptionInput.value;
+    const link = cardLinkInput.value;
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+    api
+      .addNewCard({ name, link })
+      .then((cardData) => {
+        if (cardData.isLiked === undefined) {
+          cardData.isLiked = false;
+        }
+        const newCardElement = getCardElement(cardData);
+        cardsList.prepend(newCardElement);
+
+        cardFormElement.reset();
+        disableButton(cardSubmitButton, settings);
+        closeModal(cardModal);
+      })
+      .catch((err) => {
+        console.error("Error adding new card;", err);
+      })
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleAvatarSubmit(evt) {
+    evt.preventDefault();
+    const avatar = avatarLinkInput.value;
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+    api
+      .editAvatarInfo(avatar)
+      .then((data) => {
+        document.querySelector(".profile__avatar").src = data.avatar;
+        cardFormElement.reset();
path: src/index.js
user: login: ernesto-av-triple-ten
body: Here you are resetting the wrong form. You should reset `avatarFormElement` instead
created_at: 2025-05-29T21:26:52Z
author_association: NONE
diff_hunk: @@ -140,23 +210,96 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+
+    api
+      .editUserInfo({
+        name: modalProfileName.value,
+        about: modalProfileDescription.value,
+      })
+      .then((data) => {
+        profileName.textContent = data.name;
+        profileDescription.textContent = data.about;
+        closeModal(editProfileModal);
+      })
+      .catch(console.error)
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleDeleteCard(cardElement, cardId) {
+    selectedCard = cardElement;
+    selectedCardId = cardId;
+    openModal(deleteModal);
+  }
+
+  function handleDeleteSubmit(evt) {
+    evt.preventDefault();
+
+    const submitBtn = evt.submitter;
+    submitBtn.textContent = "Deleting...";
path: src/index.js
user: login: ernesto-av-triple-ten
body: Please,  use the `setButtonText()` function to have a consistent way of modifying the button's text. Let's do it here at the start of the form submission and in the `.finally()` block:

```javascript
setButtonText(submitBtn, true, "Deleting...", "Delete");
```
created_at: 2025-05-29T21:30:25Z
author_association: NONE
diff_hunk: @@ -140,23 +210,96 @@ document.addEventListener("DOMContentLoaded", function () {
 
   function handleModalFormSubmit(evt) {
     evt.preventDefault();
-    profileName.textContent = modalProfileName.value;
-    profileDescription.textContent = modalProfileDescription.value;
-    closeModal(editProfileModal);
+
+    const submitBtn = evt.submitter;
+    setButtonText(submitBtn, true);
+
+    api
+      .editUserInfo({
+        name: modalProfileName.value,
+        about: modalProfileDescription.value,
+      })
+      .then((data) => {
+        profileName.textContent = data.name;
+        profileDescription.textContent = data.about;
+        closeModal(editProfileModal);
+      })
+      .catch(console.error)
+      .finally(() => {
+        setButtonText(submitBtn, false);
+      });
+  }
+
+  function handleDeleteCard(cardElement, cardId) {
+    selectedCard = cardElement;
+    selectedCardId = cardId;
+    openModal(deleteModal);
+  }
+
+  function handleDeleteSubmit(evt) {
+    evt.preventDefault();
+
+    const submitBtn = evt.submitter;
+    submitBtn.textContent = "Deleting...";
+    api
+      .deleteCard(selectedCardId)
+      .then(() => {
+        selectedCard.remove();
+        closeModal(deleteModal);
+      })
+      .catch((err) => {
+        console.error(err);
+      })
+      .finally(() => {
+        submitBtn.textContent = "Delete";
path: src/index.js
user: login: ernesto-av-triple-ten
body: Let's also use the helper function here:

```javascript
setButtonText(submitBtn, false, "Deleting...", "Delete");
```
created_at: 2025-05-29T21:32:18Z
author_association: NONE
diff_hunk: @@ -66,15 +80,71 @@ document.addEventListener("DOMContentLoaded", function () {
   const cardSubmitButton = cardModal.querySelector(".modal__submit-button");
   const cardLinkInput = cardModal.querySelector("#add-card-link-input");
   const cardCaptionInput = cardModal.querySelector("#add-card-caption-input");
+  const cardLikeButton = document.querySelector(".card__like-button");
path: src/index.js
user: login: ernesto-av-triple-ten
body: **COULD BE IMPROVED**

You should remove the unused variables
created_at: 2025-05-29T21:33:35Z
author_association: NONE
diff_hunk: @@ -66,15 +80,71 @@ document.addEventListener("DOMContentLoaded", function () {
   const cardSubmitButton = cardModal.querySelector(".modal__submit-button");
   const cardLinkInput = cardModal.querySelector("#add-card-link-input");
   const cardCaptionInput = cardModal.querySelector("#add-card-caption-input");
+  const cardLikeButton = document.querySelector(".card__like-button");
 
   const previewModal = document.querySelector("#preview-modal");
   const previewModalImage = previewModal.querySelector(".modal__image");
   const previewModalCaption = previewModal.querySelector(".modal__caption");
 
+  //Avatar modal elements
+  const avatarModal = document.querySelector("#avatar-modal");
+  const avatarFormElement = avatarModal.querySelector(".modal__form");
+  const avatarSubmitButton = avatarModal.querySelector(".modal__submit-button");
path: src/index.js
user: login: ernesto-av-triple-ten
body: **COULD BE IMPROVED**

You should remove the unused variables
created_at: 2025-05-29T21:33:54Z
author_association: NONE

PR comments:
user: login: FaridaNelson
created_at: 2025-05-26T21:29:27Z
body: Hi, Sebastian!

thank you very much for your review. Please, check out the new additions I've added to the branch project-9. I'm stuck with the cardLikeButton. It doesn't seem to toggle the classes... Can you help in leading me how to fix this?
author_association: OWNER
user: login: FaridaNelson
created_at: 2025-05-27T16:13:00Z
body: Dear Gennady, 

Thank you very much for your comment. I have successfully fixed the likeButton issue. Everything is working now. Looking forward to your review.
author_association: OWNER
user: login: FaridaNelson
created_at: 2025-05-28T15:35:02Z
body: Dear Sebastian, 

Thank you very much for a detailed explanation. I have added all the edits that you've pointed out. 
Looking forward to hearing back from you. 

Thank you!
author_association: OWNER