From b66f3937c181186439e6a86cd59c1e0ea6ee6d0b Mon Sep 17 00:00:00 2001 From: WeHaveBOOST <80750542+WeHaveBOOST@users.noreply.github.com> Date: Mon, 28 Aug 2023 22:48:21 +0300 Subject: [PATCH 01/43] Update README.md Clear readme.md --- README.md | 82 ------------------------------------------------------- 1 file changed, 82 deletions(-) diff --git a/README.md b/README.md index bcd1a1367..8b1378917 100644 --- a/README.md +++ b/README.md @@ -1,83 +1 @@ -### Ветка, в которой делаете задания спринта, должна называться sprint_i, где i - номер спринта. Не переименовывайте её. -### Откройте pull request в ветку main из ветки, где вы разрабатывали проект, и добавьте ссылку на этот pr в README.md в ветке main. -### ВАЖНО: pull request должен называться “Sprint i” (i — номер спринта). - -### Например, задания для проектной работы во втором спринте вы делаете в ветке sprint_2. Открываете из неё pull request в ветку main. Ссылку на этот pr добавляете в README.md в ветке main. После этого на платформе Практикума нажимаете «Проверить задание». - -### Также не забудьте проверить, что репозиторий публичный. ---- - - -Даже законченный проект остаётся только заготовкой, пока им не начнут пользоваться. Но сначала пользователь должен понять, зачем ему пользоваться вашим кодом. В этом помогает файл README. - -README — первое, что прочитает пользователь, когда попадёт в репозиторий на «Гитхабе». Хороший REAMDE отвечает на четыре вопроса: - -- Готов ли проект к использованию? -- В чём его польза? -- Как установить? -- Как применять? - -## Бейджи - -Быстро понять статус проекта помогают бейджи на «Гитхабе». Иногда разработчики ограничиваются парой бейджев, которые сообщат о статусе тестов кода: - -![Бэйджи](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/b.png) - -Если пользователь увидит ошибку в работе тестов, то поймёт: использовать текущую версию в важном проекте — не лучшая идея. - -Бейджи помогают похвастаться достижениями: насколько популярен проект, как много разработчиков создавало этот код. Через бейджи можно даже пригласить пользователя в чат: - -![Версии](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/vers.png) - -В README **Webpack** строка бейджев подробно рассказывает о покрытии кода тестами. Когда проект протестирован, это вызывает доверие пользователя. Последний бейдж приглашает присоединиться к разработке. - -Другая строка убедит пользователя в стабильности инфраструктуры и популярности проекта. Последний бейдж зовёт в чат проекта. - -## Описание - -Краткое опишите, какую задачу решает проект. Пользователь не верит обещаниям и не готов читать «полотна» текста. Поэтому в описании достаточно нескольких строк: - -![Описание](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/desc.png) - -Авторы **React** дробят описание на абзацы и списки — так проще пробежаться глазами по тексту и найти ключевую информацию. - -Если у проекта есть сайт, добавьте ссылку в заголовок. - -## Установка - -Лучше всего пользователя убеждает собственный опыт. Чем быстрее он начнёт пользоваться проектом, тем раньше почувствует пользу. Для этого помогите ему установить приложение: напишите краткую пошаговую инструкцию. - -Если проект предназначен для разработчиков, добавьте информацию об установке тестовых версий. Например: - -- `npm install` — установка стабильной версии, -- `npm start` — запуск версии для разработчика, -- `npm run build:prod` — сборка стабильной версии. - -## **Примеры использования** - -Хорошо, если сразу после установки пользователь сможет решить свои задачи без изучения проекта. Это особенно верно, если ваш пользователь — не профессиональный разработчик. Но даже профессионал поймёт вас лучше, если показать примеры использования: - -![Ссылки](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/link.png) - -Для более подробных инструкции добавьте новые разделы или ссылки: - -- на документацию, -- вики проекта, -- описание API. - -В учебном проекте будут полезен раздел с описанием стиля кода и правилами разработки: как работать с ветками, пул-реквестами и релизами. - -### **Команда** - -Если вы работаете в команде, укажите основных участников: им будет приятно, а новые разработчики охотнее присоединятся к проекту. «Гитхаб» — не просто инструмент, это социальная сеть разработчиков. - -![Команда](https://github.com/yandex-praktikum/mf.messenger.praktikum.yandex.images/blob/master/mf/team.png) - -### **Примеры README** - -- «[Реакт](https://github.com/facebook/react)», -- «[Эхо](https://github.com/labstack/echo)», -- «[Вебпак](https://github.com/webpack/webpack)», -- «[ТДенгине](https://github.com/taosdata/TDengine)», -- «[Соул-хантинг](https://github.com/vladpereskokov/soul-hunting/)». From 756dd61ce068e40b56b62dc32f2252f7f6102e24 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 00:21:55 +0300 Subject: [PATCH 02/43] initial commit --- .gitignore | 25 + README.md | 21 + package-lock.json | 3451 +++++++++++++++++++++ package.json | 25 + server.js | 10 + src/404.html | 2 + src/500.html | 2 + src/chats-and-chat.html | 2 + src/components/btn/btn.pug | 30 + src/components/btn/btn.scss | 37 + src/components/field-text/field-text.pug | 47 + src/components/field-text/field-text.scss | 28 + src/components/form/form.pug | 45 + src/components/form/form.scss | 28 + src/index.html | 2 + src/layout/main.pug | 18 + src/layout/mixins.pug | 3 + src/pages/404.pug | 16 + src/pages/500.pug | 16 + src/pages/chats-and-chat.pug | 11 + src/pages/registration.pug | 58 + src/pages/sign-in.pug | 30 + src/pages/user-settings.pug | 43 + src/registration.html | 2 + src/scss/additions.scss | 11 + src/scss/main.scss | 242 ++ src/scss/reset.scss | 106 + src/scss/style.scss | 9 + src/style.js | 1 + src/user-settings.html | 2 + static/fonts/roboto-100.woff2 | Bin 0 -> 21864 bytes static/fonts/roboto-400.woff2 | Bin 0 -> 22232 bytes static/fonts/roboto-500.woff2 | Bin 0 -> 22632 bytes static/fonts/roboto-700.woff2 | Bin 0 -> 22404 bytes static/img/chats-and-chat-cap.jpg | Bin 0 -> 164062 bytes static/img/favicon/apple-touch-icon.png | Bin 0 -> 2391 bytes static/img/favicon/favicon-16x16.png | Bin 0 -> 686 bytes static/img/favicon/favicon-32x32.png | Bin 0 -> 1010 bytes vite.config.js | 28 + 39 files changed, 4351 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js create mode 100644 src/404.html create mode 100644 src/500.html create mode 100644 src/chats-and-chat.html create mode 100644 src/components/btn/btn.pug create mode 100644 src/components/btn/btn.scss create mode 100644 src/components/field-text/field-text.pug create mode 100644 src/components/field-text/field-text.scss create mode 100644 src/components/form/form.pug create mode 100644 src/components/form/form.scss create mode 100644 src/index.html create mode 100644 src/layout/main.pug create mode 100644 src/layout/mixins.pug create mode 100644 src/pages/404.pug create mode 100644 src/pages/500.pug create mode 100644 src/pages/chats-and-chat.pug create mode 100644 src/pages/registration.pug create mode 100644 src/pages/sign-in.pug create mode 100644 src/pages/user-settings.pug create mode 100644 src/registration.html create mode 100644 src/scss/additions.scss create mode 100644 src/scss/main.scss create mode 100644 src/scss/reset.scss create mode 100644 src/scss/style.scss create mode 100644 src/style.js create mode 100644 src/user-settings.html create mode 100644 static/fonts/roboto-100.woff2 create mode 100644 static/fonts/roboto-400.woff2 create mode 100644 static/fonts/roboto-500.woff2 create mode 100644 static/fonts/roboto-700.woff2 create mode 100644 static/img/chats-and-chat-cap.jpg create mode 100644 static/img/favicon/apple-touch-icon.png create mode 100644 static/img/favicon/favicon-16x16.png create mode 100644 static/img/favicon/favicon-32x32.png create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..09da1a974 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +build +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md index 8b1378917..c4b3c0b3b 100644 --- a/README.md +++ b/README.md @@ -1 +1,22 @@ +«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6)» +## Установка + +- `npm install` — инициализация проекта, +- `npm run start` — сборка проекта и запуск сервера (http://localhost:3000), +- `npm run dev` — запуск версии для разработки, +- `npm run build` — сборка проекта. + +## Структура + +- /src/layout/ - макет +- /src/layout/mixins.pug - собираем все компоненты +- /src/pages/ - шаблоны страниц +- /src/components/- компоненты +- /src/scss/ - стили проекта +- /src/scss/style.scss - собираем все стили + +## Ключевые технологии + +- шаблонизатор - pug +- css препроцессор - sass \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..909c08b9d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3451 @@ +{ + "name": "messenger", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "messenger", + "version": "0.0.0", + "dependencies": { + "vite-plugin-pug-transformer": "^1.0.3" + }, + "devDependencies": { + "concurrently": "^8.2.1", + "express": "^4.18.2", + "sass": "^1.66.1", + "vite": "^4.4.5" + }, + "engines": { + "node": "v16.19.1", + "npm": "8.19.3" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.14", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", + "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", + "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "devOptional": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dependencies": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", + "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.66.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", + "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "devOptional": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-pug-transformer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vite-plugin-pug-transformer/-/vite-plugin-pug-transformer-1.0.3.tgz", + "integrity": "sha512-cndWLK7iQE/yryjRNGJAOxPYnL7v5miMbwCXUbkP754BILh5hwJKbE10X4QKDl1X46ntIb1oBMBYKcw4NVBnkg==", + "dependencies": { + "picocolors": "^1.0.0", + "pug": "^3.0.2" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "vite": "^2.5.10 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" + }, + "@babel/parser": { + "version": "7.22.14", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", + "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==" + }, + "@babel/runtime": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.11.tgz", + "integrity": "sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@babel/types": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", + "to-fast-properties": "^2.0.0" + } + }, + "@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "optional": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "requires": { + "@babel/types": "^7.9.6" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "requires": { + "is-regex": "^1.0.3" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concurrently": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", + "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + } + }, + "constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "requires": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.21.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true + }, + "esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "requires": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "devOptional": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "requires": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + }, + "jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "requires": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true + }, + "postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "requires": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "requires": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "requires": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "requires": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "requires": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "requires": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "requires": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "requires": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "requires": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "requires": { + "pug-error": "^2.0.0" + } + }, + "pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", + "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "requires": { + "fsevents": "~2.3.2" + } + }, + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.66.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", + "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "devOptional": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "spawn-command": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", + "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, + "vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "requires": { + "esbuild": "^0.18.10", + "fsevents": "~2.3.2", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + } + }, + "vite-plugin-pug-transformer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vite-plugin-pug-transformer/-/vite-plugin-pug-transformer-1.0.3.tgz", + "integrity": "sha512-cndWLK7iQE/yryjRNGJAOxPYnL7v5miMbwCXUbkP754BILh5hwJKbE10X4QKDl1X46ntIb1oBMBYKcw4NVBnkg==", + "requires": { + "picocolors": "^1.0.0", + "pug": "^3.0.2" + } + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" + }, + "with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "requires": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..5db21f1da --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "messenger", + "private": true, + "version": "0.0.0", + "type": "module", + "engines": { + "node": "v16.19.1", + "npm": "8.19.3" + }, + "scripts": { + "start": "concurrently \"npm run build\" \"node server.js\"", + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "concurrently": "^8.2.1", + "express": "^4.18.2", + "sass": "^1.66.1", + "vite": "^4.4.5" + }, + "dependencies": { + "vite-plugin-pug-transformer": "^1.0.3" + } +} diff --git a/server.js b/server.js new file mode 100644 index 000000000..276ead405 --- /dev/null +++ b/server.js @@ -0,0 +1,10 @@ +import express from 'express' + +const app = express() +const port = 3000 + +app.use(express.static('build')) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) \ No newline at end of file diff --git a/src/404.html b/src/404.html new file mode 100644 index 000000000..38b61b0f6 --- /dev/null +++ b/src/404.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/500.html b/src/500.html new file mode 100644 index 000000000..5b0425089 --- /dev/null +++ b/src/500.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/chats-and-chat.html b/src/chats-and-chat.html new file mode 100644 index 000000000..07283a583 --- /dev/null +++ b/src/chats-and-chat.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/components/btn/btn.pug b/src/components/btn/btn.pug new file mode 100644 index 000000000..361310f68 --- /dev/null +++ b/src/components/btn/btn.pug @@ -0,0 +1,30 @@ +mixin btn(text, mods, isInput) + + //- Принимает: + //- text {string} - текст кнопки + //- mods {string} - список модификаторов + //- isInput {bool} - флаг «это тег input» + //- Вызов: + +btn('Кнопка-ссылка')(href='/') - есть href, это точно ссылка + +btn('Кнопка-input', '', true) - есть флаг isInput, это input + +btn('Кнопка-button', 'success') - нет href, нет isInput — это button + + - + var allMods = ''; + if(typeof(mods) !== 'undefined' && mods) { + var modsList = mods.split(','); + for (var i = 0; i < modsList.length; i++) { + allMods = allMods + ' btn--' + modsList[i].trim(); + } + } + + if (attributes.href) + a.btn(class=allMods)&attributes(attributes)!= text + block + + else if (typeof(isInput) !== 'undefined' && isInput) + input.btn(class=allMods, value=text, type='button')&attributes(attributes) + + else + button.btn(class=allMods)&attributes(attributes)!= text + block diff --git a/src/components/btn/btn.scss b/src/components/btn/btn.scss new file mode 100644 index 000000000..148ae1510 --- /dev/null +++ b/src/components/btn/btn.scss @@ -0,0 +1,37 @@ +.btn { + display: inline-flex; + justify-content: center; + border: 1px solid var(--m-color-1); + padding: var(--v-indent) 50px; + border-radius: var(--b-radius); + background-color: var(--m-color-1); + color: #fff; + font-weight: 700; + cursor: pointer; + user-select: none; + transition-property: border-color, background-color; + transition-duration: var(--t-duration); + + &:hover { + border-color: var(--m-color-1-1); + background-color: var(--m-color-1-1); + } + + &:focus-visible { + box-shadow: var(--on-focus); + } + + &:disabled { + opacity: 0.65; + cursor: default; + } + + &--w-100 { + width: 100%; + } + + &--big { + padding-top: 14px; + padding-bottom: 14px; + } +} diff --git a/src/components/field-text/field-text.pug b/src/components/field-text/field-text.pug new file mode 100644 index 000000000..23345c704 --- /dev/null +++ b/src/components/field-text/field-text.pug @@ -0,0 +1,47 @@ +mixin field-text(props) + + //- Принимает: + //- props { + //- title: '' {string} - текст с названием (выводится над полем) + //- isTextarea: false {bool} - флаг input/textarea + //- helpText: '' {string} - пояснение под полем + //- mods: '' {string} - модификаторы блока + //- val: '' {string} - текст в поле + //- attrs: {object} - любые атрибуты для input/textarea + //- type: {string} + //- placeholder: {string} + //- Вызов: + +field-text({ + title: 'Название', + isTextarea: true, + helpText: 'Подсказка', + mods: '', + val: '', + attrs: { + name: 'comment', + } + }) + + - + if(typeof(props) === 'undefined') { + var props = {}; + } + var allMods = ''; + if(typeof(props.mods) !== 'undefined' && props.mods) { + var modsList = props.mods.split(','); + for (var i = 0; i < modsList.length; i++) { + allMods = allMods + ' field-text--' + modsList[i].trim(); + } + } + + label.field-text(class=allMods)&attributes(attributes) + if(typeof(props.title) !== 'undefined' && props.title) + span.field-text__name!= props.title + span.field-text__input-wrap + if(typeof(props.isTextarea) !== 'undefined' && props.isTextarea) + textarea.field-text__input&attributes(props.attrs)= props.val + else + input.field-text__input(type=(typeof(props.attrs) !== 'undefined' && props.attrs.type) ? props.attrs.type : 'text', value=props.val)&attributes(props.attrs) + if(typeof(props.helpText) !== 'undefined' && props.helpText) + span.field-text__help-text!= props.helpText + block diff --git a/src/components/field-text/field-text.scss b/src/components/field-text/field-text.scss new file mode 100644 index 000000000..c3128d84c --- /dev/null +++ b/src/components/field-text/field-text.scss @@ -0,0 +1,28 @@ +.field-text { + $block-name: &; + + display: block; + + &__name { + display: block; + margin-bottom: 10px; + font-weight: 500; + } + + &__input-wrap { + } + + &__input { + padding: var(--v-indent) var(--h-indent); + width: 100%; + border-radius: var(--b-radius); + background-color: #d9d9d9; + + &:focus-visible { + box-shadow: var(--on-focus); + } + } + + &__help-text { + } +} diff --git a/src/components/form/form.pug b/src/components/form/form.pug new file mode 100644 index 000000000..a3c425577 --- /dev/null +++ b/src/components/form/form.pug @@ -0,0 +1,45 @@ +mixin form(title, mods) + + //- Принимает: + //- title {string} - form title + //- mods {string} - список модификаторов + //- Вызов: + +form('title', 'mods') + +form-field() + some html + +form-field() + some html + + - + var allMods = ''; + if(typeof(mods) !== 'undefined' && mods) { + var modsList = mods.split(','); + for (var i = 0; i < modsList.length; i++) { + allMods = allMods + ' form--' + modsList[i].trim(); + } + } + + form.form(class=allMods)&attributes(attributes) + if (title) + h1.form__title= title + block + +mixin form-field(mods) + + //- Принимает: + //- mods {string} - список модификаторов + //- Вызов: + +form-field() + some html + + - + var allMods = ''; + if(typeof(mods) !== 'undefined' && mods) { + var modsList = mods.split(','); + for (var i = 0; i < modsList.length; i++) { + allMods = allMods + ' form__field--' + modsList[i].trim(); + } + } + + .form__field(class=allMods)&attributes(attributes) + block diff --git a/src/components/form/form.scss b/src/components/form/form.scss new file mode 100644 index 000000000..dbdc6de02 --- /dev/null +++ b/src/components/form/form.scss @@ -0,0 +1,28 @@ +.form { + $block-name: &; + + margin-left: auto; + margin-right: auto; + padding: 50px; + width: 400px; + max-width: 100%; + border-radius: var(--b-radius); + background-color: #f5f5f5; + + &__title { + margin-bottom: 70px; + font-size: 35px; + font-weight: 500; + text-align: center; + } + + &__field { + & + & { + margin-top: 20px; + } + + & + &--accent { + margin-top: 40px; + } + } +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 000000000..d5b329b5a --- /dev/null +++ b/src/index.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/layout/main.pug b/src/layout/main.pug new file mode 100644 index 000000000..c583a8467 --- /dev/null +++ b/src/layout/main.pug @@ -0,0 +1,18 @@ +include ./mixins.pug + +doctype html +html(class='page', lang='en') + head + meta(charset='utf-8') + meta(name='viewport', content='width=device-width, initial-scale=1') + + link(rel='apple-touch-icon', sizes='180x180', href='img/favicon/apple-touch-icon.png') + link(rel='icon', type='image/png', sizes='32x32', href='img/favicon/favicon-32x32.png') + link(rel='icon', type='image/png', sizes='16x16', href='img/favicon/favicon-16x16.png') + + block meta + title Home + + body + .page__content + block content diff --git a/src/layout/mixins.pug b/src/layout/mixins.pug new file mode 100644 index 000000000..9a2f68326 --- /dev/null +++ b/src/layout/mixins.pug @@ -0,0 +1,3 @@ +include ../components/btn/btn.pug +include ../components/field-text/field-text.pug +include ../components/form/form.pug \ No newline at end of file diff --git a/src/pages/404.pug b/src/pages/404.pug new file mode 100644 index 000000000..2b60f3bbe --- /dev/null +++ b/src/pages/404.pug @@ -0,0 +1,16 @@ +extends ../layout/main.pug + +block meta + - const pageName = '404 page'; + + title= pageName + meta(name='description', content=pageName) + +block content + + section.error-page + h1.error-page__title 404 + p.error-page__description who seeks will always find + .error-page__bottom + a.error-page__link.link(href="chats-and-chat.html") go to chats page + diff --git a/src/pages/500.pug b/src/pages/500.pug new file mode 100644 index 000000000..7c9677bf0 --- /dev/null +++ b/src/pages/500.pug @@ -0,0 +1,16 @@ +extends ../layout/main.pug + +block meta + - const pageName = '500 page'; + + title= pageName + meta(name='description', content=pageName) + +block content + + section.error-page + h1.error-page__title 500 + p.error-page__description something went wrong + .error-page__bottom + a.error-page__link.link(href="chats-and-chat.html") go to chats page + diff --git a/src/pages/chats-and-chat.pug b/src/pages/chats-and-chat.pug new file mode 100644 index 000000000..6f7b82cb9 --- /dev/null +++ b/src/pages/chats-and-chat.pug @@ -0,0 +1,11 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'Chats and chat'; + + title= pageName + meta(name='description', content=pageName) + +block content + + img(src="img/chats-and-chat-cap.jpg", alt="chats-and-chat-cap") diff --git a/src/pages/registration.pug b/src/pages/registration.pug new file mode 100644 index 000000000..43c765c8b --- /dev/null +++ b/src/pages/registration.pug @@ -0,0 +1,58 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'Registration page'; + + title= pageName + meta(name='description', content=pageName) + +block content + + +form('Sign up') + +form-field() + +field-text({ + title: 'First name:', + attrs: { + name: 'first_name', + } + }) + +form-field() + +field-text({ + title: 'Second name:', + attrs: { + name: 'second_name', + } + }) + +form-field() + +field-text({ + title: 'Email:', + attrs: { + name: 'email', + } + }) + +form-field() + +field-text({ + title: 'Phone:', + attrs: { + name: 'phone', + } + }) + +form-field() + +field-text({ + title: 'Login:', + attrs: { + name: 'login', + } + }) + +form-field() + +field-text({ + title: 'Password:', + attrs: { + type: 'password', + name: 'password', + } + }) + +form-field('accent') + +btn('Create profile', 'w-100, big')(type="button") + +form-field().t-right + a.link(href="index.html") Sign in diff --git a/src/pages/sign-in.pug b/src/pages/sign-in.pug new file mode 100644 index 000000000..9d1ab23de --- /dev/null +++ b/src/pages/sign-in.pug @@ -0,0 +1,30 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'Sign in'; + + title= pageName + meta(name='description', content=pageName) + +block content + + +form('Sign in') + +form-field() + +field-text({ + title: 'Login:', + attrs: { + name: 'login', + } + }) + +form-field() + +field-text({ + title: 'Password:', + attrs: { + type: 'password', + name: 'password', + } + }) + +form-field('accent') + +btn('Sign in', 'w-100, big')(type="button") + +form-field().t-right + a.link(href="registration.html") Sign up diff --git a/src/pages/user-settings.pug b/src/pages/user-settings.pug new file mode 100644 index 000000000..5e86ffffa --- /dev/null +++ b/src/pages/user-settings.pug @@ -0,0 +1,43 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'User settings'; + + title= pageName + meta(name='description', content=pageName) + +block content + + .modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name User name + + .user-settings__s + ul.user-settings__list + li.user-settings__list-item + span.user-settings__list-item-name Nickname: + span.user-settings__list-item-value user name + li.user-settings__list-item + span.user-settings__list-item-name First name: + span.user-settings__list-item-value first name + li.user-settings__list-item + span.user-settings__list-item-name Second name: + span.user-settings__list-item-value second name + li.user-settings__list-item + span.user-settings__list-item-name Email: + span.user-settings__list-item-value test@test.ru + li.user-settings__list-item + span.user-settings__list-item-name Phone: + span.user-settings__list-item-value +7 (000) 000-00-00 + li.user-settings__list-item + span.user-settings__list-item-name Login: + span.user-settings__list-item-value mylogin + + .user-settings__t + button.link(type="button") Change settings + button.link(type="button") Change password diff --git a/src/registration.html b/src/registration.html new file mode 100644 index 000000000..103a29729 --- /dev/null +++ b/src/registration.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/scss/additions.scss b/src/scss/additions.scss new file mode 100644 index 000000000..486bd910d --- /dev/null +++ b/src/scss/additions.scss @@ -0,0 +1,11 @@ +.t-right { + text-align: right; +} + +.t-left { + text-align: left; +} + +.t-center { + text-align: center; +} diff --git a/src/scss/main.scss b/src/scss/main.scss new file mode 100644 index 000000000..9b2214ba2 --- /dev/null +++ b/src/scss/main.scss @@ -0,0 +1,242 @@ +@font-face { + font-display: swap; + font-family: "Roboto"; + font-style: normal; + font-weight: 100; + src: url("../fonts/roboto-100.woff2") format("woff2"); +} + +@font-face { + font-display: swap; + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + src: url("../fonts/roboto-400.woff2") format("woff2"); +} + +@font-face { + font-display: swap; + font-family: "Roboto"; + font-style: normal; + font-weight: 500; + src: url("../fonts/roboto-500.woff2") format("woff2"); +} + +@font-face { + font-display: swap; + font-family: "Roboto"; + font-style: normal; + font-weight: 700; + src: url("../fonts/roboto-700.woff2") format("woff2"); +} + +:root { + --v-indent: 9px; + --h-indent: 15px; + --b-radius: 5px; + --on-focus: 0 0 0 2px var(--m-color-1); + + --m-color-1: #784dd4; + --m-color-1-1: #5e36b2; + --m-color-2: #2872e0; + --m-color-2-1: #1e5bb4; + + --t-l-grey: #9c9c9c; + + --t-duration: 0.3s; +} + +body { + font: 400 16px/1.5 "Roboto", sans-serif; + color: #000; +} + +.page { + &__content { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + } +} + +.link { + border-radius: var(--b-radius); + color: var(--m-color-2); + font-weight: 500; + cursor: pointer; + transition-property: color; + transition-duration: var(--t-duration); + + &:hover { + color: var(--m-color-2-1); + } + + &:focus-visible { + box-shadow: var(--on-focus); + } +} + +/* ----- .modal ----- */ + +.modal { + $block-name: &; + + display: flex; + justify-content: center; + align-items: center; + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.65); + + &__inner { + position: relative; + overflow-y: auto; + padding: 75px; + width: 1024px; + max-width: 100%; + max-height: 90%; + border-radius: var(--b-radius); + background-color: #fff; + } + + &__close { + position: absolute; + top: 15px; + right: 15px; + width: 35px; + height: 35px; + border-radius: 50%; + cursor: pointer; + + &::before, + &::after { + content: ""; + position: absolute; + left: 50%; + top: 50%; + width: 80%; + height: 2px; + border-radius: 5px; + background-color: #333; + } + + &::before { + transform: translate(-50%, -50%) rotate(-45deg); + } + + &::after { + transform: translate(-50%, -50%) rotate(45deg); + } + } + + &__content { + } +} + +/* ----- .user-settings ----- */ + +.user-settings { + $block-name: &; + + display: flex; + flex-direction: column; + align-items: center; + margin-left: auto; + margin-right: auto; + width: 320px; + max-width: 100%; + + &__f, + &__s { + margin-bottom: 75px; + } + + &__f { + text-align: center; + } + + &__avatar { + display: inline-block; + margin-bottom: 15px; + width: 100px; + height: 100px; + border-radius: 50%; + background-color: #d9d9d9; + } + + &__name { + font-size: 18px; + font-weight: 700; + } + + &__s, + &__t { + width: 100%; + } + + &__s { + } + + &__list { + } + + &__list-item { + display: flex; + justify-content: space-between; + align-content: center; + padding-bottom: 7px; + border-bottom: 1px solid #eeeeee; + font-weight: 500; + font-size: 15px; + + & + & { + margin-top: 15px; + } + } + + &__list-item-name { + } + + &__list-item-value { + color: var(--t-l-grey); + } + + &__t { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px 0; + } +} + +/* ----- .error-page ----- */ + +.error-page { + $block-name: &; + + text-align: center; + + &__title { + margin-bottom: 25px; + font-weight: 100; + font-size: 150px; + line-height: 1; + letter-spacing: 5px; + } + + &__description { + font-size: 20px; + color: var(--t-l-grey); + } + + &__bottom { + margin-top: 75px; + } + + &__link { + } +} diff --git a/src/scss/reset.scss b/src/scss/reset.scss new file mode 100644 index 000000000..af080da18 --- /dev/null +++ b/src/scss/reset.scss @@ -0,0 +1,106 @@ +/*** + The new CSS reset - version 1.9 (last updated 19.6.2023) + GitHub page: https://github.com/elad2412/the-new-css-reset +***/ + +/* + Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property + - The "symbol *" part is to solve Firefox SVG sprite bug + - The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36) + */ +*:where( + :not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *) + ) { + all: unset; + display: revert; +} + +/* Preferred box-sizing value */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Reapply the pointer cursor for anchor tags */ +a, +button { + cursor: revert; +} + +/* Remove list styles (bullets/numbers) */ +ol, +ul, +menu { + list-style: none; +} + +/* For images to not be able to exceed their container */ +img { + max-inline-size: 100%; + max-block-size: 100%; +} + +/* removes spacing between cells in tables */ +table { + border-collapse: collapse; +} + +/* Safari - solving issue when using user-select:none on the text input doesn't working */ +input, +textarea { + -webkit-user-select: auto; +} + +/* revert the 'white-space' property for textarea elements on Safari */ +textarea { + white-space: revert; +} + +/* minimum style to allow to style meter element */ +meter { + -webkit-appearance: revert; + appearance: revert; +} + +/* preformatted text - use only for this feature */ +:where(pre) { + all: revert; +} + +/* reset default text opacity of input placeholder */ +::placeholder { + color: unset; +} + +/* remove default dot (•) sign */ +::marker { + content: initial; +} + +/* fix the feature of 'hidden' attribute. + display:revert; revert to element instead of attribute */ +:where([hidden]) { + display: none; +} + +/* revert for bug in Chromium browsers + - fix for the content editable attribute will work properly. + - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/ +:where([contenteditable]:not([contenteditable="false"])) { + -moz-user-modify: read-write; + -webkit-user-modify: read-write; + overflow-wrap: break-word; + -webkit-line-break: after-white-space; + -webkit-user-select: auto; +} + +/* apply back the draggable feature - exist only in Chromium and Safari */ +:where([draggable="true"]) { + -webkit-user-drag: element; +} + +/* Revert Modal native behavior */ +:where(dialog:modal) { + all: revert; +} diff --git a/src/scss/style.scss b/src/scss/style.scss new file mode 100644 index 000000000..8453c1f8f --- /dev/null +++ b/src/scss/style.scss @@ -0,0 +1,9 @@ +@import "./reset.scss"; + +@import "./main.scss"; + +@import "../components/btn/btn.scss"; +@import "../components/field-text/field-text.scss"; +@import "../components/form/form.scss"; + +@import "./additions.scss"; diff --git a/src/style.js b/src/style.js new file mode 100644 index 000000000..894fafc7b --- /dev/null +++ b/src/style.js @@ -0,0 +1 @@ +import './scss/style.scss'; \ No newline at end of file diff --git a/src/user-settings.html b/src/user-settings.html new file mode 100644 index 000000000..4b989e89f --- /dev/null +++ b/src/user-settings.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/static/fonts/roboto-100.woff2 b/static/fonts/roboto-100.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2c927c50c6214b3adcd6f5268bfffcb753e47bbe GIT binary patch literal 21864 zcmV)4K+3;&Pew8T0RR91099xJ5&!@I0MuLn096410RR9100000000000000000000 z0000Qfh-%fd>n;d24Db$cnC-dgFF!o3WCKzf}&{)gAGz1_8f_MiY z41r@C_r5i3Ty3`70TH3-b}^Z5?v&dBrO3Y*jfxoKzyQwyN&f#65~Pe_Y1pm>1jYRe zhcH{M^v>Qx?Q`b!h6E3A7d zqYL$+fE)7{N{Zb#_qmg}-7kF0`oNcQ;DBurM%5lD*RoQ5&1R{T)mY{>pUn^tLk$?|Irw-zrt>(H~&(90>hjMB@1 zf~e|ONnO<~$=#9+YRTq-_K+ldL7pQ?3tB*o4#BdAmw=$HHoBtS|5#8IjdGun$igG z5Ej30?@!Bc|5Ey;4zg55Wg%n?V3yN}1xDkz#(0813j-s3%Y3}0i=)S+`-EY;r7F$e(6hT^klSuUX3RkrEI>Zi&)Qej3PWs#^_HPXv(BIz{- zruj~@Ew?!6VKY*7`H(xA_x)C=>7whSedE`pXBf`KA8rVwdnBAnW@lgCw5P^e(*yfG zeoQ90!JWK#3}(Pw#Pl!zN9u!=TtZJuvys!kB&!rBJNDXuY(d@e1K>M>20rx{3{Bsm zW&_~;+$UWen~^zHLy`Doe4AD2NYdNR`Y=sh-7)LQwfdy^6#T|W2|MMd2;kIjo-x3I zy>0f%p3tKr^G=dD2`;P0Wk7r1(C(A&WP6-da1Z;CtJFlkCi{h438hr)>AnPxy-;}R zLztP9`(f4RdhM|FhK~Z{=g=EgiOqL%+xym{V)2fQs=<0+;nWjMy5fL)G1Bb(D)Uf} zvgJRa`!l=zr+V%p#B?}3q4r}ds7K~rp4sx6uS!-Z6A5#gt%jY)8rI}58!KJR{;}P@ zY+vO*$HeMvsp`zquYQdQDgvC`<;J(J1T8P>E&b&e?dY}k11Dnia;Kg2)?LiI)X1LN z?Suy+3npJNIqCV&-js!@!YnE$XHw2J=Mrq@5GOtEB=l}Bw<32hj`|jF$w`m8_)g+E zZ(%h~eD6(iU_xHpkUD;oH8NzgFP+=p=x*`UvH_a+A|E5+Gwg2_(Z&7q2H?5OjQG#Iu{z`u2gT(~0<@?c6N0F9U!heS9F(PG$=if1qJrf-zII8Q1C2N^nF z*5b~TR9xihZt`_^^}2wrkx-{T9xfRqHhj}#jQ%Q$WpquPn{G)kZI;Y}B`NN>E6u7k z>F#?VGk{K$9h>k}#4&uk;~tUP_$APh1V!RRLK5y&BCAN$^%C1ORUT&tTj&4@Fa7(jm$+p_+(Nkiuw!S;+f0hLxqVfZ5IKAJa`h7 zt}H93np}^rn=Yk? zd0!QmOVUp>K!$o5kx}EBNR!Rj1=l<`aMQF|OLeu2*4!@-UWrY&;vTQXuWbC;9abgr z-AqF5^ma)ha#~uoq_0sbswz42W!vbYwKP|Db>@AUNlPI1;*m>s}}z_i;s2W z9#t>w(Jq#xoRFGAHRaS8V<%Qm-S4aFa(Vg;?H?Pv9-Hnh39Fj;FHSs=NHHmAG)SmyO(^ajrjxHZ(or~+#SBqDTsH!JNm)1C!oF~tD z_{_~K>{aw3=yZ@|e{PHWc4PqH%&REX%@)nr~0fQqTBHgiZ#XG18 zXKwf(qeoK~M&BvMu3-|F7E(rN5#6dYUEaD&=^+>M_Pz?nDq4IcHbn`m&P{yjB$SD! zXrL`6L<9w)kkCHLpg$g~WHFBsH6i3LsFKiHlccM$vN3JxMKfa~wHkR+w4CY&XoFP^ ztwu5`<0eeTxX(4Yk(-z{Tb9;w4@pv5TJ=mtc~(FV1F0rzRo0Q)jJ2&+S;PJEU?Gt@ zi5gjFQ)f%ry@p^AXE-UY^XjcqOptnORIFNazdY!&u`RnEE3wtZkxDpvn>Xp2FjW@1 z7@3$^SU>yrDYD(++nvEP$#U%RMPi1U=%U3Ih=a7nGm{WCtx$SXqRJ&rYk#mGjrE(U zERaRoDl==iUmh&Pwt6(Qbo48OVgLXD00hA$MAZ*9{z)X=p5&x@m7_*M)pD36H{_kE zbr;F%G33oy-Sybap@n^hD;7;0q!OfST8>CqHQE%~@a7K-uUo|dEso-36F!+#ilQF0 zRo3?4_1xO~+T*cW7PXK_?L>`6Z=J3EaQ+|&f*=Tj=R=6GgUlr2yq4_g3bT6Q!}pp}TMBnKKmW?{kA~GTbwa?R2{*&Gd}9wp-~*cY7bM8;hX=V?B_A zf)CTbtVAn=71X7m%>pbU1DUUGs8EMaRD;p}edj5iX{q;^w)C#O*Od59%P1zx$M=^0 zUzPQ%16^^n&z z9e0IU_0VRIJr)x{=N23Hh?K=IfvOXfE%qcTF^(oKGAELpboEgsUt82s>x?EE=V0=Y zkXWLkvc$l!0Sn6pe0&&Z&TP1F!Q{#n;>Hb;Cr_qCM5w%Y;qv7R@#BX>Ow3G>Af_ZF zYy}HuEkp>0P@!nTgfSN_8cB>8WU*pd7`jhEh}@EPR*pEu8rj@dY%wVyOD;|1tDpe zL5Kuc$cPNgP!JV}Va5UqH`YvJ6C1SHhKCe~II#GLPbhzOM~EOIc>LneBmt))CQxlm zaCQD{NJ3E)hT$||br?t3}OW10NqBRU8ap+N&Cn8^ZDw8EkVzL6kd1Q6p%JHEvD z6BD>bcTFo(n7|Tjn1c#N@XLKEBteFp0vv>dONU4%X|mUdu9=GhikW@ACt(^zOcN2E znL@&JLXIw)>Y=%d0IL`;iiaOBkuZi8#mm9nnh5!+Zn` zrZ5M22qh^=0YCr_G?M~!h$rJzv?zDr&H}}lo;pM+&<-3os9*nb1t>>3%Kxp3>AfCO zQ3j{(Q>E5GP6BfJcgd-dX z{%KOR;HA)reTWz!D8j6I$flcl3r3HYQvc_g;*?}tw)-!y>}10Z<`p#m_?ImUT$Zd@ z7r$?h1Ji|&?b*S;jC5Lo<1zAvefayF=K?o4Uj4i-to*n<%&+}dow4Z;@ zVODruFFXkHD^aA+OZ&H7jO zur4?bPoG!y8!&Cj`@Z&5f{}}F8wlr_UNdH<%+@*d?D3~afs{O>7HPY+((gs`I!WFM z;A+4XKy8}1fA!(=;l$xMDD>ZfgqlLhpRR-XgURE|X5?V-VBnzlpzBcZpz5ILz~eyj z#oUY0=S$i<^Bshp7Ee=nibJ$k&!tBIfuR2ijVzg2v&m9CV>2)7)-lJ+_J`xi2`8&B z*W2B_Q%-k%{_^#kcW2ZMeE0niKdK-7cZ_b_*@@qN|3jy9x@P|~=lr}^78Z3c>2X2t z@{Efst842Un_K$4y1m1o-+;kgLxzp)88v3y#JZTF zOY-SPUr91}cUy`dsYYj{ej@9o9b&9KC*T^hUf{TVb8L(0r5VbZ=M3O+(7sfk?LQAF zFl!|fu)1G^oRtT^OXJ5Nw*jYK5OCH70PCBN&}T}Vxc)dj(NejV#}x#B8Ld^|^)h-)g% zqKkOVX>mi$Eq3Y48#=%wqaoa2L@_LBD^}2F#c1A`cTqHcd5pp@oHQMeR60up(PF5D zSnwYHiNnoWQF3$&HHIMPXN$Ye%fY!JN<=y6&t9>p)y_F*P7ae7-ZatbHb(uVk}ggg zg-RmsT=q+LqwY3WQ3oCHQk#^0_VLPoplnb6zLaJ(-**Yh8B9Ypc=f;}D}> zQqo#P(LETSyi;m%)^+E3Tc3iy+DKjW;*7#aqL&gM&D$`EcAx8h`P zOy|8!@oCAq30_j9BN}fsf}!5vff_&)qwGumN&5cuMe4%ufE~!d*(=`q1($w?2G}h? zCWeyj)Y`F*vbODUe#V0=2uD_W1Ibc5ZA|KY=Y2uiAOl_{@$7SXP%RaXH*dC`PX61{ z!22E1__nujHC;vjO0>&Q(OsVba<>EXJx~C-6$WJE-h%mt_bGX^-qTSRJdS==ikw%( zh%8Ns&aHBOkY?=jXC)i5rHd~pms>@bE?FF4cln})-nISi)uCj<08?;jV(03ac*u%3 zHsKlSnstDXHlv;9+ME=Zr|R}ehL%_vo9RkQt$`N!GPYYhm#+8A)|VZzjY*zT>JhsremfcW6*e+ZH~9#6#Rd-lLz5h)^ht7Z|-IZC&t7y z7>(J(V;1qz>`RDgBShAL%Dsi@dS9xD65-xhnH87QeZzw5#`61gH2oj3NS({W?eo6D zN&39{dl}rJ$y@omWKbDe^>L``0$~h^PLQNga~qb_sJV1Fv&oL2;=i4?nR!-%%R7Rq zwbOCM(ljNGQKw79()b^fcruHU)D)7k9M&RoEFH(-;UJ7?o)4w|HrTC}BD5SEr3a<4 zW_sc3$4KB>^=e*-`(p4kYt@;tIyOZ!6aKcsbdpk2rKk0bFUKcy`((P?G^>3J)JKWY z=t}fma9q81ZD=YKJ72eUok8*(UFdR9mc1oAdWd=~bbYE~plR_o)zb0)lXk?!0@%p0(%D3c3aXK#p z&&nsln!#vNo0GHaZH$4pv+LVlOgFv#+el?T(nKUSHW(I`24?1};=SwAJW~|8CUE4> z?$r}N<8vcBOf)9WacnGR{|$#HOwu}2$_2Ypk_XIYgeLZv5FaOV?UWCECp5412U}dD zzNF!eaAiMW7<0x^=-3f6rZyPZS^LWFDs$$V=%*@LK-(n?sC90T}5;Z)~c8x z@oB_hOUcJb>pUy*vG&Aiwv+bDb4%RBj;}0I0~yqok$d^1w>cP92acu_6hmyIrPU!D z8_Rwe9CgYXI~ZZBby!=0z*#;9)P?QtN%xt)mgkS8HLSR1yY1X?Vj-_#7UZ~pDz=Fw ztGnF;LgW9MPox@>J0}=vc+;6_6-_Zp=@F>Mh6|;EFQGj8}pev0!wfHBa@2Epf&>X*%7hpDalpG^E#z0ukYtE1~yRETBn+Tl!Rxid1p(@vJ zR0~|oTy`xQtKA*50PL;G!Ze+wRzVQ_rbVP-G*gxn28V}tM5Xmw0mL5vddZ4>}?aSj8_YHn7g9O6r`ms%E+ zPA3|wu&n0jTLfpN$UsL9sqQZk2`sQ-AA|>RKiX(vi2L>fQEy*&p8rZpu8jo-9I8G;Rt7Ex4!0o#2`k{&-E<`QiQa|5wkZL zHI~Fqs2b4J-Yv7$fo_<=Y*~DRu8Zz3ZZ^kRymS>!G;oAts0_l`RJODH9~U&B?lrL% zz<(gd7_t#}sIJ4i#oyW0Now<;1Gd`P+KicHCgYG0S-~BmGe9O92?5PXVSo)VDNl+Y zNMOk`>M!QIRFTBmL!V+pgHWu;0b6et8i}5R*G;5W_%D?-PmNwI*Cx|%Z&R!;G~@C- zG}QhdxvIA;G8Kvp#sHE0B8uxOccro!_A_eAS5g?z#Px(Ux&fwGfzg(LTv5a*5aNPl z@|q{Zr+n#qpq?R1M8;LzHNw5MxG;#g)up> zsAk?&sW5F~urX;}h05AzdJo`;(4XGTENos($^I&=@e$H0TY=G<_p48^bb@JN@r3i^ zKlQsw5;I;38689XaRd+K^qOc5IB^&H2H4mepapw22VCGXpS?_-v6fD}yV{vL553H} z8t8aDF|14uXGcLVmu+|W*h5Tp81(v56h}#%{kUe$zX(3{%jG{!TCXu3U^qku2^}F# zqhgZc9C|NhjNRTf#)482~l$r;raj~ z#xuujgnVEOJ*q;$FnAaS;lGy+ZUd^in5*ZaknghS{~?mcpZ=006=N=HmJkr?0|2g* z;)nN(WuK`oOS9WC3Im{1A*);At$Xn3`3LCi8E;DS>J-afS@g1J^d`wmSlOzF)Ho~q z6uN7tyVR^tHd7CwhWhAd4#q*#V@gBycx#%IvOnM)x7 #!MIewu=g%B^B(rLIZ|KZ(;qpMIsA_LPLZMfKyk+YGcyKs@#%x^SaKlY zxF+~&JHB+dr?GZztPBMC_D#8ljqE?`4a)6_z2m!ry-=0#v?P?e3cG zuc_L2M1caTq^lKh=7sWeU(*=q4GH$=BZ(-mQI` z9y(dSG>p33G}iH`yKQT&cYeFsqZGC4C!I72B#k{TXv$%C!xA1JQ*Wlbos7f>CvQfC zpTKgv61|&k6f#aLZ-&KEUjH2|or4dL&m6ldeI@X-5m0<}I2TZjR;*RR5qm?q2t1Ew zVh8@LuWtNWABd}+Ch&xE<@VybU#*Oco~=V`dxD2+zY3)`!ch z7J3Q@Psz2_l+GY@=QHVm=NTDcW3gU`DOuj{r&7WW-*7`hgTGe15<;9!hzl-;sYuR0 zYURsP`n$|9;nf=DuoWJPnXmJAFDd?QB`<9pAxU*`Xca|MT~(mEICv5uzU*sJQ^DP} zDiQMPX<0B|WkOejmg^mF{hZ>ulx8> zRK?D)s(3e-h;Rlk?~@n!#2?I*tG_-9n*&W$KJ!WEDdoHr6DnszkCx@Rz#r zzsECt?RN`f75uyAsygL4*~qG#Y-D+vxYt!|h-9-_h?+5P&PRI_lUl>CrZV@@Zcb##uWd` z&t!lu4b`O4{~!`!+KTb3J7vls1R^p7C_2h5GBrRPUZ=Azc3e4+mVGJ*_h{yDbNbSE^x9P6!%!_Xa zv(x9B`>;ZpoT;6WCi2eYRF0wh$gn_?%Dc}%<#e6N`lkJ~10Q{U`tBYb%e(Ny@q+&6 z1dc?XOLD03x~Gklr=?BD6Ej42H5dkC5j*G?Q98EOC!+DlmO%RL9{nT{bTLkCj(u!RPQj=BT9+sCqwO0ASmWWkgbHOTqQ2W3# ziIu;WL{_|#KPp))UVLS8RPkB?S%Kvk>%c3;yiQX8KFjb*?e*}RVHJi~aRYT52kYBM z7OI@4DFQ%Xzdf~O8)U}81z|LsVYtjBul`LMofC+5@C00k_~+|FhypU2mqrB50li}{ zI^bCG*Y~j~2Q`*HLtb!0T5v;ANO~C<00S;|>2LDm^s0B z!x%~Urh#XDFT%Jl)3PAqd78u5j zxd7{C01*VF%X$uaM~rTB(gwcnr>VyerwgW@3kD2FrZx1?V>#~Tjh51-0@|{}(T1n* zdH!&Jd(Si1@?w#u3DD$>k_&qls7|?#C~*C7KEyWXC~nYO?qMc?2m)Gx?U)O0cw2xf z- z*2cswOxitT>G^cA{K0Uw`@?^T8>nFtRFGevq+=AQq~?W7i!Hf@x`l8LoBuWlAM%m) zoJR3&?4FN!cVq5ZnkpFsIp(34*(5}jnn4M3fENVA!0#!iUfk|qnKYv zV))RN79-=1Xfu~3KOQb zVhK;PBJnMu94TT!n`z1IO;ga+EEw%1G!?-n;Q_@eR@5e8Vm?S{U}h~*8uD!`H5I>^ z6!sN5FJ2b>bt{!+D<$*`)McLHc`zCkF>uPZdppVNa5Or6;5GY(hBvf|7;~1f)Ls(b zz!Ma9#5)|Euebp}k|B`rOTc#&ms;OP>lbcjs-jBkNuO6rTh3uFVrJ0WeKYJ{PzB>mL(W*N!{j~ zsqHO^-)|uuD?QpbU5&l z5wGx_NtB1G1IE}s`P~ujT`nNXBPoPJ^+sN>ki7VFRV(hiZdOVT(RD( zkSIHVb^pBH-gWccVEk>QN>W7s<#}3e6HY4}HQwqhs_5bu7mLawG)8Ghp`Wxki^#e9 zCgU_a`*3?l_zeqq=LIXnCA2S5FGuNL-2KXZ{^CyX#%!aus~P6!XsVa;dz80Z3B3;D ziKgXO>RAx>SF#f3Nw2d8R_GKLrcN7MXP3G_MN?}*UhPaDonip+*7hqiGFf}@>6xvO zaeG%tXHQo9yKluE!;eFT#+s^5Ll!Iy^+v~29#0f@d_K!)>lsMV{1j1=%lNY>JB!B4 zWh^Pqru$WL=Xc3Gz6!dItaKf5!54);$3tsPpqY$HKL5ku&GGp{Sju8NeXf7=#dB~z z3%&tPb;ov(n#^=$rc7|IU*)HPrI+vnigEXU(=&Z*qy#H%&l+PQ-=%vSodoaV%miet zq;KBC@-HJxo9_=OpkaHZw|~7DZ>!~1Yf2JclIq4-#eaX_0uiWc;=M5XUc(l@)XQKa zv99LEz5~|D3@4dp?YO}`xhHIIS9LEctIEu7-yrL@cB~V!N^A3_6JlcD=k%586lC{? zeM1B;`wx>2n(% zv)%KG*U}1)@wfM`#}zecxH|>8c*j`U0&G=$Tu^FOqQV1qi+lW<`51Ip!-Y0dj+{gW z5I>S(=MC7JR)W-}T9w6yI>eATriNQ{GemE74 zU*DhEG99bxxP4B}iV zezwL9e-#puy^!iGy~3S~U(f~c;i4%bxwHGybQwTP!RPIt(+7~81#EPsA$)UPpo<~y z2L?Y&U#I_f+yPNjsPl@Sm>PD82GwtA z1O4o7dO+uT-H5qyqcJ?Ni0H@_gLm=5I(so{Wo&H6B;Rcsq;9JdX}%uys&Nag?P|+N z>^lEPEc0nsP2Y`chG;v)_ip5qgc9#3vw2tlapZ2j?l6*RA$YaO_mC{02A{(j?Zo! ztjQql4a~s=Y|65l^GU;nQJOi=J3BJl@~)(#@DyVF;P&adAyR*5`TNL1Ox(7CL5mVv zT-vx)HUP72CsGfetVj$hN{~Fk-;V>MitmUBZSbn<*48n zDgPZp^Of^f@}|g!z>ikeXYpgZxYV#ybBW)!1^79?B}mPVM#OzFIH_ae<?F+I-Jx-cG~wHBm74?n0`cqnK&SJ;zzB zy5E-~<3y(|i+k4*VV2UqyD6mo7;rXgCaN4qAtr)unfb8Xi}5qfKY^58#l8V(aMLdv z(q3duAil|uzW{5HZ;54kM-4w)5hpw^bglg5{UbyQ`mvVM zV$1z^&-HIdL~BJVPo5A5jz2CK3h76?Zw^Fw|K}4w7en}*_wI>EnOOb%zKT>N@$NDD zc;35p%F_4g?xXpQN&%{03{is<{S(TUPTup&3sY14h$%6#bj$sKt-p(}R}j`(hIxZk z+sQTC$x&Ow)sE=mB-$#iau16w(m+K8dk3hB6g)O@anm)+IXmeY5F^k) zRZCu3W zg@L#;+%xRnEhM|>eAiOVOZ#oH`S9Mx&M}f{Xh2(>UyhtYrES_F@AW= z|H;8fZQ0In4tzK?k2FtC=OWKA9!W1p0M?+1ZX^`oWrZC0mKs!Z+ z`(D*a>q_63u~HBe*>iwRd;_BlhL?3Eam%Uj46^T?Wxe)}8i_(x{aBgV{nS_2uv_yQ zHYGc@0qtM#)#)MsWwd${y>52=gfTsRHu4EMnbPUKWmr0X8~IL^$EB4^Eof~{ZtvxQ zgeBfxF*73O2r9Fk7 z@2@tXmxbV=bqbf|TeL3AkY`m$7V1#^&0y|8;_!`H6raQu0DH&fRm#@qM z))yB)9GAW?i@ycyI~k7WIwzI>$MBK$g}ayJW3b^KgsS8D3uiKxe!V)Xho~ui^oKM#RMWl{IJYz5%vE!?O2_d0Zg%L&Run#UCnn@5 z+fNfZe{{Q?jbLpIJlY}*IbU4nekJd+6o8i*c>QJcZlvepXkbMD>wj~1f;}e3d>wnx zK~u|wR2!cp>=l?dV?iD^eWAENif%2Tv^^pK+ZkONBV$tA5Eu~D<I8Diy)xnrX(Dc)l&%(I^BB z>(9$P+(|NwS4PAYVYhhc{HluKnenZOQx!C7^%inf@K)E^89?he^rD!{nE@JnF8_?O z=tUvQ5dh7gELV$ogaC*qE}e{FVMQgjiy3Tp{PWu0NN-PLK~g^)}neC z3RFxFAhb0+5#3Pc+yZ~vT}YhkX@eJ2`PY|9T9=WF;v-v%3So|C`Oe~v9;VPOYH9`?p~*Y?I{2S*wz}A*O@T( z3!QMedj4dmCU3-tzef~dzXLQVmB@eJL^!!gG#ZR&TzaC+G#$i}QWu>$+FSz{Rt(Na z4~1ng*yPrxJ98et(`#S5-zeKAVn>Ry8gjx|#V@pwz}A)asAL`gVf1be%=P8$ z`ordy z36<<=*;o-DSn6Ka!dTqb#+X4dmYrfeI89!EmXkSjBlOHfxcbk!& z8Jo!oW1dn6>h{=w5@vNTAmOS55&Jh>X-Kqo-UDitHS}t_rEA6~Q0yA*^Y``AU`Nrt zXgZKRXp+l_RdQNU18OWnWb3-%p~^=cML9Uxzy_0B!BN>o_{3j#qzupiFLlyAB8a8C zY5)@UCP%zbfba$QQe%hDP%qZ;>R>>`0yOBpu)Ox;f^hq>42UX~WE1(%OaI*q6HChH zA0^wU`@FWvIq7GxG0E?4p^5U)Dz2x(eo6GfxOq;k1AeC%&2h3Db@W73nO-Eu?doB@rVFUDeh z!#2Rj(<$$Y-(BaMk}Z!rXv_ZwDe4DiWWLQV^o=a7h}EZTz6F|^(K>nx52IsUECVAS z`vtnjeu?=a8}*V}@*djfzKV&R8k;_wgNM3HaY$@JafpkygR4H9+7)AriepC586oiI zo^Gtee2je&4)f3hhdJ@G39#1D4z%d?x5@~{1jz(`4pr6<%qsB>EvyJm%&5!PU3j`a z3SGU-Q3Y#xv~Oz^Zo;O*8y^(wiU~`!w+)DP-Oh_hn zq}&vNk2({@TM*6769Zc9XZ6Q|_a-*)bEQ=_dTL1`fUj%ROAoa9wbLm~UouH?>-uj1T z;*~Tsb)X7)5&XC|@ej>>9tq{Kw*1>q8 zSH4^3+;jJX`_cVW|MPQ$1UCO=YIg{>Exwt*%mm{+_==xK`7ikkUz=Ngv(AJsR$Rn&{}O zfFV&h->WZhpgFA2I>3&mXNS*XkdUROh2(1o+i#9b&klda(4M>&zgl#<>oGuIn{L0^ z;8>d>^jjP3ctUZ(Y&ruMi(M7zUGLRJUz@hxX0I=ZHb44hY_K|4RKQRi&|dJ{f##+M zqsoQGuyt?rElE%Kt0eb+O9zBavnvyq-1j>X*Sbu|Rh&tDrn z729F;2KA(m-4l56%p3etjG~4#=Ia7|_gg$oR7?1I181~$Vs34<-pbba!y7{QS_i@p zE)XLG(IyqEj0`$b6=_f)S8_@wi2-T@MIcjTC9}&UNaEvY!>P8sZK>r>#Eww&1|%YD zr4f$3jO;CST^s?M>n7a1fhB>JE{HWT%jQ(S-7I^Gv+68jd+cOxsn1^vob`_g5H=cW=Htmc3Qs;=P3mrF9g|Oaf9aIZE3=WL{>(%JO_+Xx1$WZRV z^^JGW*4Y~U#v+@C)4l% zjn+}BMQbZBKd$rC!HGWI8o;>cIwo`+9_%sB0nFF!!f8Mlpa%%`(zNcQ<{Rt0WvQ!7 zDquiJArdE-+o>-EKO<~=9MjSID>%-L=>zqX9UV?qp6~4x7>Ecs>DH#6Ue7K(AQT$c zy=vztN9VD;z5&i%p9kJ;TBy5msP|EeVJ6Asw2bRZ2(0gHzAg^ezbhbb^kA{@H`fOp z9sjrM00US)yuMAT^O|PF7tr**QRB|hOCQGuICp)%>;l35hRe_fv@)zEGr@Tl{M2)v zb;web9$YT1Lm2-GE&THKHHS*XSTl^2)V%{{;4F?22>oQoYTr&x@O?gm$jocMFQHn6 zUVuRLEJ1*Jrt=iFlnJfb{r&3=R(Wsjw=Q3ckCvPg31@k+B3APjbs1zS!R4U3z@Env z=k3-{ov^xawfpz$Hx`Yz=FBXxya7DlwRB^Yf}WLmRQ*Jvm;WWaUukz65kIRWDoS3p zTxT6J;Y@JQDU(opiCfjer>c$d{#w7^b2!XovUj+<0NMG4Utg}50)Gw4RnqqP?>PV( z*nT0wuprAJOr^T z^{oh5B!a0&7*c`=BN6h;Ht~TSxMl|_kxqfmr4}Z08ckm#yqI75J&mrF4~@4mU}76Tl~w@tznKRa^PS5PkG-ZU)c#Ufi*L@2Cvp+I=_q< zW+TM%gL!oWoh1jfwEU~wr4Id(qtMHnJ$WIv=EZp+ngx`(#X@iPMhP8l)w@|d??v7Y!_o7#+e;=ZeL*G7n!I+7d(4?|b3 zff7I;-%1t$TR}_G63#o8;pqD`jTFXYkLjQbQYmgZcFllE2NL~s#sr~nGGFG0%;aM7 zsI(i>;VZ!L$2a%Pv>sTW0gdFN5(=>O1}$&U-9uUC1iXTShnIdSkjZQjQloFST1!uA zqab(9XE};+L6LJ=xe7Us6)EqcpU9UYBISrvlcjlxsE_0J zbc1H~w71`kndTuFMhK8PU=7{WKp%%bnVlgWi^0YtcPOaRY%%V z(L$B3D-4mn95RZ%9vBPEi95r#I;1vL-mw~jVR*SHFaeX2N}_engDKBC#3%`jJPeeX zBryYQe036uOo_#?mB{G$8C zpY$E)FMVcw;6-J0`YigdXgR43Ic5M&00*z3TQKiKZx|J-TEz{lXMK23VxfE-VBJ9` zO0-DW1IjSO=uPj5oivRyHyxrd*!MLfs+v$Umt8#oz~BQ@n$qtLnNopCfUvSwFT$zA z6%j&Z;i-Z;4`(LvAUTPgwn_c93zYMik=pi2VKCQGP@Zz6Vn!;yFL+8Ie!31e;XU6- zUDC{|6~bg$2k|a6=c$pxO5x$M++IW(zz>D+R8Muu>X7zR`@EoC{Pr;r7qKW()e2lm zW*p&H+NC63XmorHE#tr!aj<0sS(MjB@RHOo!livEk~5(v9q%0oAlCn0D9lok-7R{4* z*k`t8tW+m`D(+9NlrO&Efp+UXwPW&$4W}v0du_&n9??mVP1%DB3__;4w-m;3Cc?tPpmTuM2- z^9m)GM|NRsiwg$&7@Flm<8H#G+^h_l;I1kZBd7PFvg*gVOWyNUW1j;X@y%5qmkKg^D7J8Q5Zd8q}4CsUk$zZ1m#3GiT--Bm1$`!yj9 ztfU?QtN^7ua$2>-8;;a|ddo~x&1^BH0+&$HBStf8@^|b7p(OkBq%_|~WjD~hzycod zPA|KTv-G<$HE2LM3pWIC z=xWH8rC=5=H ze_CGEX&5-US#w*og!wXq_spw$)bOY(NA7U^>EbZ10ssc`U?x;if5zbFbE8ZophjFT zSV$zKM3geYQI+>$h3J$nfv5)U9j@h*dJF!3*_#+$| zv=?tH(zk8umuP*zif)^T>ohtuJCZQFBAJ64u_GUCAMR)yF)0mS#~-h|uPVeR@6$ee zJ15a2bKC!1!xsoE3R?*F&d5k9{p`_bp!|vMyyi8fTsia!4x`w{DvS7`IOGhRIpE1| zkP zATnM!j1Zau(`X9&@t9r!5L8%K{2ri~7mK9Cv>z^k1fLPRu4|17w#FCsDd%>)(ZWKiF_0x2S+%GZ z4%00A3PF`a7S$hvQP^v&@?z$cR#>E2BkwL;jZyq52NHPzstdE6bW=8k7F#glVkKL~ z-w~#97?OYizO^rz%*va1oelA^($La*P zP|n-}$20L0w8b1i-Aa^n9r4-ulRi2QvfXx|MZQ!jFXQ08^!JrdGzFThDWWy$N4KO; zH`)l*J+1Vh!P?_vu8%%;VGi+hWC_#2;8l<$0=uMYoSUu)$kx?-9Te8RGD2R-3QruC zXHhG`lD!<{bd*oDetF7Pt#GOIMK|`q7$ZglH#L>vrpUh@{)_m^m-~m8llNg4%VUf; zxjWBacsdD{w^JWwv@%|$2(?AxukG+JkP`d?;E6x#8=I&Bu<8h^vWUqY;5?{IL}HhXep#4C zZi$-6XXRc$6%mSARaL;{oydc)7Q!D7+gam14NIvdLX8+J8+R?E)6jNxKy%26etdwccBW<35S#ME~na_3Du0}MEF0`zDGA8>6 zB0d#_Md2FEg0%u;BGxAuDY=tJN$?eCxbJh)ep}Q4U*V_To@!j zjgnw~hKe@zq4PV#Zg$JtM(8$^I8YMG`QT2i9nr(<`|yeozsOD6xW zLPls~<^yK=y70X{uf0_x5lT-D?dj`O83mpM)xIAT%|s(p9tkOxT5(!mPxglhs$bW< z-T|kS?1tXo=z~+uJQSk)%HqM@L8AhLaxth;U1eg1gnW0DLpbr zS#78Y!ltr2>eSg`II67Y<3btkxB)03IvS)@+Gm({qq`clQWnNiN{kJ#+@(?WR)4ZL z>Gwg<6d0+8lgo{EsT*8*{)%KCon;BzX#XolF}hT=ss5OvHwO;0Z`M@Q9>#eoc>V~0uDN=DW zgukUIQKxkI*REwT>LKJZ5kG{|v06FX6td2rNc^+}ageZ zWm4#|uY2M}jQy|Cw;nV`TcAtX#>f+cqA+h-##f%aBB{b;&R8azKbzRZ$T*tI!xLY_ zl0g^%6Jj{a!nKbRN=3;Q8CQiph}vw$M|Du53V#gyDYku@RoYQjStQLVLA(qh>FCUn zYcl?=XBJNN?{OmuA9!(mnWl%;TsV4erS}d8B#1kPpr5wv0#>w1J$|a`&9TUQ7q{U2emKD0nbU_#Ax%h2QWL+--4V8E>-Bj)ZRI0 zT?~uydA-qnINcaVGnKl|UJ!Q#4O6Ar>xRnoo=TcZ@b{V9zcae~NGw!r^4JdaL_zB= zJ@2xp_MRUT5&-7hkX$H^o)q|QI)+^81gQme{0-e3sieDF=->w1Std@@qeK2N0WmPy zybQXXGX;H_SJ~nKO)bBY-2e!7& z{CdbUZ4k5&gV#GCN;b!*N#?}?(ge9o9yek{axD3ZtckSGLlwoVA#F0@{~cu8(UVSU z<`slo&Wwr<<12?gr%>^gIVHVIpo*4BPdgYD<82CaWwsfSLn_PD+^=K-7da!1a_mVr zo_0nS&!>1+gUq=#i^tPH=IE26F7-f5P8WE3n(to4t=oc{&fQ@gPI+jh&W_=74=;tk z(uvM=!^2OtV__$fGvY5hFiAms7u$xrQUn&=Y2)OX0azcdCrTI zp9NY=u>e(}7sTPoCh#i3I*#a~MKo5{5U%NB&}^;fPf}p$Zfh?fo}xgA7&I)>mlb9B%;sQ;er?Q<@5LO)(5!|4Z#{}0+uYo9MNGI~dQ6H#<_YoV{0 z3adNE=|qosh|j^3)ALcx={O^03SKZZjl6(oCR{b=JP+#CTVWYR0N_0a4wpgvZDh3g z2JM2)(7;HD^7BkVG%o!sQFUbzTzXj)9A-4+q}h(Jt@$b#rO)s_y8-MIy8820Aqoc| zEcOVTbJU+YB7aJl1u*wu2ft^AbAHK&ZdzLuH#2rY+LhgfbuQEs82doOG{Szz@*VOx zk$L(@*cFo}qC%|OOCc$4l)a?zS@F{HoA}CTvu$|=4k)&YS5M@QNz1ottwIA#zG0;o z0XTBw?_uLDOREmK7dP9Rhy3F}c>sXV{+a0s;Cqq(=bv-^|GgswN;Pl<1`x1&(4I!Y zk@KLvxZ0@!+4h$QFO3SB_;2_1o~C1%K<8BR&FSx3|5PiBcEI(#}+%R#xja(m|zhq-2X z6=_{VEYD^sUDa}ke(kL@xPF>f%9XPt4)*p;!S%`pg_HAL%BI(DZeF)_E(=`KP0b}v zyKtdc0X=T5WqFx2zK|d&ll{32sTNt?QRwUpk~7ubn&zNpCbg3Snd77_Q)Ay$Gvo~y zaJ4ni>|c&~bE(rdWooy2)r-K1#TKjLha_`z|yL8XT@jQDX@^tmCTD?+m__U z*#3E%bgE^JhI(6esdnwITh3yqYsuCz;#Do)l(WFhe5SE}Ys>1P^&nNi!K>!BT%N1W z+zOq^+T?5>V9y1GGi#*dxZ>cjPKa6C8K-%3yLdNtEPi84?f$mQ3}tc;r+3?|&msA< zU@lXSFB*oKC3tgYJE>4MgZ||&S33)Y>pXItFP-JOzO8m{rM`f6lQ3*zhSh$j-t8)J zdJ$^3{az^3Fx90iZ`bw(M_C47Uxy<)OQk#x$g7h8b=M2&*{qdiv!bjgi;yV4*_uCA z@@d_%U-$gl)W}gv>m5s-i1Fw;O|`fKOVjgX6|=?VDX?WfXWRK=fP+iRnX5Vu_tMh#-{W~w+m%YwSiFd*3ROzHQrl_5D%aVlnn)t4NYRp{ndO0lUU1v9s;5FTd*`u& zcY?r3h?u}+K6p!#F9ym5KS00#n;d24Db$cnDMpgFF!o3WC58f}KYTgAGz1_8f^-KU z41!4;!@Mc)$tq+Ixx!l7x;;uw3r0eP3Lg<1cRLcu05aPMAq0Z?-3mJ#BO2}7PlQ?P zQpgY~pB5YabynffG2^Zw$Li!1`JWbVa%Drj8|Nz~3s=EPFycjZ-s5(tP(`SK(V?f0 zA;f%SI&;#$bljTp$*JoISAeu4%POu(EnVO^FI5wl_{aX@|7#^XIenin5iu?pp?q*qaLV{8c?KWP^G3&RW5Z>tCcKEwi9n; zj6x0{@7+Ce|8)rnsUD{X^iF@M*>oRF8lvRlr+Zg~Lz4V;4Z6Xj+s|Bg%%uo!dQztz z4!mH1=GKi!W3Z7gNC+mWr&}JfQR4qMwfxhX zW~5Q8)^1N$*SZ7P0azb5fC*sraRV3t4d4P801rU_k*sAen*2|;cP6+$DV ze1L3DnW1Wlwg-6LUHbO`zu;3%EU{Y9RzRf(Ah)A?+<)~-409=jnDcXXp-8Z3*jnW*ZygWqAVa(zBb1Y-p|DtdIe@k1fEF};kgrU7f=Dt6?zos}) zwt}QPrD@vgyN&|Gay;+(A{agqH;AuP$O#T!pumMt{1X8XXQmGo!tQpd&8?xPY z$bbHW?6L>4&q>ID0mzVH$f!}s6VG7*ba5!I@q-eOBq(Xgf*=@h2yg@h1hN7G4x&$t zbcHJgM}xubZwqIG!JV%;v%ugUtHpD{0J{4f7tRGXgoOtXpaBgxsbI}eKz28g0An`M z0r*|sUAnl45v&Jp1eb^J($B-;a5xMndM;(f^*twQEgBEE7fll_gEQct84S@@cn_S* zd&9T^n|tVzqrrst>kZ7TL$=r|vuo?zwBgZF*0t>6F*yA2yCVj0#*s(jb|HLg9@V$d ziZyQ-`{-AwEz}h{247Rz1>S=EXMX1GoqNq~YryLEBc-w4o7`3i>q*xiX|Mq|3Nf4^(VP&s>1*dLx_fQy zQTqHZAf+cj0$}*lR9K)0av~8`j(cz+z^jQi`MsccVTs}%d`);lPTFL8L8ldx6SI>) zQ>xQC+Xv8fv35-|f>S$v|9;B4E4qb2%<1mXtR zSx2fhDospo2Dg=&+$`ZrI!Qb1J^X8XT(i_c%Gx{~$0Ws@=0fC(){^u-h6fUHTW^M#_m>G{P`Y=RW!;O?1qa@ zCHh-ys0PzcNy5pd>absir&J^eL<-bpv`=qiRnKH~k_W-n?vZ4ek@ifF3^iDMZqIhv zgstRWM{+EuXGsqe-&uCiS{Mg3-9`3`D3QoUu%C3Y@>31KV*?iL&)ZNQ7Ij-HbH}x+ zvjkSX@&;@CvE+J;CJ(7KMPcx*@%&|LTnk?rBP)(2YCL+NK9tY)r)XjXOxDJ8cVwK$ zMO)*wM@PodJKbZ+9#&pLwo3s%8Qi3kZDl;LxLA|yFRyB@2@Zf3N~2wI)qh|Iq6e3z zAIcSh-m`o+sTULdy*_vUdmY^B&mSni-6GKSl^4hdGHi_%QjlPtj4&`^lq8Ahze_M= zf=tW|odtVLjvVnwxKrlKk29#NfQ;)RMYPh zYthZjHU~KBUDD6N|9yY`jtOwmDM1FE7Gl&H;m*4t%5^uym~c~E039nKf(XrvZbX*G zBoxM*!gDAYOu3XF?DrB9XmByQGrw7a&RN6B@_WM6wX) zMYygGO{+=UYKlPHPaq|0AGHlcZK?$TwZOO3B2mEOi6eHgGALyzVp29)l`rxr%vYY1 zoPDz)O=p^1!*u`GL-%YTUiAQdELsFP}sTt@44Y&T4ln^VzQVsz=zClVq;bWO%i ziqvH2Fo*vl0w5J6Mm2dEokWK&J^DmKM2IdKUjP?KQ9Nr&I4Gj(m_p2qIg1k3L13>- zxW?UbXV3^i5ClPP6AriF+sb>s>{9g*H8RNNS_2n#To?DtJ}^HTe-Ei2n$p1KZmJfH zj(M&Ub~pVp;ChCl;WnZS$1{d;TsO?ub>%i}mF@Qi8g_Pv_J#LjKBA7OA7vMH6ftNf zZFZJG3G+lJ5=)Yznw1)6*W=<6JD`a#itABk1hp@1zr9Y}{tQpp4Qx0MLnJWBDEip5X~@3UY;^S zB4lrr*xIsMAJ3L0mHS=$QgSHA)#ieZBVkyMui-DQt)r`_-vBkO=NJAlf?kOtMm>{b z21&LBMqN|hS~%K#7gTUjX;lJk_@9sIeQ}{qNrfOx3Kz+gfc*@Pe~`)5|4Ms zupO`Dmv^!qi0e>_`Uysf<~q76YU&!AS{q=D6EUWxsQMqrS_$LPBV$AjF^+Kz;u(gJ zGL+D~)nhdfW_+-bWRPs`n+DJjX#_WlUkP<}z%mfRLRbuR6{T;#7^IkUD~KHt!6Q{+ zm^CVBtqoAF_flRW5JBS_xi>$${j@%L>`Y$<*0V;Kk6jWWN#^CqZf(%TZO z7tjGk&cvvR94W1z?RuUYm?$@=emQ>(VWKKAB{_uTK)ms&8s+^7EMa8pJ_fG4VWQle zjKn4BP~}e-Kq_eYWpC6~LtaKFSJpPRb{~9+3a^)5dU}r)OWt9FOaUXlY4ZmJK-vOR z5VUI)2-y;2NFmi(_kbS``Ac3$0b}iYhuy$LxjD57{nX6dVsqIv00000f(7^9n4^D6WbjLLt?vUdj;`2`uAW}hMN_9UZq1rfL%<;W~ z(ZkZa#N1jowstt3Rq|d3iEJC*Nnu~rUL0Z>!>M2PA7ilBdRQ-600co01VQlg5JbN) z1;Gj58jj%!Uq{Y~bB_k?;@qy$&E12H(+hUuf19)cz$HoP(QHHrO@}{v;@XGS=eJ(a zB+9gUi)c5o1n8CFMdOQ7pOPL$MwEkzwOf)~=KKk(=XC34Oo{Q8TcyKBJrVYb*=L0V z^S54u>bK2+zJ?5HSU2bNb;0Z~9Vt7IGTgd~{T`-u;}ajN@OJ&1ZKC|&QV26;%bXdJoW^5svBl$3^G z!8AXNkXGqR485LYsq|I!hFY{TvI!HNWvYu1uO1fmgFP7zXjoLOX?~p43FCiYv;dF+jsmQZ(N*257sGsvo$OigBjahi@a}mRtKM zLhBbGL5K`kD2M`_P!R)&aH0%_A2sv{BEXD#gvil}4&@K}g8JPADW@GwBt2q55F%l+|hWE8Yh9KkRW3x*vJVnYQhXpxKR>e z%84{uqKunpqb9~wlQim2$w{S>w4@uFwffG)`4T3ujZWLq;zB7)xz+H9C zdT>yNgYt^98MFt;ikS`!8VsSVi6Fbh@D#(Au|X)+XsTf`)Rk-~#jFGd9YrXED4_{W z10--zA{DfZCsy=hCUFjKE~v_})iO#Z&cSht@g*>m$z0|#_x*+FcevNQIZ*O{(LI8y zdlcklKubbr{hoWwT`~t`_n4P88;*S1T?i-clbJpJ0Q~$cx;kyT^^oZ|$jz&6I}fNs zx$Mn+g@}LoZnS-NrLLzCrmuPJU?IXnFB@w?8PcbuBb?yRlM4i|3XRx9 zWG@6oOr$Q+|C`+~J(!v8@0{c&FZn6(XJKX$(12;j^viGRl<}!hrN;PJ6Az{hDFrFa z+(lZPgX0FWQ^U0#%%%V5jn`h8GVQH*-uvJq%t~~ht+dEuUwrk=cR&1uAeUgW&4!t6 zF${)B6Et;3hcK%@`O`uAa3-@mkkXJA6r~l+WViso@^R!@QT^GcJx)SAftfxhgK$p= z!y)Kryh>7s0OMuD2IQo4zkgZo<0c;!AEU{cMZ?2kx}BHxNRv z2GqrdjF1q%lyp5t#dI2wT6St)+c)8Xpb8vnjc$AGGhoaWFT6K{tP<5uw6S)#O_r!E z%D2KQt?H}yWK4KKc(Cvop+Kl5)D;>CZG;k`4=tv>I(!{nUGBe`uK%wtfI|s&+iIWv z2Ay%$OCMS#vcfq7=}cu=eidGICEKihv`|&3v2E5ur#nime=H<*rA4k3a2eoYU?n#5 zw*6iBd*ttR07btuA|z%a{v6z0+MT)HHRHRSU2u13cVO?#qpiEN-KbsbhvyzoJX)ax zUwQ-C`mV-z1KW5M-*aq7-vUAMw-bhNL_!22!@2-EBAjre6ke3Aw;}wfL^Wy=*r+(_ z(THZWq8*_Ur7?+V#4(F`ER-paWvpTyo7k#|UD9H&DGr+B7^g_$tVOG~xF$VrHpN|g zJmRS%UOH{o74Nv%5})|SFa8OLG=aKpO;CdEwaisViTA6Bp7qX*(4@2NzO5`S&<6Mjms7)QK@vXY@3S{`qUT!j@hTU8Nys1h#J8|Y9*1UrZcoXr}@rU1}cc|v3{hN8>oATv)X?WV@nj0W7kvmzS zbOTHbWTFjlF{QvoX_xatUg)J;FHGsU+JYoX*%w82KA}K>C_dTv(X8Pi!LIC`NYQ|_ zoR?(!1gNF+Lf$ibY~XJY;#y(cpv@gdkqzKs-56Sv!(cCkK^y2yDNJsadE@JpYno6@ zvI!YfA*~lQ4;l;!zJg5VHHyNp!0X9HHG>EEMQ~8XBMDsOPIgh7p%oP(2=qozrUblz zHK2)WJ$AO~(~_c#VdNZPfbj%O@y9T8jlAtP{yY>mUn;x<|G>!NMFQyc7{YgdR^_nU zq=Fb8mkCLY`D3hXU?9et4UY!afMBSwwUmI|6VSc`awBl`LlvBOW`OY;Q0D>H?m&oS zJJ{(60f)L`DPXNQY)M{cICOE+21V?;B49evgdwwU2^VTeVrzk9JwJo3XoYnOPYQU1 z2wlNwG+lTU=ba6%ioMJ(zY<}!u|*JSy4|N%tyP*GqtYF^SHw9EgAe?E;DX;ARk$Y< zJMzG=<`2QqXoF9NC-(GF-&ZFTnPqV|?50r`s*5Ncy+clfXY-K$d8rb#Cn>EY(Y+S;dF0ovIr_-j+fxkv>YTam8+l+8?%AKp@ z?iwvzWNqf-b3b@tQ%jx?a}Hd&3gJnZrQm`{4Z#fa2cB30n3vSMVKebEF&#Wg%lod@ zak_bNT=B)#yx5PgL=olKP}TkSzwOWJk5kO(=tkrmnOgnJ}S?jJ2IP% z=-3K^aRk&eaRt!gzkV`W(17AQjW9_)vzb;A1c3BSTt#nU3bDvYt7qg|bh{C#Fm-4+ z$xPB}v#FOJ(`Qq-kdUAm23%c_`h5N=(;b>N+G&!&xAM>*bpBwI;WpLR<1x`2b6>V{ ztIhO~iO%kg9q;b=*d8q?JxLDt^ddE^KsxA3prz~%fCWa4YVl`X{5 zsaHGKZEMGYbG0#shvFsL-CC^50qkyX?&36N8p@?m9pj)yZ?1sh(kp6^3D7||5=@oy zKXPyoLzM0j%@kabp>ajgGhO%^0}h~PnNM+Rc%AH@>NH3;x$@4I*k-MPP|OIgsKUXQ z$R>=mW~=CBJ`pusngiGOLliXeanDxZon5>DjbL~ao|y?=6*W{MpUz?HgM}v^9rOTc zteL~DMJ7XZK|D;1C;NjJi#+^auFki5xciqH|7P+Rq*M3V!^3|r&gHHeJRN^B`%|d3 z$iGge8sAiph!vo%c;%@$cv&1PPnD27{1b1UuIS{Y9tmzJrv;!@r6}bFUhWcT<)6Bl zQ}04_W;pU<*y3%7oLDpP2YVo{YYiioFGaz;FQ_6-e%F=4W}&|%i@ew;MVBbeeQpp% z;-z+GWtH@LjVET}#I-9K{y~M!b5GE?6m#cBhQzIyG&&GcV3vm2t7C49EiLX3f%c5< z5<_=Sl0MSM!}2xPZc9lNdTr<>;G1uvM4at)zMIh+tVUltQ`WgKY32ymC2ZBxs#o+nE#lO4wd+8V4% zsbR3SeDzYhl0AO@z5OH(q7-q!Fe#K$%A9H9CcO;i{P!jnNgHClBj`75g+W0Jzr^aV#ka&6gC0H!Y5R5y6WX(rB0h2{lR=@|>?|Z$`lked0FkSd)zRS}6)N znh2zKmy5t>b9~We41@C18bcg^p_2i{BRz>}^eR~j{{TuW4*q#4peYu0& z)mZ+hp0plDVHj!b%!qs#Z4k>Uw+Gt?GA!E`fEf%pM-I+7o)SsQwE%y#5^R#8>Bk7< zNW}exB0@<-@2awC#eMX_3<|c1Mataf~NgU+Z z$JN!(Evi0f6m0blHNq$;^JQ#-z7{8BZ~kT{rptjv^;>R5Y49NyQjy6OLc?(0T106v zx^jClM9;;IdX(ko_AF0M&-D3e(ZIMODBL&vM<~5lwUKLHmae;0jpf5+=cbTmEa@Qc zd3B&kVdw=O9f7xHK4bsLV@iSexRv@Q4Pov=7nx+s3h?L8(q|ao4Z4NQn@G3A-8s;9 z7!!c*DU6XEMc6>AZ0O(pejeKk>HHrHenxQL|dL9%fvN zw^ozBH*V(_UgxKQ$cw8!hkYG;qq@OLlnGbm$)f63CkHedMMjKy1u6TA21@eqigGVr zZFt-Kx-fox8QqOrXdl(c+l*he-AZ?65|`^UwdBSbUXAnjH@e2aTN`_7>=X*?h@<`6 z+d-rF`(CH zZWIPaiSfMWG_{12 zZTs>9i+{U(lxkW`RA=-GxYt@A7fU}P2|7jLi6NBabX?8uDeR&bI(M#QS3RcnIu=<5 z7{=C4Sr!L$GFidFOt~_>Wo%n`itGl@$R&qz&*dy+)d=C4(Gqi|yxl&gu^3ia*pWJ+9Y9~{Y?p-ax5=M0c=(Ct|G%Hr+dcc&a& zOT0Jx{T_@_pne8K)ZE&ZD*7la;yL)5m^a~=x`gS5ivCRl%9%WKLd7i+M(mzZbvxv} zNcNN3jpZB^CY3^Ms8G`@t&Ml0D9z@z%gN9><8+*(D^tu*;35sY$F-!>^NHX!KC-{+ z%|l)Dht29iBv8%p*jj-ck+%qX1~hha@P(tLPf zUDTVkKs68K%^ud@NvMb0F4a-2e2NPPecH>&!*kMGLKP>q`A7BYvxtieYb!$HT$m1I zTH|Sm-_m?YE*1rX~o_tR9Y}D^4f@Sth7xelY z_#lKtf=(M<{DXh&03GkKOqm^r;aNCRDh01WP(#BDs;H(94*P3+e!XzFL(VI#$3-^C1v{x?@@(G4B-abWTXxhE)F^6kLY}q4ey3v9 zs9HX=taN|y_<(eVkHYDv3Y0#|EzT|bPr8%yUx8wzwLhM>wEcQjc*vqEQ|o2xOYzzu z4I;Kr<9si+{1`ifsVZQ`fSEMMT0V51e*IVnxBljN-{I}l!*iI^$e}lR+r*08Ey%-D z(`CDalKc&xr}}q}ttA$Bh|OtAv^fRe)aPZnGmzMls)SNnLm9Zp^X=}1H=EaX#Ec49 z_no9ewFr0!xd02yR29YXVDIn!;pJC%Zv>`Yi#nU4g73?onR(U@+&{ueAeUqnmJ{-_ z>x-%(g!D_nug+7KTsf}P*i+LVM-4xp8C~+UyM4!Y>rJ=A*|KP(;`vtsyL%t8dsCk# z*eCj+8N{sQ-0HsiY6d$$)j~%wTjxtJU1JR{NhI? zgfQ(VMS2#EZb4a`^zhxXYV@lM>BV=xd#POLbSiY^JJE1*AOG^4^E0J0UfIoVi2gJ+ zt%g%euHgDYp@JLYf6v(Hq*rSzrp@qOTh5y`nVFb1nw`|_FD3Cz=mw`%>jtND`PsFQ zWX%$LH+-R6Kx|ZOa@3Xd7+(<5^ki;me0}L!UsES4#>Sb(HE{AgkQ=J$tLTRvmBXVt z?Yi!zu67kwFT^jhT5&uRHBm0vXPk_*Pm4cqj3+$i9}v&CqB<@*j2%o7`6Bv_h*ITV z^BFwbe*(LGQM2G@#G^izsH`aW;gR%r?|)=H+}CEZH~(Yn8GnnJ63qMLg!^kh?7VLhIK%>_Ys7vYVCK!aMq2N@4u{A?barddkS^(O>0n zXQlcYyDI-1uwJ7;{e*HmLl;;`S;m*BYTGpAu$_3)(u1!`Gsy2Rxf4j=h-YgG-$Obb zAY?U+jm;DngBu${^SA&ZD`d=l%<^*J4%kKsMY8*0EQ&Vde73Dtl;pnhE3Jt^U7^y{ z*bx9o`SMsefND~=v36;IqMUPpp{%1haG6Xh(gv!?{teokGx`{Djs zZe}q7pHfW*N-ShsuZ{eF+Y4MRTzP4*UbRK-`QoUCetJSR(bQ>y1Y2%q$GiA}r7vejc0~T6+NhGU-I%M?VYPTw~0oA|FL_7JE|{1E=8@^n~HSx z^oev3O}0)!c(1^Z53RznuQ9*Zwd9dd z>MMA{oSelwHwrXxNZy-xoYp6Qj`Io)Y>`ek+13DnE=r!d4sE|ywHI&GPN(cW92%UP zdGeL|c)PfI5wD4iI<#E%>SS$4O-4~8kqQ`OA&b9SJ-STm5#ODpyiUlunL4$xol;xD z$cXc%q(z6{S{c$3cMZ1rlERBEo6nxwc!SnLYf9g4P7Je665j-ZI|&fnjjk)|c5UoO zz$GB=9aTI~N9ghH#63pu)uxu7UdDaHiodd?-gU)MS(oB<_S&T<=l>fx)g#XPqgkxx z`^f|H(=6rvAxUL+pZJW3kCsHk5>@&n`DI-1Q|5R-wI>(Wwjb_?UyQi;^wz^$YkM(a zo2%~KJ)Tu{oU3hrH9pXEY%rytsMOqFFUI&*Zl!SjXEcJjHCbs(=|A z22hI907`!vZ3-ZlO`R09j*jp3oY`J`dV9}Fy&NiuN;)RjdXEWFd8}vjPgu_>7-+mT zNazHPy&gmcCt%}43qq|qE?CNpXY%LR%BmjhIOOqmZ%pmTLVfDB#K1a#5d*#Fu; z`UOU)D}`)l`Ulsxo?`0S6?@nNCE-Wit!cj>)Z}iwlE6bA;>`Y;(vTu2EmMqV(W>~O zrTNrmv1<7vl&YdS)Qdgc#O}DO;CPqGE{*(BH!(Oe1pA`)MR$0h%AeOJLt|)yP)eu5 z`j3z6OCDz-JOa_l)jdTNYNN@lUCWrCkw&Y8R zQP|9gqBN0+}RFU zbOMQ@Ib>1?$R&e389tTm7sjnM6pvrVxJv7{x;Z8|7wiuAjqHz;IQBWQA>r|!*5*;> zaKmn-E6%g(#Z?eL?~7>-0{Q$(QP`*~_b}-s6M-e-64O-I#8e@jVgs|x$Rw9CXNj`{ z!CE;nFmzZo8L#_<@qo zAqp%Y^0H#ssaWX~=a&NYD5+H6Vih+T`&ykmtCU!_X8-=!{HO8y&5u{n(AC|3Efwsl zm+aD0mKV$W*<~K_+n!qHhsgl>6d5M|^Spj#@v zo1e~~7~H$6spa@dn8CSIVw0`YQDduo#?dW0pb^qIe4AiTFz##oF%=w;5NOfa-2sgA zPBY2&3K94|(YD2h)!+oZ`uHk@=l<5%$jzrBXrqsqZ-<%0&R1ouu5In2Wu^Ypw zPlnSl>#O7+;0O*AKfMgQ;i)(vqfOaDuMn9QZ5A08W>a298AfeJnS$t*+ws+hr8rUx z$G&o;t*iRRL3axc>!Pp@-no6uf`jj+Qp{~R1V2D&C~iv(@-B~Dbv>*;iT10D<6QSN z)vziGV~NZ^dda(Y8_aC4BUChELo6>k6`II9by#D9^m638yrt}9oy6_JEUk2%@=gD9 zVLQOw!YsW?QTYN$- zcwF(rM1Y^4Tln9+9_9)0HWRTn=82vzx}rF%sS(!7P{wvHalGy3ifreOc`uC)c-pOw z&Dt#=_NRrMw6mTkITaXJ zAl^tjAWna88Aqs~$@o9-JIZbB+-lCLu?g1EpxD#hpa8qf15JK*t#*OecHlG9vrSSp zfm&A&erVMOsBkn5%iEXTU=8s!yYH2H=xfK~5V zyLP(wj$=_sqPVGGYbay%MqT|Vmu1J~OzE7QYHQ{X3yODl3&4guh6csExdg^Sg3O>$ z=;d~x;8a#%(lA#f1Rk4!jSb7d_=1qe-J8QRTMGld%&RDjsY5l_fJ_m!bN-I>PQn0- zjs)r4N`K-&$cAYHus!}xVoJIIj6Lz-U zc$c8M3gYwe$w;?;=_+s6WL#-2XZ$VZKvWD(LO%yrDVrCEqghQ^SN)i=J3ND>VDFPBKK+o07uQ`J={mjhl zC0}j3fKei{$ey`$ZOCQttnZn+qlIU6V=(@%I<|ph)gC1--lfa#0TIz&_e8TCcX>qV zfC+LhrM!K#hf06a`|vR`CN?cHiV*8EEKd9|IGWJss_AOv*y|Cs{t|e-=nlEBcY;j9 zU4G|YO2-*vC^mFkiMP)ZA%s{rhbTW?UfTpx7qnFNcz!|klD4nJcS@~4Bk}i6ZDG;< z9NgoQnz)yjb8}m8@#;6K%I?YrqP>hY zos&u18}Tq(kAL3(JW!7yPA|5cXXHEa{8em)n~y3p?e}g45$%84rY0l&*6CUkM*5$} zWtEXgC0kNP=+Z^f$b}o}XpifUZA#nkh7S&Tpxyc+%?PY}V7M8!ww_r^H+TV)cSGFR zD@YE4BZsL3!mq)x&40**BS4p3Pbu_IOLImi%Y8Wy% zzwm*e`rm$`Vdf5@gt@&u)Oe?~sAa0EVPT9u9a7!QTvNl`G{nq8Q_Ixy zjP|ohR9b=G>46}_o@1vOn&|>DID)@&LZF`F@w1oA)lAI!#U}uQI|YO+`k z32&LOoMvt~-WerO2VbQ7J?IV!ah|LI|Guu%?ECrQF7{w!Y8hxPD`@R(JAGpiAhgwllN+>*DvJ%@fqXZYLUX$>?kt*xH={?*L%fv5PCHXL_3 z1E2C__^NyhPQiVQrnL$AKMBWyZ8L|^41hM|0`@x3 z$v0B2TN3@_!w&WckBM6*W^|8OOG&Wz^e+-7gCAdFAsC?Q-FDI>YBgeC{vQ~mG4p01 zA^b95SDyoXe{L4?dXMJ}z^_{88T^4_q^@a<*TF$$|*x_3(QnF{ubEyAkMS*%|y*XG&L@lO7i;6+1h zbAgzgCBP(|793m4)Ogl6tn%C@UJyQ}|6kkMa?$zRh1(G^GHCf#_KVL~fRJfw|Jc~d ztOf*bVhyb|p{fbLZ+&4u&|mZ^<{6I=kZ|4M%K8-J=KUF#jO`n=Lh~9H}im_u1;fNHp4{RZ9fkvO)H+yuw59;g%!iZw9VSY&27CJyV^P z$Bf6w&w9C|ABP%7oXRj!(Ye8nz9`28uwikGuS6#w0U|(&SL#r}heFhb85q8s!pDJ?AGm0nmH2Q~fN7E2{oI1m_yt}!= zGl*j?A6vkdT(O;~Kqk#WTfPtbMXASSIo1+kh?cSzu!YdVLAaX$ z5-EJ}iq%4sp}P*>i@}h6#IGf4!;r1frsn(8oTX;d9|^6n$oOb~A2c=;5{#UgGzLO$ zMnZ7Je$A>6&8;pjXU@ayq>wihTAAs=_D|}Z4vXF(X?)dgOa8fCRyug_xSf5ay!1*+ z?XYMgg+@ADMP?Tu(R}b7s=)cp!*U|egoQ5nX|W~@J$i?C2SkA2sX^9V*&Pq(uC+fb zD{a5qXpo3NaN4B)?pQd=jZi@|qDc=2LEwInQ%sN-V2~#gks21NssqaN1oGG9L|5lE znxV^)>T`JO2tNf}WISdMeKue#t+fyAlP|K4W?T(6pMOgGbO`zpb`p@^lK6F}_?w6Q z{S}F?WeYcuXe41Kt%qs&S<)$goo9WJRI@%h#Iw`nBH0Fm*FSBAn6|jN3)`~}txK|w zYsbUF6C*ub;sZl~{~;Sc)Pi)S0p3+Mg?fiGz9jNNgoEI8Ha^p9PLd{c1S1fWP7tZY zZm?S?eXGgG(g?ROFw7faWu`05OSZVceWooqgBNs^o4z%15Z_(o>d@y(1=fC9Jk`Y` ziC2Q=b!bhJk=A~>JjBXjJdhPMr&A>xY2%Z{QDjR{({qHgE&M92C0#-sdIJY!=6{LyGHDLEBLRk>;&Of|n8dSub{k|~o`K*}K% z(B{~Pln5;z*TOJeak(7c8v|=?iQ$ScW{Mo{`!RifMqfsMNq=U)Fu#WUr@|6>SQAPK z-O66#AI;9pDaj$EnKndJM3frTgX5PtoECrj2-v^?IZe%cApy}I?tW1~T6i#;NO$?* zg~BbuZ;5zlGzbu~n<_r>@xv^`XF8Q7I)vg99~lg>f>?o(@%cR8xZu0cV^%Kmg z=Es(zM|Xy-L@PAr$C!OD;;LPa6KlXB*44g;ACL$ z!0@&3GX?_avRU;W$Og`>HC4H^9e7f-_y! z-ihqqr-cr}qECn~G*~oKd&>#+-N2TbmbzX-Ikg+o&>+AqE#Ms(xIxJ09kdZz+SAPk zB|4pn!N+vcJ5%_>ar{l`uO2Eg0^{(SRgd!hB|1%x+2vFer)DrK3sYH{{9*ONA-Sg3 zb{0ks_I9>iVM=-Od19i7f6w0@n_O6#lE|pdC$QS6+N<}U-r~!w(zZW)RM*|r-Pq8< zF~jPzODo5Z!}6=1#m8uunk6S+C`IH&GjUKRF51jC=x4Hhas(wQGmDZ`JgXC;XJl-r zr=xpWFYB@%;o#ykOY;}=UnGCc{A%oD5}sUEl9k%b%q^*J<*6}jD1!xMQ}Tk-=mDp# z4BQ-@4D>I%nVZ@=_$!rPt8m93n0U(X+=H`2(Ql`sU@#~QDg%Sb7^>KuP_f~h;8(rh zM%A8g=Tf=Zyuuo%YJdM(bU5(c|7Ul1?{@)@SyEC*%1=3G@;AVXbBGS7&(L6OHqyFu zl|6Xl-MAu%5aB&xu5bwF-it}HpV^bgzmxu*dmrx5_Bh*a#)}tn$PcKK5})^<6#Hzz z*k=MM&(JftBG*>|<0~J( zdx5<+roxGl-0%v8jEGeKn@i5WI|wZ!;Hl zj&l;*GL3z(m*kjTVWGmmZIjN4`Pzg}3};ca zvMQD--6yr~#=9w^wFw5O4T&0;MqTXISYd@28*M~vF~kuUd{rvw_YK&#RHBF`MUtzI z(e3xg%B4k`8poHA%F(4NLfyeW1LvhkiZ^GjgDx15epn0`&mH@OFZeXfEByO$-1b&k)m>Np;UDMjsQj{O$EOmP;x!PU*{o5hvmUTrmJo@PhT7|edA&dyUu%1EQKtk zE^GoC`54qw;Bo=F-<6hHo4`M>$H%k?A+w1Q`C!W6L)tRrb^t5=#Uf7r`U2OtMpuU0 z2`YWwKg->!eNbsR@6RfUyCeNG3g{itp09c3F)d9$-XFIbUm0o_g08tc`cMy>VKK+WE(b)H*+j9WSmkWZL!pGLyDy zIeKl3Zm(spuKt6Rvc3b67F?jESS-E+%>c5U2}gbFL;x?`1m=R`_4$9NKof)=Qlta( zWWg86d#a26UO7MghjcP5_scW-a+gZuP46dkCGXvb#XarJ8V1*Sy()8x~ znl&}7yIZY?wbe=nbKr)5Wn=8U>kN*bY9!>#y<-C}qk64xvtRRO(W7q-q7G}v%e&<+ z@BIF=BD=l{*XrH$YBx^pHZQWA<$eNs(n(n(mraa8^E_Q8M={~?`=$&!pe+V1&=*Kf z2AqYeNi}WFG696c%lky8oTHSIJUs&09UPBAh(Lsb#=yp$3{zg;2feOA1QFzWXwp=L z&SDU34BL?0<#1 z=t?l6fFDqZLc_?OQ`dg+)32G2X9OoDiJg1s&-oPeOdE>!n4Ntv^9C`DrWC0HL=w;= zy$G3|?0LqZNjZvU27LWE7%?XD3MWu{nutB85FQg>vmhaUeLa+Lb8@i|98< zN|HG9klf{G$Vg`E#+3ATy-$W`GB+CePD%O}z1@-RMn2vlSDVgV_bcyM*N%7iO>b_O zI zBaOESNw(O(ovhnq*|ITiCE#wJS(GuJj2EU*;+aOj2q@6dRG_!*4W?SVG$&%CU&@LBf}zZcn|oYE99^t>b9~0WuV0Mqy)qeHgAr580P#YcgJ>&9j}fNBjEEKretazlWicyO8PF4);=W{lbDK* z0bc)3>X0}pAU-u1Tv-fAMv|U`cWhQGlzcMeI&l>w@&*vFjvwUYcp^uIE=!>RR_ar2 zw56LY9VdQ(f;A+)Dh4BF_T5UAogA8y$j{sU7Jn?bI;pMS-SnSYhkNJ+6VfQQplzeF z8Tw*CzMc=Fi@H)%b|qq;nQ-0^)>MlO$~Nyk zZ@Q5?D2}zLLuHkn&bnmhS&{ebEMn)X!FC-aq_M3u)*9fKq|?!egwr&Tnq<6#Gq|8u za@VKo$xL8OpvNU|Cs~rOa4BNoAegt)TWO&_doktF#NYv~qY4o*l|pJ$hU}iRB%))g zClN}+Ob|Odq##SPZ@X+F6app|gJVH=z8D-u(%k<7*kq`;M{nE!Hn#$KmmNc=A+JpI z@vcV{Swem=eL0@`7XTDPl1-jJtUE1Dok`h*01^}B-SDwJucbK8f5(IYOz*u3r<5_S zTb84>lf`GqI-{IwmF8=tn0YhFLad2PX`j=Yih35v$a^OFoc|5>c_VHLkVAgyX$hJ> z`r+RRy9V-XzP$)}A^uW9Qy!%?QRlS-v9s?xHIUijR9o8TPs}eH)cjf0)G3P*9ZV8C z0wS5TAxG0>ei{;AAF?&hTsv!oIEXjkz&MqH|N0uB%LZ03U85v|rBLN{l;v`U#})GA z3xXJ>5kX5Kvhr;pnStZ|WXjyfyIfy*k8@-ty!4l`hHK-bbcvm#CFx$AC2lVXWYWta zk&}9|_tF#3>%E7Erlaw?wRoik)h1+()JV)cPK>kFjc4cXW)lgu2VDY~E$oVDt7KKhDu=D+BnaIKAh>C}ml z#Pf|vI&&_Irxfq5wy;?QHdV8r;wFhck>-nKy*6gC5*R*)1c;-IdPeHilNWjw8>tmy zW_8u+Y^ozNfSzvaIsg0anYp72Y4t)vSmQ#q?rkgEsMEH5P7l1(U}$&%EsAoWyD*`Z2FKf$<7t7j!LOS zGM@mBL3@an$b^-rOG-xN-%-LPZRKtF@O3z!yS?jlm}nR0;eXRQz*@DSVGlO_J)C4B zjw%n%aQ5PKL=j@T(?ggR zYGh+FVjbh#>+nvTS9=`tZX$^H?2xQLBZmB`LD8h6E0<&QZqujz6(-u7TL4){y4nXD zKe(HTd>uPG8qn6kK8fc`#1~lArCvCAFE%A;s=%wwIi#|b`aG7x(x-}gl0ttD@og0M z2vkEl1EiJs7FsT#ONc`|fqyqsOCE)l%g~#>4*ZALIzZhn%Pf^>R8-MXN?H3|Qk{O= zL783Yr!b)~x$z3>Q1sd$q=uGjv#uolrXN7I2nt8QwgLoR1lWwX`IAGI>q9Zj4jgEzWJq1P?qQP5*if|EIJXFGAPO>tGCLsITd3N!>h=ju(++ywv~Ff61=NDI_{@z5f1NV z_vWwoUiO`i4aVWC%~#^ah{R<#B8JmB`2IV7?n#kG=@}z7lPA`Rd$0Dn7^F5em2wSU zy;D|~WVlv26;7^~XBei{bGOiqT?2Y};WKOAN_p>$7B90v^)0GdM5xKn5_*rbgytI` z;G6N6I#HrSi`QdnD|uCR+vyD9pDO`T0%4#Z!kUZAgeCh=)-goPst>H=E2%l3Y=XIm z)H2};83%@s8%(K>EMW=Y~ZuhHD_-m4Wf${0dBftzyH*;Xo@{ZI% z2_;0)x`7Q*X){7K!!}aud4{@I|F17?b$|ggaBxKE}I+9WY!6GZox_?WKEJ{gP6PPuuVIk(`K~i)ecJEL_lpu z<lMNuC3{me0^uih-wve>Y(0RrC1H4gb4IG`aHCnB;@`2B3s>^HbEF6C;^^GT=5dw3`QL~dk*$09AY ze1_5&Z3RDXj}VPW>d&@@D2t_suo6DRg_o_|J$T7{JgOTVjaX~{)E0%M&23f}qGM)- zJq>Fj9{#hH0zRpNcld_i=&4H|ReZ1C=lA2WvwwXO0N{q=IujxU4gv0 zdyQc9wX;vxylbOTWaC+C$xfnzRH>p1L`588TjeVcoPp#hG)7iY+MIC^HvJ8*T6TFF z&$AB9d(+E7Djvw64S&5LPO{bJHkimRVKOgXouTy!SKo2TQAei;YuIX=DLQ}~GAR{? z6k+Y@HG~Jy8`VA+bE!=$MB24{nNMTNG*3i<4|(9%GD`yPBfq%V_4meTK9`M zCYFP9Ld7ggm2#P2^s@WY&8+o>JGQyqPHwzF$41dTUu8=y9GsU^^jeC-cbB*wEy&X5 zXD@j&0ndP4%mz>7mlDCbxV6uv_5@7(v;6ROr>$h9#}H=(4$;XedOIg&l)C|36rlAa z_UmPH;9ktkqG82UcIvz;)nDyXpOMJGIaE6ky!KyK5Z|T`D7XaPDcbY&j+HU2uF9ve zR66SbC>T{Lg{sz#nL9gnm&+eg=T*RWHf`%J*K3Dv?E$n>QeS5Y5Nx)vgTV?Q6R^lq_0Bw+ zRn&D~Xk}j$#Hq2~qnPo8NF!1sH1n>zw}LS$$5Wr?7$O?3gP|%#XK@Rt;oV-VR&3d^ zcwMM3T2yYZ3dNv(4pL33d?~~mALcl5vcwSwFvMmBQ!w+B0PhcTf`rfA7!hEHfQF?* z?nu?(#!nvDY^zJjM61xWhfn$;&2qt7wQm8~$N+sG-nK$S%xC$D~BU z;w<@~Il(B?+Jp<}3_&5d`5Ihg^Zx>jSRQXK-C^T_fmG#Pc9L9_fZWJ^$P8>#kbM%j zBQ&83M_h_lYUXN!jZc6k+jxwqoW66vVoYB?1E zL!G~$Q>2O&zyXsrOxXU3F7g4Xx5`Rz*y%3d@z}qD8DnNtodsel!%pbpT!CiE#=^K3 zC=d?uFIS=!En3x3+R=PwZ~~j)v;-K3>xF!BrH2*f-3OV3-&i~bv|wbIHhz^*mF;kDBlWj$|?c1oc*Xv;qgNDTtTJDc)5FN z=*mwANTM26{yJ)R?agXI7+Pk#EiiAbkuRo?;?6!h^oW(kIh7nxqO?3JW-;r@*zG;; zs&^5$xJ~(@0WD|<`I(sE_)>tGwiN8>Y>SU&e!)%YCgc}leWR<6qs2VB=?IbhQ4DlL zmr)CfwITkTUpk9A?>{;#Ry94#tdtv2k1^hIRQlF_?HJP~K@2=n8~R%g#5Zavm1#Y5 z;&LKij}TDEya|6pB-43bk(o*2>#8jE-TP@CVl}Z^H#z%a>&**0IsE<$w*Ei7Z_aExet)PmCyfqO zMLTM5tNNGtklCZ{n)Cil(t*-C6C`AcZ>4YU+GXU`8dI5GXNHNge?OiNSC9@pCK)LKW%!+W)}>c za9C2I?yipgIIE%SD^11njK_0_Ok~{xP5z9^!uM`Wuki#))GT9u8`@R$&WF19byU4y z=*d;=WS@@73u{OryHiCo)Sc@nx}0Kc1`z|ihyh;2F$&16fVs@^LV*f8WAIpatfT5p zv`#ntk(NU=^N$=x#8m!_LIKrN)Xb2U)HS^D=;+l-FI71pF|Ppu`D=NvUX@m_$)lCP zb*9<(xVWd&dvKS$@t5+^@T>q;-SE97Jpk2vdhxI9AS2#0sUSTP%q%ON#~cOfa$Fpq zzZ{0YIjUf%ftYeYs2eEZP2TRS#454Rb<$zC%7L_$&dGMtSgqSCB2hj69i8Wi+)QN? zNhG38k{DYk&`cx){6Jr$ODhX3eH7JFuEX$6L>{xJrP8qsTlYPtWSBvHk=gr#bqgk) z{{OV|$BZh2_h#3PlR4H$?7_Za!i?C3QbgYaykG21@2}%rSuO837;K7#O;Qm8>fZqa z>Ype)L^X;89-44jfU6*PbC!ENJR{zXJBZquR+q24q=vQu@UcH}%mMg%BLDX5xW5xL z%iSX201O~tyT_ghaNw%w`xl63Inj8zXRne?8vng|K-=Na-D;K9Tgz&Vxnoj6{gjg& zdF_Pac9ub3NTbSyrh#U&BWmjEdNA%xUj*!i6i5X-Xormu0`u?a?0is?UdF`{P}$nb zTuDD8XtPi_9BI^VyM~=*!`-f`TKepKjYU?DLq(dIqgBXmkZKaT()?pryHRB6V5TqK zIrUag4G6C>R>M-&P@%D@aUCRZs>>AXyx69#p$9N(+GstVNAE;xD>zl6IrTqPWhuEf zNGn$Cv!?3#SDB>h)SO>Bwyp9v9~phbu3l(e+h;`|v#J*99f$Re z8P`U(Rl9mtyB&JxdT!$o*MxZ}WBsbwoA+Xl%d z7kf_W8w6}0*%~)PM~A9}nk}OmZ0e5+}I;)#_ytlbF>&zADw;7E~ zvg>4i#S-Mr%e2yOi+MZ?vv(tlHy4q~@s?wurIzeLi!@JWEQ|Y>oVLVl8BMWup+yQd=hkNa&V~c$ zMm~0s`GncgP`$s~d=eJn>av(OGXIsVR&vsDo`pjeDX0!|%xyD^^ue!SQr>)pisH+x zjb#ZJl~$o_uWvfU^i5!@FYIQTz9W(SIC`YSQl!oX>e(Glz{SmVc%QC!V)0jTG};P} zyu7W5FH-6?T};(P*q=jJO;O|pxAe1C7p4Be$r3$L*W5YWNg!JE73~dpqA$HokiF(+ zY`8-xU(7piDGhbe6kQz+Ca>i2d8ZhYfBG{nB}aJi*4#rF@^AzHjGbb{l literal 0 HcmV?d00001 diff --git a/static/fonts/roboto-500.woff2 b/static/fonts/roboto-500.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..5722705e1f94a6d04d1099c11d851ce3b489b2cc GIT binary patch literal 22632 zcmV)LK)JtnPew8T0RR9109a@M5&!@I0M$qU09XP50RR9100000000000000000000 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 b@7Tour6;hWTC%6y1oTL{NL|!LMgaf-Vi?-~ literal 0 HcmV?d00001 diff --git a/static/fonts/roboto-700.woff2 b/static/fonts/roboto-700.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..f48dacf2c50d3f36609564941321ce1f4b3194fa GIT binary patch literal 22404 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 HC;$Ke)Kx6Z literal 0 HcmV?d00001 diff --git a/static/img/chats-and-chat-cap.jpg b/static/img/chats-and-chat-cap.jpg new file mode 100644 index 0000000000000000000000000000000000000000..92b8376f2b52b75e4c7701803c0c4fe5f4e03365 GIT binary patch literal 164062 zcmeEv3p|wV+V3NW2{9yum`b6 zF%Fd+a?FS^qm%PYNl%QK{q%n8_pSZyz1Fu@?|R?8*V;S%m>;9ZbKm!M{9pg;dPJ{9 zBY?ubJ+^xQu_a=_Ug#en8U%I$V*ljF_lx|Kmk<*ZJp~k(N^FBgh>Ix#OBBV#6~#o2 z00IESB>&^uz@I43Ykr0=Zl#qaaI~;l+kWiFdzGjP+ zl+q!0*xG;*?i<^SKxpbSan+5*ig96B`$wkeHT!{YFOSpKfN|&Mzn| zD!y~~-lOsgT4mMaC)Ewi#-`?$XU|`Bb@%l4^}ilqak!&z-@X6vacrFb>GSNDxv${2 z`S0rz1H}Jx%l>0w|I50dO%PimAt5dS`@Sx*CBe|AxT1vQnk`bxtq#H51C-Woy}WeA z&TF^I>ZP@f4)c^xUw9>>vd);Zp8tJmzpm^bTUg|8TG@Xt>@VwL0n5b2pu-ba1TcW` zksgq@Bti!GysO@j4PCdlYy14h zB@XW_RoT{k9)loeMmmCzc zlmu1)KVN>+79dXiK^uqA?fms%#NL1o4e(M*RK_J0=fIt^8Ylcb0J*Z&hhMkLRl-~w zuf$rcw0j)c5~L^H@xH54Mc#IdC*Y)|%V9G?3QE+4mX8)56jEgQezn*Sm>U#W?e}J1(vIcP?Sa`W{u? zc)xLFuGuNL-5=to|K(lZkK7=-Vlfk~M$qP(33M^Mo8FW`#A^}2yCMQSML=V#W4Ewv z@s&tIYrV>1VmHzvAe_j zFvAPV?HvNL{|;~QkH6~ak_a^&wxPWUxaffw0l~PT{*;?}@auP$)Ur<6`d-v5Xc!)w zdT)mtP_d5Wms(T7Q8E+P_J(cgrL z!z?9j7j`fd>(FE53U*|j9+++2DG1^sm0bna`~%gwYm%6CYii>fDGKg;wwuRnD2alRf3OYp0HA* zhge1TQcdtDsS%BOkjA61B$EeSl`JGjV|R^$>Q*3Ybo z6_-$u#9g2Br9Hzh$klwtrPq(R=AIQN%t2m_Xi?1azMAB8?#uST4vT}nHCN%!99EFp zgiFEfg-zsoUlD*~D1mX@RDr?FK)+B%f58VUkm)xjCm|G#<&d09#Usi1r$X)26TFs~ zS?ux?1e{4upigVQ&wQycJ)D$NIw?Nm@(5VY z*WhFdls<4$n^M&$*cFJWTU^RO(g-ZV1dbrsnv9WFgW4Q6lPd3{r4Q!t(HHNw>C|%Z zv_ahbIb{CF!_V;-y>8q4h;c;#fWgh+iih7hyEbgun zZxML$Fw9}K#mgdK3JL{wtJwHpeylR&pLHZ&B>bKIc3Dy0Rx(nuP$nO+$7|C@z&@1}R zeL*DFE$<6LDt>e`eKpHa1GDXT{!~0y&cm7~EPdccZcz2&EZBRT=&5*24KnZ?JV<}? zr048Sn*Kw0&7Gg=++WSX7MOE7A|UIg2)N)SoC*~C8uL8~g1u!-nTUY(jAr&%0}(K; zop%rx^=lv=?*0dby+q3Q3yTFGpogP{UGr$?KJJFf*0(H%=WLiLzAs^#(6$A$yPP>zp1W85+L2KXo*Gblv!i z=^YYV@aX~Hc5U3SJxD_QgAbr5{-GnD@(4Rg;|DjZP!#GmlG+jC=yinYCIfCIKQ)E4 z0@P@7)7e|9ov6PJ>(V!CF|>zpEVW)@08+_!A-kXM}(3}d2G&bEtet=emKcf zjr>B@AZ~F`XyNrYt5?NT?67IVz&-evGUemAj|Fh9Y^xd#FI}84>k<}@Xw=Vh9h)e{ zo!?bFzVm(8x){ste%Lt@2&cXl?Cmz`h@?mdC0mTHA4-M{!JvTyrz0BaN7{fLJKuya zWDBe#M{UwD>TKNAUCYdaJ|w6feo~gQGOh1K#yT0XT^!0}?}E8Nwa0*#8jTSX$`g@& zekdce$Wj_L4l?X04UVP{5_ZxzmFt@-V_25=vClkHpq&n;*`lmWs)n5!w!y8Io&x{f!tY8(tXa90?9S;UX0YHC#rF66b4lIuolz zcjEGW>NfE)jXR_RFBgK{jc&Rw8f&-)zKt2x8HJ^?7KiShe3L||1TF{-7H>dt5f1Nnpr}i3`<-n}}6lIA_$Iw6Rdn zo9k&Ql#S~uGkDJupNe}h8RadIwdY9JX`CcDjCj?vWjlDD2xS)mg2H4hqbuLG=M}MA zd@tmhMR6*!{1eUzCF7cH!w9(>lNzQ9i{p<^zY7YYE4^3+R4?XYycTAb5qI*eXP$OM zRpl-NtGG36O~G+qaz7I(d6MA4#iy7U>|{Fj5YO^uEwgur>o@1>GkOC{kwA^tAWw!zZ2^kv5QCBFckX5TFg2b3w2KG~*wmYs(B0jtSQgO?c#_x4d_^ zM^((%Wlg7s>)brG?^c+sX>1#7+rWrt%GNxs)wY)<7G)7Q((R{|$TE2ST*m)Lu)F)J3O2?5opZLx1L?Hn-Q zEmZe~Vsm-+H$M=H&9AS3Vsm@q_t<<;1Q;-&*gP@<4&tbhh*=BryDILC@Zdq%htw8~ zk~e7!SjyRIQM)z#07pR@Z)l>qPg;jaYkhQOcKl-CV|z`8tI!xWrgLrb|Eq!U^v3_lMw+|IwjSCZ|MK1Y{-9T zAR*ItuYEC#VtG7quX>-+Hkd)UtQ}~`Hh%clJ;_eB-E}=MS7WfV<#4ovN08jh-Qv}{ z5)bz5d=|HSxA5-T{FHIMCGUXKKEgF!6(Us-ulU zc|Mo8oi}rN8s)`3LD%&gwP-cvJI0|l81!X^-1RZ{tD|tdO~$&&%7mD=UDS2y_K#AA zyN1-8Es_uDC-uYtTZrKc`%e%o8bfE|W;s@Yq}Q9F zCCkA$WMU9p74)dD%yd>>%pN~@0`zG;`NTXmUa-gbo!yhbJ5%>h?FuetJ-GcfGr>Pk zHFGXfRcKnxYl#ym-t}Rrq;udB#GMfC;ct>-VcS)Klq58>9c#>Qw8iw`@0}b!u99`c z)jEH`rDMH7mgxNch3_`^I-sKyf>6qvSnKO5DAFi*4q1lK(xA1PuX>pnu>SqE`;Awf zy))I@lY_ZK+73qc9Lav;FDYNG(>}TG>3Sa=AObqGc3^-99Pyh_7uqryl&v zH9gqtp1*&fq)@P5XoFM{0k7Mr-3>WE&=tBMwE z;aa4|la~dO6XtJb*UxY1G-j^=Lq))$-r1lofff3CMyHSBxJuS=a`;7Ge3)rYomt{} z8T9tW>kkADCE)GPw*1W4O;dC)-rycE;GQd($+?uu#VdjrI(Bu^45aZSt#K9eme>k1 ztf_PtdDVR1H4o0`(}sQ-qqf4ASDnM7#e0YvJo8qjc}v2~7lU)Y^TCOADgtv5OD?Fq z&bqLe^fU_}AJ|$lS7U#8>WweY_mk&y_n3-Tcp9F%zn%ls^MdQK@pY@py6C!hiDxs9 zgJB#8S)aP)ysEeF zj_u7E?Ocm^rbkZUs90IMQ6jKl$Q*Tu@Go`GojFRee;jzkAg4L!ZpXUiev;kokIKL2 zI?I*&EKkTaDOq?gVG9fq5Hzrb{7(BjGH@0`1|E~XBLhtk;7B~OiN#g&{<`ZM|@sF{-KfTiLDW>1O(yDvyFXHb{Pbw=~d3t)p z96OZuvM~aXNISnh4}Rt$s66UBc*6f|rgeAL8Tg#tLTg!&g8Nk+7kl*dI^wD8pObEV zJE3@V;` zmWY5CJ^+SeNoW;DlGH@N(>6!QZ}mW?D1x84C?PNs0hhC=B4EQEKm^2yjUwlzK`#*? zZh{pa`R>PL#GA3RO1uuCln+Bt1o3fJz^*Vp>T)Q8WxeEY_K;`$c~3w0>0eTw#11cv zI3}Mf^?Z`zr*zQ!5M?sMEHgPs@8F61`a#9cjWd^Hc5N+BQx@OS1Q1#`96omW_~BzW zE=%s+wmRzBYM#|wbqFf_ai6s$rTFgHyeTE5#HZ@~2^=e&UKL!GX{a4LJgkgdm$qdR z;8<>&+_|=V^I@^ia{W_ryhp>_6YkwaT=**gXPK9(52R&$zLzFZW-!O_x}^B@&F!!g zXMkjW$r(TfV$%&^mXSY7j&=x?K{7;qNQ9L85osk9kIJ@CKz*JFQe%@9P$lk+U<+gz zR8uiLM~(;(`shJ##6AZ-M1Unyi#$SQiU2{+cgdAY=d}nU+)xm61q&6{zuke9Ttk>^rX~)Wb7Mid=Vv75kWW4m-I%9ppTze4KnX)_X9D z_UdxISmyM@WlI57?;iym1RZ(une~Yp%~~sti`}5x-O|?wc8T9}j$DdTu#wPOng{Q! z{!O6$->xo-f9`1BcXt%7d>gozyRQG((euiVN2>v`*8s%MZR>=M{Ynu2kz+Funa}p672MC&@4VJ?)r$4;Ws3RMvcpT)L5$>{@){&kp2YmNq*=| z#70CwMZe%0T!Z|kN(9`!blDP-Hv9Jr=Kpok|DNBGDo8IGpLU~^pnfG?VIgY~2y6OL z$w%Cr73(JGL)-yr^6R!d5ir)*7lGM%=ev2?I6Tb4RhF}{Z>(`RKMlJbjnmqRdOa7M zQZK$bdiG}gG0Av{0Pmno3|sn%Mc7ln{+JUBCq^`=mAl_+rw&x%$ zg)Ok-58r;-O~^hH7oh7GT~c%}>gh2R>2v2{;_GtXW;|c5>_;b$hS|VX6KQ>?teV>M zFA{EQl?|i#*TxI?<#Ho-=rb8wM5{CWCa#8^pHF|pSB14Fd^TtnN}5Rz8}^*M&CHXYYK_zJ)L{pw?0@q$d#M-Shut&V`&XpAa;DTq)>7}_%qu>VsM{$+Fo zQHm%>LK-X~0^U6TuEGpUE&h*L0jSO7eK-&}452dDS{tx)M&6kDAR6S-?g4sBwx3N| zT9D;+;#RC#hSRE;y`#x?H8onwhpaqxBgAwf&}+aOe5sjc=Yp%wt((wVkFGzU;L;-B zb?XJm79dEt3(brciNFYZMSxZyd%$bXZSgh(7ml@g%-70UzzE=AF+XF1nUOB*OI6fm z;w2_XNGyENb*rsrVRMzv)vS|d7dJ%q+0h<9)?apEGaw8kd(FI_5z2Hd92GWWrO6|= zs}Ta_sL|qBvL8MLyG(#sa3F48q_`*5v&<$XJ@UYr-4FR9fQgOF)dOw)IIfPz(rtR^ z8h6LkRTBhWrsa3WD;-%eZBu=jrQ_zl<5}@A96x{V0|ZUQ5TQD3V)fftq>3?tU!ocyR&I3M{?I*XK^MbZ*=N9hlXsaWrzA zGdvkNn`6_+0(*&SoR6rjUs;0WGh%ab4OCG7YXaFD`5NEApqWj6U4W5ZkyY!ACq#fI z%6h?s5H)xBRS;(Bm^!0@okUvJ8?-~W*%6^E-0a(R0)+Y)Wds%`F_b}}_IRa_--xErr@@7W&WXsh>T`cfn$WH~XBpxanH*3?JrmSKG zegrTVpc(*$yi#aJBrT@Yi4k2FZ=+YX@$$J<$wEznmvjH@2DjRqql*uxsBiqKa@FwO@R6sVPHQmzwtN*E?hlAWgQ0q6StJ;iBWRznk zhd69Fm_DjHh2+AoV5HF!pvRGl-pRm4?6Ig3STuU=o2rC5v@79=eNAmuzei_tM1Et| zj^WFv`(qcZ7=6Gt5dhsD&zY)FHKjO`I#4yYdod2ZQTTdz8wk})B!plPbS^N^vrZk% z8G*;x-6a}>G2ELK+2IyVGyEk(#thi5VsBsf3nt!QC<;E+j4J|L4t@#FZTaKy!yg*e zy_ZO)B%Z;l5$M`u)4scw0FBI#lnk+=I(Va}gw9#_!J95>z82)G#J zhksuk(y!1`Z4C&_A3?fO{%eyc1JuJ`!Fb~b9Bp{2(2krz#v{rdnT%Mh7=1n8v!fa6 zVZA&GXLU5N<@|-R1li`g9Z|be>*tYIOb{!Hj=bPFfmhJT1V)A6Qr{5nZ?AiTKNK6I zQdJ6ssa|H_sVo>LIF;dzjKoxCPJSz36Wu|p1v5hM++&_j<^udVA2!MqoCEFeg2iq; z)g+Ym2-Hbe(m;~qUuP@Vts)HCbj{YZt=~WAwxvtp!CA!bb5%awvuQ0*49VCLXdO8| zUl;fu|i%2hWl|ZP= zOhN!|KSTB+$BF=TJpJNA5HXN%R-cVf@MS2~Z6rE@7jF@CpW0YH?D6QMZkiG*`>4OK z{M;miQwh#UAAVyk`R?v1IExH-xcBCxx@LPd%fdHU9eor1XjtpTmPjU1SKw z4V|TB${dC571AcJ4;LVYU(98E68}V3+Mj&&bsjwBFEj*rC@9C>zKOQLkhfd2U|5b{ z-}Fdpr;q8Do3;n{%IK82q#8#!Wevaakl72&vm#I*Mqv#MDPj<4$H$CN8vV9I&R7Jf z3bnviPF#v{MPQ=+t_C+0Z#tiYS9EIHbZ!6Dwtxbk%z#}+yYym@+Y&1WDk8|+(Xxw? z6E<)82epBy2cEkGykCIN<+po!(kr;O6*^bF74mSFdP#+qip^uDZjNHLi z=uXi_DFallSt{DZn^K-RrNN8iw%_X?mg6CtkV*tc&J;Cqis(KPx78=WdpT&-q$Qqt zf_|0lqds)w_TX?t5L<#g63wX4O5zy_Wq0uMoBP>i{ZC6Azzx`lI!PQtLZGy;$$QwS z0(5{F1fa_ZLUpW)w6c%B;T}P@ekWYMp6lmp)7_Cs+%{iVHtKtZ4{y|TVGgVJe{ttn ziY>G*ECCU7=^%DNo2UpnEu0vG?Aj#Bh-k?3yulkhnm(c$PseewvGde8l&qg>EK0TX z#4xzPbW`PPR+il(xa{wmrdzw4ME70wMTV@8dBL*ROuh=^A|Vqsl1QPUA*(L2X7MI@ zB=aj84T|Zuu%i%K#_&WfJw8!u1DME$&CJRn=bHIdQ?dbGdA^^B83k}4(eOF_kn&LaxZ>C$X6XSjF189TP{^LETP#HHAlL5}VDWjRrxdMCjC0|esZS{^ z{khU!lF>L67kEbBgx3bc(p0FWcbUcaw{hWrl@~ zx=g{ELQ7L999>{>*T++P za=!oT*-%3 zX<^yt;mN{PAU{)Y?0Z-fkh4Be>J4i3xwt~eM zp$6~0P&GPk))i4-w~;A9BUVcx)k@R!<~bLH%Z-8 z_a4?L%k|v>Kj7lGmF2XCX0uxB+JBSF!MOcUtz5^k36Y$M;T?4v0b@oGOR>U!>mv2C<72%kiTojcv*hg#2-3!VPVnJW%H zpXuyhJyB#S_GAPzfSluj`TXor%9InI&2_9t4jh?_;hRksa@YgfbK&HH#0kg60%&AP zCKO~#mGCWE7%K&Kx-HZgs2FdIRVUOmxfzn>2MO4ERT7LW2Oen{)=bpI9_R0&mauI- z#YWk@gBVb|xCzS&?U;MSpQ)z~I&xd0>kNfG=%t|Ah#a}zZ9BC2lVbrqHwPJ_Qm+7W z$6KgS!MFc9S;N;Itzynd<~So)673*q^m>Xmp>@&ViEbNug8ZD@xh;q2$(B22<{m8O zhyXlQ0Y}=%L)6kLhKvz zzmcUML=OLD@Q=TO+Q24kCR@M5LG_rgTgl_D)J_=vhmp~56iZFBNXFX>yiADb4j1P5 zd5h0(gkqC#`g4&_F7Zv1JZ(RXbY{HULpu01G-mRE?l6lelx(m2BGJxQS?~G;WPw_!R|;rIR6^> zHvSihnTAGZpz}u=%Nmkup7-Q4E?BKOV(-Y|d@OtJ~m%@g7#NJX6CT%WE zj0D<{kYvT6*!9g~;?P@q19SHE+#>Nl5>b{~W_+c& z>`YG3bPnz=E?1_M(_ z4nht%#yA9JQ8F~Xehsf9iPom_!7g{ZK%Y~wAfH%y{E{>JVcW&KgxJ@1cgFk74f-~{ z5s$#K?6}Hp(|-ztTtTR2a}w7f34(HvoSc0hxOM|?-hhmTtklF?6+I@&J5Z{Z0;#g> zG2!x_57o7_$Gu;|>}o=$IIj%3=Hbn^#h@5@>U7|cDl>ys97jZOs9L^m#^8;S72wsUGAY`BbhnNzb&l$ZDM;vqUFhB%`O|^|Tz*TEVm`>BG}52MOB^Lz|LTt^-1_ zu?(NDy)?#(kC|v?UOO%1wgAcZYHTy_=HMHBu?fK!tD+6>mr@0aCA7@Aic-^#rq7!D zTAn5C=^^eaQp*hss!M+n>yjrQ)<~(yObw!5#wZF`6V$so*FzaGv$e28mA$C#d>y2^ z(^$ZGxxH3lvCsUm{>b}5e#oZzRadQ7Wa(7p4UVbD)PAh4=qE1NWp9f>_jj%9E$o{8 zW-?)K&U6mjt8uiv%S1NE#jdhW58W+KxjT%@G8p=D+wQT|#ejmb&-?y_Ggx!_DB#`s zcipapP^ zJtp>$b8V<5CmG|*pBK4~^#|u_QJT#!W#U5ov$6;mTAI##uU)VRoPC7bQ~*ps>CSs5 zXK^N3w=1YN^s_y`IFaU{hK{;tTWDY8t^S@79&(Qm>ni2qs?%}YB^-aGHf{d>;PIX> z-cyCUUCkypSG;;D*6t*b>D?4 zbCqOYzAtx}a4bs z9n+Y*OwEa@-cMJmcT9G3a_kziydogDTb;NIO0Jj_SQsu>yqBn4JkByKyah%vS%)5f zB6XqcIg6nS*1gk*$GwB(E;cyUY4uP~sqovjo0^BQ0Gkrw%es}lc)_lBgpL-LO^o0W zmmx=(aN_N`5yC0#oEErnY*EJZo<;LeLKrh6II_MBD}!4C6?z(%j~Q&j_(XOMzqfGm zi$IaNHczqYV16TM&G%G05TW4hwt{cg*db4te*X!Xkaetuc_x?Ls4maoIw%bj3}!8m zD=Et3Hv1R@oX2=P3gU4~OXb7kvu1}~?so#=vWR+p3yhN6ggG*`ZY|-WWiRn0G59_x zYt>tkY{qmhPV~&uFWvdc7Ysy#`%CYel)R3atIc~&xYxh4&+zS&u(lmtb8{9E@)QVo zmZh8U#gFo)?{cM0wi3*QX~ZP3+S-$OGcKSL=ebU=U`O6_4g)p;zl93;*iA5N z5UM?)_08sUCd56sh#fTBU!Khu%wJAybc)!+D7T5B&O+FUiV(@iCkycRi8j2V?2#Pb zCi9_|*uce0-OMcGDo5vI4}L)za8lu8av`|zV4Yh!CHKahi*AJnmX!*=nkLQd6q|9@ zp#&9-sr%myyYGWuQ&UzR**AK!xBEcqk>0bhn^VJyS=OEtIV<*#I@f72`f(WDf#8(6}-{m$Q?XwOMHVnQFBHgVlJ1k1)FhciCC zPzG8h==3>$Y=)YdojTpH^_x zFGVl^;GINs9&BCO%L^~};n+3RorIKJKB!7{6=_=4sxvCp~Gg+0WBuRidTb2{offaX=XruyESDPNT;}&)8nS zAuE|0D?o5MR43+gH-HIVBh(e+w%lYHq!Ml(5h1_?mHK94465_SDlY>C%dcaz@x3PTYmdBIcS7rE?2=MLt~BvNL~HXpK( zb!yoMdQfD^%*LK5%M>09tPoiARLG&QpdB{tS!GUG9+-NfHu1&h13mtmtfBJdQ}Ogy z3}201T)QdNCUa!8!IYn14IkFLNhkr{C>HGQoz=(39c&7}htt|z(H&?f2jAC+3~UL@ z-WEt!B1CSRF8%PZ##;^DX=$`CGe>zM^{|6a6co zDarbl-6-n-_xmR>v4PsE@og!EtI`Js?8A$u&Z=aUzT~^QG(a6Z(b$T2)JBG?_wb6E zE&&3EOeC7zBNSU@{+c_Wf`f~gh0lxBj1jBG=H}&7h(=tsO|&&(GR|)%LXQ@8A1q5f zVs`wjC*bPAeZYWNZ1ISSP2F#B)w$P3resI%SIcK|Q&m0+rFoUf0o-W*N%Q9XJ7A`x z?V7IpCkLH}*mTqCqFVuT+e#~jwoXr<;GB{tkorP+hBU4T=hOA_W!Svd?Q*xSiqqQ`avl@pU2#_xX)JIUBYGYd3y+jAC;`~(Eu?%fXick@uV0GIkgEjfJe}gaX z;+>E4*uj|E$5P}7hHt4^bLeowDPxS>NoPWbC0~azvH*t>Ei3q$DQmS5uMAPPQc0ua zrS-SQt`R&=_RZ?sl_Xh&Y2q7AD?@)l-og$wg`N(HFd#V2<=66I5h%Y=&d7}XgaYW; za9p@SON)nS)Dt*zlQc?hx|#7P$pVW2P7d6Smr`4Fd$Hv3V|#t)u8clS>#1qaj3)PL zV7MFOZD4Z{#B&j=nC`sXg$3;sUB)G@SX*%DmL2cCH|=OSjv7Q&^$FFwQ9|$!m!8g* zbJ>F|hO(M6D- zgOF@=e@j+X5{LhgcZY$OEsmWrcweQ@G3_g@h0Bj=2u*Du6Q-}%8FAn<#Hr* zVeLT0g2vQwUsq#smT(!-@ex?d3Aa00RoPvNG)5>vQ(pQ`zcP7EKg9WFvcphczbu#o zW!}uQMGt8Cus4 zyzl5Ks=o;V;!`nJHuGIrJ-jM;G0tY3oLySZHQOZ&r zLjk46rHcC+v0ZRzBs4snQ@d|;f5x!p9$8J#W?$L6=RB(`Ybz6{w|QNKj%&#hQJwk^+MV!-VR&Y3RudDOfeZ+DZ_4&w$qV%e8uruM^Q>Q}Emp*NvV@SOaeD z?j60%AzYLDBiX_YDHkt@wYM!`aF@O=!OIdY!PJqXb-eyq;s)*=`i8q8sn0}vb zC;9d;o6RQp9_*RjLDJmd=#cKlJ3A8_q-JnfVtGEx>AAm{R})(-kfJ_u`twPCN23L0 znQbZP(dbBl`r)fE`!+g?ZiA?99(!Np;4r9fbN+|8cbCaI+ z(=*AhC4w=4vHg*z`QQY)^{7L<*2eBYjKTz3pEnalw=Th{&g;f~8M*)^BL}K8?R)!o zMzzQlIS-6GUK?|k{F+2HcHR6!vNWv;?hX|K zCt`4B&S1aj8!;m#5&>Zf_`$(p~QE1zx%X5{>|RvVd0M)N4MCG7-aFnZ)FgobcicuM3$w$HCP+HYe*@dpwoEkr) z{dK-WzD zyISj7b@z+pQUNB<+Xze%_Q~ppSr~XVebrjsJ7s{HjpVPdp=XVVYcyj4l>VrJOOw`W z%1Qq5R4SN$7{ouYx`$JB-bR+6pvZjaH6$9`{a9I@l5odq-;@sZQgvxjja0dNm}2s2 z8tv?`<;K@U@wk2Ed|4bt8LdA+$Zj0o+KmdnM`&j|^61WO%{4^?&(?;!_=`nM&PuxO z9WZpl;b9fTAq}O*AuFz3x@PMondOY*4@4L_EaspL3dZW>qU`u)R{|F=*5_jQu*Ph% z%Ag(Ra_NNDI)0#fEd}CLRGxdwqvxvnVO+bv)C{40cbG9*-eokE);u7(2NP8!t%T)%<^<|B-_6@)J19_^!0PwT|CMw6y&aOSUO}CRyfu)2 zHUnOQt&2H9+XP6iG~M+snAzaAwTHBIf~-Q&?j^R=4lTL`*Z*K4*PJPf>MWye~IRl+a;A^Q8r>Q+zH8z@|NYb8gbVkIRkeB-e zXEoQHJwJ@B?lWFkkPaLowQK6I?JIdxQEsKv$($Lvfsg9PZ-jYxn9v??!DNYf?dHif zCnKZZWwx*tOgcbocmDpZHl@C%N-f-2zR6^8fCIO&qU&7xk!lBdsnr}|;@;DjFq$-mEG`Awq~e*}ks$O1ph0zY~(|FyLJdzA&`I+nRv6%#U< zteEa^m-@`#r-z&eb=fx9J!(CM64O6~?la$Ri8KM8Mm7&=eOFXdaVXoeo6hn=26k&yPYQ zntY*gOd3Rch&MRp2$}xxBbuW7p?OTEV73T=v8d1!ZoW@&k)}c;nf&->LO2a8+y{*x zQNluFq6WEm0RkG@bOV~*^7EE{?$W=QEQuZe+$db%b1KYrSEKp6FBN}c<3mcYZ=QnN zH8@$E(Q^t*U;F|+#zP)5zdwmtKjedcA7a*j^~%53cfVn_;7`Z(PdhGCl!d!|30F>b z|Km-odxDa;He85XwuW9CIlQy@%4S;)m^N&M*u0v1@$0cm4_}Y6hSnprtd@hc*iT&?_3fq8+D_U*r;hTN zu|Up)$AOrwn@`CBBmx-OV4&~TH~U!D*xa9b_r%Wj3scHDlYRV*ZEB~lMYf3Rq7F(~ z13!zVKa#Bc(M8kWvEk|`!v61ouy4mJ61tgg%KImr3sgRD%}9B%qhGb_%JLe6)$ola z*Jz$MJR-I*_vJ%;K~0D#DxKf>(wGe&H@hb-He)z7%X>;zIFWv6wNm#si}QP78-b03 zq|Ui>BW?ue_e(!*?PFCq`l~*XHi*ee|A=}Dho1Bp>KI4bNHA)|Yu45k1TGA0Ufz1# z`q7Pnc$sT2-Rw3Lcv>9Sdysn^6C?+O8vIRs<{#bKpSk@%izEGBx&7au{H+ih!LAVM z*TrlSYVZc{_U@eQ2{P0)W^XZ?3p@7CO`tE8cKn5Nz)G9P26Lz2*NY$Lj^q6OJu|r6 zV4O~Fh?Y~~wRWes*IF%VwCuL5%Popn^DC6`6`KF9il5yuHA`0PSU(p%dCewdLkQkD z@BF=bq1WR_2T-q9qF(8?o!jeB{zB}_+Y2_v0j)~+ukA}(cR?Fws~xl~hoZoQkZz6)h*D@vLAJf8}8!Ji8A5jAdc{1@j*k*;~JX!)}6Dy8@?F09PgR& zS6f})Jv%7to76gZcW6yjWvp$%+1;lBOb!{0*Jy$og$Eg|4-HtJ9h(I`%#UZk!|XWS zJZ|b91Qs$&k;gFb3fJTIh(^lF3dX>LPy9N)aqP0dkkT0wZLaB)@@5~(K~Sv`c-J_n`+a}rv2MCk@x**e8P3-r=B+xeyYI`_P8d6wtbtwzQSp~KjzYO` zQ%9^RRtjqy=jM=}qK!^oFrCBISN$iM-u~LPoh%_N8AQ3`>^ddxY3R4iGB2Ah|hmZiFOhu#< z4MLiQ78p?oLkRJVx%NKm-o5W$Ywy+WbI$Y3e^3xG8RH%A`)l9N7coZC^dqbn*rn#I zUfc!xBb42zdqKGC&E`TZC`TmV*aW6b^8uo(}hhQRi+QZU) zz&ub_%%cmJVx7XvGm9n{;W}dv-|m71;Sa7nhnzt%v4riw;vK4?2oDinyE?~BTrh2r z|7e^5-7+pKKqn1wXI%D=>;B#lG9R;a8p((dx^HuLtZq>DxPL9KVAHl$ScJHrST)y{ z>fqcj-VP~lEdhoz^!>3jqKFDVPZR_?AWQqZ8QiHsC?4V1qB^shNr^Q*R@06^&SG+5 z4Bd&axj9)!_iMY#k-S5=rMpSj_RE?=LdnP>3WkG7XbkJZ#Dpi1s2g!Xj80EUz&5je zZuJnA0^&rrg3NZ>8qljt*L2x?^t~Ig&6Hz{b*p47K(p_d zPN5U)gHWe7`)I7#mIe}cDm_rwL0rdT%>$PLxG=I zZ;(?@13JsX3XkODGTw~LP9JO@+F0F?zEOe9o8uz@Q=uEMfv7_B#U|^jfcEU|5NiTj zwWGM~PK_^}ZF3#S?Gy_nqR%MyMsM)#7yg;D8|$iTqWumldU*V{rMjjecOzVH=qcN& z-3KGH4#I)v2Kl75UpF&X=T7_mxX`v)?{-w5bZdII-hjQ?y8#D7%B$aITtB5BHJY8d z>6(*t_3}-7y*|nR9Vtjo&D}v7r~ibZn}D*JGQFiUkyVa9`@9M$DH}$9OxM2qa_ntH z64GO!vp#JNOmboe?1zJJ7Bt|Jm}iB0D-}c^(rQn7A+DE4p6L;Ea|~i=oGw z;GDuF{Pt%BPp!LG*%kCcm>}WO1ADU@EAj56U2Q>T5~45S*C@b)_Q6ni20GQSqO~jc zshdQ5z%oc4x<+Z`F+mEH6gm#k*pE{I5;v6GK~BPGinVZICqak8iCbCEG4eGPYwS3z zWXo_H-R+HnZDfylx+7z@?8;!xoMMM=YB4O#?Q4r^9HNFS+He*KII>cKf{wSi@PSDp zfF;FHx3CDkKVgbSHnxJ87K9v9-(lGg(g!s6T_T+aW^*{0^{?3u2u-lCZRuzoBt@Dz zk!`-R<@mtdlR^DTmMAj)dLj!jn2Uv@dF~PY6#+|#SQ|^8$4$hl3m2w5A;E#)19a0+ zA#4M!4U?dy(MkKDB38HyB;1)N#Ssznw(t`xzlitXA=7JCm4j#lxZlPD)kaQaeyI^) zh2fyYZ6Z&TB8`pYj9NGG5nWljg%Rbr<+hAkv5i(wPhlbtCb?`3UG#(CsL&UZrHNEB zg;0Dm^Ms|)OJ5D1<~V9QkvN6%#x^?7=mPYC{?ZUqiv5cTbtW=KPuGZ;sGc<=)~8Vi z&n#XT`jY9H{`GXq*_hLfF!2tts`w47ssaKpe1N~-BBTL}t-T3Lmi!a6I_W6NQF66@ zHYaDtAWtr=k;q>W$Z{UW{en^C)M8XSILnB&zFFt<3*+;KHTKsI89f`}3_ft(joB*= zmE2pssHUPVV5T5jENjOmE8#6x;!!@mDG+QSK7rG-5szKTq8bzWQFU{Cj{->0e7?L8 z8d3yRc&QPcOIZ5c9hB@mU;AKP=1Bqc*}8y3El?afgxo85d>xwRvwR~V#Lh$l2zDq7)?77m$5O_Fimr%D z#bA;d8UePA4>}DQ&tlD%b8bzadzmqMK8?8qgTKXosA7k;vSf&@YAALrvBoC>xgJCu zT`4fffX0|sN6E9`q8F#x1d$R>iZ3PlVn|}0SJ3fJI?^E6%8HqpC&ECB0Y=-NDae@l zBN%+5A;rO=-bM%;T6rPb{?t|62N8!{N%4p}=Pvk%vusFiorpw-^A2Pm7ofhFMQwgI1&uru`?=+R9!?cLjR;*`w;L8I`4=VJ5>88R zde6S142H`3VvWpY-BS#wtrJJwBTB66b7iyrxEGy{`NZ2LyS!Hmxq4=&ujCJtm12V8 z`-yP~x*sjTTY+}Kn{m^4gdEWq4goIzW@?+;`q*vNA{ zP8M&7pSbLc_XRg`$eIL5 zR9LxEC{k`}MXg5p`Vzf*4xMWrffyU7MhJVsx=tFLAP-$-M4ZS2_-tb@2y3Ounc8?n zL`o&_#hD zjSJw-(RPG}$kC)3TOc~#km&$h!iZ%w1OXg7I-Dun$*QI$(Sm49ZSgwN@>v{NylxCA zK*eL^Y&?KDp$~(yM<4|adLVa#lY%XDjEurl?%Wy?u@7mAKM8zoCu@y^Xr5^+F^X#Q zl2N0Ilq4S#5NMn+EIn%&ke(yWyyhX2SW2j?tPkJ0(w)8Q?AY+TS!uwm!x2 zKq=o%yce2z>cJ{e9B#htT-~t!tI^h+_wD5>!Ih&K`(QQu6+gO97ou*xy5Dsic3)}Bku>vjhtD5Ae5xq%$&ME8g|~b#Jq@?<3i39_{?~&>Q&cLFu72&CR6;WnDJa#<|(KTuj=OXft3l z@Dh4E@R&cT?zZ)nY@PV?%TcImxmPVV2c8+67f3zW#U^Jkh1v;|;ŏp3#UA5qCHflXM`|Vxi(ZNyp(%Ox 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 literal 0 HcmV?d00001 diff --git a/static/img/favicon/apple-touch-icon.png b/static/img/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..659ab3c4f635102bf18f9f260e1bcb12e2f4a26b GIT binary patch literal 2391 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 Src;4dFnGH9xvX Date: Mon, 4 Sep 2023 00:40:13 +0300 Subject: [PATCH 03/43] Added netlify.toml file --- netlify.toml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 netlify.toml diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 000000000..c7d9945d6 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,9 @@ +# Global settings applied to the whole site. +# +# “base” is the directory to change to before starting build. If you set base: +# that is where we will look for package.json/.nvmrc/etc, not repo root! +# “command” is your build command. +# “publish” is the directory to publish (relative to the root of your repo). + +[build] + publish = "build" \ No newline at end of file From 2709cd17a1d3a51836d857c9053e2f9d5ec96ef4 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 00:53:14 +0300 Subject: [PATCH 04/43] Change engines in package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5db21f1da..589b1f8a1 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "version": "0.0.0", "type": "module", "engines": { - "node": "v16.19.1", - "npm": "8.19.3" + "node": ">=v16.19.1", + "npm": ">=8.19.3" }, "scripts": { "start": "concurrently \"npm run build\" \"node server.js\"", From aad50552bac613f9a53f63b4c117a045d9a44744 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 01:06:06 +0300 Subject: [PATCH 05/43] Added links to Netlify in readme.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4b3c0b3b..f1190574e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ -«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6)» +«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6){:target="_blank"}» +«[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/){:target="_blank"}» + +## Netlify links + +- «[Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/){:target="_blank"}» +- «[Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration){:target="_blank"}» +- «[Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat){:target="_blank"}» +- «[User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings){:target="_blank"}» +- «[Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404){:target="_blank"}» +- «[Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500){:target="_blank"}» ## Установка From b3180d3700b724ce68bc40143634fa1a06c872dd Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 01:10:14 +0300 Subject: [PATCH 06/43] Changes in readme.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f1190574e..dfaa385b5 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6){:target="_blank"}» -«[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/){:target="_blank"}» +«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6)» +«[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/)» ## Netlify links -- «[Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/){:target="_blank"}» -- «[Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration){:target="_blank"}» -- «[Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat){:target="_blank"}» -- «[User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings){:target="_blank"}» -- «[Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404){:target="_blank"}» -- «[Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500){:target="_blank"}» +- «[Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/)» +- «[Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration)» +- «[Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat)» +- «[User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings)» +- «[Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404)» +- «[Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500)» ## Установка From fe4ce0a877bc03172a5769df9852a4b6143b2dd3 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 01:12:47 +0300 Subject: [PATCH 07/43] Changes in readme.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dfaa385b5..08f7ea716 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -«[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6)» -«[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/)» +[Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6) +[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/) ## Netlify links -- «[Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/)» -- «[Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration)» -- «[Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat)» -- «[User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings)» -- «[Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404)» -- «[Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500)» +- [Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/) +- [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration) +- [Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat) +- [User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings) +- [Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404) +- [Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500) ## Установка From 462fa9e44c3600df019b57a7458828c92f785b4f Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 01:13:25 +0300 Subject: [PATCH 08/43] Changes in readme.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 08f7ea716..d030dc68c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ [Ссылка на прототип](https://www.figma.com/file/zoLY1xVwlhbMUxpHslGQDp/middle.messenger.praktikum.yandex?type=design&t=ruOBLon7eRgVs26J-6) -[Netlify](https://deploy--jocular-rugelach-1c03ff.netlify.app/) ## Netlify links From f01a20f36681ec6a96b14727bff605b9978fff4c Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 4 Sep 2023 11:54:23 +0300 Subject: [PATCH 09/43] Added main tag, added user-editing pages, fix EOF errors --- README.md | 8 +++--- src/404.html | 2 +- src/500.html | 2 +- src/chats-and-chat.html | 2 +- src/components/form/form.scss | 2 +- src/index.html | 2 +- src/layout/main.pug | 2 +- src/pages/user-editing-password.pug | 34 ++++++++++++++++++++++++ src/pages/user-editing-settings.pug | 41 +++++++++++++++++++++++++++++ src/registration.html | 2 +- src/scss/main.scss | 3 ++- src/user-editing-password.html | 2 ++ src/user-editing-settings.html | 2 ++ src/user-settings.html | 2 +- vite.config.js | 4 ++- 15 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 src/pages/user-editing-password.pug create mode 100644 src/pages/user-editing-settings.pug create mode 100644 src/user-editing-password.html create mode 100644 src/user-editing-settings.html diff --git a/README.md b/README.md index d030dc68c..4b82538f9 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,10 @@ - [Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/) - [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration) -- [Chats-and-chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat) -- [User-settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings) +- [Chats and chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat) +- [User settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings) +- [User editing settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-editing-settings) +- [User editing password](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-editing-password) - [Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404) - [Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500) @@ -28,4 +30,4 @@ ## Ключевые технологии - шаблонизатор - pug -- css препроцессор - sass \ No newline at end of file +- css препроцессор - sass diff --git a/src/404.html b/src/404.html index 38b61b0f6..2f08f3e8a 100644 --- a/src/404.html +++ b/src/404.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/src/500.html b/src/500.html index 5b0425089..fb5cf4990 100644 --- a/src/500.html +++ b/src/500.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/src/chats-and-chat.html b/src/chats-and-chat.html index 07283a583..93dca1cfc 100644 --- a/src/chats-and-chat.html +++ b/src/chats-and-chat.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/src/components/form/form.scss b/src/components/form/form.scss index dbdc6de02..c6c755485 100644 --- a/src/components/form/form.scss +++ b/src/components/form/form.scss @@ -7,7 +7,7 @@ width: 400px; max-width: 100%; border-radius: var(--b-radius); - background-color: #f5f5f5; + background-color: var(--bg-whiteSmoke); &__title { margin-bottom: 70px; diff --git a/src/index.html b/src/index.html index d5b329b5a..36ece22be 100644 --- a/src/index.html +++ b/src/index.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/src/layout/main.pug b/src/layout/main.pug index c583a8467..b516eb5be 100644 --- a/src/layout/main.pug +++ b/src/layout/main.pug @@ -14,5 +14,5 @@ html(class='page', lang='en') title Home body - .page__content + main.page__content block content diff --git a/src/pages/user-editing-password.pug b/src/pages/user-editing-password.pug new file mode 100644 index 000000000..6aeb92790 --- /dev/null +++ b/src/pages/user-editing-password.pug @@ -0,0 +1,34 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'User editing password'; + + title= pageName + meta(name='description', content=pageName) + +block content + + .modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name User name + + .user-settings__s + form#userSettingsForm.user-settings__form + ul.user-settings__list + li.user-settings__list-item + label.user-settings__list-item-name(for="oldPassword") Current password: + input.user-settings__list-item-value.t-right(id="oldPassword" type="password" name="oldPassword") + li.user-settings__list-item + label.user-settings__list-item-name(for="newPassword") New password: + input.user-settings__list-item-value.t-right(id="newPassword" type="password" name="newPassword") + li.user-settings__list-item + label.user-settings__list-item-name(for="repeatPassword") Repeat new password: + input.user-settings__list-item-value.t-right(id="repeatPassword" type="password" name="repeatPassword") + + .user-settings__t + button.link(type="button") Save password diff --git a/src/pages/user-editing-settings.pug b/src/pages/user-editing-settings.pug new file mode 100644 index 000000000..e4c6e1848 --- /dev/null +++ b/src/pages/user-editing-settings.pug @@ -0,0 +1,41 @@ +extends ../layout/main.pug + +block meta + - const pageName = 'User editing settings'; + + title= pageName + meta(name='description', content=pageName) + +block content + + .modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name User name + + .user-settings__s + form#userSettingsForm.user-settings__form + ul.user-settings__list + li.user-settings__list-item + label.user-settings__list-item-name(for="display_name") Nickname: + input.user-settings__list-item-value.t-right(id="display_name" type="text" name="display_name" value="user name") + li.user-settings__list-item + label.user-settings__list-item-name(for="first_name") First name: + input.user-settings__list-item-value.t-right(id="first_name" type="text" name="first_name" value="first name") + li.user-settings__list-item + label.user-settings__list-item-name(for="second_name") Second name: + input.user-settings__list-item-value.t-right(id="second_name" type="text" name="second_name" value="second name") + li.user-settings__list-item + label.user-settings__list-item-name(for="email") Email: + input.user-settings__list-item-value.t-right(id="email" type="text" name="email" value="test@test.ru") + li.user-settings__list-item + label.user-settings__list-item-name(for="phone") Phone: + input.user-settings__list-item-value.t-right(id="phone" type="text" name="phone" value="+7 (000) 000-00-00") + input(type="file", name="avatar", hidden) + + .user-settings__t + button.link(type="button") Save settings diff --git a/src/registration.html b/src/registration.html index 103a29729..bff96e5bd 100644 --- a/src/registration.html +++ b/src/registration.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/src/scss/main.scss b/src/scss/main.scss index 9b2214ba2..513dd35c2 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -42,6 +42,7 @@ --m-color-2-1: #1e5bb4; --t-l-grey: #9c9c9c; + --bg-whiteSmoke: #f5f5f5; --t-duration: 0.3s; } @@ -147,7 +148,7 @@ body { align-items: center; margin-left: auto; margin-right: auto; - width: 320px; + width: 350px; max-width: 100%; &__f, diff --git a/src/user-editing-password.html b/src/user-editing-password.html new file mode 100644 index 000000000..da3afe8e2 --- /dev/null +++ b/src/user-editing-password.html @@ -0,0 +1,2 @@ + + diff --git a/src/user-editing-settings.html b/src/user-editing-settings.html new file mode 100644 index 000000000..8a5a27663 --- /dev/null +++ b/src/user-editing-settings.html @@ -0,0 +1,2 @@ + + diff --git a/src/user-settings.html b/src/user-settings.html index 4b989e89f..690fe8ad5 100644 --- a/src/user-settings.html +++ b/src/user-settings.html @@ -1,2 +1,2 @@ - \ No newline at end of file + diff --git a/vite.config.js b/vite.config.js index 0861f9e0b..3b0142df8 100644 --- a/vite.config.js +++ b/vite.config.js @@ -19,10 +19,12 @@ export default defineConfig({ registration: resolve(root, 'registration.html'), chatsAndChat: resolve(root, 'chats-and-chat.html'), userSettings: resolve(root, 'user-settings.html'), + userEditingSettings: resolve(root, 'user-editing-settings.html'), + userEditingPassword: resolve(root, 'user-editing-password.html'), 404: resolve(root, '404.html'), 500: resolve(root, '500.html'), }, } }, publicDir: resolve(__dirname, 'static'), -}) \ No newline at end of file +}) From f3857e25e71d0db85d263b74545caa8a65e24f5b Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Wed, 13 Sep 2023 22:40:12 +0300 Subject: [PATCH 10/43] Added TS in project --- package-lock.json | 193 ++++++++++++++++++++++++++++++- package.json | 3 +- server.js => server.ts | 0 src/404.html | 2 +- src/500.html | 2 +- src/chats-and-chat.html | 2 +- src/index.html | 2 +- src/registration.html | 2 +- src/{style.js => style.ts} | 0 src/user-editing-password.html | 2 +- src/user-editing-settings.html | 2 +- src/user-settings.html | 2 +- tsconfig.json | 22 ++++ vite.config.js => vite.config.ts | 0 14 files changed, 223 insertions(+), 11 deletions(-) rename server.js => server.ts (100%) rename src/{style.js => style.ts} (100%) create mode 100644 tsconfig.json rename vite.config.js => vite.config.ts (100%) diff --git a/package-lock.json b/package-lock.json index 909c08b9d..88f4b0823 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,14 +11,15 @@ "vite-plugin-pug-transformer": "^1.0.3" }, "devDependencies": { + "@types/express": "^4.17.17", "concurrently": "^8.2.1", "express": "^4.18.2", "sass": "^1.66.1", "vite": "^4.4.5" }, "engines": { - "node": "v16.19.1", - "npm": "8.19.3" + "node": ">=v16.19.1", + "npm": ">=8.19.3" } }, "node_modules/@babel/helper-string-parser": { @@ -403,6 +404,100 @@ "node": ">=12" } }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.36", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz", + "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", + "devOptional": true + }, + "node_modules/@types/qs": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2236,6 +2331,100 @@ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "optional": true }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.36", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz", + "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/node": { + "version": "20.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", + "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", + "devOptional": true + }, + "@types/qs": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", diff --git a/package.json b/package.json index 589b1f8a1..4346df317 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,13 @@ "npm": ">=8.19.3" }, "scripts": { - "start": "concurrently \"npm run build\" \"node server.js\"", + "start": "concurrently \"npm run build\" \"ts-node-esm server.ts\"", "dev": "vite", "build": "vite build", "preview": "vite preview" }, "devDependencies": { + "@types/express": "^4.17.17", "concurrently": "^8.2.1", "express": "^4.18.2", "sass": "^1.66.1", diff --git a/server.js b/server.ts similarity index 100% rename from server.js rename to server.ts diff --git a/src/404.html b/src/404.html index 2f08f3e8a..0caf80630 100644 --- a/src/404.html +++ b/src/404.html @@ -1,2 +1,2 @@ - + diff --git a/src/500.html b/src/500.html index fb5cf4990..429fba24f 100644 --- a/src/500.html +++ b/src/500.html @@ -1,2 +1,2 @@ - + diff --git a/src/chats-and-chat.html b/src/chats-and-chat.html index 93dca1cfc..73bc09822 100644 --- a/src/chats-and-chat.html +++ b/src/chats-and-chat.html @@ -1,2 +1,2 @@ - + diff --git a/src/index.html b/src/index.html index 36ece22be..0350a15f5 100644 --- a/src/index.html +++ b/src/index.html @@ -1,2 +1,2 @@ - + diff --git a/src/registration.html b/src/registration.html index bff96e5bd..e110b6360 100644 --- a/src/registration.html +++ b/src/registration.html @@ -1,2 +1,2 @@ - + diff --git a/src/style.js b/src/style.ts similarity index 100% rename from src/style.js rename to src/style.ts diff --git a/src/user-editing-password.html b/src/user-editing-password.html index da3afe8e2..f4aee4b0c 100644 --- a/src/user-editing-password.html +++ b/src/user-editing-password.html @@ -1,2 +1,2 @@ - + diff --git a/src/user-editing-settings.html b/src/user-editing-settings.html index 8a5a27663..62f6ac9a6 100644 --- a/src/user-editing-settings.html +++ b/src/user-editing-settings.html @@ -1,2 +1,2 @@ - + diff --git a/src/user-settings.html b/src/user-settings.html index 690fe8ad5..85ca8e567 100644 --- a/src/user-settings.html +++ b/src/user-settings.html @@ -1,2 +1,2 @@ - + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..371b2f573 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "strict": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "skipLibCheck": true, + "sourceMap": true, + "strictNullChecks": true, + }, + "include": ["src"] + } diff --git a/vite.config.js b/vite.config.ts similarity index 100% rename from vite.config.js rename to vite.config.ts From 6d5be32012bed3f4fc70239445f0f45e704d180f Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Wed, 13 Sep 2023 23:25:37 +0300 Subject: [PATCH 11/43] Added eslint, stylelint --- .editorconfig | 15 + .eslintignore | 3 + .eslintrc.json | 9 + .stylelintrc.json | 3 + package-lock.json | 8721 ++++++++++++++++++++++++++++++++++++++++++--- package.json | 6 + tsconfig.json | 42 +- 7 files changed, 8204 insertions(+), 595 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 .stylelintrc.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..21bfb63d8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# Универсальные настройки редактора +# +# http://editorconfig.org +# https://habrahabr.ru/post/220131/ +# https://packagecontrol.io/packages/EditorConfig + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = crlf +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..61b52e49f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +/build +**/*.min.js +/node_modules diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..17a0423bd --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,9 @@ +{ + "extends": "airbnb", + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "rules": { + "max-len": [2, 100], + "@typescript-eslint/no-unused-vars": 2 + } +} diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 000000000..eff256099 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-standard-scss" +} diff --git a/package-lock.json b/package-lock.json index 88f4b0823..6115de28a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,15 @@ }, "devDependencies": { "@types/express": "^4.17.17", + "@typescript-eslint/eslint-plugin": "^6.7.0", + "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", + "eslint": "^8.49.0", + "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", "sass": "^1.66.1", + "stylelint": "^15.10.3", + "stylelint-config-standard-scss": "^11.0.0", "vite": "^4.4.5" }, "engines": { @@ -22,6 +28,99 @@ "npm": ">=8.19.3" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", @@ -38,6 +137,91 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { "version": "7.22.14", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", @@ -74,6 +258,92 @@ "node": ">=6.9.0" } }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", + "integrity": "sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.2.0" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz", + "integrity": "sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.4.tgz", + "integrity": "sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", + "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -404,6 +674,176 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -453,18 +893,43 @@ "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "peer": true + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, "node_modules/@types/node": { "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", "devOptional": true }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, "node_modules/@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", @@ -477,6 +942,12 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "dev": true + }, "node_modules/@types/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", @@ -498,624 +969,2926 @@ "@types/node": "*" } }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">= 0.6" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" + "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" }, "engines": { - "node": ">=0.4.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@typescript-eslint/parser": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=8" + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "ms": "2.1.2" }, "engines": { - "node": ">= 8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "node_modules/assert-never": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" - }, - "node_modules/babel-walk": { - "version": "3.0.0-canary-5", - "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", - "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "dev": true, "dependencies": { - "@babel/types": "^7.9.6" + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" }, "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, - "engines": { - "node": ">=8" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "node_modules/@typescript-eslint/type-utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/@typescript-eslint/type-utils/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", "dev": true, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": ">=10" + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/character-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { - "is-regex": "^1.0.3" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "node_modules/@typescript-eslint/utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "dev": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "semver": "^7.5.4" }, "engines": { - "node": ">= 8.10.0" + "node": "^16.0.0 || >=18.0.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@typescript-eslint/types": "6.7.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=7.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concurrently": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", - "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "chalk": "^4.1.2", - "date-fns": "^2.30.0", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" + "acorn": "bin/acorn" }, "engines": { - "node": "^14.13.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + "node": ">=0.4.0" } }, - "node_modules/constantinople": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", - "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", - "dependencies": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "safe-buffer": "5.2.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 0.6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, + "peer": true, "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "dequal": "^2.0.3" } }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, "dependencies": { - "ms": "2.0.0" + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=8" } }, - "node_modules/doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "dev": true, + "peer": true + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "peer": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.1.tgz", + "integrity": "sha512-9l850jDDPnKq48nbad8SiEelCv4OrUWrKab/cPj0GScVg6cb6NbCCt/Ulk26QEq5jP9NnGr04Bit1BHyV6r5CQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", + "destroy": "1.2.0", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", + "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "raw-body": "2.5.1", "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "devOptional": true, "dependencies": { - "to-regex-range": "^5.0.1" + "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concurrently": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", + "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz", + "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "peer": true + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", + "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "dev": true, + "peer": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.0", + "safe-array-concat": "^1.0.0" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "peer": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", + "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + }, + "engines": { + "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "peer": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", + "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "peer": true + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "peer": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "dependencies": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "devOptional": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "call-bind": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">= 0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, "engines": { "node": ">= 0.4" }, @@ -1123,198 +3896,352 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/http-errors": { + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/iterator.prototype": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz", + "integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==", "dev": true, + "peer": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.3" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" }, - "engines": { - "node": ">= 0.8" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "peer": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "peer": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "devOptional": true + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", + "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", "dev": true }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", "dev": true, - "engines": { - "node": ">= 0.10" + "peer": true + }, + "node_modules/language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "dev": true, + "peer": true, + "dependencies": { + "language-subtag-registry": "~0.3.2" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "dependencies": { - "has": "^1.0.3" + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-expression": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", - "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "peer": true, "dependencies": { - "acorn": "^7.1.1", - "object-assign": "^4.1.1" + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, "engines": { - "node": ">=0.12.0" + "node": ">= 0.6" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" }, "engines": { - "node": ">= 0.4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" - }, - "node_modules/jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", - "dependencies": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" + "node_modules/meow/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, "node_modules/merge-descriptors": { @@ -1323,6 +4250,15 @@ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -1332,6 +4268,19 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -1365,6 +4314,51 @@ "node": ">= 0.6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1388,51 +4382,277 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 0.6" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "peer": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "ee-first": "1.1.1" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">= 0.8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parseurl": { @@ -1444,6 +4664,33 @@ "node": ">= 0.8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -1455,6 +4702,15 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1499,6 +4755,88 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.8.tgz", + "integrity": "sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -1507,6 +4845,18 @@ "asap": "~2.0.3" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1632,6 +4982,15 @@ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1647,6 +5006,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1671,6 +5062,72 @@ "node": ">= 0.8" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "peer": true + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1683,12 +5140,66 @@ "node": ">=8.10.0" } }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", "dev": true }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1698,6 +5209,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", @@ -1714,6 +5234,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "3.28.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", @@ -1729,6 +5283,29 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -1738,6 +5315,24 @@ "tslib": "^2.1.0" } }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1758,6 +5353,20 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1781,6 +5390,15 @@ "node": ">=14.0.0" } }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1826,12 +5444,47 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", @@ -1855,6 +5508,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -1869,6 +5560,38 @@ "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1892,6 +5615,72 @@ "node": ">=8" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dev": true, + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1904,6 +5693,226 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true + }, + "node_modules/stylelint": { + "version": "15.10.3", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.3.tgz", + "integrity": "sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.2.0", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.28.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.27", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", + "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.0.0.tgz", + "integrity": "sha512-7AmMIsHTsuwUQm7I+DD5BGeIgCvqYZ4BpeYJJpb1cUXQwrJAKjA+GBotFZgUEGP8lAM+wmd91ovzOi8xfAyWEw==", + "dev": true, + "dependencies": { + "postcss-scss": "^4.0.7", + "stylelint-config-recommended": "^13.0.0", + "stylelint-scss": "^5.1.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-config-standard": { + "version": "34.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz", + "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^13.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-standard-scss": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.0.0.tgz", + "integrity": "sha512-fGE79NBOLg09a9afqGH/guJulRULCaQWWv4cv1v2bMX92B+fGb0y56WqIguwvFcliPmmUXiAhKrrnXilIeXoHA==", + "dev": true, + "dependencies": { + "stylelint-config-recommended-scss": "^13.0.0", + "stylelint-config-standard": "^34.0.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-scss": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.1.0.tgz", + "integrity": "sha512-E+KlQFXv1Euha43qw3q+wKBSli557wxbbo6/39DWhRNXlUa9Cz+FYrcgz+PT6ag0l6UisCYjAGCNhoSl4FcwlA==", + "dev": true, + "dependencies": { + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "stylelint": "^14.5.1 || ^15.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1913,10 +5922,35 @@ "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -1930,6 +5964,56 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -1973,12 +6057,73 @@ "tree-kill": "cli.js" } }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "peer": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1992,6 +6137,100 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2001,6 +6240,21 @@ "node": ">= 0.8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -2010,6 +6264,16 @@ "node": ">= 0.4.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2096,6 +6360,99 @@ "node": ">=0.10.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "peer": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "peer": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/with": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", @@ -2127,6 +6484,25 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -2136,6 +6512,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -2162,9 +6544,95 @@ "engines": { "node": ">=12" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, + "@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@babel/helper-string-parser": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", @@ -2175,6 +6643,75 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" }, + "@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@babel/parser": { "version": "7.22.14", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", @@ -2199,6 +6736,33 @@ "to-fast-properties": "^2.0.0" } }, + "@csstools/css-parser-algorithms": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", + "integrity": "sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==", + "dev": true, + "requires": {} + }, + "@csstools/css-tokenizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz", + "integrity": "sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==", + "dev": true + }, + "@csstools/media-query-list-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.4.tgz", + "integrity": "sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==", + "dev": true, + "requires": {} + }, + "@csstools/selector-specificity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", + "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "dev": true, + "requires": {} + }, "@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -2331,6 +6895,127 @@ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "optional": true }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@eslint/js": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz", + "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, "@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -2380,18 +7065,43 @@ "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", "dev": true }, + "@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "peer": true + }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, "@types/node": { "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", "devOptional": true }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, "@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", @@ -2404,6 +7114,12 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "@types/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "dev": true + }, "@types/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", @@ -2425,6 +7141,203 @@ "@types/node": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", + "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/type-utils": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz", + "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz", + "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz", + "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.7.0", + "@typescript-eslint/utils": "6.7.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@typescript-eslint/types": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz", + "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz", + "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/visitor-keys": "6.7.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz", + "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.7.0", + "@typescript-eslint/types": "6.7.0", + "@typescript-eslint/typescript-estree": "6.7.0", + "semver": "^7.5.4" + }, + "dependencies": { + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz", + "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.7.0", + "eslint-visitor-keys": "^3.4.1" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2440,6 +7353,25 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2465,12 +7397,133 @@ "picomatch": "^2.0.4" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "peer": true, + "requires": { + "dequal": "^2.0.3" + } + }, + "array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, + "array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -2481,6 +7534,52 @@ "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "dev": true, + "peer": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "peer": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "axe-core": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.1.tgz", + "integrity": "sha512-9l850jDDPnKq48nbad8SiEelCv4OrUWrKab/cPj0GScVg6cb6NbCCt/Ulk26QEq5jP9NnGr04Bit1BHyV6r5CQ==", + "dev": true, + "peer": true + }, + "axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "peer": true, + "requires": { + "dequal": "^2.0.3" + } + }, "babel-walk": { "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", @@ -2489,6 +7588,12 @@ "@babel/types": "^7.9.6" } }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2515,6 +7620,16 @@ "unpipe": "1.0.0" } }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -2535,8 +7650,40 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "requires": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } } }, "chalk": { @@ -2610,6 +7757,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, "concurrently": { "version": "8.2.1", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", @@ -2627,6 +7786,12 @@ "yargs": "^17.7.2" } }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, "constantinople": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", @@ -2663,6 +7828,58 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-functions-list": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz", + "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==", + "dev": true + }, + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "peer": true + }, "date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -2681,18 +7898,101 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true + } + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "peer": true + }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -2716,6 +8016,117 @@ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + } + }, + "es-iterator-helpers": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", + "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "dev": true, + "peer": true, + "requires": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.0", + "safe-array-concat": "^1.0.0" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "peer": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -2757,6 +8168,377 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz", + "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.49.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-config-airbnb": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", + "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + } + }, + "eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "peer": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + } + } + }, + "eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "peer": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + } + } + }, + "eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "peer": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "peer": true, + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "peer": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", + "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "dependencies": { + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "peer": true + } + } + }, + "eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "peer": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "peer": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "peer": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "peer": true, + "requires": {} + }, + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "dependencies": { + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true + } + } + }, + "esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -2802,6 +8584,61 @@ "vary": "~1.1.2" } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2826,6 +8663,42 @@ "unpipe": "~1.0.0" } }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "requires": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2838,6 +8711,12 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2849,6 +8728,24 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2866,6 +8763,30 @@ "has-symbols": "^1.0.3" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -2875,6 +8796,96 @@ "is-glob": "^4.0.1" } }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2883,12 +8894,27 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -2907,6 +8933,21 @@ "has-symbols": "^1.0.2" } }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -2929,24 +8970,121 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, "immutable": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", "devOptional": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, + "is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "peer": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2956,6 +9094,22 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, "is-core-module": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", @@ -2964,6 +9118,15 @@ "has": "^1.0.3" } }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-expression": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", @@ -2979,12 +9142,32 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "devOptional": true }, + "is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "peer": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2994,12 +9177,52 @@ "is-extglob": "^2.1.1" } }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "peer": true + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "devOptional": true }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -3014,11 +9237,155 @@ "has-tostringtag": "^1.0.0" } }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "peer": true + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.11" + } + }, + "is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "peer": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "iterator.prototype": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz", + "integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==", + "dev": true, + "peer": true, + "requires": { + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.3" + } + }, "js-stringify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.0" + } + }, "jstransformer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", @@ -3028,30 +9395,205 @@ "promise": "^7.0.1" } }, + "jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "peer": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + } + }, + "keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "known-css-properties": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", + "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "dev": true + }, + "language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true, + "peer": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "dev": true, + "peer": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "peer": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true + }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, + "meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -3073,6 +9615,39 @@ "mime-db": "1.52.0" } }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "peer": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3084,12 +9659,41 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3107,6 +9711,83 @@ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "peer": true, + "requires": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -3116,12 +9797,92 @@ "ee-first": "1.1.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -3133,6 +9894,12 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -3154,6 +9921,54 @@ "source-map-js": "^1.0.2" } }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "requires": {} + }, + "postcss-scss": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.8.tgz", + "integrity": "sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==", + "dev": true, + "requires": {} + }, + "postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -3162,6 +9977,18 @@ "asap": "~2.0.3" } }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -3284,6 +10111,12 @@ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -3293,6 +10126,18 @@ "side-channel": "^1.0.4" } }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -3311,6 +10156,52 @@ "unpipe": "1.0.0" } }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "peer": true + }, + "read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "requires": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + } + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3320,18 +10211,60 @@ "picomatch": "^2.2.1" } }, + "redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "requires": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + } + }, + "reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + } + }, "regenerator-runtime": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "resolve": { "version": "1.22.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", @@ -3342,6 +10275,27 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "rollup": { "version": "3.28.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", @@ -3350,13 +10304,34 @@ "fsevents": "~2.3.2" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, "requires": { - "tslib": "^2.1.0" + "tslib": "^2.1.0" + } + }, + "safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" } }, "safe-buffer": { @@ -3365,6 +10340,17 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3382,6 +10368,12 @@ "source-map-js": ">=0.6.2 <2.0.0" } }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -3423,12 +10415,38 @@ "send": "0.18.0" } }, + "set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + } + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", @@ -3446,6 +10464,29 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -3457,6 +10498,38 @@ "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, + "spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -3474,6 +10547,57 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dev": true, + "peer": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3483,6 +10607,160 @@ "ansi-regex": "^5.0.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "peer": true + }, + "strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "requires": { + "min-indent": "^1.0.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true + }, + "stylelint": { + "version": "15.10.3", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.3.tgz", + "integrity": "sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==", + "dev": true, + "requires": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.2.0", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.28.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.27", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "stylelint-config-recommended": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", + "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "dev": true, + "requires": {} + }, + "stylelint-config-recommended-scss": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.0.0.tgz", + "integrity": "sha512-7AmMIsHTsuwUQm7I+DD5BGeIgCvqYZ4BpeYJJpb1cUXQwrJAKjA+GBotFZgUEGP8lAM+wmd91ovzOi8xfAyWEw==", + "dev": true, + "requires": { + "postcss-scss": "^4.0.7", + "stylelint-config-recommended": "^13.0.0", + "stylelint-scss": "^5.1.0" + } + }, + "stylelint-config-standard": { + "version": "34.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz", + "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==", + "dev": true, + "requires": { + "stylelint-config-recommended": "^13.0.0" + } + }, + "stylelint-config-standard-scss": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.0.0.tgz", + "integrity": "sha512-fGE79NBOLg09a9afqGH/guJulRULCaQWWv4cv1v2bMX92B+fGb0y56WqIguwvFcliPmmUXiAhKrrnXilIeXoHA==", + "dev": true, + "requires": { + "stylelint-config-recommended-scss": "^13.0.0", + "stylelint-config-standard": "^34.0.0" + } + }, + "stylelint-scss": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.1.0.tgz", + "integrity": "sha512-E+KlQFXv1Euha43qw3q+wKBSli557wxbbo6/39DWhRNXlUa9Cz+FYrcgz+PT6ag0l6UisCYjAGCNhoSl4FcwlA==", + "dev": true, + "requires": { + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + } + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -3492,11 +10770,77 @@ "has-flag": "^4.0.0" } }, + "supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -3528,12 +10872,53 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, + "trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true + }, + "ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "requires": {} + }, + "tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "peer": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3544,18 +10929,109 @@ "mime-types": "~2.1.24" } }, + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "peer": true + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -3587,6 +11063,75 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "peer": true, + "requires": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + } + }, + "which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "peer": true, + "requires": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + } + }, + "which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "with": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", @@ -3609,12 +11154,34 @@ "strip-ansi": "^6.0.0" } }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -3635,6 +11202,12 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 4346df317..2046ed33c 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,15 @@ }, "devDependencies": { "@types/express": "^4.17.17", + "@typescript-eslint/eslint-plugin": "^6.7.0", + "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", + "eslint": "^8.49.0", + "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", "sass": "^1.66.1", + "stylelint": "^15.10.3", + "stylelint-config-standard-scss": "^11.0.0", "vite": "^4.4.5" }, "dependencies": { diff --git a/tsconfig.json b/tsconfig.json index 371b2f573..9db061ae1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ESNext", "DOM"], - "moduleResolution": "Node", - "strict": true, - "resolveJsonModule": true, - "isolatedModules": true, - "esModuleInterop": true, - "noEmit": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "skipLibCheck": true, - "sourceMap": true, - "strictNullChecks": true, - }, - "include": ["src"] - } + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "strict": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "skipLibCheck": true, + "sourceMap": true, + "strictNullChecks": true, + }, + "include": ["src"] +} From f284a9886f5a3a43d03d9d1a65c3a3a8e9dc3745 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Sat, 16 Sep 2023 23:31:44 +0300 Subject: [PATCH 12/43] Added eslint, stylelint, ts, chats and chat page almost done --- .editorconfig | 2 +- .eslintrc.json | 3 +- server.ts | 12 +-- src/layout/main.pug | 11 +-- src/pages/chats-and-chat.pug | 82 +++++++++++++++++- src/scss/main.scss | 139 +++++++++++++++++++++++++++++- static/img/avatar-dummy-1.jpg | Bin 0 -> 1760 bytes static/img/chats-and-chat-cap.jpg | Bin 164062 -> 0 bytes vite.config.ts | 8 +- 9 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 static/img/avatar-dummy-1.jpg delete mode 100644 static/img/chats-and-chat-cap.jpg diff --git a/.editorconfig b/.editorconfig index 21bfb63d8..d6abdaac6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,6 +10,6 @@ root = true charset = utf-8 indent_style = space indent_size = 2 -end_of_line = crlf +end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true diff --git a/.eslintrc.json b/.eslintrc.json index 17a0423bd..7041a4b85 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,6 +4,7 @@ "plugins": ["@typescript-eslint"], "rules": { "max-len": [2, 100], - "@typescript-eslint/no-unused-vars": 2 + "@typescript-eslint/no-unused-vars": 2, + "no-console": 0 } } diff --git a/server.ts b/server.ts index 276ead405..761344110 100644 --- a/server.ts +++ b/server.ts @@ -1,10 +1,10 @@ -import express from 'express' +import express from 'express'; // eslint-disable-line -const app = express() -const port = 3000 +const app = express(); +const port = 3000; -app.use(express.static('build')) +app.use(express.static('build')); app.listen(port, () => { - console.log(`Example app listening on port ${port}`) -}) \ No newline at end of file + console.log(`Example app listening on port ${port}`); +}); diff --git a/src/layout/main.pug b/src/layout/main.pug index b516eb5be..e7431595a 100644 --- a/src/layout/main.pug +++ b/src/layout/main.pug @@ -2,7 +2,7 @@ include ./mixins.pug doctype html html(class='page', lang='en') - head + head meta(charset='utf-8') meta(name='viewport', content='width=device-width, initial-scale=1') @@ -11,8 +11,9 @@ html(class='page', lang='en') link(rel='icon', type='image/png', sizes='16x16', href='img/favicon/favicon-16x16.png') block meta - title Home - - body - main.page__content + title Home + + body + //main.page__content + main block content diff --git a/src/pages/chats-and-chat.pug b/src/pages/chats-and-chat.pug index 6f7b82cb9..98ad6f708 100644 --- a/src/pages/chats-and-chat.pug +++ b/src/pages/chats-and-chat.pug @@ -6,6 +6,84 @@ block meta title= pageName meta(name='description', content=pageName) -block content +block content - img(src="img/chats-and-chat-cap.jpg", alt="chats-and-chat-cap") + .chats-and-chat + aside.sidebar + .sidebar__f + form.search + +field-text({ + mods: 'white, center', + val: '', + attrs: { + name: 'search', + placeholder: 'search', + } + }) + + .sidebar__s + .chats + each val in [1, 2, 3, 4, 5, 7, 8, 9, 10] + article.chat(tabindex="0") + .chat__f + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .chat__s + .chat__s-f + h6.name Chat name + time.chat__time 10:45 + .chat__s-s + p.chat__last-message last message last message last message last message last message last message + + .sidebar__t + .user-information + .user-information__f + .user-information__f-f + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .user-information__f-s + h6.name User name + + .user-information__s + button.settings(type="button") ... + + .chat-area + .chat-area__f + .chat-area__f-f + .chat-area__info + .chat-area__info-l + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .chat-area__info-r + h6.name Chat name + + .chat-area__f-s + button.settings(type="button") ... + + .chat-area__s + .messages-area + .messages-area__f + .messages-area__conversation + .messages-area__conversation-received + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + + .messages-area__conversation-sent + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + + + .messages-area__s + +field-text({ + mods: 'main', + attrs: { + name: 'message', + placeholder: 'Type a message', + } + }) + button.settings(type="button") ... + button.settings(type="button") ... + + .chat-area__t diff --git a/src/scss/main.scss b/src/scss/main.scss index 513dd35c2..0db7c4f26 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -41,7 +41,8 @@ --m-color-2: #2872e0; --m-color-2-1: #1e5bb4; - --t-l-grey: #9c9c9c; + --t-l-grey-1: #9c9c9c; + --t-l-grey-2: #d9d9d9; --bg-whiteSmoke: #f5f5f5; --t-duration: 0.3s; @@ -241,3 +242,139 @@ body { &__link { } } + +.chats-and-chat { + display: grid; + grid-template-columns: 30% 70%; +} + +/* ----- .sidebar ----- */ + +.sidebar { + --indent: 15px; + + $block-name: &; + + background-color: var(--t-l-grey-2); + + &__f, + &__s { + padding-left: var(--indent); + padding-right: var(--indent); + } + + &__f { + padding-top: 15px; + } + + &__s { + margin-top: 15px; + } + + &__t { + } +} + +/* ----- .chats ----- */ + +.chats { + $block-name: &; +} + +/* ----- .chat ----- */ + +.chat { + $block-name: &; + + &__f { + } + + &__s { + } + + &__s-f { + .name { + } + } + + &__time { + } + + &__s-s { + } + + &__last-message { + } +} + +/* ----- .avatar ----- */ + +.avatar { + $block-name: &; + + &__img { + } +} + +/* ----- .user-information ----- */ + +.user-information { + $block-name: &; + + &__f { + } + + &__f-f { + } + + &__f-s { + } + + &__s { + } +} + +/* ----- .chat-area ----- */ + +.chat-area { + $block-name: &; + + &__f { + } + + &__f-f { + } + + &__info { + } + + &__info-l { + } + + &__info-r { + } + + &__f-s { + } +} + +/* ----- .messages-area ----- */ + +.messages-area { + $block-name: &; + + &__f { + } + + &__conversation { + } + + &__conversation-received { + } + + &__conversation-sent { + } + + &__conversation-message { + } +} diff --git a/static/img/avatar-dummy-1.jpg b/static/img/avatar-dummy-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0a14a82f97b0b57037a2c99e5b7acb70f14dd7dc GIT binary patch literal 1760 zcmbu7doPv5aCoqS`Qok?|NZ*+O~0R!U485n|d?1{*19hN2Rs zyhG)kJQAj5nIeht$Rkr*aY!q+n4Q^n+jI7>J=^`B?_c+x&pn@euV_Ft2IO|wG3)?@ zfPlUD0nre!0nk^51oD*#2ol`~I4NKb%wY%z5I6|NL83OG1^|Tm%m#l2gn*H#RcI+` z3|3rFEe8+~3?q;*3WY?9tB;HG0Et84*XvuYA~^3wtB1=Q#Bp<_G_3EmDD3W;B^w4D ziI>JGDy=0dYieohY|y0`8E-W)HM61H+HJRI?AYVt>gMj@>9ucv;DMlE=D~=_sH4#_ ztYZm3olHzRm3%ra{rrWD%!`*UU%!!;Ur<<7TvAb4Rb5kCcenmQYg;?-;m;kNy-)g{ z_CFgK6pT+yzL*leeD&+=xp(vLe_Qylxb(Zk3j*+$k$o2XmzQ`55CVyWk!Xn*goqY@ z7>7iy*I$LVaz^hBC#W05Ny%GtbMLfBYZ&gHRR}oJgHa??#x>_8YJZyjH?jEtW%fnv zA1?urfg$noU>u-r>PmjXvvP%#JP{|_&ps2dx79vSQ@u5oL8U1@$gC;EF5e8owEu|XZyoWrtr?xzVwM#=J>?`lNL2xA z3O5>IRd@Gdm(5;dhp6Y*tZr{OL*CUWOFU-4aibqH4<)L)_7#DPkM2)!z`LcfqzV*GJ#& zl)q12%>00_xjwt|o$3!Y1xyDAos-IMRzJn7x2%dARb z=0Q`Zp9W;~G#$d@`4gjv!H{l(en=Y|nmgXs9TC2*b$Lmc5%iKqDd!L8IBsNZ3q~jd z9dHf7#sD2S+F@?>N_yx*e}$RdJmsyz!r8Z6-Y(->>OQ{+0sET?U(@&JC z_7)tl-Nb)xI(2UOm4Hn-VIH%?;m41$N?vrY(WQWjr>EbkH=IJ*c56d(-r!>ImQ9VRq4(OztCT<;q%2F#Mj-sw__; zKBhFv4kvnJT~a;e<+SUM1m3G_A)m7lG6FG-0hM**wt#t1QSn&*1%7rc!e`LWde)~! z>u3id1;??`lO?KR>P_73+?_1Z?JKlJ-Rpu^q3_e&GRx$cqROU+&y6~2p#`CqaHxOM2fzK9fYdBL z01e&xii$)xl&1%xG|&Gg%&|fvNm65v(dmm><4W;S^twg|>Buvj0=wfRm#XB>)Wlx< z@{Kppiz$jdh9rkjA=`rftZIOAufL|2l?{c-bft)Z-UXGs@YL)RepS$$SlJcjnAo;g zn~hAX9XZssAv2pMPVdaObl2(;Vj}n*&h>kf!qya0zLj}ppgs?!`V%dw<@nst2nKi7N4wW@DF~@!jk|1 literal 0 HcmV?d00001 diff --git a/static/img/chats-and-chat-cap.jpg b/static/img/chats-and-chat-cap.jpg deleted file mode 100644 index 92b8376f2b52b75e4c7701803c0c4fe5f4e03365..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164062 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ŏp3#UA5qCHflXM`|Vxi(ZNyp(%Ox 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 diff --git a/vite.config.ts b/vite.config.ts index 3b0142df8..4215779e4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ import { resolve } from 'path'; -import { defineConfig } from "vite" +import { defineConfig } from "vite"; // eslint-disable-line -import vitePugPlugin from 'vite-plugin-pug-transformer' +import vitePugPlugin from 'vite-plugin-pug-transformer'; const locals = { bundler: 'Vite' }; const root = resolve(__dirname, 'src'); @@ -24,7 +24,7 @@ export default defineConfig({ 404: resolve(root, '404.html'), 500: resolve(root, '500.html'), }, - } + }, }, publicDir: resolve(__dirname, 'static'), -}) +}); From a8b3b24804c1e7d75e9a59115eb557f58f49aed9 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Sun, 17 Sep 2023 15:08:21 +0300 Subject: [PATCH 13/43] Chats and chat page done --- src/components/field-text/field-text.scss | 19 ++ src/pages/chats-and-chat.pug | 65 +++---- src/scss/main.scss | 205 ++++++++++++++++++++-- 3 files changed, 247 insertions(+), 42 deletions(-) diff --git a/src/components/field-text/field-text.scss b/src/components/field-text/field-text.scss index c3128d84c..27435d690 100644 --- a/src/components/field-text/field-text.scss +++ b/src/components/field-text/field-text.scss @@ -25,4 +25,23 @@ &__help-text { } + + &--white { + #{$block-name}__input { + background-color: #fff; + } + } + + &--center { + text-align: center; + } + + &--main { + #{$block-name}__input { + padding-left: 30px; + padding-right: 30px; + height: 60px; + border-radius: 50px; + } + } } diff --git a/src/pages/chats-and-chat.pug b/src/pages/chats-and-chat.pug index 98ad6f708..4f13737c8 100644 --- a/src/pages/chats-and-chat.pug +++ b/src/pages/chats-and-chat.pug @@ -22,18 +22,19 @@ block content }) .sidebar__s - .chats - each val in [1, 2, 3, 4, 5, 7, 8, 9, 10] - article.chat(tabindex="0") - .chat__f - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .chat__s - .chat__s-f - h6.name Chat name - time.chat__time 10:45 - .chat__s-s - p.chat__last-message last message last message last message last message last message last message + .sidebar__s-inner + .chats + each val in [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15] + article.chat(tabindex="0") + .chat__f + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .chat__s + .chat__s-f + h6.name Chat name + time.chat__time 10:45 + .chat__s-s + p.chat__last-message last message last message last message last message last message last message .sidebar__t .user-information @@ -64,26 +65,26 @@ block content .messages-area .messages-area__f .messages-area__conversation - .messages-area__conversation-received - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - - .messages-area__conversation-sent - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + each val in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .messages-area__conversation-item.messages-area__conversation-received + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .messages-area__conversation-item.messages-area__conversation-sent + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? .messages-area__s - +field-text({ - mods: 'main', - attrs: { - name: 'message', - placeholder: 'Type a message', - } - }) - button.settings(type="button") ... - button.settings(type="button") ... - - .chat-area__t + .messages-area__s-inner + +field-text({ + mods: 'main', + attrs: { + name: 'message', + placeholder: 'Type a message', + } + }) + .messages-area__buttons + button.settings(type="button") ... + button.settings(type="button") ... diff --git a/src/scss/main.scss b/src/scss/main.scss index 0db7c4f26..5d971f5dc 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -38,11 +38,15 @@ --m-color-1: #784dd4; --m-color-1-1: #5e36b2; + --m-color-1-2: #d6c4ff; + --m-color-1-3: #f2ecff; --m-color-2: #2872e0; --m-color-2-1: #1e5bb4; --t-l-grey-1: #9c9c9c; --t-l-grey-2: #d9d9d9; + --t-l-grey-3: #f0f0f0; + --bg-whiteSmoke: #f5f5f5; --t-duration: 0.3s; @@ -204,7 +208,7 @@ body { } &__list-item-value { - color: var(--t-l-grey); + color: var(--t-l-grey-1); } &__t { @@ -232,7 +236,7 @@ body { &__description { font-size: 20px; - color: var(--t-l-grey); + color: var(--t-l-grey-1); } &__bottom { @@ -243,35 +247,87 @@ body { } } +%d-scroll { + &::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + &::-webkit-scrollbar-thumb { + background: #b8b8b8; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + scrollbar-color: #b8b8b8 transparent; + scrollbar-width: thin; +} + .chats-and-chat { display: grid; grid-template-columns: 30% 70%; + margin: 0 auto; + max-width: 1920px; + height: 100vh; } /* ----- .sidebar ----- */ .sidebar { --indent: 15px; + --height-t: 59px; + --height-b: 100px; $block-name: &; + padding: 0 var(--indent); background-color: var(--t-l-grey-2); - &__f, - &__s { - padding-left: var(--indent); - padding-right: var(--indent); - } - &__f { - padding-top: 15px; + display: flex; + align-items: flex-end; + height: var(--height-t); + + .search { + width: 100%; + } } &__s { - margin-top: 15px; + // position: relative; + + padding: var(--indent) 0; + height: calc(100vh - (var(--height-t) + var(--height-b))); + + // &::before { + // content: ""; + // position: absolute; + // left: 0; + // bottom: 0; + // width: 100%; + // height: 50%; + // background: linear-gradient( + // 90deg, + // rgba(255, 255, 255, 0) 0%, + // rgba(255, 255, 255, 0) 100% + // ); + // } + } + + &__s-inner { + @extend %d-scroll; + + overflow-y: auto; + height: 100%; } &__t { + padding: 20px; + height: var(--height-b); + background-color: #fff; + border-radius: var(--b-radius); } } @@ -286,33 +342,68 @@ body { .chat { $block-name: &; + display: flex; + padding: 20px; + background-color: #fff; + border-radius: var(--b-radius); + + & + & { + margin-top: 15px; + } + &__f { } &__s { + margin-left: 15px; } &__s-f { + display: flex; + justify-content: space-between; + .name { } } &__time { + font-size: 14px; } &__s-s { + margin-top: 5px; } &__last-message { + font-size: 14px; + color: var(--t-l-grey-1); + + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; } } +.name { + font-weight: 600; +} + /* ----- .avatar ----- */ .avatar { $block-name: &; + overflow: hidden; + width: 60px; + height: 60px; + border-radius: 50%; + &__img { + width: 100%; + height: 100%; + object-fit: contain; + object-position: center; } } @@ -321,13 +412,20 @@ body { .user-information { $block-name: &; + display: flex; + justify-content: space-between; + align-items: center; + &__f { + display: flex; + align-items: center; } &__f-f { } &__f-s { + margin-left: 15px; } &__s { @@ -339,23 +437,50 @@ body { .chat-area { $block-name: &; + --indent-h: 30px; + --height-f: 72px; + + height: 100vh; + + &__f, + &__s { + padding-left: var(--indent-h); + padding-right: var(--indent-h); + } + &__f { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 15px; + padding-bottom: 15px; + height: var(--height-f); + background-color: var(--t-l-grey-2); } &__f-f { } &__info { + display: flex; + align-items: center; } &__info-l { } &__info-r { + margin-left: 15px; } &__f-s { } + + &__s { + padding-top: 15px; + padding-bottom: 15px; + height: calc(100% - var(--height-f)); + } } /* ----- .messages-area ----- */ @@ -363,18 +488,78 @@ body { .messages-area { $block-name: &; + --height-s: 75px; + + margin: 0 auto; + max-width: 1050px; + height: 100%; + &__f { + @extend %d-scroll; + + overflow-y: auto; + padding: 15px; + border: 2px solid var(--m-color-1-2); + height: calc(100% - var(--height-s)); + border-radius: var(--b-radius); + } + + &__s { + --indent-h: 15px; + + display: flex; + align-items: flex-end; + gap: var(--indent-h); + height: var(--height-s); + } + + &__s-inner { + display: flex; + align-items: center; + gap: var(--indent-h); + width: 100%; + + .field-text { + width: 75%; + } } &__conversation { } + &__conversation-item { + display: flex; + flex-direction: column; + + & + & { + margin-top: 20px; + } + } + &__conversation-received { } &__conversation-sent { + align-items: flex-end; + + #{$block-name}__conversation-message { + background-color: var(--m-color-1-3); + } } &__conversation-message { + padding: 15px; + width: 50%; + border-radius: var(--b-radius); + background-color: var(--t-l-grey-3); + + & + & { + margin-top: 10px; + } + } + + &__buttons { + display: flex; + gap: 5px var(--indent-h); } } From 83328964dc30e6e50d27d1137f0bb2dec49c53b0 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Sat, 23 Sep 2023 16:23:18 +0300 Subject: [PATCH 14/43] Work in progress --- .eslintrc.json | 12 +- _http | 76 +++ _proxyProps.js | 68 +++ package-lock.json | 501 +++++++++++++++--- package.json | 6 +- src/404.html | 2 - src/500.html | 2 - src/chats-and-chat.html | 2 - .../{btn/btn.scss => Button/Button.scss} | 0 src/components/Button/Button.tmp.pug | 1 + src/components/Button/Button.ts | 12 + src/components/btn/btn.pug | 30 -- src/core/Block.js | 217 ++++++++ src/core/EventBus.ts | 44 ++ src/core/index.js | 7 + src/index.html | 13 +- src/index.ts | 11 + src/layout/main.pug | 19 - src/layout/mixins.pug | 3 - src/pages/registration/registration.tmp.pug | 20 + src/pages/registration/registration.ts | 15 + src/registration.html | 2 - src/style.ts | 1 - src/user-editing-password.html | 2 - src/user-editing-settings.html | 2 - src/user-settings.html | 2 - vite-plugin-pug-precompile.ts | 22 + vite.config.ts | 18 +- 28 files changed, 938 insertions(+), 172 deletions(-) create mode 100644 _http create mode 100644 _proxyProps.js delete mode 100644 src/404.html delete mode 100644 src/500.html delete mode 100644 src/chats-and-chat.html rename src/components/{btn/btn.scss => Button/Button.scss} (100%) create mode 100644 src/components/Button/Button.tmp.pug create mode 100644 src/components/Button/Button.ts delete mode 100644 src/components/btn/btn.pug create mode 100644 src/core/Block.js create mode 100644 src/core/EventBus.ts create mode 100644 src/core/index.js create mode 100644 src/index.ts delete mode 100644 src/layout/main.pug delete mode 100644 src/layout/mixins.pug create mode 100644 src/pages/registration/registration.tmp.pug create mode 100644 src/pages/registration/registration.ts delete mode 100644 src/registration.html delete mode 100644 src/style.ts delete mode 100644 src/user-editing-password.html delete mode 100644 src/user-editing-settings.html delete mode 100644 src/user-settings.html create mode 100644 vite-plugin-pug-precompile.ts diff --git a/.eslintrc.json b/.eslintrc.json index 7041a4b85..9061692da 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,9 +2,19 @@ "extends": "airbnb", "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], + "settings": { + "import/resolver": { + "node": { + "extensions": [".js", ".ts", ".scss", ".pug"] + } + } + }, "rules": { "max-len": [2, 100], "@typescript-eslint/no-unused-vars": 2, - "no-console": 0 + "no-console": 0, + "import/extensions": 0, + "quotes": 0, + "semi": 0 } } diff --git a/_http b/_http new file mode 100644 index 000000000..c89287cdb --- /dev/null +++ b/_http @@ -0,0 +1,76 @@ +/* eslint-disable */ + +const METHODS = { + GET: 'GET', + POST: 'POST', + PUT: 'PUT', + DELETE: 'DELETE', +}; + +function queryStringify (data) { + let result = '?'; + + for (const [key, value] of Object.entries(data)) { + result += `${key}=${value.toString()}&`; + } + + return result.slice(0, result.length - 1); +} + +class HTTPTransport { + get = (url, options = {}) => { + const { data } = options; + return this.request((data ? `${url}${queryStringify(data)}` : url), {...options, method: METHODS.GET}); + }; + + post = () => { + return this.request(url, {...options, method: METHODS.POST}); + } + + put = () => { + return this.request(url, {...options, method: METHODS.PUT}); + } + + delete = () => { + return this.request(url, {...options, method: METHODS.DELETE}); + } + + request = (url, options) => { + const {method, headers, data, timeout = 5000} = options; + + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open(method, url); + if (headers) xhr.setRequestHeader(...headers); + + xhr.onload = () => { + resolve(xhr); + }; + + xhr.onabort = reject; + xhr.onerror = reject; + xhr.ontimeout = reject; + + if (method === METHODS.GET) { + xhr.send(); + } else { + xhr.send(JSON.stringify(data)); + } + + setTimeout(() => { + xhr.abort(); + }, timeout) + }) + }; +} + +function fetchWithRetry (url, options = {}) { + let { retries = 2 } = options; + + if (retries === 0) { + throw new Error('The number of attempts has been exhausted'); + } + + return new HTTPTransport().get(url, options) + .catch(err => fetchWithRetry(url, {...options, retries: retries - 1})) +} diff --git a/_proxyProps.js b/_proxyProps.js new file mode 100644 index 000000000..d28d8bbac --- /dev/null +++ b/_proxyProps.js @@ -0,0 +1,68 @@ +const props = { + name: 'Abby', + chat: 'the last of us. Part II', + getChat() { + this._privateMethod(); + }, + _privateMethod() { + console.log(this._privateProp); + }, + __privateMethodToo() {}, + _privateProp: 'Нельзя получить просто так', +}; + +const proxyProps = new Proxy(props, { + get(o, name) { + if (name.search('_') !== -1) { + // console.log('Нет прав'); + // return false; + } + + return o[name]; + // return o[name]; + }, + set(o, name, newValue) { + if (name.search('_') !== -1) { + throw new Error('Нет прав'); + } + + o[name] = newValue; + + return true; + }, + deleteProperty(o, name) { + if (name.search('_') !== -1) { + throw new Error('Нет прав'); + } + + return true; + }, +}); + +// proxyProps.getChat(); +// delete proxyProps.chat; + +// proxyProps.newProp = 2; +// console.log(proxyProps.newProp); + +try { + proxyProps._newPrivateProp = 'Super game'; +} catch (error) { + console.log(error); +} + +console.log(props); + +// try { +// delete proxyProps._privateProp; +// } catch (error) { +// console.log(error); // Error: Нет прав +// } + +/* + * Вывод в консоль следующий: +Нельзя получить просто так +2 +Error: Нет прав +Error: Нет прав +*/ diff --git a/package-lock.json b/package-lock.json index 6115de28a..2b92ab99c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,11 @@ "name": "messenger", "version": "0.0.0", "dependencies": { - "vite-plugin-pug-transformer": "^1.0.3" + "pug": "^3.0.2" }, "devDependencies": { "@types/express": "^4.17.17", + "@types/pug": "^2.0.6", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", @@ -21,10 +22,11 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "uuid": "^9.0.1", "vite": "^4.4.5" }, "engines": { - "node": ">=v16.19.1", + "node": "v16.19.1", "npm": ">=8.19.3" } }, @@ -130,9 +132,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -223,9 +225,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==", + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -246,12 +248,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.19", "to-fast-properties": "^2.0.0" }, "engines": { @@ -351,6 +353,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -366,6 +369,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -381,6 +385,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -396,6 +401,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -411,6 +417,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -426,6 +433,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -441,6 +449,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -456,6 +465,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -471,6 +481,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -486,6 +497,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -501,6 +513,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -516,6 +529,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -531,6 +545,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -546,6 +561,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -561,6 +577,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -576,6 +593,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -591,6 +609,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -606,6 +625,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -621,6 +641,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -636,6 +657,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -651,6 +673,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -666,6 +689,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -809,6 +833,76 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -922,7 +1016,7 @@ "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", - "devOptional": true + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -930,6 +1024,12 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "node_modules/@types/pug": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", + "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", + "dev": true + }, "node_modules/@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", @@ -1372,7 +1472,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1636,7 +1736,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -1679,7 +1779,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1687,6 +1787,14 @@ "node": ">=8" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1799,7 +1907,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "funding": [ { "type": "individual", @@ -1860,6 +1968,14 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2342,6 +2458,7 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -2987,7 +3104,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3086,6 +3203,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -3190,7 +3308,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -3461,7 +3579,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -3606,7 +3724,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -3681,7 +3799,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3728,7 +3846,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -3762,7 +3880,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.12.0" } @@ -4369,6 +4487,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, "funding": [ { "type": "github", @@ -4431,7 +4550,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -4714,13 +4833,14 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8.6" }, @@ -4732,6 +4852,7 @@ "version": "8.4.29", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -5132,7 +5253,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -5272,6 +5393,7 @@ "version": "3.28.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -5377,7 +5499,7 @@ "version": "1.66.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -5546,14 +5668,38 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/spawn-command": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", @@ -6008,6 +6154,40 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/terser": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6026,7 +6206,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -6264,6 +6444,19 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -6287,6 +6480,7 @@ "version": "4.4.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -6337,21 +6531,6 @@ } } }, - "node_modules/vite-plugin-pug-transformer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vite-plugin-pug-transformer/-/vite-plugin-pug-transformer-1.0.3.tgz", - "integrity": "sha512-cndWLK7iQE/yryjRNGJAOxPYnL7v5miMbwCXUbkP754BILh5hwJKbE10X4QKDl1X46ntIb1oBMBYKcw4NVBnkg==", - "dependencies": { - "picocolors": "^1.0.0", - "pug": "^3.0.2" - }, - "engines": { - "node": ">=12.22.0" - }, - "peerDependencies": { - "vite": "^2.5.10 || ^3.0.0 || ^4.0.0" - } - }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -6639,9 +6818,9 @@ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/highlight": { "version": "7.22.13", @@ -6713,9 +6892,9 @@ } }, "@babel/parser": { - "version": "7.22.14", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.14.tgz", - "integrity": "sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==" + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==" }, "@babel/runtime": { "version": "7.22.11", @@ -6727,12 +6906,12 @@ } }, "@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", "requires": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.19", "to-fast-properties": "^2.0.0" } }, @@ -6767,132 +6946,154 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "dev": true, "optional": true }, "@esbuild/android-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "dev": true, "optional": true }, "@esbuild/android-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "dev": true, "optional": true }, "@esbuild/darwin-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "dev": true, "optional": true }, "@esbuild/darwin-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "dev": true, "optional": true }, "@esbuild/freebsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "dev": true, "optional": true }, "@esbuild/linux-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "dev": true, "optional": true }, "@esbuild/linux-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "dev": true, "optional": true }, "@esbuild/linux-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "dev": true, "optional": true }, "@esbuild/linux-mips64el": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "dev": true, "optional": true }, "@esbuild/linux-ppc64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "dev": true, "optional": true }, "@esbuild/linux-riscv64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "dev": true, "optional": true }, "@esbuild/linux-s390x": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "dev": true, "optional": true }, "@esbuild/linux-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "dev": true, "optional": true }, "@esbuild/netbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "dev": true, "optional": true }, "@esbuild/openbsd-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "dev": true, "optional": true }, "@esbuild/sunos-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "dev": true, "optional": true }, "@esbuild/win32-arm64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "dev": true, "optional": true }, "@esbuild/win32-ia32": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "dev": true, "optional": true }, "@esbuild/win32-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "dev": true, "optional": true }, "@eslint-community/eslint-utils": { @@ -6990,6 +7191,67 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "optional": true, + "peer": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "optional": true, + "peer": true + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "optional": true, + "peer": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7094,7 +7356,7 @@ "version": "20.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", - "devOptional": true + "dev": true }, "@types/normalize-package-data": { "version": "2.4.1", @@ -7102,6 +7364,12 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "@types/pug": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", + "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", + "dev": true + }, "@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", @@ -7391,7 +7659,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -7598,7 +7866,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true + "dev": true }, "body-parser": { "version": "1.20.1", @@ -7634,11 +7902,19 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "dev": true, "requires": { "fill-range": "^7.0.1" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -7719,7 +7995,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -7763,6 +8039,14 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "dev": true }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -8131,6 +8415,7 @@ "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, "requires": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", @@ -8643,7 +8928,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -8721,6 +9006,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "optional": true }, "function-bind": { @@ -8791,7 +9077,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -8980,7 +9266,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "devOptional": true + "dev": true }, "import-fresh": { "version": "3.3.0", @@ -9089,7 +9375,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -9140,7 +9426,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true + "dev": true }, "is-finalizationregistry": { "version": "1.0.2", @@ -9172,7 +9458,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -9194,7 +9480,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true + "dev": true }, "is-number-object": { "version": "1.0.7", @@ -9657,7 +9943,8 @@ "nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -9698,7 +9985,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -9903,18 +10190,20 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true + "dev": true }, "postcss": { "version": "8.4.29", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "dev": true, "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -10206,7 +10495,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -10300,6 +10589,7 @@ "version": "3.28.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", "integrity": "sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==", + "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -10361,7 +10651,7 @@ "version": "1.66.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", - "devOptional": true, + "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -10487,10 +10777,31 @@ "is-fullwidth-code-point": "^3.0.0" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, "spawn-command": { "version": "0.0.2", @@ -10835,6 +11146,30 @@ } } }, + "terser": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", + "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "optional": true, + "peer": true + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -10850,7 +11185,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -11022,6 +11357,12 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -11042,6 +11383,7 @@ "version": "4.4.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, "requires": { "esbuild": "^0.18.10", "fsevents": "~2.3.2", @@ -11049,15 +11391,6 @@ "rollup": "^3.27.1" } }, - "vite-plugin-pug-transformer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vite-plugin-pug-transformer/-/vite-plugin-pug-transformer-1.0.3.tgz", - "integrity": "sha512-cndWLK7iQE/yryjRNGJAOxPYnL7v5miMbwCXUbkP754BILh5hwJKbE10X4QKDl1X46ntIb1oBMBYKcw4NVBnkg==", - "requires": { - "picocolors": "^1.0.0", - "pug": "^3.0.2" - } - }, "void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", diff --git a/package.json b/package.json index 2046ed33c..93d1234a9 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "engines": { - "node": ">=v16.19.1", + "node": "v16.19.1", "npm": ">=8.19.3" }, "scripts": { @@ -15,6 +15,7 @@ }, "devDependencies": { "@types/express": "^4.17.17", + "@types/pug": "^2.0.6", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", @@ -24,9 +25,10 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "uuid": "^9.0.1", "vite": "^4.4.5" }, "dependencies": { - "vite-plugin-pug-transformer": "^1.0.3" + "pug": "^3.0.2" } } diff --git a/src/404.html b/src/404.html deleted file mode 100644 index 0caf80630..000000000 --- a/src/404.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/500.html b/src/500.html deleted file mode 100644 index 429fba24f..000000000 --- a/src/500.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/chats-and-chat.html b/src/chats-and-chat.html deleted file mode 100644 index 73bc09822..000000000 --- a/src/chats-and-chat.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/components/btn/btn.scss b/src/components/Button/Button.scss similarity index 100% rename from src/components/btn/btn.scss rename to src/components/Button/Button.scss diff --git a/src/components/Button/Button.tmp.pug b/src/components/Button/Button.tmp.pug new file mode 100644 index 000000000..bd2c8044a --- /dev/null +++ b/src/components/Button/Button.tmp.pug @@ -0,0 +1 @@ +button.btn text diff --git a/src/components/Button/Button.ts b/src/components/Button/Button.ts new file mode 100644 index 000000000..c3ad80a4a --- /dev/null +++ b/src/components/Button/Button.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Button.tmp.pug"; + +export default class Button extends Block { + constructor(props) { + super('button', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/btn/btn.pug b/src/components/btn/btn.pug deleted file mode 100644 index 361310f68..000000000 --- a/src/components/btn/btn.pug +++ /dev/null @@ -1,30 +0,0 @@ -mixin btn(text, mods, isInput) - - //- Принимает: - //- text {string} - текст кнопки - //- mods {string} - список модификаторов - //- isInput {bool} - флаг «это тег input» - //- Вызов: - +btn('Кнопка-ссылка')(href='/') - есть href, это точно ссылка - +btn('Кнопка-input', '', true) - есть флаг isInput, это input - +btn('Кнопка-button', 'success') - нет href, нет isInput — это button - - - - var allMods = ''; - if(typeof(mods) !== 'undefined' && mods) { - var modsList = mods.split(','); - for (var i = 0; i < modsList.length; i++) { - allMods = allMods + ' btn--' + modsList[i].trim(); - } - } - - if (attributes.href) - a.btn(class=allMods)&attributes(attributes)!= text - block - - else if (typeof(isInput) !== 'undefined' && isInput) - input.btn(class=allMods, value=text, type='button')&attributes(attributes) - - else - button.btn(class=allMods)&attributes(attributes)!= text - block diff --git a/src/core/Block.js b/src/core/Block.js new file mode 100644 index 000000000..779eb2815 --- /dev/null +++ b/src/core/Block.js @@ -0,0 +1,217 @@ +/* eslint-disable */ + +import EventBus from "./EventBus"; +import { v4 as uuid } from "uuid"; + +export default class Block { + static EVENTS = { + INIT: "init", + FLOW_CDM: "flow:component-did-mount", + FLOW_CDU: "flow:component-did-update", + FLOW_RENDER: "flow:render", + }; + + _element = null; + _meta = null; + _id = null; + + constructor(tagName = "div", propsAndChildren = {}) { + const { children, props } = this._getChildren(propsAndChildren); + const eventBus = new EventBus(); + + this.children = children; + this._meta = { + tagName, + props, + }; + + if (props.withId) { + this._id = uuid(); + this.props = this._makePropsProxy({...props, __id: this._id}); + } else { + this.props = this._makePropsProxy(props); + } + + this.eventBus = () => eventBus; + this._registerEvents(eventBus); + + eventBus.emit(Block.EVENTS.INIT); + } + + _registerEvents(eventBus) { + eventBus.on(Block.EVENTS.INIT, this.init.bind(this)); + eventBus.on(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); + eventBus.on(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); + eventBus.on(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); + } + + _unregisterEvents(eventBus) { + eventBus.off(Block.EVENTS.INIT, this.init.bind(this)); + eventBus.off(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); + eventBus.off(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); + eventBus.off(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); + } + + _getChildren(propsAndChildren) { + const children = {}; + const props = {}; + + Object.entries(propsAndChildren).forEach(([key, value]) => { + if (value instanceof Block) { + children[key] = value; + } else { + props[key] = value; + } + }) + + return { children, props }; + } + + init() { + console.log('init'); + this._createResources(); + this.eventBus().emit(Block.EVENTS.FLOW_RENDER); + } + + _createResources() { + const { tagName } = this._meta; + this._element = this._createDocumentElement(tagName); + } + + _createDocumentElement(tagName) { + const element = document.createElement(tagName); + if (this._id) { + element.dataset.id = this._id; + } + + return element; + } + + _componentDidMount() { + console.log('_componentDidMount'); + this.componentDidMount(); + // this.eventBus().emit(Block.EVENTS.FLOW_RENDER); + } + + // Может переопределять пользователь, необязательно трогать + componentDidMount(oldProps) { + console.log('componentDidMount'); + + dispatchComponentDidMoun(); + } + + dispatchComponentDidMoun() { + console.log('dispatchComponentDidMoun'); + this.eventBus().emit(Block.EVENTS.FLOW_CDM); + } + + _componentDidUpdate(oldProps, newProps) { + console.log('_componentDidUpdate'); + const response = this.componentDidUpdate(oldProps, newProps); + } + + // Может переопределять пользователь, необязательно трогать + componentDidUpdate(oldProps, newProps) { + console.log('componentDidUpdate'); + console.log(oldProps); + console.log(newProps); + // this.eventBus().emit(Block.EVENTS.FLOW_RENDER); + // return true; + + + if (true) { + return true; + } + + return false; + } + + setProps = newProps => { + console.log('setProps'); + if (!newProps) { + return; + } + + // this.eventBus().emit(Block.EVENTS.FLOW_CDU, this.props, newProps); + // Object.assign(this.props, newProps); + // this.eventBus().emit(Block.EVENTS.FLOW_CDU); + }; + + get element() { + return this._element; + } + + _render() { + const block = this.render(); + + this._removeEvents(); + + this._element.innerHTML = block; + + this._addEvents(); + } + + // Может переопределять пользователь, необязательно трогать + render() { + console.log('render'); + } + + compile(template, props) { + const propsAndStubs = {...props}; + + Object.entries(this.children).forEach(([key, child]) => { + propsAndStubs[key] = `
`; + }) + + console.log(propsAndStubs); + + return template(propsAndStubs); + } + + _addEvents() { + const {events = new Map()} = this.props; + + events.forEach((eventFun, eventName) => { + this._element.addEventListener(eventName, eventFun); + }) + } + + _removeEvents() { + const {events = new Map()} = this.props; + + events.forEach((eventFun, eventName) => { + this._element.removeEventListener(eventName, eventFun); + }) + } + + getContent() { + return this.element; + } + + _makePropsProxy(props) { + // Можно и так передать this + // Такой способ больше не применяется с приходом ES6+ + const self = this; + const proxyProps = new Proxy(props, { + set(target, prop, newValue) { + if (prop.indexOf('_') === 0) { + throw new Error('Permission denied'); + } + + target[prop] = newValue; + self.eventBus().emit(Block.EVENTS.FLOW_CDU); + + return true; + }, + deleteProperty() { + throw new Error('Permission denied'); + }, + }) + + return proxyProps; + } + + show() {} + + hide() {} +} diff --git a/src/core/EventBus.ts b/src/core/EventBus.ts new file mode 100644 index 000000000..fbf969f66 --- /dev/null +++ b/src/core/EventBus.ts @@ -0,0 +1,44 @@ +export default class EventBus { + listeners: Map; + + constructor() { + this.listeners = new Map(); + } + + on(event: string, curCallback: Function) { + const { listeners } = this; + const callbacks = listeners.get(event); + + if (callbacks) { + callbacks.push(curCallback); + } else { + listeners.set(event, [curCallback]); + } + + return this; + } + + off(event: string, curCallback: Function) { + const { listeners } = this; + const callbacks = listeners.get(event); + + if (!callbacks) { + throw new Error(`event ${event} not exist`); + } + + listeners.set(event, callbacks.filter((callback) => curCallback !== callback)); + + return this; + } + + emit(event: string, ...args: number[]) { + const { listeners } = this; + const callbacks = listeners.get(event); + + if (!callbacks) { + throw new Error(`event ${event} not exist`); + } + + callbacks.forEach((callback) => callback(args)); + } +} diff --git a/src/core/index.js b/src/core/index.js new file mode 100644 index 000000000..f03cb4c2f --- /dev/null +++ b/src/core/index.js @@ -0,0 +1,7 @@ +import EventBus from './EventBus'; +import Block from './Block'; + +export { + Block, + EventBus, +}; diff --git a/src/index.html b/src/index.html index 0350a15f5..a4251a4ba 100644 --- a/src/index.html +++ b/src/index.html @@ -1,2 +1,11 @@ - - + + + + + Chats + + +
+ + + diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..2fdd32322 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,11 @@ +import Button from "./components/Button/Button"; + +const button = new Button({ + text: 'Click me', +}) + +document.addEventListener('DOMContentLoaded', () => { + const app = document.getElementById('app'); + + app.innerHTML = button; +}) diff --git a/src/layout/main.pug b/src/layout/main.pug deleted file mode 100644 index e7431595a..000000000 --- a/src/layout/main.pug +++ /dev/null @@ -1,19 +0,0 @@ -include ./mixins.pug - -doctype html -html(class='page', lang='en') - head - meta(charset='utf-8') - meta(name='viewport', content='width=device-width, initial-scale=1') - - link(rel='apple-touch-icon', sizes='180x180', href='img/favicon/apple-touch-icon.png') - link(rel='icon', type='image/png', sizes='32x32', href='img/favicon/favicon-32x32.png') - link(rel='icon', type='image/png', sizes='16x16', href='img/favicon/favicon-16x16.png') - - block meta - title Home - - body - //main.page__content - main - block content diff --git a/src/layout/mixins.pug b/src/layout/mixins.pug deleted file mode 100644 index 9a2f68326..000000000 --- a/src/layout/mixins.pug +++ /dev/null @@ -1,3 +0,0 @@ -include ../components/btn/btn.pug -include ../components/field-text/field-text.pug -include ../components/form/form.pug \ No newline at end of file diff --git a/src/pages/registration/registration.tmp.pug b/src/pages/registration/registration.tmp.pug new file mode 100644 index 000000000..b1eb73fa0 --- /dev/null +++ b/src/pages/registration/registration.tmp.pug @@ -0,0 +1,20 @@ +form.form + h1.form__title Sign in + + .form__field + label.field-text + span.field-text__name Login: + span.field-text__input-wrap + input.field-text__input(type='text', name='login') + + .form__field + label.field-text + span.field-text__name Password: + span.field-text__input-wrap + input.field-text__input(type='password', name='password') + + .form__field.form__field--accent + button.btn.btn--w-100.btn--big(type='button') Sign in + + .form__field.t-right + a.link(href='#') Sign up diff --git a/src/pages/registration/registration.ts b/src/pages/registration/registration.ts new file mode 100644 index 000000000..647480a0c --- /dev/null +++ b/src/pages/registration/registration.ts @@ -0,0 +1,15 @@ +// import { compileClient } from 'pug'; +// // import { Block } from '../../core/index'; + +// const template = 'p #{name} is a #{occupation}'; +// const data = { name: 'John Doe', occupation: 'gardener' }; + +// // export default class RegistrationPage extends Block { +// // render() { +// // return compileClient(template, data); +// // } +// // } + +// const res = compileClient(template, data); + +// export { res }; diff --git a/src/registration.html b/src/registration.html deleted file mode 100644 index e110b6360..000000000 --- a/src/registration.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/style.ts b/src/style.ts deleted file mode 100644 index 894fafc7b..000000000 --- a/src/style.ts +++ /dev/null @@ -1 +0,0 @@ -import './scss/style.scss'; \ No newline at end of file diff --git a/src/user-editing-password.html b/src/user-editing-password.html deleted file mode 100644 index f4aee4b0c..000000000 --- a/src/user-editing-password.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/user-editing-settings.html b/src/user-editing-settings.html deleted file mode 100644 index 62f6ac9a6..000000000 --- a/src/user-editing-settings.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/user-settings.html b/src/user-settings.html deleted file mode 100644 index 85ca8e567..000000000 --- a/src/user-settings.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/vite-plugin-pug-precompile.ts b/vite-plugin-pug-precompile.ts new file mode 100644 index 000000000..870136f7c --- /dev/null +++ b/vite-plugin-pug-precompile.ts @@ -0,0 +1,22 @@ +import { PluginOption } from "vite"; +import pug from "pug"; + +export default function pugPrecompile(): PluginOption { + const fileRegexp = /\.pug$/; + + return { + name: 'vite-plugin-pug-precompile', + transform(src, id) { + if (fileRegexp.test(id)) { + const code = ` + ${pug.compileClient(src)}; + export default template; + `; + + return { code } + } + + return undefined; + }, + } +} diff --git a/vite.config.ts b/vite.config.ts index 4215779e4..6bf5a05d4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,30 +1,16 @@ import { resolve } from 'path'; import { defineConfig } from "vite"; // eslint-disable-line +import pugPrecompile from './vite-plugin-pug-precompile'; -import vitePugPlugin from 'vite-plugin-pug-transformer'; - -const locals = { bundler: 'Vite' }; const root = resolve(__dirname, 'src'); export default defineConfig({ root, base: '', - plugins: [vitePugPlugin({ pugLocals: locals })], build: { outDir: resolve(__dirname, 'build'), emptyOutDir: true, - rollupOptions: { - input: { - singIn: resolve(root, 'index.html'), - registration: resolve(root, 'registration.html'), - chatsAndChat: resolve(root, 'chats-and-chat.html'), - userSettings: resolve(root, 'user-settings.html'), - userEditingSettings: resolve(root, 'user-editing-settings.html'), - userEditingPassword: resolve(root, 'user-editing-password.html'), - 404: resolve(root, '404.html'), - 500: resolve(root, '500.html'), - }, - }, }, publicDir: resolve(__dirname, 'static'), + plugins: [pugPrecompile()], }); From 5758263ef35a46d36193adfdbfca7fe8c7d430a2 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 15:55:28 +0300 Subject: [PATCH 15/43] Work done --- .eslintrc.json | 10 +- .stylelintrc.json | 3 +- _proxyProps.js | 68 ------ package-lock.json | 21 +- package.json | 5 +- src/404/404.ts | 15 ++ src/404/index.html | 12 + src/500/500.ts | 15 ++ src/500/index.html | 12 + src/chats-and-chat/chats-and-chat.ts | 8 + src/chats-and-chat/index.html | 12 + .../AuthorizationForm.tmp.pug | 7 + .../AuthorizationForm/AuthorizationForm.ts | 20 ++ src/components/Button/Button.tmp.pug | 2 +- src/components/Button/Button.ts | 6 +- .../EditingPasswordForm.tmp.pug | 5 + .../EditingPasswordForm.ts | 20 ++ .../EditingSettingsForm.tmp.pug | 25 ++ .../EditingSettingsForm.ts | 20 ++ .../FieldText.scss} | 15 ++ src/components/FieldText/FieldText.tmp.pug | 7 + src/components/FieldText/FieldText.ts | 34 +++ .../FieldText/FieldTextSetting.tmp.pug | 6 + src/components/Link/Link.tmp.pug | 1 + src/components/Link/Link.ts | 12 + .../RegistrationForm/RegistrationForm.tmp.pug | 11 + .../RegistrationForm/RegistrationForm.ts | 20 ++ src/components/field-text/field-text.pug | 47 ---- src/components/form/form.pug | 45 ---- src/components/form/form.scss | 28 --- src/components/index.ts | 17 ++ src/components/utils/getValuesFromForm.ts | 21 ++ src/components/utils/index.ts | 7 + src/components/utils/validateField.ts | 33 +++ src/core/Block.js | 217 ----------------- src/core/Block.ts | 228 ++++++++++++++++++ src/core/{index.js => index.ts} | 0 src/editing-password/editing-password.ts | 8 + src/editing-password/index.html | 12 + src/editing-settings/editing-settings.ts | 8 + src/editing-settings/index.html | 12 + src/index.html | 3 +- src/index.ts | 13 +- src/pages/404.pug | 16 -- src/pages/500.pug | 16 -- src/pages/Authorization/Authorization.tmp.pug | 1 + src/pages/Authorization/Authorization.ts | 52 ++++ src/pages/ChatsAndChat/ChatsAndChat.tmp.pug | 64 +++++ src/pages/ChatsAndChat/ChatsAndChat.ts | 33 +++ .../EditingPassword/EditingPassword.tmp.pug | 11 + src/pages/EditingPassword/EditingPassword.ts | 60 +++++ .../EditingSettings/EditingSettings.tmp.pug | 11 + src/pages/EditingSettings/EditingSettings.ts | 97 ++++++++ src/pages/ErrorPage/ErrorPage.tmp.pug | 7 + src/pages/ErrorPage/ErrorPage.ts | 12 + src/pages/UserSettings/UserSettings.tmp.pug | 33 +++ src/pages/UserSettings/UserSettings.ts | 25 ++ src/pages/chats-and-chat.pug | 90 ------- src/pages/index.ts | 17 ++ src/pages/registration.pug | 58 ----- src/pages/registration/registration.tmp.pug | 21 +- src/pages/registration/registration.ts | 107 +++++++- src/pages/sign-in.pug | 30 --- src/pages/user-editing-settings.pug | 41 ---- src/pages/user-settings.pug | 43 ---- src/registration/index.html | 12 + src/registration/registration.ts | 8 + src/scss/index.scss | 3 + src/scss/main.scss | 55 ++++- src/scss/style.scss | 9 - src/user-settings/index.html | 12 + src/user-settings/user-settings.ts | 8 + src/utils/index.ts | 5 + src/utils/render.ts | 11 + tsconfig.json | 3 +- types/pug.d.ts | 1 + vite.config.ts | 14 ++ 77 files changed, 1314 insertions(+), 763 deletions(-) delete mode 100644 _proxyProps.js create mode 100644 src/404/404.ts create mode 100644 src/404/index.html create mode 100644 src/500/500.ts create mode 100644 src/500/index.html create mode 100644 src/chats-and-chat/chats-and-chat.ts create mode 100644 src/chats-and-chat/index.html create mode 100644 src/components/AuthorizationForm/AuthorizationForm.tmp.pug create mode 100644 src/components/AuthorizationForm/AuthorizationForm.ts create mode 100644 src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug create mode 100644 src/components/EditingPasswordForm/EditingPasswordForm.ts create mode 100644 src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug create mode 100644 src/components/EditingSettingsForm/EditingSettingsForm.ts rename src/components/{field-text/field-text.scss => FieldText/FieldText.scss} (72%) create mode 100644 src/components/FieldText/FieldText.tmp.pug create mode 100644 src/components/FieldText/FieldText.ts create mode 100644 src/components/FieldText/FieldTextSetting.tmp.pug create mode 100644 src/components/Link/Link.tmp.pug create mode 100644 src/components/Link/Link.ts create mode 100644 src/components/RegistrationForm/RegistrationForm.tmp.pug create mode 100644 src/components/RegistrationForm/RegistrationForm.ts delete mode 100644 src/components/field-text/field-text.pug delete mode 100644 src/components/form/form.pug delete mode 100644 src/components/form/form.scss create mode 100644 src/components/index.ts create mode 100644 src/components/utils/getValuesFromForm.ts create mode 100644 src/components/utils/index.ts create mode 100644 src/components/utils/validateField.ts delete mode 100644 src/core/Block.js create mode 100644 src/core/Block.ts rename src/core/{index.js => index.ts} (100%) create mode 100644 src/editing-password/editing-password.ts create mode 100644 src/editing-password/index.html create mode 100644 src/editing-settings/editing-settings.ts create mode 100644 src/editing-settings/index.html delete mode 100644 src/pages/404.pug delete mode 100644 src/pages/500.pug create mode 100644 src/pages/Authorization/Authorization.tmp.pug create mode 100644 src/pages/Authorization/Authorization.ts create mode 100644 src/pages/ChatsAndChat/ChatsAndChat.tmp.pug create mode 100644 src/pages/ChatsAndChat/ChatsAndChat.ts create mode 100644 src/pages/EditingPassword/EditingPassword.tmp.pug create mode 100644 src/pages/EditingPassword/EditingPassword.ts create mode 100644 src/pages/EditingSettings/EditingSettings.tmp.pug create mode 100644 src/pages/EditingSettings/EditingSettings.ts create mode 100644 src/pages/ErrorPage/ErrorPage.tmp.pug create mode 100644 src/pages/ErrorPage/ErrorPage.ts create mode 100644 src/pages/UserSettings/UserSettings.tmp.pug create mode 100644 src/pages/UserSettings/UserSettings.ts delete mode 100644 src/pages/chats-and-chat.pug create mode 100644 src/pages/index.ts delete mode 100644 src/pages/registration.pug delete mode 100644 src/pages/sign-in.pug delete mode 100644 src/pages/user-editing-settings.pug delete mode 100644 src/pages/user-settings.pug create mode 100644 src/registration/index.html create mode 100644 src/registration/registration.ts create mode 100644 src/scss/index.scss delete mode 100644 src/scss/style.scss create mode 100644 src/user-settings/index.html create mode 100644 src/user-settings/user-settings.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/render.ts create mode 100644 types/pug.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index 9061692da..165b37538 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,14 @@ "no-console": 0, "import/extensions": 0, "quotes": 0, - "semi": 0 + "semi": 0, + "no-underscore-dangle": 0, + "no-tabs": 0, + "lines-between-class-members": 0, + "class-methods-use-this": 0, + "no-undef": 0, + "no-param-reassign": 0, + "import/prefer-default-export": 0, + "import/no-extraneous-dependencies": 0 } } diff --git a/.stylelintrc.json b/.stylelintrc.json index eff256099..5d5ff9fcf 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,3 +1,4 @@ { - "extends": "stylelint-config-standard-scss" + "extends": "stylelint-config-standard-scss", + "ignoreFiles": ["build/*", "node_modules/*", "static/*"] } diff --git a/_proxyProps.js b/_proxyProps.js deleted file mode 100644 index d28d8bbac..000000000 --- a/_proxyProps.js +++ /dev/null @@ -1,68 +0,0 @@ -const props = { - name: 'Abby', - chat: 'the last of us. Part II', - getChat() { - this._privateMethod(); - }, - _privateMethod() { - console.log(this._privateProp); - }, - __privateMethodToo() {}, - _privateProp: 'Нельзя получить просто так', -}; - -const proxyProps = new Proxy(props, { - get(o, name) { - if (name.search('_') !== -1) { - // console.log('Нет прав'); - // return false; - } - - return o[name]; - // return o[name]; - }, - set(o, name, newValue) { - if (name.search('_') !== -1) { - throw new Error('Нет прав'); - } - - o[name] = newValue; - - return true; - }, - deleteProperty(o, name) { - if (name.search('_') !== -1) { - throw new Error('Нет прав'); - } - - return true; - }, -}); - -// proxyProps.getChat(); -// delete proxyProps.chat; - -// proxyProps.newProp = 2; -// console.log(proxyProps.newProp); - -try { - proxyProps._newPrivateProp = 'Super game'; -} catch (error) { - console.log(error); -} - -console.log(props); - -// try { -// delete proxyProps._privateProp; -// } catch (error) { -// console.log(error); // Error: Нет прав -// } - -/* - * Вывод в консоль следующий: -Нельзя получить просто так -2 -Error: Нет прав -Error: Нет прав -*/ diff --git a/package-lock.json b/package-lock.json index 2b92ab99c..5a0c0ac7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,13 @@ "name": "messenger", "version": "0.0.0", "dependencies": { - "pug": "^3.0.2" + "pug": "^3.0.2", + "uuid": "^9.0.1" }, "devDependencies": { "@types/express": "^4.17.17", "@types/pug": "^2.0.6", + "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", @@ -22,7 +24,6 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", - "uuid": "^9.0.1", "vite": "^4.4.5" }, "engines": { @@ -1069,6 +1070,12 @@ "@types/node": "*" } }, + "node_modules/@types/uuid": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz", + "integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", @@ -6448,7 +6455,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -7409,6 +7415,12 @@ "@types/node": "*" } }, + "@types/uuid": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.4.tgz", + "integrity": "sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==", + "dev": true + }, "@typescript-eslint/eslint-plugin": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz", @@ -11360,8 +11372,7 @@ "uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/package.json b/package.json index 93d1234a9..3b0406ca9 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@types/express": "^4.17.17", "@types/pug": "^2.0.6", + "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", @@ -25,10 +26,10 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", - "uuid": "^9.0.1", "vite": "^4.4.5" }, "dependencies": { - "pug": "^3.0.2" + "pug": "^3.0.2", + "uuid": "^9.0.1" } } diff --git a/src/404/404.ts b/src/404/404.ts new file mode 100644 index 000000000..2433ffdea --- /dev/null +++ b/src/404/404.ts @@ -0,0 +1,15 @@ +import { render } from "../utils/index"; +import { ErrorPage } from "../pages/index"; + +import "../scss/index.scss"; + +const props = { + title: '404', + text: 'who seeks will always find', + linkText: 'go to chats page', + linkHref: '/chats-and-chat/', +} + +const page = new ErrorPage(props); + +render(page); diff --git a/src/404/index.html b/src/404/index.html new file mode 100644 index 000000000..cb37bcf87 --- /dev/null +++ b/src/404/index.html @@ -0,0 +1,12 @@ + + + + + + 404 page + + +
+ + + diff --git a/src/500/500.ts b/src/500/500.ts new file mode 100644 index 000000000..4b36001e8 --- /dev/null +++ b/src/500/500.ts @@ -0,0 +1,15 @@ +import { render } from "../utils/index"; +import { ErrorPage } from "../pages/index"; + +import "../scss/index.scss"; + +const props = { + title: '500', + text: 'something went wrong', + linkText: 'go to chats page', + linkHref: '/chats-and-chat/', +} + +const page = new ErrorPage(props); + +render(page); diff --git a/src/500/index.html b/src/500/index.html new file mode 100644 index 000000000..96bda3a4c --- /dev/null +++ b/src/500/index.html @@ -0,0 +1,12 @@ + + + + + + 500 page + + +
+ + + diff --git a/src/chats-and-chat/chats-and-chat.ts b/src/chats-and-chat/chats-and-chat.ts new file mode 100644 index 000000000..2db5caf47 --- /dev/null +++ b/src/chats-and-chat/chats-and-chat.ts @@ -0,0 +1,8 @@ +import { render } from "../utils/index"; +import { ChatsAndChat } from "../pages/index"; + +import "../scss/index.scss"; + +const page = new ChatsAndChat(); + +render(page); diff --git a/src/chats-and-chat/index.html b/src/chats-and-chat/index.html new file mode 100644 index 000000000..9955f2bb3 --- /dev/null +++ b/src/chats-and-chat/index.html @@ -0,0 +1,12 @@ + + + + + + Chats and chat page + + +
+ + + diff --git a/src/components/AuthorizationForm/AuthorizationForm.tmp.pug b/src/components/AuthorizationForm/AuthorizationForm.tmp.pug new file mode 100644 index 000000000..034d78a4b --- /dev/null +++ b/src/components/AuthorizationForm/AuthorizationForm.tmp.pug @@ -0,0 +1,7 @@ +form.form + if (title) + h1.form__title= title + .form__field!= fieldLogin + .form__field!= fieldPassword + .form__field.form__field--accent!= sendBtn + .form__field.t-right!= link diff --git a/src/components/AuthorizationForm/AuthorizationForm.ts b/src/components/AuthorizationForm/AuthorizationForm.ts new file mode 100644 index 000000000..346ae2484 --- /dev/null +++ b/src/components/AuthorizationForm/AuthorizationForm.ts @@ -0,0 +1,20 @@ +import { Block } from "../../core/index"; +import template from "./AuthorizationForm.tmp.pug"; +import { getValuesFromForm } from "../utils/index"; + +export default class AuthorizationForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: object) => getValuesFromForm(event, this)], + ]), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Button/Button.tmp.pug b/src/components/Button/Button.tmp.pug index bd2c8044a..05c97b708 100644 --- a/src/components/Button/Button.tmp.pug +++ b/src/components/Button/Button.tmp.pug @@ -1 +1 @@ -button.btn text +button(class=className, type=type, form=form)= text diff --git a/src/components/Button/Button.ts b/src/components/Button/Button.ts index c3ad80a4a..a4c786a57 100644 --- a/src/components/Button/Button.ts +++ b/src/components/Button/Button.ts @@ -1,9 +1,11 @@ import { Block } from "../../core/index"; import template from "./Button.tmp.pug"; +import "./Button.scss"; + export default class Button extends Block { - constructor(props) { - super('button', props); + constructor(props?: object) { + super('div', props); } render() { diff --git a/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug b/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug new file mode 100644 index 000000000..c99ac1ada --- /dev/null +++ b/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug @@ -0,0 +1,5 @@ +form#userSettingsForm.user-settings__form + ul.user-settings__list + li.user-settings__list-item!= currentPassword + li.user-settings__list-item!= newPassword + li.user-settings__list-item!= repeatNewPassword diff --git a/src/components/EditingPasswordForm/EditingPasswordForm.ts b/src/components/EditingPasswordForm/EditingPasswordForm.ts new file mode 100644 index 000000000..facbb6277 --- /dev/null +++ b/src/components/EditingPasswordForm/EditingPasswordForm.ts @@ -0,0 +1,20 @@ +import { Block } from "../../core/index"; +import template from "./EditingPasswordForm.tmp.pug"; +import { getValuesFromForm } from "../utils/index"; + +export default class EditingPasswordForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: object) => getValuesFromForm(event, this)], + ]), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug b/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug new file mode 100644 index 000000000..63528fb32 --- /dev/null +++ b/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug @@ -0,0 +1,25 @@ +form#userSettingsForm.user-settings__form + ul.user-settings__list + li.user-settings__list-item!= nickname + li.user-settings__list-item!= firstName + li.user-settings__list-item!= secondName + li.user-settings__list-item!= email + li.user-settings__list-item!= phone + + //ul.user-settings__list + li.user-settings__list-item + label.user-settings__list-item-name(for="display_name") Nickname: + input.user-settings__list-item-value.t-right(id="display_name" type="text" name="display_name" value="user name") + li.user-settings__list-item + label.user-settings__list-item-name(for="first_name") First name: + input.user-settings__list-item-value.t-right(id="first_name" type="text" name="first_name" value="first name") + li.user-settings__list-item + label.user-settings__list-item-name(for="second_name") Second name: + input.user-settings__list-item-value.t-right(id="second_name" type="text" name="second_name" value="second name") + li.user-settings__list-item + label.user-settings__list-item-name(for="email") Email: + input.user-settings__list-item-value.t-right(id="email" type="text" name="email" value="test@test.ru") + li.user-settings__list-item + label.user-settings__list-item-name(for="phone") Phone: + input.user-settings__list-item-value.t-right(id="phone" type="text" name="phone" value="+7 (000) 000-00-00") + //input(type="file", name="avatar", hidden) diff --git a/src/components/EditingSettingsForm/EditingSettingsForm.ts b/src/components/EditingSettingsForm/EditingSettingsForm.ts new file mode 100644 index 000000000..199368c04 --- /dev/null +++ b/src/components/EditingSettingsForm/EditingSettingsForm.ts @@ -0,0 +1,20 @@ +import { Block } from "../../core/index"; +import template from "./EditingSettingsForm.tmp.pug"; +import { getValuesFromForm } from "../utils/index"; + +export default class EditingSettingsForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: object) => getValuesFromForm(event, this)], + ]), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/field-text/field-text.scss b/src/components/FieldText/FieldText.scss similarity index 72% rename from src/components/field-text/field-text.scss rename to src/components/FieldText/FieldText.scss index 27435d690..23ff0d704 100644 --- a/src/components/field-text/field-text.scss +++ b/src/components/FieldText/FieldText.scss @@ -24,6 +24,10 @@ } &__help-text { + display: none; + margin-top: 8px; + font-size: 12px; + color: #333; } &--white { @@ -44,4 +48,15 @@ border-radius: 50px; } } + + &--invalid { + #{$block-name}__input { + box-shadow: var(--on-error); + color: tomato; + } + + #{$block-name}__help-text { + display: block; + } + } } diff --git a/src/components/FieldText/FieldText.tmp.pug b/src/components/FieldText/FieldText.tmp.pug new file mode 100644 index 000000000..1523c9432 --- /dev/null +++ b/src/components/FieldText/FieldText.tmp.pug @@ -0,0 +1,7 @@ +label.field-text(class=mods) + if(typeof(title) !== 'undefined' && title) + span.field-text__name= title + span.field-text__input-wrap + input.field-text__input(type=type, name=name, value=value, data-pattern=pattern placeholder=placeholder, autocomplete="off") + if(typeof(helpText) !== 'undefined' && helpText) + span.field-text__help-text= helpText diff --git a/src/components/FieldText/FieldText.ts b/src/components/FieldText/FieldText.ts new file mode 100644 index 000000000..b0b0f5e0e --- /dev/null +++ b/src/components/FieldText/FieldText.ts @@ -0,0 +1,34 @@ +import { Block } from "../../core/index"; +import template from "./FieldText.tmp.pug"; +import templateSetting from "./FieldTextSetting.tmp.pug"; +import { validateField } from "../utils/index"; + +import "./FieldText.scss"; + +export default class FieldText extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['blur', validateField], + ]), + } + + super('div', newProps); + } + + public value() { + return this.element.querySelector('input').value; + } + + public validate() { + const input = this.element.querySelector('input'); + validateField(input); + } + + render() { + const isSettingTmp = this.props.tmp; + + return this.compile(isSettingTmp ? templateSetting : template, this.props); + } +} diff --git a/src/components/FieldText/FieldTextSetting.tmp.pug b/src/components/FieldText/FieldTextSetting.tmp.pug new file mode 100644 index 000000000..8ecad9bd5 --- /dev/null +++ b/src/components/FieldText/FieldTextSetting.tmp.pug @@ -0,0 +1,6 @@ +.field-text + if(typeof(title) !== 'undefined' && title) + label.user-settings__list-item-name(for=name)= title + input.user-settings__list-item-value.t-right(id=name, type=type, name=name, value=value, data-pattern=pattern, placeholder=placeholder) + if(typeof(helpText) !== 'undefined' && helpText) + span.field-text__help-text= helpText diff --git a/src/components/Link/Link.tmp.pug b/src/components/Link/Link.tmp.pug new file mode 100644 index 000000000..205d5c9ba --- /dev/null +++ b/src/components/Link/Link.tmp.pug @@ -0,0 +1 @@ +a.link(class=className, href=href)= text diff --git a/src/components/Link/Link.ts b/src/components/Link/Link.ts new file mode 100644 index 000000000..b63fcbc4d --- /dev/null +++ b/src/components/Link/Link.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Link.tmp.pug"; + +export default class Link extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/RegistrationForm/RegistrationForm.tmp.pug b/src/components/RegistrationForm/RegistrationForm.tmp.pug new file mode 100644 index 000000000..0448cc793 --- /dev/null +++ b/src/components/RegistrationForm/RegistrationForm.tmp.pug @@ -0,0 +1,11 @@ +form.form + if (title) + h1.form__title= title + .form__field!= fieldFirstName + .form__field!= fieldSecondName + .form__field!= fieldEmail + .form__field!= fieldPhone + .form__field!= fieldLogin + .form__field!= fieldPassword + .form__field.form__field--accent!= sendBtn + .form__field.t-right!= link diff --git a/src/components/RegistrationForm/RegistrationForm.ts b/src/components/RegistrationForm/RegistrationForm.ts new file mode 100644 index 000000000..7979493bc --- /dev/null +++ b/src/components/RegistrationForm/RegistrationForm.ts @@ -0,0 +1,20 @@ +import { Block } from "../../core/index"; +import template from "./RegistrationForm.tmp.pug"; +import { getValuesFromForm } from "../utils/index"; + +export default class RegistrationForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: object) => getValuesFromForm(event, this)], + ]), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/field-text/field-text.pug b/src/components/field-text/field-text.pug deleted file mode 100644 index 23345c704..000000000 --- a/src/components/field-text/field-text.pug +++ /dev/null @@ -1,47 +0,0 @@ -mixin field-text(props) - - //- Принимает: - //- props { - //- title: '' {string} - текст с названием (выводится над полем) - //- isTextarea: false {bool} - флаг input/textarea - //- helpText: '' {string} - пояснение под полем - //- mods: '' {string} - модификаторы блока - //- val: '' {string} - текст в поле - //- attrs: {object} - любые атрибуты для input/textarea - //- type: {string} - //- placeholder: {string} - //- Вызов: - +field-text({ - title: 'Название', - isTextarea: true, - helpText: 'Подсказка', - mods: '', - val: '', - attrs: { - name: 'comment', - } - }) - - - - if(typeof(props) === 'undefined') { - var props = {}; - } - var allMods = ''; - if(typeof(props.mods) !== 'undefined' && props.mods) { - var modsList = props.mods.split(','); - for (var i = 0; i < modsList.length; i++) { - allMods = allMods + ' field-text--' + modsList[i].trim(); - } - } - - label.field-text(class=allMods)&attributes(attributes) - if(typeof(props.title) !== 'undefined' && props.title) - span.field-text__name!= props.title - span.field-text__input-wrap - if(typeof(props.isTextarea) !== 'undefined' && props.isTextarea) - textarea.field-text__input&attributes(props.attrs)= props.val - else - input.field-text__input(type=(typeof(props.attrs) !== 'undefined' && props.attrs.type) ? props.attrs.type : 'text', value=props.val)&attributes(props.attrs) - if(typeof(props.helpText) !== 'undefined' && props.helpText) - span.field-text__help-text!= props.helpText - block diff --git a/src/components/form/form.pug b/src/components/form/form.pug deleted file mode 100644 index a3c425577..000000000 --- a/src/components/form/form.pug +++ /dev/null @@ -1,45 +0,0 @@ -mixin form(title, mods) - - //- Принимает: - //- title {string} - form title - //- mods {string} - список модификаторов - //- Вызов: - +form('title', 'mods') - +form-field() - some html - +form-field() - some html - - - - var allMods = ''; - if(typeof(mods) !== 'undefined' && mods) { - var modsList = mods.split(','); - for (var i = 0; i < modsList.length; i++) { - allMods = allMods + ' form--' + modsList[i].trim(); - } - } - - form.form(class=allMods)&attributes(attributes) - if (title) - h1.form__title= title - block - -mixin form-field(mods) - - //- Принимает: - //- mods {string} - список модификаторов - //- Вызов: - +form-field() - some html - - - - var allMods = ''; - if(typeof(mods) !== 'undefined' && mods) { - var modsList = mods.split(','); - for (var i = 0; i < modsList.length; i++) { - allMods = allMods + ' form__field--' + modsList[i].trim(); - } - } - - .form__field(class=allMods)&attributes(attributes) - block diff --git a/src/components/form/form.scss b/src/components/form/form.scss deleted file mode 100644 index c6c755485..000000000 --- a/src/components/form/form.scss +++ /dev/null @@ -1,28 +0,0 @@ -.form { - $block-name: &; - - margin-left: auto; - margin-right: auto; - padding: 50px; - width: 400px; - max-width: 100%; - border-radius: var(--b-radius); - background-color: var(--bg-whiteSmoke); - - &__title { - margin-bottom: 70px; - font-size: 35px; - font-weight: 500; - text-align: center; - } - - &__field { - & + & { - margin-top: 20px; - } - - & + &--accent { - margin-top: 40px; - } - } -} diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 000000000..bfd40e712 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,17 @@ +import AuthorizationForm from "./AuthorizationForm/AuthorizationForm"; +import RegistrationForm from "./RegistrationForm/RegistrationForm"; +import EditingSettingsForm from "./EditingSettingsForm/EditingSettingsForm" +import EditingPasswordForm from "./EditingPasswordForm/EditingPasswordForm"; +import FieldText from "./FieldText/FieldText"; +import Button from "./Button/Button"; +import Link from "./Link/Link"; + +export { + AuthorizationForm, + RegistrationForm, + EditingSettingsForm, + EditingPasswordForm, + FieldText, + Button, + Link, +} diff --git a/src/components/utils/getValuesFromForm.ts b/src/components/utils/getValuesFromForm.ts new file mode 100644 index 000000000..973d954b4 --- /dev/null +++ b/src/components/utils/getValuesFromForm.ts @@ -0,0 +1,21 @@ +type Event = { + preventDefault: Function +} + +type Instance = { + children: PropertyKey, +} + +export default function getValuesFromForm(event: Event, instance: Instance) { + event.preventDefault(); + const formValues: Record = {}; + + Object.entries(instance.children).forEach(([name, child]: [string, any]) => { + if (child.value) { + formValues[name] = child.value(); + child.validate(); + } + }) + + console.log(formValues); +} diff --git a/src/components/utils/index.ts b/src/components/utils/index.ts new file mode 100644 index 000000000..4674dd817 --- /dev/null +++ b/src/components/utils/index.ts @@ -0,0 +1,7 @@ +import validateField from "./validateField"; +import getValuesFromForm from "./getValuesFromForm"; + +export { + validateField, + getValuesFromForm, +}; diff --git a/src/components/utils/validateField.ts b/src/components/utils/validateField.ts new file mode 100644 index 000000000..e7290dbc4 --- /dev/null +++ b/src/components/utils/validateField.ts @@ -0,0 +1,33 @@ +interface DOMStringMap { + [name: string]: string | undefined +} + +interface HTMLInputElement { + value: string, + dataset: DOMStringMap, + closest: Function, +} + +interface EventTarget { + target: HTMLInputElement, +} + +export default function validateField(event: EventTarget): void { + const input = event.target || event; + const { value } = input; + const { pattern } = input.dataset; + + if (!pattern) { + return; + } + + const parent = input.closest('.field-text'); + const errClass = 'field-text--invalid'; + const regExp = new RegExp(pattern, 'g'); + + if (!regExp.test(value)) { + parent?.classList.add(errClass); + } else { + parent?.classList.remove(errClass); + } +} diff --git a/src/core/Block.js b/src/core/Block.js deleted file mode 100644 index 779eb2815..000000000 --- a/src/core/Block.js +++ /dev/null @@ -1,217 +0,0 @@ -/* eslint-disable */ - -import EventBus from "./EventBus"; -import { v4 as uuid } from "uuid"; - -export default class Block { - static EVENTS = { - INIT: "init", - FLOW_CDM: "flow:component-did-mount", - FLOW_CDU: "flow:component-did-update", - FLOW_RENDER: "flow:render", - }; - - _element = null; - _meta = null; - _id = null; - - constructor(tagName = "div", propsAndChildren = {}) { - const { children, props } = this._getChildren(propsAndChildren); - const eventBus = new EventBus(); - - this.children = children; - this._meta = { - tagName, - props, - }; - - if (props.withId) { - this._id = uuid(); - this.props = this._makePropsProxy({...props, __id: this._id}); - } else { - this.props = this._makePropsProxy(props); - } - - this.eventBus = () => eventBus; - this._registerEvents(eventBus); - - eventBus.emit(Block.EVENTS.INIT); - } - - _registerEvents(eventBus) { - eventBus.on(Block.EVENTS.INIT, this.init.bind(this)); - eventBus.on(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); - eventBus.on(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); - eventBus.on(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); - } - - _unregisterEvents(eventBus) { - eventBus.off(Block.EVENTS.INIT, this.init.bind(this)); - eventBus.off(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); - eventBus.off(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); - eventBus.off(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); - } - - _getChildren(propsAndChildren) { - const children = {}; - const props = {}; - - Object.entries(propsAndChildren).forEach(([key, value]) => { - if (value instanceof Block) { - children[key] = value; - } else { - props[key] = value; - } - }) - - return { children, props }; - } - - init() { - console.log('init'); - this._createResources(); - this.eventBus().emit(Block.EVENTS.FLOW_RENDER); - } - - _createResources() { - const { tagName } = this._meta; - this._element = this._createDocumentElement(tagName); - } - - _createDocumentElement(tagName) { - const element = document.createElement(tagName); - if (this._id) { - element.dataset.id = this._id; - } - - return element; - } - - _componentDidMount() { - console.log('_componentDidMount'); - this.componentDidMount(); - // this.eventBus().emit(Block.EVENTS.FLOW_RENDER); - } - - // Может переопределять пользователь, необязательно трогать - componentDidMount(oldProps) { - console.log('componentDidMount'); - - dispatchComponentDidMoun(); - } - - dispatchComponentDidMoun() { - console.log('dispatchComponentDidMoun'); - this.eventBus().emit(Block.EVENTS.FLOW_CDM); - } - - _componentDidUpdate(oldProps, newProps) { - console.log('_componentDidUpdate'); - const response = this.componentDidUpdate(oldProps, newProps); - } - - // Может переопределять пользователь, необязательно трогать - componentDidUpdate(oldProps, newProps) { - console.log('componentDidUpdate'); - console.log(oldProps); - console.log(newProps); - // this.eventBus().emit(Block.EVENTS.FLOW_RENDER); - // return true; - - - if (true) { - return true; - } - - return false; - } - - setProps = newProps => { - console.log('setProps'); - if (!newProps) { - return; - } - - // this.eventBus().emit(Block.EVENTS.FLOW_CDU, this.props, newProps); - // Object.assign(this.props, newProps); - // this.eventBus().emit(Block.EVENTS.FLOW_CDU); - }; - - get element() { - return this._element; - } - - _render() { - const block = this.render(); - - this._removeEvents(); - - this._element.innerHTML = block; - - this._addEvents(); - } - - // Может переопределять пользователь, необязательно трогать - render() { - console.log('render'); - } - - compile(template, props) { - const propsAndStubs = {...props}; - - Object.entries(this.children).forEach(([key, child]) => { - propsAndStubs[key] = `
`; - }) - - console.log(propsAndStubs); - - return template(propsAndStubs); - } - - _addEvents() { - const {events = new Map()} = this.props; - - events.forEach((eventFun, eventName) => { - this._element.addEventListener(eventName, eventFun); - }) - } - - _removeEvents() { - const {events = new Map()} = this.props; - - events.forEach((eventFun, eventName) => { - this._element.removeEventListener(eventName, eventFun); - }) - } - - getContent() { - return this.element; - } - - _makePropsProxy(props) { - // Можно и так передать this - // Такой способ больше не применяется с приходом ES6+ - const self = this; - const proxyProps = new Proxy(props, { - set(target, prop, newValue) { - if (prop.indexOf('_') === 0) { - throw new Error('Permission denied'); - } - - target[prop] = newValue; - self.eventBus().emit(Block.EVENTS.FLOW_CDU); - - return true; - }, - deleteProperty() { - throw new Error('Permission denied'); - }, - }) - - return proxyProps; - } - - show() {} - - hide() {} -} diff --git a/src/core/Block.ts b/src/core/Block.ts new file mode 100644 index 000000000..3ee89534b --- /dev/null +++ b/src/core/Block.ts @@ -0,0 +1,228 @@ +import { v4 as uuid } from "uuid"; +import EventBus from "./EventBus"; + +// использую any, потому что не получилось типизировать по хорошему, +// а время на исходе) + +export default class Block { + children: any; + props: any; + eventBus: () => EventBus; + + static EVENTS = { + INIT: "init", + FLOW_CDM: "flow:component-did-mount", + FLOW_CDU: "flow:component-did-update", + FLOW_RENDER: "flow:render", + }; + + _element: any = null; + _meta: any = null; + _id: any = null; + + constructor(tagName = "div", propsAndChildren = {}) { + const { children, props } = this._getChildren(propsAndChildren); + const eventBus = new EventBus(); + + this.children = children; + + this._meta = { + tagName, + props, + }; + + if (props.withId) { + this._id = uuid(); + this.props = this._makePropsProxy({ ...props, __id: this._id }); + } else { + this.props = this._makePropsProxy(props); + } + + this.eventBus = () => eventBus; + + this._registerEvents(eventBus); + + eventBus.emit(Block.EVENTS.INIT); + } + + _registerEvents(eventBus: EventBus) { + eventBus.on(Block.EVENTS.INIT, this.init.bind(this)); + eventBus.on(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); + eventBus.on(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); + eventBus.on(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); + } + + _getChildren(propsAndChildren: any) { + const children: any = {}; + const props: any = {}; + + Object.entries(propsAndChildren).forEach(([key, value]) => { + if (value instanceof Block) { + children[key] = value; + } else { + props[key] = value; + } + }) + + return { children, props }; + } + + init() { + this._createResources(); + this.eventBus().emit(Block.EVENTS.FLOW_RENDER); + } + + _createResources() { + const { tagName } = this._meta; + this._element = this._createDocumentElement(tagName); + } + + _createDocumentElement(tagName: string): any { + const element = document.createElement(tagName); + if (this._id) { + element.dataset.id = this._id; + } + + return element; + } + + _componentDidMount() { + this.componentDidMount(); + + Object.values(this.children).forEach((child: any) => { + child.dispatchComponentDidMount(); + }); + } + + // Может переопределять пользователь, необязательно трогать + componentDidMount(oldProps?: any) { + console.log(oldProps); + } + + dispatchComponentDidMount() {} + + setProps = (newProps: any) => { + if (!newProps) { + return; + } + + this._componentDidUpdate(this.props, newProps); + // this.eventBus().emit(Block.EVENTS.FLOW_CDU, this.props, newProps); + // Object.assign(this.props, newProps); + // this.eventBus().emit(Block.EVENTS.FLOW_CDU); + }; + + _componentDidUpdate(oldProps: any, newProps: any) { + const response = this.componentDidUpdate(oldProps, newProps); + + if (response) { + Object.assign(oldProps, newProps); + } + } + + // Может переопределять пользователь, необязательно трогать + componentDidUpdate(oldProps: any, newProps: any) { + let update = false; + Object.keys(newProps).forEach((key) => { + if (oldProps[key] !== newProps[key]) { + update = true; + } + }) + + return update; + } + + _render() { + const block = this.render(); + + this._removeEvents(); + this._element.innerHTML = ''; + + this._element.appendChild(block); + this._addEvents(); + } + + // Может переопределять пользователь, необязательно трогать + render(): any {} + + compile(template: Function, props: any) { + if (this.children) { + const propsAndStubs = { ...props }; + + Object.entries(this.children).forEach(([key, child]: [string, any]) => { + propsAndStubs[key] = `
`; + }) + + const fragment = this._createDocumentElement('template'); + fragment.innerHTML = template(propsAndStubs); + + Object.values(this.children).forEach((child: any) => { + const stub = fragment.content.querySelector(`[data-id="${child._id}"]`); + stub.replaceWith(child.getContent()); + }); + + return fragment.content; + } + + return template(props); + } + + _addEvents() { + const { events = new Map() } = this.props; + + events.forEach((eventFun: Function, eventName: string) => { + if (eventName === 'blur') { + this._element.querySelector('input')?.addEventListener(eventName, eventFun); + } else { + this._element.addEventListener(eventName, eventFun); + } + }) + } + + _removeEvents() { + const { events = new Map() } = this.props; + + events.forEach((eventFun: Function, eventName: string) => { + if (eventName === 'blur') { + this._element.querySelector('input')?.removeEventListener(eventName, eventFun); + } else { + this._element.removeEventListener(eventName, eventFun); + } + + // if (eventName === 'submit') { + // this._element.querySelector('form')?.removeEventListener(eventName, eventFun); + // } else { + // this._element.removeEventListener(eventName, eventFun); + // } + }) + } + + getContent() { + return this.element; + } + + get element() { + return this._element; + } + + _makePropsProxy(props: any) { + const self = this; + const proxyProps = new Proxy(props, { + set(target: any, prop: string, newValue) { + if (prop.indexOf('_') === 0) { + throw new Error('Permission denied'); + } + + target[prop] = newValue; + self.eventBus().emit(Block.EVENTS.INIT); + + return true; + }, + deleteProperty() { + throw new Error('Permission denied'); + }, + }) + + return proxyProps; + } +} diff --git a/src/core/index.js b/src/core/index.ts similarity index 100% rename from src/core/index.js rename to src/core/index.ts diff --git a/src/editing-password/editing-password.ts b/src/editing-password/editing-password.ts new file mode 100644 index 000000000..012a7c9c8 --- /dev/null +++ b/src/editing-password/editing-password.ts @@ -0,0 +1,8 @@ +import { render } from "../utils/index"; +import { EditingPassword } from "../pages/index"; + +import "../scss/index.scss"; + +const page = new EditingPassword(); + +render(page); diff --git a/src/editing-password/index.html b/src/editing-password/index.html new file mode 100644 index 000000000..5bdc0f74b --- /dev/null +++ b/src/editing-password/index.html @@ -0,0 +1,12 @@ + + + + + + Editing password page + + +
+ + + diff --git a/src/editing-settings/editing-settings.ts b/src/editing-settings/editing-settings.ts new file mode 100644 index 000000000..94e454f26 --- /dev/null +++ b/src/editing-settings/editing-settings.ts @@ -0,0 +1,8 @@ +import { render } from "../utils/index"; +import { EditingSettings } from "../pages/index"; + +import "../scss/index.scss"; + +const page = new EditingSettings(); + +render(page); diff --git a/src/editing-settings/index.html b/src/editing-settings/index.html new file mode 100644 index 000000000..c4daa207a --- /dev/null +++ b/src/editing-settings/index.html @@ -0,0 +1,12 @@ + + + + + + Editing settings page + + +
+ + + diff --git a/src/index.html b/src/index.html index a4251a4ba..1e268a943 100644 --- a/src/index.html +++ b/src/index.html @@ -1,8 +1,9 @@ + - Chats + Authorization page
diff --git a/src/index.ts b/src/index.ts index 2fdd32322..de1c14736 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,8 @@ -import Button from "./components/Button/Button"; +import { render } from "./utils/index"; +import { Authorization } from "./pages/index"; -const button = new Button({ - text: 'Click me', -}) +import "./scss/index.scss"; -document.addEventListener('DOMContentLoaded', () => { - const app = document.getElementById('app'); +const page = new Authorization(); - app.innerHTML = button; -}) +render(page); diff --git a/src/pages/404.pug b/src/pages/404.pug deleted file mode 100644 index 2b60f3bbe..000000000 --- a/src/pages/404.pug +++ /dev/null @@ -1,16 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = '404 page'; - - title= pageName - meta(name='description', content=pageName) - -block content - - section.error-page - h1.error-page__title 404 - p.error-page__description who seeks will always find - .error-page__bottom - a.error-page__link.link(href="chats-and-chat.html") go to chats page - diff --git a/src/pages/500.pug b/src/pages/500.pug deleted file mode 100644 index 7c9677bf0..000000000 --- a/src/pages/500.pug +++ /dev/null @@ -1,16 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = '500 page'; - - title= pageName - meta(name='description', content=pageName) - -block content - - section.error-page - h1.error-page__title 500 - p.error-page__description something went wrong - .error-page__bottom - a.error-page__link.link(href="chats-and-chat.html") go to chats page - diff --git a/src/pages/Authorization/Authorization.tmp.pug b/src/pages/Authorization/Authorization.tmp.pug new file mode 100644 index 000000000..d6145b8c0 --- /dev/null +++ b/src/pages/Authorization/Authorization.tmp.pug @@ -0,0 +1 @@ +.page__content!= authForm diff --git a/src/pages/Authorization/Authorization.ts b/src/pages/Authorization/Authorization.ts new file mode 100644 index 000000000..84ebb16fa --- /dev/null +++ b/src/pages/Authorization/Authorization.ts @@ -0,0 +1,52 @@ +import { Block } from "../../core/index"; +import template from "./Authorization.tmp.pug"; +import { + AuthorizationForm, + FieldText, + Button, + Link, +} from "../../components/index"; + +const authForm = new AuthorizationForm({ + withId: true, + title: 'Sign in', + fieldLogin: new FieldText({ + withId: true, + title: 'Login:', + type: 'text', + name: 'login', + helpText: ` + от 3 до 20 символов, латиница, может содержать цифры, + но не состоять из них, без пробелов, без спецсимволов (допустимы дефис и нижнее подчёркивание) + `, + pattern: '(?=^.{3,20}$)[a-zA-Z_-]+[0-9_-a-zA-Z]*', + }), + fieldPassword: new FieldText({ + withId: true, + title: 'Password:', + type: 'password', + name: 'password', + value: '', + helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', + pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*[0-9]).*', + }), + sendBtn: new Button({ + className: 'btn btn--w-100 btn--big', + type: 'submit', + text: 'Sign in', + }), + link: new Link({ + href: '/registration/', + text: 'Sign up', + }), +}) + +export default class Authorization extends Block { + constructor(props?: object) { + super('div', { ...props, authForm }); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug b/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug new file mode 100644 index 000000000..9533c251c --- /dev/null +++ b/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug @@ -0,0 +1,64 @@ +.chats-and-chat + aside.sidebar + .sidebar__f + form.search!= fieldSearch + .sidebar__s + .sidebar__s-inner + .chats + each val in [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15] + article.chat(tabindex="0") + .chat__f + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .chat__s + .chat__s-f + h6.name Chat name + time.chat__time 10:45 + .chat__s-s + p.chat__last-message last message last message last message last message last message last message + + .sidebar__t + .user-information + .user-information__f + .user-information__f-f + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .user-information__f-s + h6.name User name + + .user-information__s + button.settings(type="button") ... + + .chat-area + .chat-area__f + .chat-area__f-f + .chat-area__info + .chat-area__info-l + .avatar + img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") + .chat-area__info-r + h6.name Chat name + + .chat-area__f-s + button.settings(type="button") ... + + .chat-area__s + .messages-area + .messages-area__f + .messages-area__conversation + each val in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + .messages-area__conversation-item.messages-area__conversation-received + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + + .messages-area__conversation-item.messages-area__conversation-sent + .messages-area__conversation-message + | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + + .messages-area__s + .messages-area__s-inner!= fieldMessage + .messages-area__buttons + button.settings(type="button") ... + button.settings(type="button") ... diff --git a/src/pages/ChatsAndChat/ChatsAndChat.ts b/src/pages/ChatsAndChat/ChatsAndChat.ts new file mode 100644 index 000000000..6de8f8968 --- /dev/null +++ b/src/pages/ChatsAndChat/ChatsAndChat.ts @@ -0,0 +1,33 @@ +import { Block } from "../../core/index"; +import template from "./ChatsAndChat.tmp.pug"; +import { + FieldText, +} from "../../components/index"; + +const fieldSearch = new FieldText({ + withId: true, + mods: 'field-text--center field-text--white', + type: 'text', + name: 'search', + value: '', + placeholder: 'search', +}) + +const fieldMessage = new FieldText({ + withId: true, + mods: 'field-text--main', + type: 'text', + name: 'message', + value: '', + placeholder: 'Type a message', +}) + +export default class ChatsAndChat extends Block { + constructor(props?: object) { + super('div', { ...props, fieldSearch, fieldMessage }); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/EditingPassword/EditingPassword.tmp.pug b/src/pages/EditingPassword/EditingPassword.tmp.pug new file mode 100644 index 000000000..534777381 --- /dev/null +++ b/src/pages/EditingPassword/EditingPassword.tmp.pug @@ -0,0 +1,11 @@ +.modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name= userName + + .user-settings__s!= userSettings + .user-settings__t!= saveBtn diff --git a/src/pages/EditingPassword/EditingPassword.ts b/src/pages/EditingPassword/EditingPassword.ts new file mode 100644 index 000000000..4d7572fbb --- /dev/null +++ b/src/pages/EditingPassword/EditingPassword.ts @@ -0,0 +1,60 @@ +import { Block } from "../../core/index"; +import template from "./EditingPassword.tmp.pug"; +import { + EditingPasswordForm, + FieldText, + Button, +} from "../../components/index"; + +export default class EditingPassword extends Block { + constructor(props?: object) { + const newProps = { + ...props, + userName: 'User name', + userSettings: new EditingPasswordForm({ + currentPassword: new FieldText({ + withId: true, + title: 'Current password:', + type: 'password', + name: 'old_password', + value: 'jzuXon8ZOT', + helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', + pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', + tmp: 'setting', + }), + newPassword: new FieldText({ + withId: true, + title: 'New password:', + type: 'password', + name: 'new_password', + value: '', + helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', + pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', + tmp: 'setting', + }), + repeatNewPassword: new FieldText({ + withId: true, + title: 'Repeat new password:', + type: 'password', + name: 'repeat_password', + value: '', + helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', + pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', + tmp: 'setting', + }), + }), + saveBtn: new Button({ + className: 'link', + type: 'submit', + form: 'userSettingsForm', + text: 'Save password', + }), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/EditingSettings/EditingSettings.tmp.pug b/src/pages/EditingSettings/EditingSettings.tmp.pug new file mode 100644 index 000000000..534777381 --- /dev/null +++ b/src/pages/EditingSettings/EditingSettings.tmp.pug @@ -0,0 +1,11 @@ +.modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name= userName + + .user-settings__s!= userSettings + .user-settings__t!= saveBtn diff --git a/src/pages/EditingSettings/EditingSettings.ts b/src/pages/EditingSettings/EditingSettings.ts new file mode 100644 index 000000000..fbce677dc --- /dev/null +++ b/src/pages/EditingSettings/EditingSettings.ts @@ -0,0 +1,97 @@ +import { Block } from "../../core/index"; +import template from "./EditingSettings.tmp.pug"; +import { + EditingSettingsForm, + FieldText, + Button, +} from "../../components/index"; + +export default class EditingSettings extends Block { + constructor(props?: object) { + const newProps = { + ...props, + userName: 'User name', + userSettings: new EditingSettingsForm({ + nickname: new FieldText({ + withId: true, + title: 'Nickname:', + type: 'text', + name: 'display_name', + value: 'userNickName', + helpText: ` + латиница или кириллица, без пробелов и без цифр, + нет спецсимволов (допустим только дефис) + `, + pattern: '^[a-zA-Zа-яА-Я-]+$', + tmp: 'setting', + }), + firstName: new FieldText({ + withId: true, + title: 'First name:', + type: 'text', + name: 'first_name', + value: 'Firstname', + helpText: ` + латиница или кириллица, первая буква должна быть заглавной, + без пробелов и без цифр, нет спецсимволов (допустим только дефис) + `, + pattern: '(?=^[A-ZА-Я])[a-zA-Zа-яА-Я-]+$', + tmp: 'setting', + }), + secondName: new FieldText({ + withId: true, + title: 'Second name:', + type: 'text', + name: 'second_name', + value: 'Sirstname', + helpText: ` + латиница или кириллица, первая буква должна быть заглавной, + без пробелов и без цифр, нет спецсимволов (допустим только дефис) + `, + pattern: '(?=^[A-ZА-Я])[a-zA-Zа-яА-Я-]+$', + tmp: 'setting', + }), + email: new FieldText({ + withId: true, + title: 'Email:', + type: 'text', + inputmode: 'email', + name: 'email', + value: 'test@test.ru', + helpText: ` + латиница, может включать цифры и спецсимволы вроде дефиса и подчёркивания, + обязательно должна быть «собака» (@) и точка после неё, + но перед точкой обязательно должны быть буквы + `, + pattern: '^[a-zA-Z\\d_-]+@[a-z]+\\.[a-z]{2,3}$', + tmp: 'setting', + }), + phone: new FieldText({ + withId: true, + title: 'Phone:', + type: 'text', + inputmode: 'tel', + name: 'phone', + value: '+70000000000', + helpText: ` + от 10 до 15 символов, состоит из цифр, может начинается с плюса. + `, + pattern: '(?=^.{10,15}$)\\+?[0-9]+$', + tmp: 'setting', + }), + }), + saveBtn: new Button({ + className: 'link', + type: 'submit', + form: 'userSettingsForm', + text: 'Save settings', + }), + } + + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/ErrorPage/ErrorPage.tmp.pug b/src/pages/ErrorPage/ErrorPage.tmp.pug new file mode 100644 index 000000000..342bbab9d --- /dev/null +++ b/src/pages/ErrorPage/ErrorPage.tmp.pug @@ -0,0 +1,7 @@ +.page__content + section.error-page + h1.error-page__title= title + p.error-page__description= text + .error-page__bottom + a.error-page__link.link(href=linkHref)= linkText + diff --git a/src/pages/ErrorPage/ErrorPage.ts b/src/pages/ErrorPage/ErrorPage.ts new file mode 100644 index 000000000..1796546d7 --- /dev/null +++ b/src/pages/ErrorPage/ErrorPage.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./ErrorPage.tmp.pug"; + +export default class ErrorPage extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/UserSettings/UserSettings.tmp.pug b/src/pages/UserSettings/UserSettings.tmp.pug new file mode 100644 index 000000000..79f236a9c --- /dev/null +++ b/src/pages/UserSettings/UserSettings.tmp.pug @@ -0,0 +1,33 @@ +.modal + .modal__inner + button.modal__close(title="Close modal") + .modal__content + section.user-settings + .user-settings__f + .user-settings__avatar + h2.user-settings__name= userName + + .user-settings__s + ul.user-settings__list + li.user-settings__list-item + span.user-settings__list-item-name Nickname: + span.user-settings__list-item-value user name + li.user-settings__list-item + span.user-settings__list-item-name First name: + span.user-settings__list-item-value first name + li.user-settings__list-item + span.user-settings__list-item-name Second name: + span.user-settings__list-item-value second name + li.user-settings__list-item + span.user-settings__list-item-name Email: + span.user-settings__list-item-value test@test.ru + li.user-settings__list-item + span.user-settings__list-item-name Phone: + span.user-settings__list-item-value +7 (000) 000-00-00 + li.user-settings__list-item + span.user-settings__list-item-name Login: + span.user-settings__list-item-value mylogin + + .user-settings__t + | !{linkToSettings} + | !{linkToPassword} diff --git a/src/pages/UserSettings/UserSettings.ts b/src/pages/UserSettings/UserSettings.ts new file mode 100644 index 000000000..9775596bb --- /dev/null +++ b/src/pages/UserSettings/UserSettings.ts @@ -0,0 +1,25 @@ +import { Block } from "../../core/index"; +import template from "./UserSettings.tmp.pug"; +import { Link } from "../../components/index"; + +export default class ChatsAndChat extends Block { + constructor(props?: object) { + const newProps = { + ...props, + userName: 'User name', + linkToSettings: new Link({ + href: '/editing-settings/', + text: 'Change settings', + }), + linkToPassword: new Link({ + href: '/editing-password/', + text: 'Change password', + }), + } + super('div', newProps); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/chats-and-chat.pug b/src/pages/chats-and-chat.pug deleted file mode 100644 index 4f13737c8..000000000 --- a/src/pages/chats-and-chat.pug +++ /dev/null @@ -1,90 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'Chats and chat'; - - title= pageName - meta(name='description', content=pageName) - -block content - - .chats-and-chat - aside.sidebar - .sidebar__f - form.search - +field-text({ - mods: 'white, center', - val: '', - attrs: { - name: 'search', - placeholder: 'search', - } - }) - - .sidebar__s - .sidebar__s-inner - .chats - each val in [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15] - article.chat(tabindex="0") - .chat__f - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .chat__s - .chat__s-f - h6.name Chat name - time.chat__time 10:45 - .chat__s-s - p.chat__last-message last message last message last message last message last message last message - - .sidebar__t - .user-information - .user-information__f - .user-information__f-f - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .user-information__f-s - h6.name User name - - .user-information__s - button.settings(type="button") ... - - .chat-area - .chat-area__f - .chat-area__f-f - .chat-area__info - .chat-area__info-l - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .chat-area__info-r - h6.name Chat name - - .chat-area__f-s - button.settings(type="button") ... - - .chat-area__s - .messages-area - .messages-area__f - .messages-area__conversation - each val in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - .messages-area__conversation-item.messages-area__conversation-received - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - - .messages-area__conversation-item.messages-area__conversation-sent - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - - .messages-area__s - .messages-area__s-inner - +field-text({ - mods: 'main', - attrs: { - name: 'message', - placeholder: 'Type a message', - } - }) - .messages-area__buttons - button.settings(type="button") ... - button.settings(type="button") ... diff --git a/src/pages/index.ts b/src/pages/index.ts new file mode 100644 index 000000000..e3f957b3f --- /dev/null +++ b/src/pages/index.ts @@ -0,0 +1,17 @@ +import Authorization from "./Authorization/Authorization"; +import Registration from "./Registration/Registration"; +import ErrorPage from "./ErrorPage/ErrorPage"; +import ChatsAndChat from "./ChatsAndChat/ChatsAndChat"; +import UserSettings from "./UserSettings/UserSettings" +import EditingSettings from "./EditingSettings/EditingSettings" +import EditingPassword from "./EditingPassword/EditingPassword"; + +export { + Authorization, + Registration, + ErrorPage, + ChatsAndChat, + UserSettings, + EditingSettings, + EditingPassword, +} diff --git a/src/pages/registration.pug b/src/pages/registration.pug deleted file mode 100644 index 43c765c8b..000000000 --- a/src/pages/registration.pug +++ /dev/null @@ -1,58 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'Registration page'; - - title= pageName - meta(name='description', content=pageName) - -block content - - +form('Sign up') - +form-field() - +field-text({ - title: 'First name:', - attrs: { - name: 'first_name', - } - }) - +form-field() - +field-text({ - title: 'Second name:', - attrs: { - name: 'second_name', - } - }) - +form-field() - +field-text({ - title: 'Email:', - attrs: { - name: 'email', - } - }) - +form-field() - +field-text({ - title: 'Phone:', - attrs: { - name: 'phone', - } - }) - +form-field() - +field-text({ - title: 'Login:', - attrs: { - name: 'login', - } - }) - +form-field() - +field-text({ - title: 'Password:', - attrs: { - type: 'password', - name: 'password', - } - }) - +form-field('accent') - +btn('Create profile', 'w-100, big')(type="button") - +form-field().t-right - a.link(href="index.html") Sign in diff --git a/src/pages/registration/registration.tmp.pug b/src/pages/registration/registration.tmp.pug index b1eb73fa0..1c3aa7595 100644 --- a/src/pages/registration/registration.tmp.pug +++ b/src/pages/registration/registration.tmp.pug @@ -1,20 +1 @@ -form.form - h1.form__title Sign in - - .form__field - label.field-text - span.field-text__name Login: - span.field-text__input-wrap - input.field-text__input(type='text', name='login') - - .form__field - label.field-text - span.field-text__name Password: - span.field-text__input-wrap - input.field-text__input(type='password', name='password') - - .form__field.form__field--accent - button.btn.btn--w-100.btn--big(type='button') Sign in - - .form__field.t-right - a.link(href='#') Sign up +.page__content!= registratonForm diff --git a/src/pages/registration/registration.ts b/src/pages/registration/registration.ts index 647480a0c..edd4c0221 100644 --- a/src/pages/registration/registration.ts +++ b/src/pages/registration/registration.ts @@ -1,15 +1,98 @@ -// import { compileClient } from 'pug'; -// // import { Block } from '../../core/index'; +import { Block } from "../../core/index"; +import template from "./Registration.tmp.pug"; +import { + RegistrationForm, + FieldText, + Button, + Link, +} from "../../components/index"; -// const template = 'p #{name} is a #{occupation}'; -// const data = { name: 'John Doe', occupation: 'gardener' }; +const registratonForm = new RegistrationForm({ + withId: true, + title: 'Sign up', + fieldFirstName: new FieldText({ + withId: true, + title: 'First name:', + type: 'text', + name: 'first_name', + helpText: ` + латиница или кириллица, первая буква должна быть заглавной, + без пробелов и без цифр, нет спецсимволов (допустим только дефис) + `, + pattern: '(?=^[A-ZА-Я])[a-zA-Zа-яА-Я-]+$', + }), + fieldSecondName: new FieldText({ + withId: true, + title: 'Second name:', + type: 'text', + name: 'second_name', + helpText: ` + латиница или кириллица, первая буква должна быть заглавной, + без пробелов и без цифр, нет спецсимволов (допустим только дефис) + `, + pattern: '(?=^[A-ZА-Я])[a-zA-Zа-яА-Я-]+$', + }), + fieldEmail: new FieldText({ + withId: true, + title: 'Email:', + type: 'text', + inputmode: 'email', + name: 'email', + helpText: ` + латиница, может включать цифры и спецсимволы вроде дефиса и подчёркивания, + обязательно должна быть «собака» (@) и точка после неё, + но перед точкой обязательно должны быть буквы + `, + pattern: '^[a-zA-Z\\d_-]+@[a-z]+\\.[a-z]{2,3}$', + }), + fieldPhone: new FieldText({ + withId: true, + title: 'Phone:', + type: 'text', + inputmode: 'tel', + name: 'phone', + helpText: ` + от 10 до 15 символов, состоит из цифр, может начинается с плюса. + `, + pattern: '(?=^.{10,15}$)\\+?[0-9]+$', + }), + fieldLogin: new FieldText({ + withId: true, + title: 'Login:', + type: 'text', + name: 'login', + helpText: ` + от 3 до 20 символов, латиница, может содержать цифры, + но не состоять из них, без пробелов, без спецсимволов (допустимы дефис и нижнее подчёркивание) + `, + pattern: '(?=^.{3,20}$)[a-zA-Z_-]+[\\d_-a-zA-Z]*', + }), + fieldPassword: new FieldText({ + withId: true, + title: 'Password:', + type: 'password', + name: 'password', + value: '', + helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', + pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', + }), + sendBtn: new Button({ + className: 'btn btn--w-100 btn--big', + type: 'submit', + text: 'Sign in', + }), + link: new Link({ + href: '/', + text: 'Sign in', + }), +}) -// // export default class RegistrationPage extends Block { -// // render() { -// // return compileClient(template, data); -// // } -// // } +export default class Registration extends Block { + constructor(props?: object) { + super('div', { ...props, registratonForm }); + } -// const res = compileClient(template, data); - -// export { res }; + render() { + return this.compile(template, this.props); + } +} diff --git a/src/pages/sign-in.pug b/src/pages/sign-in.pug deleted file mode 100644 index 9d1ab23de..000000000 --- a/src/pages/sign-in.pug +++ /dev/null @@ -1,30 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'Sign in'; - - title= pageName - meta(name='description', content=pageName) - -block content - - +form('Sign in') - +form-field() - +field-text({ - title: 'Login:', - attrs: { - name: 'login', - } - }) - +form-field() - +field-text({ - title: 'Password:', - attrs: { - type: 'password', - name: 'password', - } - }) - +form-field('accent') - +btn('Sign in', 'w-100, big')(type="button") - +form-field().t-right - a.link(href="registration.html") Sign up diff --git a/src/pages/user-editing-settings.pug b/src/pages/user-editing-settings.pug deleted file mode 100644 index e4c6e1848..000000000 --- a/src/pages/user-editing-settings.pug +++ /dev/null @@ -1,41 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'User editing settings'; - - title= pageName - meta(name='description', content=pageName) - -block content - - .modal - .modal__inner - button.modal__close(title="Close modal") - .modal__content - section.user-settings - .user-settings__f - .user-settings__avatar - h2.user-settings__name User name - - .user-settings__s - form#userSettingsForm.user-settings__form - ul.user-settings__list - li.user-settings__list-item - label.user-settings__list-item-name(for="display_name") Nickname: - input.user-settings__list-item-value.t-right(id="display_name" type="text" name="display_name" value="user name") - li.user-settings__list-item - label.user-settings__list-item-name(for="first_name") First name: - input.user-settings__list-item-value.t-right(id="first_name" type="text" name="first_name" value="first name") - li.user-settings__list-item - label.user-settings__list-item-name(for="second_name") Second name: - input.user-settings__list-item-value.t-right(id="second_name" type="text" name="second_name" value="second name") - li.user-settings__list-item - label.user-settings__list-item-name(for="email") Email: - input.user-settings__list-item-value.t-right(id="email" type="text" name="email" value="test@test.ru") - li.user-settings__list-item - label.user-settings__list-item-name(for="phone") Phone: - input.user-settings__list-item-value.t-right(id="phone" type="text" name="phone" value="+7 (000) 000-00-00") - input(type="file", name="avatar", hidden) - - .user-settings__t - button.link(type="button") Save settings diff --git a/src/pages/user-settings.pug b/src/pages/user-settings.pug deleted file mode 100644 index 5e86ffffa..000000000 --- a/src/pages/user-settings.pug +++ /dev/null @@ -1,43 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'User settings'; - - title= pageName - meta(name='description', content=pageName) - -block content - - .modal - .modal__inner - button.modal__close(title="Close modal") - .modal__content - section.user-settings - .user-settings__f - .user-settings__avatar - h2.user-settings__name User name - - .user-settings__s - ul.user-settings__list - li.user-settings__list-item - span.user-settings__list-item-name Nickname: - span.user-settings__list-item-value user name - li.user-settings__list-item - span.user-settings__list-item-name First name: - span.user-settings__list-item-value first name - li.user-settings__list-item - span.user-settings__list-item-name Second name: - span.user-settings__list-item-value second name - li.user-settings__list-item - span.user-settings__list-item-name Email: - span.user-settings__list-item-value test@test.ru - li.user-settings__list-item - span.user-settings__list-item-name Phone: - span.user-settings__list-item-value +7 (000) 000-00-00 - li.user-settings__list-item - span.user-settings__list-item-name Login: - span.user-settings__list-item-value mylogin - - .user-settings__t - button.link(type="button") Change settings - button.link(type="button") Change password diff --git a/src/registration/index.html b/src/registration/index.html new file mode 100644 index 000000000..ba9f4ce2d --- /dev/null +++ b/src/registration/index.html @@ -0,0 +1,12 @@ + + + + + + Registration page + + +
+ + + diff --git a/src/registration/registration.ts b/src/registration/registration.ts new file mode 100644 index 000000000..a6640ec49 --- /dev/null +++ b/src/registration/registration.ts @@ -0,0 +1,8 @@ +import { render } from "../utils/index"; +import { Registration } from "../pages/index"; + +import "../scss/index.scss"; + +const page = new Registration(); + +render(page); diff --git a/src/scss/index.scss b/src/scss/index.scss new file mode 100644 index 000000000..d0a275cb0 --- /dev/null +++ b/src/scss/index.scss @@ -0,0 +1,3 @@ +@import "./reset.scss"; +@import "./main.scss"; +@import "./additions.scss"; diff --git a/src/scss/main.scss b/src/scss/main.scss index 5d971f5dc..eaebafa48 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -35,6 +35,7 @@ --h-indent: 15px; --b-radius: 5px; --on-focus: 0 0 0 2px var(--m-color-1); + --on-error: 0 0 0 2px tomato; --m-color-1: #784dd4; --m-color-1-1: #5e36b2; @@ -199,6 +200,18 @@ body { font-weight: 500; font-size: 15px; + .field-text, + > div:first-child { + width: 100%; + } + + .field-text { + display: flex; + justify-content: space-between; + align-content: center; + flex-wrap: wrap; + } + & + & { margin-top: 15px; } @@ -209,6 +222,10 @@ body { &__list-item-value { color: var(--t-l-grey-1); + + @at-root .field-text--invalid & { + color: tomato; + } } &__t { @@ -398,6 +415,7 @@ body { width: 60px; height: 60px; border-radius: 50%; + background-color: var(--t-l-grey-3); &__img { width: 100%; @@ -519,9 +537,13 @@ body { gap: var(--indent-h); width: 100%; - .field-text { + > div:first-child { width: 75%; } + + .field-text { + width: 100%; + } } &__conversation { @@ -563,3 +585,34 @@ body { gap: 5px var(--indent-h); } } + +/* ----- .form ----- */ + +.form { + $block-name: &; + + margin-left: auto; + margin-right: auto; + padding: 50px; + width: 400px; + max-width: 100%; + border-radius: var(--b-radius); + background-color: var(--bg-whiteSmoke); + + &__title { + margin-bottom: 70px; + font-size: 35px; + font-weight: 500; + text-align: center; + } + + &__field { + & + & { + margin-top: 20px; + } + + & + &--accent { + margin-top: 40px; + } + } +} diff --git a/src/scss/style.scss b/src/scss/style.scss deleted file mode 100644 index 8453c1f8f..000000000 --- a/src/scss/style.scss +++ /dev/null @@ -1,9 +0,0 @@ -@import "./reset.scss"; - -@import "./main.scss"; - -@import "../components/btn/btn.scss"; -@import "../components/field-text/field-text.scss"; -@import "../components/form/form.scss"; - -@import "./additions.scss"; diff --git a/src/user-settings/index.html b/src/user-settings/index.html new file mode 100644 index 000000000..3dc836112 --- /dev/null +++ b/src/user-settings/index.html @@ -0,0 +1,12 @@ + + + + + + User settings page + + +
+ + + diff --git a/src/user-settings/user-settings.ts b/src/user-settings/user-settings.ts new file mode 100644 index 000000000..24f43142a --- /dev/null +++ b/src/user-settings/user-settings.ts @@ -0,0 +1,8 @@ +import { render } from "../utils/index"; +import { UserSettings } from "../pages/index"; + +import "../scss/index.scss"; + +const page = new UserSettings(); + +render(page); diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 000000000..bb2b1416b --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,5 @@ +import render from "./render"; + +export { + render, +} diff --git a/src/utils/render.ts b/src/utils/render.ts new file mode 100644 index 000000000..fbc45d394 --- /dev/null +++ b/src/utils/render.ts @@ -0,0 +1,11 @@ +type Page = { + getContent: Function +} + +export default function render(page: Page) { + document.addEventListener('DOMContentLoaded', () => { + const app = document.getElementById('app'); + + app?.append(page.getContent()); + }) +} diff --git a/tsconfig.json b/tsconfig.json index 9db061ae1..dec7251c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,5 +18,6 @@ "sourceMap": true, "strictNullChecks": true, }, - "include": ["src"] + "include": ["src", "types/pug.d.ts"], + "exclude": ["node_modules", "build", "static"] } diff --git a/types/pug.d.ts b/types/pug.d.ts new file mode 100644 index 000000000..1485f02a0 --- /dev/null +++ b/types/pug.d.ts @@ -0,0 +1 @@ +declare module "*.pug"; diff --git a/vite.config.ts b/vite.config.ts index 6bf5a05d4..1f6e297fe 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,12 +4,26 @@ import pugPrecompile from './vite-plugin-pug-precompile'; const root = resolve(__dirname, 'src'); +console.log(__dirname); + export default defineConfig({ root, base: '', build: { outDir: resolve(__dirname, 'build'), emptyOutDir: true, + rollupOptions: { + input: { + index: resolve(__dirname, 'src/index.html'), + registration: resolve(__dirname, 'src/registration/index.html'), + page404: resolve(__dirname, 'src/404/index.html'), + page500: resolve(__dirname, 'src/500/index.html'), + chatsAndchat: resolve(__dirname, 'src/chats-and-chat/index.html'), + userSettings: resolve(__dirname, 'src/user-settings/index.html'), + editingSettings: resolve(__dirname, 'src/editing-settings/index.html'), + editingPassword: resolve(__dirname, 'src/editing-password/index.html'), + }, + }, }, publicDir: resolve(__dirname, 'static'), plugins: [pugPrecompile()], From c18bfa32944fb6bcb641becd2490f1c716afd5d3 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 16:00:22 +0300 Subject: [PATCH 16/43] Change readme.md --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4b82538f9..c4cb30be6 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ## Netlify links - [Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/) -- [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration) -- [Chats and chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat) -- [User settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings) -- [User editing settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-editing-settings) -- [User editing password](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-editing-password) -- [Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404) -- [Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500) +- [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration/) +- [Chats and chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat/) +- [User settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings/) +- [User editing settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/editing-settings/) +- [User editing password](https://deploy--jocular-rugelach-1c03ff.netlify.app/editing-password/) +- [Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404/) +- [Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500/) ## Установка @@ -20,14 +20,15 @@ ## Структура -- /src/layout/ - макет -- /src/layout/mixins.pug - собираем все компоненты -- /src/pages/ - шаблоны страниц -- /src/components/- компоненты +- /src/pages/ - Компоненты страниц +- /src/components/ - Компоненты +- /src/components/utils/ - Утилиты компонентов +- /src/core/- Ключевые классы - /src/scss/ - стили проекта -- /src/scss/style.scss - собираем все стили +- /src/utils/ - Утилиты ## Ключевые технологии +- typescript - шаблонизатор - pug - css препроцессор - sass From cb6b0c2e4c1d2323ed23cd6077de8e8c666ff584 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 17:34:31 +0300 Subject: [PATCH 17/43] Change paths in src/pages/index.ts --- src/pages/index.ts | 14 ++++++------ src/pages/user-editing-password.pug | 34 ----------------------------- tsconfig.json | 1 + vite.config.ts | 2 +- 4 files changed, 9 insertions(+), 42 deletions(-) delete mode 100644 src/pages/user-editing-password.pug diff --git a/src/pages/index.ts b/src/pages/index.ts index e3f957b3f..0a744adb2 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,10 +1,10 @@ -import Authorization from "./Authorization/Authorization"; -import Registration from "./Registration/Registration"; -import ErrorPage from "./ErrorPage/ErrorPage"; -import ChatsAndChat from "./ChatsAndChat/ChatsAndChat"; -import UserSettings from "./UserSettings/UserSettings" -import EditingSettings from "./EditingSettings/EditingSettings" -import EditingPassword from "./EditingPassword/EditingPassword"; +import Authorization from "./Authorization/Authorization.ts"; +import Registration from "./Registration/Registration.ts"; +import ErrorPage from "./ErrorPage/ErrorPage.ts"; +import ChatsAndChat from "./ChatsAndChat/ChatsAndChat.ts"; +import UserSettings from "./UserSettings/UserSettings.ts" +import EditingSettings from "./EditingSettings/EditingSettings.ts" +import EditingPassword from "./EditingPassword/EditingPassword.ts"; export { Authorization, diff --git a/src/pages/user-editing-password.pug b/src/pages/user-editing-password.pug deleted file mode 100644 index 6aeb92790..000000000 --- a/src/pages/user-editing-password.pug +++ /dev/null @@ -1,34 +0,0 @@ -extends ../layout/main.pug - -block meta - - const pageName = 'User editing password'; - - title= pageName - meta(name='description', content=pageName) - -block content - - .modal - .modal__inner - button.modal__close(title="Close modal") - .modal__content - section.user-settings - .user-settings__f - .user-settings__avatar - h2.user-settings__name User name - - .user-settings__s - form#userSettingsForm.user-settings__form - ul.user-settings__list - li.user-settings__list-item - label.user-settings__list-item-name(for="oldPassword") Current password: - input.user-settings__list-item-value.t-right(id="oldPassword" type="password" name="oldPassword") - li.user-settings__list-item - label.user-settings__list-item-name(for="newPassword") New password: - input.user-settings__list-item-value.t-right(id="newPassword" type="password" name="newPassword") - li.user-settings__list-item - label.user-settings__list-item-name(for="repeatPassword") Repeat new password: - input.user-settings__list-item-value.t-right(id="repeatPassword" type="password" name="repeatPassword") - - .user-settings__t - button.link(type="button") Save password diff --git a/tsconfig.json b/tsconfig.json index dec7251c9..b37ef2120 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,7 @@ "skipLibCheck": true, "sourceMap": true, "strictNullChecks": true, + "allowImportingTsExtensions": true, }, "include": ["src", "types/pug.d.ts"], "exclude": ["node_modules", "build", "static"] diff --git a/vite.config.ts b/vite.config.ts index 1f6e297fe..c7bb1985e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,5 @@ import { resolve } from 'path'; -import { defineConfig } from "vite"; // eslint-disable-line +import { defineConfig } from "vite"; import pugPrecompile from './vite-plugin-pug-precompile'; const root = resolve(__dirname, 'src'); From 8475bad7b4dd8c305fa9773854624dceab9d9026 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 17:58:33 +0300 Subject: [PATCH 18/43] Try to fix netlify error with deploy --- .eslintrc.json | 3 ++- src/pages/index.ts | 16 ++++++++-------- src/registration/registration.ts | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 165b37538..9eb6b14a3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,6 +23,7 @@ "no-undef": 0, "no-param-reassign": 0, "import/prefer-default-export": 0, - "import/no-extraneous-dependencies": 0 + "import/no-extraneous-dependencies": 0, + "import/no-unresolved": 0 } } diff --git a/src/pages/index.ts b/src/pages/index.ts index 0a744adb2..cb09cd377 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,14 +1,14 @@ -import Authorization from "./Authorization/Authorization.ts"; -import Registration from "./Registration/Registration.ts"; -import ErrorPage from "./ErrorPage/ErrorPage.ts"; -import ChatsAndChat from "./ChatsAndChat/ChatsAndChat.ts"; -import UserSettings from "./UserSettings/UserSettings.ts" -import EditingSettings from "./EditingSettings/EditingSettings.ts" -import EditingPassword from "./EditingPassword/EditingPassword.ts"; +import Authorization from "./Authorization/Authorization"; +import registration from "./registration/registration"; +import ErrorPage from "./ErrorPage/ErrorPage"; +import ChatsAndChat from "./ChatsAndChat/ChatsAndChat"; +import UserSettings from "./UserSettings/UserSettings" +import EditingSettings from "./EditingSettings/EditingSettings" +import EditingPassword from "./EditingPassword/EditingPassword"; export { Authorization, - Registration, + registration, ErrorPage, ChatsAndChat, UserSettings, diff --git a/src/registration/registration.ts b/src/registration/registration.ts index a6640ec49..e8af456d2 100644 --- a/src/registration/registration.ts +++ b/src/registration/registration.ts @@ -1,5 +1,5 @@ import { render } from "../utils/index"; -import { Registration } from "../pages/index"; +import { registration as Registration } from "../pages/index"; import "../scss/index.scss"; From a61707219ded458b59df56b37d60db2d4bf4975b Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 18:00:42 +0300 Subject: [PATCH 19/43] Try to fix netlify error with deploy --- src/pages/registration/registration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/registration/registration.ts b/src/pages/registration/registration.ts index edd4c0221..8e6857b3c 100644 --- a/src/pages/registration/registration.ts +++ b/src/pages/registration/registration.ts @@ -1,5 +1,5 @@ import { Block } from "../../core/index"; -import template from "./Registration.tmp.pug"; +import template from "./registration.tmp.pug"; import { RegistrationForm, FieldText, From 1eff39fc216790124b724f3234a9998438b30baf Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:04:00 +0300 Subject: [PATCH 20/43] Added http class, install ts in devDependencies --- .eslintrc.json | 6 ++- _http | 76 -------------------------------- package-lock.json | 5 +-- package.json | 1 + src/utils/http.ts | 107 +++++++++++++++++++++++++++++++++++++++++++++ src/utils/index.ts | 3 ++ tsconfig.json | 2 +- 7 files changed, 119 insertions(+), 81 deletions(-) delete mode 100644 _http create mode 100644 src/utils/http.ts diff --git a/.eslintrc.json b/.eslintrc.json index 9eb6b14a3..d13fb52f7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -24,6 +24,10 @@ "no-param-reassign": 0, "import/prefer-default-export": 0, "import/no-extraneous-dependencies": 0, - "import/no-unresolved": 0 + "import/no-unresolved": 0, + "arrow-body-style": 0, + "no-restricted-syntax": 0, + "no-use-before-define": 0 } } + diff --git a/_http b/_http deleted file mode 100644 index c89287cdb..000000000 --- a/_http +++ /dev/null @@ -1,76 +0,0 @@ -/* eslint-disable */ - -const METHODS = { - GET: 'GET', - POST: 'POST', - PUT: 'PUT', - DELETE: 'DELETE', -}; - -function queryStringify (data) { - let result = '?'; - - for (const [key, value] of Object.entries(data)) { - result += `${key}=${value.toString()}&`; - } - - return result.slice(0, result.length - 1); -} - -class HTTPTransport { - get = (url, options = {}) => { - const { data } = options; - return this.request((data ? `${url}${queryStringify(data)}` : url), {...options, method: METHODS.GET}); - }; - - post = () => { - return this.request(url, {...options, method: METHODS.POST}); - } - - put = () => { - return this.request(url, {...options, method: METHODS.PUT}); - } - - delete = () => { - return this.request(url, {...options, method: METHODS.DELETE}); - } - - request = (url, options) => { - const {method, headers, data, timeout = 5000} = options; - - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open(method, url); - if (headers) xhr.setRequestHeader(...headers); - - xhr.onload = () => { - resolve(xhr); - }; - - xhr.onabort = reject; - xhr.onerror = reject; - xhr.ontimeout = reject; - - if (method === METHODS.GET) { - xhr.send(); - } else { - xhr.send(JSON.stringify(data)); - } - - setTimeout(() => { - xhr.abort(); - }, timeout) - }) - }; -} - -function fetchWithRetry (url, options = {}) { - let { retries = 2 } = options; - - if (retries === 0) { - throw new Error('The number of attempts has been exhausted'); - } - - return new HTTPTransport().get(url, options) - .catch(err => fetchWithRetry(url, {...options, retries: retries - 1})) -} diff --git a/package-lock.json b/package-lock.json index 5a0c0ac7a..44f734c2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "typescript": "^5.2.2", "vite": "^4.4.5" }, "engines": { @@ -6394,7 +6395,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11327,8 +11327,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "peer": true + "dev": true }, "unbox-primitive": { "version": "1.0.2", diff --git a/package.json b/package.json index 3b0406ca9..8087769a0 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "typescript": "^5.2.2", "vite": "^4.4.5" }, "dependencies": { diff --git a/src/utils/http.ts b/src/utils/http.ts new file mode 100644 index 000000000..fdc27fb8c --- /dev/null +++ b/src/utils/http.ts @@ -0,0 +1,107 @@ +const METHODS = { + GET: 'GET', + POST: 'POST', + PUT: 'PUT', + DELETE: 'DELETE', +}; + +interface IHTTP { + get: Function, + post: Function, + put: Function, + delete: Function, + request: Function, +} + +type Options = { + method: string, + headers?: [string, string], + data?: [string, string][], + timeout?: number, + retries?: number, +} + +class HTTP implements IHTTP { + get = (url: string, options: Options = { method: METHODS.GET }) => { + let resUrl = url; + const { data } = options; + + if (data) { + resUrl = queryStringify(data); + } + + return this.request(resUrl, options); + }; + + post = (url: string, options: Options = { method: METHODS.POST }) => { + return this.request(url, options); + } + + put = (url: string, options: Options = { method: METHODS.PUT }) => { + return this.request(url, options); + } + + delete = (url: string, options: Options = { method: METHODS.DELETE }) => { + return this.request(url, options); + } + + request = (url: string, options: Options) => { + const { + method, + headers, + data, + timeout = 5000, + } = options; + + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open(method, url); + if (headers) xhr.setRequestHeader(...headers); + + xhr.onload = () => { + resolve(xhr); + }; + + xhr.onabort = reject; + xhr.onerror = reject; + xhr.ontimeout = reject; + + if (method === METHODS.GET) { + xhr.send(); + } else { + xhr.send(JSON.stringify(data)); + } + + setTimeout(() => { + xhr.abort(); + }, timeout) + }) + }; +} + +function queryStringify(data: [string, string][]): string { + let result = '?'; + + for (const [key, value] of Object.entries(data)) { + result += `${key}=${value.toString()}&`; + } + + return result.slice(0, result.length - 1); +} + +function fetchWithRetry(url: string, options: Options): unknown { + const { retries = 2 } = options; + + if (retries === 0) { + throw new Error('The number of attempts has been exhausted'); + } + + return new HTTP().get(url, options) + .catch(() => fetchWithRetry(url, { ...options, retries: retries - 1 })) +} + +export default HTTP; + +export { + fetchWithRetry, +} diff --git a/src/utils/index.ts b/src/utils/index.ts index bb2b1416b..16a0e8961 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,8 @@ import render from "./render"; +import HTTP, { fetchWithRetry } from "./http"; export { render, + HTTP, + fetchWithRetry, } diff --git a/tsconfig.json b/tsconfig.json index b37ef2120..564ec3145 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ESNext", "DOM"], + "lib": ["ESNext", "DOM", "es6"], "moduleResolution": "Node", "strict": true, "resolveJsonModule": true, From 436e1ec2cb53de78cc621b0e798045828410b113 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:13:03 +0300 Subject: [PATCH 21/43] Try to fix tsconfig for test --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 564ec3145..1b94f9f57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,7 @@ "skipLibCheck": true, "sourceMap": true, "strictNullChecks": true, - "allowImportingTsExtensions": true, + "allowImportingTsExtensions": true }, "include": ["src", "types/pug.d.ts"], "exclude": ["node_modules", "build", "static"] From ad372159f4b8a93409635995a2179a35e29d6a36 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:23:29 +0300 Subject: [PATCH 22/43] Try to fix stylelint --- src/scss/index.scss | 6 ++--- src/scss/main.scss | 65 +++++++-------------------------------------- src/scss/reset.scss | 11 +++----- 3 files changed, 16 insertions(+), 66 deletions(-) diff --git a/src/scss/index.scss b/src/scss/index.scss index d0a275cb0..45a17856d 100644 --- a/src/scss/index.scss +++ b/src/scss/index.scss @@ -1,3 +1,3 @@ -@import "./reset.scss"; -@import "./main.scss"; -@import "./additions.scss"; +@import "./reset"; +@import "./main"; +@import "./additions"; diff --git a/src/scss/main.scss b/src/scss/main.scss index eaebafa48..3ea9411dd 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -1,6 +1,6 @@ @font-face { font-display: swap; - font-family: "Roboto"; + font-family: Roboto; font-style: normal; font-weight: 100; src: url("../fonts/roboto-100.woff2") format("woff2"); @@ -8,7 +8,7 @@ @font-face { font-display: swap; - font-family: "Roboto"; + font-family: Roboto; font-style: normal; font-weight: 400; src: url("../fonts/roboto-400.woff2") format("woff2"); @@ -16,7 +16,7 @@ @font-face { font-display: swap; - font-family: "Roboto"; + font-family: Roboto; font-style: normal; font-weight: 500; src: url("../fonts/roboto-500.woff2") format("woff2"); @@ -24,7 +24,7 @@ @font-face { font-display: swap; - font-family: "Roboto"; + font-family: Roboto; font-style: normal; font-weight: 700; src: url("../fonts/roboto-700.woff2") format("woff2"); @@ -36,25 +36,21 @@ --b-radius: 5px; --on-focus: 0 0 0 2px var(--m-color-1); --on-error: 0 0 0 2px tomato; - --m-color-1: #784dd4; --m-color-1-1: #5e36b2; --m-color-1-2: #d6c4ff; --m-color-1-3: #f2ecff; --m-color-2: #2872e0; --m-color-2-1: #1e5bb4; - --t-l-grey-1: #9c9c9c; --t-l-grey-2: #d9d9d9; --t-l-grey-3: #f0f0f0; - - --bg-whiteSmoke: #f5f5f5; - + --bg-whiteSmoke: #f5f5f5; /* stylelint-disable-line */ --t-duration: 0.3s; } body { - font: 400 16px/1.5 "Roboto", sans-serif; + font: 400 16px/1.5 Roboto, sans-serif; color: #000; } @@ -97,7 +93,7 @@ body { top: 0; width: 100%; height: 100%; - background-color: rgba(0, 0, 0, 0.65); + background-color: rgb(0 0 0 / 65%); &__inner { position: relative; @@ -139,9 +135,6 @@ body { transform: translate(-50%, -50%) rotate(45deg); } } - - &__content { - } } /* ----- .user-settings ----- */ @@ -185,18 +178,12 @@ body { width: 100%; } - &__s { - } - - &__list { - } - &__list-item { display: flex; justify-content: space-between; align-content: center; padding-bottom: 7px; - border-bottom: 1px solid #eeeeee; + border-bottom: 1px solid #eee; font-weight: 500; font-size: 15px; @@ -217,9 +204,6 @@ body { } } - &__list-item-name { - } - &__list-item-value { color: var(--t-l-grey-1); @@ -259,9 +243,6 @@ body { &__bottom { margin-top: 75px; } - - &__link { - } } %d-scroll { @@ -368,9 +349,6 @@ body { margin-top: 15px; } - &__f { - } - &__s { margin-left: 15px; } @@ -378,9 +356,6 @@ body { &__s-f { display: flex; justify-content: space-between; - - .name { - } } &__time { @@ -394,7 +369,6 @@ body { &__last-message { font-size: 14px; color: var(--t-l-grey-1); - display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; @@ -439,15 +413,9 @@ body { align-items: center; } - &__f-f { - } - &__f-s { margin-left: 15px; } - - &__s { - } } /* ----- .chat-area ----- */ @@ -476,24 +444,15 @@ body { background-color: var(--t-l-grey-2); } - &__f-f { - } - &__info { display: flex; align-items: center; } - &__info-l { - } - &__info-r { margin-left: 15px; } - &__f-s { - } - &__s { padding-top: 15px; padding-bottom: 15px; @@ -546,9 +505,6 @@ body { } } - &__conversation { - } - &__conversation-item { display: flex; flex-direction: column; @@ -558,9 +514,6 @@ body { } } - &__conversation-received { - } - &__conversation-sent { align-items: flex-end; @@ -597,7 +550,7 @@ body { width: 400px; max-width: 100%; border-radius: var(--b-radius); - background-color: var(--bg-whiteSmoke); + background-color: var(--bg-whiteSmoke); /* stylelint-disable-line */ &__title { margin-bottom: 70px; diff --git a/src/scss/reset.scss b/src/scss/reset.scss index af080da18..fcfbe6d2a 100644 --- a/src/scss/reset.scss +++ b/src/scss/reset.scss @@ -8,9 +8,7 @@ - The "symbol *" part is to solve Firefox SVG sprite bug - The "html" element is excluded, otherwise a bug in Chrome breaks the CSS hyphens property (https://github.com/elad2412/the-new-css-reset/issues/36) */ -*:where( - :not(html, iframe, canvas, img, svg, video, audio):not(svg *, symbol *) - ) { +*:where(:not(html, iframe, canvas, img, svg, video, audio, svg *, symbol *)) { all: unset; display: revert; } @@ -49,7 +47,7 @@ table { /* Safari - solving issue when using user-select:none on the text input doesn't working */ input, textarea { - -webkit-user-select: auto; + user-select: auto; } /* revert the 'white-space' property for textarea elements on Safari */ @@ -59,7 +57,6 @@ textarea { /* minimum style to allow to style meter element */ meter { - -webkit-appearance: revert; appearance: revert; } @@ -86,13 +83,13 @@ meter { /* revert for bug in Chromium browsers - fix for the content editable attribute will work properly. - - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element*/ + - webkit-user-select: auto; added for Safari in case of using user-select:none on wrapper element */ :where([contenteditable]:not([contenteditable="false"])) { -moz-user-modify: read-write; -webkit-user-modify: read-write; overflow-wrap: break-word; -webkit-line-break: after-white-space; - -webkit-user-select: auto; + user-select: auto; } /* apply back the draggable feature - exist only in Chromium and Safari */ From ad6c2c381e744fe5b2e9880dd939796e78e79942 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:28:00 +0300 Subject: [PATCH 23/43] Try to fix stylelint --- src/components/FieldText/FieldText.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/FieldText/FieldText.scss b/src/components/FieldText/FieldText.scss index 23ff0d704..ba5d2c387 100644 --- a/src/components/FieldText/FieldText.scss +++ b/src/components/FieldText/FieldText.scss @@ -9,9 +9,6 @@ font-weight: 500; } - &__input-wrap { - } - &__input { padding: var(--v-indent) var(--h-indent); width: 100%; From 72eba7f9f611ea8e0113395af9516bfb594ebf96 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:36:48 +0300 Subject: [PATCH 24/43] Try to fix typescript checks --- src/components/AuthorizationForm/AuthorizationForm.ts | 3 ++- src/components/EditingPasswordForm/EditingPasswordForm.ts | 3 ++- src/components/EditingSettingsForm/EditingSettingsForm.ts | 3 ++- src/components/utils/getValuesFromForm.ts | 4 ++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/AuthorizationForm/AuthorizationForm.ts b/src/components/AuthorizationForm/AuthorizationForm.ts index 346ae2484..65e4797ac 100644 --- a/src/components/AuthorizationForm/AuthorizationForm.ts +++ b/src/components/AuthorizationForm/AuthorizationForm.ts @@ -1,13 +1,14 @@ import { Block } from "../../core/index"; import template from "./AuthorizationForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; +import { Event } from "../utils/getValuesFromForm"; export default class AuthorizationForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: object) => getValuesFromForm(event, this)], + ['submit', (event: Event) => getValuesFromForm(event, this)], ]), } diff --git a/src/components/EditingPasswordForm/EditingPasswordForm.ts b/src/components/EditingPasswordForm/EditingPasswordForm.ts index facbb6277..207bb9907 100644 --- a/src/components/EditingPasswordForm/EditingPasswordForm.ts +++ b/src/components/EditingPasswordForm/EditingPasswordForm.ts @@ -1,13 +1,14 @@ import { Block } from "../../core/index"; import template from "./EditingPasswordForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; +import { Event } from "../utils/getValuesFromForm"; export default class EditingPasswordForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: object) => getValuesFromForm(event, this)], + ['submit', (event: Event) => getValuesFromForm(event, this)], ]), } diff --git a/src/components/EditingSettingsForm/EditingSettingsForm.ts b/src/components/EditingSettingsForm/EditingSettingsForm.ts index 199368c04..ff74bea44 100644 --- a/src/components/EditingSettingsForm/EditingSettingsForm.ts +++ b/src/components/EditingSettingsForm/EditingSettingsForm.ts @@ -1,13 +1,14 @@ import { Block } from "../../core/index"; import template from "./EditingSettingsForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; +import { Event } from "../utils/getValuesFromForm"; export default class EditingSettingsForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: object) => getValuesFromForm(event, this)], + ['submit', (event: Event) => getValuesFromForm(event, this)], ]), } diff --git a/src/components/utils/getValuesFromForm.ts b/src/components/utils/getValuesFromForm.ts index 973d954b4..bd6f515f7 100644 --- a/src/components/utils/getValuesFromForm.ts +++ b/src/components/utils/getValuesFromForm.ts @@ -19,3 +19,7 @@ export default function getValuesFromForm(event: Event, instance: Instance) { console.log(formValues); } + +export type { + Event, +} From 50cf02b83a6f5ca77410999934e7c26a1610d7b4 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:40:03 +0300 Subject: [PATCH 25/43] Try to fix typescript checks --- src/components/RegistrationForm/RegistrationForm.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/RegistrationForm/RegistrationForm.ts b/src/components/RegistrationForm/RegistrationForm.ts index 7979493bc..8bc83ee35 100644 --- a/src/components/RegistrationForm/RegistrationForm.ts +++ b/src/components/RegistrationForm/RegistrationForm.ts @@ -1,13 +1,14 @@ import { Block } from "../../core/index"; import template from "./RegistrationForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; +import { Event } from "../utils/getValuesFromForm"; export default class RegistrationForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: object) => getValuesFromForm(event, this)], + ['submit', (event: Event) => getValuesFromForm(event, this)], ]), } From 74ad8c9cceb0a155426ec9f1834c6af207db0e39 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 25 Sep 2023 19:51:40 +0300 Subject: [PATCH 26/43] Try to fix npm run start --- package-lock.json | 283 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + 2 files changed, 273 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44f734c2a..d67a541f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "ts-node": "^10.9.1", "typescript": "^5.2.2", "vite": "^4.4.5" }, @@ -262,6 +263,28 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -856,8 +879,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "optional": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -889,9 +910,7 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.19", @@ -940,6 +959,30 @@ "node": ">= 8" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -1436,6 +1479,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1489,6 +1541,12 @@ "node": ">= 8" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2094,6 +2152,12 @@ } } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2286,6 +2350,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4286,6 +4359,12 @@ "node": ">=10" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -6269,6 +6348,61 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -6463,6 +6597,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -6730,6 +6870,15 @@ "node": ">=12" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -6921,6 +7070,27 @@ "to-fast-properties": "^2.0.0" } }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -7214,9 +7384,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@jridgewell/set-array": { "version": "1.1.2", @@ -7242,9 +7410,7 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@jridgewell/trace-mapping": { "version": "0.3.19", @@ -7284,6 +7450,30 @@ "fastq": "^1.6.0" } }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -7640,6 +7830,12 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -7677,6 +7873,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -8136,6 +8338,12 @@ "path-type": "^4.0.0" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -8271,6 +8479,12 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -9806,6 +10020,12 @@ "yallist": "^4.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -11232,6 +11452,35 @@ "dev": true, "requires": {} }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true + } + } + }, "tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -11373,6 +11622,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -11546,6 +11801,12 @@ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 8087769a0..fd6fb0aad 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "sass": "^1.66.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", + "ts-node": "^10.9.1", "typescript": "^5.2.2", "vite": "^4.4.5" }, From e53aae3d8c31e92364cb77527e4d907d5f2414a5 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Tue, 26 Sep 2023 09:28:50 +0300 Subject: [PATCH 27/43] Fix problems with typification --- src/components/utils/getValuesFromForm.ts | 6 +----- src/core/Block.ts | 24 ++++++++++++----------- src/utils/http.ts | 20 ++++++++++--------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/components/utils/getValuesFromForm.ts b/src/components/utils/getValuesFromForm.ts index bd6f515f7..c85ee2928 100644 --- a/src/components/utils/getValuesFromForm.ts +++ b/src/components/utils/getValuesFromForm.ts @@ -2,11 +2,7 @@ type Event = { preventDefault: Function } -type Instance = { - children: PropertyKey, -} - -export default function getValuesFromForm(event: Event, instance: Instance) { +export default function getValuesFromForm(event: Event, instance: any) { event.preventDefault(); const formValues: Record = {}; diff --git a/src/core/Block.ts b/src/core/Block.ts index 3ee89534b..7a3080887 100644 --- a/src/core/Block.ts +++ b/src/core/Block.ts @@ -4,9 +4,11 @@ import EventBus from "./EventBus"; // использую any, потому что не получилось типизировать по хорошему, // а время на исходе) -export default class Block { - children: any; - props: any; +type Props = Record; + +export default abstract class Block { + children: Props; + props: Props; eventBus: () => EventBus; static EVENTS = { @@ -52,7 +54,7 @@ export default class Block { eventBus.on(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); } - _getChildren(propsAndChildren: any) { + _getChildren(propsAndChildren: Props) { const children: any = {}; const props: any = {}; @@ -95,13 +97,13 @@ export default class Block { } // Может переопределять пользователь, необязательно трогать - componentDidMount(oldProps?: any) { + componentDidMount(oldProps?: Props) { console.log(oldProps); } dispatchComponentDidMount() {} - setProps = (newProps: any) => { + setProps = (newProps: Props) => { if (!newProps) { return; } @@ -112,7 +114,7 @@ export default class Block { // this.eventBus().emit(Block.EVENTS.FLOW_CDU); }; - _componentDidUpdate(oldProps: any, newProps: any) { + _componentDidUpdate(oldProps: Props, newProps: Props) { const response = this.componentDidUpdate(oldProps, newProps); if (response) { @@ -121,7 +123,7 @@ export default class Block { } // Может переопределять пользователь, необязательно трогать - componentDidUpdate(oldProps: any, newProps: any) { + componentDidUpdate(oldProps: Props, newProps: Props) { let update = false; Object.keys(newProps).forEach((key) => { if (oldProps[key] !== newProps[key]) { @@ -145,7 +147,7 @@ export default class Block { // Может переопределять пользователь, необязательно трогать render(): any {} - compile(template: Function, props: any) { + compile(template: Function, props: Props) { if (this.children) { const propsAndStubs = { ...props }; @@ -156,7 +158,7 @@ export default class Block { const fragment = this._createDocumentElement('template'); fragment.innerHTML = template(propsAndStubs); - Object.values(this.children).forEach((child: any) => { + Object.values(this.children).forEach((child: Props) => { const stub = fragment.content.querySelector(`[data-id="${child._id}"]`); stub.replaceWith(child.getContent()); }); @@ -205,7 +207,7 @@ export default class Block { return this._element; } - _makePropsProxy(props: any) { + _makePropsProxy(props: Props) { const self = this; const proxyProps = new Proxy(props, { set(target: any, prop: string, newValue) { diff --git a/src/utils/http.ts b/src/utils/http.ts index fdc27fb8c..ca4dd428a 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -21,8 +21,10 @@ type Options = { retries?: number, } +type HTTPMethod = (url: string, options: Options) => Promise; + class HTTP implements IHTTP { - get = (url: string, options: Options = { method: METHODS.GET }) => { + get: HTTPMethod = (url, options) => { let resUrl = url; const { data } = options; @@ -30,22 +32,22 @@ class HTTP implements IHTTP { resUrl = queryStringify(data); } - return this.request(resUrl, options); + return this.request(resUrl, { ...options, method: METHODS.GET }); }; - post = (url: string, options: Options = { method: METHODS.POST }) => { - return this.request(url, options); + post: HTTPMethod = (url, options) => { + return this.request(url, { ...options, method: METHODS.POST }); } - put = (url: string, options: Options = { method: METHODS.PUT }) => { - return this.request(url, options); + put: HTTPMethod = (url, options) => { + return this.request(url, { ...options, method: METHODS.PUT }); } - delete = (url: string, options: Options = { method: METHODS.DELETE }) => { - return this.request(url, options); + delete: HTTPMethod = (url, options) => { + return this.request(url, { ...options, method: METHODS.DELETE }); } - request = (url: string, options: Options) => { + request: HTTPMethod = (url, options) => { const { method, headers, From 405a11f93a87ce059d1246581646df7781253789 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Thu, 5 Oct 2023 23:18:21 +0300 Subject: [PATCH 28/43] Added some utils functions, added Router ... --- .eslintrc.json | 3 +- src/core/Block.ts | 51 +++++++------------ src/core/Router/Route.ts | 41 +++++++++++++++ src/core/Router/Router.ts | 65 ++++++++++++++++++++++++ src/core/index.ts | 4 ++ src/index.ts | 16 ++++-- src/pages/Authorization/Authorization.ts | 2 +- src/utils/cloneDeep.ts | 31 +++++++++++ src/utils/index.ts | 16 ++++++ src/utils/isArray.ts | 3 ++ src/utils/isArrayOrObject.ts | 5 ++ src/utils/isEqualObjects.ts | 23 +++++++++ src/utils/isPlainObject.ts | 11 ++++ src/utils/merge.ts | 3 ++ src/utils/queryStringify.ts | 53 +++++++++++++++++++ src/utils/render.ts | 10 ++-- src/utils/set.ts | 23 +++++++++ src/utils/trim.ts | 5 ++ vite.config.ts | 2 - 19 files changed, 322 insertions(+), 45 deletions(-) create mode 100644 src/core/Router/Route.ts create mode 100644 src/core/Router/Router.ts create mode 100644 src/utils/cloneDeep.ts create mode 100644 src/utils/isArray.ts create mode 100644 src/utils/isArrayOrObject.ts create mode 100644 src/utils/isEqualObjects.ts create mode 100644 src/utils/isPlainObject.ts create mode 100644 src/utils/merge.ts create mode 100644 src/utils/queryStringify.ts create mode 100644 src/utils/set.ts create mode 100644 src/utils/trim.ts diff --git a/.eslintrc.json b/.eslintrc.json index d13fb52f7..9f541042b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -27,7 +27,8 @@ "import/no-unresolved": 0, "arrow-body-style": 0, "no-restricted-syntax": 0, - "no-use-before-define": 0 + "no-use-before-define": 0, + "operator-linebreak": ["error", "after"] } } diff --git a/src/core/Block.ts b/src/core/Block.ts index 7a3080887..b7faf0b7c 100644 --- a/src/core/Block.ts +++ b/src/core/Block.ts @@ -1,5 +1,6 @@ import { v4 as uuid } from "uuid"; import EventBus from "./EventBus"; +// import { isEqualObjects } from "../utils"; // использую any, потому что не получилось типизировать по хорошему, // а время на исходе) @@ -97,42 +98,24 @@ export default abstract class Block { } // Может переопределять пользователь, необязательно трогать - componentDidMount(oldProps?: Props) { - console.log(oldProps); - } + componentDidMount() {} - dispatchComponentDidMount() {} + dispatchComponentDidMount() { + this._addEvents(); + } setProps = (newProps: Props) => { if (!newProps) { return; } - this._componentDidUpdate(this.props, newProps); - // this.eventBus().emit(Block.EVENTS.FLOW_CDU, this.props, newProps); - // Object.assign(this.props, newProps); - // this.eventBus().emit(Block.EVENTS.FLOW_CDU); + Object.assign(this.props, newProps); }; - _componentDidUpdate(oldProps: Props, newProps: Props) { - const response = this.componentDidUpdate(oldProps, newProps); - - if (response) { - Object.assign(oldProps, newProps); - } - } + _componentDidUpdate() {} // Может переопределять пользователь, необязательно трогать - componentDidUpdate(oldProps: Props, newProps: Props) { - let update = false; - Object.keys(newProps).forEach((key) => { - if (oldProps[key] !== newProps[key]) { - update = true; - } - }) - - return update; - } + componentDidUpdate() {} _render() { const block = this.render(); @@ -141,11 +124,11 @@ export default abstract class Block { this._element.innerHTML = ''; this._element.appendChild(block); - this._addEvents(); + this.eventBus().emit(Block.EVENTS.FLOW_CDM); } // Может переопределять пользователь, необязательно трогать - render(): any {} + render() {} compile(template: Function, props: Props) { if (this.children) { @@ -190,12 +173,6 @@ export default abstract class Block { } else { this._element.removeEventListener(eventName, eventFun); } - - // if (eventName === 'submit') { - // this._element.querySelector('form')?.removeEventListener(eventName, eventFun); - // } else { - // this._element.removeEventListener(eventName, eventFun); - // } }) } @@ -216,7 +193,7 @@ export default abstract class Block { } target[prop] = newValue; - self.eventBus().emit(Block.EVENTS.INIT); + self.eventBus().emit(Block.EVENTS.FLOW_RENDER); return true; }, @@ -227,4 +204,10 @@ export default abstract class Block { return proxyProps; } + + _hide() { + this.hide(); + } + + hide() {} } diff --git a/src/core/Router/Route.ts b/src/core/Router/Route.ts new file mode 100644 index 000000000..c44589961 --- /dev/null +++ b/src/core/Router/Route.ts @@ -0,0 +1,41 @@ +import { render } from "../../utils"; + +export default class Route { + constructor(pathname: string, view: any, props: object) { + this._pathname = pathname; + this._blockClass = view; + this._block = null; + this._props = props; + } + + navigate(pathname) { + if (this.match(pathname)) { + this._pathname = pathname; + this.render(); + } + } + + leave() { + if (this._block) { + this._block.hide(); + } + } + + match(pathname) { + return pathname === this._pathname; + } + + render() { + if (!this._block) { + + console.log(this._blockClass); + + this._block = new this._blockClass(); + render(this._props.rootQuery, this._block); + + return; + } + + this._block.show(); + } +} diff --git a/src/core/Router/Router.ts b/src/core/Router/Router.ts new file mode 100644 index 000000000..06e31c641 --- /dev/null +++ b/src/core/Router/Router.ts @@ -0,0 +1,65 @@ +import Route from "./Route"; + +export default class Router { + constructor(rootQuery: string) { + if (Router.__instance) { + return Router.__instance; + } + + this.routes = []; + this.history = window.history; + this._currentRoute = null; + this._rootQuery = rootQuery; + + Router.__instance = this; + } + + use(pathname: string, block: object) { + const route = new Route(pathname, block, { rootQuery: this._rootQuery }); + this.routes.push(route); + + return this; + } + + start() { + window.onpopstate = (event) => { + this._onRoute(event.currentTarget.location.pathname); + } + + this._onRoute(window.location.pathname); + } + + _onRoute(pathname: string) { + console.log(pathname); + + const route = this.getRoute(pathname); + + if (!route) { + return; + } + + if (this._currentRoute) { + this._currentRoute.leave(); + } + + this._currentRoute = route; + route.render(route, pathname); + } + + go(pathname: string) { + this.history.pushState({}, "", pathname); + this._onRoute(pathname); + } + + back() { + this.history.back(); + } + + forward() { + this.history.forward(); + } + + getRoute(pathname: string) { + return this.routes.find(route => route.match(pathname)); + } +} diff --git a/src/core/index.ts b/src/core/index.ts index f03cb4c2f..195b92bad 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,7 +1,11 @@ import EventBus from './EventBus'; import Block from './Block'; +import Router from './Router/Router'; +import Route from './Router/Route'; export { Block, EventBus, + Router, + Route, }; diff --git a/src/index.ts b/src/index.ts index de1c14736..0e393ecdb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,16 @@ -import { render } from "./utils/index"; -import { Authorization } from "./pages/index"; +import { Router } from "./core/index"; +import { Authorization, registration as Registration } from "./pages/index"; import "./scss/index.scss"; -const page = new Authorization(); +const router = new Router('#app'); +router + .use("/", Authorization) + .use("/sign-up", Registration) + .start() -render(page); +// const root = document.querySelector('#app'); + +// if (root) { +// render(root, page); +// } diff --git a/src/pages/Authorization/Authorization.ts b/src/pages/Authorization/Authorization.ts index 84ebb16fa..285d78ae1 100644 --- a/src/pages/Authorization/Authorization.ts +++ b/src/pages/Authorization/Authorization.ts @@ -36,7 +36,7 @@ const authForm = new AuthorizationForm({ text: 'Sign in', }), link: new Link({ - href: '/registration/', + href: '/sign-up', text: 'Sign up', }), }) diff --git a/src/utils/cloneDeep.ts b/src/utils/cloneDeep.ts new file mode 100644 index 000000000..784ca77cc --- /dev/null +++ b/src/utils/cloneDeep.ts @@ -0,0 +1,31 @@ +import { isArray, isPlainObject, isArrayOrObject } from './index'; + +type Object = { + [key: string]: any +} + +export default function cloneDeep(structure: Object) { + if (!isArrayOrObject(structure)) { + return structure; + } + + let root: Object; + + if (isArray(structure)) { + root = []; + } else if (isPlainObject(structure)) { + root = {}; + } else { + throw new Error(`${structure} is not an instance of an array or an object`); + } + + for (const [key, value] of Object.entries(structure)) { + if (isArrayOrObject(value)) { + root[key] = cloneDeep(value); + } else { + root[key] = value; + } + } + + return root; +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 16a0e8961..da46a35d1 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,8 +1,24 @@ import render from "./render"; import HTTP, { fetchWithRetry } from "./http"; +import trim from "./trim"; +import isEqualObjects from "./isEqualObjects"; +import merge from "./merge"; +import isArray from "./isArray"; +import isPlainObject from "./isPlainObject"; +import isArrayOrObject from "./isArrayOrObject"; +import cloneDeep from "./cloneDeep"; +import queryStringify from "./queryStringify"; export { render, HTTP, fetchWithRetry, + trim, + isEqualObjects, + merge, + isArray, + isPlainObject, + isArrayOrObject, + cloneDeep, + queryStringify, } diff --git a/src/utils/isArray.ts b/src/utils/isArray.ts new file mode 100644 index 000000000..7061afa61 --- /dev/null +++ b/src/utils/isArray.ts @@ -0,0 +1,3 @@ +export default function isArray(structure: any): boolean { + return Array.isArray(structure); +} diff --git a/src/utils/isArrayOrObject.ts b/src/utils/isArrayOrObject.ts new file mode 100644 index 000000000..8ec95112f --- /dev/null +++ b/src/utils/isArrayOrObject.ts @@ -0,0 +1,5 @@ +import { isArray, isPlainObject } from './index'; + +export default function isArrayOrObject(structure: any): boolean { + return isArray(structure) || isPlainObject(structure); +} diff --git a/src/utils/isEqualObjects.ts b/src/utils/isEqualObjects.ts new file mode 100644 index 000000000..da075cae6 --- /dev/null +++ b/src/utils/isEqualObjects.ts @@ -0,0 +1,23 @@ +type Object = { + [key: string]: any +} + +export default function isEqualObjects(a: Object, b: Object): boolean { + for (const key of Object.keys(a)) { + if (a[key]?.constructor === Object) { + if (b[key]?.constructor !== Object) { + return false; + } + + if (!isEqualObjects(a[key], b[key])) { + return false; + } + } + + if (String(a[key]) !== String(b[key])) { + return false; + } + } + + return true; +} diff --git a/src/utils/isPlainObject.ts b/src/utils/isPlainObject.ts new file mode 100644 index 000000000..564ae15c8 --- /dev/null +++ b/src/utils/isPlainObject.ts @@ -0,0 +1,11 @@ +export default function isPlainObject(structure: any): boolean { + if ( + structure !== null && + typeof structure === 'object' && + structure.toString() === '[object Object]' + ) { + return true; + } + + return false; +} diff --git a/src/utils/merge.ts b/src/utils/merge.ts new file mode 100644 index 000000000..a738bd95e --- /dev/null +++ b/src/utils/merge.ts @@ -0,0 +1,3 @@ +export default function merge(arrObj: object[]): object { + return Object.assign({}, ...arrObj); +} diff --git a/src/utils/queryStringify.ts b/src/utils/queryStringify.ts new file mode 100644 index 000000000..46f504924 --- /dev/null +++ b/src/utils/queryStringify.ts @@ -0,0 +1,53 @@ +import { isPlainObject, isArray } from './index'; + +type Object = { + [key: string]: any +} + +export default function queryStringify(structure: Object) { + if (!isPlainObject(structure)) { + throw new Error('input must be an object'); + } + + const root = []; + + for (const [key, value] of Object.entries(structure)) { + if (isArray(value)) { + value.forEach((item: any, i: string) => { + root.push(`${key}[${i}]=${item}`); + }) + } else if (isPlainObject(value)) { + root.push(throughObject(value)); + } else { + root.push(`${key}=${value}`) + } + } + + return root.join('&'); +} + +function throughObject(obj: Object) { + const keys: string[] = []; + let path = ''; + + const innerFun = (innerObj: Object) => { + for (const [key, value] of Object.entries(innerObj)) { + if (path === '') { + path += `${key}`; + } else { + path += `[${key}]`; + } + + if (isPlainObject(value)) { + innerFun(value); + } else { + keys.push(`${path}=${value}`); + path = ''; + } + } + } + + innerFun(obj); + + return keys.join('&'); +} diff --git a/src/utils/render.ts b/src/utils/render.ts index fbc45d394..7cf33a294 100644 --- a/src/utils/render.ts +++ b/src/utils/render.ts @@ -2,10 +2,14 @@ type Page = { getContent: Function } -export default function render(page: Page) { +export default function render(root: string, page: Page) { document.addEventListener('DOMContentLoaded', () => { - const app = document.getElementById('app'); + const renderPlace = document.querySelector(root); - app?.append(page.getContent()); + if (renderPlace) { + renderPlace.append(page.getContent()); + } else { + throw new Error('The render root is not found'); + } }) } diff --git a/src/utils/set.ts b/src/utils/set.ts new file mode 100644 index 000000000..5edccb847 --- /dev/null +++ b/src/utils/set.ts @@ -0,0 +1,23 @@ +import { merge } from "./index"; + +type Object = { + [key: string]: any +} + +export default function set(obj: Object, path: string, value: any): Object { + if (obj.constructor !== Object) { + return obj; + } + + if (typeof path !== 'string') { + throw new Error('path must be string'); + } + + const keys = path.split('.'); + const objFromKeys = keys.reduceRight( + (acc, key, i, { length }) => ({ [key]: i === length - 1 ? value : acc }), + {}, + ) + + return merge([obj, objFromKeys]); +} diff --git a/src/utils/trim.ts b/src/utils/trim.ts new file mode 100644 index 000000000..0be54b686 --- /dev/null +++ b/src/utils/trim.ts @@ -0,0 +1,5 @@ +export default function trim(str: string, pattern = '\\s'): string { + const regExp = new RegExp(`[${pattern}]`, 'gi'); + + return str.replace(regExp, ''); +} diff --git a/vite.config.ts b/vite.config.ts index c7bb1985e..1d957c4ea 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,8 +4,6 @@ import pugPrecompile from './vite-plugin-pug-precompile'; const root = resolve(__dirname, 'src'); -console.log(__dirname); - export default defineConfig({ root, base: '', From 31030d742fa631b8019ed4bde9a5442c967a315e Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 16:02:01 +0300 Subject: [PATCH 29/43] sprint_3 done --- src/404/404.ts | 22 +- src/500/500.ts | 22 +- src/api/auth-api.ts | 45 ++ src/api/base-api.ts | 21 + src/api/chats-api.ts | 75 ++++ src/api/users-api.ts | 50 +++ src/chats-and-chat/chats-and-chat.ts | 8 - src/chats-and-chat/index.html | 12 - .../AddUserForm/AddUserForm.tmp.pug | 6 + src/components/AddUserForm/AddUserForm.ts | 54 +++ .../AuthorizationForm.tmp.pug | 2 + .../AuthorizationForm/AuthorizationForm.ts | 28 +- src/components/Avatar/Avatar.scss | 16 + src/components/Avatar/Avatar.tmp.pug | 2 + src/components/Avatar/Avatar.ts | 14 + src/components/Button/Button.scss | 10 + src/components/Button/Button.tmp.pug | 2 +- src/components/Chat/Chat.scss | 50 +++ src/components/Chat/Chat.tmp.pug | 11 + src/components/Chat/Chat.ts | 20 + src/components/ChatArea/ChatArea.scss | 39 ++ src/components/ChatArea/ChatArea.tmp.pug | 10 + src/components/ChatArea/ChatArea.ts | 14 + .../ChatInformation/ChatInformation.tmp.pug | 23 + .../ChatInformation/ChatInformation.ts | 12 + src/components/Chats/Chats.tmp.pug | 3 + src/components/Chats/Chats.ts | 12 + .../Conversation/Conversation.tmp.pug | 2 + src/components/Conversation/Conversation.ts | 12 + .../CreateChatForm/CreateChatForm.tmp.pug | 6 + .../CreateChatForm/CreateChatForm.ts | 36 ++ .../DeleteUserForm/DeleteUserForm.tmp.pug | 6 + .../DeleteUserForm/DeleteUserForm.ts | 54 +++ .../EditingPasswordForm.tmp.pug | 1 + .../EditingPasswordForm.ts | 36 +- .../EditingSettingsForm.tmp.pug | 20 +- .../EditingSettingsForm.ts | 108 ++++- src/components/FieldText/FieldText.tmp.pug | 2 +- src/components/FieldText/FieldText.ts | 12 +- src/components/Layout/Layout.tmp.pug | 1 + src/components/Layout/Layout.ts | 12 + src/components/Message/Message.ts | 15 + .../Message/MessageInner.tmp copy.pug | 2 + src/components/Message/MessageOuter.tmp.pug | 2 + src/components/Modal/Modal.scss | 170 ++++++++ src/components/Modal/Modal.tmp.pug | 9 + src/components/Modal/Modal.ts | 82 ++++ .../RegistrationForm/RegistrationForm.tmp.pug | 1 + .../RegistrationForm/RegistrationForm.ts | 30 +- src/components/Spinner/Spinner.scss | 28 ++ src/components/Spinner/Spinner.tmp.pug | 2 + src/components/Spinner/Spinner.ts | 14 + src/components/Title/Title.tmp.pug | 13 + src/components/Title/Title.ts | 12 + .../UploadAvatarForm/UploadAvatarForm.tmp.pug | 7 + .../UploadAvatarForm/UploadAvatarForm.ts | 49 +++ .../UserInformation/UserInformation.scss | 16 + .../UserInformation/UserInformation.tmp.pug | 6 + .../UserInformation/UserInformation.ts | 14 + src/components/index.ts | 32 ++ src/components/utils/getValuesFromForm.ts | 20 +- src/controllers/AuthController.ts | 68 +++ src/controllers/ChatsController.ts | 168 ++++++++ src/controllers/UsersController.ts | 90 ++++ src/controllers/index.ts | 9 + src/core/Block.ts | 88 +++- src/core/Router/Route.ts | 19 +- src/core/Router/Router.ts | 54 ++- src/core/Store.ts | 60 +++ src/core/WebSocket.ts | 5 + src/core/index.ts | 7 +- src/editing-password/editing-password.ts | 8 - src/editing-password/index.html | 12 - src/editing-settings/editing-settings.ts | 8 - src/editing-settings/index.html | 12 - src/index.ts | 16 +- src/pages/Authorization/Authorization.ts | 1 + src/pages/ChatsAndChat/ChatsAndChat.tmp.pug | 75 +--- src/pages/ChatsAndChat/ChatsAndChat.ts | 403 +++++++++++++++++- .../EditingPassword/EditingPassword.tmp.pug | 10 +- src/pages/EditingPassword/EditingPassword.ts | 46 +- .../EditingSettings/EditingSettings.tmp.pug | 7 +- src/pages/EditingSettings/EditingSettings.ts | 86 +++- src/pages/UserSettings/UserSettings.tmp.pug | 19 +- src/pages/UserSettings/UserSettings.ts | 58 ++- src/pages/registration/registration.ts | 1 + src/registration/index.html | 12 - src/registration/registration.ts | 8 - src/scss/additions.scss | 4 + src/scss/main.scss | 331 +++++++------- src/user-settings/index.html | 12 - src/user-settings/user-settings.ts | 8 - src/utils/http.ts | 38 +- src/utils/index.ts | 4 + src/utils/initDropDowns.ts | 69 +++ src/utils/merge.ts | 4 +- src/utils/render.ts | 17 +- src/utils/set.ts | 2 +- 98 files changed, 2785 insertions(+), 469 deletions(-) create mode 100644 src/api/auth-api.ts create mode 100644 src/api/base-api.ts create mode 100644 src/api/chats-api.ts create mode 100644 src/api/users-api.ts delete mode 100644 src/chats-and-chat/chats-and-chat.ts delete mode 100644 src/chats-and-chat/index.html create mode 100644 src/components/AddUserForm/AddUserForm.tmp.pug create mode 100644 src/components/AddUserForm/AddUserForm.ts create mode 100644 src/components/Avatar/Avatar.scss create mode 100644 src/components/Avatar/Avatar.tmp.pug create mode 100644 src/components/Avatar/Avatar.ts create mode 100644 src/components/Chat/Chat.scss create mode 100644 src/components/Chat/Chat.tmp.pug create mode 100644 src/components/Chat/Chat.ts create mode 100644 src/components/ChatArea/ChatArea.scss create mode 100644 src/components/ChatArea/ChatArea.tmp.pug create mode 100644 src/components/ChatArea/ChatArea.ts create mode 100644 src/components/ChatInformation/ChatInformation.tmp.pug create mode 100644 src/components/ChatInformation/ChatInformation.ts create mode 100644 src/components/Chats/Chats.tmp.pug create mode 100644 src/components/Chats/Chats.ts create mode 100644 src/components/Conversation/Conversation.tmp.pug create mode 100644 src/components/Conversation/Conversation.ts create mode 100644 src/components/CreateChatForm/CreateChatForm.tmp.pug create mode 100644 src/components/CreateChatForm/CreateChatForm.ts create mode 100644 src/components/DeleteUserForm/DeleteUserForm.tmp.pug create mode 100644 src/components/DeleteUserForm/DeleteUserForm.ts create mode 100644 src/components/Layout/Layout.tmp.pug create mode 100644 src/components/Layout/Layout.ts create mode 100644 src/components/Message/Message.ts create mode 100644 src/components/Message/MessageInner.tmp copy.pug create mode 100644 src/components/Message/MessageOuter.tmp.pug create mode 100644 src/components/Modal/Modal.scss create mode 100644 src/components/Modal/Modal.tmp.pug create mode 100644 src/components/Modal/Modal.ts create mode 100644 src/components/Spinner/Spinner.scss create mode 100644 src/components/Spinner/Spinner.tmp.pug create mode 100644 src/components/Spinner/Spinner.ts create mode 100644 src/components/Title/Title.tmp.pug create mode 100644 src/components/Title/Title.ts create mode 100644 src/components/UploadAvatarForm/UploadAvatarForm.tmp.pug create mode 100644 src/components/UploadAvatarForm/UploadAvatarForm.ts create mode 100644 src/components/UserInformation/UserInformation.scss create mode 100644 src/components/UserInformation/UserInformation.tmp.pug create mode 100644 src/components/UserInformation/UserInformation.ts create mode 100644 src/controllers/AuthController.ts create mode 100644 src/controllers/ChatsController.ts create mode 100644 src/controllers/UsersController.ts create mode 100644 src/controllers/index.ts create mode 100644 src/core/Store.ts create mode 100644 src/core/WebSocket.ts delete mode 100644 src/editing-password/editing-password.ts delete mode 100644 src/editing-password/index.html delete mode 100644 src/editing-settings/editing-settings.ts delete mode 100644 src/editing-settings/index.html delete mode 100644 src/registration/index.html delete mode 100644 src/registration/registration.ts delete mode 100644 src/user-settings/index.html delete mode 100644 src/user-settings/user-settings.ts create mode 100644 src/utils/initDropDowns.ts diff --git a/src/404/404.ts b/src/404/404.ts index 2433ffdea..992d8400f 100644 --- a/src/404/404.ts +++ b/src/404/404.ts @@ -1,15 +1,15 @@ -import { render } from "../utils/index"; -import { ErrorPage } from "../pages/index"; +// import { render } from "../utils/index"; +// import { ErrorPage } from "../pages/index"; -import "../scss/index.scss"; +// import "../scss/index.scss"; -const props = { - title: '404', - text: 'who seeks will always find', - linkText: 'go to chats page', - linkHref: '/chats-and-chat/', -} +// const props = { +// title: '404', +// text: 'who seeks will always find', +// linkText: 'go to chats page', +// linkHref: '/chats-and-chat/', +// } -const page = new ErrorPage(props); +// const page = new ErrorPage(props); -render(page); +// render(page); diff --git a/src/500/500.ts b/src/500/500.ts index 4b36001e8..3b533146c 100644 --- a/src/500/500.ts +++ b/src/500/500.ts @@ -1,15 +1,15 @@ -import { render } from "../utils/index"; -import { ErrorPage } from "../pages/index"; +// import { render } from "../utils/index"; +// import { ErrorPage } from "../pages/index"; -import "../scss/index.scss"; +// import "../scss/index.scss"; -const props = { - title: '500', - text: 'something went wrong', - linkText: 'go to chats page', - linkHref: '/chats-and-chat/', -} +// const props = { +// title: '500', +// text: 'something went wrong', +// linkText: 'go to chats page', +// linkHref: '/chats-and-chat/', +// } -const page = new ErrorPage(props); +// const page = new ErrorPage(props); -render(page); +// render(page); diff --git a/src/api/auth-api.ts b/src/api/auth-api.ts new file mode 100644 index 000000000..f2bd1a663 --- /dev/null +++ b/src/api/auth-api.ts @@ -0,0 +1,45 @@ +import { HTTP } from "../utils/index"; +import BaseAPI from "./base-api"; + +type SignupData = { + first_name: string, + second_name: string, + email: string, + phone: string, + login: string, + password: string, +} + +type SigninData = { + login: string, + password: string, +} + +const authAPIInstance = new HTTP(); + +class AuthAPI extends BaseAPI { + private _baseURL = 'https://ya-praktikum.tech/api/v2/auth/'; + + signup(data: SignupData) { + return authAPIInstance.post(`${this._baseURL}signup`, { data }) + } + + signin(data: SigninData) { + return authAPIInstance.post(`${this._baseURL}signin`, { data }) + } + + logout() { + return authAPIInstance.post(`${this._baseURL}logout`) + } + + getUserInfo() { + return authAPIInstance.get(`${this._baseURL}user`) + } +} + +export type { + SignupData, + SigninData, +} + +export default new AuthAPI(); diff --git a/src/api/base-api.ts b/src/api/base-api.ts new file mode 100644 index 000000000..33d43b83a --- /dev/null +++ b/src/api/base-api.ts @@ -0,0 +1,21 @@ +/* eslint-disable */ +//@ts-nocheck + +export default class BaseAPI { + + create(data: any): any { + throw new Error('Not implemented') + } + + request(data: any): any { + throw new Error('Not implemented') + } + + update(data: any): any { + throw new Error('Not implemented') + } + + delete(data: any): any { + throw new Error('Not implemented') + } +} diff --git a/src/api/chats-api.ts b/src/api/chats-api.ts new file mode 100644 index 000000000..ae8c028fd --- /dev/null +++ b/src/api/chats-api.ts @@ -0,0 +1,75 @@ +import { HTTP, queryStringify } from "../utils/index"; +import BaseAPI from "./base-api"; + +export type CreateData = { + title: string, +} + +export type IdData = { + chatId: number, +} + +export type UsersData = { + chatId: number, + users: number[], +} + +const chatsAPIInstance = new HTTP(); + +class ChatsAPI extends BaseAPI { + private _baseURL = 'https://ya-praktikum.tech/api/v2/chats/'; + + request() { + return chatsAPIInstance.get(`${this._baseURL}`); + } + + create(data: CreateData) { + return chatsAPIInstance.post(`${this._baseURL}`, { data }); + } + + delete(data: IdData) { + return chatsAPIInstance.delete(`${this._baseURL}`, { data }); + } + + getFiles(id: number) { + return chatsAPIInstance.get(`${this._baseURL}${id}/files`); + } + + getArchive(parameters: { [key: string]: any }) { + return chatsAPIInstance.get(`${this._baseURL}archive${queryStringify(parameters)}`); + } + + archive(data: IdData) { + return chatsAPIInstance.post(`${this._baseURL}archive`, { data }); + } + + unarchive(data: IdData) { + return chatsAPIInstance.post(`${this._baseURL}unarchive`, { data }); + } + + getUsers(id: number, parameters = {}) { + return chatsAPIInstance.get(`${this._baseURL}${id}/users${queryStringify(parameters)}`); + } + + getNewMessagesCount(id: number) { + return chatsAPIInstance.get(`${this._baseURL}new/${id}`); + } + + uploadAvatar(data: FormData) { + return chatsAPIInstance.put(`${this._baseURL}avatar`, { data }); + } + + addUsers(data: UsersData) { + return chatsAPIInstance.put(`${this._baseURL}users/`, { data }); + } + + deleteUsers(data: UsersData) { + return chatsAPIInstance.delete(`${this._baseURL}users/`, { data }); + } + + getToken(id: number) { + return chatsAPIInstance.post(`${this._baseURL}token/${id}`); + } +} + +export default new ChatsAPI(); diff --git a/src/api/users-api.ts b/src/api/users-api.ts new file mode 100644 index 000000000..802f0651d --- /dev/null +++ b/src/api/users-api.ts @@ -0,0 +1,50 @@ +import { HTTP } from "../utils/index"; +import BaseAPI from "./base-api"; + +export type UserData = { + first_name: string, + second_name: string, + display_name: string, + login: string, + email: string, + phone: string, +} + +export type PasswordData = { + oldPassword: string, + newPassword: string, +} + +export type SearchData = { + login: string, +} + +const usersAPIInstance = new HTTP(); + +class UsersAPI extends BaseAPI { + private _baseURL = 'https://ya-praktikum.tech/api/v2/user/'; + + request(id: number) { + return usersAPIInstance.get(`${this._baseURL}${id}`); + } + + changeProfile(data: UserData) { + return usersAPIInstance.put(`${this._baseURL}profile`, { data }); + } + + changeAvatar(data: FormData) { + const headers = new Map([['Content-Type', 'multipart/form-data']]); + + return usersAPIInstance.put(`${this._baseURL}profile/avatar`, { data, headers }); + } + + changePassword(data: PasswordData) { + return usersAPIInstance.put(`${this._baseURL}password`, { data }); + } + + search(data: SearchData) { + return usersAPIInstance.post(`${this._baseURL}search`, { data }); + } +} + +export default new UsersAPI(); diff --git a/src/chats-and-chat/chats-and-chat.ts b/src/chats-and-chat/chats-and-chat.ts deleted file mode 100644 index 2db5caf47..000000000 --- a/src/chats-and-chat/chats-and-chat.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { render } from "../utils/index"; -import { ChatsAndChat } from "../pages/index"; - -import "../scss/index.scss"; - -const page = new ChatsAndChat(); - -render(page); diff --git a/src/chats-and-chat/index.html b/src/chats-and-chat/index.html deleted file mode 100644 index 9955f2bb3..000000000 --- a/src/chats-and-chat/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Chats and chat page - - -
- - - diff --git a/src/components/AddUserForm/AddUserForm.tmp.pug b/src/components/AddUserForm/AddUserForm.tmp.pug new file mode 100644 index 000000000..c8b0204c6 --- /dev/null +++ b/src/components/AddUserForm/AddUserForm.tmp.pug @@ -0,0 +1,6 @@ +form.form.form--t-1 + .form__field(style="display: none")!= fieldChatId + .form__field!= fieldAddUser + .form__field!= sendBtn + .form__field.form__field--error.t-center!= errorText + .form__field.form__field--ok.t-center!= errorText diff --git a/src/components/AddUserForm/AddUserForm.ts b/src/components/AddUserForm/AddUserForm.ts new file mode 100644 index 000000000..d35af8f96 --- /dev/null +++ b/src/components/AddUserForm/AddUserForm.ts @@ -0,0 +1,54 @@ +import { Block } from "../../core/index"; +import template from "./AddUserForm.tmp.pug"; +import { ChatsController } from "../../controllers"; +import getValuesFromForm from "../utils/getValuesFromForm"; + +import type { Event } from "../utils/getValuesFromForm"; + +export default class AddUserForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', async (event: Event) => { + event.preventDefault(); + this.hideError(); + this.hideResult(); + + const formData = getValuesFromForm(event, this); + + if (formData) { + const res = await ChatsController.addUsers(formData); + + this.setProps({ + errorText: res, + }) + this.showResult(); + } + }], + ]), + } + + super('div', newProps); + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + + public showResult() { + this.element.querySelector('.form__field--ok').classList.add('active'); + } + + public hideResult() { + this.element.querySelector('.form__field--ok').classList.remove('active'); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/AuthorizationForm/AuthorizationForm.tmp.pug b/src/components/AuthorizationForm/AuthorizationForm.tmp.pug index 034d78a4b..8a2876152 100644 --- a/src/components/AuthorizationForm/AuthorizationForm.tmp.pug +++ b/src/components/AuthorizationForm/AuthorizationForm.tmp.pug @@ -5,3 +5,5 @@ form.form .form__field!= fieldPassword .form__field.form__field--accent!= sendBtn .form__field.t-right!= link + .form__field.t-right!= link + .form__field.form__field--error!= errorText diff --git a/src/components/AuthorizationForm/AuthorizationForm.ts b/src/components/AuthorizationForm/AuthorizationForm.ts index 65e4797ac..7c9893bc8 100644 --- a/src/components/AuthorizationForm/AuthorizationForm.ts +++ b/src/components/AuthorizationForm/AuthorizationForm.ts @@ -1,5 +1,6 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./AuthorizationForm.tmp.pug"; +import { AuthController } from "../../controllers/index"; import { getValuesFromForm } from "../utils/index"; import { Event } from "../utils/getValuesFromForm"; @@ -8,13 +9,36 @@ export default class AuthorizationForm extends Block { const newProps = { ...props, events: new Map([ - ['submit', (event: Event) => getValuesFromForm(event, this)], + ['submit', (event: Event) => { + const formData = getValuesFromForm(event, this); + + if (formData) { + AuthController.signin(formData); + + Store.on(StoreEvents.Error, () => { + const { error } = Store.getState(); + + this.setProps({ + errorText: error, + }) + this.showError(); + }); + } + }], ]), } super('div', newProps); } + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + render() { return this.compile(template, this.props); } diff --git a/src/components/Avatar/Avatar.scss b/src/components/Avatar/Avatar.scss new file mode 100644 index 000000000..c104a3c8b --- /dev/null +++ b/src/components/Avatar/Avatar.scss @@ -0,0 +1,16 @@ +.avatar { + $block-name: &; + + overflow: hidden; + width: 60px; + height: 60px; + border-radius: 50%; + background-color: var(--t-l-grey-3); + + &__img { + width: 100%; + height: 100%; + object-fit: contain; + object-position: center; + } +} diff --git a/src/components/Avatar/Avatar.tmp.pug b/src/components/Avatar/Avatar.tmp.pug new file mode 100644 index 000000000..a275154f4 --- /dev/null +++ b/src/components/Avatar/Avatar.tmp.pug @@ -0,0 +1,2 @@ +.avatar + img.avatar__img(src=src ? `https://ya-praktikum.tech/api/v2/resources${src}` : 'img/avatar-dummy-1.jpg', alt=alt, loading="lazy") diff --git a/src/components/Avatar/Avatar.ts b/src/components/Avatar/Avatar.ts new file mode 100644 index 000000000..0b4dc213c --- /dev/null +++ b/src/components/Avatar/Avatar.ts @@ -0,0 +1,14 @@ +import { Block } from "../../core/index"; +import template from "./Avatar.tmp.pug"; + +import "./Avatar.scss"; + +export default class Avatar extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Button/Button.scss b/src/components/Button/Button.scss index 148ae1510..dbf6ea069 100644 --- a/src/components/Button/Button.scss +++ b/src/components/Button/Button.scss @@ -34,4 +34,14 @@ padding-top: 14px; padding-bottom: 14px; } + + &--red { + border-color: rgb(240, 91, 64); + background-color: rgb(240, 91, 64); + + &:hover { + border-color: rgb(219, 76, 51); + background-color: rgb(219, 76, 51); + } + } } diff --git a/src/components/Button/Button.tmp.pug b/src/components/Button/Button.tmp.pug index 05c97b708..dfcccc033 100644 --- a/src/components/Button/Button.tmp.pug +++ b/src/components/Button/Button.tmp.pug @@ -1 +1 @@ -button(class=className, type=type, form=form)= text +button(class=className, type=type, form=form)&attributes(attributes)= text diff --git a/src/components/Chat/Chat.scss b/src/components/Chat/Chat.scss new file mode 100644 index 000000000..fd01925e7 --- /dev/null +++ b/src/components/Chat/Chat.scss @@ -0,0 +1,50 @@ +.chat { + $block-name: &; + + display: flex; + padding: 20px; + background-color: #fff; + border-radius: var(--b-radius); + transition: background-color var(--t-duration); + cursor: pointer; + + &:hover, + &:focus-within { + background-color: var(--m-color-1-3); + } + + & + & { + margin-top: 15px; + } + + &__s { + margin-left: 15px; + width: 100%; + } + + &__s-f { + display: flex; + justify-content: space-between; + } + + &__time { + font-size: 14px; + } + + &__s-s { + margin-top: 5px; + } + + &__last-message { + font-size: 14px; + color: var(--t-l-grey-1); + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + + b { + color: #000; + } + } +} diff --git a/src/components/Chat/Chat.tmp.pug b/src/components/Chat/Chat.tmp.pug new file mode 100644 index 000000000..56d7dc98f --- /dev/null +++ b/src/components/Chat/Chat.tmp.pug @@ -0,0 +1,11 @@ +a.chat(tabindex="0", id=id, href='javascript:void(0)') + .chat__f!= chatAvatar + .chat__s + .chat__s-f + h6.name!= chatName + if (lastMessage) + - const middle = lastMessage.time.search('T') + time.chat__time= lastMessage.time.substring(middle + 1, middle + 6) + if (lastMessage) + .chat__s-s + p.chat__last-message #[b #{lastMessage.user.display_name}:] #{lastMessage.content} diff --git a/src/components/Chat/Chat.ts b/src/components/Chat/Chat.ts new file mode 100644 index 000000000..e486fa312 --- /dev/null +++ b/src/components/Chat/Chat.ts @@ -0,0 +1,20 @@ +import { Block, Store } from "../../core/index"; +import template from "./Chat.tmp.pug"; + +import "./Chat.scss"; + +export default class Chat extends Block { + constructor(props?: object) { + super('div', { + ...props, + events: new Map([[ + 'click', () => { + Store.set('selectedChat', this.props.id) + }]]), + }); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/ChatArea/ChatArea.scss b/src/components/ChatArea/ChatArea.scss new file mode 100644 index 000000000..512af2224 --- /dev/null +++ b/src/components/ChatArea/ChatArea.scss @@ -0,0 +1,39 @@ +.chat-area { + $block-name: &; + + --indent-h: 30px; + --height-f: 72px; + + height: 100vh; + + &__f, + &__s { + padding-left: var(--indent-h); + padding-right: var(--indent-h); + } + + &__f { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 15px; + padding-bottom: 15px; + height: var(--height-f); + background-color: var(--t-l-grey-2); + } + + &__info { + display: flex; + align-items: center; + } + + &__info-r { + margin-left: 15px; + } + + &__s { + padding-top: 15px; + padding-bottom: 15px; + height: calc(100% - var(--height-f)); + } +} diff --git a/src/components/ChatArea/ChatArea.tmp.pug b/src/components/ChatArea/ChatArea.tmp.pug new file mode 100644 index 000000000..59fbfca7c --- /dev/null +++ b/src/components/ChatArea/ChatArea.tmp.pug @@ -0,0 +1,10 @@ +.chat-area + | !{chatInfo} + + .chat-area__s + .messages-area + .messages-area__f + .messages-area__conversation!= conversation + + .messages-area__s + .messages-area__s-inner!= fieldMessage diff --git a/src/components/ChatArea/ChatArea.ts b/src/components/ChatArea/ChatArea.ts new file mode 100644 index 000000000..641e966ef --- /dev/null +++ b/src/components/ChatArea/ChatArea.ts @@ -0,0 +1,14 @@ +import { Block } from "../../core/index"; +import template from "./ChatArea.tmp.pug"; + +import "./ChatArea.scss"; + +export default class ChatArea extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/ChatInformation/ChatInformation.tmp.pug b/src/components/ChatInformation/ChatInformation.tmp.pug new file mode 100644 index 000000000..dff0f5975 --- /dev/null +++ b/src/components/ChatInformation/ChatInformation.tmp.pug @@ -0,0 +1,23 @@ +.chat-area__f + .chat-area__f-f + .chat-area__info + .chat-area__info-l!= chatAvatar + .chat-area__info-r + h6.name!= chatName + + .chat-area__f-s + .dropdown.dropdown--t-6 + button.dropdown__trigger( + type="button", + title="Open chat settings menu", + aria-expanded="false", + aria-controls="chatSettings" + data-open-text="Open chat settings menu" + data-close-text="Close chat settings menu" + ) + span.link Chat settings + #chatSettings.dropdown__body + .dropdown__body-inner + .btns + each btn in chatButtons + | !{btn} diff --git a/src/components/ChatInformation/ChatInformation.ts b/src/components/ChatInformation/ChatInformation.ts new file mode 100644 index 000000000..5aa6906e8 --- /dev/null +++ b/src/components/ChatInformation/ChatInformation.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./ChatInformation.tmp.pug"; + +export default class ChatInformation extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Chats/Chats.tmp.pug b/src/components/Chats/Chats.tmp.pug new file mode 100644 index 000000000..657689419 --- /dev/null +++ b/src/components/Chats/Chats.tmp.pug @@ -0,0 +1,3 @@ +.chats + each chat in chats + | !{chat} diff --git a/src/components/Chats/Chats.ts b/src/components/Chats/Chats.ts new file mode 100644 index 000000000..bd5c30590 --- /dev/null +++ b/src/components/Chats/Chats.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Chats.tmp.pug"; + +export default class Chats extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Conversation/Conversation.tmp.pug b/src/components/Conversation/Conversation.tmp.pug new file mode 100644 index 000000000..0d035d557 --- /dev/null +++ b/src/components/Conversation/Conversation.tmp.pug @@ -0,0 +1,2 @@ +each message in content + | !{message} diff --git a/src/components/Conversation/Conversation.ts b/src/components/Conversation/Conversation.ts new file mode 100644 index 000000000..efb560737 --- /dev/null +++ b/src/components/Conversation/Conversation.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Conversation.tmp.pug"; + +export default class Conversation extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/CreateChatForm/CreateChatForm.tmp.pug b/src/components/CreateChatForm/CreateChatForm.tmp.pug new file mode 100644 index 000000000..ae6e73464 --- /dev/null +++ b/src/components/CreateChatForm/CreateChatForm.tmp.pug @@ -0,0 +1,6 @@ +form + .form__field.form__field--x2 + | !{chatName} + | !{createBtn} + .form__field.form__field--error!= errorText + diff --git a/src/components/CreateChatForm/CreateChatForm.ts b/src/components/CreateChatForm/CreateChatForm.ts new file mode 100644 index 000000000..6245b51d5 --- /dev/null +++ b/src/components/CreateChatForm/CreateChatForm.ts @@ -0,0 +1,36 @@ +import { Block } from "../../core/index"; +import template from "./CreateChatForm.tmp.pug"; +import { getValuesFromForm } from "../utils/index"; +import { ChatsController } from "../../controllers"; + +import type { Event } from "../utils/getValuesFromForm"; + +export default class CreateChatForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: Event) => { + const formData = getValuesFromForm(event, this); + if (formData) { + ChatsController.create(formData); + } + }], + ]), + } + + super('div', newProps); + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/DeleteUserForm/DeleteUserForm.tmp.pug b/src/components/DeleteUserForm/DeleteUserForm.tmp.pug new file mode 100644 index 000000000..6c7df09b8 --- /dev/null +++ b/src/components/DeleteUserForm/DeleteUserForm.tmp.pug @@ -0,0 +1,6 @@ +form.form.form--t-1 + .form__field(style="display: none")!= fieldChatId + .form__field!= fieldDeleteUser + .form__field!= sendBtn + .form__field.form__field--error.t-center!= errorText + .form__field.form__field--ok.t-center!= errorText diff --git a/src/components/DeleteUserForm/DeleteUserForm.ts b/src/components/DeleteUserForm/DeleteUserForm.ts new file mode 100644 index 000000000..edcea26f8 --- /dev/null +++ b/src/components/DeleteUserForm/DeleteUserForm.ts @@ -0,0 +1,54 @@ +import { Block } from "../../core/index"; +import template from "./DeleteUserForm.tmp.pug"; +import { ChatsController } from "../../controllers"; +import getValuesFromForm from "../utils/getValuesFromForm"; + +import type { Event } from "../utils/getValuesFromForm"; + +export default class DeleteUserForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', async (event: Event) => { + event.preventDefault(); + this.hideError(); + this.hideResult(); + + const formData = getValuesFromForm(event, this); + + if (formData) { + const res = await ChatsController.deleteUsers(formData); + + this.setProps({ + errorText: res, + }) + this.showResult(); + } + }], + ]), + } + + super('div', newProps); + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + + public showResult() { + this.element.querySelector('.form__field--ok').classList.add('active'); + } + + public hideResult() { + this.element.querySelector('.form__field--ok').classList.remove('active'); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug b/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug index c99ac1ada..0573c514b 100644 --- a/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug +++ b/src/components/EditingPasswordForm/EditingPasswordForm.tmp.pug @@ -3,3 +3,4 @@ form#userSettingsForm.user-settings__form li.user-settings__list-item!= currentPassword li.user-settings__list-item!= newPassword li.user-settings__list-item!= repeatNewPassword + li.user-settings__list-item.form__field--error!= errorText diff --git a/src/components/EditingPasswordForm/EditingPasswordForm.ts b/src/components/EditingPasswordForm/EditingPasswordForm.ts index 207bb9907..bbdb04427 100644 --- a/src/components/EditingPasswordForm/EditingPasswordForm.ts +++ b/src/components/EditingPasswordForm/EditingPasswordForm.ts @@ -1,18 +1,48 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./EditingPasswordForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; -import { Event } from "../utils/getValuesFromForm"; +import { UsersController } from "../../controllers"; + +import type { Event } from "../utils/getValuesFromForm"; export default class EditingPasswordForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: Event) => getValuesFromForm(event, this)], + ['submit', (event: Event) => { + this.hideError(); + const formData = getValuesFromForm(event, this); + + if (formData) { + const { oldPassword, newPassword } = formData; + const data = { oldPassword, newPassword } + + UsersController.changePassword(data); + } + }], ]), } super('div', newProps); + + Store + .on(StoreEvents.Error, () => { + const { error } = Store.getState(); + + this.setProps({ + errorText: error, + }) + this.showError(); + }) + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); } render() { diff --git a/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug b/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug index 63528fb32..7c3cfc99c 100644 --- a/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug +++ b/src/components/EditingSettingsForm/EditingSettingsForm.tmp.pug @@ -5,21 +5,5 @@ form#userSettingsForm.user-settings__form li.user-settings__list-item!= secondName li.user-settings__list-item!= email li.user-settings__list-item!= phone - - //ul.user-settings__list - li.user-settings__list-item - label.user-settings__list-item-name(for="display_name") Nickname: - input.user-settings__list-item-value.t-right(id="display_name" type="text" name="display_name" value="user name") - li.user-settings__list-item - label.user-settings__list-item-name(for="first_name") First name: - input.user-settings__list-item-value.t-right(id="first_name" type="text" name="first_name" value="first name") - li.user-settings__list-item - label.user-settings__list-item-name(for="second_name") Second name: - input.user-settings__list-item-value.t-right(id="second_name" type="text" name="second_name" value="second name") - li.user-settings__list-item - label.user-settings__list-item-name(for="email") Email: - input.user-settings__list-item-value.t-right(id="email" type="text" name="email" value="test@test.ru") - li.user-settings__list-item - label.user-settings__list-item-name(for="phone") Phone: - input.user-settings__list-item-value.t-right(id="phone" type="text" name="phone" value="+7 (000) 000-00-00") - //input(type="file", name="avatar", hidden) + li.user-settings__list-item.form__field--error!= errorText + input(id="avatar" type="file", name="avatar", accept=".png, .jpg, .jpeg, .webp", hidden) diff --git a/src/components/EditingSettingsForm/EditingSettingsForm.ts b/src/components/EditingSettingsForm/EditingSettingsForm.ts index ff74bea44..0acb8513d 100644 --- a/src/components/EditingSettingsForm/EditingSettingsForm.ts +++ b/src/components/EditingSettingsForm/EditingSettingsForm.ts @@ -1,18 +1,120 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./EditingSettingsForm.tmp.pug"; import { getValuesFromForm } from "../utils/index"; -import { Event } from "../utils/getValuesFromForm"; +import { UsersController } from "../../controllers"; +import { isEqualObjects } from "../../utils"; + +import type { Event } from "../utils/getValuesFromForm"; export default class EditingSettingsForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: Event) => getValuesFromForm(event, this)], + ['submit', (event: Event) => { + this.hideError(); + const formData = getValuesFromForm(event, this); + + const { + user: { + display_name, + first_name, + second_name, + email, + phone, + }, + } = Store.getState(); + + const user = { + display_name, + first_name, + second_name, + email, + phone, + } + + if (!isEqualObjects(formData, user)) { + UsersController.changeProfile(formData); + } + + const avatarFile = this.element.querySelector('#avatar').files[0]; + if (avatarFile) { + const formData = new FormData(); + formData.set('avatar', avatarFile); + + UsersController.changeAvatar(formData); + } + }], ]), } super('div', newProps); + + Store + .on(StoreEvents.UserUpdate, () => { + const { + user: { + display_name, + first_name, + second_name, + email, + phone, + }, + } = Store.getState(); + const { + nickname: nicknameField, + firstName: firstNameField, + secondName: secondNameField, + email: emailField, + phone: phoneField, + } = this.children; + + if (display_name) { + nicknameField.setProps({ + value: display_name, + }) + } + + if (first_name) { + firstNameField.setProps({ + value: first_name, + }) + } + + if (second_name) { + secondNameField.setProps({ + value: second_name, + }) + } + + if (email) { + emailField.setProps({ + value: email, + }) + } + + if (phone) { + phoneField.setProps({ + value: phone, + }) + } + }) + .on(StoreEvents.Error, () => { + const { error } = Store.getState(); + + this.setProps({ + errorText: error, + }) + this.showError(); + }) + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); } render() { diff --git a/src/components/FieldText/FieldText.tmp.pug b/src/components/FieldText/FieldText.tmp.pug index 1523c9432..add40b1bf 100644 --- a/src/components/FieldText/FieldText.tmp.pug +++ b/src/components/FieldText/FieldText.tmp.pug @@ -2,6 +2,6 @@ label.field-text(class=mods) if(typeof(title) !== 'undefined' && title) span.field-text__name= title span.field-text__input-wrap - input.field-text__input(type=type, name=name, value=value, data-pattern=pattern placeholder=placeholder, autocomplete="off") + input.field-text__input(type=type, name=name, value=value, data-pattern=pattern placeholder=placeholder, autocomplete="off")&attributes(attributes) if(typeof(helpText) !== 'undefined' && helpText) span.field-text__help-text= helpText diff --git a/src/components/FieldText/FieldText.ts b/src/components/FieldText/FieldText.ts index b0b0f5e0e..16c2cd627 100644 --- a/src/components/FieldText/FieldText.ts +++ b/src/components/FieldText/FieldText.ts @@ -6,15 +6,13 @@ import { validateField } from "../utils/index"; import "./FieldText.scss"; export default class FieldText extends Block { - constructor(props?: object) { - const newProps = { - ...props, - events: new Map([ - ['blur', validateField], - ]), + constructor(props?: any) { + const { events = new Map() } = props; + if (events.size === 0) { + events.set('blur', validateField); } - super('div', newProps); + super('div', { ...props, events }); } public value() { diff --git a/src/components/Layout/Layout.tmp.pug b/src/components/Layout/Layout.tmp.pug new file mode 100644 index 000000000..b4fcba4c9 --- /dev/null +++ b/src/components/Layout/Layout.tmp.pug @@ -0,0 +1 @@ +.layout!= content diff --git a/src/components/Layout/Layout.ts b/src/components/Layout/Layout.ts new file mode 100644 index 000000000..7e42d63c6 --- /dev/null +++ b/src/components/Layout/Layout.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Layout.tmp.pug"; + +export default class Layout extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Message/Message.ts b/src/components/Message/Message.ts new file mode 100644 index 000000000..640a1a6e1 --- /dev/null +++ b/src/components/Message/Message.ts @@ -0,0 +1,15 @@ +import { Block } from "../../core/index"; +import templateInner from "./MessageInner.tmp copy.pug"; +import templateOuter from "./MessageOuter.tmp.pug"; + +export default class Message extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + const { login, active_user_login } = this.props; + + return this.compile(login === active_user_login ? templateInner : templateOuter, this.props); + } +} diff --git a/src/components/Message/MessageInner.tmp copy.pug b/src/components/Message/MessageInner.tmp copy.pug new file mode 100644 index 000000000..66099e59b --- /dev/null +++ b/src/components/Message/MessageInner.tmp copy.pug @@ -0,0 +1,2 @@ +.messages-area__conversation-item.messages-area__conversation-sent + .messages-area__conversation-message!= content diff --git a/src/components/Message/MessageOuter.tmp.pug b/src/components/Message/MessageOuter.tmp.pug new file mode 100644 index 000000000..ab3dd3007 --- /dev/null +++ b/src/components/Message/MessageOuter.tmp.pug @@ -0,0 +1,2 @@ +.messages-area__conversation-item.messages-area__conversation-received + .messages-area__conversation-message!= content diff --git a/src/components/Modal/Modal.scss b/src/components/Modal/Modal.scss new file mode 100644 index 000000000..d64f9d859 --- /dev/null +++ b/src/components/Modal/Modal.scss @@ -0,0 +1,170 @@ +.d-modal { + $block-name: &; + + position: fixed; + top: 0; + left: 0; + z-index: 1000; + display: none; + width: 100%; + height: 100%; + overflow: hidden; + outline: 0; + opacity: 0; + visibility: hidden; + + &__dialog { + position: relative; + display: flex; + align-items: center; + width: 480px; + max-width: 100%; + min-height: calc(100% - 4em); + margin: 2em auto; + pointer-events: none; + } + + &__content { + position: relative; + display: flex; + flex-direction: column; + padding-top: 30px; + padding-bottom: 30px; + width: 100%; + min-height: 40px; + pointer-events: auto; + background-color: #fff; + outline: 0; + border-radius: var(--b-radius); + } + + &__header { + } + + &__title { + margin-bottom: 30px; + font-size: 20px; + text-align: center; + } + + &__close { + display: inline-flex; + align-items: center; + justify-content: center; + position: absolute; + z-index: 1; + top: 10px; + right: 10px; + width: 32px; + height: 32px; + border: none; + padding: 0; + background: transparent; + user-select: none; + cursor: pointer; + + span { + position: relative; + display: block; + width: 60%; + height: 2px; + font-size: 0; + color: transparent; + background: transparent; + pointer-events: none; + + &:before, + &:after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 2px; + background: #333; + transform-origin: 50% 50%; + } + + &:before { + transform: rotate3d(0, 0, 1, 45deg); + } + + &:after { + transform: rotate3d(0, 0, 1, -45deg); + } + } + } + + &__body, + &__footer { + padding-left: 30px; + padding-right: 30px; + } + + &__body { + position: relative; + flex: 1 1 auto; + } + + &__footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: flex-start; + justify-content: flex-end; + gap: 10px 15px; + margin-top: 15px; + + &--t-1 { + justify-content: space-between; + } + } + + &--show { + #{$block-name}__dialog { + animation: modal-dialog 0.3s 1 ease-out forwards; + } + } +} + +.modal-open { + overflow: hidden; + + .d-modal { + opacity: 1; + visibility: visible; + overflow-x: hidden; + overflow-y: auto; + } +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 999; + width: 100vw; + height: 100vh; + background-color: #000000; + animation: modal-backdrop 0.3s 1 ease-out forwards; +} + +@keyframes modal-backdrop { + from { + opacity: 0; + } + + to { + opacity: 0.6; + } +} + +@keyframes modal-dialog { + from { + transform: translate(0, -2em); + } + + to { + transform: translate(0, 0); + } +} diff --git a/src/components/Modal/Modal.tmp.pug b/src/components/Modal/Modal.tmp.pug new file mode 100644 index 000000000..254e4c42f --- /dev/null +++ b/src/components/Modal/Modal.tmp.pug @@ -0,0 +1,9 @@ +section.d-modal(id="defaultModal", class=className, tabindex='-1', aria-hidden='true')&attributes(attributes) + .d-modal__dialog + .d-modal__content + button.d-modal__close(data-modal='close', title='Close modal') #[span] + if title + header.d-modal__header + h5.d-modal__title!= title + .d-modal__body!= content + diff --git a/src/components/Modal/Modal.ts b/src/components/Modal/Modal.ts new file mode 100644 index 000000000..50b6fa14c --- /dev/null +++ b/src/components/Modal/Modal.ts @@ -0,0 +1,82 @@ +import { Block } from "../../core/index"; +import template from "./Modal.tmp.pug"; + +import "./Modal.scss"; + +export default class Modal extends Block { + bodyPaddingRightOriginal: any; + backdrop: any; + + constructor(props?: object) { + super('div', props); + this._id = 'defaultModal'; + this.bodyPaddingRightOriginal = + parseInt(window.getComputedStyle(document.body, null).getPropertyValue('padding-right'), 10); + this.closeModal = this.closeModal.bind(this); + } + + initClose() { + document.addEventListener('click', this.closeModal); + } + + removeClose() { + document.removeEventListener('click', this.closeModal); + } + + closeModal(event: any) { + const target = event; + if ( + target.getAttribute('data-modal') === 'close' || + !target.closest('.d-modal__content, [data-modal="open"]') + ) { + this.hide(); + } + } + + show() { + if ((document.body.clientHeight - document.documentElement.clientHeight) > 0) { + document.body.style.paddingRight = `${this.bodyPaddingRightOriginal}px`; + } + this.initClose(); + this.backdrop = document.createElement('div'); + document.body.classList.add('modal-open'); + const modal = document.getElementById(this._id); + + if (modal) { + modal.classList.add('d-modal--show'); + modal.style.display = 'block'; + modal.ariaModal = 'true'; + modal.ariaHidden = null; + modal.setAttribute('role', 'dialog'); + } + + this.backdrop.className = 'modal-backdrop'; + document.body.append(this.backdrop); + } + + hide() { + document.body.classList.remove('modal-open'); + document.body.style.paddingRight = ''; + + const modal: HTMLElement | null = document.querySelector('.d-modal'); + + if (!modal) { + console.error('Modal element not found'); + + return; + } + + modal.classList.remove('d-modal--show'); + modal.style.display = 'none'; + modal.ariaModal = null; + modal.ariaHidden = 'true'; + modal.removeAttribute('role'); + + this.backdrop.remove(); + this.removeClose(); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/RegistrationForm/RegistrationForm.tmp.pug b/src/components/RegistrationForm/RegistrationForm.tmp.pug index 0448cc793..b5c7d8119 100644 --- a/src/components/RegistrationForm/RegistrationForm.tmp.pug +++ b/src/components/RegistrationForm/RegistrationForm.tmp.pug @@ -9,3 +9,4 @@ form.form .form__field!= fieldPassword .form__field.form__field--accent!= sendBtn .form__field.t-right!= link + .form__field.form__field--error!= errorText diff --git a/src/components/RegistrationForm/RegistrationForm.ts b/src/components/RegistrationForm/RegistrationForm.ts index 8bc83ee35..39f7c5f42 100644 --- a/src/components/RegistrationForm/RegistrationForm.ts +++ b/src/components/RegistrationForm/RegistrationForm.ts @@ -1,20 +1,46 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./RegistrationForm.tmp.pug"; +import AuthController from "../../controllers/AuthController"; import { getValuesFromForm } from "../utils/index"; import { Event } from "../utils/getValuesFromForm"; +// import type { SignupData } from "../../api/auth-api"; + export default class RegistrationForm extends Block { constructor(props?: object) { const newProps = { ...props, events: new Map([ - ['submit', (event: Event) => getValuesFromForm(event, this)], + ['submit', (event: Event) => { + const formData = getValuesFromForm(event, this); + + if (formData) { + AuthController.signup(formData); + + Store.on(StoreEvents.Error, () => { + const { error } = Store.getState(); + + this.setProps({ + errorText: error, + }) + this.showError(); + }); + } + }], ]), } super('div', newProps); } + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + render() { return this.compile(template, this.props); } diff --git a/src/components/Spinner/Spinner.scss b/src/components/Spinner/Spinner.scss new file mode 100644 index 000000000..f0f3d8b18 --- /dev/null +++ b/src/components/Spinner/Spinner.scss @@ -0,0 +1,28 @@ +.loader-wrapper { + display: flex; + justify-content: center; + + @at-root .chats & { + margin-top: 15px; + } +} + +.loader { + display: inline-block; + box-sizing: border-box; + border: 5px solid #fff; + border-bottom-color: var(--m-color-1); + width: 48px; + height: 48px; + border-radius: 50%; + animation: rotation 1s linear infinite; +} + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/components/Spinner/Spinner.tmp.pug b/src/components/Spinner/Spinner.tmp.pug new file mode 100644 index 000000000..d73d945b0 --- /dev/null +++ b/src/components/Spinner/Spinner.tmp.pug @@ -0,0 +1,2 @@ +.loader-wrapper + span.loader diff --git a/src/components/Spinner/Spinner.ts b/src/components/Spinner/Spinner.ts new file mode 100644 index 000000000..4c260c59c --- /dev/null +++ b/src/components/Spinner/Spinner.ts @@ -0,0 +1,14 @@ +import { Block } from "../../core/index"; +import template from "./Spinner.tmp.pug"; + +import "./Spinner.scss"; + +export default class Spinner extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/Title/Title.tmp.pug b/src/components/Title/Title.tmp.pug new file mode 100644 index 000000000..ce06f356c --- /dev/null +++ b/src/components/Title/Title.tmp.pug @@ -0,0 +1,13 @@ +case tag + when 'h1' + h1(className=className)= text + when 'h2' + h2(className=className)= text + when 'h3' + h3(className=className)= text + when 'h4' + h4(className=className)= text + when 'h5' + h5(className=className)= text + when 'h6' + h6(className=className)= text diff --git a/src/components/Title/Title.ts b/src/components/Title/Title.ts new file mode 100644 index 000000000..a01cb0ca0 --- /dev/null +++ b/src/components/Title/Title.ts @@ -0,0 +1,12 @@ +import { Block } from "../../core/index"; +import template from "./Title.tmp.pug"; + +export default class Title extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/UploadAvatarForm/UploadAvatarForm.tmp.pug b/src/components/UploadAvatarForm/UploadAvatarForm.tmp.pug new file mode 100644 index 000000000..2ffab774a --- /dev/null +++ b/src/components/UploadAvatarForm/UploadAvatarForm.tmp.pug @@ -0,0 +1,7 @@ +form.form.form--t-1 + .form__field.t-center + label.link(for="avatar") Choose avatar + input(id="avatar", name="avatar", type="file", accept=".jpg, .jpeg, .png, .webp", hidden) + input(name="chatId", value=chatId type="text", hidden) + .form__field!= sendBtn + .form__field.form__field--error.t-center!= errorText diff --git a/src/components/UploadAvatarForm/UploadAvatarForm.ts b/src/components/UploadAvatarForm/UploadAvatarForm.ts new file mode 100644 index 000000000..2be9c0c20 --- /dev/null +++ b/src/components/UploadAvatarForm/UploadAvatarForm.ts @@ -0,0 +1,49 @@ +import { Block, Store, StoreEvents } from "../../core/index"; +import template from "./UploadAvatarForm.tmp.pug"; +import { ChatsController } from "../../controllers"; + +import type { Event } from "../utils/getValuesFromForm"; + +export default class UploadAvatarForm extends Block { + constructor(props?: object) { + const newProps = { + ...props, + events: new Map([ + ['submit', (event: Event) => { + event.preventDefault(); + this.hideError(); + + const form = this.element.querySelector('form'); + const formData = new FormData(form); + + if (formData) { + ChatsController.uploadAvatar(formData); + + Store.on(StoreEvents.Error, () => { + const { error } = Store.getState(); + + this.setProps({ + errorText: error, + }) + this.showError(); + }); + } + }], + ]), + } + + super('div', newProps); + } + + public showError() { + this.element.querySelector('.form__field--error').classList.add('active'); + } + + public hideError() { + this.element.querySelector('.form__field--error').classList.remove('active'); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/UserInformation/UserInformation.scss b/src/components/UserInformation/UserInformation.scss new file mode 100644 index 000000000..9c9533a47 --- /dev/null +++ b/src/components/UserInformation/UserInformation.scss @@ -0,0 +1,16 @@ +.user-information { + $block-name: &; + + display: flex; + justify-content: space-between; + align-items: center; + + &__f { + display: flex; + align-items: center; + } + + &__f-s { + margin-left: 15px; + } +} diff --git a/src/components/UserInformation/UserInformation.tmp.pug b/src/components/UserInformation/UserInformation.tmp.pug new file mode 100644 index 000000000..897e4b296 --- /dev/null +++ b/src/components/UserInformation/UserInformation.tmp.pug @@ -0,0 +1,6 @@ +.user-information + .user-information__f + .user-information__f-f!= userAvatar + .user-information__f-s!= userName + + .user-information__s!= userProfileLink diff --git a/src/components/UserInformation/UserInformation.ts b/src/components/UserInformation/UserInformation.ts new file mode 100644 index 000000000..27f43e0d3 --- /dev/null +++ b/src/components/UserInformation/UserInformation.ts @@ -0,0 +1,14 @@ +import { Block } from "../../core/index"; +import template from "./UserInformation.tmp.pug"; + +import "./UserInformation.scss"; + +export default class UserInformation extends Block { + constructor(props?: object) { + super('div', props); + } + + render() { + return this.compile(template, this.props); + } +} diff --git a/src/components/index.ts b/src/components/index.ts index bfd40e712..81daca0b5 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -2,9 +2,25 @@ import AuthorizationForm from "./AuthorizationForm/AuthorizationForm"; import RegistrationForm from "./RegistrationForm/RegistrationForm"; import EditingSettingsForm from "./EditingSettingsForm/EditingSettingsForm" import EditingPasswordForm from "./EditingPasswordForm/EditingPasswordForm"; +import CreateChatForm from "./CreateChatForm/CreateChatForm"; import FieldText from "./FieldText/FieldText"; import Button from "./Button/Button"; import Link from "./Link/Link"; +import Avatar from "./Avatar/Avatar"; +import Title from "./Title/Title"; +import Chats from "./Chats/Chats"; +import Chat from "./Chat/Chat"; +import UserInformation from "./UserInformation/UserInformation"; +import Spinner from "./Spinner/Spinner"; +import Layout from "./Layout/Layout"; +import ChatArea from "./ChatArea/ChatArea"; +import ChatInformation from "./ChatInformation/ChatInformation"; +import Modal from "./Modal/Modal"; +import UploadAvatarForm from "./UploadAvatarForm/UploadAvatarForm"; +import AddUserForm from "./AddUserForm/AddUserForm"; +import DeleteUserForm from "./DeleteUserForm/DeleteUserForm"; +import Message from "./Message/Message"; +import Conversation from "./Conversation/Conversation"; export { AuthorizationForm, @@ -14,4 +30,20 @@ export { FieldText, Button, Link, + Avatar, + Title, + Chat, + Chats, + UserInformation, + Spinner, + Layout, + CreateChatForm, + ChatArea, + ChatInformation, + Modal, + UploadAvatarForm, + AddUserForm, + DeleteUserForm, + Message, + Conversation, } diff --git a/src/components/utils/getValuesFromForm.ts b/src/components/utils/getValuesFromForm.ts index c85ee2928..776e454fc 100644 --- a/src/components/utils/getValuesFromForm.ts +++ b/src/components/utils/getValuesFromForm.ts @@ -2,18 +2,32 @@ type Event = { preventDefault: Function } +function isValidForm(form: Element) { + const errors = form.querySelectorAll('.field-text--invalid'); + + if (errors.length === 0) return true; + + return false; +} + export default function getValuesFromForm(event: Event, instance: any) { event.preventDefault(); - const formValues: Record = {}; - Object.entries(instance.children).forEach(([name, child]: [string, any]) => { + const formValues: any = {}; + + Object.values(instance.children).forEach((child: any) => { if (child.value) { + const { name } = child._meta.props; formValues[name] = child.value(); child.validate(); } }) - console.log(formValues); + if (isValidForm(instance.element)) { + return formValues; + } + + return undefined; } export type { diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts new file mode 100644 index 000000000..d85b31f8a --- /dev/null +++ b/src/controllers/AuthController.ts @@ -0,0 +1,68 @@ +import AuthAPI from "../api/auth-api"; +import { Store, router } from "../core"; + +import type { SignupData, SigninData } from "../api/auth-api"; + +class AuthController { + public signup(data: SignupData) { + AuthAPI.signup(data) + .then((xhr) => { + if (xhr.status === 200) { + sessionStorage.setItem("inSystem", "true"); + router.go('/messenger'); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public signin(data: SigninData) { + AuthAPI.signin(data) + .then((xhr) => { + if (xhr.status === 200) { + sessionStorage.setItem("inSystem", "true"); + router.go('/messenger'); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public logout() { + AuthAPI.logout() + .then(() => { + sessionStorage.removeItem("inSystem"); + router.go('/'); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public getUserInfo() { + AuthAPI.getUserInfo() + .then((xhr) => { + if (xhr.status === 200) { + const userData = JSON.parse(xhr.responseText); + Store.set('user', userData); + } + }) + .catch((error) => { + console.error(`${error}`); + }) + } +} + +export default new AuthController(); diff --git a/src/controllers/ChatsController.ts b/src/controllers/ChatsController.ts new file mode 100644 index 000000000..b015c3806 --- /dev/null +++ b/src/controllers/ChatsController.ts @@ -0,0 +1,168 @@ +import { Store } from "../core"; +import ChatsAPI from "../api/chats-api"; +import { UsersController } from "./index"; +import { merge } from "../utils/index"; + +import type { CreateData, IdData } from "../api/chats-api"; + +type ActionUser = { + chatId: number, + login: string +} + +class ChatsController { + public request() { + ChatsAPI.request() + .then((xhr) => { + if (xhr.status === 200) { + const chats = JSON.parse(xhr.responseText); + Store.set('chats', chats); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public create(data: CreateData) { + ChatsAPI.create(data) + .then((xhr) => { + if (xhr.status === 200) { + this.request(); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public uploadAvatar(data: FormData) { + ChatsAPI.uploadAvatar(data) + .then((xhr) => { + if (xhr.status === 200) { + const data = JSON.parse(xhr.responseText); + const { chats } = Store.getState(); + + chats.forEach((chat: any) => { + if (chat.id === data.id) { + merge(chat, data) + } + }) + + Store.set('chats', chats); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public async addUsers(item: ActionUser) { + const { chatId, login } = item; + const searchData = { login }; + const users: any[] = await UsersController.search(searchData); + + if (!users || users.length === 0) return; + + const foundUser = users.find(({ login: userLogin }) => userLogin === login); + + if (!foundUser) return `User with login:${login} not found`; + + const addUsersData = { + chatId, + users: [foundUser.id], + } + const xhr = await ChatsAPI.addUsers(addUsersData); + + return xhr.responseText; + } + + public async deleteUsers(item: ActionUser) { + const { chatId, login } = item; + const users: any[] = await this.getUsers(chatId); + + if (!users || users.length === 0) return; + + const foundUser = users.find(({ login: userLogin }) => userLogin === login); + + if (!foundUser) return `User with login:${login} not found`; + + const addUsersData = { + chatId, + users: [foundUser.id], + } + const xhr = await ChatsAPI.deleteUsers(addUsersData); + + return xhr.responseText; + } + + public async getUsers(id: number, parameters = {}) { + const xhr = await ChatsAPI.getUsers(id, parameters); + + if (xhr.status !== 200) return; + + let res = null; + + try { + res = JSON.parse(xhr.responseText); + } catch (error) { + console.error(error); + } + + return res; + } + + public delete(data: IdData) { + ChatsAPI.delete(data) + .then((xhr) => { + if (xhr.status === 200) { + const { result } = JSON.parse(xhr.responseText); + const { chats } = Store.getState(); + const updatedChats = chats.filter((chat: any) => chat.id !== result.id); + Store.set('chats', updatedChats); + Store.set('selectedChat', null); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public async getToken(id: number) { + const xhr = await ChatsAPI.getToken(id); + + if (xhr.status !== 200) return; + + let res = null; + + try { + res = JSON.parse(xhr.responseText); + } catch (error) { + console.error(error); + } + + return res; + } +} + +export default new ChatsController(); diff --git a/src/controllers/UsersController.ts b/src/controllers/UsersController.ts new file mode 100644 index 000000000..df6632d40 --- /dev/null +++ b/src/controllers/UsersController.ts @@ -0,0 +1,90 @@ +import UsersAPI from "../api/users-api"; +import { Store } from "../core"; + +import type { + UserData, + PasswordData, + SearchData, +} from "../api/users-api"; + +class UsersController { + public changeProfile(data: UserData) { + UsersAPI.changeProfile(data) + .then((xhr) => { + if (xhr.status === 200) { + const userData = JSON.parse(xhr.responseText); + Store.set('user', userData); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public changeAvatar(data: FormData) { + UsersAPI.changeAvatar(data) + .then((xhr) => { + if (xhr.status === 200) { + const userData = JSON.parse(xhr.responseText); + Store.set('user', userData); + + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public changePassword(data: PasswordData) { + UsersAPI.changePassword(data) + .then((xhr) => { + if (xhr.status === 200) { + return; + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + }) + .catch((error) => { + console.error(`${error}`); + }) + } + + public async search(data: SearchData) { + const xhr = await UsersAPI.search(data); + + if (xhr.status === 200) { + return JSON.parse(xhr.responseText); + } + + const { reason } = JSON.parse(xhr.responseText); + Store.set('error', reason); + } + + public async request(id: number) { + const xhr = await UsersAPI.request(id); + + if (xhr.status !== 200) return; + + let res = null; + + try { + res = JSON.parse(xhr.responseText); + } catch (error) { + console.error(error); + } + + return res; + } +} + +export default new UsersController(); diff --git a/src/controllers/index.ts b/src/controllers/index.ts new file mode 100644 index 000000000..5d3598cf9 --- /dev/null +++ b/src/controllers/index.ts @@ -0,0 +1,9 @@ +import AuthController from "./AuthController"; +import ChatsController from "./ChatsController"; +import UsersController from "./UsersController"; + +export { + AuthController, + ChatsController, + UsersController, +} diff --git a/src/core/Block.ts b/src/core/Block.ts index b7faf0b7c..5cfa9c9d0 100644 --- a/src/core/Block.ts +++ b/src/core/Block.ts @@ -1,9 +1,5 @@ import { v4 as uuid } from "uuid"; import EventBus from "./EventBus"; -// import { isEqualObjects } from "../utils"; - -// использую any, потому что не получилось типизировать по хорошему, -// а время на исходе) type Props = Record; @@ -16,6 +12,7 @@ export default abstract class Block { INIT: "init", FLOW_CDM: "flow:component-did-mount", FLOW_CDU: "flow:component-did-update", + FLOW_CWU: "flow:component-will-unmount", FLOW_RENDER: "flow:render", }; @@ -52,6 +49,7 @@ export default abstract class Block { eventBus.on(Block.EVENTS.INIT, this.init.bind(this)); eventBus.on(Block.EVENTS.FLOW_CDM, this._componentDidMount.bind(this)); eventBus.on(Block.EVENTS.FLOW_CDU, this._componentDidUpdate.bind(this)); + eventBus.on(Block.EVENTS.FLOW_CWU, this._componentWillUnmount.bind(this)); eventBus.on(Block.EVENTS.FLOW_RENDER, this._render.bind(this)); } @@ -62,6 +60,14 @@ export default abstract class Block { Object.entries(propsAndChildren).forEach(([key, value]) => { if (value instanceof Block) { children[key] = value; + } else if (Array.isArray(value)) { + children[key] = []; + + value.forEach((item) => { + if (item instanceof Block) { + children[key].push(item); + } + }) } else { props[key] = value; } @@ -92,8 +98,16 @@ export default abstract class Block { _componentDidMount() { this.componentDidMount(); + this.dispatchComponentDidMount(); + Object.values(this.children).forEach((child: any) => { - child.dispatchComponentDidMount(); + if (Array.isArray(child)) { + child.forEach((item) => { + item.dispatchComponentDidMount(); + }) + } else { + child.dispatchComponentDidMount(); + } }); } @@ -104,6 +118,26 @@ export default abstract class Block { this._addEvents(); } + _componentWillUnmount() { + this.componentWillUnmount(); + + Object.values(this.children).forEach((child: any) => { + if (Array.isArray(child)) { + child.forEach((item) => { + item.dispatchComponentWillUnmount(); + }) + } else { + child.dispatchComponentWillUnmount(); + } + }); + } + + componentWillUnmount() {} + + dispatchComponentWillUnmount() { + this._removeEvents(); + } + setProps = (newProps: Props) => { if (!newProps) { return; @@ -123,7 +157,12 @@ export default abstract class Block { this._removeEvents(); this._element.innerHTML = ''; - this._element.appendChild(block); + if (this.props.append === false) { + this._element = block; + } else { + this._element.appendChild(block); + } + this.eventBus().emit(Block.EVENTS.FLOW_CDM); } @@ -135,15 +174,30 @@ export default abstract class Block { const propsAndStubs = { ...props }; Object.entries(this.children).forEach(([key, child]: [string, any]) => { - propsAndStubs[key] = `
`; + if (Array.isArray(child)) { + propsAndStubs[key] = []; + + child.forEach((item) => { + propsAndStubs[key].push(`
`); + }) + } else { + propsAndStubs[key] = `
`; + } }) const fragment = this._createDocumentElement('template'); fragment.innerHTML = template(propsAndStubs); Object.values(this.children).forEach((child: Props) => { - const stub = fragment.content.querySelector(`[data-id="${child._id}"]`); - stub.replaceWith(child.getContent()); + if (Array.isArray(child)) { + child.forEach((item) => { + const stub = fragment.content.querySelector(`[data-id="${item._id}"]`); + stub.replaceWith(item.getContent()); + }) + } else { + const stub = fragment.content.querySelector(`[data-id="${child._id}"]`); + stub.replaceWith(child.getContent()); + } }); return fragment.content; @@ -158,6 +212,8 @@ export default abstract class Block { events.forEach((eventFun: Function, eventName: string) => { if (eventName === 'blur') { this._element.querySelector('input')?.addEventListener(eventName, eventFun); + } else if (eventName === 'keydown') { + this._element.querySelector('input')?.addEventListener(eventName, eventFun); } else { this._element.addEventListener(eventName, eventFun); } @@ -170,6 +226,8 @@ export default abstract class Block { events.forEach((eventFun: Function, eventName: string) => { if (eventName === 'blur') { this._element.querySelector('input')?.removeEventListener(eventName, eventFun); + } else if (eventName === 'keydown') { + this._element.querySelector('input')?.removeEventListener(eventName, eventFun); } else { this._element.removeEventListener(eventName, eventFun); } @@ -205,9 +263,19 @@ export default abstract class Block { return proxyProps; } + _show() { + this.show(); + } + + show() { + } + _hide() { this.hide(); } - hide() {} + hide() { + this.eventBus().emit(Block.EVENTS.FLOW_CWU); + this._element.remove(); + } } diff --git a/src/core/Router/Route.ts b/src/core/Router/Route.ts index c44589961..4dd96830b 100644 --- a/src/core/Router/Route.ts +++ b/src/core/Router/Route.ts @@ -1,6 +1,11 @@ -import { render } from "../../utils"; +import { render as renderPage } from "../../utils"; export default class Route { + _pathname: string; + _blockClass: any; + _block: any; + _props: any; + constructor(pathname: string, view: any, props: object) { this._pathname = pathname; this._blockClass = view; @@ -8,7 +13,7 @@ export default class Route { this._props = props; } - navigate(pathname) { + navigate(pathname: string) { if (this.match(pathname)) { this._pathname = pathname; this.render(); @@ -21,21 +26,15 @@ export default class Route { } } - match(pathname) { + match(pathname: string) { return pathname === this._pathname; } render() { if (!this._block) { - - console.log(this._blockClass); - this._block = new this._blockClass(); - render(this._props.rootQuery, this._block); - - return; } - this._block.show(); + renderPage(this._props.rootQuery, this._block); } } diff --git a/src/core/Router/Router.ts b/src/core/Router/Router.ts index 06e31c641..6fe03b153 100644 --- a/src/core/Router/Router.ts +++ b/src/core/Router/Router.ts @@ -1,8 +1,25 @@ import Route from "./Route"; -export default class Router { +import { + Authorization, + registration as Registration, + UserSettings, + ChatsAndChat, + EditingSettings, + EditingPassword, +} from "../../pages/index"; + +class Router { + __instance: any; + routes: any; + history: any; + _currentRoute: any; + _rootQuery; + constructor(rootQuery: string) { + // @ts-ignore if (Router.__instance) { + // @ts-ignore return Router.__instance; } @@ -10,7 +27,7 @@ export default class Router { this.history = window.history; this._currentRoute = null; this._rootQuery = rootQuery; - + // @ts-ignore Router.__instance = this; } @@ -22,7 +39,8 @@ export default class Router { } start() { - window.onpopstate = (event) => { + window.onpopstate = (event: any) => { + event.preventDefault(); this._onRoute(event.currentTarget.location.pathname); } @@ -31,10 +49,28 @@ export default class Router { _onRoute(pathname: string) { console.log(pathname); + const inSystem = sessionStorage.getItem("inSystem"); + console.log(inSystem); + + if (pathname !== '/') { + if (!inSystem || inSystem === 'false') { + this.go('/'); + + return; + } + } else if (pathname === '/') { + if (inSystem === 'true') { + this.go('/messenger'); + + return; + } + } const route = this.getRoute(pathname); if (!route) { + this.go('/messenger'); + return; } @@ -43,7 +79,7 @@ export default class Router { } this._currentRoute = route; - route.render(route, pathname); + route.render(); } go(pathname: string) { @@ -60,6 +96,14 @@ export default class Router { } getRoute(pathname: string) { - return this.routes.find(route => route.match(pathname)); + return this.routes.find((route: Route) => route.match(pathname)); } } + +export default new Router('#app') + .use("/", Authorization) + .use("/sign-up", Registration) + .use('/messenger', ChatsAndChat) + .use('/settings', UserSettings) + .use('/editing-settings', EditingSettings) + .use('/editing-password', EditingPassword) diff --git a/src/core/Store.ts b/src/core/Store.ts new file mode 100644 index 000000000..84abd807d --- /dev/null +++ b/src/core/Store.ts @@ -0,0 +1,60 @@ +import { EventBus } from "./index"; +import { set } from "../utils/index" + +export enum StoreEvents { + Updated = 'updated', + UserUpdate = 'user:update', + ChatsUpdate = 'chats:update', + ChatsSelected = 'chats:selected', + ChatsMessage = 'chats:message', + Error = 'error', +} + +type GetState = { + error: string, + user: any, + chats: any[], + messages: any[], + selectedChat: any, +} + +class Store extends EventBus { + private state = { + error: '', + user: {}, + chats: [], + messages: [], + selectedChat: null, + }; + + public getState(): GetState { + return this.state; + } + + public set(path: string, value: unknown) { + set(this.state, path, value); + + switch (path) { + case 'user': + this.emit(StoreEvents.UserUpdate); + break; + case 'chats': + this.emit(StoreEvents.ChatsUpdate); + break; + case 'selectedChat': + this.emit(StoreEvents.ChatsSelected); + break; + case 'messages': + this.emit(StoreEvents.ChatsMessage); + break; + case 'error': + this.emit(StoreEvents.Error); + break; + default: + this.emit(StoreEvents.Updated); + break; + } + } +} + +export default new Store(); diff --git a/src/core/WebSocket.ts b/src/core/WebSocket.ts new file mode 100644 index 000000000..d1c22084d --- /dev/null +++ b/src/core/WebSocket.ts @@ -0,0 +1,5 @@ +// export default class WSocket { +// constructor(url) { +// this._socket = new WebSocket(url); +// } +// } diff --git a/src/core/index.ts b/src/core/index.ts index 195b92bad..5b982f18a 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,11 +1,14 @@ import EventBus from './EventBus'; import Block from './Block'; -import Router from './Router/Router'; +import router from './Router/Router'; import Route from './Router/Route'; +import Store, { StoreEvents } from './Store'; export { Block, EventBus, - Router, + router, Route, + Store, + StoreEvents, }; diff --git a/src/editing-password/editing-password.ts b/src/editing-password/editing-password.ts deleted file mode 100644 index 012a7c9c8..000000000 --- a/src/editing-password/editing-password.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { render } from "../utils/index"; -import { EditingPassword } from "../pages/index"; - -import "../scss/index.scss"; - -const page = new EditingPassword(); - -render(page); diff --git a/src/editing-password/index.html b/src/editing-password/index.html deleted file mode 100644 index 5bdc0f74b..000000000 --- a/src/editing-password/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Editing password page - - -
- - - diff --git a/src/editing-settings/editing-settings.ts b/src/editing-settings/editing-settings.ts deleted file mode 100644 index 94e454f26..000000000 --- a/src/editing-settings/editing-settings.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { render } from "../utils/index"; -import { EditingSettings } from "../pages/index"; - -import "../scss/index.scss"; - -const page = new EditingSettings(); - -render(page); diff --git a/src/editing-settings/index.html b/src/editing-settings/index.html deleted file mode 100644 index c4daa207a..000000000 --- a/src/editing-settings/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Editing settings page - - -
- - - diff --git a/src/index.ts b/src/index.ts index 0e393ecdb..9f395a717 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,4 @@ -import { Router } from "./core/index"; -import { Authorization, registration as Registration } from "./pages/index"; - +import { router } from "./core/index"; import "./scss/index.scss"; -const router = new Router('#app'); -router - .use("/", Authorization) - .use("/sign-up", Registration) - .start() - -// const root = document.querySelector('#app'); - -// if (root) { -// render(root, page); -// } +router.start(); diff --git a/src/pages/Authorization/Authorization.ts b/src/pages/Authorization/Authorization.ts index 285d78ae1..f9f7009db 100644 --- a/src/pages/Authorization/Authorization.ts +++ b/src/pages/Authorization/Authorization.ts @@ -39,6 +39,7 @@ const authForm = new AuthorizationForm({ href: '/sign-up', text: 'Sign up', }), + errorText: '', }) export default class Authorization extends Block { diff --git a/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug b/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug index 9533c251c..5f1aec271 100644 --- a/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug +++ b/src/pages/ChatsAndChat/ChatsAndChat.tmp.pug @@ -1,64 +1,25 @@ .chats-and-chat aside.sidebar .sidebar__f - form.search!= fieldSearch - .sidebar__s - .sidebar__s-inner - .chats - each val in [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15] - article.chat(tabindex="0") - .chat__f - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .chat__s - .chat__s-f - h6.name Chat name - time.chat__time 10:45 - .chat__s-s - p.chat__last-message last message last message last message last message last message last message - - .sidebar__t - .user-information - .user-information__f - .user-information__f-f - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .user-information__f-s - h6.name User name - - .user-information__s - button.settings(type="button") ... + .dropdown.dropdown--t-6 + button.dropdown__trigger( + type="button", + title="Open the chat creation menu", + aria-expanded="false", + aria-controls="createChat" + data-open-text="Open the chat creation menu" + data-close-text="Close the chat creation menu" + ) + span.link Create chat + #createChat.dropdown__body + .dropdown__body-inner!= createChatForm - .chat-area - .chat-area__f - .chat-area__f-f - .chat-area__info - .chat-area__info-l - .avatar - img.avatar__img(src="img/avatar-dummy-1.jpg", alt="user name avatar", loading="lazy") - .chat-area__info-r - h6.name Chat name - - .chat-area__f-s - button.settings(type="button") ... + form.search!= fieldSearch - .chat-area__s - .messages-area - .messages-area__f - .messages-area__conversation - each val in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - .messages-area__conversation-item.messages-area__conversation-received - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .sidebar__s + .sidebar__s-inner!= chatsArea - .messages-area__conversation-item.messages-area__conversation-sent - .messages-area__conversation-message - | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptatum iste non corrupti molestias. Provident dolorum nostrum quasi id modi cumque doloribus nemo, beatae veritatis rem. Ducimus, amet dicta? Adipisci, corrupti? + .sidebar__t!= userInformation - .messages-area__s - .messages-area__s-inner!= fieldMessage - .messages-area__buttons - button.settings(type="button") ... - button.settings(type="button") ... + | !{chatArea} + | !{modal} diff --git a/src/pages/ChatsAndChat/ChatsAndChat.ts b/src/pages/ChatsAndChat/ChatsAndChat.ts index 6de8f8968..ac59b3f92 100644 --- a/src/pages/ChatsAndChat/ChatsAndChat.ts +++ b/src/pages/ChatsAndChat/ChatsAndChat.ts @@ -1,11 +1,44 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./ChatsAndChat.tmp.pug"; import { FieldText, + Avatar, + Title, + UserInformation, + Link, + Spinner, + Chats, + Chat, + Layout, + CreateChatForm, + Button, + ChatArea, + ChatInformation, + Modal, + UploadAvatarForm, + AddUserForm, + DeleteUserForm, + Message, + Conversation, } from "../../components/index"; +import { AuthController, ChatsController, UsersController } from "../../controllers"; + +const createChatForm = new CreateChatForm({ + chatName: new FieldText({ + withId: true, + type: 'text', + name: 'title', + placeholder: 'Enter chat name', + }), + createBtn: new Button({ + withId: true, + className: 'btn btn--w-100', + text: 'Create chat', + }), + errorText: '', +}); const fieldSearch = new FieldText({ - withId: true, mods: 'field-text--center field-text--white', type: 'text', name: 'search', @@ -13,18 +46,370 @@ const fieldSearch = new FieldText({ placeholder: 'search', }) -const fieldMessage = new FieldText({ +const chatsArea = new Chats({ withId: true, - mods: 'field-text--main', - type: 'text', - name: 'message', - value: '', - placeholder: 'Type a message', + chats: [new Spinner()], +}) + +const userInformation = new UserInformation({ + userAvatar: new Avatar(), + userName: new Title({ + tag: 'h6', + className: 'name', + text: '', + }), + userProfileLink: new Link({ + className: 'name', + href: '/settings', + text: 'Settings', + }), +}); + +const chatArea = new Layout({ + withId: true, + content: '

Select chat

', +}) + +const modal = new Modal({ + title: 'My modal', + content: '

Modal content

', }) export default class ChatsAndChat extends Block { constructor(props?: object) { - super('div', { ...props, fieldSearch, fieldMessage }); + super('div', { + ...props, + createChatForm, + fieldSearch, + chatsArea, + userInformation, + chatArea, + modal, + }); + + ChatsController.request(); + AuthController.getUserInfo(); + + Store + .on(StoreEvents.UserUpdate, () => { + const { user: { avatar, first_name } } = Store.getState(); + const { userAvatar, userName } = this.children.userInformation.children; + + if (avatar) { + userAvatar.setProps({ + src: avatar, + alt: `${first_name} avatar`, + }) + } + + userName.setProps({ + text: first_name, + }) + }) + .on(StoreEvents.ChatsUpdate, () => { + const { chats, selectedChat } = Store.getState(); + const { chatsArea, chatArea } = this.children; + + if (chats.length > 0) { + chatsArea.children['chats'] = chats.map(( + { + id, + avatar, + title, + last_message, + }, + ) => { + return new Chat({ + id, + withId: true, + chatAvatar: new Avatar({ + src: avatar, + alt: `Avatar of the chat ${title}`, + }), + chatName: title, + lastMessage: last_message || null, + }) + }); + chatsArea._render(); + + if (selectedChat) { + const { chatInfo } = chatArea.children['content'].children; + const { chatAvatar } = chatInfo.children; + + for (const chat of chats) { + if (chat.id === selectedChat) { + chatAvatar.setProps({ + src: chat.avatar, + }) + break; + } + } + } + } else { + chatsArea.children = []; + chatsArea.setProps({ + chats: '

Create your first chat!

', + }) + } + }) + .on(StoreEvents.ChatsSelected, async () => { + const { chatArea, modal } = this.children; + const { + user, + chats, + selectedChat: selectedChatId, + } = Store.getState(); + + if (!selectedChatId) { + chatArea.children = []; + chatArea.setProps({ + content: ` +

Select chat

+ `, + }) + + return; + } + + const { + id, + avatar, + title, + last_message, + } = chats.find((chat) => chat.id === selectedChatId); + + id as number; + + const wsBaseURL = 'wss://ya-praktikum.tech/ws/chats/'; + const response = await ChatsController.getToken(id); + const { token } = response; + + const socket = new WebSocket(`${wsBaseURL}${user.id}/${id}/${token}`); + + socket.addEventListener('open', () => { + console.log('Соединение установлено'); + }); + + socket.addEventListener('close', (event) => { + if (event.wasClean) { + console.log('Соединение закрыто чисто'); + } else { + console.log('Обрыв соединения'); + } + + console.log(`Код: ${event.code} | Причина: ${event.reason}`); + }); + + socket.addEventListener('message', async (event) => { + let result = null; + try { + result = JSON.parse(event.data); + } catch (error) { + console.error(error); + } + const { content, time, user_id } = result; + const { chats, selectedChat: selectedChatId, messages } = Store.getState(); + const userInfo = await UsersController.request(user_id); + + const updatedChats = chats.map((item) => { + if (item.id === selectedChatId) { + item.last_message = { + content, + time, + user: userInfo, + } + } + + return item; + }); + + messages.push({ + content, + time, + user: userInfo, + }); + + Store.set('chats', updatedChats); + Store.set('messages', messages); + }); + + socket.addEventListener('error', (event: any) => { + console.log('Ошибка', event.message); + }); + + const arrMessages = last_message ? [last_message] : []; + + chatArea.children['content'] = new ChatArea({ + chatInfo: new ChatInformation({ + chatAvatar: new Avatar({ + src: avatar, + alt: `avatar ${title}`, + }), + chatName: title, + chatButtons: [ + new Button({ + className: 'btn btn--w-100', + type: 'button', + text: 'Change avatar', + attributes: { 'data-modal': 'open' }, + events: new Map([ + ['click', () => { + modal.children['content'] = new UploadAvatarForm({ + chatId: id, + sendBtn: new Button({ + className: 'btn btn--w-100', + text: 'Send', + }), + }); + modal.setProps({ + title: 'Change chat avatar', + content: '', + }) + modal.show(); + }], + ]), + }), + new Button({ + className: 'btn btn--w-100', + type: 'button', + text: 'Add user', + attributes: { 'data-modal': 'open' }, + events: new Map([ + ['click', () => { + modal.children['content'] = new AddUserForm({ + chatId: id, + fieldChatId: new FieldText({ + name: 'chatId', + value: id, + attributes: { hidden: '' }, + }), + fieldAddUser: new FieldText({ + type: 'text', + name: 'login', + placeholder: 'Enter the user\'s login', + helpText: ` + от 3 до 20 символов, латиница, может содержать цифры, + но не состоять из них, без пробелов, без спецсимволов + (допустимы дефис и нижнее подчёркивание) + `, + pattern: '(?=^.{3,20}$)[a-zA-Z_-]+[0-9_-a-zA-Z]*', + }), + sendBtn: new Button({ + className: 'btn btn--w-100', + text: 'Send', + }), + }); + modal.setProps({ + title: 'Add user in chat', + content: '', + }) + modal.show(); + }], + ]), + }), + new Button({ + className: 'btn btn--w-100 btn--red', + type: 'button', + text: 'Delete user', + attributes: { 'data-modal': 'open' }, + events: new Map([ + ['click', () => { + modal.children['content'] = new DeleteUserForm({ + chatId: id, + fieldChatId: new FieldText({ + name: 'chatId', + value: id, + attributes: { hidden: '' }, + }), + fieldDeleteUser: new FieldText({ + type: 'text', + name: 'login', + placeholder: 'Enter the user\'s login', + helpText: ` + от 3 до 20 символов, латиница, может содержать цифры, + но не состоять из них, без пробелов, без спецсимволов + (допустимы дефис и нижнее подчёркивание) + `, + pattern: '(?=^.{3,20}$)[a-zA-Z_-]+[0-9_-a-zA-Z]*', + }), + sendBtn: new Button({ + className: 'btn btn--w-100', + text: 'Send', + }), + }); + modal.setProps({ + title: 'Delete user from chat', + content: '', + }) + modal.show(); + }], + ]), + }), + new Button({ + className: 'btn btn--w-100 btn--red', + type: 'button', + text: 'Delete chat', + events: new Map([ + ['click', () => { + ChatsController.delete({ chatId: id }) + }], + ]), + }), + ], + }), + conversation: new Conversation({ + content: arrMessages.map(({ user: { login }, time, content }) => { + return new Message({ + login, + time, + content, + active_user_login: user.login, + append: false, + }) + }), + }), + fieldMessage: new FieldText({ + mods: 'field-text--main', + type: 'text', + name: 'message', + value: '', + placeholder: 'Type a message, press Enter to send the message', + pattern: '[\\S\\s]+[\\S]+', + events: new Map([ + ['keydown', (event: any) => { + const { target, key } = event + + const value = target.value.trim(); + if (key !== 'Enter' || value.length === 0) return; + + socket.send(JSON.stringify({ + type: 'message', + content: value, + })) + }], + ]), + }), + }) + chatArea._render(); + Store.set('messages', arrMessages); + }) + .on(StoreEvents.ChatsMessage, () => { + const { chatArea } = this.children; + const { conversation } = chatArea.children.content.children; + const { messages, user } = Store.getState(); + + conversation.children['content'] = messages.map(({ user: { login }, time, content }) => { + return new Message({ + login, + time, + content, + active_user_login: user.login, + append: false, + }) + }) + + conversation._render(); + }) } render() { diff --git a/src/pages/EditingPassword/EditingPassword.tmp.pug b/src/pages/EditingPassword/EditingPassword.tmp.pug index 534777381..34f92fe84 100644 --- a/src/pages/EditingPassword/EditingPassword.tmp.pug +++ b/src/pages/EditingPassword/EditingPassword.tmp.pug @@ -4,8 +4,12 @@ .modal__content section.user-settings .user-settings__f - .user-settings__avatar - h2.user-settings__name= userName + .user-settings__avatar(style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") + h2.user-settings__name= first_name .user-settings__s!= userSettings - .user-settings__t!= saveBtn + .user-settings__t + | !{saveBtn} + | !{linkToEditingSettings} + | !{linkToSettings} + | !{linkToChats} diff --git a/src/pages/EditingPassword/EditingPassword.ts b/src/pages/EditingPassword/EditingPassword.ts index 4d7572fbb..38febab45 100644 --- a/src/pages/EditingPassword/EditingPassword.ts +++ b/src/pages/EditingPassword/EditingPassword.ts @@ -1,23 +1,25 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./EditingPassword.tmp.pug"; import { EditingPasswordForm, FieldText, Button, + Link, } from "../../components/index"; +import { AuthController } from "../../controllers"; export default class EditingPassword extends Block { constructor(props?: object) { const newProps = { ...props, - userName: 'User name', + first_name: '-', userSettings: new EditingPasswordForm({ currentPassword: new FieldText({ withId: true, title: 'Current password:', type: 'password', - name: 'old_password', - value: 'jzuXon8ZOT', + name: 'oldPassword', + value: '', helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', tmp: 'setting', @@ -26,7 +28,7 @@ export default class EditingPassword extends Block { withId: true, title: 'New password:', type: 'password', - name: 'new_password', + name: 'newPassword', value: '', helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', @@ -36,22 +38,52 @@ export default class EditingPassword extends Block { withId: true, title: 'Repeat new password:', type: 'password', - name: 'repeat_password', + name: 'repeatNewPassword', value: '', helpText: 'от 8 до 40 символов, обязательно хотя бы одна заглавная буква и цифра', pattern: '(?=^.{8,40}$)(?=.*[A-Z])(?=.*\\d).*', tmp: 'setting', }), + errorText: '', }), saveBtn: new Button({ - className: 'link', + className: 'link link--t-1', type: 'submit', form: 'userSettingsForm', text: 'Save password', }), + linkToEditingSettings: new Link({ + href: '/editing-settings', + text: 'Change settings', + }), + linkToSettings: new Link({ + href: '/settings', + text: 'Profile page', + }), + linkToChats: new Link({ + href: '/messenger', + text: 'Chats page', + }), } super('div', newProps); + + AuthController.getUserInfo(); + + Store + .on(StoreEvents.UserUpdate, () => { + const { + user: { + avatar, + first_name, + }, + } = Store.getState(); + + this.setProps({ + avatar, + first_name, + }) + }) } render() { diff --git a/src/pages/EditingSettings/EditingSettings.tmp.pug b/src/pages/EditingSettings/EditingSettings.tmp.pug index 534777381..ef68a9d6d 100644 --- a/src/pages/EditingSettings/EditingSettings.tmp.pug +++ b/src/pages/EditingSettings/EditingSettings.tmp.pug @@ -4,8 +4,11 @@ .modal__content section.user-settings .user-settings__f - .user-settings__avatar + label.user-settings__avatar(for="avatar", title="Change avatar", style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") h2.user-settings__name= userName .user-settings__s!= userSettings - .user-settings__t!= saveBtn + .user-settings__t + | !{saveBtn} + | !{linkChangePass} + | !{linkProfilePage} diff --git a/src/pages/EditingSettings/EditingSettings.ts b/src/pages/EditingSettings/EditingSettings.ts index fbce677dc..58d255161 100644 --- a/src/pages/EditingSettings/EditingSettings.ts +++ b/src/pages/EditingSettings/EditingSettings.ts @@ -1,23 +1,26 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./EditingSettings.tmp.pug"; import { EditingSettingsForm, FieldText, Button, + Link, } from "../../components/index"; +import { AuthController } from "../../controllers"; export default class EditingSettings extends Block { constructor(props?: object) { const newProps = { ...props, - userName: 'User name', + withId: true, + userName: '-', userSettings: new EditingSettingsForm({ nickname: new FieldText({ withId: true, title: 'Nickname:', type: 'text', name: 'display_name', - value: 'userNickName', + value: '-', helpText: ` латиница или кириллица, без пробелов и без цифр, нет спецсимволов (допустим только дефис) @@ -30,7 +33,7 @@ export default class EditingSettings extends Block { title: 'First name:', type: 'text', name: 'first_name', - value: 'Firstname', + value: '-', helpText: ` латиница или кириллица, первая буква должна быть заглавной, без пробелов и без цифр, нет спецсимволов (допустим только дефис) @@ -43,7 +46,7 @@ export default class EditingSettings extends Block { title: 'Second name:', type: 'text', name: 'second_name', - value: 'Sirstname', + value: '-', helpText: ` латиница или кириллица, первая буква должна быть заглавной, без пробелов и без цифр, нет спецсимволов (допустим только дефис) @@ -57,7 +60,7 @@ export default class EditingSettings extends Block { type: 'text', inputmode: 'email', name: 'email', - value: 'test@test.ru', + value: '-', helpText: ` латиница, может включать цифры и спецсимволы вроде дефиса и подчёркивания, обязательно должна быть «собака» (@) и точка после неё, @@ -72,23 +75,90 @@ export default class EditingSettings extends Block { type: 'text', inputmode: 'tel', name: 'phone', - value: '+70000000000', + value: '-', helpText: ` от 10 до 15 символов, состоит из цифр, может начинается с плюса. `, pattern: '(?=^.{10,15}$)\\+?[0-9]+$', tmp: 'setting', }), + errorText: '', }), saveBtn: new Button({ - className: 'link', + className: 'link link--t-1', type: 'submit', form: 'userSettingsForm', text: 'Save settings', }), + linkChangePass: new Link({ + href: '/editing-password', + text: 'Change password', + }), + linkProfilePage: new Link({ + href: '/settings', + text: 'Profile page', + }), } super('div', newProps); + + AuthController.getUserInfo(); + + Store + .on(StoreEvents.UserUpdate, () => { + const { + user: { + avatar, + display_name, + first_name, + second_name, + email, + phone, + }, + } = Store.getState(); + const { + nickname: nicknameField, + firstName: firstNameField, + secondName: secondNameField, + email: emailField, + phone: phoneField, + } = this.children.userSettings.children; + + if (display_name) { + nicknameField.setProps({ + value: display_name, + }) + } + + if (first_name) { + this.setProps({ + avatar, + userName: first_name, + }) + + firstNameField.setProps({ + value: first_name, + }) + } + + if (second_name) { + secondNameField.setProps({ + value: second_name, + }) + } + + if (email) { + emailField.setProps({ + value: email, + }) + } + + if (phone) { + phoneField.setProps({ + value: phone, + }) + } + }) } render() { diff --git a/src/pages/UserSettings/UserSettings.tmp.pug b/src/pages/UserSettings/UserSettings.tmp.pug index 79f236a9c..10e305ae4 100644 --- a/src/pages/UserSettings/UserSettings.tmp.pug +++ b/src/pages/UserSettings/UserSettings.tmp.pug @@ -1,33 +1,34 @@ .modal .modal__inner - button.modal__close(title="Close modal") + | !{logoutBtn} .modal__content section.user-settings .user-settings__f - .user-settings__avatar - h2.user-settings__name= userName + .user-settings__avatar(style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") + h2.user-settings__name= first_name .user-settings__s ul.user-settings__list li.user-settings__list-item span.user-settings__list-item-name Nickname: - span.user-settings__list-item-value user name + span.user-settings__list-item-value= display_name li.user-settings__list-item span.user-settings__list-item-name First name: - span.user-settings__list-item-value first name + span.user-settings__list-item-value= first_name li.user-settings__list-item span.user-settings__list-item-name Second name: - span.user-settings__list-item-value second name + span.user-settings__list-item-value= second_name li.user-settings__list-item span.user-settings__list-item-name Email: - span.user-settings__list-item-value test@test.ru + span.user-settings__list-item-value= email li.user-settings__list-item span.user-settings__list-item-name Phone: - span.user-settings__list-item-value +7 (000) 000-00-00 + span.user-settings__list-item-value= phone li.user-settings__list-item span.user-settings__list-item-name Login: - span.user-settings__list-item-value mylogin + span.user-settings__list-item-value= login .user-settings__t | !{linkToSettings} | !{linkToPassword} + | !{linkToChats} diff --git a/src/pages/UserSettings/UserSettings.ts b/src/pages/UserSettings/UserSettings.ts index 9775596bb..684f1ccf2 100644 --- a/src/pages/UserSettings/UserSettings.ts +++ b/src/pages/UserSettings/UserSettings.ts @@ -1,22 +1,68 @@ -import { Block } from "../../core/index"; +import { Block, Store, StoreEvents } from "../../core/index"; import template from "./UserSettings.tmp.pug"; -import { Link } from "../../components/index"; +import { Link, Button } from "../../components/index"; +import { AuthController } from "../../controllers"; -export default class ChatsAndChat extends Block { +export default class UserSettings extends Block { constructor(props?: object) { const newProps = { ...props, - userName: 'User name', + logoutBtn: new Button({ + className: 'modal__close', + type: 'button', + text: 'logout', + events: new Map([['click', () => { + AuthController.logout(); + }]]), + }), + avatar: '-', + display_name: '-', + first_name: '-', + second_name: '-', + email: '-', + phone: '-', + login: '-', linkToSettings: new Link({ - href: '/editing-settings/', + href: '/editing-settings', text: 'Change settings', }), linkToPassword: new Link({ - href: '/editing-password/', + href: '/editing-password', text: 'Change password', }), + linkToChats: new Link({ + href: '/messenger', + text: 'Chats page', + }), } super('div', newProps); + + AuthController.getUserInfo(); + + Store + .on(StoreEvents.UserUpdate, () => { + const { + user: { + avatar, + display_name, + first_name, + second_name, + email, + phone, + login, + }, + } = Store.getState(); + + this.setProps({ + avatar, + display_name, + first_name, + second_name, + email, + phone, + login, + }) + }) } render() { diff --git a/src/pages/registration/registration.ts b/src/pages/registration/registration.ts index 8e6857b3c..8a1043a18 100644 --- a/src/pages/registration/registration.ts +++ b/src/pages/registration/registration.ts @@ -85,6 +85,7 @@ const registratonForm = new RegistrationForm({ href: '/', text: 'Sign in', }), + errorText: '', }) export default class Registration extends Block { diff --git a/src/registration/index.html b/src/registration/index.html deleted file mode 100644 index ba9f4ce2d..000000000 --- a/src/registration/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Registration page - - -
- - - diff --git a/src/registration/registration.ts b/src/registration/registration.ts deleted file mode 100644 index e8af456d2..000000000 --- a/src/registration/registration.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { render } from "../utils/index"; -import { registration as Registration } from "../pages/index"; - -import "../scss/index.scss"; - -const page = new Registration(); - -render(page); diff --git a/src/scss/additions.scss b/src/scss/additions.scss index 486bd910d..cd739d448 100644 --- a/src/scss/additions.scss +++ b/src/scss/additions.scss @@ -9,3 +9,7 @@ .t-center { text-align: center; } + +.color-l-grey { + color: var(--t-l-grey-1); +} diff --git a/src/scss/main.scss b/src/scss/main.scss index 3ea9411dd..7b8ccb21d 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -36,6 +36,7 @@ --b-radius: 5px; --on-focus: 0 0 0 2px var(--m-color-1); --on-error: 0 0 0 2px tomato; + --m-color-1: #784dd4; --m-color-1-1: #5e36b2; --m-color-1-2: #d6c4ff; @@ -46,6 +47,7 @@ --t-l-grey-2: #d9d9d9; --t-l-grey-3: #f0f0f0; --bg-whiteSmoke: #f5f5f5; /* stylelint-disable-line */ + --t-duration: 0.3s; } @@ -78,6 +80,14 @@ body { &:focus-visible { box-shadow: var(--on-focus); } + + &--t-1 { + color: var(--m-color-1); + + &:hover { + color: var(--m-color-1-1); + } + } } /* ----- .modal ----- */ @@ -93,7 +103,7 @@ body { top: 0; width: 100%; height: 100%; - background-color: rgb(0 0 0 / 65%); + background-color: rgb(0 0 0 / 15%); &__inner { position: relative; @@ -108,32 +118,41 @@ body { &__close { position: absolute; - top: 15px; - right: 15px; - width: 35px; - height: 35px; - border-radius: 50%; + top: 30px; + right: 30px; cursor: pointer; + border-radius: var(--b-radius); + transition: color var(--t-duration); - &::before, - &::after { - content: ""; - position: absolute; - left: 50%; - top: 50%; - width: 80%; - height: 2px; - border-radius: 5px; - background-color: #333; + &:hover, + &:focus { + color: tomato; } - &::before { - transform: translate(-50%, -50%) rotate(-45deg); + &:focus-visible { + border-radius: 4px; + box-shadow: var(--on-focus); } - &::after { - transform: translate(-50%, -50%) rotate(45deg); - } + // &::before, + // &::after { + // content: ""; + // position: absolute; + // left: 50%; + // top: 50%; + // width: 80%; + // height: 2px; + // border-radius: 5px; + // background-color: #333; + // } + + // &::before { + // transform: translate(-50%, -50%) rotate(-45deg); + // } + + // &::after { + // transform: translate(-50%, -50%) rotate(45deg); + // } } } @@ -165,7 +184,11 @@ body { width: 100px; height: 100px; border-radius: 50%; - background-color: #d9d9d9; + background: #d9d9d9 center/cover no-repeat; + + &:not(div) { + cursor: pointer; + } } &__name { @@ -206,6 +229,12 @@ body { &__list-item-value { color: var(--t-l-grey-1); + transition: color 0.1s; + + &:not(span):hover, + &:not(span):focus { + color: #555; + } @at-root .field-text--invalid & { color: tomato; @@ -275,7 +304,7 @@ body { .sidebar { --indent: 15px; - --height-t: 59px; + --height-t: 96px; --height-b: 100px; $block-name: &; @@ -285,9 +314,19 @@ body { &__f { display: flex; - align-items: flex-end; + flex-direction: column; + padding-top: var(--indent); height: var(--height-t); + .dropdown { + margin-bottom: 15px; + + .dropdown__trigger { + width: 100%; + text-align: center; + } + } + .search { width: 100%; } @@ -333,133 +372,16 @@ body { .chats { $block-name: &; -} - -/* ----- .chat ----- */ - -.chat { - $block-name: &; - display: flex; - padding: 20px; - background-color: #fff; - border-radius: var(--b-radius); - - & + & { + > div + div { margin-top: 15px; } - - &__s { - margin-left: 15px; - } - - &__s-f { - display: flex; - justify-content: space-between; - } - - &__time { - font-size: 14px; - } - - &__s-s { - margin-top: 5px; - } - - &__last-message { - font-size: 14px; - color: var(--t-l-grey-1); - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - } } .name { font-weight: 600; } -/* ----- .avatar ----- */ - -.avatar { - $block-name: &; - - overflow: hidden; - width: 60px; - height: 60px; - border-radius: 50%; - background-color: var(--t-l-grey-3); - - &__img { - width: 100%; - height: 100%; - object-fit: contain; - object-position: center; - } -} - -/* ----- .user-information ----- */ - -.user-information { - $block-name: &; - - display: flex; - justify-content: space-between; - align-items: center; - - &__f { - display: flex; - align-items: center; - } - - &__f-s { - margin-left: 15px; - } -} - -/* ----- .chat-area ----- */ - -.chat-area { - $block-name: &; - - --indent-h: 30px; - --height-f: 72px; - - height: 100vh; - - &__f, - &__s { - padding-left: var(--indent-h); - padding-right: var(--indent-h); - } - - &__f { - display: flex; - justify-content: space-between; - align-items: center; - padding-top: 15px; - padding-bottom: 15px; - height: var(--height-f); - background-color: var(--t-l-grey-2); - } - - &__info { - display: flex; - align-items: center; - } - - &__info-r { - margin-left: 15px; - } - - &__s { - padding-top: 15px; - padding-bottom: 15px; - height: calc(100% - var(--height-f)); - } -} - /* ----- .messages-area ----- */ .messages-area { @@ -553,7 +475,7 @@ body { background-color: var(--bg-whiteSmoke); /* stylelint-disable-line */ &__title { - margin-bottom: 70px; + margin-bottom: 50px; font-size: 35px; font-weight: 500; text-align: center; @@ -567,5 +489,128 @@ body { & + &--accent { margin-top: 40px; } + + &--ok, + &--error { + display: none; + + &.active { + display: block; + } + } + + &--error { + color: tomato; + } + + &--ok { + color: #333; + } + + &--x2 { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px; + } + } + + &--t-1 { + padding: 0; + background-color: transparent; + } +} + +/* ----- .dropdown ----- */ + +.dropdown { + $block-name: &; + + position: relative; + + &.active { + #{$block-name}__body { + opacity: 1; + visibility: visible; + } } + + &__trigger { + position: relative; + text-align: right; + cursor: pointer; + } + + &__body { + position: absolute; + z-index: 4; + right: 0; + padding-top: 10px; + width: 265px; + opacity: 0; + visibility: hidden; + transition-property: opacity, visibility; + transition-duration: var(--t-duration); + } + + &__body-inner { + padding: 15px; + border-radius: var(--b-radius); + box-shadow: 0 5px 20px 0 rgba(20, 44, 64, 0.15), + 0 8px 10px 0 rgba(20, 44, 64, 0.05); + background-color: #fff; + } + + &__body-menu { + font-weight: 500; + font-size: 13px; + line-height: 1.3; + } + + &__body-menu-item { + & + & { + border-top: 1px solid #e9f1f2; + } + } + + &__body-menu-item-link { + display: block; + padding: 16px 24px; + + &:hover { + color: var(--color-1); + } + + &:active { + color: var(--color-1-1); + } + } + + &--t-2 { + #{$block-name}__body { + left: 0; + right: inherit; + } + } + + &--t-6 { + display: inline-block; + + #{$block-name}__body { + min-width: 100%; + } + } +} + +.btns { + display: flex; + flex-wrap: wrap; + gap: 10px; + + > div { + width: 100%; + } +} + +b { + font-weight: 700; } diff --git a/src/user-settings/index.html b/src/user-settings/index.html deleted file mode 100644 index 3dc836112..000000000 --- a/src/user-settings/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - User settings page - - -
- - - diff --git a/src/user-settings/user-settings.ts b/src/user-settings/user-settings.ts deleted file mode 100644 index 24f43142a..000000000 --- a/src/user-settings/user-settings.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { render } from "../utils/index"; -import { UserSettings } from "../pages/index"; - -import "../scss/index.scss"; - -const page = new UserSettings(); - -render(page); diff --git a/src/utils/http.ts b/src/utils/http.ts index ca4dd428a..323a969a4 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -14,17 +14,22 @@ interface IHTTP { } type Options = { - method: string, - headers?: [string, string], - data?: [string, string][], + method?: string, + headers?: Map, + data?: [string, string][] | object, timeout?: number, retries?: number, } -type HTTPMethod = (url: string, options: Options) => Promise; +type XHRInstance = { + status: number, + responseText: string, +} + +type HTTPMethod = (url: string, options?: Options) => Promise; class HTTP implements IHTTP { - get: HTTPMethod = (url, options) => { + get: HTTPMethod = (url, options = {}) => { let resUrl = url; const { data } = options; @@ -35,19 +40,19 @@ class HTTP implements IHTTP { return this.request(resUrl, { ...options, method: METHODS.GET }); }; - post: HTTPMethod = (url, options) => { + post: HTTPMethod = (url, options = {}) => { return this.request(url, { ...options, method: METHODS.POST }); } - put: HTTPMethod = (url, options) => { + put: HTTPMethod = (url, options = {}) => { return this.request(url, { ...options, method: METHODS.PUT }); } - delete: HTTPMethod = (url, options) => { + delete: HTTPMethod = (url, options = {}) => { return this.request(url, { ...options, method: METHODS.DELETE }); } - request: HTTPMethod = (url, options) => { + request: HTTPMethod = (url, options = {}) => { const { method, headers, @@ -57,8 +62,12 @@ class HTTP implements IHTTP { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); + // @ts-ignore xhr.open(method, url); - if (headers) xhr.setRequestHeader(...headers); + xhr.withCredentials = true; + if (headers) { + headers.forEach((value, header) => xhr.setRequestHeader(header, value)) + } xhr.onload = () => { resolve(xhr); @@ -70,7 +79,10 @@ class HTTP implements IHTTP { if (method === METHODS.GET) { xhr.send(); + } else if (data instanceof FormData) { + xhr.send(data as FormData); } else { + xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(data)); } @@ -81,7 +93,7 @@ class HTTP implements IHTTP { }; } -function queryStringify(data: [string, string][]): string { +function queryStringify(data: [string, string][] | object): string { let result = '?'; for (const [key, value] of Object.entries(data)) { @@ -107,3 +119,7 @@ export default HTTP; export { fetchWithRetry, } + +export type { + Options, +} diff --git a/src/utils/index.ts b/src/utils/index.ts index da46a35d1..d48ea537e 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -8,6 +8,8 @@ import isPlainObject from "./isPlainObject"; import isArrayOrObject from "./isArrayOrObject"; import cloneDeep from "./cloneDeep"; import queryStringify from "./queryStringify"; +import set from "./set"; +import initDropdowns from "./initDropDowns"; export { render, @@ -21,4 +23,6 @@ export { isArrayOrObject, cloneDeep, queryStringify, + set, + initDropdowns, } diff --git a/src/utils/initDropDowns.ts b/src/utils/initDropDowns.ts new file mode 100644 index 000000000..31add366c --- /dev/null +++ b/src/utils/initDropDowns.ts @@ -0,0 +1,69 @@ +const initDropdowns = (() => { + function hideDropDown(dropdown: Element, trigger: Element) { + dropdown.classList.remove('active'); + + if (!trigger) return; + + trigger.setAttribute('aria-expanded', 'false'); + if (trigger.hasAttribute('title')) { + const openText = trigger.getAttribute('data-open-text'); + if (openText) { + trigger.setAttribute('title', openText); + } + } + } + + return () => { + const dropdowns = document.querySelectorAll('.dropdown'); + + if (dropdowns.length === 0) return; + + document.addEventListener('click', (e) => { + const dropdowns = document.querySelectorAll('.dropdown'); + const { target } = e; + + if (target instanceof HTMLElement) { + const parent = target.closest('.dropdown'); + + if (!parent) { + dropdowns.forEach((dropdown) => { + const trigger = dropdown.querySelector('.dropdown__trigger'); + if (trigger) { + hideDropDown(dropdown, trigger); + } + }) + + return; + } + + if (!target.closest('.dropdown__trigger')) { + return; + } + + dropdowns.forEach((dropdown) => { + if (dropdown !== parent) { + const trigger = dropdown.querySelector('.dropdown__trigger'); + if (trigger) { + hideDropDown(dropdown, trigger); + } + } + }) + + if (parent.classList.contains('active')) { + hideDropDown(parent, target); + } else { + parent.classList.add('active'); + target.setAttribute('aria-expanded', 'true'); + if (target.hasAttribute('title')) { + const closeText = target.getAttribute('data-close-text'); + if (closeText) { + target.setAttribute('title', closeText); + } + } + } + } + }) + } +})() + +export default initDropdowns; diff --git a/src/utils/merge.ts b/src/utils/merge.ts index a738bd95e..72b88b33e 100644 --- a/src/utils/merge.ts +++ b/src/utils/merge.ts @@ -1,3 +1,3 @@ -export default function merge(arrObj: object[]): object { - return Object.assign({}, ...arrObj); +export default function merge(targetObj: object, obj: object): object { + return Object.assign(targetObj, obj); } diff --git a/src/utils/render.ts b/src/utils/render.ts index 7cf33a294..c92bb64e3 100644 --- a/src/utils/render.ts +++ b/src/utils/render.ts @@ -1,15 +1,16 @@ +import { initDropdowns } from "./index"; + type Page = { getContent: Function } export default function render(root: string, page: Page) { - document.addEventListener('DOMContentLoaded', () => { - const renderPlace = document.querySelector(root); + const renderPlace = document.querySelector(root); - if (renderPlace) { - renderPlace.append(page.getContent()); - } else { - throw new Error('The render root is not found'); - } - }) + if (renderPlace) { + renderPlace.append(page.getContent()); + initDropdowns(); + } else { + throw new Error('The render root is not found'); + } } diff --git a/src/utils/set.ts b/src/utils/set.ts index 5edccb847..05da07f02 100644 --- a/src/utils/set.ts +++ b/src/utils/set.ts @@ -19,5 +19,5 @@ export default function set(obj: Object, path: string, value: any): Object { {}, ) - return merge([obj, objFromKeys]); + return merge(obj, objFromKeys); } From 7f6dacd75cfa1e1fbd9588947a38be6ab6f64152 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 16:15:16 +0300 Subject: [PATCH 30/43] Fix netlify error --- .eslintrc.json | 8 ++++++-- README.md | 8 +++----- package.json | 3 ++- vite.config.ts | 7 ------- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 9f541042b..c0af92cd0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -28,7 +28,11 @@ "arrow-body-style": 0, "no-restricted-syntax": 0, "no-use-before-define": 0, - "operator-linebreak": ["error", "after"] + "operator-linebreak": ["error", "after"], + "no-shadow": 0, + "camelcase": 0, + "dot-notation": 0, + "consistent-return": 0, + "no-constructor-return": 0 } } - diff --git a/README.md b/README.md index c4cb30be6..35427390e 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,11 @@ ## Netlify links - [Sign in](https://deploy--jocular-rugelach-1c03ff.netlify.app/) -- [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/registration/) -- [Chats and chat](https://deploy--jocular-rugelach-1c03ff.netlify.app/chats-and-chat/) -- [User settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/user-settings/) +- [Sign out](https://deploy--jocular-rugelach-1c03ff.netlify.app/sign-up/) +- [Messenger](https://deploy--jocular-rugelach-1c03ff.netlify.app/messenger/) +- [User settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/settings/) - [User editing settings](https://deploy--jocular-rugelach-1c03ff.netlify.app/editing-settings/) - [User editing password](https://deploy--jocular-rugelach-1c03ff.netlify.app/editing-password/) -- [Page 404](https://deploy--jocular-rugelach-1c03ff.netlify.app/404/) -- [Page 500](https://deploy--jocular-rugelach-1c03ff.netlify.app/500/) ## Установка diff --git a/package.json b/package.json index fd6fb0aad..dfb3d09dd 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "start": "concurrently \"npm run build\" \"ts-node-esm server.ts\"", "dev": "vite", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "type-check": "tsc" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/vite.config.ts b/vite.config.ts index 1d957c4ea..3cb19d13b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,13 +13,6 @@ export default defineConfig({ rollupOptions: { input: { index: resolve(__dirname, 'src/index.html'), - registration: resolve(__dirname, 'src/registration/index.html'), - page404: resolve(__dirname, 'src/404/index.html'), - page500: resolve(__dirname, 'src/500/index.html'), - chatsAndchat: resolve(__dirname, 'src/chats-and-chat/index.html'), - userSettings: resolve(__dirname, 'src/user-settings/index.html'), - editingSettings: resolve(__dirname, 'src/editing-settings/index.html'), - editingPassword: resolve(__dirname, 'src/editing-password/index.html'), }, }, }, From e2cf5c35796648f9da624ff404ef6547b30464ad Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 16:23:44 +0300 Subject: [PATCH 31/43] Fix netlify redirects --- netlify.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index c7d9945d6..04c3e20f6 100644 --- a/netlify.toml +++ b/netlify.toml @@ -6,4 +6,9 @@ # “publish” is the directory to publish (relative to the root of your repo). [build] - publish = "build" \ No newline at end of file + publish = "build" + +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 From 8d581f32bc385e4ba3bb23cb5848ff325007db6a Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 16:32:36 +0300 Subject: [PATCH 32/43] Fix AuthController --- src/controllers/AuthController.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index d85b31f8a..88a96d60b 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -33,6 +33,12 @@ class AuthController { } const { reason } = JSON.parse(xhr.responseText); + if (reason === 'User already in system') { + sessionStorage.setItem("inSystem", "true"); + router.go('/messenger'); + + return; + } Store.set('error', reason); }) .catch((error) => { From b005067964f8fb354a790935fb13d39400e9fe59 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 16:49:03 +0300 Subject: [PATCH 33/43] Fix Router --- src/core/Router/Router.ts | 60 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/core/Router/Router.ts b/src/core/Router/Router.ts index 6fe03b153..bb32b3e1d 100644 --- a/src/core/Router/Router.ts +++ b/src/core/Router/Router.ts @@ -48,29 +48,59 @@ class Router { } _onRoute(pathname: string) { - console.log(pathname); const inSystem = sessionStorage.getItem("inSystem"); - console.log(inSystem); - if (pathname !== '/') { - if (!inSystem || inSystem === 'false') { - this.go('/'); - - return; - } - } else if (pathname === '/') { - if (inSystem === 'true') { - this.go('/messenger'); - - return; - } + switch (pathname) { + case '/': + if (inSystem === 'true') { + this.go('/messenger'); + return; + } + break; + + case '/sign-up': + if (inSystem === 'true') { + this.go('/messenger'); + return; + } + break; + + case '/messenger': + if (!inSystem || inSystem === 'false') { + this.go('/'); + return; + } + break; + + case '/settings': + if (!inSystem || inSystem === 'false') { + this.go('/'); + return; + } + break; + + case '/editing-settings': + if (!inSystem || inSystem === 'false') { + this.go('/'); + return; + } + break; + + case '/editing-password': + if (!inSystem || inSystem === 'false') { + this.go('/'); + return; + } + break; + + default: + break; } const route = this.getRoute(pathname); if (!route) { this.go('/messenger'); - return; } From b12290fc5c9dfde0c2505d83ed2181259dcca975 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 17:03:16 +0300 Subject: [PATCH 34/43] Fix test stylelint --- src/components/Button/Button.scss | 8 ++++---- src/components/Modal/Modal.scss | 13 +++++------- src/components/Spinner/Spinner.scss | 1 + src/scss/main.scss | 32 ++++++++--------------------- 4 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/components/Button/Button.scss b/src/components/Button/Button.scss index dbf6ea069..6773adab7 100644 --- a/src/components/Button/Button.scss +++ b/src/components/Button/Button.scss @@ -36,12 +36,12 @@ } &--red { - border-color: rgb(240, 91, 64); - background-color: rgb(240, 91, 64); + border-color: rgb(240 91 64); + background-color: rgb(240 91 64); &:hover { - border-color: rgb(219, 76, 51); - background-color: rgb(219, 76, 51); + border-color: rgb(219 76 51); + background-color: rgb(219 76 51); } } } diff --git a/src/components/Modal/Modal.scss b/src/components/Modal/Modal.scss index d64f9d859..653edf5ce 100644 --- a/src/components/Modal/Modal.scss +++ b/src/components/Modal/Modal.scss @@ -38,9 +38,6 @@ border-radius: var(--b-radius); } - &__header { - } - &__title { margin-bottom: 30px; font-size: 20px; @@ -73,8 +70,8 @@ background: transparent; pointer-events: none; - &:before, - &:after { + &::before, + &::after { content: ""; position: absolute; top: 0; @@ -85,11 +82,11 @@ transform-origin: 50% 50%; } - &:before { + &::before { transform: rotate3d(0, 0, 1, 45deg); } - &:after { + &::after { transform: rotate3d(0, 0, 1, -45deg); } } @@ -145,7 +142,7 @@ z-index: 999; width: 100vw; height: 100vh; - background-color: #000000; + background-color: #000; animation: modal-backdrop 0.3s 1 ease-out forwards; } diff --git a/src/components/Spinner/Spinner.scss b/src/components/Spinner/Spinner.scss index f0f3d8b18..2ec3f344d 100644 --- a/src/components/Spinner/Spinner.scss +++ b/src/components/Spinner/Spinner.scss @@ -22,6 +22,7 @@ 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } diff --git a/src/scss/main.scss b/src/scss/main.scss index 7b8ccb21d..ef6be0309 100644 --- a/src/scss/main.scss +++ b/src/scss/main.scss @@ -1,3 +1,5 @@ +/* stylelint-disable selector-class-pattern, no-descending-specificity, color-function-notation */ + @font-face { font-display: swap; font-family: Roboto; @@ -36,7 +38,6 @@ --b-radius: 5px; --on-focus: 0 0 0 2px var(--m-color-1); --on-error: 0 0 0 2px tomato; - --m-color-1: #784dd4; --m-color-1-1: #5e36b2; --m-color-1-2: #d6c4ff; @@ -47,7 +48,6 @@ --t-l-grey-2: #d9d9d9; --t-l-grey-3: #f0f0f0; --bg-whiteSmoke: #f5f5f5; /* stylelint-disable-line */ - --t-duration: 0.3s; } @@ -320,11 +320,11 @@ body { .dropdown { margin-bottom: 15px; + } - .dropdown__trigger { - width: 100%; - text-align: center; - } + .dropdown__trigger { + width: 100%; + text-align: center; } .search { @@ -333,24 +333,8 @@ body { } &__s { - // position: relative; - padding: var(--indent) 0; height: calc(100vh - (var(--height-t) + var(--height-b))); - - // &::before { - // content: ""; - // position: absolute; - // left: 0; - // bottom: 0; - // width: 100%; - // height: 50%; - // background: linear-gradient( - // 90deg, - // rgba(255, 255, 255, 0) 0%, - // rgba(255, 255, 255, 0) 100% - // ); - // } } &__s-inner { @@ -555,8 +539,8 @@ body { &__body-inner { padding: 15px; border-radius: var(--b-radius); - box-shadow: 0 5px 20px 0 rgba(20, 44, 64, 0.15), - 0 8px 10px 0 rgba(20, 44, 64, 0.05); + box-shadow: 0 5px 20px 0 rgba(20, 44, 64, 15%), + 0 8px 10px 0 rgba(20, 44, 64, 5%); background-color: #fff; } From 120710bd965e59a5d76099902bf5df6964a9369e Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 17:08:51 +0300 Subject: [PATCH 35/43] Fix ts error --- .eslintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index c0af92cd0..e0b45bd1d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -33,6 +33,7 @@ "camelcase": 0, "dot-notation": 0, "consistent-return": 0, - "no-constructor-return": 0 + "no-constructor-return": 0, + "@typescript-eslint/ban-ts-comment": 0 } } From f2256a4b49dabff2220bc3f4b52afd20fe45700d Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 17:11:18 +0300 Subject: [PATCH 36/43] Fix ts error --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index e0b45bd1d..50d3e8c75 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -34,6 +34,6 @@ "dot-notation": 0, "consistent-return": 0, "no-constructor-return": 0, - "@typescript-eslint/ban-ts-comment": 0 + "@typescript-eslint/ban-ts-comment": "off" } } From 393b3d6a05e3b5cdbcc565b7791dfd8beea330fc Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 17:18:53 +0300 Subject: [PATCH 37/43] Fix ts error --- .eslintrc.json | 3 +-- src/core/Router/Router.ts | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 50d3e8c75..c0af92cd0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -33,7 +33,6 @@ "camelcase": 0, "dot-notation": 0, "consistent-return": 0, - "no-constructor-return": 0, - "@typescript-eslint/ban-ts-comment": "off" + "no-constructor-return": 0 } } diff --git a/src/core/Router/Router.ts b/src/core/Router/Router.ts index bb32b3e1d..047d0dd1a 100644 --- a/src/core/Router/Router.ts +++ b/src/core/Router/Router.ts @@ -10,16 +10,14 @@ import { } from "../../pages/index"; class Router { - __instance: any; + static __instance: Router; routes: any; history: any; _currentRoute: any; _rootQuery; constructor(rootQuery: string) { - // @ts-ignore if (Router.__instance) { - // @ts-ignore return Router.__instance; } @@ -27,7 +25,6 @@ class Router { this.history = window.history; this._currentRoute = null; this._rootQuery = rootQuery; - // @ts-ignore Router.__instance = this; } From 2b992b1989bea8276af46027e1a460eb3047918b Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 17:25:08 +0300 Subject: [PATCH 38/43] Fix ts error --- src/utils/http.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/http.ts b/src/utils/http.ts index 323a969a4..2ab1178da 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -62,8 +62,9 @@ class HTTP implements IHTTP { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); - // @ts-ignore - xhr.open(method, url); + if (method) { + xhr.open(method, url); + } xhr.withCredentials = true; if (headers) { headers.forEach((value, header) => xhr.setRequestHeader(header, value)) From eb8ec2952170fd83cde0eb0b697bdac6d6916ce0 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 18:15:26 +0300 Subject: [PATCH 39/43] Fix express error --- package-lock.json | 43 +++++++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ server.ts | 15 ++++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index d67a541f6..61e63f754 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,14 @@ "uuid": "^9.0.1" }, "devDependencies": { + "@types/cors": "^2.8.14", "@types/express": "^4.17.17", "@types/pug": "^2.0.6", "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", + "cors": "^2.8.5", "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", @@ -1002,6 +1004,15 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.14", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.14.tgz", + "integrity": "sha512-RXHUvNWYICtbP6s18PnOCaqToK8y14DnLd75c6HfyKf228dxy7pHNOQkxPtvXKp/hINFMDjbYzsj63nnpPMSRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -2126,6 +2137,19 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -7493,6 +7517,15 @@ "@types/node": "*" } }, + "@types/cors": { + "version": "2.8.14", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.14.tgz", + "integrity": "sha512-RXHUvNWYICtbP6s18PnOCaqToK8y14DnLd75c6HfyKf228dxy7pHNOQkxPtvXKp/hINFMDjbYzsj63nnpPMSRQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/express": { "version": "4.17.17", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", @@ -8326,6 +8359,16 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", diff --git a/package.json b/package.json index dfb3d09dd..04546ef8f 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,14 @@ "type-check": "tsc" }, "devDependencies": { + "@types/cors": "^2.8.14", "@types/express": "^4.17.17", "@types/pug": "^2.0.6", "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", + "cors": "^2.8.5", "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", diff --git a/server.ts b/server.ts index 761344110..23b959292 100644 --- a/server.ts +++ b/server.ts @@ -1,10 +1,23 @@ -import express from 'express'; // eslint-disable-line +import path from 'path'; +import { fileURLToPath } from 'url'; +import express from 'express'; +import cors from 'cors'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); const app = express(); const port = 3000; +app.use(cors()); + app.use(express.static('build')); +// @ts-ignore +app.get('*', (req, res) => { + res.sendFile(path.join(__dirname, 'build/index.html')) +}) + app.listen(port, () => { console.log(`Example app listening on port ${port}`); }); From 289483298ecc570535365669b11862106375b07f Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 18:19:51 +0300 Subject: [PATCH 40/43] Fix express error --- server.ts | 1 - tsconfig.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/server.ts b/server.ts index 23b959292..ddb79ddda 100644 --- a/server.ts +++ b/server.ts @@ -13,7 +13,6 @@ app.use(cors()); app.use(express.static('build')); -// @ts-ignore app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build/index.html')) }) diff --git a/tsconfig.json b/tsconfig.json index 1b94f9f57..c98056eed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "esModuleInterop": true, "noEmit": true, "noUnusedLocals": true, - "noUnusedParameters": true, + "noUnusedParameters": false, "noImplicitAny": true, "noImplicitReturns": true, "skipLibCheck": true, From d62cfffe36eab740750ed0f79072591a24d5941e Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Mon, 16 Oct 2023 18:21:40 +0300 Subject: [PATCH 41/43] Fix express error --- server.ts | 1 + tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server.ts b/server.ts index ddb79ddda..baa304deb 100644 --- a/server.ts +++ b/server.ts @@ -14,6 +14,7 @@ app.use(cors()); app.use(express.static('build')); app.get('*', (req, res) => { + console.log(req); res.sendFile(path.join(__dirname, 'build/index.html')) }) diff --git a/tsconfig.json b/tsconfig.json index c98056eed..1b94f9f57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "esModuleInterop": true, "noEmit": true, "noUnusedLocals": true, - "noUnusedParameters": false, + "noUnusedParameters": true, "noImplicitAny": true, "noImplicitReturns": true, "skipLibCheck": true, From c902ad263612461c544020e087e7a30d2d8beeed Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Wed, 18 Oct 2023 12:06:01 +0300 Subject: [PATCH 42/43] Fix modal close error, clear input after send message, fix changes avatar error, added BASE_URL const etc... --- package-lock.json | 19 +++++ package.json | 1 + server.ts | 3 +- src/.env | 1 + src/api/auth-api.ts | 12 ++-- src/api/chats-api.ts | 30 ++++---- src/api/users-api.ts | 16 ++--- src/components/Avatar/Avatar.tmp.pug | 2 +- src/components/Avatar/Avatar.ts | 2 +- src/components/Message/Message.ts | 4 +- src/components/Modal/Modal.ts | 2 +- src/controllers/AuthController.ts | 24 +++---- src/controllers/ChatsController.ts | 72 +++++++------------ src/controllers/UsersController.ts | 50 +++++-------- src/env.d.ts | 9 +++ src/index.ts | 1 + src/pages/ChatsAndChat/ChatsAndChat.ts | 51 ++++++++----- .../EditingPassword/EditingPassword.tmp.pug | 2 +- src/pages/EditingPassword/EditingPassword.ts | 2 + .../EditingSettings/EditingSettings.tmp.pug | 2 +- src/pages/EditingSettings/EditingSettings.ts | 1 + src/pages/UserSettings/UserSettings.tmp.pug | 2 +- src/pages/UserSettings/UserSettings.ts | 1 + src/utils/http.ts | 66 ++++++++++++----- 24 files changed, 208 insertions(+), 167 deletions(-) create mode 100644 src/.env create mode 100644 src/env.d.ts diff --git a/package-lock.json b/package-lock.json index 61e63f754..ae4800f48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", "cors": "^2.8.5", + "dotenv": "^16.3.1", "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", @@ -2412,6 +2413,18 @@ "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -8551,6 +8564,12 @@ "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" }, + "dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "dev": true + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package.json b/package.json index 04546ef8f..b7b244ef7 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@typescript-eslint/parser": "^6.7.0", "concurrently": "^8.2.1", "cors": "^2.8.5", + "dotenv": "^16.3.1", "eslint": "^8.49.0", "eslint-config-airbnb": "^19.0.4", "express": "^4.18.2", diff --git a/server.ts b/server.ts index baa304deb..5ded08fed 100644 --- a/server.ts +++ b/server.ts @@ -13,8 +13,7 @@ app.use(cors()); app.use(express.static('build')); -app.get('*', (req, res) => { - console.log(req); +app.get('*', (_req, res) => { res.sendFile(path.join(__dirname, 'build/index.html')) }) diff --git a/src/.env b/src/.env new file mode 100644 index 000000000..9ce8f3d63 --- /dev/null +++ b/src/.env @@ -0,0 +1 @@ +VITE_BASE_URL=https://ya-praktikum.tech/api/v2/ diff --git a/src/api/auth-api.ts b/src/api/auth-api.ts index f2bd1a663..e3804a716 100644 --- a/src/api/auth-api.ts +++ b/src/api/auth-api.ts @@ -15,25 +15,23 @@ type SigninData = { password: string, } -const authAPIInstance = new HTTP(); +const authAPIInstance = new HTTP(`${import.meta.env.VITE_BASE_URL}auth/`); class AuthAPI extends BaseAPI { - private _baseURL = 'https://ya-praktikum.tech/api/v2/auth/'; - signup(data: SignupData) { - return authAPIInstance.post(`${this._baseURL}signup`, { data }) + return authAPIInstance.post(`signup`, { data }) } signin(data: SigninData) { - return authAPIInstance.post(`${this._baseURL}signin`, { data }) + return authAPIInstance.post(`signin`, { data }) } logout() { - return authAPIInstance.post(`${this._baseURL}logout`) + return authAPIInstance.post(`logout`) } getUserInfo() { - return authAPIInstance.get(`${this._baseURL}user`) + return authAPIInstance.get(`user`) } } diff --git a/src/api/chats-api.ts b/src/api/chats-api.ts index ae8c028fd..1c8fcb688 100644 --- a/src/api/chats-api.ts +++ b/src/api/chats-api.ts @@ -14,61 +14,59 @@ export type UsersData = { users: number[], } -const chatsAPIInstance = new HTTP(); +const chatsAPIInstance = new HTTP(`${import.meta.env.VITE_BASE_URL}chats/`); class ChatsAPI extends BaseAPI { - private _baseURL = 'https://ya-praktikum.tech/api/v2/chats/'; - request() { - return chatsAPIInstance.get(`${this._baseURL}`); + return chatsAPIInstance.get(); } create(data: CreateData) { - return chatsAPIInstance.post(`${this._baseURL}`, { data }); + return chatsAPIInstance.post('', { data }); } delete(data: IdData) { - return chatsAPIInstance.delete(`${this._baseURL}`, { data }); + return chatsAPIInstance.delete('', { data }); } getFiles(id: number) { - return chatsAPIInstance.get(`${this._baseURL}${id}/files`); + return chatsAPIInstance.get(`${id}/files`); } getArchive(parameters: { [key: string]: any }) { - return chatsAPIInstance.get(`${this._baseURL}archive${queryStringify(parameters)}`); + return chatsAPIInstance.get(`archive${queryStringify(parameters)}`); } archive(data: IdData) { - return chatsAPIInstance.post(`${this._baseURL}archive`, { data }); + return chatsAPIInstance.post(`archive`, { data }); } unarchive(data: IdData) { - return chatsAPIInstance.post(`${this._baseURL}unarchive`, { data }); + return chatsAPIInstance.post(`unarchive`, { data }); } getUsers(id: number, parameters = {}) { - return chatsAPIInstance.get(`${this._baseURL}${id}/users${queryStringify(parameters)}`); + return chatsAPIInstance.get(`${id}/users${queryStringify(parameters)}`); } getNewMessagesCount(id: number) { - return chatsAPIInstance.get(`${this._baseURL}new/${id}`); + return chatsAPIInstance.get(`new/${id}`); } uploadAvatar(data: FormData) { - return chatsAPIInstance.put(`${this._baseURL}avatar`, { data }); + return chatsAPIInstance.put(`avatar`, { data }); } addUsers(data: UsersData) { - return chatsAPIInstance.put(`${this._baseURL}users/`, { data }); + return chatsAPIInstance.put(`users/`, { data }); } deleteUsers(data: UsersData) { - return chatsAPIInstance.delete(`${this._baseURL}users/`, { data }); + return chatsAPIInstance.delete(`users/`, { data }); } getToken(id: number) { - return chatsAPIInstance.post(`${this._baseURL}token/${id}`); + return chatsAPIInstance.post(`token/${id}`); } } diff --git a/src/api/users-api.ts b/src/api/users-api.ts index 802f0651d..36e239523 100644 --- a/src/api/users-api.ts +++ b/src/api/users-api.ts @@ -19,31 +19,27 @@ export type SearchData = { login: string, } -const usersAPIInstance = new HTTP(); +const usersAPIInstance = new HTTP(`${import.meta.env.VITE_BASE_URL}user/`); class UsersAPI extends BaseAPI { - private _baseURL = 'https://ya-praktikum.tech/api/v2/user/'; - request(id: number) { - return usersAPIInstance.get(`${this._baseURL}${id}`); + return usersAPIInstance.get(`${id}`); } changeProfile(data: UserData) { - return usersAPIInstance.put(`${this._baseURL}profile`, { data }); + return usersAPIInstance.put(`profile`, { data }); } changeAvatar(data: FormData) { - const headers = new Map([['Content-Type', 'multipart/form-data']]); - - return usersAPIInstance.put(`${this._baseURL}profile/avatar`, { data, headers }); + return usersAPIInstance.put(`profile/avatar`, { data }); } changePassword(data: PasswordData) { - return usersAPIInstance.put(`${this._baseURL}password`, { data }); + return usersAPIInstance.put(`password`, { data }); } search(data: SearchData) { - return usersAPIInstance.post(`${this._baseURL}search`, { data }); + return usersAPIInstance.post(`search`, { data }); } } diff --git a/src/components/Avatar/Avatar.tmp.pug b/src/components/Avatar/Avatar.tmp.pug index a275154f4..fd61497a0 100644 --- a/src/components/Avatar/Avatar.tmp.pug +++ b/src/components/Avatar/Avatar.tmp.pug @@ -1,2 +1,2 @@ .avatar - img.avatar__img(src=src ? `https://ya-praktikum.tech/api/v2/resources${src}` : 'img/avatar-dummy-1.jpg', alt=alt, loading="lazy") + img.avatar__img(src=src ? `${baseURL}resources${src}` : 'img/avatar-dummy-1.jpg', alt=alt, loading="lazy") diff --git a/src/components/Avatar/Avatar.ts b/src/components/Avatar/Avatar.ts index 0b4dc213c..27393cbc7 100644 --- a/src/components/Avatar/Avatar.ts +++ b/src/components/Avatar/Avatar.ts @@ -5,7 +5,7 @@ import "./Avatar.scss"; export default class Avatar extends Block { constructor(props?: object) { - super('div', props); + super('div', { ...props, baseURL: import.meta.env.VITE_BASE_URL }); } render() { diff --git a/src/components/Message/Message.ts b/src/components/Message/Message.ts index 640a1a6e1..45ba3c723 100644 --- a/src/components/Message/Message.ts +++ b/src/components/Message/Message.ts @@ -8,8 +8,8 @@ export default class Message extends Block { } render() { - const { login, active_user_login } = this.props; + const { user_id, active_user_id } = this.props; - return this.compile(login === active_user_login ? templateInner : templateOuter, this.props); + return this.compile(user_id === active_user_id ? templateInner : templateOuter, this.props); } } diff --git a/src/components/Modal/Modal.ts b/src/components/Modal/Modal.ts index 50b6fa14c..ecc8b9086 100644 --- a/src/components/Modal/Modal.ts +++ b/src/components/Modal/Modal.ts @@ -24,7 +24,7 @@ export default class Modal extends Block { } closeModal(event: any) { - const target = event; + const { target } = event; if ( target.getAttribute('data-modal') === 'close' || !target.closest('.d-modal__content, [data-modal="open"]') diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index 88a96d60b..05ee37dad 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -6,16 +6,15 @@ import type { SignupData, SigninData } from "../api/auth-api"; class AuthController { public signup(data: SignupData) { AuthAPI.signup(data) - .then((xhr) => { - if (xhr.status === 200) { + .then((res) => { + if (res.status === 200) { sessionStorage.setItem("inSystem", "true"); router.go('/messenger'); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -24,22 +23,22 @@ class AuthController { public signin(data: SigninData) { AuthAPI.signin(data) - .then((xhr) => { - if (xhr.status === 200) { + .then((res) => { + if (res.status === 200) { sessionStorage.setItem("inSystem", "true"); router.go('/messenger'); return; } - const { reason } = JSON.parse(xhr.responseText); - if (reason === 'User already in system') { + if (res.response === 'User already in system') { sessionStorage.setItem("inSystem", "true"); router.go('/messenger'); return; } - Store.set('error', reason); + + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -59,10 +58,9 @@ class AuthController { public getUserInfo() { AuthAPI.getUserInfo() - .then((xhr) => { - if (xhr.status === 200) { - const userData = JSON.parse(xhr.responseText); - Store.set('user', userData); + .then((res) => { + if (res.status === 200) { + Store.set('user', res.response); } }) .catch((error) => { diff --git a/src/controllers/ChatsController.ts b/src/controllers/ChatsController.ts index b015c3806..00a9a97bd 100644 --- a/src/controllers/ChatsController.ts +++ b/src/controllers/ChatsController.ts @@ -13,16 +13,14 @@ type ActionUser = { class ChatsController { public request() { ChatsAPI.request() - .then((xhr) => { - if (xhr.status === 200) { - const chats = JSON.parse(xhr.responseText); - Store.set('chats', chats); + .then((res) => { + if (res.status === 200) { + Store.set('chats', res.response); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -31,15 +29,14 @@ class ChatsController { public create(data: CreateData) { ChatsAPI.create(data) - .then((xhr) => { - if (xhr.status === 200) { + .then((res) => { + if (res.status === 200) { this.request(); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -48,9 +45,9 @@ class ChatsController { public uploadAvatar(data: FormData) { ChatsAPI.uploadAvatar(data) - .then((xhr) => { - if (xhr.status === 200) { - const data = JSON.parse(xhr.responseText); + .then((res) => { + if (res.status === 200) { + const { response: data } = res; const { chats } = Store.getState(); chats.forEach((chat: any) => { @@ -64,8 +61,7 @@ class ChatsController { return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -87,9 +83,9 @@ class ChatsController { chatId, users: [foundUser.id], } - const xhr = await ChatsAPI.addUsers(addUsersData); + const res = await ChatsAPI.addUsers(addUsersData); - return xhr.responseText; + return res.response; } public async deleteUsers(item: ActionUser) { @@ -106,42 +102,34 @@ class ChatsController { chatId, users: [foundUser.id], } - const xhr = await ChatsAPI.deleteUsers(addUsersData); + const res = await ChatsAPI.deleteUsers(addUsersData); - return xhr.responseText; + return res.response; } public async getUsers(id: number, parameters = {}) { - const xhr = await ChatsAPI.getUsers(id, parameters); - - if (xhr.status !== 200) return; + const res = await ChatsAPI.getUsers(id, parameters); - let res = null; - - try { - res = JSON.parse(xhr.responseText); - } catch (error) { - console.error(error); - } + if (res.status !== 200) return; - return res; + return res.response; } public delete(data: IdData) { ChatsAPI.delete(data) - .then((xhr) => { - if (xhr.status === 200) { - const { result } = JSON.parse(xhr.responseText); + .then((res) => { + if (res.status === 200) { + const { result } = res.response; const { chats } = Store.getState(); const updatedChats = chats.filter((chat: any) => chat.id !== result.id); + Store.set('chats', updatedChats); Store.set('selectedChat', null); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -149,19 +137,11 @@ class ChatsController { } public async getToken(id: number) { - const xhr = await ChatsAPI.getToken(id); - - if (xhr.status !== 200) return; + const res = await ChatsAPI.getToken(id); - let res = null; - - try { - res = JSON.parse(xhr.responseText); - } catch (error) { - console.error(error); - } + if (res.status !== 200) return; - return res; + return res.response; } } diff --git a/src/controllers/UsersController.ts b/src/controllers/UsersController.ts index df6632d40..ea0cca4da 100644 --- a/src/controllers/UsersController.ts +++ b/src/controllers/UsersController.ts @@ -10,16 +10,14 @@ import type { class UsersController { public changeProfile(data: UserData) { UsersAPI.changeProfile(data) - .then((xhr) => { - if (xhr.status === 200) { - const userData = JSON.parse(xhr.responseText); - Store.set('user', userData); + .then((res) => { + if (res.status === 200) { + Store.set('user', res.response); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -28,16 +26,14 @@ class UsersController { public changeAvatar(data: FormData) { UsersAPI.changeAvatar(data) - .then((xhr) => { - if (xhr.status === 200) { - const userData = JSON.parse(xhr.responseText); - Store.set('user', userData); + .then((res) => { + if (res.status === 200) { + Store.set('user', res.response); return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -46,13 +42,12 @@ class UsersController { public changePassword(data: PasswordData) { UsersAPI.changePassword(data) - .then((xhr) => { - if (xhr.status === 200) { + .then((res) => { + if (res.status === 200) { return; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); }) .catch((error) => { console.error(`${error}`); @@ -60,30 +55,21 @@ class UsersController { } public async search(data: SearchData) { - const xhr = await UsersAPI.search(data); + const res = await UsersAPI.search(data); - if (xhr.status === 200) { - return JSON.parse(xhr.responseText); + if (res.status === 200) { + return res.response; } - const { reason } = JSON.parse(xhr.responseText); - Store.set('error', reason); + Store.set('error', res.response); } public async request(id: number) { - const xhr = await UsersAPI.request(id); + const res = await UsersAPI.request(id); - if (xhr.status !== 200) return; + if (res.status !== 200) return; - let res = null; - - try { - res = JSON.parse(xhr.responseText); - } catch (error) { - console.error(error); - } - - return res; + return res.response; } } diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 000000000..0288fa787 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,9 @@ +/// + +interface ImportMetaEnv { + readonly VITE_BASE_URL: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} diff --git a/src/index.ts b/src/index.ts index 9f395a717..b1994e726 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { router } from "./core/index"; + import "./scss/index.scss"; router.start(); diff --git a/src/pages/ChatsAndChat/ChatsAndChat.ts b/src/pages/ChatsAndChat/ChatsAndChat.ts index ac59b3f92..f05ef2560 100644 --- a/src/pages/ChatsAndChat/ChatsAndChat.ts +++ b/src/pages/ChatsAndChat/ChatsAndChat.ts @@ -158,6 +158,7 @@ export default class ChatsAndChat extends Block { user, chats, selectedChat: selectedChatId, + messages, } = Store.getState(); if (!selectedChatId) { @@ -175,7 +176,6 @@ export default class ChatsAndChat extends Block { id, avatar, title, - last_message, } = chats.find((chat) => chat.id === selectedChatId); id as number; @@ -188,6 +188,17 @@ export default class ChatsAndChat extends Block { socket.addEventListener('open', () => { console.log('Соединение установлено'); + + socket.send(JSON.stringify({ + type: 'get old', + content: '0', + })) + + setInterval(() => { + socket.send(JSON.stringify({ + type: 'ping', + })) + }, 30000) }); socket.addEventListener('close', (event) => { @@ -207,8 +218,20 @@ export default class ChatsAndChat extends Block { } catch (error) { console.error(error); } + + if (result.type === 'pong') { + return; + } + + if (Array.isArray(result)) { + Store.set('messages', result.reverse()); + + return; + } + const { content, time, user_id } = result; const { chats, selectedChat: selectedChatId, messages } = Store.getState(); + const userInfo = await UsersController.request(user_id); const updatedChats = chats.map((item) => { @@ -223,11 +246,7 @@ export default class ChatsAndChat extends Block { return item; }); - messages.push({ - content, - time, - user: userInfo, - }); + messages.push(result); Store.set('chats', updatedChats); Store.set('messages', messages); @@ -237,8 +256,6 @@ export default class ChatsAndChat extends Block { console.log('Ошибка', event.message); }); - const arrMessages = last_message ? [last_message] : []; - chatArea.children['content'] = new ChatArea({ chatInfo: new ChatInformation({ chatAvatar: new Avatar({ @@ -358,12 +375,12 @@ export default class ChatsAndChat extends Block { ], }), conversation: new Conversation({ - content: arrMessages.map(({ user: { login }, time, content }) => { + content: messages.map(({ user_id, time, content }) => { return new Message({ - login, + user_id, time, content, - active_user_login: user.login, + active_user_id: user.id, append: false, }) }), @@ -385,25 +402,27 @@ export default class ChatsAndChat extends Block { socket.send(JSON.stringify({ type: 'message', content: value, - })) + })); + + target.value = ''; }], ]), }), }) + chatArea._render(); - Store.set('messages', arrMessages); }) .on(StoreEvents.ChatsMessage, () => { const { chatArea } = this.children; const { conversation } = chatArea.children.content.children; const { messages, user } = Store.getState(); - conversation.children['content'] = messages.map(({ user: { login }, time, content }) => { + conversation.children['content'] = messages.map(({ user_id, time, content }) => { return new Message({ - login, + user_id, time, content, - active_user_login: user.login, + active_user_id: user.id, append: false, }) }) diff --git a/src/pages/EditingPassword/EditingPassword.tmp.pug b/src/pages/EditingPassword/EditingPassword.tmp.pug index 34f92fe84..7cd65b3be 100644 --- a/src/pages/EditingPassword/EditingPassword.tmp.pug +++ b/src/pages/EditingPassword/EditingPassword.tmp.pug @@ -4,7 +4,7 @@ .modal__content section.user-settings .user-settings__f - .user-settings__avatar(style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") + .user-settings__avatar(style=`background-image: url(${baseURL}resources${avatar})`) h2.user-settings__name= first_name .user-settings__s!= userSettings diff --git a/src/pages/EditingPassword/EditingPassword.ts b/src/pages/EditingPassword/EditingPassword.ts index 38febab45..a6be5469f 100644 --- a/src/pages/EditingPassword/EditingPassword.ts +++ b/src/pages/EditingPassword/EditingPassword.ts @@ -12,8 +12,10 @@ export default class EditingPassword extends Block { constructor(props?: object) { const newProps = { ...props, + baseURL: import.meta.env.VITE_BASE_URL, first_name: '-', userSettings: new EditingPasswordForm({ + baseURL: import.meta.env.VITE_BASE_URL, currentPassword: new FieldText({ withId: true, title: 'Current password:', diff --git a/src/pages/EditingSettings/EditingSettings.tmp.pug b/src/pages/EditingSettings/EditingSettings.tmp.pug index ef68a9d6d..addc340d9 100644 --- a/src/pages/EditingSettings/EditingSettings.tmp.pug +++ b/src/pages/EditingSettings/EditingSettings.tmp.pug @@ -4,7 +4,7 @@ .modal__content section.user-settings .user-settings__f - label.user-settings__avatar(for="avatar", title="Change avatar", style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") + label.user-settings__avatar(for="avatar", title="Change avatar", style=`background-image: url(${baseURL}resources${avatar})`) h2.user-settings__name= userName .user-settings__s!= userSettings diff --git a/src/pages/EditingSettings/EditingSettings.ts b/src/pages/EditingSettings/EditingSettings.ts index 58d255161..b4c57754c 100644 --- a/src/pages/EditingSettings/EditingSettings.ts +++ b/src/pages/EditingSettings/EditingSettings.ts @@ -14,6 +14,7 @@ export default class EditingSettings extends Block { ...props, withId: true, userName: '-', + baseURL: import.meta.env.VITE_BASE_URL, userSettings: new EditingSettingsForm({ nickname: new FieldText({ withId: true, diff --git a/src/pages/UserSettings/UserSettings.tmp.pug b/src/pages/UserSettings/UserSettings.tmp.pug index 10e305ae4..d06af7f78 100644 --- a/src/pages/UserSettings/UserSettings.tmp.pug +++ b/src/pages/UserSettings/UserSettings.tmp.pug @@ -4,7 +4,7 @@ .modal__content section.user-settings .user-settings__f - .user-settings__avatar(style="background-image: url(" + `https://ya-praktikum.tech/api/v2/resources${avatar}` + ")") + .user-settings__avatar(style=`background-image: url(${baseURL}resources${avatar})`) h2.user-settings__name= first_name .user-settings__s diff --git a/src/pages/UserSettings/UserSettings.ts b/src/pages/UserSettings/UserSettings.ts index 684f1ccf2..d98282cf8 100644 --- a/src/pages/UserSettings/UserSettings.ts +++ b/src/pages/UserSettings/UserSettings.ts @@ -7,6 +7,7 @@ export default class UserSettings extends Block { constructor(props?: object) { const newProps = { ...props, + baseURL: import.meta.env.VITE_BASE_URL, logoutBtn: new Button({ className: 'modal__close', type: 'button', diff --git a/src/utils/http.ts b/src/utils/http.ts index 2ab1178da..2e2d14ce7 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -14,45 +14,68 @@ interface IHTTP { } type Options = { - method?: string, headers?: Map, data?: [string, string][] | object, timeout?: number, retries?: number, } -type XHRInstance = { +type MethodOnly = { + method: string, +} + +type OptionsWithMethod = Options & MethodOnly; + +// type XHRInstance = { +// status: number, +// responseText: string, +// } + +type ReturnedData = { status: number, - responseText: string, + response: any } -type HTTPMethod = (url: string, options?: Options) => Promise; +type HTTPMethod = (url?: string, options?: Options) => Promise; +type HTTPMethodRequest = (url: string, options: OptionsWithMethod) => Promise; class HTTP implements IHTTP { - get: HTTPMethod = (url, options = {}) => { - let resUrl = url; + private _baseURL; + + constructor(baseURL?: string) { + this._baseURL = baseURL || ''; + } + + get: HTTPMethod = (url = '', options = {}) => { + let resURL = `${this._baseURL}${url}`; const { data } = options; if (data) { - resUrl = queryStringify(data); + resURL = queryStringify(data); } - return this.request(resUrl, { ...options, method: METHODS.GET }); + return this.request(resURL, { ...options, method: METHODS.GET }); }; post: HTTPMethod = (url, options = {}) => { - return this.request(url, { ...options, method: METHODS.POST }); + const resURL = `${this._baseURL}${url}`; + + return this.request(resURL, { ...options, method: METHODS.POST }); } put: HTTPMethod = (url, options = {}) => { - return this.request(url, { ...options, method: METHODS.PUT }); + const resURL = `${this._baseURL}${url}`; + + return this.request(resURL, { ...options, method: METHODS.PUT }); } delete: HTTPMethod = (url, options = {}) => { - return this.request(url, { ...options, method: METHODS.DELETE }); + const resURL = `${this._baseURL}${url}`; + + return this.request(resURL, { ...options, method: METHODS.DELETE }); } - request: HTTPMethod = (url, options = {}) => { + request: HTTPMethodRequest = (url, options) => { const { method, headers, @@ -62,16 +85,25 @@ class HTTP implements IHTTP { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); - if (method) { - xhr.open(method, url); - } + xhr.open(method, url); xhr.withCredentials = true; if (headers) { headers.forEach((value, header) => xhr.setRequestHeader(header, value)) } xhr.onload = () => { - resolve(xhr); + let response = ''; + try { + response = JSON.parse(xhr.responseText); + } catch (error) { + console.error(error); + } + + const data = { + response, + status: xhr.status, + } + resolve(data); }; xhr.onabort = reject; @@ -81,7 +113,7 @@ class HTTP implements IHTTP { if (method === METHODS.GET) { xhr.send(); } else if (data instanceof FormData) { - xhr.send(data as FormData); + xhr.send(data); } else { xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(data)); From d0f037200bc5e612ecc89559878d99336ea47871 Mon Sep 17 00:00:00 2001 From: Evgeny Talagaev Date: Wed, 18 Oct 2023 14:05:50 +0300 Subject: [PATCH 43/43] Fix autologin redirect --- src/controllers/AuthController.ts | 9 ++++++--- src/controllers/ChatsController.ts | 12 ++++++++---- src/controllers/UsersController.ts | 12 ++++++++---- src/utils/http.ts | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index 05ee37dad..a30eaf519 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -14,7 +14,8 @@ class AuthController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -31,14 +32,16 @@ class AuthController { return; } - if (res.response === 'User already in system') { + const { reason } = res.response; + + if (reason === 'User already in system') { sessionStorage.setItem("inSystem", "true"); router.go('/messenger'); return; } - Store.set('error', res.response); + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); diff --git a/src/controllers/ChatsController.ts b/src/controllers/ChatsController.ts index 00a9a97bd..24bed7679 100644 --- a/src/controllers/ChatsController.ts +++ b/src/controllers/ChatsController.ts @@ -20,7 +20,8 @@ class ChatsController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -36,7 +37,8 @@ class ChatsController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -61,7 +63,8 @@ class ChatsController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -129,7 +132,8 @@ class ChatsController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); diff --git a/src/controllers/UsersController.ts b/src/controllers/UsersController.ts index ea0cca4da..2ac79101a 100644 --- a/src/controllers/UsersController.ts +++ b/src/controllers/UsersController.ts @@ -17,7 +17,8 @@ class UsersController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -33,7 +34,8 @@ class UsersController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -47,7 +49,8 @@ class UsersController { return; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); }) .catch((error) => { console.error(`${error}`); @@ -61,7 +64,8 @@ class UsersController { return res.response; } - Store.set('error', res.response); + const { reason } = res.response; + Store.set('error', reason); } public async request(id: number) { diff --git a/src/utils/http.ts b/src/utils/http.ts index 2e2d14ce7..f5056e489 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -96,7 +96,7 @@ class HTTP implements IHTTP { try { response = JSON.parse(xhr.responseText); } catch (error) { - console.error(error); + // Send error to logger } const data = {