Index: backend/node_modules/.package-lock.json
===================================================================
--- backend/node_modules/.package-lock.json	(revision 3eb6a6868b6e398cb6b08affac6b16894683d0c1)
+++ backend/node_modules/.package-lock.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -130,4 +130,21 @@
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
+    "node_modules/axios": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+      "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
@@ -184,4 +201,10 @@
       }
     },
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+      "license": "ISC"
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
@@ -244,4 +267,280 @@
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/cheerio": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+      "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
+      "license": "MIT",
+      "dependencies": {
+        "cheerio-select": "^2.1.0",
+        "dom-serializer": "^2.0.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.1.0",
+        "encoding-sniffer": "^0.2.0",
+        "htmlparser2": "^9.1.0",
+        "parse5": "^7.1.2",
+        "parse5-htmlparser2-tree-adapter": "^7.0.0",
+        "parse5-parser-stream": "^7.1.2",
+        "undici": "^6.19.5",
+        "whatwg-mimetype": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=18.17"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+      "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-select": "^5.1.0",
+        "css-what": "^6.1.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/css-select": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+      "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-what": "^6.1.0",
+        "domhandler": "^5.0.2",
+        "domutils": "^3.0.1",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/css-what": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+      "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/cheerio-select/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/domutils": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/nth-check": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/cheerio/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/domutils": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/htmlparser2": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+      "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.1.0",
+        "entities": "^4.5.0"
+      }
+    },
+    "node_modules/cheerio/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/parse5/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cherio": {
+      "version": "1.0.0-rc.2",
+      "resolved": "https://registry.npmjs.org/cherio/-/cherio-1.0.0-rc.2.tgz",
+      "integrity": "sha512-6uMRxujZ6LouVnjv9dYNehbqGEkzQE0anmo70ExdxX3NlyliOcUcAcWDaUEVVPKGGdK5CP6I+bB76+Ud+SEJ6Q==",
+      "license": "MIT",
+      "dependencies": {
+        "css-select": "~1.2.0",
+        "dom-serializer": "~0.1.0",
+        "entities": "~1.1.1",
+        "htmlparser2": "^3.9.1",
+        "lodash": "^4.15.0",
+        "parse5": "^3.0.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
       }
     },
@@ -271,4 +570,16 @@
       }
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
@@ -317,4 +628,25 @@
       }
     },
+    "node_modules/css-select": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+      "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==",
+      "license": "BSD-like",
+      "dependencies": {
+        "boolbase": "~1.0.0",
+        "css-what": "2.1",
+        "domutils": "1.5.1",
+        "nth-check": "~1.0.1"
+      }
+    },
+    "node_modules/css-what": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/debug": {
       "version": "4.4.0",
@@ -334,4 +666,13 @@
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/depd": {
       "version": "2.0.0",
@@ -341,4 +682,38 @@
       "engines": {
         "node": ">= 0.8"
+      }
+    },
+    "node_modules/dom-serializer": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+      "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^1.3.0",
+        "entities": "^1.1.1"
+      }
+    },
+    "node_modules/domelementtype": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/domhandler": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "1"
+      }
+    },
+    "node_modules/domutils": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+      "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==",
+      "dependencies": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
       }
     },
@@ -384,4 +759,23 @@
       }
     },
+    "node_modules/encoding-sniffer": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+      "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "^0.6.3",
+        "whatwg-encoding": "^3.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+      }
+    },
+    "node_modules/entities": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+      "license": "BSD-2-Clause"
+    },
     "node_modules/es-define-property": {
       "version": "1.0.1",
@@ -409,4 +803,19 @@
       "dependencies": {
         "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
       },
       "engines": {
@@ -501,4 +910,61 @@
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
+      "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.2",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
@@ -524,19 +990,4 @@
       "engines": {
         "node": ">= 0.8"
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
     },
@@ -634,4 +1085,19 @@
       }
     },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/hasown": {
       "version": "2.0.2",
@@ -644,4 +1110,18 @@
       "engines": {
         "node": ">= 0.4"
+      }
+    },
+    "node_modules/htmlparser2": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^1.3.1",
+        "domhandler": "^2.3.0",
+        "domutils": "^1.5.1",
+        "entities": "^1.1.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^3.1.1"
       }
     },
@@ -757,4 +1237,10 @@
         "russian-bad-words": "^0.5.0"
       }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+      "license": "MIT"
     },
     "node_modules/math-intrinsics": {
@@ -896,4 +1382,13 @@
       }
     },
+    "node_modules/nth-check": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "~1.0.0"
+      }
+    },
     "node_modules/object-inspect": {
       "version": "1.13.4",
@@ -950,4 +1445,113 @@
       }
     },
+    "node_modules/parse5": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+      "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+      "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+      "license": "MIT",
+      "dependencies": {
+        "domhandler": "^5.0.3",
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+      "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+      "license": "MIT",
+      "dependencies": {
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
     "node_modules/parseurl": {
       "version": "1.3.3",
@@ -993,4 +1597,10 @@
         "node": ">= 0.10"
       }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
     },
     "node_modules/pstree.remy": {
@@ -1038,4 +1648,18 @@
       "engines": {
         "node": ">= 0.8"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
@@ -1255,4 +1879,13 @@
       }
     },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "node_modules/supports-color": {
       "version": "5.5.0",
@@ -1327,4 +1960,13 @@
       "license": "MIT"
     },
+    "node_modules/undici": {
+      "version": "6.21.3",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
+      "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18.17"
+      }
+    },
     "node_modules/undici-types": {
       "version": "6.21.0",
@@ -1342,4 +1984,10 @@
       }
     },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "license": "MIT"
+    },
     "node_modules/vary": {
       "version": "1.1.2",
@@ -1356,4 +2004,25 @@
       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
       "license": "BSD-2-Clause"
+    },
+    "node_modules/whatwg-encoding": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+      "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "0.6.3"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/whatwg-mimetype": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+      "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
     },
     "node_modules/whatwg-url": {
Index: backend/package-lock.json
===================================================================
--- backend/package-lock.json	(revision 3eb6a6868b6e398cb6b08affac6b16894683d0c1)
+++ backend/package-lock.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -11,5 +11,8 @@
       "dependencies": {
         "@supabase/supabase-js": "^2.39.7",
+        "axios": "^1.9.0",
         "bcrypt": "^6.0.0",
+        "cheerio": "^1.0.0",
+        "cherio": "^1.0.0-rc.2",
         "dotenv": "^16.5.0",
         "express": "^5.1.0",
@@ -144,4 +147,21 @@
       "engines": {
         "node": ">= 8"
+      }
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
+    "node_modules/axios": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+      "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
       }
     },
@@ -200,4 +220,10 @@
       }
     },
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+      "license": "ISC"
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
@@ -260,4 +286,280 @@
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/cheerio": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+      "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
+      "license": "MIT",
+      "dependencies": {
+        "cheerio-select": "^2.1.0",
+        "dom-serializer": "^2.0.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.1.0",
+        "encoding-sniffer": "^0.2.0",
+        "htmlparser2": "^9.1.0",
+        "parse5": "^7.1.2",
+        "parse5-htmlparser2-tree-adapter": "^7.0.0",
+        "parse5-parser-stream": "^7.1.2",
+        "undici": "^6.19.5",
+        "whatwg-mimetype": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=18.17"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+      "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-select": "^5.1.0",
+        "css-what": "^6.1.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/css-select": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+      "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-what": "^6.1.0",
+        "domhandler": "^5.0.2",
+        "domutils": "^3.0.1",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/css-what": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+      "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/cheerio-select/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/domutils": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cheerio-select/node_modules/nth-check": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/cheerio/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/domutils": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+      "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/htmlparser2": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+      "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.1.0",
+        "entities": "^4.5.0"
+      }
+    },
+    "node_modules/cheerio/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/cheerio/node_modules/parse5/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/cherio": {
+      "version": "1.0.0-rc.2",
+      "resolved": "https://registry.npmjs.org/cherio/-/cherio-1.0.0-rc.2.tgz",
+      "integrity": "sha512-6uMRxujZ6LouVnjv9dYNehbqGEkzQE0anmo70ExdxX3NlyliOcUcAcWDaUEVVPKGGdK5CP6I+bB76+Ud+SEJ6Q==",
+      "license": "MIT",
+      "dependencies": {
+        "css-select": "~1.2.0",
+        "dom-serializer": "~0.1.0",
+        "entities": "~1.1.1",
+        "htmlparser2": "^3.9.1",
+        "lodash": "^4.15.0",
+        "parse5": "^3.0.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
       }
     },
