[
  {
    "path": ".all-contributorsrc",
    "content": "{\n  \"projectName\": \"usehooks-ts\",\n  \"projectOwner\": \"juliencrn\",\n  \"repoType\": \"github\",\n  \"repoHost\": \"https://github.com\",\n  \"files\": [\n    \".github/CONTRIBUTING.md\",\n    \"README.md\",\n    \"packages/usehooks-ts/README.md\"\n  ],\n  \"imageSize\": 64,\n  \"commit\": false,\n  \"commitConvention\": \"none\",\n  \"contributors\": [\n    {\n      \"login\": \"juliencrn\",\n      \"name\": \"Julien\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/14028029?v=4\",\n      \"profile\": \"https://github.com/juliencrn\",\n      \"contributions\": [\"content\", \"code\", \"design\", \"ideas\"]\n    },\n    {\n      \"login\": \"a777med\",\n      \"name\": \"a777med\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15968280?v=4\",\n      \"profile\": \"https://github.com/a777med\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"datkira\",\n      \"name\": \"Nguyen Tien Dat\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/53250212?v=4\",\n      \"profile\": \"https://datkira.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"elifer5000\",\n      \"name\": \"Elias Cohenca\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4311278?v=4\",\n      \"profile\": \"https://github.com/elifer5000\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"joaoderoldo\",\n      \"name\": \"João Deroldo\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/17601527?v=4\",\n      \"profile\": \"http://joaov.com.br/\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"Nishit-Dua\",\n      \"name\": \"Nishit\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/35453301?v=4\",\n      \"profile\": \"https://github.com/Nishit-Dua\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"jonkoops\",\n      \"name\": \"Jon Koops\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/695720?v=4\",\n      \"profile\": \"https://github.com/jonkoops\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"LoneRifle\",\n      \"name\": \"LoneRifle\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10572368?v=4\",\n      \"profile\": \"https://github.com/LoneRifle\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"vfonic\",\n      \"name\": \"Viktor\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/67437?v=4\",\n      \"profile\": \"https://github.com/vfonic\",\n      \"contributions\": [\"ideas\", \"bug\"]\n    },\n    {\n      \"login\": \"bclermont\",\n      \"name\": \"Bruno Clermont\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/474302?v=4\",\n      \"profile\": \"https://github.com/bclermont\",\n      \"contributions\": [\"question\"]\n    },\n    {\n      \"login\": \"yoannesbourg\",\n      \"name\": \"yoannesbourg\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/73404603?v=4\",\n      \"profile\": \"https://github.com/yoannesbourg\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"strange2x\",\n      \"name\": \"Strange2x\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10759731?v=4\",\n      \"profile\": \"https://github.com/strange2x\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"steinybot\",\n      \"name\": \"Jason Pickens\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4659562?v=4\",\n      \"profile\": \"https://github.com/steinybot\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"selvinkuik\",\n      \"name\": \"Sel-Vin Kuik\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3469560?v=4\",\n      \"profile\": \"http://smackagency.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"isaacalves\",\n      \"name\": \"isaac\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1765942?v=4\",\n      \"profile\": \"https://github.com/isaacalves\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"brunorzn\",\n      \"name\": \"Bruno RZN\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/18266054?v=4\",\n      \"profile\": \"https://github.com/brunorzn\",\n      \"contributions\": [\"code\", \"review\"]\n    },\n    {\n      \"login\": \"Cykelero\",\n      \"name\": \"Nathan Manceaux-Panot\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/2979318?v=4\",\n      \"profile\": \"http://www.cykeprojects.com/\",\n      \"contributions\": [\"code\", \"review\"]\n    },\n    {\n      \"login\": \"meotimdihia\",\n      \"name\": \"Dien Vu\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/300961?v=4\",\n      \"profile\": \"https://github.com/meotimdihia\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"olegKusov\",\n      \"name\": \"Oleg Kusov\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/28058268?v=4\",\n      \"profile\": \"https://github.com/olegKusov\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"mankittens\",\n      \"name\": \"Matthew Guy\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6647355?v=4\",\n      \"profile\": \"http://mattguy.me/\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"andrewbihl\",\n      \"name\": \"andrewbihl\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/16709744?v=4\",\n      \"profile\": \"https://github.com/andrewbihl\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"lancepollard\",\n      \"name\": \"lancepollard\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/86631222?v=4\",\n      \"profile\": \"https://github.com/lancepollard\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"gmukul01\",\n      \"name\": \"Mukul Bansal\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3636885?v=4\",\n      \"profile\": \"https://github.com/gmukul01\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jeanlucmongrain\",\n      \"name\": \"Jean-Luc Mongrain sur la Brosse\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/474302?v=4\",\n      \"profile\": \"http://127.0.0.1:8000/\",\n      \"contributions\": [\"code\", \"ideas\"]\n    },\n    {\n      \"login\": \"n1c\",\n      \"name\": \"Nic\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/284075?v=4\",\n      \"profile\": \"https://github.com/n1c\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"valtism\",\n      \"name\": \"Dan Wood\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1286001?v=4\",\n      \"profile\": \"http://valtism.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"Wendenburg\",\n      \"name\": \"jo wendenbuerger\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/25299148?v=4\",\n      \"profile\": \"http://www.sixt.de/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"noseratio\",\n      \"name\": \"Andrew Nosenko\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4774875?v=4\",\n      \"profile\": \"https://nozillium.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"CharlieJhonSmith\",\n      \"name\": \"CharlieJhonSmith\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/90845154?v=4\",\n      \"profile\": \"https://github.com/CharlieJhonSmith\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"soullivaneuh\",\n      \"name\": \"Sullivan SENECHAL\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1698357?v=4\",\n      \"profile\": \"https://keybase.io/soullivaneuh\",\n      \"contributions\": [\"ideas\", \"bug\", \"code\"]\n    },\n    {\n      \"login\": \"jaslong\",\n      \"name\": \"Jason Long\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/797348?v=4\",\n      \"profile\": \"https://github.com/jaslong\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"kxm766\",\n      \"name\": \"kxm766\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/88443148?v=4\",\n      \"profile\": \"https://github.com/kxm766\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"qlaffont\",\n      \"name\": \"Quentin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10044790?v=4\",\n      \"profile\": \"http://qlaffont.com/\",\n      \"contributions\": [\"code\", \"ideas\", \"content\"]\n    },\n    {\n      \"login\": \"ducktordanny\",\n      \"name\": \"Daniel Lazar\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/38068717?v=4\",\n      \"profile\": \"https://github.com/ducktordanny\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"mterrel\",\n      \"name\": \"Mark Terrel\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/17746857?v=4\",\n      \"profile\": \"https://github.com/mterrel\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"mendrik\",\n      \"name\": \"Andreas Herd\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/160805?v=4\",\n      \"profile\": \"https://github.com/mendrik\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"sonjoydatta\",\n      \"name\": \"Sonjoy Datta\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/49079726?v=4\",\n      \"profile\": \"https://sonjoydatta.me/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"oluckyman\",\n      \"name\": \"Ilya Belsky\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/642673?v=4\",\n      \"profile\": \"https://github.com/oluckyman\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"JamesBarrettDev\",\n      \"name\": \"James Barrett\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/42980207?v=4\",\n      \"profile\": \"https://jamesbarrett.io/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"AbbalYouness\",\n      \"name\": \"AbbalYouness\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15120524?v=4\",\n      \"profile\": \"https://github.com/AbbalYouness\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"DidrikLind\",\n      \"name\": \"didriklind\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/14201715?v=4\",\n      \"profile\": \"https://github.com/DidrikLind\",\n      \"contributions\": [\"code\", \"test\"]\n    },\n    {\n      \"login\": \"hexp1989\",\n      \"name\": \"hexp1989\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/2241985?v=4\",\n      \"profile\": \"https://github.com/hexp1989\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"alvaroserrrano\",\n      \"name\": \"Alvaro Serrano\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/43758471?v=4\",\n      \"profile\": \"https://www.linkedin.com/in/alvaro-serrano-rivas/\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"egehandulger\",\n      \"name\": \"Egehan Dülger\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/14878259?v=4\",\n      \"profile\": \"https://github.com/egehandulger\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"PabloLION\",\n      \"name\": \"PabloLION\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/36828324?v=4\",\n      \"profile\": \"https://github.com/PabloLION\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"emulienfou\",\n      \"name\": \"David Sanchez\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/84061?v=4\",\n      \"profile\": \"https://davidsanchez.me/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"AjayTheWizard\",\n      \"name\": \"Ajay Raja\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/92772740?v=4\",\n      \"profile\": \"https://github.com/AjayTheWizard\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"docmars\",\n      \"name\": \"Andy Merskin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/758090?v=4\",\n      \"profile\": \"http://andymerskin.com/\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"GrayGalaxy\",\n      \"name\": \"Avirup Ghosh\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/49820575?v=4\",\n      \"profile\": \"https://github.com/GrayGalaxy\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"tilnea\",\n      \"name\": \"Sanne Wintrén\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3692320?v=4\",\n      \"profile\": \"https://github.com/tilnea\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"a-barbieri\",\n      \"name\": \"Alessandro\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1528468?v=4\",\n      \"profile\": \"http://lacolonia.studio/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"atatarenko\",\n      \"name\": \"Andrey Tatarenko\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/9846273?v=4\",\n      \"profile\": \"https://github.com/atatarenko\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"arusak\",\n      \"name\": \"Anton Rusak\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4231915?v=4\",\n      \"profile\": \"https://github.com/arusak\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"createdbymahmood\",\n      \"name\": \"Mahmood Bagheri\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/40164360?v=4\",\n      \"profile\": \"https://github.com/createdbymahmood\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"anver\",\n      \"name\": \"Anver Sadutt\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/506491?v=4\",\n      \"profile\": \"https://wpowner.com/\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"bogdanailincaipnt\",\n      \"name\": \"Bogdan Ailincai\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/93596663?v=4\",\n      \"profile\": \"https://github.com/bogdanailincaipnt\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"SimeonGriggs\",\n      \"name\": \"Simeon Griggs\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/9684022?v=4\",\n      \"profile\": \"https://github.com/SimeonGriggs\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Kepro\",\n      \"name\": \"Kepro\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1714370?v=4\",\n      \"profile\": \"https://github.com/Kepro\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Jake-Lippert\",\n      \"name\": \"Jake Lippert\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/17753127?v=4\",\n      \"profile\": \"https://github.com/Jake-Lippert\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"TunA-Kai\",\n      \"name\": \"Tu Nguyen Anh\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/92641762?v=4\",\n      \"profile\": \"https://github.com/TunA-Kai\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"skve\",\n      \"name\": \"Luke Shiels\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/47612057?v=4\",\n      \"profile\": \"https://github.com/skve\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"SleLLl\",\n      \"name\": \"Sergei Kolyago\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/66108429?v=4\",\n      \"profile\": \"https://github.com/SleLLl\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"adhamaa\",\n      \"name\": \"Adham Akmal Azmi\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/50027371?v=4\",\n      \"profile\": \"https://github.com/adhamaa\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"alex-kowalczyk\",\n      \"name\": \"Alek Kowalczyk\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/7422175?v=4\",\n      \"profile\": \"https://github.com/alex-kowalczyk\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Scalahansolo\",\n      \"name\": \"Sean Callahan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4317253?v=4\",\n      \"profile\": \"https://github.com/Scalahansolo\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jbean96\",\n      \"name\": \"Joshua Bean\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/22803097?v=4\",\n      \"profile\": \"https://github.com/jbean96\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"ZhaoTim\",\n      \"name\": \"Tim Zhao\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/30540533?v=4\",\n      \"profile\": \"https://github.com/ZhaoTim\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"patryk-smc\",\n      \"name\": \"Patrick\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/37963339?v=4\",\n      \"profile\": \"https://github.com/patryk-smc\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"brycedorn\",\n      \"name\": \"Bryce Dorn\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3171252?v=4\",\n      \"profile\": \"https://bryce.io/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"angusd3v\",\n      \"name\": \"angusd3v\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/52683145?v=4\",\n      \"profile\": \"https://github.com/angusd3v\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"ddisimone\",\n      \"name\": \"Davide Di Simone\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/78792352?v=4\",\n      \"profile\": \"https://github.com/ddisimone\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jherr\",\n      \"name\": \"Jack Herrington\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/22392?v=4\",\n      \"profile\": \"https://github.com/jherr\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"sharvit\",\n      \"name\": \"Avi Sharvit\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1262502?v=4\",\n      \"profile\": \"https://sharvit.github.io/\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"nmaties\",\n      \"name\": \"Nicolae Maties\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/16613184?v=4\",\n      \"profile\": \"https://github.com/nmaties\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"secretshardul\",\n      \"name\": \"Shardul Aeer\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/49580849?v=4\",\n      \"profile\": \"https://github.com/secretshardul\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"herlon214\",\n      \"name\": \"Herlon Aguiar\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3419441?v=4\",\n      \"profile\": \"https://github.com/herlon214\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"alexisoney\",\n      \"name\": \"Alexis Oney\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/28802989?v=4\",\n      \"profile\": \"https://github.com/alexisoney\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"curtvict\",\n      \"name\": \"curtvict\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/96080054?v=4\",\n      \"profile\": \"https://convictional.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"JoshuaCS94\",\n      \"name\": \"Josué Cortina\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/23385700?v=4\",\n      \"profile\": \"https://github.com/JoshuaCS94\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"KATT\",\n      \"name\": \"Alex / KATT\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/459267?v=4\",\n      \"profile\": \"https://katt.dev/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"modex98\",\n      \"name\": \"Mourad EL CADI\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/72814784?v=4\",\n      \"profile\": \"https://github.com/modex98\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"Guesswhoitis\",\n      \"name\": \"James Hulena\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/63756285?v=4\",\n      \"profile\": \"https://github.com/Guesswhoitis\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"hailwood\",\n      \"name\": \"Matthew Hailwood\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/709773?v=4\",\n      \"profile\": \"http://hailwood.nz/\",\n      \"contributions\": [\"code\", \"review\"]\n    },\n    {\n      \"login\": \"mike247\",\n      \"name\": \"Michael Norrie\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/676071?v=4\",\n      \"profile\": \"https://github.com/mike247\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"valentinpolitov\",\n      \"name\": \"Valentin Politov\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/39585375?v=4\",\n      \"profile\": \"https://github.com/valentinpolitov\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"marnusw\",\n      \"name\": \"Marnus Weststrate\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/971499?v=4\",\n      \"profile\": \"https://github.com/marnusw\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"mancuoj\",\n      \"name\": \"mancuoj\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/45707684?v=4\",\n      \"profile\": \"https://github.com/mancuoj\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"jcsumlin\",\n      \"name\": \"Chat Sumlin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3067479?v=4\",\n      \"profile\": \"https://www.chatsumlin.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"owenshaupt\",\n      \"name\": \"Owen Haupt\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/52288188?v=4\",\n      \"profile\": \"https://github.com/owenshaupt\",\n      \"contributions\": [\"bug\", \"content\"]\n    },\n    {\n      \"login\": \"ubarbaxor\",\n      \"name\": \"ubarbaxor\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/26365493?v=4\",\n      \"profile\": \"https://github.com/ubarbaxor\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"michaelmior\",\n      \"name\": \"Michael Mior\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/82501?v=4\",\n      \"profile\": \"https://michael.mior.ca/\",\n      \"contributions\": [\"bug\", \"content\"]\n    },\n    {\n      \"login\": \"pkhodaveissi\",\n      \"name\": \"Pierre\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4170795?v=4\",\n      \"profile\": \"https://github.com/pkhodaveissi\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"harrywebdev\",\n      \"name\": \"Harry B\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3617415?v=4\",\n      \"profile\": \"https://github.com/harrywebdev\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"valyrie97\",\n      \"name\": \"Valerie\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6365746?v=4\",\n      \"profile\": \"https://github.com/valyrie97\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"stevenvachon\",\n      \"name\": \"Steven Vachon\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/170197?v=4\",\n      \"profile\": \"https://svachon.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"sskirby\",\n      \"name\": \"Sean Kirby\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/25760?v=4\",\n      \"profile\": \"https://github.com/sskirby\",\n      \"contributions\": [\"test\", \"code\"]\n    },\n    {\n      \"login\": \"AlecsFarias\",\n      \"name\": \"Alecsander Farias\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/91743821?v=4\",\n      \"profile\": \"https://github.com/AlecsFarias\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"BlankParticle\",\n      \"name\": \"Rahul Mishra\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/130567419?v=4\",\n      \"profile\": \"https://blankparticle.in/\",\n      \"contributions\": [\"code\", \"review\", \"content\"]\n    },\n    {\n      \"login\": \"bryantcodesart\",\n      \"name\": \"Bryant Smith\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/14097078?v=4\",\n      \"profile\": \"https://github.com/bryantcodesart\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"RobHannay\",\n      \"name\": \"Rob Hannay\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/609062?v=4\",\n      \"profile\": \"https://github.com/RobHannay\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"hooriza\",\n      \"name\": \"Hooriza\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/507927?v=4\",\n      \"profile\": \"https://github.com/hooriza\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"ShanSenanayake\",\n      \"name\": \"ShanSenanayake\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/8779685?v=4\",\n      \"profile\": \"https://github.com/ShanSenanayake\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"philipgher\",\n      \"name\": \"Philip Ghering\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/32325241?v=4\",\n      \"profile\": \"https://github.com/philipgher\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"ladislasdellinger\",\n      \"name\": \"Ladislas Dellinger\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/111739019?v=4\",\n      \"profile\": \"https://github.com/ladislasdellinger\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"TheHaff\",\n      \"name\": \"Haff\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/2486653?v=4\",\n      \"profile\": \"https://github.com/TheHaff\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"lisandro52\",\n      \"name\": \"Lisandro\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/5612241?v=4\",\n      \"profile\": \"https://github.com/lisandro52\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"amirking59\",\n      \"name\": \"Amir hossein rezaei\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/58273240?v=4\",\n      \"profile\": \"https://github.com/amirking59\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"nmacianx\",\n      \"name\": \"Nicolas Macian\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/40004186?v=4\",\n      \"profile\": \"https://github.com/nmacianx\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"nateforsyth\",\n      \"name\": \"Nate Forsyth\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/13162026?v=4\",\n      \"profile\": \"https://dreamsof.dev/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"satelllte\",\n      \"name\": \"satelllte\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/20585619?v=4\",\n      \"profile\": \"https://github.com/satelllte\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"fedemp\",\n      \"name\": \"Federico Panico\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/735314?v=4\",\n      \"profile\": \"https://github.com/fedemp\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"iamwillnbcu\",\n      \"name\": \"William Pei Yuan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/137317773?v=4\",\n      \"profile\": \"https://github.com/iamwillnbcu\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"DarkAng3L\",\n      \"name\": \"Mihai\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/757999?v=4\",\n      \"profile\": \"http://www.gazeta-cu-anunturi.ro/\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"ogunsolahabib\",\n      \"name\": \"Habib Ogunsola\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/39172573?v=4\",\n      \"profile\": \"https://habib.ogunsola.me/\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"ashfurrow\",\n      \"name\": \"Ash Furrow\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/498212?v=4\",\n      \"profile\": \"https://ashfurrow.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"danielturus\",\n      \"name\": \"Daniel Turuș\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/32390499?v=4\",\n      \"profile\": \"https://turus.ro/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"rahulchaudhary2244\",\n      \"name\": \"Rahul Chaudhary\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/54467972?v=4\",\n      \"profile\": \"https://www.linkedin.com/in/rahulchaudhary2244/\",\n      \"contributions\": [\"content\", \"bug\"]\n    },\n    {\n      \"login\": \"Joshyahweh\",\n      \"name\": \"Joshua Ojoawo\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/61137067?v=4\",\n      \"profile\": \"https://github.com/Joshyahweh\",\n      \"contributions\": [\"ideas\", \"bug\"]\n    },\n    {\n      \"login\": \"jackdh\",\n      \"name\": \"Jack\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1907451?v=4\",\n      \"profile\": \"https://jackdh.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"jonlinkens\",\n      \"name\": \"Jon Linkens\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/20417521?v=4\",\n      \"profile\": \"https://github.com/jonlinkens\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"ojj1123\",\n      \"name\": \"Jeongjin Oh\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/33178048?v=4\",\n      \"profile\": \"https://velog.io/@ojj1123\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"tli26\",\n      \"name\": \"Tianning Li\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/114947190?v=4\",\n      \"profile\": \"https://github.com/tli26\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"LarsArtmann\",\n      \"name\": \"Lars Artmann\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/23587853?v=4\",\n      \"profile\": \"https://larsartmann.com/\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"KBobovskiy\",\n      \"name\": \"KBobovskiy\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/35502578?v=4\",\n      \"profile\": \"https://github.com/KBobovskiy\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"ryngonzalez\",\n      \"name\": \"✨ Kathryn Gonzalez ✨\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/635300?v=4\",\n      \"profile\": \"https://github.com/ryngonzalez\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"slavik-chapelskyi\",\n      \"name\": \"Yaroslav Chapelskyi\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/33541009?v=4\",\n      \"profile\": \"https://github.com/slavik-chapelskyi\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"sverps\",\n      \"name\": \"Samuel Van Erps\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15879327?v=4\",\n      \"profile\": \"https://github.com/sverps\",\n      \"contributions\": [\"review\"]\n    },\n    {\n      \"login\": \"ojolowoblue\",\n      \"name\": \"ojolowoblue\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/104099474?v=4\",\n      \"profile\": \"https://github.com/ojolowoblue\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"gugu\",\n      \"name\": \"Andrii Kostenko\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/75169?v=4\",\n      \"profile\": \"http://short.io/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"AkeemAllen\",\n      \"name\": \"Akeem Allen\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/32404761?v=4\",\n      \"profile\": \"https://github.com/AkeemAllen\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"trongbinh15\",\n      \"name\": \"trongbinhnguyen\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/43725147?v=4\",\n      \"profile\": \"https://github.com/trongbinh15\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"lawlesx\",\n      \"name\": \"Aniruddha Sil\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/52166437?v=4\",\n      \"profile\": \"https://lawlesx.vercel.app/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"okinawaa\",\n      \"name\": \"박찬혁\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/69495129?v=4\",\n      \"profile\": \"https://github.com/okinawaa\",\n      \"contributions\": [\"review\"]\n    },\n    {\n      \"login\": \"novanish\",\n      \"name\": \"Anish\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/98446102?v=4\",\n      \"profile\": \"https://anishchhetri.com.np/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"hugohutri\",\n      \"name\": \"Hugo Hutri\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/55588133?v=4\",\n      \"profile\": \"https://hutri.fi/\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"BalzGuenat\",\n      \"name\": \"Balz Guenat\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6719014?v=4\",\n      \"profile\": \"http://balzguenat.ch/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"ottergeorge\",\n      \"name\": \"OtterGeorge\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/108759685?v=4\",\n      \"profile\": \"https://github.com/ottergeorge\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"samay-rgb\",\n      \"name\": \"Samay Sagar\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/73112080?v=4\",\n      \"profile\": \"https://github.com/samay-rgb\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"pedrobslisboa\",\n      \"name\": \"Pedro Lisboa\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/35539594?v=4\",\n      \"profile\": \"https://github.com/pedrobslisboa\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"henriqemalheiros\",\n      \"name\": \"Henrique Malheiros\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/23730762?v=4\",\n      \"profile\": \"https://github.com/henriqemalheiros\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"CaptainN\",\n      \"name\": \"Kevin Newman\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/245825?v=4\",\n      \"profile\": \"http://www.unfocus.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"a503189\",\n      \"name\": \"a503189\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/28802989?v=4\",\n      \"profile\": \"https://github.com/a503189\",\n      \"contributions\": [\"content\"]\n    },\n    {\n      \"login\": \"mod7ex\",\n      \"name\": \"Mourad EL CADI\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/72814784?v=4\",\n      \"profile\": \"https://t.me/mouradelcadi\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"Lop3sPedro\",\n      \"name\": \"Pedro Henrique Lopes\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/89090945?v=4\",\n      \"profile\": \"https://github.com/Lop3sPedro\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"danbiilee\",\n      \"name\": \"Danbi Lee\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/53761241?v=4\",\n      \"profile\": \"https://github.com/danbiilee\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"cojennin\",\n      \"name\": \"Connor Jennings\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1888152?v=4\",\n      \"profile\": \"https://github.com/cojennin\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"lgxm3z\",\n      \"name\": \"Lucas Gomes\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/28831375?v=4\",\n      \"profile\": \"https://github.com/lgxm3z\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"zaggino\",\n      \"name\": \"Martin Zagora\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1067319?v=4\",\n      \"profile\": \"https://github.com/zaggino\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"kvdo2\",\n      \"name\": \"KvD\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/78251524?v=4\",\n      \"profile\": \"https://github.com/kvdo2\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"SupraSmooth\",\n      \"name\": \"Alex\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/18029247?v=4\",\n      \"profile\": \"https://github.com/SupraSmooth\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"kaceycleveland\",\n      \"name\": \"Kacey Cleveland\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/88064187?v=4\",\n      \"profile\": \"https://github.com/kaceycleveland\",\n      \"contributions\": [\"review\"]\n    },\n    {\n      \"login\": \"oviirup\",\n      \"name\": \"Avirup Ghosh\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/49820575?v=4\",\n      \"profile\": \"https://github.com/oviirup\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"yabbal\",\n      \"name\": \"yabbal\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15120524?v=4\",\n      \"profile\": \"https://github.com/yabbal\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"patik\",\n      \"name\": \"Craig Patik\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/262137?v=4\",\n      \"profile\": \"https://patik.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Silverium\",\n      \"name\": \"Soldeplata Saketos Candela\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10578392?v=4\",\n      \"profile\": \"https://github.com/Silverium\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"TENDOUZHI\",\n      \"name\": \"TENDOUZHI\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/82806526?v=4\",\n      \"profile\": \"https://github.com/TENDOUZHI\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"wachulski\",\n      \"name\": \"Marcin Wachulski\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1669844?v=4\",\n      \"profile\": \"https://github.com/wachulski\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"salmanfazal01\",\n      \"name\": \"Salman Fazal\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15085416?v=4\",\n      \"profile\": \"https://salmans.work/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"shrugs\",\n      \"name\": \"shrugs\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1535001?v=4\",\n      \"profile\": \"https://github.com/shrugs\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Hyodori04\",\n      \"name\": \"hyodori\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/57362573?v=4\",\n      \"profile\": \"https://github.com/Hyodori04\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"eleazareramos\",\n      \"name\": \"Eleazar “E” Ramos\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/25910203?v=4\",\n      \"profile\": \"https://github.com/eleazareramos\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"retnag\",\n      \"name\": \"retnag\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/18302198?v=4\",\n      \"profile\": \"https://github.com/retnag\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"beefiker\",\n      \"name\": \"J young Lee\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/55247450?v=4\",\n      \"profile\": \"https://jaeyoung.dev/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"fiws\",\n      \"name\": \"Filip Weiss\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3409958?v=4\",\n      \"profile\": \"https://github.com/fiws\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"mariusGundersen\",\n      \"name\": \"Marius Gundersen\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/464152?v=4\",\n      \"profile\": \"https://mariusgundersen.net/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"VenomFate-619\",\n      \"name\": \"Syed Aman Ali\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/67755128?v=4\",\n      \"profile\": \"https://github.com/VenomFate-619\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"ingadi\",\n      \"name\": \"Axel Ingadi\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6121225?v=4\",\n      \"profile\": \"https://ingadi.work/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"andyjphu\",\n      \"name\": \"AndyP\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/51890861?v=4\",\n      \"profile\": \"https://github.com/andyjphu\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"ishanVaghasiya\",\n      \"name\": \"ishanVaghasiya\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/98661936?v=4\",\n      \"profile\": \"https://github.com/ishanVaghasiya\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"nico-martinucci\",\n      \"name\": \"Nico Martinucci\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/80868741?v=4\",\n      \"profile\": \"https://github.com/nico-martinucci\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"technophile-04\",\n      \"name\": \"Shiv Bhonde | shivbhonde.eth\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/80153681?v=4\",\n      \"profile\": \"https://github.com/technophile-04\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"fritzmonkey\",\n      \"name\": \"fritzmonkey\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10103840?v=4\",\n      \"profile\": \"https://github.com/fritzmonkey\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"rrmesquita\",\n      \"name\": \"Rodrigo Mesquita\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/30835404?v=4\",\n      \"profile\": \"https://github.com/rrmesquita\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"moshest\",\n      \"name\": \"Moshe Simantov\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/534911?v=4\",\n      \"profile\": \"https://moshe.io/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"BekaArabidze98\",\n      \"name\": \"Beka\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/122085038?v=4\",\n      \"profile\": \"https://github.com/BekaArabidze98\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"abdofola\",\n      \"name\": \"Abdallah Alkaser\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/30251052?v=4\",\n      \"profile\": \"https://github.com/abdofola\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"CarlosNZ\",\n      \"name\": \"Carl Smith\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/5456533?v=4\",\n      \"profile\": \"https://github.com/CarlosNZ\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"ogroppo\",\n      \"name\": \"Orlando Groppo\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/4820803?v=4\",\n      \"profile\": \"https://github.com/ogroppo\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"thany\",\n      \"name\": \"Martĳn Saly\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/152227?v=4\",\n      \"profile\": \"https://github.com/thany\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"quinn\",\n      \"name\": \"Quinn Shanahan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3764?v=4\",\n      \"profile\": \"https://quinn.io/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"AntoineKM\",\n      \"name\": \"Antoine Kingue\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/54948363?v=4\",\n      \"profile\": \"https://antoinek.fr/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"zanzlender\",\n      \"name\": \"Žan Žlender\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/44570474?v=4\",\n      \"profile\": \"https://github.com/zanzlender\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"sebadom\",\n      \"name\": \"Sebastian Dominguez\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3877952?v=4\",\n      \"profile\": \"https://github.com/sebadom\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jmc420\",\n      \"name\": \"James Cowan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/11723529?v=4\",\n      \"profile\": \"https://github.com/jmc420\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"bayraak\",\n      \"name\": \"Bayram Ali Basgul\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10470072?v=4\",\n      \"profile\": \"https://github.com/bayraak\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"WyattCast44\",\n      \"name\": \"Wyatt Castaneda\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/17957937?v=4\",\n      \"profile\": \"http://wyatt.castaneda.family/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"tsnevillecom\",\n      \"name\": \"Tim Neville\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3151454?v=4\",\n      \"profile\": \"https://github.com/tsnevillecom\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"shoooe\",\n      \"name\": \"Thomas Pigarelli\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/733227?v=4\",\n      \"profile\": \"https://github.com/shoooe\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jherdman\",\n      \"name\": \"James Herdman\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3300?v=4\",\n      \"profile\": \"https://github.com/jherdman\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"pociej\",\n      \"name\": \"Grzegorz Pociejewski\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3854675?v=4\",\n      \"profile\": \"https://github.com/pociej\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"flyon\",\n      \"name\": \"René Verheij\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/341567?v=4\",\n      \"profile\": \"https://github.com/flyon\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"PatrykKuniczak\",\n      \"name\": \"PatrykKuniczak\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/64608510?v=4\",\n      \"profile\": \"https://github.com/PatrykKuniczak\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"CroModder\",\n      \"name\": \"Paolo Božac\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/7691110?v=4\",\n      \"profile\": \"https://cromodder.github.io/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"reinos\",\n      \"name\": \"Rein\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/633730?v=4\",\n      \"profile\": \"https://github.com/reinos\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"FloorianB\",\n      \"name\": \"FloorianB\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/110407858?v=4\",\n      \"profile\": \"https://github.com/FloorianB\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"xuanhung1509\",\n      \"name\": \"Xuan Hung\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/89293664?v=4\",\n      \"profile\": \"https://github.com/xuanhung1509\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"mxvsh\",\n      \"name\": \"Monawwar Abdullah\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/31907722?v=4\",\n      \"profile\": \"https://monawwar.io/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"haroldo-ok\",\n      \"name\": \"Haroldo de Oliveira Pinheiro\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1457465?v=4\",\n      \"profile\": \"https://github.com/haroldo-ok\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"TamjidAhmed10\",\n      \"name\": \"Tamjid Ahmed\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/57794102?v=4\",\n      \"profile\": \"https://portfoliobytamjid.vercel.app/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jv-lopez\",\n      \"name\": \"jv-lopez\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/93750956?v=4\",\n      \"profile\": \"https://github.com/jv-lopez\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"callumacrae\",\n      \"name\": \"Callum Macrae\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/472830?v=4\",\n      \"profile\": \"http://macr.ae/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"0529bill\",\n      \"name\": \"bywater529\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/62455148?v=4\",\n      \"profile\": \"https://github.com/0529bill\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"kevinxh\",\n      \"name\": \"Kevin He\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10948652?v=4\",\n      \"profile\": \"https://github.com/kevinxh\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"FredericoGauz\",\n      \"name\": \"FredericoGauz\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/18327882?v=4\",\n      \"profile\": \"https://github.com/FredericoGauz\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"JonLemOfficial\",\n      \"name\": \"Jonathan \\\"JonLem\\\" Lemos\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/38771842?v=4\",\n      \"profile\": \"https://www.jonlemofficial.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"xegulon\",\n      \"name\": \"Xegulon\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/74178038?v=4\",\n      \"profile\": \"https://github.com/xegulon\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"TomSmedley\",\n      \"name\": \"Tom Smedley\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/95056193?v=4\",\n      \"profile\": \"https://github.com/TomSmedley\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"lightbluepoppy\",\n      \"name\": \"lightbluepoppy\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/65863981?v=4\",\n      \"profile\": \"https://github.com/lightbluepoppy\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Dchole\",\n      \"name\": \"Derek Oware\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/47068381?v=4\",\n      \"profile\": \"https://github.com/Dchole\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"lancegliser\",\n      \"name\": \"Lance Gliser\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/12085479?v=4\",\n      \"profile\": \"http://fragmentedthought.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"lewxdev\",\n      \"name\": \"J. Lewis\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6710419?v=4\",\n      \"profile\": \"https://github.com/lewxdev\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"yairy\",\n      \"name\": \"Yair\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3206243?v=4\",\n      \"profile\": \"https://github.com/yairy\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Nishchit14\",\n      \"name\": \"Nishchit\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/5078921?v=4\",\n      \"profile\": \"https://firecamp.dev/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Nejjer\",\n      \"name\": \"Devofy\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/80219537?v=4\",\n      \"profile\": \"https://github.com/Nejjer\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"nightness\",\n      \"name\": \"Josh Guyette\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/28668902?v=4\",\n      \"profile\": \"https://joshguyette.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"dora-ljh\",\n      \"name\": \"Dora Li\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/35205701?v=4\",\n      \"profile\": \"https://github.com/dora-ljh\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"kg-currenxie\",\n      \"name\": \"Kristian Gerardsson\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/48229166?v=4\",\n      \"profile\": \"https://github.com/kg-currenxie\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"jdpt0\",\n      \"name\": \"James Powell\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/19761394?v=4\",\n      \"profile\": \"https://github.com/jdpt0\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"boazpoolman\",\n      \"name\": \"Boaz Poolman\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/9551934?v=4\",\n      \"profile\": \"https://www.linkedin.com/in/boaz-poolman-662162115/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"roker15\",\n      \"name\": \"roker15\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/59526869?v=4\",\n      \"profile\": \"https://github.com/roker15\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"fadhilx\",\n      \"name\": \"Fadhil Ahmad\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15516786?v=4\",\n      \"profile\": \"https://github.com/fadhilx\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Chandler-Zhu\",\n      \"name\": \"Chandler-Zhu\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/61914365?v=4\",\n      \"profile\": \"https://github.com/Chandler-Zhu\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"nixjs\",\n      \"name\": \"Nghi Nguyen\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/23132483?v=4\",\n      \"profile\": \"https://github.com/nixjs\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"ShravanSunder\",\n      \"name\": \"Shravan Sunder\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/5294949?v=4\",\n      \"profile\": \"https://github.com/ShravanSunder\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"Johannes5\",\n      \"name\": \"Johannes5\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/14299835?v=4\",\n      \"profile\": \"https://github.com/Johannes5\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"sebahhpeya\",\n      \"name\": \"sebahhpeya\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/93996817?v=4\",\n      \"profile\": \"https://github.com/sebahhpeya\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"ornakash\",\n      \"name\": \"Or Nakash\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/45389557?v=4\",\n      \"profile\": \"https://onezero.co.il/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"hepiyellow\",\n      \"name\": \"Erez Makavy\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/6338722?v=4\",\n      \"profile\": \"https://github.com/hepiyellow\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"andymerskin\",\n      \"name\": \"Andy Merskin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/758090?v=4\",\n      \"profile\": \"http://andymerskin.com/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"chainalert-bot\",\n      \"name\": \"ChainAlert Bot\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/95303823?v=4\",\n      \"profile\": \"https://github.com/chainalert-bot\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"tmdesigned\",\n      \"name\": \"Taylor Morgan\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3608018?v=4\",\n      \"profile\": \"https://github.com/tmdesigned\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"wisdomabioye\",\n      \"name\": \"wisdomabioye\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/18709032?v=4\",\n      \"profile\": \"https://abkabioye.me/\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"SamuelQuinones\",\n      \"name\": \"Samuel Quiñones\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/51345689?v=4\",\n      \"profile\": \"http://www.samtheq.com\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"ymc-maha\",\n      \"name\": \"Manuel\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/697307?v=4\",\n      \"profile\": \"https://github.com/ymc-maha\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"Yurchishin\",\n      \"name\": \"Yurii Rybak\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/36650915?v=4\",\n      \"profile\": \"https://github.com/Yurchishin\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"iuriiiurevich\",\n      \"name\": \"Yury Demin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/15759600?v=4\",\n      \"profile\": \"https://github.com/iuriiiurevich\",\n      \"contributions\": [\"bug\", \"code\"]\n    },\n    {\n      \"login\": \"jontewks\",\n      \"name\": \"Jon Tewksbury\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3970573?v=4\",\n      \"profile\": \"http://tewks.io/\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"novacdenis\",\n      \"name\": \"Novac Denis\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/45555668?v=4\",\n      \"profile\": \"https://github.com/novacdenis\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"kyrylo-soulandwolf\",\n      \"name\": \"kyrylo-soulandwolf\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/54762253?v=4\",\n      \"profile\": \"https://github.com/kyrylo-soulandwolf\",\n      \"contributions\": [\"code\", \"bug\"]\n    },\n    {\n      \"login\": \"misidoro\",\n      \"name\": \"Miguel Isidoro\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/3635023?v=4\",\n      \"profile\": \"https://github.com/misidoro\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"gromchen\",\n      \"name\": \"Yuriy Gromchenko\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/828918?v=4\",\n      \"profile\": \"https://crowds.space/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"jcbhmr\",\n      \"name\": \"Jacob Hummer\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/61068799?v=4\",\n      \"profile\": \"http://jcbhmr.me\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"k-melnychuk\",\n      \"name\": \"Kyrylo Melnychuk\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/22131019?v=4\",\n      \"profile\": \"https://github.com/k-melnychuk\",\n      \"contributions\": [\"content\", \"code\"]\n    },\n    {\n      \"login\": \"LumaKernel\",\n      \"name\": \"Luma\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/29811106?v=4\",\n      \"profile\": \"https://github.com/LumaKernel\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"Newbie012\",\n      \"name\": \"Eliya Cohen\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/10504365?v=4\",\n      \"profile\": \"https://github.com/Newbie012\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"isumix\",\n      \"name\": \"Igor Sukharev\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/16747416?v=4\",\n      \"profile\": \"https://github.com/isumix\",\n      \"contributions\": [\"bug\"]\n    },\n    {\n      \"login\": \"pookmish\",\n      \"name\": \"pookmish\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/7185045?v=4\",\n      \"profile\": \"https://github.com/pookmish\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"metav-drimz\",\n      \"name\": \"metav-drimz\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/113976282?v=4\",\n      \"profile\": \"https://github.com/metav-drimz\",\n      \"contributions\": [\"ideas\"]\n    },\n    {\n      \"login\": \"luckrnx09\",\n      \"name\": \"luckrnx09\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/113882203?v=4\",\n      \"profile\": \"https://luckrnx09.com/\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"RubyHuntsman\",\n      \"name\": \"Hubert Kuczmierczyk\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/24682602?v=4\",\n      \"profile\": \"https://github.com/RubyHuntsman\",\n      \"contributions\": [\"ideas\", \"review\"]\n    },\n    {\n      \"login\": \"dandubya\",\n      \"name\": \"dandubya\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/67660308?v=4\",\n      \"profile\": \"https://github.com/dandubya\",\n      \"contributions\": [\"doc\"]\n    },\n    {\n      \"login\": \"LonelyFellas\",\n      \"name\": \"Darwish\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/38754760?v=4\",\n      \"profile\": \"https://github.com/LonelyFellas\",\n      \"contributions\": [\"code\"]\n    },\n    {\n      \"login\": \"jraoult\",\n      \"name\": \"Jonathan Raoult\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/2046871?v=4\",\n      \"profile\": \"http://www.jesuisjo.com/\",\n      \"contributions\": [\"bug\", \"review\"]\n    }\n  ],\n  \"contributorsPerLine\": 7,\n  \"commitType\": \"docs\"\n}\n\n"
  },
  {
    "path": ".changeset/README.md",
    "content": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works\nwith multi-package repos, or single-package repos to help you version and publish your code. You can\nfind the full documentation for it [in our repository](https://github.com/changesets/changesets)\n\nWe have a quick list of common questions to get you started engaging with this project in\n[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@2.3.0/schema.json\",\n  \"changelog\": \"@changesets/cli/changelog\",\n  \"commit\": false,\n  \"fixed\": [],\n  \"linked\": [],\n  \"access\": \"public\",\n  \"baseBranch\": \"master\",\n  \"updateInternalDependencies\": \"patch\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\n\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual\nidentity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or advances of\n  any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official email address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n<juliencaron@protonmail.com>.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.1, available at\n[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at\n[https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to `usehooks-ts`\n\nThanks for wanting to contribute! It's more than welcome 🤗\n\nAs the creators and maintainers of this project, we want to ensure that `usehooks-ts` lives and continues to grow and evolve. We would like to encourage everyone to help and support this library by contributing\n\n## Ways to contribute\n\n1. **Replying and handling open issues or discussions.**\n\n   We get some issues and discussions, and some of them may lack necessary information. You can help out by guiding people through the process of filling out the issue template, asking for clarifying information, or pointing them to existing issues that match their description of the problem.\n\n2. **Reviewing pull requests.**\n\n   Pull requests (PRs) are essential for introducing new features, fixing bugs, and improving the overall quality of the codebase. As a reviewer, your role is crucial in ensuring that each PR meets the project's standards and goals. Here are some key aspects to consider when reviewing pull requests:\n\n   - **Code Quality**: Examine the changes for readability, maintainability, and adherence to coding standards. Look for any potential code smells, redundant code, or opportunities for optimization.\n\n   - **Functionality**: Test the changes locally if possible to verify that they work as intended. Check if the new feature functions correctly and if the bug fixes address the reported issues.\n\n   - **Compatibility**: Ensure that the changes don't introduce breaking changes or compatibility issues with existing functionality. Consider how the changes may impact other parts of the codebase and any dependent projects.\n\n   - **Documentation**: Confirm that the PR includes any necessary updates to documentation, including code comments, README files, changesets, or API references.\n\n   - **Testing**: Assess whether the PR includes sufficient unit tests to cover the modified code. If necessary, suggest additional test cases or improvements to the testing strategy.\n\n   - **Feedback**: Provide constructive feedback to the contributor, highlighting areas for improvement and praising positive aspects of the contribution. Encourage collaboration and discussion to address any concerns or questions.\n\n   Your thorough review helps maintain the quality and stability of the project. Remember to be respectful and supportive in your feedback, fostering a positive and inclusive community for contributors.\n\n3. **Help people write unit-tests.**\n\n   Some pull requests sent to the main repository may lack a proper test plan. These help reviewers understand how the change was tested, and can speed up the time it takes for a contribution to be accepted.\n\n4. **Improving the documentation.**\n\n   Reviewing documentation updates can be as simple as checking for spelling and grammar. If you encounter situations that can be explained better in the docs, click Edit at the top of most docs pages to get started with your own contribution.\n\n5. **Contribute the to code.**\n\n   Code-level contributions to `usehooks-ts` like creating or fixing a hook generally come in the form of pull requests. These are done by forking the repo and making changes locally explained below.\n\n## Code contributions\n\nHere is a quick guide to doing code contributions to the library.\n\n1. Make sure to have the right dependencies up-to-date:\n\n   - `\"node\": \">=18.17.0\"`\n   - `\"pnpm\": \"^8\"`\n\n2. Fork and clone the repo to your local machine:\n\n   ```shellscript\n   git clone https://github.com/YOUR_GITHUB_USERNAME/usehooks-ts.git\n   ```\n\n3. Create a new branch from `master` with a meaningful name for a new feature or an issue you want to work on:\n\n   ```shellscript\n   git checkout -b your-meaningful-branch-name\n   ```\n\n4. Install packages by running:\n\n   ```shellscript\n   pnpm install\n   pnpm build\n   ```\n\n5. If you want to create a new hook, use the generator:\n\n   ```shellscript\n   pnpm gen-hook\n   ```\n\n6. Ensure your code lints without errors and the test suite still passes.\n\n   ```shellscript\n   pnpm build && pnpm lint && pnpm test\n   ```\n\n7. Try to write some unit tests to cover as much of your code as possible.\n\n8. Push your branch: `git push -u origin your-meaningful-branch-name`\n\n9. Submit a pull request to the upstream `usehooks-ts` repository.\n\n10. Choose a descriptive title and describe your changes briefly.\n\n## Coding style\n\nPlease follow the coding style of the project. `usehooks-ts` uses eslint and prettier. If possible, enable their respective plugins in your editor to get real-time feedback. The linting can be run manually with the following command: `pnpm lint` and `pnpm prettier`.\n\n## License\n\nBy contributing your code to the `usehooks-ts` GitHub repository, you agree to license your contribution under the [MIT license](https://github.com/juliencrn/usehooks-ts/blob/master/LICENSE).\n\n## Contributors\n\nBig thanks go to all our contributors! [[Become a contributor](https://github.com/juliencrn/usehooks-ts/blob/master/.github/CONTRIBUTING.md)]\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/juliencrn\"><img src=\"https://avatars.githubusercontent.com/u/14028029?v=4?s=64\" width=\"64px;\" alt=\"Julien\"/><br /><sub><b>Julien</b></sub></a><br /><a href=\"#content-juliencrn\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=juliencrn\" title=\"Code\">💻</a> <a href=\"#design-juliencrn\" title=\"Design\">🎨</a> <a href=\"#ideas-juliencrn\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a777med\"><img src=\"https://avatars.githubusercontent.com/u/15968280?v=4?s=64\" width=\"64px;\" alt=\"a777med\"/><br /><sub><b>a777med</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=a777med\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://datkira.com/\"><img src=\"https://avatars.githubusercontent.com/u/53250212?v=4?s=64\" width=\"64px;\" alt=\"Nguyen Tien Dat\"/><br /><sub><b>Nguyen Tien Dat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=datkira\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/elifer5000\"><img src=\"https://avatars.githubusercontent.com/u/4311278?v=4?s=64\" width=\"64px;\" alt=\"Elias Cohenca\"/><br /><sub><b>Elias Cohenca</b></sub></a><br /><a href=\"#content-elifer5000\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://joaov.com.br/\"><img src=\"https://avatars.githubusercontent.com/u/17601527?v=4?s=64\" width=\"64px;\" alt=\"João Deroldo\"/><br /><sub><b>João Deroldo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajoaoderoldo\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=joaoderoldo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nishit-Dua\"><img src=\"https://avatars.githubusercontent.com/u/35453301?v=4?s=64\" width=\"64px;\" alt=\"Nishit\"/><br /><sub><b>Nishit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Nishit-Dua\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonkoops\"><img src=\"https://avatars.githubusercontent.com/u/695720?v=4?s=64\" width=\"64px;\" alt=\"Jon Koops\"/><br /><sub><b>Jon Koops</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonkoops\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LoneRifle\"><img src=\"https://avatars.githubusercontent.com/u/10572368?v=4?s=64\" width=\"64px;\" alt=\"LoneRifle\"/><br /><sub><b>LoneRifle</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LoneRifle\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/vfonic\"><img src=\"https://avatars.githubusercontent.com/u/67437?v=4?s=64\" width=\"64px;\" alt=\"Viktor\"/><br /><sub><b>Viktor</b></sub></a><br /><a href=\"#ideas-vfonic\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avfonic\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bclermont\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Bruno Clermont\"/><br /><sub><b>Bruno Clermont</b></sub></a><br /><a href=\"#question-bclermont\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yoannesbourg\"><img src=\"https://avatars.githubusercontent.com/u/73404603?v=4?s=64\" width=\"64px;\" alt=\"yoannesbourg\"/><br /><sub><b>yoannesbourg</b></sub></a><br /><a href=\"#ideas-yoannesbourg\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/strange2x\"><img src=\"https://avatars.githubusercontent.com/u/10759731?v=4?s=64\" width=\"64px;\" alt=\"Strange2x\"/><br /><sub><b>Strange2x</b></sub></a><br /><a href=\"#ideas-strange2x\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/steinybot\"><img src=\"https://avatars.githubusercontent.com/u/4659562?v=4?s=64\" width=\"64px;\" alt=\"Jason Pickens\"/><br /><sub><b>Jason Pickens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asteinybot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://smackagency.com/\"><img src=\"https://avatars.githubusercontent.com/u/3469560?v=4?s=64\" width=\"64px;\" alt=\"Sel-Vin Kuik\"/><br /><sub><b>Sel-Vin Kuik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aselvinkuik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isaacalves\"><img src=\"https://avatars.githubusercontent.com/u/1765942?v=4?s=64\" width=\"64px;\" alt=\"isaac\"/><br /><sub><b>isaac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisaacalves\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/brunorzn\"><img src=\"https://avatars.githubusercontent.com/u/18266054?v=4?s=64\" width=\"64px;\" alt=\"Bruno RZN\"/><br /><sub><b>Bruno RZN</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brunorzn\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Abrunorzn\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.cykeprojects.com/\"><img src=\"https://avatars.githubusercontent.com/u/2979318?v=4?s=64\" width=\"64px;\" alt=\"Nathan Manceaux-Panot\"/><br /><sub><b>Nathan Manceaux-Panot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Cykelero\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ACykelero\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/meotimdihia\"><img src=\"https://avatars.githubusercontent.com/u/300961?v=4?s=64\" width=\"64px;\" alt=\"Dien Vu\"/><br /><sub><b>Dien Vu</b></sub></a><br /><a href=\"#ideas-meotimdihia\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/olegKusov\"><img src=\"https://avatars.githubusercontent.com/u/28058268?v=4?s=64\" width=\"64px;\" alt=\"Oleg Kusov\"/><br /><sub><b>Oleg Kusov</b></sub></a><br /><a href=\"#ideas-olegKusov\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://mattguy.me/\"><img src=\"https://avatars.githubusercontent.com/u/6647355?v=4?s=64\" width=\"64px;\" alt=\"Matthew Guy\"/><br /><sub><b>Matthew Guy</b></sub></a><br /><a href=\"#ideas-mankittens\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andrewbihl\"><img src=\"https://avatars.githubusercontent.com/u/16709744?v=4?s=64\" width=\"64px;\" alt=\"andrewbihl\"/><br /><sub><b>andrewbihl</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandrewbihl\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lancepollard\"><img src=\"https://avatars.githubusercontent.com/u/86631222?v=4?s=64\" width=\"64px;\" alt=\"lancepollard\"/><br /><sub><b>lancepollard</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancepollard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gmukul01\"><img src=\"https://avatars.githubusercontent.com/u/3636885?v=4?s=64\" width=\"64px;\" alt=\"Mukul Bansal\"/><br /><sub><b>Mukul Bansal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Agmukul01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://127.0.0.1:8000/\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Jean-Luc Mongrain sur la Brosse\"/><br /><sub><b>Jean-Luc Mongrain sur la Brosse</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jeanlucmongrain\" title=\"Code\">💻</a> <a href=\"#ideas-jeanlucmongrain\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/n1c\"><img src=\"https://avatars.githubusercontent.com/u/284075?v=4?s=64\" width=\"64px;\" alt=\"Nic\"/><br /><sub><b>Nic</b></sub></a><br /><a href=\"#content-n1c\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://valtism.com/\"><img src=\"https://avatars.githubusercontent.com/u/1286001?v=4?s=64\" width=\"64px;\" alt=\"Dan Wood\"/><br /><sub><b>Dan Wood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valtism\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.sixt.de/\"><img src=\"https://avatars.githubusercontent.com/u/25299148?v=4?s=64\" width=\"64px;\" alt=\"jo wendenbuerger\"/><br /><sub><b>jo wendenbuerger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWendenburg\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://nozillium.com/\"><img src=\"https://avatars.githubusercontent.com/u/4774875?v=4?s=64\" width=\"64px;\" alt=\"Andrew Nosenko\"/><br /><sub><b>Andrew Nosenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anoseratio\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CharlieJhonSmith\"><img src=\"https://avatars.githubusercontent.com/u/90845154?v=4?s=64\" width=\"64px;\" alt=\"CharlieJhonSmith\"/><br /><sub><b>CharlieJhonSmith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CharlieJhonSmith\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://keybase.io/soullivaneuh\"><img src=\"https://avatars.githubusercontent.com/u/1698357?v=4?s=64\" width=\"64px;\" alt=\"Sullivan SENECHAL\"/><br /><sub><b>Sullivan SENECHAL</b></sub></a><br /><a href=\"#ideas-soullivaneuh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asoullivaneuh\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=soullivaneuh\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jaslong\"><img src=\"https://avatars.githubusercontent.com/u/797348?v=4?s=64\" width=\"64px;\" alt=\"Jason Long\"/><br /><sub><b>Jason Long</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajaslong\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kxm766\"><img src=\"https://avatars.githubusercontent.com/u/88443148?v=4?s=64\" width=\"64px;\" alt=\"kxm766\"/><br /><sub><b>kxm766</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akxm766\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://qlaffont.com/\"><img src=\"https://avatars.githubusercontent.com/u/10044790?v=4?s=64\" width=\"64px;\" alt=\"Quentin\"/><br /><sub><b>Quentin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=qlaffont\" title=\"Code\">💻</a> <a href=\"#ideas-qlaffont\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#content-qlaffont\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ducktordanny\"><img src=\"https://avatars.githubusercontent.com/u/38068717?v=4?s=64\" width=\"64px;\" alt=\"Daniel Lazar\"/><br /><sub><b>Daniel Lazar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ducktordanny\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aducktordanny\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mterrel\"><img src=\"https://avatars.githubusercontent.com/u/17746857?v=4?s=64\" width=\"64px;\" alt=\"Mark Terrel\"/><br /><sub><b>Mark Terrel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amterrel\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mterrel\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mendrik\"><img src=\"https://avatars.githubusercontent.com/u/160805?v=4?s=64\" width=\"64px;\" alt=\"Andreas Herd\"/><br /><sub><b>Andreas Herd</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amendrik\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sonjoydatta.me/\"><img src=\"https://avatars.githubusercontent.com/u/49079726?v=4?s=64\" width=\"64px;\" alt=\"Sonjoy Datta\"/><br /><sub><b>Sonjoy Datta</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sonjoydatta\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oluckyman\"><img src=\"https://avatars.githubusercontent.com/u/642673?v=4?s=64\" width=\"64px;\" alt=\"Ilya Belsky\"/><br /><sub><b>Ilya Belsky</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoluckyman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jamesbarrett.io/\"><img src=\"https://avatars.githubusercontent.com/u/42980207?v=4?s=64\" width=\"64px;\" alt=\"James Barrett\"/><br /><sub><b>James Barrett</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=JamesBarrettDev\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AbbalYouness\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"AbbalYouness\"/><br /><sub><b>AbbalYouness</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AbbalYouness\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/DidrikLind\"><img src=\"https://avatars.githubusercontent.com/u/14201715?v=4?s=64\" width=\"64px;\" alt=\"didriklind\"/><br /><sub><b>didriklind</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Tests\">⚠️</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hexp1989\"><img src=\"https://avatars.githubusercontent.com/u/2241985?v=4?s=64\" width=\"64px;\" alt=\"hexp1989\"/><br /><sub><b>hexp1989</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hexp1989\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/alvaro-serrano-rivas/\"><img src=\"https://avatars.githubusercontent.com/u/43758471?v=4?s=64\" width=\"64px;\" alt=\"Alvaro Serrano\"/><br /><sub><b>Alvaro Serrano</b></sub></a><br /><a href=\"#content-alvaroserrrano\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/egehandulger\"><img src=\"https://avatars.githubusercontent.com/u/14878259?v=4?s=64\" width=\"64px;\" alt=\"Egehan Dülger\"/><br /><sub><b>Egehan Dülger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=egehandulger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PabloLION\"><img src=\"https://avatars.githubusercontent.com/u/36828324?v=4?s=64\" width=\"64px;\" alt=\"PabloLION\"/><br /><sub><b>PabloLION</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APabloLION\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=PabloLION\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://davidsanchez.me/\"><img src=\"https://avatars.githubusercontent.com/u/84061?v=4?s=64\" width=\"64px;\" alt=\"David Sanchez\"/><br /><sub><b>David Sanchez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aemulienfou\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AjayTheWizard\"><img src=\"https://avatars.githubusercontent.com/u/92772740?v=4?s=64\" width=\"64px;\" alt=\"Ajay Raja\"/><br /><sub><b>Ajay Raja</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAjayTheWizard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"#ideas-docmars\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/GrayGalaxy\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=GrayGalaxy\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGrayGalaxy\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tilnea\"><img src=\"https://avatars.githubusercontent.com/u/3692320?v=4?s=64\" width=\"64px;\" alt=\"Sanne Wintrén\"/><br /><sub><b>Sanne Wintrén</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atilnea\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://lacolonia.studio/\"><img src=\"https://avatars.githubusercontent.com/u/1528468?v=4?s=64\" width=\"64px;\" alt=\"Alessandro\"/><br /><sub><b>Alessandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aa-barbieri\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/atatarenko\"><img src=\"https://avatars.githubusercontent.com/u/9846273?v=4?s=64\" width=\"64px;\" alt=\"Andrey Tatarenko\"/><br /><sub><b>Andrey Tatarenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aatatarenko\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/arusak\"><img src=\"https://avatars.githubusercontent.com/u/4231915?v=4?s=64\" width=\"64px;\" alt=\"Anton Rusak\"/><br /><sub><b>Anton Rusak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aarusak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/createdbymahmood\"><img src=\"https://avatars.githubusercontent.com/u/40164360?v=4?s=64\" width=\"64px;\" alt=\"Mahmood Bagheri\"/><br /><sub><b>Mahmood Bagheri</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=createdbymahmood\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://wpowner.com/\"><img src=\"https://avatars.githubusercontent.com/u/506491?v=4?s=64\" width=\"64px;\" alt=\"Anver Sadutt\"/><br /><sub><b>Anver Sadutt</b></sub></a><br /><a href=\"#content-anver\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bogdanailincaipnt\"><img src=\"https://avatars.githubusercontent.com/u/93596663?v=4?s=64\" width=\"64px;\" alt=\"Bogdan Ailincai\"/><br /><sub><b>Bogdan Ailincai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bogdanailincaipnt\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SimeonGriggs\"><img src=\"https://avatars.githubusercontent.com/u/9684022?v=4?s=64\" width=\"64px;\" alt=\"Simeon Griggs\"/><br /><sub><b>Simeon Griggs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ASimeonGriggs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Kepro\"><img src=\"https://avatars.githubusercontent.com/u/1714370?v=4?s=64\" width=\"64px;\" alt=\"Kepro\"/><br /><sub><b>Kepro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AKepro\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Jake-Lippert\"><img src=\"https://avatars.githubusercontent.com/u/17753127?v=4?s=64\" width=\"64px;\" alt=\"Jake Lippert\"/><br /><sub><b>Jake Lippert</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJake-Lippert\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TunA-Kai\"><img src=\"https://avatars.githubusercontent.com/u/92641762?v=4?s=64\" width=\"64px;\" alt=\"Tu Nguyen Anh\"/><br /><sub><b>Tu Nguyen Anh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATunA-Kai\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TunA-Kai\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/skve\"><img src=\"https://avatars.githubusercontent.com/u/47612057?v=4?s=64\" width=\"64px;\" alt=\"Luke Shiels\"/><br /><sub><b>Luke Shiels</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Askve\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SleLLl\"><img src=\"https://avatars.githubusercontent.com/u/66108429?v=4?s=64\" width=\"64px;\" alt=\"Sergei Kolyago\"/><br /><sub><b>Sergei Kolyago</b></sub></a><br /><a href=\"#ideas-SleLLl\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/adhamaa\"><img src=\"https://avatars.githubusercontent.com/u/50027371?v=4?s=64\" width=\"64px;\" alt=\"Adham Akmal Azmi\"/><br /><sub><b>Adham Akmal Azmi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aadhamaa\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alex-kowalczyk\"><img src=\"https://avatars.githubusercontent.com/u/7422175?v=4?s=64\" width=\"64px;\" alt=\"Alek Kowalczyk\"/><br /><sub><b>Alek Kowalczyk</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aalex-kowalczyk\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Scalahansolo\"><img src=\"https://avatars.githubusercontent.com/u/4317253?v=4?s=64\" width=\"64px;\" alt=\"Sean Callahan\"/><br /><sub><b>Sean Callahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AScalahansolo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jbean96\"><img src=\"https://avatars.githubusercontent.com/u/22803097?v=4?s=64\" width=\"64px;\" alt=\"Joshua Bean\"/><br /><sub><b>Joshua Bean</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jbean96\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajbean96\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ZhaoTim\"><img src=\"https://avatars.githubusercontent.com/u/30540533?v=4?s=64\" width=\"64px;\" alt=\"Tim Zhao\"/><br /><sub><b>Tim Zhao</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AZhaoTim\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/patryk-smc\"><img src=\"https://avatars.githubusercontent.com/u/37963339?v=4?s=64\" width=\"64px;\" alt=\"Patrick\"/><br /><sub><b>Patrick</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatryk-smc\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://bryce.io/\"><img src=\"https://avatars.githubusercontent.com/u/3171252?v=4?s=64\" width=\"64px;\" alt=\"Bryce Dorn\"/><br /><sub><b>Bryce Dorn</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brycedorn\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/angusd3v\"><img src=\"https://avatars.githubusercontent.com/u/52683145?v=4?s=64\" width=\"64px;\" alt=\"angusd3v\"/><br /><sub><b>angusd3v</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=angusd3v\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ddisimone\"><img src=\"https://avatars.githubusercontent.com/u/78792352?v=4?s=64\" width=\"64px;\" alt=\"Davide Di Simone\"/><br /><sub><b>Davide Di Simone</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Addisimone\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherr\"><img src=\"https://avatars.githubusercontent.com/u/22392?v=4?s=64\" width=\"64px;\" alt=\"Jack Herrington\"/><br /><sub><b>Jack Herrington</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherr\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sharvit.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/1262502?v=4?s=64\" width=\"64px;\" alt=\"Avi Sharvit\"/><br /><sub><b>Avi Sharvit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sharvit\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asharvit\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmaties\"><img src=\"https://avatars.githubusercontent.com/u/16613184?v=4?s=64\" width=\"64px;\" alt=\"Nicolae Maties\"/><br /><sub><b>Nicolae Maties</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmaties\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/secretshardul\"><img src=\"https://avatars.githubusercontent.com/u/49580849?v=4?s=64\" width=\"64px;\" alt=\"Shardul Aeer\"/><br /><sub><b>Shardul Aeer</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asecretshardul\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/herlon214\"><img src=\"https://avatars.githubusercontent.com/u/3419441?v=4?s=64\" width=\"64px;\" alt=\"Herlon Aguiar\"/><br /><sub><b>Herlon Aguiar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aherlon214\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alexisoney\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"Alexis Oney\"/><br /><sub><b>Alexis Oney</b></sub></a><br /><a href=\"#content-alexisoney\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://convictional.com/\"><img src=\"https://avatars.githubusercontent.com/u/96080054?v=4?s=64\" width=\"64px;\" alt=\"curtvict\"/><br /><sub><b>curtvict</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=curtvict\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/JoshuaCS94\"><img src=\"https://avatars.githubusercontent.com/u/23385700?v=4?s=64\" width=\"64px;\" alt=\"Josué Cortina\"/><br /><sub><b>Josué Cortina</b></sub></a><br /><a href=\"#content-JoshuaCS94\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://katt.dev/\"><img src=\"https://avatars.githubusercontent.com/u/459267?v=4?s=64\" width=\"64px;\" alt=\"Alex / KATT\"/><br /><sub><b>Alex / KATT</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KATT\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/modex98\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=modex98\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amodex98\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Guesswhoitis\"><img src=\"https://avatars.githubusercontent.com/u/63756285?v=4?s=64\" width=\"64px;\" alt=\"James Hulena\"/><br /><sub><b>James Hulena</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGuesswhoitis\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://hailwood.nz/\"><img src=\"https://avatars.githubusercontent.com/u/709773?v=4?s=64\" width=\"64px;\" alt=\"Matthew Hailwood\"/><br /><sub><b>Matthew Hailwood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hailwood\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ahailwood\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mike247\"><img src=\"https://avatars.githubusercontent.com/u/676071?v=4?s=64\" width=\"64px;\" alt=\"Michael Norrie\"/><br /><sub><b>Michael Norrie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amike247\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valentinpolitov\"><img src=\"https://avatars.githubusercontent.com/u/39585375?v=4?s=64\" width=\"64px;\" alt=\"Valentin Politov\"/><br /><sub><b>Valentin Politov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valentinpolitov\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/marnusw\"><img src=\"https://avatars.githubusercontent.com/u/971499?v=4?s=64\" width=\"64px;\" alt=\"Marnus Weststrate\"/><br /><sub><b>Marnus Weststrate</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=marnusw\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mancuoj\"><img src=\"https://avatars.githubusercontent.com/u/45707684?v=4?s=64\" width=\"64px;\" alt=\"mancuoj\"/><br /><sub><b>mancuoj</b></sub></a><br /><a href=\"#content-mancuoj\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.chatsumlin.com/\"><img src=\"https://avatars.githubusercontent.com/u/3067479?v=4?s=64\" width=\"64px;\" alt=\"Chat Sumlin\"/><br /><sub><b>Chat Sumlin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jcsumlin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/owenshaupt\"><img src=\"https://avatars.githubusercontent.com/u/52288188?v=4?s=64\" width=\"64px;\" alt=\"Owen Haupt\"/><br /><sub><b>Owen Haupt</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aowenshaupt\" title=\"Bug reports\">🐛</a> <a href=\"#content-owenshaupt\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ubarbaxor\"><img src=\"https://avatars.githubusercontent.com/u/26365493?v=4?s=64\" width=\"64px;\" alt=\"ubarbaxor\"/><br /><sub><b>ubarbaxor</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ubarbaxor\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://michael.mior.ca/\"><img src=\"https://avatars.githubusercontent.com/u/82501?v=4?s=64\" width=\"64px;\" alt=\"Michael Mior\"/><br /><sub><b>Michael Mior</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amichaelmior\" title=\"Bug reports\">🐛</a> <a href=\"#content-michaelmior\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pkhodaveissi\"><img src=\"https://avatars.githubusercontent.com/u/4170795?v=4?s=64\" width=\"64px;\" alt=\"Pierre\"/><br /><sub><b>Pierre</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=pkhodaveissi\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/harrywebdev\"><img src=\"https://avatars.githubusercontent.com/u/3617415?v=4?s=64\" width=\"64px;\" alt=\"Harry B\"/><br /><sub><b>Harry B</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharrywebdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valyrie97\"><img src=\"https://avatars.githubusercontent.com/u/6365746?v=4?s=64\" width=\"64px;\" alt=\"Valerie\"/><br /><sub><b>Valerie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avalyrie97\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valyrie97\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://svachon.com/\"><img src=\"https://avatars.githubusercontent.com/u/170197?v=4?s=64\" width=\"64px;\" alt=\"Steven Vachon\"/><br /><sub><b>Steven Vachon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=stevenvachon\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sskirby\"><img src=\"https://avatars.githubusercontent.com/u/25760?v=4?s=64\" width=\"64px;\" alt=\"Sean Kirby\"/><br /><sub><b>Sean Kirby</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AlecsFarias\"><img src=\"https://avatars.githubusercontent.com/u/91743821?v=4?s=64\" width=\"64px;\" alt=\"Alecsander Farias\"/><br /><sub><b>Alecsander Farias</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AlecsFarias\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://blankparticle.in/\"><img src=\"https://avatars.githubusercontent.com/u/130567419?v=4?s=64\" width=\"64px;\" alt=\"Rahul Mishra\"/><br /><sub><b>Rahul Mishra</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BlankParticle\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ABlankParticle\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"#content-BlankParticle\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bryantcodesart\"><img src=\"https://avatars.githubusercontent.com/u/14097078?v=4?s=64\" width=\"64px;\" alt=\"Bryant Smith\"/><br /><sub><b>Bryant Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bryantcodesart\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abryantcodesart\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RobHannay\"><img src=\"https://avatars.githubusercontent.com/u/609062?v=4?s=64\" width=\"64px;\" alt=\"Rob Hannay\"/><br /><sub><b>Rob Hannay</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=RobHannay\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hooriza\"><img src=\"https://avatars.githubusercontent.com/u/507927?v=4?s=64\" width=\"64px;\" alt=\"Hooriza\"/><br /><sub><b>Hooriza</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hooriza\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahooriza\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShanSenanayake\"><img src=\"https://avatars.githubusercontent.com/u/8779685?v=4?s=64\" width=\"64px;\" alt=\"ShanSenanayake\"/><br /><sub><b>ShanSenanayake</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ShanSenanayake\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/philipgher\"><img src=\"https://avatars.githubusercontent.com/u/32325241?v=4?s=64\" width=\"64px;\" alt=\"Philip Ghering\"/><br /><sub><b>Philip Ghering</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=philipgher\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ladislasdellinger\"><img src=\"https://avatars.githubusercontent.com/u/111739019?v=4?s=64\" width=\"64px;\" alt=\"Ladislas Dellinger\"/><br /><sub><b>Ladislas Dellinger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ladislasdellinger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TheHaff\"><img src=\"https://avatars.githubusercontent.com/u/2486653?v=4?s=64\" width=\"64px;\" alt=\"Haff\"/><br /><sub><b>Haff</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TheHaff\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lisandro52\"><img src=\"https://avatars.githubusercontent.com/u/5612241?v=4?s=64\" width=\"64px;\" alt=\"Lisandro\"/><br /><sub><b>Lisandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lisandro52\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/amirking59\"><img src=\"https://avatars.githubusercontent.com/u/58273240?v=4?s=64\" width=\"64px;\" alt=\"Amir hossein rezaei\"/><br /><sub><b>Amir hossein rezaei</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=amirking59\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmacianx\"><img src=\"https://avatars.githubusercontent.com/u/40004186?v=4?s=64\" width=\"64px;\" alt=\"Nicolas Macian\"/><br /><sub><b>Nicolas Macian</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmacianx\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nmacianx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://dreamsof.dev/\"><img src=\"https://avatars.githubusercontent.com/u/13162026?v=4?s=64\" width=\"64px;\" alt=\"Nate Forsyth\"/><br /><sub><b>Nate Forsyth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nateforsyth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/satelllte\"><img src=\"https://avatars.githubusercontent.com/u/20585619?v=4?s=64\" width=\"64px;\" alt=\"satelllte\"/><br /><sub><b>satelllte</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=satelllte\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asatelllte\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fedemp\"><img src=\"https://avatars.githubusercontent.com/u/735314?v=4?s=64\" width=\"64px;\" alt=\"Federico Panico\"/><br /><sub><b>Federico Panico</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=fedemp\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iamwillnbcu\"><img src=\"https://avatars.githubusercontent.com/u/137317773?v=4?s=64\" width=\"64px;\" alt=\"William Pei Yuan\"/><br /><sub><b>William Pei Yuan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iamwillnbcu\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.gazeta-cu-anunturi.ro/\"><img src=\"https://avatars.githubusercontent.com/u/757999?v=4?s=64\" width=\"64px;\" alt=\"Mihai\"/><br /><sub><b>Mihai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DarkAng3L\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADarkAng3L\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://habib.ogunsola.me/\"><img src=\"https://avatars.githubusercontent.com/u/39172573?v=4?s=64\" width=\"64px;\" alt=\"Habib Ogunsola\"/><br /><sub><b>Habib Ogunsola</b></sub></a><br /><a href=\"#content-ogunsolahabib\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ashfurrow.com/\"><img src=\"https://avatars.githubusercontent.com/u/498212?v=4?s=64\" width=\"64px;\" alt=\"Ash Furrow\"/><br /><sub><b>Ash Furrow</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ashfurrow\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://turus.ro/\"><img src=\"https://avatars.githubusercontent.com/u/32390499?v=4?s=64\" width=\"64px;\" alt=\"Daniel Turuș\"/><br /><sub><b>Daniel Turuș</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danielturus\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/rahulchaudhary2244/\"><img src=\"https://avatars.githubusercontent.com/u/54467972?v=4?s=64\" width=\"64px;\" alt=\"Rahul Chaudhary\"/><br /><sub><b>Rahul Chaudhary</b></sub></a><br /><a href=\"#content-rahulchaudhary2244\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arahulchaudhary2244\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Joshyahweh\"><img src=\"https://avatars.githubusercontent.com/u/61137067?v=4?s=64\" width=\"64px;\" alt=\"Joshua Ojoawo\"/><br /><sub><b>Joshua Ojoawo</b></sub></a><br /><a href=\"#ideas-Joshyahweh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJoshyahweh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jackdh.com/\"><img src=\"https://avatars.githubusercontent.com/u/1907451?v=4?s=64\" width=\"64px;\" alt=\"Jack\"/><br /><sub><b>Jack</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jackdh\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonlinkens\"><img src=\"https://avatars.githubusercontent.com/u/20417521?v=4?s=64\" width=\"64px;\" alt=\"Jon Linkens\"/><br /><sub><b>Jon Linkens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonlinkens\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajonlinkens\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://velog.io/@ojj1123\"><img src=\"https://avatars.githubusercontent.com/u/33178048?v=4?s=64\" width=\"64px;\" alt=\"Jeongjin Oh\"/><br /><sub><b>Jeongjin Oh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aojj1123\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tli26\"><img src=\"https://avatars.githubusercontent.com/u/114947190?v=4?s=64\" width=\"64px;\" alt=\"Tianning Li\"/><br /><sub><b>Tianning Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=tli26\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://larsartmann.com/\"><img src=\"https://avatars.githubusercontent.com/u/23587853?v=4?s=64\" width=\"64px;\" alt=\"Lars Artmann\"/><br /><sub><b>Lars Artmann</b></sub></a><br /><a href=\"#content-LarsArtmann\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/KBobovskiy\"><img src=\"https://avatars.githubusercontent.com/u/35502578?v=4?s=64\" width=\"64px;\" alt=\"KBobovskiy\"/><br /><sub><b>KBobovskiy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KBobovskiy\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ryngonzalez\"><img src=\"https://avatars.githubusercontent.com/u/635300?v=4?s=64\" width=\"64px;\" alt=\"✨ Kathryn Gonzalez ✨\"/><br /><sub><b>✨ Kathryn Gonzalez ✨</b></sub></a><br /><a href=\"#content-ryngonzalez\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/slavik-chapelskyi\"><img src=\"https://avatars.githubusercontent.com/u/33541009?v=4?s=64\" width=\"64px;\" alt=\"Yaroslav Chapelskyi\"/><br /><sub><b>Yaroslav Chapelskyi</b></sub></a><br /><a href=\"#content-slavik-chapelskyi\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sverps\"><img src=\"https://avatars.githubusercontent.com/u/15879327?v=4?s=64\" width=\"64px;\" alt=\"Samuel Van Erps\"/><br /><sub><b>Samuel Van Erps</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Asverps\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ojolowoblue\"><img src=\"https://avatars.githubusercontent.com/u/104099474?v=4?s=64\" width=\"64px;\" alt=\"ojolowoblue\"/><br /><sub><b>ojolowoblue</b></sub></a><br /><a href=\"#content-ojolowoblue\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://short.io/\"><img src=\"https://avatars.githubusercontent.com/u/75169?v=4?s=64\" width=\"64px;\" alt=\"Andrii Kostenko\"/><br /><sub><b>Andrii Kostenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gugu\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AkeemAllen\"><img src=\"https://avatars.githubusercontent.com/u/32404761?v=4?s=64\" width=\"64px;\" alt=\"Akeem Allen\"/><br /><sub><b>Akeem Allen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AkeemAllen\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAkeemAllen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/trongbinh15\"><img src=\"https://avatars.githubusercontent.com/u/43725147?v=4?s=64\" width=\"64px;\" alt=\"trongbinhnguyen\"/><br /><sub><b>trongbinhnguyen</b></sub></a><br /><a href=\"#content-trongbinh15\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://lawlesx.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/52166437?v=4?s=64\" width=\"64px;\" alt=\"Aniruddha Sil\"/><br /><sub><b>Aniruddha Sil</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lawlesx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/okinawaa\"><img src=\"https://avatars.githubusercontent.com/u/69495129?v=4?s=64\" width=\"64px;\" alt=\"박찬혁\"/><br /><sub><b>박찬혁</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Aokinawaa\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://anishchhetri.com.np/\"><img src=\"https://avatars.githubusercontent.com/u/98446102?v=4?s=64\" width=\"64px;\" alt=\"Anish\"/><br /><sub><b>Anish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novanish\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://hutri.fi/\"><img src=\"https://avatars.githubusercontent.com/u/55588133?v=4?s=64\" width=\"64px;\" alt=\"Hugo Hutri\"/><br /><sub><b>Hugo Hutri</b></sub></a><br /><a href=\"#content-hugohutri\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://balzguenat.ch/\"><img src=\"https://avatars.githubusercontent.com/u/6719014?v=4?s=64\" width=\"64px;\" alt=\"Balz Guenat\"/><br /><sub><b>Balz Guenat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BalzGuenat\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ottergeorge\"><img src=\"https://avatars.githubusercontent.com/u/108759685?v=4?s=64\" width=\"64px;\" alt=\"OtterGeorge\"/><br /><sub><b>OtterGeorge</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ottergeorge\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/samay-rgb\"><img src=\"https://avatars.githubusercontent.com/u/73112080?v=4?s=64\" width=\"64px;\" alt=\"Samay Sagar\"/><br /><sub><b>Samay Sagar</b></sub></a><br /><a href=\"#content-samay-rgb\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pedrobslisboa\"><img src=\"https://avatars.githubusercontent.com/u/35539594?v=4?s=64\" width=\"64px;\" alt=\"Pedro Lisboa\"/><br /><sub><b>Pedro Lisboa</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apedrobslisboa\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/henriqemalheiros\"><img src=\"https://avatars.githubusercontent.com/u/23730762?v=4?s=64\" width=\"64px;\" alt=\"Henrique Malheiros\"/><br /><sub><b>Henrique Malheiros</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahenriqemalheiros\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.unfocus.com/\"><img src=\"https://avatars.githubusercontent.com/u/245825?v=4?s=64\" width=\"64px;\" alt=\"Kevin Newman\"/><br /><sub><b>Kevin Newman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CaptainN\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a503189\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"a503189\"/><br /><sub><b>a503189</b></sub></a><br /><a href=\"#content-a503189\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://t.me/mouradelcadi\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mod7ex\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Lop3sPedro\"><img src=\"https://avatars.githubusercontent.com/u/89090945?v=4?s=64\" width=\"64px;\" alt=\"Pedro Henrique Lopes\"/><br /><sub><b>Pedro Henrique Lopes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Lop3sPedro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/danbiilee\"><img src=\"https://avatars.githubusercontent.com/u/53761241?v=4?s=64\" width=\"64px;\" alt=\"Danbi Lee\"/><br /><sub><b>Danbi Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danbiilee\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/cojennin\"><img src=\"https://avatars.githubusercontent.com/u/1888152?v=4?s=64\" width=\"64px;\" alt=\"Connor Jennings\"/><br /><sub><b>Connor Jennings</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=cojennin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lgxm3z\"><img src=\"https://avatars.githubusercontent.com/u/28831375?v=4?s=64\" width=\"64px;\" alt=\"Lucas Gomes\"/><br /><sub><b>Lucas Gomes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Algxm3z\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lgxm3z\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zaggino\"><img src=\"https://avatars.githubusercontent.com/u/1067319?v=4?s=64\" width=\"64px;\" alt=\"Martin Zagora\"/><br /><sub><b>Martin Zagora</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=zaggino\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kvdo2\"><img src=\"https://avatars.githubusercontent.com/u/78251524?v=4?s=64\" width=\"64px;\" alt=\"KvD\"/><br /><sub><b>KvD</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kvdo2\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SupraSmooth\"><img src=\"https://avatars.githubusercontent.com/u/18029247?v=4?s=64\" width=\"64px;\" alt=\"Alex\"/><br /><sub><b>Alex</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=SupraSmooth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kaceycleveland\"><img src=\"https://avatars.githubusercontent.com/u/88064187?v=4?s=64\" width=\"64px;\" alt=\"Kacey Cleveland\"/><br /><sub><b>Kacey Cleveland</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Akaceycleveland\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oviirup\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoviirup\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yabbal\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"yabbal\"/><br /><sub><b>yabbal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=yabbal\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://patik.com/\"><img src=\"https://avatars.githubusercontent.com/u/262137?v=4?s=64\" width=\"64px;\" alt=\"Craig Patik\"/><br /><sub><b>Craig Patik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Silverium\"><img src=\"https://avatars.githubusercontent.com/u/10578392?v=4?s=64\" width=\"64px;\" alt=\"Soldeplata Saketos Candela\"/><br /><sub><b>Soldeplata Saketos Candela</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Silverium\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TENDOUZHI\"><img src=\"https://avatars.githubusercontent.com/u/82806526?v=4?s=64\" width=\"64px;\" alt=\"TENDOUZHI\"/><br /><sub><b>TENDOUZHI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATENDOUZHI\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/wachulski\"><img src=\"https://avatars.githubusercontent.com/u/1669844?v=4?s=64\" width=\"64px;\" alt=\"Marcin Wachulski\"/><br /><sub><b>Marcin Wachulski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awachulski\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://salmans.work/\"><img src=\"https://avatars.githubusercontent.com/u/15085416?v=4?s=64\" width=\"64px;\" alt=\"Salman Fazal\"/><br /><sub><b>Salman Fazal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asalmanfazal01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shrugs\"><img src=\"https://avatars.githubusercontent.com/u/1535001?v=4?s=64\" width=\"64px;\" alt=\"shrugs\"/><br /><sub><b>shrugs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashrugs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Hyodori04\"><img src=\"https://avatars.githubusercontent.com/u/57362573?v=4?s=64\" width=\"64px;\" alt=\"hyodori\"/><br /><sub><b>hyodori</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AHyodori04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/eleazareramos\"><img src=\"https://avatars.githubusercontent.com/u/25910203?v=4?s=64\" width=\"64px;\" alt=\"Eleazar “E” Ramos\"/><br /><sub><b>Eleazar “E” Ramos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aeleazareramos\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/retnag\"><img src=\"https://avatars.githubusercontent.com/u/18302198?v=4?s=64\" width=\"64px;\" alt=\"retnag\"/><br /><sub><b>retnag</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aretnag\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jaeyoung.dev/\"><img src=\"https://avatars.githubusercontent.com/u/55247450?v=4?s=64\" width=\"64px;\" alt=\"J young Lee\"/><br /><sub><b>J young Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abeefiker\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fiws\"><img src=\"https://avatars.githubusercontent.com/u/3409958?v=4?s=64\" width=\"64px;\" alt=\"Filip Weiss\"/><br /><sub><b>Filip Weiss</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afiws\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://mariusgundersen.net/\"><img src=\"https://avatars.githubusercontent.com/u/464152?v=4?s=64\" width=\"64px;\" alt=\"Marius Gundersen\"/><br /><sub><b>Marius Gundersen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AmariusGundersen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/VenomFate-619\"><img src=\"https://avatars.githubusercontent.com/u/67755128?v=4?s=64\" width=\"64px;\" alt=\"Syed Aman Ali\"/><br /><sub><b>Syed Aman Ali</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AVenomFate-619\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ingadi.work/\"><img src=\"https://avatars.githubusercontent.com/u/6121225?v=4?s=64\" width=\"64px;\" alt=\"Axel Ingadi\"/><br /><sub><b>Axel Ingadi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aingadi\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andyjphu\"><img src=\"https://avatars.githubusercontent.com/u/51890861?v=4?s=64\" width=\"64px;\" alt=\"AndyP\"/><br /><sub><b>AndyP</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandyjphu\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ishanVaghasiya\"><img src=\"https://avatars.githubusercontent.com/u/98661936?v=4?s=64\" width=\"64px;\" alt=\"ishanVaghasiya\"/><br /><sub><b>ishanVaghasiya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AishanVaghasiya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nico-martinucci\"><img src=\"https://avatars.githubusercontent.com/u/80868741?v=4?s=64\" width=\"64px;\" alt=\"Nico Martinucci\"/><br /><sub><b>Nico Martinucci</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anico-martinucci\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/technophile-04\"><img src=\"https://avatars.githubusercontent.com/u/80153681?v=4?s=64\" width=\"64px;\" alt=\"Shiv Bhonde &#124; shivbhonde.eth\"/><br /><sub><b>Shiv Bhonde &#124; shivbhonde.eth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atechnophile-04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fritzmonkey\"><img src=\"https://avatars.githubusercontent.com/u/10103840?v=4?s=64\" width=\"64px;\" alt=\"fritzmonkey\"/><br /><sub><b>fritzmonkey</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afritzmonkey\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/rrmesquita\"><img src=\"https://avatars.githubusercontent.com/u/30835404?v=4?s=64\" width=\"64px;\" alt=\"Rodrigo Mesquita\"/><br /><sub><b>Rodrigo Mesquita</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arrmesquita\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://moshe.io/\"><img src=\"https://avatars.githubusercontent.com/u/534911?v=4?s=64\" width=\"64px;\" alt=\"Moshe Simantov\"/><br /><sub><b>Moshe Simantov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amoshest\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/BekaArabidze98\"><img src=\"https://avatars.githubusercontent.com/u/122085038?v=4?s=64\" width=\"64px;\" alt=\"Beka\"/><br /><sub><b>Beka</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ABekaArabidze98\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/abdofola\"><img src=\"https://avatars.githubusercontent.com/u/30251052?v=4?s=64\" width=\"64px;\" alt=\"Abdallah Alkaser\"/><br /><sub><b>Abdallah Alkaser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aabdofola\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=abdofola\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CarlosNZ\"><img src=\"https://avatars.githubusercontent.com/u/5456533?v=4?s=64\" width=\"64px;\" alt=\"Carl Smith\"/><br /><sub><b>Carl Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACarlosNZ\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ogroppo\"><img src=\"https://avatars.githubusercontent.com/u/4820803?v=4?s=64\" width=\"64px;\" alt=\"Orlando Groppo\"/><br /><sub><b>Orlando Groppo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aogroppo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/thany\"><img src=\"https://avatars.githubusercontent.com/u/152227?v=4?s=64\" width=\"64px;\" alt=\"Martĳn Saly\"/><br /><sub><b>Martĳn Saly</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Athany\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://quinn.io/\"><img src=\"https://avatars.githubusercontent.com/u/3764?v=4?s=64\" width=\"64px;\" alt=\"Quinn Shanahan\"/><br /><sub><b>Quinn Shanahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aquinn\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://antoinek.fr/\"><img src=\"https://avatars.githubusercontent.com/u/54948363?v=4?s=64\" width=\"64px;\" alt=\"Antoine Kingue\"/><br /><sub><b>Antoine Kingue</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAntoineKM\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zanzlender\"><img src=\"https://avatars.githubusercontent.com/u/44570474?v=4?s=64\" width=\"64px;\" alt=\"Žan Žlender\"/><br /><sub><b>Žan Žlender</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Azanzlender\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebadom\"><img src=\"https://avatars.githubusercontent.com/u/3877952?v=4?s=64\" width=\"64px;\" alt=\"Sebastian Dominguez\"/><br /><sub><b>Sebastian Dominguez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebadom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jmc420\"><img src=\"https://avatars.githubusercontent.com/u/11723529?v=4?s=64\" width=\"64px;\" alt=\"James Cowan\"/><br /><sub><b>James Cowan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajmc420\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bayraak\"><img src=\"https://avatars.githubusercontent.com/u/10470072?v=4?s=64\" width=\"64px;\" alt=\"Bayram Ali Basgul\"/><br /><sub><b>Bayram Ali Basgul</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abayraak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://wyatt.castaneda.family/\"><img src=\"https://avatars.githubusercontent.com/u/17957937?v=4?s=64\" width=\"64px;\" alt=\"Wyatt Castaneda\"/><br /><sub><b>Wyatt Castaneda</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWyattCast44\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tsnevillecom\"><img src=\"https://avatars.githubusercontent.com/u/3151454?v=4?s=64\" width=\"64px;\" alt=\"Tim Neville\"/><br /><sub><b>Tim Neville</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atsnevillecom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shoooe\"><img src=\"https://avatars.githubusercontent.com/u/733227?v=4?s=64\" width=\"64px;\" alt=\"Thomas Pigarelli\"/><br /><sub><b>Thomas Pigarelli</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashoooe\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherdman\"><img src=\"https://avatars.githubusercontent.com/u/3300?v=4?s=64\" width=\"64px;\" alt=\"James Herdman\"/><br /><sub><b>James Herdman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherdman\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pociej\"><img src=\"https://avatars.githubusercontent.com/u/3854675?v=4?s=64\" width=\"64px;\" alt=\"Grzegorz Pociejewski\"/><br /><sub><b>Grzegorz Pociejewski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apociej\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/flyon\"><img src=\"https://avatars.githubusercontent.com/u/341567?v=4?s=64\" width=\"64px;\" alt=\"René Verheij\"/><br /><sub><b>René Verheij</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aflyon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PatrykKuniczak\"><img src=\"https://avatars.githubusercontent.com/u/64608510?v=4?s=64\" width=\"64px;\" alt=\"PatrykKuniczak\"/><br /><sub><b>PatrykKuniczak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APatrykKuniczak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://cromodder.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/7691110?v=4?s=64\" width=\"64px;\" alt=\"Paolo Božac\"/><br /><sub><b>Paolo Božac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACroModder\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/reinos\"><img src=\"https://avatars.githubusercontent.com/u/633730?v=4?s=64\" width=\"64px;\" alt=\"Rein\"/><br /><sub><b>Rein</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Areinos\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FloorianB\"><img src=\"https://avatars.githubusercontent.com/u/110407858?v=4?s=64\" width=\"64px;\" alt=\"FloorianB\"/><br /><sub><b>FloorianB</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFloorianB\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xuanhung1509\"><img src=\"https://avatars.githubusercontent.com/u/89293664?v=4?s=64\" width=\"64px;\" alt=\"Xuan Hung\"/><br /><sub><b>Xuan Hung</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axuanhung1509\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://monawwar.io/\"><img src=\"https://avatars.githubusercontent.com/u/31907722?v=4?s=64\" width=\"64px;\" alt=\"Monawwar Abdullah\"/><br /><sub><b>Monawwar Abdullah</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amxvsh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/haroldo-ok\"><img src=\"https://avatars.githubusercontent.com/u/1457465?v=4?s=64\" width=\"64px;\" alt=\"Haroldo de Oliveira Pinheiro\"/><br /><sub><b>Haroldo de Oliveira Pinheiro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharoldo-ok\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://portfoliobytamjid.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/57794102?v=4?s=64\" width=\"64px;\" alt=\"Tamjid Ahmed\"/><br /><sub><b>Tamjid Ahmed</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATamjidAhmed10\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jv-lopez\"><img src=\"https://avatars.githubusercontent.com/u/93750956?v=4?s=64\" width=\"64px;\" alt=\"jv-lopez\"/><br /><sub><b>jv-lopez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajv-lopez\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://macr.ae/\"><img src=\"https://avatars.githubusercontent.com/u/472830?v=4?s=64\" width=\"64px;\" alt=\"Callum Macrae\"/><br /><sub><b>Callum Macrae</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Acallumacrae\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/0529bill\"><img src=\"https://avatars.githubusercontent.com/u/62455148?v=4?s=64\" width=\"64px;\" alt=\"bywater529\"/><br /><sub><b>bywater529</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3A0529bill\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kevinxh\"><img src=\"https://avatars.githubusercontent.com/u/10948652?v=4?s=64\" width=\"64px;\" alt=\"Kevin He\"/><br /><sub><b>Kevin He</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akevinxh\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FredericoGauz\"><img src=\"https://avatars.githubusercontent.com/u/18327882?v=4?s=64\" width=\"64px;\" alt=\"FredericoGauz\"/><br /><sub><b>FredericoGauz</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFredericoGauz\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.jonlemofficial.com/\"><img src=\"https://avatars.githubusercontent.com/u/38771842?v=4?s=64\" width=\"64px;\" alt=\"Jonathan &quot;JonLem&quot; Lemos\"/><br /><sub><b>Jonathan &quot;JonLem&quot; Lemos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJonLemOfficial\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xegulon\"><img src=\"https://avatars.githubusercontent.com/u/74178038?v=4?s=64\" width=\"64px;\" alt=\"Xegulon\"/><br /><sub><b>Xegulon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axegulon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TomSmedley\"><img src=\"https://avatars.githubusercontent.com/u/95056193?v=4?s=64\" width=\"64px;\" alt=\"Tom Smedley\"/><br /><sub><b>Tom Smedley</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATomSmedley\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lightbluepoppy\"><img src=\"https://avatars.githubusercontent.com/u/65863981?v=4?s=64\" width=\"64px;\" alt=\"lightbluepoppy\"/><br /><sub><b>lightbluepoppy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alightbluepoppy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Dchole\"><img src=\"https://avatars.githubusercontent.com/u/47068381?v=4?s=64\" width=\"64px;\" alt=\"Derek Oware\"/><br /><sub><b>Derek Oware</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADchole\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://fragmentedthought.com/\"><img src=\"https://avatars.githubusercontent.com/u/12085479?v=4?s=64\" width=\"64px;\" alt=\"Lance Gliser\"/><br /><sub><b>Lance Gliser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancegliser\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lewxdev\"><img src=\"https://avatars.githubusercontent.com/u/6710419?v=4?s=64\" width=\"64px;\" alt=\"J. Lewis\"/><br /><sub><b>J. Lewis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alewxdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yairy\"><img src=\"https://avatars.githubusercontent.com/u/3206243?v=4?s=64\" width=\"64px;\" alt=\"Yair\"/><br /><sub><b>Yair</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ayairy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://firecamp.dev/\"><img src=\"https://avatars.githubusercontent.com/u/5078921?v=4?s=64\" width=\"64px;\" alt=\"Nishchit\"/><br /><sub><b>Nishchit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANishchit14\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nejjer\"><img src=\"https://avatars.githubusercontent.com/u/80219537?v=4?s=64\" width=\"64px;\" alt=\"Devofy\"/><br /><sub><b>Devofy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANejjer\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://joshguyette.com/\"><img src=\"https://avatars.githubusercontent.com/u/28668902?v=4?s=64\" width=\"64px;\" alt=\"Josh Guyette\"/><br /><sub><b>Josh Guyette</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anightness\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dora-ljh\"><img src=\"https://avatars.githubusercontent.com/u/35205701?v=4?s=64\" width=\"64px;\" alt=\"Dora Li\"/><br /><sub><b>Dora Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Adora-ljh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kg-currenxie\"><img src=\"https://avatars.githubusercontent.com/u/48229166?v=4?s=64\" width=\"64px;\" alt=\"Kristian Gerardsson\"/><br /><sub><b>Kristian Gerardsson</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akg-currenxie\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jdpt0\"><img src=\"https://avatars.githubusercontent.com/u/19761394?v=4?s=64\" width=\"64px;\" alt=\"James Powell\"/><br /><sub><b>James Powell</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajdpt0\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/boaz-poolman-662162115/\"><img src=\"https://avatars.githubusercontent.com/u/9551934?v=4?s=64\" width=\"64px;\" alt=\"Boaz Poolman\"/><br /><sub><b>Boaz Poolman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aboazpoolman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/roker15\"><img src=\"https://avatars.githubusercontent.com/u/59526869?v=4?s=64\" width=\"64px;\" alt=\"roker15\"/><br /><sub><b>roker15</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aroker15\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fadhilx\"><img src=\"https://avatars.githubusercontent.com/u/15516786?v=4?s=64\" width=\"64px;\" alt=\"Fadhil Ahmad\"/><br /><sub><b>Fadhil Ahmad</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afadhilx\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Chandler-Zhu\"><img src=\"https://avatars.githubusercontent.com/u/61914365?v=4?s=64\" width=\"64px;\" alt=\"Chandler-Zhu\"/><br /><sub><b>Chandler-Zhu</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AChandler-Zhu\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nixjs\"><img src=\"https://avatars.githubusercontent.com/u/23132483?v=4?s=64\" width=\"64px;\" alt=\"Nghi Nguyen\"/><br /><sub><b>Nghi Nguyen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anixjs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShravanSunder\"><img src=\"https://avatars.githubusercontent.com/u/5294949?v=4?s=64\" width=\"64px;\" alt=\"Shravan Sunder\"/><br /><sub><b>Shravan Sunder</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AShravanSunder\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Johannes5\"><img src=\"https://avatars.githubusercontent.com/u/14299835?v=4?s=64\" width=\"64px;\" alt=\"Johannes5\"/><br /><sub><b>Johannes5</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJohannes5\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebahhpeya\"><img src=\"https://avatars.githubusercontent.com/u/93996817?v=4?s=64\" width=\"64px;\" alt=\"sebahhpeya\"/><br /><sub><b>sebahhpeya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebahhpeya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://onezero.co.il/\"><img src=\"https://avatars.githubusercontent.com/u/45389557?v=4?s=64\" width=\"64px;\" alt=\"Or Nakash\"/><br /><sub><b>Or Nakash</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aornakash\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hepiyellow\"><img src=\"https://avatars.githubusercontent.com/u/6338722?v=4?s=64\" width=\"64px;\" alt=\"Erez Makavy\"/><br /><sub><b>Erez Makavy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahepiyellow\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandymerskin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/chainalert-bot\"><img src=\"https://avatars.githubusercontent.com/u/95303823?v=4?s=64\" width=\"64px;\" alt=\"ChainAlert Bot\"/><br /><sub><b>ChainAlert Bot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Achainalert-bot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tmdesigned\"><img src=\"https://avatars.githubusercontent.com/u/3608018?v=4?s=64\" width=\"64px;\" alt=\"Taylor Morgan\"/><br /><sub><b>Taylor Morgan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atmdesigned\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://abkabioye.me/\"><img src=\"https://avatars.githubusercontent.com/u/18709032?v=4?s=64\" width=\"64px;\" alt=\"wisdomabioye\"/><br /><sub><b>wisdomabioye</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awisdomabioye\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.samtheq.com\"><img src=\"https://avatars.githubusercontent.com/u/51345689?v=4?s=64\" width=\"64px;\" alt=\"Samuel Quiñones\"/><br /><sub><b>Samuel Quiñones</b></sub></a><br /><a href=\"#ideas-SamuelQuinones\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ymc-maha\"><img src=\"https://avatars.githubusercontent.com/u/697307?v=4?s=64\" width=\"64px;\" alt=\"Manuel\"/><br /><sub><b>Manuel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ymc-maha\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aymc-maha\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Yurchishin\"><img src=\"https://avatars.githubusercontent.com/u/36650915?v=4?s=64\" width=\"64px;\" alt=\"Yurii Rybak\"/><br /><sub><b>Yurii Rybak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AYurchishin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iuriiiurevich\"><img src=\"https://avatars.githubusercontent.com/u/15759600?v=4?s=64\" width=\"64px;\" alt=\"Yury Demin\"/><br /><sub><b>Yury Demin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aiuriiiurevich\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iuriiiurevich\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://tewks.io/\"><img src=\"https://avatars.githubusercontent.com/u/3970573?v=4?s=64\" width=\"64px;\" alt=\"Jon Tewksbury\"/><br /><sub><b>Jon Tewksbury</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jontewks\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajontewks\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/novacdenis\"><img src=\"https://avatars.githubusercontent.com/u/45555668?v=4?s=64\" width=\"64px;\" alt=\"Novac Denis\"/><br /><sub><b>Novac Denis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novacdenis\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anovacdenis\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kyrylo-soulandwolf\"><img src=\"https://avatars.githubusercontent.com/u/54762253?v=4?s=64\" width=\"64px;\" alt=\"kyrylo-soulandwolf\"/><br /><sub><b>kyrylo-soulandwolf</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kyrylo-soulandwolf\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akyrylo-soulandwolf\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/misidoro\"><img src=\"https://avatars.githubusercontent.com/u/3635023?v=4?s=64\" width=\"64px;\" alt=\"Miguel Isidoro\"/><br /><sub><b>Miguel Isidoro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=misidoro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://crowds.space/\"><img src=\"https://avatars.githubusercontent.com/u/828918?v=4?s=64\" width=\"64px;\" alt=\"Yuriy Gromchenko\"/><br /><sub><b>Yuriy Gromchenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gromchen\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://jcbhmr.me\"><img src=\"https://avatars.githubusercontent.com/u/61068799?v=4?s=64\" width=\"64px;\" alt=\"Jacob Hummer\"/><br /><sub><b>Jacob Hummer</b></sub></a><br /><a href=\"#ideas-jcbhmr\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/k-melnychuk\"><img src=\"https://avatars.githubusercontent.com/u/22131019?v=4?s=64\" width=\"64px;\" alt=\"Kyrylo Melnychuk\"/><br /><sub><b>Kyrylo Melnychuk</b></sub></a><br /><a href=\"#content-k-melnychuk\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=k-melnychuk\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LumaKernel\"><img src=\"https://avatars.githubusercontent.com/u/29811106?v=4?s=64\" width=\"64px;\" alt=\"Luma\"/><br /><sub><b>Luma</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LumaKernel\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Newbie012\"><img src=\"https://avatars.githubusercontent.com/u/10504365?v=4?s=64\" width=\"64px;\" alt=\"Eliya Cohen\"/><br /><sub><b>Eliya Cohen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Newbie012\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isumix\"><img src=\"https://avatars.githubusercontent.com/u/16747416?v=4?s=64\" width=\"64px;\" alt=\"Igor Sukharev\"/><br /><sub><b>Igor Sukharev</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisumix\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pookmish\"><img src=\"https://avatars.githubusercontent.com/u/7185045?v=4?s=64\" width=\"64px;\" alt=\"pookmish\"/><br /><sub><b>pookmish</b></sub></a><br /><a href=\"#ideas-pookmish\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/metav-drimz\"><img src=\"https://avatars.githubusercontent.com/u/113976282?v=4?s=64\" width=\"64px;\" alt=\"metav-drimz\"/><br /><sub><b>metav-drimz</b></sub></a><br /><a href=\"#ideas-metav-drimz\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://luckrnx09.com/\"><img src=\"https://avatars.githubusercontent.com/u/113882203?v=4?s=64\" width=\"64px;\" alt=\"luckrnx09\"/><br /><sub><b>luckrnx09</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=luckrnx09\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RubyHuntsman\"><img src=\"https://avatars.githubusercontent.com/u/24682602?v=4?s=64\" width=\"64px;\" alt=\"Hubert Kuczmierczyk\"/><br /><sub><b>Hubert Kuczmierczyk</b></sub></a><br /><a href=\"#ideas-RubyHuntsman\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ARubyHuntsman\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dandubya\"><img src=\"https://avatars.githubusercontent.com/u/67660308?v=4?s=64\" width=\"64px;\" alt=\"dandubya\"/><br /><sub><b>dandubya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=dandubya\" title=\"Documentation\">📖</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LonelyFellas\"><img src=\"https://avatars.githubusercontent.com/u/38754760?v=4?s=64\" width=\"64px;\" alt=\"Darwish\"/><br /><sub><b>Darwish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LonelyFellas\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.jesuisjo.com/\"><img src=\"https://avatars.githubusercontent.com/u/2046871?v=4?s=64\" width=\"64px;\" alt=\"Jonathan Raoult\"/><br /><sub><b>Jonathan Raoult</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajraoult\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ajraoult\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification ([emoji key](https://allcontributors.org/docs/en/emoji-key)). Contributions of any kind welcome!\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [juliencrn]\n# patreon: # Replace with a single Patreon username\n# open_collective: #usehooks-ts # Replace with a single Open Collective username\n# ko_fi: # Replace with a single Ko-fi username\n# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\n# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\n# liberapay: # Replace with a single Liberapay username\n# issuehunt: # Replace with a single IssueHunt username\n# otechie: # Replace with a single Otechie username\n# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry\ncustom: [\n  \"https://juliencaron.com/donate\",\n  \"https://www.paypal.com/paypalme/juliencrn\",\n  \"https://buy.stripe.com/fZefZY8Bv32cg9O3cc\",\n  \"https://www.buymeacoffee.com/juliencrn\"\n]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: 'Bug report 🐞'\ndescription: >-\n  Create a report to help us improve\ntitle: '[BUG]'\nlabels:\n  - bug\nbody:\n  - type: textarea\n    id: describe_bug\n    attributes:\n      label: Describe the bug\n      description: A clear and concise description of what the bug is. Include any error messages or unexpected behaviors.\n    validations:\n      required: true\n\n  - type: textarea\n    id: reproduce_steps\n    attributes:\n      label: To Reproduce\n      description: Outline the steps to reproduce the issue. Be specific and include details like browser, OS, or any relevant configurations.\n    validations:\n      required: true\n\n  - type: textarea\n    id: expected_behavior\n    attributes:\n      label: Expected behavior\n      description: Explain what you expected to happen.\n    validations:\n      required: true\n\n  - type: textarea\n    id: additional_context\n    attributes:\n      label: Additional context\n      description: Include any other relevant information that might help understand the issue.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: View documentation 📚\n    url: https://usehooks-ts.com/\n    about: Check out the official docs for answers to common questions.\n  - name: Feature requests 💡\n    url: https://github.com/juliencrn/usehooks-ts/discussions/categories/ideas\n    about: Suggest a new React hook idea.\n  - name: Questions 💭\n    url: https://github.com/juliencrn/usehooks-ts/discussions/categories/help\n    about: Need support with a React hook problem? Open up a help request.\n  - name: Donate ❤️\n    url: https://github.com/sponsors/juliencrn\n    about: Love usehooks-ts? Show your support by donating today!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/update-docs.yml",
    "content": "name: Update docs ✍️\ndescription: >-\n  Find a mistake in our documentation, or have a suggestion to improve them? Let us know here.\nlabels:\n  - documentation\nbody:\n  - type: textarea\n    id: description\n    attributes:\n      label: Describe the problem\n      description: A clear and concise description of what is wrong in the documentation or what you would like to improve. Please include URLs to the pages you're referring to.\n    validations:\n      required: true\n  - type: textarea\n    id: context\n    attributes:\n      label: Additional context\n      description: Add any other context about the problem here.\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Build and test\n\non:\n  push:\n    branches:\n      - 'master'\n  pull_request:\n\nenv:\n  NODE_VERSION: 20\n  PNPM_VERSION: 8\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    timeout-minutes: 15\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n\n      - name: Setup Pnpm\n        uses: pnpm/action-setup@v3\n        with:\n          version: ${{ env.PNPM_VERSION }}\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'pnpm'\n          cache-dependency-path: '**/pnpm-lock.yaml'\n\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile\n\n      - name: Build\n        run: pnpm build\n\n      - name: Lint\n        run: pnpm lint\n\n      - name: Test\n        run: pnpm test\n"
  },
  {
    "path": ".github/workflows/update-algolia-index.yml",
    "content": "name: Update Algolia index\n\non:\n  push:\n    branches:\n      - master\n\nenv:\n  NODE_VERSION: 20\n  PNPM_VERSION: 8\n\njobs:\n  run:\n    runs-on: ubuntu-latest\n    timeout-minutes: 15\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n\n      - name: Setup Pnpm\n        uses: pnpm/action-setup@v3\n        with:\n          version: ${{ env.PNPM_VERSION }}\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'pnpm'\n          cache-dependency-path: '**/pnpm-lock.yaml'\n\n      - name: Install dependencies\n        run: pnpm install --frozen-lockfile\n\n      - name: Build\n        run: pnpm build\n\n      - name: Generate documentation from JSDoc\n        run: pnpm generate-doc\n\n      - name: Update Algolia index\n        env:\n          ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}\n          ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}\n        run: pnpm update-algolia-index\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nnpm-debug.log*\n*.tsbuildinfo\n\n# Cache\n.npm\n.cache\n.eslintcache\n.turbo\n\n# Compiled stuff\ndist\ngenerated\n\n# Coverage\ncoverage\n\n# dotenv environment variable files\n.env*\n!.env.example\n\n# Output of 'npm pack'\n*.tgz\n\n# Mac files\n.DS_Store\n\n# Local Netlify folder\n.netlify\n"
  },
  {
    "path": ".prettierignore",
    "content": "node_modules\ntemplates\ndist\n.turbo\npublic\n.cache\npnpm-lock.yaml\n.changeset\n.github\napps/www/.next\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"arrowParens\": \"avoid\",\n  \"semi\": false,\n  \"printWidth\": 80,\n  \"singleQuote\": true,\n  \"tabWidth\": 2,\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"editor.formatOnSave\": true,\n  \"editor.tabSize\": 2,\n  \"files.encoding\": \"utf8\",\n  \"files.trimTrailingWhitespace\": true,\n  \"files.insertFinalNewline\": true,\n  \"search.exclude\": {\n    \"public/**\": true,\n    \"node_modules/**\": true,\n    \"coverage/**\": true,\n    \"dist/**\": true,\n    \"generated/**\": true,\n    \".cache/**\": true,\n    \".git/**\": true,\n    \"**/package-lock.json\": true,\n    \"**/pnpm-lock.yaml\": true\n  },\n  \"eslint.validate\": [\n    \"javascript\",\n    \"javascriptreact\",\n    \"typescript\",\n    \"typescriptreact\"\n  ],\n  \"eslint.format.enable\": true,\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\",\n    \"source.fixAll\": \"explicit\"\n  },\n  \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"cSpell.words\": [\n    \"algolia\",\n    \"clsx\",\n    \"cmdk\",\n    \"contentlayer\",\n    \"fira\",\n    \"frontmatter\",\n    \"gtag\",\n    \"juliencrn\",\n    \"lucide\",\n    \"nextjs\",\n    \"okaidia\",\n    \"prismjs\",\n    \"rehype\",\n    \"tailwindcss\",\n    \"UMAMI\",\n    \"usehooks\"\n  ],\n  \"eslint.workingDirectories\": [\n    {\n      \"directory\": \"apps/www\",\n      \"changeProcessCWD\": true\n    },\n    {\n      \"directory\": \"packages/eslint-config-custom\",\n      \"changeProcessCWD\": true\n    },\n    {\n      \"directory\": \"packages/usehooks-ts\",\n      \"changeProcessCWD\": true\n    }\n  ],\n  \"[jsonc]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[json]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[yaml]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[typescript]\": {\n    \"editor.defaultFormatter\": \"dbaeumer.vscode-eslint\"\n  },\n  \"[typescriptreact]\": {\n    \"editor.defaultFormatter\": \"dbaeumer.vscode-eslint\"\n  },\n  \"files.associations\": { \"*.json\": \"jsonc\" }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2020 Julien CARON\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "<img src=\"https://github.com/juliencrn/usehooks-ts/blob/master/.github/screenshot.png\" alt=\"usehooks-ts banner\" align=\"center\" />\n\n<br />\n\n<div align=\"center\">\n<h1>usehooks-ts</h1>\n\n<div>React hook library, ready to use, written in Typescript.</div>\n\n<br />\n\n<!-- Badges -->\n\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md)\n![NPM Downloads](https://img.shields.io/npm/dm/usehooks-ts)\n![NPM Downloads](https://img.shields.io/npm/dt/usehooks-ts)\n[![License](https://badgen.net/badge/License/MIT/blue)](https://github.com/juliencrn/usehooks-ts/blob/master/LICENSE)\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/usehooks-ts)\n![npm](https://img.shields.io/npm/v/usehooks-ts)<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->\n[![All Contributors](https://img.shields.io/badge/all_contributors-253-orange.svg?style=flat-square)](#contributors-)\n\n<!-- ALL-CONTRIBUTORS-BADGE:END -->\n\n<br />\n  <pre>npm i <a href=\"https://www.npmjs.com/package/usehooks-ts\">usehooks-ts</a></pre>\n  <br />\n\n<div align=\"center\">\n  <sub>Created by <a href=\"https://github.com/juliencrn\">Julien Caron</a> and maintained with ❤️ by an amazing <a href=\"#contributors\">team of developers</a>.</sub>\n</div>\n\n</div>\n\n<br />\n\n## 💫 Introduction\n\nuseHooks(🔥).ts is a React hooks library, written in Typescript and easy to use. It provides a set of hooks that enables you to build your React applications faster. The hooks are built upon the principles of DRY (Don't Repeat Yourself). There are hooks for most common use cases you might need.\n\nThe library is designed to be as minimal as possible. It is fully tree-shakable (using the ESM version), meaning that you only import the hooks you need, and the rest will be removed from your bundle making the cost of using this library negligible. Most hooks are extensively tested and are being used in production environments.\n\n### Usage example\n\n```tsx\nimport { useLocalStorage } from 'usehooks-ts'\n\nfunction Component() {\n  const [value, setValue] = useLocalStorage('my-localStorage-key', 0)\n\n  // ...\n}\n```\n\n## 🪝 Available Hooks\n\n<!-- HOOKS:START -->\n\n- [`useBoolean`](https://usehooks-ts.com/react-hook/use-boolean) — handles boolean state with useful utility functions.\n- [`useClickAnyWhere`](https://usehooks-ts.com/react-hook/use-click-any-where) — handles click events anywhere on the document.\n- [`useCopyToClipboard`](https://usehooks-ts.com/react-hook/use-copy-to-clipboard) — copies text to the clipboard using the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).\n- [`useCountdown`](https://usehooks-ts.com/react-hook/use-countdown) — manages countdown.\n- [`useCounter`](https://usehooks-ts.com/react-hook/use-counter) — manages a counter with increment, decrement, reset, and setCount functionalities.\n- [`useDarkMode`](https://usehooks-ts.com/react-hook/use-dark-mode) — returns the current state of the dark mode.\n- [`useDebounceCallback`](https://usehooks-ts.com/react-hook/use-debounce-callback) — creates a debounced version of a callback function.\n- [`useDebounceValue`](https://usehooks-ts.com/react-hook/use-debounce-value) — returns a debounced version of the provided value, along with a function to update it.\n- [`useDocumentTitle`](https://usehooks-ts.com/react-hook/use-document-title) — sets the document title.\n- [`useEventCallback`](https://usehooks-ts.com/react-hook/use-event-callback) — creates a memoized event callback.\n- [`useEventListener`](https://usehooks-ts.com/react-hook/use-event-listener) — attaches event listeners to DOM elements, the window, or media query lists.\n- [`useHover`](https://usehooks-ts.com/react-hook/use-hover) — tracks whether a DOM element is being hovered over.\n- [`useIntersectionObserver`](https://usehooks-ts.com/react-hook/use-intersection-observer) — tracks the intersection of a DOM element with its containing element or the viewport using the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).\n- [`useInterval`](https://usehooks-ts.com/react-hook/use-interval) — creates an interval that invokes a callback function at a specified delay using the [setInterval API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval).\n- [`useIsClient`](https://usehooks-ts.com/react-hook/use-is-client) — determines if the code is running on the client side (in the browser).\n- [`useIsMounted`](https://usehooks-ts.com/react-hook/use-is-mounted) — determines if the component is currently mounted.\n- [`useIsomorphicLayoutEffect`](https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect) — uses either useLayoutEffect or useEffect based on the environment (client-side or server-side).\n- [`useLocalStorage`](https://usehooks-ts.com/react-hook/use-local-storage) — uses the [localStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to persist state across page reloads.\n- [`useMap`](https://usehooks-ts.com/react-hook/use-map) — manages a key-value [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) state with setter actions.\n- [`useMediaQuery`](https://usehooks-ts.com/react-hook/use-media-query) — tracks the state of a media query using the [Match Media API](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia).\n- [`useOnClickOutside`](https://usehooks-ts.com/react-hook/use-on-click-outside) — handles clicks outside a specified element.\n- [`useReadLocalStorage`](https://usehooks-ts.com/react-hook/use-read-local-storage) — reads a value from [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), closely related to [useLocalStorage()](https://usehooks-ts.com/react-hook/use-local-storage).\n- [`useResizeObserver`](https://usehooks-ts.com/react-hook/use-resize-observer) — observes the size of an element using the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n- [`useScreen`](https://usehooks-ts.com/react-hook/use-screen) — tracks the [screen](https://developer.mozilla.org/en-US/docs/Web/API/Window/screen) dimensions and properties.\n- [`useScript`](https://usehooks-ts.com/react-hook/use-script) — dynamically loads scripts and tracking their loading status.\n- [`useScrollLock`](https://usehooks-ts.com/react-hook/use-scroll-lock) — A custom hook that locks and unlocks scroll.\n- [`useSessionStorage`](https://usehooks-ts.com/react-hook/use-session-storage) — uses the [sessionStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) to persist state across page reloads.\n- [`useStep`](https://usehooks-ts.com/react-hook/use-step) — manages and navigates between steps in a multi-step process.\n- [`useTernaryDarkMode`](https://usehooks-ts.com/react-hook/use-ternary-dark-mode) — manages ternary (system, dark, light) dark mode with local storage support.\n- [`useTimeout`](https://usehooks-ts.com/react-hook/use-timeout) — handles timeouts in React components using the [setTimeout API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout).\n- [`useToggle`](https://usehooks-ts.com/react-hook/use-toggle) — manages a boolean toggle state in React components.\n- [`useUnmount`](https://usehooks-ts.com/react-hook/use-unmount) — runs a cleanup function when the component is unmounted.\n- [`useWindowSize`](https://usehooks-ts.com/react-hook/use-window-size) — tracks the size of the window.\n<!-- HOOKS:END -->\n\n## 💚 Backers\n\nBig thanks go to all our backers! [[Become a backer](https://github.com/sponsors/juliencrn)]\n\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/getsentry\"><img src=\"https://avatars.githubusercontent.com/u/1396951?v=4\" width=\"100px;\" alt=\"Sentry\"/><br /><sub><b>Sentry</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/KATT\"><img src=\"https://avatars.githubusercontent.com/u/459267?v=4\" width=\"100px;\" alt=\"KATT\"/><br /><sub><b>KATT</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/adhiravishankar\"><img src=\"https://avatars.githubusercontent.com/u/3884741?v=4\" width=\"100px;\" alt=\"Adhi Ravishankar\"/><br /><sub><b>Adhi Ravishankar</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/great-work-told-is\"><img src=\"https://avatars.githubusercontent.com/u/113922084?v=4\" width=\"100px;\" alt=\"great-work-told-is\"/><br /><sub><b>great-work-told-is</b></sub></a></td>\n    </tr>\n  </tbody>\n</table>\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n## ✨ Contributors\n\nBig thanks go to all our contributors! [[Become a contributor](https://github.com/juliencrn/usehooks-ts/blob/master/.github/CONTRIBUTING.md)]\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/juliencrn\"><img src=\"https://avatars.githubusercontent.com/u/14028029?v=4?s=64\" width=\"64px;\" alt=\"Julien\"/><br /><sub><b>Julien</b></sub></a><br /><a href=\"#content-juliencrn\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=juliencrn\" title=\"Code\">💻</a> <a href=\"#design-juliencrn\" title=\"Design\">🎨</a> <a href=\"#ideas-juliencrn\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a777med\"><img src=\"https://avatars.githubusercontent.com/u/15968280?v=4?s=64\" width=\"64px;\" alt=\"a777med\"/><br /><sub><b>a777med</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=a777med\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://datkira.com/\"><img src=\"https://avatars.githubusercontent.com/u/53250212?v=4?s=64\" width=\"64px;\" alt=\"Nguyen Tien Dat\"/><br /><sub><b>Nguyen Tien Dat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=datkira\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/elifer5000\"><img src=\"https://avatars.githubusercontent.com/u/4311278?v=4?s=64\" width=\"64px;\" alt=\"Elias Cohenca\"/><br /><sub><b>Elias Cohenca</b></sub></a><br /><a href=\"#content-elifer5000\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://joaov.com.br/\"><img src=\"https://avatars.githubusercontent.com/u/17601527?v=4?s=64\" width=\"64px;\" alt=\"João Deroldo\"/><br /><sub><b>João Deroldo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajoaoderoldo\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=joaoderoldo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nishit-Dua\"><img src=\"https://avatars.githubusercontent.com/u/35453301?v=4?s=64\" width=\"64px;\" alt=\"Nishit\"/><br /><sub><b>Nishit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Nishit-Dua\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonkoops\"><img src=\"https://avatars.githubusercontent.com/u/695720?v=4?s=64\" width=\"64px;\" alt=\"Jon Koops\"/><br /><sub><b>Jon Koops</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonkoops\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LoneRifle\"><img src=\"https://avatars.githubusercontent.com/u/10572368?v=4?s=64\" width=\"64px;\" alt=\"LoneRifle\"/><br /><sub><b>LoneRifle</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LoneRifle\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/vfonic\"><img src=\"https://avatars.githubusercontent.com/u/67437?v=4?s=64\" width=\"64px;\" alt=\"Viktor\"/><br /><sub><b>Viktor</b></sub></a><br /><a href=\"#ideas-vfonic\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avfonic\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bclermont\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Bruno Clermont\"/><br /><sub><b>Bruno Clermont</b></sub></a><br /><a href=\"#question-bclermont\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yoannesbourg\"><img src=\"https://avatars.githubusercontent.com/u/73404603?v=4?s=64\" width=\"64px;\" alt=\"yoannesbourg\"/><br /><sub><b>yoannesbourg</b></sub></a><br /><a href=\"#ideas-yoannesbourg\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/strange2x\"><img src=\"https://avatars.githubusercontent.com/u/10759731?v=4?s=64\" width=\"64px;\" alt=\"Strange2x\"/><br /><sub><b>Strange2x</b></sub></a><br /><a href=\"#ideas-strange2x\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/steinybot\"><img src=\"https://avatars.githubusercontent.com/u/4659562?v=4?s=64\" width=\"64px;\" alt=\"Jason Pickens\"/><br /><sub><b>Jason Pickens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asteinybot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://smackagency.com/\"><img src=\"https://avatars.githubusercontent.com/u/3469560?v=4?s=64\" width=\"64px;\" alt=\"Sel-Vin Kuik\"/><br /><sub><b>Sel-Vin Kuik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aselvinkuik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isaacalves\"><img src=\"https://avatars.githubusercontent.com/u/1765942?v=4?s=64\" width=\"64px;\" alt=\"isaac\"/><br /><sub><b>isaac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisaacalves\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/brunorzn\"><img src=\"https://avatars.githubusercontent.com/u/18266054?v=4?s=64\" width=\"64px;\" alt=\"Bruno RZN\"/><br /><sub><b>Bruno RZN</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brunorzn\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Abrunorzn\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.cykeprojects.com/\"><img src=\"https://avatars.githubusercontent.com/u/2979318?v=4?s=64\" width=\"64px;\" alt=\"Nathan Manceaux-Panot\"/><br /><sub><b>Nathan Manceaux-Panot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Cykelero\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ACykelero\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/meotimdihia\"><img src=\"https://avatars.githubusercontent.com/u/300961?v=4?s=64\" width=\"64px;\" alt=\"Dien Vu\"/><br /><sub><b>Dien Vu</b></sub></a><br /><a href=\"#ideas-meotimdihia\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/olegKusov\"><img src=\"https://avatars.githubusercontent.com/u/28058268?v=4?s=64\" width=\"64px;\" alt=\"Oleg Kusov\"/><br /><sub><b>Oleg Kusov</b></sub></a><br /><a href=\"#ideas-olegKusov\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://mattguy.me/\"><img src=\"https://avatars.githubusercontent.com/u/6647355?v=4?s=64\" width=\"64px;\" alt=\"Matthew Guy\"/><br /><sub><b>Matthew Guy</b></sub></a><br /><a href=\"#ideas-mankittens\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andrewbihl\"><img src=\"https://avatars.githubusercontent.com/u/16709744?v=4?s=64\" width=\"64px;\" alt=\"andrewbihl\"/><br /><sub><b>andrewbihl</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandrewbihl\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lancepollard\"><img src=\"https://avatars.githubusercontent.com/u/86631222?v=4?s=64\" width=\"64px;\" alt=\"lancepollard\"/><br /><sub><b>lancepollard</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancepollard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gmukul01\"><img src=\"https://avatars.githubusercontent.com/u/3636885?v=4?s=64\" width=\"64px;\" alt=\"Mukul Bansal\"/><br /><sub><b>Mukul Bansal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Agmukul01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://127.0.0.1:8000/\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Jean-Luc Mongrain sur la Brosse\"/><br /><sub><b>Jean-Luc Mongrain sur la Brosse</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jeanlucmongrain\" title=\"Code\">💻</a> <a href=\"#ideas-jeanlucmongrain\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/n1c\"><img src=\"https://avatars.githubusercontent.com/u/284075?v=4?s=64\" width=\"64px;\" alt=\"Nic\"/><br /><sub><b>Nic</b></sub></a><br /><a href=\"#content-n1c\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://valtism.com/\"><img src=\"https://avatars.githubusercontent.com/u/1286001?v=4?s=64\" width=\"64px;\" alt=\"Dan Wood\"/><br /><sub><b>Dan Wood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valtism\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.sixt.de/\"><img src=\"https://avatars.githubusercontent.com/u/25299148?v=4?s=64\" width=\"64px;\" alt=\"jo wendenbuerger\"/><br /><sub><b>jo wendenbuerger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWendenburg\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://nozillium.com/\"><img src=\"https://avatars.githubusercontent.com/u/4774875?v=4?s=64\" width=\"64px;\" alt=\"Andrew Nosenko\"/><br /><sub><b>Andrew Nosenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anoseratio\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CharlieJhonSmith\"><img src=\"https://avatars.githubusercontent.com/u/90845154?v=4?s=64\" width=\"64px;\" alt=\"CharlieJhonSmith\"/><br /><sub><b>CharlieJhonSmith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CharlieJhonSmith\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://keybase.io/soullivaneuh\"><img src=\"https://avatars.githubusercontent.com/u/1698357?v=4?s=64\" width=\"64px;\" alt=\"Sullivan SENECHAL\"/><br /><sub><b>Sullivan SENECHAL</b></sub></a><br /><a href=\"#ideas-soullivaneuh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asoullivaneuh\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=soullivaneuh\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jaslong\"><img src=\"https://avatars.githubusercontent.com/u/797348?v=4?s=64\" width=\"64px;\" alt=\"Jason Long\"/><br /><sub><b>Jason Long</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajaslong\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kxm766\"><img src=\"https://avatars.githubusercontent.com/u/88443148?v=4?s=64\" width=\"64px;\" alt=\"kxm766\"/><br /><sub><b>kxm766</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akxm766\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://qlaffont.com/\"><img src=\"https://avatars.githubusercontent.com/u/10044790?v=4?s=64\" width=\"64px;\" alt=\"Quentin\"/><br /><sub><b>Quentin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=qlaffont\" title=\"Code\">💻</a> <a href=\"#ideas-qlaffont\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#content-qlaffont\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ducktordanny\"><img src=\"https://avatars.githubusercontent.com/u/38068717?v=4?s=64\" width=\"64px;\" alt=\"Daniel Lazar\"/><br /><sub><b>Daniel Lazar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ducktordanny\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aducktordanny\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mterrel\"><img src=\"https://avatars.githubusercontent.com/u/17746857?v=4?s=64\" width=\"64px;\" alt=\"Mark Terrel\"/><br /><sub><b>Mark Terrel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amterrel\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mterrel\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mendrik\"><img src=\"https://avatars.githubusercontent.com/u/160805?v=4?s=64\" width=\"64px;\" alt=\"Andreas Herd\"/><br /><sub><b>Andreas Herd</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amendrik\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sonjoydatta.me/\"><img src=\"https://avatars.githubusercontent.com/u/49079726?v=4?s=64\" width=\"64px;\" alt=\"Sonjoy Datta\"/><br /><sub><b>Sonjoy Datta</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sonjoydatta\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oluckyman\"><img src=\"https://avatars.githubusercontent.com/u/642673?v=4?s=64\" width=\"64px;\" alt=\"Ilya Belsky\"/><br /><sub><b>Ilya Belsky</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoluckyman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jamesbarrett.io/\"><img src=\"https://avatars.githubusercontent.com/u/42980207?v=4?s=64\" width=\"64px;\" alt=\"James Barrett\"/><br /><sub><b>James Barrett</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=JamesBarrettDev\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AbbalYouness\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"AbbalYouness\"/><br /><sub><b>AbbalYouness</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AbbalYouness\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/DidrikLind\"><img src=\"https://avatars.githubusercontent.com/u/14201715?v=4?s=64\" width=\"64px;\" alt=\"didriklind\"/><br /><sub><b>didriklind</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Tests\">⚠️</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hexp1989\"><img src=\"https://avatars.githubusercontent.com/u/2241985?v=4?s=64\" width=\"64px;\" alt=\"hexp1989\"/><br /><sub><b>hexp1989</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hexp1989\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/alvaro-serrano-rivas/\"><img src=\"https://avatars.githubusercontent.com/u/43758471?v=4?s=64\" width=\"64px;\" alt=\"Alvaro Serrano\"/><br /><sub><b>Alvaro Serrano</b></sub></a><br /><a href=\"#content-alvaroserrrano\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/egehandulger\"><img src=\"https://avatars.githubusercontent.com/u/14878259?v=4?s=64\" width=\"64px;\" alt=\"Egehan Dülger\"/><br /><sub><b>Egehan Dülger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=egehandulger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PabloLION\"><img src=\"https://avatars.githubusercontent.com/u/36828324?v=4?s=64\" width=\"64px;\" alt=\"PabloLION\"/><br /><sub><b>PabloLION</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APabloLION\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=PabloLION\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://davidsanchez.me/\"><img src=\"https://avatars.githubusercontent.com/u/84061?v=4?s=64\" width=\"64px;\" alt=\"David Sanchez\"/><br /><sub><b>David Sanchez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aemulienfou\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AjayTheWizard\"><img src=\"https://avatars.githubusercontent.com/u/92772740?v=4?s=64\" width=\"64px;\" alt=\"Ajay Raja\"/><br /><sub><b>Ajay Raja</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAjayTheWizard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"#ideas-docmars\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/GrayGalaxy\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=GrayGalaxy\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGrayGalaxy\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tilnea\"><img src=\"https://avatars.githubusercontent.com/u/3692320?v=4?s=64\" width=\"64px;\" alt=\"Sanne Wintrén\"/><br /><sub><b>Sanne Wintrén</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atilnea\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://lacolonia.studio/\"><img src=\"https://avatars.githubusercontent.com/u/1528468?v=4?s=64\" width=\"64px;\" alt=\"Alessandro\"/><br /><sub><b>Alessandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aa-barbieri\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/atatarenko\"><img src=\"https://avatars.githubusercontent.com/u/9846273?v=4?s=64\" width=\"64px;\" alt=\"Andrey Tatarenko\"/><br /><sub><b>Andrey Tatarenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aatatarenko\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/arusak\"><img src=\"https://avatars.githubusercontent.com/u/4231915?v=4?s=64\" width=\"64px;\" alt=\"Anton Rusak\"/><br /><sub><b>Anton Rusak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aarusak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/createdbymahmood\"><img src=\"https://avatars.githubusercontent.com/u/40164360?v=4?s=64\" width=\"64px;\" alt=\"Mahmood Bagheri\"/><br /><sub><b>Mahmood Bagheri</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=createdbymahmood\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://wpowner.com/\"><img src=\"https://avatars.githubusercontent.com/u/506491?v=4?s=64\" width=\"64px;\" alt=\"Anver Sadutt\"/><br /><sub><b>Anver Sadutt</b></sub></a><br /><a href=\"#content-anver\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bogdanailincaipnt\"><img src=\"https://avatars.githubusercontent.com/u/93596663?v=4?s=64\" width=\"64px;\" alt=\"Bogdan Ailincai\"/><br /><sub><b>Bogdan Ailincai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bogdanailincaipnt\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SimeonGriggs\"><img src=\"https://avatars.githubusercontent.com/u/9684022?v=4?s=64\" width=\"64px;\" alt=\"Simeon Griggs\"/><br /><sub><b>Simeon Griggs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ASimeonGriggs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Kepro\"><img src=\"https://avatars.githubusercontent.com/u/1714370?v=4?s=64\" width=\"64px;\" alt=\"Kepro\"/><br /><sub><b>Kepro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AKepro\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Jake-Lippert\"><img src=\"https://avatars.githubusercontent.com/u/17753127?v=4?s=64\" width=\"64px;\" alt=\"Jake Lippert\"/><br /><sub><b>Jake Lippert</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJake-Lippert\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TunA-Kai\"><img src=\"https://avatars.githubusercontent.com/u/92641762?v=4?s=64\" width=\"64px;\" alt=\"Tu Nguyen Anh\"/><br /><sub><b>Tu Nguyen Anh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATunA-Kai\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TunA-Kai\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/skve\"><img src=\"https://avatars.githubusercontent.com/u/47612057?v=4?s=64\" width=\"64px;\" alt=\"Luke Shiels\"/><br /><sub><b>Luke Shiels</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Askve\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SleLLl\"><img src=\"https://avatars.githubusercontent.com/u/66108429?v=4?s=64\" width=\"64px;\" alt=\"Sergei Kolyago\"/><br /><sub><b>Sergei Kolyago</b></sub></a><br /><a href=\"#ideas-SleLLl\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/adhamaa\"><img src=\"https://avatars.githubusercontent.com/u/50027371?v=4?s=64\" width=\"64px;\" alt=\"Adham Akmal Azmi\"/><br /><sub><b>Adham Akmal Azmi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aadhamaa\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alex-kowalczyk\"><img src=\"https://avatars.githubusercontent.com/u/7422175?v=4?s=64\" width=\"64px;\" alt=\"Alek Kowalczyk\"/><br /><sub><b>Alek Kowalczyk</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aalex-kowalczyk\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Scalahansolo\"><img src=\"https://avatars.githubusercontent.com/u/4317253?v=4?s=64\" width=\"64px;\" alt=\"Sean Callahan\"/><br /><sub><b>Sean Callahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AScalahansolo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jbean96\"><img src=\"https://avatars.githubusercontent.com/u/22803097?v=4?s=64\" width=\"64px;\" alt=\"Joshua Bean\"/><br /><sub><b>Joshua Bean</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jbean96\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajbean96\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ZhaoTim\"><img src=\"https://avatars.githubusercontent.com/u/30540533?v=4?s=64\" width=\"64px;\" alt=\"Tim Zhao\"/><br /><sub><b>Tim Zhao</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AZhaoTim\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/patryk-smc\"><img src=\"https://avatars.githubusercontent.com/u/37963339?v=4?s=64\" width=\"64px;\" alt=\"Patrick\"/><br /><sub><b>Patrick</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatryk-smc\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://bryce.io/\"><img src=\"https://avatars.githubusercontent.com/u/3171252?v=4?s=64\" width=\"64px;\" alt=\"Bryce Dorn\"/><br /><sub><b>Bryce Dorn</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brycedorn\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/angusd3v\"><img src=\"https://avatars.githubusercontent.com/u/52683145?v=4?s=64\" width=\"64px;\" alt=\"angusd3v\"/><br /><sub><b>angusd3v</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=angusd3v\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ddisimone\"><img src=\"https://avatars.githubusercontent.com/u/78792352?v=4?s=64\" width=\"64px;\" alt=\"Davide Di Simone\"/><br /><sub><b>Davide Di Simone</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Addisimone\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherr\"><img src=\"https://avatars.githubusercontent.com/u/22392?v=4?s=64\" width=\"64px;\" alt=\"Jack Herrington\"/><br /><sub><b>Jack Herrington</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherr\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sharvit.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/1262502?v=4?s=64\" width=\"64px;\" alt=\"Avi Sharvit\"/><br /><sub><b>Avi Sharvit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sharvit\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asharvit\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmaties\"><img src=\"https://avatars.githubusercontent.com/u/16613184?v=4?s=64\" width=\"64px;\" alt=\"Nicolae Maties\"/><br /><sub><b>Nicolae Maties</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmaties\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/secretshardul\"><img src=\"https://avatars.githubusercontent.com/u/49580849?v=4?s=64\" width=\"64px;\" alt=\"Shardul Aeer\"/><br /><sub><b>Shardul Aeer</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asecretshardul\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/herlon214\"><img src=\"https://avatars.githubusercontent.com/u/3419441?v=4?s=64\" width=\"64px;\" alt=\"Herlon Aguiar\"/><br /><sub><b>Herlon Aguiar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aherlon214\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alexisoney\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"Alexis Oney\"/><br /><sub><b>Alexis Oney</b></sub></a><br /><a href=\"#content-alexisoney\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://convictional.com/\"><img src=\"https://avatars.githubusercontent.com/u/96080054?v=4?s=64\" width=\"64px;\" alt=\"curtvict\"/><br /><sub><b>curtvict</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=curtvict\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/JoshuaCS94\"><img src=\"https://avatars.githubusercontent.com/u/23385700?v=4?s=64\" width=\"64px;\" alt=\"Josué Cortina\"/><br /><sub><b>Josué Cortina</b></sub></a><br /><a href=\"#content-JoshuaCS94\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://katt.dev/\"><img src=\"https://avatars.githubusercontent.com/u/459267?v=4?s=64\" width=\"64px;\" alt=\"Alex / KATT\"/><br /><sub><b>Alex / KATT</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KATT\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/modex98\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=modex98\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amodex98\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Guesswhoitis\"><img src=\"https://avatars.githubusercontent.com/u/63756285?v=4?s=64\" width=\"64px;\" alt=\"James Hulena\"/><br /><sub><b>James Hulena</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGuesswhoitis\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://hailwood.nz/\"><img src=\"https://avatars.githubusercontent.com/u/709773?v=4?s=64\" width=\"64px;\" alt=\"Matthew Hailwood\"/><br /><sub><b>Matthew Hailwood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hailwood\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ahailwood\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mike247\"><img src=\"https://avatars.githubusercontent.com/u/676071?v=4?s=64\" width=\"64px;\" alt=\"Michael Norrie\"/><br /><sub><b>Michael Norrie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amike247\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valentinpolitov\"><img src=\"https://avatars.githubusercontent.com/u/39585375?v=4?s=64\" width=\"64px;\" alt=\"Valentin Politov\"/><br /><sub><b>Valentin Politov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valentinpolitov\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/marnusw\"><img src=\"https://avatars.githubusercontent.com/u/971499?v=4?s=64\" width=\"64px;\" alt=\"Marnus Weststrate\"/><br /><sub><b>Marnus Weststrate</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=marnusw\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mancuoj\"><img src=\"https://avatars.githubusercontent.com/u/45707684?v=4?s=64\" width=\"64px;\" alt=\"mancuoj\"/><br /><sub><b>mancuoj</b></sub></a><br /><a href=\"#content-mancuoj\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.chatsumlin.com/\"><img src=\"https://avatars.githubusercontent.com/u/3067479?v=4?s=64\" width=\"64px;\" alt=\"Chat Sumlin\"/><br /><sub><b>Chat Sumlin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jcsumlin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/owenshaupt\"><img src=\"https://avatars.githubusercontent.com/u/52288188?v=4?s=64\" width=\"64px;\" alt=\"Owen Haupt\"/><br /><sub><b>Owen Haupt</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aowenshaupt\" title=\"Bug reports\">🐛</a> <a href=\"#content-owenshaupt\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ubarbaxor\"><img src=\"https://avatars.githubusercontent.com/u/26365493?v=4?s=64\" width=\"64px;\" alt=\"ubarbaxor\"/><br /><sub><b>ubarbaxor</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ubarbaxor\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://michael.mior.ca/\"><img src=\"https://avatars.githubusercontent.com/u/82501?v=4?s=64\" width=\"64px;\" alt=\"Michael Mior\"/><br /><sub><b>Michael Mior</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amichaelmior\" title=\"Bug reports\">🐛</a> <a href=\"#content-michaelmior\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pkhodaveissi\"><img src=\"https://avatars.githubusercontent.com/u/4170795?v=4?s=64\" width=\"64px;\" alt=\"Pierre\"/><br /><sub><b>Pierre</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=pkhodaveissi\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/harrywebdev\"><img src=\"https://avatars.githubusercontent.com/u/3617415?v=4?s=64\" width=\"64px;\" alt=\"Harry B\"/><br /><sub><b>Harry B</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharrywebdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valyrie97\"><img src=\"https://avatars.githubusercontent.com/u/6365746?v=4?s=64\" width=\"64px;\" alt=\"Valerie\"/><br /><sub><b>Valerie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avalyrie97\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valyrie97\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://svachon.com/\"><img src=\"https://avatars.githubusercontent.com/u/170197?v=4?s=64\" width=\"64px;\" alt=\"Steven Vachon\"/><br /><sub><b>Steven Vachon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=stevenvachon\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sskirby\"><img src=\"https://avatars.githubusercontent.com/u/25760?v=4?s=64\" width=\"64px;\" alt=\"Sean Kirby\"/><br /><sub><b>Sean Kirby</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AlecsFarias\"><img src=\"https://avatars.githubusercontent.com/u/91743821?v=4?s=64\" width=\"64px;\" alt=\"Alecsander Farias\"/><br /><sub><b>Alecsander Farias</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AlecsFarias\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://blankparticle.in/\"><img src=\"https://avatars.githubusercontent.com/u/130567419?v=4?s=64\" width=\"64px;\" alt=\"Rahul Mishra\"/><br /><sub><b>Rahul Mishra</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BlankParticle\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ABlankParticle\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"#content-BlankParticle\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bryantcodesart\"><img src=\"https://avatars.githubusercontent.com/u/14097078?v=4?s=64\" width=\"64px;\" alt=\"Bryant Smith\"/><br /><sub><b>Bryant Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bryantcodesart\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abryantcodesart\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RobHannay\"><img src=\"https://avatars.githubusercontent.com/u/609062?v=4?s=64\" width=\"64px;\" alt=\"Rob Hannay\"/><br /><sub><b>Rob Hannay</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=RobHannay\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hooriza\"><img src=\"https://avatars.githubusercontent.com/u/507927?v=4?s=64\" width=\"64px;\" alt=\"Hooriza\"/><br /><sub><b>Hooriza</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hooriza\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahooriza\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShanSenanayake\"><img src=\"https://avatars.githubusercontent.com/u/8779685?v=4?s=64\" width=\"64px;\" alt=\"ShanSenanayake\"/><br /><sub><b>ShanSenanayake</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ShanSenanayake\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/philipgher\"><img src=\"https://avatars.githubusercontent.com/u/32325241?v=4?s=64\" width=\"64px;\" alt=\"Philip Ghering\"/><br /><sub><b>Philip Ghering</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=philipgher\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ladislasdellinger\"><img src=\"https://avatars.githubusercontent.com/u/111739019?v=4?s=64\" width=\"64px;\" alt=\"Ladislas Dellinger\"/><br /><sub><b>Ladislas Dellinger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ladislasdellinger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TheHaff\"><img src=\"https://avatars.githubusercontent.com/u/2486653?v=4?s=64\" width=\"64px;\" alt=\"Haff\"/><br /><sub><b>Haff</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TheHaff\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lisandro52\"><img src=\"https://avatars.githubusercontent.com/u/5612241?v=4?s=64\" width=\"64px;\" alt=\"Lisandro\"/><br /><sub><b>Lisandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lisandro52\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/amirking59\"><img src=\"https://avatars.githubusercontent.com/u/58273240?v=4?s=64\" width=\"64px;\" alt=\"Amir hossein rezaei\"/><br /><sub><b>Amir hossein rezaei</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=amirking59\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmacianx\"><img src=\"https://avatars.githubusercontent.com/u/40004186?v=4?s=64\" width=\"64px;\" alt=\"Nicolas Macian\"/><br /><sub><b>Nicolas Macian</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmacianx\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nmacianx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://dreamsof.dev/\"><img src=\"https://avatars.githubusercontent.com/u/13162026?v=4?s=64\" width=\"64px;\" alt=\"Nate Forsyth\"/><br /><sub><b>Nate Forsyth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nateforsyth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/satelllte\"><img src=\"https://avatars.githubusercontent.com/u/20585619?v=4?s=64\" width=\"64px;\" alt=\"satelllte\"/><br /><sub><b>satelllte</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=satelllte\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asatelllte\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fedemp\"><img src=\"https://avatars.githubusercontent.com/u/735314?v=4?s=64\" width=\"64px;\" alt=\"Federico Panico\"/><br /><sub><b>Federico Panico</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=fedemp\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iamwillnbcu\"><img src=\"https://avatars.githubusercontent.com/u/137317773?v=4?s=64\" width=\"64px;\" alt=\"William Pei Yuan\"/><br /><sub><b>William Pei Yuan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iamwillnbcu\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.gazeta-cu-anunturi.ro/\"><img src=\"https://avatars.githubusercontent.com/u/757999?v=4?s=64\" width=\"64px;\" alt=\"Mihai\"/><br /><sub><b>Mihai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DarkAng3L\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADarkAng3L\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://habib.ogunsola.me/\"><img src=\"https://avatars.githubusercontent.com/u/39172573?v=4?s=64\" width=\"64px;\" alt=\"Habib Ogunsola\"/><br /><sub><b>Habib Ogunsola</b></sub></a><br /><a href=\"#content-ogunsolahabib\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ashfurrow.com/\"><img src=\"https://avatars.githubusercontent.com/u/498212?v=4?s=64\" width=\"64px;\" alt=\"Ash Furrow\"/><br /><sub><b>Ash Furrow</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ashfurrow\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://turus.ro/\"><img src=\"https://avatars.githubusercontent.com/u/32390499?v=4?s=64\" width=\"64px;\" alt=\"Daniel Turuș\"/><br /><sub><b>Daniel Turuș</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danielturus\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/rahulchaudhary2244/\"><img src=\"https://avatars.githubusercontent.com/u/54467972?v=4?s=64\" width=\"64px;\" alt=\"Rahul Chaudhary\"/><br /><sub><b>Rahul Chaudhary</b></sub></a><br /><a href=\"#content-rahulchaudhary2244\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arahulchaudhary2244\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Joshyahweh\"><img src=\"https://avatars.githubusercontent.com/u/61137067?v=4?s=64\" width=\"64px;\" alt=\"Joshua Ojoawo\"/><br /><sub><b>Joshua Ojoawo</b></sub></a><br /><a href=\"#ideas-Joshyahweh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJoshyahweh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jackdh.com/\"><img src=\"https://avatars.githubusercontent.com/u/1907451?v=4?s=64\" width=\"64px;\" alt=\"Jack\"/><br /><sub><b>Jack</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jackdh\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonlinkens\"><img src=\"https://avatars.githubusercontent.com/u/20417521?v=4?s=64\" width=\"64px;\" alt=\"Jon Linkens\"/><br /><sub><b>Jon Linkens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonlinkens\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajonlinkens\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://velog.io/@ojj1123\"><img src=\"https://avatars.githubusercontent.com/u/33178048?v=4?s=64\" width=\"64px;\" alt=\"Jeongjin Oh\"/><br /><sub><b>Jeongjin Oh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aojj1123\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tli26\"><img src=\"https://avatars.githubusercontent.com/u/114947190?v=4?s=64\" width=\"64px;\" alt=\"Tianning Li\"/><br /><sub><b>Tianning Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=tli26\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://larsartmann.com/\"><img src=\"https://avatars.githubusercontent.com/u/23587853?v=4?s=64\" width=\"64px;\" alt=\"Lars Artmann\"/><br /><sub><b>Lars Artmann</b></sub></a><br /><a href=\"#content-LarsArtmann\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/KBobovskiy\"><img src=\"https://avatars.githubusercontent.com/u/35502578?v=4?s=64\" width=\"64px;\" alt=\"KBobovskiy\"/><br /><sub><b>KBobovskiy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KBobovskiy\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ryngonzalez\"><img src=\"https://avatars.githubusercontent.com/u/635300?v=4?s=64\" width=\"64px;\" alt=\"✨ Kathryn Gonzalez ✨\"/><br /><sub><b>✨ Kathryn Gonzalez ✨</b></sub></a><br /><a href=\"#content-ryngonzalez\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/slavik-chapelskyi\"><img src=\"https://avatars.githubusercontent.com/u/33541009?v=4?s=64\" width=\"64px;\" alt=\"Yaroslav Chapelskyi\"/><br /><sub><b>Yaroslav Chapelskyi</b></sub></a><br /><a href=\"#content-slavik-chapelskyi\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sverps\"><img src=\"https://avatars.githubusercontent.com/u/15879327?v=4?s=64\" width=\"64px;\" alt=\"Samuel Van Erps\"/><br /><sub><b>Samuel Van Erps</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Asverps\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ojolowoblue\"><img src=\"https://avatars.githubusercontent.com/u/104099474?v=4?s=64\" width=\"64px;\" alt=\"ojolowoblue\"/><br /><sub><b>ojolowoblue</b></sub></a><br /><a href=\"#content-ojolowoblue\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://short.io/\"><img src=\"https://avatars.githubusercontent.com/u/75169?v=4?s=64\" width=\"64px;\" alt=\"Andrii Kostenko\"/><br /><sub><b>Andrii Kostenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gugu\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AkeemAllen\"><img src=\"https://avatars.githubusercontent.com/u/32404761?v=4?s=64\" width=\"64px;\" alt=\"Akeem Allen\"/><br /><sub><b>Akeem Allen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AkeemAllen\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAkeemAllen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/trongbinh15\"><img src=\"https://avatars.githubusercontent.com/u/43725147?v=4?s=64\" width=\"64px;\" alt=\"trongbinhnguyen\"/><br /><sub><b>trongbinhnguyen</b></sub></a><br /><a href=\"#content-trongbinh15\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://lawlesx.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/52166437?v=4?s=64\" width=\"64px;\" alt=\"Aniruddha Sil\"/><br /><sub><b>Aniruddha Sil</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lawlesx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/okinawaa\"><img src=\"https://avatars.githubusercontent.com/u/69495129?v=4?s=64\" width=\"64px;\" alt=\"박찬혁\"/><br /><sub><b>박찬혁</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Aokinawaa\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://anishchhetri.com.np/\"><img src=\"https://avatars.githubusercontent.com/u/98446102?v=4?s=64\" width=\"64px;\" alt=\"Anish\"/><br /><sub><b>Anish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novanish\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://hutri.fi/\"><img src=\"https://avatars.githubusercontent.com/u/55588133?v=4?s=64\" width=\"64px;\" alt=\"Hugo Hutri\"/><br /><sub><b>Hugo Hutri</b></sub></a><br /><a href=\"#content-hugohutri\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://balzguenat.ch/\"><img src=\"https://avatars.githubusercontent.com/u/6719014?v=4?s=64\" width=\"64px;\" alt=\"Balz Guenat\"/><br /><sub><b>Balz Guenat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BalzGuenat\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ottergeorge\"><img src=\"https://avatars.githubusercontent.com/u/108759685?v=4?s=64\" width=\"64px;\" alt=\"OtterGeorge\"/><br /><sub><b>OtterGeorge</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ottergeorge\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/samay-rgb\"><img src=\"https://avatars.githubusercontent.com/u/73112080?v=4?s=64\" width=\"64px;\" alt=\"Samay Sagar\"/><br /><sub><b>Samay Sagar</b></sub></a><br /><a href=\"#content-samay-rgb\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pedrobslisboa\"><img src=\"https://avatars.githubusercontent.com/u/35539594?v=4?s=64\" width=\"64px;\" alt=\"Pedro Lisboa\"/><br /><sub><b>Pedro Lisboa</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apedrobslisboa\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/henriqemalheiros\"><img src=\"https://avatars.githubusercontent.com/u/23730762?v=4?s=64\" width=\"64px;\" alt=\"Henrique Malheiros\"/><br /><sub><b>Henrique Malheiros</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahenriqemalheiros\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.unfocus.com/\"><img src=\"https://avatars.githubusercontent.com/u/245825?v=4?s=64\" width=\"64px;\" alt=\"Kevin Newman\"/><br /><sub><b>Kevin Newman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CaptainN\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a503189\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"a503189\"/><br /><sub><b>a503189</b></sub></a><br /><a href=\"#content-a503189\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://t.me/mouradelcadi\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mod7ex\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Lop3sPedro\"><img src=\"https://avatars.githubusercontent.com/u/89090945?v=4?s=64\" width=\"64px;\" alt=\"Pedro Henrique Lopes\"/><br /><sub><b>Pedro Henrique Lopes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Lop3sPedro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/danbiilee\"><img src=\"https://avatars.githubusercontent.com/u/53761241?v=4?s=64\" width=\"64px;\" alt=\"Danbi Lee\"/><br /><sub><b>Danbi Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danbiilee\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/cojennin\"><img src=\"https://avatars.githubusercontent.com/u/1888152?v=4?s=64\" width=\"64px;\" alt=\"Connor Jennings\"/><br /><sub><b>Connor Jennings</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=cojennin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lgxm3z\"><img src=\"https://avatars.githubusercontent.com/u/28831375?v=4?s=64\" width=\"64px;\" alt=\"Lucas Gomes\"/><br /><sub><b>Lucas Gomes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Algxm3z\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lgxm3z\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zaggino\"><img src=\"https://avatars.githubusercontent.com/u/1067319?v=4?s=64\" width=\"64px;\" alt=\"Martin Zagora\"/><br /><sub><b>Martin Zagora</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=zaggino\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kvdo2\"><img src=\"https://avatars.githubusercontent.com/u/78251524?v=4?s=64\" width=\"64px;\" alt=\"KvD\"/><br /><sub><b>KvD</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kvdo2\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SupraSmooth\"><img src=\"https://avatars.githubusercontent.com/u/18029247?v=4?s=64\" width=\"64px;\" alt=\"Alex\"/><br /><sub><b>Alex</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=SupraSmooth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kaceycleveland\"><img src=\"https://avatars.githubusercontent.com/u/88064187?v=4?s=64\" width=\"64px;\" alt=\"Kacey Cleveland\"/><br /><sub><b>Kacey Cleveland</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Akaceycleveland\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oviirup\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoviirup\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yabbal\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"yabbal\"/><br /><sub><b>yabbal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=yabbal\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://patik.com/\"><img src=\"https://avatars.githubusercontent.com/u/262137?v=4?s=64\" width=\"64px;\" alt=\"Craig Patik\"/><br /><sub><b>Craig Patik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Silverium\"><img src=\"https://avatars.githubusercontent.com/u/10578392?v=4?s=64\" width=\"64px;\" alt=\"Soldeplata Saketos Candela\"/><br /><sub><b>Soldeplata Saketos Candela</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Silverium\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TENDOUZHI\"><img src=\"https://avatars.githubusercontent.com/u/82806526?v=4?s=64\" width=\"64px;\" alt=\"TENDOUZHI\"/><br /><sub><b>TENDOUZHI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATENDOUZHI\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/wachulski\"><img src=\"https://avatars.githubusercontent.com/u/1669844?v=4?s=64\" width=\"64px;\" alt=\"Marcin Wachulski\"/><br /><sub><b>Marcin Wachulski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awachulski\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://salmans.work/\"><img src=\"https://avatars.githubusercontent.com/u/15085416?v=4?s=64\" width=\"64px;\" alt=\"Salman Fazal\"/><br /><sub><b>Salman Fazal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asalmanfazal01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shrugs\"><img src=\"https://avatars.githubusercontent.com/u/1535001?v=4?s=64\" width=\"64px;\" alt=\"shrugs\"/><br /><sub><b>shrugs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashrugs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Hyodori04\"><img src=\"https://avatars.githubusercontent.com/u/57362573?v=4?s=64\" width=\"64px;\" alt=\"hyodori\"/><br /><sub><b>hyodori</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AHyodori04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/eleazareramos\"><img src=\"https://avatars.githubusercontent.com/u/25910203?v=4?s=64\" width=\"64px;\" alt=\"Eleazar “E” Ramos\"/><br /><sub><b>Eleazar “E” Ramos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aeleazareramos\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/retnag\"><img src=\"https://avatars.githubusercontent.com/u/18302198?v=4?s=64\" width=\"64px;\" alt=\"retnag\"/><br /><sub><b>retnag</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aretnag\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jaeyoung.dev/\"><img src=\"https://avatars.githubusercontent.com/u/55247450?v=4?s=64\" width=\"64px;\" alt=\"J young Lee\"/><br /><sub><b>J young Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abeefiker\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fiws\"><img src=\"https://avatars.githubusercontent.com/u/3409958?v=4?s=64\" width=\"64px;\" alt=\"Filip Weiss\"/><br /><sub><b>Filip Weiss</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afiws\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://mariusgundersen.net/\"><img src=\"https://avatars.githubusercontent.com/u/464152?v=4?s=64\" width=\"64px;\" alt=\"Marius Gundersen\"/><br /><sub><b>Marius Gundersen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AmariusGundersen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/VenomFate-619\"><img src=\"https://avatars.githubusercontent.com/u/67755128?v=4?s=64\" width=\"64px;\" alt=\"Syed Aman Ali\"/><br /><sub><b>Syed Aman Ali</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AVenomFate-619\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ingadi.work/\"><img src=\"https://avatars.githubusercontent.com/u/6121225?v=4?s=64\" width=\"64px;\" alt=\"Axel Ingadi\"/><br /><sub><b>Axel Ingadi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aingadi\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andyjphu\"><img src=\"https://avatars.githubusercontent.com/u/51890861?v=4?s=64\" width=\"64px;\" alt=\"AndyP\"/><br /><sub><b>AndyP</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandyjphu\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ishanVaghasiya\"><img src=\"https://avatars.githubusercontent.com/u/98661936?v=4?s=64\" width=\"64px;\" alt=\"ishanVaghasiya\"/><br /><sub><b>ishanVaghasiya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AishanVaghasiya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nico-martinucci\"><img src=\"https://avatars.githubusercontent.com/u/80868741?v=4?s=64\" width=\"64px;\" alt=\"Nico Martinucci\"/><br /><sub><b>Nico Martinucci</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anico-martinucci\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/technophile-04\"><img src=\"https://avatars.githubusercontent.com/u/80153681?v=4?s=64\" width=\"64px;\" alt=\"Shiv Bhonde &#124; shivbhonde.eth\"/><br /><sub><b>Shiv Bhonde &#124; shivbhonde.eth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atechnophile-04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fritzmonkey\"><img src=\"https://avatars.githubusercontent.com/u/10103840?v=4?s=64\" width=\"64px;\" alt=\"fritzmonkey\"/><br /><sub><b>fritzmonkey</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afritzmonkey\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/rrmesquita\"><img src=\"https://avatars.githubusercontent.com/u/30835404?v=4?s=64\" width=\"64px;\" alt=\"Rodrigo Mesquita\"/><br /><sub><b>Rodrigo Mesquita</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arrmesquita\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://moshe.io/\"><img src=\"https://avatars.githubusercontent.com/u/534911?v=4?s=64\" width=\"64px;\" alt=\"Moshe Simantov\"/><br /><sub><b>Moshe Simantov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amoshest\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/BekaArabidze98\"><img src=\"https://avatars.githubusercontent.com/u/122085038?v=4?s=64\" width=\"64px;\" alt=\"Beka\"/><br /><sub><b>Beka</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ABekaArabidze98\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/abdofola\"><img src=\"https://avatars.githubusercontent.com/u/30251052?v=4?s=64\" width=\"64px;\" alt=\"Abdallah Alkaser\"/><br /><sub><b>Abdallah Alkaser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aabdofola\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=abdofola\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CarlosNZ\"><img src=\"https://avatars.githubusercontent.com/u/5456533?v=4?s=64\" width=\"64px;\" alt=\"Carl Smith\"/><br /><sub><b>Carl Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACarlosNZ\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ogroppo\"><img src=\"https://avatars.githubusercontent.com/u/4820803?v=4?s=64\" width=\"64px;\" alt=\"Orlando Groppo\"/><br /><sub><b>Orlando Groppo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aogroppo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/thany\"><img src=\"https://avatars.githubusercontent.com/u/152227?v=4?s=64\" width=\"64px;\" alt=\"Martĳn Saly\"/><br /><sub><b>Martĳn Saly</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Athany\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://quinn.io/\"><img src=\"https://avatars.githubusercontent.com/u/3764?v=4?s=64\" width=\"64px;\" alt=\"Quinn Shanahan\"/><br /><sub><b>Quinn Shanahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aquinn\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://antoinek.fr/\"><img src=\"https://avatars.githubusercontent.com/u/54948363?v=4?s=64\" width=\"64px;\" alt=\"Antoine Kingue\"/><br /><sub><b>Antoine Kingue</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAntoineKM\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zanzlender\"><img src=\"https://avatars.githubusercontent.com/u/44570474?v=4?s=64\" width=\"64px;\" alt=\"Žan Žlender\"/><br /><sub><b>Žan Žlender</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Azanzlender\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebadom\"><img src=\"https://avatars.githubusercontent.com/u/3877952?v=4?s=64\" width=\"64px;\" alt=\"Sebastian Dominguez\"/><br /><sub><b>Sebastian Dominguez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebadom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jmc420\"><img src=\"https://avatars.githubusercontent.com/u/11723529?v=4?s=64\" width=\"64px;\" alt=\"James Cowan\"/><br /><sub><b>James Cowan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajmc420\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bayraak\"><img src=\"https://avatars.githubusercontent.com/u/10470072?v=4?s=64\" width=\"64px;\" alt=\"Bayram Ali Basgul\"/><br /><sub><b>Bayram Ali Basgul</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abayraak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://wyatt.castaneda.family/\"><img src=\"https://avatars.githubusercontent.com/u/17957937?v=4?s=64\" width=\"64px;\" alt=\"Wyatt Castaneda\"/><br /><sub><b>Wyatt Castaneda</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWyattCast44\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tsnevillecom\"><img src=\"https://avatars.githubusercontent.com/u/3151454?v=4?s=64\" width=\"64px;\" alt=\"Tim Neville\"/><br /><sub><b>Tim Neville</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atsnevillecom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shoooe\"><img src=\"https://avatars.githubusercontent.com/u/733227?v=4?s=64\" width=\"64px;\" alt=\"Thomas Pigarelli\"/><br /><sub><b>Thomas Pigarelli</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashoooe\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherdman\"><img src=\"https://avatars.githubusercontent.com/u/3300?v=4?s=64\" width=\"64px;\" alt=\"James Herdman\"/><br /><sub><b>James Herdman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherdman\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pociej\"><img src=\"https://avatars.githubusercontent.com/u/3854675?v=4?s=64\" width=\"64px;\" alt=\"Grzegorz Pociejewski\"/><br /><sub><b>Grzegorz Pociejewski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apociej\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/flyon\"><img src=\"https://avatars.githubusercontent.com/u/341567?v=4?s=64\" width=\"64px;\" alt=\"René Verheij\"/><br /><sub><b>René Verheij</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aflyon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PatrykKuniczak\"><img src=\"https://avatars.githubusercontent.com/u/64608510?v=4?s=64\" width=\"64px;\" alt=\"PatrykKuniczak\"/><br /><sub><b>PatrykKuniczak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APatrykKuniczak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://cromodder.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/7691110?v=4?s=64\" width=\"64px;\" alt=\"Paolo Božac\"/><br /><sub><b>Paolo Božac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACroModder\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/reinos\"><img src=\"https://avatars.githubusercontent.com/u/633730?v=4?s=64\" width=\"64px;\" alt=\"Rein\"/><br /><sub><b>Rein</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Areinos\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FloorianB\"><img src=\"https://avatars.githubusercontent.com/u/110407858?v=4?s=64\" width=\"64px;\" alt=\"FloorianB\"/><br /><sub><b>FloorianB</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFloorianB\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xuanhung1509\"><img src=\"https://avatars.githubusercontent.com/u/89293664?v=4?s=64\" width=\"64px;\" alt=\"Xuan Hung\"/><br /><sub><b>Xuan Hung</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axuanhung1509\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://monawwar.io/\"><img src=\"https://avatars.githubusercontent.com/u/31907722?v=4?s=64\" width=\"64px;\" alt=\"Monawwar Abdullah\"/><br /><sub><b>Monawwar Abdullah</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amxvsh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/haroldo-ok\"><img src=\"https://avatars.githubusercontent.com/u/1457465?v=4?s=64\" width=\"64px;\" alt=\"Haroldo de Oliveira Pinheiro\"/><br /><sub><b>Haroldo de Oliveira Pinheiro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharoldo-ok\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://portfoliobytamjid.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/57794102?v=4?s=64\" width=\"64px;\" alt=\"Tamjid Ahmed\"/><br /><sub><b>Tamjid Ahmed</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATamjidAhmed10\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jv-lopez\"><img src=\"https://avatars.githubusercontent.com/u/93750956?v=4?s=64\" width=\"64px;\" alt=\"jv-lopez\"/><br /><sub><b>jv-lopez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajv-lopez\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://macr.ae/\"><img src=\"https://avatars.githubusercontent.com/u/472830?v=4?s=64\" width=\"64px;\" alt=\"Callum Macrae\"/><br /><sub><b>Callum Macrae</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Acallumacrae\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/0529bill\"><img src=\"https://avatars.githubusercontent.com/u/62455148?v=4?s=64\" width=\"64px;\" alt=\"bywater529\"/><br /><sub><b>bywater529</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3A0529bill\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kevinxh\"><img src=\"https://avatars.githubusercontent.com/u/10948652?v=4?s=64\" width=\"64px;\" alt=\"Kevin He\"/><br /><sub><b>Kevin He</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akevinxh\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FredericoGauz\"><img src=\"https://avatars.githubusercontent.com/u/18327882?v=4?s=64\" width=\"64px;\" alt=\"FredericoGauz\"/><br /><sub><b>FredericoGauz</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFredericoGauz\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.jonlemofficial.com/\"><img src=\"https://avatars.githubusercontent.com/u/38771842?v=4?s=64\" width=\"64px;\" alt=\"Jonathan &quot;JonLem&quot; Lemos\"/><br /><sub><b>Jonathan &quot;JonLem&quot; Lemos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJonLemOfficial\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xegulon\"><img src=\"https://avatars.githubusercontent.com/u/74178038?v=4?s=64\" width=\"64px;\" alt=\"Xegulon\"/><br /><sub><b>Xegulon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axegulon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TomSmedley\"><img src=\"https://avatars.githubusercontent.com/u/95056193?v=4?s=64\" width=\"64px;\" alt=\"Tom Smedley\"/><br /><sub><b>Tom Smedley</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATomSmedley\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lightbluepoppy\"><img src=\"https://avatars.githubusercontent.com/u/65863981?v=4?s=64\" width=\"64px;\" alt=\"lightbluepoppy\"/><br /><sub><b>lightbluepoppy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alightbluepoppy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Dchole\"><img src=\"https://avatars.githubusercontent.com/u/47068381?v=4?s=64\" width=\"64px;\" alt=\"Derek Oware\"/><br /><sub><b>Derek Oware</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADchole\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://fragmentedthought.com/\"><img src=\"https://avatars.githubusercontent.com/u/12085479?v=4?s=64\" width=\"64px;\" alt=\"Lance Gliser\"/><br /><sub><b>Lance Gliser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancegliser\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lewxdev\"><img src=\"https://avatars.githubusercontent.com/u/6710419?v=4?s=64\" width=\"64px;\" alt=\"J. Lewis\"/><br /><sub><b>J. Lewis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alewxdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yairy\"><img src=\"https://avatars.githubusercontent.com/u/3206243?v=4?s=64\" width=\"64px;\" alt=\"Yair\"/><br /><sub><b>Yair</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ayairy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://firecamp.dev/\"><img src=\"https://avatars.githubusercontent.com/u/5078921?v=4?s=64\" width=\"64px;\" alt=\"Nishchit\"/><br /><sub><b>Nishchit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANishchit14\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nejjer\"><img src=\"https://avatars.githubusercontent.com/u/80219537?v=4?s=64\" width=\"64px;\" alt=\"Devofy\"/><br /><sub><b>Devofy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANejjer\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://joshguyette.com/\"><img src=\"https://avatars.githubusercontent.com/u/28668902?v=4?s=64\" width=\"64px;\" alt=\"Josh Guyette\"/><br /><sub><b>Josh Guyette</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anightness\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dora-ljh\"><img src=\"https://avatars.githubusercontent.com/u/35205701?v=4?s=64\" width=\"64px;\" alt=\"Dora Li\"/><br /><sub><b>Dora Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Adora-ljh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kg-currenxie\"><img src=\"https://avatars.githubusercontent.com/u/48229166?v=4?s=64\" width=\"64px;\" alt=\"Kristian Gerardsson\"/><br /><sub><b>Kristian Gerardsson</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akg-currenxie\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jdpt0\"><img src=\"https://avatars.githubusercontent.com/u/19761394?v=4?s=64\" width=\"64px;\" alt=\"James Powell\"/><br /><sub><b>James Powell</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajdpt0\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/boaz-poolman-662162115/\"><img src=\"https://avatars.githubusercontent.com/u/9551934?v=4?s=64\" width=\"64px;\" alt=\"Boaz Poolman\"/><br /><sub><b>Boaz Poolman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aboazpoolman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/roker15\"><img src=\"https://avatars.githubusercontent.com/u/59526869?v=4?s=64\" width=\"64px;\" alt=\"roker15\"/><br /><sub><b>roker15</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aroker15\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fadhilx\"><img src=\"https://avatars.githubusercontent.com/u/15516786?v=4?s=64\" width=\"64px;\" alt=\"Fadhil Ahmad\"/><br /><sub><b>Fadhil Ahmad</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afadhilx\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Chandler-Zhu\"><img src=\"https://avatars.githubusercontent.com/u/61914365?v=4?s=64\" width=\"64px;\" alt=\"Chandler-Zhu\"/><br /><sub><b>Chandler-Zhu</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AChandler-Zhu\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nixjs\"><img src=\"https://avatars.githubusercontent.com/u/23132483?v=4?s=64\" width=\"64px;\" alt=\"Nghi Nguyen\"/><br /><sub><b>Nghi Nguyen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anixjs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShravanSunder\"><img src=\"https://avatars.githubusercontent.com/u/5294949?v=4?s=64\" width=\"64px;\" alt=\"Shravan Sunder\"/><br /><sub><b>Shravan Sunder</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AShravanSunder\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Johannes5\"><img src=\"https://avatars.githubusercontent.com/u/14299835?v=4?s=64\" width=\"64px;\" alt=\"Johannes5\"/><br /><sub><b>Johannes5</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJohannes5\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebahhpeya\"><img src=\"https://avatars.githubusercontent.com/u/93996817?v=4?s=64\" width=\"64px;\" alt=\"sebahhpeya\"/><br /><sub><b>sebahhpeya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebahhpeya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://onezero.co.il/\"><img src=\"https://avatars.githubusercontent.com/u/45389557?v=4?s=64\" width=\"64px;\" alt=\"Or Nakash\"/><br /><sub><b>Or Nakash</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aornakash\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hepiyellow\"><img src=\"https://avatars.githubusercontent.com/u/6338722?v=4?s=64\" width=\"64px;\" alt=\"Erez Makavy\"/><br /><sub><b>Erez Makavy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahepiyellow\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandymerskin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/chainalert-bot\"><img src=\"https://avatars.githubusercontent.com/u/95303823?v=4?s=64\" width=\"64px;\" alt=\"ChainAlert Bot\"/><br /><sub><b>ChainAlert Bot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Achainalert-bot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tmdesigned\"><img src=\"https://avatars.githubusercontent.com/u/3608018?v=4?s=64\" width=\"64px;\" alt=\"Taylor Morgan\"/><br /><sub><b>Taylor Morgan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atmdesigned\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://abkabioye.me/\"><img src=\"https://avatars.githubusercontent.com/u/18709032?v=4?s=64\" width=\"64px;\" alt=\"wisdomabioye\"/><br /><sub><b>wisdomabioye</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awisdomabioye\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.samtheq.com\"><img src=\"https://avatars.githubusercontent.com/u/51345689?v=4?s=64\" width=\"64px;\" alt=\"Samuel Quiñones\"/><br /><sub><b>Samuel Quiñones</b></sub></a><br /><a href=\"#ideas-SamuelQuinones\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ymc-maha\"><img src=\"https://avatars.githubusercontent.com/u/697307?v=4?s=64\" width=\"64px;\" alt=\"Manuel\"/><br /><sub><b>Manuel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ymc-maha\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aymc-maha\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Yurchishin\"><img src=\"https://avatars.githubusercontent.com/u/36650915?v=4?s=64\" width=\"64px;\" alt=\"Yurii Rybak\"/><br /><sub><b>Yurii Rybak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AYurchishin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iuriiiurevich\"><img src=\"https://avatars.githubusercontent.com/u/15759600?v=4?s=64\" width=\"64px;\" alt=\"Yury Demin\"/><br /><sub><b>Yury Demin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aiuriiiurevich\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iuriiiurevich\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://tewks.io/\"><img src=\"https://avatars.githubusercontent.com/u/3970573?v=4?s=64\" width=\"64px;\" alt=\"Jon Tewksbury\"/><br /><sub><b>Jon Tewksbury</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jontewks\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajontewks\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/novacdenis\"><img src=\"https://avatars.githubusercontent.com/u/45555668?v=4?s=64\" width=\"64px;\" alt=\"Novac Denis\"/><br /><sub><b>Novac Denis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novacdenis\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anovacdenis\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kyrylo-soulandwolf\"><img src=\"https://avatars.githubusercontent.com/u/54762253?v=4?s=64\" width=\"64px;\" alt=\"kyrylo-soulandwolf\"/><br /><sub><b>kyrylo-soulandwolf</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kyrylo-soulandwolf\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akyrylo-soulandwolf\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/misidoro\"><img src=\"https://avatars.githubusercontent.com/u/3635023?v=4?s=64\" width=\"64px;\" alt=\"Miguel Isidoro\"/><br /><sub><b>Miguel Isidoro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=misidoro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://crowds.space/\"><img src=\"https://avatars.githubusercontent.com/u/828918?v=4?s=64\" width=\"64px;\" alt=\"Yuriy Gromchenko\"/><br /><sub><b>Yuriy Gromchenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gromchen\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://jcbhmr.me\"><img src=\"https://avatars.githubusercontent.com/u/61068799?v=4?s=64\" width=\"64px;\" alt=\"Jacob Hummer\"/><br /><sub><b>Jacob Hummer</b></sub></a><br /><a href=\"#ideas-jcbhmr\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/k-melnychuk\"><img src=\"https://avatars.githubusercontent.com/u/22131019?v=4?s=64\" width=\"64px;\" alt=\"Kyrylo Melnychuk\"/><br /><sub><b>Kyrylo Melnychuk</b></sub></a><br /><a href=\"#content-k-melnychuk\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=k-melnychuk\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LumaKernel\"><img src=\"https://avatars.githubusercontent.com/u/29811106?v=4?s=64\" width=\"64px;\" alt=\"Luma\"/><br /><sub><b>Luma</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LumaKernel\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Newbie012\"><img src=\"https://avatars.githubusercontent.com/u/10504365?v=4?s=64\" width=\"64px;\" alt=\"Eliya Cohen\"/><br /><sub><b>Eliya Cohen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Newbie012\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isumix\"><img src=\"https://avatars.githubusercontent.com/u/16747416?v=4?s=64\" width=\"64px;\" alt=\"Igor Sukharev\"/><br /><sub><b>Igor Sukharev</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisumix\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pookmish\"><img src=\"https://avatars.githubusercontent.com/u/7185045?v=4?s=64\" width=\"64px;\" alt=\"pookmish\"/><br /><sub><b>pookmish</b></sub></a><br /><a href=\"#ideas-pookmish\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/metav-drimz\"><img src=\"https://avatars.githubusercontent.com/u/113976282?v=4?s=64\" width=\"64px;\" alt=\"metav-drimz\"/><br /><sub><b>metav-drimz</b></sub></a><br /><a href=\"#ideas-metav-drimz\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://luckrnx09.com/\"><img src=\"https://avatars.githubusercontent.com/u/113882203?v=4?s=64\" width=\"64px;\" alt=\"luckrnx09\"/><br /><sub><b>luckrnx09</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=luckrnx09\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RubyHuntsman\"><img src=\"https://avatars.githubusercontent.com/u/24682602?v=4?s=64\" width=\"64px;\" alt=\"Hubert Kuczmierczyk\"/><br /><sub><b>Hubert Kuczmierczyk</b></sub></a><br /><a href=\"#ideas-RubyHuntsman\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ARubyHuntsman\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dandubya\"><img src=\"https://avatars.githubusercontent.com/u/67660308?v=4?s=64\" width=\"64px;\" alt=\"dandubya\"/><br /><sub><b>dandubya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=dandubya\" title=\"Documentation\">📖</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LonelyFellas\"><img src=\"https://avatars.githubusercontent.com/u/38754760?v=4?s=64\" width=\"64px;\" alt=\"Darwish\"/><br /><sub><b>Darwish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LonelyFellas\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.jesuisjo.com/\"><img src=\"https://avatars.githubusercontent.com/u/2046871?v=4?s=64\" width=\"64px;\" alt=\"Jonathan Raoult\"/><br /><sub><b>Jonathan Raoult</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajraoult\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ajraoult\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification ([emoji key](https://allcontributors.org/docs/en/emoji-key)). Contributions of any kind welcome!\n\n## 💞 Donate\n\nIf you find this piece of software helpful, please consider a donation. Any amount is greatly appreciated.\n\n[![GitHub Sponsors](https://badgen.net/badge/GitHub%20Sponsors/Donate/blue)](https://github.com/sponsors/juliencrn)\n[![Paypal](https://badgen.net/badge/Paypal/Donate/blue)](https://www.paypal.com/paypalme/juliencrn)\n[![Stripe](https://badgen.net/badge/Stripe/Donate/blue)](https://buy.stripe.com/fZefZY8Bv32cg9O3cc)\n[![Buy me a coffee](https://badgen.net/badge/Buy%20me%20a%20coffee/Donate/blue)](https://www.buymeacoffee.com/juliencrn)\n\nBTC: `bc1qwys40tnd0lxf9lr9l0t6xc63dpxyucj4x4nay0`\n\nETH: `0x36a85155a8300754C56395D5af24553FB18915D6`\n\n## 📝 License\n\nThis project is [MIT](https://github.com/juliencrn/usehooks-ts/blob/master/LICENSE) licensed.\n"
  },
  {
    "path": "apps/www/.eslintrc.cjs",
    "content": "module.exports = {\n  extends: ['next/core-web-vitals', 'custom'],\n  rules: {\n    '@typescript-eslint/require-await': 'off',\n  },\n}\n"
  },
  {
    "path": "apps/www/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# generated\n/.next/\n/out/\n/build\ngenerated\npublic/sitemap.xml\npublic/robots.txt\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# local env files\n.env*.local\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\n\n\n"
  },
  {
    "path": "apps/www/CHANGELOG.md",
    "content": "# www\n\n## 1.0.4\n\n### Patch Changes\n\n- Updated dependencies [b1dffb9]\n  - usehooks-ts@3.1.1\n\n## 1.0.3\n\n### Patch Changes\n\n- Updated dependencies [e62c41f]\n- Updated dependencies [90a33f5]\n- Updated dependencies [06dfd5e]\n  - usehooks-ts@3.1.0\n\n## 1.0.2\n\n### Patch Changes\n\n- 4f40e02: Fix a link in migration docs\n- Updated dependencies [b14db5b]\n- Updated dependencies [59c0b93]\n- Updated dependencies [b14db5b]\n- Updated dependencies [b14db5b]\n- Updated dependencies [09341a3]\n  - usehooks-ts@3.0.2\n\n## 1.0.1\n\n### Patch Changes\n\n- Updated dependencies\n  - usehooks-ts@3.0.1\n\n## 1.0.0\n\n### Major Changes\n\n- a8e8968: Remove previously deprecated hooks and hooks' signatures (#503)\n- a8e8968: Move the full workspace into ES Module\n\n### Minor Changes\n\n- a8e8968: Prefer type over interface (#515)\n\n### Patch Changes\n\n- Updated dependencies [a8e8968]\n- Updated dependencies [a8e8968]\n- Updated dependencies [a8e8968]\n- Updated dependencies [a8e8968]\n  - usehooks-ts@3.0.0\n\n## 0.2.4\n\n### Patch Changes\n\n- 0d99db9: chore(deps): update all non-major dependencies\n- Updated dependencies [d881f08]\n- Updated dependencies [fc25779]\n- Updated dependencies [9b65ce8]\n- Updated dependencies [d42741f]\n- Updated dependencies [d42741f]\n- Updated dependencies [d881f08]\n- Updated dependencies [0d99db9]\n- Updated dependencies [d881f08]\n  - usehooks-ts@2.16.0\n\n## 0.2.3\n\n### Patch Changes\n\n- Updated dependencies [b88cc01]\n- Updated dependencies [823b62f]\n  - usehooks-ts@2.15.1\n\n## 0.2.2\n\n### Patch Changes\n\n- 4456e32: chore: improve introduction page\n- Updated dependencies [649ef39]\n- Updated dependencies [649ef39]\n- Updated dependencies [6514683]\n  - usehooks-ts@2.15.0\n\n## 0.2.1\n\n### Patch Changes\n\n- Updated dependencies [7d74e09]\n- Updated dependencies [2660580]\n- Updated dependencies [bc3f967]\n- Updated dependencies [d60f1c6]\n  - usehooks-ts@2.14.0\n\n## 0.2.0\n\n### Minor Changes\n\n- b5b9e1f: chore: Updated dependencies\n- 4c8c330: various improvements to the site\n\n### Patch Changes\n\n- bdf7bda: Add eslint rules to comply with verbatimModuleSyntax to avoid side-effects\n- Updated dependencies [87a5141]\n- Updated dependencies [b5b9e1f]\n- Updated dependencies [87ba579]\n- Updated dependencies [4146c39]\n- Updated dependencies [bdf7bda]\n- Updated dependencies [6b582de]\n- Updated dependencies [f39078f]\n- Updated dependencies [a444ba7]\n- Updated dependencies [e807ab3]\n- Updated dependencies [be8c35b]\n  - usehooks-ts@2.13.0\n\n## 0.1.6\n\n### Patch Changes\n\n- Updated dependencies\n  - usehooks-ts@2.12.1\n\n## 0.1.5\n\n### Patch Changes\n\n- Updated dependencies [cb6eb5c]\n- Updated dependencies [b8ee088]\n  - usehooks-ts@2.12.0\n\n## 0.1.4\n\n### Patch Changes\n\n- add1431: Upgrade dependencies\n- 0321342: Make Typescript and typescript-eslint stricter\n- Updated dependencies [4a9fc88]\n- Updated dependencies [add1431]\n- Updated dependencies [add1431]\n- Updated dependencies [4a9fc88]\n- Updated dependencies [a192167]\n- Updated dependencies [0321342]\n- Updated dependencies [382161a]\n- Updated dependencies [5c210c1]\n- Updated dependencies [add1431]\n- Updated dependencies [add1431]\n- Updated dependencies [382161a]\n- Updated dependencies [a192167]\n- Updated dependencies [5c210c1]\n- Updated dependencies [0321342]\n- Updated dependencies [fc8a30e]\n  - usehooks-ts@2.11.0\n\n## 0.1.3\n\n### Patch Changes\n\n- Updated dependencies [a816d6b]\n- Updated dependencies [42f3a3a]\n- Updated dependencies [9bc05f4]\n- Updated dependencies [4b3ed4e]\n- Updated dependencies [8f3c90f]\n- Updated dependencies [a3588b8]\n- Updated dependencies [c326dd3]\n- Updated dependencies [e8aa777]\n- Updated dependencies [c5ad2b9]\n- Updated dependencies [7406e3c]\n- Updated dependencies [ffe0f32]\n- Updated dependencies [ae47c9a]\n- Updated dependencies [771afa5]\n  - usehooks-ts@2.10.0\n\n## 0.1.2\n\n### Patch Changes\n\n- 7141d01: Upgrade internal dependencies\n- Update useCopyToClipboard documentation\n- Fix typo in useEventListener\n- Updated dependencies [7141d01]\n- Updated dependencies\n- Updated dependencies\n  - usehooks-ts@2.9.5\n\n## 0.1.1\n\n### Patch Changes\n\n- Updated dependencies\n  - usehooks-ts@2.9.4\n"
  },
  {
    "path": "apps/www/env.js",
    "content": "/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport { createEnv } from '@t3-oss/env-nextjs'\nimport { z } from 'zod'\n\nexport const env = createEnv({\n  server: {},\n  client: {\n    NEXT_PUBLIC_GA_MEASUREMENT_ID: z.string().optional().default(''),\n    NEXT_PUBLIC_ALGOLIA_APP_ID: z.string().optional().default(''),\n    NEXT_PUBLIC_ALGOLIA_SEARCH_KEY: z.string().optional().default(''),\n    NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.string().optional().default(''),\n  },\n  runtimeEnv: {\n    NEXT_PUBLIC_GA_MEASUREMENT_ID: process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID,\n    NEXT_PUBLIC_ALGOLIA_APP_ID: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,\n    NEXT_PUBLIC_ALGOLIA_SEARCH_KEY: process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY,\n    NEXT_PUBLIC_UMAMI_WEBSITE_ID: process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID,\n  },\n})\n"
  },
  {
    "path": "apps/www/next-sitemap.config.js",
    "content": "/**\n * Generate sitemap.xml and robots.txt for all kind of pages\n * @doc https://www.npmjs.com/package/next-sitemap\n */\n\n/** @type {import('next-sitemap').IConfig} */\nconst config = {\n  siteUrl: 'https://usehooks-ts.com',\n  changefreq: 'daily',\n  priority: 0.7,\n  generateIndexSitemap: false,\n  generateRobotsTxt: true,\n  robotsTxtOptions: {\n    policies: [\n      {\n        userAgent: '*',\n        allow: '/',\n      },\n    ],\n  },\n}\n\nexport default config\n"
  },
  {
    "path": "apps/www/next.config.js",
    "content": "import './env.js'\n\nconst deletedHooks = [\n  'use-debounce',\n  'use-effect-once',\n  'use-element-size',\n  'use-fetch',\n  'use-image-on-load',\n  'use-is-first-render',\n  'use-locked-body',\n  'use-update-effect',\n]\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  async redirects() {\n    return deletedHooks.map(slug => ({\n      source: `/react-hook/${slug}`,\n      destination: '/migrate-to-v3#removed-hooks',\n      permanent: true,\n    }))\n  },\n}\n\nexport default nextConfig\n"
  },
  {
    "path": "apps/www/package.json",
    "content": "{\n  \"name\": \"www\",\n  \"version\": \"1.0.4\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"pnpm generate-doc && next build && pnpm generate-sitemap\",\n    \"generate-sitemap\": \"rimraf public/sitemap.xml public/robots.txt && next-sitemap --config ./next-sitemap.config.js\",\n    \"start\": \"next start\",\n    \"lint\": \"next lint && tsc --noEmit\",\n    \"clean\": \"rimraf *.tsbuildinfo .next .turbo\",\n    \"generate-doc\": \"cd ../.. && pnpm generate-doc && cd -\"\n  },\n  \"dependencies\": {\n    \"@next/third-parties\": \"^14.1.0\",\n    \"@radix-ui/react-dialog\": \"^1.0.5\",\n    \"@radix-ui/react-dropdown-menu\": \"^2.0.6\",\n    \"@radix-ui/react-slot\": \"^1.0.2\",\n    \"@t3-oss/env-nextjs\": \"^0.9.2\",\n    \"@types/voca\": \"^1.4.1\",\n    \"algoliasearch\": \"^4.22.1\",\n    \"class-variance-authority\": \"^0.7.0\",\n    \"clsx\": \"^2.1.0\",\n    \"cmdk\": \"^1.0.0\",\n    \"date-fns\": \"^3.3.1\",\n    \"gray-matter\": \"^4.0.3\",\n    \"lucide-react\": \"^0.364.0\",\n    \"next\": \"14.1.4\",\n    \"next-mdx-remote\": \"^4.4.1\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"react-instantsearch\": \"^7.6.0\",\n    \"rehype-prism-plus\": \"^2.0.0\",\n    \"remark-gfm\": \"^3.0.1\",\n    \"schema-dts\": \"^1.1.2\",\n    \"tailwind-merge\": \"^2.2.1\",\n    \"tailwindcss\": \"3.4.3\",\n    \"tailwindcss-animate\": \"^1.0.7\",\n    \"usehooks-ts\": \"workspace:*\",\n    \"voca\": \"^1.4.1\",\n    \"zod\": \"^3.22.4\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/line-clamp\": \"^0.4.4\",\n    \"@tailwindcss/typography\": \"^0.5.10\",\n    \"@types/node\": \"20.12.2\",\n    \"@types/react\": \"18.2.73\",\n    \"@types/react-dom\": \"18.2.23\",\n    \"autoprefixer\": \"10.4.19\",\n    \"eslint-config-custom\": \"workspace:*\",\n    \"eslint-config-next\": \"14.1.4\",\n    \"next-sitemap\": \"^4.2.3\",\n    \"postcss\": \"8.4.38\",\n    \"typescript\": \"5.4.3\"\n  }\n}\n"
  },
  {
    "path": "apps/www/postcss.config.cjs",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "apps/www/public/site.webmanifest",
    "content": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/android-chrome-512x512.png\",\"sizes\":\"512x512\",\"type\":\"image/png\"}],\"theme_color\":\"#ffffff\",\"background_color\":\"#ffffff\",\"display\":\"standalone\"}"
  },
  {
    "path": "apps/www/src/app/(docs)/introduction/page.tsx",
    "content": "import { CommandCopy } from '@/components/command-copy'\nimport { PageHeader } from '@/components/docs/page-header'\nimport { RightSidebar } from '@/components/docs/right-sidebar'\nimport { components } from '@/components/ui/components'\nimport { siteConfig } from '@/config/site'\n\nexport default async function IntroductionPage() {\n  return (\n    <main className=\"relative py-6 lg:gap-10 lg:py-10 xl:grid xl:grid-cols-[1fr_300px]\">\n      <div className=\"mx-auto w-full min-w-0\">\n        <PageHeader\n          id=\"introduction\"\n          className=\"scroll-m-20\"\n          heading={'Getting started'}\n        />\n        <components.h2>Introduction</components.h2>\n        <components.p>\n          <span className=\"font-bold\">useHooks(🔥).ts </span>\n          is a React hooks library, written in Typescript and easy to use. It\n          provides a set of hooks that enables you to build your React\n          applications faster. The hooks are built upon the principles of{' '}\n          <span className=\"font-semibold\">DRY</span> (Don&apos;t Repeat\n          Yourself). There are hooks for most common use cases you might need.\n        </components.p>\n        <components.p>\n          The library is designed to be as minimal as possible. It is fully\n          tree-shakable (using the ESM version), meaning that you only import\n          the hooks you need, and the rest will be removed from your bundle\n          making the cost of using this library negligible. Most hooks are\n          extensively tested and are being used in production environments.\n        </components.p>\n        <components.h2>Install</components.h2>\n        <components.p>\n          Get started installing{' '}\n          <components.code>\n            <components.a href={siteConfig.links.npm}>usehooks-ts</components.a>\n          </components.code>{' '}\n          using your preferred package manager.\n        </components.p>\n        <CommandCopy\n          className=\"my-2\"\n          command={{\n            npm: 'npm install usehooks-ts',\n            pnpm: 'pnpm add usehooks-ts',\n            yarn: 'yarn add usehooks-ts',\n            bun: 'bun add usehooks-ts',\n          }}\n        />\n      </div>\n\n      <RightSidebar\n        toc={{\n          items: [\n            { title: 'Introduction', url: '#introduction' },\n            { title: 'Install', url: '#install' },\n          ],\n        }}\n      />\n    </main>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/(docs)/layout.tsx",
    "content": "import Link from 'next/link'\n\nimport { DocSearch } from '@/components/doc-search'\nimport { LeftSidebar } from '@/components/docs/left-sidebar'\nimport { MainNav } from '@/components/main-nav'\nimport { GitHub } from '@/components/ui/icons'\nimport { docsConfig } from '@/config/docs'\nimport { siteConfig } from '@/config/site'\nimport { getHookList } from '@/lib/api'\n\ntype DocsLayoutProps = {\n  children: React.ReactNode\n}\n\nexport default async function DocsLayout({ children }: DocsLayoutProps) {\n  const hooks = await getHookList()\n\n  return (\n    <>\n      <header className=\"sticky top-0 z-40 w-full border-b bg-background\">\n        <div className=\"container flex h-16 items-center space-x-4 sm:justify-between sm:space-x-0\">\n          <MainNav items={docsConfig.mainNav}>\n            <LeftSidebar items={docsConfig.sidebarNav} hooks={hooks} />\n          </MainNav>\n          <div className=\"flex flex-1 items-center space-x-4 sm:justify-end\">\n            <nav className=\"flex space-x-4\">\n              <DocSearch />\n              <Link\n                href={siteConfig.links.github}\n                target=\"_blank\"\n                rel=\"noreferrer\"\n                className=\"flex\"\n              >\n                <GitHub className=\"h-6 w-6 my-auto\" />\n                <span className=\"sr-only\">GitHub</span>\n              </Link>\n            </nav>\n          </div>\n        </div>\n      </header>\n\n      <main className=\"container flex-1\">\n        <div className=\"flex-1 md:grid md:grid-cols-[220px_1fr] md:gap-6 lg:grid-cols-[240px_1fr] lg:gap-10\">\n          <LeftSidebar items={docsConfig.sidebarNav} hooks={hooks} />\n          {children}\n        </div>\n      </main>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/(docs)/migrate-to-v3/page.tsx",
    "content": "import { PageHeader } from '@/components/docs/page-header'\nimport { RightSidebar } from '@/components/docs/right-sidebar'\nimport { components } from '@/components/ui/components'\n\nexport default async function MigrateToV3Page() {\n  return (\n    <main className=\"relative py-6 lg:gap-10 lg:py-10 xl:grid xl:grid-cols-[1fr_300px]\">\n      <div className=\"mx-auto w-full min-w-0\">\n        <PageHeader\n          id=\"migrate-to-v3\"\n          className=\"scroll-m-20\"\n          heading={'Migrate to v3'}\n        />\n        <components.h2>Introduction</components.h2>\n        <components.p>\n          <components.code>usehooks-ts</components.code>\n          {` bumped to version\n          3 and it's a major release with a lot of changes\n          and improvements.`}\n        </components.p>\n\n        <components.p></components.p>\n\n        <components.h2>Changes</components.h2>\n        <components.h3>Removed hooks</components.h3>\n        <components.p>\n          Some hooks were removed from the library. The following hooks were\n          removed:\n        </components.p>\n        <components.ul>\n          <components.li>\n            <components.code>useDebounce</components.code>: Replaced by both{' '}\n            <components.a href=\"/react-hook/use-debounce-value\">\n              useDebounceValue\n            </components.a>{' '}\n            and{' '}\n            <components.a href=\"/react-hook/use-debounce-callback\">\n              useDebounceCallback\n            </components.a>\n            .\n          </components.li>\n          <components.li>\n            <components.code>useFetch</components.code>\n            {`: Prefer other solutions\n            like React server components, your framework's data fetching\n            solution, or a caching library like `}\n            <components.a href=\"https://swr.vercel.app\">SWR</components.a> or{' '}\n            <components.a href=\"https://tanstack.com/query/latest\">\n              React Query\n            </components.a>\n            .\n          </components.li>\n          <components.li>\n            <components.code>useElementSize</components.code>: Replaced by more\n            performant{' '}\n            <components.a href=\"/react-hook/use-resize-observer\">\n              <components.code>useResizeObserver</components.code>\n            </components.a>\n            .\n          </components.li>\n          <components.li>\n            <components.code>useLockedBody</components.code>: Replaced by more\n            generic{' '}\n            <components.a href=\"/react-hook/use-scroll-lock\">\n              <components.code>useScrollLock</components.code>\n            </components.a>\n            .\n          </components.li>\n          <components.li>\n            <components.code>useIsFirstRender</components.code>: Not comply with\n            the React functional mindset.\n          </components.li>\n          <components.li>\n            <components.code>useSsr</components.code>: It was not a React hook.\n          </components.li>\n          <components.li>\n            <components.code>useEffectOnce</components.code>: Unnecessary\n            abstraction, prefer built-in React hooks.\n          </components.li>\n          <components.li>\n            <components.code>useUpdateEffect</components.code>: Unnecessary\n            abstraction, prefer built-in React hooks.\n          </components.li>\n          <components.li>\n            <components.code>useImageOnLoad</components.code>: Too opinionated.\n          </components.li>\n        </components.ul>\n\n        <components.h3>Updated hook signatures</components.h3>\n        <components.p>\n          Some hook signature have been updated introducing breaking changes.\n        </components.p>\n        <components.ul>\n          <components.li>\n            <components.a href=\"/react-hook/use-countdown\">\n              <components.code>useCountdown</components.code>\n            </components.a>\n          </components.li>\n          <components.li>\n            <components.a href=\"/react-hook/use-dark-mode\">\n              <components.code>useDarkMode</components.code>\n            </components.a>\n          </components.li>\n          <components.li>\n            <components.a href=\"/react-hook/use-intersection-observer\">\n              <components.code>useIntersectionObserver</components.code>\n            </components.a>\n          </components.li>\n          <components.li>\n            <components.a href=\"/react-hook/use-media-query\">\n              <components.code>useMediaQuery</components.code>\n            </components.a>\n          </components.li>\n          <components.li>\n            <components.a href=\"/react-hook/use-ternary-dark-mode\">\n              <components.code>useTernaryDarkMode</components.code>\n            </components.a>\n          </components.li>\n        </components.ul>\n      </div>\n\n      <RightSidebar\n        toc={{\n          items: [\n            { title: 'Introduction', url: '#introduction' },\n            {\n              title: 'Changes',\n              url: '#changes',\n              items: [\n                { title: 'Removed hooks', url: '#removed-hooks' },\n                {\n                  title: 'Updated hook signatures',\n                  url: '#updated-hook-signatures',\n                },\n              ],\n            },\n          ],\n        }}\n      />\n    </main>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/(docs)/react-hook/[slug]/page.tsx",
    "content": "import type { Metadata } from 'next'\nimport type { Article, WithContext } from 'schema-dts'\n\nimport { PageHeader } from '@/components/docs/page-header'\nimport { Pager } from '@/components/docs/pager'\nimport { RightSidebar } from '@/components/docs/right-sidebar'\nimport { siteConfig } from '@/config/site'\nimport { getHook, getHookList } from '@/lib/api'\n\nexport const generateStaticParams = async () => {\n  const hooks = await getHookList()\n  return hooks.map(hook => ({ slug: hook.slug }))\n}\n\nfunction stringifyDescription(description: string) {\n  return description.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1').replace(/`/g, '')\n}\n\nfunction getPostUrl(slug: string) {\n  return `${siteConfig.url}/react-hook/${slug}`\n}\n\nfunction getImageUrl(name: string) {\n  return `https://via.placeholder.com/1200x630.png/007ACC/fff/?text=${name}`\n}\n\nexport const generateMetadata = async (props: {\n  params: { slug: string }\n}): Promise<Metadata> => {\n  const hooks = await getHookList()\n  const hook = hooks.find(hook => hook.slug === props.params.slug)\n  if (!hook) {\n    return {}\n  }\n\n  const title = hook.name\n  const description = stringifyDescription(hook.summary)\n  const url = getPostUrl(hook.slug)\n  const imageUrl = getImageUrl(title)\n  return {\n    title,\n    description,\n    openGraph: {\n      title,\n      description,\n      type: 'article',\n      url,\n      images: [\n        {\n          url: imageUrl,\n          width: 1200,\n          height: 630,\n          alt: title,\n        },\n      ],\n    },\n    twitter: {\n      card: 'summary_large_image',\n      title,\n      description,\n      images: [imageUrl],\n    },\n  }\n}\n\nexport default async function HookPage({\n  params,\n}: {\n  params: { slug: string }\n}) {\n  const [{ frontmatter, content }, hookList] = await Promise.all([\n    getHook(params.slug),\n    getHookList(),\n  ])\n\n  const ldJson: WithContext<Article> = {\n    '@context': 'https://schema.org',\n    '@type': 'Article',\n    headline: frontmatter.name,\n    description: stringifyDescription(frontmatter.summary),\n    url: getPostUrl(frontmatter.slug),\n    image: [getImageUrl(frontmatter.name)],\n    author: [\n      {\n        '@type': 'Organization',\n        name: 'usehooks-ts',\n        url: siteConfig.url,\n      },\n    ],\n  }\n\n  return (\n    <>\n      <script\n        id=\"ld-json\"\n        type=\"application/ld+json\"\n        dangerouslySetInnerHTML={{\n          __html: JSON.stringify(ldJson),\n        }}\n      />\n\n      <main className=\"relative py-6 lg:gap-10 lg:py-10 xl:grid xl:grid-cols-[1fr_300px] xl:grid-rows-[auto_1fr_auto]\">\n        <div className=\"mx-auto w-full min-w-0 grid\">\n          <PageHeader\n            id=\"introduction\"\n            className=\"scroll-m-20\"\n            heading={frontmatter.name}\n          />\n\n          {content}\n\n          <hr className=\"my-4 md:my-6\" />\n          <Pager slug={frontmatter.slug} hooks={hookList} />\n        </div>\n\n        <RightSidebar\n          toc={{\n            items: [\n              { title: 'Usage', url: '#usage' },\n              { title: 'API', url: '#api' },\n              { title: 'Hook', url: '#hook' },\n            ],\n          }}\n        />\n      </main>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/(marketing)/layout.tsx",
    "content": "import Link from 'next/link'\n\nimport { DocSearch } from '@/components/doc-search'\nimport { MainNav } from '@/components/main-nav'\nimport { GitHub } from '@/components/ui/icons'\nimport { marketingConfig } from '@/config/marketing'\nimport { siteConfig } from '@/config/site'\n\ntype MarketingLayoutProps = {\n  children: React.ReactNode\n}\n\nexport default async function MarketingLayout({\n  children,\n}: MarketingLayoutProps) {\n  return (\n    <>\n      <header className=\"container z-40 bg-background\">\n        <div className=\"flex h-20 items-center justify-between py-6\">\n          <MainNav items={marketingConfig.mainNav} />\n          <nav className=\"flex space-x-4 justify-center align-middle\">\n            <DocSearch />\n\n            <Link\n              href={siteConfig.links.github}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n              className=\"flex\"\n            >\n              <GitHub className=\"h-6 w-6 my-auto\" />\n              <span className=\"sr-only\">GitHub</span>\n            </Link>\n          </nav>\n        </div>\n      </header>\n\n      <main className=\"flex-1\">{children}</main>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/(marketing)/page.tsx",
    "content": "import type { LucideIcon } from 'lucide-react'\nimport { Blocks, ChevronRight, Gift, Star } from 'lucide-react'\nimport Link from 'next/link'\nimport type { BreadcrumbList, WithContext } from 'schema-dts'\n\nimport { buttonVariants } from '@/components/ui/button'\nimport {\n  Code,\n  GitHub,\n  Globe,\n  Leaf,\n  Puzzle,\n  Unplug,\n  Zap,\n} from '@/components/ui/icons'\nimport { siteConfig } from '@/config/site'\nimport { getHookList } from '@/lib/api'\nimport { cn } from '@/lib/utils'\n\ntype Feature = {\n  icon: LucideIcon\n  title: string\n  content: string\n}\n\nconst features: Feature[] = [\n  {\n    icon: Zap,\n    title: 'Lightweight',\n    content:\n      'usehooks-ts is a tiny library without any dependencies, ensuring a lean and efficient solution.',\n  },\n  {\n    icon: Unplug,\n    title: 'Type-Safe',\n    content:\n      'Catch compile-time errors with ease and unlock strong typing benefits.',\n  },\n  {\n    icon: Leaf,\n    title: 'Tree-Shakable',\n    content:\n      'Eliminating unused code and delivering leaner bundles for lightning-fast load times.',\n  },\n  {\n    icon: Puzzle,\n    title: 'Easy to Use',\n    content:\n      'Get started in no time! Explore comprehensive documentation and rich examples.',\n  },\n  {\n    icon: Code,\n    title: 'Developer-Friendly',\n    content:\n      \"Simplify development with an intuitive and powerful API. Don't repeat yourself.\",\n  },\n  {\n    icon: Globe,\n    title: 'Open-Source',\n    content:\n      'Join the vibrant community! Collaborate, contribute, and unlock endless possibilities together.',\n  },\n]\n\nasync function getGitHubStars(): Promise<string | null> {\n  try {\n    const response = await fetch(\n      'https://api.github.com/repos/juliencrn/usehooks-ts',\n      {\n        headers: {\n          Accept: 'application/vnd.github+json',\n        },\n        next: {\n          revalidate: 60,\n        },\n      },\n    )\n\n    if (!response?.ok) {\n      return null\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n    const json = await response.json()\n\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/dot-notation\n    return parseInt(json['stargazers_count']).toLocaleString()\n  } catch (error) {\n    return null\n  }\n}\n\nexport default async function IndexPage() {\n  const stars = await getGitHubStars()\n  const hooks = await getHookList()\n\n  const ldJson: WithContext<BreadcrumbList> = {\n    '@context': 'https://schema.org',\n    '@type': 'BreadcrumbList',\n    name: siteConfig.name,\n    description: siteConfig.description,\n    url: siteConfig.url,\n    itemListElement: (hooks || []).map((hook, index) => ({\n      '@type': 'ListItem',\n      position: index + 1,\n      name: hook.name,\n      item: `${siteConfig.url}/react-hook/${hook.slug}`,\n    })),\n  }\n\n  return (\n    <>\n      <script\n        type=\"application/ld+json\"\n        dangerouslySetInnerHTML={{\n          __html: JSON.stringify(ldJson),\n        }}\n      />\n\n      <section className=\"space-y-6 pb-12 pt-10 lg:py-32\">\n        <div className=\"container flex max-w-[64rem] flex-col items-center gap-4 text-center\">\n          <h1 className=\"font-heading text-3xl sm:text-5xl md:text-6xl lg:text-7xl\">\n            {siteConfig.name}\n          </h1>\n          <p className=\"max-w-[42rem] leading-normal text-muted-foreground sm:text-xl sm:leading-8\">\n            {siteConfig.description}\n          </p>\n          <div className=\"my-2\">\n            <Link\n              href=\"/introduction\"\n              className={cn(buttonVariants({ size: 'lg' }))}\n            >\n              Explore the docs{` `}\n              <ChevronRight className=\"ml-3 h-5 w-5\" />\n            </Link>\n          </div>\n        </div>\n      </section>\n\n      <section\n        id=\"features\"\n        className=\"container space-y-6 bg-slate-50 dark:bg-transparent py-16 lg:py-32\"\n      >\n        <div className=\"mx-auto flex max-w-[58rem] flex-col items-center space-y-4 text-center\">\n          <h2 className=\"font-heading text-3xl leading-[1.1] sm:text-3xl md:text-6xl\">\n            Features\n          </h2>\n          {/* <p className=\"max-w-[85%] leading-normal text-muted-foreground sm:text-lg sm:leading-7\">\n            This project is an experiment to see how a modern app, with features\n            like auth, subscriptions, API routes, and static pages would work in\n            Next.js 13 app dir.\n          </p> */}\n        </div>\n        <div className=\"mx-auto grid justify-center gap-4 sm:grid-cols-2 md:max-w-[64rem] md:grid-cols-3\">\n          {features.map(({ title, content, icon: Icon }, i) => (\n            <div\n              key={i}\n              className=\"relative overflow-hidden rounded-lg border bg-background p-2\"\n            >\n              <div className=\"flex min-h-[180px] flex-col justify-start rounded-md p-6\">\n                <Icon className=\"h-8 w-8 mb-3\" />\n                <div className=\"space-y-2\">\n                  <h3 className=\"font-bold\">{title}</h3>\n                  <p className=\"text-sm\">{content}</p>\n                </div>\n              </div>\n            </div>\n          ))}\n        </div>\n      </section>\n\n      <section id=\"pricing\" className=\"container  py-16 lg:py-32\">\n        <div className=\"mx-auto flex max-w-[58rem] flex-col items-center justify-center gap-4 text-center mb-8 lg:mb-12\">\n          <h2 className=\"font-heading text-3xl leading-[1.1] sm:text-3xl md:text-6xl\">\n            Pricing\n          </h2>\n          <p className=\"max-w-[85%] leading-normal text-muted-foreground sm:text-lg sm:leading-7\">\n            Just kidding! usehooks-ts is free and open-source.\n            <br />\n            You can still make your contribution!\n          </p>\n        </div>\n\n        <div className=\"mx-auto flex max-w-[40rem] divide-x divide-solid\">\n          <div className=\"flex-1 p-4 md:px-8 flex flex-col justify-end gap-3\">\n            <Link\n              className={cn(\n                buttonVariants({ variant: 'secondary' }),\n                'justify-start',\n              )}\n              href={siteConfig.links.github}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n            >\n              <Star fill=\"white\" className=\"h-6 w-6 mr-2\" />\n              Give us a star\n            </Link>\n            <Link\n              className={cn(\n                buttonVariants({ variant: 'secondary' }),\n                'justify-start',\n              )}\n              href={`${siteConfig.links.github}/blob/master/.github/CONTRIBUTING.md`}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n            >\n              <Blocks fill=\"white\" className=\"h-6 w-6 mr-2\" />\n              Contribute\n            </Link>\n          </div>\n\n          <div className=\"flex-1 p-4 md:px-8 flex flex-col justify-end gap-3\">\n            <Link\n              href={`https://github.com/sponsors/juliencrn`}\n              className={cn(\n                buttonVariants({ variant: 'secondary' }),\n                'justify-start',\n              )}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n            >\n              <Gift className=\"h-6 w-6 mr-2\" />\n              Become a sponsor\n            </Link>\n          </div>\n        </div>\n      </section>\n\n      <section id=\"get-started\" className=\"container py-16 lg:py-32\">\n        <div className=\"mx-auto flex max-w-[58rem] flex-col items-center justify-center gap-4 text-center\">\n          <h2 className=\"font-heading text-3xl leading-[1.1] sm:text-3xl md:text-6xl\">\n            Ready to get started?\n          </h2>\n          <div className=\"my-4\">\n            <Link\n              href=\"/introduction\"\n              className={cn(buttonVariants({ size: 'lg' }))}\n            >\n              Explore the docs{` `}\n              <ChevronRight className=\"ml-3 h-5 w-5\" />\n            </Link>\n          </div>\n        </div>\n      </section>\n\n      <section id=\"open-source\" className=\"container py-16 lg:py-32\">\n        <div className=\"mx-auto flex max-w-[58rem] flex-col items-center justify-center gap-4 text-center\">\n          <h2 className=\"font-heading text-3xl leading-[1.1] sm:text-3xl md:text-6xl\">\n            Proudly Open Source\n          </h2>\n          <p className=\"max-w-[85%] leading-normal text-muted-foreground sm:text-lg sm:leading-7\">\n            usehooks-ts is open source and powered by open source software.{' '}\n            <br /> The code is available on{' '}\n            <Link\n              href={siteConfig.links.github}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n              className=\"underline underline-offset-4\"\n            >\n              GitHub\n            </Link>\n            .{' '}\n          </p>\n          {stars && (\n            <Link\n              href={siteConfig.links.github}\n              target=\"_blank\"\n              rel=\"noreferrer\"\n              className=\"flex\"\n            >\n              <div className=\"flex h-10 w-10 items-center justify-center space-x-2 rounded-md border border-muted bg-muted\">\n                <GitHub className=\"h-6 w-6\" />\n              </div>\n              <div className=\"flex items-center\">\n                <div className=\"h-4 w-4 border-y-8 border-l-0 border-r-8 border-solid border-muted border-y-transparent\"></div>\n                <div className=\"flex h-10 items-center rounded-md border border-muted bg-muted px-4 font-medium\">\n                  {stars} stars on GitHub\n                </div>\n              </div>\n            </Link>\n          )}\n        </div>\n      </section>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/globals.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n@import './prism.css';\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 222.2 47.4% 11.2%;\n\n    --muted: 210 40% 96.1%;\n    --muted-foreground: 215.4 16.3% 46.9%;\n\n    --popover: 0 0% 100%;\n    --popover-foreground: 222.2 47.4% 11.2%;\n\n    --card: 0 0% 100%;\n    --card-foreground: 222.2 47.4% 11.2%;\n\n    --border: 214.3 31.8% 91.4%;\n    --input: 214.3 31.8% 91.4%;\n\n    --primary: 222.2 47.4% 11.2%;\n    --primary-foreground: 210 40% 98%;\n\n    --secondary: 210 40% 96.1%;\n    --secondary-foreground: 222.2 47.4% 11.2%;\n\n    --accent: 210 40% 96.1%;\n    --accent-foreground: 222.2 47.4% 11.2%;\n\n    --destructive: 0 100% 50%;\n    --destructive-foreground: 210 40% 98%;\n\n    --ring: 215 20.2% 65.1%;\n\n    --radius: 0.5rem;\n  }\n\n  @media (prefers-color-scheme: dark) {\n    :root {\n      --background: 224 71% 4%;\n      --foreground: 213 31% 91%;\n\n      --muted: 223 47% 11%;\n      --muted-foreground: 215.4 16.3% 56.9%;\n\n      --popover: 224 71% 4%;\n      --popover-foreground: 215 20.2% 65.1%;\n\n      --card: 224 71% 4%;\n      --card-foreground: 213 31% 91%;\n\n      --border: 216 34% 17%;\n      --input: 216 34% 17%;\n\n      --primary: 210 40% 98%;\n      --primary-foreground: 222.2 47.4% 1.2%;\n\n      --secondary: 222.2 47.4% 11.2%;\n      --secondary-foreground: 210 40% 98%;\n\n      --accent: 216 34% 17%;\n      --accent-foreground: 210 40% 98%;\n\n      --destructive: 0 63% 31%;\n      --destructive-foreground: 210 40% 98%;\n\n      --ring: 216 34% 17%;\n\n      --radius: 0.5rem;\n    }\n  }\n}\n\n@layer base {\n  * {\n    @apply border-border;\n  }\n  html {\n    scroll-behavior: smooth;\n\n    color-scheme: light;\n\n    @media (prefers-color-scheme: dark) {\n      color-scheme: dark;\n    }\n  }\n  body {\n    @apply bg-background text-foreground;\n    font-feature-settings:\n      'rlig' 1,\n      'calt' 1;\n  }\n\n  /* Override the default styles for the Carbon Ads block */\n  .carbon-wrap * {\n    --carbon-bg-primary: hsl(var(--background));\n    --carbon-bg-secondary: hsl(var(--border));\n    --carbon-text-color: hsl(var(--foreground));\n  }\n\n  .carbon-wrap .carbon-responsive-wrap {\n    @apply !rounded-md;\n  }\n\n  .carbon-wrap .carbon-poweredby {\n    @apply !opacity-100 !text-muted-foreground;\n  }\n}\n"
  },
  {
    "path": "apps/www/src/app/layout.tsx",
    "content": "import { GoogleAnalytics } from '@next/third-parties/google'\nimport type { Metadata, Viewport } from 'next'\nimport { Inter as FontSans } from 'next/font/google'\nimport localFont from 'next/font/local'\nimport Script from 'next/script'\n\nimport './globals.css'\nimport { BuyMeACoffee } from '@/components/buy-me-a-coffee'\nimport { siteConfig } from '@/config/site'\nimport { cn } from '@/lib/utils'\n\nconst fontSans = FontSans({\n  subsets: ['latin'],\n  variable: '--font-sans',\n})\n\nconst fontHeading = localFont({\n  src: '../assets/fonts/CalSans-SemiBold.woff2',\n  variable: '--font-heading',\n})\n\ntype RootLayoutProps = {\n  children: React.ReactNode\n}\n\nexport const viewport: Viewport = {\n  themeColor: [\n    { media: '(prefers-color-scheme: light)', color: 'white' },\n    { media: '(prefers-color-scheme: dark)', color: 'black' },\n  ],\n}\n\nexport const metadata: Metadata = {\n  metadataBase: new URL(siteConfig.url),\n  alternates: {\n    canonical: '/',\n  },\n  title: {\n    default: siteConfig.name,\n    template: `%s | ${siteConfig.name}`,\n  },\n  description: siteConfig.description,\n  keywords: ['react', 'hooks', 'react-hooks', 'usehooks', 'typescript'],\n  authors: [\n    {\n      name: 'juliencrn',\n      url: 'https://github.com/juliencrn',\n    },\n  ],\n  creator: 'juliencrn',\n\n  openGraph: {\n    type: 'website',\n    locale: 'en_US',\n    url: siteConfig.url,\n    title: siteConfig.name,\n    description: siteConfig.description,\n    siteName: siteConfig.name,\n    images: [siteConfig.ogImage],\n  },\n  twitter: {\n    card: 'summary_large_image',\n    title: siteConfig.name,\n    description: siteConfig.description,\n    images: [siteConfig.ogImage],\n  },\n  icons: {\n    icon: '/favicon.ico',\n    shortcut: '/favicon-16x16.png',\n    apple: '/apple-touch-icon.png',\n  },\n  manifest: '/site.webmanifest',\n}\n\nexport default function RootLayout({ children }: RootLayoutProps) {\n  return (\n    <html lang=\"en\" suppressHydrationWarning>\n      <body\n        suppressHydrationWarning\n        className={cn(\n          'min-h-screen bg-background font-sans antialiased flex flex-col relative',\n          fontSans.variable,\n          fontHeading.variable,\n        )}\n      >\n        {children}\n\n        <BuyMeACoffee />\n      </body>\n\n      {process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID && (\n        <GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID} />\n      )}\n\n      {process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID && (\n        <Script\n          src=\"https://analytics.eu.umami.is/script.js\"\n          data-website-id={process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID}\n          strategy=\"lazyOnload\"\n        />\n      )}\n    </html>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/app/prism.css",
    "content": "@tailwind base;\n\n@layer base {\n  :root {\n    --github-background: #ffffff;\n    --github-color: #24292e;\n    --github-comment: #6a737d;\n    --github-tag: #22863a;\n    --github-boolean: #005cc5;\n    --github-string: #032f62;\n    --github-function: #6f42c1;\n    --github-keyword: #d73a49;\n    --github-regex: #e36209;\n    --github-highlight-background: hsl(var(--muted));\n    --github-highlight-border: #fbbf24;\n  }\n\n  @media (prefers-color-scheme: dark) {\n    :root {\n      --github-background: #0d1117;\n      --github-color: #c9d1d9;\n      --github-comment: #8b949e;\n      --github-tag: #7ee787;\n      --github-boolean: #79c0ff;\n      --github-string: #a5d6ff;\n      --github-function: #d2a8ff;\n      --github-keyword: #ff7b72;\n      --github-regex: #ffa657;\n      --github-highlight-background: #27272a;\n      --github-highlight-border: #fbbf24;\n    }\n  }\n}\n\npre[class*='language-'] {\n  background: var(--github-background);\n  color: var(--github-color);\n  border: 1px solid hsl(var(--border));\n  border-radius: var(--radius);\n  padding: 8px 0px;\n}\n\npre[class*='language-'] > code[class*='language-'] {\n  border: none;\n  padding: 0;\n  margin-left: 2.8rem;\n  min-width: calc(100% - 2.8rem);\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata {\n  color: var(--github-comment);\n}\n\n.token.punctuation {\n  color: var(--github-color);\n}\n\n.token.namespace {\n  opacity: 0.7;\n}\n\n.token.property,\n.token.tag,\n.token.constant,\n.token.symbol,\n.token.deleted {\n  color: var(--github-tag);\n}\n\n.token.boolean,\n.token.number {\n  color: var(--github-boolean);\n}\n\n.token.selector,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n  color: var(--github-string);\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string,\n.token.variable {\n  color: var(--github-color);\n}\n\n.token.atrule,\n.token.attr-value,\n.token.function,\n.token.class-name {\n  color: var(--github-function);\n}\n\n.token.keyword {\n  color: var(--github-keyword);\n}\n\n.token.regex,\n.token.important {\n  color: var(--github-regex);\n}\n\n.token.important,\n.token.bold {\n  font-weight: bold;\n}\n.token.italic {\n  font-style: italic;\n}\n\n.token.entity {\n  cursor: help;\n}\n\n.code-highlight {\n  float: left;\n  min-width: 100%;\n}\n\n.code-line {\n  display: block;\n  border-left: 4px solid transparent;\n}\n\n.highlight-line {\n  background-color: var(--github-highlight-background);\n  border-left: 4px solid var(--github-highlight-border);\n  margin-left: -2.8rem;\n  padding-left: 2.8rem;\n}\n\n.line-number::before {\n  display: inline-block;\n  width: 2rem;\n  text-align: right;\n  color: var(--github-comment);\n  opacity: 0.25;\n  content: attr(line);\n  position: absolute;\n  left: -3rem;\n}\n"
  },
  {
    "path": "apps/www/src/components/buy-me-a-coffee.tsx",
    "content": "import type { CSSProperties } from 'react'\n\nexport function BuyMeACoffee() {\n  return (\n    <a\n      href=\"https://www.buymeacoffee.com/juliencrn\"\n      target=\"_blank\"\n      className=\"flex items-center justify-center size-16 bg-[#FFDD00] rounded-full fixed right-5 bottom-5 shadow-sm z-50 cursor-pointer font-semibold\"\n      rel=\"noreferrer\"\n      title=\"Buy Me A Coffee\"\n    >\n      <BuyMeACoffeeLogo />\n    </a>\n  )\n}\n\nfunction BuyMeACoffeeLogo({\n  fill = '#FFFFFF',\n  stroke = '#0D0C22',\n  size = 32,\n}: {\n  fill?: CSSProperties['color']\n  stroke?: CSSProperties['color']\n  size?: number\n}) {\n  return (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      width={size}\n      height={size}\n      viewBox=\"0 0 35 50\"\n      fill=\"none\"\n    >\n      <path\n        d=\"M30.7512 11.6307L30.7171 11.6106L30.6382 11.5865C30.6699 11.6134 30.7097 11.6289 30.7512 11.6307Z\"\n        fill={stroke}\n      />\n      <path d=\"M31.2481 15.2031L31.21 15.2138L31.2481 15.2031Z\" fill={stroke} />\n      <path\n        d=\"M30.7659 11.6253C30.761 11.6247 30.7563 11.6236 30.7517 11.6219C30.7514 11.6251 30.7514 11.6283 30.7517 11.6314C30.7569 11.6307 30.7618 11.6286 30.7659 11.6253Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M30.7515 11.6314H30.7572V11.6278L30.7515 11.6314Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M31.2178 15.1962L31.2753 15.1634L31.2967 15.1514L31.3161 15.1307C31.2796 15.1464 31.2463 15.1686 31.2178 15.1962Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M30.8507 11.7088L30.7945 11.6553L30.7563 11.6345C30.7768 11.6707 30.8107 11.6973 30.8507 11.7088Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M16.715 46.3714C16.6701 46.3908 16.6307 46.4212 16.6006 46.4597L16.636 46.4369C16.6601 46.4149 16.6942 46.3888 16.715 46.3714Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M24.9235 44.7473C24.9235 44.6965 24.8987 44.7059 24.9048 44.8864C24.9048 44.8717 24.9108 44.857 24.9134 44.843C24.9168 44.8109 24.9195 44.7794 24.9235 44.7473Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M24.0719 46.3714C24.027 46.3908 23.9877 46.4212 23.9575 46.4597L23.993 46.4369C24.017 46.4149 24.0512 46.3888 24.0719 46.3714Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M10.9344 46.7574C10.9003 46.7277 10.8586 46.7082 10.814 46.7012C10.8501 46.7186 10.8862 46.736 10.9103 46.7493L10.9344 46.7574Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M9.63391 45.5042C9.62859 45.4515 9.61242 45.4005 9.58643 45.3544C9.60484 45.4024 9.62025 45.4516 9.63258 45.5015L9.63391 45.5042Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M18.3715 23.0976C16.5857 23.8665 14.5591 24.7382 11.9326 24.7382C10.8339 24.736 9.74049 24.5844 8.68213 24.2875L10.4987 43.0444C10.563 43.8284 10.9181 44.5594 11.4935 45.0923C12.0689 45.6251 12.8225 45.9208 13.6047 45.9207C13.6047 45.9207 16.1804 46.0552 17.0398 46.0552C17.9648 46.0552 20.7385 45.9207 20.7385 45.9207C21.5205 45.9207 22.274 45.6249 22.8493 45.092C23.4245 44.5592 23.7795 43.8283 23.8438 43.0444L25.7895 22.3173C24.92 22.0187 24.0425 21.8203 23.0533 21.8203C21.3424 21.8196 19.964 22.4122 18.3715 23.0976Z\"\n        fill={fill}\n      />\n      <path\n        d=\"M3.05859 15.095L3.08936 15.1238L3.10943 15.1358C3.09397 15.1205 3.07693 15.1068 3.05859 15.095Z\"\n        fill={stroke}\n      />\n      <path\n        d=\"M34.1896 13.3639L33.916 11.9762C33.6706 10.7312 33.1134 9.55468 31.8426 9.10468C31.4353 8.96073 30.9732 8.89885 30.6608 8.60086C30.3485 8.30288 30.2562 7.84009 30.1839 7.41094C30.0502 6.62326 29.9244 5.83492 29.7873 5.04859C29.6689 4.37257 29.5753 3.61315 29.267 2.99296C28.8657 2.16022 28.033 1.67322 27.205 1.35102C26.7807 1.19173 26.3477 1.05698 25.9081 0.947426C23.8394 0.398542 21.6644 0.196746 19.5362 0.0817228C16.9817 -0.0600379 14.4204 -0.0173274 11.872 0.209526C9.97525 0.383071 7.97745 0.592939 6.17495 1.25281C5.51616 1.49429 4.8373 1.7842 4.33634 2.29609C3.72169 2.92502 3.52104 3.89768 3.96982 4.68199C4.28886 5.23895 4.82927 5.63245 5.40246 5.89276C6.14906 6.22818 6.92877 6.48341 7.72865 6.65421C9.95585 7.14928 12.2626 7.34368 14.538 7.42641C17.0599 7.52878 19.5859 7.44582 22.0958 7.1782C22.7165 7.10959 23.336 7.0273 23.9545 6.93134C24.6828 6.81901 25.1503 5.86115 24.9356 5.19388C24.6788 4.39611 23.9886 4.08669 23.208 4.2071C23.093 4.22526 22.9786 4.24208 22.8636 4.25889L22.7807 4.271C22.5163 4.30463 22.2518 4.33602 21.9874 4.36517C21.4412 4.42437 20.8937 4.4728 20.3448 4.51046C19.1155 4.59656 17.8828 4.63625 16.6508 4.63827C15.4403 4.63827 14.229 4.60396 13.0211 4.52392C12.47 4.48759 11.9202 4.4414 11.3718 4.38535C11.1223 4.35912 10.8735 4.33154 10.6247 4.3006L10.3879 4.27033L10.3364 4.26293L10.091 4.22728C9.58933 4.15127 9.08771 4.06382 8.59144 3.95822C8.54136 3.94704 8.49657 3.91902 8.46446 3.87879C8.43236 3.83855 8.41486 3.7885 8.41486 3.73691C8.41486 3.68533 8.43236 3.63528 8.46446 3.59504C8.49657 3.55481 8.54136 3.52679 8.59144 3.51561H8.6008C9.03086 3.42346 9.46426 3.34476 9.899 3.27615C10.0439 3.25328 10.1893 3.23086 10.3351 3.20888H10.3391C10.6113 3.19072 10.8849 3.14162 11.1557 3.10933C13.5125 2.86279 15.8832 2.77874 18.2513 2.85776C19.4011 2.89139 20.5501 2.95933 21.6945 3.07637C21.9406 3.10193 22.1854 3.12884 22.4302 3.15911C22.5238 3.17054 22.6181 3.18399 22.7124 3.19543L22.9024 3.22301C23.4562 3.30597 24.0071 3.40664 24.5551 3.52503C25.367 3.70261 26.4097 3.76046 26.7709 4.65508C26.8859 4.93894 26.9381 5.25442 27.0016 5.5524L27.0826 5.93245C27.0847 5.93927 27.0863 5.94624 27.0873 5.9533C27.2785 6.85017 27.4701 7.74704 27.6618 8.64391C27.6758 8.71017 27.6762 8.77862 27.6628 8.84501C27.6493 8.9114 27.6225 8.97429 27.5838 9.02977C27.5451 9.08525 27.4955 9.13212 27.4381 9.16746C27.3806 9.2028 27.3165 9.22585 27.2498 9.23517H27.2444L27.1274 9.25132L27.0117 9.26679C26.6452 9.31477 26.2782 9.35961 25.9108 9.40132C25.1871 9.48428 24.4623 9.55603 23.7364 9.61657C22.294 9.7372 20.8486 9.81635 19.4004 9.85401C18.6625 9.87374 17.9247 9.88294 17.1872 9.88159C14.2517 9.87926 11.3188 9.70768 8.40283 9.36769C8.08714 9.33002 7.77145 9.28966 7.45577 9.24863C7.70056 9.28024 7.27786 9.22441 7.19225 9.2123C6.9916 9.18405 6.79095 9.15468 6.5903 9.12419C5.91679 9.02262 5.24729 8.8975 4.57511 8.78786C3.76249 8.65333 2.98531 8.72059 2.25026 9.12419C1.6469 9.45624 1.15857 9.96544 0.850401 10.5838C0.533376 11.243 0.439071 11.9608 0.297279 12.6691C0.155487 13.3774 -0.0652275 14.1395 0.0183763 14.8666C0.198292 16.4359 1.28915 17.7113 2.85823 17.9965C4.33434 18.2655 5.81847 18.4835 7.30662 18.6691C13.1524 19.3892 19.0582 19.4753 24.9223 18.9261C25.3998 18.8812 25.8767 18.8324 26.3529 18.7794C26.5016 18.763 26.6521 18.7802 26.7934 18.8299C26.9347 18.8795 27.0631 18.9603 27.1693 19.0663C27.2755 19.1724 27.3567 19.3009 27.4071 19.4426C27.4575 19.5843 27.4757 19.7356 27.4605 19.8853L27.312 21.3369C27.0128 24.2701 26.7136 27.2031 26.4144 30.1358C26.1023 33.2157 25.7882 36.2953 25.472 39.3747C25.3829 40.242 25.2937 41.109 25.2045 41.9758C25.1189 42.8294 25.1069 43.7099 24.9457 44.5534C24.6915 45.8799 23.7986 46.6945 22.4957 46.9925C21.3021 47.2657 20.0827 47.4091 18.8586 47.4203C17.5016 47.4277 16.1452 47.3672 14.7881 47.3746C13.3395 47.3826 11.5651 47.2481 10.4468 46.1638C9.46426 45.2113 9.32849 43.72 9.19472 42.4306C9.01637 40.7234 8.83957 39.0164 8.66434 37.3097L7.68116 27.8192L7.0451 21.6786C7.0344 21.577 7.0237 21.4768 7.01367 21.3745C6.93742 20.642 6.42176 19.925 5.60913 19.962C4.91354 19.9929 4.12299 20.5875 4.20458 21.3745L4.67611 25.927L5.65126 35.3442C5.92905 38.0191 6.20617 40.6944 6.48262 43.3703C6.53613 43.8828 6.58628 44.3967 6.64247 44.9093C6.94812 47.7102 9.075 49.2196 11.7089 49.6448C13.2472 49.8936 14.8229 49.9448 16.384 49.9703C18.3851 50.0026 20.4063 50.08 22.3747 49.7154C25.2915 49.1773 27.4799 47.2185 27.7922 44.1801C27.8814 43.303 27.9706 42.4256 28.0597 41.548C28.3563 38.6458 28.6523 35.7433 28.9479 32.8406L29.9151 23.3562L30.3585 19.0095C30.3806 18.794 30.4711 18.5913 30.6166 18.4315C30.7621 18.2717 30.9549 18.1633 31.1665 18.1223C32.0005 17.9588 32.7977 17.6796 33.391 17.0413C34.3354 16.0249 34.5233 14.6998 34.1896 13.3639ZM2.81542 14.3016C2.82813 14.2955 2.80472 14.4052 2.79469 14.4563C2.79268 14.3789 2.7967 14.3103 2.81542 14.3016ZM2.89635 14.9312C2.90304 14.9265 2.9231 14.9534 2.94384 14.9857C2.9124 14.9561 2.89234 14.9339 2.89568 14.9312H2.89635ZM2.97594 15.0368C3.0047 15.0859 3.02009 15.1168 2.97594 15.0368V15.0368ZM3.13579 15.1673H3.1398C3.1398 15.172 3.14716 15.1767 3.14984 15.1814C3.1454 15.1762 3.14048 15.1715 3.13513 15.1673H3.13579ZM31.1277 14.9722C30.828 15.2588 30.3766 15.392 29.9305 15.4586C24.9276 16.2052 19.8519 16.5832 14.7942 16.4164C11.1745 16.292 7.59287 15.8877 4.00928 15.3785C3.65815 15.3287 3.27758 15.2642 3.03614 15.0038C2.58133 14.5128 2.80472 13.524 2.9231 12.9307C3.03145 12.3872 3.23879 11.6628 3.88154 11.5854C4.88478 11.467 6.04989 11.8928 7.04243 12.0442C8.2374 12.2276 9.43684 12.3744 10.6407 12.4848C15.7787 12.9556 21.0029 12.8823 26.1181 12.1935C27.0505 12.0675 27.9795 11.9211 28.9051 11.7543C29.7298 11.6056 30.6441 11.3264 31.1424 12.1854C31.4841 12.7706 31.5296 13.5536 31.4768 14.2148C31.4605 14.5029 31.3354 14.7739 31.127 14.9722H31.1277Z\"\n        fill={stroke}\n      />\n    </svg>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/carbon-ads/ads.tsx",
    "content": "import type { ComponentPropsWithoutRef } from 'react'\n\nimport { useScript } from './use-script'\nimport { cn } from '@/lib/utils'\n\nconst adIds = {\n  home: 'CWYIE23E',\n  docs: 'CWYIEKJU',\n} as const\n\ntype CarbonAdsProps = {\n  variant: keyof typeof adIds\n  /** @default cover */\n  format?: 'responsive' | 'cover'\n} & ComponentPropsWithoutRef<'div'>\n\nexport function CarbonAds({\n  variant,\n  format = 'cover',\n  className,\n  ...props\n}: CarbonAdsProps) {\n  const ref = useScript(\n    `//cdn.carbonads.com/carbon.js?serve=${adIds[variant]}&placement=usehooks-tscom&format=${format}`,\n    '_carbonads_js',\n  )\n\n  return <div {...props} className={cn('carbon-wrap', className)} ref={ref} />\n}\n"
  },
  {
    "path": "apps/www/src/components/carbon-ads/index.ts",
    "content": "'use client'\n\nexport * from './ads'\n"
  },
  {
    "path": "apps/www/src/components/carbon-ads/use-script.ts",
    "content": "import { useEffect, useRef } from 'react'\n\n// TODO: We can't use usehooks-ts's useScript because it mounts the script in the document.body, maybe provide a way to specify the mount point\nexport const useScript = (scriptUrl: string, scriptId: string) => {\n  const ref = useRef<HTMLDivElement>(null)\n\n  useEffect(() => {\n    const existingScript = document.getElementById(scriptId)\n\n    if (!existingScript) {\n      const script = document.createElement('script')\n\n      script.setAttribute('async', '')\n      script.setAttribute('type', 'text/javascript')\n      script.setAttribute('src', scriptUrl)\n      script.setAttribute('id', scriptId)\n\n      ref.current?.appendChild(script)\n    }\n\n    return () => {\n      if (existingScript) {\n        existingScript.remove()\n      }\n    }\n  }, [scriptUrl, scriptId])\n\n  return ref\n}\n"
  },
  {
    "path": "apps/www/src/components/command-copy.tsx",
    "content": "'use client'\n\nimport { useState } from 'react'\n\nimport { Check, Copy } from 'lucide-react'\nimport type { ComponentProps } from 'react'\nimport { useCopyToClipboard } from 'usehooks-ts'\n\nimport { Button } from './ui/button'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from './ui/dropdown-menu'\nimport { cn } from '@/lib/utils'\n\ntype CommandCopyProps = {\n  command: Record<string, string> | string\n  defaultCommand?: string\n} & ComponentProps<'code'>\n\nexport function CommandCopy({\n  className,\n  command,\n  defaultCommand,\n  ...props\n}: CommandCopyProps) {\n  const [copiedStatus, setCopiedStatus] = useState(false)\n  const [, copy] = useCopyToClipboard()\n\n  const handleCopy = (text: string) => {\n    setCopiedStatus(true)\n    void copy(text)\n    setTimeout(() => {\n      setCopiedStatus(false)\n    }, 2000)\n  }\n  const renderedCommand =\n    typeof command === 'string'\n      ? command\n      : command[defaultCommand ?? Object.keys(command)[0]]\n\n  return (\n    <code\n      className={cn(\n        'rounded border p-2 gap-2 font-mono text-sm flex dark:bg-[#0d1117] bg-white items-center justify-between',\n        className,\n      )}\n      {...props}\n    >\n      <div className=\"px-2\">\n        {renderedCommand.split(' ').map((arg, i) => (\n          <span\n            key={arg}\n            className={cn(i === 0 ? 'font-bold' : 'text-muted-foreground')}\n          >\n            {arg}{' '}\n          </span>\n        ))}\n      </div>\n      <DropdownMenu open={typeof command === 'string' ? false : undefined}>\n        <DropdownMenuTrigger asChild>\n          <Button\n            variant=\"ghost\"\n            size=\"icon\"\n            onClick={() => {\n              if (typeof command === 'string') {\n                handleCopy(renderedCommand)\n              }\n            }}\n          >\n            {copiedStatus ? (\n              <Check size={16} className=\"text-muted-foreground\" />\n            ) : (\n              <Copy size={16} className=\"text-muted-foreground\" />\n            )}\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent>\n          {command &&\n            Object.entries(command).map(([key, value]) => (\n              <DropdownMenuItem\n                key={key}\n                onClick={() => {\n                  handleCopy(value)\n                }}\n              >\n                {key}\n              </DropdownMenuItem>\n            ))}\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </code>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/command-menu.tsx",
    "content": "import { Index } from 'react-instantsearch'\n\nimport { Footer } from './footer'\nimport { RenderHits } from './hits'\nimport { SearchInput } from './input'\nimport { useCommandMenuContext } from './modal.context'\nimport {\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandList,\n} from '@/components/ui/command'\n\nexport function CommandMenu() {\n  const { open, setOpen } = useCommandMenuContext()\n\n  return (\n    <CommandDialog open={open} onOpenChange={setOpen}>\n      <SearchInput />\n      <CommandList>\n        <Index indexName=\"hooks\">\n          <CommandGroup heading=\"Hooks\">\n            <RenderHits />\n          </CommandGroup>\n        </Index>\n        <Index indexName=\"removed-hooks\">\n          <CommandGroup heading=\"Removed hooks\">\n            <RenderHits />\n          </CommandGroup>\n        </Index>\n        <CommandEmpty>No results found.</CommandEmpty>\n      </CommandList>\n      <Footer />\n    </CommandDialog>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/doc-search.tsx",
    "content": "'use client'\n\nimport algoliasearch from 'algoliasearch/lite'\nimport { InstantSearch } from 'react-instantsearch'\n\nimport { CommandMenu } from './command-menu'\nimport { CommandMenuProvider } from './modal.context'\nimport { OpenButton } from './open-button'\n\nconst searchClient = algoliasearch(\n  process.env.NEXT_PUBLIC_ALGOLIA_APP_ID ?? '',\n  process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_KEY ?? '',\n)\n\nexport const DocSearch = () => {\n  return (\n    <CommandMenuProvider>\n      <OpenButton />\n      <InstantSearch\n        searchClient={searchClient}\n        indexName=\"hooks\"\n        future={{ preserveSharedStateOnUnmount: true }}\n      >\n        <CommandMenu />\n      </InstantSearch>\n    </CommandMenuProvider>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/footer.tsx",
    "content": "export function Footer() {\n  return (\n    <footer className=\"flex flex-row-reverse items-center justify-between relative px-4 py-2.5 select-none w-full text-xs border-t text-muted-foreground\">\n      <div>\n        <a\n          href=\"https://www.algolia.com/?utm_medium=AOS-referral\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n          className=\"flex items-center gap-1\"\n        >\n          <span>Search by</span>\n          <AlgoliaLogo />\n        </a>\n      </div>\n      <ul className=\"flex gap-3\">\n        <li className=\"flex items-center gap-1\">\n          <Kbd>\n            <EnterKey />\n          </Kbd>\n          <span>to select</span>\n        </li>\n        <li className=\"flex items-center gap-1\">\n          <Kbd>\n            <ArrowDownKey />\n          </Kbd>\n          <Kbd>\n            <ArrowUpKey />\n          </Kbd>\n          <span>to navigate</span>\n        </li>\n        <li className=\"flex items-center gap-1\">\n          <Kbd>\n            <EscapeKey />\n          </Kbd>\n          <span>to close</span>\n        </li>\n      </ul>\n    </footer>\n  )\n}\n\nfunction EscapeKey() {\n  return (\n    <svg width=\"15\" height=\"15\" aria-label=\"Escape key\" role=\"img\">\n      <g\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.2\"\n      >\n        <path d=\"M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956\"></path>\n      </g>\n    </svg>\n  )\n}\n\nfunction ArrowDownKey() {\n  return (\n    <svg width=\"15\" height=\"15\" aria-label=\"Arrow down\" role=\"img\">\n      <g\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.2\"\n      >\n        <path d=\"M7.5 3.5v8M10.5 8.5l-3 3-3-3\"></path>\n      </g>\n    </svg>\n  )\n}\nfunction ArrowUpKey() {\n  return (\n    <svg width=\"15\" height=\"15\" aria-label=\"Arrow up\" role=\"img\">\n      <g\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.2\"\n      >\n        <path d=\"M7.5 11.5v-8M10.5 6.5l-3-3-3 3\"></path>\n      </g>\n    </svg>\n  )\n}\n\nfunction EnterKey() {\n  return (\n    <svg width=\"15\" height=\"15\" aria-label=\"Enter key\" role=\"img\">\n      <g\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.2\"\n      >\n        <path d=\"M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3\"></path>\n      </g>\n    </svg>\n  )\n}\n\nfunction Kbd({ children }: { children: React.ReactNode }) {\n  return (\n    <kbd className=\"flex items-center border-none rounded-sm bg-zinc-200 text-zinc-500 p-[2px] h-5 w-5\">\n      {children}\n    </kbd>\n  )\n}\n\nfunction AlgoliaLogo() {\n  return (\n    <svg\n      width=\"77\"\n      height=\"19\"\n      aria-label=\"Algolia\"\n      role=\"img\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      viewBox=\"0 0 2196.2 500\"\n    >\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z\"\n      ></path>\n      <rect\n        style={{ fill: '#003dff' }}\n        x=\"1845.88\"\n        y=\"104.73\"\n        width=\"62.58\"\n        height=\"277.9\"\n        rx=\"5.9\"\n        ry=\"5.9\"\n      ></rect>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        className=\"cls-2\"\n        d=\"M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff', fillRule: 'evenodd' }}\n        d=\"M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z\"\n      ></path>\n      <path\n        style={{ fill: '#003dff' }}\n        d=\"M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z\"\n      ></path>\n    </svg>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/hits.tsx",
    "content": "import { useRouter } from 'next/navigation'\nimport { useHits } from 'react-instantsearch'\n\nimport { CommandItem } from '../ui/command'\nimport { useCommandMenuContext } from './modal.context'\nimport type { Hit } from './types'\n\nexport function RenderHits() {\n  const { hits, results } = useHits<Hit>()\n\n  if (!results?.index) {\n    return null\n  }\n\n  return (\n    <>\n      {hits.map(hit => (\n        <HitComponent\n          key={hit.objectID}\n          hit={hit}\n          makeUrl={slug =>\n            results.index === 'hooks'\n              ? `/react-hook/${slug}`\n              : `/migrate-to-v3#removed-hooks`\n          }\n        />\n      ))}\n    </>\n  )\n}\n\ntype HitProps = {\n  hit: Hit\n  makeUrl: (slug: string) => string\n}\n\nfunction HitComponent({ hit, makeUrl }: HitProps) {\n  const { handleClose } = useCommandMenuContext()\n  const router = useRouter()\n\n  return (\n    <CommandItem\n      className=\"flex flex-col [&_mark]:bg-accent [&_mark]:text-accent-foreground\"\n      onSelect={() => {\n        handleClose()\n\n        const url = makeUrl(hit.objectID)\n        router.push(url)\n      }}\n    >\n      <div\n        className=\"font-mono\"\n        dangerouslySetInnerHTML={{\n          __html: (hit._highlightResult.name?.value || hit.name) + '()',\n        }}\n      />\n      <div\n        className=\"text-sm text-muted-foreground\"\n        dangerouslySetInnerHTML={{\n          __html: (\n            hit._highlightResult.summary?.value ??\n            hit?.summary ??\n            ''\n          ).replace('Custom hook that ', ''),\n        }}\n      />\n    </CommandItem>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/index.ts",
    "content": "export * from './doc-search'\n"
  },
  {
    "path": "apps/www/src/components/doc-search/input.tsx",
    "content": "import { useRef, useState } from 'react'\n\nimport { useSearchBox } from 'react-instantsearch'\n\nimport { CommandInput } from '../ui/command'\n\nexport function SearchInput() {\n  const { query, refine } = useSearchBox()\n  const [inputValue, setInputValue] = useState(query)\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  function setQuery(newQuery: string) {\n    setInputValue(newQuery)\n    refine(newQuery)\n  }\n\n  return (\n    <form\n      action=\"\"\n      role=\"search\"\n      noValidate\n      onSubmit={event => {\n        event.preventDefault()\n        event.stopPropagation()\n\n        if (inputRef.current) {\n          inputRef.current.blur()\n        }\n      }}\n      onReset={event => {\n        event.preventDefault()\n        event.stopPropagation()\n\n        setQuery('')\n\n        if (inputRef.current) {\n          inputRef.current.focus()\n        }\n      }}\n    >\n      <CommandInput\n        ref={inputRef}\n        autoComplete=\"off\"\n        autoCorrect=\"off\"\n        autoCapitalize=\"off\"\n        placeholder=\"Search for hooks…\"\n        spellCheck={false}\n        maxLength={512}\n        value={inputValue}\n        onValueChange={setQuery}\n      />\n    </form>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/modal.context.tsx",
    "content": "import { createContext, useContext, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\nimport { useCmdK } from './use-cmd-k'\n\ntype CommandMenuContextType = {\n  open: boolean\n  setOpen: Dispatch<SetStateAction<boolean>>\n  handleOpen: () => void\n  handleClose: () => void\n}\n\nconst initialContext: CommandMenuContextType = {\n  open: false,\n  setOpen: () => undefined,\n  handleOpen: () => undefined,\n  handleClose: () => undefined,\n}\n\nconst CommandMenuContext = createContext<CommandMenuContextType>(initialContext)\n\nexport function CommandMenuProvider(props: { children: React.ReactNode }) {\n  const [open, setOpen] = useState(initialContext.open)\n\n  // Toggle the menu when ⌘K is pressed\n  useCmdK(() => {\n    setOpen(open => !open)\n  })\n\n  const handleOpen = () => {\n    setOpen(true)\n  }\n\n  const handleClose = () => {\n    setOpen(false)\n  }\n\n  return (\n    <CommandMenuContext.Provider\n      value={{ open, setOpen, handleOpen, handleClose }}\n    >\n      {props.children}\n    </CommandMenuContext.Provider>\n  )\n}\n\nexport function useCommandMenuContext() {\n  const context = useContext(CommandMenuContext)\n\n  if (!context) {\n    throw new Error(\n      '`useCommandMenuContext` must be used within a `CommandMenuProvider`',\n    )\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/open-button.tsx",
    "content": "import { forwardRef } from 'react'\n\nimport { Search } from 'lucide-react'\nimport type { ButtonHTMLAttributes } from 'react'\n\nimport { buttonVariants } from '../ui/button'\nimport { useCommandMenuContext } from './modal.context'\nimport { cn } from '@/lib/utils'\ntype ButtonProps = Omit<\n  ButtonHTMLAttributes<HTMLButtonElement>,\n  'children' | 'onClick' | 'ref'\n>\n\nexport const OpenButton = forwardRef<HTMLButtonElement, ButtonProps>(\n  function OpenButton(props, ref) {\n    const { handleOpen } = useCommandMenuContext()\n\n    return (\n      <button\n        ref={ref}\n        onClick={handleOpen}\n        {...props}\n        className={cn(\n          buttonVariants({ variant: 'secondary' }),\n          'hidden sm:flex items-center w-60 text-left space-x-2 text-muted-foreground',\n          props.className,\n        )}\n      >\n        <Search className=\"flex-none w-5 h-5\" />\n\n        <span className=\"flex-auto\">Quick search...</span>\n        <kbd className=\"font-sans\">\n          <abbr title=\"Command\" className=\"no-underline\">\n            ⌘\n          </abbr>{' '}\n          K\n        </kbd>\n      </button>\n    )\n  },\n)\n"
  },
  {
    "path": "apps/www/src/components/doc-search/types.ts",
    "content": "type Highlight = {\n  value: string\n  matchLevel: string\n  matchedWords: string[]\n}\n\ntype Fields<T> = {\n  objectID: T\n  name: T\n  summary?: T\n}\n\nexport type Hit = Fields<string> & {\n  __position: number\n  _highlightResult: Fields<Highlight>\n}\n"
  },
  {
    "path": "apps/www/src/components/doc-search/use-cmd-k.ts",
    "content": "import { useEventListener } from 'usehooks-ts'\n\nexport function useCmdK(callback: () => void) {\n  useEventListener('keydown', event => {\n    if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {\n      event.preventDefault()\n      callback()\n    }\n  })\n}\n"
  },
  {
    "path": "apps/www/src/components/docs/left-sidebar.tsx",
    "content": "'use client'\n\nimport Link from 'next/link'\nimport { usePathname } from 'next/navigation'\n\nimport { cn, mapHookToNavLink } from '@/lib/utils'\nimport type { BaseHook, SidebarNavItem } from '@/types'\n\ntype DocsSidebarNavProps = {\n  items: SidebarNavItem[]\n  hooks: BaseHook[]\n}\n\nexport function LeftSidebar(props: DocsSidebarNavProps) {\n  const pathname = usePathname()\n  const items = [\n    ...props.items,\n    { title: 'Hooks', items: props.hooks.map(mapHookToNavLink) },\n  ]\n\n  if (!items.length) {\n    return null\n  }\n\n  return (\n    <aside className=\"fixed top-16 z-30 hidden h-[calc(100vh-4rem-1px)] w-full shrink-0 overflow-y-auto border-r py-6 pr-2 md:sticky md:block lg:py-10\">\n      {items.map((item, index) => (\n        <div key={index} className={'pb-8'}>\n          <h4 className=\"mb-1 rounded-md px-2 py-1 text-sm font-medium\">\n            {item.title}\n          </h4>\n          {item.items ? (\n            <NavItems items={item.items} pathname={pathname} />\n          ) : null}\n        </div>\n      ))}\n    </aside>\n  )\n}\n\ntype NavItemsProps = {\n  items: SidebarNavItem[]\n  pathname: string | null\n}\n\nfunction NavItems({ items, pathname }: NavItemsProps) {\n  return items?.length ? (\n    <div className=\"grid grid-flow-row auto-rows-max text-sm\">\n      {items.map((item, index) =>\n        !item.disabled && item.href ? (\n          <Link\n            key={index}\n            href={item.href}\n            className={cn(\n              'flex w-full items-center rounded-md p-2 hover:underline',\n              {\n                'bg-muted': pathname === item.href,\n              },\n            )}\n            target={item.external ? '_blank' : ''}\n            rel={item.external ? 'noreferrer' : ''}\n          >\n            {item.title}\n          </Link>\n        ) : (\n          <span\n            key={index}\n            className=\"flex w-full cursor-not-allowed items-center rounded-md p-2 opacity-60\"\n          >\n            {item.title}\n          </span>\n        ),\n      )}\n    </div>\n  ) : null\n}\n"
  },
  {
    "path": "apps/www/src/components/docs/page-header.tsx",
    "content": "import { cn } from '@/lib/utils'\n\ntype DocsPageHeaderProps = {\n  heading: string\n  text?: string\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport function PageHeader({\n  heading,\n  text,\n  className,\n  ...props\n}: DocsPageHeaderProps) {\n  return (\n    <>\n      <div className={cn('space-y-4', className)} {...props}>\n        <h1 className=\"inline-block font-heading text-4xl lg:text-5xl\">\n          {heading}\n        </h1>\n        {text && <p className=\"text-xl text-muted-foreground\">{text}</p>}\n      </div>\n      <hr className=\"my-4\" />\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/docs/pager.tsx",
    "content": "import Link from 'next/link'\n\nimport { buttonVariants } from '@/components/ui/button'\nimport { ChevronLeft, ChevronRight } from '@/components/ui/icons'\nimport { cn, mapHookToNavLink } from '@/lib/utils'\nimport type { BaseHook } from '@/types'\n\ntype DocsPagerProps = {\n  slug: string\n  hooks: BaseHook[]\n}\n\nexport function Pager({ slug, hooks }: DocsPagerProps) {\n  const { prev, next } = getPaperElements({ slug, hooks })\n\n  if (!prev && !next) {\n    return null\n  }\n\n  return (\n    <div className=\"flex flex-row items-center justify-between\">\n      {prev && (\n        <Link\n          href={prev.href}\n          className={cn(buttonVariants({ variant: 'ghost' }))}\n        >\n          <ChevronLeft className=\"mr-2 h-4 w-4\" />\n          {prev.title}\n        </Link>\n      )}\n      {next && (\n        <Link\n          href={next.href}\n          className={cn(buttonVariants({ variant: 'ghost' }), 'ml-auto')}\n        >\n          {next.title}\n          <ChevronRight className=\"ml-2 h-4 w-4\" />\n        </Link>\n      )}\n    </div>\n  )\n}\n\nfunction getPaperElements({ slug, hooks }: DocsPagerProps) {\n  const activeIndex = hooks.findIndex(h => h.slug === slug)\n  const links = hooks.map(mapHookToNavLink)\n  const prev = activeIndex !== 0 ? links[activeIndex - 1] : null\n  const next = activeIndex !== hooks.length - 1 ? links[activeIndex + 1] : null\n\n  return { prev, next }\n}\n"
  },
  {
    "path": "apps/www/src/components/docs/right-sidebar.tsx",
    "content": "import { CarbonAds } from '../carbon-ads'\nimport type { TableOfContents } from './table-of-content'\nimport { TableOfContent } from './table-of-content'\n\ntype Props = {\n  toc: TableOfContents\n}\n\nexport function RightSidebar({ toc }: Props) {\n  return (\n    <aside className=\"hidden text-sm xl:block\">\n      <div className=\"sticky top-16 -mt-10 max-h-[calc(var(--vh)-4rem)] overflow-y-auto pt-10 flex flex-col gap-10\">\n        <TableOfContent toc={toc} />\n\n        <CarbonAds variant=\"docs\" />\n      </div>\n    </aside>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/docs/table-of-content.tsx",
    "content": "'use client'\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\ntype Item = {\n  title: string\n  url: string\n  items?: Item[]\n}\n\ntype Items = {\n  items?: Item[]\n}\n\nexport type TableOfContents = Items\nexport type TocItem = Item\n\ntype TocProps = {\n  toc: TableOfContents\n}\n\nexport function TableOfContent({ toc }: TocProps) {\n  const itemIds = React.useMemo(\n    () =>\n      toc.items\n        ? toc.items\n            .flatMap(item => [item.url, item?.items?.map(item => item.url)])\n            .flat()\n            .filter(Boolean)\n            .map(id => id?.split('#')[1])\n        : [],\n    [toc],\n  )\n  const activeHeading = useActiveItem(itemIds)\n\n  if (!toc?.items) {\n    return null\n  }\n\n  return (\n    <div className=\"space-y-2\">\n      <p className=\"font-medium\">On This Page</p>\n      <Tree tree={toc} activeItem={activeHeading} />\n    </div>\n  )\n}\n\n// TODO: use useIntersectionObserver from usehooks-ts\nfunction useActiveItem(itemIds: (string | undefined)[]) {\n  const [activeId, setActiveId] = React.useState<string>('')\n\n  React.useEffect(() => {\n    const observer = new IntersectionObserver(\n      entries => {\n        entries.forEach(entry => {\n          if (entry.isIntersecting) {\n            setActiveId(entry.target.id)\n          }\n        })\n      },\n      { rootMargin: `0% 0% -80% 0%` },\n    )\n\n    itemIds?.forEach(id => {\n      if (!id) {\n        return\n      }\n\n      const element = document.getElementById(id)\n      if (element) {\n        observer.observe(element)\n      }\n    })\n\n    return () => {\n      itemIds?.forEach(id => {\n        if (!id) {\n          return\n        }\n\n        const element = document.getElementById(id)\n        if (element) {\n          observer.unobserve(element)\n        }\n      })\n    }\n  }, [itemIds])\n\n  return activeId\n}\n\ntype TreeProps = {\n  tree: TableOfContents\n  level?: number\n  activeItem?: string | null\n}\n\nfunction Tree({ tree, level = 1, activeItem }: TreeProps) {\n  return tree?.items?.length && level < 3 ? (\n    <ul className={cn('m-0 list-none', { 'pl-4': level !== 1 })}>\n      {tree.items.map((item, index) => {\n        return (\n          <li key={index} className={cn('mt-0 pt-2')}>\n            <a\n              href={item.url}\n              className={cn(\n                'inline-block no-underline',\n                item.url === `#${activeItem}`\n                  ? 'font-medium text-primary'\n                  : 'text-sm text-muted-foreground',\n              )}\n            >\n              {item.title}\n            </a>\n            {item.items?.length ? (\n              <Tree tree={item} level={level + 1} activeItem={activeItem} />\n            ) : null}\n          </li>\n        )\n      })}\n    </ul>\n  ) : null\n}\n"
  },
  {
    "path": "apps/www/src/components/main-nav.tsx",
    "content": "'use client'\n\nimport * as React from 'react'\n\nimport Link from 'next/link'\nimport { useSelectedLayoutSegment } from 'next/navigation'\n\nimport { MobileNav } from '@/components/mobile-nav'\nimport { Close, Logo } from '@/components/ui/icons'\nimport { siteConfig } from '@/config/site'\nimport { cn } from '@/lib/utils'\nimport type { MainNavItem } from '@/types'\n\ntype MainNavProps = {\n  items?: MainNavItem[]\n  children?: React.ReactNode\n}\n\nexport function MainNav({ items, children }: MainNavProps) {\n  const segment = useSelectedLayoutSegment()\n  const [showMobileMenu, setShowMobileMenu] = React.useState<boolean>(false)\n\n  return (\n    <div className=\"flex gap-6 md:gap-10\">\n      <Link href=\"/\" className=\"hidden items-center space-x-2 md:flex\">\n        <Logo />\n        <span className=\"hidden font-bold sm:inline-block\">\n          {siteConfig.name}\n        </span>\n      </Link>\n      {items?.length ? (\n        <nav className=\"hidden gap-6 md:flex\">\n          {items?.map((item, index) => (\n            <Link\n              key={index}\n              href={item.disabled ? '#' : item.href}\n              className={cn(\n                'flex items-center text-lg font-medium transition-colors hover:text-foreground/80 sm:text-sm',\n                item.href.startsWith(`/${segment}`)\n                  ? 'text-foreground'\n                  : 'text-foreground/60',\n                item.disabled && 'cursor-not-allowed opacity-80',\n              )}\n            >\n              {item.title}\n            </Link>\n          ))}\n        </nav>\n      ) : null}\n      <button\n        className=\"flex items-center space-x-2 md:hidden\"\n        onClick={() => {\n          setShowMobileMenu(!showMobileMenu)\n        }}\n      >\n        {showMobileMenu ? <Close /> : <Logo />}\n        <span className=\"font-bold\">Menu</span>\n      </button>\n      {showMobileMenu && items && (\n        <MobileNav items={items}>{children}</MobileNav>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/mobile-nav.tsx",
    "content": "import * as React from 'react'\n\nimport Link from 'next/link'\nimport { useScrollLock } from 'usehooks-ts'\n\nimport { Logo } from '@/components/ui/icons'\nimport { siteConfig } from '@/config/site'\nimport { cn } from '@/lib/utils'\nimport type { MainNavItem } from '@/types'\n\ntype MobileNavProps = {\n  items: MainNavItem[]\n  children?: React.ReactNode\n}\n\nexport function MobileNav({ items, children }: MobileNavProps) {\n  useScrollLock()\n\n  return (\n    <div\n      className={cn(\n        'fixed inset-0 top-16 z-50 grid h-[calc(100vh-4rem)] grid-flow-row auto-rows-max overflow-auto p-6 pb-32 shadow-md animate-in slide-in-from-bottom-80 md:hidden',\n      )}\n    >\n      <div className=\"relative z-20 grid gap-6 rounded-md bg-popover p-4 text-popover-foreground shadow-md\">\n        <Link href=\"/\" className=\"flex items-center space-x-2\">\n          <Logo />\n          <span className=\"font-bold\">{siteConfig.name}</span>\n        </Link>\n        <nav className=\"grid grid-flow-row auto-rows-max text-sm\">\n          {items.map((item, index) => (\n            <Link\n              key={index}\n              href={item.disabled ? '#' : item.href}\n              className={cn(\n                'flex w-full items-center rounded-md p-2 text-sm font-medium hover:underline',\n                item.disabled && 'cursor-not-allowed opacity-60',\n              )}\n            >\n              {item.title}\n            </Link>\n          ))}\n        </nav>\n        {children}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/www/src/components/ui/button.tsx",
    "content": "import * as React from 'react'\n\nimport { Slot } from '@radix-ui/react-slot'\nimport type { VariantProps } from 'class-variance-authority'\nimport { cva } from 'class-variance-authority'\n\nimport { cn } from '@/lib/utils'\n\nconst buttonVariants = cva(\n  'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',\n  {\n    variants: {\n      variant: {\n        default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n        destructive:\n          'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n        outline:\n          'border border-input hover:bg-accent hover:text-accent-foreground',\n        secondary:\n          'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n        ghost: 'hover:bg-accent hover:text-accent-foreground',\n        link: 'underline-offset-4 hover:underline text-primary',\n      },\n      size: {\n        default: 'h-10 py-2 px-4',\n        sm: 'h-9 px-3 rounded-md',\n        lg: 'h-11 px-8 rounded-md',\n        icon: 'h-10 w-10',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  },\n)\n\nexport type ButtonProps = {\n  asChild?: boolean\n} & React.ButtonHTMLAttributes<HTMLButtonElement> &\n  VariantProps<typeof buttonVariants>\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n  ({ className, variant, size, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : 'button'\n    return (\n      <Comp\n        className={cn(buttonVariants({ variant, size, className }))}\n        ref={ref}\n        {...props}\n      />\n    )\n  },\n)\nButton.displayName = 'Button'\n\nexport { Button, buttonVariants }\n"
  },
  {
    "path": "apps/www/src/components/ui/command.tsx",
    "content": "'use client'\n\nimport * as React from 'react'\n\nimport type { DialogProps } from '@radix-ui/react-dialog'\nimport { Command as CommandPrimitive } from 'cmdk'\nimport { Loader, Search } from 'lucide-react'\n\nimport { Dialog, DialogContent } from '@/components/ui/dialog'\nimport { cn } from '@/lib/utils'\n\nconst Command = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive\n    ref={ref}\n    className={cn(\n      'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',\n      className,\n    )}\n    {...props}\n  />\n))\nCommand.displayName = CommandPrimitive.displayName\n\ntype CommandDialogProps = DialogProps\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n  return (\n    <Dialog {...props}>\n      <DialogContent className=\"overflow-hidden p-0 shadow-lg w-full max-w-[750px]\">\n        <Command className=\"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nconst CommandInput = React.forwardRef<\n  HTMLInputElement,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> & {\n    isLoading?: boolean\n  }\n>(({ isLoading, className, ...props }, ref) => (\n  <div className=\"flex items-center border-b px-3\">\n    {isLoading ? (\n      <Loader className=\"mr-2 h-4 w-4 shrink-0 animate-spin opacity-50\" />\n    ) : (\n      <Search className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n    )}\n    <CommandPrimitive.Input\n      ref={ref}\n      className={cn(\n        'flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',\n        className,\n      )}\n      {...props}\n    />\n  </div>\n))\n\nCommandInput.displayName = 'CommandInput'\n\nconst CommandList = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.List>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.List\n    ref={ref}\n    className={cn('max-h-[400px] overflow-y-auto overflow-x-hidden', className)}\n    {...props}\n  />\n))\n\nCommandList.displayName = CommandPrimitive.List.displayName\n\nconst CommandEmpty = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Empty>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n  <CommandPrimitive.Empty\n    ref={ref}\n    className=\"py-6 text-center text-sm\"\n    {...props}\n  />\n))\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName\n\nconst CommandGroup = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Group>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Group\n    ref={ref}\n    className={cn(\n      'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',\n      className,\n    )}\n    {...props}\n  />\n))\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName\n\nconst CommandSeparator = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Separator\n    ref={ref}\n    className={cn('-mx-1 h-px bg-border', className)}\n    {...props}\n  />\n))\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName\n\nconst CommandItem = React.forwardRef<\n  React.ElementRef<typeof CommandPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n  <CommandPrimitive.Item\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n      className,\n    )}\n    {...props}\n  />\n))\n\nCommandItem.displayName = CommandPrimitive.Item.displayName\n\nconst CommandShortcut = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n  return (\n    <span\n      className={cn(\n        'ml-auto text-xs tracking-widest text-muted-foreground',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\nCommandShortcut.displayName = 'CommandShortcut'\n\nexport {\n  Command,\n  CommandDialog,\n  type DialogProps as CommandDialogProps,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n}\n"
  },
  {
    "path": "apps/www/src/components/ui/components.tsx",
    "content": "/* eslint-disable jsx-a11y/heading-has-content */\n\nimport Link from 'next/link'\nimport type { ComponentProps, ReactNode } from 'react'\nimport voca from 'voca'\n\nimport { cn } from '@/lib/utils'\n\n// This file was created to be used in src/components/remote-mdx.tsx\n// TODO: It can be simplified, refactored, and/or removed.\n\nconst slugify = (children?: ReactNode, id?: string): string => {\n  return voca.slugify(children?.toString() ?? id)\n}\n\nexport const H1 = ({ id, className, ...props }: ComponentProps<'h1'>) => (\n  <h1\n    id={slugify(props.children, id)}\n    className={cn(\n      'mt-2 scroll-m-20 text-4xl font-bold tracking-tight',\n      className,\n    )}\n    {...props}\n  />\n)\n\nexport const H2 = ({ id, className, ...props }: ComponentProps<'h2'>) => (\n  <h2\n    id={slugify(props.children, id)}\n    className={cn(\n      'mt-10 scroll-m-20 pb-1 text-3xl font-semibold tracking-tight first:mt-0',\n      className,\n    )}\n    {...props}\n  />\n)\n\nexport const H3 = ({ id, className, ...props }: ComponentProps<'h3'>) => (\n  <h3\n    id={slugify(props.children, id)}\n    className={cn(\n      'mt-8 scroll-m-20 text-2xl font-semibold tracking-tight',\n      className,\n    )}\n    {...props}\n  />\n)\n\nconst isInternal = (href?: string): href is string => !!href?.startsWith('/')\n\nexport const SmartLink = ({\n  className,\n  href,\n  ref: _,\n  children,\n  ...props\n}: ComponentProps<'a'>) => {\n  const classes = cn('font-medium underline underline-offset-4', className)\n\n  if (isInternal(href)) {\n    return (\n      <Link {...props} href={href} className={classes}>\n        {children}\n      </Link>\n    )\n  }\n\n  return (\n    <a\n      rel=\"noopener noreferrer\"\n      target=\"_blank\"\n      {...props}\n      href={href}\n      className={classes}\n    >\n      {children}\n    </a>\n  )\n}\n\nexport const components = {\n  h1: H1,\n  h2: H2,\n  h3: H3,\n  h4: ({ className, ...props }: ComponentProps<'h4'>) => (\n    <h4\n      className={cn(\n        'mt-8 scroll-m-20 text-xl font-semibold tracking-tight',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  h5: ({ className, ...props }: ComponentProps<'h5'>) => (\n    <h5\n      className={cn(\n        'mt-8 scroll-m-20 text-lg font-semibold tracking-tight',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  h6: ({ className, ...props }: ComponentProps<'h6'>) => (\n    <h6\n      className={cn(\n        'mt-8 scroll-m-20 text-base font-semibold tracking-tight',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  a: SmartLink,\n  p: ({ className, ...props }: ComponentProps<'p'>) => (\n    <p\n      className={cn('leading-7 [&:not(:first-child)]:mt-6', className)}\n      {...props}\n    />\n  ),\n  ul: ({ className, ...props }: ComponentProps<'ul'>) => (\n    <ul className={cn('my-6 ml-6 list-disc', className)} {...props} />\n  ),\n  ol: ({ className, ...props }: ComponentProps<'ol'>) => (\n    <ol className={cn('my-6 ml-6 list-decimal', className)} {...props} />\n  ),\n  li: ({ className, ...props }: ComponentProps<'li'>) => (\n    <li className={cn('mt-2', className)} {...props} />\n  ),\n  blockquote: ({ className, ...props }: ComponentProps<'blockquote'>) => (\n    <blockquote\n      className={cn(\n        'mt-6 border-l-2 pl-6 italic [&>*]:text-muted-foreground',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  // img: ({ className, alt, ...props }: ComponentProps<'img'>) => (\n  //   <img className={cn('rounded-md border', className)} alt={alt} {...props} />\n  // ),\n  hr: ({ ...props }: ComponentProps<'hr'>) => (\n    <hr className=\"my-4 md:my-8\" {...props} />\n  ),\n  table: ({ className, ...props }: ComponentProps<'table'>) => (\n    <div className=\"my-6 w-full overflow-y-auto\">\n      <table className={cn('w-full', className)} {...props} />\n    </div>\n  ),\n  tr: ({ className, ...props }: ComponentProps<'tr'>) => (\n    <tr\n      className={cn('m-0 border-t p-0 even:bg-muted', className)}\n      {...props}\n    />\n  ),\n  th: ({ className, ...props }: ComponentProps<'th'>) => (\n    <th\n      className={cn(\n        'border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  td: ({ className, ...props }: ComponentProps<'td'>) => (\n    <td\n      className={cn(\n        'border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right',\n        className,\n      )}\n      {...props}\n    />\n  ),\n  pre: ({ className, ...props }: ComponentProps<'pre'>) => (\n    <pre className={cn('mb-4 mt-6 overflow-x-auto', className)} {...props} />\n  ),\n  code: ({ className, ...props }: ComponentProps<'code'>) => (\n    <code\n      className={cn(\n        'relative rounded border px-[0.3rem] py-[0.2rem] font-mono text-sm',\n        className,\n      )}\n      {...props}\n    />\n  ),\n}\n"
  },
  {
    "path": "apps/www/src/components/ui/dialog.tsx",
    "content": "'use client'\n\nimport * as React from 'react'\n\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { X } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = ({ ...props }: DialogPrimitive.DialogPortalProps) => (\n  <DialogPrimitive.Portal {...props} />\n)\nDialogPortal.displayName = DialogPrimitive.Portal.displayName\n\nconst DialogOverlay = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Overlay\n    ref={ref}\n    className={cn(\n      'fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n      className,\n    )}\n    {...props}\n  />\n))\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nconst DialogContent = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n  <DialogPortal>\n    <DialogOverlay />\n    <DialogPrimitive.Content\n      ref={ref}\n      className={cn(\n        'fixed left-[50%] top-[10%] z-50 grid w-full max-w-lg translate-x-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full',\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n        <X className=\"h-4 w-4\" />\n        <span className=\"sr-only\">Close</span>\n      </DialogPrimitive.Close>\n    </DialogPrimitive.Content>\n  </DialogPortal>\n))\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nconst DialogHeader = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      'flex flex-col space-y-1.5 text-center sm:text-left',\n      className,\n    )}\n    {...props}\n  />\n)\nDialogHeader.displayName = 'DialogHeader'\n\nconst DialogFooter = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n  <div\n    className={cn(\n      'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n      className,\n    )}\n    {...props}\n  />\n)\nDialogFooter.displayName = 'DialogFooter'\n\nconst DialogTitle = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Title\n    ref={ref}\n    className={cn(\n      'text-lg font-semibold leading-none tracking-tight',\n      className,\n    )}\n    {...props}\n  />\n))\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nconst DialogDescription = React.forwardRef<\n  React.ElementRef<typeof DialogPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <DialogPrimitive.Description\n    ref={ref}\n    className={cn('text-sm text-muted-foreground', className)}\n    {...props}\n  />\n))\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n}\n"
  },
  {
    "path": "apps/www/src/components/ui/dropdown-menu.tsx",
    "content": "'use client'\n\nimport * as React from 'react'\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { Check, ChevronRight, Circle } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n    inset?: boolean\n  }\n>(({ className, inset, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubTrigger\n    ref={ref}\n    className={cn(\n      'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',\n      inset && 'pl-8',\n      className,\n    )}\n    {...props}\n  >\n    {children}\n    <ChevronRight className=\"ml-auto h-4 w-4\" />\n  </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownMenuSubTrigger.displayName =\n  DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownMenuSubContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubContent\n    ref={ref}\n    className={cn(\n      'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1',\n      className,\n    )}\n    {...props}\n  />\n))\nDropdownMenuSubContent.displayName =\n  DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <DropdownMenuPrimitive.Portal>\n    <DropdownMenuPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n        className,\n      )}\n      {...props}\n    />\n  </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n    inset?: boolean\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Item\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      inset && 'pl-8',\n      className,\n    )}\n    {...props}\n  />\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n  <DropdownMenuPrimitive.CheckboxItem\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      className,\n    )}\n    checked={checked}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Check className=\"h-4 w-4\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownMenuCheckboxItem.displayName =\n  DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownMenuRadioItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.RadioItem\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      className,\n    )}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Circle className=\"h-2 w-2 fill-current\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.RadioItem>\n))\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n    inset?: boolean\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Label\n    ref={ref}\n    className={cn(\n      'px-2 py-1.5 text-sm font-semibold',\n      inset && 'pl-8',\n      className,\n    )}\n    {...props}\n  />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Separator\n    ref={ref}\n    className={cn('-mx-1 my-1 h-px bg-muted', className)}\n    {...props}\n  />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuShortcut = ({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n  return (\n    <span\n      className={cn('ml-auto text-xs tracking-widest opacity-60', className)}\n      {...props}\n    />\n  )\n}\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut'\n\nexport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuPortal,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n}\n"
  },
  {
    "path": "apps/www/src/components/ui/icons.tsx",
    "content": "import { forwardRef } from 'react'\n\nimport type { LucideIcon, LucideProps } from 'lucide-react'\n\nexport { Flame as Logo } from 'lucide-react'\nexport { X as Close } from 'lucide-react'\nexport { Loader2 as Spinner } from 'lucide-react'\nexport { ChevronLeft } from 'lucide-react'\nexport { ChevronRight } from 'lucide-react'\nexport { Trash } from 'lucide-react'\nexport { FileText as Post } from 'lucide-react'\nexport { File as Page } from 'lucide-react'\nexport { Image as Media } from 'lucide-react'\nexport { Settings } from 'lucide-react'\nexport { CreditCard as Billing } from 'lucide-react'\nexport { MoreVertical as Ellipsis } from 'lucide-react'\nexport { Plus as Add } from 'lucide-react'\nexport { AlertTriangle as Warning } from 'lucide-react'\nexport { User } from 'lucide-react'\nexport { ArrowRight } from 'lucide-react'\nexport { HelpCircle as Help } from 'lucide-react'\nexport { Pizza } from 'lucide-react'\nexport { SunMedium as Sun } from 'lucide-react'\nexport { Moon } from 'lucide-react'\nexport { Laptop } from 'lucide-react'\nexport { Zap } from 'lucide-react'\nexport { Leaf } from 'lucide-react'\nexport { Globe } from 'lucide-react'\nexport { Code2 as Code } from 'lucide-react'\nexport { BookOpenCheck as Book } from 'lucide-react'\nexport { Unplug } from 'lucide-react'\nexport { Puzzle } from 'lucide-react'\nexport { Twitter } from 'lucide-react'\nexport { Check } from 'lucide-react'\n\nexport const GitHub: LucideIcon = forwardRef<SVGSVGElement, LucideProps>(\n  function GitHub({ ...props }, ref) {\n    return (\n      <svg\n        aria-hidden=\"true\"\n        focusable=\"false\"\n        data-prefix=\"fab\"\n        data-icon=\"github\"\n        role=\"img\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 496 512\"\n        {...props}\n        ref={ref}\n      >\n        <path\n          fill=\"currentColor\"\n          d=\"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"\n        ></path>\n      </svg>\n    )\n  },\n)\n"
  },
  {
    "path": "apps/www/src/config/docs.ts",
    "content": "import type { DocsConfig } from '@/types'\n\nexport const docsConfig: DocsConfig = {\n  mainNav: [\n    {\n      title: 'Documentation',\n      href: '/introduction',\n    },\n  ],\n  sidebarNav: [\n    {\n      title: 'Getting Started',\n      items: [\n        {\n          title: 'Introduction',\n          href: '/introduction',\n        },\n        {\n          title: 'Migrate to v3',\n          href: '/migrate-to-v3',\n        },\n      ],\n    },\n    // Note: Hooks are added here dynamically\n  ],\n}\n"
  },
  {
    "path": "apps/www/src/config/marketing.ts",
    "content": "import type { MarketingConfig } from '@/types'\n\nexport const marketingConfig: MarketingConfig = {\n  mainNav: [\n    {\n      title: 'Features',\n      href: '/#features',\n    },\n    {\n      title: 'Documentation',\n      href: '/introduction',\n    },\n  ],\n}\n"
  },
  {
    "path": "apps/www/src/config/site.ts",
    "content": "import type { SiteConfig } from '@/types'\n\nexport const siteConfig: SiteConfig = {\n  name: 'usehooks-ts',\n  description: 'React hook library, ready to use, written in Typescript.',\n  url: 'https://usehooks-ts.com',\n  ogImage:\n    'https://via.placeholder.com/1200x630.png/007ACC/fff/?text=usehooks-ts',\n  links: {\n    github: 'https://github.com/juliencrn/usehooks-ts',\n    npm: 'https://www.npmjs.com/package/usehooks-ts',\n  },\n}\n"
  },
  {
    "path": "apps/www/src/lib/api.ts",
    "content": "'use server'\n\nimport { compileMDX } from 'next-mdx-remote/rsc'\nimport path from 'path'\nimport rehypePrism from 'rehype-prism-plus'\nimport remarkGfm from 'remark-gfm'\n\nimport { components } from '@/components/ui/components'\nimport type { BaseHook } from '@/types'\nimport fs from 'fs/promises'\n\nconst SOURCE_PATH = path.resolve(process.cwd(), '..', '..', 'generated', 'docs')\n\n/**\n * Fetches and compiles the Markdown content for a specific hook.\n * @param slug The slug of the hook to fetch.\n * @returns Compiled MDX content for the hook.\n */\nexport const getHook = async (slug: string) => {\n  try {\n    const filename = path.resolve(SOURCE_PATH, 'hooks', `${slug}.md`)\n    const source = await fs.readFile(filename, { encoding: 'utf-8' })\n    return await compileMDX<BaseHook>({\n      source,\n      options: {\n        parseFrontmatter: true,\n        mdxOptions: {\n          // @ts-ignore any\n          rehypePlugins: [[rehypePrism]],\n          remarkPlugins: [remarkGfm],\n        },\n      },\n      components,\n    })\n  } catch (error) {\n    console.error(`Error fetching hook with slug '${slug}': `, error)\n    throw error\n  }\n}\n\n/**\n * Retrieves a list of all hooks from the JSON file.\n * @returns An array of BaseHook objects representing all hooks.\n */\nexport const getHookList = async () => {\n  try {\n    const filename = path.resolve(SOURCE_PATH, 'hooks.json')\n    const file = await fs.readFile(filename, { encoding: 'utf-8' })\n    return JSON.parse(file) as BaseHook[]\n  } catch (error) {\n    console.error(`Error retrieving hook list: `, error)\n    throw error\n  }\n}\n"
  },
  {
    "path": "apps/www/src/lib/utils.ts",
    "content": "import type { ClassValue } from 'clsx'\nimport { clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nimport type { BaseHook, NavItem } from '@/types'\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function mapHookToNavLink(hook: BaseHook): NavItem {\n  return {\n    title: hook.name,\n    href: hook.path,\n  }\n}\n"
  },
  {
    "path": "apps/www/src/types/index.ts",
    "content": "import type { IconNode } from 'lucide-react'\n\nexport type SiteConfig = {\n  name: string\n  description: string\n  url: string\n  ogImage: string\n  links: {\n    github: string\n    npm: string\n  }\n}\n\nexport type BaseHook = {\n  name: string\n  slug: string\n  summary: string\n  path: string\n}\n\nexport type NavItem = {\n  title: string\n  href: string\n  disabled?: boolean\n}\n\nexport type MainNavItem = NavItem\n\nexport type SidebarNavItem = {\n  title: string\n  disabled?: boolean\n  external?: boolean\n  icon?: keyof IconNode\n} & (\n  | {\n      href: string\n      items?: never\n    }\n  | {\n      href?: string\n      items: NavItem[]\n    }\n)\n\nexport type DocsConfig = {\n  mainNav: MainNavItem[]\n  sidebarNav: SidebarNavItem[]\n}\n\nexport type MarketingConfig = {\n  mainNav: MainNavItem[]\n}\n"
  },
  {
    "path": "apps/www/tailwind.config.js",
    "content": "import { fontFamily } from 'tailwindcss/defaultTheme'\n\n/** @type {import('tailwindcss').Config} */\nconst config = {\n  content: ['./src/**/*.{ts,tsx,css}'],\n  theme: {\n    container: {\n      center: true,\n      padding: '2rem',\n      screens: {\n        '2xl': '1400px',\n      },\n    },\n    extend: {\n      colors: {\n        border: 'hsl(var(--border))',\n        input: 'hsl(var(--input))',\n        ring: 'hsl(var(--ring))',\n        background: 'hsl(var(--background))',\n        foreground: 'hsl(var(--foreground))',\n        primary: {\n          DEFAULT: 'hsl(var(--primary))',\n          foreground: 'hsl(var(--primary-foreground))',\n        },\n        secondary: {\n          DEFAULT: 'hsl(var(--secondary))',\n          foreground: 'hsl(var(--secondary-foreground))',\n        },\n        destructive: {\n          DEFAULT: 'hsl(var(--destructive))',\n          foreground: 'hsl(var(--destructive-foreground))',\n        },\n        muted: {\n          DEFAULT: 'hsl(var(--muted))',\n          foreground: 'hsl(var(--muted-foreground))',\n        },\n        accent: {\n          DEFAULT: 'hsl(var(--accent))',\n          foreground: 'hsl(var(--accent-foreground))',\n        },\n        popover: {\n          DEFAULT: 'hsl(var(--popover))',\n          foreground: 'hsl(var(--popover-foreground))',\n        },\n        card: {\n          DEFAULT: 'hsl(var(--card))',\n          foreground: 'hsl(var(--card-foreground))',\n        },\n      },\n      borderRadius: {\n        lg: 'var(--radius)',\n        md: 'calc(var(--radius) - 2px)',\n        sm: 'calc(var(--radius) - 4px)',\n      },\n      fontFamily: {\n        sans: ['var(--font-sans)', ...fontFamily.sans],\n        heading: ['var(--font-heading)', ...fontFamily.sans],\n      },\n      keyframes: {\n        'accordion-down': {\n          from: { height: 0 },\n          to: { height: 'var(--radix-accordion-content-height)' },\n        },\n        'accordion-up': {\n          from: { height: 'var(--radix-accordion-content-height)' },\n          to: { height: 0 },\n        },\n      },\n      animation: {\n        'accordion-down': 'accordion-down 0.2s ease-out',\n        'accordion-up': 'accordion-up 0.2s ease-out',\n      },\n    },\n  },\n  plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],\n}\n\nexport default config\n"
  },
  {
    "path": "apps/www/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true,\n    \"plugins\": [\n      {\n        \"name\": \"next\"\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    }\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \".next/types/**/*.ts\",\n    \"**/*.js\"\n  ],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"workspace\",\n  \"private\": true,\n  \"description\": \"React hook library, ready to use, written in Typescript.\",\n  \"author\": \"Julien CARON <juliencaron@protonmail.com>\",\n  \"homepage\": \"https://usehooks-ts.com\",\n  \"module\": \"true\",\n  \"type\": \"module\",\n  \"keywords\": [\n    \"typescript\",\n    \"react\",\n    \"hooks\"\n  ],\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"preinstall\": \"npx only-allow pnpm\",\n    \"dev\": \"turbo run dev\",\n    \"build\": \"turbo run build\",\n    \"test\": \"turbo run test\",\n    \"clean\": \"rimraf .turbo generated && turbo run clean\",\n    \"format\": \"prettier --write \\\"**/*.{json,md,mdx,css,scss,yaml,yml}\\\" --ignore-path .prettierignore\",\n    \"lint\": \"turbo run lint\",\n    \"update-testing-issue\": \"zx ./scripts/update-testing-issue.js\",\n    \"update-algolia-index\": \"zx ./scripts/update-algolia-index.js\",\n    \"gen-hook\": \"turbo gen hook --config \\\"turbo/generators/config.cts\\\" && pnpm format\",\n    \"changeset\": \"npx changeset\",\n    \"changeset-version\": \"npx changeset version\",\n    \"changeset-publish\": \"npx changeset publish\",\n    \"generate-doc\": \"zx ./scripts/generate-doc.js\"\n  },\n  \"resolutions\": {\n    \"typescript\": \"^5.3.3\"\n  },\n  \"devDependencies\": {\n    \"@changesets/cli\": \"^2.27.1\",\n    \"@turbo/gen\": \"^1.12.4\",\n    \"@t3-oss/env-core\": \"^0.9.2\",\n    \"all-contributors-cli\": \"^6.26.1\",\n    \"algoliasearch\": \"^4.22.1\",\n    \"date-fns\": \"^3.3.1\",\n    \"dotenv\": \"16.4.5\",\n    \"eslint\": \"^8.56.0\",\n    \"prettier\": \"^3.2.5\",\n    \"rimraf\": \"^5.0.5\",\n    \"turbo\": \"^1.12.4\",\n    \"typedoc\": \"^0.25.9\",\n    \"typedoc-plugin-markdown\": \"^3.17.1\",\n    \"typedoc-plugin-mdn-links\": \"^3.1.17\",\n    \"typedoc-plugin-missing-exports\": \"^2.2.0\",\n    \"zod\": \"3.22.4\",\n    \"zx\": \"^7.2.3\"\n  },\n  \"engines\": {\n    \"node\": \">=18.17.0\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/juliencrn/usehooks-ts\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/juliencrn/usehooks-ts/issues\"\n  }\n}\n"
  },
  {
    "path": "packages/eslint-config-custom/.eslintrc.cjs",
    "content": "module.exports = {\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    ecmaVersion: 2020,\n    sourceType: 'module',\n    project: ['./tsconfig.json'],\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n  ignorePatterns: ['dist', '.eslintrc.*'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended-type-checked',\n    'plugin:@typescript-eslint/strict-type-checked',\n    'plugin:@typescript-eslint/stylistic-type-checked',\n    'plugin:react-hooks/recommended',\n    'plugin:react/recommended',\n    'plugin:jsx-a11y/recommended',\n    'plugin:import/typescript',\n  ],\n  plugins: [\n    '@typescript-eslint',\n    'react',\n    'simple-import-sort',\n    'prettier',\n    'jsx-a11y',\n    'eslint-plugin-import',\n  ],\n  env: {\n    browser: true,\n    es6: true,\n    node: true,\n  },\n  settings: {\n    react: {\n      version: 'detect',\n    },\n  },\n  rules: {\n    // Format\n    'prettier/prettier': 'error',\n\n    // React\n    'react/prop-types': 'off',\n    'react/jsx-uses-react': 'off',\n    'react/react-in-jsx-scope': 'off',\n\n    // Import\n    'sort-imports': 'off',\n    'import/order': 'off',\n    'import/no-cycle': 'error',\n    'import/no-duplicates': 'error',\n    'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],\n    '@typescript-eslint/consistent-type-exports': 'error',\n    '@typescript-eslint/consistent-type-imports': 'error',\n    '@typescript-eslint/no-import-type-side-effects': 'error',\n    'simple-import-sort/exports': 'error',\n    'simple-import-sort/imports': [\n      'error',\n      {\n        groups: [\n          ['^\\\\u0000'], // side effect (E.g.\"import \"normalize.css\"\")\n          ['^react$'],\n          ['^[^.]'], // Libs\n          ['^../|^~/|^./'],\n        ],\n      },\n    ],\n\n    // We should absolutely avoid using ts-ignore, but it\"s not always possible.\n    // particular when a dependencies types are incorrect.\n    '@typescript-eslint/ban-ts-comment': [\n      'error',\n      { 'ts-ignore': 'allow-with-description' },\n    ],\n\n    // Allow unused variables that start with an underscore.\n    '@typescript-eslint/no-unused-vars': [\n      'error',\n      {\n        argsIgnorePattern: '^_',\n        ignoreRestSiblings: true,\n      },\n    ],\n\n    // Opinionated: no enums\n    'no-restricted-syntax': [\n      'warn',\n      {\n        selector: 'TSEnumDeclaration',\n        message: 'Prefer union type',\n      },\n    ],\n\n    // Opinionated: prefer \"type\" over \"interface\"\n    '@typescript-eslint/consistent-type-definitions': ['warn', 'type'],\n\n    // Disable some TypeScript rules\n    '@typescript-eslint/explicit-module-boundary-types': 'off', // Too noisy\n    // '@typescript-eslint/consistent-type-definitions': 'off', // Will come in v3\n    '@typescript-eslint/no-unnecessary-condition': 'off', // TODO: Enable it\n    '@typescript-eslint/prefer-ts-expect-error': 'off',\n  },\n  overrides: [\n    // Specials rules for testing\n    {\n      extends: ['plugin:vitest/recommended'],\n      files: ['**/*.test.ts'],\n      plugins: ['vitest'],\n      rules: {\n        // you should turn the original rule off *only* for test files\n        '@typescript-eslint/unbound-method': 'off',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/eslint-config-custom/.gitignore",
    "content": "node_modules\n"
  },
  {
    "path": "packages/eslint-config-custom/CHANGELOG.md",
    "content": "# eslint-config-custom\n\n## 2.0.0\n\n### Major Changes\n\n- a8e8968: Move the full workspace into ES Module\n\n### Minor Changes\n\n- a8e8968: Prefer type over interface (#515)\n\n## 1.2.0\n\n### Minor Changes\n\n- b5b9e1f: chore: Updated dependencies\n\n## 1.1.1\n\n### Patch Changes\n\n- add1431: Upgrade dependencies\n- 0321342: Make Typescript and typescript-eslint stricter\n- a192167: Migrate from jest to vitest\n\n## 1.1.0\n\n### Minor Changes\n\n- 4b3ed4e: Prevent circular dependencies with Eslint\n\n## 1.0.1\n\n### Patch Changes\n\n- 7141d01: Upgrade internal dependencies\n"
  },
  {
    "path": "packages/eslint-config-custom/README.md",
    "content": "# eslint-config-custom\n\n## Usage\n\nin your .eslintrc\n\n```json\n{\n  \"extends\": [\"custom-config\"]\n}\n```\n"
  },
  {
    "path": "packages/eslint-config-custom/index.cjs",
    "content": "const eslintrc = require('./.eslintrc.cjs')\n\nmodule.exports = eslintrc\n"
  },
  {
    "path": "packages/eslint-config-custom/package.json",
    "content": "{\n  \"name\": \"eslint-config-custom\",\n  \"private\": true,\n  \"version\": \"2.0.0\",\n  \"description\": \"Base configuration for Eslint\",\n  \"main\": \"index.cjs\",\n  \"author\": \"Julien CARON <juliencaron@protonmail.com>\",\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"devDependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^7.0.2\",\n    \"@typescript-eslint/parser\": \"^7.0.2\",\n    \"eslint-config-prettier\": \"^9.1.0\",\n    \"eslint-plugin-import\": \"^2.29.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.8.0\",\n    \"eslint-plugin-prettier\": \"^5.1.3\",\n    \"eslint-plugin-react\": \"^7.33.2\",\n    \"eslint-plugin-react-hooks\": \"^4.6.0\",\n    \"eslint-plugin-simple-import-sort\": \"^12.0.0\",\n    \"eslint-plugin-vitest\": \"^0.4.0\",\n    \"typescript\": \"^5.3.3\"\n  }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/.eslintrc.cjs",
    "content": "module.exports = {\n  extends: ['custom'],\n  plugins: ['jsdoc'],\n  rules: {\n    'jsdoc/check-access': 'warn', // Recommended\n    'jsdoc/check-alignment': 'warn', // Recommended\n    // 'jsdoc/check-examples': 'warn',\n    'jsdoc/check-indentation': 'warn',\n    'jsdoc/check-line-alignment': 'warn',\n    'jsdoc/check-param-names': 'warn', // Recommended\n    'jsdoc/check-property-names': 'warn', // Recommended\n    'jsdoc/check-syntax': 'warn',\n    // Allow more tags\n    'jsdoc/check-tag-names': 'warn', // Recommended\n    // 'jsdoc/check-tag-names': [\n    //   'warn',\n    //   {\n    //     definedTags: ['aliases', 'includeExample', 'keywords'],\n    //   },\n    // ], // Recommended\n    'jsdoc/check-types': 'warn', // Recommended\n    'jsdoc/check-values': 'warn', // Recommended\n    'jsdoc/empty-tags': 'warn', // Recommended\n    'jsdoc/implements-on-classes': 'warn', // Recommended\n    // 'jsdoc/informative-docs': 'warn',\n    'jsdoc/match-description': 'warn',\n    'jsdoc/multiline-blocks': 'warn', // Recommended\n    'jsdoc/no-bad-blocks': 'warn',\n    'jsdoc/no-blank-block-descriptions': 'warn',\n    'jsdoc/no-defaults': 'warn',\n    // 'jsdoc/no-missing-syntax': 'warn',\n    'jsdoc/no-multi-asterisks': 'warn', // Recommended\n    // 'jsdoc/no-restricted-syntax': 'warn',\n    // 'jsdoc/no-types': 'warn',\n    'jsdoc/no-undefined-types': 'warn', // Recommended\n    'jsdoc/require-asterisk-prefix': 'warn',\n    'jsdoc/require-description': 'warn',\n    'jsdoc/require-description-complete-sentence': 'warn',\n    'jsdoc/require-example': 'warn',\n    // 'jsdoc/require-file-overview': 'warn',\n    'jsdoc/require-hyphen-before-param-description': 'warn',\n    // 'jsdoc/require-jsdoc': 'warn', // Recommended\n    'jsdoc/require-param': 'warn', // Recommended\n    'jsdoc/require-param-description': 'warn', // Recommended\n    'jsdoc/require-param-name': 'warn', // Recommended\n    'jsdoc/require-param-type': 'warn', // Recommended\n    'jsdoc/require-property': 'warn', // Recommended\n    'jsdoc/require-property-description': 'warn', // Recommended\n    'jsdoc/require-property-name': 'warn', // Recommended\n    'jsdoc/require-property-type': 'warn', // Recommended\n    'jsdoc/require-returns': 'warn', // Recommended\n    'jsdoc/require-returns-check': 'warn', // Recommended\n    'jsdoc/require-returns-description': 'warn', // Recommended\n    'jsdoc/require-returns-type': 'warn', // Recommended\n    'jsdoc/require-throws': 'warn',\n    'jsdoc/require-yields': 'warn', // Recommended\n    'jsdoc/require-yields-check': 'warn', // Recommended\n    'jsdoc/sort-tags': 'warn',\n    'jsdoc/tag-lines': 'warn', // Recommended\n    'jsdoc/valid-types': 'warn', // Recommended\n  },\n  overrides: [\n    // Track tree-shaking potential error in the lib\n    {\n      files: ['./src/**/!(*.test|*.spec).ts'],\n      plugins: ['tree-shaking'],\n      rules: {\n        'tree-shaking/no-side-effects-in-initialization': 'error',\n      },\n    },\n  ],\n  ignorePatterns: ['./dist', './node_modules', './turbo'],\n  overrides: [\n    {\n      files: ['*.test.ts'],\n      rules: {\n        'jsdoc/require-jsdoc': 'off',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/usehooks-ts/.gitignore",
    "content": "node_modules\n.turbo\ndist\n"
  },
  {
    "path": "packages/usehooks-ts/CHANGELOG.md",
    "content": "# Changelog\n\n## 3.1.1\n\n### Patch Changes\n\n- b1dffb9: feat: Update peerDependencies to include React 19 @michal-worwag\n\n## 3.1.0\n\n### Minor Changes\n\n- 06dfd5e: Add `remove` function to `useLocalStorage` and `useSessionStorage` (@k-melnychuk & @RubyHuntsman)\n\n### Patch Changes\n\n- e62c41f: Restoration of the `useTernaryDarkMode` related types (@soullivaneuh)\n- 90a33f5: fix: reject non-boolean value as a `defaultValue` for `useBoolean` (@luckrnx09)\n- 7ba7e3a: test reset for `useCounter` (#570 by @luckrnx09)\n\n## 3.0.2\n\n### Patch Changes\n\n- b14db5b: Add support for focus event to `useOnClickOutside` (Fixes: #522)\n- 59c0b93: Add SVG element support to `useEventListener` (#546 by @LumaKernel)\n- b14db5b: Expose `AddEventListenerOptions` in `useOnClickOutside` (Fixes #554 from @metav-drimz)\n- b14db5b: Support missing refs in `useOnClickOutside` (Fixes: #531)\n- 09341a3: feat(useEventCallback): allow optional callback (#550 by @Newbie012)\n\n## 3.0.1\n\n### Patch Changes\n\n- Fix: Update exported files\n\n## 3.0.0\n\n### Major Changes\n\n- a8e8968: Remove previously deprecated hooks and hooks' signatures (#503)\n- a8e8968: Improve JSDoc comments and rename or make private some type aliases\n- a8e8968: Prefer type over interface (#515)\n- a8e8968: Move the full workspace into ES Module\n\n## 2.16.0\n\n### Minor Changes\n\n- 9b65ce8: Add `id` param to `useScript` hook (from #285 by @misidoro)\n\n### Patch Changes\n\n- d881f08: Add `isLocked` state to the `useScrollLock` return (#521 by @kyrylo-soulandwolf)\n- fc25779: Resolve warning when using `useScrollLock` in an SSR environment (#521 by @kyrylo-soulandwolf)\n- d42741f: Wrap `useCountdown` methods with `useCallback` (from #326 by @gromchen)\n- d42741f: Wrap `useCounter` methods with `useCallback` (from #326 by @gromchen)\n- d881f08: Fixed `useScrollLock` leaving inline styles (#516 from @novacdenis)\n- 0d99db9: chore(deps): update all non-major dependencies\n- d881f08: Fixed reflow not considering the padding before the lock (#521 by @kyrylo-soulandwolf)\n\n## 2.15.1\n\n### Patch Changes\n\n- b88cc01: fix `useResizeObserver` initialSize mutation (#504 from @iuriiiurevich)\n- 823b62f: Resolve scroll lock issue on ios safari (#509 by @jontewks)\n\n## 2.15.0\n\n### Minor Changes\n\n- 649ef39: ✨ Feature: add `useScrollLock` hook\n\n### Patch Changes\n\n- 649ef39: Deprecated `useLockedBody` replaced by `useScrollLock`\n- 6514683: Fix `useMediaQuery` by defining getMatches before use\n- d8d8e5d: Upgrade dependencies\n\n## 2.14.0\n\n### Minor Changes\n\n- d60f1c6: Added debounce option to both `useScreen` and `useWindowSize`\n\n### Patch Changes\n\n- 7d74e09: Release documentation for `useEventCallback`\n- 2660580: Depreciated `useFetch`, see documentation for more information\n- bc3f967: Deprecated `useEffectOnce`, `useIsFirstRender` and `useUpdateEffect`\n\n## 2.13.0\n\n### Minor Changes\n\n- 87a5141: Improve `useOnClickOutside`:\n\n  - Prevent handling callback when clicking on a not connected element (#374 by @hooriza)\n  - Add support to accept multiple references\n  - Add support for touch events in addition to mouse events\n\n- 87ba579: Fix SSR hooks by fallback with default or initial value instead of `undefined`\n- f39078f: Updated `useIntersectionObserver` API and fixed #395, #271 and #182, see #464.\n- a444ba7: Depreciated `useElementSize` replaced by `useResizeObserver`\n- e807ab3: Create `useResizeObserver` hook\n\n### Patch Changes\n\n- b5b9e1f: chore: Updated dependencies\n- 4146c39: fix: `useScript` failed to remove script from cache when passing `removeOnUnmount` prop (#354 by @ShanSenanayake)\n- bdf7bda: Add eslint rules to comply with `verbatimModuleSyntax` to avoid side-effects\n- 6b582de: use `tsup` as bundler instead of transpiling with tsc (@BlankParticle)\n- be8c35b: Fix `useScreen` is not rerendering on screen resize (#280 by @philipgher)\n\n## 2.12.1\n\n### Patch Changes\n\n- Don't remove comments during package build to keep JSdoc comments\n\n## 2.12.0\n\n### Minor Changes\n\n- cb6eb5c: Added an optional option param in `useDocumentTitle()` to reset title on un-mount (#345 by @ladislasdellinger)\n\n### Patch Changes\n\n- b8ee088: move `lodash.debounce` to dependencies from peerDependencies\n\n## 2.11.0\n\n### Minor Changes\n\n- add1431: Created `useUnmount` hook\n- add1431: Created `useDebounceCallback` and `useDebounceValue` hooks\n- add1431: Depreciated `useDebounce` hook (replaced by `useDebounceCallback` or `useDebounceValue`)\n- fc8a30e: Fix hydration issues in both useScreen and useMediaQuery (Fixes #394, thanks to @bryantcodesart)\n- 4a9fc88: Introduce the SSR-friendly new optional `{ initializeWithValue?: boolean }` parameter to useLocalStorage, useReadLocalStorage, useSessionStorage, useDarkMode, useTernaryDarkMode, useMediaQuery, useScreen, useWindowSize and useElementSize, see #451.\n- 5c210c1: Add `defaultValue` option to `useTernaryDarkMode` and update its signature (using function overload for smooth migration)\n- 5c210c1: Update `useDarkMode` signature (using function overload for smooth migration)\n- 0321342,4a9fc88: Drop `Map`, `Set` and `Date` supports in use\\*Storage hooks, it isn't compatible with `useReadLocalStorage` making the API un-consistent. Use a custom serializer/deserializer instead.\n\n### Patch Changes\n\n- add1431: Upgrade dependencies\n- a192167: Upgraded `react` and `@testing-library/react` (thanks to @TheHaff)\n- 0321342: Make Typescript and `@typescript-eslint` stricter to catch bugs sooner\n- 382161a: Depreciate `useImageOnLoad`, too opinionated\n- 382161a: Add JSdoc comments to improve DX via in-IDE documentation\n- a192167: Migrate from `jest` to `vitest` (making test-suite execution 2 times faster)\n\n## 2.10.0\n\n### Minor Changes\n\n- 8f3c90f: Enable setting localStorage key for useDarkTheme & useTernaryDarkMode (#298 by @ubarbaxor)\n- ae47c9a: Expose setting dark mode value directly (#299 by ubarbaxor)\n- 771afa5: Add serialization support for use-\\*-storage hooks\n\n### Patch Changes\n\n- a816d6b: Depreciated useSsr [#258](https://github.com/juliencrn/usehooks-ts/issues/258)\n- 42f3a3a: Remove the need of commenting out useEffect deps in useMediaQuery (#383 by @lisandro52)\n- 9bc05f4: Fix hydration mismatch on use\\*\\*\\*Storage (fixes #176, #369 with #320 & #251)\n- 771afa5: Add Date, Set & Map support to use\\*Storage (#309 by @AlecsFarias)\n- 4b3ed4e: Fix circular dependencies (#310)\n- a3588b8: Added unit tests for useFetch hook\n- c326dd3: Prevent unrelated storage keys from being updated unexpectedly in useLocalStorage and useSessionStorage (#313 by @stevenvachon fixes #384)\n- e8aa777: make useLocalStorage and useSessionStorage compliant with useState (fixes #204 with #242 by @valyrie97)\n- c5ad2b9: Recalculate useLocalStorage & useSessionStorage default value on dynamic key change (#355 by @amirking59)\n- 7406e3c: fix(useCopyToClipboard): added useCallback to 'copy' to avoid rerendering (by @nmacianx)\n- ffe0f32: Set sideEffects to false in package.json\n\n## 2.9.5\n\n### Patch Changes\n\n- 7141d01: Upgrade internal dependencies\n- Update useCopyToClipboard documentation\n- Fix typo in useEventListener\n\n## 2.9.4\n\n### Patch Changes\n\n- hotfix: package files missing\n\n## [2.9.3](https://www.npmjs.com/package/usehooks-ts/v/2.9.3) - 2024-01-13\n\n### Patch Changes\n\n- Fix #420\n\n## 2.9.2\n\n### Patch Changes\n\n- 55a1904: added export map in package.json\n- use named exports instead of default exports\n- fix useEventListener docs typo\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.9.1](https://www.npmjs.com/package/usehooks-ts/v/2.9.1) - 2022-10-13\n\n### Fixes\n\n- fix hard-coded useLockedBody anchor id\n- useEventListener passes options to removeEventListener (#235 by @marnusw)\n- rename useBoolean, useCounter, useLockedBody and useSidebar hooks ReturnType to Output (#234 by valentinpolitov)\n\n## [2.9.0](https://www.npmjs.com/package/usehooks-ts/v/2.9.0) - 2022-10-13\n\n### Fixes\n\n- Transpile commonjs to es5 (fixes #232)\n\n## [2.8.0](https://www.npmjs.com/package/usehooks-ts/v/2.8.0) - 2022-10-13\n\n### Added\n\n- Added useToggle\n- Added options in useScript (#203, #197 by @curtvict)\n- Added media query support to useEventListener (#194 by @modex98)\n\n### Updated\n\n- Remove React import line in all files\n\n### Fixes\n\n- docs misspelling (#189 by @JoshuaCS94)\n- useIntersectionObserver deps (#195 by @Guesswhoitis)\n\n## [2.7.2](https://www.npmjs.com/package/usehooks-ts/v/2.7.2) - 2022-09-30\n\n### Added\n\n- Added useDocumentTitle (#218 by @curtvict)\n\n### Updated\n\n- Removed `import React` line (not needed since react 17)\n\n### Fixes\n\n- Fixed misspelling (thanks to @alexisoney and @JoshuaCS94)\n\n## [2.7.1](https://www.npmjs.com/package/usehooks-ts/v/2.7.1) - 2022-09-22\n\n### Added\n\n- Support React 18 (#214 by @sharvit)\n\n### Updated\n\n- Remove hooks index files\n- Remove source-map\n\n## [2.7.0](https://www.npmjs.com/package/usehooks-ts/v/2.7.0) - 2022-09-19\n\n### Updated\n\n- Move usehooks-ts to the root\n- Simplify config files (removing some tools)\n- Split the documentation website from the workspace\n- Regroup hooks related files together (test, doc, demo, hook)\n- Upgrade dependencies\n\n## [2.6.0](https://www.npmjs.com/package/usehooks-ts/v/2.6.0) - 2022-06-20\n\n### Added\n\n- useEventListener now supports `Document` events\n- useEventListener now supports native event listener options\n- Add useSessionStorage (#171 by @createdbymahmood)\n- Add unit tests on useHover (#169 by @createdbymahmood)\n\n## [2.5.4](https://www.npmjs.com/package/usehooks-ts/v/2.5.4) - 2022-05-30\n\n### Added\n\n- improve useCountdown interface (#160 by @PabloLION)\n- add SSR unit tests on useIsClient (#161 by @createdbymahmood)\n\n## [2.5.3](https://www.npmjs.com/package/usehooks-ts/v/2.5.3) - 2022-05-16\n\n### Added\n\n- Ignore unrelated 'storage' events in useLocalStorage (#153 from @bogdanailincaipnt)\n\n### Fixes\n\n- Revert #143 useEffectOnce (#152 from @jherr)\n\n## [2.5.2](https://www.npmjs.com/package/usehooks-ts/v/2.5.2) - 2022-05-02\n\n### Fixes\n\n- Fix useFetch (#139 from @daiky218)\n- Fix useEffectOnce (#147 from @3GOMESz)\n\n## [2.5.1](https://www.npmjs.com/package/usehooks-ts/v/2.5.1) - 2022-04-12\n\n### Fixes\n\n- Revert dependencies\n\n## [2.5.0](https://www.npmjs.com/package/usehooks-ts/v/2.5.0) - 2022-04-11\n\n### Added\n\n- Memoise useBoolean (#122 from @angusd3v)\n- make setter from useLocalStorage referentially stable (#133 from @jbean96)\n- add support for useMediaQuery in older versions (#135 from @brycedorn)\n- update dependencies\n\n## [2.4.2](https://www.npmjs.com/package/usehooks-ts/v/2.4.2) - 2022-02-27\n\n### Added\n\n- Improve useEventListener reactivity (#117 from @TunA-Kai)\n- Use useIsomorphicLayoutEffect instead of useLayoutEffect\n- Memoise useLocalStorage setter (from #118)\n\n## [2.4.1](https://www.npmjs.com/package/usehooks-ts/v/2.4.1) - 2022-02-21\n\n### Added\n\n- Add unit tests on useWindowSize (#112 from @createdbymahmood)\n- Add unit tests on useElementSize (#111 from @createdbymahmood)\n- Add useIsomorphicLayoutEffect and replace all useLayoutEffect (#116)\n\n### Fixes\n\n- Fix use[Read]LocalStorage render cycle (#109 from @bogdanailincaipnt)\n\n## [2.4.0](https://www.npmjs.com/package/usehooks-ts/v/2.4.0) - 2022-02-12\n\n### Added\n\n- Add unit tests on useInterval (#104/#106 from @createdbymahmood)\n- Add unit tests on useDarkMode (#105/#106 from @createdbymahmood)\n\n### Updated\n\n- Update local-storage key in useTernaryDarMode (#98 from @PabloLION)\n- Update local-storage key in useDarMode (#98 from @PabloLION)\n- Update Typescript to 4.5.5 (minor)\n\n## [2.3.0](https://www.npmjs.com/package/usehooks-ts/v/2.3.0) - 2022-01-30\n\n### Added\n\n- Create useTernaryDarMode (#89 from @PabloLION)\n\n## [2.2.2](https://www.npmjs.com/package/usehooks-ts/v/2.2.2) - 2022-01-25\n\n### Fix\n\n- Fix esm and source map (issued (#88) by @egehandulger)\n\n## [2.2.1](https://www.npmjs.com/package/usehooks-ts/v/2.2.1) - 2022-01-12\n\n### Added\n\n- Fix types add tests on useEventListener (#82 from @egehandulger)\n\n## [2.2.0](https://www.npmjs.com/package/usehooks-ts/v/2.2.0) - 2022-01-03\n\n### Added\n\n- Add tests on useIsMounted (#75 from @DidrikLind)\n- Add useCountdown() hook (#76 from @hexp1989)\n- Add tests on useDebounce (#80 from @DidrikLind)\n\n## [2.1.0](https://www.npmjs.com/package/usehooks-ts/v/2.1.0) - 2021-12-01\n\n### Added\n\n- Create media query hook (#74 from @AbbalYouness)\n- Add param to allow 'mouseup' event on useOnClickOutside (#69 from @JamesBarretDev)\n\n## [2.0.2](https://www.npmjs.com/package/usehooks-ts/v/2.0.2) - 2021-11-19\n\n### Added\n\n- Create useClickAnyWhere hook (#66 from @sonjoydatta)\n\n### Fixes\n\n- Fix useTimeout and useInterval (#65 from @oluckyman).\n- Fix useOnClickOutside (bug introduced in the 2.0.1).\n\n## [2.0.1](https://www.npmjs.com/package/usehooks-ts/v/2.0.1) - 2021-11-17\n\n### Added\n\n- Simplify useOnClickOutside (introduces a bug fixed in 2.0.2)\n\n## [2.0.0](https://www.npmjs.com/package/usehooks-ts/v/2.0.0) - 2021-11-16\n\n### BREAKING CHANGE\n\n- Fixing the useElementSize changes the hook interface.\n\n## [1.2.1](https://www.npmjs.com/package/usehooks-ts/v/1.2.1) - 2021-11-10\n\n### Added\n\n- useEffectOnce()\n- useUpdateEffect()\n- useIsFirstRender()\n- Add Revonate\n\n### Fixes\n\n- fix(site-templates-post): Fixed edit link (#59 from @ducktordanny)\n\n## [1.1.1](https://www.npmjs.com/package/usehooks-ts/v/1.1.1) - 2021-11-08\n\n### Added\n\n- Add renovate bot.\n- Upgrade @Material-ui to Mui@5 (including a lot of UI refactoring)\n- Upgrade Gatsby to v4.\n\n### Fix\n\n- Re-generate package-lock.json due wrong npm version.\n\n## [1.1.0](https://www.npmjs.com/package/usehooks-ts/v/1.1.0) - 2021-11-06\n\n- Use useEventListener in the hooks when possible #DRY.\n- Enforce tree-shaking support with an Eslint plugin.\n- New hook: useStep() (#48 from @qlaffont).\n\n## [1.0.14](https://www.npmjs.com/package/usehooks-ts/v/1.0.14) - 2021-11-03\n\n### Added\n\n- CHANGELOG.md was created.\n- SemVer started.\n- Upgrade Node and NPM to publish quickly with lerna\n"
  },
  {
    "path": "packages/usehooks-ts/README.md",
    "content": "<img src=\"https://github.com/juliencrn/usehooks-ts/blob/master/.github/screenshot.png\" alt=\"usehooks-ts banner\" align=\"center\" />\n\n<br />\n\n<div align=\"center\">\n<h1>usehooks-ts</h1>\n\n<div>React hook library, ready to use, written in Typescript.</div>\n\n<br />\n\n<!-- Badges -->\n\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md)\n![NPM Downloads](https://img.shields.io/npm/dm/usehooks-ts)\n![NPM Downloads](https://img.shields.io/npm/dt/usehooks-ts)\n[![License](https://badgen.net/badge/License/MIT/blue)](https://github.com/juliencrn/usehooks-ts/blob/master/LICENSE)\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/usehooks-ts)\n![npm](https://img.shields.io/npm/v/usehooks-ts)<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->\n[![All Contributors](https://img.shields.io/badge/all_contributors-253-orange.svg?style=flat-square)](#contributors-)\n\n<!-- ALL-CONTRIBUTORS-BADGE:END -->\n\n<br />\n  <pre>npm i <a href=\"https://www.npmjs.com/package/usehooks-ts\">usehooks-ts</a></pre>\n  <br />\n\n<div align=\"center\">\n  <sub>Created by <a href=\"https://github.com/juliencrn\">Julien Caron</a> and maintained with ❤️ by an amazing <a href=\"#contributors\">team of developers</a>.</sub>\n</div>\n\n</div>\n\n<br />\n\n## 💫 Introduction\n\nuseHooks(🔥).ts is a React hooks library, written in Typescript and easy to use. It provides a set of hooks that enables you to build your React applications faster. The hooks are built upon the principles of DRY (Don't Repeat Yourself). There are hooks for most common use cases you might need.\n\nThe library is designed to be as minimal as possible. It is fully tree-shakable (using the ESM version), meaning that you only import the hooks you need, and the rest will be removed from your bundle making the cost of using this library negligible. Most hooks are extensively tested and are being used in production environments.\n\n### Usage example\n\n```tsx\nimport { useLocalStorage } from 'usehooks-ts'\n\nfunction Component() {\n  const [value, setValue] = useLocalStorage('my-localStorage-key', 0)\n\n  // ...\n}\n```\n\n## 🪝 Available Hooks\n\n<!-- HOOKS:START -->\n\n- [`useBoolean`](https://usehooks-ts.com/react-hook/use-boolean) — handles boolean state with useful utility functions.\n- [`useClickAnyWhere`](https://usehooks-ts.com/react-hook/use-click-any-where) — handles click events anywhere on the document.\n- [`useCopyToClipboard`](https://usehooks-ts.com/react-hook/use-copy-to-clipboard) — copies text to the clipboard using the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).\n- [`useCountdown`](https://usehooks-ts.com/react-hook/use-countdown) — manages countdown.\n- [`useCounter`](https://usehooks-ts.com/react-hook/use-counter) — manages a counter with increment, decrement, reset, and setCount functionalities.\n- [`useDarkMode`](https://usehooks-ts.com/react-hook/use-dark-mode) — returns the current state of the dark mode.\n- [`useDebounceCallback`](https://usehooks-ts.com/react-hook/use-debounce-callback) — creates a debounced version of a callback function.\n- [`useDebounceValue`](https://usehooks-ts.com/react-hook/use-debounce-value) — returns a debounced version of the provided value, along with a function to update it.\n- [`useDocumentTitle`](https://usehooks-ts.com/react-hook/use-document-title) — sets the document title.\n- [`useEventCallback`](https://usehooks-ts.com/react-hook/use-event-callback) — creates a memoized event callback.\n- [`useEventListener`](https://usehooks-ts.com/react-hook/use-event-listener) — attaches event listeners to DOM elements, the window, or media query lists.\n- [`useHover`](https://usehooks-ts.com/react-hook/use-hover) — tracks whether a DOM element is being hovered over.\n- [`useIntersectionObserver`](https://usehooks-ts.com/react-hook/use-intersection-observer) — tracks the intersection of a DOM element with its containing element or the viewport using the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).\n- [`useInterval`](https://usehooks-ts.com/react-hook/use-interval) — creates an interval that invokes a callback function at a specified delay using the [setInterval API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval).\n- [`useIsClient`](https://usehooks-ts.com/react-hook/use-is-client) — determines if the code is running on the client side (in the browser).\n- [`useIsMounted`](https://usehooks-ts.com/react-hook/use-is-mounted) — determines if the component is currently mounted.\n- [`useIsomorphicLayoutEffect`](https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect) — uses either useLayoutEffect or useEffect based on the environment (client-side or server-side).\n- [`useLocalStorage`](https://usehooks-ts.com/react-hook/use-local-storage) — uses the [localStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to persist state across page reloads.\n- [`useMap`](https://usehooks-ts.com/react-hook/use-map) — manages a key-value [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) state with setter actions.\n- [`useMediaQuery`](https://usehooks-ts.com/react-hook/use-media-query) — tracks the state of a media query using the [Match Media API](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia).\n- [`useOnClickOutside`](https://usehooks-ts.com/react-hook/use-on-click-outside) — handles clicks outside a specified element.\n- [`useReadLocalStorage`](https://usehooks-ts.com/react-hook/use-read-local-storage) — reads a value from [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), closely related to [useLocalStorage()](https://usehooks-ts.com/react-hook/use-local-storage).\n- [`useResizeObserver`](https://usehooks-ts.com/react-hook/use-resize-observer) — observes the size of an element using the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n- [`useScreen`](https://usehooks-ts.com/react-hook/use-screen) — tracks the [screen](https://developer.mozilla.org/en-US/docs/Web/API/Window/screen) dimensions and properties.\n- [`useScript`](https://usehooks-ts.com/react-hook/use-script) — dynamically loads scripts and tracking their loading status.\n- [`useScrollLock`](https://usehooks-ts.com/react-hook/use-scroll-lock) — A custom hook that locks and unlocks scroll.\n- [`useSessionStorage`](https://usehooks-ts.com/react-hook/use-session-storage) — uses the [sessionStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) to persist state across page reloads.\n- [`useStep`](https://usehooks-ts.com/react-hook/use-step) — manages and navigates between steps in a multi-step process.\n- [`useTernaryDarkMode`](https://usehooks-ts.com/react-hook/use-ternary-dark-mode) — manages ternary (system, dark, light) dark mode with local storage support.\n- [`useTimeout`](https://usehooks-ts.com/react-hook/use-timeout) — handles timeouts in React components using the [setTimeout API](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout).\n- [`useToggle`](https://usehooks-ts.com/react-hook/use-toggle) — manages a boolean toggle state in React components.\n- [`useUnmount`](https://usehooks-ts.com/react-hook/use-unmount) — runs a cleanup function when the component is unmounted.\n- [`useWindowSize`](https://usehooks-ts.com/react-hook/use-window-size) — tracks the size of the window.\n<!-- HOOKS:END -->\n\n## 💚 Backers\n\nBig thanks go to all our backers! [[Become a backer](https://github.com/sponsors/juliencrn)]\n\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/getsentry\"><img src=\"https://avatars.githubusercontent.com/u/1396951?v=4\" width=\"100px;\" alt=\"Sentry\"/><br /><sub><b>Sentry</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/KATT\"><img src=\"https://avatars.githubusercontent.com/u/459267?v=4\" width=\"100px;\" alt=\"KATT\"/><br /><sub><b>KATT</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/adhiravishankar\"><img src=\"https://avatars.githubusercontent.com/u/3884741?v=4\" width=\"100px;\" alt=\"Adhi Ravishankar\"/><br /><sub><b>Adhi Ravishankar</b></sub></a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/great-work-told-is\"><img src=\"https://avatars.githubusercontent.com/u/113922084?v=4\" width=\"100px;\" alt=\"great-work-told-is\"/><br /><sub><b>great-work-told-is</b></sub></a></td>\n    </tr>\n  </tbody>\n</table>\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n## ✨ Contributors\n\nBig thanks go to all our contributors! [[Become a contributor](https://github.com/juliencrn/usehooks-ts/blob/master/.github/CONTRIBUTING.md)]\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/juliencrn\"><img src=\"https://avatars.githubusercontent.com/u/14028029?v=4?s=64\" width=\"64px;\" alt=\"Julien\"/><br /><sub><b>Julien</b></sub></a><br /><a href=\"#content-juliencrn\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=juliencrn\" title=\"Code\">💻</a> <a href=\"#design-juliencrn\" title=\"Design\">🎨</a> <a href=\"#ideas-juliencrn\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a777med\"><img src=\"https://avatars.githubusercontent.com/u/15968280?v=4?s=64\" width=\"64px;\" alt=\"a777med\"/><br /><sub><b>a777med</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=a777med\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://datkira.com/\"><img src=\"https://avatars.githubusercontent.com/u/53250212?v=4?s=64\" width=\"64px;\" alt=\"Nguyen Tien Dat\"/><br /><sub><b>Nguyen Tien Dat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=datkira\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/elifer5000\"><img src=\"https://avatars.githubusercontent.com/u/4311278?v=4?s=64\" width=\"64px;\" alt=\"Elias Cohenca\"/><br /><sub><b>Elias Cohenca</b></sub></a><br /><a href=\"#content-elifer5000\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://joaov.com.br/\"><img src=\"https://avatars.githubusercontent.com/u/17601527?v=4?s=64\" width=\"64px;\" alt=\"João Deroldo\"/><br /><sub><b>João Deroldo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajoaoderoldo\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=joaoderoldo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nishit-Dua\"><img src=\"https://avatars.githubusercontent.com/u/35453301?v=4?s=64\" width=\"64px;\" alt=\"Nishit\"/><br /><sub><b>Nishit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Nishit-Dua\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonkoops\"><img src=\"https://avatars.githubusercontent.com/u/695720?v=4?s=64\" width=\"64px;\" alt=\"Jon Koops\"/><br /><sub><b>Jon Koops</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonkoops\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LoneRifle\"><img src=\"https://avatars.githubusercontent.com/u/10572368?v=4?s=64\" width=\"64px;\" alt=\"LoneRifle\"/><br /><sub><b>LoneRifle</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LoneRifle\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/vfonic\"><img src=\"https://avatars.githubusercontent.com/u/67437?v=4?s=64\" width=\"64px;\" alt=\"Viktor\"/><br /><sub><b>Viktor</b></sub></a><br /><a href=\"#ideas-vfonic\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avfonic\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bclermont\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Bruno Clermont\"/><br /><sub><b>Bruno Clermont</b></sub></a><br /><a href=\"#question-bclermont\" title=\"Answering Questions\">💬</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yoannesbourg\"><img src=\"https://avatars.githubusercontent.com/u/73404603?v=4?s=64\" width=\"64px;\" alt=\"yoannesbourg\"/><br /><sub><b>yoannesbourg</b></sub></a><br /><a href=\"#ideas-yoannesbourg\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/strange2x\"><img src=\"https://avatars.githubusercontent.com/u/10759731?v=4?s=64\" width=\"64px;\" alt=\"Strange2x\"/><br /><sub><b>Strange2x</b></sub></a><br /><a href=\"#ideas-strange2x\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/steinybot\"><img src=\"https://avatars.githubusercontent.com/u/4659562?v=4?s=64\" width=\"64px;\" alt=\"Jason Pickens\"/><br /><sub><b>Jason Pickens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asteinybot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://smackagency.com/\"><img src=\"https://avatars.githubusercontent.com/u/3469560?v=4?s=64\" width=\"64px;\" alt=\"Sel-Vin Kuik\"/><br /><sub><b>Sel-Vin Kuik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aselvinkuik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isaacalves\"><img src=\"https://avatars.githubusercontent.com/u/1765942?v=4?s=64\" width=\"64px;\" alt=\"isaac\"/><br /><sub><b>isaac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisaacalves\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/brunorzn\"><img src=\"https://avatars.githubusercontent.com/u/18266054?v=4?s=64\" width=\"64px;\" alt=\"Bruno RZN\"/><br /><sub><b>Bruno RZN</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brunorzn\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Abrunorzn\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.cykeprojects.com/\"><img src=\"https://avatars.githubusercontent.com/u/2979318?v=4?s=64\" width=\"64px;\" alt=\"Nathan Manceaux-Panot\"/><br /><sub><b>Nathan Manceaux-Panot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Cykelero\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ACykelero\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/meotimdihia\"><img src=\"https://avatars.githubusercontent.com/u/300961?v=4?s=64\" width=\"64px;\" alt=\"Dien Vu\"/><br /><sub><b>Dien Vu</b></sub></a><br /><a href=\"#ideas-meotimdihia\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/olegKusov\"><img src=\"https://avatars.githubusercontent.com/u/28058268?v=4?s=64\" width=\"64px;\" alt=\"Oleg Kusov\"/><br /><sub><b>Oleg Kusov</b></sub></a><br /><a href=\"#ideas-olegKusov\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://mattguy.me/\"><img src=\"https://avatars.githubusercontent.com/u/6647355?v=4?s=64\" width=\"64px;\" alt=\"Matthew Guy\"/><br /><sub><b>Matthew Guy</b></sub></a><br /><a href=\"#ideas-mankittens\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andrewbihl\"><img src=\"https://avatars.githubusercontent.com/u/16709744?v=4?s=64\" width=\"64px;\" alt=\"andrewbihl\"/><br /><sub><b>andrewbihl</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandrewbihl\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lancepollard\"><img src=\"https://avatars.githubusercontent.com/u/86631222?v=4?s=64\" width=\"64px;\" alt=\"lancepollard\"/><br /><sub><b>lancepollard</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancepollard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gmukul01\"><img src=\"https://avatars.githubusercontent.com/u/3636885?v=4?s=64\" width=\"64px;\" alt=\"Mukul Bansal\"/><br /><sub><b>Mukul Bansal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Agmukul01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://127.0.0.1:8000/\"><img src=\"https://avatars.githubusercontent.com/u/474302?v=4?s=64\" width=\"64px;\" alt=\"Jean-Luc Mongrain sur la Brosse\"/><br /><sub><b>Jean-Luc Mongrain sur la Brosse</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jeanlucmongrain\" title=\"Code\">💻</a> <a href=\"#ideas-jeanlucmongrain\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/n1c\"><img src=\"https://avatars.githubusercontent.com/u/284075?v=4?s=64\" width=\"64px;\" alt=\"Nic\"/><br /><sub><b>Nic</b></sub></a><br /><a href=\"#content-n1c\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://valtism.com/\"><img src=\"https://avatars.githubusercontent.com/u/1286001?v=4?s=64\" width=\"64px;\" alt=\"Dan Wood\"/><br /><sub><b>Dan Wood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valtism\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.sixt.de/\"><img src=\"https://avatars.githubusercontent.com/u/25299148?v=4?s=64\" width=\"64px;\" alt=\"jo wendenbuerger\"/><br /><sub><b>jo wendenbuerger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWendenburg\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://nozillium.com/\"><img src=\"https://avatars.githubusercontent.com/u/4774875?v=4?s=64\" width=\"64px;\" alt=\"Andrew Nosenko\"/><br /><sub><b>Andrew Nosenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anoseratio\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CharlieJhonSmith\"><img src=\"https://avatars.githubusercontent.com/u/90845154?v=4?s=64\" width=\"64px;\" alt=\"CharlieJhonSmith\"/><br /><sub><b>CharlieJhonSmith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CharlieJhonSmith\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://keybase.io/soullivaneuh\"><img src=\"https://avatars.githubusercontent.com/u/1698357?v=4?s=64\" width=\"64px;\" alt=\"Sullivan SENECHAL\"/><br /><sub><b>Sullivan SENECHAL</b></sub></a><br /><a href=\"#ideas-soullivaneuh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asoullivaneuh\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=soullivaneuh\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jaslong\"><img src=\"https://avatars.githubusercontent.com/u/797348?v=4?s=64\" width=\"64px;\" alt=\"Jason Long\"/><br /><sub><b>Jason Long</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajaslong\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kxm766\"><img src=\"https://avatars.githubusercontent.com/u/88443148?v=4?s=64\" width=\"64px;\" alt=\"kxm766\"/><br /><sub><b>kxm766</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akxm766\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://qlaffont.com/\"><img src=\"https://avatars.githubusercontent.com/u/10044790?v=4?s=64\" width=\"64px;\" alt=\"Quentin\"/><br /><sub><b>Quentin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=qlaffont\" title=\"Code\">💻</a> <a href=\"#ideas-qlaffont\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#content-qlaffont\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ducktordanny\"><img src=\"https://avatars.githubusercontent.com/u/38068717?v=4?s=64\" width=\"64px;\" alt=\"Daniel Lazar\"/><br /><sub><b>Daniel Lazar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ducktordanny\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aducktordanny\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mterrel\"><img src=\"https://avatars.githubusercontent.com/u/17746857?v=4?s=64\" width=\"64px;\" alt=\"Mark Terrel\"/><br /><sub><b>Mark Terrel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amterrel\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mterrel\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mendrik\"><img src=\"https://avatars.githubusercontent.com/u/160805?v=4?s=64\" width=\"64px;\" alt=\"Andreas Herd\"/><br /><sub><b>Andreas Herd</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amendrik\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sonjoydatta.me/\"><img src=\"https://avatars.githubusercontent.com/u/49079726?v=4?s=64\" width=\"64px;\" alt=\"Sonjoy Datta\"/><br /><sub><b>Sonjoy Datta</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sonjoydatta\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oluckyman\"><img src=\"https://avatars.githubusercontent.com/u/642673?v=4?s=64\" width=\"64px;\" alt=\"Ilya Belsky\"/><br /><sub><b>Ilya Belsky</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoluckyman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jamesbarrett.io/\"><img src=\"https://avatars.githubusercontent.com/u/42980207?v=4?s=64\" width=\"64px;\" alt=\"James Barrett\"/><br /><sub><b>James Barrett</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=JamesBarrettDev\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AbbalYouness\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"AbbalYouness\"/><br /><sub><b>AbbalYouness</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AbbalYouness\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/DidrikLind\"><img src=\"https://avatars.githubusercontent.com/u/14201715?v=4?s=64\" width=\"64px;\" alt=\"didriklind\"/><br /><sub><b>didriklind</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DidrikLind\" title=\"Tests\">⚠️</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hexp1989\"><img src=\"https://avatars.githubusercontent.com/u/2241985?v=4?s=64\" width=\"64px;\" alt=\"hexp1989\"/><br /><sub><b>hexp1989</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hexp1989\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/alvaro-serrano-rivas/\"><img src=\"https://avatars.githubusercontent.com/u/43758471?v=4?s=64\" width=\"64px;\" alt=\"Alvaro Serrano\"/><br /><sub><b>Alvaro Serrano</b></sub></a><br /><a href=\"#content-alvaroserrrano\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/egehandulger\"><img src=\"https://avatars.githubusercontent.com/u/14878259?v=4?s=64\" width=\"64px;\" alt=\"Egehan Dülger\"/><br /><sub><b>Egehan Dülger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=egehandulger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PabloLION\"><img src=\"https://avatars.githubusercontent.com/u/36828324?v=4?s=64\" width=\"64px;\" alt=\"PabloLION\"/><br /><sub><b>PabloLION</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APabloLION\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=PabloLION\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://davidsanchez.me/\"><img src=\"https://avatars.githubusercontent.com/u/84061?v=4?s=64\" width=\"64px;\" alt=\"David Sanchez\"/><br /><sub><b>David Sanchez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aemulienfou\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AjayTheWizard\"><img src=\"https://avatars.githubusercontent.com/u/92772740?v=4?s=64\" width=\"64px;\" alt=\"Ajay Raja\"/><br /><sub><b>Ajay Raja</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAjayTheWizard\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"#ideas-docmars\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/GrayGalaxy\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=GrayGalaxy\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGrayGalaxy\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tilnea\"><img src=\"https://avatars.githubusercontent.com/u/3692320?v=4?s=64\" width=\"64px;\" alt=\"Sanne Wintrén\"/><br /><sub><b>Sanne Wintrén</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atilnea\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://lacolonia.studio/\"><img src=\"https://avatars.githubusercontent.com/u/1528468?v=4?s=64\" width=\"64px;\" alt=\"Alessandro\"/><br /><sub><b>Alessandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aa-barbieri\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/atatarenko\"><img src=\"https://avatars.githubusercontent.com/u/9846273?v=4?s=64\" width=\"64px;\" alt=\"Andrey Tatarenko\"/><br /><sub><b>Andrey Tatarenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aatatarenko\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/arusak\"><img src=\"https://avatars.githubusercontent.com/u/4231915?v=4?s=64\" width=\"64px;\" alt=\"Anton Rusak\"/><br /><sub><b>Anton Rusak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aarusak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/createdbymahmood\"><img src=\"https://avatars.githubusercontent.com/u/40164360?v=4?s=64\" width=\"64px;\" alt=\"Mahmood Bagheri\"/><br /><sub><b>Mahmood Bagheri</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=createdbymahmood\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://wpowner.com/\"><img src=\"https://avatars.githubusercontent.com/u/506491?v=4?s=64\" width=\"64px;\" alt=\"Anver Sadutt\"/><br /><sub><b>Anver Sadutt</b></sub></a><br /><a href=\"#content-anver\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bogdanailincaipnt\"><img src=\"https://avatars.githubusercontent.com/u/93596663?v=4?s=64\" width=\"64px;\" alt=\"Bogdan Ailincai\"/><br /><sub><b>Bogdan Ailincai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bogdanailincaipnt\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SimeonGriggs\"><img src=\"https://avatars.githubusercontent.com/u/9684022?v=4?s=64\" width=\"64px;\" alt=\"Simeon Griggs\"/><br /><sub><b>Simeon Griggs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ASimeonGriggs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Kepro\"><img src=\"https://avatars.githubusercontent.com/u/1714370?v=4?s=64\" width=\"64px;\" alt=\"Kepro\"/><br /><sub><b>Kepro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AKepro\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Jake-Lippert\"><img src=\"https://avatars.githubusercontent.com/u/17753127?v=4?s=64\" width=\"64px;\" alt=\"Jake Lippert\"/><br /><sub><b>Jake Lippert</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJake-Lippert\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TunA-Kai\"><img src=\"https://avatars.githubusercontent.com/u/92641762?v=4?s=64\" width=\"64px;\" alt=\"Tu Nguyen Anh\"/><br /><sub><b>Tu Nguyen Anh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATunA-Kai\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TunA-Kai\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/skve\"><img src=\"https://avatars.githubusercontent.com/u/47612057?v=4?s=64\" width=\"64px;\" alt=\"Luke Shiels\"/><br /><sub><b>Luke Shiels</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Askve\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SleLLl\"><img src=\"https://avatars.githubusercontent.com/u/66108429?v=4?s=64\" width=\"64px;\" alt=\"Sergei Kolyago\"/><br /><sub><b>Sergei Kolyago</b></sub></a><br /><a href=\"#ideas-SleLLl\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/adhamaa\"><img src=\"https://avatars.githubusercontent.com/u/50027371?v=4?s=64\" width=\"64px;\" alt=\"Adham Akmal Azmi\"/><br /><sub><b>Adham Akmal Azmi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aadhamaa\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alex-kowalczyk\"><img src=\"https://avatars.githubusercontent.com/u/7422175?v=4?s=64\" width=\"64px;\" alt=\"Alek Kowalczyk\"/><br /><sub><b>Alek Kowalczyk</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aalex-kowalczyk\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Scalahansolo\"><img src=\"https://avatars.githubusercontent.com/u/4317253?v=4?s=64\" width=\"64px;\" alt=\"Sean Callahan\"/><br /><sub><b>Sean Callahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AScalahansolo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jbean96\"><img src=\"https://avatars.githubusercontent.com/u/22803097?v=4?s=64\" width=\"64px;\" alt=\"Joshua Bean\"/><br /><sub><b>Joshua Bean</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jbean96\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajbean96\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ZhaoTim\"><img src=\"https://avatars.githubusercontent.com/u/30540533?v=4?s=64\" width=\"64px;\" alt=\"Tim Zhao\"/><br /><sub><b>Tim Zhao</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AZhaoTim\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/patryk-smc\"><img src=\"https://avatars.githubusercontent.com/u/37963339?v=4?s=64\" width=\"64px;\" alt=\"Patrick\"/><br /><sub><b>Patrick</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatryk-smc\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://bryce.io/\"><img src=\"https://avatars.githubusercontent.com/u/3171252?v=4?s=64\" width=\"64px;\" alt=\"Bryce Dorn\"/><br /><sub><b>Bryce Dorn</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=brycedorn\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/angusd3v\"><img src=\"https://avatars.githubusercontent.com/u/52683145?v=4?s=64\" width=\"64px;\" alt=\"angusd3v\"/><br /><sub><b>angusd3v</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=angusd3v\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ddisimone\"><img src=\"https://avatars.githubusercontent.com/u/78792352?v=4?s=64\" width=\"64px;\" alt=\"Davide Di Simone\"/><br /><sub><b>Davide Di Simone</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Addisimone\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherr\"><img src=\"https://avatars.githubusercontent.com/u/22392?v=4?s=64\" width=\"64px;\" alt=\"Jack Herrington\"/><br /><sub><b>Jack Herrington</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherr\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://sharvit.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/1262502?v=4?s=64\" width=\"64px;\" alt=\"Avi Sharvit\"/><br /><sub><b>Avi Sharvit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sharvit\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asharvit\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmaties\"><img src=\"https://avatars.githubusercontent.com/u/16613184?v=4?s=64\" width=\"64px;\" alt=\"Nicolae Maties\"/><br /><sub><b>Nicolae Maties</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmaties\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/secretshardul\"><img src=\"https://avatars.githubusercontent.com/u/49580849?v=4?s=64\" width=\"64px;\" alt=\"Shardul Aeer\"/><br /><sub><b>Shardul Aeer</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asecretshardul\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/herlon214\"><img src=\"https://avatars.githubusercontent.com/u/3419441?v=4?s=64\" width=\"64px;\" alt=\"Herlon Aguiar\"/><br /><sub><b>Herlon Aguiar</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aherlon214\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/alexisoney\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"Alexis Oney\"/><br /><sub><b>Alexis Oney</b></sub></a><br /><a href=\"#content-alexisoney\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://convictional.com/\"><img src=\"https://avatars.githubusercontent.com/u/96080054?v=4?s=64\" width=\"64px;\" alt=\"curtvict\"/><br /><sub><b>curtvict</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=curtvict\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/JoshuaCS94\"><img src=\"https://avatars.githubusercontent.com/u/23385700?v=4?s=64\" width=\"64px;\" alt=\"Josué Cortina\"/><br /><sub><b>Josué Cortina</b></sub></a><br /><a href=\"#content-JoshuaCS94\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://katt.dev/\"><img src=\"https://avatars.githubusercontent.com/u/459267?v=4?s=64\" width=\"64px;\" alt=\"Alex / KATT\"/><br /><sub><b>Alex / KATT</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KATT\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/modex98\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=modex98\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amodex98\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Guesswhoitis\"><img src=\"https://avatars.githubusercontent.com/u/63756285?v=4?s=64\" width=\"64px;\" alt=\"James Hulena\"/><br /><sub><b>James Hulena</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AGuesswhoitis\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://hailwood.nz/\"><img src=\"https://avatars.githubusercontent.com/u/709773?v=4?s=64\" width=\"64px;\" alt=\"Matthew Hailwood\"/><br /><sub><b>Matthew Hailwood</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hailwood\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ahailwood\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mike247\"><img src=\"https://avatars.githubusercontent.com/u/676071?v=4?s=64\" width=\"64px;\" alt=\"Michael Norrie\"/><br /><sub><b>Michael Norrie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amike247\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valentinpolitov\"><img src=\"https://avatars.githubusercontent.com/u/39585375?v=4?s=64\" width=\"64px;\" alt=\"Valentin Politov\"/><br /><sub><b>Valentin Politov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valentinpolitov\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/marnusw\"><img src=\"https://avatars.githubusercontent.com/u/971499?v=4?s=64\" width=\"64px;\" alt=\"Marnus Weststrate\"/><br /><sub><b>Marnus Weststrate</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=marnusw\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/mancuoj\"><img src=\"https://avatars.githubusercontent.com/u/45707684?v=4?s=64\" width=\"64px;\" alt=\"mancuoj\"/><br /><sub><b>mancuoj</b></sub></a><br /><a href=\"#content-mancuoj\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.chatsumlin.com/\"><img src=\"https://avatars.githubusercontent.com/u/3067479?v=4?s=64\" width=\"64px;\" alt=\"Chat Sumlin\"/><br /><sub><b>Chat Sumlin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jcsumlin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/owenshaupt\"><img src=\"https://avatars.githubusercontent.com/u/52288188?v=4?s=64\" width=\"64px;\" alt=\"Owen Haupt\"/><br /><sub><b>Owen Haupt</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aowenshaupt\" title=\"Bug reports\">🐛</a> <a href=\"#content-owenshaupt\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ubarbaxor\"><img src=\"https://avatars.githubusercontent.com/u/26365493?v=4?s=64\" width=\"64px;\" alt=\"ubarbaxor\"/><br /><sub><b>ubarbaxor</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ubarbaxor\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://michael.mior.ca/\"><img src=\"https://avatars.githubusercontent.com/u/82501?v=4?s=64\" width=\"64px;\" alt=\"Michael Mior\"/><br /><sub><b>Michael Mior</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amichaelmior\" title=\"Bug reports\">🐛</a> <a href=\"#content-michaelmior\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pkhodaveissi\"><img src=\"https://avatars.githubusercontent.com/u/4170795?v=4?s=64\" width=\"64px;\" alt=\"Pierre\"/><br /><sub><b>Pierre</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=pkhodaveissi\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/harrywebdev\"><img src=\"https://avatars.githubusercontent.com/u/3617415?v=4?s=64\" width=\"64px;\" alt=\"Harry B\"/><br /><sub><b>Harry B</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharrywebdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/valyrie97\"><img src=\"https://avatars.githubusercontent.com/u/6365746?v=4?s=64\" width=\"64px;\" alt=\"Valerie\"/><br /><sub><b>Valerie</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Avalyrie97\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=valyrie97\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://svachon.com/\"><img src=\"https://avatars.githubusercontent.com/u/170197?v=4?s=64\" width=\"64px;\" alt=\"Steven Vachon\"/><br /><sub><b>Steven Vachon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=stevenvachon\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sskirby\"><img src=\"https://avatars.githubusercontent.com/u/25760?v=4?s=64\" width=\"64px;\" alt=\"Sean Kirby\"/><br /><sub><b>Sean Kirby</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Tests\">⚠️</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=sskirby\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AlecsFarias\"><img src=\"https://avatars.githubusercontent.com/u/91743821?v=4?s=64\" width=\"64px;\" alt=\"Alecsander Farias\"/><br /><sub><b>Alecsander Farias</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AlecsFarias\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://blankparticle.in/\"><img src=\"https://avatars.githubusercontent.com/u/130567419?v=4?s=64\" width=\"64px;\" alt=\"Rahul Mishra\"/><br /><sub><b>Rahul Mishra</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BlankParticle\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ABlankParticle\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"#content-BlankParticle\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bryantcodesart\"><img src=\"https://avatars.githubusercontent.com/u/14097078?v=4?s=64\" width=\"64px;\" alt=\"Bryant Smith\"/><br /><sub><b>Bryant Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=bryantcodesart\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abryantcodesart\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RobHannay\"><img src=\"https://avatars.githubusercontent.com/u/609062?v=4?s=64\" width=\"64px;\" alt=\"Rob Hannay\"/><br /><sub><b>Rob Hannay</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=RobHannay\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hooriza\"><img src=\"https://avatars.githubusercontent.com/u/507927?v=4?s=64\" width=\"64px;\" alt=\"Hooriza\"/><br /><sub><b>Hooriza</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=hooriza\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahooriza\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShanSenanayake\"><img src=\"https://avatars.githubusercontent.com/u/8779685?v=4?s=64\" width=\"64px;\" alt=\"ShanSenanayake\"/><br /><sub><b>ShanSenanayake</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ShanSenanayake\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/philipgher\"><img src=\"https://avatars.githubusercontent.com/u/32325241?v=4?s=64\" width=\"64px;\" alt=\"Philip Ghering\"/><br /><sub><b>Philip Ghering</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=philipgher\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ladislasdellinger\"><img src=\"https://avatars.githubusercontent.com/u/111739019?v=4?s=64\" width=\"64px;\" alt=\"Ladislas Dellinger\"/><br /><sub><b>Ladislas Dellinger</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ladislasdellinger\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TheHaff\"><img src=\"https://avatars.githubusercontent.com/u/2486653?v=4?s=64\" width=\"64px;\" alt=\"Haff\"/><br /><sub><b>Haff</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=TheHaff\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lisandro52\"><img src=\"https://avatars.githubusercontent.com/u/5612241?v=4?s=64\" width=\"64px;\" alt=\"Lisandro\"/><br /><sub><b>Lisandro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lisandro52\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/amirking59\"><img src=\"https://avatars.githubusercontent.com/u/58273240?v=4?s=64\" width=\"64px;\" alt=\"Amir hossein rezaei\"/><br /><sub><b>Amir hossein rezaei</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=amirking59\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nmacianx\"><img src=\"https://avatars.githubusercontent.com/u/40004186?v=4?s=64\" width=\"64px;\" alt=\"Nicolas Macian\"/><br /><sub><b>Nicolas Macian</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anmacianx\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nmacianx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://dreamsof.dev/\"><img src=\"https://avatars.githubusercontent.com/u/13162026?v=4?s=64\" width=\"64px;\" alt=\"Nate Forsyth\"/><br /><sub><b>Nate Forsyth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=nateforsyth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/satelllte\"><img src=\"https://avatars.githubusercontent.com/u/20585619?v=4?s=64\" width=\"64px;\" alt=\"satelllte\"/><br /><sub><b>satelllte</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=satelllte\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asatelllte\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fedemp\"><img src=\"https://avatars.githubusercontent.com/u/735314?v=4?s=64\" width=\"64px;\" alt=\"Federico Panico\"/><br /><sub><b>Federico Panico</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=fedemp\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iamwillnbcu\"><img src=\"https://avatars.githubusercontent.com/u/137317773?v=4?s=64\" width=\"64px;\" alt=\"William Pei Yuan\"/><br /><sub><b>William Pei Yuan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iamwillnbcu\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.gazeta-cu-anunturi.ro/\"><img src=\"https://avatars.githubusercontent.com/u/757999?v=4?s=64\" width=\"64px;\" alt=\"Mihai\"/><br /><sub><b>Mihai</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=DarkAng3L\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADarkAng3L\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://habib.ogunsola.me/\"><img src=\"https://avatars.githubusercontent.com/u/39172573?v=4?s=64\" width=\"64px;\" alt=\"Habib Ogunsola\"/><br /><sub><b>Habib Ogunsola</b></sub></a><br /><a href=\"#content-ogunsolahabib\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ashfurrow.com/\"><img src=\"https://avatars.githubusercontent.com/u/498212?v=4?s=64\" width=\"64px;\" alt=\"Ash Furrow\"/><br /><sub><b>Ash Furrow</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ashfurrow\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://turus.ro/\"><img src=\"https://avatars.githubusercontent.com/u/32390499?v=4?s=64\" width=\"64px;\" alt=\"Daniel Turuș\"/><br /><sub><b>Daniel Turuș</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danielturus\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/rahulchaudhary2244/\"><img src=\"https://avatars.githubusercontent.com/u/54467972?v=4?s=64\" width=\"64px;\" alt=\"Rahul Chaudhary\"/><br /><sub><b>Rahul Chaudhary</b></sub></a><br /><a href=\"#content-rahulchaudhary2244\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arahulchaudhary2244\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Joshyahweh\"><img src=\"https://avatars.githubusercontent.com/u/61137067?v=4?s=64\" width=\"64px;\" alt=\"Joshua Ojoawo\"/><br /><sub><b>Joshua Ojoawo</b></sub></a><br /><a href=\"#ideas-Joshyahweh\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJoshyahweh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jackdh.com/\"><img src=\"https://avatars.githubusercontent.com/u/1907451?v=4?s=64\" width=\"64px;\" alt=\"Jack\"/><br /><sub><b>Jack</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jackdh\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jonlinkens\"><img src=\"https://avatars.githubusercontent.com/u/20417521?v=4?s=64\" width=\"64px;\" alt=\"Jon Linkens\"/><br /><sub><b>Jon Linkens</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jonlinkens\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajonlinkens\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://velog.io/@ojj1123\"><img src=\"https://avatars.githubusercontent.com/u/33178048?v=4?s=64\" width=\"64px;\" alt=\"Jeongjin Oh\"/><br /><sub><b>Jeongjin Oh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aojj1123\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tli26\"><img src=\"https://avatars.githubusercontent.com/u/114947190?v=4?s=64\" width=\"64px;\" alt=\"Tianning Li\"/><br /><sub><b>Tianning Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=tli26\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://larsartmann.com/\"><img src=\"https://avatars.githubusercontent.com/u/23587853?v=4?s=64\" width=\"64px;\" alt=\"Lars Artmann\"/><br /><sub><b>Lars Artmann</b></sub></a><br /><a href=\"#content-LarsArtmann\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/KBobovskiy\"><img src=\"https://avatars.githubusercontent.com/u/35502578?v=4?s=64\" width=\"64px;\" alt=\"KBobovskiy\"/><br /><sub><b>KBobovskiy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=KBobovskiy\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ryngonzalez\"><img src=\"https://avatars.githubusercontent.com/u/635300?v=4?s=64\" width=\"64px;\" alt=\"✨ Kathryn Gonzalez ✨\"/><br /><sub><b>✨ Kathryn Gonzalez ✨</b></sub></a><br /><a href=\"#content-ryngonzalez\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/slavik-chapelskyi\"><img src=\"https://avatars.githubusercontent.com/u/33541009?v=4?s=64\" width=\"64px;\" alt=\"Yaroslav Chapelskyi\"/><br /><sub><b>Yaroslav Chapelskyi</b></sub></a><br /><a href=\"#content-slavik-chapelskyi\" title=\"Content\">🖋</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sverps\"><img src=\"https://avatars.githubusercontent.com/u/15879327?v=4?s=64\" width=\"64px;\" alt=\"Samuel Van Erps\"/><br /><sub><b>Samuel Van Erps</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Asverps\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ojolowoblue\"><img src=\"https://avatars.githubusercontent.com/u/104099474?v=4?s=64\" width=\"64px;\" alt=\"ojolowoblue\"/><br /><sub><b>ojolowoblue</b></sub></a><br /><a href=\"#content-ojolowoblue\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://short.io/\"><img src=\"https://avatars.githubusercontent.com/u/75169?v=4?s=64\" width=\"64px;\" alt=\"Andrii Kostenko\"/><br /><sub><b>Andrii Kostenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gugu\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/AkeemAllen\"><img src=\"https://avatars.githubusercontent.com/u/32404761?v=4?s=64\" width=\"64px;\" alt=\"Akeem Allen\"/><br /><sub><b>Akeem Allen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=AkeemAllen\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAkeemAllen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/trongbinh15\"><img src=\"https://avatars.githubusercontent.com/u/43725147?v=4?s=64\" width=\"64px;\" alt=\"trongbinhnguyen\"/><br /><sub><b>trongbinhnguyen</b></sub></a><br /><a href=\"#content-trongbinh15\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://lawlesx.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/52166437?v=4?s=64\" width=\"64px;\" alt=\"Aniruddha Sil\"/><br /><sub><b>Aniruddha Sil</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lawlesx\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/okinawaa\"><img src=\"https://avatars.githubusercontent.com/u/69495129?v=4?s=64\" width=\"64px;\" alt=\"박찬혁\"/><br /><sub><b>박찬혁</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Aokinawaa\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://anishchhetri.com.np/\"><img src=\"https://avatars.githubusercontent.com/u/98446102?v=4?s=64\" width=\"64px;\" alt=\"Anish\"/><br /><sub><b>Anish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novanish\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://hutri.fi/\"><img src=\"https://avatars.githubusercontent.com/u/55588133?v=4?s=64\" width=\"64px;\" alt=\"Hugo Hutri\"/><br /><sub><b>Hugo Hutri</b></sub></a><br /><a href=\"#content-hugohutri\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://balzguenat.ch/\"><img src=\"https://avatars.githubusercontent.com/u/6719014?v=4?s=64\" width=\"64px;\" alt=\"Balz Guenat\"/><br /><sub><b>Balz Guenat</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=BalzGuenat\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ottergeorge\"><img src=\"https://avatars.githubusercontent.com/u/108759685?v=4?s=64\" width=\"64px;\" alt=\"OtterGeorge\"/><br /><sub><b>OtterGeorge</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ottergeorge\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/samay-rgb\"><img src=\"https://avatars.githubusercontent.com/u/73112080?v=4?s=64\" width=\"64px;\" alt=\"Samay Sagar\"/><br /><sub><b>Samay Sagar</b></sub></a><br /><a href=\"#content-samay-rgb\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pedrobslisboa\"><img src=\"https://avatars.githubusercontent.com/u/35539594?v=4?s=64\" width=\"64px;\" alt=\"Pedro Lisboa\"/><br /><sub><b>Pedro Lisboa</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apedrobslisboa\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/henriqemalheiros\"><img src=\"https://avatars.githubusercontent.com/u/23730762?v=4?s=64\" width=\"64px;\" alt=\"Henrique Malheiros\"/><br /><sub><b>Henrique Malheiros</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahenriqemalheiros\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.unfocus.com/\"><img src=\"https://avatars.githubusercontent.com/u/245825?v=4?s=64\" width=\"64px;\" alt=\"Kevin Newman\"/><br /><sub><b>Kevin Newman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=CaptainN\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/a503189\"><img src=\"https://avatars.githubusercontent.com/u/28802989?v=4?s=64\" width=\"64px;\" alt=\"a503189\"/><br /><sub><b>a503189</b></sub></a><br /><a href=\"#content-a503189\" title=\"Content\">🖋</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://t.me/mouradelcadi\"><img src=\"https://avatars.githubusercontent.com/u/72814784?v=4?s=64\" width=\"64px;\" alt=\"Mourad EL CADI\"/><br /><sub><b>Mourad EL CADI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=mod7ex\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Lop3sPedro\"><img src=\"https://avatars.githubusercontent.com/u/89090945?v=4?s=64\" width=\"64px;\" alt=\"Pedro Henrique Lopes\"/><br /><sub><b>Pedro Henrique Lopes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Lop3sPedro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/danbiilee\"><img src=\"https://avatars.githubusercontent.com/u/53761241?v=4?s=64\" width=\"64px;\" alt=\"Danbi Lee\"/><br /><sub><b>Danbi Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=danbiilee\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/cojennin\"><img src=\"https://avatars.githubusercontent.com/u/1888152?v=4?s=64\" width=\"64px;\" alt=\"Connor Jennings\"/><br /><sub><b>Connor Jennings</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=cojennin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lgxm3z\"><img src=\"https://avatars.githubusercontent.com/u/28831375?v=4?s=64\" width=\"64px;\" alt=\"Lucas Gomes\"/><br /><sub><b>Lucas Gomes</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Algxm3z\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=lgxm3z\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zaggino\"><img src=\"https://avatars.githubusercontent.com/u/1067319?v=4?s=64\" width=\"64px;\" alt=\"Martin Zagora\"/><br /><sub><b>Martin Zagora</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=zaggino\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kvdo2\"><img src=\"https://avatars.githubusercontent.com/u/78251524?v=4?s=64\" width=\"64px;\" alt=\"KvD\"/><br /><sub><b>KvD</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kvdo2\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/SupraSmooth\"><img src=\"https://avatars.githubusercontent.com/u/18029247?v=4?s=64\" width=\"64px;\" alt=\"Alex\"/><br /><sub><b>Alex</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=SupraSmooth\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kaceycleveland\"><img src=\"https://avatars.githubusercontent.com/u/88064187?v=4?s=64\" width=\"64px;\" alt=\"Kacey Cleveland\"/><br /><sub><b>Kacey Cleveland</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Akaceycleveland\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/oviirup\"><img src=\"https://avatars.githubusercontent.com/u/49820575?v=4?s=64\" width=\"64px;\" alt=\"Avirup Ghosh\"/><br /><sub><b>Avirup Ghosh</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aoviirup\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yabbal\"><img src=\"https://avatars.githubusercontent.com/u/15120524?v=4?s=64\" width=\"64px;\" alt=\"yabbal\"/><br /><sub><b>yabbal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=yabbal\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://patik.com/\"><img src=\"https://avatars.githubusercontent.com/u/262137?v=4?s=64\" width=\"64px;\" alt=\"Craig Patik\"/><br /><sub><b>Craig Patik</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apatik\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Silverium\"><img src=\"https://avatars.githubusercontent.com/u/10578392?v=4?s=64\" width=\"64px;\" alt=\"Soldeplata Saketos Candela\"/><br /><sub><b>Soldeplata Saketos Candela</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Silverium\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TENDOUZHI\"><img src=\"https://avatars.githubusercontent.com/u/82806526?v=4?s=64\" width=\"64px;\" alt=\"TENDOUZHI\"/><br /><sub><b>TENDOUZHI</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATENDOUZHI\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/wachulski\"><img src=\"https://avatars.githubusercontent.com/u/1669844?v=4?s=64\" width=\"64px;\" alt=\"Marcin Wachulski\"/><br /><sub><b>Marcin Wachulski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awachulski\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://salmans.work/\"><img src=\"https://avatars.githubusercontent.com/u/15085416?v=4?s=64\" width=\"64px;\" alt=\"Salman Fazal\"/><br /><sub><b>Salman Fazal</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asalmanfazal01\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shrugs\"><img src=\"https://avatars.githubusercontent.com/u/1535001?v=4?s=64\" width=\"64px;\" alt=\"shrugs\"/><br /><sub><b>shrugs</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashrugs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Hyodori04\"><img src=\"https://avatars.githubusercontent.com/u/57362573?v=4?s=64\" width=\"64px;\" alt=\"hyodori\"/><br /><sub><b>hyodori</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AHyodori04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/eleazareramos\"><img src=\"https://avatars.githubusercontent.com/u/25910203?v=4?s=64\" width=\"64px;\" alt=\"Eleazar “E” Ramos\"/><br /><sub><b>Eleazar “E” Ramos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aeleazareramos\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/retnag\"><img src=\"https://avatars.githubusercontent.com/u/18302198?v=4?s=64\" width=\"64px;\" alt=\"retnag\"/><br /><sub><b>retnag</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aretnag\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://jaeyoung.dev/\"><img src=\"https://avatars.githubusercontent.com/u/55247450?v=4?s=64\" width=\"64px;\" alt=\"J young Lee\"/><br /><sub><b>J young Lee</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abeefiker\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fiws\"><img src=\"https://avatars.githubusercontent.com/u/3409958?v=4?s=64\" width=\"64px;\" alt=\"Filip Weiss\"/><br /><sub><b>Filip Weiss</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afiws\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://mariusgundersen.net/\"><img src=\"https://avatars.githubusercontent.com/u/464152?v=4?s=64\" width=\"64px;\" alt=\"Marius Gundersen\"/><br /><sub><b>Marius Gundersen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AmariusGundersen\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/VenomFate-619\"><img src=\"https://avatars.githubusercontent.com/u/67755128?v=4?s=64\" width=\"64px;\" alt=\"Syed Aman Ali\"/><br /><sub><b>Syed Aman Ali</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AVenomFate-619\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://ingadi.work/\"><img src=\"https://avatars.githubusercontent.com/u/6121225?v=4?s=64\" width=\"64px;\" alt=\"Axel Ingadi\"/><br /><sub><b>Axel Ingadi</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aingadi\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/andyjphu\"><img src=\"https://avatars.githubusercontent.com/u/51890861?v=4?s=64\" width=\"64px;\" alt=\"AndyP\"/><br /><sub><b>AndyP</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandyjphu\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ishanVaghasiya\"><img src=\"https://avatars.githubusercontent.com/u/98661936?v=4?s=64\" width=\"64px;\" alt=\"ishanVaghasiya\"/><br /><sub><b>ishanVaghasiya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AishanVaghasiya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nico-martinucci\"><img src=\"https://avatars.githubusercontent.com/u/80868741?v=4?s=64\" width=\"64px;\" alt=\"Nico Martinucci\"/><br /><sub><b>Nico Martinucci</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anico-martinucci\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/technophile-04\"><img src=\"https://avatars.githubusercontent.com/u/80153681?v=4?s=64\" width=\"64px;\" alt=\"Shiv Bhonde &#124; shivbhonde.eth\"/><br /><sub><b>Shiv Bhonde &#124; shivbhonde.eth</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atechnophile-04\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fritzmonkey\"><img src=\"https://avatars.githubusercontent.com/u/10103840?v=4?s=64\" width=\"64px;\" alt=\"fritzmonkey\"/><br /><sub><b>fritzmonkey</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afritzmonkey\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/rrmesquita\"><img src=\"https://avatars.githubusercontent.com/u/30835404?v=4?s=64\" width=\"64px;\" alt=\"Rodrigo Mesquita\"/><br /><sub><b>Rodrigo Mesquita</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Arrmesquita\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://moshe.io/\"><img src=\"https://avatars.githubusercontent.com/u/534911?v=4?s=64\" width=\"64px;\" alt=\"Moshe Simantov\"/><br /><sub><b>Moshe Simantov</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amoshest\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/BekaArabidze98\"><img src=\"https://avatars.githubusercontent.com/u/122085038?v=4?s=64\" width=\"64px;\" alt=\"Beka\"/><br /><sub><b>Beka</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ABekaArabidze98\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/abdofola\"><img src=\"https://avatars.githubusercontent.com/u/30251052?v=4?s=64\" width=\"64px;\" alt=\"Abdallah Alkaser\"/><br /><sub><b>Abdallah Alkaser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aabdofola\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=abdofola\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/CarlosNZ\"><img src=\"https://avatars.githubusercontent.com/u/5456533?v=4?s=64\" width=\"64px;\" alt=\"Carl Smith\"/><br /><sub><b>Carl Smith</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACarlosNZ\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ogroppo\"><img src=\"https://avatars.githubusercontent.com/u/4820803?v=4?s=64\" width=\"64px;\" alt=\"Orlando Groppo\"/><br /><sub><b>Orlando Groppo</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aogroppo\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/thany\"><img src=\"https://avatars.githubusercontent.com/u/152227?v=4?s=64\" width=\"64px;\" alt=\"Martĳn Saly\"/><br /><sub><b>Martĳn Saly</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Athany\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://quinn.io/\"><img src=\"https://avatars.githubusercontent.com/u/3764?v=4?s=64\" width=\"64px;\" alt=\"Quinn Shanahan\"/><br /><sub><b>Quinn Shanahan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aquinn\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://antoinek.fr/\"><img src=\"https://avatars.githubusercontent.com/u/54948363?v=4?s=64\" width=\"64px;\" alt=\"Antoine Kingue\"/><br /><sub><b>Antoine Kingue</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AAntoineKM\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/zanzlender\"><img src=\"https://avatars.githubusercontent.com/u/44570474?v=4?s=64\" width=\"64px;\" alt=\"Žan Žlender\"/><br /><sub><b>Žan Žlender</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Azanzlender\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebadom\"><img src=\"https://avatars.githubusercontent.com/u/3877952?v=4?s=64\" width=\"64px;\" alt=\"Sebastian Dominguez\"/><br /><sub><b>Sebastian Dominguez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebadom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jmc420\"><img src=\"https://avatars.githubusercontent.com/u/11723529?v=4?s=64\" width=\"64px;\" alt=\"James Cowan\"/><br /><sub><b>James Cowan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajmc420\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bayraak\"><img src=\"https://avatars.githubusercontent.com/u/10470072?v=4?s=64\" width=\"64px;\" alt=\"Bayram Ali Basgul\"/><br /><sub><b>Bayram Ali Basgul</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Abayraak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://wyatt.castaneda.family/\"><img src=\"https://avatars.githubusercontent.com/u/17957937?v=4?s=64\" width=\"64px;\" alt=\"Wyatt Castaneda\"/><br /><sub><b>Wyatt Castaneda</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AWyattCast44\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tsnevillecom\"><img src=\"https://avatars.githubusercontent.com/u/3151454?v=4?s=64\" width=\"64px;\" alt=\"Tim Neville\"/><br /><sub><b>Tim Neville</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atsnevillecom\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/shoooe\"><img src=\"https://avatars.githubusercontent.com/u/733227?v=4?s=64\" width=\"64px;\" alt=\"Thomas Pigarelli\"/><br /><sub><b>Thomas Pigarelli</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ashoooe\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jherdman\"><img src=\"https://avatars.githubusercontent.com/u/3300?v=4?s=64\" width=\"64px;\" alt=\"James Herdman\"/><br /><sub><b>James Herdman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajherdman\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pociej\"><img src=\"https://avatars.githubusercontent.com/u/3854675?v=4?s=64\" width=\"64px;\" alt=\"Grzegorz Pociejewski\"/><br /><sub><b>Grzegorz Pociejewski</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Apociej\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/flyon\"><img src=\"https://avatars.githubusercontent.com/u/341567?v=4?s=64\" width=\"64px;\" alt=\"René Verheij\"/><br /><sub><b>René Verheij</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aflyon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/PatrykKuniczak\"><img src=\"https://avatars.githubusercontent.com/u/64608510?v=4?s=64\" width=\"64px;\" alt=\"PatrykKuniczak\"/><br /><sub><b>PatrykKuniczak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3APatrykKuniczak\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://cromodder.github.io/\"><img src=\"https://avatars.githubusercontent.com/u/7691110?v=4?s=64\" width=\"64px;\" alt=\"Paolo Božac\"/><br /><sub><b>Paolo Božac</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ACroModder\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/reinos\"><img src=\"https://avatars.githubusercontent.com/u/633730?v=4?s=64\" width=\"64px;\" alt=\"Rein\"/><br /><sub><b>Rein</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Areinos\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FloorianB\"><img src=\"https://avatars.githubusercontent.com/u/110407858?v=4?s=64\" width=\"64px;\" alt=\"FloorianB\"/><br /><sub><b>FloorianB</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFloorianB\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xuanhung1509\"><img src=\"https://avatars.githubusercontent.com/u/89293664?v=4?s=64\" width=\"64px;\" alt=\"Xuan Hung\"/><br /><sub><b>Xuan Hung</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axuanhung1509\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://monawwar.io/\"><img src=\"https://avatars.githubusercontent.com/u/31907722?v=4?s=64\" width=\"64px;\" alt=\"Monawwar Abdullah\"/><br /><sub><b>Monawwar Abdullah</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Amxvsh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/haroldo-ok\"><img src=\"https://avatars.githubusercontent.com/u/1457465?v=4?s=64\" width=\"64px;\" alt=\"Haroldo de Oliveira Pinheiro\"/><br /><sub><b>Haroldo de Oliveira Pinheiro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aharoldo-ok\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://portfoliobytamjid.vercel.app/\"><img src=\"https://avatars.githubusercontent.com/u/57794102?v=4?s=64\" width=\"64px;\" alt=\"Tamjid Ahmed\"/><br /><sub><b>Tamjid Ahmed</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATamjidAhmed10\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jv-lopez\"><img src=\"https://avatars.githubusercontent.com/u/93750956?v=4?s=64\" width=\"64px;\" alt=\"jv-lopez\"/><br /><sub><b>jv-lopez</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajv-lopez\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://macr.ae/\"><img src=\"https://avatars.githubusercontent.com/u/472830?v=4?s=64\" width=\"64px;\" alt=\"Callum Macrae\"/><br /><sub><b>Callum Macrae</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Acallumacrae\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/0529bill\"><img src=\"https://avatars.githubusercontent.com/u/62455148?v=4?s=64\" width=\"64px;\" alt=\"bywater529\"/><br /><sub><b>bywater529</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3A0529bill\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kevinxh\"><img src=\"https://avatars.githubusercontent.com/u/10948652?v=4?s=64\" width=\"64px;\" alt=\"Kevin He\"/><br /><sub><b>Kevin He</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akevinxh\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/FredericoGauz\"><img src=\"https://avatars.githubusercontent.com/u/18327882?v=4?s=64\" width=\"64px;\" alt=\"FredericoGauz\"/><br /><sub><b>FredericoGauz</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AFredericoGauz\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.jonlemofficial.com/\"><img src=\"https://avatars.githubusercontent.com/u/38771842?v=4?s=64\" width=\"64px;\" alt=\"Jonathan &quot;JonLem&quot; Lemos\"/><br /><sub><b>Jonathan &quot;JonLem&quot; Lemos</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJonLemOfficial\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/xegulon\"><img src=\"https://avatars.githubusercontent.com/u/74178038?v=4?s=64\" width=\"64px;\" alt=\"Xegulon\"/><br /><sub><b>Xegulon</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Axegulon\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/TomSmedley\"><img src=\"https://avatars.githubusercontent.com/u/95056193?v=4?s=64\" width=\"64px;\" alt=\"Tom Smedley\"/><br /><sub><b>Tom Smedley</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ATomSmedley\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lightbluepoppy\"><img src=\"https://avatars.githubusercontent.com/u/65863981?v=4?s=64\" width=\"64px;\" alt=\"lightbluepoppy\"/><br /><sub><b>lightbluepoppy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alightbluepoppy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Dchole\"><img src=\"https://avatars.githubusercontent.com/u/47068381?v=4?s=64\" width=\"64px;\" alt=\"Derek Oware\"/><br /><sub><b>Derek Oware</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ADchole\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://fragmentedthought.com/\"><img src=\"https://avatars.githubusercontent.com/u/12085479?v=4?s=64\" width=\"64px;\" alt=\"Lance Gliser\"/><br /><sub><b>Lance Gliser</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alancegliser\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/lewxdev\"><img src=\"https://avatars.githubusercontent.com/u/6710419?v=4?s=64\" width=\"64px;\" alt=\"J. Lewis\"/><br /><sub><b>J. Lewis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Alewxdev\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/yairy\"><img src=\"https://avatars.githubusercontent.com/u/3206243?v=4?s=64\" width=\"64px;\" alt=\"Yair\"/><br /><sub><b>Yair</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ayairy\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://firecamp.dev/\"><img src=\"https://avatars.githubusercontent.com/u/5078921?v=4?s=64\" width=\"64px;\" alt=\"Nishchit\"/><br /><sub><b>Nishchit</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANishchit14\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Nejjer\"><img src=\"https://avatars.githubusercontent.com/u/80219537?v=4?s=64\" width=\"64px;\" alt=\"Devofy\"/><br /><sub><b>Devofy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3ANejjer\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://joshguyette.com/\"><img src=\"https://avatars.githubusercontent.com/u/28668902?v=4?s=64\" width=\"64px;\" alt=\"Josh Guyette\"/><br /><sub><b>Josh Guyette</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anightness\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dora-ljh\"><img src=\"https://avatars.githubusercontent.com/u/35205701?v=4?s=64\" width=\"64px;\" alt=\"Dora Li\"/><br /><sub><b>Dora Li</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Adora-ljh\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kg-currenxie\"><img src=\"https://avatars.githubusercontent.com/u/48229166?v=4?s=64\" width=\"64px;\" alt=\"Kristian Gerardsson\"/><br /><sub><b>Kristian Gerardsson</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akg-currenxie\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/jdpt0\"><img src=\"https://avatars.githubusercontent.com/u/19761394?v=4?s=64\" width=\"64px;\" alt=\"James Powell\"/><br /><sub><b>James Powell</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajdpt0\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://www.linkedin.com/in/boaz-poolman-662162115/\"><img src=\"https://avatars.githubusercontent.com/u/9551934?v=4?s=64\" width=\"64px;\" alt=\"Boaz Poolman\"/><br /><sub><b>Boaz Poolman</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aboazpoolman\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/roker15\"><img src=\"https://avatars.githubusercontent.com/u/59526869?v=4?s=64\" width=\"64px;\" alt=\"roker15\"/><br /><sub><b>roker15</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aroker15\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/fadhilx\"><img src=\"https://avatars.githubusercontent.com/u/15516786?v=4?s=64\" width=\"64px;\" alt=\"Fadhil Ahmad\"/><br /><sub><b>Fadhil Ahmad</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Afadhilx\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Chandler-Zhu\"><img src=\"https://avatars.githubusercontent.com/u/61914365?v=4?s=64\" width=\"64px;\" alt=\"Chandler-Zhu\"/><br /><sub><b>Chandler-Zhu</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AChandler-Zhu\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/nixjs\"><img src=\"https://avatars.githubusercontent.com/u/23132483?v=4?s=64\" width=\"64px;\" alt=\"Nghi Nguyen\"/><br /><sub><b>Nghi Nguyen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anixjs\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ShravanSunder\"><img src=\"https://avatars.githubusercontent.com/u/5294949?v=4?s=64\" width=\"64px;\" alt=\"Shravan Sunder\"/><br /><sub><b>Shravan Sunder</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AShravanSunder\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Johannes5\"><img src=\"https://avatars.githubusercontent.com/u/14299835?v=4?s=64\" width=\"64px;\" alt=\"Johannes5\"/><br /><sub><b>Johannes5</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AJohannes5\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sebahhpeya\"><img src=\"https://avatars.githubusercontent.com/u/93996817?v=4?s=64\" width=\"64px;\" alt=\"sebahhpeya\"/><br /><sub><b>sebahhpeya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Asebahhpeya\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://onezero.co.il/\"><img src=\"https://avatars.githubusercontent.com/u/45389557?v=4?s=64\" width=\"64px;\" alt=\"Or Nakash\"/><br /><sub><b>Or Nakash</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aornakash\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hepiyellow\"><img src=\"https://avatars.githubusercontent.com/u/6338722?v=4?s=64\" width=\"64px;\" alt=\"Erez Makavy\"/><br /><sub><b>Erez Makavy</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ahepiyellow\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://andymerskin.com/\"><img src=\"https://avatars.githubusercontent.com/u/758090?v=4?s=64\" width=\"64px;\" alt=\"Andy Merskin\"/><br /><sub><b>Andy Merskin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aandymerskin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/chainalert-bot\"><img src=\"https://avatars.githubusercontent.com/u/95303823?v=4?s=64\" width=\"64px;\" alt=\"ChainAlert Bot\"/><br /><sub><b>ChainAlert Bot</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Achainalert-bot\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/tmdesigned\"><img src=\"https://avatars.githubusercontent.com/u/3608018?v=4?s=64\" width=\"64px;\" alt=\"Taylor Morgan\"/><br /><sub><b>Taylor Morgan</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Atmdesigned\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://abkabioye.me/\"><img src=\"https://avatars.githubusercontent.com/u/18709032?v=4?s=64\" width=\"64px;\" alt=\"wisdomabioye\"/><br /><sub><b>wisdomabioye</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Awisdomabioye\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.samtheq.com\"><img src=\"https://avatars.githubusercontent.com/u/51345689?v=4?s=64\" width=\"64px;\" alt=\"Samuel Quiñones\"/><br /><sub><b>Samuel Quiñones</b></sub></a><br /><a href=\"#ideas-SamuelQuinones\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ymc-maha\"><img src=\"https://avatars.githubusercontent.com/u/697307?v=4?s=64\" width=\"64px;\" alt=\"Manuel\"/><br /><sub><b>Manuel</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=ymc-maha\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aymc-maha\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Yurchishin\"><img src=\"https://avatars.githubusercontent.com/u/36650915?v=4?s=64\" width=\"64px;\" alt=\"Yurii Rybak\"/><br /><sub><b>Yurii Rybak</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3AYurchishin\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/iuriiiurevich\"><img src=\"https://avatars.githubusercontent.com/u/15759600?v=4?s=64\" width=\"64px;\" alt=\"Yury Demin\"/><br /><sub><b>Yury Demin</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aiuriiiurevich\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=iuriiiurevich\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://tewks.io/\"><img src=\"https://avatars.githubusercontent.com/u/3970573?v=4?s=64\" width=\"64px;\" alt=\"Jon Tewksbury\"/><br /><sub><b>Jon Tewksbury</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=jontewks\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajontewks\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/novacdenis\"><img src=\"https://avatars.githubusercontent.com/u/45555668?v=4?s=64\" width=\"64px;\" alt=\"Novac Denis\"/><br /><sub><b>Novac Denis</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=novacdenis\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Anovacdenis\" title=\"Bug reports\">🐛</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kyrylo-soulandwolf\"><img src=\"https://avatars.githubusercontent.com/u/54762253?v=4?s=64\" width=\"64px;\" alt=\"kyrylo-soulandwolf\"/><br /><sub><b>kyrylo-soulandwolf</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=kyrylo-soulandwolf\" title=\"Code\">💻</a> <a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Akyrylo-soulandwolf\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/misidoro\"><img src=\"https://avatars.githubusercontent.com/u/3635023?v=4?s=64\" width=\"64px;\" alt=\"Miguel Isidoro\"/><br /><sub><b>Miguel Isidoro</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=misidoro\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://crowds.space/\"><img src=\"https://avatars.githubusercontent.com/u/828918?v=4?s=64\" width=\"64px;\" alt=\"Yuriy Gromchenko\"/><br /><sub><b>Yuriy Gromchenko</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=gromchen\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://jcbhmr.me\"><img src=\"https://avatars.githubusercontent.com/u/61068799?v=4?s=64\" width=\"64px;\" alt=\"Jacob Hummer\"/><br /><sub><b>Jacob Hummer</b></sub></a><br /><a href=\"#ideas-jcbhmr\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/k-melnychuk\"><img src=\"https://avatars.githubusercontent.com/u/22131019?v=4?s=64\" width=\"64px;\" alt=\"Kyrylo Melnychuk\"/><br /><sub><b>Kyrylo Melnychuk</b></sub></a><br /><a href=\"#content-k-melnychuk\" title=\"Content\">🖋</a> <a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=k-melnychuk\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LumaKernel\"><img src=\"https://avatars.githubusercontent.com/u/29811106?v=4?s=64\" width=\"64px;\" alt=\"Luma\"/><br /><sub><b>Luma</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LumaKernel\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Newbie012\"><img src=\"https://avatars.githubusercontent.com/u/10504365?v=4?s=64\" width=\"64px;\" alt=\"Eliya Cohen\"/><br /><sub><b>Eliya Cohen</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=Newbie012\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/isumix\"><img src=\"https://avatars.githubusercontent.com/u/16747416?v=4?s=64\" width=\"64px;\" alt=\"Igor Sukharev\"/><br /><sub><b>Igor Sukharev</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Aisumix\" title=\"Bug reports\">🐛</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/pookmish\"><img src=\"https://avatars.githubusercontent.com/u/7185045?v=4?s=64\" width=\"64px;\" alt=\"pookmish\"/><br /><sub><b>pookmish</b></sub></a><br /><a href=\"#ideas-pookmish\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/metav-drimz\"><img src=\"https://avatars.githubusercontent.com/u/113976282?v=4?s=64\" width=\"64px;\" alt=\"metav-drimz\"/><br /><sub><b>metav-drimz</b></sub></a><br /><a href=\"#ideas-metav-drimz\" title=\"Ideas, Planning, & Feedback\">🤔</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://luckrnx09.com/\"><img src=\"https://avatars.githubusercontent.com/u/113882203?v=4?s=64\" width=\"64px;\" alt=\"luckrnx09\"/><br /><sub><b>luckrnx09</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=luckrnx09\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/RubyHuntsman\"><img src=\"https://avatars.githubusercontent.com/u/24682602?v=4?s=64\" width=\"64px;\" alt=\"Hubert Kuczmierczyk\"/><br /><sub><b>Hubert Kuczmierczyk</b></sub></a><br /><a href=\"#ideas-RubyHuntsman\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3ARubyHuntsman\" title=\"Reviewed Pull Requests\">👀</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dandubya\"><img src=\"https://avatars.githubusercontent.com/u/67660308?v=4?s=64\" width=\"64px;\" alt=\"dandubya\"/><br /><sub><b>dandubya</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=dandubya\" title=\"Documentation\">📖</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LonelyFellas\"><img src=\"https://avatars.githubusercontent.com/u/38754760?v=4?s=64\" width=\"64px;\" alt=\"Darwish\"/><br /><sub><b>Darwish</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/commits?author=LonelyFellas\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://www.jesuisjo.com/\"><img src=\"https://avatars.githubusercontent.com/u/2046871?v=4?s=64\" width=\"64px;\" alt=\"Jonathan Raoult\"/><br /><sub><b>Jonathan Raoult</b></sub></a><br /><a href=\"https://github.com/juliencrn/usehooks-ts/issues?q=author%3Ajraoult\" title=\"Bug reports\">🐛</a> <a href=\"https://github.com/juliencrn/usehooks-ts/pulls?q=is%3Apr+reviewed-by%3Ajraoult\" title=\"Reviewed Pull Requests\">👀</a></td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification ([emoji key](https://allcontributors.org/docs/en/emoji-key)). Contributions of any kind welcome!\n\n## 💞 Donate\n\nIf you find this piece of software helpful, please consider a donation. Any amount is greatly appreciated.\n\n[![GitHub Sponsors](https://badgen.net/badge/GitHub%20Sponsors/Donate/blue)](https://github.com/sponsors/juliencrn)\n[![Paypal](https://badgen.net/badge/Paypal/Donate/blue)](https://www.paypal.com/paypalme/juliencrn)\n[![Stripe](https://badgen.net/badge/Stripe/Donate/blue)](https://buy.stripe.com/fZefZY8Bv32cg9O3cc)\n[![Buy me a coffee](https://badgen.net/badge/Buy%20me%20a%20coffee/Donate/blue)](https://www.buymeacoffee.com/juliencrn)\n\nBTC: `bc1qwys40tnd0lxf9lr9l0t6xc63dpxyucj4x4nay0`\n\nETH: `0x36a85155a8300754C56395D5af24553FB18915D6`\n\n## 📝 License\n\nThis project is [MIT](https://github.com/juliencrn/usehooks-ts/blob/master/LICENSE) licensed.\n"
  },
  {
    "path": "packages/usehooks-ts/package.json",
    "content": "{\n  \"name\": \"usehooks-ts\",\n  \"private\": false,\n  \"version\": \"3.1.1\",\n  \"description\": \"React hook library, ready to use, written in Typescript.\",\n  \"author\": \"Julien CARON <juliencaron@protonmail.com>\",\n  \"homepage\": \"https://usehooks-ts.com\",\n  \"keywords\": [\n    \"typescript\",\n    \"react\",\n    \"hooks\"\n  ],\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \"./package.json\": \"./package.json\",\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    }\n  },\n  \"sideEffects\": false,\n  \"scripts\": {\n    \"build\": \"tsup\",\n    \"dev\": \"tsup --watch\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest\",\n    \"clean\": \"rimraf dist .turbo *.tsbuildinfo\",\n    \"lint\": \"eslint './src/**/*.{ts,tsx}' && tsc --noEmit\"\n  },\n  \"devDependencies\": {\n    \"@juggle/resize-observer\": \"^3.4.0\",\n    \"@testing-library/jest-dom\": \"^6.4.2\",\n    \"@testing-library/react\": \"^14.2.1\",\n    \"@types/lodash.debounce\": \"^4.0.9\",\n    \"@types/node\": \"^20.11.19\",\n    \"@types/react\": \"18.2.73\",\n    \"eslint-config-custom\": \"workspace:*\",\n    \"eslint-plugin-jsdoc\": \"^48.1.0\",\n    \"eslint-plugin-tree-shaking\": \"^1.12.1\",\n    \"jsdom\": \"^24.0.0\",\n    \"react\": \"18.2.0\",\n    \"tsup\": \"^8.0.2\",\n    \"typescript\": \"^5.3.3\",\n    \"vitest\": \"^1.3.1\"\n  },\n  \"dependencies\": {\n    \"lodash.debounce\": \"^4.0.8\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^16.8.0  || ^17 || ^18 || ^19 || ^19.0.0-rc\"\n  },\n  \"engines\": {\n    \"node\": \">=16.15.0\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/juliencrn/usehooks-ts\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/juliencrn/usehooks-ts/issues\"\n  }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/index.ts",
    "content": "export * from './useBoolean'\nexport * from './useClickAnyWhere'\nexport * from './useCopyToClipboard'\nexport * from './useCountdown'\nexport * from './useCounter'\nexport * from './useDarkMode'\nexport * from './useDebounceCallback'\nexport * from './useDebounceValue'\nexport * from './useDocumentTitle'\nexport * from './useEventCallback'\nexport * from './useEventListener'\nexport * from './useHover'\nexport * from './useIntersectionObserver'\nexport * from './useInterval'\nexport * from './useIsClient'\nexport * from './useIsMounted'\nexport * from './useIsomorphicLayoutEffect'\nexport * from './useLocalStorage'\nexport * from './useMap'\nexport * from './useMediaQuery'\nexport * from './useOnClickOutside'\nexport * from './useReadLocalStorage'\nexport * from './useResizeObserver'\nexport * from './useScreen'\nexport * from './useScript'\nexport * from './useScrollLock'\nexport * from './useSessionStorage'\nexport * from './useStep'\nexport * from './useTernaryDarkMode'\nexport * from './useTimeout'\nexport * from './useToggle'\nexport * from './useUnmount'\nexport * from './useWindowSize'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useBoolean/index.ts",
    "content": "export * from './useBoolean'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useBoolean/useBoolean.demo.tsx",
    "content": "import { useBoolean } from './useBoolean'\n\nexport default function Component() {\n  const { value, setValue, setTrue, setFalse, toggle } = useBoolean(false)\n\n  // Just an example to use \"setValue\"\n  const customToggle = () => {\n    setValue((x: boolean) => !x)\n  }\n\n  return (\n    <>\n      <p>\n        Value is <code>{value.toString()}</code>\n      </p>\n      <button onClick={setTrue}>set true</button>\n      <button onClick={setFalse}>set false</button>\n      <button onClick={toggle}>toggle</button>\n      <button onClick={customToggle}>custom toggle</button>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useBoolean/useBoolean.md",
    "content": "A simple abstraction to play with a boolean, don't repeat yourself.\n\nRelated hooks:\n\n- [`useToggle()`](/react-hook/use-toggle)\n"
  },
  {
    "path": "packages/usehooks-ts/src/useBoolean/useBoolean.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useBoolean } from './useBoolean'\n\ndescribe('useBoolean()', () => {\n  it('should use boolean', () => {\n    const { result } = renderHook(() => useBoolean())\n\n    expect(result.current.value).toBe(false)\n    expect(typeof result.current.setTrue).toBe('function')\n    expect(typeof result.current.setFalse).toBe('function')\n    expect(typeof result.current.toggle).toBe('function')\n    expect(typeof result.current.setValue).toBe('function')\n  })\n\n  it('should default value works (1)', () => {\n    const { result } = renderHook(() => useBoolean(true))\n\n    expect(result.current.value).toBe(true)\n  })\n\n  it('should default value works (2)', () => {\n    const { result } = renderHook(() => useBoolean(false))\n\n    expect(result.current.value).toBe(false)\n  })\n\n  it('should set to true (1)', () => {\n    const { result } = renderHook(() => useBoolean(false))\n\n    act(() => {\n      result.current.setTrue()\n    })\n\n    expect(result.current.value).toBe(true)\n  })\n\n  it('should set to true (2)', () => {\n    const { result } = renderHook(() => useBoolean(false))\n\n    act(() => {\n      result.current.setTrue()\n      result.current.setTrue()\n    })\n\n    expect(result.current.value).toBe(true)\n  })\n\n  it('should set to false (1)', () => {\n    const { result } = renderHook(() => useBoolean(true))\n\n    act(() => {\n      result.current.setFalse()\n    })\n\n    expect(result.current.value).toBe(false)\n  })\n\n  it('should set to false (2)', () => {\n    const { result } = renderHook(() => useBoolean(true))\n\n    act(() => {\n      result.current.setFalse()\n      result.current.setFalse()\n    })\n\n    expect(result.current.value).toBe(false)\n  })\n\n  it('should toggle value', () => {\n    const { result } = renderHook(() => useBoolean(true))\n\n    act(() => {\n      result.current.toggle()\n    })\n\n    expect(result.current.value).toBe(false)\n  })\n\n  it('should toggle value from prev using setValue', () => {\n    const { result } = renderHook(() => useBoolean(true))\n\n    act(() => {\n      result.current.setValue(x => !x)\n    })\n\n    expect(result.current.value).toBe(false)\n  })\n\n  it('should throw an error', () => {\n    const nonBoolean = '' as never\n    vi.spyOn(console, 'error').mockImplementation(() => vi.fn())\n    expect(() => {\n      renderHook(() => useBoolean(nonBoolean))\n    }).toThrowError(/defaultValue must be `true` or `false`/)\n    vi.resetAllMocks()\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useBoolean/useBoolean.ts",
    "content": "import { useCallback, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\n/** The useBoolean return type. */\ntype UseBooleanReturn = {\n  /** The current boolean state value. */\n  value: boolean\n  /** Function to set the boolean state directly. */\n  setValue: Dispatch<SetStateAction<boolean>>\n  /** Function to set the boolean state to `true`. */\n  setTrue: () => void\n  /** Function to set the boolean state to `false`. */\n  setFalse: () => void\n  /** Function to toggle the boolean state. */\n  toggle: () => void\n}\n\n/**\n * Custom hook that handles boolean state with useful utility functions.\n * @param {boolean} [defaultValue] - The initial value for the boolean state (default is `false`).\n * @returns {UseBooleanReturn} An object containing the boolean state value and utility functions to manipulate the state.\n * @throws Will throw an error if `defaultValue` is an invalid boolean value.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-boolean)\n * @example\n * ```tsx\n * const { value, setTrue, setFalse, toggle } = useBoolean(true);\n * ```\n */\nexport function useBoolean(defaultValue = false): UseBooleanReturn {\n  if (typeof defaultValue !== 'boolean') {\n    throw new Error('defaultValue must be `true` or `false`')\n  }\n  const [value, setValue] = useState(defaultValue)\n\n  const setTrue = useCallback(() => {\n    setValue(true)\n  }, [])\n\n  const setFalse = useCallback(() => {\n    setValue(false)\n  }, [])\n\n  const toggle = useCallback(() => {\n    setValue(x => !x)\n  }, [])\n\n  return { value, setValue, setTrue, setFalse, toggle }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useClickAnyWhere/index.ts",
    "content": "export * from './useClickAnyWhere'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useClickAnyWhere/useClickAnyWhere.demo.tsx",
    "content": "import { useState } from 'react'\n\nimport { useClickAnyWhere } from './useClickAnyWhere'\n\nexport default function Component() {\n  const [count, setCount] = useState(0)\n\n  useClickAnyWhere(() => {\n    setCount(prev => prev + 1)\n  })\n\n  return <p>Click count: {count}</p>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useClickAnyWhere/useClickAnyWhere.md",
    "content": "This simple React hook offers you a click event listener at the page level, don't repeat yourself.\n\nIt is made on the [useEventListener](/react-hook/use-event-listener).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useClickAnyWhere/useClickAnyWhere.test.ts",
    "content": "import { act, fireEvent, renderHook } from '@testing-library/react'\n\nimport { useClickAnyWhere } from './useClickAnyWhere'\n\ndescribe('useClickAnyWhere()', () => {\n  it('should call handler (0)', () => {\n    const mockHandler: (event: MouseEvent) => void = vitest.fn()\n    renderHook(() => {\n      useClickAnyWhere(mockHandler)\n    })\n\n    act(() => {\n      fireEvent.doubleClick(window)\n    })\n\n    expect(mockHandler).toHaveBeenCalledTimes(0)\n  })\n\n  it('should call handler (1) with MouseEvent', () => {\n    const mockHandler: (event: MouseEvent) => void = vitest.fn()\n\n    renderHook(() => {\n      useClickAnyWhere(mockHandler)\n    })\n\n    act(() => {\n      fireEvent.click(window)\n    })\n\n    expect(mockHandler).toHaveBeenCalledTimes(1)\n    expect(mockHandler).toHaveBeenCalledWith(expect.any(MouseEvent))\n  })\n\n  it('should call handler (2)', () => {\n    const mockHandler: (event: MouseEvent) => void = vitest.fn()\n    renderHook(() => {\n      useClickAnyWhere(mockHandler)\n    })\n\n    act(() => {\n      fireEvent.click(window)\n      fireEvent.click(window)\n    })\n\n    expect(mockHandler).toHaveBeenCalledTimes(2)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useClickAnyWhere/useClickAnyWhere.ts",
    "content": "import { useEventListener } from '../useEventListener'\n\n/**\n * Custom hook that handles click events anywhere on the document.\n * @param {Function} handler - The function to be called when a click event is detected anywhere on the document.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-click-any-where)\n * @example\n * ```tsx\n * const handleClick = (event) => {\n *   console.log('Document clicked!', event);\n * };\n *\n * // Attach click event handler to document\n * useClickAnywhere(handleClick);\n * ```\n */\nexport function useClickAnyWhere(handler: (event: MouseEvent) => void) {\n  useEventListener('click', event => {\n    handler(event)\n  })\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCopyToClipboard/index.ts",
    "content": "export * from './useCopyToClipboard'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCopyToClipboard/useCopyToClipboard.demo.tsx",
    "content": "import { useCopyToClipboard } from './useCopyToClipboard'\n\nexport default function Component() {\n  const [copiedText, copy] = useCopyToClipboard()\n\n  const handleCopy = (text: string) => () => {\n    copy(text)\n      .then(() => {\n        console.log('Copied!', { text })\n      })\n      .catch(error => {\n        console.error('Failed to copy!', error)\n      })\n  }\n\n  return (\n    <>\n      <h1>Click to copy:</h1>\n      <div style={{ display: 'flex' }}>\n        <button onClick={handleCopy('A')}>A</button>\n        <button onClick={handleCopy('B')}>B</button>\n        <button onClick={handleCopy('C')}>C</button>\n      </div>\n      <p>Copied value: {copiedText ?? 'Nothing is copied yet!'}</p>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCopyToClipboard/useCopyToClipboard.md",
    "content": "React Hook for easy clipboard copy functionality.\n\nThis hook provides a simple method to copy a string to the [clipboard](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/clipboard) and keeps track of the copied value. If the copying process encounters an issue, it logs a warning in the console, and the copied value remains null.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCopyToClipboard/useCopyToClipboard.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useCopyToClipboard } from './useCopyToClipboard'\n\ndescribe('useCopyToClipboard()', () => {\n  const originalClipboard = { ...global.navigator.clipboard }\n  const mockData = 'Test value'\n\n  beforeEach(() => {\n    const mockClipboard = {\n      writeText: vitest.fn(),\n    }\n    // @ts-ignore mock clipboard\n    global.navigator.clipboard = mockClipboard\n  })\n\n  afterEach(() => {\n    vitest.resetAllMocks()\n    // @ts-ignore mock clipboard\n    global.navigator.clipboard = originalClipboard\n  })\n\n  it('should use clipboard', () => {\n    const { result } = renderHook(() => useCopyToClipboard())\n\n    expect(result.current[0]).toBe(null)\n    expect(typeof result.current[1]).toBe('function')\n  })\n\n  it('should copy to the clipboard and the state', async () => {\n    const { result } = renderHook(() => useCopyToClipboard())\n\n    await act(async () => {\n      await result.current[1](mockData)\n    })\n\n    expect(navigator.clipboard.writeText).toHaveBeenCalledTimes(1)\n    expect(navigator.clipboard.writeText).toHaveBeenCalledWith(mockData)\n    expect(result.current[0]).toBe(mockData)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCopyToClipboard/useCopyToClipboard.ts",
    "content": "import { useCallback, useState } from 'react'\n\n/**\n * The copied text as `string` or `null` if nothing has been copied yet.\n */\ntype CopiedValue = string | null\n\n/**\n * Function to copy text to the clipboard.\n * @param text - The text to copy to the clipboard.\n * @returns {Promise<boolean>} A promise that resolves to `true` if the text was copied successfully, or `false` otherwise.\n */\ntype CopyFn = (text: string) => Promise<boolean>\n\n/**\n * Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API).\n * @returns {[CopiedValue, CopyFn]} An tuple containing the copied text and a function to copy text to the clipboard.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-copy-to-clipboard)\n * @example\n * ```tsx\n * const [copiedText, copyToClipboard] = useCopyToClipboard();\n * const textToCopy = 'Hello, world!';\n *\n * // Attempt to copy text to the clipboard\n * copyToClipboard(textToCopy)\n *   .then(success => {\n *     if (success) {\n *       console.log(`Text \"${textToCopy}\" copied to clipboard successfully.`);\n *     } else {\n *       console.error('Failed to copy text to clipboard.');\n *     }\n *   });\n * ```\n */\nexport function useCopyToClipboard(): [CopiedValue, CopyFn] {\n  const [copiedText, setCopiedText] = useState<CopiedValue>(null)\n\n  const copy: CopyFn = useCallback(async text => {\n    if (!navigator?.clipboard) {\n      console.warn('Clipboard not supported')\n      return false\n    }\n\n    // Try to save to clipboard then save it in the state if worked\n    try {\n      await navigator.clipboard.writeText(text)\n      setCopiedText(text)\n      return true\n    } catch (error) {\n      console.warn('Copy failed', error)\n      setCopiedText(null)\n      return false\n    }\n  }, [])\n\n  return [copiedText, copy]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCountdown/index.ts",
    "content": "export * from './useCountdown'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCountdown/useCountdown.demo.tsx",
    "content": "import { useState } from 'react'\n\nimport type { ChangeEvent } from 'react'\n\nimport { useCountdown } from './useCountdown'\n\nexport default function Component() {\n  const [intervalValue, setIntervalValue] = useState<number>(1000)\n  const [count, { startCountdown, stopCountdown, resetCountdown }] =\n    useCountdown({\n      countStart: 60,\n      intervalMs: intervalValue,\n    })\n\n  const handleChangeIntervalValue = (event: ChangeEvent<HTMLInputElement>) => {\n    setIntervalValue(Number(event.target.value))\n  }\n  return (\n    <div>\n      <p>Count: {count}</p>\n\n      <input\n        type=\"number\"\n        value={intervalValue}\n        onChange={handleChangeIntervalValue}\n      />\n      <button onClick={startCountdown}>start</button>\n      <button onClick={stopCountdown}>stop</button>\n      <button onClick={resetCountdown}>reset</button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCountdown/useCountdown.md",
    "content": "**IMPORTANT**: The new useCountdown is deprecating the old one on the next major version.\n\nA simple countdown implementation. Support increment and decrement.\n\nNEW VERSION: A simple countdown implementation. Accepts `countStop`(new), `countStart` (was `seconds`), `intervalMs`(was `interval`) and `isIncrement` as keys of the call argument. Support increment and decrement. Will stop when at `countStop`.\n\nRelated hooks:\n\n- [`useBoolean()`](/react-hook/use-boolean)\n- [`useToggle()`](/react-hook/use-toggle)\n- [`useCounter()`](/react-hook/use-counter)\n- [`useInterval()`](/react-hook/use-interval)\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCountdown/useCountdown.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useCountdown } from './useCountdown'\n\nvitest.useFakeTimers()\n\ndescribe('useCountdown()', () => {\n  it('should return callable functions', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 500, isIncrement: false }),\n    )\n\n    expect(result.current[0]).toBe(60)\n    expect(typeof result.current[1].startCountdown).toBe('function')\n    expect(typeof result.current[1].stopCountdown).toBe('function')\n    expect(typeof result.current[1].resetCountdown).toBe('function')\n  })\n\n  it('should increment count', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 500, isIncrement: true }),\n    )\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(1000)\n    })\n\n    expect(result.current[0]).toBe(62)\n  })\n\n  it('should decrement count', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 500 }),\n    )\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(1000)\n    })\n\n    expect(result.current[0]).toBe(58)\n  })\n\n  it('should accept countStart', () => {\n    const { result } = renderHook(() => useCountdown({ countStart: 30 }))\n\n    expect(result.current[0]).toBe(30)\n    expect(typeof result.current[1].startCountdown).toBe('function')\n    expect(typeof result.current[1].stopCountdown).toBe('function')\n    expect(typeof result.current[1].resetCountdown).toBe('function')\n  })\n\n  it('should accept intervalMs', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 500 }),\n    )\n\n    expect(result.current[0]).toBe(60)\n    expect(typeof result.current[1].startCountdown).toBe('function')\n    expect(typeof result.current[1].stopCountdown).toBe('function')\n    expect(typeof result.current[1].resetCountdown).toBe('function')\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(500)\n    })\n\n    expect(result.current[0]).toBe(59)\n  })\n\n  it('should stop at countStop (default: 0)', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 1000 }),\n    )\n\n    expect(result.current[0]).toBe(60)\n    expect(typeof result.current[1].startCountdown).toBe('function')\n    expect(typeof result.current[1].stopCountdown).toBe('function')\n    expect(typeof result.current[1].resetCountdown).toBe('function')\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(60 * 1000)\n    })\n\n    expect(result.current[0]).toBe(0)\n\n    act(() => {\n      vitest.advanceTimersByTime(1000)\n    })\n\n    expect(result.current[0]).toBe(0)\n  })\n\n  it('should stop at custom countStop', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 1000, countStop: 30 }),\n    )\n\n    expect(result.current[0]).toBe(60)\n    expect(typeof result.current[1].startCountdown).toBe('function')\n    expect(typeof result.current[1].stopCountdown).toBe('function')\n    expect(typeof result.current[1].resetCountdown).toBe('function')\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(30 * 1000)\n    })\n\n    expect(result.current[0]).toBe(30)\n\n    act(() => {\n      vitest.advanceTimersByTime(1000)\n    })\n\n    expect(result.current[0]).toBe(30)\n  })\n\n  it('should stop countdown', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 1000 }),\n    )\n\n    expect(result.current[0]).toBe(60)\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(2000)\n    })\n\n    expect(result.current[0]).toBe(58)\n    act(result.current[1].stopCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(3000)\n    })\n    expect(result.current[0]).toBe(58)\n  })\n\n  it('should stop reversed countdown', () => {\n    const { result } = renderHook(() =>\n      useCountdown({\n        countStart: 10,\n        intervalMs: 1000,\n        countStop: 20,\n        isIncrement: true,\n      }),\n    )\n\n    expect(result.current[0]).toBe(10)\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(2 * 1000)\n    })\n\n    expect(result.current[0]).toBe(12)\n\n    act(() => {\n      vitest.advanceTimersByTime(8 * 1000)\n    })\n    expect(result.current[0]).toBe(20)\n\n    act(() => {\n      vitest.advanceTimersByTime(3 * 1000)\n    })\n\n    expect(result.current[0]).toBe(20)\n  })\n\n  it('should reset count', () => {\n    const { result } = renderHook(() =>\n      useCountdown({ countStart: 60, intervalMs: 1000 }),\n    )\n\n    act(result.current[1].startCountdown)\n    act(() => {\n      vitest.advanceTimersByTime(1000)\n    })\n    act(result.current[1].stopCountdown)\n    expect(result.current[0]).toBeLessThan(60)\n\n    act(result.current[1].resetCountdown)\n    expect(result.current[0]).toBe(60)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCountdown/useCountdown.ts",
    "content": "import { useCallback } from 'react'\n\nimport { useBoolean } from '../useBoolean'\nimport { useCounter } from '../useCounter'\nimport { useInterval } from '../useInterval'\n\n/** The countdown's options. */\ntype CountdownOptions = {\n  /** The countdown's starting number, initial value of the returned number. */\n  countStart: number\n\n  /**\n   * The countdown's interval, in milliseconds.\n   * @default 1000\n   */\n  intervalMs?: number\n  /**\n   * True if the countdown is increment.\n   * @default false\n   */\n  isIncrement?: boolean\n\n  /**\n   * The countdown's stopping number. Pass `-Infinity` to decrease forever.\n   * @default 0\n   */\n  countStop?: number\n}\n\n/** The countdown's controllers. */\ntype CountdownControllers = {\n  /** Start the countdown. */\n  startCountdown: () => void\n  /** Stop the countdown. */\n  stopCountdown: () => void\n  /** Reset the countdown. */\n  resetCountdown: () => void\n}\n\n/**\n * Custom hook that manages countdown.\n * @param {CountdownOptions} countdownOptions - The countdown's options.\n * @returns {[number, CountdownControllers]} An array containing the countdown's count and its controllers.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-countdown)\n * @example\n * ```tsx\n * const [counter, { start, stop, reset }] = useCountdown({\n *   countStart: 10,\n *   intervalMs: 1000,\n *   isIncrement: false,\n * });\n * ```\n */\nexport function useCountdown({\n  countStart,\n  countStop = 0,\n  intervalMs = 1000,\n  isIncrement = false,\n}: CountdownOptions): [number, CountdownControllers] {\n  const {\n    count,\n    increment,\n    decrement,\n    reset: resetCounter,\n  } = useCounter(countStart)\n\n  /*\n   * Note: used to control the useInterval\n   * running: If true, the interval is running\n   * start: Should set running true to trigger interval\n   * stop: Should set running false to remove interval.\n   */\n  const {\n    value: isCountdownRunning,\n    setTrue: startCountdown,\n    setFalse: stopCountdown,\n  } = useBoolean(false)\n\n  // Will set running false and reset the seconds to initial value.\n  const resetCountdown = useCallback(() => {\n    stopCountdown()\n    resetCounter()\n  }, [stopCountdown, resetCounter])\n\n  const countdownCallback = useCallback(() => {\n    if (count === countStop) {\n      stopCountdown()\n      return\n    }\n\n    if (isIncrement) {\n      increment()\n    } else {\n      decrement()\n    }\n  }, [count, countStop, decrement, increment, isIncrement, stopCountdown])\n\n  useInterval(countdownCallback, isCountdownRunning ? intervalMs : null)\n\n  return [count, { startCountdown, stopCountdown, resetCountdown }]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCounter/index.ts",
    "content": "export * from './useCounter'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCounter/useCounter.demo.tsx",
    "content": "import { useCounter } from './useCounter'\n\nexport default function Component() {\n  const { count, setCount, increment, decrement, reset } = useCounter(0)\n\n  const multiplyBy2 = () => {\n    setCount((x: number) => x * 2)\n  }\n\n  return (\n    <>\n      <p>Count is {count}</p>\n      <button onClick={increment}>Increment</button>\n      <button onClick={decrement}>Decrement</button>\n      <button onClick={reset}>Reset</button>\n      <button onClick={multiplyBy2}>Multiply by 2</button>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCounter/useCounter.md",
    "content": "A simple abstraction to play with a counter, don't repeat yourself.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCounter/useCounter.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useCounter } from './useCounter'\n\ndescribe('useCounter()', () => {\n  it('should use counter', () => {\n    const { result } = renderHook(() => useCounter())\n\n    expect(result.current.count).toBe(0)\n    expect(typeof result.current.increment).toBe('function')\n    expect(typeof result.current.decrement).toBe('function')\n    expect(typeof result.current.reset).toBe('function')\n    expect(typeof result.current.setCount).toBe('function')\n  })\n\n  it('should increment counter', () => {\n    const { result } = renderHook(() => useCounter())\n\n    act(() => {\n      result.current.increment()\n    })\n\n    expect(result.current.count).toBe(1)\n  })\n\n  it('should decrement counter', () => {\n    const { result } = renderHook(() => useCounter())\n\n    act(() => {\n      result.current.decrement()\n    })\n\n    expect(result.current.count).toBe(-1)\n  })\n\n  it('should default value works', () => {\n    const { result } = renderHook(() => useCounter(3))\n\n    expect(result.current.count).toBe(3)\n  })\n\n  it('should decrement counter with default value', () => {\n    const { result } = renderHook(() => useCounter(3))\n\n    act(() => {\n      result.current.decrement()\n    })\n\n    expect(result.current.count).toBe(2)\n  })\n\n  it('should set counter', () => {\n    const { result } = renderHook(() => useCounter())\n\n    act(() => {\n      result.current.setCount(5)\n    })\n\n    expect(result.current.count).toBe(5)\n  })\n\n  it('should set counter with prev value', () => {\n    const { result } = renderHook(() => useCounter(5))\n\n    act(() => {\n      result.current.setCount(x => x + 2)\n    })\n\n    expect(result.current.count).toBe(7)\n  })\n\n  it('should reset counter', () => {\n    const { result } = renderHook(() => useCounter(0))\n\n    act(() => {\n      result.current.increment()\n      result.current.reset()\n    })\n\n    expect(result.current.count).toBe(0)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useCounter/useCounter.ts",
    "content": "import { useCallback, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\n/** The hook return type. */\ntype UseCounterReturn = {\n  /** The current count value. */\n  count: number\n  /** Function to increment the counter by 1. */\n  increment: () => void\n  /** Function to decrement the counter by 1. */\n  decrement: () => void\n  /** Function to reset the counter to its initial value. */\n  reset: () => void\n  /** Function to set a specific value to the counter. */\n  setCount: Dispatch<SetStateAction<number>>\n}\n\n/**\n * Custom hook that manages a counter with increment, decrement, reset, and setCount functionalities.\n * @param {number} [initialValue] - The initial value for the counter.\n * @returns {UseCounterReturn} An object containing the current count and functions to interact with the counter.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-counter)\n * @example\n * ```tsx\n * const { count, increment, decrement, reset, setCount } = useCounter(5);\n * ```\n */\nexport function useCounter(initialValue?: number): UseCounterReturn {\n  const [count, setCount] = useState(initialValue ?? 0)\n\n  const increment = useCallback(() => {\n    setCount(x => x + 1)\n  }, [])\n\n  const decrement = useCallback(() => {\n    setCount(x => x - 1)\n  }, [])\n\n  const reset = useCallback(() => {\n    setCount(initialValue ?? 0)\n  }, [initialValue])\n\n  return {\n    count,\n    increment,\n    decrement,\n    reset,\n    setCount,\n  }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDarkMode/index.ts",
    "content": "export * from './useDarkMode'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDarkMode/useDarkMode.demo.tsx",
    "content": "import { useDarkMode } from './useDarkMode'\n\nexport default function Component() {\n  const { isDarkMode, toggle, enable, disable } = useDarkMode()\n\n  return (\n    <div>\n      <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>\n      <button onClick={toggle}>Toggle</button>\n      <button onClick={enable}>Enable</button>\n      <button onClick={disable}>Disable</button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDarkMode/useDarkMode.md",
    "content": "This React Hook offers you an interface to set, enable, disable, toggle and read the dark theme mode.\nThe returned value (`isDarkMode`) is a boolean to let you be able to use with your logic.\n\nIt uses internally [`useLocalStorage()`](/react-hook/use-local-storage) to persist the value and listens the OS color scheme preferences.\n\n**Note**: If you use this hook in an SSR context, set the `initializeWithValue` option to `false`.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDarkMode/useDarkMode.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { mockMatchMedia, mockStorage } from '../../tests/mocks'\nimport { useDarkMode } from './useDarkMode'\n\nmockStorage('localStorage')\n\ndescribe('useDarkMode()', () => {\n  beforeEach(() => {\n    window.localStorage.clear()\n  })\n\n  it('should initiate correctly', () => {\n    mockMatchMedia(false)\n    const { result } = renderHook(() => useDarkMode())\n    expect(typeof result.current.isDarkMode).toBe('boolean')\n    expect(typeof result.current.disable).toBe('function')\n    expect(typeof result.current.toggle).toBe('function')\n    expect(typeof result.current.enable).toBe('function')\n    expect(typeof result.current.set).toBe('function')\n    expect(result.current.isDarkMode).toBe(false)\n  })\n\n  it('should have a default value', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(true)\n  })\n\n  it('should toggle dark mode', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(true)\n    act(() => {\n      result.current.toggle()\n    })\n    expect(result.current.isDarkMode).toBe(false)\n    act(() => {\n      result.current.toggle()\n    })\n    expect(result.current.isDarkMode).toBe(true)\n  })\n\n  it('should enable dark mode (1)', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(true)\n    act(() => {\n      result.current.enable()\n    })\n    expect(result.current.isDarkMode).toBe(true)\n  })\n\n  it('should enable dark mode (2)', () => {\n    mockMatchMedia(false)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(false)\n    act(() => {\n      result.current.enable()\n    })\n    expect(result.current.isDarkMode).toBe(true)\n  })\n\n  it('should disable dark mode (1)', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(true)\n    act(() => {\n      result.current.disable()\n    })\n    expect(result.current.isDarkMode).toBe(false)\n  })\n\n  it('should disable dark mode (2)', () => {\n    mockMatchMedia(false)\n    const { result } = renderHook(() => useDarkMode())\n    expect(result.current.isDarkMode).toBe(false)\n    act(() => {\n      result.current.disable()\n    })\n    expect(result.current.isDarkMode).toBe(false)\n  })\n\n  it('should set dark mode', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useDarkMode())\n    act(() => {\n      result.current.set(false)\n    })\n    expect(result.current.isDarkMode).toBe(false)\n    act(() => {\n      result.current.set(true)\n    })\n    expect(result.current.isDarkMode).toBe(true)\n  })\n\n  it('should accept a custom localStorage key', () => {\n    mockMatchMedia(false)\n    const { result } = renderHook(() =>\n      useDarkMode({ localStorageKey: 'custom-key' }),\n    )\n\n    expect(result.current.isDarkMode).toBe(false)\n\n    act(() => {\n      result.current.toggle()\n    })\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(window.localStorage.getItem('custom-key')).toBe(JSON.stringify(true))\n  })\n\n  it('should accept a custom default value', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() =>\n      useDarkMode({ defaultValue: true, initializeWithValue: false }),\n    )\n\n    expect(result.current.isDarkMode).toBe(true)\n\n    act(() => {\n      result.current.toggle()\n    })\n\n    expect(result.current.isDarkMode).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDarkMode/useDarkMode.ts",
    "content": "import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\nimport { useLocalStorage } from '../useLocalStorage'\nimport { useMediaQuery } from '../useMediaQuery'\n\nconst COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'\nconst LOCAL_STORAGE_KEY = 'usehooks-ts-dark-mode'\n\n/** The hook options. */\ntype DarkModeOptions = {\n  /**\n   * The initial value of the dark mode.\n   * @default false\n   */\n  defaultValue?: boolean\n  /**\n   * The key to use in the local storage.\n   * @default 'usehooks-ts-dark-mode'\n   */\n  localStorageKey?: string\n  /**\n   * If `true` (default), the hook will initialize reading `localStorage`.\n   * In SSR, you should set it to `false`, returning the `defaultValue` or `false` initially.\n   * @default true\n   */\n  initializeWithValue?: boolean\n}\n\n/** The hook return type. */\ntype DarkModeReturn = {\n  /** The current state of the dark mode. */\n  isDarkMode: boolean\n  /** Function to toggle the dark mode. */\n  toggle: () => void\n  /** Function to enable the dark mode. */\n  enable: () => void\n  /** Function to disable the dark mode. */\n  disable: () => void\n  /** Function to set a specific value to the dark mode. */\n  set: (value: boolean) => void\n}\n\n/**\n * Custom hook that returns the current state of the dark mode.\n * @param {?DarkModeOptions} [options] - The initial value of the dark mode, default `false`.\n * @returns {DarkModeReturn} An object containing the dark mode's state and its controllers.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-dark-mode)\n * @example\n * ```tsx\n * const { isDarkMode, toggle, enable, disable, set } = useDarkMode({ defaultValue: true });\n * ```\n */\nexport function useDarkMode(options: DarkModeOptions = {}): DarkModeReturn {\n  const {\n    defaultValue,\n    localStorageKey = LOCAL_STORAGE_KEY,\n    initializeWithValue = true,\n  } = options\n\n  const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY, {\n    initializeWithValue,\n    defaultValue,\n  })\n  const [isDarkMode, setDarkMode] = useLocalStorage<boolean>(\n    localStorageKey,\n    defaultValue ?? isDarkOS ?? false,\n    { initializeWithValue },\n  )\n\n  // Update darkMode if os prefers changes\n  useIsomorphicLayoutEffect(() => {\n    if (isDarkOS !== isDarkMode) {\n      setDarkMode(isDarkOS)\n    }\n  }, [isDarkOS])\n\n  return {\n    isDarkMode,\n    toggle: () => {\n      setDarkMode(prev => !prev)\n    },\n    enable: () => {\n      setDarkMode(true)\n    },\n    disable: () => {\n      setDarkMode(false)\n    },\n    set: value => {\n      setDarkMode(value)\n    },\n  }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceCallback/index.ts",
    "content": "export * from './useDebounceCallback'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.demo.tsx",
    "content": "import { useState } from 'react'\n\nimport { useDebounceCallback } from './useDebounceCallback'\n\nexport default function Component() {\n  const [value, setValue] = useState('')\n\n  const debounced = useDebounceCallback(setValue, 500)\n\n  return (\n    <div>\n      <p>Debounced value: {value}</p>\n\n      <input\n        type=\"text\"\n        defaultValue={value}\n        onChange={event => debounced(event.target.value)}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.md",
    "content": "Creates a debounced version of a callback function.\n\n### Parameters\n\n- `func`: The callback function to be debounced.\n- `delay` (optional): The delay in milliseconds before the callback is invoked (default is 500 milliseconds).\n- `options` (optional): Options to control the behavior of the debounced function.\n\n### Returns\n\nA debounced version of the original callback along with control functions.\n\n### Dependency\n\nThis hook is built upon [`lodash.debounce`](https://www.npmjs.com/package/lodash.debounce).\n\n### Related hooks\n\n- [`useDebounceValue`](/react-hook/use-debounce-value): Built on top of `useDebounceCallback`, it returns the debounce value instead\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useDebounceCallback } from './useDebounceCallback'\n\ndescribe('useDebounceCallback()', () => {\n  vitest.useFakeTimers()\n\n  it('should debounce the callback', () => {\n    const delay = 500\n    const debouncedCallback = vitest.fn()\n    const { result } = renderHook(() =>\n      useDebounceCallback(debouncedCallback, delay),\n    )\n\n    act(() => {\n      result.current('argument')\n    })\n\n    // The callback should not be invoked immediately\n    expect(debouncedCallback).not.toHaveBeenCalled()\n\n    // Fast forward time by 500 milliseconds\n    vitest.advanceTimersByTime(delay)\n\n    // The callback should be invoked after the debounce interval\n    expect(debouncedCallback).toHaveBeenCalledTimes(1)\n  })\n\n  it('should handle options', () => {\n    const delay = 500\n    const debouncedCallback = vitest.fn()\n    const { result } = renderHook(() =>\n      useDebounceCallback(debouncedCallback, delay, { leading: true }),\n    )\n\n    act(() => {\n      result.current('argument')\n    })\n\n    // The callback should be invoked immediately due to leading option\n    expect(debouncedCallback).toHaveBeenCalledWith('argument')\n\n    // Fast forward time by 500 milliseconds\n    vitest.advanceTimersByTime(delay)\n\n    // The callback should not be invoked again after the interval\n    expect(debouncedCallback).toHaveBeenCalledTimes(1)\n  })\n\n  it('should debounce the callback function', () => {\n    const callback = vitest.fn()\n    const { result } = renderHook(() => useDebounceCallback(callback, 100))\n\n    act(() => {\n      result.current('test1')\n      result.current('test2')\n      result.current('test3')\n    })\n\n    expect(callback).not.toBeCalled()\n\n    // Fast forward time\n    vitest.advanceTimersByTime(200)\n\n    expect(callback).toBeCalledTimes(1)\n    expect(callback).toBeCalledWith('test3')\n  })\n\n  it('should cancel the debounced callback', () => {\n    const delay = 500\n    const debouncedCallback = vitest.fn()\n    const { result } = renderHook(() =>\n      useDebounceCallback(debouncedCallback, delay),\n    )\n\n    act(() => {\n      result.current('argument')\n      result.current.cancel()\n    })\n\n    // Fast forward time\n    vitest.advanceTimersByTime(200)\n\n    // The callback should not be invoked after cancellation\n    expect(debouncedCallback).not.toHaveBeenCalled()\n  })\n\n  it('should flush the debounced callback', () => {\n    const delay = 500\n    const debouncedCallback = vitest.fn()\n    const { result } = renderHook(() =>\n      useDebounceCallback(debouncedCallback, delay),\n    )\n\n    act(() => {\n      result.current('argument')\n    })\n\n    // The callback should not be invoked immediately\n    expect(debouncedCallback).not.toHaveBeenCalled()\n\n    // Flush the debounced callback\n    act(() => {\n      result.current.flush()\n    })\n\n    // The callback should be invoked immediately after flushing\n    expect(debouncedCallback).toHaveBeenCalled()\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceCallback/useDebounceCallback.ts",
    "content": "import { useEffect, useMemo, useRef } from 'react'\n\nimport debounce from 'lodash.debounce'\n\nimport { useUnmount } from '../useUnmount'\n\n/** Configuration options for controlling the behavior of the debounced function. */\ntype DebounceOptions = {\n  /**\n   * Determines whether the function should be invoked on the leading edge of the timeout.\n   * @default false\n   */\n  leading?: boolean\n  /**\n   * Determines whether the function should be invoked on the trailing edge of the timeout.\n   * @default false\n   */\n  trailing?: boolean\n  /**\n   * The maximum time the specified function is allowed to be delayed before it is invoked.\n   */\n  maxWait?: number\n}\n\n/** Functions to manage a debounced callback. */\ntype ControlFunctions = {\n  /** Cancels pending function invocations. */\n  cancel: () => void\n  /** Immediately invokes pending function invocations. */\n  flush: () => void\n  /**\n   * Checks if there are any pending function invocations.\n   * @returns `true` if there are pending invocations, otherwise `false`.\n   */\n  isPending: () => boolean\n}\n\n/**\n * Represents the state and control functions of a debounced callback.\n * Subsequent calls to the debounced function return the result of the last invocation.\n * Note: If there are no previous invocations, the result will be undefined.\n * Ensure proper handling in your code.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type DebouncedState<T extends (...args: any) => ReturnType<T>> = ((\n  ...args: Parameters<T>\n) => ReturnType<T> | undefined) &\n  ControlFunctions\n\n/**\n * Custom hook that creates a debounced version of a callback function.\n * @template T - Type of the original callback function.\n * @param {T} func - The callback function to be debounced.\n * @param {number} delay - The delay in milliseconds before the callback is invoked (default is `500` milliseconds).\n * @param {DebounceOptions} [options] - Options to control the behavior of the debounced function.\n * @returns {DebouncedState<T>} A debounced version of the original callback along with control functions.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-debounce-callback)\n * @example\n * ```tsx\n * const debouncedCallback = useDebounceCallback(\n *   (searchTerm) => {\n *     // Perform search after user stops typing for 500 milliseconds\n *     searchApi(searchTerm);\n *   },\n *   500\n * );\n *\n * // Later in the component\n * debouncedCallback('react hooks'); // Will invoke the callback after 500 milliseconds of inactivity.\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useDebounceCallback<T extends (...args: any) => ReturnType<T>>(\n  func: T,\n  delay = 500,\n  options?: DebounceOptions,\n): DebouncedState<T> {\n  const debouncedFunc = useRef<ReturnType<typeof debounce>>()\n\n  useUnmount(() => {\n    if (debouncedFunc.current) {\n      debouncedFunc.current.cancel()\n    }\n  })\n\n  const debounced = useMemo(() => {\n    const debouncedFuncInstance = debounce(func, delay, options)\n\n    const wrappedFunc: DebouncedState<T> = (...args: Parameters<T>) => {\n      return debouncedFuncInstance(...args)\n    }\n\n    wrappedFunc.cancel = () => {\n      debouncedFuncInstance.cancel()\n    }\n\n    wrappedFunc.isPending = () => {\n      return !!debouncedFunc.current\n    }\n\n    wrappedFunc.flush = () => {\n      return debouncedFuncInstance.flush()\n    }\n\n    return wrappedFunc\n  }, [func, delay, options])\n\n  // Update the debounced function ref whenever func, wait, or options change\n  useEffect(() => {\n    debouncedFunc.current = debounce(func, delay, options)\n  }, [func, delay, options])\n\n  return debounced\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceValue/index.ts",
    "content": "export * from './useDebounceValue'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceValue/useDebounceValue.demo.tsx",
    "content": "import { useDebounceValue } from './useDebounceValue'\n\nexport default function Component({ defaultValue = 'John' }) {\n  const [debouncedValue, setValue] = useDebounceValue(defaultValue, 500)\n\n  return (\n    <div>\n      <p>Debounced value: {debouncedValue}</p>\n\n      <input\n        type=\"text\"\n        defaultValue={defaultValue}\n        onChange={event => setValue(event.target.value)}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceValue/useDebounceValue.md",
    "content": "Returns a debounced version of the provided value, along with a function to update it.\n\n### Parameters\n\n- `value`: The value to be debounced.\n- `delay`: The delay in milliseconds before the value is updated.\n- `options` (optional): Optional configurations for the debouncing behavior.\n  - `leading` (optional): Determines if the debounced function should be invoked on the leading edge of the timeout.\n  - `trailing` (optional): Determines if the debounced function should be invoked on the trailing edge of the timeout.\n  - `maxWait` (optional): The maximum time the debounced function is allowed to be delayed before it's invoked.\n  - `equalityFn` (optional): A custom equality function to compare the current and previous values.\n\n### Returns\n\nAn array containing the debounced value and the function to update it.\n\n### Dependency\n\nThis hook is built upon [`lodash.debounce`](https://www.npmjs.com/package/lodash.debounce).\n\n### Related hooks\n\n- [`useDebounceCallback`](/react-hook/use-debounce-callback): `useDebounceValue` is built on top of `useDebounceCallback`, it gives more control.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceValue/useDebounceValue.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useDebounceValue } from './useDebounceValue'\n\ndescribe('useDebounceValue()', () => {\n  vitest.useFakeTimers()\n\n  it('should debounce the value update', () => {\n    const { result } = renderHook(() => useDebounceValue('initial', 100))\n\n    expect(result.current[0]).toBe('initial')\n\n    act(() => {\n      result.current[1]('update1')\n      result.current[1]('update2')\n      result.current[1]('update3')\n    })\n\n    expect(result.current[0]).toBe('initial')\n\n    // Advance timers by more than delay\n    act(() => {\n      vitest.advanceTimersByTime(200)\n    })\n\n    expect(result.current[0]).toBe('update3')\n\n    // Advance timers by more than delay again\n    act(() => {\n      vitest.advanceTimersByTime(200)\n    })\n\n    expect(result.current[0]).toBe('update3')\n  })\n\n  it('should handle options', () => {\n    const delay = 500\n    const { result } = renderHook(() =>\n      useDebounceValue('initial', delay, { leading: true }),\n    )\n\n    expect(result.current[0]).toBe('initial')\n\n    act(() => {\n      result.current[1]('updated')\n    })\n\n    // The debounced value should be updated immediately due to leading option\n    expect(result.current[0]).toBe('updated')\n\n    // Wait for the debounce interval to elapse\n    vitest.advanceTimersByTime(delay)\n\n    // The debounced value should not be updated again after the interval\n    expect(result.current[0]).toBe('updated')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDebounceValue/useDebounceValue.ts",
    "content": "import { useRef, useState } from 'react'\n\nimport type { DebouncedState } from '../useDebounceCallback'\nimport { useDebounceCallback } from '../useDebounceCallback'\n\n/**\n * Hook options.\n * @template T - The type of the value.\n */\ntype UseDebounceValueOptions<T> = {\n  /**\n   * Determines whether the function should be invoked on the leading edge of the timeout.\n   * @default false\n   */\n  leading?: boolean\n  /**\n   * Determines whether the function should be invoked on the trailing edge of the timeout.\n   * @default false\n   */\n  trailing?: boolean\n  /**\n   * The maximum time the specified function is allowed to be delayed before it is invoked.\n   */\n  maxWait?: number\n  /** A function to determine if the value has changed. Defaults to a function that checks if the value is strictly equal to the previous value. */\n  equalityFn?: (left: T, right: T) => boolean\n}\n\n/**\n * Custom hook that returns a debounced version of the provided value, along with a function to update it.\n * @template T - The type of the value.\n * @param {T | (() => T)} initialValue - The value to be debounced.\n * @param {number} delay - The delay in milliseconds before the value is updated (default is 500ms).\n * @param {object} [options] - Optional configurations for the debouncing behavior.\n * @returns {[T, DebouncedState<(value: T) => void>]} An array containing the debounced value and the function to update it.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-debounce-value)\n * @example\n * ```tsx\n * const [debouncedValue, updateDebouncedValue] = useDebounceValue(inputValue, 500, { leading: true });\n * ```\n */\nexport function useDebounceValue<T>(\n  initialValue: T | (() => T),\n  delay: number,\n  options?: UseDebounceValueOptions<T>,\n): [T, DebouncedState<(value: T) => void>] {\n  const eq = options?.equalityFn ?? ((left: T, right: T) => left === right)\n  const unwrappedInitialValue =\n    initialValue instanceof Function ? initialValue() : initialValue\n  const [debouncedValue, setDebouncedValue] = useState<T>(unwrappedInitialValue)\n  const previousValueRef = useRef<T | undefined>(unwrappedInitialValue)\n\n  const updateDebouncedValue = useDebounceCallback(\n    setDebouncedValue,\n    delay,\n    options,\n  )\n\n  // Update the debounced value if the initial value changes\n  if (!eq(previousValueRef.current as T, unwrappedInitialValue)) {\n    updateDebouncedValue(unwrappedInitialValue)\n    previousValueRef.current = unwrappedInitialValue\n  }\n\n  return [debouncedValue, updateDebouncedValue]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDocumentTitle/index.ts",
    "content": "export * from './useDocumentTitle'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDocumentTitle/useDocumentTitle.demo.tsx",
    "content": "import { useDocumentTitle } from './useDocumentTitle'\n\nexport default function Component() {\n  useDocumentTitle('foo bar')\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDocumentTitle/useDocumentTitle.md",
    "content": "An easy way to set the title of the current document.\n\nSetting `preserveTitleOnUnmount` to `false` allows the document title to be reset to its default value (defined by the `<title>` tag) when the component is unmounted.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDocumentTitle/useDocumentTitle.test.ts",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { useDocumentTitle } from './useDocumentTitle'\n\ndescribe('useDocumentTitle()', () => {\n  it('title should be in the document', () => {\n    renderHook(() => {\n      useDocumentTitle('foo')\n    })\n    expect(window.document.title).toEqual('foo')\n  })\n\n  it('should unset title on unmount with `preserveTitleOnUnmount` options to `false`', () => {\n    window.document.title = 'initial'\n    const { unmount } = renderHook(() => {\n      useDocumentTitle('updated', { preserveTitleOnUnmount: false })\n    })\n    expect(window.document.title).toEqual('updated')\n    unmount()\n    expect(window.document.title).toEqual('initial')\n  })\n\n  it(\"shouldn't unset title on unmount with `preserveTitleOnUnmount` options to `true` (default)\", () => {\n    window.document.title = 'initial'\n    const { unmount } = renderHook(() => {\n      useDocumentTitle('updated')\n    })\n    expect(window.document.title).toEqual('updated')\n    unmount()\n    expect(window.document.title).toEqual('updated')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useDocumentTitle/useDocumentTitle.ts",
    "content": "import { useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\nimport { useUnmount } from '../useUnmount'\n\n/** Hook options. */\ntype UseDocumentTitleOptions = {\n  /** Whether to keep the title after unmounting the component (default is `true`). */\n  preserveTitleOnUnmount?: boolean\n}\n\n/**\n * Custom hook that sets the document title.\n * @param {string} title - The title to set.\n * @param {?UseDocumentTitleOptions} [options] - The options.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-document-title)\n * @example\n * ```tsx\n * useDocumentTitle('My new title');\n * ```\n */\nexport function useDocumentTitle(\n  title: string,\n  options: UseDocumentTitleOptions = {},\n): void {\n  const { preserveTitleOnUnmount = true } = options\n  const defaultTitle = useRef<string | null>(null)\n\n  useIsomorphicLayoutEffect(() => {\n    defaultTitle.current = window.document.title\n  }, [])\n\n  useIsomorphicLayoutEffect(() => {\n    window.document.title = title\n  }, [title])\n\n  useUnmount(() => {\n    if (!preserveTitleOnUnmount && defaultTitle.current) {\n      window.document.title = defaultTitle.current\n    }\n  })\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventCallback/index.ts",
    "content": "export * from './useEventCallback'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventCallback/useEventCallback.demo.tsx",
    "content": "import { useEventCallback } from './useEventCallback'\n\nexport default function Component() {\n  const handleClick = useEventCallback(event => {\n    // Handle the event here\n    console.log('Clicked', event)\n  })\n\n  return <button onClick={handleClick}>Click me</button>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventCallback/useEventCallback.md",
    "content": "The `useEventCallback` hook is a utility for creating memoized event callback functions in React applications. It ensures that the provided callback function is memoized and stable across renders, while also preventing its invocation during the render phase.\n\nSee: [How to read an often-changing value from useCallback?](https://legacy.reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback)\n\n### Parameters\n\n- `fn: (args) => result` - The callback function to be memoized.\n\n### Return Value\n\n- `(args) => result` - A memoized event callback function.\n\n### Features\n\n- **Memoization**: Optimizes performance by memoizing the callback function to avoid unnecessary re-renders.\n- **Prevents Invocation During Render**: Ensures the callback isn't called during rendering, preventing potential issues.\n- **Error Handling**: Throws an error if the callback is mistakenly invoked during rendering.\n- **Strict Mode Compatibility**: Works seamlessly with React's strict mode for better debugging and reliability.\n\n### Notes\n\nAvoid using `useEventCallback` for callback functions that depend on frequently changing state or props.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventCallback/useEventCallback.test.tsx",
    "content": "import { fireEvent, render, renderHook, screen } from '@testing-library/react'\nimport type { Mock } from 'vitest'\n\nimport { useEventCallback } from './useEventCallback'\n\ndescribe('useEventCallback()', () => {\n  it('should not call the callback during render', () => {\n    const fn = vi.fn()\n    const { result } = renderHook(() => useEventCallback(fn))\n\n    render(<button onClick={result.current}>Click me</button>)\n\n    expect(fn).not.toHaveBeenCalled()\n  })\n\n  it('should call the callback when the event is triggered', () => {\n    const fn = vi.fn()\n    const { result } = renderHook(() => useEventCallback(fn))\n\n    render(<button onClick={result.current}>Click me</button>)\n\n    fireEvent.click(screen.getByText('Click me'))\n\n    expect(fn).toHaveBeenCalled()\n  })\n\n  it('should be typed accordingly', () => {\n    const fn1: Mock<[React.MouseEvent<HTMLButtonElement>], void> = vi.fn()\n    const fn1Result = renderHook(() => useEventCallback(fn1))\n\n    expectTypeOf(fn1Result.result.current).toEqualTypeOf<\n      (event: React.MouseEvent<HTMLButtonElement>) => void\n    >()\n\n    const fn2 = undefined as\n      | Mock<[React.MouseEvent<HTMLButtonElement>], void>\n      | undefined\n    const fn2Result = renderHook(() => useEventCallback(fn2))\n\n    expectTypeOf(fn2Result.result.current).toEqualTypeOf<\n      ((event: React.MouseEvent<HTMLButtonElement>) => void) | undefined\n    >()\n  })\n\n  it('should allow to pass optional callback without errors', () => {\n    const optionalFn = undefined as\n      | ((event: React.MouseEvent<HTMLButtonElement>) => void)\n      | undefined\n\n    const { result } = renderHook(() => useEventCallback(optionalFn))\n\n    render(<button onClick={result.current}>Click me</button>)\n\n    fireEvent.click(screen.getByText('Click me'))\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventCallback/useEventCallback.ts",
    "content": "import { useCallback, useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/**\n * Custom hook that creates a memoized event callback.\n * @template Args - An array of argument types for the event callback.\n * @template R - The return type of the event callback.\n * @param {(...args: Args) => R} fn - The callback function.\n * @returns {(...args: Args) => R} A memoized event callback function.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-event-callback)\n * @example\n * ```tsx\n * const handleClick = useEventCallback((event) => {\n *   // Handle the event here\n * });\n * ```\n */\nexport function useEventCallback<Args extends unknown[], R>(\n  fn: (...args: Args) => R,\n): (...args: Args) => R\nexport function useEventCallback<Args extends unknown[], R>(\n  fn: ((...args: Args) => R) | undefined,\n): ((...args: Args) => R) | undefined\nexport function useEventCallback<Args extends unknown[], R>(\n  fn: ((...args: Args) => R) | undefined,\n): ((...args: Args) => R) | undefined {\n  const ref = useRef<typeof fn>(() => {\n    throw new Error('Cannot call an event handler while rendering.')\n  })\n\n  useIsomorphicLayoutEffect(() => {\n    ref.current = fn\n  }, [fn])\n\n  return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (\n    ...args: Args\n  ) => R\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventListener/index.ts",
    "content": "export * from './useEventListener'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventListener/useEventListener.demo.tsx",
    "content": "import { useRef } from 'react'\n\nimport { useEventListener } from './useEventListener'\n\nexport default function Component() {\n  // Define button ref\n  const buttonRef = useRef<HTMLButtonElement>(null)\n  const documentRef = useRef<Document>(document)\n\n  const onScroll = (event: Event) => {\n    console.log('window scrolled!', event)\n  }\n\n  const onClick = (event: Event) => {\n    console.log('button clicked!', event)\n  }\n\n  const onVisibilityChange = (event: Event) => {\n    console.log('doc visibility changed!', {\n      isVisible: !document.hidden,\n      event,\n    })\n  }\n\n  // example with window based event\n  useEventListener('scroll', onScroll)\n\n  // example with document based event\n  useEventListener('visibilitychange', onVisibilityChange, documentRef)\n\n  // example with element based event\n  useEventListener('click', onClick, buttonRef)\n\n  return (\n    <div style={{ minHeight: '200vh' }}>\n      <button ref={buttonRef}>Click me</button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventListener/useEventListener.md",
    "content": "Use EventListener with simplicity by React Hook.\n\nSupports `Window`, `Element` and `Document` and custom events with almost the same parameters as the native [`addEventListener` options](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#syntax). See examples below.\n\nIf you want to use your CustomEvent using Typescript, you have to declare the event type.\nFind which kind of Event you want to extends:\n\n- `MediaQueryListEventMap`\n- `WindowEventMap`\n- `HTMLElementEventMap`\n- `DocumentEventMap`\n\nThen declare your custom event:\n\n```ts\ndeclare global {\n  interface DocumentEventMap {\n    'my-custom-event': CustomEvent<{ exampleArg: string }>\n  }\n}\n```\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventListener/useEventListener.test.ts",
    "content": "/* eslint-disable @typescript-eslint/consistent-type-definitions */\nimport { fireEvent, renderHook } from '@testing-library/react'\n\nimport { useEventListener } from './useEventListener'\n\ndeclare global {\n  interface WindowEventMap {\n    'test-event': CustomEvent\n  }\n\n  interface HTMLElementEventMap {\n    'test-event': CustomEvent\n  }\n\n  interface SVGElementEventMap {\n    'test-event': CustomEvent\n  }\n\n  interface DocumentEventMap {\n    'test-event': CustomEvent\n  }\n}\n\nconst windowAddEventListenerSpy = vitest.spyOn(window, 'addEventListener')\nconst windowRemoveEventListenerSpy = vitest.spyOn(window, 'removeEventListener')\n\nconst ref = { current: document.createElement('div') }\nconst refAddEventListenerSpy = vitest.spyOn(ref.current, 'addEventListener')\nconst refRemoveEventListenerSpy = vitest.spyOn(\n  ref.current,\n  'removeEventListener',\n)\n\nconst docRef = { current: window.document }\nconst docAddEventListenerSpy = vitest.spyOn(docRef.current, 'addEventListener')\nconst docRemoveEventListenerSpy = vitest.spyOn(\n  docRef.current,\n  'removeEventListener',\n)\n\ndescribe('useEventListener()', () => {\n  afterEach(() => {\n    vitest.clearAllMocks()\n  })\n\n  it('should bind/unbind the event listener to the window when element is not provided', () => {\n    const eventName = 'test-event'\n    const handler = vitest.fn()\n    const options = undefined\n\n    const { unmount } = renderHook(() => {\n      useEventListener(eventName, handler)\n    })\n\n    expect(windowAddEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n\n    unmount()\n\n    expect(windowRemoveEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n  })\n\n  it('should bind/unbind the event listener to the element when element is provided', () => {\n    const eventName = 'test-event'\n    const handler = vitest.fn()\n    const options = undefined\n\n    const { unmount } = renderHook(() => {\n      useEventListener(eventName, handler, ref, options)\n    })\n\n    expect(refAddEventListenerSpy).toHaveBeenCalledTimes(1)\n    expect(refAddEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n\n    unmount()\n\n    expect(refRemoveEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n  })\n\n  it('should bind/unbind the event listener to the document when document is provided', () => {\n    const eventName = 'test-event'\n    const handler = vitest.fn()\n    const options = undefined\n\n    const { unmount } = renderHook(() => {\n      useEventListener(eventName, handler, docRef, options)\n    })\n\n    expect(docAddEventListenerSpy).toHaveBeenCalledTimes(1)\n    expect(docAddEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n\n    unmount()\n\n    expect(docRemoveEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n  })\n\n  it('should pass the options to the event listener', () => {\n    const eventName = 'test-event'\n    const handler = vitest.fn()\n    const options = {\n      passive: true,\n      once: true,\n      capture: true,\n    }\n\n    renderHook(() => {\n      useEventListener(eventName, handler, undefined, options)\n    })\n\n    expect(windowAddEventListenerSpy).toHaveBeenCalledWith(\n      eventName,\n      expect.any(Function),\n      options,\n    )\n  })\n\n  it('should call the event listener handler when the event is triggered', () => {\n    const eventName = 'click'\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useEventListener(eventName, handler, ref)\n    })\n\n    fireEvent.click(ref.current)\n\n    expect(handler).toHaveBeenCalledTimes(1)\n  })\n\n  it('should have the correct event type', () => {\n    const clickHandler = vitest.fn()\n    const keydownHandler = vitest.fn()\n\n    renderHook(() => {\n      useEventListener('click', clickHandler, ref)\n    })\n    renderHook(() => {\n      useEventListener('keydown', keydownHandler, ref)\n    })\n\n    fireEvent.click(ref.current)\n    fireEvent.keyDown(ref.current)\n\n    expect(clickHandler).toHaveBeenCalledWith(expect.any(MouseEvent))\n    expect(keydownHandler).toHaveBeenCalledWith(expect.any(KeyboardEvent))\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useEventListener/useEventListener.ts",
    "content": "import { useEffect, useRef } from 'react'\n\nimport type { RefObject } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect'\n\n// MediaQueryList Event based useEventListener interface\nfunction useEventListener<K extends keyof MediaQueryListEventMap>(\n  eventName: K,\n  handler: (event: MediaQueryListEventMap[K]) => void,\n  element: RefObject<MediaQueryList>,\n  options?: boolean | AddEventListenerOptions,\n): void\n\n// Window Event based useEventListener interface\nfunction useEventListener<K extends keyof WindowEventMap>(\n  eventName: K,\n  handler: (event: WindowEventMap[K]) => void,\n  element?: undefined,\n  options?: boolean | AddEventListenerOptions,\n): void\n\n// Element Event based useEventListener interface\nfunction useEventListener<\n  K extends keyof HTMLElementEventMap & keyof SVGElementEventMap,\n  T extends Element = K extends keyof HTMLElementEventMap\n    ? HTMLDivElement\n    : SVGElement,\n>(\n  eventName: K,\n  handler:\n    | ((event: HTMLElementEventMap[K]) => void)\n    | ((event: SVGElementEventMap[K]) => void),\n  element: RefObject<T>,\n  options?: boolean | AddEventListenerOptions,\n): void\n\n// Document Event based useEventListener interface\nfunction useEventListener<K extends keyof DocumentEventMap>(\n  eventName: K,\n  handler: (event: DocumentEventMap[K]) => void,\n  element: RefObject<Document>,\n  options?: boolean | AddEventListenerOptions,\n): void\n\n/**\n * Custom hook that attaches event listeners to DOM elements, the window, or media query lists.\n * @template KW - The type of event for window events.\n * @template KH - The type of event for HTML or SVG element events.\n * @template KM - The type of event for media query list events.\n * @template T - The type of the DOM element (default is `HTMLElement`).\n * @param {KW | KH | KM} eventName - The name of the event to listen for.\n * @param {(event: WindowEventMap[KW] | HTMLElementEventMap[KH] | SVGElementEventMap[KH] | MediaQueryListEventMap[KM] | Event) => void} handler - The event handler function.\n * @param {RefObject<T>} [element] - The DOM element or media query list to attach the event listener to (optional).\n * @param {boolean | AddEventListenerOptions} [options] - An options object that specifies characteristics about the event listener (optional).\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-event-listener)\n * @example\n * ```tsx\n * // Example 1: Attach a window event listener\n * useEventListener('resize', handleResize);\n * ```\n * @example\n * ```tsx\n * // Example 2: Attach a document event listener with options\n * const elementRef = useRef(document);\n * useEventListener('click', handleClick, elementRef, { capture: true });\n * ```\n * @example\n * ```tsx\n * // Example 3: Attach an element event listener\n * const buttonRef = useRef<HTMLButtonElement>(null);\n * useEventListener('click', handleButtonClick, buttonRef);\n * ```\n */\nfunction useEventListener<\n  KW extends keyof WindowEventMap,\n  KH extends keyof HTMLElementEventMap & keyof SVGElementEventMap,\n  KM extends keyof MediaQueryListEventMap,\n  T extends HTMLElement | SVGAElement | MediaQueryList = HTMLElement,\n>(\n  eventName: KW | KH | KM,\n  handler: (\n    event:\n      | WindowEventMap[KW]\n      | HTMLElementEventMap[KH]\n      | SVGElementEventMap[KH]\n      | MediaQueryListEventMap[KM]\n      | Event,\n  ) => void,\n  element?: RefObject<T>,\n  options?: boolean | AddEventListenerOptions,\n) {\n  // Create a ref that stores handler\n  const savedHandler = useRef(handler)\n\n  useIsomorphicLayoutEffect(() => {\n    savedHandler.current = handler\n  }, [handler])\n\n  useEffect(() => {\n    // Define the listening target\n    const targetElement: T | Window = element?.current ?? window\n\n    if (!(targetElement && targetElement.addEventListener)) return\n\n    // Create event listener that calls handler function stored in ref\n    const listener: typeof handler = event => {\n      savedHandler.current(event)\n    }\n\n    targetElement.addEventListener(eventName, listener, options)\n\n    // Remove event listener on cleanup\n    return () => {\n      targetElement.removeEventListener(eventName, listener, options)\n    }\n  }, [eventName, element, options])\n}\n\nexport { useEventListener }\n"
  },
  {
    "path": "packages/usehooks-ts/src/useHover/index.ts",
    "content": "export * from './useHover'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useHover/useHover.demo.tsx",
    "content": "import { useRef } from 'react'\n\nimport { useHover } from './useHover'\n\nexport default function Component() {\n  const hoverRef = useRef(null)\n  const isHover = useHover(hoverRef)\n\n  return (\n    <div ref={hoverRef}>\n      {`The current div is ${isHover ? `hovered` : `unhovered`}`}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useHover/useHover.md",
    "content": "React UI sensor hook that determine if the mouse element is in the hover element using Typescript instead CSS.\nThis way you can separate the logic from the UI.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useHover/useHover.test.ts",
    "content": "import { act, fireEvent, renderHook } from '@testing-library/react'\n\nimport { useHover } from './useHover'\n\ndescribe('useHover()', () => {\n  const el = {\n    current: document.createElement('div'),\n  }\n\n  it('result must be initially false', () => {\n    const { result } = renderHook(() => useHover(el))\n    expect(result.current).toBe(false)\n  })\n\n  it('value must be true when firing hover action on element', () => {\n    const { result } = renderHook(() => useHover(el))\n\n    expect(result.current).toBe(false)\n\n    act(() => void fireEvent.mouseEnter(el.current))\n    expect(result.current).toBe(true)\n  })\n\n  it('value must turn back into false when firing mouseleave action on element', () => {\n    const { result } = renderHook(() => useHover(el))\n\n    expect(result.current).toBe(false)\n\n    act(() => void fireEvent.mouseEnter(el.current))\n    expect(result.current).toBe(true)\n\n    act(() => void fireEvent.mouseLeave(el.current))\n    expect(result.current).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useHover/useHover.ts",
    "content": "import { useState } from 'react'\n\nimport type { RefObject } from 'react'\n\nimport { useEventListener } from '../useEventListener'\n\n/**\n * Custom hook that tracks whether a DOM element is being hovered over.\n * @template T - The type of the DOM element. Defaults to `HTMLElement`.\n * @param {RefObject<T>} elementRef - The ref object for the DOM element to track.\n * @returns {boolean} A boolean value indicating whether the element is being hovered over.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-hover)\n * @example\n * ```tsx\n * const buttonRef = useRef<HTMLButtonElement>(null);\n * const isHovered = useHover(buttonRef);\n * // Access the isHovered variable to determine if the button is being hovered over.\n * ```\n */\nexport function useHover<T extends HTMLElement = HTMLElement>(\n  elementRef: RefObject<T>,\n): boolean {\n  const [value, setValue] = useState<boolean>(false)\n\n  const handleMouseEnter = () => {\n    setValue(true)\n  }\n  const handleMouseLeave = () => {\n    setValue(false)\n  }\n\n  useEventListener('mouseenter', handleMouseEnter, elementRef)\n  useEventListener('mouseleave', handleMouseLeave, elementRef)\n\n  return value\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIntersectionObserver/index.ts",
    "content": "export * from './useIntersectionObserver'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIntersectionObserver/useIntersectionObserver.demo.tsx",
    "content": "import { useIntersectionObserver } from './useIntersectionObserver'\n\nconst Section = (props: { title: string }) => {\n  const { isIntersecting, ref } = useIntersectionObserver({\n    threshold: 0.5,\n  })\n\n  console.log(`Render Section ${props.title}`, {\n    isIntersecting,\n  })\n\n  return (\n    <div\n      ref={ref}\n      style={{\n        minHeight: '100vh',\n        display: 'flex',\n        border: '1px dashed #000',\n        fontSize: '2rem',\n      }}\n    >\n      <div style={{ margin: 'auto' }}>{props.title}</div>\n    </div>\n  )\n}\n\nexport default function Component() {\n  return (\n    <>\n      {Array.from({ length: 5 }).map((_, index) => (\n        <Section key={index + 1} title={`${index + 1}`} />\n      ))}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIntersectionObserver/useIntersectionObserver.md",
    "content": "This React Hook detects visibility of a component on the viewport using the [`IntersectionObserver` API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) natively present in the browser.\n\nIt can be very useful to lazy-loading of images, implementing \"infinite scrolling\", tracking view in GA or starting animations for example.\n\n### Option properties\n\n- `threshold` (optional, default: `0`): A threshold indicating the percentage of the target's visibility needed to trigger the callback. Can be a single number or an array of numbers.\n- `root` (optional, default: `null`): The element that is used as the viewport for checking visibility of the target. It can be an Element, Document, or null.\n- `rootMargin` (optional, default: `'0%'`): A margin around the root. It specifies the size of the root's margin area.\n- `freezeOnceVisible` (optional, default: `false`): If true, freezes the intersection state once the element becomes visible. Once the element enters the viewport and triggers the callback, further changes in intersection will not update the state.\n- `onChange` (optional): A callback function to be invoked when the intersection state changes. It receives two parameters: `isIntersecting` (a boolean indicating if the element is intersecting) and `entry` (an IntersectionObserverEntry object representing the state of the intersection).\n- `initialIsIntersecting` (optional, default: `false`): The initial state of the intersection. If set to true, indicates that the element is intersecting initially.\n\n**Note:** This interface extends the native `IntersectionObserverInit` interface, which provides the base options for configuring the Intersection Observer.\n\nFor more information on the Intersection Observer API and its options, refer to the [MDN Intersection Observer API documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).\n\n### Return\n\nThe `IntersectionResult` type supports both array and object destructuring and includes the following properties:\n\n- `ref`: A function that can be used as a ref callback to set the target element.\n- `isIntersecting`: A boolean indicating if the target element is intersecting with the viewport.\n- `entry`: An optional `IntersectionObserverEntry` object representing the state of the intersection.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIntersectionObserver/useIntersectionObserver.ts",
    "content": "import { useEffect, useRef, useState } from 'react'\n\n/** The hook internal state. */\ntype State = {\n  /** A boolean indicating if the element is intersecting. */\n  isIntersecting: boolean\n  /** The intersection observer entry. */\n  entry?: IntersectionObserverEntry\n}\n\n/** Represents the options for configuring the Intersection Observer. */\ntype UseIntersectionObserverOptions = {\n  /**\n   * The element that is used as the viewport for checking visibility of the target.\n   * @default null\n   */\n  root?: Element | Document | null\n  /**\n   * A margin around the root.\n   * @default '0%'\n   */\n  rootMargin?: string\n  /**\n   * A threshold indicating the percentage of the target's visibility needed to trigger the callback.\n   * @default 0\n   */\n  threshold?: number | number[]\n  /**\n   * If true, freezes the intersection state once the element becomes visible.\n   * @default false\n   */\n  freezeOnceVisible?: boolean\n  /**\n   * A callback function to be invoked when the intersection state changes.\n   * @param {boolean} isIntersecting - A boolean indicating if the element is intersecting.\n   * @param {IntersectionObserverEntry} entry - The intersection observer Entry.\n   * @default undefined\n   */\n  onChange?: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void\n  /**\n   * The initial state of the intersection.\n   * @default false\n   */\n  initialIsIntersecting?: boolean\n}\n\n/**\n * The return type of the useIntersectionObserver hook.\n *\n * Supports both tuple and object destructing.\n * @param {(node: Element | null) => void} ref - The ref callback function.\n * @param {boolean} isIntersecting - A boolean indicating if the element is intersecting.\n * @param {IntersectionObserverEntry | undefined} entry - The intersection observer Entry.\n */\ntype IntersectionReturn = [\n  (node?: Element | null) => void,\n  boolean,\n  IntersectionObserverEntry | undefined,\n] & {\n  ref: (node?: Element | null) => void\n  isIntersecting: boolean\n  entry?: IntersectionObserverEntry\n}\n\n/**\n * Custom hook that tracks the intersection of a DOM element with its containing element or the viewport using the [`Intersection Observer API`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).\n * @param {UseIntersectionObserverOptions} options - The options for the Intersection Observer.\n * @returns {IntersectionReturn} The ref callback, a boolean indicating if the element is intersecting, and the intersection observer entry.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-intersection-observer)\n * @example\n * ```tsx\n * // Example 1\n * const [ref, isIntersecting, entry] = useIntersectionObserver({ threshold: 0.5 });\n * ```\n *\n * ```tsx\n * // Example 2\n * const { ref, isIntersecting, entry } = useIntersectionObserver({ threshold: 0.5 });\n * ```\n */\nexport function useIntersectionObserver({\n  threshold = 0,\n  root = null,\n  rootMargin = '0%',\n  freezeOnceVisible = false,\n  initialIsIntersecting = false,\n  onChange,\n}: UseIntersectionObserverOptions = {}): IntersectionReturn {\n  const [ref, setRef] = useState<Element | null>(null)\n\n  const [state, setState] = useState<State>(() => ({\n    isIntersecting: initialIsIntersecting,\n    entry: undefined,\n  }))\n\n  const callbackRef = useRef<UseIntersectionObserverOptions['onChange']>()\n\n  callbackRef.current = onChange\n\n  const frozen = state.entry?.isIntersecting && freezeOnceVisible\n\n  useEffect(() => {\n    // Ensure we have a ref to observe\n    if (!ref) return\n\n    // Ensure the browser supports the Intersection Observer API\n    if (!('IntersectionObserver' in window)) return\n\n    // Skip if frozen\n    if (frozen) return\n\n    let unobserve: (() => void) | undefined\n\n    const observer = new IntersectionObserver(\n      (entries: IntersectionObserverEntry[]): void => {\n        const thresholds = Array.isArray(observer.thresholds)\n          ? observer.thresholds\n          : [observer.thresholds]\n\n        entries.forEach(entry => {\n          const isIntersecting =\n            entry.isIntersecting &&\n            thresholds.some(threshold => entry.intersectionRatio >= threshold)\n\n          setState({ isIntersecting, entry })\n\n          if (callbackRef.current) {\n            callbackRef.current(isIntersecting, entry)\n          }\n\n          if (isIntersecting && freezeOnceVisible && unobserve) {\n            unobserve()\n            unobserve = undefined\n          }\n        })\n      },\n      { threshold, root, rootMargin },\n    )\n\n    observer.observe(ref)\n\n    return () => {\n      observer.disconnect()\n    }\n\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [\n    ref,\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    JSON.stringify(threshold),\n    root,\n    rootMargin,\n    frozen,\n    freezeOnceVisible,\n  ])\n\n  // ensures that if the observed element changes, the intersection observer is reinitialized\n  const prevRef = useRef<Element | null>(null)\n\n  useEffect(() => {\n    if (\n      !ref &&\n      state.entry?.target &&\n      !freezeOnceVisible &&\n      !frozen &&\n      prevRef.current !== state.entry.target\n    ) {\n      prevRef.current = state.entry.target\n      setState({ isIntersecting: initialIsIntersecting, entry: undefined })\n    }\n  }, [ref, state.entry, freezeOnceVisible, frozen, initialIsIntersecting])\n\n  const result = [\n    setRef,\n    !!state.isIntersecting,\n    state.entry,\n  ] as IntersectionReturn\n\n  // Support object destructuring, by adding the specific values.\n  result.ref = result[0]\n  result.isIntersecting = result[1]\n  result.entry = result[2]\n\n  return result\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useInterval/index.ts",
    "content": "export * from './useInterval'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useInterval/useInterval.demo.tsx",
    "content": "import { useState } from 'react'\n\nimport type { ChangeEvent } from 'react'\n\nimport { useInterval } from './useInterval'\n\nexport default function Component() {\n  // The counter\n  const [count, setCount] = useState<number>(0)\n  // Dynamic delay\n  const [delay, setDelay] = useState<number>(1000)\n  // ON/OFF\n  const [isPlaying, setPlaying] = useState<boolean>(false)\n\n  useInterval(\n    () => {\n      // Your custom logic here\n      setCount(count + 1)\n    },\n    // Delay in milliseconds or null to stop it\n    isPlaying ? delay : null,\n  )\n\n  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n    setDelay(Number(event.target.value))\n  }\n\n  return (\n    <>\n      <h1>{count}</h1>\n      <button\n        onClick={() => {\n          setPlaying(!isPlaying)\n        }}\n      >\n        {isPlaying ? 'pause' : 'play'}\n      </button>\n      <p>\n        <label htmlFor=\"delay\">Delay: </label>\n        <input\n          type=\"number\"\n          name=\"delay\"\n          onChange={handleChange}\n          value={delay}\n        />\n      </p>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useInterval/useInterval.md",
    "content": "Use [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) in functional React component with the same API.\nSet your callback function as a first parameter and a delay (in milliseconds) for the second argument. You can also stop the timer passing `null` instead the delay or even, execute it right away passing `0`.\n\nThe main difference between the `setInterval` you know and this `useInterval` hook is that its arguments are \"dynamic\". You can get more information in the Dan Abramov's [blog post](https://overreacted.io/making-setinterval-declarative-with-react-hooks/).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useInterval/useInterval.test.ts",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { useInterval } from './useInterval'\n\ndescribe('useInterval()', () => {\n  beforeEach(() => {\n    vitest.clearAllMocks()\n    vitest.useFakeTimers()\n  })\n\n  it('should fire the callback function (1)', () => {\n    const timeout = 500\n    const callback = vitest.fn()\n    renderHook(() => {\n      useInterval(callback, timeout)\n    })\n    vitest.advanceTimersByTime(timeout)\n    expect(callback).toHaveBeenCalledTimes(1)\n  })\n\n  it('should fire the callback function (2)', () => {\n    const timeout = 500\n    const earlyTimeout = 400\n    const callback = vitest.fn()\n    renderHook(() => {\n      useInterval(callback, timeout)\n    })\n    vitest.advanceTimersByTime(earlyTimeout)\n    expect(callback).not.toHaveBeenCalled()\n  })\n\n  it('should call set interval on start', () => {\n    mockSetInterval()\n    const timeout = 1200\n    const callback = vitest.fn()\n    renderHook(() => {\n      useInterval(callback, timeout)\n    })\n    expect(setInterval).toHaveBeenCalledTimes(1)\n    expect(setInterval).toHaveBeenCalledWith(expect.any(Function), timeout)\n  })\n\n  it('should call clearTimeout on unmount', () => {\n    mockClearInterval()\n    const callback = vitest.fn()\n    const { unmount } = renderHook(() => {\n      useInterval(callback, 1200)\n    })\n    unmount()\n    expect(clearInterval).toHaveBeenCalledTimes(1)\n  })\n})\n\nfunction mockSetInterval() {\n  vitest.spyOn(global, 'setInterval')\n}\n\nfunction mockClearInterval() {\n  vitest.spyOn(global, 'clearInterval')\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useInterval/useInterval.ts",
    "content": "import { useEffect, useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/**\n * Custom hook that creates an interval that invokes a callback function at a specified delay using the [`setInterval API`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval).\n * @param {() => void} callback - The function to be invoked at each interval.\n * @param {number | null} delay - The time, in milliseconds, between each invocation of the callback. Use `null` to clear the interval.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-interval)\n * @example\n * ```tsx\n * const handleInterval = () => {\n *   // Code to be executed at each interval\n * };\n * useInterval(handleInterval, 1000);\n * ```\n */\nexport function useInterval(callback: () => void, delay: number | null) {\n  const savedCallback = useRef(callback)\n\n  // Remember the latest callback if it changes.\n  useIsomorphicLayoutEffect(() => {\n    savedCallback.current = callback\n  }, [callback])\n\n  // Set up the interval.\n  useEffect(() => {\n    // Don't schedule if no delay is specified.\n    // Note: 0 is a valid value for delay.\n    if (delay === null) {\n      return\n    }\n\n    const id = setInterval(() => {\n      savedCallback.current()\n    }, delay)\n\n    return () => {\n      clearInterval(id)\n    }\n  }, [delay])\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsClient/index.ts",
    "content": "export * from './useIsClient'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsClient/useIsClient.demo.tsx",
    "content": "import { useIsClient } from './useIsClient'\n\nexport default function Component() {\n  const isClient = useIsClient()\n\n  return <div>{isClient ? 'Client' : 'server'}</div>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsClient/useIsClient.md",
    "content": "This React Hook can be useful in a SSR environment to wait until be in a browser to execution some functions.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsClient/useIsClient.test.ts",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { useIsClient } from './useIsClient'\n\ndescribe('useIsClient()', () => {\n  // TODO: currently don't know how to simulate hydration of hooks. @see https://github.com/testing-library/react-testing-library/issues/1120\n  it.skip('should be false when rendering on the server', () => {\n    const { result } = renderHook(() => useIsClient(), { hydrate: false })\n    expect(result.current).toBe(false)\n  })\n\n  it('should be true when after hydration', () => {\n    const { result } = renderHook(() => useIsClient(), { hydrate: true })\n    expect(result.current).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsClient/useIsClient.ts",
    "content": "import { useEffect, useState } from 'react'\n\n/**\n * Custom hook that determines if the code is running on the client side (in the browser).\n * @returns {boolean} A boolean value indicating whether the code is running on the client side.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-is-client)\n * @example\n * ```tsx\n * const isClient = useIsClient();\n * // Use isClient to conditionally render or execute code specific to the client side.\n * ```\n */\nexport function useIsClient() {\n  const [isClient, setClient] = useState(false)\n\n  useEffect(() => {\n    setClient(true)\n  }, [])\n\n  return isClient\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsMounted/index.ts",
    "content": "export * from './useIsMounted'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsMounted/useIsMounted.demo.tsx",
    "content": "import { useEffect, useState } from 'react'\n\nimport { useIsMounted } from './useIsMounted'\n\nconst delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))\n\nfunction Child() {\n  const [data, setData] = useState('loading')\n  const isMounted = useIsMounted()\n\n  // simulate an api call and update state\n  useEffect(() => {\n    void delay(3000).then(() => {\n      if (isMounted()) setData('OK')\n    })\n  }, [isMounted])\n\n  return <p>{data}</p>\n}\n\nexport default function Component() {\n  const [isVisible, setVisible] = useState<boolean>(false)\n\n  const toggleVisibility = () => {\n    setVisible(state => !state)\n  }\n\n  return (\n    <>\n      <button onClick={toggleVisibility}>{isVisible ? 'Hide' : 'Show'}</button>\n\n      {isVisible && <Child />}\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsMounted/useIsMounted.md",
    "content": "In React, once a component is unmounted, it is deleted from memory and will never be mounted again. That's why we don't define a state in a disassembled component.\nChanging the state in an unmounted component will result this error:\n\n```txt\nWarning: Can't perform a React state update on an unmounted component.\nThis is a no-op, but it indicates a memory leak in your application.\nTo fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.\n```\n\nThe right way to solve this is cleaning effect like the above message said.\nFor example, see [`useInterval`](/react-hook/use-interval) or [`useEventListener`](/react-hook/use-event-listener).\n\nBut, there are some cases like Promise or API calls where it's impossible to know if the component is still mounted at the resolve time.\n\nThis React hook help you to avoid this error with a function that return a boolean, `isMounted`.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsMounted/useIsMounted.test.ts",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { useIsMounted } from './useIsMounted'\n\ndescribe('useIsMounted()', () => {\n  it('should return true when component is mounted', () => {\n    const {\n      result: { current: isMounted },\n    } = renderHook(() => useIsMounted())\n\n    expect(isMounted()).toBe(true)\n  })\n\n  it('should return false when component is unmounted', () => {\n    const {\n      result: { current: isMounted },\n      unmount,\n    } = renderHook(() => useIsMounted())\n\n    unmount()\n\n    expect(isMounted()).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsMounted/useIsMounted.ts",
    "content": "import { useCallback, useEffect, useRef } from 'react'\n\n/**\n * Custom hook that determines if the component is currently mounted.\n * @returns {() => boolean} A function that returns a boolean value indicating whether the component is mounted.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-is-mounted)\n * @example\n * ```tsx\n * const isComponentMounted = useIsMounted();\n * // Use isComponentMounted() to check if the component is currently mounted before performing certain actions.\n * ```\n */\nexport function useIsMounted(): () => boolean {\n  const isMounted = useRef(false)\n\n  useEffect(() => {\n    isMounted.current = true\n\n    return () => {\n      isMounted.current = false\n    }\n  }, [])\n\n  return useCallback(() => isMounted.current, [])\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsomorphicLayoutEffect/index.ts",
    "content": "export * from './useIsomorphicLayoutEffect'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.demo.tsx",
    "content": "import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\nexport default function Component() {\n  useIsomorphicLayoutEffect(() => {\n    console.log(\n      \"In the browser, I'm an `useLayoutEffect`, but in SSR, I'm an `useEffect`.\",\n    )\n  }, [])\n\n  return <p>Hello, world</p>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.md",
    "content": "The React documentation says about `useLayoutEffect`:\n\n> The signature is identical to useEffect, but it fires synchronously after all DOM mutations.\n\nThat means this hook is a browser hook. But React code could be generated from the server without the Window API.\n\nIf you're using NextJS, you'll have this error message:\n\n> Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.\n\nThis hook fixes this problem by switching between `useEffect` and `useLayoutEffect` following the execution environment.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.ts",
    "content": "import { useEffect, useLayoutEffect } from 'react'\n\n/**\n * Custom hook that uses either `useLayoutEffect` or `useEffect` based on the environment (client-side or server-side).\n * @param {Function} effect - The effect function to be executed.\n * @param {Array<any>} [dependencies] - An array of dependencies for the effect (optional).\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect)\n * @example\n * ```tsx\n * useIsomorphicLayoutEffect(() => {\n *   // Code to be executed during the layout phase on the client side\n * }, [dependency1, dependency2]);\n * ```\n */\nexport const useIsomorphicLayoutEffect =\n  typeof window !== 'undefined' ? useLayoutEffect : useEffect\n"
  },
  {
    "path": "packages/usehooks-ts/src/useLocalStorage/index.ts",
    "content": "export * from './useLocalStorage'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useLocalStorage/useLocalStorage.demo.tsx",
    "content": "import { useLocalStorage } from './useLocalStorage'\n\nexport default function Component() {\n  const [value, setValue, removeValue] = useLocalStorage('test-key', 0)\n\n  return (\n    <div>\n      <p>Count: {value}</p>\n      <button\n        onClick={() => {\n          setValue((x: number) => x + 1)\n        }}\n      >\n        Increment\n      </button>\n      <button\n        onClick={() => {\n          setValue((x: number) => x - 1)\n        }}\n      >\n        Decrement\n      </button>\n      <button\n        onClick={() => {\n          removeValue()\n        }}\n      >\n        Reset\n      </button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useLocalStorage/useLocalStorage.md",
    "content": "Persist the state with [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) so that it remains after a page refresh. This can be useful for a dark theme.\nThis hook is used in the same way as useState except that you must pass the storage key in the 1st parameter.\n\nYou can also pass an optional third parameter to use a custom serializer/deserializer.\n\n**Note**: If you use this hook in an SSR context, set the `initializeWithValue` option to `false`, it will initialize in SSR with the initial value.\n\n### Related hooks\n\n- [`useDarkMode()`](/react-hook/use-dark-mode): Helps create a dark theme switch, built on top of `useLocalStorage()`.\n- [`useReadLocalStorage()`](/react-hook/use-read-local-storage): Read values from local storage.\n- [`useSessionStorage()`](/react-hook/use-session-storage): Its implementation is almost the same of `useLocalStorage()`, but on [session storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) instead.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useLocalStorage/useLocalStorage.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { mockStorage } from '../../tests/mocks'\nimport { useLocalStorage } from './useLocalStorage'\n\nmockStorage('localStorage')\n\ndescribe('useLocalStorage()', () => {\n  beforeEach(() => {\n    window.localStorage.clear()\n  })\n\n  afterEach(() => {\n    vitest.clearAllMocks()\n  })\n\n  it('initial state is in the returned state', () => {\n    const { result } = renderHook(() => useLocalStorage('key', 'value'))\n\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Initial state is a callback function', () => {\n    const { result } = renderHook(() => useLocalStorage('key', () => 'value'))\n\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Initial state is an array', () => {\n    const { result } = renderHook(() => useLocalStorage('digits', [1, 2]))\n\n    expect(result.current[0]).toEqual([1, 2])\n  })\n\n  it('Initial state is a Map', () => {\n    const { result } = renderHook(() =>\n      useLocalStorage('map', new Map([['a', 1]])),\n    )\n\n    expect(result.current[0]).toEqual(new Map([['a', 1]]))\n  })\n\n  it('Initial state is a Set', () => {\n    const { result } = renderHook(() => useLocalStorage('set', new Set([1, 2])))\n\n    expect(result.current[0]).toEqual(new Set([1, 2]))\n  })\n\n  it('Initial state is a Date', () => {\n    const { result } = renderHook(() =>\n      useLocalStorage('date', new Date(2020, 1, 1)),\n    )\n\n    expect(result.current[0]).toEqual(new Date(2020, 1, 1))\n  })\n\n  it('Update the state', () => {\n    const { result } = renderHook(() => useLocalStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('edited')\n    })\n\n    expect(result.current[0]).toBe('edited')\n  })\n\n  it('Update the state writes localStorage', () => {\n    const { result } = renderHook(() => useLocalStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('edited')\n    })\n\n    expect(window.localStorage.getItem('key')).toBe(JSON.stringify('edited'))\n  })\n\n  it('Remove the state removes localStorage key', () => {\n    const { result } = renderHook(() => useLocalStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('updated')\n    })\n\n    expect(result.current[0]).toBe('updated')\n    expect(window.localStorage.getItem('key')).toBe(JSON.stringify('updated'))\n\n    act(() => {\n      const removeValue = result.current[2]\n      removeValue()\n    })\n\n    // Expect null as it's a default return if storage key doesn't exist\n    expect(window.localStorage.getItem('key')).toBeNull()\n    // Expect the state to match the default value\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Update the state with undefined', () => {\n    const { result } = renderHook(() =>\n      useLocalStorage<string | undefined>('key', 'value'),\n    )\n\n    act(() => {\n      const setState = result.current[1]\n      setState(undefined)\n    })\n\n    expect(result.current[0]).toBeUndefined()\n  })\n\n  it('Update the state with null', () => {\n    const { result } = renderHook(() =>\n      useLocalStorage<string | null>('key', 'value'),\n    )\n\n    act(() => {\n      const setState = result.current[1]\n      setState(null)\n    })\n\n    expect(result.current[0]).toBeNull()\n  })\n\n  it('Update the state with a callback function', () => {\n    const { result } = renderHook(() => useLocalStorage('count', 2))\n\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[0]).toBe(3)\n    expect(window.localStorage.getItem('count')).toEqual('3')\n  })\n\n  it('Update the state with a callback function multiple times per render', () => {\n    const { result } = renderHook(() => useLocalStorage('count', 2))\n\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n      setState(prev => prev + 1)\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[0]).toBe(5)\n    expect(window.localStorage.getItem('count')).toEqual('5')\n  })\n\n  it('[Event] Update one hook updates the others', () => {\n    const initialValues: [string, unknown] = ['key', 'initial']\n    const { result: A } = renderHook(() => useLocalStorage(...initialValues))\n    const { result: B } = renderHook(() => useLocalStorage(...initialValues))\n    const { result: C } = renderHook(() =>\n      useLocalStorage('other-key', 'initial'),\n    )\n\n    act(() => {\n      const setState = A.current[1]\n      setState('edited')\n    })\n\n    expect(B.current[0]).toBe('edited')\n    expect(C.current[0]).toBe('initial')\n  })\n\n  it('[Event] Updating one hook does not update others with a different key', () => {\n    let renderCount = 0\n    const { result: A } = renderHook(() => {\n      renderCount++\n      return useLocalStorage('key1', {})\n    })\n    const { result: B } = renderHook(() => useLocalStorage('key2', 'initial'))\n\n    expect(renderCount).toBe(1)\n\n    act(() => {\n      const setStateA = A.current[1]\n      setStateA({ a: 1 })\n    })\n\n    expect(renderCount).toBe(2)\n\n    act(() => {\n      const setStateB = B.current[1]\n      setStateB('edited')\n    })\n\n    expect(renderCount).toBe(2)\n  })\n\n  it('setValue is referentially stable', () => {\n    const { result } = renderHook(() => useLocalStorage('count', 1))\n\n    // Store a reference to the original setValue\n    const originalCallback = result.current[1]\n\n    // Now invoke a state update, if setValue is not referentially stable then this will cause the originalCallback\n    // reference to not be equal to the new setValue function\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[1] === originalCallback).toBe(true)\n  })\n\n  it('should use default JSON.stringify and JSON.parse when serializer/deserializer not provided', () => {\n    const { result } = renderHook(() => useLocalStorage('key', 'initialValue'))\n\n    act(() => {\n      result.current[1]('newValue')\n    })\n\n    expect(localStorage.getItem('key')).toBe(JSON.stringify('newValue'))\n  })\n\n  it('should use custom serializer and deserializer when provided', () => {\n    const serializer = (value: string) => value.toUpperCase()\n    const deserializer = (value: string) => value.toLowerCase()\n\n    const { result } = renderHook(() =>\n      useLocalStorage('key', 'initialValue', { serializer, deserializer }),\n    )\n\n    act(() => {\n      result.current[1]('NewValue')\n    })\n\n    expect(localStorage.getItem('key')).toBe('NEWVALUE')\n  })\n\n  it('should handle undefined values with custom deserializer', () => {\n    const serializer = (value: number | undefined) => String(value)\n    const deserializer = (value: string) =>\n      value === 'undefined' ? undefined : Number(value)\n\n    const { result } = renderHook(() =>\n      useLocalStorage<number | undefined>('key', 0, {\n        serializer,\n        deserializer,\n      }),\n    )\n\n    act(() => {\n      result.current[1](undefined)\n    })\n\n    expect(localStorage.getItem('key')).toBe('undefined')\n\n    act(() => {\n      result.current[1](42)\n    })\n\n    expect(localStorage.getItem('key')).toBe('42')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useLocalStorage/useLocalStorage.ts",
    "content": "import { useCallback, useEffect, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\nimport { useEventCallback } from '../useEventCallback'\nimport { useEventListener } from '../useEventListener'\n\ndeclare global {\n  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n  interface WindowEventMap {\n    'local-storage': CustomEvent\n  }\n}\n\n/**\n * Options for customizing the behavior of serialization and deserialization.\n * @template T - The type of the state to be stored in local storage.\n */\ntype UseLocalStorageOptions<T> = {\n  /** A function to serialize the value before storing it. */\n  serializer?: (value: T) => string\n  /** A function to deserialize the stored value. */\n  deserializer?: (value: string) => T\n  /**\n   * If `true` (default), the hook will initialize reading the local storage. In SSR, you should set it to `false`, returning the initial value initially.\n   * @default true\n   */\n  initializeWithValue?: boolean\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n/**\n * Custom hook that uses the [`localStorage API`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to persist state across page reloads.\n * @template T - The type of the state to be stored in local storage.\n * @param {string} key - The key under which the value will be stored in local storage.\n * @param {T | (() => T)} initialValue - The initial value of the state or a function that returns the initial value.\n * @param {UseLocalStorageOptions<T>} [options] - Options for customizing the behavior of serialization and deserialization (optional).\n * @returns {[T, Dispatch<SetStateAction<T>>, () => void]} A tuple containing the stored value, a function to set the value and a function to remove the key from storage.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-local-storage)\n * @example\n * ```tsx\n * const [count, setCount, removeCount] = useLocalStorage('count', 0);\n * // Access the `count` value, the `setCount` function to update it and `removeCount` function to remove the key from storage.\n * ```\n */\nexport function useLocalStorage<T>(\n  key: string,\n  initialValue: T | (() => T),\n  options: UseLocalStorageOptions<T> = {},\n): [T, Dispatch<SetStateAction<T>>, () => void] {\n  const { initializeWithValue = true } = options\n\n  const serializer = useCallback<(value: T) => string>(\n    value => {\n      if (options.serializer) {\n        return options.serializer(value)\n      }\n\n      return JSON.stringify(value)\n    },\n    [options],\n  )\n\n  const deserializer = useCallback<(value: string) => T>(\n    value => {\n      if (options.deserializer) {\n        return options.deserializer(value)\n      }\n      // Support 'undefined' as a value\n      if (value === 'undefined') {\n        return undefined as unknown as T\n      }\n\n      const defaultValue =\n        initialValue instanceof Function ? initialValue() : initialValue\n\n      let parsed: unknown\n      try {\n        parsed = JSON.parse(value)\n      } catch (error) {\n        console.error('Error parsing JSON:', error)\n        return defaultValue // Return initialValue if parsing fails\n      }\n\n      return parsed as T\n    },\n    [options, initialValue],\n  )\n\n  // Get from local storage then\n  // parse stored json or return initialValue\n  const readValue = useCallback((): T => {\n    const initialValueToUse =\n      initialValue instanceof Function ? initialValue() : initialValue\n\n    // Prevent build error \"window is undefined\" but keep working\n    if (IS_SERVER) {\n      return initialValueToUse\n    }\n\n    try {\n      const raw = window.localStorage.getItem(key)\n      return raw ? deserializer(raw) : initialValueToUse\n    } catch (error) {\n      console.warn(`Error reading localStorage key “${key}”:`, error)\n      return initialValueToUse\n    }\n  }, [initialValue, key, deserializer])\n\n  const [storedValue, setStoredValue] = useState(() => {\n    if (initializeWithValue) {\n      return readValue()\n    }\n\n    return initialValue instanceof Function ? initialValue() : initialValue\n  })\n\n  // Return a wrapped version of useState's setter function that ...\n  // ... persists the new value to localStorage.\n  const setValue: Dispatch<SetStateAction<T>> = useEventCallback(value => {\n    // Prevent build error \"window is undefined\" but keeps working\n    if (IS_SERVER) {\n      console.warn(\n        `Tried setting localStorage key “${key}” even though environment is not a client`,\n      )\n    }\n\n    try {\n      // Allow value to be a function so we have the same API as useState\n      const newValue = value instanceof Function ? value(readValue()) : value\n\n      // Save to local storage\n      window.localStorage.setItem(key, serializer(newValue))\n\n      // Save state\n      setStoredValue(newValue)\n\n      // We dispatch a custom event so every similar useLocalStorage hook is notified\n      window.dispatchEvent(new StorageEvent('local-storage', { key }))\n    } catch (error) {\n      console.warn(`Error setting localStorage key “${key}”:`, error)\n    }\n  })\n\n  const removeValue = useEventCallback(() => {\n    // Prevent build error \"window is undefined\" but keeps working\n    if (IS_SERVER) {\n      console.warn(\n        `Tried removing localStorage key “${key}” even though environment is not a client`,\n      )\n    }\n\n    const defaultValue =\n      initialValue instanceof Function ? initialValue() : initialValue\n\n    // Remove the key from local storage\n    window.localStorage.removeItem(key)\n\n    // Save state with default value\n    setStoredValue(defaultValue)\n\n    // We dispatch a custom event so every similar useLocalStorage hook is notified\n    window.dispatchEvent(new StorageEvent('local-storage', { key }))\n  })\n\n  useEffect(() => {\n    setStoredValue(readValue())\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [key])\n\n  const handleStorageChange = useCallback(\n    (event: StorageEvent | CustomEvent) => {\n      if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n        return\n      }\n      setStoredValue(readValue())\n    },\n    [key, readValue],\n  )\n\n  // this only works for other documents, not the current one\n  useEventListener('storage', handleStorageChange)\n\n  // this is a custom event, triggered in writeValueToLocalStorage\n  // See: useLocalStorage()\n  useEventListener('local-storage', handleStorageChange)\n\n  return [storedValue, setValue, removeValue]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMap/index.ts",
    "content": "export * from './useMap'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMap/useMap.demo.tsx",
    "content": "import { Fragment } from 'react'\n\nimport { useMap } from './useMap'\n\nexport default function Component() {\n  const [map, actions] = useMap<string, string>([['key', '🆕']])\n\n  const set = () => {\n    actions.set(String(Date.now()), '📦')\n  }\n  const setAll = () => {\n    actions.setAll([\n      ['hello', '👋'],\n      ['data', '📦'],\n    ])\n  }\n  const reset = () => {\n    actions.reset()\n  }\n  const remove = () => {\n    actions.remove('hello')\n  }\n\n  return (\n    <div>\n      <button onClick={set}>Add</button>\n      <button onClick={reset}>Reset</button>\n      <button onClick={setAll}>Set new data</button>\n      <button onClick={remove} disabled={!map.get('hello')}>\n        {'Remove \"hello\"'}\n      </button>\n\n      <pre>\n        Map (\n        {Array.from(map.entries()).map(([key, value]) => (\n          <Fragment key={key}>{`\\n  ${key}: ${value}`}</Fragment>\n        ))}\n        <br />)\n      </pre>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMap/useMap.md",
    "content": "This React hook provides an API to interact with a `Map` ([Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))\n\nIt takes as initial entries a `Map` or an array like `[[\"key\": \"value\"], [..]]` or nothing and returns:\n\n- An array with an instance of `Map` (including: `foreach, get, has, entries, keys, values, size`)\n- And an object of methods (`set, setAll, remove, reset`)\n\nMake sure to use these methods to update the map, a `map.set(..)` would not re-render the component.\n\n<br />\n\n**Why use Map instead of an object ?**\n\nMap is an iterable, a simple hash and it performs better in storing large data ([Read more](https://azimi.io/es6-map-with-react-usestate-9175cd7b409b)).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMap/useMap.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useMap } from './useMap'\n\ndescribe('useMap()', () => {\n  it('should be ok when initiated with a map', () => {\n    const initialMap = new Map([[1, 'initial']])\n    const { result } = renderHook(() => useMap(initialMap))\n\n    expect(result.current[0].get(1)).toBe('initial')\n  })\n\n  it('should be ok when initiated with an array', () => {\n    const { result } = renderHook(() => useMap([[1, 'initial']]))\n\n    expect(result.current[0].get(1)).toBe('initial')\n  })\n\n  it('should be ok when initiated without nothing', () => {\n    const { result } = renderHook(() => useMap())\n\n    expect(result.current[0].size).toBe(0)\n  })\n\n  it('should add new value', () => {\n    const { result } = renderHook(() => useMap<number, string>())\n    const [, actions] = result.current\n\n    expect(result.current[0].get(1)).toBeUndefined()\n\n    act(() => {\n      actions.set(1, 'added')\n    })\n\n    expect(result.current[0].get(1)).toBe('added')\n  })\n\n  it('should update existing value', () => {\n    const initialMap = new Map([[1, 'initial']])\n    const { result } = renderHook(() => useMap(initialMap))\n    const [, actions] = result.current\n\n    act(() => {\n      actions.set(1, 'edited')\n    })\n\n    expect(result.current[0].get(1)).toBe('edited')\n  })\n\n  it('should setAll replaces all existing values', () => {\n    const initialMap = new Map([\n      [1, 'initial'],\n      [2, 'example'],\n    ])\n    const { result } = renderHook(() => useMap(initialMap))\n    const [, actions] = result.current\n\n    expect(result.current[0].get(1)).toBe('initial')\n    expect(result.current[0].get(2)).toBe('example')\n    expect(result.current[0].size).toBe(2)\n\n    act(() => {\n      actions.setAll([[1, 'edited']])\n    })\n\n    expect(result.current[0].get(1)).toBe('edited')\n    expect(result.current[0].size).toBe(1)\n  })\n\n  it('should remove existing value', () => {\n    const initialMap = new Map([[1, 'initial']])\n    const { result } = renderHook(() => useMap(initialMap))\n    const [, actions] = result.current\n\n    act(() => {\n      actions.remove(1)\n    })\n\n    expect(result.current[0].get(1)).toBeUndefined()\n  })\n\n  it('should reset the map state', () => {\n    const initialMap = new Map([[1, 'initial']])\n    const { result } = renderHook(() => useMap(initialMap))\n    const [, actions] = result.current\n\n    act(() => {\n      actions.reset()\n    })\n\n    expect(result.current[0].get(1)).toBeUndefined()\n    expect(result.current[0].size).toBe(0)\n  })\n\n  it('should change value reference equality after change', () => {\n    const initialMap = new Map<number, number>()\n    const { result } = renderHook(() => useMap(initialMap))\n    const [originalMapRef, actions] = result.current\n\n    act(() => {\n      actions.set(1, 1)\n    })\n\n    expect(originalMapRef).not.toStrictEqual(result.current[0])\n    expect(originalMapRef.get(1)).toBeUndefined()\n    expect(result.current[0].get(1)).toBe(1)\n  })\n  it('should keep actions reference equality after value change', () => {\n    const initialMap = new Map<number, number>()\n    const { result } = renderHook(() => useMap(initialMap))\n    const [, originalActionsRef] = result.current\n\n    expect(result.current[1]).toStrictEqual(originalActionsRef)\n\n    act(() => {\n      originalActionsRef.set(1, 1)\n    })\n\n    expect(originalActionsRef).toStrictEqual(result.current[1])\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMap/useMap.ts",
    "content": "import { useCallback, useState } from 'react'\n\n/**\n * Represents the type for either a Map or an array of key-value pairs.\n * @template K - The type of keys in the map.\n * @template V - The type of values in the map.\n */\ntype MapOrEntries<K, V> = Map<K, V> | [K, V][]\n\n/**\n * Represents the actions available to interact with the map state.\n * @template K - The type of keys in the map.\n * @template V - The type of values in the map.\n */\ntype UseMapActions<K, V> = {\n  /** Set a key-value pair in the map. */\n  set: (key: K, value: V) => void\n  /** Set all key-value pairs in the map. */\n  setAll: (entries: MapOrEntries<K, V>) => void\n  /** Remove a key-value pair from the map. */\n  remove: (key: K) => void\n  /** Reset the map to an empty state. */\n  reset: Map<K, V>['clear']\n}\n\n/**\n * Represents the return type of the `useMap` hook.\n * We hide some setters from the returned map to disable autocompletion.\n * @template K - The type of keys in the map.\n * @template V - The type of values in the map.\n */\ntype UseMapReturn<K, V> = [\n  Omit<Map<K, V>, 'set' | 'clear' | 'delete'>,\n  UseMapActions<K, V>,\n]\n\n/**\n * Custom hook that manages a key-value [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) state with setter actions.\n * @template K - The type of keys in the map.\n * @template V - The type of values in the map.\n * @param {MapOrEntries<K, V>} [initialState] - The initial state of the map as a Map or an array of key-value pairs (optional).\n * @returns {UseMapReturn<K, V>} A tuple containing the map state and actions to interact with the map.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-map)\n * @example\n * ```tsx\n * const [map, mapActions] = useMap();\n * // Access the `map` state and use `mapActions` to set, remove, or reset entries.\n * ```\n */\nexport function useMap<K, V>(\n  initialState: MapOrEntries<K, V> = new Map(),\n): UseMapReturn<K, V> {\n  const [map, setMap] = useState(new Map(initialState))\n\n  const actions: UseMapActions<K, V> = {\n    set: useCallback((key, value) => {\n      setMap(prev => {\n        const copy = new Map(prev)\n        copy.set(key, value)\n        return copy\n      })\n    }, []),\n\n    setAll: useCallback(entries => {\n      setMap(() => new Map(entries))\n    }, []),\n\n    remove: useCallback(key => {\n      setMap(prev => {\n        const copy = new Map(prev)\n        copy.delete(key)\n        return copy\n      })\n    }, []),\n\n    reset: useCallback(() => {\n      setMap(() => new Map())\n    }, []),\n  }\n\n  return [map, actions]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMediaQuery/index.ts",
    "content": "export * from './useMediaQuery'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMediaQuery/useMediaQuery.demo.tsx",
    "content": "import { useMediaQuery } from './useMediaQuery'\n\nexport default function Component() {\n  const matches = useMediaQuery('(min-width: 768px)')\n\n  return (\n    <div>\n      {`The view port is ${matches ? 'at least' : 'less than'} 768 pixels wide`}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMediaQuery/useMediaQuery.md",
    "content": "Easily retrieve media dimensions with this Hook React which also works onResize.\n\n**Note:**\n\n- If you use this hook in an SSR context, set the `initializeWithValue` option to `false`.\n- Before Safari 14, `MediaQueryList` is based on `EventTarget` and only supports `addListener`/`removeListener` for media queries. If you don't support these versions you may remove these checks. Read more about this on [MDN](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useMediaQuery/useMediaQuery.ts",
    "content": "import { useState } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/** Hook options. */\ntype UseMediaQueryOptions = {\n  /**\n   * The default value to return if the hook is being run on the server.\n   * @default false\n   */\n  defaultValue?: boolean\n  /**\n   * If `true` (default), the hook will initialize reading the media query. In SSR, you should set it to `false`, returning `options.defaultValue` or `false` initially.\n   * @default true\n   */\n  initializeWithValue?: boolean\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n/**\n * Custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia).\n * @param {string} query - The media query to track.\n * @param {?UseMediaQueryOptions} [options] - The options for customizing the behavior of the hook (optional).\n * @returns {boolean} The current state of the media query (true if the query matches, false otherwise).\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-media-query)\n * @example\n * ```tsx\n * const isSmallScreen = useMediaQuery('(max-width: 600px)');\n * // Use `isSmallScreen` to conditionally apply styles or logic based on the screen size.\n * ```\n */\nexport function useMediaQuery(\n  query: string,\n  {\n    defaultValue = false,\n    initializeWithValue = true,\n  }: UseMediaQueryOptions = {},\n): boolean {\n  const getMatches = (query: string): boolean => {\n    if (IS_SERVER) {\n      return defaultValue\n    }\n    return window.matchMedia(query).matches\n  }\n\n  const [matches, setMatches] = useState<boolean>(() => {\n    if (initializeWithValue) {\n      return getMatches(query)\n    }\n    return defaultValue\n  })\n\n  // Handles the change event of the media query.\n  function handleChange() {\n    setMatches(getMatches(query))\n  }\n\n  useIsomorphicLayoutEffect(() => {\n    const matchMedia = window.matchMedia(query)\n\n    // Triggered at the first client-side load and if query changes\n    handleChange()\n\n    // Use deprecated `addListener` and `removeListener` to support Safari < 14 (#135)\n    if (matchMedia.addListener) {\n      matchMedia.addListener(handleChange)\n    } else {\n      matchMedia.addEventListener('change', handleChange)\n    }\n\n    return () => {\n      if (matchMedia.removeListener) {\n        matchMedia.removeListener(handleChange)\n      } else {\n        matchMedia.removeEventListener('change', handleChange)\n      }\n    }\n  }, [query])\n\n  return matches\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useOnClickOutside/index.ts",
    "content": "export * from './useOnClickOutside'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useOnClickOutside/useOnClickOuside.test.ts",
    "content": "import { act, fireEvent, renderHook } from '@testing-library/react'\n\nimport { useOnClickOutside } from './useOnClickOutside'\n\ndescribe('useOnClickOutside(', () => {\n  it('should call the handler when a clicking outside the element (single ref)', () => {\n    const containerRef = { current: document.createElement('div') }\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useOnClickOutside(containerRef, handler)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(0)\n\n    // Simulate click outside the container\n    act(() => {\n      fireEvent.mouseDown(document)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(1)\n  })\n\n  it('should call the handler when a clicking outside the element (multiple refs)', () => {\n    const containerRef1 = { current: document.createElement('div') }\n    const containerRef2 = { current: document.createElement('div') }\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useOnClickOutside([containerRef1, containerRef2], handler)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(0)\n\n    // Simulate click outside the containers\n    act(() => {\n      fireEvent.mouseDown(document)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(1)\n  })\n\n  it('should call the handler when a clicking outside the element (multiple refs with a null)', () => {\n    const containerRef1 = { current: document.createElement('div') }\n    const containerRef2 = { current: null }\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useOnClickOutside([containerRef1, containerRef2], handler)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(0)\n\n    // Simulate click outside the containers\n    act(() => {\n      fireEvent.mouseDown(document)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(1)\n  })\n\n  it('should NOT call the handler when a clicking inside the element', () => {\n    const containerRef = { current: document.createElement('div') }\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useOnClickOutside([containerRef], handler)\n    })\n\n    // Simulate click inside the container\n    act(() => {\n      fireEvent.mouseDown(containerRef.current)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(0)\n  })\n\n  it('should NOT call the handler when clicking a non-connected element', () => {\n    const containerRef = { current: document.createElement('div') }\n    const handler = vitest.fn()\n\n    renderHook(() => {\n      useOnClickOutside([containerRef], handler)\n    })\n\n    // Simulate click on a non-connected element\n    act(() => {\n      const element = document.createElement('div')\n      document.body.appendChild(element)\n      document.body.removeChild(element)\n      fireEvent.mouseDown(element)\n    })\n\n    expect(handler).toHaveBeenCalledTimes(0)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useOnClickOutside/useOnClickOutside.demo.tsx",
    "content": "import { useRef } from 'react'\n\nimport { useOnClickOutside } from './useOnClickOutside'\n\nexport default function Component() {\n  const ref = useRef(null)\n\n  const handleClickOutside = () => {\n    // Your custom logic here\n    console.log('clicked outside')\n  }\n\n  const handleClickInside = () => {\n    // Your custom logic here\n    console.log('clicked inside')\n  }\n\n  useOnClickOutside(ref, handleClickOutside)\n\n  return (\n    <button\n      ref={ref}\n      onClick={handleClickInside}\n      style={{ width: 200, height: 200, background: 'cyan' }}\n    />\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useOnClickOutside/useOnClickOutside.md",
    "content": "React hook for listening for clicks outside of a specified element (see `useRef`).\n\nThis can be useful for closing a modal, a dropdown menu etc.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useOnClickOutside/useOnClickOutside.ts",
    "content": "import type { RefObject } from 'react'\n\nimport { useEventListener } from '../useEventListener'\n\n/** Supported event types. */\ntype EventType =\n  | 'mousedown'\n  | 'mouseup'\n  | 'touchstart'\n  | 'touchend'\n  | 'focusin'\n  | 'focusout'\n\n/**\n * Custom hook that handles clicks outside a specified element.\n * @template T - The type of the element's reference.\n * @param {RefObject<T> | RefObject<T>[]} ref - The React ref object(s) representing the element(s) to watch for outside clicks.\n * @param {(event: MouseEvent | TouchEvent | FocusEvent) => void} handler - The callback function to be executed when a click outside the element occurs.\n * @param {EventType} [eventType] - The mouse event type to listen for (optional, default is 'mousedown').\n * @param {?AddEventListenerOptions} [eventListenerOptions] - The options object to be passed to the `addEventListener` method (optional).\n * @returns {void}\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-on-click-outside)\n * @example\n * ```tsx\n * const containerRef = useRef(null);\n * useOnClickOutside([containerRef], () => {\n *   // Handle clicks outside the container.\n * });\n * ```\n */\nexport function useOnClickOutside<T extends HTMLElement = HTMLElement>(\n  ref: RefObject<T> | RefObject<T>[],\n  handler: (event: MouseEvent | TouchEvent | FocusEvent) => void,\n  eventType: EventType = 'mousedown',\n  eventListenerOptions: AddEventListenerOptions = {},\n): void {\n  useEventListener(\n    eventType,\n    event => {\n      const target = event.target as Node\n\n      // Do nothing if the target is not connected element with document\n      if (!target || !target.isConnected) {\n        return\n      }\n\n      const isOutside = Array.isArray(ref)\n        ? ref\n            .filter(r => Boolean(r.current))\n            .every(r => r.current && !r.current.contains(target))\n        : ref.current && !ref.current.contains(target)\n\n      if (isOutside) {\n        handler(event)\n      }\n    },\n    undefined,\n    eventListenerOptions,\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useReadLocalStorage/index.ts",
    "content": "export * from './useReadLocalStorage'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useReadLocalStorage/useReadLocalStorage.demo.tsx",
    "content": "import { useReadLocalStorage } from './useReadLocalStorage'\n\nexport default function Component() {\n  // Assuming a value was set in localStorage with this key\n  const darkMode = useReadLocalStorage('darkMode')\n\n  return <p>DarkMode is {darkMode ? 'enabled' : 'disabled'}</p>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useReadLocalStorage/useReadLocalStorage.md",
    "content": "This React Hook allows you to read a value from localStorage by its key. It can be useful if you just want to read without passing a default value.\nIf the window object is not present (as in SSR), or if the value doesn't exist, `useReadLocalStorage()` will return `null`.\n\n**Note:**\n\n- If you use this hook in an SSR context, set the `initializeWithValue` option to `false`.\n- If you want to be able to change the value, see [useLocalStorage()](/react-hook/use-local-storage).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useReadLocalStorage/useReadLocalStorage.test.ts",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { useReadLocalStorage } from './useReadLocalStorage'\n\ndescribe('useReadLocalStorage()', () => {\n  it('should use read local storage', () => {\n    const { result } = renderHook(() => useReadLocalStorage('test'))\n\n    expect(result.current).toBe(null)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useReadLocalStorage/useReadLocalStorage.ts",
    "content": "import { useCallback, useEffect, useState } from 'react'\n\nimport { useEventListener } from '../useEventListener'\n\nconst IS_SERVER = typeof window === 'undefined'\n\n/**\n * Represents the type for the options available when reading from local storage.\n * @template T - The type of the stored value.\n */\ntype Options<T, InitializeWithValue extends boolean | undefined> = {\n  /** Custom deserializer function to convert the stored string value to the desired type (optional). */\n  deserializer?: (value: string) => T\n  /** If `true` (default), the hook will initialize reading the local storage. In SSR, you should set it to `false`, returning `undefined` initially. */\n  initializeWithValue: InitializeWithValue\n}\n\n// SSR version\nexport function useReadLocalStorage<T>(\n  key: string,\n  options: Options<T, false>,\n): T | null | undefined\n// CSR version\nexport function useReadLocalStorage<T>(\n  key: string,\n  options?: Partial<Options<T, true>>,\n): T | null\n/**\n * Custom hook that reads a value from [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), closely related to [`useLocalStorage()`](https://usehooks-ts.com/react-hook/use-local-storage).\n * @template T - The type of the stored value.\n * @param {string} key - The key associated with the value in local storage.\n * @param {Options<T>} [options] - Additional options for reading the value (optional).\n * @returns {T | null | undefined} The stored value, or null if the key is not present or an error occurs.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-read-local-storage)\n * @example\n * ```tsx\n * const storedData = useReadLocalStorage('myKey');\n * // Access the stored data from local storage.\n * ```\n */\nexport function useReadLocalStorage<T>(\n  key: string,\n  options: Partial<Options<T, boolean>> = {},\n): T | null | undefined {\n  let { initializeWithValue = true } = options\n  if (IS_SERVER) {\n    initializeWithValue = false\n  }\n\n  const deserializer = useCallback<(value: string) => T | null>(\n    value => {\n      if (options.deserializer) {\n        return options.deserializer(value)\n      }\n      // Support 'undefined' as a value\n      if (value === 'undefined') {\n        return undefined as unknown as T\n      }\n\n      let parsed: unknown\n      try {\n        parsed = JSON.parse(value)\n      } catch (error) {\n        console.error('Error parsing JSON:', error)\n        return null\n      }\n\n      return parsed as T\n    },\n    [options],\n  )\n\n  // Get from local storage then\n  // parse stored json or return initialValue\n  const readValue = useCallback((): T | null => {\n    // Prevent build error \"window is undefined\" but keep keep working\n    if (IS_SERVER) {\n      return null\n    }\n\n    try {\n      const raw = window.localStorage.getItem(key)\n      return raw ? deserializer(raw) : null\n    } catch (error) {\n      console.warn(`Error reading localStorage key “${key}”:`, error)\n      return null\n    }\n  }, [key, deserializer])\n\n  const [storedValue, setStoredValue] = useState(() => {\n    if (initializeWithValue) {\n      return readValue()\n    }\n    return undefined\n  })\n\n  // Listen if localStorage changes\n  useEffect(() => {\n    setStoredValue(readValue())\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [key])\n\n  const handleStorageChange = useCallback(\n    (event: StorageEvent | CustomEvent) => {\n      if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n        return\n      }\n      setStoredValue(readValue())\n    },\n    [key, readValue],\n  )\n\n  // this only works for other documents, not the current one\n  useEventListener('storage', handleStorageChange)\n\n  // this is a custom event, triggered in writeValueToLocalStorage\n  // See: useLocalStorage()\n  useEventListener('local-storage', handleStorageChange)\n\n  return storedValue\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useResizeObserver/index.ts",
    "content": "export * from './useResizeObserver'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useResizeObserver/useResizeObserver.demo.tsx",
    "content": "import { useRef, useState } from 'react'\n\nimport { useDebounceCallback } from '../useDebounceCallback'\nimport { useResizeObserver } from './useResizeObserver'\n\ntype Size = {\n  width?: number\n  height?: number\n}\n\nexport default function Component() {\n  const ref = useRef<HTMLDivElement>(null)\n  const { width = 0, height = 0 } = useResizeObserver({\n    ref,\n    box: 'border-box',\n  })\n\n  return (\n    <div ref={ref} style={{ border: '1px solid palevioletred', width: '100%' }}>\n      {width} x {height}\n    </div>\n  )\n}\n\nexport function WithDebounce() {\n  const ref = useRef<HTMLDivElement>(null)\n  const [{ width, height }, setSize] = useState<Size>({\n    width: undefined,\n    height: undefined,\n  })\n\n  const onResize = useDebounceCallback(setSize, 200)\n\n  useResizeObserver({\n    ref,\n    onResize,\n  })\n\n  return (\n    <div\n      ref={ref}\n      style={{\n        border: '1px solid palevioletred',\n        width: '100%',\n        resize: 'both',\n        overflow: 'auto',\n        maxWidth: '100%',\n      }}\n    >\n      debounced: {width} x {height}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useResizeObserver/useResizeObserver.md",
    "content": "A React hook for observing the size of an element using the [ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n\n### Parameters\n\n- `ref`: The ref of the element to observe.\n- `onResize`: When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback. (default is `undefined`).\n- `box`: The box model to use for the ResizeObserver. (default is `'content-box'`)\n\n### Returns\n\n- An object with the `width` and `height` of the element if the `onResize` optional callback is not provided.\n\n### Polyfill\n\nThe `useResizeObserver` hook does not provide polyfill to give you control, but it's recommended. You can add it by re-exporting the hook like this:\n\n```ts\n// useResizeObserver.ts\nimport { ResizeObserver } from '@juggle/resize-observer'\nimport { useResizeObserver } from 'usehooks-ts'\n\nif (!window.ResizeObserver) {\n  window.ResizeObserver = ResizeObserver\n}\n\nexport { useResizeObserver }\n```\n"
  },
  {
    "path": "packages/usehooks-ts/src/useResizeObserver/useResizeObserver.test.tsx",
    "content": "/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport { ResizeObserver } from '@juggle/resize-observer'\nimport { renderHook } from '@testing-library/react'\n\nimport { useResizeObserver } from './useResizeObserver'\n\ndescribe('useResizeObserver()', () => {\n  beforeEach(() => {\n    // Mock the ResizeObserver\n    window.ResizeObserver = ResizeObserver\n  })\n\n  afterEach(() => {\n    vitest.restoreAllMocks()\n  })\n\n  it('should return initial undefined sizes', () => {\n    const ref = { current: document.createElement('div') }\n    const { result } = renderHook(() =>\n      useResizeObserver({\n        ref,\n      }),\n    )\n\n    expect(result.current.width).toBeUndefined()\n    expect(result.current.height).toBeUndefined()\n  })\n\n  it.skip('should return the observed element sizes', () => {\n    const ref = { current: document.createElement('div') }\n    const { result } = renderHook(() =>\n      useResizeObserver({\n        ref,\n      }),\n    )\n\n    // TODO: Mock the observed element's size\n\n    expect(result.current.width).toBe(100)\n    expect(result.current.height).toBe(100)\n  })\n\n  it.skip('should update size when element is resized', () => {\n    const ref = { current: document.createElement('div') }\n    const { result } = renderHook(() =>\n      useResizeObserver({\n        ref,\n      }),\n    )\n\n    // TODO: Mock the observed element's size\n\n    expect(result.current.width).toBe(300)\n    expect(result.current.height).toBe(200)\n  })\n\n  it.skip('should use onResize callback to update the size', () => {\n    const ref = { current: document.createElement('div') }\n    const onResize = vitest.fn()\n    renderHook(() =>\n      useResizeObserver({\n        ref,\n        onResize,\n      }),\n    )\n\n    // TODO: Mock the observed element's size\n\n    expect(onResize).toHaveBeenCalledWith({ width: 200, height: 200 })\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useResizeObserver/useResizeObserver.ts",
    "content": "import { useEffect, useRef, useState } from 'react'\n\nimport type { RefObject } from 'react'\n\nimport { useIsMounted } from '../useIsMounted'\n\n/** The size of the observed element. */\ntype Size = {\n  /** The width of the observed element. */\n  width: number | undefined\n  /** The height of the observed element. */\n  height: number | undefined\n}\n\n/** The options for the ResizeObserver. */\ntype UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {\n  /** The ref of the element to observe. */\n  ref: RefObject<T>\n  /**\n   * When using `onResize`, the hook doesn't re-render on element size changes; it delegates handling to the provided callback.\n   * @default undefined\n   */\n  onResize?: (size: Size) => void\n  /**\n   * The box model to use for the ResizeObserver.\n   * @default 'content-box'\n   */\n  box?: 'border-box' | 'content-box' | 'device-pixel-content-box'\n}\n\nconst initialSize: Size = {\n  width: undefined,\n  height: undefined,\n}\n\n/**\n * Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n * @template T - The type of the element to observe.\n * @param {UseResizeObserverOptions<T>} options - The options for the ResizeObserver.\n * @returns {Size} - The size of the observed element.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-resize-observer)\n * @example\n * ```tsx\n * const myRef = useRef(null);\n * const { width = 0, height = 0 } = useResizeObserver({\n *   ref: myRef,\n *   box: 'content-box',\n * });\n *\n * <div ref={myRef}>Hello, world!</div>\n * ```\n */\nexport function useResizeObserver<T extends HTMLElement = HTMLElement>(\n  options: UseResizeObserverOptions<T>,\n): Size {\n  const { ref, box = 'content-box' } = options\n  const [{ width, height }, setSize] = useState<Size>(initialSize)\n  const isMounted = useIsMounted()\n  const previousSize = useRef<Size>({ ...initialSize })\n  const onResize = useRef<((size: Size) => void) | undefined>(undefined)\n  onResize.current = options.onResize\n\n  useEffect(() => {\n    if (!ref.current) return\n\n    if (typeof window === 'undefined' || !('ResizeObserver' in window)) return\n\n    const observer = new ResizeObserver(([entry]) => {\n      const boxProp =\n        box === 'border-box'\n          ? 'borderBoxSize'\n          : box === 'device-pixel-content-box'\n            ? 'devicePixelContentBoxSize'\n            : 'contentBoxSize'\n\n      const newWidth = extractSize(entry, boxProp, 'inlineSize')\n      const newHeight = extractSize(entry, boxProp, 'blockSize')\n\n      const hasChanged =\n        previousSize.current.width !== newWidth ||\n        previousSize.current.height !== newHeight\n\n      if (hasChanged) {\n        const newSize: Size = { width: newWidth, height: newHeight }\n        previousSize.current.width = newWidth\n        previousSize.current.height = newHeight\n\n        if (onResize.current) {\n          onResize.current(newSize)\n        } else {\n          if (isMounted()) {\n            setSize(newSize)\n          }\n        }\n      }\n    })\n\n    observer.observe(ref.current, { box })\n\n    return () => {\n      observer.disconnect()\n    }\n  }, [box, ref, isMounted])\n\n  return { width, height }\n}\n\n/** @private */\ntype BoxSizesKey = keyof Pick<\n  ResizeObserverEntry,\n  'borderBoxSize' | 'contentBoxSize' | 'devicePixelContentBoxSize'\n>\n\nfunction extractSize(\n  entry: ResizeObserverEntry,\n  box: BoxSizesKey,\n  sizeType: keyof ResizeObserverSize,\n): number | undefined {\n  if (!entry[box]) {\n    if (box === 'contentBoxSize') {\n      return entry.contentRect[sizeType === 'inlineSize' ? 'width' : 'height']\n    }\n    return undefined\n  }\n\n  return Array.isArray(entry[box])\n    ? entry[box][0][sizeType]\n    : // @ts-ignore Support Firefox's non-standard behavior\n      (entry[box][sizeType] as number)\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScreen/index.ts",
    "content": "export * from './useScreen'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScreen/useScreen.demo.tsx",
    "content": "import { useScreen } from './useScreen'\n\nexport default function Component() {\n  const screen = useScreen()\n\n  return (\n    <div>\n      The current window dimensions are:{' '}\n      <code>{JSON.stringify(screen, null, 2)}</code>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScreen/useScreen.md",
    "content": "Easily retrieve `window.screen` object with this Hook React which also works onResize.\n\n### Parameters\n\n- `initializeWithValue?: boolean`: If you use this hook in an SSR context, set it to `false`, it will initialize with `undefined` (default `true`).\n- `debounceDelay?: number`: The delay in milliseconds before the callback is invoked (disabled by default for retro-compatibility).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScreen/useScreen.ts",
    "content": "import { useState } from 'react'\n\nimport { useDebounceCallback } from '../useDebounceCallback'\nimport { useEventListener } from '../useEventListener'\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/**\n * The hooks options.\n * @template InitializeWithValue - If `true` (default), the hook will initialize reading the screen dimensions. In SSR, you should set it to `false`, returning `undefined` initially.\n */\ntype UseScreenOptions<InitializeWithValue extends boolean | undefined> = {\n  /**\n   * If `true` (default), the hook will initialize reading the screen dimensions. In SSR, you should set it to `false`, returning `undefined` initially.\n   * @default true\n   */\n  initializeWithValue: InitializeWithValue\n  /**\n   * The delay in milliseconds before the state is updated (disabled by default for retro-compatibility).\n   * @default undefined\n   */\n  debounceDelay?: number\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n// SSR version of useScreen.\nexport function useScreen(options: UseScreenOptions<false>): Screen | undefined\n// CSR version of useScreen.\nexport function useScreen(options?: Partial<UseScreenOptions<true>>): Screen\n/**\n * Custom hook that tracks the [`screen`](https://developer.mozilla.org/en-US/docs/Web/API/Window/screen) dimensions and properties.\n * @param {?UseScreenOptions} [options] - The options for customizing the behavior of the hook (optional).\n * @returns {Screen | undefined} The current `Screen` object representing the screen dimensions and properties, or `undefined` if not available.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-screen)\n * @example\n * ```tsx\n * const currentScreen = useScreen();\n * // Access properties of the current screen, such as width and height.\n * ```\n */\nexport function useScreen(\n  options: Partial<UseScreenOptions<boolean>> = {},\n): Screen | undefined {\n  let { initializeWithValue = true } = options\n  if (IS_SERVER) {\n    initializeWithValue = false\n  }\n\n  const readScreen = () => {\n    if (IS_SERVER) {\n      return undefined\n    }\n    return window.screen\n  }\n\n  const [screen, setScreen] = useState<Screen | undefined>(() => {\n    if (initializeWithValue) {\n      return readScreen()\n    }\n    return undefined\n  })\n\n  const debouncedSetScreen = useDebounceCallback(\n    setScreen,\n    options.debounceDelay,\n  )\n\n  // Handles the resize event of the window.\n  function handleSize() {\n    const newScreen = readScreen()\n    const setSize = options.debounceDelay ? debouncedSetScreen : setScreen\n\n    if (newScreen) {\n      // Create a shallow clone to trigger a re-render (#280).\n      const {\n        width,\n        height,\n        availHeight,\n        availWidth,\n        colorDepth,\n        orientation,\n        pixelDepth,\n      } = newScreen\n\n      setSize({\n        width,\n        height,\n        availHeight,\n        availWidth,\n        colorDepth,\n        orientation,\n        pixelDepth,\n      })\n    }\n  }\n\n  useEventListener('resize', handleSize)\n\n  // Set size at the first client-side load\n  useIsomorphicLayoutEffect(() => {\n    handleSize()\n  }, [])\n\n  return screen\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScript/index.ts",
    "content": "export * from './useScript'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScript/useScript.demo.tsx",
    "content": "import { useEffect } from 'react'\n\nimport { useScript } from './useScript'\n\n// it's an example, use your types instead\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const jQuery: any\n\nexport default function Component() {\n  // Load the script asynchronously\n  const status = useScript(`https://code.jquery.com/jquery-3.5.1.min.js`, {\n    removeOnUnmount: false,\n    id: 'jquery',\n  })\n\n  useEffect(() => {\n    if (typeof jQuery !== 'undefined') {\n      // jQuery is loaded => print the version\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n      alert(jQuery.fn.jquery)\n    }\n  }, [status])\n\n  return (\n    <div>\n      <p>{`Current status: ${status}`}</p>\n\n      {status === 'ready' && <p>You can use the script here.</p>}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScript/useScript.md",
    "content": "Dynamically load an external script in one line with this React hook. This can be useful to integrate a third party library like Google Analytics or Stripe.\n\nThis avoids loading this script in the `<head> </head>` on all your pages if it is not necessary.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScript/useScript.test.ts",
    "content": "import { act, cleanup, renderHook } from '@testing-library/react'\n\nimport { useScript } from './useScript'\n\ndescribe('useScript', () => {\n  it('should handle script loading error', () => {\n    const src = 'https://example.com/myscript.js'\n\n    const { result } = renderHook(() => useScript(src))\n\n    expect(result.current).toBe('loading')\n\n    act(() => {\n      // Simulate script error\n      document\n        .querySelector(`script[src=\"${src}\"]`)\n        ?.dispatchEvent(new Event('error'))\n    })\n\n    expect(result.current).toBe('error')\n  })\n\n  it('should remove script on unmount', () => {\n    const src = '/'\n\n    // First load the script\n    const { result } = renderHook(() =>\n      useScript(src, { removeOnUnmount: true }),\n    )\n\n    expect(result.current).toBe('loading')\n\n    // Make sure the document is loaded\n    act(() => {\n      document\n        .querySelector(`script[src=\"${src}\"]`)\n        ?.dispatchEvent(new Event('load'))\n    })\n\n    expect(result.current).toBe('ready')\n\n    // Remove the hook by unmounting and cleaning up the hook\n    cleanup()\n\n    // Check if the script is removed from the DOM\n    expect(document.querySelector(`script[src=\"${src}\"]`)).toBeNull()\n\n    // Try loading the script again\n    const { result: result2 } = renderHook(() =>\n      useScript(src, { removeOnUnmount: true }),\n    )\n\n    expect(result2.current).toBe('loading')\n\n    // Make sure the document is loaded\n    act(() => {\n      document\n        .querySelector(`script[src=\"${src}\"]`)\n        ?.dispatchEvent(new Event('load'))\n    })\n\n    expect(result2.current).toBe('ready')\n  })\n\n  it('should have a `id` attribute when given', () => {\n    const src = '/'\n    const id = 'my-script'\n\n    const { result } = renderHook(() => useScript(src, { id }))\n\n    // Make sure the document is loaded\n    act(() => {\n      document\n        .querySelector(`script[src=\"${src}\"]`)\n        ?.dispatchEvent(new Event('load'))\n    })\n\n    expect(result.current).toBe('ready')\n\n    expect(document.querySelector(`script[id=\"${id}\"]`)).not.toBeNull()\n    expect(document.querySelector(`script[src=\"${src}\"]`)?.id).toBe(id)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScript/useScript.ts",
    "content": "import { useEffect, useState } from 'react'\n\n/** Script loading status. */\ntype UseScriptStatus = 'idle' | 'loading' | 'ready' | 'error'\n\n/** Hook options. */\ntype UseScriptOptions = {\n  /** If `true`, prevents the script from being loaded (optional). */\n  shouldPreventLoad?: boolean\n  /** If `true`, removes the script from the DOM when the component unmounts (optional). */\n  removeOnUnmount?: boolean\n  /** Script's `id` (optional). */\n  id?: string\n}\n\n// Cached script statuses\nconst cachedScriptStatuses = new Map<string, UseScriptStatus | undefined>()\n\n/**\n * Gets the script element with the specified source URL.\n * @param {string} src - The source URL of the script to get.\n * @returns {{ node: HTMLScriptElement | null, status: UseScriptStatus | undefined }} The script element and its loading status.\n * @public\n * @example\n * ```tsx\n * const script = getScriptNode(src);\n * ```\n */\nfunction getScriptNode(src: string) {\n  const node: HTMLScriptElement | null = document.querySelector(\n    `script[src=\"${src}\"]`,\n  )\n  const status = node?.getAttribute('data-status') as\n    | UseScriptStatus\n    | undefined\n\n  return {\n    node,\n    status,\n  }\n}\n\n/**\n * Custom hook that dynamically loads scripts and tracking their loading status.\n * @param {string | null} src - The source URL of the script to load. Set to `null` or omit to prevent loading (optional).\n * @param {UseScriptOptions} [options] - Additional options for controlling script loading (optional).\n * @returns {UseScriptStatus} The status of the script loading, which can be one of 'idle', 'loading', 'ready', or 'error'.\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-script)\n * @example\n * const scriptStatus = useScript('https://example.com/script.js', { removeOnUnmount: true });\n * // Access the status of the script loading (e.g., 'loading', 'ready', 'error').\n */\nexport function useScript(\n  src: string | null,\n  options?: UseScriptOptions,\n): UseScriptStatus {\n  const [status, setStatus] = useState<UseScriptStatus>(() => {\n    if (!src || options?.shouldPreventLoad) {\n      return 'idle'\n    }\n\n    if (typeof window === 'undefined') {\n      // SSR Handling - always return 'loading'\n      return 'loading'\n    }\n\n    return cachedScriptStatuses.get(src) ?? 'loading'\n  })\n\n  useEffect(() => {\n    if (!src || options?.shouldPreventLoad) {\n      return\n    }\n\n    const cachedScriptStatus = cachedScriptStatuses.get(src)\n    if (cachedScriptStatus === 'ready' || cachedScriptStatus === 'error') {\n      // If the script is already cached, set its status immediately\n      setStatus(cachedScriptStatus)\n      return\n    }\n\n    // Fetch existing script element by src\n    // It may have been added by another instance of this hook\n    const script = getScriptNode(src)\n    let scriptNode = script.node\n\n    if (!scriptNode) {\n      // Create script element and add it to document body\n      scriptNode = document.createElement('script')\n      scriptNode.src = src\n      scriptNode.async = true\n      if (options?.id) {\n        scriptNode.id = options.id\n      }\n      scriptNode.setAttribute('data-status', 'loading')\n      document.body.appendChild(scriptNode)\n\n      // Store status in attribute on script\n      // This can be read by other instances of this hook\n      const setAttributeFromEvent = (event: Event) => {\n        const scriptStatus: UseScriptStatus =\n          event.type === 'load' ? 'ready' : 'error'\n\n        scriptNode?.setAttribute('data-status', scriptStatus)\n      }\n\n      scriptNode.addEventListener('load', setAttributeFromEvent)\n      scriptNode.addEventListener('error', setAttributeFromEvent)\n    } else {\n      // Grab existing script status from attribute and set to state.\n      setStatus(script.status ?? cachedScriptStatus ?? 'loading')\n    }\n\n    // Script event handler to update status in state\n    // Note: Even if the script already exists we still need to add\n    // event handlers to update the state for *this* hook instance.\n    const setStateFromEvent = (event: Event) => {\n      const newStatus = event.type === 'load' ? 'ready' : 'error'\n      setStatus(newStatus)\n      cachedScriptStatuses.set(src, newStatus)\n    }\n\n    // Add event listeners\n    scriptNode.addEventListener('load', setStateFromEvent)\n    scriptNode.addEventListener('error', setStateFromEvent)\n\n    // Remove event listeners on cleanup\n    return () => {\n      if (scriptNode) {\n        scriptNode.removeEventListener('load', setStateFromEvent)\n        scriptNode.removeEventListener('error', setStateFromEvent)\n      }\n\n      if (scriptNode && options?.removeOnUnmount) {\n        scriptNode.remove()\n        cachedScriptStatuses.delete(src)\n      }\n    }\n  }, [src, options?.shouldPreventLoad, options?.removeOnUnmount, options?.id])\n\n  return status\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScrollLock/index.ts",
    "content": "export * from './useScrollLock'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScrollLock/useScrollLock.demo.tsx",
    "content": "import { useScrollLock } from './useScrollLock'\n\n// Example 1: Auto lock the scroll of the body element when the modal mounts\nexport default function Modal() {\n  useScrollLock()\n  return <div>Modal</div>\n}\n\n// Example 2: Manually lock and unlock the scroll for a specific target\nexport function App() {\n  const { lock, unlock } = useScrollLock({\n    autoLock: false,\n    lockTarget: '#scrollable',\n  })\n\n  return (\n    <>\n      <div id=\"scrollable\" style={{ maxHeight: '50vh', overflow: 'scroll' }}>\n        {['red', 'blue', 'green'].map(color => (\n          <div key={color} style={{ backgroundColor: color, height: '30vh' }} />\n        ))}\n      </div>\n\n      <div style={{ gap: 16, display: 'flex' }}>\n        <button onClick={lock}>Lock</button>\n        <button onClick={unlock}>Unlock</button>\n      </div>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScrollLock/useScrollLock.md",
    "content": "A custom hook for locking and unlocking scroll.\n\nIt can be used when you need to automatically lock the scroll, like for a modal or a sidebar.\nYou can also use it to manually lock and unlock the scroll by disabling the `autoLock` feature.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScrollLock/useScrollLock.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useScrollLock } from './useScrollLock'\n\ndescribe('useScrollLock()', () => {\n  beforeEach(() => {\n    document.body.style.removeProperty('overflow')\n  })\n\n  it('should initially lock and unlock body', () => {\n    const { unmount } = renderHook(() => useScrollLock())\n\n    expect(document.body.style.overflow).toBe('hidden')\n    unmount()\n    expect(document.body.style.overflow).toBe('')\n  })\n\n  it('should initially lock and unlock the target element', () => {\n    const target = document.createElement('div')\n\n    document.body.appendChild(target)\n\n    const { unmount } = renderHook(() => useScrollLock({ lockTarget: target }))\n\n    expect(target.style.overflow).toBe('hidden')\n    unmount()\n    expect(target.style.overflow).toBe('')\n  })\n\n  it('should initially lock and unlock the target element by selector', () => {\n    const target = document.createElement('div')\n\n    target.id = 'target'\n    document.body.appendChild(target)\n\n    const { unmount } = renderHook(() =>\n      useScrollLock({ lockTarget: '#target' }),\n    )\n\n    expect(target.style.overflow).toBe('hidden')\n    unmount()\n    expect(target.style.overflow).toBe('')\n  })\n\n  it('should not initially lock and unlock', () => {\n    const { unmount } = renderHook(() => useScrollLock({ autoLock: false }))\n\n    expect(document.body.style.overflow).toBe('')\n    unmount()\n    expect(document.body.style.overflow).toBe('')\n  })\n\n  it('should lock and unlock manually', () => {\n    const { result } = renderHook(() => useScrollLock({ autoLock: false }))\n\n    expect(document.body.style.overflow).toBe('')\n    act(() => {\n      result.current.lock()\n    })\n    expect(document.body.style.overflow).toBe('hidden')\n    act(() => {\n      result.current.unlock()\n    })\n    expect(document.body.style.overflow).toBe('')\n  })\n\n  it(\"should keep the original style of the target element when it's unlocked\", () => {\n    const target = document.createElement('div')\n\n    target.style.overflow = 'auto'\n    document.body.appendChild(target)\n\n    const { result } = renderHook(() => useScrollLock({ lockTarget: target }))\n\n    expect(target.style.overflow).toBe('hidden')\n    act(() => {\n      result.current.unlock()\n    })\n    expect(target.style.overflow).toBe('auto')\n  })\n\n  it('should unlock on unmount even with initial is locked', () => {\n    const { unmount, result } = renderHook(() =>\n      useScrollLock({ autoLock: false }),\n    )\n\n    expect(document.body.style.overflow).toBe('')\n    act(() => {\n      result.current.lock()\n    })\n    expect(document.body.style.overflow).toBe('hidden')\n    unmount()\n    expect(document.body.style.overflow).toBe('')\n  })\n\n  it('should fallback to document.body if the target element is not found', () => {\n    const { unmount } = renderHook(() =>\n      useScrollLock({ lockTarget: '#non-existing' }),\n    )\n\n    expect(document.body.style.overflow).toBe('hidden')\n    unmount()\n    expect(document.body.style.overflow).toBe('')\n  })\n\n  it('should add padding-right to prevent width reflow', () => {\n    const { unmount } = renderHook(() => useScrollLock())\n\n    const scrollbarWidth = window.innerWidth - document.body.scrollWidth\n\n    expect(document.body.style.paddingRight).toBe(`${scrollbarWidth}px`)\n    unmount()\n    expect(document.body.style.paddingRight).toBe('')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useScrollLock/useScrollLock.ts",
    "content": "import { useRef, useState } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/** Hook options. */\ntype UseScrollLockOptions = {\n  /**\n   * Whether to lock the scroll initially.\n   * @default true\n   */\n  autoLock?: boolean\n  /**\n   * The target element to lock the scroll (default is the body element).\n   * @default document.body\n   */\n  lockTarget?: HTMLElement | string\n  /**\n   * Whether to prevent width reflow when locking the scroll.\n   * @default true\n   */\n  widthReflow?: boolean\n}\n\n/** Hook return type. */\ntype UseScrollLockReturn = {\n  /** Whether the scroll is locked. */\n  isLocked: boolean\n  /** Lock the scroll. */\n  lock: () => void\n  /** Unlock the scroll. */\n  unlock: () => void\n}\n\ntype OriginalStyle = {\n  overflow: CSSStyleDeclaration['overflow']\n  paddingRight: CSSStyleDeclaration['paddingRight']\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n/**\n * A custom hook that locks and unlocks scroll.\n * @param {UseScrollLockOptions} [options] - Options to configure the hook, by default it will lock the scroll automatically.\n * @returns {UseScrollLockReturn} - An object containing the lock and unlock functions.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-scroll-lock)\n * @example\n * ```tsx\n * // Lock the scroll when the modal is mounted, and unlock it when it's unmounted\n * useScrollLock()\n * ```\n * @example\n * ```tsx\n * // Manually lock and unlock the scroll\n * const { lock, unlock } = useScrollLock({ autoLock: false })\n *\n * return (\n *  <div>\n *   <button onClick={lock}>Lock</button>\n *   <button onClick={unlock}>Unlock</button>\n *  </div>\n * )\n * ```\n */\nexport function useScrollLock(\n  options: UseScrollLockOptions = {},\n): UseScrollLockReturn {\n  const { autoLock = true, lockTarget, widthReflow = true } = options\n  const [isLocked, setIsLocked] = useState(false)\n  const target = useRef<HTMLElement | null>(null)\n  const originalStyle = useRef<OriginalStyle | null>(null)\n\n  const lock = () => {\n    if (target.current) {\n      const { overflow, paddingRight } = target.current.style\n\n      // Save the original styles\n      originalStyle.current = { overflow, paddingRight }\n\n      // Prevent width reflow\n      if (widthReflow) {\n        // Use window inner width if body is the target as global scrollbar isn't part of the document\n        const offsetWidth =\n          target.current === document.body\n            ? window.innerWidth\n            : target.current.offsetWidth\n        // Get current computed padding right in pixels\n        const currentPaddingRight =\n          parseInt(window.getComputedStyle(target.current).paddingRight, 10) ||\n          0\n\n        const scrollbarWidth = offsetWidth - target.current.scrollWidth\n        target.current.style.paddingRight = `${scrollbarWidth + currentPaddingRight}px`\n      }\n\n      // Lock the scroll\n      target.current.style.overflow = 'hidden'\n\n      setIsLocked(true)\n    }\n  }\n\n  const unlock = () => {\n    if (target.current && originalStyle.current) {\n      target.current.style.overflow = originalStyle.current.overflow\n\n      // Only reset padding right if we changed it\n      if (widthReflow) {\n        target.current.style.paddingRight = originalStyle.current.paddingRight\n      }\n    }\n\n    setIsLocked(false)\n  }\n\n  useIsomorphicLayoutEffect(() => {\n    if (IS_SERVER) return\n\n    if (lockTarget) {\n      target.current =\n        typeof lockTarget === 'string'\n          ? document.querySelector(lockTarget)\n          : lockTarget\n    }\n\n    if (!target.current) {\n      target.current = document.body\n    }\n\n    if (autoLock) {\n      lock()\n    }\n\n    return () => {\n      unlock()\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [autoLock, lockTarget, widthReflow])\n\n  return { isLocked, lock, unlock }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useSessionStorage/index.ts",
    "content": "export * from './useSessionStorage'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useSessionStorage/useSessionStorage.demo.tsx",
    "content": "import { useSessionStorage } from './useSessionStorage'\n\nexport default function Component() {\n  const [value, setValue, removeValue] = useSessionStorage('test-key', 0)\n\n  return (\n    <div>\n      <p>Count: {value}</p>\n      <button\n        onClick={() => {\n          setValue((x: number) => x + 1)\n        }}\n      >\n        Increment\n      </button>\n      <button\n        onClick={() => {\n          setValue((x: number) => x - 1)\n        }}\n      >\n        Decrement\n      </button>\n      <button\n        onClick={() => {\n          removeValue()\n        }}\n      >\n        Reset\n      </button>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useSessionStorage/useSessionStorage.md",
    "content": "Persist the state with session storage so that it remains after a page refresh. This can be useful to record session information. This hook is used in the same way as useState except that you must pass the storage key in the 1st parameter. If the window object is not present (as in SSR), `useSessionStorage()` will return the default value.\n\nYou can also pass an optional third parameter to use a custom serializer/deserializer.\n\n**Note**: If you use this hook in an SSR context, set the `initializeWithValue` option to `false`, it will initialize in SSR with the initial value.\n\nRelated hooks:\n\n- [`useLocalStorage()`](/react-hook/use-local-storage)\n"
  },
  {
    "path": "packages/usehooks-ts/src/useSessionStorage/useSessionStorage.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { mockStorage } from '../../tests/mocks'\nimport { useSessionStorage } from './useSessionStorage'\n\nmockStorage('sessionStorage')\n\ndescribe('useSessionStorage()', () => {\n  beforeEach(() => {\n    window.sessionStorage.clear()\n  })\n\n  afterEach(() => {\n    vitest.clearAllMocks()\n  })\n\n  it('initial state is in the returned state', () => {\n    const { result } = renderHook(() => useSessionStorage('key', 'value'))\n\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Initial state is a callback function', () => {\n    const { result } = renderHook(() => useSessionStorage('key', () => 'value'))\n\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Initial state is an array', () => {\n    const { result } = renderHook(() => useSessionStorage('digits', [1, 2]))\n\n    expect(result.current[0]).toEqual([1, 2])\n  })\n\n  it('Initial state is a Map', () => {\n    const { result } = renderHook(() =>\n      useSessionStorage('map', new Map([['a', 1]])),\n    )\n\n    expect(result.current[0]).toEqual(new Map([['a', 1]]))\n  })\n\n  it('Initial state is a Set', () => {\n    const { result } = renderHook(() =>\n      useSessionStorage('set', new Set([1, 2])),\n    )\n\n    expect(result.current[0]).toEqual(new Set([1, 2]))\n  })\n\n  it('Initial state is a Date', () => {\n    const { result } = renderHook(() =>\n      useSessionStorage('date', new Date(2020, 1, 1)),\n    )\n\n    expect(result.current[0]).toEqual(new Date(2020, 1, 1))\n  })\n\n  it('Update the state', () => {\n    const { result } = renderHook(() => useSessionStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('edited')\n    })\n\n    expect(result.current[0]).toBe('edited')\n  })\n\n  it('Update the state writes sessionStorage', () => {\n    const { result } = renderHook(() => useSessionStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('edited')\n    })\n\n    expect(window.sessionStorage.getItem('key')).toBe(JSON.stringify('edited'))\n  })\n\n  it('Remove the state removes sessionStorage key', () => {\n    const { result } = renderHook(() => useSessionStorage('key', 'value'))\n\n    act(() => {\n      const setState = result.current[1]\n      setState('updated')\n    })\n\n    expect(result.current[0]).toBe('updated')\n    expect(window.sessionStorage.getItem('key')).toBe(JSON.stringify('updated'))\n\n    act(() => {\n      const removeValue = result.current[2]\n      removeValue()\n    })\n\n    // Expect null as it's a default return if storage key doesn't exist\n    expect(window.sessionStorage.getItem('key')).toBeNull()\n    // Expect the state to match the default value\n    expect(result.current[0]).toBe('value')\n  })\n\n  it('Update the state with undefined', () => {\n    const { result } = renderHook(() =>\n      useSessionStorage<string | undefined>('keytest', 'value'),\n    )\n\n    act(() => {\n      const setState = result.current[1]\n      setState(undefined)\n    })\n\n    expect(result.current[0]).toBeUndefined()\n  })\n\n  it('Update the state with a callback function', () => {\n    const { result } = renderHook(() => useSessionStorage('count', 2))\n\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[0]).toBe(3)\n    expect(window.sessionStorage.getItem('count')).toEqual('3')\n  })\n\n  it('Update the state with a callback function multiple times per render', () => {\n    const { result } = renderHook(() => useSessionStorage('count', 2))\n\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n      setState(prev => prev + 1)\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[0]).toBe(5)\n    expect(window.sessionStorage.getItem('count')).toEqual('5')\n  })\n\n  it('[Event] Update one hook updates the others', () => {\n    const initialValues: [string, unknown] = ['key', 'initial']\n    const { result: A } = renderHook(() => useSessionStorage(...initialValues))\n    const { result: B } = renderHook(() => useSessionStorage(...initialValues))\n    const { result: C } = renderHook(() =>\n      useSessionStorage('other-key', 'initial'),\n    )\n\n    act(() => {\n      const setState = A.current[1]\n      setState('edited')\n    })\n\n    expect(B.current[0]).toBe('edited')\n    expect(C.current[0]).toBe('initial')\n  })\n\n  it('[Event] Updating one hook does not update others with a different key', () => {\n    let renderCount = 0\n    const { result: A } = renderHook(() => {\n      renderCount++\n      return useSessionStorage('key1', {})\n    })\n    const { result: B } = renderHook(() => useSessionStorage('key2', 'initial'))\n\n    expect(renderCount).toBe(1)\n\n    act(() => {\n      const setStateA = A.current[1]\n      setStateA({ a: 1 })\n    })\n\n    expect(renderCount).toBe(2)\n\n    act(() => {\n      const setStateB = B.current[1]\n      setStateB('edited')\n    })\n\n    expect(renderCount).toBe(2)\n  })\n\n  it('setValue is referentially stable', () => {\n    const { result } = renderHook(() => useSessionStorage('count', 1))\n\n    // Store a reference to the original setValue\n    const originalCallback = result.current[1]\n\n    // Now invoke a state update, if setValue is not referentially stable then this will cause the originalCallback\n    // reference to not be equal to the new setValue function\n    act(() => {\n      const setState = result.current[1]\n      setState(prev => prev + 1)\n    })\n\n    expect(result.current[1] === originalCallback).toBe(true)\n  })\n\n  it('should use default JSON.stringify and JSON.parse when serializer/deserializer not provided', () => {\n    const { result } = renderHook(() =>\n      useSessionStorage('key', 'initialValue'),\n    )\n\n    act(() => {\n      result.current[1]('newValue')\n    })\n\n    expect(sessionStorage.getItem('key')).toBe(JSON.stringify('newValue'))\n  })\n\n  it('should use custom serializer and deserializer when provided', () => {\n    const serializer = (value: string) => value.toUpperCase()\n    const deserializer = (value: string) => value.toLowerCase()\n\n    const { result } = renderHook(() =>\n      useSessionStorage('key', 'initialValue', { serializer, deserializer }),\n    )\n\n    act(() => {\n      result.current[1]('NewValue')\n    })\n\n    expect(sessionStorage.getItem('key')).toBe('NEWVALUE')\n  })\n\n  it('should handle undefined values with custom deserializer', () => {\n    const serializer = (value: number | undefined) => String(value)\n    const deserializer = (value: string) =>\n      value === 'undefined' ? undefined : Number(value)\n\n    const { result } = renderHook(() =>\n      useSessionStorage<number | undefined>('key', 0, {\n        serializer,\n        deserializer,\n      }),\n    )\n\n    act(() => {\n      result.current[1](undefined)\n    })\n\n    expect(sessionStorage.getItem('key')).toBe('undefined')\n\n    act(() => {\n      result.current[1](42)\n    })\n\n    expect(sessionStorage.getItem('key')).toBe('42')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useSessionStorage/useSessionStorage.ts",
    "content": "import { useCallback, useEffect, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\nimport { useEventCallback } from '../useEventCallback'\nimport { useEventListener } from '../useEventListener'\n\ndeclare global {\n  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n  interface WindowEventMap {\n    'session-storage': CustomEvent\n  }\n}\n\n/**\n * Represents the options for customizing the behavior of serialization and deserialization.\n * @template T - The type of the state to be stored in session storage.\n */\ntype UseSessionStorageOptions<T> = {\n  /** A function to serialize the value before storing it. */\n  serializer?: (value: T) => string\n  /** A function to deserialize the stored value. */\n  deserializer?: (value: string) => T\n  /**\n   * If `true` (default), the hook will initialize reading the session storage. In SSR, you should set it to `false`, returning the initial value initially.\n   * @default true\n   */\n  initializeWithValue?: boolean\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n/**\n * Custom hook that uses the [`sessionStorage API`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) to persist state across page reloads.\n * @template T - The type of the state to be stored in session storage.\n * @param {string} key - The key under which the value will be stored in session storage.\n * @param {T | (() => T)} initialValue - The initial value of the state or a function that returns the initial value.\n * @param {?UseSessionStorageOptions<T>} [options] - Options for customizing the behavior of serialization and deserialization (optional).\n * @returns {[T, Dispatch<SetStateAction<T>>, () => void]} A tuple containing the stored value, a function to set the value and a function to remove the key from storage.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-session-storage)\n * @example\n * ```tsx\n * const [count, setCount, removeCount] = useSessionStorage('count', 0);\n * // Access the `count` value, the `setCount` function to update it and `removeCount` function to remove the key from storage.\n * ```\n */\nexport function useSessionStorage<T>(\n  key: string,\n  initialValue: T | (() => T),\n  options: UseSessionStorageOptions<T> = {},\n): [T, Dispatch<SetStateAction<T>>, () => void] {\n  const { initializeWithValue = true } = options\n\n  const serializer = useCallback<(value: T) => string>(\n    value => {\n      if (options.serializer) {\n        return options.serializer(value)\n      }\n\n      return JSON.stringify(value)\n    },\n    [options],\n  )\n\n  const deserializer = useCallback<(value: string) => T>(\n    value => {\n      if (options.deserializer) {\n        return options.deserializer(value)\n      }\n      // Support 'undefined' as a value\n      if (value === 'undefined') {\n        return undefined as unknown as T\n      }\n\n      const defaultValue =\n        initialValue instanceof Function ? initialValue() : initialValue\n\n      let parsed: unknown\n      try {\n        parsed = JSON.parse(value)\n      } catch (error) {\n        console.error('Error parsing JSON:', error)\n        return defaultValue // Return initialValue if parsing fails\n      }\n\n      return parsed as T\n    },\n    [options, initialValue],\n  )\n\n  // Get from session storage then\n  // parse stored json or return initialValue\n  const readValue = useCallback((): T => {\n    const initialValueToUse =\n      initialValue instanceof Function ? initialValue() : initialValue\n\n    // Prevent build error \"window is undefined\" but keep working\n    if (IS_SERVER) {\n      return initialValueToUse\n    }\n\n    try {\n      const raw = window.sessionStorage.getItem(key)\n      return raw ? deserializer(raw) : initialValueToUse\n    } catch (error) {\n      console.warn(`Error reading sessionStorage key “${key}”:`, error)\n      return initialValueToUse\n    }\n  }, [initialValue, key, deserializer])\n\n  const [storedValue, setStoredValue] = useState(() => {\n    if (initializeWithValue) {\n      return readValue()\n    }\n\n    return initialValue instanceof Function ? initialValue() : initialValue\n  })\n\n  // Return a wrapped version of useState's setter function that ...\n  // ... persists the new value to sessionStorage.\n  const setValue: Dispatch<SetStateAction<T>> = useEventCallback(value => {\n    // Prevent build error \"window is undefined\" but keeps working\n    if (IS_SERVER) {\n      console.warn(\n        `Tried setting sessionStorage key “${key}” even though environment is not a client`,\n      )\n    }\n\n    try {\n      // Allow value to be a function so we have the same API as useState\n      const newValue = value instanceof Function ? value(readValue()) : value\n\n      // Save to session storage\n      window.sessionStorage.setItem(key, serializer(newValue))\n\n      // Save state\n      setStoredValue(newValue)\n\n      // We dispatch a custom event so every similar useSessionStorage hook is notified\n      window.dispatchEvent(new StorageEvent('session-storage', { key }))\n    } catch (error) {\n      console.warn(`Error setting sessionStorage key “${key}”:`, error)\n    }\n  })\n\n  const removeValue = useEventCallback(() => {\n    // Prevent build error \"window is undefined\" but keeps working\n    if (IS_SERVER) {\n      console.warn(\n        `Tried removing sessionStorage key “${key}” even though environment is not a client`,\n      )\n    }\n\n    const defaultValue =\n      initialValue instanceof Function ? initialValue() : initialValue\n\n    // Remove the key from session storage\n    window.sessionStorage.removeItem(key)\n\n    // Save state with default value\n    setStoredValue(defaultValue)\n\n    // We dispatch a custom event so every similar useSessionStorage hook is notified\n    window.dispatchEvent(new StorageEvent('session-storage', { key }))\n  })\n\n  useEffect(() => {\n    setStoredValue(readValue())\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [key])\n\n  const handleStorageChange = useCallback(\n    (event: StorageEvent | CustomEvent) => {\n      if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n        return\n      }\n      setStoredValue(readValue())\n    },\n    [key, readValue],\n  )\n\n  // this only works for other documents, not the current one\n  useEventListener('storage', handleStorageChange)\n\n  // this is a custom event, triggered in writeValueToSessionStorage\n  // See: useSessionStorage()\n  useEventListener('session-storage', handleStorageChange)\n\n  return [storedValue, setValue, removeValue]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useStep/index.ts",
    "content": "export * from './useStep'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useStep/useStep.demo.tsx",
    "content": "import { useStep } from './useStep'\n\nexport default function Component() {\n  const [currentStep, helpers] = useStep(5)\n\n  const {\n    canGoToPrevStep,\n    canGoToNextStep,\n    goToNextStep,\n    goToPrevStep,\n    reset,\n    setStep,\n  } = helpers\n\n  return (\n    <>\n      <p>Current step is {currentStep}</p>\n      <p>Can go to previous step {canGoToPrevStep ? 'yes' : 'no'}</p>\n      <p>Can go to next step {canGoToNextStep ? 'yes' : 'no'}</p>\n      <button onClick={goToNextStep}>Go to next step</button>\n      <button onClick={goToPrevStep}>Go to previous step</button>\n      <button onClick={reset}>Reset</button>\n      <button\n        onClick={() => {\n          setStep(3)\n        }}\n      >\n        Set to step 3\n      </button>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useStep/useStep.md",
    "content": "A simple abstraction to play with a stepper, don't repeat yourself.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useStep/useStep.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useStep } from './useStep'\n\ndescribe('useStep()', () => {\n  it('should use step', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    expect(result.current[0]).toBe(1)\n    expect(typeof result.current[1].goToNextStep).toBe('function')\n    expect(typeof result.current[1].goToPrevStep).toBe('function')\n    expect(typeof result.current[1].setStep).toBe('function')\n    expect(typeof result.current[1].reset).toBe('function')\n    expect(typeof result.current[1].canGoToNextStep).toBe('boolean')\n    expect(typeof result.current[1].canGoToPrevStep).toBe('boolean')\n  })\n\n  it('should increment step', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    act(() => {\n      result.current[1].goToNextStep()\n    })\n\n    expect(result.current[0]).toBe(2)\n  })\n\n  it('should decrement step', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    act(() => {\n      result.current[1].setStep(2)\n    })\n\n    act(() => {\n      result.current[1].goToPrevStep()\n    })\n\n    expect(result.current[0]).toBe(1)\n  })\n\n  it('should reset step', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    act(() => {\n      result.current[1].reset()\n    })\n\n    expect(result.current[0]).toBe(1)\n  })\n\n  it('should set step', () => {\n    const { result } = renderHook(() => useStep(3))\n\n    const newStep = 2\n\n    act(() => {\n      result.current[1].setStep(newStep)\n    })\n\n    expect(result.current[0]).toBe(newStep)\n  })\n\n  it('should return if prev step is available', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    act(() => {\n      result.current[1].setStep(2)\n    })\n\n    expect(result.current[1].canGoToPrevStep).toBe(true)\n  })\n\n  it('should return if next step is available', () => {\n    const { result } = renderHook(() => useStep(2))\n\n    expect(result.current[1].canGoToNextStep).toBe(true)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useStep/useStep.ts",
    "content": "import { useCallback, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\n/** Represents the second element of the output of the `useStep` hook. */\ntype UseStepActions = {\n  /** Go to the next step in the process. */\n  goToNextStep: () => void\n  /** Go to the previous step in the process. */\n  goToPrevStep: () => void\n  /** Reset the step to the initial step. */\n  reset: () => void\n  /** Check if the next step is available. */\n  canGoToNextStep: boolean\n  /** Check if the previous step is available. */\n  canGoToPrevStep: boolean\n  /** Set the current step to a specific value. */\n  setStep: Dispatch<SetStateAction<number>>\n}\n\ntype SetStepCallbackType = (step: number | ((step: number) => number)) => void\n\n/**\n * Custom hook that manages and navigates between steps in a multi-step process.\n * @param {number} maxStep - The maximum step in the process.\n * @returns {[number, UseStepActions]} An tuple containing the current step and helper functions for navigating steps.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-step)\n * @example\n * ```tsx\n * const [currentStep, { goToNextStep, goToPrevStep, reset, canGoToNextStep, canGoToPrevStep, setStep }] = useStep(3);\n * // Access and use the current step and provided helper functions.\n * ```\n */\nexport function useStep(maxStep: number): [number, UseStepActions] {\n  const [currentStep, setCurrentStep] = useState(1)\n\n  const canGoToNextStep = currentStep + 1 <= maxStep\n  const canGoToPrevStep = currentStep - 1 > 0\n\n  const setStep = useCallback<SetStepCallbackType>(\n    step => {\n      // Allow value to be a function so we have the same API as useState\n      const newStep = step instanceof Function ? step(currentStep) : step\n\n      if (newStep >= 1 && newStep <= maxStep) {\n        setCurrentStep(newStep)\n        return\n      }\n\n      throw new Error('Step not valid')\n    },\n    [maxStep, currentStep],\n  )\n\n  const goToNextStep = useCallback(() => {\n    if (canGoToNextStep) {\n      setCurrentStep(step => step + 1)\n    }\n  }, [canGoToNextStep])\n\n  const goToPrevStep = useCallback(() => {\n    if (canGoToPrevStep) {\n      setCurrentStep(step => step - 1)\n    }\n  }, [canGoToPrevStep])\n\n  const reset = useCallback(() => {\n    setCurrentStep(1)\n  }, [])\n\n  return [\n    currentStep,\n    {\n      goToNextStep,\n      goToPrevStep,\n      canGoToNextStep,\n      canGoToPrevStep,\n      setStep,\n      reset,\n    },\n  ]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTernaryDarkMode/index.ts",
    "content": "export * from './useTernaryDarkMode'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTernaryDarkMode/useTernaryDarkMode.demo.tsx",
    "content": "import { useTernaryDarkMode } from './useTernaryDarkMode'\n\ntype TernaryDarkMode = ReturnType<typeof useTernaryDarkMode>['ternaryDarkMode']\n\nexport default function Component() {\n  const {\n    isDarkMode,\n    ternaryDarkMode,\n    setTernaryDarkMode,\n    toggleTernaryDarkMode,\n  } = useTernaryDarkMode()\n\n  return (\n    <div>\n      <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>\n      <p>ternaryMode: {ternaryDarkMode}</p>\n      <p>\n        Toggle between three modes\n        <button onClick={toggleTernaryDarkMode}>\n          Toggle from {ternaryDarkMode}\n        </button>\n      </p>\n      <p>\n        Select a mode\n        <br />\n        <select\n          name=\"select-ternaryDarkMode\"\n          onChange={ev => {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n            setTernaryDarkMode(ev.target.value as TernaryDarkMode)\n          }}\n          value={ternaryDarkMode}\n        >\n          <option value=\"light\">light</option>\n          <option value=\"system\">system</option>\n          <option value=\"dark\">dark</option>\n        </select>\n      </p>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTernaryDarkMode/useTernaryDarkMode.md",
    "content": "This React Hook offers you an interface to toggle and read the dark theme mode between three values. It uses internally [`useLocalStorage()`](/react-hook/use-local-storage) to persist the value and listens the OS color scheme preferences.\n\nIf no value exists in local storage, it will default to `\"system\"`, though this can be changed by using the `defaultValue` hook parameter.\n\n**Note**: If you use this hook in an SSR context, set the `initializeWithValue` option to `false`.\n\nReturned value\n\n- The `isDarkMode` is a boolean for the final outcome, to let you be able to use with your logic.\n- The `ternaryModeCode` is of a literal type `\"dark\" | \"system\" | \"light\"`.\n\n  When `ternaryModeCode` is set to `system`, the `isDarkMode` will use system theme, like of iOS and MacOS.\n\n  Also, `ternaryModeCode` implicitly exports a type with `type TernaryDarkMode = typeof ternaryDarkMode`\n\nReturned interface\n\n- The `toggleTernaryDarkMode` is a function to cycle `ternaryModeCode` between `dark`, `system` and `light`(in this order).\n- The `setTernaryDarkMode` accepts a parameter of type `TernaryDarkMode` and set it as `ternaryModeCode`.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTernaryDarkMode/useTernaryDarkMode.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { mockMatchMedia, mockStorage } from '../../tests/mocks'\nimport { useTernaryDarkMode } from './useTernaryDarkMode'\n\nmockStorage('localStorage')\n\ndescribe('useTernaryDarkMode()', () => {\n  beforeEach(() => {\n    window.localStorage.clear()\n    mockMatchMedia(false)\n  })\n\n  it('should initialize with default value (light)', () => {\n    const { result } = renderHook(() => useTernaryDarkMode())\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('system')\n  })\n\n  it('should initialize with default value (dark)', () => {\n    mockMatchMedia(true)\n    const { result } = renderHook(() => useTernaryDarkMode())\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(result.current.ternaryDarkMode).toBe('system')\n  })\n\n  it('should setter work', () => {\n    const { result } = renderHook(() => useTernaryDarkMode())\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('system')\n\n    act(() => {\n      result.current.setTernaryDarkMode('dark')\n    })\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(result.current.ternaryDarkMode).toBe('dark')\n\n    act(() => {\n      result.current.setTernaryDarkMode('light')\n    })\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('light')\n  })\n\n  it('should toggle dark mode', () => {\n    const { result } = renderHook(() => useTernaryDarkMode())\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('system')\n\n    act(() => {\n      result.current.toggleTernaryDarkMode()\n    })\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(result.current.ternaryDarkMode).toBe('dark')\n\n    act(() => {\n      result.current.toggleTernaryDarkMode()\n    })\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('light')\n  })\n\n  it('should accept a custom localStorage key', () => {\n    const { result } = renderHook(() =>\n      useTernaryDarkMode({ localStorageKey: 'custom-key' }),\n    )\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('system')\n\n    act(() => {\n      result.current.toggleTernaryDarkMode()\n    })\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(result.current.ternaryDarkMode).toBe('dark')\n    expect(window.localStorage.getItem('custom-key')).toBe(\n      JSON.stringify('dark'),\n    )\n\n    act(() => {\n      result.current.toggleTernaryDarkMode()\n    })\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('light')\n    expect(window.localStorage.getItem('custom-key')).toBe(\n      JSON.stringify('light'),\n    )\n  })\n\n  it('should accept a custom default value (dark)', () => {\n    const { result } = renderHook(() =>\n      useTernaryDarkMode({ defaultValue: 'dark' }),\n    )\n\n    expect(result.current.isDarkMode).toBe(true)\n    expect(result.current.ternaryDarkMode).toBe('dark')\n  })\n\n  it('should accept a custom default value (light)', () => {\n    const { result } = renderHook(() =>\n      useTernaryDarkMode({ defaultValue: 'light' }),\n    )\n\n    expect(result.current.isDarkMode).toBe(false)\n    expect(result.current.ternaryDarkMode).toBe('light')\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTernaryDarkMode/useTernaryDarkMode.ts",
    "content": "import type { Dispatch, SetStateAction } from 'react'\n\nimport { useLocalStorage } from '../useLocalStorage'\nimport { useMediaQuery } from '../useMediaQuery'\n\nconst COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'\nconst LOCAL_STORAGE_KEY = 'usehooks-ts-ternary-dark-mode'\n\n/** Ternary dark mode options. */\nexport type TernaryDarkMode = 'system' | 'dark' | 'light'\n\n/** Options for the `useTernaryDarkMode` hook. */\nexport type TernaryDarkModeOptions = {\n  /**\n   * The default value for the dark mode.\n   * @default 'system'\n   */\n  defaultValue?: TernaryDarkMode\n  /**\n   * The key for storing dark mode preference in local storage.\n   * @default 'usehooks-ts-ternary-dark-mode'\n   */\n  localStorageKey?: string\n  /**\n   * If `true` (default), the hook will initialize reading `localStorage`. In SSR, you should set it to `false`, returning default values initially.\n   * @default true\n   */\n  initializeWithValue?: boolean\n}\n\n/** Represents the return type of the `useTernaryDarkMode` hook. */\nexport type TernaryDarkModeReturn = {\n  /** The current state of the dark mode. */\n  isDarkMode: boolean\n  /** The current state of the dark mode. */\n  ternaryDarkMode: TernaryDarkMode\n  /** A function to set the dark mode state. */\n  setTernaryDarkMode: Dispatch<SetStateAction<TernaryDarkMode>>\n  /** A function to toggle the dark mode state. */\n  toggleTernaryDarkMode: () => void\n}\n\n/**\n * Custom hook that manages ternary (system, dark, light) dark mode with local storage support.\n * @param {?TernaryDarkModeOptions | string} [options] - Options or the local storage key for the hook.\n * @returns {TernaryDarkModeReturn} An object containing the dark mode state and helper functions.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-ternary-dark-mode)\n * @example\n * ```tsx\n * const { isDarkMode, ternaryDarkMode, setTernaryDarkMode, toggleTernaryDarkMode } = useTernaryDarkMode({ defaultValue: 'dark' });\n * // Access and use the dark mode state and provided helper functions.\n * ```\n */\nexport function useTernaryDarkMode({\n  defaultValue = 'system',\n  localStorageKey = LOCAL_STORAGE_KEY,\n  initializeWithValue = true,\n}: TernaryDarkModeOptions = {}): TernaryDarkModeReturn {\n  const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY, { initializeWithValue })\n  const [mode, setMode] = useLocalStorage(localStorageKey, defaultValue, {\n    initializeWithValue,\n  })\n\n  const isDarkMode = mode === 'dark' || (mode === 'system' && isDarkOS)\n\n  const toggleTernaryDarkMode = () => {\n    const modes: TernaryDarkMode[] = ['light', 'system', 'dark']\n    setMode((prevMode): TernaryDarkMode => {\n      const nextIndex = (modes.indexOf(prevMode) + 1) % modes.length\n      return modes[nextIndex]\n    })\n  }\n\n  return {\n    isDarkMode,\n    ternaryDarkMode: mode,\n    setTernaryDarkMode: setMode,\n    toggleTernaryDarkMode,\n  }\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTimeout/index.ts",
    "content": "export * from './useTimeout'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTimeout/useTimeout.demo.tsx",
    "content": "import { useState } from 'react'\n\nimport { useTimeout } from './useTimeout'\n\nexport default function Component() {\n  const [visible, setVisible] = useState(true)\n\n  const hide = () => {\n    setVisible(false)\n  }\n\n  useTimeout(hide, 5000)\n\n  return (\n    <div>\n      <p>\n        {visible\n          ? \"I'm visible for 5000ms\"\n          : 'You can no longer see this content'}\n      </p>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTimeout/useTimeout.md",
    "content": "Very similar to the [`useInterval` ](/react-hook/use-interval) hook, this React hook implements the native [`setTimeout`](https://www.w3schools.com/jsref/met_win_settimeout.asp) function keeping the same interface.\n\nYou can enable the timeout by setting `delay` as a `number` or disabling it using `null`.\n\nWhen the time finishes, the callback function is called.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTimeout/useTimeout.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useTimeout } from './useTimeout'\n\ndescribe('useTimeout()', () => {\n  it('should call the callback after 1 min', () => {\n    vitest.useFakeTimers()\n\n    const delay = 60000\n    const callback = vitest.fn()\n\n    renderHook(() => {\n      useTimeout(callback, delay)\n    })\n\n    expect(callback).not.toHaveBeenCalled()\n\n    act(() => {\n      vitest.advanceTimersByTime(delay)\n    })\n\n    expect(callback).toHaveBeenCalledTimes(1)\n  })\n\n  it('should not do anything if \"delay\" is null', () => {\n    vitest.useFakeTimers()\n\n    const delay = null\n    const callback = vitest.fn()\n\n    renderHook(() => {\n      useTimeout(callback, delay)\n    })\n\n    expect(callback).not.toHaveBeenCalled()\n\n    act(() => {\n      vitest.runAllTimers()\n    })\n\n    expect(callback).not.toHaveBeenCalled()\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useTimeout/useTimeout.ts",
    "content": "import { useEffect, useRef } from 'react'\n\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/**\n * Custom hook that handles timeouts in React components using the [`setTimeout API`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout).\n * @param {() => void} callback - The function to be executed when the timeout elapses.\n * @param {number | null} delay - The duration (in milliseconds) for the timeout. Set to `null` to clear the timeout.\n * @returns {void} This hook does not return anything.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-timeout)\n * @example\n * ```tsx\n * // Usage of useTimeout hook\n * useTimeout(() => {\n *   // Code to be executed after the specified delay\n * }, 1000); // Set a timeout of 1000 milliseconds (1 second)\n * ```\n */\nexport function useTimeout(callback: () => void, delay: number | null): void {\n  const savedCallback = useRef(callback)\n\n  // Remember the latest callback if it changes.\n  useIsomorphicLayoutEffect(() => {\n    savedCallback.current = callback\n  }, [callback])\n\n  // Set up the timeout.\n  useEffect(() => {\n    // Don't schedule if no delay is specified.\n    // Note: 0 is a valid value for delay.\n    if (!delay && delay !== 0) {\n      return\n    }\n\n    const id = setTimeout(() => {\n      savedCallback.current()\n    }, delay)\n\n    return () => {\n      clearTimeout(id)\n    }\n  }, [delay])\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useToggle/index.ts",
    "content": "export * from './useToggle'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useToggle/useToggle.demo.tsx",
    "content": "import { useToggle } from './useToggle'\n\nexport default function Component() {\n  const [value, toggle, setValue] = useToggle()\n\n  // Just an example to use \"setValue\"\n  const customToggle = () => {\n    setValue((x: boolean) => !x)\n  }\n\n  return (\n    <>\n      <p>\n        Value is <code>{value.toString()}</code>\n      </p>\n      <button\n        onClick={() => {\n          setValue(true)\n        }}\n      >\n        set true\n      </button>\n      <button\n        onClick={() => {\n          setValue(false)\n        }}\n      >\n        set false\n      </button>\n      <button onClick={toggle}>toggle</button>\n      <button onClick={customToggle}>custom toggle</button>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useToggle/useToggle.md",
    "content": "A simple abstraction to play with a boolean, don't repeat yourself.\n\nRelated hooks:\n\n- [`useBoolean()`](/react-hook/use-boolean)\n"
  },
  {
    "path": "packages/usehooks-ts/src/useToggle/useToggle.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useToggle } from './useToggle'\n\ndescribe('use toggle()', () => {\n  it('should use toggle be ok', () => {\n    const { result } = renderHook(() => useToggle())\n    const [value, toggle, setValue] = result.current\n\n    expect(value).toBe(false)\n    expect(typeof toggle).toBe('function')\n    expect(typeof setValue).toBe('function')\n  })\n\n  it('should default value works', () => {\n    const { result } = renderHook(() => useToggle(true))\n    const [value] = result.current\n\n    expect(value).toBe(true)\n  })\n\n  it('setValue should mutate the value', () => {\n    const { result } = renderHook(() => useToggle())\n    const [, , setValue] = result.current\n\n    expect(result.current[0]).toBe(false)\n\n    act(() => {\n      setValue(true)\n    })\n\n    expect(result.current[0]).toBe(true)\n\n    act(() => {\n      setValue(prev => !prev)\n    })\n\n    expect(result.current[0]).toBe(false)\n  })\n\n  it('toggle should mutate the value', () => {\n    const { result } = renderHook(() => useToggle())\n    const [, toggle] = result.current\n\n    expect(result.current[0]).toBe(false)\n\n    act(() => {\n      toggle()\n    })\n\n    expect(result.current[0]).toBe(true)\n\n    act(() => {\n      toggle()\n    })\n\n    expect(result.current[0]).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useToggle/useToggle.ts",
    "content": "import { useCallback, useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\n/**\n * Custom hook that manages a boolean toggle state in React components.\n * @param {boolean} [defaultValue] - The initial value for the toggle state.\n * @returns {[boolean, () => void, Dispatch<SetStateAction<boolean>>]} A tuple containing the current state,\n * a function to toggle the state, and a function to set the state explicitly.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-toggle)\n * @example\n * ```tsx\n * const [isToggled, toggle, setToggle] = useToggle(); // Initial value is false\n * // OR\n * const [isToggled, toggle, setToggle] = useToggle(true); // Initial value is true\n * // Use isToggled in your component, toggle to switch the state, setToggle to set the state explicitly.\n * ```\n */\nexport function useToggle(\n  defaultValue?: boolean,\n): [boolean, () => void, Dispatch<SetStateAction<boolean>>] {\n  const [value, setValue] = useState(!!defaultValue)\n\n  const toggle = useCallback(() => {\n    setValue(x => !x)\n  }, [])\n\n  return [value, toggle, setValue]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useUnmount/index.ts",
    "content": "export * from './useUnmount'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useUnmount/useUnmount.demo.tsx",
    "content": "import { useUnmount } from './useUnmount'\n\nexport default function Component() {\n  useUnmount(() => {\n    // Cleanup logic here\n  })\n\n  return <div>Hello world</div>\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useUnmount/useUnmount.md",
    "content": "Hook that runs a cleanup function when the component is unmounted.\n\n### Parameters\n\n- `func`: The cleanup function to be executed on unmount.\n"
  },
  {
    "path": "packages/usehooks-ts/src/useUnmount/useUnmount.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useUnmount } from './useUnmount'\n\ndescribe('useUnmount()', () => {\n  it('should call the cleanup function on unmount', () => {\n    const cleanupMock = vitest.fn()\n\n    const { unmount } = renderHook(() => {\n      useUnmount(cleanupMock)\n    })\n\n    expect(cleanupMock).not.toHaveBeenCalled()\n\n    act(() => {\n      unmount()\n    })\n\n    expect(cleanupMock).toHaveBeenCalled()\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useUnmount/useUnmount.ts",
    "content": "import { useEffect, useRef } from 'react'\n\n/**\n * Custom hook that runs a cleanup function when the component is unmounted.\n * @param {() => void} func - The cleanup function to be executed on unmount.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-unmount)\n * @example\n * ```tsx\n * useUnmount(() => {\n *   // Cleanup logic here\n * });\n * ```\n */\nexport function useUnmount(func: () => void) {\n  const funcRef = useRef(func)\n\n  funcRef.current = func\n\n  useEffect(\n    () => () => {\n      funcRef.current()\n    },\n    [],\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useWindowSize/index.ts",
    "content": "export * from './useWindowSize'\n"
  },
  {
    "path": "packages/usehooks-ts/src/useWindowSize/useWindowSize.demo.tsx",
    "content": "import { useWindowSize } from './useWindowSize'\n\nexport default function Component() {\n  const { width = 0, height = 0 } = useWindowSize()\n\n  return (\n    <div>\n      The current window dimensions are:{' '}\n      <code>{JSON.stringify({ width, height })}</code>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/usehooks-ts/src/useWindowSize/useWindowSize.md",
    "content": "Easily retrieve window dimensions with this React Hook which also works onResize.\n\n### Parameters\n\n- `initializeWithValue?: boolean`: If you use this hook in an SSR context, set it to `false` (default `true`)\n- `debounceDelay?: number`: The delay in milliseconds before the callback is invoked (disabled by default for retro-compatibility).\n"
  },
  {
    "path": "packages/usehooks-ts/src/useWindowSize/useWindowSize.test.ts",
    "content": "import { act, renderHook } from '@testing-library/react'\n\nimport { useWindowSize } from './useWindowSize'\n\nconst windowResize = (dimension: 'width' | 'height', value: number): void => {\n  if (dimension === 'width') {\n    window.innerWidth = value\n  }\n\n  if (dimension === 'height') {\n    window.innerHeight = value\n  }\n\n  window.dispatchEvent(new Event('resize'))\n}\n\ndescribe('useWindowSize()', () => {\n  beforeEach(() => {\n    vi.clearAllMocks()\n    vi.useFakeTimers() // Mock timers\n\n    // Set the initial window size\n    windowResize('width', 1920)\n    windowResize('height', 1080)\n  })\n\n  it('should initialize', () => {\n    const { result } = renderHook(() => useWindowSize())\n    const { height, width } = result.current\n    expect(typeof height).toBe('number')\n    expect(typeof width).toBe('number')\n    expect(result.current.width).toBe(1920)\n    expect(result.current.height).toBe(1080)\n  })\n\n  it('should return the corresponding height', () => {\n    const { result } = renderHook(() => useWindowSize())\n\n    act(() => {\n      windowResize('height', 420)\n    })\n\n    expect(result.current.height).toBe(420)\n\n    act(() => {\n      windowResize('height', 2196)\n    })\n\n    expect(result.current.height).toBe(2196)\n  })\n\n  it('should return the corresponding width', () => {\n    const { result } = renderHook(() => useWindowSize())\n\n    act(() => {\n      windowResize('width', 420)\n    })\n\n    expect(result.current.width).toBe(420)\n\n    act(() => {\n      windowResize('width', 2196)\n    })\n\n    expect(result.current.width).toBe(2196)\n  })\n\n  it('should debounce the callback', () => {\n    const { result } = renderHook(() => useWindowSize({ debounceDelay: 100 }))\n\n    expect(result.current.width).toBe(1920)\n    expect(result.current.height).toBe(1080)\n\n    act(() => {\n      windowResize('width', 2196)\n      windowResize('height', 2196)\n    })\n\n    // Don't changed yet\n    expect(result.current.width).toBe(1920)\n    expect(result.current.height).toBe(1080)\n\n    act(() => {\n      vi.advanceTimersByTime(200)\n    })\n\n    expect(result.current.width).toBe(2196)\n    expect(result.current.height).toBe(2196)\n  })\n})\n"
  },
  {
    "path": "packages/usehooks-ts/src/useWindowSize/useWindowSize.ts",
    "content": "import { useState } from 'react'\n\nimport { useDebounceCallback } from '../useDebounceCallback'\nimport { useEventListener } from '../useEventListener'\nimport { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'\n\n/**\n * Represent the dimension of the window.\n * @template T - The type of the dimension (number or undefined).\n */\ntype WindowSize<T extends number | undefined = number | undefined> = {\n  /** The width of the window. */\n  width: T\n  /** The height of the window. */\n  height: T\n}\n\n/**\n * Hook options.\n * @template InitializeWithValue - If `true` (default), the hook will initialize reading the window size. In SSR, you should set it to `false`, returning `undefined` initially.\n */\ntype UseWindowSizeOptions<InitializeWithValue extends boolean | undefined> = {\n  /**\n   * If `true` (default), the hook will initialize reading the window size. In SSR, you should set it to `false`, returning `undefined` initially.\n   * @default true\n   */\n  initializeWithValue: InitializeWithValue\n  /**\n   * The delay in milliseconds before the state is updated (disabled by default for retro-compatibility).\n   * @default undefined\n   */\n  debounceDelay?: number\n}\n\nconst IS_SERVER = typeof window === 'undefined'\n\n// SSR version of useWindowSize.\nexport function useWindowSize(options: UseWindowSizeOptions<false>): WindowSize\n// CSR version of useWindowSize.\nexport function useWindowSize(\n  options?: Partial<UseWindowSizeOptions<true>>,\n): WindowSize<number>\n/**\n * Custom hook that tracks the size of the window.\n * @param {?UseWindowSizeOptions} [options] - The options for customizing the behavior of the hook (optional).\n * @returns {object} An object containing the width and height of the window.\n * @public\n * @see [Documentation](https://usehooks-ts.com/react-hook/use-window-size)\n * @example\n * ```tsx\n * const { width = 0, height = 0 } = useWindowSize();\n * console.log(`Window size: ${width} x ${height}`);\n * ```\n */\nexport function useWindowSize(\n  options: Partial<UseWindowSizeOptions<boolean>> = {},\n): WindowSize | WindowSize<number> {\n  let { initializeWithValue = true } = options\n  if (IS_SERVER) {\n    initializeWithValue = false\n  }\n\n  const [windowSize, setWindowSize] = useState<WindowSize>(() => {\n    if (initializeWithValue) {\n      return {\n        width: window.innerWidth,\n        height: window.innerHeight,\n      }\n    }\n    return {\n      width: undefined,\n      height: undefined,\n    }\n  })\n\n  const debouncedSetWindowSize = useDebounceCallback(\n    setWindowSize,\n    options.debounceDelay,\n  )\n\n  function handleSize() {\n    const setSize = options.debounceDelay\n      ? debouncedSetWindowSize\n      : setWindowSize\n\n    setSize({\n      width: window.innerWidth,\n      height: window.innerHeight,\n    })\n  }\n\n  useEventListener('resize', handleSize)\n\n  // Set size at the first client-side load\n  useIsomorphicLayoutEffect(() => {\n    handleSize()\n  }, [])\n\n  return windowSize\n}\n"
  },
  {
    "path": "packages/usehooks-ts/tests/mocks.ts",
    "content": "/**\n * Mocks the matchMedia API\n * @param {boolean} matches - True for dark, false for light\n * @example\n * mockMatchMedia(false)\n */\nexport const mockMatchMedia = (matches: boolean): void => {\n  Object.defineProperty(window, 'matchMedia', {\n    writable: true,\n    value: vitest.fn().mockImplementation(query => ({\n      matches,\n      media: query,\n      onchange: null,\n      addEventListener: vitest.fn(),\n      removeEventListener: vitest.fn(),\n      dispatchEvent: vitest.fn(),\n    })),\n  })\n}\n\n/**\n * Mocks the Storage API\n * @param {'localStorage' | 'sessionStorage'} name - The name of the storage to mock\n * @example\n * mockStorage('localStorage')\n * // Then use window.localStorage as usual (it will be mocked)\n */\nexport const mockStorage = (name: 'localStorage' | 'sessionStorage'): void => {\n  class StorageMock implements Omit<Storage, 'key' | 'length'> {\n    store: Record<string, string> = {}\n\n    clear() {\n      this.store = {}\n    }\n\n    getItem(key: string) {\n      return this.store[key] || null\n    }\n\n    setItem(key: string, value: unknown) {\n      this.store[key] = value + ''\n    }\n\n    removeItem(key: string) {\n      delete this.store[key]\n    }\n  }\n\n  Object.defineProperty(window, name, {\n    value: new StorageMock(),\n  })\n}\n"
  },
  {
    "path": "packages/usehooks-ts/tests/setup.ts",
    "content": "import * as matchers from '@testing-library/jest-dom/matchers'\nimport { cleanup } from '@testing-library/react'\nimport { afterEach, expect } from 'vitest'\n\nexpect.extend(matchers)\n\nafterEach(() => {\n  cleanup()\n})\n"
  },
  {
    "path": "packages/usehooks-ts/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"declaration\": true,\n    \"pretty\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"jsx\": \"react-jsx\",\n    \"strict\": true,\n    \"lib\": [\"ESNEXT\", \"DOM\", \"DOM.Iterable\"],\n    // use global types for vite's expect, describe, etc.\n    \"types\": [\"vitest/globals\"],\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Bundler\"\n  },\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n"
  },
  {
    "path": "packages/usehooks-ts/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup'\n\nexport default defineConfig({\n  entry: ['src/index.ts'],\n  dts: true,\n  outDir: 'dist',\n  clean: true,\n  format: ['cjs', 'esm'],\n  treeshake: true,\n  splitting: false,\n  cjsInterop: true,\n})\n"
  },
  {
    "path": "packages/usehooks-ts/vitest.config.ts",
    "content": "import { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    setupFiles: './tests/setup.ts',\n  },\n})\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - 'apps/*'\n  - 'packages/*'\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\n    \"config:base\",\n    \"schedule:monthly\",\n    \":preserveSemverRanges\",\n    \"npm:unpublishSafe\",\n    \"workarounds:typesNodeVersioning\",\n    \"group:allNonMajor\",\n    \"helpers:disableTypesNodeMajor\"\n  ],\n  \"updateInternalDeps\": true\n}\n"
  },
  {
    "path": "scripts/env.js",
    "content": "import 'dotenv/config'\nimport { createEnv } from '@t3-oss/env-core'\nimport { z } from 'zod'\n\nexport const env = createEnv({\n  server: {\n    ALGOLIA_APP_ID: z.string(),\n    ALGOLIA_ADMIN_KEY: z.string(),\n  },\n  runtimeEnv: process.env,\n})\n\nconst s = env\n"
  },
  {
    "path": "scripts/generate-doc.js",
    "content": "import { path, fs } from 'zx'\n\nimport { getHooks } from './utils/get-hooks.js'\nimport { generateDocFiles } from './utils/generate-doc-files.js'\nimport { updateReadme } from './utils/update-readme.js'\n\nconst generatedDir = path.resolve('./generated')\n\n// Clean the generated directory\nawait $`rimraf ${generatedDir}/docs`\nawait $`rimraf ${generatedDir}/typedoc`\n\n// Generate base from JSDoc comments using typedoc\nawait $`typedoc`\n\n// Read hook list from the `generated/typedoc/all.json` file\nconst hooks = getHooks()\n\n// Create the markdown files\nfs.mkdirSync(path.join(generatedDir, 'docs'))\nfs.mkdirSync(path.join(generatedDir, 'docs', 'hooks'))\n\nfor (const hook of hooks) {\n  generateDocFiles(hook)\n}\n\n// Create the JSON file\nfs.writeFileSync(\n  path.join(generatedDir, 'docs', 'hooks.json'),\n  JSON.stringify(hooks, null, 2),\n)\n\n// Update the README file\nupdateReadme(hooks)\n\n// Format with Prettier\nawait $`pnpm format --log-level error`\n"
  },
  {
    "path": "scripts/update-algolia-index.js",
    "content": "import { getHooks } from './utils/get-hooks.js'\n\nimport algoliasearch from 'algoliasearch'\nimport { env } from './env.js'\n\n// Prepare the algolia records from the hooks\nconst records = getHooks().map(({ name, slug, summary }) => ({\n  objectID: slug,\n  name,\n  summary,\n}))\n\n// Connect and authenticate with your Algolia app\nconst client = algoliasearch(env.ALGOLIA_APP_ID, env.ALGOLIA_ADMIN_KEY)\n\n// Create a new index\nconst index = client.initIndex('hooks')\n\n// Set the index settings\nindex.setSettings({\n  camelCaseAttributes: ['name'],\n  searchableAttributes: ['name', 'objectID', 'summary'],\n  hitsPerPage: 1000,\n})\n\n// Add or update the records\nindex\n  .saveObjects(records)\n  .then(({ objectIDs }) => {\n    console.log({ count: objectIDs.length, objectIDs })\n  })\n  .catch(err => {\n    console.error(err)\n    process.exit(1)\n  })\n\n// Include removed hooks\nconst removedHooks = [\n  { objectID: 'use-debounce', name: 'useDebounce' },\n  { objectID: 'use-fetch', name: 'useFetch' },\n  { objectID: 'use-element-size', name: 'useElementSize' },\n  { objectID: 'use-locked-body', name: 'useLockedBody' },\n  { objectID: 'use-is-first-render', name: 'useIsFirstRender' },\n  { objectID: 'use-ssr', name: 'useSsr' },\n  { objectID: 'use-effect-once', name: 'useEffectOnce' },\n  { objectID: 'use-update-effect', name: 'useUpdateEffect' },\n  { objectID: 'use-image-on-load', name: 'useImageOnLoad' },\n]\n\nconst removedIndex = client.initIndex('removed-hooks')\n\nremovedIndex.setSettings({\n  camelCaseAttributes: ['name'],\n  searchableAttributes: ['name', 'objectID'],\n  hitsPerPage: 1000,\n})\n\nremovedIndex\n  .saveObjects(removedHooks)\n  .then(({ objectIDs }) => {\n    console.log({ count: objectIDs.length, objectIDs })\n  })\n  .catch(err => {\n    console.error(err)\n    process.exit(1)\n  })\n"
  },
  {
    "path": "scripts/update-testing-issue.js",
    "content": "import { path, fs, $ } from 'zx'\n\nimport { getHooks } from './utils/get-hooks.js'\n\nconst SOURCE_DIR = path.resolve('./packages/usehooks-ts/src')\nconst GITHUB_REPO = `juliencrn/usehooks-ts`\nconst GITHUB_ISSUE_PATH = `${GITHUB_REPO}/issues/423`\nconst EXCLUDED_HOOK = ['useIsomorphicLayoutEffect']\n\n// Read hook list from the `generated/typedoc/all.json` file\nconst hooks = getHooks()\n  // Filter excluded hooks\n  .filter(hook => !EXCLUDED_HOOK.includes(hook.name))\n  // For each hook, check if there is a test file\n  .map(hook => {\n    const files = fs.readdirSync(path.resolve(SOURCE_DIR, hook.name))\n    return { ...hook, hasTest: files.some(isTestFile) }\n  })\n  // Generate the markdown lines\n  .map(hook => {\n    const url = `https://github.com/${GITHUB_REPO}/tree/master/packages/usehooks-ts/src/${hook.name}`\n    return {\n      ...hook,\n      markdown: `- [${hook.hasTest ? 'x' : ' '}] [\\`${hook.name}\\`](${url})`,\n    }\n  })\n\n// Compute the state of the issue\nconst url = `https://github.com/${GITHUB_ISSUE_PATH}`\nconst testedCount = hooks.filter(({ hasTest }) => hasTest).length\nconst state = hooks.length === testedCount ? 'closed' : 'open'\nconst body = hooks.map(({ markdown }) => markdown).join('\\n')\n\n// Update the github testing issue\nawait $`gh api \\\n--method PATCH \\\n-H \"Accept: application/vnd.github+json\" \\\n-H \"X-GitHub-Api-Version: 2022-11-28\" \\\n/repos/${GITHUB_ISSUE_PATH} \\\n-f body=${issueTemplate(body)} \\\n-f state=${state}\n`\n\nconsole.log(`\\n\\n✅ Issue successfully updated! -> ${url}`)\n\n// Utils\n\nfunction isTestFile(filename) {\n  return /^use[A-Z][a-zA-Z]*.test.tsx?$/.test(filename)\n}\n\nfunction issueTemplate(body) {\n  return `## Overview\n\nThis GitHub issue serves as a central hub for the unit-testing journey of our React hook library. Our goal is to ensure robust and reliable testing for each individual hook in the library.\n\n## Objectives\n\n1. **Comprehensive Testing**: Write unit tests for each hook to ensure thorough coverage of functionality.\n2. **Consistent Test Structure**: Maintain a consistent structure/format for unit tests across all hooks.\n3. **Documentation**: Document the purpose and usage of each test to enhance overall project understanding.\n\n## Getting Started\n\n1. Fork the repository to your account.\n2. Create a new branch for your tests: git checkout -b feature/hook-name-tests.\n3. Write tests for the specific hook in \\`packages/usehooks-ts/src/useExample/useExample.test.ts\\`.\n4. Ensure all tests pass before submitting a pull request.\n\n## Hooks to Test\n\n${body}\n\nLet's ensure our hooks are well-tested and reliable!`\n}\n"
  },
  {
    "path": "scripts/utils/data-transform.js",
    "content": "/**\n * Transform this:\n *\n * import { useBoolean } from '../useBoolean'\n * import { useCounter } from '../useCounter'\n * import { useInterval } from '../useInterval'\n *\n * Or this:\n *\n * import { useBoolean } from './useBoolean'\n *\n * Into this:\n *\n * import { useBoolean, useCounter, useInterval } from 'usehooks-ts'\n */\nexport function transformImports(data) {\n  // const importRegex = /import { ([^}]+) } from ['\"]\\.\\.\\/use([^'\"]+)['\"]/g\n  const importRegex = /import { ([^}]+) } from ['\"]\\.\\.?(\\/[^'\"]+)['\"]/g\n\n  const imports = Array.from(data.matchAll(importRegex)).map(match => ({\n    importName: match[1],\n    startIndex: match.index,\n    endIndex: match.index + match[0].length,\n  }))\n\n  // If there are imports to transform\n  if (imports.length > 0) {\n    // Concatenate import names and create the new import statement\n    const importNames = imports.map(({ importName }) => importName).join(', ')\n    const newImportStatement = `import { ${importNames} } from 'usehooks-ts'`\n\n    // Replace existing import statements with the new one\n    if (data.indexOf(imports[0].importName) !== -1) {\n      const startIndex = imports[0].startIndex\n      const endIndex = imports[imports.length - 1].endIndex\n\n      data = `${data.slice(0, startIndex)}${newImportStatement}${data.slice(endIndex)}`\n    }\n  }\n\n  return data\n}\n\n/**\n * Remove JSDoc comments from a string\n * @param {string} data - The string to remove JSDoc comments from\n * @returns {string} - The string without JSDoc comments\n */\nexport function removeJSDocComments(data) {\n  const inlineJsdocRegex = /\\/\\*\\*\\s*([\\s\\S]*?)\\*\\/\\n?/g\n  const multiLineJsdocRegex = /\\/\\*\\*\\s*\\n([^\\*]|(\\*(?!\\/)))*\\*\\/\\n?/g\n  return data.replace(inlineJsdocRegex, '').replace(multiLineJsdocRegex, '')\n}\n\n/**\n * Remove the first line from a string\n * @param {string} data - The string to remove the first line from\n * @returns {string} - The string without the first line\n */\nexport function removeFirstLine(data) {\n  return data.split('\\n').slice(1).join('\\n')\n}\n\n/**\n * Remove \"Defined in\" section from a string\n * @param {string} data - The string to remove the \"Defined in\" sections from\n * @returns {string} - The string without the \"Defined in\" sections\n */\nexport function removeDefinedInSections(data) {\n  let lines = data.split('\\n')\n  const occurrences = lines.filter(line => line === '#### Defined in').length\n\n  for (let index = 0; index < occurrences; index++) {\n    const index = lines.findIndex(line => line === '#### Defined in')\n    const before = lines.slice(0, index)\n    const after = lines.slice(index + 3)\n    lines = [...before, ...after]\n  }\n\n  return lines.join('\\n')\n}\n\n/**\n * Remove ESLint disable comments from a string\n * @param {string} data - The string to remove ESLint disable comments from\n * @returns {string} - The string without ESLint disable comments\n */\nexport function removeEslintDisableComments(data) {\n  return data\n    .split('\\n')\n    .filter(line => !line.startsWith('// eslint-disable-next-line'))\n    .join('\\n')\n}\n\nexport function camelToKebabCase(str) {\n  return str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)\n}\n\nexport function replaceRelativePaths(data) {\n  return data.replace(/\\[([^\\[]+)\\]\\((.*?)\\)/g, (match, title, link) => {\n    const sanitizedLink = link.trim()\n\n    if (sanitizedLink.startsWith('http')) {\n      return match\n    }\n\n    const filename = sanitizedLink.replace('../types/', '').replace('.md', '')\n    const hookName = filename.split('_')[0]\n    const typeName = filename.split('.').at(-1)\n    const newLink = `/react-hook/${camelToKebabCase(hookName)}#${typeName}`\n\n    return `[${title}](${newLink})`\n  })\n}\n"
  },
  {
    "path": "scripts/utils/generate-doc-files.js",
    "content": "import { fs, path } from 'zx'\nimport {\n  removeDefinedInSections,\n  removeEslintDisableComments,\n  removeFirstLine,\n  removeJSDocComments,\n  transformImports,\n  replaceRelativePaths,\n} from './data-transform.js'\nimport {\n  getCodeData,\n  getDemoData,\n  getHookDocData,\n  getTypeAliasesData,\n} from './get-markdown-data.js'\n\nexport function generateDocFiles(hook) {\n  const [hookDoc] = getHookDocData(hook)\n    .map(removeFirstLine)\n    .map(removeDefinedInSections)\n    .map(replaceRelativePaths)\n  // .map(data => data.trim())\n\n  const typeAliases = getTypeAliasesData(hook)\n    .map(removeFirstLine)\n    .map(removeDefinedInSections)\n    .map(replaceRelativePaths)\n\n  const [demo] = getDemoData(hook)\n    .map(removeJSDocComments)\n    .map(removeEslintDisableComments)\n    .map(transformImports)\n\n  const [code] = getCodeData(hook)\n    .map(removeJSDocComments)\n    .map(removeEslintDisableComments)\n    .map(transformImports)\n    .map(data => data.trim())\n\n  const hookHighlightIndexes = demo\n    .split('\\n')\n    .map((line, index) => {\n      if (line.startsWith('import')) return null\n      if (!line.includes(hook.name)) return null\n      return index + 1\n    })\n    .filter(Boolean)\n\n  // Template\n  const data = `---\nname: ${hook.name}\nslug: ${hook.slug}\npath: /react-hook/${hook.slug}\nsummary: ${hook.summary}\n---\n\n${hook.summary}\n\n## Usage\n\n\\`\\`\\`tsx showLineNumbers {${hookHighlightIndexes.join(',')}}\n${demo.trim()}\n\\`\\`\\`\n\n## API\n\n${hookDoc}\n\n${typeAliases.length > 0 ? '### Type aliases\\n\\n' + typeAliases.join('\\n') + '\\n' : ''}\n\n## Hook\n\n\\`\\`\\`ts showLineNumbers\n${code}\n\\`\\`\\`\n`\n\n  // Write the file\n  const file = path.resolve(`./generated/docs/hooks/${hook.slug}.md`)\n  const writeStream = fs.createWriteStream(file)\n  writeStream.write(data)\n  writeStream.end()\n}\n"
  },
  {
    "path": "scripts/utils/get-hooks.js",
    "content": "import { path, fs } from 'zx'\nimport { camelToKebabCase } from './data-transform.js'\n\nexport function getHooks() {\n  const jsonFilePath = path.resolve('./generated/typedoc/all.json')\n  const jsonFile = fs.readFileSync(jsonFilePath, 'utf-8')\n  if (!jsonFile) {\n    throw new Error(\n      `Could not read ${jsonFilePath} file. Please run the typedoc command first.`,\n    )\n  }\n  return JSON.parse(jsonFile).children.map(child => {\n    const name = child.name.split('/')[0]\n    const slug = camelToKebabCase(name)\n    const funcGroup = child.groups?.find(g => g.title === 'Functions')\n    const typesGroup = child.groups?.filter(g => g.title === 'Type Aliases')\n    const hookFunc = child.children?.find(c => c.id === funcGroup.children[0])\n    const types = typesGroup?.length ? typesGroup[0].children || [] : []\n    const summary = (hookFunc.signatures[0].comment?.summary || [])\n      .map(s => s.text || '')\n      .join('')\n\n    // .reduce(\n    //   (acc, item) => {\n    //     if (item.text) {\n    //       acc += item.text\n    //     }\n    //     return acc\n    //   },\n    //   '',\n    // )\n\n    return {\n      id: child.id,\n      name,\n      slug,\n      path: `/react-hook/${slug}`,\n      summary,\n      flags: hookFunc.flags,\n      links: {\n        doc: `https://usehooks-ts.com/react-hook/${slug}`,\n        github: hookFunc.sources[0].url,\n      },\n      types: types.map(id => {\n        const item = child.children.find(c => c.id === id)\n        return {\n          id: item.id,\n          name: item.name,\n          summary: item.comment?.summary[0].text,\n        }\n      }),\n    }\n  })\n}\n"
  },
  {
    "path": "scripts/utils/get-markdown-data.js",
    "content": "import { path, fs } from 'zx'\n\nconst typedocDir = path.resolve('./generated/typedoc')\nconst hooksSrcDir = path.resolve('./packages/usehooks-ts/src')\n\nexport function getHookDocData(hook) {\n  const filename = `${hook.name}_${hook.name}.${hook.name}.md`\n  const pathname = path.join(typedocDir, 'functions', filename)\n  return getFile(pathname, 'documentation')\n}\n\nexport function getTypeAliasesData(hook) {\n  return (\n    hook.types.map(t => {\n      const filename = `${hook.name}_${hook.name}.${t.name}.md`\n      const pathname = path.join(typedocDir, 'types', filename)\n      const [file] = getFile(pathname, 'type aliases')\n      return file\n    }) || []\n  )\n}\n\nexport function getCodeData(hook) {\n  const pathname = path.join(hooksSrcDir, `${hook.name}`, `${hook.name}.ts`)\n  return getFile(pathname, 'code')\n}\n\nexport function getDemoData(hook) {\n  const filename = `${hook.name}.demo.tsx`\n  const pathname = path.join(hooksSrcDir, `${hook.name}`, filename)\n  return getFile(pathname, 'demo')\n}\n\n// Utils\n\nfunction getFile(filename, type) {\n  const file = fs.readFileSync(filename, 'utf-8')\n\n  if (!file && ['code', 'demo', 'docs'].includes(type)) {\n    const name = filename.split('/').slice(-1)[0]\n    throw new Error(`No ${type} found for ${name}`)\n  }\n\n  return [file]\n}\n"
  },
  {
    "path": "scripts/utils/update-readme.js",
    "content": "import { path, fs } from 'zx'\n\nconst readmeFile = path.resolve('./README.md')\nconst readmeUseHook = path.resolve('./packages/usehooks-ts/README.md')\n\nexport function updateReadme(hooks) {\n  const data = fs\n    .readFileSync(readmeFile, 'utf-8')\n    .replace(\n      /<!-- HOOKS:START -->(.*)<!-- HOOKS:END -->/gms,\n      `<!-- HOOKS:START -->\\n\\n${hooks.map(formatHook).join('\\n')}\\n<!-- HOOKS:END -->`,\n    )\n\n  fs.writeFileSync(readmeFile, data, 'utf-8')\n  fs.writeFileSync(readmeUseHook, data, 'utf-8')\n}\n\n// Utils\n\nfunction formatHook(hook) {\n  const trimmedSummary = hook.summary\n    .replace(/^Custom hook that /, '')\n    .replace(/`/g, '')\n  return `- [\\`${hook.name}\\`](${hook.links.doc}) — ${trimmedSummary}`\n}\n"
  },
  {
    "path": "turbo/generators/config.cts",
    "content": "import type { PlopTypes } from '@turbo/gen'\nimport { format } from 'date-fns'\nimport path from 'path'\n\nexport default function generator(plop: PlopTypes.NodePlopAPI): void {\n  const usehooksSrcPath = path.resolve('packages/usehooks-ts/src')\n  plop.setGenerator('hook', {\n    description: 'Create a post',\n    prompts: [\n      {\n        type: 'input',\n        name: 'name',\n        message: 'post name please (eg: \"use test\")',\n      },\n    ],\n    actions: [\n      // Create the hook file itself\n      {\n        type: 'add',\n        path: usehooksSrcPath + '/{{camelCase name}}/{{camelCase name}}.ts',\n        templateFile: 'templates/hook/hook.ts.hbs',\n      },\n\n      // Create the test file\n      {\n        type: 'add',\n        path: usehooksSrcPath + '/{{camelCase name}}/{{camelCase name}}.test.ts',\n        templateFile: 'templates/hook/hook.test.ts.hbs',\n      },\n\n      // Create the markdown file to present the hook (doc)\n      {\n        data: {\n          date: format(new Date(), 'yyyy-MM-dd'),\n        },\n        type: 'add',\n        path: usehooksSrcPath + '/{{camelCase name}}/{{camelCase name}}.md',\n        templateFile: 'templates/hook/hook.mdx.hbs',\n      },\n\n      // Create the demo react component file\n      {\n        type: 'add',\n        path: usehooksSrcPath + '/{{camelCase name}}/{{camelCase name}}.demo.tsx',\n        templateFile: 'templates/hook/hook.demo.tsx.hbs',\n      },\n\n      // Create the hook's index file\n      {\n        type: 'add',\n        path: usehooksSrcPath + '/{{camelCase name}}/index.ts',\n        templateFile: 'templates/hook/index.ts.hbs',\n      },\n\n      // Update the global hooks index file\n      {\n        type: 'append',\n        path: usehooksSrcPath + '/index.ts',\n        templateFile: 'templates/index.ts.hbs',\n      },\n    ],\n  })\n}\n"
  },
  {
    "path": "turbo/generators/templates/hook/hook.demo.tsx.hbs",
    "content": "import { {{camelCase name}} } from './{{camelCase name}}'\n\nexport default function Component() {\nconst [two] = {{camelCase name}}()\n\nreturn <div>Hello {two}</div>\n}\n"
  },
  {
    "path": "turbo/generators/templates/hook/hook.mdx.hbs",
    "content": "This hook description markdown text.\n"
  },
  {
    "path": "turbo/generators/templates/hook/hook.test.ts.hbs",
    "content": "import { renderHook } from '@testing-library/react'\n\nimport { {{camelCase name}} } from './{{camelCase name}}'\n\ndescribe('{{camelCase name}}()', () => {\n  it('should {{name}} be ok', () => {\n    const { result } = renderHook(() => {{camelCase name}}())\n    const [value, setNumber] = result.current\n\n    expect(value).toBe(2)\n    expect(typeof setNumber).toBe('function')\n  })\n})\n\n"
  },
  {
    "path": "turbo/generators/templates/hook/hook.ts.hbs",
    "content": "import { useState } from 'react'\n\nimport type { Dispatch, SetStateAction } from 'react'\n\n/** Hook return type */\ntype {{pascalCase name}}ReturnType = {\n  /** The value of ... */\n  value: number\n  /** A method to update the value of ... */\n  setValue: Dispatch<SetStateAction<number>>\n}\n\n/**\n * Custom hook that ...\n * @param {boolean} [defaultValue] - The initial value for ... (default is `0`).\n * @returns {[number, Dispatch<SetStateAction<number>>]} A tuple containing ...\n * @see [Documentation](https://usehooks-ts.com/react-hook/{{kebabCase name}})\n * @public\n * @example\n * ```tsx\n * const { value, setValue } = {{camelCase name}}(2);\n *\n * console.log(value); // 2\n * ```\n */\nexport function {{camelCase name}}(\n  defaultValue?: number,\n): {{pascalCase name}}ReturnType {\n  const [value, setValue] = useState(defaultValue || 0)\n\n  return { value, setValue }\n}\n"
  },
  {
    "path": "turbo/generators/templates/hook/index.ts.hbs",
    "content": "export * from './{{camelCase name}}'\n"
  },
  {
    "path": "turbo/generators/templates/index.ts.hbs",
    "content": "export * from './{{camelCase name}}'\n"
  },
  {
    "path": "turbo.json",
    "content": "{\n  \"$schema\": \"https://turbo.build/schema.json\",\n  \"pipeline\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist\", \".next/**\", \"!.next/cache/**\"],\n      \"cache\": false\n    },\n    \"lint\": {\n      \"outputs\": [],\n      \"cache\": false\n    },\n    \"test\": {\n      \"outputs\": [],\n      \"cache\": false\n    },\n    \"dev\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [],\n      \"cache\": false\n    },\n    \"clean\": {\n      \"outputs\": [],\n      \"cache\": false\n    },\n    \"generate-doc\": {\n      \"dependsOn\": [\"usehooks#build\"],\n      \"outputs\": [\"generated/**\", \"README.md\", \"packages/usehooks-ts/README.md\"]\n    }\n  },\n  \"globalDependencies\": [\"tsconfig.json\"]\n}\n"
  },
  {
    "path": "typedoc.json",
    "content": "{\n  \"$schema\": \"https://typedoc.org/schema.json\",\n\n  // Essentials\n  \"name\": \"usehooks-ts\",\n  \"tsconfig\": \"packages/usehooks-ts/tsconfig.json\",\n  \"jsDocCompatibility\": true,\n  \"entryPoints\": [\"packages/usehooks-ts/src/**/*.ts\"],\n  \"entryPointStrategy\": \"resolve\",\n  \"json\": \"./generated/typedoc/all.json\",\n  \"out\": \"./generated/typedoc\",\n  \"readme\": \"none\",\n\n  // Exclude\n  \"exclude\": [\n    \"packages/usehooks-ts/src/**/demo.*\",\n    \"packages/usehooks-ts/src/**/test.*\",\n    \"packages/usehooks-ts/src/**/index.ts\"\n  ],\n  \"externalPattern\": [\"**/node_modules/**\"],\n  \"excludeExternals\": true,\n  \"excludePrivate\": true,\n  \"excludeProtected\": true,\n  \"excludeInternal\": true,\n  \"excludeNotDocumented\": true,\n  \"excludeReferences\": true,\n  \"excludeTags\": [\n    \"@override\",\n    \"@virtual\",\n    \"@privateRemarks\",\n    \"@satisfies\",\n    \"@overload\",\n    \"@example\",\n    \"@see\"\n  ],\n\n  // Plugins\n  \"plugin\": [\n    \"typedoc-plugin-mdn-links\",\n    \"typedoc-plugin-markdown\",\n    \"typedoc-plugin-missing-exports\"\n  ],\n\n  // Validation\n  \"validation\": {\n    \"notExported\": true,\n    \"invalidLink\": true,\n    \"notDocumented\": false\n  },\n  // Emit warnings for any tags not listed here\n  \"blockTags\": [\"@param\", \"@returns\", \"@see\", \"@example\", \"@template\"],\n\n  // Markdown and styles\n  \"allReflectionsHaveOwnDocument\": true,\n  \"hidePageTitle\": true,\n  \"hideInPageTOC\": true,\n  \"hideGenerator\": true,\n  \"hideBreadcrumbs\": true,\n  \"hideParameterTypesInTitle\": true,\n  \"navigation\": {\n    \"includeCategories\": false,\n    \"includeGroups\": false,\n    \"includeFolders\": false\n  },\n  \"sort\": [\"alphabetical\"],\n  \"preserveLinkText\": true,\n  \"placeInternalsInOwningModule\": true\n}\n"
  }
]