@@ -287,4 +589,16 @@
       }
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
@@ -333,4 +647,25 @@
       }
     },
+    "node_modules/css-select": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+      "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==",
+      "license": "BSD-like",
+      "dependencies": {
+        "boolbase": "~1.0.0",
+        "css-what": "2.1",
+        "domutils": "1.5.1",
+        "nth-check": "~1.0.1"
+      }
+    },
+    "node_modules/css-what": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/debug": {
       "version": "4.4.0",
@@ -350,4 +685,13 @@
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/depd": {
       "version": "2.0.0",
@@ -357,4 +701,38 @@
       "engines": {
         "node": ">= 0.8"
+      }
+    },
+    "node_modules/dom-serializer": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+      "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^1.3.0",
+        "entities": "^1.1.1"
+      }
+    },
+    "node_modules/domelementtype": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/domhandler": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "1"
+      }
+    },
+    "node_modules/domutils": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+      "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==",
+      "dependencies": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
       }
     },
@@ -400,4 +778,23 @@
       }
     },
+    "node_modules/encoding-sniffer": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+      "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "^0.6.3",
+        "whatwg-encoding": "^3.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+      }
+    },
+    "node_modules/entities": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+      "license": "BSD-2-Clause"
+    },
     "node_modules/es-define-property": {
       "version": "1.0.1",
@@ -425,4 +822,19 @@
       "dependencies": {
         "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
       },
       "engines": {
@@ -517,4 +929,61 @@
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
+      "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.2",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/form-data/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
@@ -650,4 +1119,19 @@
       }
     },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/hasown": {
       "version": "2.0.2",
@@ -660,4 +1144,18 @@
       "engines": {
         "node": ">= 0.4"
+      }
+    },
+    "node_modules/htmlparser2": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+      "license": "MIT",
+      "dependencies": {
+        "domelementtype": "^1.3.1",
+        "domhandler": "^2.3.0",
+        "domutils": "^1.5.1",
+        "entities": "^1.1.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^3.1.1"
       }
     },
@@ -773,4 +1271,10 @@
         "russian-bad-words": "^0.5.0"
       }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+      "license": "MIT"
     },
     "node_modules/math-intrinsics": {
@@ -912,4 +1416,13 @@
       }
     },
+    "node_modules/nth-check": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "boolbase": "~1.0.0"
+      }
+    },
     "node_modules/object-inspect": {
       "version": "1.13.4",
@@ -966,4 +1479,113 @@
       }
     },
+    "node_modules/parse5": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+      "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+      "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+      "license": "MIT",
+      "dependencies": {
+        "domhandler": "^5.0.3",
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+      "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+      "license": "MIT",
+      "dependencies": {
+        "parse5": "^7.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream/node_modules/entities": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
+      "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/parse5-parser-stream/node_modules/parse5": {
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+      "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+      "license": "MIT",
+      "dependencies": {
+        "entities": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/inikulin/parse5?sponsor=1"
+      }
+    },
     "node_modules/parseurl": {
       "version": "1.3.3",
@@ -1009,4 +1631,10 @@
         "node": ">= 0.10"
       }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
     },
     "node_modules/pstree.remy": {
@@ -1054,4 +1682,18 @@
       "engines": {
         "node": ">= 0.8"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
@@ -1271,4 +1913,13 @@
       }
     },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
     "node_modules/supports-color": {
       "version": "5.5.0",
@@ -1343,4 +1994,13 @@
       "license": "MIT"
     },
+    "node_modules/undici": {
+      "version": "6.21.3",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
+      "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18.17"
+      }
+    },
     "node_modules/undici-types": {
       "version": "6.21.0",
@@ -1358,4 +2018,10 @@
       }
     },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "license": "MIT"
+    },
     "node_modules/vary": {
       "version": "1.1.2",
@@ -1372,4 +2038,25 @@
       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
       "license": "BSD-2-Clause"
+    },
+    "node_modules/whatwg-encoding": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+      "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+      "license": "MIT",
+      "dependencies": {
+        "iconv-lite": "0.6.3"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/whatwg-mimetype": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+      "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
     },
     "node_modules/whatwg-url": {
Index: backend/package.json
===================================================================
--- backend/package.json	(revision 3eb6a6868b6e398cb6b08affac6b16894683d0c1)
+++ backend/package.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -14,5 +14,8 @@
   "dependencies": {
     "@supabase/supabase-js": "^2.39.7",
+    "axios": "^1.9.0",
     "bcrypt": "^6.0.0",
+    "cheerio": "^1.0.0",
+    "cherio": "^1.0.0-rc.2",
     "dotenv": "^16.5.0",
     "express": "^5.1.0",
Index: backend/scripts/tasksScraper.js
===================================================================
--- backend/scripts/tasksScraper.js	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
+++ backend/scripts/tasksScraper.js	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -0,0 +1,58 @@
+const axios = require('axios');
+const cheerio = require('cheerio');
+const fs = require('fs').promises;
+
+const ROOT_URL =
+  'https://github.com/theoludwig/programming-challenges/tree/master/challenges';
+const BASE_RAW =
+  'https://raw.githubusercontent.com/theoludwig/programming-challenges/master/challenges/';
+const OUTPUT_FILE = 'challenges-output.txt';
+
+async function getChallengeFolders() {
+  const res = await axios.get(
+    'https://api.github.com/repos/theoludwig/programming-challenges/contents/challenges'
+  );
+
+  return res.data
+    .filter((item) => item.type === 'dir')
+    .map((item) => item.name);
+}
+
+async function fetchMarkdown(folder, outputStram) {
+  const url = `${BASE_RAW}${folder}/README.md`;
+  try {
+    const res = await axios.get(url);
+    const output = `\n=== ${folder} ===\n${res.data}\n`;
+
+    console.log(output);
+
+    return output;
+  } catch (err) {
+    console.error(`No README found for ${folder}: ${err.response?.status}`);
+  }
+}
+
+(async () => {
+  try {
+    // Clear/create the output file
+    await fs.writeFile(
+      OUTPUT_FILE,
+      'PROGRAMMING CHALLENGES\n' +
+        '=====================\n\n' +
+        `Generated on: ${new Date().toISOString()}\n\n`
+    );
+
+    const folders = await getChallengeFolders();
+    console.log(`Found ${folders.length} challenge folders`);
+
+    for (const folder of folders) {
+      const output = await fetchMarkdown(folder);
+      // Append each result to the file
+      await fs.appendFile(OUTPUT_FILE, output);
+    }
+
+    console.log(`\nAll results saved to ${OUTPUT_FILE}`);
+  } catch (error) {
+    console.error('Error during execution:', error);
+  }
+})();
Index: backend/tasks/challenges-output.txt
===================================================================
--- backend/tasks/challenges-output.txt	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
+++ backend/tasks/challenges-output.txt	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -0,0 +1,1572 @@
+PROGRAMMING CHALLENGES
+=====================
+
+Generated on: 2025-06-08T08:43:48.583Z
+
+
+=== a-phone-code ===
+# a-phone-code
+
+Created by [@theoludwig](https://github.com/theoludwig) on 13 May 2025.
+
+## Instructions
+
+Polycarpus has n friends in Tarasov city. Polycarpus knows phone numbers of all his friends: they are strings s1, s2, ..., sn. All these strings consist only of digits and have the same length.
+
+Once Polycarpus needed to figure out Tarasov city phone code. He assumed that the phone code of the city is the longest common prefix of all phone numbers of his friends. In other words, it is the longest string c which is a prefix (the beginning) of each si for all i. Help Polycarpus determine the length of the city phone code.
+
+### Input
+
+The first line of the input contains an integer n — the number of Polycarpus's friends. The following n lines contain strings — the phone numbers of Polycarpus's friends. It is guaranteed that all strings consist only of digits and have the same length from 1 to 20, inclusive. It is also guaranteed that all strings are different.
+
+### Output
+
+Print the number of digits in the city phone code.
+
+## Source
+
+[Codeforces - A. Phone Code](https://codeforces.com/problemset/problem/172/A)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== acronyms ===
+# acronyms
+
+Created by [@theoludwig](https://github.com/theoludwig) on 30 June 2021.
+
+## Instructions
+
+Convert a given sentence to its acronym.
+
+## Examples
+
+### Example 1
+
+### Input
+
+```txt
+Programming Challenges is really cool
+```
+
+### Output
+
+```txt
+PCIRC
+```
+
+#### Output
+
+See the `test` folder for examples of input/output.
+
+
+=== ascii-art ===
+# ascii-art
+
+Created by [@theoludwig](https://github.com/theoludwig) on 1 May 2022.
+
+## Instructions
+
+### Goal
+
+In stations and airports you often see this type of screen:
+
+![Led Display](./led_display.jpg)
+
+Have you ever asked yourself how it might be possible to simulate this display on a good old terminal? We have: with ASCII art!
+
+### Rules
+
+ASCII art allows you to represent forms by using characters. To be precise, in our case, these forms are words. For example, the word "MANHATTAN" could be displayed as follows in ASCII art:
+
+```txt
+# #  #  ### # #  #  ### ###  #  ###
+### # # # # # # # #  #   #  # # # #
+### ### # # ### ###  #   #  ### # #
+# # # # # # # # # #  #   #  # # # #
+# # # # # # # # # #  #   #  # # # #
+```
+
+​Your mission is to write a program that can display a line of text in ASCII art in a style you are given as input.
+
+### Input
+
+- **Line 1:** The width `W` of a letter represented in ASCII art. All letters are the same width.
+- **Line 2:** The height `H` of a letter represented in ASCII art. All letters are the same height.
+- **Line 3:** The line of text `T`, composed of `N` ASCII characters.
+- **Following lines:** the string of characters `ABCDEFGHIJKLMNOPQRSTUVWXYZ?` Represented in ASCII art.
+
+### Output
+
+The text `T` in ASCII art.
+
+The characters a to z are shown in ASCII art by their equivalent in upper case.
+
+The characters that are not in the intervals `[a-z]` or `[A-Z]` will be shown as a question mark in ASCII art.
+
+### Constraints
+
+- $$0 < W < 30$$
+- $$0 < H < 30$$
+- $$0 < N < 200$$
+
+## Source
+
+[CodinGame](https://www.codingame.com/training/easy/ascii-art)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== caesar-cipher ===
+# caesar-cipher
+
+Created by [@theoludwig](https://github.com/theoludwig) on 25 June 2021.
+
+## Instructions
+
+In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of -3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.
+
+### Example of the alphabet with a shift of +3 (shift to the right)
+
+```text
+Alphabet original   : ABCDEFGHIJKLMNOPQRSTUVWXYZ
+Alphabet rotated +3 : DEFGHIJKLMNOPQRSTUVWXYZABC
+```
+
+Create a function that will return the sentence after shifting the alphabet.
+
+- If it is a **positive** number then we shift the alphabet to the **right**
+- If it is a **negative** number then we shift the alphabet to the **left**
+
+### Example of Inputs
+
+```py
+'ANTHONY' # a character string (all capital letters)
+'-2' # an integer, the shift in the alphabet
+```
+
+## Source
+
+[Wikipedia - Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== cakes-swerc-2020-2021 ===
+# cakes-swerc-2020-2021
+
+Created by [@theoludwig](https://github.com/theoludwig) on 23 April 2022.
+
+## Instructions
+
+This summer, you plan to organize a large party and invite many
+friends. They have a sweet tooth, so you plan to bake nice cakes for them.
+You know the recipe for a nice chocolate cake, and you want to cook as
+many of them as possible.
+
+Given the `N` ingredients needed to make a single cake and the
+ingredients that you have in your kitchen, how many cakes can you
+make?
+
+### Input
+
+- **Line 1:** Single integer `N` for the number of ingredients.
+- **`N` next lines:** One for each ingredient. Each of these lines contains two positive integers: the first one is the required quantity of this ingredient per cake, the second one is the quantity of this ingredient you have in your kitchen.
+
+### Output
+
+The output should contain a single integer: the maximum number of cakes you can make using the
+available ingredients.
+
+### Constraints
+
+- $$1 \leq N \leq 10$$
+- All ingredient quantities will be integers between 1 and 10 000.
+
+## Source
+
+[SWERC 2020-2021 - Problem E: Cake](https://swerc.eu/2020/problems/)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+3
+100 500
+2 5
+70 1000
+```
+
+#### Output
+
+```txt
+2
+```
+
+### Example 2
+
+#### Input
+
+```txt
+3
+100 50
+2 5
+70 1000
+```
+
+#### Output
+
+```txt
+0
+```
+
+
+=== camel-case ===
+# camel-case
+
+Created by [@theoludwig](https://github.com/theoludwig) on 5 July 2020.
+
+## Instructions
+
+Write a simple camelCase function for strings. All words (except the first) must have their first letter capitalized without spaces.
+
+**Note:** camelCase is the practice of writing phrases such that each word in the middle of the phrase begins with a capital letter, with no intervening spaces or punctuation.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== consecutive-numbers ===
+# consecutive-numbers
+
+Created by [@theoludwig](https://github.com/theoludwig) on 28 June 2021.
+
+## Instructions
+
+Write a function which takes a list of integers, and which returns the list of of successive consecutive integers that there may be in the list.
+
+First input, is the number of consecutive numbers needed to consider it as "consecutive", the second input is the list of integers.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+2
+5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7
+```
+
+#### Output
+
+```txt
+1 ; 2
+2 ; 3
+-5 ; -4
+```
+
+### Example 2
+
+#### Input
+
+```txt
+3
+5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7
+```
+
+#### Output
+
+```txt
+1 ; 2 ; 3
+```
+
+
+=== convert-number-from-base-to-another ===
+# convert-number-from-base-to-another
+
+Created by [@theoludwig](https://github.com/theoludwig) on 20 October 2021.
+
+## Instructions
+
+Convert a natural number (`number`) from a certain base (`base_from`) to another base (`base_target`).
+
+For bases up to and including 10, we use the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9.
+
+For bases between 11 and 36, we use the 10 digits then the letters (capitals). For example, for base 16, the symbols used are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. For base 36, we uses the symbols 0,1,2,3,4,5,6,7,8,9, A, B, C, D, E, F, G, H, I, J, K, L, M, N , O, P, Q, R, S, T, U, V, W, X, Y, Z.
+
+### Input
+
+- **Line 1:** The `number` to be converted (natural number)
+- **Line 2:** The base of the number `base_from`
+- **Line 3:** The base to convert to `base_target`
+
+### Output
+
+The converted number.
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+15
+10
+16
+```
+
+#### Output
+
+```txt
+F
+```
+
+### Example 2
+
+#### Input
+
+```txt
+100000000
+2
+16
+```
+
+#### Output
+
+```txt
+100
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== defibrillators ===
+# defibrillators
+
+Created by [@theoludwig](https://github.com/theoludwig) on 28 June 2021.
+
+## Instructions
+
+### Goal
+
+The city of Montpellier has equipped its streets with defibrillators to help save victims of cardiac arrests. The data corresponding to [the position of all defibrillators](http://data.montpellier3m.fr/dataset/d%C3%A9fibrillateurs-de-montpellier) is available online.
+
+Based on the data we provide in the tests, write a program that will allow users to find the defibrillator nearest to their location using their mobile phone.
+
+### Rules
+
+The input data you require for your program is provided in text format.
+This data is comprised of lines, each of which represents a defibrillator. Each defibrillator is represented by the following fields:
+
+- A number identifying the defibrillator
+- Name
+- Address
+- Contact Phone number
+- Longitude (degrees)
+- Latitude (degrees)
+
+These fields are separated by a semicolon (`;`).
+
+**Beware:** the decimal numbers use the comma (,) as decimal separator. Remember to turn the comma (,) into dot (.) if necessary in order to use the data in your program.
+
+### Distance
+
+The distance `d` between two points `A` and `B` will be calculated using the following formula:
+
+![Distance Formula](./distance-formula.png)
+
+**Note:** In this formula, the latitudes and longitudes are expressed in radians. 6371 corresponds to the radius of the earth in km.
+
+The program will display the name of the defibrillator located the closest to the user’s position. This position is given as input to the program.
+
+### Input
+
+- **Line 1:** User's longitude (in degrees)
+- **Line 2:** User's latitude (in degrees)
+- **Line 3:** The number `N` of defibrillators located in the streets of Montpellier
+- **`N` next lines:** a description of each defibrillator
+
+### Output
+
+The name of the defibrillator located the closest to the user’s position.
+
+### Constraints
+
+- $$0 < N < 10 000$$
+
+## Source
+
+[CodinGame](https://www.codingame.com/training/easy/defibrillators)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== fibonacci ===
+# fibonacci
+
+Created by [@theoludwig](https://github.com/theoludwig) on 5 July 2020.
+
+## Instructions
+
+The function should return an array of fibonacci numbers. The function takes a `number` as an argument to decide how many number of elements to produce.
+
+**Note:** The Fibonacci Sequence is the series of numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... Each subsequent number is the sum of the previous two.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== find-closest-number ===
+# find-closest-number
+
+Created by [@theoludwig](https://github.com/theoludwig) on 1 May 2022.
+
+## Instructions
+
+Given an array of `n` integers, find the closest value to the given number (`given_number`).
+
+## Input
+
+- **Line 1:** An integer `given_number` for the number to find the closest value to
+- **Line 2:** An integer `n` for the length of the list of integers
+- **`n` next lines:** the integers
+
+## Output
+
+The closest value in the array to the given number.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+3
+6
+1
+2
+3
+4
+5
+6
+```
+
+#### Output
+
+```txt
+3
+```
+
+**Explanation:** The given number is `3` and `3` is in the array, so the closest value is `3`.
+
+### Example 2
+
+#### Input
+
+```txt
+0
+14
+7
+-10
+13
+8
+4
+-7
+-12
+-3
+3
+-9
+6
+-1
+-6
+7
+```
+
+#### Output
+
+```txt
+-1
+```
+
+
+=== find-outlier-number ===
+# find-outlier-number
+
+Created by [@theoludwig](https://github.com/theoludwig) on 5 July 2020.
+
+## Instructions
+
+You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer `N`. Write a function that takes the array as an argument and returns this "outlier" `N`.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== first-non-repeating-character ===
+# first-non-repeating-character
+
+Created by [@theoludwig](https://github.com/theoludwig) on 15 November 2020.
+
+## Instructions
+
+Write a function that takes a string input, and returns the first character that is not repeated anywhere in the string.
+
+For example, if given the input `'stress'`, the function should return `'t'`, since the letter `'t'` only occurs once in the string, and occurs first in the string.
+
+If a string contains all repeating characters, it should return an empty string (`""`).
+
+## Source
+
+[First non-repeating character - Codewars](https://www.codewars.com/kata/52bc74d4ac05d0945d00054e/)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== fizzbuzz ===
+# fizzbuzz
+
+Created by [@theoludwig](https://github.com/theoludwig) on 30 June 2021.
+
+## Instructions
+
+Write a program that print the numbers from 1 to `n` but:
+
+- if number is divisible by 3, print `Fizz`
+- if number is divisible by 5, print `Buzz`
+- if number is divisible by both 3 and 5, print `FizzBuzz`
+- otherwise print the number
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+5
+```
+
+#### Output
+
+```txt
+1
+2
+Fizz
+4
+Buzz
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== frequency-deviation ===
+# frequency-deviation
+
+Created by [@theoludwig](https://github.com/theoludwig) on 16 September 2023.
+
+## Instructions
+
+Given a string consisting of lowercase English letters, we define the frequency deviation of a substring as the difference between the maximum and the minimum frequencies of the characters in that substring.
+
+A substring of a string is formed by any contiguous segment of the string. For example, given "bbacccc", the character appearing most frequently is 'c' with $4$ occurrences. The character that appears the fewest times is 'a' with $1$ occurrence. The frequency deviation of the entire string is $4 - 1 = 3$.
+
+Given a string, $s$, representing the input string, find the maximum possible frequency deviation of any of its substrings.
+
+### Constraints
+
+- $$1 \leq s.length \leq 10^4$$
+- $s$ consists of lowercase English letters.
+
+## Source
+
+- [LeetCode - Substring With Largest Variance](https://leetcode.com/problems/substring-with-largest-variance/)
+- [Twitter @CoderNolimit](https://twitter.com/CoderNolimit/status/1668147202173050881)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+bbacccc
+```
+
+#### Output
+
+```txt
+3
+```
+
+### Example 2
+
+#### Input
+
+```txt
+aabb
+```
+
+#### Output
+
+```txt
+1
+```
+
+### Example 3
+
+#### Input
+
+```txt
+aaaaa
+```
+
+#### Output
+
+```txt
+0
+```
+
+
+=== heap-algorithm ===
+# heap-algorithm
+
+Created by [@theoludwig](https://github.com/theoludwig) on 8 November 2021.
+
+## Instructions
+
+Write a program that generates all possible unique permutations of a string.
+
+The order of the generated permutations is important, see the example below.
+
+## Source
+
+[Heap's Algorithm - Wikipedia](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+abc
+```
+
+#### Output
+
+```txt
+abc
+bac
+cab
+acb
+bca
+cba
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== hello-world ===
+# hello-world
+
+Created by [@theoludwig](https://github.com/theoludwig) on 6 June 2021.
+
+## Instructions
+
+Your function should return Hello depending of the parameter.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== is-palindrome ===
+# is-palindrome
+
+Created by [@theoludwig](https://github.com/theoludwig) on 5 July 2020.
+
+## Instructions
+
+The function should return `true` if a given string (case insensitive) is a palindrome and `false` if it's not the case.
+
+**Note:** a **Palindrome** is a word, phrase, or sequence that reads the **same backwards as forwards**, e.g. Kayak.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== is-prime-number ===
+# is-prime-number
+
+Created by [@theoludwig](https://github.com/theoludwig) on 5 July 2020.
+
+## Instructions
+
+The function should return `true` if a given number is a prime number and `false` otherwise.
+
+**Note :** A prime number is a natural integer which admits exactly two distinct positive divisors. (1 and itself). Example: 2, 3, 5, 7, 11, 13, 17, 19 ...
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== is-valid-array-subsequence ===
+# is-valid-array-subsequence
+
+Created by [@theoludwig](https://github.com/theoludwig) on 23 April 2022.
+
+## Instructions
+
+Given two non-empty arrays of integers, write a function that determines whether the second array is a subsequence of the first one.
+
+A subsequence of an array is a set of numbers that aren't necessarily adjacent in the array but that are in the same order as they appear in the array. For instance, the numbers `[1, 3, 4]` form a subsequence of the array `[1, 2, 3, 4]`, and so do the numbers `[2, 4]`. Note that a single number in an array and the array itself are both valid subsequences of the array.
+
+### Input
+
+- **Line 1:** `array` Integers separated by spaces
+- **Line 2:** `sequence` Integers separated by spaces
+
+### Output
+
+The output should return `true` if the `sequence` is a subsequence of `array` and `false` otherwise.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+5 1 22 25 6 -1 8 10
+1 6 -1 10
+```
+
+#### Output
+
+```txt
+true
+```
+
+### Example 2
+
+#### Input
+
+```txt
+5 1 22 25 6 -1 8 10
+5 1 22 25 6 -1 8 10 12
+```
+
+#### Output
+
+```txt
+false
+```
+
+
+=== left-pad ===
+# left-pad
+
+Created by [@theoludwig](https://github.com/theoludwig) on 21 May 2023.
+
+## Instructions
+
+Create a function that pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length. The padding is applied from the start (left) of the current string.
+
+Inspired from [left-pad (JavaScript npm package)](https://www.npmjs.com/package/left-pad).
+
+### Input
+
+- **Line 1:** The current string
+- **Line 2:** The length of the resulting string
+- **Line 3:** The string to pad the current string with
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+foo
+12
+-
+```
+
+#### Output
+
+```txt
+---------foo
+```
+
+
+=== look-and-say-sequence-conway ===
+# look-and-say-sequence-conway
+
+Created by [@theoludwig](https://github.com/theoludwig) on 30 November 2021.
+
+## Instructions
+
+In mathematics, the **look-and-say sequence** is the sequence of integers beginning as follows: `1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ...`.
+
+The look-and-say sequence was introduced and analyzed by John **Conway**.
+
+To generate a member of the sequence from the previous member, read off the digits of the previous member, counting the number of digits in groups of the same digit. For example:
+
+- `1` is read off as "one 1" or 11.
+- `11` is read off as "two 1s" or 21.
+- `21` is read off as "one 2, then one 1" or 1211.
+- `1211` is read off as "one 1, one 2, then two 1s" or 111221.
+- `111221` is read off as "three 1s, two 2s, then one 1" or 312211.
+
+Write a program that prints the next term of the **look-and-say sequence**.
+
+## Source
+
+[Look-and-say sequence - Wikipedia](https://en.wikipedia.org/wiki/Look-and-say_sequence)
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+11
+```
+
+#### Output
+
+```txt
+21
+```
+
+### Example 2
+
+#### Input
+
+```txt
+1211
+```
+
+#### Output
+
+```txt
+111221
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== maximum-subarray-sum ===
+# maximum-subarray-sum
+
+Created by [@theoludwig](https://github.com/theoludwig) on 1 May 2022.
+
+## Instructions
+
+Given an array of `n` integers, find the contiguous subarray with the largest sum.
+
+Contiguous subarray is any sub series of elements in a given array that are contiguous ie their indices are continuous. The problem is interesting when there may be negative values in the array, because if the array only contains positive values, the maximum subarray sum is basically the sum of the array (the subarray being the complete array).
+
+## Input
+
+- **Line 1:** An integer `n` for the length of the list of integers
+- **`n` next lines:** the integers
+
+## Output
+
+The largest sum of a contiguous subarray.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+6
+1
+2
+3
+4
+5
+6
+```
+
+#### Output
+
+```txt
+21
+```
+
+**Explanation:** The subarray with the largest sum is the array itself (as there is no negative values) `[1, 2, 3, 4, 5, 6]` which has a sum of `21`.
+
+### Example 2
+
+#### Input
+
+```txt
+8
+-1
+2
+4
+-3
+5
+2
+-5
+2
+```
+
+#### Output
+
+```txt
+10
+```
+
+**Explanation:** The subarray with the largest sum is `[2, 4, -3, 5, 2]` which has a sum of `10`.
+
+
+=== offset-arrays ===
+# offset-arrays
+
+Created by [@theoludwig](https://github.com/theoludwig) on 29 June 2021.
+
+## Instructions
+
+### Goal
+
+To settle the debate of 0-based vs 1-based indexing I have created a language where you must explicitly state the range of indices an array should have.
+
+For example, given an array definition "A[-1..1] = 1 2 3", you would have:
+
+- A[-1] = 1
+- A[0] = 2
+- A[1] = 3
+
+You are given a list of `n` array definitions and your job is to figure out what number is found in a given index `i` of an array `arr`. Note that the indexing operations may be nested (in the above example, A[A[-1]] would produce result 3).
+
+### Input
+
+- **Line 1:** An integer `n` for the number of array assignments
+- **`n` next lines:** One array assignment per line: `array_identifier` [ `first_index` .. `last_index` ] = `last_index - first_index + 1` integers separated by space
+- **Line `n+2`:** Element to print: `arr` [ `i` ]
+
+### Constraints
+
+- $$1 \leq n \leq 100$$
+- Array names consist only of uppercase letters A to Z.
+- Array lengths are between 1 and 100 (no empty arrays).
+- Indexing operations have at most 50 levels of nesting.
+- Indices are always within bounds in the test cases.
+
+## Source
+
+[CodinGame](https://www.codingame.com/ide/puzzle/offset-arrays)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+3
+A[-1..1] = 1 2 3
+B[3..7] = 3 4 5 6 7
+C[-2..1] = 1 2 3 4
+A[0]
+```
+
+#### Output
+
+```txt
+2
+```
+
+
+=== prefix-suffix ===
+# prefix-suffix
+
+Created by [@theoludwig](https://github.com/theoludwig) on 2 December 2021.
+
+## Instructions
+
+A prefix is an affix which is placed before the stem of a word. Adding it to the beginning of one word changes it into another word. For example, when the prefix un- is added to the word happy, it creates the word unhappy.
+
+A suffix is an affix which is placed after the stem of a word. Common examples are case endings, which indicate the grammatical case of nouns, adjectives, and verb endings, which form the conjugation of verbs. Suffixes can carry grammatical information or lexical information.
+
+Write a programs that takes 2 strings ("words") and prints if one is a prefix/suffix of the other.
+
+### Input
+
+- **Line 1:** The word to be checked
+- **Line 2:** The potential prefix/suffix
+
+### Output
+
+- **Line 1:** `true` if the second word is a **prefix** of the first, `false` otherwise
+- **Line 1:** `true` if the second word is a **suffix** of the first, `false` otherwise
+
+## Sources
+
+- [Wikipedia - Prefix](https://en.wikipedia.org/wiki/Prefix)
+- [Wikipedia - Suffix](https://en.wikipedia.org/wiki/Suffix)
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+Py
+AlgoPy
+```
+
+#### Output
+
+```txt
+false
+false
+```
+
+### Example 2
+
+#### Input
+
+```txt
+AlgoPy
+Py
+```
+
+#### Output
+
+```txt
+false
+true
+```
+
+### Example 3
+
+#### Input
+
+```txt
+same-word
+same-word
+```
+
+#### Output
+
+```txt
+true
+true
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== prime-numbers-decomposition ===
+# prime-numbers-decomposition
+
+Created by [@theoludwig](https://github.com/theoludwig) on 16 October 2021.
+
+## Instructions
+
+## Definition
+
+In mathematics, product decomposition of prime factors (also known as integer factorization into prime numbers) involves writing a strictly positive integer as a product of prime numbers.
+
+This factorization is unique and exists for all numbers and has many applications, particularly in RSA cryptography.
+
+**Note :** A prime number is a natural integer which admits exactly two distinct positive divisors. (1 and itself). Example: 2, 3, 5, 7, 11, 13, 17, 19...
+
+## How to decompose a number into a product of factors of prime numbers?
+
+To find the product decomposition of prime factors of a number `N`, there is no mathematical formula. To achieve this, there are algorithms, the most basic of which attempts to divide the number `N` by the set of prime factors `p` which are less than `N`.
+If `p` is a divisor of `N` then start again by taking a new `N = N / p` as long as there are possible prime divisors.
+
+## Examples
+
+### Example
+
+#### Input
+
+```txt
+32
+```
+
+#### Output
+
+```txt
+2 * 2 * 2 * 2 * 2
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== print-pyramid ===
+# print-pyramid
+
+Created by [@theoludwig](https://github.com/theoludwig) on 21 September 2021.
+
+## Instructions
+
+Display a pyramid of stars (`*`) whose height is given and in the right order (`normal` or `reverse`).
+
+### Input
+
+- **Line 1:** The string : `normal` or `reverse` to determine how to show the pyramid.
+- **Line 2:** The integer : height of the pyramid.
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== reverse-polish-notation ===
+# reverse-polish-notation
+
+Created by [@theoludwig](https://github.com/theoludwig) on 29 September 2020.
+
+## Instructions
+
+Your job is to create a calculator which evaluates expressions in Reverse Polish notation (a mathematical notation in which operators follow their operands. It does not need any parentheses as long as each operator has a fixed number of operands).
+
+For example expression 5 3 + (which is equivalent to 5 + 3 in normal notation) should evaluate to 8.
+
+For your convenience, the input is formatted such that a space is provided between every token.
+
+Empty expression should evaluate to 0.
+
+Valid operations are +, -, \*, /.
+
+You may assume that there won't be exceptional situations (like stack underflow or division by zero).
+
+All the numbers are integers; you don't need to worry about floating point numbers.
+
+## Source
+
+[Reverse polish notation - Codewars](https://www.codewars.com/kata/52f78966747862fc9a0009ae)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== roman-numerals ===
+# roman-numerals
+
+Created by [@theoludwig](https://github.com/theoludwig) on 30 June 2021.
+
+## Instructions
+
+The objective of this challenge is to create a function that translates a number into Roman numerals or the other way around.
+
+We will use the letters `I`, `V`, `X`, `L`, `C`, `D`, `M` to build the Roman numerals.
+
+Here are the rules for building a Roman numeral:
+
+- The numbers `1`, `2` and `3` are written respectively as `I`, `II` and `III`
+- The number `5` is written as `V`
+- The number `10` is written as `X`
+- The number `50` is written as `L`
+- The number `100` is written as `C`
+- The number `500` is written as `D`
+- The number `1000` is written as `M`
+- When writing two letters in a row, if the numerical value of the first is greater than the numerical value of the second, their numerical values ​​are added. For example the number `6` is written `VI`. We add `V` (5) + `I` (1) = 6.
+- When writing two letters in a row, if the numerical value of the first is less than the numerical value of the second, the value of the first is subtracted from the second. For example the number `4` is written `IV`. We subtract `V` (5) - `I` (1) = 4.
+- Subtractions of values ​​are limited to 2 letters only. For example we **cannot** write `8` while doing `IIX`. We must use the addition of letters like this `VIII`.
+- Therefore, the first ten numbers are written as `I`, `II`, `III`, `IV`, `V`, `VI`, `VII`, `VIII`, `IX`, `X` . Larger numbers follow the same pattern.
+- You can associate as many symbols as you want to write larger numbers, for example:
+    - `36` is written as `XXXVI`
+    - `42` is written as `XLII`
+    - `2448` is written as `MMCDXLVIII`.
+
+| Symbol | I   | V   | X   | L   | C   | D   | M    |
+| ------ | --- | --- | --- | --- | --- | --- | ---- |
+| Value  | 1   | 5   | 10  | 50  | 100 | 500 | 1000 |
+
+### Input
+
+- **Line 1:** The string : `arabic to roman` or `roman to arabic` to determine how to convert the number
+- **Line 2:** The number to convert
+
+## Sources
+
+- [Wikipedia - Roman numerals](https://en.wikipedia.org/wiki/Roman_numerals)
+- [Wikipedia - Arabic numerals](https://en.wikipedia.org/wiki/Arabic_numerals)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== rotate-2-dimensional-array-90-degrees ===
+# rotate-2-dimensional-array-90-degrees
+
+Created by [@theoludwig](https://github.com/theoludwig) on 3 December 2021.
+
+## Instructions
+
+Given a square/rectangle matrix representing an image and a direction of rotation (`clockwise` or `anticlockwise`), rotate the image by 90 degrees.
+
+### Input
+
+- **Line 1:** The direction (`clockwise` or `anticlockwise`) of rotation
+- **Next Lines:** The matrix of the image
+
+### Output
+
+- **Lines:** The rotated matrix
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+clockwise
+1 2 3
+4 5 6
+7 8 9
+```
+
+#### Output
+
+```txt
+7 4 1
+8 5 2
+9 6 3
+```
+
+### Example 2
+
+#### Input
+
+```txt
+anticlockwise
+1 2 3
+4 5 6
+7 8 9
+```
+
+#### Output
+
+```txt
+1 4 7
+2 5 8
+3 6 9
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== single-number ===
+# single-number
+
+Created by [@theoludwig](https://github.com/theoludwig) on 21 August 2023.
+
+## Instructions
+
+Given a **non-empty** array of integers, every element appears twice except for one. Find that single one.
+
+You must implement a solution with a linear runtime complexity and use only constant extra space.
+
+### Constraints
+
+- $$1 \leq numbers.length \leq 3 \times 10^4$$
+- $$-3 \times 10^4 \leq numbers[index] \leq 3 \times 10^4$$
+- Each element in the array appears twice except for one element which appears only once.
+
+## Source
+
+[LeetCode - Single Number](https://leetcode.com/problems/single-number/)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+4
+1
+2
+1
+2
+```
+
+#### Output
+
+```txt
+4
+```
+
+
+=== slugify ===
+# slugify
+
+Created by [@theoludwig](https://github.com/theoludwig) on 10 November 2021.
+
+## Instructions
+
+Write a function that generates a slug from a string.
+
+A Slug is the unique identifying part of a web address, typically at the end of the URL.
+
+The rules for generating a slug are as follows (`kebab-case`):
+
+- Replace spaces with hyphens.
+- Remove all non-alphanumeric characters.
+
+## Examples
+
+### Example 1
+
+#### Input
+
+```txt
+hello world
+```
+
+#### Output
+
+```txt
+hello-world
+```
+
+### Example 2
+
+#### Input
+
+```txt
+--hello world--
+```
+
+### Output
+
+```txt
+hello-world
+```
+
+### Example 3
+
+#### Input
+
+```txt
+😄 emoji
+```
+
+### Output
+
+```txt
+emoji
+```
+
+See the `test` folder for examples of input/output.
+
+
+=== sorting-algorithms ===
+# sorting-algorithms
+
+Created by [@theoludwig](https://github.com/theoludwig) on 29 June 2021.
+
+## Instructions
+
+In computer science, a sorting algorithm is an algorithm that puts elements of a list in a certain order.
+We will use the [numerical order](https://en.wikipedia.org/wiki/Numerical_order).
+
+Write a function that takes a list of integers and sort them in ascending order.
+
+## Input
+
+- **Line 1:** An integer $n$ for the length of the list of integers
+- **$n$ next lines:** the numbers to sort
+
+### Constraints
+
+- $$n \leq 25 000$$
+
+## Source
+
+[Wikipedia - Sorting algorithm](https://en.wikipedia.org/wiki/Sorting_algorithm)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== sudoku ===
+# sudoku
+
+Created by [@theoludwig](https://github.com/theoludwig) on 6 July 2021.
+
+## Instructions
+
+Sudoku is a logic-based, combinatorial number-placement puzzle.
+
+The objective is to fill a 9×9 grid with digits so that each column, each row, and each of the nine 3×3 subgrids that compose the grid (also called "boxes", "blocks", or "regions") contains all of the digits from 1 to 9. The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a single solution.
+
+You can't use the same numbers twice in a:
+
+- row
+- column
+- square of 3x3
+
+Write a program that solves the Sudoku given in input.
+
+The empty cells are represented by 0.
+
+## Source
+
+[Wikipedia - Sudoku](https://en.wikipedia.org/wiki/Sudoku)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+5 3 0 0 7 0 0 0 0
+6 0 0 1 9 5 0 0 0
+0 9 8 0 0 0 0 6 0
+8 0 0 0 6 0 0 0 3
+4 0 0 8 0 3 0 0 1
+7 0 0 0 2 0 0 0 6
+0 6 0 0 0 0 2 8 0
+0 0 0 4 1 9 0 0 5
+0 0 0 0 8 0 0 7 9
+```
+
+#### Output
+
+```txt
+5 3 4 6 7 8 9 1 2
+6 7 2 1 9 5 3 4 8
+1 9 8 3 4 2 5 6 7
+8 5 9 7 6 1 4 2 3
+4 2 6 8 5 3 7 9 1
+7 1 3 9 2 4 8 5 6
+9 6 1 5 3 7 2 8 4
+2 8 7 4 1 9 6 3 5
+3 4 5 2 8 6 1 7 9
+```
+
+
+=== triangle-type ===
+# triangle-type
+
+Created by [@theoludwig](https://github.com/theoludwig) on 30 June 2021.
+
+## Instructions
+
+Given the lengths of the 3 sides of a triangle, your function should return whether it is `equilateral`, `isosceles`, `scalene` or `impossible`.
+
+- A triangle is `equilateral` when its 3 sides are equal
+- A triangle is `isosceles` when 2 of its sides are equal
+- A triangle is `scalene` when none of its sides is equal to another side
+- A triangle is `impossible` when the sum of two of its sides is strictly less than the third side
+
+## Input
+
+- **Line 1 to 3:** The length of each side of the triangle
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+
+=== valid-parentheses ===
+# valid-parentheses
+
+Created by [@theoludwig](https://github.com/theoludwig) on 18 November 2024.
+
+## Instructions
+
+Given a string containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
+
+An input string is valid if:
+
+- Open brackets must be closed by the same type of brackets.
+- Open brackets must be closed in the correct order.
+- Every close bracket has a corresponding open bracket of the same type.
+
+## Source
+
+[LeetCode - Valid Parentheses](https://leetcode.com/problems/valid-parentheses)
+
+## Examples
+
+See the `test` folder for examples of input/output.
+
+### Example 1
+
+#### Input
+
+```txt
+()
+```
+
+#### Output
+
+```txt
+true
+```
+
+### Example 2
+
+#### Input
+
+```txt
+(]
+```
+
+#### Output
+
+```txt
+false
+```
+
Index: backend/tasks/initialTasks.json
===================================================================
--- backend/tasks/initialTasks.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
+++ backend/tasks/initialTasks.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -0,0 +1,167 @@
+[
+  {
+    "title": "a-phone-code",
+    "description": "Your task is to calculate the length of the longest common starting sequence (prefix) among a list of phone numbers, which represents the city's phone code.",
+    "examples": [
+      {
+        "input": "3\n007\n00123\n00124",
+        "output": "2"
+      },
+      {
+        "input": "4\n12345\n123\n123987\n123456",
+        "output": "3"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "acronyms",
+    "description": "Develop a function that takes a sentence and converts it into its acronym by taking the first letter of each word.",
+    "examples": [
+      {
+        "input": "Programming Challenges is really cool",
+        "output": "PCIRC"
+      },
+      {
+        "input": "Portable Network Graphics",
+        "output": "PNG"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "caesar-cipher",
+    "description": "Implement a function that encrypts a message using the Caesar cipher technique, which involves shifting each letter of the alphabet by a specified number of places.",
+    "examples": [
+      {
+        "input": "'ANTHONY', -3",
+        "output": "XKQELKV"
+      },
+      {
+        "input": "'JULIUS CAESAR', 3",
+        "output": "MXOLXV FDHVDU"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "cakes-swerc-2020-2021",
+    "description": "You need to determine the maximum number of cakes you can bake given a list of required ingredients per cake and the quantities of those ingredients you currently possess.",
+    "examples": [
+      {
+        "input": "3\n100 500\n2 5\n70 1000",
+        "output": "2"
+      },
+      {
+        "input": "3\n100 50\n2 5\n70 1000",
+        "output": "0"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "camel-case",
+    "description": "Construct a function that converts a standard string into camelCase format, where all words except the first begin with a capital letter and are joined without spaces.",
+    "examples": [
+      {
+        "input": "hello world",
+        "output": "helloWorld"
+      },
+      {
+        "input": "first name",
+        "output": "firstName"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "consecutive-numbers",
+    "description": "Design a function that identifies and returns all sequences of consecutive integers within a given list of numbers. The required length for a sequence to be considered 'consecutive' is given as the first input.",
+    "examples": [
+      {
+        "input": "2\n5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7",
+        "output": "1 ; 2\n2 ; 3\n-5 ; -4"
+      },
+      {
+        "input": "3\n5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7",
+        "output": "1 ; 2 ; 3"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "convert-number-from-base-to-another",
+    "description": "Create a function capable of converting a given natural number from its initial base to a target base. The function should handle bases from 2 to 36, using digits 0-9 and then capital letters A-Z.",
+    "examples": [
+      {
+        "input": "15\n10\n16",
+        "output": "F"
+      },
+      {
+        "input": "100000000\n2\n16",
+        "output": "100"
+      }
+    ],
+    "difficulty": "Medium"
+  },
+  {
+    "title": "fibonacci",
+    "description": "Your goal is to build a function that generates an array containing a specified quantity of Fibonacci numbers. The Fibonacci sequence starts with 0 and 1, and each subsequent number is the sum of the two preceding ones.",
+    "examples": [
+      {
+        "input": "8",
+        "output": "[0, 1, 1, 2, 3, 5, 8, 13]"
+      },
+      {
+        "input": "14",
+        "output": "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "find-closest-number",
+    "description": "Given a list of integers and a separate target integer, your function must find and return the integer from the list that is numerically closest to the target.",
+    "examples": [
+      {
+        "input": "given_number: 3\narray: [1, 2, 3, 4, 5, 6]",
+        "output": "3"
+      },
+      {
+        "input": "given_number: 0\narray: [7, -10, 13, 8, 4, -7, -12, -3, 3, -9, 6, -1, -6, 7]",
+        "output": "-1"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "find-outlier-number",
+    "description": "You're provided an array of integers that is composed almost entirely of either odd or even numbers, with the exception of one unique number. Your task is to write a function that identifies and returns this single outlier.",
+    "examples": [
+      {
+        "input": "[2, 4, 0, 100, 4, 11, 2602, 36]",
+        "output": "11"
+      },
+      {
+        "input": "[160, 3, 1719, 19, 11, 13, -21]",
+        "output": "160"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "first-non-repeating-character",
+    "description": "Write a function to find the first character in a string that does not appear again in that string. If every character is repeated, the function should return an empty string.",
+    "examples": [
+      {
+        "input": "'stress'",
+        "output": "'t'"
+      },
+      {
+        "input": "'aabbcc'",
+        "output": "''"
+      }
+    ],
+    "difficulty": "Easy"
+  }
+]
Index: backend/tasks/tasks.json
===================================================================
--- backend/tasks/tasks.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
+++ backend/tasks/tasks.json	(revision d8ef34b76505ef9d7e84f03750c749f8fe8780ea)
@@ -0,0 +1,353 @@
+[
+  {
+    "title": "a-phone-code",
+    "description": "Your task is to calculate the length of the longest common starting sequence (prefix) among a list of phone numbers, which represents the city's phone code.",
+    "examples": [
+      {
+        "input": "3\n007\n00123\n00124",
+        "output": "2"
+      },
+      {
+        "input": "4\n12345\n123\n123987\n123456",
+        "output": "3"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "acronyms",
+    "description": "Develop a function that takes a sentence and converts it into its acronym by taking the first letter of each word.",
+    "examples": [
+      {
+        "input": "Programming Challenges is really cool",
+        "output": "PCIRC"
+      },
+      {
+        "input": "Portable Network Graphics",
+        "output": "PNG"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "caesar-cipher",
+    "description": "Implement a function that encrypts a message using the Caesar cipher technique, which involves shifting each letter of the alphabet by a specified number of places.",
+    "examples": [
+      {
+        "input": "'ANTHONY', -3",
+        "output": "XKQELKV"
+      },
+      {
+        "input": "'JULIUS CAESAR', 3",
+        "output": "MXOLXV FDHVDU"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "cakes-swerc-2020-2021",
+    "description": "You need to determine the maximum number of cakes you can bake given a list of required ingredients per cake and the quantities of those ingredients you currently possess.",
+    "examples": [
+      {
+        "input": "3\n100 500\n2 5\n70 1000",
+        "output": "2"
+      },
+      {
+        "input": "3\n100 50\n2 5\n70 1000",
+        "output": "0"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "camel-case",
+    "description": "Construct a function that converts a standard string into camelCase format, where all words except the first begin with a capital letter and are joined without spaces.",
+    "examples": [
+      {
+        "input": "hello world",
+        "output": "helloWorld"
+      },
+      {
+        "input": "first name",
+        "output": "firstName"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "consecutive-numbers",
+    "description": "Design a function that identifies and returns all sequences of consecutive integers within a given list of numbers. The required length for a sequence to be considered 'consecutive' is given as the first input.",
+    "examples": [
+      {
+        "input": "2\n5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7",
+        "output": "1 ; 2\n2 ; 3\n-5 ; -4"
+      },
+      {
+        "input": "3\n5 ; 1 ; 2 ; 3 ; 8 ; -5 ; -4 ; 7",
+        "output": "1 ; 2 ; 3"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "convert-number-from-base-to-another",
+    "description": "Create a function capable of converting a given natural number from its initial base to a target base. The function should handle bases from 2 to 36, using digits 0-9 and then capital letters A-Z.",
+    "examples": [
+      {
+        "input": "15\n10\n16",
+        "output": "F"
+      },
+      {
+        "input": "100000000\n2\n16",
+        "output": "100"
+      }
+    ],
+    "difficulty": "Medium"
+  },
+  {
+    "title": "fibonacci",
+    "description": "Your goal is to build a function that generates an array containing a specified quantity of Fibonacci numbers. The Fibonacci sequence starts with 0 and 1, and each subsequent number is the sum of the two preceding ones.",
+    "examples": [
+      {
+        "input": "8",
+        "output": "[0, 1, 1, 2, 3, 5, 8, 13]"
+      },
+      {
+        "input": "14",
+        "output": "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "find-closest-number",
+    "description": "Given a list of integers and a separate target integer, your function must find and return the integer from the list that is numerically closest to the target.",
+    "examples": [
+      {
+        "input": "given_number: 3\narray: [1, 2, 3, 4, 5, 6]",
+        "output": "3"
+      },
+      {
+        "input": "given_number: 0\narray: [7, -10, 13, 8, 4, -7, -12, -3, 3, -9, 6, -1, -6, 7]",
+        "output": "-1"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "find-outlier-number",
+    "description": "You're provided an array of integers that is composed almost entirely of either odd or even numbers, with the exception of one unique number. Your task is to write a function that identifies and returns this single outlier.",
+    "examples": [
+      {
+        "input": "[2, 4, 0, 100, 4, 11, 2602, 36]",
+        "output": "11"
+      },
+      {
+        "input": "[160, 3, 1719, 19, 11, 13, -21]",
+        "output": "160"
+      }
+    ],
+    "difficulty": "Easy"
+  },
+  {
+    "title": "first-non-repeating-character",
+    "description": "Write a function to find the first character in a string that does not appear again in that string. If every character is repeated, the function should return an empty string.",
+    "examples": [
+      {
+        "input": "'stress'",
+        "output": "'t'"
+      },
+      {
+        "input": "'aabbcc'",
+        "output": "''"
+      }
+    ],
+    "difficulty": "Easy"
+  }
+  //   {
+  //     "title": "fizzbuzz",
+  //     "description": "Write a program that print the numbers from 1 to `n` but:\n\n- if number is divisible by 3, print `Fizz`\n- if number is divisible by 5, print `Buzz`\n- if number is divisible by both 3 and 5, print `FizzBuzz`\n- otherwise print the number",
+  //     "example": {
+  //       "input": "5",
+  //       "output": "1\n2\nFizz\n4\nBuzz"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "frequency-deviation",
+  //     "description": "Given a string consisting of lowercase English letters, we define the frequency deviation of a substring as the difference between the maximum and the minimum frequencies of the characters in that substring.\n\nA substring of a string is formed by any contiguous segment of the string. For example, given \"bbacccc\", the character appearing most frequently is 'c' with $4$ occurrences. The character that appears the fewest times is 'a' with $1$ occurrence. The frequency deviation of the entire string is $4 - 1 = 3$.\n\nGiven a string, $s$, representing the input string, find the maximum possible frequency deviation of any of its substrings.",
+  //     "example": {
+  //       "input": "bbacccc",
+  //       "output": "3"
+  //     },
+  //     "difficulty": "Hard"
+  //   },
+  //   {
+  //     "title": "heap-algorithm",
+  //     "description": "Write a program that generates all possible unique permutations of a string.\n\nThe order of the generated permutations is important, see the example below.",
+  //     "example": {
+  //       "input": "abc",
+  //       "output": "abc\nbac\ncab\nacb\nbca\ncba"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "hello-world",
+  //     "description": "Your function should return Hello depending of the parameter.",
+  //     "example": null,
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "is-palindrome",
+  //     "description": "The function should return `true` if a given string (case insensitive) is a palindrome and `false` if it's not the case.",
+  //     "example": null,
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "is-prime-number",
+  //     "description": "The function should return `true` if a given number is a prime number and `false` otherwise.",
+  //     "example": null,
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "is-valid-array-subsequence",
+  //     "description": "Given two non-empty arrays of integers, write a function that determines whether the second array is a subsequence of the first one.",
+  //     "example": {
+  //       "input": "5 1 22 25 6 -1 8 10\n1 6 -1 10",
+  //       "output": "true"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "left-pad",
+  //     "description": "Create a function that pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length. The padding is applied from the start (left) of the current string.",
+  //     "example": {
+  //       "input": "foo\n12\n-",
+  //       "output": "---------foo"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "look-and-say-sequence-conway",
+  //     "description": "Write a program that prints the next term of the **look-and-say sequence**.",
+  //     "example": {
+  //       "input": "11",
+  //       "output": "21"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "maximum-subarray-sum",
+  //     "description": "Given an array of `n` integers, find the contiguous subarray with the largest sum.",
+  //     "example": {
+  //       "input": "8\n-1\n2\n4\n-3\n5\n2\n-5\n2",
+  //       "output": "10"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "offset-arrays",
+  //     "description": "To settle the debate of 0-based vs 1-based indexing I have created a language where you must explicitly state the range of indices an array should have.\n\nFor example, given an array definition \"A[-1..1] = 1 2 3\", you would have:\n\n- A[-1] = 1\n- A[0] = 2\n- A[1] = 3\n\nYou are given a list of `n` array definitions and your job is to figure out what number is found in a given index `i` of an array `arr`. Note that the indexing operations may be nested (in the above example, A[A[-1]] would produce result 3).",
+  //     "example": {
+  //       "input": "3\nA[-1..1] = 1 2 3\nB[3..7] = 3 4 5 6 7\nC[-2..1] = 1 2 3 4\nA[0]",
+  //       "output": "2"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "prefix-suffix",
+  //     "description": "Write a programs that takes 2 strings (\"words\") and prints if one is a prefix/suffix of the other.",
+  //     "example": {
+  //       "input": "AlgoPy\nPy",
+  //       "output": "false\ntrue"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "prime-numbers-decomposition",
+  //     "description": "In mathematics, product decomposition of prime factors (also known as integer factorization into prime numbers) involves writing a strictly positive integer as a product of prime numbers.",
+  //     "example": {
+  //       "input": "32",
+  //       "output": "2 * 2 * 2 * 2 * 2"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "print-pyramid",
+  //     "description": "Display a pyramid of stars (`*`) whose height is given and in the right order (`normal` or `reverse`).",
+  //     "example": null,
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "reverse-polish-notation",
+  //     "description": "Your job is to create a calculator which evaluates expressions in Reverse Polish notation (a mathematical notation in which operators follow their operands. It does not need any parentheses as long as each operator has a fixed number of operands).",
+  //     "example": null,
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "roman-numerals",
+  //     "description": "The objective of this challenge is to create a function that translates a number into Roman numerals or the other way around.",
+  //     "example": null,
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "rotate-2-dimensional-array-90-degrees",
+  //     "description": "Given a square/rectangle matrix representing an image and a direction of rotation (`clockwise` or `anticlockwise`), rotate the image by 90 degrees.",
+  //     "example": {
+  //       "input": "clockwise\n1 2 3\n4 5 6\n7 8 9",
+  //       "output": "7 4 1\n8 5 2\n9 6 3"
+  //     },
+  //     "difficulty": "Medium"
+  //   },
+  //   {
+  //     "title": "single-number",
+  //     "description": "Given a **non-empty** array of integers, every element appears twice except for one. Find that single one.\n\nYou must implement a solution with a linear runtime complexity and use only constant extra space.",
+  //     "example": {
+  //       "input": "4\n1\n2\n1\n2",
+  //       "output": "4"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "slugify",
+  //     "description": "Write a function that generates a slug from a string.\n\nA Slug is the unique identifying part of a web address, typically at the end of the URL.\n\nThe rules for generating a slug are as follows (`kebab-case`):\n\n- Replace spaces with hyphens.\n- Remove all non-alphanumeric characters.",
+  //     "example": {
+  //       "input": "hello world",
+  //       "output": "hello-world"
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "sorting-algorithms",
+  //     "description": "Write a function that takes a list of integers and sort them in ascending order.",
+  //     "example": null,
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "sudoku",
+  //     "description": "Write a program that solves the Sudoku given in input.\n\nThe empty cells are represented by 0.",
+  //     "example": {
+  //       "input": "5 3 0 0 7 0 0 0 0\n6 0 0 1 9 5 0 0 0\n0 9 8 0 0 0 0 6 0\n8 0 0 0 6 0 0 0 3\n4 0 0 8 0 3 0 0 1\n7 0 0 0 2 0 0 0 6\n0 6 0 0 0 0 2 8 0\n0 0 0 4 1 9 0 0 5\n0 0 0 0 8 0 0 7 9",
+  //       "output": "5 3 4 6 7 8 9 1 2\n6 7 2 1 9 5 3 4 8\n1 9 8 3 4 2 5 6 7\n8 5 9 7 6 1 4 2 3\n4 2 6 8 5 3 7 9 1\n7 1 3 9 2 4 8 5 6\n9 6 1 5 3 7 2 8 4\n2 8 7 4 1 9 6 3 5\n3 4 5 2 8 6 1 7 9"
+  //     },
+  //     "difficulty": "Hard"
+  //   },
+  //   {
+  //     "title": "triangle-type",
+  //     "description": "Given the lengths of the 3 sides of a triangle, your function should return whether it is `equilateral`, `isosceles`, `scalene` or `impossible`.",
+  //     "example": {
+  //       "input": "- **Line 1 to 3:** The length of each side of the triangle",
+  //       "output": null
+  //     },
+  //     "difficulty": "Easy"
+  //   },
+  //   {
+  //     "title": "valid-parentheses",
+  //     "description": "Given a string containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.",
+  //     "example": {
+  //       "input": "()",
+  //       "output": "true"
+  //     },
+  //     "difficulty": "Easy"
+  //   }
+]
